From 722a6c143ae9adbab020df4bae4495e612a677ee Mon Sep 17 00:00:00 2001 From: Ascathor Date: Thu, 25 Jul 2013 01:49:04 +0200 Subject: Core/Account: Make account password change security variable and various changes Settings within worldserver.conf: Three settings for secruity level: 0 - None - No change to current system 1 - Email - Always requires the email entered on registration for confirming. 2 - RBAC - Groups applied with the RBAC role always require the email entered on registration for confirming. RBAC default to every group. Changed some logs to make it more clear what is going on at all. Emails may now no longer exceed 64 chars. Current email is used as regmail. On account creation, two emails are saved. Registration email and normal email. Normal email is relevant afterwards. Registration email can be changed by console ONLY. Includes new commands and changes to existing ones: .account fulfills several new functions: * Still prints GM Level. * If account has permission, it displays the current email. This is not defaulted to any group. * Security level is displayed. Also displays if user has RBAC perm if RBAC security mode is selected .account email allows user to change email with sufficient confirmation .account set sec email allows higher sec with higher sec than account to change the normal email. Registrationemail remains untouched here. .account set sec regmail allows console to change registration email. .pinfo now displays the registration and normal mail. Also fixes .learn all crafts. Closes #10558 --- src/server/scripts/Commands/cs_account.cpp | 358 +++++++++++++++++++++++++++-- src/server/scripts/Commands/cs_learn.cpp | 8 +- src/server/scripts/Commands/cs_misc.cpp | 60 ++--- 3 files changed, 372 insertions(+), 54 deletions(-) (limited to 'src/server/scripts/Commands') diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp index 42e33faee1c..467b74f4954 100644 --- a/src/server/scripts/Commands/cs_account.cpp +++ b/src/server/scripts/Commands/cs_account.cpp @@ -35,35 +35,43 @@ public: ChatCommand* GetCommands() const OVERRIDE { + static ChatCommand accountSetSecTable[] = + { + { "regmail", RBAC_PERM_COMMAND_ACCOUNT_SET_SEC_REGMAIL, true, &HandleAccountSetRegEmailCommand, "", NULL }, + { "email", RBAC_PERM_COMMAND_ACCOUNT_SET_SEC_EMAIL, true, &HandleAccountSetEmailCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } + }; static ChatCommand accountSetCommandTable[] = { - { "addon", RBAC_PERM_COMMAND_ACCOUNT_SET_ADDON, true, &HandleAccountSetAddonCommand, "", NULL }, - { "gmlevel", RBAC_PERM_COMMAND_ACCOUNT_SET_GMLEVEL, true, &HandleAccountSetGmLevelCommand, "", NULL }, - { "password", RBAC_PERM_COMMAND_ACCOUNT_SET_PASSWORD, true, &HandleAccountSetPasswordCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } + { "addon", RBAC_PERM_COMMAND_ACCOUNT_SET_ADDON, true, &HandleAccountSetAddonCommand, "", NULL }, + { "sec", RBAC_PERM_COMMAND_ACCOUNT_SET_SEC, true, NULL, "", accountSetSecTable }, + { "gmlevel", RBAC_PERM_COMMAND_ACCOUNT_SET_GMLEVEL, true, &HandleAccountSetGmLevelCommand, "", NULL }, + { "password", RBAC_PERM_COMMAND_ACCOUNT_SET_PASSWORD, true, &HandleAccountSetPasswordCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand accountLockCommandTable[] = { - { "country", RBAC_PERM_COMMAND_ACCOUNT_LOCK_COUNTRY, true, &HandleAccountLockCountryCommand, "", NULL }, - { "ip", RBAC_PERM_COMMAND_ACCOUNT_LOCK_IP, true, &HandleAccountLockIpCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } + { "country", RBAC_PERM_COMMAND_ACCOUNT_LOCK_COUNTRY, true, &HandleAccountLockCountryCommand, "", NULL }, + { "ip", RBAC_PERM_COMMAND_ACCOUNT_LOCK_IP, true, &HandleAccountLockIpCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand accountCommandTable[] = { - { "addon", RBAC_PERM_COMMAND_ACCOUNT_ADDON, false, &HandleAccountAddonCommand, "", NULL }, - { "create", RBAC_PERM_COMMAND_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "", NULL }, - { "delete", RBAC_PERM_COMMAND_ACCOUNT_DELETE, true, &HandleAccountDeleteCommand, "", NULL }, - { "onlinelist", RBAC_PERM_COMMAND_ACCOUNT_ONLINE_LIST, true, &HandleAccountOnlineListCommand, "", NULL }, - { "lock", RBAC_PERM_COMMAND_ACCOUNT_LOCK, false, NULL, "", accountLockCommandTable }, - { "set", RBAC_PERM_COMMAND_ACCOUNT_SET, true, NULL, "", accountSetCommandTable }, - { "password", RBAC_PERM_COMMAND_ACCOUNT_PASSWORD, false, &HandleAccountPasswordCommand, "", NULL }, - { "", RBAC_PERM_COMMAND_ACCOUNT, false, &HandleAccountCommand, "", NULL }, - { NULL, 0, false, NULL, "", NULL } + { "addon", RBAC_PERM_COMMAND_ACCOUNT_ADDON, false, &HandleAccountAddonCommand, "", NULL }, + { "create", RBAC_PERM_COMMAND_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "", NULL }, + { "delete", RBAC_PERM_COMMAND_ACCOUNT_DELETE, true, &HandleAccountDeleteCommand, "", NULL }, + { "email", RBAC_PERM_COMMAND_ACCOUNT_EMAIL, false, &HandleAccountEmailCommand, "", NULL }, + { "onlinelist", RBAC_PERM_COMMAND_ACCOUNT_ONLINE_LIST, true, &HandleAccountOnlineListCommand, "", NULL }, + { "lock", RBAC_PERM_COMMAND_ACCOUNT_LOCK, false, NULL, "", accountLockCommandTable }, + { "set", RBAC_PERM_COMMAND_ACCOUNT_SET, true, NULL, "", accountSetCommandTable }, + { "password", RBAC_PERM_COMMAND_ACCOUNT_PASSWORD, false, &HandleAccountPasswordCommand, "", NULL }, + { "", RBAC_PERM_COMMAND_ACCOUNT, false, &HandleAccountCommand, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand commandTable[] = { - { "account", RBAC_PERM_COMMAND_ACCOUNT, true, NULL, "", accountCommandTable }, - { NULL, 0, false, NULL, "", NULL } + { "account", RBAC_PERM_COMMAND_ACCOUNT, true, NULL, "", accountCommandTable }, + { NULL, 0, false, NULL, "", NULL } }; return commandTable; } @@ -106,29 +114,35 @@ public: if (!*args) return false; + char* email; + ///- %Parse the command line arguments char* accountName = strtok((char*)args, " "); char* password = strtok(NULL, " "); + if (!(email = strtok(NULL, " '"))) + email = ""; + if (!accountName || !password) return false; - AccountOpResult result = sAccountMgr->CreateAccount(std::string(accountName), std::string(password)); + AccountOpResult result = sAccountMgr->CreateAccount(std::string(accountName), std::string(password), std::string(email)); switch (result) { case AOR_OK: handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName); if (handler->GetSession()) { - TC_LOG_INFO(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Character:[%s] (GUID: %u) Change Password.", + TC_LOG_INFO(LOG_FILTER_CHARACTER, "Account: %d (IP: %s) Character:[%s] (GUID: %u) created Account %s (Email: '%s')", handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), - handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow()); + handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(), + accountName, email); } break; case AOR_NAME_TOO_LONG: handler->SendSysMessage(LANG_ACCOUNT_TOO_LONG); handler->SetSentErrorMessage(true); return false; - case AOR_NAME_ALREDY_EXIST: + case AOR_NAME_ALREADY_EXIST: handler->SendSysMessage(LANG_ACCOUNT_ALREADY_EXIST); handler->SetSentErrorMessage(true); return false; @@ -338,6 +352,89 @@ public: return false; } + static bool HandleAccountEmailCommand(ChatHandler* handler, char const* args) + { + if (!*args) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + char* oldEmail = strtok(NULL, " "); + char* password = strtok(NULL, " "); + char* email = strtok((char*)args, " "); + char* emailConfirmation = strtok(NULL, " "); + + if (!oldEmail || !password || !email || !emailConfirmation) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + if (!AccountMgr::CheckEmail(handler->GetSession()->GetAccountId(), std::string(oldEmail))) + { + handler->SendSysMessage(LANG_COMMAND_WRONGEMAIL); + handler->SetSentErrorMessage(true); + TC_LOG_INFO(LOG_FILTER_CHARACTER, "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change email, but the provided email [%s] is not equal to registration email [%s].", + handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), + handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(), + email, oldEmail); + return false; + } + + if (!AccountMgr::CheckPassword(handler->GetSession()->GetAccountId(), std::string(password))) + { + handler->SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD); + handler->SetSentErrorMessage(true); + TC_LOG_INFO(LOG_FILTER_CHARACTER, "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change email, but the provided password is wrong.", + handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), + handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow()); + return false; + } + + if (strcmp(email, oldEmail) == 0) + { + handler->SendSysMessage(LANG_OLD_EMAIL_IS_NEW_EMAIL); + handler->SetSentErrorMessage(true); + return false; + } + + if (strcmp(email, emailConfirmation) != 0) + { + handler->SendSysMessage(LANG_NEW_EMAILS_NOT_MATCH); + handler->SetSentErrorMessage(true); + TC_LOG_INFO(LOG_FILTER_CHARACTER, "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change email, but the provided password is wrong.", + handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), + handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow()); + return false; + } + + + AccountOpResult result = AccountMgr::ChangeEmail(handler->GetSession()->GetAccountId(), std::string(email)); + switch (result) + { + case AOR_OK: + handler->SendSysMessage(LANG_COMMAND_EMAIL); + TC_LOG_INFO(LOG_FILTER_CHARACTER, "Account: %u (IP: %s) Character:[%s] (GUID: %u) Changed Email from [%s] to [%s].", + handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), + handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(), + oldEmail, email); + break; + case AOR_EMAIL_TOO_LONG: + handler->SendSysMessage(LANG_EMAIL_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + default: + handler->SendSysMessage(LANG_COMMAND_NOTCHANGEEMAIL); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } + static bool HandleAccountPasswordCommand(ChatHandler* handler, char const* args) { if (!*args) @@ -347,9 +444,12 @@ public: return false; } + uint32 pwConfig = sWorld->getIntConfig(CONFIG_ACC_PASSCHANGESEC); // 0 - PW_NONE, 1 - PW_EMAIL, 2 - PW_RBAC + char* oldPassword = strtok((char*)args, " "); char* newPassword = strtok(NULL, " "); char* passwordConfirmation = strtok(NULL, " "); + char* emailConfirmation = strtok(NULL, " "); if (!oldPassword || !newPassword || !passwordConfirmation) { @@ -358,16 +458,37 @@ public: return false; } + if ((pwConfig == PW_EMAIL || pwConfig == PW_RBAC && handler->HasPermission(RBAC_PERM_EMAIL_CONFIRM_FOR_PASS_CHANGE)) && !emailConfirmation) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + TC_LOG_INFO(LOG_FILTER_CHARACTER, "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change password, but entered no email at all. Has Perm: [%s]", + handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), + handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(), + handler->HasPermission(RBAC_PERM_EMAIL_CONFIRM_FOR_PASS_CHANGE) ? "Yes" : "No"); + } + if (!AccountMgr::CheckPassword(handler->GetSession()->GetAccountId(), std::string(oldPassword))) { handler->SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD); handler->SetSentErrorMessage(true); - TC_LOG_INFO(LOG_FILTER_CHARACTER, "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change password.", + TC_LOG_INFO(LOG_FILTER_CHARACTER, "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change password, but the provided old password is wrong.", handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow()); return false; } + if ((pwConfig == PW_EMAIL || pwConfig == PW_RBAC && handler->HasPermission(RBAC_PERM_EMAIL_CONFIRM_FOR_PASS_CHANGE)) // Either PW_EMAIL or PW_RBAC with the Permission + && !AccountMgr::CheckEmail(handler->GetSession()->GetAccountId(), std::string(emailConfirmation))) + { + handler->SendSysMessage(LANG_COMMAND_WRONGEMAIL); + handler->SetSentErrorMessage(true); + TC_LOG_INFO(LOG_FILTER_CHARACTER, "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change password, but the entered email [%s] is wrong.", + handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(), + handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(), + emailConfirmation); + } + if (strcmp(newPassword, passwordConfirmation) != 0) { handler->SendSysMessage(LANG_NEW_PASSWORDS_NOT_MATCH); @@ -399,8 +520,40 @@ public: static bool HandleAccountCommand(ChatHandler* handler, char const* /*args*/) { + // GM Level AccountTypes gmLevel = handler->GetSession()->GetSecurity(); handler->PSendSysMessage(LANG_ACCOUNT_LEVEL, uint32(gmLevel)); + + // Security level required + bool hasRBAC = (handler->HasPermission(RBAC_PERM_EMAIL_CONFIRM_FOR_PASS_CHANGE) ? true : false); + uint32 pwConfig = sWorld->getIntConfig(CONFIG_ACC_PASSCHANGESEC); // 0 - PW_NONE, 1 - PW_EMAIL, 2 - PW_RBAC + + handler->PSendSysMessage(LANG_ACCOUNT_SEC_TYPE, (pwConfig == PW_NONE ? "Lowest level: No Email input required." : + pwConfig == PW_EMAIL ? "Highest level: Email input required." : + pwConfig == PW_RBAC ? "Special level: Your account may require email input depending on settings. That is the case if another lien is printed." : + "Unknown security level: Notify technician for details.")); + + // RBAC required display - is not displayed for console + if (pwConfig == PW_RBAC && handler->GetSession() && hasRBAC) + handler->PSendSysMessage(LANG_RBAC_EMAIL_REQUIRED); + + // Email display if sufficient rights + if (handler->HasPermission(RBAC_PERM_MAY_CHECK_OWN_EMAIL)) + { + std::string emailoutput; + uint32 accountId = handler->GetSession()->GetAccountId(); + + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_GET_EMAIL_BY_ID); + stmt->setUInt32(0, accountId); + PreparedQueryResult result = LoginDatabase.Query(stmt); + + if (result) + { + emailoutput = (*result)[0].GetString(); + handler->PSendSysMessage(LANG_COMMAND_EMAIL_OUTPUT, emailoutput.c_str()); + } + } + return true; } @@ -471,7 +624,11 @@ public: static bool HandleAccountSetGmLevelCommand(ChatHandler* handler, char const* args) { if (!*args) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); return false; + } std::string targetAccountName; uint32 targetAccountId = 0; @@ -524,7 +681,7 @@ public: playerSecurity = SEC_CONSOLE; // can set security level only for target with less security and to less security that we have - // This is also reject self apply in fact + // This also restricts setting handler's own security. targetSecurity = AccountMgr::GetSecurity(targetAccountId, gmRealmID); if (targetSecurity >= playerSecurity || gm >= playerSecurity) { @@ -570,7 +727,11 @@ public: static bool HandleAccountSetPasswordCommand(ChatHandler* handler, char const* args) { if (!*args) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); return false; + } ///- Get the command line arguments char* account = strtok((char*)args, " "); @@ -597,7 +758,7 @@ public: } /// can set password only for target with less security - /// This is also reject self apply in fact + /// This also restricts setting handler's own password if (handler->HasLowerSecurityAccount(NULL, targetAccountId, true)) return false; @@ -630,6 +791,153 @@ public: } return true; } + + /// Set normal email for account + static bool HandleAccountSetEmailCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + ///- Get the command line arguments + char* account = strtok((char*)args, " "); + char* email = strtok(NULL, " "); + char* emailConfirmation = strtok(NULL, " "); + + if (!account || !email || !emailConfirmation) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + std::string accountName = account; + if (!AccountMgr::normalizeString(accountName)) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 targetAccountId = AccountMgr::GetId(accountName); + if (!targetAccountId) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + /// can set email only for target with less security + /// This also restricts setting handler's own email. + if (handler->HasLowerSecurityAccount(NULL, targetAccountId, true)) + return false; + + if (strcmp(email, emailConfirmation) != 0) + { + handler->SendSysMessage(LANG_NEW_EMAILS_NOT_MATCH); + handler->SetSentErrorMessage(true); + return false; + } + + AccountOpResult result = AccountMgr::ChangeEmail(targetAccountId, email); + switch (result) + { + case AOR_OK: + handler->SendSysMessage(LANG_COMMAND_EMAIL); + TC_LOG_INFO(LOG_FILTER_CHARACTER, "ChangeEmail: Account %s [Id: %u] had it's email changed to %s.", + accountName.c_str(), targetAccountId, email); + break; + case AOR_NAME_NOT_EXIST: + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + case AOR_EMAIL_TOO_LONG: + handler->SendSysMessage(LANG_EMAIL_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + default: + handler->SendSysMessage(LANG_COMMAND_NOTCHANGEEMAIL); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } + + /// Change registration email for account + static bool HandleAccountSetRegEmailCommand(ChatHandler* handler, char const* args) + { + if (!*args) + return false; + + //- We do not want anything short of console to use this by default. + //- So we force that. + if (handler->GetSession()) + return false; + + ///- Get the command line arguments + char* account = strtok((char*)args, " "); + char* email = strtok(NULL, " "); + char* emailConfirmation = strtok(NULL, " "); + + if (!account || !email || !emailConfirmation) + { + handler->SendSysMessage(LANG_CMD_SYNTAX); + handler->SetSentErrorMessage(true); + return false; + } + + std::string accountName = account; + if (!AccountMgr::normalizeString(accountName)) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + uint32 targetAccountId = AccountMgr::GetId(accountName); + if (!targetAccountId) + { + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + } + + /// can set email only for target with less security + /// This also restricts setting handler's own email. + if (handler->HasLowerSecurityAccount(NULL, targetAccountId, true)) + return false; + + if (strcmp(email, emailConfirmation) != 0) + { + handler->SendSysMessage(LANG_NEW_EMAILS_NOT_MATCH); + handler->SetSentErrorMessage(true); + return false; + } + + AccountOpResult result = AccountMgr::ChangeRegEmail(targetAccountId, email); + switch (result) + { + case AOR_OK: + handler->SendSysMessage(LANG_COMMAND_EMAIL); + TC_LOG_INFO(LOG_FILTER_CHARACTER, "ChangeRegEmail: Account %s [Id: %u] had it's Registration Email changed to %s.", + accountName.c_str(), targetAccountId, email); + break; + case AOR_NAME_NOT_EXIST: + handler->PSendSysMessage(LANG_ACCOUNT_NOT_EXIST, accountName.c_str()); + handler->SetSentErrorMessage(true); + return false; + case AOR_EMAIL_TOO_LONG: + handler->SendSysMessage(LANG_EMAIL_TOO_LONG); + handler->SetSentErrorMessage(true); + return false; + default: + handler->SendSysMessage(LANG_COMMAND_NOTCHANGEEMAIL); + handler->SetSentErrorMessage(true); + return false; + } + + return true; + } }; void AddSC_account_commandscript() diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp index f2ff911fdf9..c165eebe3b5 100644 --- a/src/server/scripts/Commands/cs_learn.cpp +++ b/src/server/scripts/Commands/cs_learn.cpp @@ -339,8 +339,12 @@ public: return true; } - static bool HandleLearnAllCraftsCommand(ChatHandler* handler, char const* /*args*/) + static bool HandleLearnAllCraftsCommand(ChatHandler* handler, char const* args) { + Player* target; + if (!handler->extractPlayerTarget((char*)args, &target)) + return false; + for (uint32 i = 0; i < sSkillLineStore.GetNumRows(); ++i) { SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(i); @@ -350,7 +354,7 @@ public: if ((skillInfo->categoryId == SKILL_CATEGORY_PROFESSION || skillInfo->categoryId == SKILL_CATEGORY_SECONDARY) && skillInfo->canLink) // only prof. with recipes have { - HandleLearnSkillRecipesHelper(handler->GetSession()->GetPlayer(), skillInfo->id); + HandleLearnSkillRecipesHelper(target, skillInfo->id); } } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index ee31542c53a..9c29e31af96 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1520,20 +1520,21 @@ public: * ** Muted: (Time, Reason, By) - IV. LANG_PINFO_MUTED (if muted) * * Account: %s (id: %u), GM Level: %u - V. LANG_PINFO_ACC_ACCOUNT * * Last Login: %u (Failed Logins: %u) - VI. LANG_PINFO_ACC_LASTLOGIN - * * Uses OS: %s - Latency: %u ms - Email %s - VII. LANG_PINFO_ACC_OS - * * Last IP: %u (Locked: %s) - VIII. LANG_PINFO_ACC_IP - * * Level: %u (%u/%u XP (%u XP left) - IX. LANG_PINFO_CHR_LEVEL - * * Race: %s %s, Class %s - X. LANG_PINFO_CHR_RACE - * * Alive ?: %s - XI. LANG_PINFO_CHR_ALIVE - * * Phase: %s - XII. LANG_PINFO_CHR_PHASE (if not GM) - * * Money: %ug%us%uc - XIII. LANG_PINFO_CHR_MONEY - * * Map: %s, Area: %s - XIV. LANG_PINFO_CHR_MAP - * * Guild: %s (Id: %u) - XV. LANG_PINFO_CHR_GUILD (if in guild) - * ** Rank: %s - XVI. LANG_PINFO_CHR_GUILD_RANK (if in guild) - * ** Note: %s - XVII. LANG_PINFO_CHR_GUILD_NOTE (if in guild and has note) - * ** O. Note: %s - XVIII.LANG_PINFO_CHR_GUILD_ONOTE (if in guild and has officer note) - * * Played time: %s - XIX. LANG_PINFO_CHR_PLAYEDTIME - * * Mails: %u Read/%u Total - XX. LANG_PINFO_CHR_MAILS (if has mails) + * * Uses OS: %s - Latency: %u ms - VII. LANG_PINFO_ACC_OS + * * Registration Email: %s - Email: %s - VIII. LANG_PINFO_ACC_REGMAILS + * * Last IP: %u (Locked: %s) - IX. LANG_PINFO_ACC_IP + * * Level: %u (%u/%u XP (%u XP left) - X. LANG_PINFO_CHR_LEVEL + * * Race: %s %s, Class %s - XI. LANG_PINFO_CHR_RACE + * * Alive ?: %s - XII. LANG_PINFO_CHR_ALIVE + * * Phase: %s - XIII. LANG_PINFO_CHR_PHASE (if not GM) + * * Money: %ug%us%uc - XIV. LANG_PINFO_CHR_MONEY + * * Map: %s, Area: %s - XV. LANG_PINFO_CHR_MAP + * * Guild: %s (Id: %u) - XVI. LANG_PINFO_CHR_GUILD (if in guild) + * ** Rank: %s - XVII. LANG_PINFO_CHR_GUILD_RANK (if in guild) + * ** Note: %s - XVIII.LANG_PINFO_CHR_GUILD_NOTE (if in guild and has note) + * ** O. Note: %s - XVIX. LANG_PINFO_CHR_GUILD_ONOTE (if in guild and has officer note) + * * Played time: %s - XX. LANG_PINFO_CHR_PLAYEDTIME + * * Mails: %u Read/%u Total - XXI. LANG_PINFO_CHR_MAILS (if has mails) * * Not all of them can be moved to the top. These should * place the most important ones to the head, though. @@ -1546,6 +1547,7 @@ public: uint32 accId = 0; uint32 lowguid = GUID_LOPART(targetGuid); std::string eMail = handler->GetTrinityString(LANG_ERROR); + std::string regMail = handler->GetTrinityString(LANG_ERROR); uint32 security = 0; std::string lastIp = handler->GetTrinityString(LANG_ERROR); uint8 locked = 0; @@ -1666,8 +1668,9 @@ public: (!handler->GetSession() || handler->GetSession()->GetSecurity() >= AccountTypes(security))) { eMail = fields[2].GetString(); - lastIp = fields[3].GetString(); - lastLogin = fields[4].GetString(); + regMail = fields[3].GetString(); + lastIp = fields[4].GetString(); + lastLogin = fields[5].GetString(); uint32 ip = inet_addr(lastIp.c_str()); EndianConvertReverse(ip); @@ -1689,12 +1692,12 @@ public: lastIp = "Unauthorized"; lastLogin = "Unauthorized"; } - muteTime = fields[5].GetUInt64(); - muteReason = fields[6].GetString(); - muteBy = fields[7].GetString(); - failedLogins = fields[8].GetUInt32(); - locked = fields[9].GetUInt8(); - OS = fields[10].GetString(); + muteTime = fields[6].GetUInt64(); + muteReason = fields[7].GetString(); + muteBy = fields[8].GetString(); + failedLogins = fields[9].GetUInt32(); + locked = fields[10].GetUInt8(); + OS = fields[11].GetString(); } // Creates a chat link to the character. Returns nameLink @@ -1783,8 +1786,11 @@ public: // Output VI. LANG_PINFO_ACC_LASTLOGIN handler->PSendSysMessage(LANG_PINFO_ACC_LASTLOGIN, lastLogin.c_str(), failedLogins); - // Output VIII. LANG_PINFO_ACC_OS - handler->PSendSysMessage(LANG_PINFO_ACC_OS, OS.c_str(), latency, eMail.c_str()); + // Output VII. LANG_PINFO_ACC_OS + handler->PSendSysMessage(LANG_PINFO_ACC_OS, OS.c_str(), latency); + + // Output VIII. LANG_PINFO_ACC_REGMAILS + handler->PSendSysMessage(LANG_PINFO_ACC_REGMAILS, regMail.c_str(), eMail.c_str()); // Output IX. LANG_PINFO_ACC_IP handler->PSendSysMessage(LANG_PINFO_ACC_IP, lastIp.c_str(), locked ? "Yes" : "No"); @@ -1828,7 +1834,7 @@ public: if (target) handler->PSendSysMessage(LANG_PINFO_CHR_MAP, map->name[locale], (!zoneName.empty() ? zoneName.c_str() : ""), (!areaName.empty() ? areaName.c_str() : "")); - // Output XVII. - XX. if they are not empty + // Output XVII. - XVIX. if they are not empty if (!guildName.empty()) { handler->PSendSysMessage(LANG_PINFO_CHR_GUILD, guildName.c_str(), guildId); @@ -1839,7 +1845,7 @@ public: handler->PSendSysMessage(LANG_PINFO_CHR_GUILD_ONOTE, officeNote.c_str()); } - // Output XXI. LANG_PINFO_CHR_PLAYEDTIME + // Output XX. LANG_PINFO_CHR_PLAYEDTIME handler->PSendSysMessage(LANG_PINFO_CHR_PLAYEDTIME, (secsToTimeString(totalPlayerTime, true, true)).c_str()); // Mail Data - an own query, because it may or may not be useful. @@ -1861,7 +1867,7 @@ public: // ... we have to convert it from Char to int. We can use totalmail as it is rmailint = atol(readmail.c_str()); - // Output XXII. LANG_INFO_CHR_MAILS if at least one mail is given + // Output XXI. LANG_INFO_CHR_MAILS if at least one mail is given if (totalmail >= 1) handler->PSendSysMessage(LANG_PINFO_CHR_MAILS, rmailint, totalmail); } -- cgit v1.2.3