mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[9767] Add the posibility to keep deleted characters in the database for a while and also add related commands.
Added commands: * .character deleted list [$guid|$name] * .character deleted restore $guid|$name [$newname] * .character deleted delete $guid|$name * .character deleted old [$keepdays] Command .character delete renamed to .character erase Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
parent
c9ac685f04
commit
492ce567d2
22 changed files with 701 additions and 151 deletions
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
DROP TABLE IF EXISTS `character_db_version`;
|
||||
CREATE TABLE `character_db_version` (
|
||||
`required_9751_01_characters` bit(1) default NULL
|
||||
`required_9767_03_characters_characters` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
|
||||
|
||||
--
|
||||
|
|
@ -256,6 +256,10 @@ CREATE TABLE `characters` (
|
|||
`ammoId` int(10) UNSIGNED NOT NULL default '0',
|
||||
`knownTitles` longtext,
|
||||
`actionBars` tinyint(3) UNSIGNED NOT NULL default '0',
|
||||
`deleteInfos_Account` int(11) UNSIGNED default,
|
||||
`deleteInfos_Name` varchar(12) default NULL,
|
||||
`deleteDate` bigint(20) default NULL,
|
||||
|
||||
PRIMARY KEY (`guid`),
|
||||
KEY `idx_account` (`account`),
|
||||
KEY `idx_online` (`online`),
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
|
|||
`version` varchar(120) default NULL,
|
||||
`creature_ai_version` varchar(120) default NULL,
|
||||
`cache_id` int(10) default '0',
|
||||
`required_9766_01_mangos_spell_proc_event` bit(1) default NULL
|
||||
`required_9767_02_mangos_command` bit(1) default NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
|
||||
|
||||
--
|
||||
|
|
@ -451,6 +451,7 @@ CREATE TABLE `battleground_template` (
|
|||
|
||||
LOCK TABLES `battleground_template` WRITE;
|
||||
/*!40000 ALTER TABLE `battleground_template` DISABLE KEYS */;
|
||||
INSERT INTO `battleground_template` VALUES
|
||||
(1,40,40,611,2.72532,610,2.27452),
|
||||
(2,10,10,769,3.14159,770,3.14159),
|
||||
(3,15,15,890,3.40156,889,0.263892),
|
||||
|
|
@ -535,7 +536,11 @@ INSERT INTO `command` VALUES
|
|||
('cast self',3,'Syntax: .cast self #spellid [triggered]\r\nCast #spellid by target at target itself. If \'trigered\' or part provided then spell casted with triggered flag.'),
|
||||
('cast target',3,'Syntax: .cast target #spellid [triggered]\r\n Selected target will cast #spellid to his victim. If \'trigered\' or part provided then spell casted with triggered flag.'),
|
||||
('character customize',2,'Syntax: .character customize [$name]\r\n\r\nMark selected in game or by $name in command character for customize at next login.'),
|
||||
('character delete',4,'Syntax: .character delete $name\r\n\r\nDelete character $name.'),
|
||||
('character deleted delete', 4, 'Syntax: .character deleted delete $guid|$name\r\n\r\nCompletely deletes the selected characters.\r\nIf $name is supplied, only characters with that string in their name will be deleted, if $guid is supplied, only the character with that GUID will be deleted.'),
|
||||
('character deleted list', 3, 'Syntax: .character deleted list [$guid|$name]\r\n\r\nShows a list with all deleted characters.\r\nIf $name is supplied, only characters with that string in their name will be selected, if $guid is supplied, only the character with that GUID will be selected.'),
|
||||
('character deleted old', 4, 'Syntax: .character deleted old [$keepDays]\r\n\r\nCompletely deletes all characters with deleted time longer $keepDays. If $keepDays not provided the used value from mangosd.conf option \'CharDelete.KeepDays\'. If referenced config option disabled (use 0 value) then command can\'t be used without $keepDays.'),
|
||||
('character deleted restore', 3, 'Syntax: .character deleted restore #guid|$name [$newname] [#new account]\r\n\r\nRestores deleted characters.\r\nIf $name is supplied, only characters with that string in their name will be restored, if $guid is supplied, only the character with that GUID will be restored.\r\nIf $newname is set, the character will be restored with that name instead of the original one. If #newaccount is set, the character will be restored to specific account character list. This works only with one character!'),
|
||||
('character erase',4,'Syntax: .character erase $name\r\n\r\nDelete character $name. Character finally deleted in case any deleting options.'),
|
||||
('character level',3,'Syntax: .character level [$playername] [#level]\r\n\r\nSet the level of character with $playername (or the selected if not name provided) by #numberoflevels Or +1 if no #numberoflevels provided). If #numberoflevels is omitted, the level will be increase by 1. If #numberoflevels is 0, the same level will be restarted. If no character is selected and name not provided, increase your level. Command can be used for offline character. All stats and dependent values recalculated. At level decrease talents can be reset if need. Also at level decrease equipped items with greater level requirement can be lost.'),
|
||||
('character rename',2,'Syntax: .character rename [$name]\r\n\r\nMark selected in game or by $name in command character for rename at next login.'),
|
||||
('character reputation',2,'Syntax: .character reputation [$player_name]\r\n\r\nShow reputation information for selected player or player find by $player_name.'),
|
||||
|
|
@ -3576,6 +3581,17 @@ INSERT INTO `mangos_string` VALUES
|
|||
(1013,'|%15s| %20s | %15s |%4d| %9d |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1014,'No online players.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1015,'Used not fully typed quit command, need type it fully (quit), or command used not in RA command line.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1016, '| GUID | Name | Account | Delete Date |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1017, '| %10u | %20s | %15s (%10u) | %19s |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1018, '==========================================================================================',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1019, 'No characters found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1020, 'Restoring the following characters:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1021, 'Deleting the following characters:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1022, 'ERROR: You can only assign a new name if you have only selected a single character!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1023, 'Character \'%s\' (GUID: %u Account %u) can\'t be restored: account not exist!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1024, 'Character \'%s\' (GUID: %u Account %u) can\'t be restored: account character list full!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1025, 'Character \'%s\' (GUID: %u Account %u) can\'t be restored: new name already used!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1026, 'GUID: %u Name: %s Account: %s (%u) Date: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1100,'Account %s (Id: %u) have up to %u expansion allowed now.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1101,'Message of the day changed to:\r\n%s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1102,'Message sent to %s: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
|
|
|
|||
15
sql/updates/9767_01_mangos_mangos_string.sql
Normal file
15
sql/updates/9767_01_mangos_mangos_string.sql
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_9766_01_mangos_spell_proc_event required_9767_01_mangos_mangos_string bit;
|
||||
|
||||
DELETE FROM mangos_string WHERE entry IN (1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026);
|
||||
INSERT INTO mangos_string VALUES
|
||||
(1016, '| GUID | Name | Account | Delete Date |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1017, '| %10u | %20s | %15s (%10u) | %19s |',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1018, '==========================================================================================',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1019, 'No characters found.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1020, 'Restoring the following characters:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1021, 'Deleting the following characters:',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1022, 'ERROR: You can only assign a new name if you have only selected a single character!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1023, 'Character \'%s\' (GUID: %u Account %u) can\'t be restored: account not exist!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1024, 'Character \'%s\' (GUID: %u Account %u) can\'t be restored: account character list full!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1025, 'Character \'%s\' (GUID: %u Account %u) can\'t be restored: new name already used!',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
|
||||
(1026, 'GUID: %u Name: %s Account: %s (%u) Date: %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
|
||||
9
sql/updates/9767_02_mangos_command.sql
Normal file
9
sql/updates/9767_02_mangos_command.sql
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
ALTER TABLE db_version CHANGE COLUMN required_9767_01_mangos_mangos_string required_9767_02_mangos_command bit;
|
||||
|
||||
DELETE FROM command WHERE name IN('character delete', 'character deleted list', 'character deleted restore', 'character deleted delete', 'character deleted old', 'character erase');
|
||||
INSERT INTO command (name, security, help) VALUES
|
||||
('character erase',4,'Syntax: .character erase $name\r\n\r\nDelete character $name. Character finally deleted in case any deleting options.'),
|
||||
('character deleted delete', 4, 'Syntax: .character deleted delete $guid|$name\r\n\r\nCompletely deletes the selected characters.\r\nIf $name is supplied, only characters with that string in their name will be deleted, if $guid is supplied, only the character with that GUID will be deleted.'),
|
||||
('character deleted list', 3, 'Syntax: .character deleted list [$guid|$name]\r\n\r\nShows a list with all deleted characters.\r\nIf $name is supplied, only characters with that string in their name will be selected, if $guid is supplied, only the character with that GUID will be selected.'),
|
||||
('character deleted old', 4, 'Syntax: .character deleted old [$keepDays]\r\n\r\nCompletely deletes all characters with deleted time longer $keepDays. If $keepDays not provided the used value from mangosd.conf option \'CharDelete.KeepDays\'. If referenced config option disabled (use 0 value) then command can\'t be used without $keepDays.'),
|
||||
('character deleted restore', 3, 'Syntax: .character deleted restore #guid|$name [$newname] [#new account]\r\n\r\nRestores deleted characters.\r\nIf $name is supplied, only characters with that string in their name will be restored, if $guid is supplied, only the character with that GUID will be restored.\r\nIf $newname is set, the character will be restored with that name instead of the original one. If #newaccount is set, the character will be restored to specific account character list. This works only with one character!');
|
||||
6
sql/updates/9767_03_characters_characters.sql
Normal file
6
sql/updates/9767_03_characters_characters.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
ALTER TABLE character_db_version CHANGE COLUMN required_9751_01_characters required_9767_03_characters_characters bit;
|
||||
|
||||
ALTER TABLE `characters`
|
||||
ADD COLUMN `deleteInfos_Account` int(11) UNSIGNED default NULL AFTER actionBars,
|
||||
ADD COLUMN `deleteInfos_Name` varchar(12) default NULL AFTER deleteInfos_Account,
|
||||
ADD COLUMN `deleteDate` bigint(20) default NULL AFTER deleteInfos_Name;
|
||||
|
|
@ -128,6 +128,9 @@ pkgdata_DATA = \
|
|||
9761_01_mangos_mangos_string.sql \
|
||||
9763_01_mangos_battleground_template.sql \
|
||||
9766_01_mangos_spell_proc_event.sql \
|
||||
9767_01_mangos_mangos_string.sql \
|
||||
9767_02_mangos_command.sql \
|
||||
9767_03_characters_characters.sql \
|
||||
README
|
||||
|
||||
## Additional files to include when running 'make dist'
|
||||
|
|
@ -236,4 +239,7 @@ EXTRA_DIST = \
|
|||
9761_01_mangos_mangos_string.sql \
|
||||
9763_01_mangos_battleground_template.sql \
|
||||
9766_01_mangos_spell_proc_event.sql \
|
||||
9767_01_mangos_mangos_string.sql \
|
||||
9767_02_mangos_command.sql \
|
||||
9767_03_characters_characters.sql \
|
||||
README
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
|
|||
return AOR_NAME_NOT_EXIST; // account doesn't exist
|
||||
delete result;
|
||||
|
||||
// existed chaarcters list
|
||||
result = CharacterDatabase.PQuery("SELECT guid FROM characters WHERE account='%d'",accid);
|
||||
if (result)
|
||||
{
|
||||
|
|
@ -182,6 +183,21 @@ bool AccountMgr::GetName(uint32 acc_id, std::string &name)
|
|||
return false;
|
||||
}
|
||||
|
||||
uint32 AccountMgr::GetCharactersCount(uint32 acc_id)
|
||||
{
|
||||
// check character count
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%d'", acc_id);
|
||||
if (result)
|
||||
{
|
||||
Field *fields=result->Fetch();
|
||||
uint32 charcount = fields[0].GetUInt32();
|
||||
delete result;
|
||||
return charcount;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
|
||||
{
|
||||
std::string username;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ class AccountMgr
|
|||
uint32 GetId(std::string username);
|
||||
AccountTypes GetSecurity(uint32 acc_id);
|
||||
bool GetName(uint32 acc_id, std::string &name);
|
||||
uint32 GetCharactersCount(uint32 acc_id);
|
||||
std::string CalculateShaPassHash(std::string& name, std::string& password);
|
||||
|
||||
static bool normalizeString(std::string& utf8str);
|
||||
|
|
|
|||
|
|
@ -116,10 +116,20 @@ ChatCommand * ChatHandler::getCommandTable()
|
|||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
|
||||
static ChatCommand characterDeletedCommandTable[] =
|
||||
{
|
||||
{ "delete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeletedDeleteCommand, "", NULL },
|
||||
{ "list", SEC_ADMINISTRATOR, true, &ChatHandler::HandleCharacterDeletedListCommand,"", NULL },
|
||||
{ "restore", SEC_ADMINISTRATOR, true, &ChatHandler::HandleCharacterDeletedRestoreCommand,"", NULL },
|
||||
{ "old", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeletedOldCommand, "", NULL },
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
|
||||
static ChatCommand characterCommandTable[] =
|
||||
{
|
||||
{ "customize", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterCustomizeCommand, "", NULL },
|
||||
{ "delete", SEC_CONSOLE, true, &ChatHandler::HandleCharacterDeleteCommand, "", NULL },
|
||||
{ "deleted", SEC_GAMEMASTER, true, NULL, "", characterDeletedCommandTable},
|
||||
{ "erase", SEC_CONSOLE, true, &ChatHandler::HandleCharacterEraseCommand, "", NULL },
|
||||
{ "level", SEC_ADMINISTRATOR, true, &ChatHandler::HandleCharacterLevelCommand, "", NULL },
|
||||
{ "rename", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterRenameCommand, "", NULL },
|
||||
{ "reputation", SEC_GAMEMASTER, true, &ChatHandler::HandleCharacterReputationCommand, "", NULL },
|
||||
|
|
@ -598,7 +608,7 @@ ChatCommand * ChatHandler::getCommandTable()
|
|||
{ "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable },
|
||||
{ "debug", SEC_MODERATOR, true, NULL, "", debugCommandTable },
|
||||
{ "tele", SEC_MODERATOR, true, NULL, "", teleCommandTable },
|
||||
{ "character", SEC_GAMEMASTER, false, NULL, "", characterCommandTable},
|
||||
{ "character", SEC_GAMEMASTER, true, NULL, "", characterCommandTable},
|
||||
{ "event", SEC_GAMEMASTER, false, NULL, "", eventCommandTable },
|
||||
{ "gobject", SEC_GAMEMASTER, false, NULL, "", gobjectCommandTable },
|
||||
{ "honor", SEC_GAMEMASTER, false, NULL, "", honorCommandTable },
|
||||
|
|
|
|||
|
|
@ -125,7 +125,11 @@ class ChatHandler
|
|||
bool HandleCastTargetCommand(const char *args);
|
||||
|
||||
bool HandleCharacterCustomizeCommand(const char * args);
|
||||
bool HandleCharacterDeleteCommand(const char* args);
|
||||
bool HandleCharacterDeletedDeleteCommand(const char* args);
|
||||
bool HandleCharacterDeletedListCommand(const char* args);
|
||||
bool HandleCharacterDeletedRestoreCommand(const char* args);
|
||||
bool HandleCharacterDeletedOldCommand(const char* args);
|
||||
bool HandleCharacterEraseCommand(const char* args);
|
||||
bool HandleCharacterLevelCommand(const char* args);
|
||||
bool HandleCharacterRenameCommand(const char * args);
|
||||
bool HandleCharacterReputationCommand(const char* args);
|
||||
|
|
@ -546,6 +550,24 @@ class ChatHandler
|
|||
void HandleLearnSkillRecipesHelper(Player* player,uint32 skill_id);
|
||||
void ShowSpellListHelper(Player* target, SpellEntry const* spellInfo, LocaleConstant loc);
|
||||
|
||||
/**
|
||||
* Stores informations about a deleted character
|
||||
*/
|
||||
struct DeletedInfo
|
||||
{
|
||||
uint32 lowguid; ///< the low GUID from the character
|
||||
std::string name; ///< the character name
|
||||
uint32 accountId; ///< the account id
|
||||
std::string accountName; ///< the account name
|
||||
time_t deleteDate; ///< the date at which the character has been deleted
|
||||
};
|
||||
|
||||
typedef std::list<DeletedInfo> DeletedInfoList;
|
||||
bool GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString = "");
|
||||
std::string GenerateDeletedCharacterGUIDsWhereStr(DeletedInfoList::const_iterator& itr, DeletedInfoList::const_iterator& itr_end);
|
||||
void HandleCharacterDeletedListHelper(DeletedInfoList const& foundList);
|
||||
void HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo);
|
||||
|
||||
void SetSentErrorMessage(bool val){ sentErrorMessage = val;};
|
||||
private:
|
||||
WorldSession * m_session; // != NULL for chat command call and NULL for CLI command
|
||||
|
|
|
|||
|
|
@ -781,7 +781,18 @@ enum MangosStrings
|
|||
LANG_ACCOUNT_LIST_LINE = 1013,
|
||||
LANG_ACCOUNT_LIST_EMPTY = 1014,
|
||||
LANG_QUIT_WRONG_USE_ERROR = 1015,
|
||||
// Room for more level 4 1016-1099 not used
|
||||
LANG_CHARACTER_DELETED_LIST_HEADER = 1016,
|
||||
LANG_CHARACTER_DELETED_LIST_LINE_CONSOLE = 1017,
|
||||
LANG_CHARACTER_DELETED_LIST_BAR = 1018,
|
||||
LANG_CHARACTER_DELETED_LIST_EMPTY = 1019,
|
||||
LANG_CHARACTER_DELETED_RESTORE = 1020,
|
||||
LANG_CHARACTER_DELETED_DELETE = 1021,
|
||||
LANG_CHARACTER_DELETED_ERR_RENAME = 1022,
|
||||
LANG_CHARACTER_DELETED_SKIP_ACCOUNT = 1023,
|
||||
LANG_CHARACTER_DELETED_SKIP_FULL = 1024,
|
||||
LANG_CHARACTER_DELETED_SKIP_NAME = 1025,
|
||||
LANG_CHARACTER_DELETED_LIST_LINE_CHAT = 1026,
|
||||
// Room for more level 4 1027-1099 not used
|
||||
|
||||
// Level 3 (continue)
|
||||
LANG_ACCOUNT_SETADDON = 1100,
|
||||
|
|
|
|||
|
|
@ -5627,7 +5627,7 @@ bool ChatHandler::HandlePDumpWriteCommand(const char *args)
|
|||
|
||||
uint32 guid;
|
||||
// character name can't start from number
|
||||
if (isNumeric(p2[0]))
|
||||
if (isNumeric(p2))
|
||||
guid = atoi(p2);
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4037,8 +4037,31 @@ TrainerSpellState Player::GetTrainerSpellState(TrainerSpell const* trainer_spell
|
|||
return TRAINER_SPELL_GREEN;
|
||||
}
|
||||
|
||||
void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars)
|
||||
/**
|
||||
* Deletes a character from the database
|
||||
*
|
||||
* The way, how the characters will be deleted is decided based on the config option.
|
||||
*
|
||||
* @see Player::DeleteOldCharacters
|
||||
*
|
||||
* @param playerguid the low-GUID from the player which should be deleted
|
||||
* @param accountId the account id from the player
|
||||
* @param updateRealmChars when this flag is set, the amount of characters on that realm will be updated in the realmlist
|
||||
* @param deleteFinally if this flag is set, the config option will be ignored and the character will be permanently removed from the database
|
||||
*/
|
||||
void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars, bool deleteFinally)
|
||||
{
|
||||
// for not existed account avoid update realm
|
||||
if (accountId == 0)
|
||||
updateRealmChars = false;
|
||||
|
||||
uint32 charDelete_method = sWorld.getConfig(CONFIG_UINT32_CHARDELETE_METHOD);
|
||||
uint32 charDelete_minLvl = sWorld.getConfig(CONFIG_UINT32_CHARDELETE_MIN_LEVEL);
|
||||
|
||||
// if we want to finally delete the character or the character does not meet the level requirement, we set it to mode 0
|
||||
if (deleteFinally || Player::GetLevelFromDB(playerguid) < charDelete_minLvl)
|
||||
charDelete_method = 0;
|
||||
|
||||
uint32 guid = GUID_LOPART(playerguid);
|
||||
|
||||
// convert corpse to bones if exist (to prevent exiting Corpse in World without DB entry)
|
||||
|
|
@ -4046,13 +4069,9 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
|||
sObjectAccessor.ConvertCorpseForPlayer(playerguid);
|
||||
|
||||
// remove from guild
|
||||
uint32 guildId = GetGuildIdFromDB(playerguid);
|
||||
if(guildId != 0)
|
||||
{
|
||||
Guild* guild = sObjectMgr.GetGuildById(guildId);
|
||||
if(guild)
|
||||
if (uint32 guildId = GetGuildIdFromDB(playerguid))
|
||||
if (Guild* guild = sObjectMgr.GetGuildById(guildId))
|
||||
guild->DelMember(guid);
|
||||
}
|
||||
|
||||
// remove from arena teams
|
||||
LeaveAllArenaTeams(playerguid);
|
||||
|
|
@ -4070,6 +4089,11 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
|||
// remove signs from petitions (also remove petitions if owner);
|
||||
RemovePetitionsAndSigns(playerguid, 10);
|
||||
|
||||
switch(charDelete_method)
|
||||
{
|
||||
// completely remove from the database
|
||||
case 0:
|
||||
{
|
||||
// return back all mails with COD and Item 0 1 2 3 4 5 6 7
|
||||
QueryResult *resultMail = CharacterDatabase.PQuery("SELECT id,messageType,mailTemplateId,sender,subject,body,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid);
|
||||
if (resultMail)
|
||||
|
|
@ -4200,9 +4224,56 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
|
|||
CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE PlayerGuid1 = '%u' OR PlayerGuid2 = '%u'",guid, guid);
|
||||
CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE PlayerGuid = '%u'",guid);
|
||||
CharacterDatabase.CommitTransaction();
|
||||
break;
|
||||
}
|
||||
// The character gets unlinked from the account, the name gets freed up and appears as deleted ingame
|
||||
case 1:
|
||||
CharacterDatabase.PExecute("UPDATE characters SET deleteInfos_Name=name, deleteInfos_Account=account, deleteDate=%u, name='', account=0 WHERE guid=%u", uint64(time(NULL)), guid);
|
||||
break;
|
||||
default:
|
||||
sLog.outError("Player::DeleteFromDB: Unsupported delete method: %u.", charDelete_method);
|
||||
}
|
||||
|
||||
//loginDatabase.PExecute("UPDATE realmcharacters SET numchars = numchars - 1 WHERE acctid = %d AND realmid = %d", accountId, realmID);
|
||||
if(updateRealmChars) sWorld.UpdateRealmCharCount(accountId);
|
||||
if (updateRealmChars)
|
||||
sWorld.UpdateRealmCharCount(accountId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Characters which were kept back in the database after being deleted and are now too old (see config option "CharDelete.KeepDays"), will be completely deleted.
|
||||
*
|
||||
* @see Player::DeleteFromDB
|
||||
*/
|
||||
void Player::DeleteOldCharacters()
|
||||
{
|
||||
uint32 keepDays = sWorld.getConfig(CONFIG_UINT32_CHARDELETE_KEEP_DAYS);
|
||||
if (!keepDays)
|
||||
return;
|
||||
|
||||
Player::DeleteOldCharacters(keepDays);
|
||||
}
|
||||
|
||||
/**
|
||||
* Characters which were kept back in the database after being deleted and are older than the specified amount of days, will be completely deleted.
|
||||
*
|
||||
* @see Player::DeleteFromDB
|
||||
*
|
||||
* @param keepDays overrite the config option by another amount of days
|
||||
*/
|
||||
void Player::DeleteOldCharacters(uint32 keepDays)
|
||||
{
|
||||
sLog.outString("Player::DeleteOldChars: Deleting all characters which have been deleted %u days before...", keepDays);
|
||||
|
||||
QueryResult *resultChars = CharacterDatabase.PQuery("SELECT guid, deleteInfos_Account FROM characters WHERE deleteDate IS NOT NULL AND deleteDate < %u", uint64(time(NULL) - time_t(keepDays * DAY)));
|
||||
if (resultChars)
|
||||
{
|
||||
sLog.outString("Player::DeleteOldChars: Found %u character(s) to delete",resultChars->GetRowCount());
|
||||
do
|
||||
{
|
||||
Field *charFields = resultChars->Fetch();
|
||||
Player::DeleteFromDB(charFields[0].GetUInt64(), charFields[1].GetUInt32(), true, true);
|
||||
} while(resultChars->NextRow());
|
||||
delete resultChars;
|
||||
}
|
||||
}
|
||||
|
||||
void Player::SetMovement(PlayerMovementType pType)
|
||||
|
|
|
|||
|
|
@ -1454,6 +1454,10 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
static void Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair);
|
||||
static void SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint32 zone,uint64 guid);
|
||||
|
||||
static void DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars = true, bool deleteFinally = false);
|
||||
static void DeleteOldCharacters();
|
||||
static void DeleteOldCharacters(uint32 keepDays);
|
||||
|
||||
bool m_mailsUpdated;
|
||||
|
||||
void SendPetTameFailure(PetTameFailureReason reason);
|
||||
|
|
@ -1832,8 +1836,6 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
// overwrite Object::SendMessageToSetInRange
|
||||
void SendMessageToSetInRange(WorldPacket *data, float dist, bool self, bool own_team_only);
|
||||
|
||||
static void DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmChars = true);
|
||||
|
||||
Corpse *GetCorpse() const;
|
||||
void SpawnCorpseBones();
|
||||
Corpse* CreateCorpse();
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "Database/SQLStorage.h"
|
||||
#include "UpdateFields.h"
|
||||
#include "ObjectMgr.h"
|
||||
#include "AccountMgr.h"
|
||||
|
||||
// Character Dump tables
|
||||
struct DumpTable
|
||||
|
|
@ -394,19 +395,9 @@ DumpReturn PlayerDumpWriter::WriteDump(const std::string& file, uint32 guid)
|
|||
DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, std::string name, uint32 guid)
|
||||
{
|
||||
// check character count
|
||||
{
|
||||
QueryResult *result = CharacterDatabase.PQuery("SELECT COUNT(guid) FROM characters WHERE account = '%d'", account);
|
||||
uint8 charcount = 0;
|
||||
if (result)
|
||||
{
|
||||
Field *fields=result->Fetch();
|
||||
charcount = fields[0].GetUInt8();
|
||||
delete result;
|
||||
|
||||
uint32 charcount = sAccountMgr.GetCharactersCount(account);
|
||||
if (charcount >= 10)
|
||||
return DUMP_TOO_MANY_CHARS;
|
||||
}
|
||||
}
|
||||
|
||||
FILE *fin = fopen(file.c_str(), "r");
|
||||
if (!fin)
|
||||
|
|
|
|||
|
|
@ -827,6 +827,11 @@ void World::LoadConfigSettings(bool reload)
|
|||
m_MaxVisibleDistanceInFlight = MAX_VISIBILITY_DISTANCE - m_VisibleObjectGreyDistance;
|
||||
}
|
||||
|
||||
///- Load the CharDelete related config options
|
||||
setConfigMinMax(CONFIG_UINT32_CHARDELETE_METHOD, "CharDelete.Method", 0, 0, 1);
|
||||
setConfigMinMax(CONFIG_UINT32_CHARDELETE_MIN_LEVEL, "CharDelete.MinLevel", 0, 0, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL));
|
||||
setConfigPos(CONFIG_UINT32_CHARDELETE_KEEP_DAYS, "CharDelete.KeepDays", 30);
|
||||
|
||||
///- Read the "Data" directory from the config file
|
||||
std::string dataPath = sConfig.GetStringDefault("DataDir","./");
|
||||
if( dataPath.at(dataPath.length()-1)!='/' && dataPath.at(dataPath.length()-1)!='\\' )
|
||||
|
|
@ -1237,6 +1242,7 @@ void World::SetInitialWorldSettings()
|
|||
m_timers[WUPDATE_UPTIME].SetInterval(m_configUint32Values[CONFIG_UINT32_UPTIME_UPDATE]*MINUTE*IN_MILLISECONDS);
|
||||
//Update "uptime" table based on configuration entry in minutes.
|
||||
m_timers[WUPDATE_CORPSES].SetInterval(3*HOUR*IN_MILLISECONDS);
|
||||
m_timers[WUPDATE_DELETECHARS].SetInterval(DAY*IN_MILLISECONDS); // check for chars to delete every day
|
||||
|
||||
//to set mailtimer to return mails every day between 4 and 5 am
|
||||
//mailtimer is increased when updating auctions
|
||||
|
|
@ -1279,6 +1285,9 @@ void World::SetInitialWorldSettings()
|
|||
uint32 nextGameEvent = sGameEventMgr.Initialize();
|
||||
m_timers[WUPDATE_EVENTS].SetInterval(nextGameEvent); //depend on next event
|
||||
|
||||
// Delete all characters which have been deleted X days before
|
||||
Player::DeleteOldCharacters();
|
||||
|
||||
sLog.outString( "WORLD: World initialized" );
|
||||
|
||||
uint32 uStartInterval = getMSTimeDiff(uStartTime, getMSTime());
|
||||
|
|
@ -1423,6 +1432,13 @@ void World::Update(uint32 diff)
|
|||
sBattleGroundMgr.Update(diff);
|
||||
}
|
||||
|
||||
///- Delete all characters which have been deleted X days before
|
||||
if (m_timers[WUPDATE_DELETECHARS].Passed())
|
||||
{
|
||||
m_timers[WUPDATE_DELETECHARS].Reset();
|
||||
Player::DeleteOldCharacters();
|
||||
}
|
||||
|
||||
// execute callbacks from sql queries that were queued recently
|
||||
UpdateResultQueue();
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,8 @@ enum WorldTimers
|
|||
WUPDATE_UPTIME = 4,
|
||||
WUPDATE_CORPSES = 5,
|
||||
WUPDATE_EVENTS = 6,
|
||||
WUPDATE_COUNT = 7
|
||||
WUPDATE_DELETECHARS = 7,
|
||||
WUPDATE_COUNT = 8
|
||||
};
|
||||
|
||||
/// Configuration elements
|
||||
|
|
@ -177,6 +178,9 @@ enum eConfigUInt32Values
|
|||
CONFIG_UINT32_TIMERBAR_FIRE_GMLEVEL,
|
||||
CONFIG_UINT32_TIMERBAR_FIRE_MAX,
|
||||
CONFIG_UINT32_MIN_LEVEL_STAT_SAVE,
|
||||
CONFIG_UINT32_CHARDELETE_KEEP_DAYS,
|
||||
CONFIG_UINT32_CHARDELETE_METHOD,
|
||||
CONFIG_UINT32_CHARDELETE_MIN_LEVEL,
|
||||
CONFIG_UINT32_VALUE_COUNT
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,322 @@ bool ChatHandler::HandleAccountDeleteCommand(const char* args)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleCharacterDeleteCommand(const char* args)
|
||||
/**
|
||||
* Collects all GUIDs (and related info) from deleted characters which are still in the database.
|
||||
*
|
||||
* @param foundList a reference to an std::list which will be filled with info data
|
||||
* @param searchString the search string which either contains a player GUID or a part fo the character-name
|
||||
* @return returns false if there was a problem while selecting the characters (e.g. player name not normalizeable)
|
||||
*/
|
||||
bool ChatHandler::GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString)
|
||||
{
|
||||
QueryResult* resultChar;
|
||||
if (!searchString.empty())
|
||||
{
|
||||
// search by GUID
|
||||
if (isNumeric(searchString))
|
||||
resultChar = CharacterDatabase.PQuery("SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND guid = %u", uint64(atoi(searchString.c_str())));
|
||||
// search by name
|
||||
else
|
||||
{
|
||||
if(!normalizePlayerName(searchString))
|
||||
return false;
|
||||
|
||||
resultChar = CharacterDatabase.PQuery("SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL AND deleteInfos_Name " _LIKE_ " " _CONCAT3_("'%%'", "'%s'", "'%%'"), searchString.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
resultChar = CharacterDatabase.Query("SELECT guid, deleteInfos_Name, deleteInfos_Account, deleteDate FROM characters WHERE deleteDate IS NOT NULL");
|
||||
|
||||
if (resultChar)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = resultChar->Fetch();
|
||||
|
||||
DeletedInfo info;
|
||||
|
||||
info.lowguid = fields[0].GetUInt32();
|
||||
info.name = fields[1].GetCppString();
|
||||
info.accountId = fields[2].GetUInt32();
|
||||
|
||||
// account name will be empty for not existed account
|
||||
sAccountMgr.GetName (info.accountId, info.accountName);
|
||||
|
||||
info.deleteDate = time_t(fields[3].GetUInt64());
|
||||
|
||||
foundList.push_back(info);
|
||||
} while (resultChar->NextRow());
|
||||
|
||||
delete resultChar;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate WHERE guids list by deleted info in way preventing return too long where list for existed query string length limit.
|
||||
*
|
||||
* @param itr a reference to an deleted info list iterator, it updated in function for possible next function call if list to long
|
||||
* @param itr_end a reference to an deleted info list iterator end()
|
||||
* @return returns generated where list string in form: 'guid IN (gui1, guid2, ...)'
|
||||
*/
|
||||
std::string ChatHandler::GenerateDeletedCharacterGUIDsWhereStr(DeletedInfoList::const_iterator& itr, DeletedInfoList::const_iterator const const& itr_end)
|
||||
{
|
||||
std::ostringstream wherestr;
|
||||
wherestr << "guid IN ('";
|
||||
for(; itr != itr_end; ++itr)
|
||||
{
|
||||
wherestr << itr->lowguid;
|
||||
|
||||
if (wherestr.str().size() > MAX_QUERY_LEN - 50) // near to max query
|
||||
{
|
||||
++itr;
|
||||
break;
|
||||
}
|
||||
|
||||
DeletedInfoList::const_iterator itr2 = itr;
|
||||
if(++itr2 != itr_end)
|
||||
wherestr << "','";
|
||||
}
|
||||
wherestr << "')";
|
||||
return wherestr.str();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows all deleted characters which matches the given search string, expected non empty list
|
||||
*
|
||||
* @see ChatHandler::HandleCharacterDeletedListCommand
|
||||
* @see ChatHandler::HandleCharacterDeletedRestoreCommand
|
||||
* @see ChatHandler::HandleCharacterDeletedDeleteCommand
|
||||
* @see ChatHandler::DeletedInfoList
|
||||
*
|
||||
* @param foundList contains a list with all found deleted characters
|
||||
*/
|
||||
void ChatHandler::HandleCharacterDeletedListHelper(DeletedInfoList const& foundList)
|
||||
{
|
||||
if (!m_session)
|
||||
{
|
||||
SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
|
||||
SendSysMessage(LANG_CHARACTER_DELETED_LIST_HEADER);
|
||||
SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
|
||||
}
|
||||
|
||||
for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
|
||||
{
|
||||
std::string dateStr = TimeToTimestampStr(itr->deleteDate);
|
||||
|
||||
if (!m_session)
|
||||
PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CONSOLE,
|
||||
itr->lowguid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(),
|
||||
itr->accountId, dateStr.c_str());
|
||||
else
|
||||
PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CHAT,
|
||||
itr->lowguid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(),
|
||||
itr->accountId, dateStr.c_str());
|
||||
}
|
||||
|
||||
if (!m_session)
|
||||
SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the '.character deleted list' command, which shows all deleted characters which matches the given search string
|
||||
*
|
||||
* @see ChatHandler::HandleCharacterDeletedListHelper
|
||||
* @see ChatHandler::HandleCharacterDeletedRestoreCommand
|
||||
* @see ChatHandler::HandleCharacterDeletedDeleteCommand
|
||||
* @see ChatHandler::DeletedInfoList
|
||||
*
|
||||
* @param args the search string which either contains a player GUID or a part fo the character-name
|
||||
*/
|
||||
bool ChatHandler::HandleCharacterDeletedListCommand(const char* args)
|
||||
{
|
||||
DeletedInfoList foundList;
|
||||
if (!GetDeletedCharacterInfoList(foundList, args))
|
||||
return false;
|
||||
|
||||
// if no characters have been found, output a warning
|
||||
if (foundList.empty())
|
||||
{
|
||||
SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
|
||||
return false;
|
||||
}
|
||||
|
||||
HandleCharacterDeletedListHelper(foundList);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a previously deleted character
|
||||
*
|
||||
* @see ChatHandler::HandleCharacterDeletedListHelper
|
||||
* @see ChatHandler::HandleCharacterDeletedRestoreCommand
|
||||
* @see ChatHandler::HandleCharacterDeletedDeleteCommand
|
||||
* @see ChatHandler::DeletedInfoList
|
||||
*
|
||||
* @param delInfo the informations about the character which will be restored
|
||||
*/
|
||||
void ChatHandler::HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo)
|
||||
{
|
||||
if (delInfo.accountName.empty()) // account not exist
|
||||
{
|
||||
PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_ACCOUNT, delInfo.name.c_str(), delInfo.lowguid, delInfo.accountId);
|
||||
return;
|
||||
}
|
||||
|
||||
// check character count
|
||||
uint32 charcount = sAccountMgr.GetCharactersCount(delInfo.accountId);
|
||||
if (charcount >= 10)
|
||||
{
|
||||
PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_FULL, delInfo.name.c_str(), delInfo.lowguid, delInfo.accountId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (sObjectMgr.GetPlayerGUIDByName(delInfo.name))
|
||||
{
|
||||
PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_NAME, delInfo.name.c_str(), delInfo.lowguid, delInfo.accountId);
|
||||
return;
|
||||
}
|
||||
|
||||
CharacterDatabase.PExecute("UPDATE characters SET name='%s', account='%u', deleteDate=NULL, deleteInfos_Name=NULL, deleteInfos_Account=NULL WHERE deleteDate IS NOT NULL AND guid = %u",
|
||||
delInfo.name.c_str(), delInfo.accountId, delInfo.lowguid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the '.character deleted restore' command, which restores all deleted characters which matches the given search string
|
||||
*
|
||||
* The command automatically calls '.character deleted list' command with the search string to show all restored characters.
|
||||
*
|
||||
* @see ChatHandler::HandleCharacterDeletedRestoreHelper
|
||||
* @see ChatHandler::HandleCharacterDeletedListCommand
|
||||
* @see ChatHandler::HandleCharacterDeletedDeleteCommand
|
||||
*
|
||||
* @param args the search string which either contains a player GUID or a part of the character-name
|
||||
*/
|
||||
bool ChatHandler::HandleCharacterDeletedRestoreCommand(const char* args)
|
||||
{
|
||||
// It is required to submit at least one argument
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
std::string searchString;
|
||||
std::string newCharName;
|
||||
uint32 newAccount = 0;
|
||||
|
||||
std::stringstream(args) >> searchString >> newCharName >> newAccount;
|
||||
|
||||
DeletedInfoList foundList;
|
||||
if (!GetDeletedCharacterInfoList(foundList, searchString))
|
||||
return false;
|
||||
|
||||
if (foundList.empty())
|
||||
{
|
||||
SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
|
||||
return false;
|
||||
}
|
||||
|
||||
SendSysMessage(LANG_CHARACTER_DELETED_RESTORE);
|
||||
HandleCharacterDeletedListHelper(foundList);
|
||||
|
||||
if (newCharName.empty())
|
||||
{
|
||||
// Drop not existed account cases
|
||||
for (DeletedInfoList::iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
|
||||
HandleCharacterDeletedRestoreHelper(*itr);
|
||||
}
|
||||
else if (foundList.size() == 1 && normalizePlayerName(newCharName))
|
||||
{
|
||||
DeletedInfo delInfo = foundList.front();
|
||||
|
||||
// update name
|
||||
delInfo.name = newCharName;
|
||||
|
||||
// if new account provided update deleted info
|
||||
if (newAccount && newAccount != delInfo.accountId)
|
||||
{
|
||||
delInfo.accountId = newAccount;
|
||||
sAccountMgr.GetName (newAccount, delInfo.accountName);
|
||||
}
|
||||
|
||||
HandleCharacterDeletedRestoreHelper(delInfo);
|
||||
}
|
||||
else
|
||||
SendSysMessage(LANG_CHARACTER_DELETED_ERR_RENAME);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the '.character deleted delete' command, which completely deletes all deleted characters which matches the given search string
|
||||
*
|
||||
* @see Player::GetDeletedCharacterGUIDs
|
||||
* @see Player::DeleteFromDB
|
||||
* @see ChatHandler::HandleCharacterDeletedListCommand
|
||||
* @see ChatHandler::HandleCharacterDeletedRestoreCommand
|
||||
*
|
||||
* @param args the search string which either contains a player GUID or a part fo the character-name
|
||||
*/
|
||||
bool ChatHandler::HandleCharacterDeletedDeleteCommand(const char* args)
|
||||
{
|
||||
// It is required to submit at least one argument
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
DeletedInfoList foundList;
|
||||
if (!GetDeletedCharacterInfoList(foundList, args))
|
||||
return false;
|
||||
|
||||
if (foundList.empty())
|
||||
{
|
||||
SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
|
||||
return false;
|
||||
}
|
||||
|
||||
SendSysMessage(LANG_CHARACTER_DELETED_DELETE);
|
||||
HandleCharacterDeletedListHelper(foundList);
|
||||
|
||||
// Call the appropriate function to delete them (current account for deleted characters is 0)
|
||||
for(DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
|
||||
Player::DeleteFromDB(itr->lowguid, 0, false, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the '.character deleted old' command, which completely deletes all deleted characters deleted with some days ago
|
||||
*
|
||||
* @see Player::DeleteOldCharacters
|
||||
* @see Player::DeleteFromDB
|
||||
* @see ChatHandler::HandleCharacterDeletedDeleteCommand
|
||||
* @see ChatHandler::HandleCharacterDeletedListCommand
|
||||
* @see ChatHandler::HandleCharacterDeletedRestoreCommand
|
||||
*
|
||||
* @param args the search string which either contains a player GUID or a part fo the character-name
|
||||
*/
|
||||
bool ChatHandler::HandleCharacterDeletedOldCommand(const char* args)
|
||||
{
|
||||
int32 keepDays = sWorld.getConfig(CONFIG_UINT32_CHARDELETE_KEEP_DAYS);
|
||||
|
||||
char* px = strtok((char*)args, " ");
|
||||
if (px)
|
||||
{
|
||||
if (!isNumeric(px))
|
||||
return false;
|
||||
|
||||
keepDays = atoi(px);
|
||||
if (keepDays < 0)
|
||||
return false;
|
||||
}
|
||||
// config option value 0 -> disabled and can't be used
|
||||
else if (keepDays <= 0)
|
||||
return false;
|
||||
|
||||
Player::DeleteOldCharacters((uint32)keepDays);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleCharacterEraseCommand(const char* args)
|
||||
{
|
||||
if(!*args)
|
||||
return false;
|
||||
|
|
@ -153,7 +468,7 @@ bool ChatHandler::HandleCharacterDeleteCommand(const char* args)
|
|||
std::string account_name;
|
||||
sAccountMgr.GetName (account_id,account_name);
|
||||
|
||||
Player::DeleteFromDB(character_guid, account_id, true);
|
||||
Player::DeleteFromDB(character_guid, account_id, true, true);
|
||||
PSendSysMessage(LANG_CHARACTER_DELETED,character_name.c_str(),GUID_LOPART(character_guid),account_name.c_str(), account_id);
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1451,3 +1451,29 @@ SOAP.Enabled = 0
|
|||
SOAP.IP = 127.0.0.1
|
||||
SOAP.Port = 7878
|
||||
|
||||
###################################################################################################################
|
||||
# CharDelete.Method
|
||||
# Character deletion behavior
|
||||
# Default: 0 - Completely remove the character from the database
|
||||
# 1 - Unlinking, the character gets unlinked from the account,
|
||||
# the name gets freed up and appears as deleted ingame
|
||||
#
|
||||
# CharDelete.MinLevel
|
||||
# Character gets deleted by CharDelete.Mode=0 when the character
|
||||
# hasn't the specified level yet.
|
||||
# Default: 0 - For all characters the specified mode will be used
|
||||
# 1+ - Only for players which have reached the specified level
|
||||
# will be deleted by the specified mode.
|
||||
# the rest will be deleted by CharDelete.Mode=0
|
||||
#
|
||||
# CharDelete.KeepDays
|
||||
# Define the amount of days for which the characters are kept in the database before
|
||||
# they will be removed
|
||||
# Default: 30
|
||||
# 0 - Don't delete any characters, they stay in the database forever.
|
||||
#
|
||||
###################################################################################################################
|
||||
|
||||
CharDelete.Method = 0
|
||||
CharDelete.MinLevel = 0
|
||||
CharDelete.KeepDays = 30
|
||||
|
|
|
|||
|
|
@ -191,6 +191,15 @@ inline bool isNumericOrSpace(wchar_t wchar)
|
|||
return isNumeric(wchar) || wchar == L' ';
|
||||
}
|
||||
|
||||
inline bool isNumeric(char const* str)
|
||||
{
|
||||
for(char const* c = str; *c; ++c)
|
||||
if (!isNumeric(*c))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool isNumeric(std::string const& str)
|
||||
{
|
||||
for(std::string::const_iterator itr = str.begin(); itr != str.end(); ++itr)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "9766"
|
||||
#define REVISION_NR "9767"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef __REVISION_SQL_H__
|
||||
#define __REVISION_SQL_H__
|
||||
#define REVISION_DB_CHARACTERS "required_9751_01_characters"
|
||||
#define REVISION_DB_MANGOS "required_9766_01_mangos_spell_proc_event"
|
||||
#define REVISION_DB_CHARACTERS "required_9767_03_characters_characters"
|
||||
#define REVISION_DB_MANGOS "required_9767_02_mangos_command"
|
||||
#define REVISION_DB_REALMD "required_9748_01_realmd_realmlist"
|
||||
#endif // __REVISION_SQL_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue