Targets .NET Core 3.0 (#39)
This commit is contained in:
parent
0993c03b70
commit
08bf44af9a
125 changed files with 1473 additions and 14244 deletions
|
|
@ -1,251 +0,0 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Data.Odbc;
|
||||
using System.Threading;
|
||||
|
||||
namespace Server.Engines.MyRunUO
|
||||
{
|
||||
public class DatabaseCommandQueue
|
||||
{
|
||||
private string m_CompletionString;
|
||||
private string m_ConnectionString;
|
||||
private Queue m_Queue;
|
||||
private ManualResetEvent m_Sync;
|
||||
|
||||
public DatabaseCommandQueue(string completionString, string threadName) : this(Config.CompileConnectionString(),
|
||||
completionString, threadName)
|
||||
{
|
||||
}
|
||||
|
||||
public DatabaseCommandQueue(string connectionString, string completionString, string threadName)
|
||||
{
|
||||
m_CompletionString = completionString;
|
||||
m_ConnectionString = connectionString;
|
||||
|
||||
m_Queue = Queue.Synchronized(new Queue());
|
||||
|
||||
m_Queue.Enqueue(null); // signal connect
|
||||
|
||||
/*m_Queue.Enqueue( "DELETE FROM myrunuo_characters" );
|
||||
m_Queue.Enqueue( "DELETE FROM myrunuo_characters_layers" );
|
||||
m_Queue.Enqueue( "DELETE FROM myrunuo_characters_skills" );
|
||||
m_Queue.Enqueue( "DELETE FROM myrunuo_guilds" );
|
||||
m_Queue.Enqueue( "DELETE FROM myrunuo_guilds_wars" );*/
|
||||
|
||||
m_Sync = new ManualResetEvent(true);
|
||||
|
||||
// MyRunUO Database Command Queue;
|
||||
Thread thread = new Thread(Thread_Start) { Name = threadName, Priority = Config.DatabaseThreadPriority };
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
public bool HasCompleted{ get; private set; }
|
||||
|
||||
public void Enqueue(object obj)
|
||||
{
|
||||
lock (m_Queue.SyncRoot)
|
||||
{
|
||||
m_Queue.Enqueue(obj);
|
||||
try
|
||||
{
|
||||
m_Sync.Set();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Thread_Start()
|
||||
{
|
||||
bool connected = false;
|
||||
|
||||
OdbcConnection connection = null;
|
||||
OdbcCommand command = null;
|
||||
OdbcTransaction transact = null;
|
||||
|
||||
DateTime start = DateTime.UtcNow;
|
||||
|
||||
bool shouldWriteException = true;
|
||||
|
||||
while (true)
|
||||
{
|
||||
m_Sync.WaitOne();
|
||||
|
||||
while (m_Queue.Count > 0)
|
||||
try
|
||||
{
|
||||
object obj = m_Queue.Dequeue();
|
||||
|
||||
if (obj == null)
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
if (transact != null)
|
||||
try
|
||||
{
|
||||
transact.Commit();
|
||||
}
|
||||
catch (Exception commitException)
|
||||
{
|
||||
Console.WriteLine("MyRunUO: Exception caught when committing transaction");
|
||||
Console.WriteLine(commitException);
|
||||
|
||||
try
|
||||
{
|
||||
transact.Rollback();
|
||||
Console.WriteLine("MyRunUO: Transaction has been rolled back");
|
||||
}
|
||||
catch (Exception rollbackException)
|
||||
{
|
||||
Console.WriteLine("MyRunUO: Exception caught when rolling back transaction");
|
||||
Console.WriteLine(rollbackException);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
connection.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
connection.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
command.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_Sync.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
Console.WriteLine(m_CompletionString, (DateTime.UtcNow - start).TotalSeconds);
|
||||
HasCompleted = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
connected = true;
|
||||
connection = new OdbcConnection(m_ConnectionString);
|
||||
connection.Open();
|
||||
command = connection.CreateCommand();
|
||||
|
||||
if (Config.UseTransactions)
|
||||
{
|
||||
transact = connection.BeginTransaction();
|
||||
command.Transaction = transact;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
try
|
||||
{
|
||||
transact?.Rollback();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
connection?.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
connection?.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
command?.Dispose();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
m_Sync.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
Console.WriteLine("MyRunUO: Unable to connect to the database");
|
||||
Console.WriteLine(e);
|
||||
HasCompleted = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (obj is string s)
|
||||
{
|
||||
command.CommandText = s;
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] parms = (string[])obj;
|
||||
|
||||
command.CommandText = parms[0];
|
||||
|
||||
if (command.ExecuteScalar() == null)
|
||||
{
|
||||
command.CommandText = parms[1];
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (shouldWriteException)
|
||||
{
|
||||
Console.WriteLine("MyRunUO: Exception caught in database thread");
|
||||
Console.WriteLine(e);
|
||||
shouldWriteException = false;
|
||||
}
|
||||
}
|
||||
|
||||
lock (m_Queue.SyncRoot)
|
||||
{
|
||||
if (m_Queue.Count == 0)
|
||||
m_Sync.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,716 +0,0 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Server.Accounting;
|
||||
using Server.Commands;
|
||||
using Server.Guilds;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.MyRunUO
|
||||
{
|
||||
public class MyRunUO : Timer
|
||||
{
|
||||
public const char LineStart = '\"';
|
||||
public const string EntrySep = "\",\"";
|
||||
public const string LineEnd = "\"\n";
|
||||
private static double CpuInterval = 0.1; // Processor runs every 0.1 seconds
|
||||
|
||||
private static double
|
||||
CpuPercent = 0.25; // Processor runs for 25% of Interval, or ~25ms. This should take around 25% cpu
|
||||
|
||||
private static Timer m_Timer;
|
||||
|
||||
private static DatabaseCommandQueue m_Command;
|
||||
|
||||
private static List<Mobile> m_MobilesToUpdate = new List<Mobile>();
|
||||
private List<IAccount> m_Collecting;
|
||||
private int m_Index;
|
||||
|
||||
private List<Item> m_Items = new List<Item>();
|
||||
private string m_LayersPath;
|
||||
private ArrayList m_List;
|
||||
private string m_MobilesPath;
|
||||
private StreamWriter m_OpLayers;
|
||||
private StreamWriter m_OpMobiles;
|
||||
|
||||
private StreamWriter m_OpSkills;
|
||||
|
||||
private string m_SkillsPath;
|
||||
|
||||
private Stage m_Stage;
|
||||
|
||||
private DateTime m_StartTime;
|
||||
|
||||
public MyRunUO() : base(TimeSpan.FromSeconds(CpuInterval), TimeSpan.FromSeconds(CpuInterval))
|
||||
{
|
||||
m_List = new ArrayList();
|
||||
m_Collecting = new List<IAccount>();
|
||||
|
||||
m_StartTime = DateTime.UtcNow;
|
||||
Console.WriteLine("MyRunUO: Updating character database");
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (Config.Enabled)
|
||||
{
|
||||
DelayCall(TimeSpan.FromSeconds(10.0), Config.CharacterUpdateInterval, Begin);
|
||||
|
||||
CommandSystem.Register("InitMyRunUO", AccessLevel.Administrator, InitMyRunUO_OnCommand);
|
||||
CommandSystem.Register("UpdateMyRunUO", AccessLevel.Administrator, UpdateMyRunUO_OnCommand);
|
||||
|
||||
CommandSystem.Register("PublicChar", AccessLevel.Player, PublicChar_OnCommand);
|
||||
CommandSystem.Register("PrivateChar", AccessLevel.Player, PrivateChar_OnCommand);
|
||||
}
|
||||
}
|
||||
|
||||
[Usage("PublicChar")]
|
||||
[Description("Enables showing extended character stats and skills in MyRunUO.")]
|
||||
public static void PublicChar_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Mobile is PlayerMobile pm)
|
||||
{
|
||||
if (pm.PublicMyRunUO)
|
||||
{
|
||||
pm.SendMessage("You have already chosen to show your skills and stats.");
|
||||
}
|
||||
else
|
||||
{
|
||||
pm.PublicMyRunUO = true;
|
||||
pm.SendMessage("All of your skills and stats will now be shown publicly in MyRunUO.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Usage("PrivateChar")]
|
||||
[Description("Disables showing extended character stats and skills in MyRunUO.")]
|
||||
public static void PrivateChar_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (e.Mobile is PlayerMobile pm)
|
||||
{
|
||||
if (!pm.PublicMyRunUO)
|
||||
{
|
||||
pm.SendMessage("You have already chosen to not show your skills and stats.");
|
||||
}
|
||||
else
|
||||
{
|
||||
pm.PublicMyRunUO = false;
|
||||
pm.SendMessage("Only a general level of your top three skills will be shown in MyRunUO.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Usage("InitMyRunUO")]
|
||||
[Description("Initially creates the database schema.")]
|
||||
public static void InitMyRunUO_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (m_Command?.HasCompleted == true)
|
||||
{
|
||||
TableCreation();
|
||||
e.Mobile.SendMessage("MyRunUO table creation process has been started.");
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage("MyRunUO table creation is already running.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void TableCreation()
|
||||
{
|
||||
if (m_Command?.HasCompleted == false)
|
||||
return;
|
||||
// DateTime start = DateTime.Now;
|
||||
Console.WriteLine("MyRunUO: Creating tables");
|
||||
try
|
||||
{
|
||||
m_Command = new DatabaseCommandQueue("MyRunUO: Tables created in {0:F1} seconds",
|
||||
"MyRunUO Status Database Thread");
|
||||
m_Command.Enqueue(
|
||||
"CREATE TABLE IF NOT EXISTS `myrunuo_characters` ( `char_id` int(10) unsigned NOT NULL, `char_name` varchar(255) NOT NULL, `char_str` smallint(3) unsigned NOT NULL, `char_dex` smallint(3) unsigned NOT NULL, `char_int` smallint(3) unsigned NOT NULL, `char_female` tinyint(1) NOT NULL, `char_counts` smallint(6) NOT NULL, `char_guild` varchar(255) DEFAULT NULL, `char_guildtitle` varchar(255) DEFAULT NULL, `char_nototitle` varchar(255) DEFAULT NULL, `char_bodyhue` smallint(5) unsigned DEFAULT NULL, `char_public` tinyint(1) NOT NULL, PRIMARY KEY (`char_id`))");
|
||||
m_Command.Enqueue(
|
||||
"CREATE TABLE IF NOT EXISTS `myrunuo_characters_layers` ( `char_id` int(10) unsigned NOT NULL, `layer_id` tinyint(3) unsigned NOT NULL, `item_id` smallint(5) unsigned NOT NULL, `item_hue` smallint(5) unsigned NOT NULL, PRIMARY KEY (`char_id`,`layer_id`))");
|
||||
m_Command.Enqueue(
|
||||
"CREATE TABLE IF NOT EXISTS `myrunuo_characters_skills` ( `char_id` int(10) unsigned NOT NULL, `skill_id` tinyint(3) NOT NULL, `skill_value` smallint(5) unsigned NOT NULL, PRIMARY KEY (`char_id`,`skill_id`), KEY `skill_id` (`skill_id`))");
|
||||
m_Command.Enqueue(
|
||||
"CREATE TABLE IF NOT EXISTS `myrunuo_guilds` ( `guild_id` smallint(5) unsigned NOT NULL, `guild_name` varchar(255) NOT NULL, `guild_abbreviation` varchar(8) DEFAULT NULL, `guild_website` varchar(255) DEFAULT NULL, `guild_charter` varchar(255) DEFAULT NULL, `guild_type` varchar(8) NOT NULL, `guild_wars` smallint(5) unsigned NOT NULL, `guild_members` smallint(5) unsigned NOT NULL, `guild_master` int(10) unsigned NOT NULL, PRIMARY KEY (`guild_id`))");
|
||||
m_Command.Enqueue(
|
||||
"CREATE TABLE IF NOT EXISTS `myrunuo_guilds_wars` ( `guild_1` smallint(5) unsigned NOT NULL DEFAULT '0', `guild_2` smallint(5) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`guild_1`,`guild_2`), KEY `guild1` (`guild_1`), KEY `guild2` (`guild_2`))");
|
||||
m_Command.Enqueue(
|
||||
"CREATE TABLE IF NOT EXISTS `myrunuo_status` ( `char_id` int(10) NOT NULL, PRIMARY KEY (`char_id`))");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("MyRunUO: Error creating tables.");
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
|
||||
m_Command?.Enqueue(null);
|
||||
}
|
||||
|
||||
[Usage("UpdateMyRunUO")]
|
||||
[Description("Starts the process of updating the MyRunUO character and guild database.")]
|
||||
public static void UpdateMyRunUO_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (m_Command?.HasCompleted == true)
|
||||
m_Command = null;
|
||||
|
||||
if (m_Timer == null && m_Command == null)
|
||||
{
|
||||
Begin();
|
||||
e.Mobile.SendMessage("MyRunUO update process has been started.");
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage("MyRunUO database is already being updated.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Begin()
|
||||
{
|
||||
if (m_Command?.HasCompleted == true)
|
||||
m_Command = null;
|
||||
|
||||
if (m_Timer != null || m_Command != null)
|
||||
return;
|
||||
|
||||
m_Timer = new MyRunUO();
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
bool shouldExit;
|
||||
|
||||
try
|
||||
{
|
||||
shouldExit = Process(DateTime.UtcNow + TimeSpan.FromSeconds(CpuInterval * CpuPercent));
|
||||
|
||||
if (shouldExit)
|
||||
Console.WriteLine("MyRunUO: Database statements compiled in {0:F2} seconds",
|
||||
(DateTime.UtcNow - m_StartTime).TotalSeconds);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("MyRunUO: {0}: Exception cought while processing", m_Stage);
|
||||
Console.WriteLine(e);
|
||||
shouldExit = true;
|
||||
}
|
||||
|
||||
if (shouldExit)
|
||||
{
|
||||
m_Command.Enqueue(null);
|
||||
|
||||
Stop();
|
||||
m_Timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Process(DateTime endTime)
|
||||
{
|
||||
switch (m_Stage)
|
||||
{
|
||||
case Stage.CollectingMobiles:
|
||||
CollectMobiles(endTime);
|
||||
break;
|
||||
case Stage.DumpingMobiles:
|
||||
DumpMobiles(endTime);
|
||||
break;
|
||||
case Stage.CollectingGuilds:
|
||||
CollectGuilds(endTime);
|
||||
break;
|
||||
case Stage.DumpingGuilds:
|
||||
DumpGuilds(endTime);
|
||||
break;
|
||||
}
|
||||
|
||||
return m_Stage == Stage.Complete;
|
||||
}
|
||||
|
||||
public static void QueueMobileUpdate(Mobile m)
|
||||
{
|
||||
if (!Config.Enabled || Config.LoadDataInFile)
|
||||
return;
|
||||
|
||||
m_MobilesToUpdate.Add(m);
|
||||
}
|
||||
|
||||
public void CollectMobiles(DateTime endTime)
|
||||
{
|
||||
if (Config.LoadDataInFile)
|
||||
{
|
||||
if (m_Index == 0)
|
||||
m_Collecting.AddRange(Accounts.GetAccounts());
|
||||
|
||||
for (int i = m_Index; i < m_Collecting.Count; ++i)
|
||||
{
|
||||
IAccount acct = m_Collecting[i];
|
||||
|
||||
for (int j = 0; j < acct.Length; ++j)
|
||||
{
|
||||
Mobile mob = acct[j];
|
||||
|
||||
if (mob?.AccessLevel < Config.HiddenAccessLevel)
|
||||
m_List.Add(mob);
|
||||
}
|
||||
|
||||
++m_Index;
|
||||
|
||||
if (DateTime.UtcNow >= endTime)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_Index == m_Collecting.Count)
|
||||
{
|
||||
m_Collecting = new List<IAccount>();
|
||||
m_Stage = Stage.DumpingMobiles;
|
||||
m_Index = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_List = new ArrayList(m_MobilesToUpdate);
|
||||
m_MobilesToUpdate = new List<Mobile>();
|
||||
m_Stage = Stage.DumpingMobiles;
|
||||
m_Index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckConnection()
|
||||
{
|
||||
if (m_Command == null)
|
||||
{
|
||||
m_Command = new DatabaseCommandQueue("MyRunUO: Character database updated in {0:F1} seconds",
|
||||
"MyRunUO Character Database Thread");
|
||||
|
||||
if (Config.LoadDataInFile)
|
||||
{
|
||||
m_OpSkills = GetUniqueWriter("skills", out m_SkillsPath);
|
||||
m_OpLayers = GetUniqueWriter("layers", out m_LayersPath);
|
||||
m_OpMobiles = GetUniqueWriter("mobiles", out m_MobilesPath);
|
||||
|
||||
m_Command.Enqueue("TRUNCATE TABLE myrunuo_characters");
|
||||
m_Command.Enqueue("TRUNCATE TABLE myrunuo_characters_layers");
|
||||
m_Command.Enqueue("TRUNCATE TABLE myrunuo_characters_skills");
|
||||
}
|
||||
|
||||
m_Command.Enqueue("TRUNCATE TABLE myrunuo_guilds");
|
||||
m_Command.Enqueue("TRUNCATE TABLE myrunuo_guilds_wars");
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteNonQuery(string text)
|
||||
{
|
||||
m_Command.Enqueue(text);
|
||||
}
|
||||
|
||||
public void ExecuteNonQuery(string format, params object[] args)
|
||||
{
|
||||
ExecuteNonQuery(string.Format(format, args));
|
||||
}
|
||||
|
||||
public void ExecuteNonQueryIfNull(string select, string insert)
|
||||
{
|
||||
m_Command.Enqueue(new[] { select, insert });
|
||||
}
|
||||
|
||||
private void AppendCharEntity(string input, int charIndex, ref StringBuilder sb, char c)
|
||||
{
|
||||
if (sb == null)
|
||||
{
|
||||
sb = charIndex > 0 ? new StringBuilder(input, 0, charIndex, input.Length + 20) : new StringBuilder(input.Length + 20);
|
||||
}
|
||||
|
||||
sb.Append("&#");
|
||||
sb.Append((int)c);
|
||||
sb.Append(";");
|
||||
}
|
||||
|
||||
private void AppendEntityRef(string input, int charIndex, ref StringBuilder sb, string ent)
|
||||
{
|
||||
if (sb == null)
|
||||
{
|
||||
sb = charIndex > 0 ? new StringBuilder(input, 0, charIndex, input.Length + 20) : new StringBuilder(input.Length + 20);
|
||||
}
|
||||
|
||||
sb.Append(ent);
|
||||
}
|
||||
|
||||
private string SafeString(string input)
|
||||
{
|
||||
if (input == null)
|
||||
return "";
|
||||
|
||||
StringBuilder sb = null;
|
||||
|
||||
for (int i = 0; i < input.Length; ++i)
|
||||
{
|
||||
char c = input[i];
|
||||
|
||||
if (c < 0x20 || c >= 0x7F)
|
||||
AppendCharEntity(input, i, ref sb, c);
|
||||
else
|
||||
switch (c)
|
||||
{
|
||||
case '&':
|
||||
AppendEntityRef(input, i, ref sb, "&");
|
||||
break;
|
||||
case '>':
|
||||
AppendEntityRef(input, i, ref sb, ">");
|
||||
break;
|
||||
case '<':
|
||||
AppendEntityRef(input, i, ref sb, "<");
|
||||
break;
|
||||
case '"':
|
||||
AppendEntityRef(input, i, ref sb, """);
|
||||
break;
|
||||
case '\'':
|
||||
case ':':
|
||||
case '/':
|
||||
case '\\':
|
||||
AppendCharEntity(input, i, ref sb, c);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
sb?.Append(c);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sb != null ? sb.ToString() : input;
|
||||
}
|
||||
|
||||
public void InsertMobile(Mobile mob)
|
||||
{
|
||||
string guildTitle = mob.GuildTitle;
|
||||
|
||||
if (guildTitle == null || (guildTitle = guildTitle.Trim()).Length == 0)
|
||||
guildTitle = "NULL";
|
||||
else
|
||||
guildTitle = SafeString(guildTitle);
|
||||
|
||||
string notoTitle = SafeString(Titles.ComputeTitle(null, mob));
|
||||
string female = mob.Female ? "1" : "0";
|
||||
|
||||
bool pubBool = mob is PlayerMobile mobile && mobile.PublicMyRunUO;
|
||||
|
||||
string pubString = pubBool ? "1" : "0";
|
||||
|
||||
string guildId = mob.Guild == null ? "NULL" : mob.Guild.Id.ToString();
|
||||
|
||||
if (Config.LoadDataInFile)
|
||||
{
|
||||
m_OpMobiles.Write(LineStart);
|
||||
m_OpMobiles.Write(mob.Serial.Value);
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(SafeString(mob.Name));
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(mob.RawStr);
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(mob.RawDex);
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(mob.RawInt);
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(female);
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(mob.Kills);
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(guildId);
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(guildTitle);
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(notoTitle);
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(mob.Hue);
|
||||
m_OpMobiles.Write(EntrySep);
|
||||
m_OpMobiles.Write(pubString);
|
||||
m_OpMobiles.Write(LineEnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExecuteNonQuery(
|
||||
"INSERT INTO myrunuo_characters (char_id, char_name, char_str, char_dex, char_int, char_female, char_counts, char_guild, char_guildtitle, char_nototitle, char_bodyhue, char_public ) VALUES ({0}, '{1}', {2}, {3}, {4}, {5}, {6}, {7}, {8}, '{9}', {10}, {11})",
|
||||
mob.Serial.Value.ToString(), SafeString(mob.Name), mob.RawStr.ToString(), mob.RawDex.ToString(),
|
||||
mob.RawInt.ToString(), female, mob.Kills.ToString(), guildId, guildTitle, notoTitle, mob.Hue.ToString(),
|
||||
pubString);
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertSkills(Mobile mob)
|
||||
{
|
||||
Skills skills = mob.Skills;
|
||||
string serial = mob.Serial.Value.ToString();
|
||||
|
||||
for (int i = 0; i < skills.Length; ++i)
|
||||
{
|
||||
Skill skill = skills[i];
|
||||
|
||||
if (skill.BaseFixedPoint > 0)
|
||||
{
|
||||
if (Config.LoadDataInFile)
|
||||
{
|
||||
m_OpSkills.Write(LineStart);
|
||||
m_OpSkills.Write(serial);
|
||||
m_OpSkills.Write(EntrySep);
|
||||
m_OpSkills.Write(i);
|
||||
m_OpSkills.Write(EntrySep);
|
||||
m_OpSkills.Write(skill.BaseFixedPoint);
|
||||
m_OpSkills.Write(LineEnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExecuteNonQuery(
|
||||
"INSERT INTO myrunuo_characters_skills (char_id, skill_id, skill_value) VALUES ({0}, {1}, {2})",
|
||||
serial, i.ToString(), skill.BaseFixedPoint.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InsertItem(string serial, int index, int itemID, int hue)
|
||||
{
|
||||
if (Config.LoadDataInFile)
|
||||
{
|
||||
m_OpLayers.Write(LineStart);
|
||||
m_OpLayers.Write(serial);
|
||||
m_OpLayers.Write(EntrySep);
|
||||
m_OpLayers.Write(index);
|
||||
m_OpLayers.Write(EntrySep);
|
||||
m_OpLayers.Write(itemID);
|
||||
m_OpLayers.Write(EntrySep);
|
||||
m_OpLayers.Write(hue);
|
||||
m_OpLayers.Write(LineEnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
ExecuteNonQuery(
|
||||
"INSERT INTO myrunuo_characters_layers (char_id, layer_id, item_id, item_hue) VALUES ({0}, {1}, {2}, {3})",
|
||||
serial, index.ToString(), itemID.ToString(), hue.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertItems(Mobile mob)
|
||||
{
|
||||
List<Item> items = m_Items;
|
||||
items.AddRange(mob.Items);
|
||||
string serial = mob.Serial.Value.ToString();
|
||||
|
||||
items.Sort(LayerComparer.Instance);
|
||||
|
||||
int index = 0;
|
||||
|
||||
bool hidePants = false;
|
||||
bool alive = mob.Alive;
|
||||
bool hideHair = !alive;
|
||||
|
||||
for (int i = 0; i < items.Count; ++i)
|
||||
{
|
||||
Item item = items[i];
|
||||
|
||||
if (!LayerComparer.IsValid(item))
|
||||
break;
|
||||
|
||||
if (!alive && item.ItemID != 8270)
|
||||
continue;
|
||||
|
||||
if (item.ItemID == 0x1411 || item.ItemID == 0x141A) // plate legs
|
||||
hidePants = true;
|
||||
else if (hidePants && item.Layer == Layer.Pants)
|
||||
continue;
|
||||
|
||||
if (!hideHair && item.Layer == Layer.Helm)
|
||||
hideHair = true;
|
||||
|
||||
InsertItem(serial, index++, item.ItemID, item.Hue);
|
||||
}
|
||||
|
||||
if (mob.FacialHairItemID != 0 && alive)
|
||||
InsertItem(serial, index++, mob.FacialHairItemID, mob.FacialHairHue);
|
||||
|
||||
if (mob.HairItemID != 0 && !hideHair)
|
||||
InsertItem(serial, index, mob.HairItemID, mob.HairHue);
|
||||
|
||||
items.Clear();
|
||||
}
|
||||
|
||||
public void DeleteMobile(Mobile mob)
|
||||
{
|
||||
ExecuteNonQuery("DELETE FROM myrunuo_characters WHERE char_id = {0}", mob.Serial.Value.ToString());
|
||||
ExecuteNonQuery("DELETE FROM myrunuo_characters_skills WHERE char_id = {0}", mob.Serial.Value.ToString());
|
||||
ExecuteNonQuery("DELETE FROM myrunuo_characters_layers WHERE char_id = {0}", mob.Serial.Value.ToString());
|
||||
}
|
||||
|
||||
public StreamWriter GetUniqueWriter(string type, out string filePath)
|
||||
{
|
||||
filePath = Path.Combine(Core.BaseDirectory, $"myrunuodb_{type}.txt")
|
||||
.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||
|
||||
try
|
||||
{
|
||||
return new StreamWriter(filePath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
for (int i = 0; i < 100; ++i)
|
||||
try
|
||||
{
|
||||
filePath = Path.Combine(Core.BaseDirectory, $"myrunuodb_{type}_{i}.txt")
|
||||
.Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
|
||||
return new StreamWriter(filePath);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void DumpMobiles(DateTime endTime)
|
||||
{
|
||||
CheckConnection();
|
||||
|
||||
for (int i = m_Index; i < m_List.Count; ++i)
|
||||
{
|
||||
Mobile mob = (Mobile)m_List[i];
|
||||
|
||||
if (mob is PlayerMobile mobile)
|
||||
mobile.ChangedMyRunUO = false;
|
||||
|
||||
if (!mob.Deleted && mob.AccessLevel < Config.HiddenAccessLevel)
|
||||
{
|
||||
if (!Config.LoadDataInFile)
|
||||
DeleteMobile(mob);
|
||||
|
||||
InsertMobile(mob);
|
||||
InsertSkills(mob);
|
||||
InsertItems(mob);
|
||||
}
|
||||
else if (!Config.LoadDataInFile)
|
||||
{
|
||||
DeleteMobile(mob);
|
||||
}
|
||||
|
||||
++m_Index;
|
||||
|
||||
if (DateTime.UtcNow >= endTime)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_Index == m_List.Count)
|
||||
{
|
||||
m_List.Clear();
|
||||
m_Stage = Stage.CollectingGuilds;
|
||||
m_Index = 0;
|
||||
|
||||
if (Config.LoadDataInFile)
|
||||
{
|
||||
m_OpSkills.Close();
|
||||
m_OpLayers.Close();
|
||||
m_OpMobiles.Close();
|
||||
|
||||
ExecuteNonQuery(
|
||||
"LOAD DATA {0}INFILE '{1}' INTO TABLE myrunuo_characters FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n'",
|
||||
Config.DatabaseNonLocal ? "LOCAL " : "", m_MobilesPath);
|
||||
ExecuteNonQuery(
|
||||
"LOAD DATA {0}INFILE '{1}' INTO TABLE myrunuo_characters_skills FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n'",
|
||||
Config.DatabaseNonLocal ? "LOCAL " : "", m_SkillsPath);
|
||||
ExecuteNonQuery(
|
||||
"LOAD DATA {0}INFILE '{1}' INTO TABLE myrunuo_characters_layers FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n'",
|
||||
Config.DatabaseNonLocal ? "LOCAL " : "", m_LayersPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CollectGuilds(DateTime endTime)
|
||||
{
|
||||
m_List.AddRange(BaseGuild.List.Values);
|
||||
m_Stage = Stage.DumpingGuilds;
|
||||
m_Index = 0;
|
||||
}
|
||||
|
||||
public void InsertGuild(Guild guild)
|
||||
{
|
||||
string guildType = "Standard";
|
||||
|
||||
switch (guild.Type)
|
||||
{
|
||||
case GuildType.Chaos:
|
||||
guildType = "Chaos";
|
||||
break;
|
||||
case GuildType.Order:
|
||||
guildType = "Order";
|
||||
break;
|
||||
}
|
||||
|
||||
ExecuteNonQuery(
|
||||
"INSERT INTO myrunuo_guilds (guild_id, guild_name, guild_abbreviation, guild_website, guild_charter, guild_type, guild_wars, guild_members, guild_master) VALUES ({0}, '{1}', {2}, {3}, {4}, '{5}', {6}, {7}, {8})",
|
||||
guild.Id.ToString(), SafeString(guild.Name),
|
||||
guild.Abbreviation == "none" ? "NULL" : "'" + SafeString(guild.Abbreviation) + "'",
|
||||
guild.Website == null ? "NULL" : "'" + SafeString(guild.Website) + "'",
|
||||
guild.Charter == null ? "NULL" : "'" + SafeString(guild.Charter) + "'", guildType,
|
||||
guild.Enemies.Count.ToString(), guild.Members.Count.ToString(), guild.Leader.Serial.Value.ToString());
|
||||
}
|
||||
|
||||
public void InsertWars(Guild guild)
|
||||
{
|
||||
List<Guild> wars = guild.Enemies;
|
||||
|
||||
string ourId = guild.Id.ToString();
|
||||
|
||||
for (int i = 0; i < wars.Count; ++i)
|
||||
{
|
||||
Guild them = wars[i];
|
||||
string theirId = them.Id.ToString();
|
||||
|
||||
ExecuteNonQueryIfNull(
|
||||
string.Format(
|
||||
"SELECT guild_1 FROM myrunuo_guilds_wars WHERE (guild_1={0} AND guild_2={1}) OR (guild_1={1} AND guild_2={0})",
|
||||
ourId, theirId),
|
||||
$"INSERT INTO myrunuo_guilds_wars (guild_1, guild_2) VALUES ({ourId}, {theirId})");
|
||||
}
|
||||
}
|
||||
|
||||
public void DumpGuilds(DateTime endTime)
|
||||
{
|
||||
CheckConnection();
|
||||
|
||||
for (int i = m_Index; i < m_List.Count; ++i)
|
||||
{
|
||||
Guild guild = (Guild)m_List[i];
|
||||
|
||||
if (!guild.Disbanded)
|
||||
{
|
||||
InsertGuild(guild);
|
||||
InsertWars(guild);
|
||||
}
|
||||
|
||||
++m_Index;
|
||||
|
||||
if (DateTime.UtcNow >= endTime)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_Index == m_List.Count)
|
||||
{
|
||||
m_List.Clear();
|
||||
m_Stage = Stage.Complete;
|
||||
m_Index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private enum Stage
|
||||
{
|
||||
CollectingMobiles,
|
||||
DumpingMobiles,
|
||||
CollectingGuilds,
|
||||
DumpingGuilds,
|
||||
Complete
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,72 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Commands;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Engines.MyRunUO
|
||||
{
|
||||
public class MyRunUOStatus
|
||||
{
|
||||
private static DatabaseCommandQueue m_Command;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (Config.Enabled)
|
||||
{
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(20.0), Config.StatusUpdateInterval, Begin);
|
||||
|
||||
CommandSystem.Register("UpdateWebStatus", AccessLevel.Administrator, UpdateWebStatus_OnCommand);
|
||||
}
|
||||
}
|
||||
|
||||
[Usage("UpdateWebStatus")]
|
||||
[Description("Starts the process of updating the MyRunUO online status database.")]
|
||||
public static void UpdateWebStatus_OnCommand(CommandEventArgs e)
|
||||
{
|
||||
if (m_Command == null || m_Command.HasCompleted)
|
||||
{
|
||||
Begin();
|
||||
e.Mobile.SendMessage("Web status update process has been started.");
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage("Web status database is already being updated.");
|
||||
}
|
||||
}
|
||||
|
||||
public static void Begin()
|
||||
{
|
||||
if (m_Command?.HasCompleted == false)
|
||||
return;
|
||||
|
||||
Console.WriteLine("MyRunUO: Updating status database");
|
||||
|
||||
try
|
||||
{
|
||||
m_Command = new DatabaseCommandQueue("MyRunUO: Status database updated in {0:F1} seconds",
|
||||
"MyRunUO Status Database Thread");
|
||||
|
||||
m_Command.Enqueue("DELETE FROM myrunuo_status");
|
||||
|
||||
List<NetState> online = NetState.Instances;
|
||||
|
||||
for (int i = 0; i < online.Count; ++i)
|
||||
{
|
||||
NetState ns = online[i];
|
||||
Mobile mob = ns.Mobile;
|
||||
|
||||
if (mob != null)
|
||||
m_Command.Enqueue(
|
||||
$"INSERT INTO myrunuo_status (char_id) VALUES ({mob.Serial.Value.ToString()})");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("MyRunUO: Error updating status database");
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
|
||||
m_Command?.Enqueue(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue