Updated .pdump commands

Deleted (but kept in db) characters cannot be dumped

--HG--
branch : trunk
This commit is contained in:
Shauren
2010-08-02 15:14:47 +02:00
parent b2b9ed4a32
commit b76ceca24f
7 changed files with 60 additions and 23 deletions

View File

@@ -6574,6 +6574,10 @@ bool ChatHandler::HandlePDumpWriteCommand(const char *args)
PSendSysMessage(LANG_FILE_OPEN_FAIL,file);
SetSentErrorMessage(true);
return false;
case DUMP_CHARACTER_DELETED:
PSendSysMessage(LANG_COMMAND_EXPORT_DELETED_CHAR);
SetSentErrorMessage(true);
return false;
default:
PSendSysMessage(LANG_COMMAND_EXPORT_FAILED);
SetSentErrorMessage(true);

View File

@@ -792,7 +792,8 @@ enum TrinityStrings
LANG_RESET_PET_TALENTS_ONLINE = 1127,
LANG_TAXINODE_ENTRY_LIST_CHAT = 1128,
LANG_TAXINODE_ENTRY_LIST_CONSOLE = 1129,
// Room for more level 3 1130-1199 not used
LANG_COMMAND_EXPORT_DELETED_CHAR = 1130,
// Room for more level 3 1131-1199 not used
// Debug commands
LANG_CINEMATIC_NOT_EXIST = 1200,

View File

@@ -530,8 +530,9 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket & recv_data)
if (sLog.IsOutCharDump()) // optimize GetPlayerDump call
{
std::string dump = PlayerDumpWriter().GetDump(GUID_LOPART(guid));
sLog.outCharDump(dump.c_str(),GetAccountId(),GUID_LOPART(guid),name.c_str());
std::string dump;
if (PlayerDumpWriter().GetDump(GUID_LOPART(guid), dump))
sLog.outCharDump(dump.c_str(),GetAccountId(),GUID_LOPART(guid),name.c_str());
}
Player::DeleteFromDB(guid, GetAccountId());

View File

