Adds settings (#126)
This commit is contained in:
parent
8028a85ffe
commit
f336a56364
17 changed files with 229 additions and 99 deletions
|
|
@ -8,7 +8,11 @@ namespace Server.Accounting
|
|||
{
|
||||
public class AccountAttackLimiter
|
||||
{
|
||||
public static bool Enabled = true;
|
||||
public static bool Enabled;
|
||||
public static void Configure()
|
||||
{
|
||||
Enabled = ServerConfiguration.GetOrUpdateSetting("accountAttackLimiter.enabled", true);
|
||||
}
|
||||
|
||||
private static readonly List<InvalidAccountAccessLog> m_List = new List<InvalidAccountAccessLog>();
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,18 @@ namespace Server.Misc
|
|||
{
|
||||
public class AccountHandler
|
||||
{
|
||||
private static readonly int MaxAccountsPerIP = 1;
|
||||
private static readonly bool AutoAccountCreation = true;
|
||||
private static readonly bool RestrictDeletion = !TestCenter.Enabled;
|
||||
private static readonly TimeSpan DeleteDelay = TimeSpan.FromDays(7.0);
|
||||
private static int MaxAccountsPerIP;
|
||||
private static bool AutoAccountCreation;
|
||||
private static bool RestrictDeletion = !TestCenter.Enabled;
|
||||
private static TimeSpan DeleteDelay = TimeSpan.FromDays(7.0);
|
||||
private static bool PasswordCommandEnabled;
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
MaxAccountsPerIP = ServerConfiguration.GetOrUpdateSetting("accountHandler.maxAccountsPerIP", 1);
|
||||
AutoAccountCreation = ServerConfiguration.GetOrUpdateSetting("accountHandler.autoAccountCreation", true);
|
||||
PasswordCommandEnabled = ServerConfiguration.GetOrUpdateSetting("accountHandler.enablePlayerPasswordCommand", false);
|
||||
}
|
||||
|
||||
private static readonly CityInfo[] StartingCities =
|
||||
{
|
||||
|
|
@ -46,8 +54,6 @@ namespace Server.Misc
|
|||
}
|
||||
*/
|
||||
|
||||
private static readonly bool PasswordCommandEnabled = false;
|
||||
|
||||
private static Dictionary<IPAddress, int> m_IPTable;
|
||||
|
||||
private static readonly char[] m_ForbiddenChars =
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Server.Network;
|
||||
|
||||
|
|
@ -6,24 +7,23 @@ namespace Server.Misc
|
|||
{
|
||||
public class IPLimiter
|
||||
{
|
||||
public static bool Enabled = true;
|
||||
public static bool SocketBlock = true; // true to block at connection, false to block at login request
|
||||
public static bool Enabled { get; private set; }
|
||||
public static bool SocketBlock { get; private set; }
|
||||
public static int MaxAddresses { get; private set; }
|
||||
|
||||
public static int MaxAddresses = 10;
|
||||
public static void Configure()
|
||||
{
|
||||
Enabled = ServerConfiguration.GetOrUpdateSetting("ipLImiter.enabled", true);
|
||||
SocketBlock = ServerConfiguration.GetOrUpdateSetting("ipLImiter.blockAtConnection", true);
|
||||
MaxAddresses = ServerConfiguration.GetOrUpdateSetting("ipLimiter.maxConnectionsPerIP", 10);
|
||||
}
|
||||
|
||||
public static IPAddress[] Exemptions =
|
||||
{
|
||||
// IPAddress.Parse( "127.0.0.1" ),
|
||||
};
|
||||
|
||||
public static bool IsExempt(IPAddress ip)
|
||||
{
|
||||
for (int i = 0; i < Exemptions.Length; i++)
|
||||
if (ip.Equals(Exemptions[i]))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
public static bool IsExempt(IPAddress ip) => Exemptions.Contains(ip);
|
||||
|
||||
public static bool Verify(IPAddress ourAddress)
|
||||
{
|
||||
|
|
|
|||
39
Projects/Scripts/Configuration/ExpansionConfiguration.cs
Normal file
39
Projects/Scripts/Configuration/ExpansionConfiguration.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using Server.Accounting;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public static class ExpansionConfiguration
|
||||
{
|
||||
public static void Configure()
|
||||
{
|
||||
Core.Expansion = ServerConfiguration.GetOrUpdateSetting("currentExpansion", Expansion.TOL);
|
||||
|
||||
AccountGold.Enabled = ServerConfiguration.GetSetting("accountGold.enabled", Core.TOL);
|
||||
AccountGold.ConvertOnBank = ServerConfiguration.GetSetting("accountGold.convertOnBank", true);
|
||||
AccountGold.ConvertOnTrade = ServerConfiguration.GetSetting("accountGold.convertOnTrade", false);
|
||||
VirtualCheck.UseEditGump = ServerConfiguration.GetSetting("virtualChecks.useEditGump", true);
|
||||
|
||||
Mobile.InsuranceEnabled = ServerConfiguration.GetSetting("insurance.enabled", Core.AOS);
|
||||
ObjectPropertyList.Enabled = ServerConfiguration.GetSetting("opl.enabled", Core.AOS);
|
||||
bool visibleDamage = ServerConfiguration.GetSetting("visibleDamage", Core.AOS);
|
||||
Mobile.VisibleDamageType = visibleDamage ? VisibleDamageType.Related : VisibleDamageType.None;
|
||||
Mobile.GuildClickMessage = ServerConfiguration.GetSetting("guildClickMessage", !Core.AOS);
|
||||
Mobile.AsciiClickMessage = ServerConfiguration.GetSetting("asciiClickMessage", !Core.AOS);
|
||||
|
||||
Mobile.ActionDelay = ServerConfiguration.GetSetting("actionDelay", Core.AOS ? 1000 : 500);
|
||||
|
||||
if (Core.AOS)
|
||||
{
|
||||
AOS.DisableStatInfluences();
|
||||
|
||||
if (ObjectPropertyList.Enabled)
|
||||
PacketHandlers.SingleClickProps = true; // single click for everything is overridden to check object property list
|
||||
|
||||
Mobile.AOSStatusHandler = AOS.GetStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ namespace Server.Ethics
|
|||
{
|
||||
public abstract class Ethic
|
||||
{
|
||||
public static readonly bool Enabled = false;
|
||||
public static bool Enabled { get; private set; }
|
||||
|
||||
public static readonly Ethic Hero = new HeroEthic();
|
||||
public static readonly Ethic Evil = new EvilEthic();
|
||||
|
|
@ -98,6 +98,8 @@ namespace Server.Ethics
|
|||
|
||||
public static void Initialize()
|
||||
{
|
||||
Enabled = ServerConfiguration.GetOrUpdateSetting("ethics.enabled", false);
|
||||
|
||||
if (Enabled)
|
||||
EventSink.Speech += EventSink_Speech;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ namespace Server.Engines.MLQuests
|
|||
public static readonly bool Debug = false;
|
||||
|
||||
public static readonly List<MLQuest> EmptyList = new List<MLQuest>();
|
||||
|
||||
private static readonly List<MLQuest> m_EligiblePool = new List<MLQuest>();
|
||||
|
||||
public static bool Enabled { get; private set; }
|
||||
|
||||
static MLQuestSystem()
|
||||
{
|
||||
Quests = new Dictionary<Type, MLQuest>();
|
||||
|
|
@ -94,8 +95,6 @@ namespace Server.Engines.MLQuests
|
|||
}
|
||||
}
|
||||
|
||||
public static bool Enabled => Core.ML;
|
||||
|
||||
public static Dictionary<Type, MLQuest> Quests { get; }
|
||||
|
||||
public static Dictionary<Type, List<MLQuest>> QuestGivers { get; }
|
||||
|
|
@ -125,6 +124,8 @@ namespace Server.Engines.MLQuests
|
|||
|
||||
public static void Initialize()
|
||||
{
|
||||
Enabled = ServerConfiguration.GetOrUpdateSetting("questSystem.enableMLQuests", Core.ML);
|
||||
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,7 @@ namespace Server
|
|||
{
|
||||
public class PathFollower
|
||||
{
|
||||
// Should we use pathfinding? 'false' for not
|
||||
private static readonly bool Enabled = true;
|
||||
|
||||
private static bool Enabled;
|
||||
private static readonly TimeSpan RepathDelay = TimeSpan.FromSeconds(2.0);
|
||||
|
||||
private readonly Mobile m_From;
|
||||
|
|
@ -16,6 +14,11 @@ namespace Server
|
|||
private Point3D m_Next, m_LastGoalLoc;
|
||||
private MovementPath m_Path;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Enabled = ServerConfiguration.GetOrUpdateSetting("pathfinding.enabled", true);
|
||||
}
|
||||
|
||||
public PathFollower(Mobile from, IPoint3D goal)
|
||||
{
|
||||
m_From = from;
|
||||
|
|
|
|||
|
|
@ -11,11 +11,10 @@ namespace Server.Engines.VeteranRewards
|
|||
private static RewardCategory[] m_Categories;
|
||||
private static RewardList[] m_Lists;
|
||||
|
||||
public static bool Enabled = true; // change to true to enable vet rewards
|
||||
public static bool Enabled { get; private set; }
|
||||
|
||||
public static bool
|
||||
SkillCapRewards =
|
||||
true; // assuming vet rewards are enabled, should total skill cap bonuses be awarded? (720 skills total at 4th level)
|
||||
// assuming vet rewards are enabled, should total skill cap bonuses be awarded? (720 skills total at 4th level)
|
||||
public static bool SkillCapRewards { get; private set; }
|
||||
|
||||
public static TimeSpan RewardInterval = TimeSpan.FromDays(30.0);
|
||||
|
||||
|
|
@ -173,16 +172,13 @@ namespace Server.Engines.VeteranRewards
|
|||
|
||||
public static bool CheckIsUsableBy(Mobile from, Item item, object[] args = null)
|
||||
{
|
||||
if (m_Lists == null)
|
||||
SetupRewardTables();
|
||||
|
||||
bool isRelaxedRules = item is DyeTub || item is MonsterStatuette;
|
||||
|
||||
Type type = item.GetType();
|
||||
|
||||
for (int i = 0; i < m_Lists.Length; ++i)
|
||||
for (int i = 0; i < Lists.Length; ++i)
|
||||
{
|
||||
RewardList list = m_Lists[i];
|
||||
RewardList list = Lists[i];
|
||||
RewardEntry[] entries = list.Entries;
|
||||
|
||||
for (int j = 0; j < entries.Length; ++j)
|
||||
|
|
@ -235,14 +231,11 @@ namespace Server.Engines.VeteranRewards
|
|||
|
||||
public static int GetRewardYear(Item item, object[] args)
|
||||
{
|
||||
if (m_Lists == null)
|
||||
SetupRewardTables();
|
||||
|
||||
Type type = item.GetType();
|
||||
|
||||
for (int i = 0; i < m_Lists.Length; ++i)
|
||||
for (int i = 0; i < Lists.Length; ++i)
|
||||
{
|
||||
RewardList list = m_Lists[i];
|
||||
RewardList list = Lists[i];
|
||||
RewardEntry[] entries = list.Entries;
|
||||
|
||||
for (int j = 0; j < entries.Length; ++j)
|
||||
|
|
@ -462,6 +455,9 @@ namespace Server.Engines.VeteranRewards
|
|||
|
||||
public static void Initialize()
|
||||
{
|
||||
Enabled = ServerConfiguration.GetOrUpdateSetting("vetRewards.enabled", true);
|
||||
SkillCapRewards = ServerConfiguration.GetOrUpdateSetting("vetReards.skillCapRewards", true);
|
||||
|
||||
if (Enabled)
|
||||
EventSink.Login += EventSink_Login;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ namespace Server
|
|||
{
|
||||
public class BuffInfo
|
||||
{
|
||||
public static bool Enabled => Core.ML;
|
||||
public static bool Enabled { get; private set; }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Enabled = ServerConfiguration.GetOrUpdateSetting("buffIcons.enabled", Core.ML);
|
||||
|
||||
if (Enabled)
|
||||
EventSink.ClientVersionReceived += ResendBuffsOnClientVersionReceived;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@ namespace Server.Misc
|
|||
{
|
||||
public class ClientVerification
|
||||
{
|
||||
private static readonly bool m_DetectClientRequirement = true;
|
||||
private static readonly OldClientResponse m_OldClientResponse = OldClientResponse.LenientKick;
|
||||
private static bool m_DetectClientRequirement;
|
||||
private static OldClientResponse m_OldClientResponse;
|
||||
|
||||
private static readonly TimeSpan m_AgeLeniency = TimeSpan.FromDays(10);
|
||||
private static readonly TimeSpan m_GameTimeLeniency = TimeSpan.FromHours(25);
|
||||
private static TimeSpan m_AgeLeniency;
|
||||
private static TimeSpan m_GameTimeLeniency;
|
||||
|
||||
public static ClientVersion Required { get; set; }
|
||||
|
||||
|
|
@ -23,10 +23,17 @@ namespace Server.Misc
|
|||
|
||||
public static bool AllowGod { get; set; } = true;
|
||||
|
||||
public static TimeSpan KickDelay { get; set; } = TimeSpan.FromSeconds(20.0);
|
||||
public static TimeSpan KickDelay { get; set; }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
m_DetectClientRequirement = ServerConfiguration.GetOrUpdateSetting("clientVerification.enabled", true);
|
||||
m_OldClientResponse =
|
||||
ServerConfiguration.GetOrUpdateSetting("clientVerification.oldClientResponse", OldClientResponse.Kick);
|
||||
m_AgeLeniency = ServerConfiguration.GetOrUpdateSetting("clientVerification.ageLeniency", TimeSpan.FromDays(10));
|
||||
m_GameTimeLeniency = ServerConfiguration.GetOrUpdateSetting("clientVerification.gameTimeLeniency", TimeSpan.FromHours(25));
|
||||
KickDelay = ServerConfiguration.GetOrUpdateSetting("clientVerification.kickDelay", TimeSpan.FromSeconds(20.0));
|
||||
|
||||
EventSink.ClientVersionReceived += EventSink_ClientVersionReceived;
|
||||
|
||||
// ClientVersion.Required = null;
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
using Server.Accounting;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class CurrentExpansion
|
||||
{
|
||||
private static readonly Expansion Expansion = Expansion.TOL;
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
Core.Expansion = Expansion;
|
||||
|
||||
AccountGold.Enabled = Core.TOL;
|
||||
AccountGold.ConvertOnBank = true;
|
||||
AccountGold.ConvertOnTrade = false;
|
||||
VirtualCheck.UseEditGump = true;
|
||||
|
||||
bool Enabled = Core.AOS;
|
||||
|
||||
Mobile.InsuranceEnabled = Enabled;
|
||||
ObjectPropertyList.Enabled = Enabled;
|
||||
Mobile.VisibleDamageType = Enabled ? VisibleDamageType.Related : VisibleDamageType.None;
|
||||
Mobile.GuildClickMessage = !Enabled;
|
||||
Mobile.AsciiClickMessage = !Enabled;
|
||||
|
||||
if (Enabled)
|
||||
{
|
||||
AOS.DisableStatInfluences();
|
||||
|
||||
if (ObjectPropertyList.Enabled)
|
||||
PacketHandlers.SingleClickProps =
|
||||
true; // single click for everything is overridden to check object property list
|
||||
|
||||
Mobile.ActionDelay = 1000;
|
||||
Mobile.AOSStatusHandler = AOS.GetStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -36,18 +36,21 @@ namespace Server.Misc
|
|||
* IP address or hostname, whichever is applicable. Loopback clients will be directed to loopback.
|
||||
*
|
||||
* If you would like to listen on additional ports (i.e. 22, 23, 80, for clients behind highly restrictive egress
|
||||
* firewalls) or specific IP adddresses you can do so by modifying the file SocketOptions.cs found in this directory.
|
||||
* firewalls) or specific IP addresses you can do so by modifying the file SocketOptions.cs found in this directory.
|
||||
*/
|
||||
|
||||
public static readonly string Address = null;
|
||||
public const string ServerName = "ModernUO TC";
|
||||
public static string Address { get; private set; }
|
||||
public static string ServerName { get; private set; }
|
||||
|
||||
public const bool AutoDetect = true;
|
||||
public static bool AutoDetect { get; private set; }
|
||||
|
||||
private static IPAddress m_PublicAddress;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Address = ServerConfiguration.GetOrUpdateSetting("serverListing.address", "(-null-)");
|
||||
AutoDetect = ServerConfiguration.GetOrUpdateSetting("serverListing.autoDetect", true);
|
||||
|
||||
if (Address == null)
|
||||
{
|
||||
if (AutoDetect)
|
||||
|
|
|
|||
|
|
@ -3266,7 +3266,12 @@ namespace Server.Mobiles
|
|||
{
|
||||
}
|
||||
|
||||
public const bool BondingEnabled = true;
|
||||
public static void Initialize()
|
||||
{
|
||||
BondingEnabled = ServerConfiguration.GetOrUpdateSetting("taming.enableBonding", true);
|
||||
}
|
||||
|
||||
public static bool BondingEnabled { get; private set; }
|
||||
|
||||
public virtual bool IsBondable => BondingEnabled && !Summoned;
|
||||
public virtual TimeSpan BondingDelay => TimeSpan.FromDays(7.0);
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ namespace Server.Mobiles
|
|||
public override bool BardImmune => true;
|
||||
public override Poison PoisonImmune => Poison.Lethal;
|
||||
|
||||
public static void Initialize()
|
||||
public static new void Initialize()
|
||||
{
|
||||
EventSink.PlayerDeath += EventSink_PlayerDeath;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,12 @@ namespace Server.Misc
|
|||
{
|
||||
public class TestCenter
|
||||
{
|
||||
private const bool m_Enabled = false;
|
||||
public static bool Enabled => m_Enabled;
|
||||
public static bool Enabled { get; private set; }
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
Enabled = ServerConfiguration.GetOrUpdateSetting("testCenter.enabled", false);
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -34,8 +34,104 @@ namespace Server
|
|||
private static ServerSettings m_Settings;
|
||||
|
||||
public static List<string> DataDirectories => m_Settings.dataDirectories;
|
||||
public static Dictionary<string, string> Settings => m_Settings.settings;
|
||||
public static Dictionary<string, object> Metadata => m_Settings.metadata;
|
||||
|
||||
public static string GetSetting(string key, string defaultValue)
|
||||
{
|
||||
m_Settings.settings.TryGetValue(key, out string value);
|
||||
return value == "(-null-)" ? null : value ?? defaultValue;
|
||||
}
|
||||
|
||||
public static int GetSetting(string key, int defaultValue)
|
||||
{
|
||||
m_Settings.settings.TryGetValue(key, out string strValue);
|
||||
return int.TryParse(strValue, out int value) ? value : defaultValue;
|
||||
}
|
||||
|
||||
public static bool GetSetting(string key, bool defaultValue)
|
||||
{
|
||||
m_Settings.settings.TryGetValue(key, out string strValue);
|
||||
return bool.TryParse(strValue, out bool value) ? value : defaultValue;
|
||||
}
|
||||
|
||||
public static T GetSetting<T>(string key, T defaultValue) where T : struct, Enum
|
||||
{
|
||||
m_Settings.settings.TryGetValue(key, out string strValue);
|
||||
return Enum.TryParse(strValue, out T value) ? value : defaultValue;
|
||||
}
|
||||
|
||||
public static string GetOrUpdateSetting(string key, string defaultValue)
|
||||
{
|
||||
if (m_Settings.settings.TryGetValue(key, out string value))
|
||||
return value;
|
||||
|
||||
SetSetting(key, value = defaultValue);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int GetOrUpdateSetting(string key, int defaultValue)
|
||||
{
|
||||
int value;
|
||||
|
||||
if (m_Settings.settings.TryGetValue(key, out string strValue))
|
||||
value = int.TryParse(strValue, out value) ? value : defaultValue;
|
||||
else
|
||||
SetSetting(key, (value = defaultValue).ToString());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static bool GetOrUpdateSetting(string key, bool defaultValue)
|
||||
{
|
||||
bool value;
|
||||
|
||||
if (m_Settings.settings.TryGetValue(key, out string strValue))
|
||||
value = bool.TryParse(strValue, out value) ? value : defaultValue;
|
||||
else
|
||||
SetSetting(key, (value = defaultValue).ToString());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static TimeSpan GetOrUpdateSetting(string key, TimeSpan defaultValue)
|
||||
{
|
||||
TimeSpan value;
|
||||
|
||||
if (m_Settings.settings.TryGetValue(key, out string strValue))
|
||||
value = TimeSpan.TryParse(strValue, out value) ? value : defaultValue;
|
||||
else
|
||||
SetSetting(key, (value = defaultValue).ToString());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static T GetOrUpdateSetting<T>(string key, T defaultValue) where T : struct, Enum
|
||||
{
|
||||
T value;
|
||||
|
||||
if (m_Settings.settings.TryGetValue(key, out string strValue))
|
||||
value = Enum.TryParse(strValue, out value) ? value : defaultValue;
|
||||
else
|
||||
SetSetting(key, (value = defaultValue).ToString());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static void SetSetting(string key, string value)
|
||||
{
|
||||
m_Settings.settings[key] = value;
|
||||
SaveConfiguration();
|
||||
}
|
||||
|
||||
public static T GetMetadata<T>(string key) where T : class
|
||||
{
|
||||
m_Settings.metadata.TryGetValue(key, out object value);
|
||||
return value as T;
|
||||
}
|
||||
|
||||
public static void SetMetadata(string key, object value)
|
||||
{
|
||||
m_Settings.metadata[key] = value;
|
||||
}
|
||||
|
||||
public static void LoadConfiguration()
|
||||
{
|
||||
|
|
@ -70,7 +166,12 @@ namespace Server
|
|||
}
|
||||
|
||||
if (updated)
|
||||
{
|
||||
SaveConfiguration();
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine($"Core: Configuration saved to {m_RelPath}.");
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
|
||||
internal class ServerSettings
|
||||
|
|
@ -102,9 +203,6 @@ namespace Server
|
|||
public static void SaveConfiguration()
|
||||
{
|
||||
JsonConfig.Serialize(m_FilePath, m_Settings);
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine($"Core: Configuration saved to {m_RelPath}.");
|
||||
Console.ResetColor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ namespace Server.Json
|
|||
ReadCommentHandling = JsonCommentHandling.Skip,
|
||||
WriteIndented = true,
|
||||
AllowTrailingCommas = true,
|
||||
IgnoreNullValues = true
|
||||
};
|
||||
|
||||
public static T Deserialize<T>(string filePath, JsonSerializerOptions options = null)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue