void GmTicket::SaveToDB(SQLTransaction& trans) const { uint8 index = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GM_TICKET); stmt->setUInt32(index, _ticketId); stmt->setUInt64(++index, GUID_LOPART(_playerGuid)); stmt->setString(++index, _playerName); stmt->setString(++index, _message); stmt->setUInt32(++index, _ticketCreateTime); stmt->setUInt16(++index, _mapId); stmt->setFloat(++index, _pos.x); stmt->setFloat(++index, _pos.y); stmt->setFloat(++index, _pos.z); stmt->setUInt32(++index, uint32(_lastModifiedTime)); stmt->setInt64(++index, GUID_LOPART(_closedBy)); stmt->setUInt64(++index, GUID_LOPART(_assignedTo)); stmt->setString(++index, _comment); stmt->setString(++index, _response); stmt->setBool(++index, _completed); stmt->setUInt8(++index, uint8(_escalatedStatus)); stmt->setBool(++index, _viewed); stmt->setBool(++index, _haveTicket); CharacterDatabase.ExecuteOrAppend(trans, stmt); }
//unmute player bool ChatHandler::HandleUnmuteCommand(const char* args) { Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget((char*)args, &target, &target_guid, &target_name)) return false; uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid); // find only player from same account if any if (!target) if (WorldSession* session = sWorld->FindSession(accountId)) target = session->GetPlayer(); // must have strong lesser security level if (HasLowerSecurity (target, target_guid, true)) return false; if (target) { if (target->CanSpeak()) { SendSysMessage(LANG_CHAT_ALREADY_ENABLED); SetSentErrorMessage(true); return false; } target->GetSession()->m_muteTime = 0; } PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); stmt->setInt64(0, 0); stmt->setUInt32(1, accountId); LoginDatabase.Execute(stmt); if (target) ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED); std::string nameLink = playerLink(target_name); PSendSysMessage(LANG_YOU_ENABLE_CHAT, nameLink.c_str()); return true; }
void BugTicket::SaveToDB() const { uint8 idx = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GM_BUG); stmt->setUInt32(idx, _id); stmt->setUInt64(++idx, _playerGuid.GetCounter()); stmt->setString(++idx, _note); stmt->setUInt16(++idx, _mapId); stmt->setFloat(++idx, _pos.x); stmt->setFloat(++idx, _pos.y); stmt->setFloat(++idx, _pos.z); stmt->setFloat(++idx, _facing); stmt->setInt64(++idx, _closedBy.GetCounter()); stmt->setUInt64(++idx, _assignedTo.GetCounter()); stmt->setString(++idx, _comment); CharacterDatabase.Execute(stmt); }
void SuggestionTicket::SaveToDB(SQLTransaction& trans) const { uint8 idx = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GM_SUGGESTION); stmt->setUInt32(idx, _id); stmt->setUInt64(++idx, _playerGuid.GetCounter()); stmt->setString(++idx, _note); stmt->setUInt32(++idx, _mapId); stmt->setFloat(++idx, _pos.x); stmt->setFloat(++idx, _pos.y); stmt->setFloat(++idx, _pos.z); stmt->setFloat(++idx, _facing); stmt->setInt64(++idx, _closedBy.GetCounter()); stmt->setUInt64(++idx, _assignedTo.GetCounter()); stmt->setString(++idx, _comment); CharacterDatabase.ExecuteOrAppend(trans, stmt); }
void ComplaintTicket::SaveToDB(SQLTransaction& trans) const { bool isInTransaction = bool(trans); if (!isInTransaction) trans = CharacterDatabase.BeginTransaction(); uint8 idx = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GM_COMPLAINT); stmt->setUInt32(idx, _id); stmt->setUInt64(++idx, _playerGuid.GetCounter()); stmt->setString(++idx, _note); stmt->setUInt32(++idx, _mapId); stmt->setFloat(++idx, _pos.x); stmt->setFloat(++idx, _pos.y); stmt->setFloat(++idx, _pos.z); stmt->setFloat(++idx, _facing); stmt->setUInt64(++idx, _targetCharacterGuid.GetCounter()); stmt->setUInt8(++idx, _complaintType); if (_chatLog.ReportLineIndex) stmt->setInt32(++idx, *_chatLog.ReportLineIndex); else stmt->setInt32(++idx, -1); // empty ReportLineIndex stmt->setInt64(++idx, _closedBy.GetCounter()); stmt->setUInt64(++idx, _assignedTo.GetCounter()); stmt->setString(++idx, _comment); trans->Append(stmt); uint32 lineIndex = 0; for (auto const& c : _chatLog.Lines) { idx = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GM_COMPLAINT_CHATLINE); stmt->setUInt32(idx, _id); stmt->setUInt32(++idx, lineIndex); stmt->setUInt32(++idx, c.Timestamp); stmt->setString(++idx, c.Text); trans->Append(stmt); ++lineIndex; } if (!isInTransaction) CharacterDatabase.CommitTransaction(trans); }
void GmTicket::SaveToDB(SQLTransaction& trans) const { uint8 idx = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GM_TICKET); stmt->setUInt32(idx, _id); stmt->setUInt64(++idx, _playerGuid.GetCounter()); stmt->setString(++idx, _description); stmt->setUInt32(++idx, _createTime); stmt->setUInt16(++idx, _mapId); stmt->setFloat(++idx, _pos.x); stmt->setFloat(++idx, _pos.y); stmt->setFloat(++idx, _pos.z); stmt->setUInt32(++idx, uint32(_lastModifiedTime)); stmt->setInt64(++idx, int64(_closedBy.GetCounter())); stmt->setUInt64(++idx, _assignedTo.GetCounter()); stmt->setString(++idx, _comment); stmt->setString(++idx, _response); stmt->setBool(++idx, _completed); stmt->setUInt8(++idx, uint8(_assignedToStatus)); stmt->setUInt8(++idx, _openedByGmStatus); stmt->setBool(++idx, _needMoreHelp); CharacterDatabase.ExecuteOrAppend(trans, stmt); }
//mute player for some times bool ChatHandler::HandleMuteCommand(const char* args) { std::string announce; char* nameStr; char* delayStr; extractOptFirstArg((char*)args, &nameStr, &delayStr); if (!delayStr) return false; char *mutereason = strtok(NULL, "\r"); std::string mutereasonstr = "No reason"; if (mutereason != NULL) mutereasonstr = mutereason; if(!mutereason) { PSendSysMessage("You must enter a reason of mute"); SetSentErrorMessage(true); return false; } Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name)) return false; uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid); // find only player from same account if any if (!target) if (WorldSession* session = sWorld->FindSession(accountId)) target = session->GetPlayer(); uint32 notspeaktime = (uint32) atoi(delayStr); // must have strong lesser security level if (HasLowerSecurity (target, target_guid, true)) return false; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); if (target) { // Target is online, mute will be in effect right away. int64 muteTime = time(NULL) + notspeaktime * MINUTE; target->GetSession()->m_muteTime = muteTime; stmt->setInt64(0, muteTime); ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime, mutereasonstr.c_str()); } else { // Target is offline, mute will be in effect starting from the next login. int32 muteTime = -int32(notspeaktime * MINUTE); stmt->setInt64(0, muteTime); } stmt->setUInt32(1, accountId); LoginDatabase.Execute(stmt); std::string nameLink = playerLink(target_name); PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notspeaktime, mutereasonstr.c_str()); announce = "The character '"; announce += nameStr; announce += "' was muted for "; announce += delayStr; announce += " minutes by the character '"; announce += m_session->GetPlayerName(); announce += "'. The reason is: "; announce += mutereason; HandleAnnounceCommand(announce.c_str()); return true; }
void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSession, PreparedQueryResult result) { // Stop if the account is not found if (!result) { // We can not log here, as we do not know the account. Thus, no accountId. SendAuthResponseError(AUTH_UNKNOWN_ACCOUNT); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); DelayedCloseSocket(); return; } AccountInfo account(result->Fetch()); // For hook purposes, we get Remoteaddress at this point. std::string address = GetRemoteIpAddress().to_string(); // As we don't know if attempted login process by ip works, we update last_attempt_ip right away PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_ATTEMPT_IP); stmt->setString(0, address); stmt->setString(1, authSession->Account); LoginDatabase.Execute(stmt); // This also allows to check for possible "hack" attempts on account // even if auth credentials are bad, try using the session key we have - client cannot read auth response error without it _authCrypt.Init(&account.SessionKey); // First reject the connection if packet contains invalid data or realm state doesn't allow logging in if (sWorld->IsClosed()) { SendAuthResponseError(AUTH_REJECT); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: World closed, denying client (%s).", GetRemoteIpAddress().to_string().c_str()); DelayedCloseSocket(); return; } if (authSession->RealmID != realmID) { SendAuthResponseError(REALM_LIST_REALM_NOT_FOUND); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (bad realm)."); DelayedCloseSocket(); return; } // Must be done before WorldSession is created bool wardenActive = sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED); if (wardenActive && account.OS != "Win" && account.OS != "OSX") { SendAuthResponseError(AUTH_REJECT); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Client %s attempted to log in using invalid client OS (%s).", address.c_str(), account.OS.c_str()); DelayedCloseSocket(); return; } // Check that Key and account name are the same on client and server uint32 t = 0; SHA1Hash sha; sha.UpdateData(authSession->Account); sha.UpdateData((uint8*)&t, 4); sha.UpdateData((uint8*)&authSession->LocalChallenge, 4); sha.UpdateData((uint8*)&_authSeed, 4); sha.UpdateBigNumbers(&account.SessionKey, NULL); sha.Finalize(); if (memcmp(sha.GetDigest(), authSession->Digest, SHA_DIGEST_LENGTH) != 0) { SendAuthResponseError(AUTH_FAILED); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", account.Id, authSession->Account.c_str(), address.c_str()); DelayedCloseSocket(); return; } ///- Re-check ip locking (same check as in auth). if (account.IsLockedToIP) { if (account.LastIP != address) { SendAuthResponseError(AUTH_FAILED); TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs. Original IP: %s, new IP: %s).", account.LastIP.c_str(), address.c_str()); // We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well sScriptMgr->OnFailedAccountLogin(account.Id); DelayedCloseSocket(); return; } } else if (!account.LockCountry.empty() && account.LockCountry != "00" && !_ipCountry.empty()) { if (account.LockCountry != _ipCountry) { SendAuthResponseError(AUTH_FAILED); TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account country differs. Original country: %s, new country: %s).", account.LockCountry.c_str(), _ipCountry.c_str()); // We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well sScriptMgr->OnFailedAccountLogin(account.Id); DelayedCloseSocket(); return; } } int64 mutetime = account.MuteTime; //! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now. if (mutetime < 0) { mutetime = time(NULL) + llabs(mutetime); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME_LOGIN); stmt->setInt64(0, mutetime); stmt->setUInt32(1, account.Id); LoginDatabase.Execute(stmt); } if (account.IsBanned) { SendAuthResponseError(AUTH_BANNED); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); sScriptMgr->OnFailedAccountLogin(account.Id); DelayedCloseSocket(); return; } // Check locked state for server AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit(); TC_LOG_DEBUG("network", "Allowed Level: %u Player Level %u", allowedAccountType, account.Security); if (allowedAccountType > SEC_PLAYER && account.Security < allowedAccountType) { SendAuthResponseError(AUTH_UNAVAILABLE); TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); sScriptMgr->OnFailedAccountLogin(account.Id); DelayedCloseSocket(); return; } TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", authSession->Account.c_str(), address.c_str()); // Update the last_ip in the database as it was successful for login stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_IP); stmt->setString(0, address); stmt->setString(1, authSession->Account); LoginDatabase.Execute(stmt); // At this point, we can safely hook a successful login sScriptMgr->OnAccountLogin(account.Id); _authed = true; _worldSession = new WorldSession(account.Id, std::move(authSession->Account), shared_from_this(), account.Security, account.Expansion, mutetime, account.Locale, account.Recruiter, account.IsRectuiter); _worldSession->ReadAddonsInfo(authSession->AddonInfo); // Initialize Warden system only if it is enabled by config if (wardenActive) _worldSession->InitWarden(&account.SessionKey, account.OS); _queryCallback = io_service().wrap(std::bind(&WorldSocket::LoadSessionPermissionsCallback, this, std::placeholders::_1)); _queryFuture = _worldSession->LoadPermissionsAsync(); AsyncRead(); }
void WorldSocket::HandleAuthSession(WorldPacket& recvPacket) { uint8 digest[SHA_DIGEST_LENGTH]; uint32 clientSeed; uint8 security; uint32 id; LocaleConstant locale; std::string account; bool isPremium = false; SHA1Hash sha; uint32 clientBuild; uint32 serverId, loginServerType, region, battlegroup, realmIndex; uint64 unk4; WorldPacket packet, SendAddonPacked; BigNumber k; bool wardenActive = sWorld->getBoolConfig(CONFIG_WARDEN_ENABLED); // Read the content of the packet recvPacket >> clientBuild; recvPacket >> serverId; // Used for GRUNT only recvPacket >> account; recvPacket >> loginServerType; // 0 GRUNT, 1 Battle.net recvPacket >> clientSeed; recvPacket >> region >> battlegroup; // Used for Battle.net only recvPacket >> realmIndex; // realmId from auth_database.realmlist table recvPacket >> unk4; recvPacket.read(digest, 20); TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: client %u, serverId %u, account %s, loginServerType %u, clientseed %u, realmIndex %u", clientBuild, serverId, account.c_str(), loginServerType, clientSeed, realmIndex); // Get the account information from the auth database // 0 1 2 3 4 5 6 7 8 // SELECT id, sessionkey, last_ip, locked, expansion, mutetime, locale, recruiter, os FROM account WHERE username = ? PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME); stmt->setString(0, account); PreparedQueryResult result = LoginDatabase.Query(stmt); // Stop if the account is not found if (!result) { // We can not log here, as we do not know the account. Thus, no accountId. SendAuthResponseError(AUTH_UNKNOWN_ACCOUNT); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (unknown account)."); DelayedCloseSocket(); return; } Field* fields = result->Fetch(); uint8 expansion = fields[4].GetUInt8(); uint32 world_expansion = sWorld->getIntConfig(CONFIG_EXPANSION); if (expansion > world_expansion) expansion = world_expansion; // For hook purposes, we get Remoteaddress at this point. std::string address = GetRemoteIpAddress().to_string(); // As we don't know if attempted login process by ip works, we update last_attempt_ip right away stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_ATTEMPT_IP); stmt->setString(0, address); stmt->setString(1, account); LoginDatabase.Execute(stmt); // This also allows to check for possible "hack" attempts on account // id has to be fetched at this point, so that first actual account response that fails can be logged id = fields[0].GetUInt32(); k.SetHexStr(fields[1].GetCString()); // even if auth credentials are bad, try using the session key we have - client cannot read auth response error without it _authCrypt.Init(&k); // First reject the connection if packet contains invalid data or realm state doesn't allow logging in if (sWorld->IsClosed()) { SendAuthResponseError(AUTH_REJECT); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: World closed, denying client (%s).", GetRemoteIpAddress().to_string().c_str()); DelayedCloseSocket(); return; } if (realmIndex != realmID) { SendAuthResponseError(REALM_LIST_REALM_NOT_FOUND); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (bad realm)."); DelayedCloseSocket(); return; } std::string os = fields[8].GetString(); // Must be done before WorldSession is created if (wardenActive && os != "Win" && os != "OSX") { SendAuthResponseError(AUTH_REJECT); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Client %s attempted to log in using invalid client OS (%s).", address.c_str(), os.c_str()); DelayedCloseSocket(); return; } // Check that Key and account name are the same on client and server uint32 t = 0; sha.UpdateData(account); sha.UpdateData((uint8*)&t, 4); sha.UpdateData((uint8*)&clientSeed, 4); sha.UpdateData((uint8*)&_authSeed, 4); sha.UpdateBigNumbers(&k, NULL); sha.Finalize(); if (memcmp(sha.GetDigest(), digest, SHA_DIGEST_LENGTH) != 0) { SendAuthResponseError(AUTH_FAILED); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Authentication failed for account: %u ('%s') address: %s", id, account.c_str(), address.c_str()); DelayedCloseSocket(); return; } ///- Re-check ip locking (same check as in auth). if (fields[3].GetUInt8() == 1) // if ip is locked { if (strcmp(fields[2].GetCString(), address.c_str()) != 0) { SendAuthResponseError(AUTH_FAILED); TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account IP differs. Original IP: %s, new IP: %s).", fields[2].GetCString(), address.c_str()); // We could log on hook only instead of an additional db log, however action logger is config based. Better keep DB logging as well sScriptMgr->OnFailedAccountLogin(id); DelayedCloseSocket(); return; } } int64 mutetime = fields[5].GetInt64(); //! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now. if (mutetime < 0) { mutetime = time(NULL) + llabs(mutetime); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME_LOGIN); stmt->setInt64(0, mutetime); stmt->setUInt32(1, id); LoginDatabase.Execute(stmt); } locale = LocaleConstant(fields[6].GetUInt8()); if (locale >= TOTAL_LOCALES) locale = LOCALE_enUS; uint32 recruiter = fields[7].GetUInt32(); // Checks gmlevel per Realm stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_GMLEVEL_BY_REALMID); stmt->setUInt32(0, id); stmt->setInt32(1, int32(realmID)); result = LoginDatabase.Query(stmt); if (!result) security = 0; else { fields = result->Fetch(); security = fields[0].GetUInt8(); } // Re-check account ban (same check as in auth) stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BANS); stmt->setUInt32(0, id); stmt->setString(1, address); PreparedQueryResult banresult = LoginDatabase.Query(stmt); if (banresult) // if account banned { SendAuthResponseError(AUTH_BANNED); TC_LOG_ERROR("network", "WorldSocket::HandleAuthSession: Sent Auth Response (Account banned)."); sScriptMgr->OnFailedAccountLogin(id); DelayedCloseSocket(); return; } // Check premium stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_PREMIUM); stmt->setUInt32(0, id); PreparedQueryResult premresult = LoginDatabase.Query(stmt); if (premresult) { isPremium = true; } // Check locked state for server AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit(); TC_LOG_DEBUG("network", "Allowed Level: %u Player Level %u", allowedAccountType, AccountTypes(security)); if (allowedAccountType > SEC_PLAYER && AccountTypes(security) < allowedAccountType) { SendAuthResponseError(AUTH_UNAVAILABLE); TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: User tries to login but his security level is not enough"); sScriptMgr->OnFailedAccountLogin(id); DelayedCloseSocket(); return; } TC_LOG_DEBUG("network", "WorldSocket::HandleAuthSession: Client '%s' authenticated successfully from %s.", account.c_str(), address.c_str()); // Check if this user is by any chance a recruiter stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_ACCOUNT_RECRUITER); stmt->setUInt32(0, id); result = LoginDatabase.Query(stmt); bool isRecruiter = false; if (result) isRecruiter = true; // Update the last_ip in the database as it was successful for login stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LAST_IP); stmt->setString(0, address); stmt->setString(1, account); LoginDatabase.Execute(stmt); // At this point, we can safely hook a successful login sScriptMgr->OnAccountLogin(id); _authed = true; _worldSession = new WorldSession(id, shared_from_this(), AccountTypes(security), isPremium, expansion, mutetime, locale, recruiter, isRecruiter); _worldSession->LoadGlobalAccountData(); _worldSession->LoadTutorialsData(); _worldSession->ReadAddonsInfo(recvPacket); _worldSession->LoadPermissions(); // Initialize Warden system only if it is enabled by config if (wardenActive) _worldSession->InitWarden(&k, os); sWorld->AddSession(_worldSession); }
//mute player for some times bool ChatHandler::HandleMuteCommand(const char* args) { char* nameStr; char* delayStr; extractOptFirstArg((char*)args, &nameStr, &delayStr); if (!delayStr) return false; char *mutereason = strtok(NULL, "\r"); std::string mutereasonstr = "No reason"; if (mutereason != NULL) mutereasonstr = mutereason; mutereasonstr = mutereasonstr + " - Наказал - " + m_session->GetPlayer()->GetName(); Player* target; uint64 target_guid; std::string target_name; if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name)) return false; uint32 accountId = target ? target->GetSession()->GetAccountId() : sObjectMgr->GetPlayerAccountIdByGUID(target_guid); // find only player from same account if any if (!target) if (WorldSession* session = sWorld->FindSession(accountId)) target = session->GetPlayer(); uint32 notspeaktime = (uint32) atoi(delayStr); // must have strong lesser security level if (HasLowerSecurity (target, target_guid, true)) return false; PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME); if (target) { // Target is online, mute will be in effect right away. int64 muteTime = time(NULL) + notspeaktime * MINUTE; target->GetSession()->m_muteTime = muteTime; stmt->setInt64(0, muteTime); ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime, mutereasonstr.c_str()); } else { // Target is offline, mute will be in effect starting from the next login. int32 muteTime = -int32(notspeaktime * MINUTE); stmt->setInt64(0, muteTime); } stmt->setUInt32(1, accountId); LoginDatabase.Execute(stmt); std::string nameLink = playerLink(target_name); if (sWorld->getBoolConfig(CONFIG_SHOW_MUTE_IN_WORLD)) sWorld->SendWorldText(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notspeaktime, mutereasonstr.c_str()); else PSendSysMessage(target ? LANG_YOU_DISABLE_CHAT : LANG_COMMAND_DISABLE_CHAT_DELAYED, nameLink.c_str(), notspeaktime, mutereasonstr.c_str()); return true; }