2020-08-25 18:53:35 -07:00
|
|
|
/*************************************************************************
|
|
|
|
|
* ModernUO *
|
2020-09-12 15:31:21 -07:00
|
|
|
* Copyright 2019-2020 - ModernUO Development Team *
|
2020-08-25 18:53:35 -07:00
|
|
|
* Email: hi@modernuo.com *
|
|
|
|
|
* File: ServerConfiguration.cs *
|
|
|
|
|
* *
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or *
|
|
|
|
|
* (at your option) any later version. *
|
|
|
|
|
* *
|
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using Server.Json;
|
2021-04-20 08:43:54 +02:00
|
|
|
using Server.Logging;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
namespace Server;
|
|
|
|
|
|
|
|
|
|
public static class ServerConfiguration
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
private static readonly ILogger logger = LogFactory.GetLogger(typeof(ServerConfiguration));
|
2021-04-20 08:43:54 +02:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
private const string _relPath = "Configuration/modernuo.json";
|
|
|
|
|
private static readonly string m_FilePath = Path.Join(Core.BaseDirectory, _relPath);
|
|
|
|
|
private static ServerSettings m_Settings;
|
|
|
|
|
private static bool m_Mocked;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static List<string> AssemblyDirectories => m_Settings.AssemblyDirectories;
|
2021-09-03 23:35:44 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static HashSet<string> DataDirectories => m_Settings.DataDirectories;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static List<IPEndPoint> Listeners => m_Settings.Listeners;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static ClientVersion GetSetting(string key, ClientVersion defaultValue) =>
|
|
|
|
|
m_Settings.Settings.TryGetValue(key, out var value) ? new ClientVersion(value) : defaultValue;
|
2021-11-27 10:06:39 -08:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static string GetSetting(string key, string defaultValue) =>
|
|
|
|
|
m_Settings.Settings.TryGetValue(key, out var value) ? value : defaultValue;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static int GetSetting(string key, int defaultValue)
|
|
|
|
|
{
|
|
|
|
|
m_Settings.Settings.TryGetValue(key, out var strValue);
|
|
|
|
|
return int.TryParse(strValue, out var value) ? value : defaultValue;
|
|
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static long GetSetting(string key, long defaultValue)
|
|
|
|
|
{
|
|
|
|
|
m_Settings.Settings.TryGetValue(key, out var strValue);
|
|
|
|
|
return long.TryParse(strValue, out var value) ? value : defaultValue;
|
|
|
|
|
}
|
Updates movement packets & Fastwalk (#324)
- [X] Updates Movement packets
- [X] Adds OSI fastwalk packets. These aren't used on OSi anymore.
- [X] Adds new movement handling, but looks like the client doesn't use it. (Also leaving the 0x4000 Character List Flag off)
- [X] Adds time sync request handler, but also looks like the client doesn't use it.
- [X] Adds time sync response for time sync, just in case, but it isn't used, so not sure about the arguments.
- [X] Reimplements RunUO's fastwalk to use a circular array on the netstate instead of every mobile
- [X] Removes ClearFastwalkStack from RunUO implementation. This shouldn't be needed anymore
Changed fastwalk settings:
```cs
public static int WalkFootDelay { get; set; } = 440;
public static int RunFootDelay { get; set; } = 220;
public static int WalkMountDelay { get; set; } = 220;
public static int RunMountDelay { get; set; } = 110;
public static bool EnableFastwalkPrevention { get; set; } = true;
public static AccessLevel FastwalkExemptionLevel { get; set; } = AccessLevel.Counselor;
// If this is changed during runtime, then the steps array needs resizing.
public static int MaxSteps { get; private set; } = 4;
```
modernuo.json
```json
{
"settings": {
"movement.delay.runFoot": "220",
"movement.delay.runMount": "110",
"movement.delay.walkFoot": "440",
"movement.delay.walkMount": "220",
"movement.enableFastWalkPrevention": "True",
"movement.fastwalkExemptionLevel": "Counselor",
"movement.maxSteps": "4"
}
}
```
Notes about OSI fastwalk:
While it does work, I can't find a benefit in using it because of the variable speeds. If players moved at a single speed then we could refill the stack every X milliseconds with 6 keys and use a naive token bucket implementation.
Unfortunately variable speeds mount/run/walk/etc means we would have to use a leaky bucket algorithm.
If we are using a leaky bucket algorithm with a variable leak, then we don't need to send tokens because we are already tracking it on the server side.
ModernUO vs OSI Fastwalk:
When the fastwalk was implemented on OSI, it used up to 6 tokens. These tokens were probably distributed every 600-750 milliseconds. To get the same effect, the new fastwalk settings might need to be adjusted. I would tweak them and feel free to let me know what worked for you!
Bumps release version
2020-11-26 23:53:47 -08:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static bool GetSetting(string key, bool defaultValue)
|
|
|
|
|
{
|
|
|
|
|
m_Settings.Settings.TryGetValue(key, out var strValue);
|
|
|
|
|
return bool.TryParse(strValue, out var value) ? value : defaultValue;
|
|
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static T GetSetting<T>(string key, T defaultValue) where T : struct, Enum
|
|
|
|
|
{
|
|
|
|
|
m_Settings.Settings.TryGetValue(key, out var strValue);
|
|
|
|
|
return Enum.TryParse(strValue, out T value) ? value : defaultValue;
|
|
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-03-10 22:55:06 -08:00
|
|
|
public static double GetSetting(string key, double defaultValue)
|
|
|
|
|
{
|
|
|
|
|
m_Settings.Settings.TryGetValue(key, out var strValue);
|
|
|
|
|
return double.TryParse(strValue, out var value) ? value : defaultValue;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static T? GetSetting<T>(string key) where T : struct, Enum
|
|
|
|
|
{
|
|
|
|
|
if (!m_Settings.Settings.TryGetValue(key, out var strValue))
|
2021-04-14 01:45:18 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
return null;
|
2021-04-14 01:45:18 -07:00
|
|
|
}
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
return Enum.TryParse(strValue, out T value) ? value : null;
|
|
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static string GetOrUpdateSetting(string key, string defaultValue)
|
|
|
|
|
{
|
|
|
|
|
if (m_Settings.Settings.TryGetValue(key, out var value))
|
|
|
|
|
{
|
2020-08-25 18:53:35 -07:00
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
SetSetting(key, value = defaultValue);
|
|
|
|
|
return value;
|
|
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static int GetOrUpdateSetting(string key, int defaultValue)
|
|
|
|
|
{
|
|
|
|
|
int value;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
|
|
|
|
{
|
|
|
|
|
value = int.TryParse(strValue, out value) ? value : defaultValue;
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
2022-02-27 02:15:06 -08:00
|
|
|
else
|
Updates movement packets & Fastwalk (#324)
- [X] Updates Movement packets
- [X] Adds OSI fastwalk packets. These aren't used on OSi anymore.
- [X] Adds new movement handling, but looks like the client doesn't use it. (Also leaving the 0x4000 Character List Flag off)
- [X] Adds time sync request handler, but also looks like the client doesn't use it.
- [X] Adds time sync response for time sync, just in case, but it isn't used, so not sure about the arguments.
- [X] Reimplements RunUO's fastwalk to use a circular array on the netstate instead of every mobile
- [X] Removes ClearFastwalkStack from RunUO implementation. This shouldn't be needed anymore
Changed fastwalk settings:
```cs
public static int WalkFootDelay { get; set; } = 440;
public static int RunFootDelay { get; set; } = 220;
public static int WalkMountDelay { get; set; } = 220;
public static int RunMountDelay { get; set; } = 110;
public static bool EnableFastwalkPrevention { get; set; } = true;
public static AccessLevel FastwalkExemptionLevel { get; set; } = AccessLevel.Counselor;
// If this is changed during runtime, then the steps array needs resizing.
public static int MaxSteps { get; private set; } = 4;
```
modernuo.json
```json
{
"settings": {
"movement.delay.runFoot": "220",
"movement.delay.runMount": "110",
"movement.delay.walkFoot": "440",
"movement.delay.walkMount": "220",
"movement.enableFastWalkPrevention": "True",
"movement.fastwalkExemptionLevel": "Counselor",
"movement.maxSteps": "4"
}
}
```
Notes about OSI fastwalk:
While it does work, I can't find a benefit in using it because of the variable speeds. If players moved at a single speed then we could refill the stack every X milliseconds with 6 keys and use a naive token bucket implementation.
Unfortunately variable speeds mount/run/walk/etc means we would have to use a leaky bucket algorithm.
If we are using a leaky bucket algorithm with a variable leak, then we don't need to send tokens because we are already tracking it on the server side.
ModernUO vs OSI Fastwalk:
When the fastwalk was implemented on OSI, it used up to 6 tokens. These tokens were probably distributed every 600-750 milliseconds. To get the same effect, the new fastwalk settings might need to be adjusted. I would tweak them and feel free to let me know what worked for you!
Bumps release version
2020-11-26 23:53:47 -08:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
SetSetting(key, (value = defaultValue).ToString());
|
Updates movement packets & Fastwalk (#324)
- [X] Updates Movement packets
- [X] Adds OSI fastwalk packets. These aren't used on OSi anymore.
- [X] Adds new movement handling, but looks like the client doesn't use it. (Also leaving the 0x4000 Character List Flag off)
- [X] Adds time sync request handler, but also looks like the client doesn't use it.
- [X] Adds time sync response for time sync, just in case, but it isn't used, so not sure about the arguments.
- [X] Reimplements RunUO's fastwalk to use a circular array on the netstate instead of every mobile
- [X] Removes ClearFastwalkStack from RunUO implementation. This shouldn't be needed anymore
Changed fastwalk settings:
```cs
public static int WalkFootDelay { get; set; } = 440;
public static int RunFootDelay { get; set; } = 220;
public static int WalkMountDelay { get; set; } = 220;
public static int RunMountDelay { get; set; } = 110;
public static bool EnableFastwalkPrevention { get; set; } = true;
public static AccessLevel FastwalkExemptionLevel { get; set; } = AccessLevel.Counselor;
// If this is changed during runtime, then the steps array needs resizing.
public static int MaxSteps { get; private set; } = 4;
```
modernuo.json
```json
{
"settings": {
"movement.delay.runFoot": "220",
"movement.delay.runMount": "110",
"movement.delay.walkFoot": "440",
"movement.delay.walkMount": "220",
"movement.enableFastWalkPrevention": "True",
"movement.fastwalkExemptionLevel": "Counselor",
"movement.maxSteps": "4"
}
}
```
Notes about OSI fastwalk:
While it does work, I can't find a benefit in using it because of the variable speeds. If players moved at a single speed then we could refill the stack every X milliseconds with 6 keys and use a naive token bucket implementation.
Unfortunately variable speeds mount/run/walk/etc means we would have to use a leaky bucket algorithm.
If we are using a leaky bucket algorithm with a variable leak, then we don't need to send tokens because we are already tracking it on the server side.
ModernUO vs OSI Fastwalk:
When the fastwalk was implemented on OSI, it used up to 6 tokens. These tokens were probably distributed every 600-750 milliseconds. To get the same effect, the new fastwalk settings might need to be adjusted. I would tweak them and feel free to let me know what worked for you!
Bumps release version
2020-11-26 23:53:47 -08:00
|
|
|
}
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
return value;
|
|
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static long GetOrUpdateSetting(string key, long defaultValue)
|
|
|
|
|
{
|
|
|
|
|
long value;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
|
|
|
|
{
|
|
|
|
|
value = long.TryParse(strValue, out value) ? value : defaultValue;
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
2022-02-27 02:15:06 -08:00
|
|
|
else
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
SetSetting(key, (value = defaultValue).ToString());
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
return value;
|
|
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static bool GetOrUpdateSetting(string key, bool defaultValue)
|
|
|
|
|
{
|
|
|
|
|
bool value;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
|
|
|
|
{
|
|
|
|
|
value = bool.TryParse(strValue, out value) ? value : defaultValue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetSetting(key, (value = defaultValue).ToString());
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
return value;
|
|
|
|
|
}
|
2021-09-25 17:22:05 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static TimeSpan GetOrUpdateSetting(string key, TimeSpan defaultValue)
|
|
|
|
|
{
|
|
|
|
|
TimeSpan value;
|
2021-09-25 17:22:05 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
|
|
|
|
{
|
|
|
|
|
value = TimeSpan.TryParse(strValue, out value) ? value : defaultValue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetSetting(key, (value = defaultValue).ToString());
|
|
|
|
|
}
|
2021-09-25 17:22:05 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
return value;
|
|
|
|
|
}
|
2021-09-25 17:22:05 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static T GetOrUpdateSetting<T>(string key, T defaultValue) where T : struct, Enum
|
|
|
|
|
{
|
|
|
|
|
T value;
|
2021-09-25 17:22:05 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
value = Enum.TryParse(strValue, out value) ? value : defaultValue;
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
2022-02-27 02:15:06 -08:00
|
|
|
else
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
SetSetting(key, (value = defaultValue).ToString());
|
|
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
return value;
|
|
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-03-10 22:55:06 -08:00
|
|
|
public static double GetOrUpdateSetting(string key, double defaultValue)
|
|
|
|
|
{
|
|
|
|
|
double value;
|
|
|
|
|
|
|
|
|
|
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
|
|
|
|
{
|
|
|
|
|
value = double.TryParse(strValue, out value) ? value : defaultValue;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetSetting(key, (value = defaultValue).ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void SetSetting(string key, double value) => SetSetting(key, value.ToString());
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static void SetSetting(string key, TimeSpan value) => SetSetting(key, value.ToString());
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static void SetSetting(string key, int value) => SetSetting(key, value.ToString());
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static void SetSetting(string key, long value) => SetSetting(key, value.ToString());
|
2021-04-14 01:45:18 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static void SetSetting(string key, bool value) => SetSetting(key, value.ToString());
|
2021-04-14 01:45:18 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static void SetSetting<T>(string key, T value) where T : struct, Enum =>
|
|
|
|
|
SetSetting(key, value.ToString());
|
2021-04-14 01:45:18 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static void SetSetting(string key, string value)
|
|
|
|
|
{
|
|
|
|
|
m_Settings.Settings[key] = value;
|
|
|
|
|
Save();
|
|
|
|
|
}
|
2021-04-14 01:45:18 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
// If mock is enabled we skip the console readline.
|
|
|
|
|
public static void Load(bool mocked = false)
|
|
|
|
|
{
|
|
|
|
|
m_Mocked = mocked;
|
|
|
|
|
var updated = false;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (File.Exists(m_FilePath))
|
|
|
|
|
{
|
2022-06-05 01:00:22 -07:00
|
|
|
logger.Information("Reading server configuration from {Path}...", _relPath);
|
2022-02-27 02:15:06 -08:00
|
|
|
m_Settings = JsonConfig.Deserialize<ServerSettings>(m_FilePath);
|
2021-04-15 21:27:08 +02:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (m_Settings == null)
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
logger.Error("Reading server configuration failed");
|
|
|
|
|
throw new FileNotFoundException($"Failed to deserialize {m_FilePath}.");
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
logger.Information("Reading server configuration done");
|
|
|
|
|
}
|
|
|
|
|
else
|
2021-04-14 01:45:18 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
updated = true;
|
|
|
|
|
m_Settings = new ServerSettings();
|
2021-04-14 01:45:18 -07:00
|
|
|
}
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (mocked)
|
2021-04-14 01:45:18 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
return;
|
|
|
|
|
}
|
2021-04-14 01:45:18 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (m_Settings.DataDirectories.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
updated = true;
|
|
|
|
|
foreach (var directory in ServerConfigurationPrompts.GetDataDirectories())
|
2021-04-14 01:45:18 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
m_Settings.DataDirectories.Add(directory);
|
2021-04-14 01:45:18 -07:00
|
|
|
}
|
2022-02-27 02:15:06 -08:00
|
|
|
}
|
2021-04-14 01:45:18 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
UOClient.Load();
|
|
|
|
|
var cuoClientFiles = UOClient.CuoSettings?.UltimaOnlineDirectory;
|
2021-08-08 23:42:10 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (cuoClientFiles != null)
|
|
|
|
|
{
|
|
|
|
|
DataDirectories.Add(cuoClientFiles);
|
|
|
|
|
}
|
2021-04-14 01:45:18 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (m_Settings.Listeners.Count == 0)
|
|
|
|
|
{
|
|
|
|
|
updated = true;
|
|
|
|
|
m_Settings.Listeners.AddRange(ServerConfigurationPrompts.GetListeners());
|
2021-04-14 01:45:18 -07:00
|
|
|
}
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
bool? isPre60000 = null;
|
|
|
|
|
|
|
|
|
|
if (m_Settings.Expansion == null)
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
var expansion = GetSetting<Expansion>("currentExpansion");
|
|
|
|
|
var hasExpansion = expansion != null;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
expansion ??= ServerConfigurationPrompts.GetExpansion();
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (expansion <= Expansion.ML && !hasExpansion)
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
isPre60000 = ServerConfigurationPrompts.GetIsClientPre6000();
|
|
|
|
|
if (isPre60000 == true)
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-06-29 01:23:57 -07:00
|
|
|
SetSetting("maps.enablePre6000Trammel", true);
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
2022-02-27 02:15:06 -08:00
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
updated = true;
|
|
|
|
|
m_Settings.Expansion = expansion;
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
|
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (isPre60000 != true)
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
if (ServerConfigurationPrompts.GetIsClient7090())
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
updated = true;
|
|
|
|
|
SetSetting("maps.enablePostHSMultiComponentFormat", true);
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
Core.Expansion = m_Settings.Expansion.Value;
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
if (updated)
|
|
|
|
|
{
|
|
|
|
|
Save();
|
|
|
|
|
Console.Write("Server configuration saved to ");
|
|
|
|
|
Utility.PushColor(ConsoleColor.Green);
|
|
|
|
|
Console.WriteLine($"{_relPath}.");
|
|
|
|
|
Utility.PopColor();
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
2022-02-27 02:15:06 -08:00
|
|
|
}
|
2020-08-25 18:53:35 -07:00
|
|
|
|
2022-02-27 02:15:06 -08:00
|
|
|
public static void Save()
|
|
|
|
|
{
|
|
|
|
|
if (m_Mocked)
|
2020-08-25 18:53:35 -07:00
|
|
|
{
|
2022-02-27 02:15:06 -08:00
|
|
|
return;
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
2022-02-27 02:15:06 -08:00
|
|
|
|
|
|
|
|
JsonConfig.Serialize(m_FilePath, m_Settings);
|
2020-08-25 18:53:35 -07:00
|
|
|
}
|
|
|
|
|
}
|