Adds configuration system. (#125)
This commit is contained in:
parent
2b4a6e1de1
commit
5b01754e3e
18 changed files with 409 additions and 420 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -2,6 +2,7 @@
|
||||||
/Distribution/ModernUO
|
/Distribution/ModernUO
|
||||||
/Distribution/ModernUO.*
|
/Distribution/ModernUO.*
|
||||||
/Distribution/Assemblies
|
/Distribution/Assemblies
|
||||||
|
/Distribution/Configuration
|
||||||
/Distribution/Logs
|
/Distribution/Logs
|
||||||
/Distribution/Backups
|
/Distribution/Backups
|
||||||
/Distribution/Saves
|
/Distribution/Saves
|
||||||
|
|
@ -41,4 +42,4 @@
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
/packages/*
|
/packages/*
|
||||||
!/packages/do_not_delete
|
!do_not_delete
|
||||||
|
|
|
||||||
0
Distribution/Configuration/do_not_delete
Normal file
0
Distribution/Configuration/do_not_delete
Normal file
|
|
@ -1,84 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using Server.Mobiles;
|
|
||||||
using Server.Network;
|
|
||||||
|
|
||||||
namespace Server.Commands
|
|
||||||
{
|
|
||||||
public class ConvertPlayers
|
|
||||||
{
|
|
||||||
public static void Initialize()
|
|
||||||
{
|
|
||||||
CommandSystem.Register("ConvertPlayers", AccessLevel.Administrator, Convert_OnCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Convert_OnCommand(CommandEventArgs e)
|
|
||||||
{
|
|
||||||
e.Mobile.SendMessage(
|
|
||||||
"Converting all players to PlayerMobile. You will be disconnected. Please Restart the server after the world has finished saving.");
|
|
||||||
List<Mobile> mobs = new List<Mobile>(World.Mobiles.Values);
|
|
||||||
int count = 0;
|
|
||||||
|
|
||||||
foreach (Mobile m in mobs)
|
|
||||||
if (m.Player && !(m is PlayerMobile))
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
m.NetState?.Dispose();
|
|
||||||
|
|
||||||
PlayerMobile pm = new PlayerMobile(m.Serial);
|
|
||||||
pm.DefaultMobileInit();
|
|
||||||
|
|
||||||
List<Item> copy = new List<Item>(m.Items);
|
|
||||||
for (int i = 0; i < copy.Count; i++)
|
|
||||||
pm.AddItem(copy[i]);
|
|
||||||
|
|
||||||
CopyProps(pm, m);
|
|
||||||
|
|
||||||
for (int i = 0; i < m.Skills.Length; i++)
|
|
||||||
{
|
|
||||||
pm.Skills[i].Base = m.Skills[i].Base;
|
|
||||||
pm.Skills[i].SetLockNoRelay(m.Skills[i].Lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
World.Mobiles[m.Serial] = pm;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
NetState.ProcessDisposedQueue();
|
|
||||||
World.Save();
|
|
||||||
|
|
||||||
Console.WriteLine("{0} players have been converted to PlayerMobile. {1}.", count,
|
|
||||||
Core.Service ? "The server is now restarting" : "Press any key to restart the server");
|
|
||||||
|
|
||||||
if (!Core.Service)
|
|
||||||
Console.ReadKey(true);
|
|
||||||
|
|
||||||
Core.Kill(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
e.Mobile.SendMessage("Couldn't find any Players to convert.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly PropertyInfo[] _mobProps =
|
|
||||||
typeof(Mobile).GetProperties(BindingFlags.Public | BindingFlags.Instance)
|
|
||||||
.Where(prop => prop.CanRead && prop.CanWrite).ToArray();
|
|
||||||
|
|
||||||
private static void CopyProps(Mobile to, Mobile from)
|
|
||||||
{
|
|
||||||
foreach (PropertyInfo prop in _mobProps)
|
|
||||||
try
|
|
||||||
{
|
|
||||||
prop.SetValue(to, prop.GetValue(from, null), null);
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
75
Projects/Scripts/Configuration/EmailConfiguration.cs
Normal file
75
Projects/Scripts/Configuration/EmailConfiguration.cs
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using MimeKit;
|
||||||
|
using Server.Json;
|
||||||
|
|
||||||
|
namespace Server.Configurations
|
||||||
|
{
|
||||||
|
public static class EmailConfiguration
|
||||||
|
{
|
||||||
|
public static readonly bool EmailEnabled;
|
||||||
|
public static readonly MailboxAddress FromAddress;
|
||||||
|
public static readonly MailboxAddress CrashAddress;
|
||||||
|
public static readonly MailboxAddress SpeechLogPageAddress;
|
||||||
|
public static readonly string EmailServer;
|
||||||
|
public static readonly int EmailPort;
|
||||||
|
public static readonly string EmailServerUsername;
|
||||||
|
public static readonly string EmailServerPassword;
|
||||||
|
public static readonly int EmailSendRetryCount = 5; // seconds
|
||||||
|
public static readonly int EmailSendRetryDelay = 2; // seconds
|
||||||
|
|
||||||
|
static EmailConfiguration()
|
||||||
|
{
|
||||||
|
string filePath = Path.Join(Core.BaseDirectory, "Configuration/email-settings.json");
|
||||||
|
Settings settings = JsonConfig.Deserialize<Settings>(filePath) ?? new Settings();
|
||||||
|
|
||||||
|
if (settings.emailServer == null || settings.fromAddress == null)
|
||||||
|
{
|
||||||
|
JsonConfig.Serialize(filePath, settings);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmailEnabled = true;
|
||||||
|
FromAddress = new MailboxAddress(settings.fromName, settings.fromAddress);
|
||||||
|
CrashAddress = new MailboxAddress(settings.crashName, settings.crashAddress);
|
||||||
|
SpeechLogPageAddress = new MailboxAddress(settings.speechLogPageName, settings.speechLogPageAddress);
|
||||||
|
EmailServer = settings.emailServer;
|
||||||
|
EmailPort = settings.emailPort;
|
||||||
|
EmailServerUsername = settings.emailUsername;
|
||||||
|
EmailServerPassword = settings.emailPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class Settings
|
||||||
|
{
|
||||||
|
[JsonPropertyName("fromAddress")]
|
||||||
|
internal string fromAddress { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("fromName")]
|
||||||
|
internal string fromName { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("crashAddress")]
|
||||||
|
internal string crashAddress { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("crashName")]
|
||||||
|
internal string crashName { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("speechLogPageAddress")]
|
||||||
|
internal string speechLogPageAddress { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("speechLogPageName")]
|
||||||
|
internal string speechLogPageName { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("emailServer")]
|
||||||
|
internal string emailServer { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("emailPort")]
|
||||||
|
internal int emailPort { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("emailUsername")]
|
||||||
|
internal string emailUsername { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("emailPassword")]
|
||||||
|
internal string emailPassword { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Server.Configurations;
|
||||||
using Server.Misc;
|
using Server.Misc;
|
||||||
using Server.Mobiles;
|
using Server.Mobiles;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
|
|
@ -227,7 +228,7 @@ namespace Server.Engines.Help
|
||||||
entry.Sender.SendMessage(
|
entry.Sender.SendMessage(
|
||||||
"We are sorry, but no staff members are currently available to assist you. Your page will remain in the queue until one becomes available, or until you cancel it manually.");
|
"We are sorry, but no staff members are currently available to assist you. Your page will remain in the queue until one becomes available, or until you cancel it manually.");
|
||||||
|
|
||||||
if (Email.FROM_ADDRESS != null && Email.SPEECH_LOG_PAGE_ADDRESS != null && entry.SpeechLog != null)
|
if (entry.SpeechLog != null)
|
||||||
Email.SendQueueEmail(entry, GetPageTypeName(entry.Type));
|
Email.SendQueueEmail(entry, GetPageTypeName(entry.Type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ namespace Server.Misc
|
||||||
{
|
{
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
if (Accounts.Count == 0 && !Core.Service)
|
if (Accounts.Count == 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine("This server has no accounts.");
|
Console.WriteLine("This server has no accounts.");
|
||||||
Console.Write("Do you want to create the owner account now? (y/n)");
|
Console.Write("Do you want to create the owner account now? (y/n)");
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ namespace Server.Misc
|
||||||
{
|
{
|
||||||
Console.Write("Crash: Sending email...");
|
Console.Write("Crash: Sending email...");
|
||||||
|
|
||||||
if (Email.FROM_ADDRESS != null && Email.CRASH_ADDRESS != null)
|
|
||||||
Email.SendCrashEmail(filePath);
|
Email.SendCrashEmail(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,7 +228,6 @@ namespace Server.Misc
|
||||||
|
|
||||||
Console.WriteLine("done");
|
Console.WriteLine("done");
|
||||||
|
|
||||||
if (Email.FROM_ADDRESS != null && Email.CRASH_ADDRESS != null)
|
|
||||||
SendEmail(filePath);
|
SendEmail(filePath);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|
|
||||||
|
|
@ -4,22 +4,13 @@ using System.Threading.Tasks;
|
||||||
using MailKit.Net.Smtp;
|
using MailKit.Net.Smtp;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
using Server.Accounting;
|
using Server.Accounting;
|
||||||
|
using Server.Configurations;
|
||||||
using Server.Engines.Help;
|
using Server.Engines.Help;
|
||||||
|
|
||||||
namespace Server.Misc
|
namespace Server.Misc
|
||||||
{
|
{
|
||||||
public static class Email
|
public static class Email
|
||||||
{
|
{
|
||||||
public static readonly MailboxAddress FROM_ADDRESS = new MailboxAddress(Configuration.Instance.emailSettings.FromName, Configuration.Instance.emailSettings.FromAddress);
|
|
||||||
public static readonly MailboxAddress CRASH_ADDRESS = new MailboxAddress(Configuration.Instance.emailSettings.crashName, Configuration.Instance.emailSettings.crashAddress);
|
|
||||||
public static readonly MailboxAddress SPEECH_LOG_PAGE_ADDRESS = new MailboxAddress(Configuration.Instance.emailSettings.speechLogPageName, Configuration.Instance.emailSettings.speechLogPageAddress);
|
|
||||||
public static readonly string EMAIL_SERVER = Configuration.Instance.emailSettings.emailServer;
|
|
||||||
public static readonly int EMAIL_PORT = Configuration.Instance.emailSettings.emailPort;
|
|
||||||
public static readonly string EMAIL_SERVER_USERNAME = Configuration.Instance.emailSettings.emailUsername;
|
|
||||||
public static readonly string EMAIL_SERVER_PASSWORD = Configuration.Instance.emailSettings.emailPassword;
|
|
||||||
public static readonly int RETRY_SEND_EMAIL_COUNT = 5;
|
|
||||||
public static readonly int SEND_DELAY_SECONDS = 2;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sends Queue-Page request using Email
|
/// Sends Queue-Page request using Email
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -27,12 +18,14 @@ namespace Server.Misc
|
||||||
/// <param name="pageType"></param>
|
/// <param name="pageType"></param>
|
||||||
public static void SendQueueEmail(PageEntry entry, string pageType)
|
public static void SendQueueEmail(PageEntry entry, string pageType)
|
||||||
{
|
{
|
||||||
|
if (!EmailConfiguration.EmailEnabled) return;
|
||||||
|
|
||||||
Mobile sender = entry.Sender;
|
Mobile sender = entry.Sender;
|
||||||
DateTime time = DateTime.UtcNow;
|
DateTime time = DateTime.UtcNow;
|
||||||
|
|
||||||
var message = new MimeMessage();
|
var message = new MimeMessage();
|
||||||
message.From.Add(FROM_ADDRESS);
|
message.From.Add(EmailConfiguration.FromAddress);
|
||||||
message.To.Add(SPEECH_LOG_PAGE_ADDRESS);
|
message.To.Add(EmailConfiguration.SpeechLogPageAddress);
|
||||||
message.Subject = "ModernUO Speech Log Page Forwarding";
|
message.Subject = "ModernUO Speech Log Page Forwarding";
|
||||||
|
|
||||||
using (StringWriter writer = new StringWriter())
|
using (StringWriter writer = new StringWriter())
|
||||||
|
|
@ -77,9 +70,11 @@ namespace Server.Misc
|
||||||
/// <param name="filePath"></param>
|
/// <param name="filePath"></param>
|
||||||
public static void SendCrashEmail(string filePath)
|
public static void SendCrashEmail(string filePath)
|
||||||
{
|
{
|
||||||
|
if (EmailConfiguration.EmailEnabled) return;
|
||||||
|
|
||||||
var message = new MimeMessage();
|
var message = new MimeMessage();
|
||||||
message.From.Add(FROM_ADDRESS);
|
message.From.Add(EmailConfiguration.FromAddress);
|
||||||
message.To.Add(CRASH_ADDRESS);
|
message.To.Add(EmailConfiguration.CrashAddress);
|
||||||
message.Subject = "Automated ModernUO Crash Report";
|
message.Subject = "Automated ModernUO Crash Report";
|
||||||
var builder = new BodyBuilder
|
var builder = new BodyBuilder
|
||||||
{
|
{
|
||||||
|
|
@ -96,19 +91,21 @@ namespace Server.Misc
|
||||||
/// <param name="message"></param>
|
/// <param name="message"></param>
|
||||||
private static async void SendAsync(MimeMessage message)
|
private static async void SendAsync(MimeMessage message)
|
||||||
{
|
{
|
||||||
|
if (!EmailConfiguration.EmailEnabled) return;
|
||||||
|
|
||||||
DateTime now = DateTime.UtcNow;
|
DateTime now = DateTime.UtcNow;
|
||||||
string messageID = $"<{now:yyyyMMdd}.{now:HHmmssff}@{EMAIL_SERVER}>";
|
string messageID = $"<{now:yyyyMMdd}.{now:HHmmssff}@{EmailConfiguration.EmailServer}>";
|
||||||
message.Headers.Add("Message-ID", messageID);
|
message.Headers.Add("Message-ID", messageID);
|
||||||
message.From.Add(FROM_ADDRESS);
|
message.From.Add(EmailConfiguration.FromAddress);
|
||||||
|
|
||||||
int delay = SEND_DELAY_SECONDS;
|
int delay = EmailConfiguration.EmailSendRetryDelay;
|
||||||
|
|
||||||
for (int i = 0; i < RETRY_SEND_EMAIL_COUNT; i++)
|
for (int i = 0; i < EmailConfiguration.EmailSendRetryCount; i++)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using SmtpClient client = new SmtpClient();
|
using SmtpClient client = new SmtpClient();
|
||||||
await client.ConnectAsync(EMAIL_SERVER, EMAIL_PORT, true);
|
await client.ConnectAsync(EmailConfiguration.EmailServer, EmailConfiguration.EmailPort, true);
|
||||||
await client.AuthenticateAsync(EMAIL_SERVER_USERNAME, EMAIL_SERVER_PASSWORD);
|
await client.AuthenticateAsync(EmailConfiguration.EmailServerUsername, EmailConfiguration.EmailServerPassword);
|
||||||
await client.SendAsync(message);
|
await client.SendAsync(message);
|
||||||
await client.DisconnectAsync(true);
|
await client.DisconnectAsync(true);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1,133 +0,0 @@
|
||||||
/*************************************************************************
|
|
||||||
* ModernUO *
|
|
||||||
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
|
||||||
* Email: hi@modernuo.com *
|
|
||||||
* File: Configuration.cs - Created: 2019/10/04 - Updated: 2020/01/19 *
|
|
||||||
* *
|
|
||||||
* 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. *
|
|
||||||
* *
|
|
||||||
* This program is distributed in the hope that it will be useful, *
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
||||||
* GNU General Public License for more details. *
|
|
||||||
* *
|
|
||||||
* 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.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Server
|
|
||||||
{
|
|
||||||
public class Configuration
|
|
||||||
{
|
|
||||||
private static Configuration m_Configuration;
|
|
||||||
|
|
||||||
public static Configuration Instance => m_Configuration ??= ReadConfiguration();
|
|
||||||
|
|
||||||
[JsonPropertyName("dataDirectories")]
|
|
||||||
public List<string> DataDirectories { get; set; } = new List<string>();
|
|
||||||
|
|
||||||
[JsonPropertyName("emailSettings")]
|
|
||||||
public EmailSettings emailSettings { get; set; } = new EmailSettings();
|
|
||||||
|
|
||||||
private static string FilePath => Path.Join(Core.BaseDirectory, "Data/modernuo.json");
|
|
||||||
|
|
||||||
private static void PromptDataDirectories(Configuration config)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Please enter the Ultima Online directory:");
|
|
||||||
|
|
||||||
string directory;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Console.Write("> ");
|
|
||||||
directory = Console.ReadLine();
|
|
||||||
} while (!Directory.Exists(directory));
|
|
||||||
|
|
||||||
config.DataDirectories.Add(directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Configuration ReadConfiguration()
|
|
||||||
{
|
|
||||||
var relPath = new Uri($"{Core.BaseDirectory}/").MakeRelativeUri(new Uri(FilePath)).ToString();
|
|
||||||
Console.Write($"Reading configuration from {relPath}...");
|
|
||||||
Configuration config;
|
|
||||||
|
|
||||||
if (File.Exists(FilePath))
|
|
||||||
{
|
|
||||||
using var fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
||||||
Span<byte> configBytes = stackalloc byte[(int)fs.Length];
|
|
||||||
fs.Read(configBytes);
|
|
||||||
config = JsonSerializer.Deserialize<Configuration>(Utility.UTF8WithEncoding.GetString(configBytes));
|
|
||||||
Console.WriteLine("done");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine("not found");
|
|
||||||
config = new Configuration();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Extend with a config read verification function that can be extended.
|
|
||||||
if (config.DataDirectories.Count == 0)
|
|
||||||
{
|
|
||||||
PromptDataDirectories(config);
|
|
||||||
config.Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Flush()
|
|
||||||
{
|
|
||||||
using var fs = new FileStream(FilePath, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
|
|
||||||
var configJson = JsonSerializer.Serialize(this, new JsonSerializerOptions { WriteIndented = true });
|
|
||||||
Span<byte> data = stackalloc byte[Utility.UTF8WithEncoding.GetMaxByteCount(configJson.Length)];
|
|
||||||
var bytesWritten = Utility.UTF8WithEncoding.GetBytes(configJson, data);
|
|
||||||
fs.Write(data.Slice(0, bytesWritten));
|
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
|
||||||
Console.WriteLine($"Configuration saved to {FilePath}");
|
|
||||||
Console.ResetColor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Make configuration pluggable. Move this to scripts
|
|
||||||
public class EmailSettings
|
|
||||||
{
|
|
||||||
[JsonPropertyName("fromAddress")]
|
|
||||||
public string FromAddress { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("fromName")]
|
|
||||||
public string FromName { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("crashAddress")]
|
|
||||||
public string crashAddress { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("crashName")]
|
|
||||||
public string crashName { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("speechLogPageAddress")]
|
|
||||||
public string speechLogPageAddress { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("speechLogPageName")]
|
|
||||||
public string speechLogPageName { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("emailServer")]
|
|
||||||
public string emailServer { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("emailPort")]
|
|
||||||
public int emailPort { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("emailUsername")]
|
|
||||||
public string emailUsername { get; set; }
|
|
||||||
|
|
||||||
[JsonPropertyName("emailPassword")]
|
|
||||||
public string emailPassword { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
110
Projects/Server/Configuration/ServerConfiguration.cs
Normal file
110
Projects/Server/Configuration/ServerConfiguration.cs
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* ModernUO *
|
||||||
|
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||||
|
* Email: hi@modernuo.com *
|
||||||
|
* File: Configuration.cs - Created: 2019/10/04 - Updated: 2020/01/19 *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* 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.Text.Json.Serialization;
|
||||||
|
using Server.Json;
|
||||||
|
|
||||||
|
namespace Server
|
||||||
|
{
|
||||||
|
public static class ServerConfiguration
|
||||||
|
{
|
||||||
|
private const string m_RelPath = "Configuration/modernuo.json";
|
||||||
|
private static readonly string m_FilePath = Path.Join(Core.BaseDirectory, m_RelPath);
|
||||||
|
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 void LoadConfiguration()
|
||||||
|
{
|
||||||
|
bool updated = false;
|
||||||
|
|
||||||
|
if (File.Exists(m_FilePath))
|
||||||
|
{
|
||||||
|
Console.Write($"Core: Reading configuration from {m_RelPath}...");
|
||||||
|
m_Settings = JsonConfig.Deserialize<ServerSettings>(m_FilePath);
|
||||||
|
|
||||||
|
if (m_Settings == null)
|
||||||
|
{
|
||||||
|
Console.ForegroundColor = ConsoleColor.Red;
|
||||||
|
Console.WriteLine("failed");
|
||||||
|
Console.ResetColor();
|
||||||
|
throw new Exception("Core: Server configuration failed to deserialize.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine("done");
|
||||||
|
Console.WriteLine("Settings: {0}", m_Settings.settings["stuff"]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updated = true;
|
||||||
|
m_Settings = new ServerSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Settings.dataDirectories.Count == 0)
|
||||||
|
{
|
||||||
|
updated = true;
|
||||||
|
Console.WriteLine("Core: Server configuration is missing data directories.");
|
||||||
|
m_Settings.dataDirectories.Add(GetDataDirectory());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updated)
|
||||||
|
SaveConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ServerSettings
|
||||||
|
{
|
||||||
|
[JsonPropertyName("dataDirectories")]
|
||||||
|
public List<string> dataDirectories { get; set; } = new List<string>();
|
||||||
|
|
||||||
|
[JsonPropertyName("settings")]
|
||||||
|
public Dictionary<string, string> settings { get; set; } = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
[JsonExtensionData]
|
||||||
|
public Dictionary<string, object> metadata { get; set; } = new Dictionary<string, object>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetDataDirectory()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Please enter the Ultima Online directory:");
|
||||||
|
|
||||||
|
string directory;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Console.Write("> ");
|
||||||
|
directory = Console.ReadLine();
|
||||||
|
} while (!Directory.Exists(directory));
|
||||||
|
|
||||||
|
return directory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SaveConfiguration()
|
||||||
|
{
|
||||||
|
JsonConfig.Serialize(m_FilePath, m_Settings);
|
||||||
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
|
Console.WriteLine($"Core: Configuration saved to {m_RelPath}.");
|
||||||
|
Console.ResetColor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
Projects/Server/JsonConfiguration/Converters/MapConverter.cs
Normal file
35
Projects/Server/JsonConfiguration/Converters/MapConverter.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* ModernUO *
|
||||||
|
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||||
|
* Email: hi@modernuo.com *
|
||||||
|
* File: MapConverter.cs - Created: 2020/04/12 - Updated: 2020/05/02 *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
public class MapConverter : JsonConverter<Map>
|
||||||
|
{
|
||||||
|
public override Map Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
=> Map.Parse(reader.GetString());
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, Map value, JsonSerializerOptions options)
|
||||||
|
=> writer.WriteStringValue(value.Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* ModernUO *
|
||||||
|
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||||
|
* Email: hi@modernuo.com *
|
||||||
|
* File: MapConverter.cs - Created: 2020/04/12 - Updated: 2020/05/02 *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* 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
|
||||||
|
{
|
||||||
|
public class Point3dConverter : JsonConverter<Point3D>
|
||||||
|
{
|
||||||
|
public override Point3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
if (reader.TokenType != JsonTokenType.StartArray)
|
||||||
|
throw new JsonException("Point3d must be an array of x, y, z");
|
||||||
|
|
||||||
|
var data = new int[3];
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
reader.Read();
|
||||||
|
if (reader.TokenType == JsonTokenType.EndArray)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (reader.TokenType == JsonTokenType.Number)
|
||||||
|
{
|
||||||
|
if (count < 3)
|
||||||
|
data[count] = reader.GetInt32();
|
||||||
|
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < 2 || count > 3)
|
||||||
|
throw new JsonException("Point3d must be an array of x, y, z");
|
||||||
|
|
||||||
|
return new Point3D(data[0], data[1], data[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(Utf8JsonWriter writer, Point3D value, JsonSerializerOptions options)
|
||||||
|
{
|
||||||
|
writer.WriteStartArray();
|
||||||
|
writer.WriteNumberValue(value.X);
|
||||||
|
writer.WriteNumberValue(value.Y);
|
||||||
|
writer.WriteNumberValue(value.Z);
|
||||||
|
writer.WriteEndArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
49
Projects/Server/JsonConfiguration/JsonConfig.cs
Normal file
49
Projects/Server/JsonConfiguration/JsonConfig.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*************************************************************************
|
||||||
|
* ModernUO *
|
||||||
|
* Copyright (C) 2019-2020 - ModernUO Development Team *
|
||||||
|
* Email: hi@modernuo.com *
|
||||||
|
* File: JsonConfig.cs - Created: 2020/05/02 - Updated: 2020/05/02 *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* 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.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace Server.Json
|
||||||
|
{
|
||||||
|
public static class JsonConfig
|
||||||
|
{
|
||||||
|
public static readonly JsonSerializerOptions Options = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
ReadCommentHandling = JsonCommentHandling.Skip,
|
||||||
|
WriteIndented = true,
|
||||||
|
AllowTrailingCommas = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
public static T Deserialize<T>(string filePath, JsonSerializerOptions options = null)
|
||||||
|
{
|
||||||
|
if (!File.Exists(filePath)) return default;
|
||||||
|
string text = File.ReadAllText(filePath, Utility.UTF8);
|
||||||
|
return JsonSerializer.Deserialize<T>(text, options ?? Options);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Serialize(string filePath, object value, JsonSerializerOptions options = null)
|
||||||
|
{
|
||||||
|
if (File.Exists(filePath)) File.Delete(filePath);
|
||||||
|
|
||||||
|
File.WriteAllText(filePath, JsonSerializer.Serialize(value, options ?? Options));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Server.Json
|
|
||||||
{
|
|
||||||
public class MapConverter : JsonConverter<Map>
|
|
||||||
{
|
|
||||||
public override Map Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
||||||
=> Map.Parse(reader.GetString());
|
|
||||||
|
|
||||||
public override void Write(Utf8JsonWriter writer, Map value, JsonSerializerOptions options)
|
|
||||||
=> writer.WriteStringValue(value.Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.Json.Serialization;
|
|
||||||
|
|
||||||
namespace Server.Json
|
|
||||||
{
|
|
||||||
public class Point3dConverter : JsonConverter<Point3D>
|
|
||||||
{
|
|
||||||
public override Point3D Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
|
||||||
{
|
|
||||||
if (reader.TokenType != JsonTokenType.StartArray)
|
|
||||||
throw new JsonException("Point3d must be an array of x, y, z");
|
|
||||||
|
|
||||||
var data = new int[3];
|
|
||||||
var count = 0;
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
reader.Read();
|
|
||||||
if (reader.TokenType == JsonTokenType.EndArray)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (reader.TokenType == JsonTokenType.Number)
|
|
||||||
{
|
|
||||||
if (count < 3)
|
|
||||||
data[count] = reader.GetInt32();
|
|
||||||
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count < 2 || count > 3)
|
|
||||||
throw new JsonException("Point3d must be an array of x, y, z");
|
|
||||||
|
|
||||||
return new Point3D(data[0], data[1], data[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Write(Utf8JsonWriter writer, Point3D value, JsonSerializerOptions options)
|
|
||||||
{
|
|
||||||
writer.WriteStartArray();
|
|
||||||
writer.WriteNumberValue(value.X);
|
|
||||||
writer.WriteNumberValue(value.Y);
|
|
||||||
writer.WriteNumberValue(value.Z);
|
|
||||||
writer.WriteEndArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -45,8 +45,6 @@ namespace Server
|
||||||
private static string m_BaseDirectory;
|
private static string m_BaseDirectory;
|
||||||
private static string m_ExePath;
|
private static string m_ExePath;
|
||||||
|
|
||||||
private static bool m_Cache = true;
|
|
||||||
|
|
||||||
private static bool m_Profiling;
|
private static bool m_Profiling;
|
||||||
private static DateTime m_ProfileStart;
|
private static DateTime m_ProfileStart;
|
||||||
private static TimeSpan m_ProfileTime;
|
private static TimeSpan m_ProfileTime;
|
||||||
|
|
@ -69,9 +67,6 @@ namespace Server
|
||||||
private static readonly double m_HighFrequency = 1000.0 / Stopwatch.Frequency;
|
private static readonly double m_HighFrequency = 1000.0 / Stopwatch.Frequency;
|
||||||
private static readonly double m_LowFrequency = 1000.0 / TimeSpan.TicksPerSecond;
|
private static readonly double m_LowFrequency = 1000.0 / TimeSpan.TicksPerSecond;
|
||||||
|
|
||||||
private static bool m_UseHRT;
|
|
||||||
|
|
||||||
public static readonly bool Is64Bit = Environment.Is64BitProcess;
|
|
||||||
internal static ConsoleEventHandler m_ConsoleEventHandler;
|
internal static ConsoleEventHandler m_ConsoleEventHandler;
|
||||||
|
|
||||||
private static int m_CycleIndex = 1;
|
private static int m_CycleIndex = 1;
|
||||||
|
|
@ -111,8 +106,6 @@ namespace Server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Service { get; private set; }
|
|
||||||
|
|
||||||
public static bool Debug { get; private set; }
|
public static bool Debug { get; private set; }
|
||||||
|
|
||||||
internal static bool HaltOnWarning { get; private set; }
|
internal static bool HaltOnWarning { get; private set; }
|
||||||
|
|
@ -126,7 +119,7 @@ namespace Server
|
||||||
|
|
||||||
public static MultiTextWriter MultiConsoleOut { get; private set; }
|
public static MultiTextWriter MultiConsoleOut { get; private set; }
|
||||||
|
|
||||||
public static bool UsingHighResolutionTiming => m_UseHRT && m_HighRes && !Unix;
|
public static bool UsingHighResolutionTiming => m_HighRes && !Unix;
|
||||||
|
|
||||||
public static long TickCount => (long)Ticks;
|
public static long TickCount => (long)Ticks;
|
||||||
|
|
||||||
|
|
@ -134,7 +127,7 @@ namespace Server
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (m_UseHRT && m_HighRes && !Unix) return Stopwatch.GetTimestamp() * m_HighFrequency;
|
if (m_HighRes && !Unix) return Stopwatch.GetTimestamp() * m_HighFrequency;
|
||||||
|
|
||||||
return DateTime.UtcNow.Ticks * m_LowFrequency;
|
return DateTime.UtcNow.Ticks * m_LowFrequency;
|
||||||
}
|
}
|
||||||
|
|
@ -188,21 +181,12 @@ namespace Server
|
||||||
if (Debug)
|
if (Debug)
|
||||||
Utility.Separate(sb, "-debug", " ");
|
Utility.Separate(sb, "-debug", " ");
|
||||||
|
|
||||||
if (Service)
|
|
||||||
Utility.Separate(sb, "-service", " ");
|
|
||||||
|
|
||||||
if (m_Profiling)
|
if (m_Profiling)
|
||||||
Utility.Separate(sb, "-profile", " ");
|
Utility.Separate(sb, "-profile", " ");
|
||||||
|
|
||||||
if (!m_Cache)
|
|
||||||
Utility.Separate(sb, "-nocache", " ");
|
|
||||||
|
|
||||||
if (HaltOnWarning)
|
if (HaltOnWarning)
|
||||||
Utility.Separate(sb, "-haltonwarning", " ");
|
Utility.Separate(sb, "-haltonwarning", " ");
|
||||||
|
|
||||||
if (m_UseHRT)
|
|
||||||
Utility.Separate(sb, "-usehrt", " ");
|
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -216,14 +200,9 @@ namespace Server
|
||||||
|
|
||||||
public static string FindDataFile(string path)
|
public static string FindDataFile(string path)
|
||||||
{
|
{
|
||||||
var config = Configuration.Instance;
|
|
||||||
if (config.DataDirectories.Count == 0)
|
|
||||||
throw new InvalidOperationException(
|
|
||||||
"Attempted to FindDataFile before DataDirectories list has been filled.");
|
|
||||||
|
|
||||||
string fullPath = null;
|
string fullPath = null;
|
||||||
|
|
||||||
foreach (var p in config.DataDirectories)
|
foreach (var p in ServerConfiguration.DataDirectories)
|
||||||
{
|
{
|
||||||
fullPath = Path.Combine(p, path);
|
fullPath = Path.Combine(p, path);
|
||||||
|
|
||||||
|
|
@ -262,7 +241,7 @@ namespace Server
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!close && !Service)
|
if (!close)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -283,7 +262,7 @@ namespace Server
|
||||||
|
|
||||||
private static bool OnConsoleEvent(ConsoleEventType type)
|
private static bool OnConsoleEvent(ConsoleEventType type)
|
||||||
{
|
{
|
||||||
if (World.Saving || (Service && type == ConsoleEventType.CTRL_LOGOFF_EVENT))
|
if (World.Saving || type == ConsoleEventType.CTRL_LOGOFF_EVENT)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
Kill(); // Kill -> HandleClosed will handle waiting for the completion of flushing to disk
|
Kill(); // Kill -> HandleClosed will handle waiting for the completion of flushing to disk
|
||||||
|
|
@ -338,47 +317,25 @@ namespace Server
|
||||||
foreach (var a in args)
|
foreach (var a in args)
|
||||||
if (Insensitive.Equals(a, "-debug"))
|
if (Insensitive.Equals(a, "-debug"))
|
||||||
Debug = true;
|
Debug = true;
|
||||||
else if (Insensitive.Equals(a, "-service"))
|
|
||||||
Service = true;
|
|
||||||
else if (Insensitive.Equals(a, "-profile"))
|
else if (Insensitive.Equals(a, "-profile"))
|
||||||
Profiling = true;
|
Profiling = true;
|
||||||
else if (Insensitive.Equals(a, "-nocache"))
|
|
||||||
m_Cache = false;
|
|
||||||
else if (Insensitive.Equals(a, "-haltonwarning"))
|
else if (Insensitive.Equals(a, "-haltonwarning"))
|
||||||
HaltOnWarning = true;
|
HaltOnWarning = true;
|
||||||
else if (Insensitive.Equals(a, "-usehrt"))
|
|
||||||
m_UseHRT = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (Service)
|
|
||||||
{
|
|
||||||
if (!Directory.Exists("Logs"))
|
|
||||||
Directory.CreateDirectory("Logs");
|
|
||||||
|
|
||||||
Console.SetOut(MultiConsoleOut = new MultiTextWriter(new FileLogger("Logs/Console.log")));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.SetOut(MultiConsoleOut = new MultiTextWriter(Console.Out));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread = Thread.CurrentThread;
|
Thread = Thread.CurrentThread;
|
||||||
Process = Process.GetCurrentProcess();
|
Process = Process.GetCurrentProcess();
|
||||||
Assembly = Assembly.GetEntryAssembly();
|
Assembly = Assembly.GetEntryAssembly();
|
||||||
|
|
||||||
|
if (Assembly == null)
|
||||||
|
throw new Exception("Core: Assembly entry is missing.");
|
||||||
|
|
||||||
if (Thread != null)
|
if (Thread != null)
|
||||||
Thread.Name = "Core Thread";
|
Thread.Name = "Core Thread";
|
||||||
|
|
||||||
if (BaseDirectory.Length > 0)
|
if (BaseDirectory.Length > 0)
|
||||||
Directory.SetCurrentDirectory(BaseDirectory);
|
Directory.SetCurrentDirectory(BaseDirectory);
|
||||||
|
|
||||||
var ver = Assembly.GetName().Version;
|
var ver = Assembly.GetName().Version ?? new Version();
|
||||||
|
|
||||||
Console.ForegroundColor = ConsoleColor.Green;
|
Console.ForegroundColor = ConsoleColor.Green;
|
||||||
// Added to help future code support on forums, as a 'check' people can ask for to it see if they recompiled core or not
|
// Added to help future code support on forums, as a 'check' people can ask for to it see if they recompiled core or not
|
||||||
|
|
@ -389,14 +346,6 @@ namespace Server
|
||||||
Console.ResetColor();
|
Console.ResetColor();
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
var config = Configuration.Instance;
|
|
||||||
foreach (var dir in config.DataDirectories.Where(dir => !Directory.Exists(dir)))
|
|
||||||
{
|
|
||||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
|
||||||
Console.WriteLine("Core: Config directory {0} does not exist.", dir);
|
|
||||||
Console.ResetColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
var ttObj = new Timer.TimerThread();
|
var ttObj = new Timer.TimerThread();
|
||||||
timerThread = new Thread(ttObj.TimerMain)
|
timerThread = new Thread(ttObj.TimerMain)
|
||||||
{
|
{
|
||||||
|
|
@ -413,9 +362,8 @@ namespace Server
|
||||||
if (ProcessorCount > 1)
|
if (ProcessorCount > 1)
|
||||||
MultiProcessor = true;
|
MultiProcessor = true;
|
||||||
|
|
||||||
if (MultiProcessor || Is64Bit)
|
if (MultiProcessor)
|
||||||
Console.WriteLine("Core: Optimizing for {0} {2}processor{1}", ProcessorCount, ProcessorCount == 1 ? "" : "s",
|
Console.WriteLine("Core: Optimizing for {0} processor{1}", ProcessorCount, ProcessorCount == 1 ? "" : "s");
|
||||||
Is64Bit ? "64-bit " : "");
|
|
||||||
|
|
||||||
if (IsWindows)
|
if (IsWindows)
|
||||||
{
|
{
|
||||||
|
|
@ -426,13 +374,14 @@ namespace Server
|
||||||
if (GCSettings.IsServerGC)
|
if (GCSettings.IsServerGC)
|
||||||
Console.WriteLine("Core: Server garbage collection mode enabled");
|
Console.WriteLine("Core: Server garbage collection mode enabled");
|
||||||
|
|
||||||
if (m_UseHRT)
|
Console.WriteLine("Core: High resolution timing ({0})",
|
||||||
Console.WriteLine("Core: Requested high resolution timing ({0})",
|
|
||||||
UsingHighResolutionTiming ? "Supported" : "Unsupported");
|
UsingHighResolutionTiming ? "Supported" : "Unsupported");
|
||||||
|
|
||||||
Console.WriteLine("SecureRandomImpl: {0} ({1})", SecureRandomImpl.Name,
|
Console.WriteLine("SecureRandomImpl: {0} ({1})", SecureRandomImpl.Name,
|
||||||
SecureRandomImpl.IsHardwareRNG ? "Hardware" : "Software");
|
SecureRandomImpl.IsHardwareRNG ? "Hardware" : "Software");
|
||||||
|
|
||||||
|
ServerConfiguration.LoadConfiguration();
|
||||||
|
|
||||||
// Load Assembly Scripts.CS.dll
|
// Load Assembly Scripts.CS.dll
|
||||||
AssemblyHandler.LoadScripts();
|
AssemblyHandler.LoadScripts();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -208,7 +208,7 @@ namespace Server
|
||||||
|
|
||||||
for (var i = 0; i < 0x4000; ++i)
|
for (var i = 0; i < 0x4000; ++i)
|
||||||
{
|
{
|
||||||
if (i == 1 || (i > 0 && (i & 0x1F) == 0)) bin.ReadInt32(); // header
|
if (i == 1 || i > 0 && (i & 0x1F) == 0) bin.ReadInt32(); // header
|
||||||
|
|
||||||
var flags = (TileFlag)bin.ReadInt64();
|
var flags = (TileFlag)bin.ReadInt64();
|
||||||
bin.ReadInt16(); // skip 2 bytes -- textureID
|
bin.ReadInt16(); // skip 2 bytes -- textureID
|
||||||
|
|
|
||||||
|
|
@ -130,8 +130,6 @@ namespace Server
|
||||||
{
|
{
|
||||||
Console.WriteLine("failed");
|
Console.WriteLine("failed");
|
||||||
|
|
||||||
if (!Core.Service)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Error: Type '{0}' was not found. Delete all of those types? (y/n)", typeName);
|
Console.WriteLine("Error: Type '{0}' was not found. Delete all of those types? (y/n)", typeName);
|
||||||
|
|
||||||
if (Console.ReadKey(true).Key == ConsoleKey.Y)
|
if (Console.ReadKey(true).Key == ConsoleKey.Y)
|
||||||
|
|
@ -142,11 +140,6 @@ namespace Server
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("Types will not be deleted. An exception will be thrown.");
|
Console.WriteLine("Types will not be deleted. An exception will be thrown.");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine("Error: Type '{0}' was not found.", typeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception($"Bad type '{typeName}'");
|
throw new Exception($"Bad type '{typeName}'");
|
||||||
}
|
}
|
||||||
|
|
@ -454,8 +447,6 @@ namespace Server
|
||||||
Console.WriteLine(" - Type: {0}", failedType);
|
Console.WriteLine(" - Type: {0}", failedType);
|
||||||
Console.WriteLine(" - Serial: {0}", failedSerial);
|
Console.WriteLine(" - Serial: {0}", failedSerial);
|
||||||
|
|
||||||
if (!Core.Service)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Delete the object? (y/n)");
|
Console.WriteLine("Delete the object? (y/n)");
|
||||||
|
|
||||||
if (Console.ReadKey(true).Key == ConsoleKey.Y)
|
if (Console.ReadKey(true).Key == ConsoleKey.Y)
|
||||||
|
|
@ -488,11 +479,6 @@ namespace Server
|
||||||
|
|
||||||
Console.WriteLine("After pressing return an exception will be thrown and the server will terminate.");
|
Console.WriteLine("After pressing return an exception will be thrown and the server will terminate.");
|
||||||
Console.ReadLine();
|
Console.ReadLine();
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine("An exception will be thrown and the server will terminate.");
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
$"Load failed (items={failedItems}, mobiles={failedMobiles}, guilds={failedGuilds}, type={failedType}, serial={failedSerial})",
|
$"Load failed (items={failedItems}, mobiles={failedMobiles}, guilds={failedGuilds}, type={failedType}, serial={failedSerial})",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue