From dbd62e5c6fd74618737ce6c81641445cd27347d4 Mon Sep 17 00:00:00 2001 From: hondacrx Date: Tue, 22 May 2018 11:05:16 -0400 Subject: [PATCH] Core/DB: Some DB improvements --- Source/Framework/Database/DatabaseWorker.cs | 62 ++++++ Source/Framework/Database/MySqlBase.cs | 203 ++++++------------ .../Framework/Database/PreparedStatement.cs | 40 +++- Source/Framework/Database/SQLQueryHolder.cs | 59 +++-- Source/Framework/Database/SQLResult.cs | 80 ++++--- Source/Framework/Database/SQLTransaction.cs | 15 ++ Source/Framework/Realm/RealmManager.cs | 3 +- Source/Game/Accounts/AccountManager.cs | 15 +- Source/Game/Accounts/BNetAccountManager.cs | 4 +- .../Game/Achievements/AchievementManager.cs | 9 +- Source/Game/Arenas/ArenaTeamManager.cs | 3 +- Source/Game/BlackMarket/BlackMarketEntry.cs | 9 +- Source/Game/Chat/CommandHandler.cs | 2 +- Source/Game/Chat/Commands/NPCCommands.cs | 9 +- Source/Game/Conditions/DisableManager.cs | 1 - .../DataStorage/ClientReader/GameTables.cs | 2 +- Source/Game/Entities/Item/Item.cs | 31 ++- Source/Game/Globals/ObjectManager.cs | 26 ++- Source/Game/Groups/GroupManager.cs | 11 +- Source/Game/Guilds/GuildManager.cs | 18 +- .../Maps/Instances/InstanceSaveManager.cs | 32 +-- Source/Game/Tools/CharacterDatabaseCleaner.cs | 8 +- Source/WorldServer/Server.cs | 12 +- 23 files changed, 360 insertions(+), 294 deletions(-) create mode 100644 Source/Framework/Database/DatabaseWorker.cs diff --git a/Source/Framework/Database/DatabaseWorker.cs b/Source/Framework/Database/DatabaseWorker.cs new file mode 100644 index 000000000..036f0161c --- /dev/null +++ b/Source/Framework/Database/DatabaseWorker.cs @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2012-2018 CypherCore + * + * 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 . + */ + +using Framework.Threading; +using System.Threading; + +namespace Framework.Database +{ + public interface ISqlOperation + { + bool Execute(MySqlBase mySqlBase); + } + + class DatabaseWorker + { + Thread _workerThread; + volatile bool _cancelationToken; + ProducerConsumerQueue _queue; + MySqlBase _mySqlBase; + + public DatabaseWorker(ProducerConsumerQueue newQueue, MySqlBase mySqlBase) + { + _queue = newQueue; + _mySqlBase = mySqlBase; + _cancelationToken = false; + _workerThread = new Thread(WorkerThread); + _workerThread.Start(); + } + + void WorkerThread() + { + if (_queue == null) + return; + + for (; ; ) + { + ISqlOperation operation; + + _queue.WaitAndPop(out operation); + + if (_cancelationToken || operation == null) + return; + + operation.Execute(_mySqlBase); + } + } + } +} diff --git a/Source/Framework/Database/MySqlBase.cs b/Source/Framework/Database/MySqlBase.cs index f00004720..6cddbc943 100644 --- a/Source/Framework/Database/MySqlBase.cs +++ b/Source/Framework/Database/MySqlBase.cs @@ -15,6 +15,7 @@ * along with this program. If not, see . */ +using Framework.Threading; using MySql.Data.MySqlClient; using System; using System.Collections.Generic; @@ -27,19 +28,14 @@ namespace Framework.Database { public class MySqlConnectionInfo { - public MySqlConnectionInfo(int poolSize = 10) - { - Poolsize = poolSize; - } - public MySqlConnection GetConnection() { - return new MySqlConnection($"Server={Host};Port={Port};User Id={Username};Password={Password};Database={Database};Allow Zero Datetime=True;Allow User Variables=True;Pooling=true;MaximumPoolSize={Poolsize};"); + return new MySqlConnection($"Server={Host};Port={Port};User Id={Username};Password={Password};Database={Database};Allow User Variables=True;Pooling=true;"); } public MySqlConnection GetConnectionNoDatabase() { - return new MySqlConnection($"Server={Host};Port={Port};User Id={Username};Password={Password};Allow Zero Datetime=True;Allow User Variables=True;Pooling=true;MaximumPoolSize={Poolsize};"); + return new MySqlConnection($"Server={Host};Port={Port};User Id={Username};Password={Password};Allow User Variables=True;Pooling=true;"); } public string Host; @@ -52,10 +48,18 @@ namespace Framework.Database public abstract class MySqlBase { + Dictionary _preparedQueries = new Dictionary(); + ProducerConsumerQueue _queue = new ProducerConsumerQueue(); + + MySqlConnectionInfo _connectionInfo; + DatabaseUpdater _updater; + DatabaseWorker _worker; + public MySqlErrorCode Initialize(MySqlConnectionInfo connectionInfo) { _connectionInfo = connectionInfo; _updater = new DatabaseUpdater(this); + _worker = new DatabaseWorker(_queue, this); try { @@ -67,16 +71,17 @@ namespace Framework.Database } } catch (MySqlException ex) - { + { return HandleMySQLException(ex); } } - public void Execute(string sql, params object[] args) + public bool DirectExecute(string sql, params object[] args) { - Execute(new PreparedStatement(string.Format(sql, args))); + return DirectExecute(new PreparedStatement(string.Format(sql, args))); } - public void Execute(PreparedStatement stmt) + + public bool DirectExecute(PreparedStatement stmt) { try { @@ -90,15 +95,28 @@ namespace Framework.Database cmd.Parameters.AddWithValue("@" + parameter.Key, parameter.Value); cmd.ExecuteNonQuery(); + return true; } } } catch (MySqlException ex) { HandleMySQLException(ex, stmt.CommandText); + return false; } } + public void Execute(string sql, params object[] args) + { + Execute(new PreparedStatement(string.Format(sql, args))); + } + + public void Execute(PreparedStatement stmt) + { + PreparedStatementTask task = new PreparedStatementTask(stmt); + _queue.Push(task); + } + public void ExecuteOrAppend(SQLTransaction trans, PreparedStatement stmt) { if (trans == null) @@ -114,141 +132,41 @@ namespace Framework.Database public SQLResult Query(PreparedStatement stmt) { - List rows = new List(); try { - using (var Connection = _connectionInfo.GetConnection()) - { - Connection.Open(); - using (MySqlCommand cmd = Connection.CreateCommand()) - { + MySqlConnection Connection = _connectionInfo.GetConnection(); + Connection.Open(); - cmd.CommandText = stmt.CommandText; - foreach (var parameter in stmt.Parameters) - cmd.Parameters.AddWithValue("@" + parameter.Key, parameter.Value); + MySqlCommand cmd = Connection.CreateCommand(); + cmd.CommandText = stmt.CommandText; + foreach (var parameter in stmt.Parameters) + cmd.Parameters.AddWithValue("@" + parameter.Key, parameter.Value); - using (var reader = cmd.ExecuteReader()) - { - if (reader.HasRows) - { - while(reader.Read()) - { - var row = new object[reader.FieldCount]; - reader.GetValues(row); - rows.Add(row); - } - } - } - } - - } + return new SQLResult(cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection)); } catch (MySqlException ex) { HandleMySQLException(ex, stmt.CommandText); + return new SQLResult(); } - - return new SQLResult(rows); - } - - public QueryCallback AsyncQuery(string sql, params object[] args) - { - return AsyncQuery(new PreparedStatement(string.Format(sql, args))); } public QueryCallback AsyncQuery(PreparedStatement stmt) { - return new QueryCallback(_AsyncQuery(stmt)); + PreparedStatementTask task = new PreparedStatementTask(stmt, true); + // Store future result before enqueueing - task might get already processed and deleted before returning from this method + Task result = task.GetFuture(); + _queue.Push(task); + return new QueryCallback(result); } - async Task _AsyncQuery(PreparedStatement stmt) + public Task> DelayQueryHolder(SQLQueryHolder holder) { - List rows = new List(); - - try - { - using (var Connection = _connectionInfo.GetConnection()) - { - await Connection.OpenAsync(); - using (MySqlCommand cmd = Connection.CreateCommand()) - { - cmd.CommandText = stmt.CommandText; - foreach (var parameter in stmt.Parameters) - cmd.Parameters.AddWithValue("@" + parameter.Key, parameter.Value); - - using (var reader = await cmd.ExecuteReaderAsync()) - { - if (reader.HasRows) - { - while (await reader.ReadAsync()) - { - var row = new object[reader.FieldCount]; - - reader.GetValues(row); - rows.Add(row); - } - } - } - } - } - } - catch (MySqlException ex) - { - HandleMySQLException(ex, stmt.CommandText); - } - - return new SQLResult(rows); - } - - public async Task> DelayQueryHolder(SQLQueryHolder holder) - { - return await Task.Run(() => - { - string query = ""; - - try - { - using (var Connection = _connectionInfo.GetConnection()) - { - Connection.OpenAsync(); - - foreach (var pair in holder.m_queries) - { - List rows = new List(); - using (MySqlCommand cmd = Connection.CreateCommand()) - { - cmd.CommandText = pair.Value.stmt.CommandText; - foreach (var parameter in pair.Value.stmt.Parameters) - cmd.Parameters.AddWithValue("@" + parameter.Key, parameter.Value); - - query = cmd.CommandText; - using (var reader = cmd.ExecuteReader()) - { - if (reader.HasRows) - { - while (reader.Read()) - { - var row = new object[reader.FieldCount]; - - reader.GetValues(row); - rows.Add(row); - } - } - } - } - - holder.SetResult(pair.Key, new SQLResult(rows)); - } - } - - return holder; - } - catch (MySqlException ex) - { - HandleMySQLException(ex, query); - return holder; - } - }); + SQLQueryHolderTask task = new SQLQueryHolderTask(holder); + // Store future result before enqueueing - task might get already processed and deleted before returning from this method + Task> result = task.GetFuture(); + _queue.Push(task); + return result; } public void LoadPreparedStatements() @@ -268,12 +186,12 @@ namespace Framework.Database sb.Append(sql[i]); } - _queries[statement] = sb.ToString(); + _preparedQueries[statement] = sb.ToString(); } public PreparedStatement GetPreparedStatement(T statement) { - return new PreparedStatement(_queries[statement]); + return new PreparedStatement(_preparedQueries[statement]); } public bool Apply(string sql) @@ -282,9 +200,9 @@ namespace Framework.Database { using (var Connection = _connectionInfo.GetConnectionNoDatabase()) { + Connection.Open(); using (MySqlCommand cmd = Connection.CreateCommand()) { - Connection.Open(); cmd.CommandText = sql; cmd.ExecuteNonQuery(); return true; @@ -302,12 +220,16 @@ namespace Framework.Database { try { + string query = File.ReadAllText(path); + if (query.Length > 1048576) //Default size limit of querys + Apply("SET GLOBAL max_allowed_packet=1073741824;"); + using (var connection = _connectionInfo.GetConnection()) { + connection.Open(); using (MySqlCommand cmd = connection.CreateCommand()) { - connection.Open(); - cmd.CommandText = File.ReadAllText(path); + cmd.CommandText = query; cmd.ExecuteNonQuery(); return true; } @@ -326,6 +248,11 @@ namespace Framework.Database } public void CommitTransaction(SQLTransaction transaction) + { + _queue.Push(new TransactionTask(transaction)); + } + + public bool DirectCommitTransaction(SQLTransaction transaction) { using (var Connection = _connectionInfo.GetConnection()) { @@ -349,11 +276,13 @@ namespace Framework.Database trans.Commit(); scope.Complete(); } + return true; } catch (MySqlException ex) //error occurred { HandleMySQLException(ex, query); trans.Rollback(); + return false; } } } @@ -407,9 +336,5 @@ namespace Framework.Database } public abstract void PreparedStatements(); - - Dictionary _queries = new Dictionary(); - MySqlConnectionInfo _connectionInfo; - DatabaseUpdater _updater; } } diff --git a/Source/Framework/Database/PreparedStatement.cs b/Source/Framework/Database/PreparedStatement.cs index 6c5d6f615..9c9dedb71 100644 --- a/Source/Framework/Database/PreparedStatement.cs +++ b/Source/Framework/Database/PreparedStatement.cs @@ -16,11 +16,15 @@ */ using System.Collections.Generic; +using System.Threading.Tasks; namespace Framework.Database { public class PreparedStatement { + public string CommandText; + public Dictionary Parameters = new Dictionary(); + public PreparedStatement(string commandText) { CommandText = commandText; @@ -35,8 +39,40 @@ namespace Framework.Database { Parameters.Clear(); } + } - public string CommandText; - public Dictionary Parameters = new Dictionary(); + public class PreparedStatementTask : ISqlOperation + { + PreparedStatement m_stmt; + bool _needsResult; + TaskCompletionSource m_result; + + public PreparedStatementTask(PreparedStatement stmt, bool needsResult = false) + { + m_stmt = stmt; + _needsResult = needsResult; + if (needsResult) + m_result = new TaskCompletionSource(); + } + + public bool Execute(MySqlBase mySqlBase) + { + if (_needsResult) + { + SQLResult result = mySqlBase.Query(m_stmt); + if (result == null) + { + m_result.SetResult(new SQLResult()); + return false; + } + + m_result.SetResult(result); + return true; + } + + return mySqlBase.DirectExecute(m_stmt); + } + + public Task GetFuture() { return m_result.Task; } } } diff --git a/Source/Framework/Database/SQLQueryHolder.cs b/Source/Framework/Database/SQLQueryHolder.cs index 0850311bd..d656920fd 100644 --- a/Source/Framework/Database/SQLQueryHolder.cs +++ b/Source/Framework/Database/SQLQueryHolder.cs @@ -16,45 +16,62 @@ */ using System.Collections.Generic; +using System.Threading.Tasks; namespace Framework.Database { public class SQLQueryHolder { - public void SetQuery(T index, PreparedStatement _stmt) - { - m_queries[index] = new SQLResultPair(_stmt); - } + public Dictionary m_queries = new Dictionary(); + Dictionary _results = new Dictionary(); public void SetQuery(T index, string sql, params object[] args) { SetQuery(index, new PreparedStatement(string.Format(sql, args))); } - public void SetResult(T index, SQLResult _result) + public void SetQuery(T index, PreparedStatement stmt) { - m_queries[index].result = _result; + m_queries[index] = stmt; + } + + public void SetResult(T index, SQLResult result) + { + _results[index] = result; } public SQLResult GetResult(T index) { - if (!m_queries.ContainsKey(index)) + if (!_results.ContainsKey(index)) return new SQLResult(); - return m_queries[index].result; - } - - public Dictionary m_queries = new Dictionary(); - - public class SQLResultPair - { - public SQLResultPair(PreparedStatement _stmt) - { - stmt = _stmt; - } - - public PreparedStatement stmt; - public SQLResult result; + return _results[index]; } } + + class SQLQueryHolderTask : ISqlOperation + { + SQLQueryHolder m_holder; + TaskCompletionSource> m_result; + + public SQLQueryHolderTask(SQLQueryHolder holder) + { + m_holder = holder; + m_result = new TaskCompletionSource>(); + } + + public bool Execute(MySqlBase mySqlBase) + { + if (m_holder == null) + return false; + + // execute all queries in the holder and pass the results + foreach (var pair in m_holder.m_queries) + m_holder.SetResult(pair.Key, mySqlBase.Query(pair.Value)); + + return m_result.TrySetResult(m_holder); + } + + public Task> GetFuture() { return m_result.Task; } + } } diff --git a/Source/Framework/Database/SQLResult.cs b/Source/Framework/Database/SQLResult.cs index 629958593..64657acaa 100644 --- a/Source/Framework/Database/SQLResult.cs +++ b/Source/Framework/Database/SQLResult.cs @@ -15,81 +15,77 @@ * along with this program. If not, see . */ +using MySql.Data.MySqlClient; using System; -using System.Collections.Generic; namespace Framework.Database { public class SQLResult { - public SQLResult() + MySqlDataReader _reader; + + public SQLResult() { } + + public SQLResult(MySqlDataReader reader) { - _rows = new List(); + _reader = reader; + NextRow(); } - public SQLResult(List values) + + ~SQLResult() { - _rows = values; + _reader = null; } public T Read(int column) { - var value = _rows[_rowIndex][column]; + var value = _reader[column]; - if (value.GetType() == typeof(T)) - return (T)value; + if (value == DBNull.Value) + return default(T); - if (value != DBNull.Value) - return (T)Convert.ChangeType(value, typeof(T)); + if (value.GetType() != typeof(T)) + return (T)Convert.ChangeType(value, typeof(T));//todo remove me when all fields are the right type this is super slow - if (typeof(T).Name == "String") - return (T)Convert.ChangeType("", typeof(T)); - - return default(T); - } - - public T[] ReadValues(int startIndex, int numColumns) - { - T[] values = new T[numColumns]; - for (var c = 0; c < numColumns; ++c) - values[c] = Read(startIndex + c); - - return values; + return (T)value; } public bool IsNull(int column) { - return _rows[_rowIndex][column] == DBNull.Value; + return _reader.IsDBNull(column); } - public int GetRowCount() { return _rows.Count; } + public int GetFieldCount() { return _reader.FieldCount; } - public bool IsEmpty() { return GetRowCount() == 0; } + public bool IsEmpty() + { + return _reader == null || !_reader.HasRows; + } - public SQLFields GetFields() { return new SQLFields(_rows[_rowIndex]); } + public SQLFields GetFields() + { + object[] values = new object[_reader.FieldCount]; + _reader.GetValues(values); + return new SQLFields(values); + } public bool NextRow() { - if (_rowIndex >= GetRowCount() - 1) - { - _rowIndex = 0; + if (_reader == null) return false; - } - _rowIndex++; - return true; + if (_reader.Read()) + return true; + + _reader.Close(); + return false; } - - public void ResetRowIndex() - { - _rowIndex = 0; - } - - private int _rowIndex; - List _rows; } public class SQLFields { + object[] _currentRow; + public SQLFields(object[] row) { _currentRow = row; } public T Read(int column) @@ -116,7 +112,5 @@ namespace Framework.Database return values; } - - object[] _currentRow; } } diff --git a/Source/Framework/Database/SQLTransaction.cs b/Source/Framework/Database/SQLTransaction.cs index e52cc817c..777819ed0 100644 --- a/Source/Framework/Database/SQLTransaction.cs +++ b/Source/Framework/Database/SQLTransaction.cs @@ -43,4 +43,19 @@ namespace Framework.Database commands.Add(new MySqlCommand(string.Format(sql, args))); } } + + class TransactionTask : ISqlOperation + { + public TransactionTask(SQLTransaction trans) + { + m_trans = trans; + } + + public bool Execute(MySqlBase mySqlBase) + { + return mySqlBase.DirectCommitTransaction(m_trans); + } + + SQLTransaction m_trans; + } } diff --git a/Source/Framework/Realm/RealmManager.cs b/Source/Framework/Realm/RealmManager.cs index 8d9986603..1387c587e 100644 --- a/Source/Framework/Realm/RealmManager.cs +++ b/Source/Framework/Realm/RealmManager.cs @@ -59,7 +59,6 @@ public class RealmManager : Singleton { PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_REALMLIST); SQLResult result = DB.Login.Query(stmt); - Dictionary existingRealms = new Dictionary(); foreach (var p in _realms) existingRealms[p.Key] = p.Value.Name; @@ -285,7 +284,7 @@ public class RealmManager : Singleton stmt.AddValue(2, locale); stmt.AddValue(3, os); stmt.AddValue(4, accountName); - DB.Login.Execute(stmt); + DB.Login.DirectExecute(stmt); Bgs.Protocol.Attribute attribute = new Bgs.Protocol.Attribute(); attribute.Name = "Param_RealmJoinTicket"; diff --git a/Source/Game/Accounts/AccountManager.cs b/Source/Game/Accounts/AccountManager.cs index b0836e187..dff07cfa0 100644 --- a/Source/Game/Accounts/AccountManager.cs +++ b/Source/Game/Accounts/AccountManager.cs @@ -27,7 +27,7 @@ using System.Text; namespace Game { public sealed class AccountManager : Singleton - { + { const int MaxAccountLength = 16; const int MaxEmailLength = 64; @@ -59,7 +59,7 @@ namespace Game stmt.AddValue(4, null); stmt.AddValue(5, null); } - DB.Login.Execute(stmt); // Enforce saving, otherwise AddGroup can fail + DB.Login.DirectExecute(stmt); // Enforce saving, otherwise AddGroup can fail stmt = DB.Login.GetPreparedStatement(LoginStatements.INS_REALM_CHARACTERS_INIT); DB.Login.Execute(stmt); @@ -73,7 +73,6 @@ namespace Game PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_BY_ID); stmt.AddValue(0, accountId); SQLResult result = DB.Login.Query(stmt); - if (result.IsEmpty()) return AccountOpResult.NameNotExist; @@ -81,7 +80,6 @@ namespace Game stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARS_BY_ACCOUNT_ID); stmt.AddValue(0, accountId); result = DB.Characters.Query(stmt); - if (!result.IsEmpty()) { do @@ -147,7 +145,6 @@ namespace Game PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_BY_ID); stmt.AddValue(0, accountId); SQLResult result = DB.Login.Query(stmt); - if (result.IsEmpty()) return AccountOpResult.NameNotExist; @@ -231,7 +228,6 @@ namespace Game PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.GET_ACCOUNT_ID_BY_USERNAME); stmt.AddValue(0, username); SQLResult result = DB.Login.Query(stmt); - return !result.IsEmpty() ? result.Read(0) : 0; } @@ -240,7 +236,6 @@ namespace Game PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.GET_ACCOUNT_ACCESS_GMLEVEL); stmt.AddValue(0, accountId); SQLResult result = DB.Login.Query(stmt); - return !result.IsEmpty() ? (AccountTypes)result.Read(0) : AccountTypes.Player; } @@ -250,7 +245,6 @@ namespace Game stmt.AddValue(0, accountId); stmt.AddValue(1, realmId); SQLResult result = DB.Login.Query(stmt); - return !result.IsEmpty() ? (AccountTypes)result.Read(0) : AccountTypes.Player; } @@ -260,7 +254,6 @@ namespace Game PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.GET_USERNAME_BY_ID); stmt.AddValue(0, accountId); SQLResult result = DB.Login.Query(stmt); - if (!result.IsEmpty()) { name = result.Read(0); @@ -276,7 +269,6 @@ namespace Game PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.GET_EMAIL_BY_ID); stmt.AddValue(0, accountId); SQLResult result = DB.Login.Query(stmt); - if (!result.IsEmpty()) { email = result.Read(0); @@ -297,7 +289,6 @@ namespace Game stmt.AddValue(0, accountId); stmt.AddValue(1, CalculateShaPassHash(username, password)); SQLResult result = DB.Login.Query(stmt); - return result.IsEmpty() ? false : true; } @@ -321,7 +312,6 @@ namespace Game PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_SUM_CHARS); stmt.AddValue(0, accountId); SQLResult result = DB.Characters.Query(stmt); - return result.IsEmpty() ? 0 : (uint)result.Read(0); } @@ -336,7 +326,6 @@ namespace Game PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_BANNED_BY_USERNAME); stmt.AddValue(0, name); SQLResult result = DB.Login.Query(stmt); - return !result.IsEmpty(); } diff --git a/Source/Game/Accounts/BNetAccountManager.cs b/Source/Game/Accounts/BNetAccountManager.cs index 472684519..748616194 100644 --- a/Source/Game/Accounts/BNetAccountManager.cs +++ b/Source/Game/Accounts/BNetAccountManager.cs @@ -43,7 +43,7 @@ namespace Game PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.INS_BNET_ACCOUNT); stmt.AddValue(0, email); stmt.AddValue(1, CalculateShaPassHash(email, password)); - DB.Login.Execute(stmt); + DB.Login.DirectExecute(stmt); uint newAccountId = GetId(email); Contract.Assert(newAccountId != 0); @@ -173,7 +173,7 @@ namespace Game return 0; } - string CalculateShaPassHash(string name, string password) + public string CalculateShaPassHash(string name, string password) { SHA256 sha256 = SHA256.Create(); var i = sha256.ComputeHash(Encoding.UTF8.GetBytes(name)); diff --git a/Source/Game/Achievements/AchievementManager.cs b/Source/Game/Achievements/AchievementManager.cs index eedbf13e0..5c2111e18 100644 --- a/Source/Game/Achievements/AchievementManager.cs +++ b/Source/Game/Achievements/AchievementManager.cs @@ -719,10 +719,13 @@ namespace Game.Achievements CompletedAchievementData ca = _completedAchievements[achievementid]; ca.Date = achievementResult.Read(1); var guids = new StringArray(achievementResult.Read(2), ' '); - for (int i = 0; i < guids.Length; ++i) + if (!guids.IsEmpty()) { - if (ulong.TryParse(guids[i], out ulong guid)) - ca.CompletingPlayers.Add(ObjectGuid.Create(HighGuid.Player, guid)); + for (int i = 0; i < guids.Length; ++i) + { + if (ulong.TryParse(guids[i], out ulong guid)) + ca.CompletingPlayers.Add(ObjectGuid.Create(HighGuid.Player, guid)); + } } ca.Changed = false; diff --git a/Source/Game/Arenas/ArenaTeamManager.cs b/Source/Game/Arenas/ArenaTeamManager.cs index ac9fc8b34..8ae190e67 100644 --- a/Source/Game/Arenas/ArenaTeamManager.cs +++ b/Source/Game/Arenas/ArenaTeamManager.cs @@ -79,13 +79,12 @@ namespace Game.Arenas uint oldMSTime = Time.GetMSTime(); // Clean out the trash before loading anything - DB.Characters.Execute("DELETE FROM arena_team_member WHERE arenaTeamId NOT IN (SELECT arenaTeamId FROM arena_team)"); // One-time query + DB.Characters.DirectExecute("DELETE FROM arena_team_member WHERE arenaTeamId NOT IN (SELECT arenaTeamId FROM arena_team)"); // One-time query // 0 1 2 3 4 5 6 7 8 SQLResult result = DB.Characters.Query("SELECT arenaTeamId, name, captainGuid, type, backgroundColor, emblemStyle, emblemColor, borderStyle, borderColor, " + // 9 10 11 12 13 14 "rating, weekGames, weekWins, seasonGames, seasonWins, rank FROM arena_team ORDER BY arenaTeamId ASC"); - if (result.IsEmpty()) { Log.outInfo(LogFilter.ServerLoading, "Loaded 0 arena teams. DB table `arena_team` is empty!"); diff --git a/Source/Game/BlackMarket/BlackMarketEntry.cs b/Source/Game/BlackMarket/BlackMarketEntry.cs index dcb9be808..bc71ec63e 100644 --- a/Source/Game/BlackMarket/BlackMarketEntry.cs +++ b/Source/Game/BlackMarket/BlackMarketEntry.cs @@ -38,10 +38,13 @@ namespace Game.BlackMarket var bonusListIDsTok = new StringArray(fields.Read(7), ' '); List bonusListIDs = new List(); - foreach (string token in bonusListIDsTok) + if (!bonusListIDsTok.IsEmpty()) { - if (uint.TryParse(token, out uint id)) - bonusListIDs.Add(id); + foreach (string token in bonusListIDsTok) + { + if (uint.TryParse(token, out uint id)) + bonusListIDs.Add(id); + } } if (!bonusListIDs.Empty()) diff --git a/Source/Game/Chat/CommandHandler.cs b/Source/Game/Chat/CommandHandler.cs index a8e4a0c47..45b8601d8 100644 --- a/Source/Game/Chat/CommandHandler.cs +++ b/Source/Game/Chat/CommandHandler.cs @@ -772,7 +772,7 @@ namespace Game.Chat { messageChat.Initialize(ChatMsg.System, Language.Universal, null, null, lines[i]); _session.SendPacket(messageChat); - } + } } public void SendNotification(CypherStrings str, params object[] args) diff --git a/Source/Game/Chat/Commands/NPCCommands.cs b/Source/Game/Chat/Commands/NPCCommands.cs index 50b6f10fb..eb8d536e4 100644 --- a/Source/Game/Chat/Commands/NPCCommands.cs +++ b/Source/Game/Chat/Commands/NPCCommands.cs @@ -1164,10 +1164,13 @@ namespace Game.Chat if (fbonuslist.IsEmpty()) { var bonusListIDsTok = new StringArray(fbonuslist, ';'); - foreach (string token in bonusListIDsTok) + if (!bonusListIDsTok.IsEmpty()) { - if (uint.TryParse(token, out uint id)) - vItem.BonusListIDs.Add(id); + foreach (string token in bonusListIDsTok) + { + if (uint.TryParse(token, out uint id)) + vItem.BonusListIDs.Add(id); + } } } diff --git a/Source/Game/Conditions/DisableManager.cs b/Source/Game/Conditions/DisableManager.cs index dd0765fa2..0fdf81cce 100644 --- a/Source/Game/Conditions/DisableManager.cs +++ b/Source/Game/Conditions/DisableManager.cs @@ -104,7 +104,6 @@ namespace Game if (uint.TryParse(array[i++], out uint id)) data.param1.Add(id); } - } break; diff --git a/Source/Game/DataStorage/ClientReader/GameTables.cs b/Source/Game/DataStorage/ClientReader/GameTables.cs index 44639f666..d1819f31b 100644 --- a/Source/Game/DataStorage/ClientReader/GameTables.cs +++ b/Source/Game/DataStorage/ClientReader/GameTables.cs @@ -49,7 +49,7 @@ namespace Game.DataStorage while (!(line = reader.ReadLine()).IsEmpty()) { var values = new StringArray(line, '\t'); - if (values.Length == 0) + if (values.IsEmpty()) break; var obj = new T(); diff --git a/Source/Game/Entities/Item/Item.cs b/Source/Game/Entities/Item/Item.cs index 5e7877ad5..c40cd22ce 100644 --- a/Source/Game/Entities/Item/Item.cs +++ b/Source/Game/Entities/Item/Item.cs @@ -421,11 +421,13 @@ namespace Game.Entities var tokens = new StringArray(fields.Read(6), ' '); if (tokens.Length == ItemConst.MaxProtoSpells) + { for (byte i = 0; i < ItemConst.MaxProtoSpells; ++i) { if (int.TryParse(tokens[i], out int value)) SetSpellCharges(i, value); } + } SetUInt32Value(ItemFields.Flags, itemFlags); @@ -466,10 +468,13 @@ namespace Game.Entities SetUInt32Value(ItemFields.Context, fields.Read(19)); var bonusListIDs = new StringArray(fields.Read(20), ' '); - for (var i = 0; i < bonusListIDs.Length; ++i) + if (!tokens.IsEmpty()) { - if (uint.TryParse(tokens[i], out uint bonusListID)) - AddBonuses(bonusListID); + for (var i = 0; i < bonusListIDs.Length; ++i) + { + if (uint.TryParse(tokens[i], out uint bonusListID)) + AddBonuses(bonusListID); + } } SetModifier(ItemModifier.TransmogAppearanceAllSpecs, fields.Read(21)); @@ -491,11 +496,14 @@ namespace Game.Entities gemData[i] = new ItemDynamicFieldGems(); gemData[i].ItemId = fields.Read(31 + i * gemFields); var gemBonusListIDs = new StringArray(fields.Read(32 + i * gemFields), ' '); - uint b = 0; - foreach (string token in gemBonusListIDs) + if (!gemBonusListIDs.IsEmpty()) { - if (uint.TryParse(token, out uint bonusListID) && bonusListID != 0) - gemData[i].BonusListIDs[b++] = (ushort)bonusListID; + uint b = 0; + foreach (string token in gemBonusListIDs) + { + if (uint.TryParse(token, out uint bonusListID) && bonusListID != 0) + gemData[i].BonusListIDs[b++] = (ushort)bonusListID; + } } gemData[i].Context = fields.Read(33 + i * gemFields); @@ -1920,10 +1928,13 @@ namespace Game.Entities loot_item.context = item_result.Read(11); StringArray bonusLists = new StringArray(item_result.Read(12), ' '); - foreach (string line in bonusLists) + if (!bonusLists.IsEmpty()) { - if (uint.TryParse(line, out uint id)) - loot_item.BonusListIDs.Add(id); + foreach (string line in bonusLists) + { + if (uint.TryParse(line, out uint id)) + loot_item.BonusListIDs.Add(id); + } } // Copy the extra loot conditions from the item in the loot template diff --git a/Source/Game/Globals/ObjectManager.cs b/Source/Game/Globals/ObjectManager.cs index 9fb6a50e5..8c71ee4f8 100644 --- a/Source/Game/Globals/ObjectManager.cs +++ b/Source/Game/Globals/ObjectManager.cs @@ -3147,10 +3147,13 @@ namespace Game vItem.IgnoreFiltering = result.Read(8); var bonusListIDsTok = new StringArray(result.Read(6), ' '); - foreach (string token in bonusListIDsTok) + if (!bonusListIDsTok.IsEmpty()) { - if (uint.TryParse(token, out uint id)) - vItem.BonusListIDs.Add(id); + foreach (string token in bonusListIDsTok) + { + if (uint.TryParse(token, out uint id)) + vItem.BonusListIDs.Add(id); + } } if (!IsVendorItemValid(entry, vItem, null, skipvendors)) @@ -3196,10 +3199,13 @@ namespace Game vItem.IgnoreFiltering = result.Read(7); var bonusListIDsTok = new StringArray(result.Read(5), ' '); - foreach (string token in bonusListIDsTok) + if (!bonusListIDsTok.IsEmpty()) { - if (uint.TryParse(token, out uint id)) - vItem.BonusListIDs.Add(id); + foreach (string token in bonusListIDsTok) + { + if (uint.TryParse(token, out uint id)) + vItem.BonusListIDs.Add(id); + } } if (!IsVendorItemValid((uint)vendor, vItem, null, skip_vendors)) @@ -8925,8 +8931,12 @@ namespace Game uint itemId = rewardItem.Read(2); StringArray bonusListIDsTok = new StringArray(rewardItem.Read(3), ' '); List bonusListIds = new List(); - foreach (uint token in bonusListIDsTok) - bonusListIds.Add(token); + if (!bonusListIDsTok.IsEmpty()) + { + foreach (uint token in bonusListIDsTok) + bonusListIds.Add(token); + } + int quantity = rewardItem.Read(4); PlayerChoice choice = _playerChoices.LookupByKey(choiceId); diff --git a/Source/Game/Groups/GroupManager.cs b/Source/Game/Groups/GroupManager.cs index 5fe77dc93..ae2422949 100644 --- a/Source/Game/Groups/GroupManager.cs +++ b/Source/Game/Groups/GroupManager.cs @@ -108,9 +108,9 @@ namespace Game.Groups uint oldMSTime = Time.GetMSTime(); // Delete all groups whose leader does not exist - DB.Characters.Execute("DELETE FROM groups WHERE leaderGuid NOT IN (SELECT guid FROM characters)"); + DB.Characters.DirectExecute("DELETE FROM groups WHERE leaderGuid NOT IN (SELECT guid FROM characters)"); // Delete all groups with less than 2 members - DB.Characters.Execute("DELETE FROM groups WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)"); + DB.Characters.DirectExecute("DELETE FROM groups WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)"); // 0 1 2 3 4 5 6 7 8 9 SQLResult result = DB.Characters.Query("SELECT g.leaderGuid, g.lootMethod, g.looterGuid, g.lootThreshold, g.icon1, g.icon2, g.icon3, g.icon4, g.icon5, g.icon6" + @@ -150,10 +150,10 @@ namespace Game.Groups uint oldMSTime = Time.GetMSTime(); // Delete all rows from group_member or group_instance with no group - DB.Characters.Execute("DELETE FROM group_member WHERE guid NOT IN (SELECT guid FROM groups)"); - DB.Characters.Execute("DELETE FROM group_instance WHERE guid NOT IN (SELECT guid FROM groups)"); + DB.Characters.DirectExecute("DELETE FROM group_member WHERE guid NOT IN (SELECT guid FROM groups)"); + DB.Characters.DirectExecute("DELETE FROM group_instance WHERE guid NOT IN (SELECT guid FROM groups)"); // Delete all members that does not exist - DB.Characters.Execute("DELETE FROM group_member WHERE memberGuid NOT IN (SELECT guid FROM characters)"); + DB.Characters.DirectExecute("DELETE FROM group_member WHERE memberGuid NOT IN (SELECT guid FROM characters)"); // 0 1 2 3 4 SQLResult result = DB.Characters.Query("SELECT guid, memberGuid, memberFlags, subgroup, roles FROM group_member ORDER BY guid"); @@ -184,6 +184,7 @@ namespace Game.Groups Log.outInfo(LogFilter.ServerLoading, "Loading Group instance saves..."); { uint oldMSTime = Time.GetMSTime(); + // 0 1 2 3 4 5 6 7 SQLResult result = DB.Characters.Query("SELECT gi.guid, i.map, gi.instance, gi.permanent, i.difficulty, i.resettime, i.entranceId, COUNT(g.guid) " + "FROM group_instance gi INNER JOIN instance i ON gi.instance = i.id " + diff --git a/Source/Game/Guilds/GuildManager.cs b/Source/Game/Guilds/GuildManager.cs index 8e825a759..6363fcf6f 100644 --- a/Source/Game/Guilds/GuildManager.cs +++ b/Source/Game/Guilds/GuildManager.cs @@ -139,7 +139,7 @@ namespace Game uint oldMSTime = Time.GetMSTime(); // Delete orphaned guild rank entries before loading the valid ones - DB.Characters.Execute("DELETE gr FROM guild_rank gr LEFT JOIN guild g ON gr.guildId = g.guildId WHERE g.guildId IS NULL"); + DB.Characters.DirectExecute("DELETE gr FROM guild_rank gr LEFT JOIN guild g ON gr.guildId = g.guildId WHERE g.guildId IS NULL"); // 0 1 2 3 4 SQLResult result = DB.Characters.Query("SELECT guildid, rid, rname, rights, BankMoneyPerDay FROM guild_rank ORDER BY guildid ASC, rid ASC"); @@ -173,8 +173,8 @@ namespace Game uint oldMSTime = Time.GetMSTime(); // Delete orphaned guild member entries before loading the valid ones - DB.Characters.Execute("DELETE gm FROM guild_member gm LEFT JOIN guild g ON gm.guildId = g.guildId WHERE g.guildId IS NULL"); - DB.Characters.Execute("DELETE gm FROM guild_member_withdraw gm LEFT JOIN guild_member g ON gm.guid = g.guid WHERE g.guid IS NULL"); + DB.Characters.DirectExecute("DELETE gm FROM guild_member gm LEFT JOIN guild g ON gm.guildId = g.guildId WHERE g.guildId IS NULL"); + DB.Characters.DirectExecute("DELETE gm FROM guild_member_withdraw gm LEFT JOIN guild_member g ON gm.guid = g.guid WHERE g.guid IS NULL"); // 0 1 2 3 4 5 6 7 8 9 10 SQLResult result = DB.Characters.Query("SELECT gm.guildid, gm.guid, rank, pnote, offnote, w.tab0, w.tab1, w.tab2, w.tab3, w.tab4, w.tab5, " + @@ -210,7 +210,7 @@ namespace Game uint oldMSTime = Time.GetMSTime(); // Delete orphaned guild bank right entries before loading the valid ones - DB.Characters.Execute("DELETE gbr FROM guild_bank_right gbr LEFT JOIN guild g ON gbr.guildId = g.guildId WHERE g.guildId IS NULL"); + DB.Characters.DirectExecute("DELETE gbr FROM guild_bank_right gbr LEFT JOIN guild g ON gbr.guildId = g.guildId WHERE g.guildId IS NULL"); // 0 1 2 3 4 SQLResult result = DB.Characters.Query("SELECT guildid, TabId, rid, gbright, SlotPerDay FROM guild_bank_right ORDER BY guildid ASC, TabId ASC"); @@ -242,7 +242,7 @@ namespace Game { uint oldMSTime = Time.GetMSTime(); - DB.Characters.Execute("DELETE FROM guild_eventlog WHERE LogGuid > {0}", GuildConst.EventLogMaxRecords); + DB.Characters.DirectExecute("DELETE FROM guild_eventlog WHERE LogGuid > {0}", GuildConst.EventLogMaxRecords); // 0 1 2 3 4 5 6 SQLResult result = DB.Characters.Query("SELECT guildid, LogGuid, EventType, PlayerGuid1, PlayerGuid2, NewRank, TimeStamp FROM guild_eventlog ORDER BY TimeStamp DESC, LogGuid DESC"); @@ -275,7 +275,7 @@ namespace Game uint oldMSTime = Time.GetMSTime(); // Remove log entries that exceed the number of allowed entries per guild - DB.Characters.Execute("DELETE FROM guild_bank_eventlog WHERE LogGuid > {0}", GuildConst.BankLogMaxRecords); + DB.Characters.DirectExecute("DELETE FROM guild_bank_eventlog WHERE LogGuid > {0}", GuildConst.BankLogMaxRecords); // 0 1 2 3 4 5 6 7 8 SQLResult result = DB.Characters.Query("SELECT guildid, TabId, LogGuid, EventType, PlayerGuid, ItemOrMoney, ItemStackCount, DestTabId, TimeStamp FROM guild_bank_eventlog ORDER BY TimeStamp DESC, LogGuid DESC"); @@ -307,7 +307,7 @@ namespace Game { uint oldMSTime = Time.GetMSTime(); - DB.Characters.Execute("DELETE FROM guild_newslog WHERE LogGuid > {0}", GuildConst.NewsLogMaxRecords); + DB.Characters.DirectExecute("DELETE FROM guild_newslog WHERE LogGuid > {0}", GuildConst.NewsLogMaxRecords); // 0 1 2 3 4 5 6 SQLResult result = DB.Characters.Query("SELECT guildid, LogGuid, EventType, PlayerGuid, Flags, Value, Timestamp FROM guild_newslog ORDER BY TimeStamp DESC, LogGuid DESC"); @@ -338,7 +338,7 @@ namespace Game uint oldMSTime = Time.GetMSTime(); // Delete orphaned guild bank tab entries before loading the valid ones - DB.Characters.Execute("DELETE gbt FROM guild_bank_tab gbt LEFT JOIN guild g ON gbt.guildId = g.guildId WHERE g.guildId IS NULL"); + DB.Characters.DirectExecute("DELETE gbt FROM guild_bank_tab gbt LEFT JOIN guild g ON gbt.guildId = g.guildId WHERE g.guildId IS NULL"); // 0 1 2 3 4 SQLResult result = DB.Characters.Query("SELECT guildid, TabId, TabName, TabIcon, TabText FROM guild_bank_tab ORDER BY guildid ASC, TabId ASC"); @@ -371,7 +371,7 @@ namespace Game uint oldMSTime = Time.GetMSTime(); // Delete orphan guild bank items - DB.Characters.Execute("DELETE gbi FROM guild_bank_item gbi LEFT JOIN guild g ON gbi.guildId = g.guildId WHERE g.guildId IS NULL"); + DB.Characters.DirectExecute("DELETE gbi FROM guild_bank_item gbi LEFT JOIN guild g ON gbi.guildId = g.guildId WHERE g.guildId IS NULL"); SQLResult result = DB.Characters.Query(DB.Characters.GetPreparedStatement(CharStatements.SEL_GUILD_BANK_ITEMS)); if (result.IsEmpty()) diff --git a/Source/Game/Maps/Instances/InstanceSaveManager.cs b/Source/Game/Maps/Instances/InstanceSaveManager.cs index f6014cd90..4e70a0dc9 100644 --- a/Source/Game/Maps/Instances/InstanceSaveManager.cs +++ b/Source/Game/Maps/Instances/InstanceSaveManager.cs @@ -144,25 +144,25 @@ namespace Game.Maps uint oldMSTime = Time.GetMSTime(); // Delete expired instances (Instance related spawns are removed in the following cleanup queries) - DB.Characters.Execute("DELETE i FROM instance i LEFT JOIN instance_reset ir ON mapid = map AND i.difficulty = ir.difficulty " + + DB.Characters.DirectExecute("DELETE i FROM instance i LEFT JOIN instance_reset ir ON mapid = map AND i.difficulty = ir.difficulty " + "WHERE (i.resettime > 0 AND i.resettime < UNIX_TIMESTAMP()) OR (ir.resettime IS NOT NULL AND ir.resettime < UNIX_TIMESTAMP())"); // Delete invalid character_instance and group_instance references - DB.Characters.Execute("DELETE ci.* FROM character_instance AS ci LEFT JOIN characters AS c ON ci.guid = c.guid WHERE c.guid IS NULL"); - DB.Characters.Execute("DELETE gi.* FROM group_instance AS gi LEFT JOIN groups AS g ON gi.guid = g.guid WHERE g.guid IS NULL"); + DB.Characters.DirectExecute("DELETE ci.* FROM character_instance AS ci LEFT JOIN characters AS c ON ci.guid = c.guid WHERE c.guid IS NULL"); + DB.Characters.DirectExecute("DELETE gi.* FROM group_instance AS gi LEFT JOIN groups AS g ON gi.guid = g.guid WHERE g.guid IS NULL"); // Delete invalid instance references - DB.Characters.Execute("DELETE i.* FROM instance AS i LEFT JOIN character_instance AS ci ON i.id = ci.instance LEFT JOIN group_instance AS gi ON i.id = gi.instance WHERE ci.guid IS NULL AND gi.guid IS NULL"); + DB.Characters.DirectExecute("DELETE i.* FROM instance AS i LEFT JOIN character_instance AS ci ON i.id = ci.instance LEFT JOIN group_instance AS gi ON i.id = gi.instance WHERE ci.guid IS NULL AND gi.guid IS NULL"); // Delete invalid references to instance - DB.Characters.Execute("DELETE FROM creature_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); - DB.Characters.Execute("DELETE FROM gameobject_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); - DB.Characters.Execute("DELETE tmp.* FROM character_instance AS tmp LEFT JOIN instance ON tmp.instance = instance.id WHERE tmp.instance > 0 AND instance.id IS NULL"); - DB.Characters.Execute("DELETE tmp.* FROM group_instance AS tmp LEFT JOIN instance ON tmp.instance = instance.id WHERE tmp.instance > 0 AND instance.id IS NULL"); + DB.Characters.DirectExecute("DELETE FROM creature_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); + DB.Characters.DirectExecute("DELETE FROM gameobject_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); + DB.Characters.DirectExecute("DELETE tmp.* FROM character_instance AS tmp LEFT JOIN instance ON tmp.instance = instance.id WHERE tmp.instance > 0 AND instance.id IS NULL"); + DB.Characters.DirectExecute("DELETE tmp.* FROM group_instance AS tmp LEFT JOIN instance ON tmp.instance = instance.id WHERE tmp.instance > 0 AND instance.id IS NULL"); // Clean invalid references to instance - DB.Characters.Execute("UPDATE corpse SET instanceId = 0 WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); - DB.Characters.Execute("UPDATE characters AS tmp LEFT JOIN instance ON tmp.instance_id = instance.id SET tmp.instance_id = 0 WHERE tmp.instance_id > 0 AND instance.id IS NULL"); + DB.Characters.DirectExecute("UPDATE corpse SET instanceId = 0 WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)"); + DB.Characters.DirectExecute("UPDATE characters AS tmp LEFT JOIN instance ON tmp.instance_id = instance.id SET tmp.instance_id = 0 WHERE tmp.instance_id > 0 AND instance.id IS NULL"); // Initialize instance id storage (Needs to be done after the trash has been clean out) Global.MapMgr.InitInstanceIds(); @@ -225,7 +225,7 @@ namespace Game.Maps var pair = instResetTime.LookupByKey(instance); if (pair != null && pair.Item2 != resettime) { - DB.Characters.Execute("UPDATE instance SET resettime = '{0}' WHERE id = '{1}'", resettime, instance); + DB.Characters.DirectExecute("UPDATE instance SET resettime = '{0}' WHERE id = '{1}'", resettime, instance); instResetTime[instance] = Tuple.Create(pair.Item1, resettime); } } @@ -253,14 +253,14 @@ namespace Game.Maps if (mapDiff == null) { Log.outError(LogFilter.Server, "InstanceSaveManager.LoadResetTimes: invalid mapid({0})/difficulty({1}) pair in instance_reset!", mapid, difficulty); - DB.Characters.Execute("DELETE FROM instance_reset WHERE mapid = '{0}' AND difficulty = '{1}'", mapid, difficulty); + DB.Characters.DirectExecute("DELETE FROM instance_reset WHERE mapid = '{0}' AND difficulty = '{1}'", mapid, difficulty); continue; } // update the reset time if the hour in the configs changes ulong newresettime = (oldresettime / Time.Day) * Time.Day + diff; if (oldresettime != newresettime) - DB.Characters.Execute("UPDATE instance_reset SET resettime = '{0}' WHERE mapid = '{1}' AND difficulty = '{2}'", newresettime, mapid, difficulty); + DB.Characters.DirectExecute("UPDATE instance_reset SET resettime = '{0}' WHERE mapid = '{1}' AND difficulty = '{2}'", newresettime, mapid, difficulty); InitializeResetTimeFor(mapid, difficulty, (long)newresettime); } while (result.NextRow()); @@ -289,7 +289,7 @@ namespace Game.Maps { // initialize the reset time t = today + period + diff; - DB.Characters.Execute("INSERT INTO instance_reset VALUES ('{0}', '{1}', '{2}')", mapid, (uint)difficulty, (uint)t); + DB.Characters.DirectExecute("INSERT INTO instance_reset VALUES ('{0}', '{1}', '{2}')", mapid, (uint)difficulty, (uint)t); } if (t < now) @@ -298,7 +298,7 @@ namespace Game.Maps // calculate the next reset time t = (t / Time.Day) * Time.Day; t += ((today - t) / period + 1) * period + diff; - DB.Characters.Execute("UPDATE instance_reset SET resettime = '{0}' WHERE mapid = '{1}' AND difficulty= '{2}'", t, mapid, (uint)difficulty); + DB.Characters.DirectExecute("UPDATE instance_reset SET resettime = '{0}' WHERE mapid = '{1}' AND difficulty= '{2}'", t, mapid, (uint)difficulty); } InitializeResetTimeFor(mapid, difficulty, t); @@ -566,7 +566,7 @@ namespace Game.Maps ((InstanceMap)map2).Reset(InstanceResetMethod.Global); } - /// @todo delete creature/gameobject respawn times even if the maps are not loaded + // @todo delete creature/gameobject respawn times even if the maps are not loaded } public uint GetNumBoundPlayersTotal() diff --git a/Source/Game/Tools/CharacterDatabaseCleaner.cs b/Source/Game/Tools/CharacterDatabaseCleaner.cs index c91f012b9..887e98f1b 100644 --- a/Source/Game/Tools/CharacterDatabaseCleaner.cs +++ b/Source/Game/Tools/CharacterDatabaseCleaner.cs @@ -62,8 +62,8 @@ namespace Game // NOTE: In order to have persistentFlags be set in worldstates for the next cleanup, // you need to define them at least once in worldstates. - flags &= (CleaningFlags) WorldConfig.GetIntValue(WorldCfg.PersistentCharacterCleanFlags); - DB.Characters.Execute("UPDATE worldstates SET value = {0} WHERE entry = {1}", flags, (uint)WorldStates.CleaningFlags); + flags &= (CleaningFlags)WorldConfig.GetIntValue(WorldCfg.PersistentCharacterCleanFlags); + DB.Characters.DirectExecute("UPDATE worldstates SET value = {0} WHERE entry = {1}", flags, (uint)WorldStates.CleaningFlags); Global.WorldMgr.SetCleaningFlags(flags); @@ -150,13 +150,13 @@ namespace Game static void CleanCharacterTalent() { - DB.Characters.Execute("DELETE FROM character_talent WHERE talentGroup > {0}", PlayerConst.MaxSpecializations); + DB.Characters.DirectExecute("DELETE FROM character_talent WHERE talentGroup > {0}", PlayerConst.MaxSpecializations); CheckUnique("talentId", "character_talent", TalentCheck); } static void CleanCharacterQuestStatus() { - DB.Characters.Execute("DELETE FROM character_queststatus WHERE status = 0"); + DB.Characters.DirectExecute("DELETE FROM character_queststatus WHERE status = 0"); } } diff --git a/Source/WorldServer/Server.cs b/Source/WorldServer/Server.cs index eb50803a2..c06c52c86 100644 --- a/Source/WorldServer/Server.cs +++ b/Source/WorldServer/Server.cs @@ -49,7 +49,7 @@ namespace WorldServer uint startupBegin = Time.GetMSTime(); // set server offline (not connectable) - DB.Login.Execute("UPDATE realmlist SET flag = (flag & ~{0}) | {1} WHERE id = '{2}'", (uint)RealmFlags.VersionMismatch, (uint)RealmFlags.Offline, Global.WorldMgr.GetRealm().Id.Realm); + DB.Login.DirectExecute("UPDATE realmlist SET flag = (flag & ~{0}) | {1} WHERE id = '{2}'", (uint)RealmFlags.VersionMismatch, (uint)RealmFlags.Offline, Global.WorldMgr.GetRealm().Id.Realm); Global.RealmMgr.Initialize(ConfigMgr.GetDefaultValue("RealmsStateUpdateDelay", 10)); @@ -75,7 +75,7 @@ namespace WorldServer } // set server online (allow connecting now) - DB.Login.Execute("UPDATE realmlist SET flag = flag & ~{0}, population = 0 WHERE id = '{1}'", (uint)RealmFlags.Offline, Global.WorldMgr.GetRealm().Id.Realm); + DB.Login.DirectExecute("UPDATE realmlist SET flag = flag & ~{0}, population = 0 WHERE id = '{1}'", (uint)RealmFlags.Offline, Global.WorldMgr.GetRealm().Id.Realm); Global.WorldMgr.GetRealm().PopulationLevel = 0.0f; Global.WorldMgr.GetRealm().Flags = Global.WorldMgr.GetRealm().Flags & ~RealmFlags.VersionMismatch; @@ -110,7 +110,7 @@ namespace WorldServer Global.ScriptMgr.Unload(); // set server offline - DB.Login.Execute("UPDATE realmlist SET flag = flag | {0} WHERE id = '{1}'", (uint)RealmFlags.Offline, Global.WorldMgr.GetRealm().Id.Realm); + DB.Login.DirectExecute("UPDATE realmlist SET flag = flag | {0} WHERE id = '{1}'", (uint)RealmFlags.Offline, Global.WorldMgr.GetRealm().Id.Realm); Global.RealmMgr.Close(); ClearOnlineAccounts(); @@ -155,13 +155,13 @@ namespace WorldServer static void ClearOnlineAccounts() { // Reset online status for all accounts with characters on the current realm - DB.Login.Execute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = {0})", Global.WorldMgr.GetRealm().Id.Realm); + DB.Login.DirectExecute("UPDATE account SET online = 0 WHERE online > 0 AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = {0})", Global.WorldMgr.GetRealm().Id.Realm); // Reset online status for all characters - DB.Characters.Execute("UPDATE characters SET online = 0 WHERE online <> 0"); + DB.Characters.DirectExecute("UPDATE characters SET online = 0 WHERE online <> 0"); // Battlegroundinstance ids reset at server restart - DB.Characters.Execute("UPDATE character_battleground_data SET instanceId = 0"); + DB.Characters.DirectExecute("UPDATE character_battleground_data SET instanceId = 0"); } static void WorldUpdateLoop()