From 08c0b4c66a22f27ad61c4f743be7ff5acd6edf34 Mon Sep 17 00:00:00 2001
From: Cj <161484149+CJ-SPT@users.noreply.github.com>
Date: Mon, 6 Jan 2025 00:37:06 -0500
Subject: [PATCH 1/7] Add HashUtil.cs
---
Core/Utils/HashUtil.cs | 90 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
create mode 100644 Core/Utils/HashUtil.cs
diff --git a/Core/Utils/HashUtil.cs b/Core/Utils/HashUtil.cs
new file mode 100644
index 00000000..b00a3e3f
--- /dev/null
+++ b/Core/Utils/HashUtil.cs
@@ -0,0 +1,90 @@
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Security.Cryptography;
+
+namespace Types.Utils;
+
+public static partial class HashUtil
+{
+ ///
+ /// Create a 24 character id using the sha256 algorithm + current timestamp
+ ///
+ /// 24 character hash
+ public static string Generate()
+ {
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// is the passed in string a valid mongo id
+ ///
+ /// String to check
+ /// True when string is a valid mongo id
+ public static bool IsValidMongoId(string stringToCheck)
+ {
+ return MongoIdRegex().IsMatch(stringToCheck);
+ }
+
+ public static string GenerateMd5ForData(string data)
+ {
+ return GenerateHashForData(HashingAlgorithm.MD5, data);
+ }
+
+ public static string GenerateSha1ForData(string data)
+ {
+ return GenerateHashForData(HashingAlgorithm.SHA1, data);
+ }
+
+ public static string GenerateCrc32ForData(string data)
+ {
+ // TODO: Could not find a ms way of doing this.
+ // May need a custom impl to avoid an external lib. - CJ
+ throw new NotImplementedException();
+ }
+
+ ///
+ /// Create a hash for the data parameter
+ ///
+ /// algorithm to use to hash
+ /// data to be hashed
+ /// hash value
+ /// thrown if the provided algorithm is not implemented>
+ public static string GenerateHashForData(HashingAlgorithm algorithm, string data)
+ {
+ switch (algorithm)
+ {
+ case HashingAlgorithm.MD5:
+ var md5HashData = MD5.HashData(Encoding.UTF8.GetBytes(data));
+ return Convert.ToHexString(md5HashData).Replace("-", string.Empty);
+
+ case HashingAlgorithm.SHA1:
+ var sha1HashData = SHA1.HashData(Encoding.UTF8.GetBytes(data));
+ return Convert.ToHexString(sha1HashData).Replace("-", string.Empty);
+ }
+
+ throw new NotImplementedException("Provided hash algorithm is not supported.");
+ }
+
+ ///
+ /// Generates an account ID for a profile
+ ///
+ /// Generated account ID
+ public static int GenerateAccountId()
+ {
+ const int min = 1000000;
+ const int max = 1999999;
+
+ var random = new Random();
+
+ return random.Next() * (max - min + 1) + min;
+ }
+
+ [GeneratedRegex("^[a-fA-F0-9]{24}$", RegexOptions.IgnoreCase, "en")]
+ private static partial Regex MongoIdRegex();
+}
+
+public enum HashingAlgorithm
+{
+ MD5,
+ SHA1,
+}
\ No newline at end of file
From eea0872aa7626924db5ed53e27aed2bb46d55a3f Mon Sep 17 00:00:00 2001
From: Cj <161484149+CJ-SPT@users.noreply.github.com>
Date: Mon, 6 Jan 2025 01:30:38 -0500
Subject: [PATCH 2/7] Add TimeUtil.cs
---
Core/Utils/HashUtil.cs | 4 +-
Core/Utils/TimeUtil.cs | 179 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 182 insertions(+), 1 deletion(-)
create mode 100644 Core/Utils/TimeUtil.cs
diff --git a/Core/Utils/HashUtil.cs b/Core/Utils/HashUtil.cs
index b00a3e3f..c0667142 100644
--- a/Core/Utils/HashUtil.cs
+++ b/Core/Utils/HashUtil.cs
@@ -1,10 +1,12 @@
using System.Text;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
+using Types.Annotations;
namespace Types.Utils;
-public static partial class HashUtil
+[Injectable(InjectionType.Singleton)]
+public partial class HashUtil
{
///
/// Create a 24 character id using the sha256 algorithm + current timestamp
diff --git a/Core/Utils/TimeUtil.cs b/Core/Utils/TimeUtil.cs
new file mode 100644
index 00000000..b8621dce
--- /dev/null
+++ b/Core/Utils/TimeUtil.cs
@@ -0,0 +1,179 @@
+using Types.Annotations;
+
+namespace Types.Utils;
+
+[Injectable(InjectionType.Singleton)]
+public class TimeUtil
+{
+ public const int OneHourAsSeconds = 3600;
+
+ ///
+ /// Formats the time part of a date as a UTC string.
+ ///
+ /// The date to format in UTC.
+ /// The formatted time as 'HH-MM-SS'.
+ public string FormatTime(DateTime dateTime)
+ {
+ var hour = Pad(dateTime.ToUniversalTime().Hour);
+ var minute = Pad(dateTime.ToUniversalTime().Minute);
+ var second = Pad(dateTime.ToUniversalTime().Second);
+
+ return $"{hour}-{minute}-{second}";
+ }
+
+ ///
+ /// Formats the date part of a date as a UTC string.
+ ///
+ /// The date to format in UTC.
+ /// The formatted date as 'YYYY-MM-DD'.
+ public string FormatDate(DateTime dateTime)
+ {
+ var day = Pad(dateTime.ToUniversalTime().Day);
+ var month = Pad(dateTime.ToUniversalTime().Month);
+ var year = Pad(dateTime.ToUniversalTime().Year);
+
+ return $"{year}-{month}-{day}";
+ }
+
+ ///
+ /// Gets the current date as a formatted UTC string.
+ ///
+ /// The current date as 'YYYY-MM-DD'.
+ public string GetDate()
+ {
+ return FormatDate(DateTime.Now);
+ }
+
+ ///
+ /// Gets the current time as a formatted UTC string.
+ ///
+ /// The current time as 'HH-MM-SS'.
+ public string GetTime()
+ {
+ return FormatTime(DateTime.Now);
+ }
+
+ ///
+ /// Gets the current timestamp in seconds in UTC.
+ ///
+ /// The current timestamp in seconds since the Unix epoch in UTC.
+ public long GetTimeStamp()
+ {
+ return DateTimeOffset.Now.ToUnixTimeSeconds();
+ }
+
+ ///
+ /// Gets the start of day timestamp for the given date
+ ///
+ /// datetime to get the time stamp for, if null it uses current date.
+ /// Unix epoch for the start of day of the calculated date
+ public long GetStartOfDayTimeStamp(DateTime? dateTime)
+ {
+ var now = dateTime ?? DateTime.Now;
+
+ return new DateTimeOffset(new DateTime(now.Year, now.Month, now.Day, 0, 0, 0))
+ .ToUnixTimeSeconds();
+ }
+
+ ///
+ /// Get timestamp of today + passed in day count
+ ///
+ /// Days from now
+ ///
+ public long GetTimeStampFromNowDays(int daysFromNow)
+ {
+ return DateTimeOffset.Now.AddDays(daysFromNow).ToUnixTimeSeconds();
+ }
+
+ ///
+ /// Get timestamp of today + passed in hour count
+ ///
+ ///
+ ///
+ public long GetTimeStampFromNowHours(int hoursFromNow)
+ {
+ return DateTimeOffset.Now.AddHours(hoursFromNow).ToUnixTimeSeconds();
+ }
+
+ ///
+ /// Gets the current time in UTC in a format suitable for mail in EFT.
+ ///
+ /// The current time as 'HH:MM' in UTC.
+ public string GetTimeMailFormat()
+ {
+ return DateTime.UtcNow.ToString("HH:mm");
+ }
+
+ ///
+ /// Gets the current date in UTC in a format suitable for emails in EFT.
+ ///
+ /// The current date as 'DD.MM.YYYY' in UTC.
+ public string GetDateMailFormat()
+ {
+ return DateTime.UtcNow.ToString("dd.MM.yyyy");
+ }
+
+ ///
+ /// Converts a number of hours into seconds.
+ ///
+ /// The number of hours to convert.
+ /// The equivalent number of seconds.
+ public int GetHoursAsSeconds(int hours)
+ {
+ return OneHourAsSeconds * hours;
+ }
+
+ ///
+ /// Gets the time stamp of the start of the next hour in UTC
+ ///
+ /// Time stamp of the next hour in unix time seconds
+ public long GetTimeStampOfNextHour()
+ {
+ var now = DateTime.UtcNow;
+
+ var nextHour = new DateTime(
+ now.Year,
+ now.Month,
+ now.Day,
+ now.Hour,
+ 0,
+ 0,
+ DateTimeKind.Utc
+ ).AddHours(1);
+
+ return new DateTimeOffset(nextHour).ToUnixTimeSeconds();
+ }
+
+ ///
+ /// Returns the current days timestamp at 00:00
+ /// e.g. current time: 13th March 14:22 will return 13th March 00:00
+ ///
+ /// Timestamp
+ public long GetTodayMidNightTimeStamp()
+ {
+ var now = DateTime.UtcNow;
+
+ var midNight = new DateTime(
+ now.Year,
+ now.Month,
+ now.Day,
+ 0,
+ 0,
+ 0,
+ DateTimeKind.Utc
+ );
+
+ return new DateTimeOffset(midNight).ToUnixTimeSeconds();
+ }
+
+ ///
+ /// Pads a number with a leading zero if it is less than 10.
+ ///
+ /// The number to pad.
+ /// The padded number as a string.
+ ///
+ private static string Pad(int number)
+ {
+ return number.ToString().PadLeft(2, '0');
+ }
+}
\ No newline at end of file
From f09cd50266f82c158ce5dcbebd23575cdcf1b650 Mon Sep 17 00:00:00 2001
From: Cj <161484149+CJ-SPT@users.noreply.github.com>
Date: Mon, 6 Jan 2025 01:43:58 -0500
Subject: [PATCH 3/7] Fix namespaces
---
Core/Annotations/Injectable.cs | 2 +-
Core/Context/ApplicationContext.cs | 4 ++--
Core/Context/ContextVariable.cs | 2 +-
Core/Context/ContextVariableType.cs | 2 +-
Core/Core.csproj | 1 -
Core/Models/Config/HttpConfig.cs | 2 +-
Core/Models/Eft/Common/Tables/BotBase.cs | 2 +-
Core/Models/Eft/Common/Tables/BotCore.cs | 2 +-
Core/Models/Eft/Common/Tables/BotType.cs | 2 +-
Core/Models/Enums/ConfigTypes.cs | 2 +-
Core/Models/Logging/LogBackgroundColor.cs | 2 +-
Core/Models/Logging/LogTextColor.cs | 2 +-
Core/Models/Spt/Bots/Bots.cs | 2 +-
Core/Models/Spt/Server/DatabaseTables.cs | 2 +-
Core/Models/Utils/ILogger.cs | 4 ++--
Core/Servers/ConfigServer.cs | 4 ++--
Core/Servers/DatabaseServer.cs | 2 +-
Core/Servers/Http/IHttpListener.cs | 2 +-
Core/Servers/HttpServer.cs | 15 ++++++++-------
Core/Servers/WebSocketServer.cs | 4 ++--
Core/Services/I18nService.cs | 2 +-
Core/Services/LocaleService.cs | 8 ++++----
Core/Services/LocalisationService.cs | 15 ++++++++-------
Core/Utils/HashUtil.cs | 4 ++--
Core/Utils/Logging/SimpleTextLogger.cs | 11 ++++++-----
Core/Utils/RandomUtil.cs | 2 +-
Core/Utils/TimeUtil.cs | 5 ++---
Server/Program.cs | 4 ++--
28 files changed, 56 insertions(+), 55 deletions(-)
diff --git a/Core/Annotations/Injectable.cs b/Core/Annotations/Injectable.cs
index 667d0fb2..86b1d906 100644
--- a/Core/Annotations/Injectable.cs
+++ b/Core/Annotations/Injectable.cs
@@ -1,4 +1,4 @@
-namespace Types.Annotations;
+namespace Core.Annotations;
[AttributeUsage(AttributeTargets.Class)]
public class Injectable(InjectionType injectionType = InjectionType.Scoped, Type? type = null) : Attribute
diff --git a/Core/Context/ApplicationContext.cs b/Core/Context/ApplicationContext.cs
index 51f2ce84..05b10522 100644
--- a/Core/Context/ApplicationContext.cs
+++ b/Core/Context/ApplicationContext.cs
@@ -1,6 +1,6 @@
-using Types.Annotations;
+using Core.Annotations;
-namespace Types.Context;
+namespace Core.Context;
[Injectable(InjectionType.Singleton)]
public class ApplicationContext
diff --git a/Core/Context/ContextVariable.cs b/Core/Context/ContextVariable.cs
index 7bea953c..3e79b5f0 100644
--- a/Core/Context/ContextVariable.cs
+++ b/Core/Context/ContextVariable.cs
@@ -1,4 +1,4 @@
-namespace Types.Context;
+namespace Core.Context;
public class ContextVariable(object value, ContextVariableType contextVariableType)
{
diff --git a/Core/Context/ContextVariableType.cs b/Core/Context/ContextVariableType.cs
index 0f64ca1b..409e7656 100644
--- a/Core/Context/ContextVariableType.cs
+++ b/Core/Context/ContextVariableType.cs
@@ -1,4 +1,4 @@
-namespace Types.Context;
+namespace Core.Context;
public enum ContextVariableType
{
diff --git a/Core/Core.csproj b/Core/Core.csproj
index c84e1b8b..aa09572c 100644
--- a/Core/Core.csproj
+++ b/Core/Core.csproj
@@ -5,7 +5,6 @@
enable
enable
Library
- Types
diff --git a/Core/Models/Config/HttpConfig.cs b/Core/Models/Config/HttpConfig.cs
index 71a1c612..b661f3b1 100644
--- a/Core/Models/Config/HttpConfig.cs
+++ b/Core/Models/Config/HttpConfig.cs
@@ -1,4 +1,4 @@
-namespace Types.Models.Config;
+namespace Core.Models.Config;
public class HttpConfig
{
diff --git a/Core/Models/Eft/Common/Tables/BotBase.cs b/Core/Models/Eft/Common/Tables/BotBase.cs
index f1b151c6..d77fd12a 100644
--- a/Core/Models/Eft/Common/Tables/BotBase.cs
+++ b/Core/Models/Eft/Common/Tables/BotBase.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Types.Models.Eft.Common.Tables;
+namespace Core.Models.Eft.Common.Tables;
public class BotBase
{
diff --git a/Core/Models/Eft/Common/Tables/BotCore.cs b/Core/Models/Eft/Common/Tables/BotCore.cs
index 5d6c8952..38732b91 100644
--- a/Core/Models/Eft/Common/Tables/BotCore.cs
+++ b/Core/Models/Eft/Common/Tables/BotCore.cs
@@ -1,4 +1,4 @@
-namespace Types.Models.Eft.Common.Tables;
+namespace Core.Models.Eft.Common.Tables;
public class BotCore
{
diff --git a/Core/Models/Eft/Common/Tables/BotType.cs b/Core/Models/Eft/Common/Tables/BotType.cs
index baa8e24f..e9930fda 100644
--- a/Core/Models/Eft/Common/Tables/BotType.cs
+++ b/Core/Models/Eft/Common/Tables/BotType.cs
@@ -1,4 +1,4 @@
-namespace Types.Models.Eft.Common.Tables;
+namespace Core.Models.Eft.Common.Tables;
public class BotType
{
diff --git a/Core/Models/Enums/ConfigTypes.cs b/Core/Models/Enums/ConfigTypes.cs
index 822e6f27..66cfac6a 100644
--- a/Core/Models/Enums/ConfigTypes.cs
+++ b/Core/Models/Enums/ConfigTypes.cs
@@ -1,4 +1,4 @@
-namespace Types.Models.Enums;
+namespace Core.Models.Enums;
public enum ConfigTypes
{
diff --git a/Core/Models/Logging/LogBackgroundColor.cs b/Core/Models/Logging/LogBackgroundColor.cs
index 6ba9878d..08c5d2c8 100644
--- a/Core/Models/Logging/LogBackgroundColor.cs
+++ b/Core/Models/Logging/LogBackgroundColor.cs
@@ -1,4 +1,4 @@
-namespace Types.Models.Logging;
+namespace Core.Models.Logging;
public enum LogBackgroundColor
{
diff --git a/Core/Models/Logging/LogTextColor.cs b/Core/Models/Logging/LogTextColor.cs
index 4188878d..c2a76282 100644
--- a/Core/Models/Logging/LogTextColor.cs
+++ b/Core/Models/Logging/LogTextColor.cs
@@ -1,4 +1,4 @@
-namespace Types.Models.Logging;
+namespace Core.Models.Logging;
public enum LogTextColor
{
diff --git a/Core/Models/Spt/Bots/Bots.cs b/Core/Models/Spt/Bots/Bots.cs
index ae563b09..24605116 100644
--- a/Core/Models/Spt/Bots/Bots.cs
+++ b/Core/Models/Spt/Bots/Bots.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Types.Models.Spt.Bots;
+namespace Core.Models.Spt.Bots;
public class Bots
{
diff --git a/Core/Models/Spt/Server/DatabaseTables.cs b/Core/Models/Spt/Server/DatabaseTables.cs
index eea46689..fa6eb47a 100644
--- a/Core/Models/Spt/Server/DatabaseTables.cs
+++ b/Core/Models/Spt/Server/DatabaseTables.cs
@@ -1,4 +1,4 @@
-namespace Types.Models.Spt.Server;
+namespace Core.Models.Spt.Server;
public class DatabaseTables
{
diff --git a/Core/Models/Utils/ILogger.cs b/Core/Models/Utils/ILogger.cs
index cd73d2f6..3554c800 100644
--- a/Core/Models/Utils/ILogger.cs
+++ b/Core/Models/Utils/ILogger.cs
@@ -1,6 +1,6 @@
-using Types.Models.Logging;
+using Core.Models.Logging;
-namespace Types.Models.Utils;
+namespace Core.Models.Utils;
public interface ILogger
{
diff --git a/Core/Servers/ConfigServer.cs b/Core/Servers/ConfigServer.cs
index cd471290..50813186 100644
--- a/Core/Servers/ConfigServer.cs
+++ b/Core/Servers/ConfigServer.cs
@@ -1,6 +1,6 @@
-using Types.Annotations;
+using Core.Annotations;
-namespace Types.Servers;
+namespace Core.Servers;
[Injectable(InjectionType.Singleton)]
public class ConfigServer
diff --git a/Core/Servers/DatabaseServer.cs b/Core/Servers/DatabaseServer.cs
index 7045e67d..ea6a69a4 100644
--- a/Core/Servers/DatabaseServer.cs
+++ b/Core/Servers/DatabaseServer.cs
@@ -1,4 +1,4 @@
-namespace Types.Servers;
+namespace Core.Servers;
public class DatabaseServer
{
diff --git a/Core/Servers/Http/IHttpListener.cs b/Core/Servers/Http/IHttpListener.cs
index 4a74d910..5161850c 100644
--- a/Core/Servers/Http/IHttpListener.cs
+++ b/Core/Servers/Http/IHttpListener.cs
@@ -1,4 +1,4 @@
-namespace Types.Servers.Http;
+namespace Core.Servers.Http;
public interface IHttpListener
{
diff --git a/Core/Servers/HttpServer.cs b/Core/Servers/HttpServer.cs
index d3135cb1..c74ccfd0 100644
--- a/Core/Servers/HttpServer.cs
+++ b/Core/Servers/HttpServer.cs
@@ -1,13 +1,14 @@
using System.Net.WebSockets;
+using Core.Context;
+using Core.Models.Config;
+using Core.Servers.Http;
+using Core.Services;
using Microsoft.Extensions.Primitives;
-using Types.Annotations;
-using Types.Context;
-using Types.Models.Config;
-using Types.Servers.Http;
-using Types.Services;
-using ILogger = Types.Models.Utils.ILogger;
+using Core.Annotations;
+using ILogger = Core.Models.Utils.ILogger;
+using Utils_ILogger = Core.Models.Utils.ILogger;
-namespace Types.Servers;
+namespace Core.Servers;
[Injectable(InjectionType.Singleton)]
public class HttpServer
diff --git a/Core/Servers/WebSocketServer.cs b/Core/Servers/WebSocketServer.cs
index 42ce2f9e..5ec5648b 100644
--- a/Core/Servers/WebSocketServer.cs
+++ b/Core/Servers/WebSocketServer.cs
@@ -1,6 +1,6 @@
-using Types.Annotations;
+using Core.Annotations;
-namespace Types.Servers;
+namespace Core.Servers;
[Injectable(InjectionType.Singleton)]
public class WebSocketServer
diff --git a/Core/Services/I18nService.cs b/Core/Services/I18nService.cs
index bc31e90a..e508af5a 100644
--- a/Core/Services/I18nService.cs
+++ b/Core/Services/I18nService.cs
@@ -1,4 +1,4 @@
-namespace Types.Services;
+namespace Core.Services;
public class I18nService
{
diff --git a/Core/Services/LocaleService.cs b/Core/Services/LocaleService.cs
index c194da1c..ac343072 100644
--- a/Core/Services/LocaleService.cs
+++ b/Core/Services/LocaleService.cs
@@ -1,8 +1,8 @@
-using Types.Annotations;
-using Types.Servers;
-using ILogger = Types.Models.Utils.ILogger;
+using Core.Annotations;
+using Core.Servers;
+using ILogger = Core.Models.Utils.ILogger;
-namespace Types.Services;
+namespace Core.Services;
[Injectable(InjectionType.Singleton)]
public class LocaleService
diff --git a/Core/Services/LocalisationService.cs b/Core/Services/LocalisationService.cs
index 6ae740f8..87b0de06 100644
--- a/Core/Services/LocalisationService.cs
+++ b/Core/Services/LocalisationService.cs
@@ -1,21 +1,22 @@
-using Types.Annotations;
-using Types.Servers;
-using Types.Utils;
-using ILogger = Types.Models.Utils.ILogger;
+using Core.Utils;
+using Core.Annotations;
+using Core.Servers;
+using ILogger = Core.Models.Utils.ILogger;
+using Utils_ILogger = Core.Models.Utils.ILogger;
-namespace Types.Services;
+namespace Core.Services;
[Injectable(InjectionType.Singleton)]
public class LocalisationService
{
- private readonly ILogger _logger;
+ private readonly Utils_ILogger _logger;
private readonly RandomUtil _randomUtil;
private readonly DatabaseServer _databaseServer;
private readonly LocaleService _localeService;
private readonly I18nService _i18nService;
public LocalisationService(
- ILogger logger,
+ Utils_ILogger logger,
RandomUtil randomUtil,
DatabaseServer databaseServer,
LocaleService localeService
diff --git a/Core/Utils/HashUtil.cs b/Core/Utils/HashUtil.cs
index c0667142..b1a3318c 100644
--- a/Core/Utils/HashUtil.cs
+++ b/Core/Utils/HashUtil.cs
@@ -1,9 +1,9 @@
using System.Text;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
-using Types.Annotations;
+using Core.Annotations;
-namespace Types.Utils;
+namespace Core.Utils;
[Injectable(InjectionType.Singleton)]
public partial class HashUtil
diff --git a/Core/Utils/Logging/SimpleTextLogger.cs b/Core/Utils/Logging/SimpleTextLogger.cs
index a09f55af..beb1f2a0 100644
--- a/Core/Utils/Logging/SimpleTextLogger.cs
+++ b/Core/Utils/Logging/SimpleTextLogger.cs
@@ -1,11 +1,12 @@
-using Types.Annotations;
-using Types.Models.Logging;
-using ILogger = Types.Models.Utils.ILogger;
+using Core.Models.Logging;
+using Core.Annotations;
+using ILogger = Core.Models.Utils.ILogger;
+using Utils_ILogger = Core.Models.Utils.ILogger;
-namespace Types.Utils.Logging;
+namespace Core.Utils.Logging;
[Injectable(InjectionType.Singleton)]
-public class SimpleTextLogger : ILogger
+public class SimpleTextLogger : Utils_ILogger
{
// TODO: for now we simplify the logger into this barebones console writer
public void WriteToLogFile(string data)
diff --git a/Core/Utils/RandomUtil.cs b/Core/Utils/RandomUtil.cs
index 73bc97f4..ded07f39 100644
--- a/Core/Utils/RandomUtil.cs
+++ b/Core/Utils/RandomUtil.cs
@@ -1,4 +1,4 @@
-namespace Types.Utils;
+namespace Core.Utils;
public class RandomUtil
{
diff --git a/Core/Utils/TimeUtil.cs b/Core/Utils/TimeUtil.cs
index b8621dce..94fcbb61 100644
--- a/Core/Utils/TimeUtil.cs
+++ b/Core/Utils/TimeUtil.cs
@@ -1,6 +1,6 @@
-using Types.Annotations;
+using Core.Annotations;
-namespace Types.Utils;
+namespace Core.Utils;
[Injectable(InjectionType.Singleton)]
public class TimeUtil
@@ -171,7 +171,6 @@ public class TimeUtil
///
/// The number to pad.
/// The padded number as a string.
- ///
private static string Pad(int number)
{
return number.ToString().PadLeft(2, '0');
diff --git a/Server/Program.cs b/Server/Program.cs
index 765f8ee9..6e6d8a21 100644
--- a/Server/Program.cs
+++ b/Server/Program.cs
@@ -1,5 +1,5 @@
-using Types.Annotations;
-using Types.Servers;
+using Core.Annotations;
+using Core.Servers;
namespace Server;
From 7fc5a8a190b8f2b3516219a5dadb0190d9baeb18 Mon Sep 17 00:00:00 2001
From: Cj <161484149+CJ-SPT@users.noreply.github.com>
Date: Mon, 6 Jan 2025 01:54:59 -0500
Subject: [PATCH 4/7] Fix ILogger usings
---
Core/Servers/HttpServer.cs | 1 -
Core/Services/LocalisationService.cs | 5 ++---
Core/Utils/Logging/SimpleTextLogger.cs | 3 +--
3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/Core/Servers/HttpServer.cs b/Core/Servers/HttpServer.cs
index c74ccfd0..c4d9b749 100644
--- a/Core/Servers/HttpServer.cs
+++ b/Core/Servers/HttpServer.cs
@@ -6,7 +6,6 @@ using Core.Services;
using Microsoft.Extensions.Primitives;
using Core.Annotations;
using ILogger = Core.Models.Utils.ILogger;
-using Utils_ILogger = Core.Models.Utils.ILogger;
namespace Core.Servers;
diff --git a/Core/Services/LocalisationService.cs b/Core/Services/LocalisationService.cs
index 87b0de06..cbf8dfef 100644
--- a/Core/Services/LocalisationService.cs
+++ b/Core/Services/LocalisationService.cs
@@ -2,21 +2,20 @@
using Core.Annotations;
using Core.Servers;
using ILogger = Core.Models.Utils.ILogger;
-using Utils_ILogger = Core.Models.Utils.ILogger;
namespace Core.Services;
[Injectable(InjectionType.Singleton)]
public class LocalisationService
{
- private readonly Utils_ILogger _logger;
+ private readonly ILogger _logger;
private readonly RandomUtil _randomUtil;
private readonly DatabaseServer _databaseServer;
private readonly LocaleService _localeService;
private readonly I18nService _i18nService;
public LocalisationService(
- Utils_ILogger logger,
+ ILogger logger,
RandomUtil randomUtil,
DatabaseServer databaseServer,
LocaleService localeService
diff --git a/Core/Utils/Logging/SimpleTextLogger.cs b/Core/Utils/Logging/SimpleTextLogger.cs
index beb1f2a0..989b41fa 100644
--- a/Core/Utils/Logging/SimpleTextLogger.cs
+++ b/Core/Utils/Logging/SimpleTextLogger.cs
@@ -1,12 +1,11 @@
using Core.Models.Logging;
using Core.Annotations;
using ILogger = Core.Models.Utils.ILogger;
-using Utils_ILogger = Core.Models.Utils.ILogger;
namespace Core.Utils.Logging;
[Injectable(InjectionType.Singleton)]
-public class SimpleTextLogger : Utils_ILogger
+public class SimpleTextLogger : ILogger
{
// TODO: for now we simplify the logger into this barebones console writer
public void WriteToLogFile(string data)
From 468867ba3df52b695479697594f64ffa50b5581f Mon Sep 17 00:00:00 2001
From: Cj <161484149+CJ-SPT@users.noreply.github.com>
Date: Mon, 6 Jan 2025 06:09:12 -0500
Subject: [PATCH 5/7] Start porting RandomUtil.cs, not yet done.
---
Core/Utils/RandomUtil.cs | 169 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 168 insertions(+), 1 deletion(-)
diff --git a/Core/Utils/RandomUtil.cs b/Core/Utils/RandomUtil.cs
index ded07f39..dd8c41e4 100644
--- a/Core/Utils/RandomUtil.cs
+++ b/Core/Utils/RandomUtil.cs
@@ -1,6 +1,173 @@
-namespace Core.Utils;
+using System.Security.Cryptography;
+using Core.Annotations;
+namespace Core.Utils;
+
+// TODO: Finish porting this class
+[Injectable(InjectionType.Singleton)]
public class RandomUtil
{
+ private readonly Random _random = new();
+ ///
+ /// Generates a random integer between the specified minimum and maximum values, inclusive.
+ ///
+ /// The minimum value (inclusive).
+ /// The maximum value (inclusive).
+ /// A random integer between the specified minimum and maximum values.
+ public int GetInt(int min, int max)
+ {
+ // Prevents a potential integer overflow.
+ if (max == int.MaxValue)
+ {
+ max -= 1;
+ }
+
+ // maxVal is exclusive of the passed value, so add 1
+ return max > min ? _random.Next(min, max + 1) : min;
+ }
+
+ ///
+ /// Generates a random integer between 1 (inclusive) and the specified maximum value (exclusive).
+ /// If the maximum value is less than or equal to 1, it returns 1.
+ ///
+ /// The upper bound (exclusive) for the random integer generation.
+ /// A random integer between 1 and max - 1, or 1 if max is less than or equal to 1.
+ public int GetIntEx(int max)
+ {
+ return max > 2 ? _random.Next(1, max - 1) : 1;
+ }
+
+ ///
+ /// Generates a random floating-point number within the specified range.
+ ///
+ /// The minimum value of the range (inclusive).
+ /// The maximum value of the range (exclusive).
+ /// A random floating-point number between `min` (inclusive) and `max` (exclusive).
+ public float GetFloat(float min, float max)
+ {
+ return (float)GetSecureRandomNumber() * (max - min) + min;
+ }
+
+ ///
+ /// Generates a random boolean value.
+ ///
+ /// A random boolean value, where the probability of `true` and `false` is approximately equal.
+ public bool GetBool()
+ {
+ return GetSecureRandomNumber() < 0.5;
+ }
+
+ ///
+ /// Calculates the percentage of a given number and returns the result.
+ ///
+ /// The percentage to calculate.
+ /// The number to calculate the percentage of.
+ /// The number of decimal places to round the result to (default is 2).
+ /// The calculated percentage of the given number, rounded to the specified number of decimal places.
+ public float GetPercentOfValue(float percent, float number, int toFixed = 2)
+ {
+ var num = percent * number / 100;
+
+ return (float)Math.Round(num, toFixed);
+ }
+
+ ///
+ /// Reduces a given number by a specified percentage.
+ ///
+ /// The original number to be reduced.
+ /// The percentage by which to reduce the number.
+ /// The reduced number after applying the percentage reduction.
+ public float ReduceValueByPercent(float number, float percentage)
+ {
+ var reductionAmount = number * percentage / 100;
+
+ return number - reductionAmount;
+ }
+
+ ///
+ /// Determines if a random event occurs based on the given chance percentage.
+ ///
+ /// The percentage chance (0-100) that the event will occur.
+ /// `true` if the event occurs, `false` otherwise.
+ public bool GetChance100(float chancePercent)
+ {
+ chancePercent = Math.Clamp(chancePercent, 0f, 100f);
+
+ return GetIntEx(100) <= chancePercent;
+ }
+
+ ///
+ /// Returns a random string from the provided collection of strings.
+ ///
+ /// This method is separate from GetCollectionValue so we can use a generic inference with GetCollectionValue.
+ ///
+ /// The collection of strings to select a random value from.
+ /// A randomly selected string from the array.
+ public string GetStringCollectionValue(IEnumerable collection)
+ {
+ return collection.ElementAt(GetInt(0, collection.Count() - 1));
+ }
+
+ ///
+ /// Returns a random string from the provided collection of strings.
+ ///
+ ///
+ /// The type of elements in the collection.
+ /// A random element from the collection.
+ /// This was formerly getArrayValue() in the node server
+ public T GetCollectionValue(IEnumerable collection)
+ {
+ return collection.ElementAt(GetInt(0, collection.Count() - 1));
+ }
+
+ ///
+ /// Gets a random key from the given dictionary
+ ///
+ /// The dictionary from which to retrieve a key.
+ /// Type of key
+ /// Type of Value
+ /// A random TKey representing one of the keys of the dictionary.
+ public TKey GetKey(Dictionary dictionary) where TKey : notnull
+ {
+ return GetCollectionValue(dictionary.Keys);
+ }
+
+ ///
+ /// Generates a secure random number between 0 (inclusive) and 1 (exclusive).
+ ///
+ /// This method uses the `crypto` module to generate a 48-bit random integer,
+ /// which is then divided by the maximum possible 48-bit integer value to
+ /// produce a floating-point number in the range [0, 1).
+ ///
+ /// A secure random number between 0 (inclusive) and 1 (exclusive).
+ private static double GetSecureRandomNumber()
+ {
+ var buffer = new byte[6];
+
+ using var rng = RandomNumberGenerator.Create();
+
+ // Fill buffer with random bytes
+ rng.GetBytes(buffer);
+
+ var integer = 0;
+ for (var i = 0; i < 6; i++)
+ {
+ integer = (integer << 8) | buffer[i];
+ }
+
+ const ulong maxInt = 1UL << 48;
+
+ return (double)integer / maxInt;
+ }
+
+ ///
+ /// Determines the number of decimal places in a number.
+ ///
+ /// The number to analyze.
+ /// The number of decimal places, or 0 if none exist.
+ private static int GetNumberPrecision(double num)
+ {
+ return num.ToString().Split('.')[1]?.Length ?? 0;
+ }
}
\ No newline at end of file
From 6fd7e31b282625d2612588d3cea8fb5bc872fcef Mon Sep 17 00:00:00 2001
From: Alex
Date: Mon, 6 Jan 2025 16:13:48 +0000
Subject: [PATCH 6/7] more namespaces and BotBase migrated
---
Core/Models/Eft/Common/Tables/BotBase.cs | 94 ++++++++++++++++++-
.../Spt/Quests/GetRepeatableByIdResult.cs | 2 +-
.../Models/Spt/Ragfair/RagfairServerPrices.cs | 2 +-
Core/Models/Spt/Ragfair/TplWithFleaPrice.cs | 2 +-
.../Spt/Repeatable/QuestRewardValues.cs | 2 +-
Core/Models/Spt/Repeatable/QuestTypePool.cs | 2 +-
Core/Models/Spt/Server/ExhaustableArray.cs | 2 +-
Core/Models/Spt/Server/LocaleBase.cs | 2 +-
Core/Models/Spt/Server/Locations.cs | 2 +-
Core/Models/Spt/Server/ServerBase.cs | 2 +-
Core/Models/Spt/Server/SettingsBase.cs | 2 +-
11 files changed, 103 insertions(+), 11 deletions(-)
diff --git a/Core/Models/Eft/Common/Tables/BotBase.cs b/Core/Models/Eft/Common/Tables/BotBase.cs
index df51dbf4..45092c10 100644
--- a/Core/Models/Eft/Common/Tables/BotBase.cs
+++ b/Core/Models/Eft/Common/Tables/BotBase.cs
@@ -4,9 +4,101 @@ namespace Core.Models.Eft.Common.Tables;
public class BotBase
{
-
+ [JsonPropertyName("_id")]
+ public string Id { get; set; }
+ [JsonPropertyName("aid")]
+ public int Aid { get; set; }
+ /** SPT property - use to store player id - TODO - move to AID ( account id as guid of choice) */
+ [JsonPropertyName("sessionId")]
+ public string SessionId { get; set; }
+ [JsonPropertyName("savage")]
+ public string? Savage { get; set; }
+ [JsonPropertyName("karmaValue")]
+ public int KarmaValue { get; set; }
+ [JsonPropertyName("Info")]
+ public Info Info { get; set; }
+ [JsonPropertyName("Customization")]
+ public Customization Customization { get; set; }
+ [JsonPropertyName("Health")]
+ public Health Health { get; set; }
+ [JsonPropertyName("Inventory")]
+ public Inventory Inventory { get; set; }
+ [JsonPropertyName("Skills")]
+ public Skills Skills { get; set; }
+ [JsonPropertyName("Stats")]
+ public Stats Stats { get; set; }
+ [JsonPropertyName("Encyclopedia")]
+ public Dictionary Encyclopedia { get; set; }
+ [JsonPropertyName("TaskConditionCounters")]
+ public Dictionary TaskConditionCounters { get; set; }
+ [JsonPropertyName("InsuredItems")]
+ public List InsuredItems { get; set; }
+ [JsonPropertyName("Hideout")]
+ public Hideout Hideout { get; set; }
+ [JsonPropertyName("Quests")]
+ public List Quests { get; set; }
+ [JsonPropertyName("TradersInfo")]
+ public Dictionary TradersInfo { get; set; }
+ [JsonPropertyName("UnlockedInfo")]
+ public UnlockedInfo UnlockedInfo { get; set; }
+ [JsonPropertyName("RagfairInfo")]
+ public RagfairInfo RagfairInfo { get; set; }
+ /** Achievement id and timestamp */
+ [JsonPropertyName("Achievements")]
+ public Dictionary Achievements { get; set; }
+ [JsonPropertyName("RepeatableQuests")]
+ public List RepeatableQuests { get; set; }
+ [JsonPropertyName("Bonuses")]
+ public List Bonuses { get; set; }
+ [JsonPropertyName("Notes")]
+ public Notes Notes { get; set; }
+ [JsonPropertyName("CarExtractCounts")]
+ public Dictionary CarExtractCounts { get; set; }
+ [JsonPropertyName("CoopExtractCounts")]
+ public Dictionary CoopExtractCounts { get; set; }
+ [JsonPropertyName("SurvivorClass")]
+ public SurvivorClass SurvivorClass { get; set; }
+ [JsonPropertyName("WishList")]
+ public Dictionary WishList { get; set; }
+ [JsonPropertyName("moneyTransferLimitData")]
+ public MoneyTransferLimits MoneyTransferLimitData { get; set; }
+ /** SPT specific property used during bot generation in raid */
+ [JsonPropertyName("sptIsPmc")]
+ public bool? IsPmc { get; set; }
}
+public class MoneyTransferLimits
+{
+ // Resets every 24 hours in live
+ /** TODO: Implement */
+ [JsonPropertyName("nextResetTime")]
+ public double NextResetTime { get; set; }
+ [JsonPropertyName("remainingLimit")]
+ public double RemainingLimit { get; set; }
+ [JsonPropertyName("totalLimit")]
+ public double TotalLimit { get; set; }
+ [JsonPropertyName("resetInterval")]
+ public double ResetInterval { get; set; }
+}
+
+public class TaskConditionCounter
+{
+ [JsonPropertyName("id")]
+ public string Id { get; set; }
+ [JsonPropertyName("type")]
+ public string Type { get; set; }
+ [JsonPropertyName("value")]
+ public double Value { get; set; }
+ /** Quest id */
+ [JsonPropertyName("sourceId")]
+ public string SourceId { get; set; }
+}
+
+public class UnlockedInfo
+{
+ [JsonPropertyName("unlockedProductionRecipe")]
+ public List UnlockedProductionRecipe { get; set; }
+}
public class Info
{
diff --git a/Core/Models/Spt/Quests/GetRepeatableByIdResult.cs b/Core/Models/Spt/Quests/GetRepeatableByIdResult.cs
index c1abfe7d..7fa2e8e1 100644
--- a/Core/Models/Spt/Quests/GetRepeatableByIdResult.cs
+++ b/Core/Models/Spt/Quests/GetRepeatableByIdResult.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Types.Models.Spt.Quests;
+namespace Core.Models.Spt.Quests;
public class GetRepeatableByIdResult
{
diff --git a/Core/Models/Spt/Ragfair/RagfairServerPrices.cs b/Core/Models/Spt/Ragfair/RagfairServerPrices.cs
index c95c0236..74053c8d 100644
--- a/Core/Models/Spt/Ragfair/RagfairServerPrices.cs
+++ b/Core/Models/Spt/Ragfair/RagfairServerPrices.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Types.Models.Spt.Ragfair;
+namespace Core.Models.Spt.Ragfair;
public class RagfairServerPrices
{
diff --git a/Core/Models/Spt/Ragfair/TplWithFleaPrice.cs b/Core/Models/Spt/Ragfair/TplWithFleaPrice.cs
index a9181ade..50bfa61a 100644
--- a/Core/Models/Spt/Ragfair/TplWithFleaPrice.cs
+++ b/Core/Models/Spt/Ragfair/TplWithFleaPrice.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Types.Models.Spt.Ragfair;
+namespace Core.Models.Spt.Ragfair;
public class TplWithFleaPrice
{
diff --git a/Core/Models/Spt/Repeatable/QuestRewardValues.cs b/Core/Models/Spt/Repeatable/QuestRewardValues.cs
index 89963dd6..c0e986c0 100644
--- a/Core/Models/Spt/Repeatable/QuestRewardValues.cs
+++ b/Core/Models/Spt/Repeatable/QuestRewardValues.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Types.Models.Spt.Repeatable;
+namespace Core.Models.Spt.Repeatable;
public class QuestRewardValues
{
diff --git a/Core/Models/Spt/Repeatable/QuestTypePool.cs b/Core/Models/Spt/Repeatable/QuestTypePool.cs
index ad73a0d7..abdec822 100644
--- a/Core/Models/Spt/Repeatable/QuestTypePool.cs
+++ b/Core/Models/Spt/Repeatable/QuestTypePool.cs
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
-namespace Types.Models.Spt.Repeatable;
+namespace Core.Models.Spt.Repeatable;
public class QuestTypePool
{
diff --git a/Core/Models/Spt/Server/ExhaustableArray.cs b/Core/Models/Spt/Server/ExhaustableArray.cs
index 2ed7bcb9..7f539d8a 100644
--- a/Core/Models/Spt/Server/ExhaustableArray.cs
+++ b/Core/Models/Spt/Server/ExhaustableArray.cs
@@ -1,6 +1,6 @@
// using System.Collections.Generic;
//
-// namespace Types.Models.Spt.Server;
+// namespace Core.Models.Spt.Server;
//
// public class ExhaustableArray
// {
diff --git a/Core/Models/Spt/Server/LocaleBase.cs b/Core/Models/Spt/Server/LocaleBase.cs
index 37feec9e..064301db 100644
--- a/Core/Models/Spt/Server/LocaleBase.cs
+++ b/Core/Models/Spt/Server/LocaleBase.cs
@@ -1,7 +1,7 @@
using System.Text.Json.Serialization;
using System.Collections.Generic;
-namespace Types.Models.Spt.Server;
+namespace Core.Models.Spt.Server;
public class LocaleBase
{
diff --git a/Core/Models/Spt/Server/Locations.cs b/Core/Models/Spt/Server/Locations.cs
index 89d7f8b7..0d0fc118 100644
--- a/Core/Models/Spt/Server/Locations.cs
+++ b/Core/Models/Spt/Server/Locations.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Types.Models.Spt.Server;
+namespace Core.Models.Spt.Server;
public class Locations
{
diff --git a/Core/Models/Spt/Server/ServerBase.cs b/Core/Models/Spt/Server/ServerBase.cs
index 3e12c4ad..fbf2df39 100644
--- a/Core/Models/Spt/Server/ServerBase.cs
+++ b/Core/Models/Spt/Server/ServerBase.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Types.Models.Spt.Server;
+namespace Core.Models.Spt.Server;
public class ServerBase
{
diff --git a/Core/Models/Spt/Server/SettingsBase.cs b/Core/Models/Spt/Server/SettingsBase.cs
index a41cc5cd..1475d93a 100644
--- a/Core/Models/Spt/Server/SettingsBase.cs
+++ b/Core/Models/Spt/Server/SettingsBase.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace Types.Models.Spt.Server;
+namespace Core.Models.Spt.Server;
public class SettingsBase
{
From c23e9fff02dda2ca51d01ed7625a913b93ab66dc Mon Sep 17 00:00:00 2001
From: Alex
Date: Mon, 6 Jan 2025 17:16:10 +0000
Subject: [PATCH 7/7] more models
---
Core/Models/Common/MinMax.cs | 12 +
Core/Models/Eft/Common/Location.cs | 187 ++++
Core/Models/Eft/Common/LocationBase.cs | 842 ++++++++++++++++++
Core/Models/Eft/Common/LooseLoot.cs | 118 +++
Core/Models/Eft/Common/Tables/BotBase.cs | 6 +-
Core/Models/Eft/Common/Tables/Item.cs | 245 +++++
.../Models/Eft/Common/Tables/LocationsBase.cs | 26 +
Core/Models/Eft/Common/Tables/Quest.cs | 442 +++++++++
.../Eft/Common/Tables/RepeatableQuests.cs | 230 +++++
Core/Models/Eft/Common/XYZ.cs | 15 +
Core/Models/Eft/Ragfair/RagfairOffer.cs | 121 +++
Core/Models/Enums/BonusSkillType.cs | 10 +
Core/Models/Enums/BonusType.cs | 36 +
Core/Models/Enums/DogtagExchangeSide.cs | 8 +
Core/Models/Enums/ELocationName.cs | 17 +
Core/Models/Enums/HideoutAreas.cs | 34 +
Core/Models/Enums/MemberCategory.cs | 17 +
Core/Models/Enums/QuestRewardType.cs | 17 +
Core/Models/Enums/QuestStatus.cs | 15 +
Core/Models/Enums/QuestTypeEnum.cs | 18 +
Core/Models/Spt/Bots/Bots.cs | 1 +
.../Spt/Quests/GetRepeatableByIdResult.cs | 1 +
Core/Models/Spt/Repeatable/QuestTypePool.cs | 1 +
Core/Models/Spt/Server/Locations.cs | 2 +
server-csharp.sln.DotSettings | 5 +
25 files changed, 2424 insertions(+), 2 deletions(-)
create mode 100644 Core/Models/Common/MinMax.cs
create mode 100644 Core/Models/Eft/Common/Location.cs
create mode 100644 Core/Models/Eft/Common/LocationBase.cs
create mode 100644 Core/Models/Eft/Common/LooseLoot.cs
create mode 100644 Core/Models/Eft/Common/Tables/Item.cs
create mode 100644 Core/Models/Eft/Common/Tables/LocationsBase.cs
create mode 100644 Core/Models/Eft/Common/Tables/Quest.cs
create mode 100644 Core/Models/Eft/Common/Tables/RepeatableQuests.cs
create mode 100644 Core/Models/Eft/Common/XYZ.cs
create mode 100644 Core/Models/Eft/Ragfair/RagfairOffer.cs
create mode 100644 Core/Models/Enums/BonusSkillType.cs
create mode 100644 Core/Models/Enums/BonusType.cs
create mode 100644 Core/Models/Enums/DogtagExchangeSide.cs
create mode 100644 Core/Models/Enums/ELocationName.cs
create mode 100644 Core/Models/Enums/HideoutAreas.cs
create mode 100644 Core/Models/Enums/MemberCategory.cs
create mode 100644 Core/Models/Enums/QuestRewardType.cs
create mode 100644 Core/Models/Enums/QuestStatus.cs
create mode 100644 Core/Models/Enums/QuestTypeEnum.cs
create mode 100644 server-csharp.sln.DotSettings
diff --git a/Core/Models/Common/MinMax.cs b/Core/Models/Common/MinMax.cs
new file mode 100644
index 00000000..2ed8cae1
--- /dev/null
+++ b/Core/Models/Common/MinMax.cs
@@ -0,0 +1,12 @@
+using System.Text.Json.Serialization;
+
+namespace Core.Models.Common;
+
+public class MinMax
+{
+ [JsonPropertyName("max")]
+ public double Max { get; set; }
+
+ [JsonPropertyName("min")]
+ public double Min { get; set; }
+}
\ No newline at end of file
diff --git a/Core/Models/Eft/Common/Location.cs b/Core/Models/Eft/Common/Location.cs
new file mode 100644
index 00000000..d9ccba3a
--- /dev/null
+++ b/Core/Models/Eft/Common/Location.cs
@@ -0,0 +1,187 @@
+using System.Text.Json.Serialization;
+using Core.Models.Eft.Common.Tables;
+
+namespace Core.Models.Eft.Common;
+
+public class Location
+{
+ /** Map meta-data */
+ [JsonPropertyName("base")]
+ public LocationBase Base { get; set; }
+
+ /** Loose loot positions and item weights */
+ [JsonPropertyName("looseLoot")]
+ public LooseLoot LooseLoot { get; set; }
+
+ /** Static loot item weights */
+ [JsonPropertyName("staticLoot")]
+ public Dictionary StaticLoot { get; set; }
+
+ /** Static container positions and item weights */
+ [JsonPropertyName("staticContainers")]
+ public StaticContainerDetails StaticContainers { get; set; }
+
+ [JsonPropertyName("staticAmmo")]
+ public Dictionary StaticAmmo { get; set; }
+
+ /** All possible static containers on map + their assign groupings */
+ [JsonPropertyName("statics")]
+ public StaticContainer StaticContainer { get; set; }
+
+ /** All possible map extracts */
+ [JsonPropertyName("allExtracts")]
+ public Exit[] AllExtracts { get; set; }
+}
+
+public class StaticContainer
+{
+ [JsonPropertyName("containersGroups")]
+ public Dictionary ContainersGroups { get; set; }
+
+ [JsonPropertyName("containers")]
+ public Dictionary Containers { get; set; }
+}
+
+public class ContainerMinMax
+{
+ [JsonPropertyName("minContainers")]
+ public int MinContainers { get; set; }
+
+ [JsonPropertyName("maxContainers")]
+ public int MaxContainers { get; set; }
+
+ [JsonPropertyName("current")]
+ public int? Current { get; set; }
+
+ [JsonPropertyName("chosenCount")]
+ public int? ChosenCount { get; set; }
+}
+
+public class ContainerData
+{
+ [JsonPropertyName("groupId")]
+ public string GroupId { get; set; }
+}
+
+public class StaticLootDetails
+{
+ [JsonPropertyName("itemcountDistribution")]
+ public ItemCountDistribution[] ItemCountDistribution { get; set; }
+
+ [JsonPropertyName("itemDistribution")]
+ public ItemDistribution[] ItemDistribution { get; set; }
+}
+
+public class ItemCountDistribution
+{
+ [JsonPropertyName("count")]
+ public int Count { get; set; }
+
+ [JsonPropertyName("relativeProbability")]
+ public float RelativeProbability { get; set; }
+}
+
+public class ItemDistribution
+{
+ [JsonPropertyName("tpl")]
+ public string Tpl { get; set; }
+
+ [JsonPropertyName("relativeProbability")]
+ public float RelativeProbability { get; set; }
+}
+
+public class StaticPropsBase
+{
+ [JsonPropertyName("Id")]
+ public string Id { get; set; }
+
+ [JsonPropertyName("IsContainer")]
+ public bool IsContainer { get; set; }
+
+ [JsonPropertyName("useGravity")]
+ public bool UseGravity { get; set; }
+
+ [JsonPropertyName("randomRotation")]
+ public bool RandomRotation { get; set; }
+
+ [JsonPropertyName("Position")]
+ public XYZ Position { get; set; }
+
+ [JsonPropertyName("Rotation")]
+ public XYZ Rotation { get; set; }
+
+ [JsonPropertyName("IsGroupPosition")]
+ public bool IsGroupPosition { get; set; }
+
+ [JsonPropertyName("IsAlwaysSpawn")]
+ public bool IsAlwaysSpawn { get; set; }
+
+ [JsonPropertyName("GroupPositions")]
+ public GroupPosition[] GroupPositions { get; set; }
+
+ [JsonPropertyName("Root")]
+ public string Root { get; set; }
+
+ [JsonPropertyName("Items")]
+ public Item[] Items { get; set; }
+}
+
+public class StaticWeaponProps : StaticPropsBase
+{
+ [JsonPropertyName("Items")]
+ public Item[] Items { get; set; }
+}
+
+public class StaticContainerDetails
+{
+ [JsonPropertyName("staticWeapons")]
+ public StaticWeaponProps[] StaticWeapons { get; set; }
+
+ [JsonPropertyName("staticContainers")]
+ public StaticContainerData[] StaticContainers { get; set; }
+
+ [JsonPropertyName("staticForced")]
+ public StaticForcedProps[] StaticForced { get; set; }
+}
+
+public class StaticContainerData
+{
+ [JsonPropertyName("probability")]
+ public float Probability { get; set; }
+
+ [JsonPropertyName("template")]
+ public StaticContainerProps Template { get; set; }
+}
+
+public class StaticAmmoDetails
+{
+ [JsonPropertyName("tpl")]
+ public string Tpl { get; set; }
+
+ [JsonPropertyName("relativeProbability")]
+ public float RelativeProbability { get; set; }
+}
+
+public class StaticForcedProps
+{
+ [JsonPropertyName("containerId")]
+ public string ContainerId { get; set; }
+
+ [JsonPropertyName("itemTpl")]
+ public string ItemTpl { get; set; }
+}
+
+public class StaticContainerProps : StaticPropsBase
+{
+ [JsonPropertyName("Items")]
+ public StaticItem[] Items { get; set; }
+}
+
+public class StaticItem
+{
+ [JsonPropertyName("_id")]
+ public string Id { get; set; }
+
+ [JsonPropertyName("_tpl")]
+ public string Tpl { get; set; }
+}
\ No newline at end of file
diff --git a/Core/Models/Eft/Common/LocationBase.cs b/Core/Models/Eft/Common/LocationBase.cs
new file mode 100644
index 00000000..74b6d106
--- /dev/null
+++ b/Core/Models/Eft/Common/LocationBase.cs
@@ -0,0 +1,842 @@
+using System.Text.Json.Serialization;
+using Core.Models.Common;
+
+namespace Core.Models.Eft.Common;
+
+public class LocationBase
+{
+ [JsonPropertyName("AccessKeys")]
+ public List AccessKeys { get; set; }
+
+ [JsonPropertyName("AccessKeysPvE")]
+ public List AccessKeysPvE { get; set; }
+
+ [JsonPropertyName("AirdropParameters")]
+ public List AirdropParameters { get; set; }
+
+ [JsonPropertyName("Area")]
+ public int Area { get; set; }
+
+ [JsonPropertyName("AveragePlayTime")]
+ public double AveragePlayTime { get; set; }
+
+ [JsonPropertyName("AveragePlayerLevel")]
+ public double AveragePlayerLevel { get; set; }
+
+ [JsonPropertyName("Banners")]
+ public List Banners { get; set; }
+
+ [JsonPropertyName("BossLocationSpawn")]
+ public List BossLocationSpawn { get; set; }
+
+ [JsonPropertyName("BotAssault")]
+ public int BotAssault { get; set; }
+
+ /** Weighting on how likely a bot will be Easy difficulty */
+ [JsonPropertyName("BotEasy")]
+ public int BotEasy { get; set; }
+
+ /** Weighting on how likely a bot will be Hard difficulty */
+ [JsonPropertyName("BotHard")]
+ public int BotHard { get; set; }
+
+ /** Weighting on how likely a bot will be Impossible difficulty */
+ [JsonPropertyName("BotImpossible")]
+ public int BotImpossible { get; set; }
+
+ [JsonPropertyName("BotLocationModifier")]
+ public BotLocationModifier BotLocationModifier { get; set; }
+
+ [JsonPropertyName("BotMarksman")]
+ public int BotMarksman { get; set; }
+
+ /** Maximum Number of bots that are currently alive/loading/delayed */
+ [JsonPropertyName("BotMax")]
+ public int BotMax { get; set; }
+
+ /** Is not used in 33420 */
+ [JsonPropertyName("BotMaxPlayer")]
+ public int BotMaxPlayer { get; set; }
+
+ /** Is not used in 33420 */
+ [JsonPropertyName("BotMaxTimePlayer")]
+ public int BotMaxTimePlayer { get; set; }
+
+ /** Does not even exist in the client in 33420 */
+ [JsonPropertyName("BotMaxPvE")]
+ public int BotMaxPvE { get; set; }
+
+ /** Weighting on how likely a bot will be Normal difficulty */
+ [JsonPropertyName("BotNormal")]
+ public int BotNormal { get; set; }
+
+ /** How many bot slots that need to be open before trying to spawn new bots. */
+ [JsonPropertyName("BotSpawnCountStep")]
+ public int BotSpawnCountStep { get; set; }
+
+ /** How often to check if bots are spawn-able. In seconds */
+ [JsonPropertyName("BotSpawnPeriodCheck")]
+ public int BotSpawnPeriodCheck { get; set; }
+
+ /** The bot spawn will toggle on and off in intervals of Off(Min/Max) and On(Min/Max) */
+ [JsonPropertyName("BotSpawnTimeOffMax")]
+ public int BotSpawnTimeOffMax { get; set; }
+
+ [JsonPropertyName("BotSpawnTimeOffMin")]
+ public int BotSpawnTimeOffMin { get; set; }
+
+ [JsonPropertyName("BotSpawnTimeOnMax")]
+ public int BotSpawnTimeOnMax { get; set; }
+
+ [JsonPropertyName("BotSpawnTimeOnMin")]
+ public int BotSpawnTimeOnMin { get; set; }
+
+ /** How soon bots will be allowed to spawn */
+ [JsonPropertyName("BotStart")]
+ public int BotStart { get; set; }
+
+ /** After this long bots will no longer spawn */
+ [JsonPropertyName("BotStop")]
+ public int BotStop { get; set; }
+
+ [JsonPropertyName("Description")]
+ public string Description { get; set; }
+
+ [JsonPropertyName("DisabledForScav")]
+ public bool DisabledForScav { get; set; }
+
+ [JsonPropertyName("DisabledScavExits")]
+ public string DisabledScavExits { get; set; }
+
+ [JsonPropertyName("Enabled")]
+ public bool Enabled { get; set; }
+
+ [JsonPropertyName("EnableCoop")]
+ public bool EnableCoop { get; set; }
+
+ [JsonPropertyName("GlobalLootChanceModifier")]
+ public double GlobalLootChanceModifier { get; set; }
+
+ [JsonPropertyName("GlobalLootChanceModifierPvE")]
+ public double GlobalLootChanceModifierPvE { get; set; }
+
+ [JsonPropertyName("GlobalContainerChanceModifier")]
+ public double GlobalContainerChanceModifier { get; set; }
+
+ [JsonPropertyName("IconX")]
+ public int IconX { get; set; }
+
+ [JsonPropertyName("IconY")]
+ public int IconY { get; set; }
+
+ [JsonPropertyName("Id")]
+ public string Id { get; set; }
+
+ [JsonPropertyName("Insurance")]
+ public bool Insurance { get; set; }
+
+ [JsonPropertyName("IsSecret")]
+ public bool IsSecret { get; set; }
+
+ [JsonPropertyName("Locked")]
+ public bool Locked { get; set; }
+
+ [JsonPropertyName("Loot")]
+ public List Loot { get; set; }
+
+ [JsonPropertyName("MatchMakerMinPlayersByWaitTime")]
+ public List MatchMakerMinPlayersByWaitTime { get; set; }
+
+ [JsonPropertyName("MaxBotPerZone")]
+ public int MaxBotPerZone { get; set; }
+
+ [JsonPropertyName("MaxDistToFreePoint")]
+ public double MaxDistToFreePoint { get; set; }
+
+ [JsonPropertyName("MaxPlayers")]
+ public int MaxPlayers { get; set; }
+
+ [JsonPropertyName("MinDistToExitPoint")]
+ public double MinDistToExitPoint { get; set; }
+
+ [JsonPropertyName("MinDistToFreePoint")]
+ public double MinDistToFreePoint { get; set; }
+
+ [JsonPropertyName("MinMaxBots")]
+ public List MinMaxBots { get; set; }
+
+ [JsonPropertyName("MinPlayers")]
+ public int MinPlayers { get; set; }
+
+ [JsonPropertyName("MaxCoopGroup")]
+ public int MaxCoopGroup { get; set; }
+
+ [JsonPropertyName("Name")]
+ public string Name { get; set; }
+
+ [JsonPropertyName("NonWaveGroupScenario")]
+ public NonWaveGroupScenario NonWaveGroupScenario { get; set; }
+
+ [JsonPropertyName("NewSpawn")]
+ public bool NewSpawn { get; set; }
+
+ [JsonPropertyName("OcculsionCullingEnabled")]
+ public bool OcculsionCullingEnabled { get; set; }
+
+ [JsonPropertyName("OldSpawn")]
+ public bool OldSpawn { get; set; }
+
+ [JsonPropertyName("OpenZones")]
+ public string OpenZones { get; set; }
+
+ [JsonPropertyName("Preview")]
+ public Preview Preview { get; set; }
+
+ [JsonPropertyName("PlayersRequestCount")]
+ public int PlayersRequestCount { get; set; }
+
+ [JsonPropertyName("RequiredPlayerLevel")]
+ public int? RequiredPlayerLevel { get; set; }
+
+ [JsonPropertyName("RequiredPlayerLevelMin")]
+ public int? RequiredPlayerLevelMin { get; set; }
+
+ [JsonPropertyName("RequiredPlayerLevelMax")]
+ public int? RequiredPlayerLevelMax { get; set; }
+
+ [JsonPropertyName("MinPlayerLvlAccessKeys")]
+ public int MinPlayerLvlAccessKeys { get; set; }
+
+ [JsonPropertyName("PmcMaxPlayersInGroup")]
+ public int PmcMaxPlayersInGroup { get; set; }
+
+ [JsonPropertyName("ScavMaxPlayersInGroup")]
+ public int ScavMaxPlayersInGroup { get; set; }
+
+ [JsonPropertyName("Rules")]
+ public string Rules { get; set; }
+
+ [JsonPropertyName("SafeLocation")]
+ public bool SafeLocation { get; set; }
+
+ [JsonPropertyName("Scene")]
+ public Scene Scene { get; set; }
+
+ [JsonPropertyName("SpawnPointParams")]
+ public List SpawnPointParams { get; set; }
+
+ [JsonPropertyName("UnixDateTime")]
+ public long UnixDateTime { get; set; }
+
+ [JsonPropertyName("_Id")]
+ public string IdField { get; set; }
+
+ [JsonPropertyName("doors")]
+ public List