fix(core): Updates expansion and map configurations (fixes map issues) (#570)
- [X] Adds question about expansion at start of server - [X] Adds question about client version to determine old have and map diffs - [X] Adds config setting "maps.enablePre6000Trammel" - [X] Rearranges some of the loading order. - [X] Added support for deserializing nullable enums from json TODO: Expand the nullable enums deserialization factory to work with any type by pulling the factory and creating an instance of the converter.
This commit is contained in:
parent
151eef470f
commit
98ce65083a
14 changed files with 324 additions and 92 deletions
|
|
@ -15,9 +15,9 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Text.Json.Serialization;
|
||||
using Server.Json;
|
||||
|
||||
namespace Server
|
||||
|
|
@ -29,43 +29,53 @@ namespace Server
|
|||
private static ServerSettings m_Settings;
|
||||
private static bool m_Mocked;
|
||||
|
||||
public static List<string> DataDirectories => m_Settings.dataDirectories;
|
||||
public static List<string> DataDirectories => m_Settings.DataDirectories;
|
||||
|
||||
public static List<IPEndPoint> Listeners => m_Settings.listeners;
|
||||
public static List<IPEndPoint> Listeners => m_Settings.Listeners;
|
||||
|
||||
public static string GetSetting(string key, string defaultValue)
|
||||
{
|
||||
m_Settings.settings.TryGetValue(key, out var value);
|
||||
m_Settings.Settings.TryGetValue(key, out var value);
|
||||
return value ?? defaultValue;
|
||||
}
|
||||
|
||||
public static int GetSetting(string key, int defaultValue)
|
||||
{
|
||||
m_Settings.settings.TryGetValue(key, out var strValue);
|
||||
m_Settings.Settings.TryGetValue(key, out var strValue);
|
||||
return int.TryParse(strValue, out var value) ? value : defaultValue;
|
||||
}
|
||||
|
||||
public static long GetSetting(string key, long defaultValue)
|
||||
{
|
||||
m_Settings.settings.TryGetValue(key, out var strValue);
|
||||
m_Settings.Settings.TryGetValue(key, out var strValue);
|
||||
return long.TryParse(strValue, out var value) ? value : defaultValue;
|
||||
}
|
||||
|
||||
public static bool GetSetting(string key, bool defaultValue)
|
||||
{
|
||||
m_Settings.settings.TryGetValue(key, out var strValue);
|
||||
m_Settings.Settings.TryGetValue(key, out var strValue);
|
||||
return bool.TryParse(strValue, out var value) ? value : defaultValue;
|
||||
}
|
||||
|
||||
public static T GetSetting<T>(string key, T defaultValue) where T : struct, Enum
|
||||
{
|
||||
m_Settings.settings.TryGetValue(key, out var strValue);
|
||||
m_Settings.Settings.TryGetValue(key, out var strValue);
|
||||
return Enum.TryParse(strValue, out T value) ? value : defaultValue;
|
||||
}
|
||||
|
||||
public static T? GetSetting<T>(string key) where T : struct, Enum
|
||||
{
|
||||
if (!m_Settings.Settings.TryGetValue(key, out var strValue))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Enum.TryParse(strValue, out T value) ? value : null;
|
||||
}
|
||||
|
||||
public static string GetOrUpdateSetting(string key, string defaultValue)
|
||||
{
|
||||
if (m_Settings.settings.TryGetValue(key, out var value))
|
||||
if (m_Settings.Settings.TryGetValue(key, out var value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
|
@ -78,7 +88,7 @@ namespace Server
|
|||
{
|
||||
int value;
|
||||
|
||||
if (m_Settings.settings.TryGetValue(key, out var strValue))
|
||||
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
||||
{
|
||||
value = int.TryParse(strValue, out value) ? value : defaultValue;
|
||||
}
|
||||
|
|
@ -94,7 +104,7 @@ namespace Server
|
|||
{
|
||||
long value;
|
||||
|
||||
if (m_Settings.settings.TryGetValue(key, out var strValue))
|
||||
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
||||
{
|
||||
value = long.TryParse(strValue, out value) ? value : defaultValue;
|
||||
}
|
||||
|
|
@ -110,7 +120,7 @@ namespace Server
|
|||
{
|
||||
bool value;
|
||||
|
||||
if (m_Settings.settings.TryGetValue(key, out var strValue))
|
||||
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
||||
{
|
||||
value = bool.TryParse(strValue, out value) ? value : defaultValue;
|
||||
}
|
||||
|
|
@ -126,7 +136,7 @@ namespace Server
|
|||
{
|
||||
TimeSpan value;
|
||||
|
||||
if (m_Settings.settings.TryGetValue(key, out var strValue))
|
||||
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
||||
{
|
||||
value = TimeSpan.TryParse(strValue, out value) ? value : defaultValue;
|
||||
}
|
||||
|
|
@ -142,7 +152,7 @@ namespace Server
|
|||
{
|
||||
T value;
|
||||
|
||||
if (m_Settings.settings.TryGetValue(key, out var strValue))
|
||||
if (m_Settings.Settings.TryGetValue(key, out var strValue))
|
||||
{
|
||||
value = Enum.TryParse(strValue, out value) ? value : defaultValue;
|
||||
}
|
||||
|
|
@ -156,7 +166,7 @@ namespace Server
|
|||
|
||||
public static void SetSetting(string key, string value)
|
||||
{
|
||||
m_Settings.settings[key] = value;
|
||||
m_Settings.Settings[key] = value;
|
||||
Save();
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +178,7 @@ namespace Server
|
|||
|
||||
if (File.Exists(m_FilePath))
|
||||
{
|
||||
Console.Write($"Core: Reading server configuration from {m_RelPath}...");
|
||||
Core.WriteConsole($"Reading server configuration from {m_RelPath}...");
|
||||
m_Settings = JsonConfig.Deserialize<ServerSettings>(m_FilePath);
|
||||
|
||||
if (m_Settings == null)
|
||||
|
|
@ -194,33 +204,105 @@ namespace Server
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_Settings.dataDirectories.Count == 0)
|
||||
if (m_Settings.DataDirectories.Count == 0)
|
||||
{
|
||||
updated = true;
|
||||
Utility.PushColor(ConsoleColor.DarkYellow);
|
||||
Console.WriteLine("Core: Server configuration is missing data directories.");
|
||||
Utility.PopColor();
|
||||
m_Settings.dataDirectories.AddRange(GetDataDirectories());
|
||||
m_Settings.DataDirectories.AddRange(GetDataDirectories());
|
||||
}
|
||||
|
||||
if (m_Settings.listeners.Count == 0)
|
||||
if (m_Settings.Listeners.Count == 0)
|
||||
{
|
||||
updated = true;
|
||||
Utility.PushColor(ConsoleColor.DarkYellow);
|
||||
Console.WriteLine("Core: Server is missing socket listener IP addresses.");
|
||||
Utility.PopColor();
|
||||
m_Settings.listeners.AddRange(GetListeners());
|
||||
m_Settings.Listeners.AddRange(GetListeners());
|
||||
}
|
||||
|
||||
if (m_Settings.Expansion == null)
|
||||
{
|
||||
var expansion = GetSetting<Expansion>("currentExpansion");
|
||||
var hasExpansion = expansion != null;
|
||||
|
||||
expansion ??= GetExpansion();
|
||||
|
||||
if (expansion <= Expansion.ML && !hasExpansion)
|
||||
{
|
||||
SetPre6000Support();
|
||||
}
|
||||
|
||||
updated = true;
|
||||
m_Settings.Expansion = expansion;
|
||||
}
|
||||
|
||||
if (updated)
|
||||
{
|
||||
Save();
|
||||
Utility.PushColor(ConsoleColor.Green);
|
||||
Console.WriteLine($"Core: Server configuration saved to {m_RelPath}.");
|
||||
Core.WriteConsoleLine($"Server configuration saved to {m_RelPath}.");
|
||||
Utility.PopColor();
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetPre6000Support()
|
||||
{
|
||||
Console.WriteLine("Will you be using a client version older than 6.0.0.0?");
|
||||
|
||||
do
|
||||
{
|
||||
Console.Write("y or [n]> ");
|
||||
var input = Console.ReadLine();
|
||||
if (string.IsNullOrWhiteSpace(input) || input.InsensitiveStartsWith("n"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (input.InsensitiveStartsWith("y"))
|
||||
{
|
||||
SetSetting("maps.enablePre6000Trammel", true.ToString());
|
||||
SetSetting("maps.enableMapDiffPatches", true.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
Core.WriteConsoleLine($"Invalid option. ({input})");
|
||||
} while (true);
|
||||
}
|
||||
|
||||
private static Expansion GetExpansion()
|
||||
{
|
||||
Console.WriteLine("Please choose an expansion by typing the number or short name:");
|
||||
var expansions = ExpansionInfo.Table;
|
||||
|
||||
for (int i = 0; i < expansions.Length; i++)
|
||||
{
|
||||
var info = expansions[i];
|
||||
Console.WriteLine(" - {0,2}: {1} ({2})", i, ((Expansion)info.ID).ToString(), info.Name);
|
||||
}
|
||||
|
||||
var maxExpansion = (Expansion)expansions[^1].ID;
|
||||
var maxExpansionName = maxExpansion.ToString();
|
||||
|
||||
do
|
||||
{
|
||||
Console.Write("[{0}]> ", maxExpansionName);
|
||||
var input = Console.ReadLine();
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
{
|
||||
return maxExpansion;
|
||||
}
|
||||
|
||||
if (int.TryParse(input, NumberStyles.Integer, null, out var number) && number >= 0 &&
|
||||
number < expansions.Length)
|
||||
{
|
||||
return (Expansion)number;
|
||||
}
|
||||
|
||||
if (Enum.TryParse<Expansion>(input, out var expansion))
|
||||
{
|
||||
return expansion;
|
||||
}
|
||||
|
||||
Core.WriteConsoleLine($"Invalid expansion. ({input})");
|
||||
} while (true);
|
||||
}
|
||||
|
||||
private static List<string> GetDataDirectories()
|
||||
{
|
||||
Console.WriteLine("Please enter the absolute path to the Ultima Online data:");
|
||||
|
|
@ -239,11 +321,11 @@ namespace Server
|
|||
if (Directory.Exists(directory))
|
||||
{
|
||||
directories.Add(directory);
|
||||
Console.WriteLine("Core: Path {0} added.", directory);
|
||||
Core.WriteConsoleLine($"Path {directory} added.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Core: Path does not exist. ({0})");
|
||||
Core.WriteConsoleLine($"Path does not exist. ({directory})");
|
||||
}
|
||||
} while (true);
|
||||
|
||||
|
|
@ -276,11 +358,11 @@ namespace Server
|
|||
if (IPEndPoint.TryParse(ipStr, out var ip))
|
||||
{
|
||||
ips.Add(ip);
|
||||
Console.WriteLine("Core: {0} added.", ipStr);
|
||||
Core.WriteConsoleLine($"Core: {ipStr} added.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Core: {0} is not a valid IP or port");
|
||||
Core.WriteConsoleLine($"{ipStr} is not a valid IP or port");
|
||||
}
|
||||
} while (true);
|
||||
|
||||
|
|
@ -301,17 +383,5 @@ namespace Server
|
|||
|
||||
JsonConfig.Serialize(m_FilePath, m_Settings);
|
||||
}
|
||||
|
||||
internal class ServerSettings
|
||||
{
|
||||
[JsonPropertyName("dataDirectories")]
|
||||
public List<string> dataDirectories { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("listeners")]
|
||||
public List<IPEndPoint> listeners { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("settings")]
|
||||
public SortedDictionary<string, string> settings { get; set; } = new();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
36
Projects/Server/Configuration/ServerSettings.cs
Normal file
36
Projects/Server/Configuration/ServerSettings.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2021 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: ServerSettings.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.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class ServerSettings
|
||||
{
|
||||
[JsonPropertyName("dataDirectories")]
|
||||
public List<string> DataDirectories { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("listeners")]
|
||||
public List<IPEndPoint> Listeners { get; set; } = new();
|
||||
|
||||
[JsonPropertyName("expansion")]
|
||||
public Expansion? Expansion { get; set; }
|
||||
|
||||
[JsonPropertyName("settings")]
|
||||
public SortedDictionary<string, string> Settings { get; set; } = new();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ namespace Server.Accounting
|
|||
{
|
||||
public static class AccountGold
|
||||
{
|
||||
public static bool Enabled = false;
|
||||
public static bool Enabled { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// This amount specifies the value at which point Gold turns to Platinum.
|
||||
|
|
@ -20,13 +20,20 @@ namespace Server.Accounting
|
|||
/// Enables or Disables automatic conversion of Gold and Checks to Bank Currency
|
||||
/// when they are added to a bank box container.
|
||||
/// </summary>
|
||||
public static bool ConvertOnBank = true;
|
||||
public static bool ConvertOnBank { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Enables or Disables automatic conversion of Gold and Checks to Bank Currency
|
||||
/// when they are added to a secure trade container.
|
||||
/// </summary>
|
||||
public static bool ConvertOnTrade = false;
|
||||
public static bool ConvertOnTrade { get; private set; }
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
Enabled = ServerConfiguration.GetSetting("accountGold.enable", Core.TOL);
|
||||
ConvertOnBank = ServerConfiguration.GetSetting("accountGold.convertOnBank", true);
|
||||
ConvertOnTrade = ServerConfiguration.GetSetting("accountGold.convertOnTrade", false);
|
||||
}
|
||||
}
|
||||
|
||||
public interface IGoldAccount
|
||||
|
|
|
|||
|
|
@ -20,8 +20,12 @@ namespace Server.Items
|
|||
{
|
||||
public sealed class VirtualCheck : Item
|
||||
{
|
||||
// TODO: Move to configuration
|
||||
public static bool UseEditGump = false;
|
||||
public static bool UseEditGump { get; private set; }
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
UseEditGump = ServerConfiguration.GetSetting("virtualChecks.useEditGump", true);
|
||||
}
|
||||
|
||||
private int m_Gold;
|
||||
|
||||
|
|
|
|||
51
Projects/Server/Json/Converters/JsonNullableEnumConverter.cs
Normal file
51
Projects/Server/Json/Converters/JsonNullableEnumConverter.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2021 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: JsonNullableEnumConverter.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.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json.Converters
|
||||
{
|
||||
class JsonNullableEnumConverter<T> : JsonConverter<T?> where T : struct, Enum
|
||||
{
|
||||
private readonly JsonConverter<T> _converter;
|
||||
|
||||
public JsonNullableEnumConverter(JsonConverter<T> converter) => _converter = converter;
|
||||
|
||||
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.Null)
|
||||
{
|
||||
reader.Read();
|
||||
return null;
|
||||
}
|
||||
|
||||
return _converter.Read(ref reader, typeof(T), options);
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, T? value, JsonSerializerOptions options)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
writer.WriteNullValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
_converter.Write(writer, value.Value, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*************************************************************************
|
||||
* ModernUO *
|
||||
* Copyright 2019-2021 - ModernUO Development Team *
|
||||
* Email: hi@modernuo.com *
|
||||
* File: JsonNullableEnumConverterFactory.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.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Server.Json.Converters
|
||||
{
|
||||
public class JsonNullableEnumConverterFactory : JsonConverterFactory
|
||||
{
|
||||
private readonly JsonStringEnumConverter _stringEnumConverter;
|
||||
|
||||
public JsonNullableEnumConverterFactory(JsonNamingPolicy? namingPolicy = null, bool allowIntegerValues = true) =>
|
||||
_stringEnumConverter = new JsonStringEnumConverter(namingPolicy, allowIntegerValues);
|
||||
|
||||
public override bool CanConvert(Type typeToConvert) => Nullable.GetUnderlyingType(typeToConvert)?.IsEnum == true;
|
||||
|
||||
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
var type = Nullable.GetUnderlyingType(typeToConvert);
|
||||
return (JsonConverter?)Activator.CreateInstance(typeof(JsonNullableEnumConverter<>).MakeGenericType(type!),
|
||||
_stringEnumConverter.CreateConverter(type, options));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ using System.IO;
|
|||
using System.Text.Encodings.Web;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Server.Json.Converters;
|
||||
using Server.Text;
|
||||
|
||||
namespace Server.Json
|
||||
|
|
@ -39,6 +40,7 @@ namespace Server.Json
|
|||
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||||
};
|
||||
|
||||
options.Converters.Add(new JsonNullableEnumConverterFactory());
|
||||
options.Converters.Add(new JsonStringEnumConverter());
|
||||
options.Converters.Add(new MapConverterFactory());
|
||||
options.Converters.Add(new Point3DConverterFactory());
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ namespace Server
|
|||
_ => "CTRL+C"
|
||||
};
|
||||
|
||||
Console.WriteLine("Core: Detected {0} pressed.", keypress);
|
||||
WriteConsoleLine($"Detected {keypress} pressed.");
|
||||
e.Cancel = true;
|
||||
Kill();
|
||||
}
|
||||
|
|
@ -410,7 +410,7 @@ namespace Server
|
|||
".TrimMultiline());
|
||||
Utility.PopColor();
|
||||
|
||||
Console.WriteLine("Core: Running on {0}", RuntimeInformation.FrameworkDescription);
|
||||
WriteConsoleLine($"Running on {RuntimeInformation.FrameworkDescription}");
|
||||
|
||||
var ttObj = new Timer.TimerThread();
|
||||
_timerThread = new Thread(ttObj.TimerMain)
|
||||
|
|
@ -422,7 +422,7 @@ namespace Server
|
|||
|
||||
if (s.Length > 0)
|
||||
{
|
||||
Console.WriteLine("Core: Running with arguments: {0}", s);
|
||||
WriteConsoleLine($"Running with arguments: {s}");
|
||||
}
|
||||
|
||||
ProcessorCount = Environment.ProcessorCount;
|
||||
|
|
@ -434,20 +434,17 @@ namespace Server
|
|||
|
||||
if (MultiProcessor)
|
||||
{
|
||||
Console.WriteLine("Core: Optimizing for {0} processor{1}", ProcessorCount, ProcessorCount == 1 ? "" : "s");
|
||||
WriteConsoleLine($"Optimizing for {ProcessorCount} processor{(ProcessorCount == 1 ? "" : "s")}");
|
||||
}
|
||||
|
||||
Console.CancelKeyPress += Console_CancelKeyPressed;
|
||||
|
||||
if (GCSettings.IsServerGC)
|
||||
{
|
||||
Console.WriteLine("Core: Server garbage collection mode enabled");
|
||||
WriteConsoleLine(": Server garbage collection mode enabled");
|
||||
}
|
||||
|
||||
Console.WriteLine(
|
||||
"Core: High resolution timing ({0})",
|
||||
Stopwatch.IsHighResolution ? "Supported" : "Unsupported"
|
||||
);
|
||||
WriteConsoleLine($"High resolution timing ({(Stopwatch.IsHighResolution ? "Supported" : "Unsupported")})");
|
||||
|
||||
ServerConfiguration.Load();
|
||||
|
||||
|
|
@ -469,7 +466,6 @@ namespace Server
|
|||
|
||||
VerifySerialization();
|
||||
|
||||
MapLoader.LoadMaps();
|
||||
AssemblyHandler.Invoke("Configure");
|
||||
|
||||
TileMatrixLoader.LoadTileMatrix();
|
||||
|
|
@ -609,5 +605,17 @@ namespace Server
|
|||
Parallel.ForEach(assembly.GetTypes(), VerifyType);
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static void WriteConsole(string message)
|
||||
{
|
||||
Console.Write("Core: {0}", message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static void WriteConsoleLine(string message)
|
||||
{
|
||||
Console.WriteLine("Core: {0}", message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ using Server.Json;
|
|||
|
||||
namespace Server
|
||||
{
|
||||
internal static class MapLoader
|
||||
public static class MapLoader
|
||||
{
|
||||
/* Here we configure all maps. Some notes:
|
||||
*
|
||||
|
|
@ -32,7 +32,7 @@ namespace Server
|
|||
* 3) Map 255 is reserved for core use.
|
||||
* 4) Changing or removing any predefined maps may cause server instability.
|
||||
*
|
||||
* Map definitions are modified in Data/map-definitions.json:
|
||||
* Map definitions are modified in Data/Map Definitions/<expansion>.json:
|
||||
* - <index> : An unreserved unique index for this map
|
||||
* - <id> : An identification number used in client communications. For any visible maps, this value must be from 0-5
|
||||
* - <fileIndex> : A file identification number. For any visible maps, this value must be from 0-5
|
||||
|
|
@ -41,8 +41,12 @@ namespace Server
|
|||
* - <name> : Reference name for the map, used in props gump, get/set commands, region loading, etc
|
||||
* - <rules> : Rules and restrictions associated with the map. See documentation for details
|
||||
*/
|
||||
internal static void LoadMaps()
|
||||
[CallPriority(2)]
|
||||
public static void Configure()
|
||||
{
|
||||
// Set to true to support < 6.0.0 clients where map0.mul is both Felucca & Trammel
|
||||
var pre6000Trammel = ServerConfiguration.GetOrUpdateSetting("maps.enablePre6000Trammel", false);
|
||||
|
||||
var failures = new List<string>();
|
||||
var count = 0;
|
||||
|
||||
|
|
@ -59,6 +63,12 @@ namespace Server
|
|||
|
||||
foreach (var def in maps)
|
||||
{
|
||||
if (def.Id == 1 && pre6000Trammel)
|
||||
{
|
||||
// Use Old Haven by changing file index to Felucca
|
||||
def.FileIndex = 0;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
RegisterMap(def);
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace Server.Network
|
|||
if (error != ZlibError.Okay)
|
||||
{
|
||||
Utility.PushColor(ConsoleColor.Red);
|
||||
Console.WriteLine("Core: Gump compression failed {0}", error);
|
||||
Core.WriteConsoleLine($"Gump compression failed {error}");
|
||||
Utility.PopColor();
|
||||
|
||||
writer.Write(4);
|
||||
|
|
|
|||
|
|
@ -657,12 +657,14 @@ namespace Server
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void RemoveGuild(BaseGuild guild) => Guilds.Remove(guild.Serial);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void WriteConsole(string message)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
Console.Write("[{0} {1}] World: {2}", now.ToShortDateString(), now.ToLongTimeString(), message);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void WriteConsoleLine(string message)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,31 @@ using Xunit;
|
|||
|
||||
namespace UOContent.Tests
|
||||
{
|
||||
public class TestBook : BaseBook
|
||||
{
|
||||
public TestBook(int itemID, int pageCount = 20, bool writable = true) : base(itemID, pageCount, writable)
|
||||
{
|
||||
}
|
||||
|
||||
public TestBook(int itemID, string title, string author, int pageCount, bool writable) : base(itemID, title, author, pageCount, writable)
|
||||
{
|
||||
}
|
||||
|
||||
public TestBook(int itemID, bool writable) : base(itemID, writable)
|
||||
{
|
||||
}
|
||||
|
||||
public TestBook(Serial serial) : base(serial)
|
||||
{
|
||||
Pages = new BookPageInfo[20];
|
||||
|
||||
for (var i = 0; i < Pages.Length; ++i)
|
||||
{
|
||||
Pages[i] = new BookPageInfo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BookPacketTests : IClassFixture<ServerFixture>
|
||||
{
|
||||
[Theory]
|
||||
|
|
@ -17,7 +42,8 @@ namespace UOContent.Tests
|
|||
var m = new Mobile(0x1);
|
||||
m.DefaultMobileInit();
|
||||
|
||||
var book = new BlueBook { Author = author, Title = title };
|
||||
Serial serial = 0x1001;
|
||||
var book = new TestBook(serial) { Author = author, Title = title };
|
||||
|
||||
var expected = new BookHeader(m, book).Compile();
|
||||
|
||||
|
|
@ -34,7 +60,8 @@ namespace UOContent.Tests
|
|||
var m = new Mobile(0x1);
|
||||
m.DefaultMobileInit();
|
||||
|
||||
var book = new BlueBook { Author = "Some Author", Title = "Some Title" };
|
||||
Serial serial = 0x1001;
|
||||
var book = new TestBook(serial) { Author = "Some Author", Title = "Some Title" };
|
||||
book.Pages[0].Lines = new[]
|
||||
{
|
||||
"Some books start with actual content",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
using Server.Accounting;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server
|
||||
|
|
@ -8,13 +6,6 @@ namespace Server
|
|||
{
|
||||
public static void Configure()
|
||||
{
|
||||
Core.Expansion = ServerConfiguration.GetOrUpdateSetting("currentExpansion", Expansion.TOL);
|
||||
|
||||
AccountGold.Enabled = ServerConfiguration.GetSetting("accountGold.enable", 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.enable", Core.AOS);
|
||||
ObjectPropertyList.Enabled = ServerConfiguration.GetSetting("opl.enable", Core.AOS);
|
||||
var visibleDamage = ServerConfiguration.GetSetting("visibleDamage", Core.AOS);
|
||||
|
|
@ -30,8 +21,8 @@ namespace Server
|
|||
|
||||
if (ObjectPropertyList.Enabled)
|
||||
{
|
||||
IncomingEntityPackets.SingleClickProps =
|
||||
true; // single click for everything is overridden to check object property list
|
||||
// single click for everything is overridden to check object property list
|
||||
IncomingEntityPackets.SingleClickProps = true;
|
||||
}
|
||||
|
||||
Mobile.AOSStatusHandler = AOS.GetStatus;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ namespace Server.Items
|
|||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int PagesCount => Pages.Length;
|
||||
|
||||
public BookPageInfo[] Pages { get; private set; }
|
||||
public BookPageInfo[] Pages { get; protected set; }
|
||||
|
||||
public virtual BookContent DefaultContent => null;
|
||||
|
||||
|
|
@ -230,14 +230,7 @@ namespace Server.Items
|
|||
}
|
||||
else
|
||||
{
|
||||
if (content != null)
|
||||
{
|
||||
Pages = content.Copy();
|
||||
}
|
||||
else
|
||||
{
|
||||
Pages = Array.Empty<BookPageInfo>();
|
||||
}
|
||||
Pages = content?.Copy() ?? Array.Empty<BookPageInfo>();
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
@ -262,14 +255,7 @@ namespace Server.Items
|
|||
{
|
||||
var content = DefaultContent;
|
||||
|
||||
if (content != null)
|
||||
{
|
||||
Pages = content.Copy();
|
||||
}
|
||||
else
|
||||
{
|
||||
Pages = Array.Empty<BookPageInfo>();
|
||||
}
|
||||
Pages = content?.Copy() ?? Array.Empty<BookPageInfo>();
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue