Core/DBLayer: Implement async transaction completion callbacks

Port From (https://github.com/TrinityCore/TrinityCore/commit/0f0ca3a9194d76afa0227943e86469ad8368c5e2)
This commit is contained in:
hondacrx
2020-04-26 00:53:43 -04:00
parent a9d1d3f2b0
commit d450f6db3d
14 changed files with 224 additions and 109 deletions
+3 -3
View File
@@ -55,7 +55,7 @@ namespace BNetServer.Networking
stmt.AddValue(0, ip_address);
stmt.AddValue(1, BitConverter.ToUInt32(GetRemoteIpAddress().GetAddressBytes(), 0));
_queryProcessor.AddQuery(DB.Login.AsyncQuery(stmt).WithCallback(CheckIpCallback));
_queryProcessor.AddCallback(DB.Login.AsyncQuery(stmt).WithCallback(CheckIpCallback));
}
void CheckIpCallback(SQLResult result)
@@ -89,7 +89,7 @@ namespace BNetServer.Networking
if (!base.Update())
return false;
_queryProcessor.ProcessReadyQueries();
_queryProcessor.ProcessReadyCallbacks();
return true;
}
@@ -631,7 +631,7 @@ namespace BNetServer.Networking
bool _authed;
QueryCallbackProcessor _queryProcessor = new QueryCallbackProcessor();
AsyncCallbackProcessor<QueryCallback> _queryProcessor = new AsyncCallbackProcessor<QueryCallback>();
Dictionary<uint, Action<CodedInputStream>> _responseCallbacks = new Dictionary<uint, Action<CodedInputStream>>();
uint _requestToken;
@@ -19,21 +19,27 @@ using System.Collections.Generic;
namespace Framework.Database
{
public class QueryCallbackProcessor
public interface ISqlCallback
{
public void AddQuery(QueryCallback query)
bool InvokeIfReady();
}
public class AsyncCallbackProcessor<T> where T : ISqlCallback
{
List<T> _callbacks = new List<T>();
public T AddCallback(T query)
{
_callbacks.Add(query);
return query;
}
public void ProcessReadyQueries()
public void ProcessReadyCallbacks()
{
if (_callbacks.Empty())
return;
_callbacks.RemoveAll(callback => callback.InvokeIfReady() == QueryCallbackStatus.Completed);
_callbacks.RemoveAll(callback => callback.InvokeIfReady());
}
List<QueryCallback> _callbacks = new List<QueryCallback>();
}
}
+11 -4
View File
@@ -253,7 +253,15 @@ namespace Framework.Database
_queue.Push(new TransactionTask(transaction));
}
public bool DirectCommitTransaction(SQLTransaction transaction)
public TransactionCallback AsyncCommitTransaction(SQLTransaction transaction)
{
TransactionWithResultTask task = new TransactionWithResultTask(transaction);
Task<bool> result = task.GetFuture();
_queue.Push(task);
return new TransactionCallback(result);
}
public MySqlErrorCode DirectCommitTransaction(SQLTransaction transaction)
{
using (var Connection = _connectionInfo.GetConnection())
{
@@ -277,13 +285,12 @@ namespace Framework.Database
trans.Commit();
scope.Complete();
}
return true;
return MySqlErrorCode.None;
}
catch (MySqlException ex) //error occurred
{
HandleMySQLException(ex, query);
trans.Rollback();
return false;
return HandleMySQLException(ex, query);
}
}
}
+5 -12
View File
@@ -21,7 +21,7 @@ using System.Threading.Tasks;
namespace Framework.Database
{
public class QueryCallback
public class QueryCallback : ISqlCallback
{
public QueryCallback(Task<SQLResult> result)
{
@@ -49,7 +49,7 @@ namespace Framework.Database
_result = next._result;
}
public QueryCallbackStatus InvokeIfReady()
public bool InvokeIfReady()
{
QueryCallbackData callback = _callbacks.Peek();
@@ -68,17 +68,17 @@ namespace Framework.Database
if (_callbacks.Count == 0)
{
Cypher.Assert(!hasNext);
return QueryCallbackStatus.Completed;
return true;
}
// abort chain
if (!hasNext)
return QueryCallbackStatus.Completed;
return true;
callback = _callbacks.Peek();
}
else
return QueryCallbackStatus.NotReady;
return false;
}
}
@@ -100,11 +100,4 @@ namespace Framework.Database
public Action<QueryCallback, SQLResult> _result;
}
public enum QueryCallbackStatus
{
NotReady,
NextStep,
Completed
}
}
@@ -17,6 +17,8 @@
using MySql.Data.MySqlClient;
using System.Collections.Generic;
using System;
using System.Threading.Tasks;
namespace Framework.Database
{
@@ -52,10 +54,98 @@ namespace Framework.Database
}
public bool Execute<T>(MySqlBase<T> mySqlBase)
{
MySqlErrorCode errorCode = TryExecute(mySqlBase);
if (errorCode == MySqlErrorCode.None)
return true;
if (errorCode == MySqlErrorCode.LockDeadlock)
{
// Make sure only 1 async thread retries a transaction so they don't keep dead-locking each other
lock (_deadlockLock)
{
byte loopBreaker = 5; // Handle MySQL Errno 1213 without extending deadlock to the core itself
for (byte i = 0; i < loopBreaker; ++i)
if (TryExecute(mySqlBase) == MySqlErrorCode.None)
return true;
}
}
return false;
}
public MySqlErrorCode TryExecute<T>(MySqlBase<T> mySqlBase)
{
return mySqlBase.DirectCommitTransaction(m_trans);
}
SQLTransaction m_trans;
public static object _deadlockLock = new object();
}
class TransactionWithResultTask : TransactionTask
{
public TransactionWithResultTask(SQLTransaction trans) : base(trans) { }
public new bool Execute<T>(MySqlBase<T> mySqlBase)
{
MySqlErrorCode errorCode = TryExecute(mySqlBase);
if (errorCode == MySqlErrorCode.None)
{
m_result.SetResult(true);
return true;
}
if (errorCode == MySqlErrorCode.LockDeadlock)
{
// Make sure only 1 async thread retries a transaction so they don't keep dead-locking each other
lock (_deadlockLock)
{
byte loopBreaker = 5; // Handle MySQL Errno 1213 without extending deadlock to the core itself
for (byte i = 0; i < loopBreaker; ++i)
{
if (TryExecute(mySqlBase) == MySqlErrorCode.None)
{
m_result.SetResult(true);
return true;
}
}
}
}
m_result.SetResult(false);
return false;
}
public Task<bool> GetFuture() { return m_result.Task; }
TaskCompletionSource<bool> m_result = new TaskCompletionSource<bool>();
}
public class TransactionCallback : ISqlCallback
{
public TransactionCallback(Task<bool> future)
{
m_future = future;
}
public void AfterComplete(Action<bool> callback)
{
m_callback = callback;
}
public bool InvokeIfReady()
{
if (m_future != null && m_future.Wait(0))
{
m_callback(m_future.Result);
return true;
}
return false;
}
Task<bool> m_future;
Action<bool> m_callback;
}
}
@@ -73,6 +73,7 @@ namespace Game.Entities
{
return MapSpecificCreate(type, (byte)subType, (ushort)mapId, 0, entry, counter);
}
static ObjectGuid GlobalCreate(HighGuid type, ulong counter)
{
return new ObjectGuid((ulong)type << 58, counter);
+47 -42
View File
@@ -3107,6 +3107,17 @@ namespace Game.Entities
}
public void SaveToDB(bool create = false)
{
SQLTransaction loginTransaction = new SQLTransaction();
SQLTransaction characterTransaction = new SQLTransaction();
SaveToDB(loginTransaction, characterTransaction, create);
DB.Characters.CommitTransaction(characterTransaction);
DB.Login.CommitTransaction(loginTransaction);
}
public void SaveToDB(SQLTransaction loginTransaction, SQLTransaction characterTransaction, bool create = false)
{
// delay auto save at any saves (manual, in code, or autosave)
m_nextSave = WorldConfig.GetUIntValue(WorldCfg.IntervalSave);
@@ -3126,13 +3137,12 @@ namespace Game.Entities
if (!create)
Global.ScriptMgr.OnPlayerSave(this);
SQLTransaction trans = new SQLTransaction();
PreparedStatement stmt;
byte index = 0;
stmt = DB.Characters.GetPreparedStatement(CharStatements.DEL_CHAR_FISHINGSTEPS);
stmt.AddValue(0, GetGUID().GetCounter());
trans.Append(stmt);
characterTransaction.Append(stmt);
float finiteAlways(float f) { return !float.IsInfinity(f) ? f : 0.0f; };
@@ -3428,7 +3438,7 @@ namespace Game.Entities
stmt.AddValue(index, GetGUID().GetCounter());
}
trans.Append(stmt);
characterTransaction.Append(stmt);
if (m_fishingSteps != 0)
{
@@ -3436,58 +3446,55 @@ namespace Game.Entities
index = 0;
stmt.AddValue(index++, GetGUID().GetCounter());
stmt.AddValue(index++, m_fishingSteps);
trans.Append(stmt);
characterTransaction.Append(stmt);
}
if (m_mailsUpdated) //save mails only when needed
_SaveMail(trans);
_SaveMail(characterTransaction);
_SaveBGData(trans);
_SaveInventory(trans);
_SaveVoidStorage(trans);
_SaveQuestStatus(trans);
_SaveDailyQuestStatus(trans);
_SaveWeeklyQuestStatus(trans);
_SaveSeasonalQuestStatus(trans);
_SaveMonthlyQuestStatus(trans);
_SaveGlyphs(trans);
_SaveTalents(trans);
_SaveSpells(trans);
GetSpellHistory().SaveToDB<Player>(trans);
_SaveActions(trans);
_SaveAuras(trans);
_SaveSkills(trans);
m_achievementSys.SaveToDB(trans);
reputationMgr.SaveToDB(trans);
m_questObjectiveCriteriaMgr.SaveToDB(trans);
_SaveEquipmentSets(trans);
GetSession().SaveTutorialsData(trans); // changed only while character in game
_SaveInstanceTimeRestrictions(trans);
_SaveCurrency(trans);
_SaveCUFProfiles(trans);
_SaveBGData(characterTransaction);
_SaveInventory(characterTransaction);
_SaveVoidStorage(characterTransaction);
_SaveQuestStatus(characterTransaction);
_SaveDailyQuestStatus(characterTransaction);
_SaveWeeklyQuestStatus(characterTransaction);
_SaveSeasonalQuestStatus(characterTransaction);
_SaveMonthlyQuestStatus(characterTransaction);
_SaveGlyphs(characterTransaction);
_SaveTalents(characterTransaction);
_SaveSpells(characterTransaction);
GetSpellHistory().SaveToDB<Player>(characterTransaction);
_SaveActions(characterTransaction);
_SaveAuras(characterTransaction);
_SaveSkills(characterTransaction);
m_achievementSys.SaveToDB(characterTransaction);
reputationMgr.SaveToDB(characterTransaction);
m_questObjectiveCriteriaMgr.SaveToDB(characterTransaction);
_SaveEquipmentSets(characterTransaction);
GetSession().SaveTutorialsData(characterTransaction); // changed only while character in game
_SaveInstanceTimeRestrictions(characterTransaction);
_SaveCurrency(characterTransaction);
_SaveCUFProfiles(characterTransaction);
if (_garrison != null)
_garrison.SaveToDB(trans);
_garrison.SaveToDB(characterTransaction);
// check if stats should only be saved on logout
// save stats can be out of transaction
if (GetSession().IsLogingOut() || !WorldConfig.GetBoolValue(WorldCfg.StatsSaveOnlyOnLogout))
_SaveStats(trans);
DB.Characters.CommitTransaction(trans);
_SaveStats(characterTransaction);
// TODO: Move this out
trans = new SQLTransaction();
GetSession().GetCollectionMgr().SaveAccountToys(trans);
GetSession().GetBattlePetMgr().SaveToDB(trans);
GetSession().GetCollectionMgr().SaveAccountHeirlooms(trans);
GetSession().GetCollectionMgr().SaveAccountMounts(trans);
GetSession().GetCollectionMgr().SaveAccountItemAppearances(trans);
GetSession().GetCollectionMgr().SaveAccountToys(loginTransaction);
GetSession().GetBattlePetMgr().SaveToDB(loginTransaction);
GetSession().GetCollectionMgr().SaveAccountHeirlooms(loginTransaction);
GetSession().GetCollectionMgr().SaveAccountMounts(loginTransaction);
GetSession().GetCollectionMgr().SaveAccountItemAppearances(loginTransaction);
stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_BNET_LAST_PLAYER_CHARACTERS);
stmt.AddValue(0, GetSession().GetAccountId());
stmt.AddValue(1, Global.WorldMgr.GetRealmId().Region);
stmt.AddValue(2, Global.WorldMgr.GetRealmId().Site);
trans.Append(stmt);
loginTransaction.Append(stmt);
stmt = DB.Login.GetPreparedStatement(LoginStatements.INS_BNET_LAST_PLAYER_CHARACTERS);
stmt.AddValue(0, GetSession().GetAccountId());
@@ -3497,9 +3504,7 @@ namespace Game.Entities
stmt.AddValue(4, GetName());
stmt.AddValue(5, GetGUID().GetCounter());
stmt.AddValue(6, Time.UnixTime);
trans.Append(stmt);
DB.Login.CommitTransaction(trans);
loginTransaction.Append(stmt);
// save pet (hunter pet level and experience and all type pets health/mana).
Pet pet = GetPet();
@@ -383,7 +383,7 @@ namespace Game.Entities
stmt.AddValue(1, GetActiveTalentGroup());
WorldSession mySess = GetSession();
mySess.GetQueryProcessor().AddQuery(DB.Characters.AsyncQuery(stmt).WithCallback(result =>
mySess.GetQueryProcessor().AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(result =>
{
// in case player logs out before db response (player would be deleted in that case)
Player thisPlayer = mySess.GetPlayer();
+32 -26
View File
@@ -49,7 +49,7 @@ namespace Game
stmt.AddValue(0, PetSaveMode.AsCurrent);
stmt.AddValue(1, GetAccountId());
_queryProcessor.AddQuery(DB.Characters.AsyncQuery(stmt).WithCallback(HandleCharEnumCallback));
_queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(HandleCharEnumCallback));
}
void HandleCharEnumCallback(SQLResult result)
@@ -144,7 +144,7 @@ namespace Game
stmt.AddValue(0, (uint)PetSaveMode.AsCurrent);
stmt.AddValue(1, GetAccountId());
_queryProcessor.AddQuery(DB.Characters.AsyncQuery(stmt).WithCallback(HandleCharUndeleteEnumCallback));
_queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(HandleCharUndeleteEnumCallback));
}
void HandleCharUndeleteEnumCallback(SQLResult result)
@@ -307,7 +307,7 @@ namespace Game
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHECK_NAME);
stmt.AddValue(0, charCreate.CreateInfo.Name);
_queryProcessor.AddQuery(DB.Characters.AsyncQuery(stmt).WithChainingCallback((queryCallback, result) =>
_queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt).WithChainingCallback((queryCallback, result) =>
{
if (!result.IsEmpty())
{
@@ -334,6 +334,7 @@ namespace Game
stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_SUM_CHARS);
stmt.AddValue(0, GetAccountId());
queryCallback.SetNextQuery(DB.Characters.AsyncQuery(stmt));
}).WithChainingCallback((queryCallback, result) =>
{
if (!result.IsEmpty())
@@ -347,16 +348,15 @@ namespace Game
}
}
int demonHunterReqLevel = WorldConfig.GetIntValue(WorldCfg.CharacterCreatingMinLevelForDemonHunter);
bool hasDemonHunterReqLevel = demonHunterReqLevel == 0;
bool allowTwoSideAccounts = !Global.WorldMgr.IsPvPRealm() || HasPermission(RBACPermissions.TwoSideCharacterCreation);
int skipCinematics = WorldConfig.GetIntValue(WorldCfg.SkipCinematics);
bool checkDemonHunterReqs = createInfo.ClassId == Class.DemonHunter && !HasPermission(RBACPermissions.SkipCheckCharacterCreationDemonHunter);
void finalizeCharacterCreation(SQLResult result1)
{
bool haveSameRace = false;
int demonHunterReqLevel = WorldConfig.GetIntValue(WorldCfg.CharacterCreatingMinLevelForDemonHunter);
bool hasDemonHunterReqLevel = (demonHunterReqLevel == 0);
bool checkDemonHunterReqs = createInfo.ClassId == Class.DemonHunter && !HasPermission(RBACPermissions.SkipCheckCharacterCreationDemonHunter);
if (result1 != null && !result1.IsEmpty())
{
Team team = Player.TeamForRace(createInfo.RaceId);
@@ -461,33 +461,39 @@ namespace Game
newChar.atLoginFlags = AtLoginFlags.FirstLogin; // First login
// Player created, save it now
newChar.SaveToDB(true);
createInfo.CharCount += 1;
SQLTransaction characterTransaction = new SQLTransaction();
SQLTransaction loginTransaction = new SQLTransaction();
SQLTransaction trans = new SQLTransaction();
// Player created, save it now
newChar.SaveToDB(loginTransaction, characterTransaction, true);
createInfo.CharCount += 1;
stmt = DB.Login.GetPreparedStatement(LoginStatements.DEL_REALM_CHARACTERS_BY_REALM);
stmt.AddValue(0, GetAccountId());
stmt.AddValue(1, Global.WorldMgr.GetRealm().Id.Realm);
trans.Append(stmt);
loginTransaction.Append(stmt);
stmt = DB.Login.GetPreparedStatement(LoginStatements.INS_REALM_CHARACTERS);
stmt.AddValue(0, createInfo.CharCount);
stmt.AddValue(1, GetAccountId());
stmt.AddValue(2, Global.WorldMgr.GetRealm().Id.Realm);
trans.Append(stmt);
loginTransaction.Append(stmt);
DB.Login.CommitTransaction(trans);
DB.Login.CommitTransaction(loginTransaction);
// Success
SendCharCreate(ResponseCodes.CharCreateSuccess, newChar.GetGUID());
AddTransactionCallback(DB.Characters.AsyncCommitTransaction(characterTransaction)).AfterComplete(success =>
{
if (success)
{
Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Create Character: {2} {3}", GetAccountId(), GetRemoteAddress(), createInfo.Name, newChar.GetGUID().ToString());
Global.ScriptMgr.OnPlayerCreate(newChar);
Global.CharacterCacheStorage.AddCharacterCacheEntry(newChar.GetGUID(), GetAccountId(), newChar.GetName(), newChar.m_playerData.NativeSex, (byte)newChar.GetRace(), (byte)newChar.GetClass(), (byte)newChar.GetLevel(), false);
Log.outInfo(LogFilter.Player, "Account: {0} (IP: {1}) Create Character: {2} {3}", GetAccountId(), GetRemoteAddress(), createInfo.Name, newChar.GetGUID().ToString());
Global.ScriptMgr.OnPlayerCreate(newChar);
Global.CharacterCacheStorage.AddCharacterCacheEntry(newChar.GetGUID(), GetAccountId(), newChar.GetName(), newChar.m_playerData.NativeSex, (byte)newChar.GetRace(), (byte)newChar.GetClass(), (byte)newChar.GetLevel(), false);
newChar.CleanupsBeforeDelete();
SendCharCreate(ResponseCodes.CharCreateSuccess, newChar.GetGUID());
}
else
SendCharCreate(ResponseCodes.CharCreateError);
});
}
if (!allowTwoSideAccounts || skipCinematics == 1 || createInfo.ClassId == Class.DemonHunter)
@@ -1021,7 +1027,7 @@ namespace Game
stmt.AddValue(0, request.RenameInfo.Guid.GetCounter());
stmt.AddValue(1, request.RenameInfo.NewName);
_queryProcessor.AddQuery(DB.Characters.AsyncQuery(stmt).WithCallback(HandleCharRenameCallBack, request.RenameInfo));
_queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(HandleCharRenameCallBack, request.RenameInfo));
}
void HandleCharRenameCallBack(CharacterRenameInfo renameInfo, SQLResult result)
@@ -1211,7 +1217,7 @@ namespace Game
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHAR_CUSTOMIZE_INFO);
stmt.AddValue(0, packet.CustomizeInfo.CharGUID.GetCounter());
_queryProcessor.AddQuery(DB.Characters.AsyncQuery(stmt).WithCallback(HandleCharCustomizeCallback, packet.CustomizeInfo));
_queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(HandleCharCustomizeCallback, packet.CustomizeInfo));
}
void HandleCharCustomizeCallback(CharCustomizeInfo customizeInfo, SQLResult result)
@@ -1492,7 +1498,7 @@ namespace Game
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHAR_RACE_OR_FACTION_CHANGE_INFOS);
stmt.AddValue(0, packet.RaceOrFactionChangeInfo.Guid.GetCounter());
_queryProcessor.AddQuery(DB.Characters.AsyncQuery(stmt).WithCallback(HandleCharRaceOrFactionChangeCallback, packet.RaceOrFactionChangeInfo));
_queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(HandleCharRaceOrFactionChangeCallback, packet.RaceOrFactionChangeInfo));
}
void HandleCharRaceOrFactionChangeCallback(CharRaceOrFactionChangeInfo factionChangeInfo, SQLResult result)
@@ -2045,7 +2051,7 @@ namespace Game
PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_LAST_CHAR_UNDELETE);
stmt.AddValue(0, GetBattlenetAccountId());
_queryProcessor.AddQuery(DB.Login.AsyncQuery(stmt).WithCallback(HandleUndeleteCooldownStatusCallback));
_queryProcessor.AddCallback(DB.Login.AsyncQuery(stmt).WithCallback(HandleUndeleteCooldownStatusCallback));
}
void HandleUndeleteCooldownStatusCallback(SQLResult result)
@@ -2076,7 +2082,7 @@ namespace Game
stmt.AddValue(0, GetBattlenetAccountId());
CharacterUndeleteInfo undeleteInfo = undeleteCharacter.UndeleteInfo;
_queryProcessor.AddQuery(DB.Login.AsyncQuery(stmt).WithChainingCallback((queryCallback, result) =>
_queryProcessor.AddCallback(DB.Login.AsyncQuery(stmt).WithChainingCallback((queryCallback, result) =>
{
if (!result.IsEmpty())
{
+1 -1
View File
@@ -351,7 +351,7 @@ namespace Game
stmt.AddValue(1, PetSaveMode.FirstStableSlot);
stmt.AddValue(2, PetSaveMode.LastStableSlot);
_queryProcessor.AddQuery(DB.Characters.AsyncQuery(stmt).WithCallback(SendStablePetCallback, guid));
_queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(SendStablePetCallback, guid));
}
void SendStablePetCallback(ObjectGuid guid, SQLResult result)
+1 -1
View File
@@ -188,7 +188,7 @@ namespace Game
{
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_GIFT_BY_ITEM);
stmt.AddValue(0, item.GetGUID().GetCounter());
_queryProcessor.AddQuery(DB.Characters.AsyncQuery(stmt)
_queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt)
.WithCallback(result => HandleOpenWrappedItemCallback(item.GetPos(), item.GetGUID(), result)));
}
else
+6 -6
View File
@@ -65,7 +65,7 @@ namespace Game.Network
stmt.AddValue(0, ip_address);
stmt.AddValue(1, BitConverter.ToUInt32(GetRemoteIpAddress().GetAddressBytes(), 0));
_queryProcessor.AddQuery(DB.Login.AsyncQuery(stmt).WithCallback(CheckIpCallback));
_queryProcessor.AddCallback(DB.Login.AsyncQuery(stmt).WithCallback(CheckIpCallback));
}
void CheckIpCallback(SQLResult result)
@@ -356,7 +356,7 @@ namespace Game.Network
if (!base.Update())
return false;
_queryProcessor.ProcessReadyQueries();
_queryProcessor.ProcessReadyCallbacks();
return true;
}
@@ -378,7 +378,7 @@ namespace Game.Network
stmt.AddValue(0, Global.WorldMgr.GetRealm().Id.Realm);
stmt.AddValue(1, authSession.RealmJoinTicket);
_queryProcessor.AddQuery(DB.Login.AsyncQuery(stmt).WithCallback(HandleAuthSessionCallback, authSession));
_queryProcessor.AddCallback(DB.Login.AsyncQuery(stmt).WithCallback(HandleAuthSessionCallback, authSession));
}
void HandleAuthSessionCallback(AuthSession authSession, SQLResult result)
@@ -559,7 +559,7 @@ namespace Game.Network
//if (wardenActive)
//_worldSession.InitWarden(_sessionKey);
_queryProcessor.AddQuery(_worldSession.LoadPermissionsAsync().WithCallback(LoadSessionPermissionsCallback));
_queryProcessor.AddCallback(_worldSession.LoadPermissionsAsync().WithCallback(LoadSessionPermissionsCallback));
}
void LoadSessionPermissionsCallback(SQLResult result)
@@ -587,7 +587,7 @@ namespace Game.Network
PreparedStatement stmt = DB.Login.GetPreparedStatement(LoginStatements.SEL_ACCOUNT_INFO_CONTINUED_SESSION);
stmt.AddValue(0, accountId);
_queryProcessor.AddQuery(DB.Login.AsyncQuery(stmt).WithCallback(HandleAuthContinuedSessionCallback, authSession));
_queryProcessor.AddCallback(DB.Login.AsyncQuery(stmt).WithCallback(HandleAuthContinuedSessionCallback, authSession));
}
void HandleAuthContinuedSessionCallback(AuthContinuedSession authSession, SQLResult result)
@@ -745,7 +745,7 @@ namespace Game.Network
ZLib.z_stream _compressionStream;
QueryCallbackProcessor _queryProcessor = new QueryCallbackProcessor();
AsyncCallbackProcessor<QueryCallback> _queryProcessor = new AsyncCallbackProcessor<QueryCallback>();
string _ipCountry;
}
+3 -3
View File
@@ -1781,7 +1781,7 @@ namespace Game
{
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_COUNT);
stmt.AddValue(0, accountId);
_queryProcessor.AddQuery(DB.Characters.AsyncQuery(stmt).WithCallback(_UpdateRealmCharCount));
_queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt).WithCallback(_UpdateRealmCharCount));
}
void _UpdateRealmCharCount(SQLResult result)
@@ -2145,7 +2145,7 @@ namespace Game
void ProcessQueryCallbacks()
{
_queryProcessor.ProcessReadyQueries();
_queryProcessor.ProcessReadyCallbacks();
}
public void ReloadRBAC()
@@ -2324,7 +2324,7 @@ namespace Game
ConcurrentQueue<Tuple<WorldSocket, ulong>> _linkSocketQueue = new ConcurrentQueue<Tuple<WorldSocket, ulong>>();
QueryCallbackProcessor _queryProcessor = new QueryCallbackProcessor();
AsyncCallbackProcessor<QueryCallback> _queryProcessor = new AsyncCallbackProcessor<QueryCallback>();
Realm _realm;
+10 -3
View File
@@ -631,7 +631,7 @@ namespace Game
public ulong GetConnectToInstanceKey() { return _instanceConnectKey.Raw; }
public QueryCallbackProcessor GetQueryProcessor() { return _queryProcessor; }
public AsyncCallbackProcessor<QueryCallback> GetQueryProcessor() { return _queryProcessor; }
void SetLogoutStartTime(long requestTime)
{
@@ -645,7 +645,8 @@ namespace Game
void ProcessQueryCallbacks()
{
_queryProcessor.ProcessReadyQueries();
_queryProcessor.ProcessReadyCallbacks();
_transactionCallbacks.ProcessReadyCallbacks();
if (_realmAccountLoginCallback != null && _realmAccountLoginCallback.IsCompleted && _accountLoginCallback != null && _accountLoginCallback.IsCompleted)
{
@@ -662,6 +663,11 @@ namespace Game
}
}
TransactionCallback AddTransactionCallback(TransactionCallback callback)
{
return _transactionCallbacks.AddCallback(callback);
}
void InitWarden(BigInteger k)
{
if (_os == "Win")
@@ -896,7 +902,8 @@ namespace Game
Task<SQLQueryHolder<AccountInfoQueryLoad>> _accountLoginCallback;
Task<SQLQueryHolder<PlayerLoginQueryLoad>> _charLoginCallback;
QueryCallbackProcessor _queryProcessor = new QueryCallbackProcessor();
AsyncCallbackProcessor<QueryCallback> _queryProcessor = new AsyncCallbackProcessor<QueryCallback>();
AsyncCallbackProcessor<TransactionCallback> _transactionCallbacks = new AsyncCallbackProcessor<TransactionCallback>();
#endregion
}