@@ -264,7 +264,7 @@ void StoreGUID(QueryResult_AutoPtr result,uint32 data,uint32 field, std::set<uin
}
// Writing - High-level functions
void PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tableFrom, char const*tableTo, DumpTableType type)
bool PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tableFrom, char const*tableTo, DumpTableType type)
{
GUIDs const* guids = NULL;
char const* fieldname = NULL;
@@ -282,7 +282,7 @@ void PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tabl
// for guid set stop if set is empty
if (guids && guids->empty())
return; // nothing to do
return true; // nothing to do
// setup for guids case start position
GUIDs::const_iterator guids_itr;
@@ -300,7 +300,7 @@ void PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tabl
QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT * FROM %s WHERE %s", tableFrom, wherestr.c_str());
if (!result)
return;
return true;
do
{
@@ -315,6 +315,14 @@ void PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tabl
StoreGUID(result,0,mails); // mail id collection (mail.id)
case DTT_MAIL_ITEM:
StoreGUID(result,1,items); break; // item guid collection (mail_items.item_guid)
case DTT_CHARACTER:
{
if (result->GetFieldCount() <= 67) // avoid crashes on next check
return true;
if (result->Fetch()[67].GetUInt32()) // characters.deleteInfos_Account - if filled error
return false;
break;
}
default: break;
}
@@ -324,22 +332,24 @@ void PlayerDumpWriter::DumpTable(std::string& dump, uint32 guid, char const*tabl
while (result->NextRow());
}
while (guids && guids_itr != guids->end()); // not set case iterate single time, set case iterate for all guids
return true;
}
std::string PlayerDumpWriter::GetDump(uint32 guid)
bool PlayerDumpWriter::GetDump(uint32 guid, std::string &dump)
{
std::string dump;
dump = "";
dump += "IMPORTANT NOTE: THIS DUMPFILE IS MADE FOR USE WITH THE 'PDUMP' COMMAND ONLY - EITHER THROUGH INGAME CHAT OR ON CONSOLE!\n";
dump += "IMPORTANT NOTE: DO NOT apply it directly - it will irreversibly DAMAGE and CORRUPT your database! You have been warned!\n\n";
for (int i = 0; i < DUMP_TABLE_COUNT; ++i)
DumpTable(dump, guid, dumpTables[i].name, dumpTables[i].name, dumpTables[i].type);
if (!DumpTable(dump, guid, dumpTables[i].name, dumpTables[i].name, dumpTables[i].type))
return false;
// TODO: Add instance/group..
// TODO: Add a dump level option to skip some non-important tables
return dump;
return true;
}
DumpReturn PlayerDumpWriter::WriteDump(const std::string& file, uint32 guid)
@@ -348,16 +358,30 @@ DumpReturn PlayerDumpWriter::WriteDump(const std::string& file, uint32 guid)
if (!fout)
return DUMP_FILE_OPEN_ERROR;
std::string dump = GetDump(guid);
DumpReturn ret = DUMP_SUCCESS;
std::string dump;
if (!GetDump(guid, dump))
ret = DUMP_CHARACTER_DELETED;
fprintf(fout,"%s\n",dump.c_str());
fprintf(fout, "%s\n", dump.c_str());
fclose(fout);
return DUMP_SUCCESS;
return ret;
}
// Reading - High-level functions
#define ROLLBACK(DR) {CharacterDatabase.RollbackTransaction(); fclose(fin); return (DR);}
void fixNULLfields(std::string &line)
{
std::string nullString("'NULL'");
size_t pos = line.find(nullString);
while (pos != std::string::npos)
{
line.replace(pos, nullString.length(), "NULL");
pos = line.find(nullString);
}
}
DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, std::string name, uint32 guid)
{
uint32 charcount = accmgr.GetCharactersCount(account);
@@ -495,13 +519,20 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
result = CharacterDatabase.PQuery("SELECT 1 FROM characters WHERE name = '%s'", name.c_str());
if (result)
{
if (!changenth(line, 36, "1")) // characters.at_login set to "rename on login"
if (!changenth(line, 37, "1")) // characters.at_login set to "rename on login"
ROLLBACK(DUMP_FILE_BROKEN);
}
}
else if (!changenth(line, 3, name.c_str())) // characters.name
ROLLBACK(DUMP_FILE_BROKEN);
const char null[5] = "NULL";
if (!changenth(line, 68, null)) // characters.deleteInfos_Account
ROLLBACK(DUMP_FILE_BROKEN);
if (!changenth(line, 69, null)) // characters.deleteInfos_Name
ROLLBACK(DUMP_FILE_BROKEN);
if (!changenth(line, 70, null)) // characters.deleteDate
ROLLBACK(DUMP_FILE_BROKEN);
break;
}
case DTT_INVENTORY:
@@ -522,13 +553,6 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
ROLLBACK(DUMP_FILE_BROKEN); // item_instance.guid update
if (!changenth(line, 2, newguid)) // item_instance.owner_guid update
ROLLBACK(DUMP_FILE_BROKEN);
std::string vals = getnth(line,3); // item_instance.data get
if (!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, objmgr.m_hiItemGuid))
ROLLBACK(DUMP_FILE_BROKEN); // item_instance.data.OBJECT_FIELD_GUID update
if (!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid))
ROLLBACK(DUMP_FILE_BROKEN); // item_instance.data.ITEM_FIELD_OWNER update
if (!changenth(line, 3, vals.c_str())) // item_instance.data update
ROLLBACK(DUMP_FILE_BROKEN);
break;
}
case DTT_ITEM_GIFT:
@@ -603,6 +627,8 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
break;
}
fixNULLfields(line);
if (!CharacterDatabase.Execute(line.c_str()))
ROLLBACK(DUMP_FILE_BROKEN);
}

View File

@@ -61,6 +61,7 @@ enum DumpReturn
DUMP_TOO_MANY_CHARS,
DUMP_UNEXPECTED_END,
DUMP_FILE_BROKEN,
DUMP_CHARACTER_DELETED
};
class PlayerDump
@@ -74,12 +75,12 @@ class PlayerDumpWriter : public PlayerDump
public:
PlayerDumpWriter() {}
std::string GetDump(uint32 guid);
bool GetDump(uint32 guid, std::string& dump);
DumpReturn WriteDump(const std::string& file, uint32 guid);
private:
typedef std::set<uint32> GUIDs;
void DumpTable(std::string& dump, uint32 guid, char const*tableFrom, char const*tableTo, DumpTableType type);
bool DumpTable(std::string& dump, uint32 guid, char const*tableFrom, char const*tableTo, DumpTableType type);
std::string GenerateWhereStr(char const* field, GUIDs const& guids, GUIDs::const_iterator& itr);
std::string GenerateWhereStr(char const* field, uint32 guid);