diff options
author | Neo2003 <none@none> | 2008-10-09 08:42:22 -0500 |
---|---|---|
committer | Neo2003 <none@none> | 2008-10-09 08:42:22 -0500 |
commit | f736567a374e718574763f545b9cdea5d97d9ce0 (patch) | |
tree | 5b0a617c7ef4e5c6bd4aa1df6a9c7afe31757a46 /src/game/PetitionsHandler.cpp | |
parent | e3079a1ba63ebe13a19e85db3f4e1e1a392a04ed (diff) |
[svn] * Updated to 6743 and 685
Moved language id used by Arena to a higher place to solve conflicts
Added the empty script folders
--HG--
branch : trunk
rename : 6731-680 => 6743-685
Diffstat (limited to 'src/game/PetitionsHandler.cpp')
-rw-r--r-- | src/game/PetitionsHandler.cpp | 1872 |
1 files changed, 936 insertions, 936 deletions
diff --git a/src/game/PetitionsHandler.cpp b/src/game/PetitionsHandler.cpp index 6957634dc9e..2c5c4493c10 100644 --- a/src/game/PetitionsHandler.cpp +++ b/src/game/PetitionsHandler.cpp @@ -1,936 +1,936 @@ -/* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "Common.h" -#include "Language.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "World.h" -#include "ObjectMgr.h" -#include "Log.h" -#include "Opcodes.h" -#include "Guild.h" -#include "ArenaTeam.h" -#include "MapManager.h" -#include "GossipDef.h" -#include "SocialMgr.h" - -/*enum PetitionType // dbc data -{ - PETITION_TYPE_GUILD = 1, - PETITION_TYPE_ARENA_TEAM = 3 -};*/ - -// Charters ID in item_template -#define GUILD_CHARTER 5863 -#define GUILD_CHARTER_COST 1000 // 10 S -#define ARENA_TEAM_CHARTER_2v2 23560 -#define ARENA_TEAM_CHARTER_2v2_COST 800000 // 80 G -#define ARENA_TEAM_CHARTER_3v3 23561 -#define ARENA_TEAM_CHARTER_3v3_COST 1200000 // 120 G -#define ARENA_TEAM_CHARTER_5v5 23562 -#define ARENA_TEAM_CHARTER_5v5_COST 2000000 // 200 G - -void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data) -{ - CHECK_PACKET_SIZE(recv_data, 8+8+4+1+5*8+2+1+4+4); - - sLog.outDebug("Received opcode CMSG_PETITION_BUY"); - //recv_data.hexlike(); - - uint64 guidNPC; - uint64 unk1, unk3, unk4, unk5, unk6, unk7; - uint32 unk2; - std::string name; - uint16 unk8; - uint8 unk9; - uint32 unk10; // selected index - uint32 unk11; - recv_data >> guidNPC; // NPC GUID - recv_data >> unk1; // 0 - recv_data >> unk2; // 0 - recv_data >> name; // name - - // recheck - CHECK_PACKET_SIZE(recv_data, 8+8+4+(name.size()+1)+5*8+2+1+4+4); - - recv_data >> unk3; // 0 - recv_data >> unk4; // 0 - recv_data >> unk5; // 0 - recv_data >> unk6; // 0 - recv_data >> unk7; // 0 - recv_data >> unk8; // 0 - recv_data >> unk9; // 0 - recv_data >> unk10; // index - recv_data >> unk11; // 0 - sLog.outDebug("Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guidNPC), name.c_str()); - - // prevent cheating - Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guidNPC,UNIT_NPC_FLAG_PETITIONER); - if (!pCreature) - { - sLog.outDebug("WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guidNPC)); - return; - } - - // remove fake death - if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) - GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - - uint32 charterid = 0; - uint32 cost = 0; - uint32 type = 0; - if(pCreature->isTabardDesigner()) - { - // if tabard designer, then trying to buy a guild charter. - // do not let if already in guild. - if(_player->GetGuildId()) - return; - - charterid = GUILD_CHARTER; - cost = GUILD_CHARTER_COST; - type = 9; - } - else - { - // TODO: find correct opcode - if(_player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) - { - SendNotification(GetMangosString(LANG_ARENA_ONE_TOOLOW), 70); - return; - } - - for(uint8 i = 0; i < MAX_ARENA_SLOT; i++) - { - if(_player->GetArenaTeamId(i) && (i == (unk10-1))) - { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM); - return; - } - } - switch(unk10) - { - case 1: - charterid = ARENA_TEAM_CHARTER_2v2; - cost = ARENA_TEAM_CHARTER_2v2_COST; - type = 2; // 2v2 - break; - case 2: - charterid = ARENA_TEAM_CHARTER_3v3; - cost = ARENA_TEAM_CHARTER_3v3_COST; - type = 3; // 3v3 - break; - case 3: - charterid = ARENA_TEAM_CHARTER_5v5; - cost = ARENA_TEAM_CHARTER_5v5_COST; - type = 5; // 5v5 - break; - default: - sLog.outDebug("unknown selection at buy petition: %u", unk10); - return; - } - } - - if(type == 9) - { - if(objmgr.GetGuildByName(name)) - { - SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_EXISTS); - return; - } - if(objmgr.IsReservedName(name)) - { - SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_INVALID); - return; - } - if(!ObjectMgr::IsValidCharterName(name)) - { - SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_INVALID); - return; - } - } - else - { - if(objmgr.GetArenaTeamByName(name)) - { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S); - return; - } - if(objmgr.IsReservedName(name)) - { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID); - return; - } - if(!ObjectMgr::IsValidCharterName(name)) - { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID); - return; - } - } - - ItemPrototype const *pProto = objmgr.GetItemPrototype(charterid); - if(!pProto) - { - _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, charterid, 0); - return; - } - - if(_player->GetMoney() < cost) - { //player hasn't got enough money - _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, charterid, 0); - return; - } - - ItemPosCountVec dest; - uint8 msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount ); - if(msg != EQUIP_ERR_OK) - { - _player->SendBuyError(msg, pCreature, charterid, 0); - return; - } - - _player->ModifyMoney(-(int32)cost); - Item *charter = _player->StoreNewItem(dest, charterid, true); - if(!charter) - return; - - charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT, charter->GetGUIDLow()); - // ITEM_FIELD_ENCHANTMENT is guild/arenateam id - // ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item) - charter->SetState(ITEM_CHANGED, _player); - _player->SendNewItem(charter, 1, true, false); - - // a petition is invalid, if both the owner and the type matches - QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE ownerguid = '%u' AND type = '%u'", _player->GetGUIDLow(), type); - - std::ostringstream ssInvalidPetitionGUIDs; - - if (result) - { - - do - { - Field *fields = result->Fetch(); - ssInvalidPetitionGUIDs << "'" << fields[0].GetUInt32() << "' , "; - } while (result->NextRow()); - - delete result; - } - - // delete petitions with the same guid as this one - ssInvalidPetitionGUIDs << "'" << charter->GetGUIDLow() << "'"; - - sLog.outDebug("Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str()); - CharacterDatabase.escape_string(name); - CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid IN ( %s )", ssInvalidPetitionGUIDs.str().c_str()); - CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid IN ( %s )", ssInvalidPetitionGUIDs.str().c_str()); - CharacterDatabase.PExecute("INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES ('%u', '%u', '%s', '%u')", - _player->GetGUIDLow(), charter->GetGUIDLow(), name.c_str(), type); - CharacterDatabase.CommitTransaction(); -} - -void WorldSession::HandlePetitionShowSignOpcode(WorldPacket & recv_data) -{ - CHECK_PACKET_SIZE(recv_data, 8); - - // ok - sLog.outDebug("Received opcode CMSG_PETITION_SHOW_SIGNATURES"); - //recv_data.hexlike(); - - uint8 signs = 0; - uint64 petitionguid; - recv_data >> petitionguid; // petition guid - - // solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?) - uint32 petitionguid_low = GUID_LOPART(petitionguid); - - QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid, type FROM petition WHERE petitionguid = '%u'", petitionguid_low); - if(!result) - { - sLog.outError("any petition on server..."); - return; - } - Field *fields = result->Fetch(); - uint32 type = fields[1].GetUInt32(); - delete result; - // if guild petition and has guild => error, return; - if(type==9 && _player->GetGuildId()) - return; - - result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionguid_low); - - // result==NULL also correct in case no sign yet - if(result) - signs = result->GetRowCount(); - - sLog.outDebug("CMSG_PETITION_SHOW_SIGNATURES petition entry: '%u'", petitionguid_low); - - WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+1+signs*12)); - data << petitionguid; // petition guid - data << _player->GetGUID(); // owner guid - data << petitionguid_low; // guild guid (in mangos always same as GUID_LOPART(petitionguid) - data << signs; // sign's count - - for(uint8 i = 1; i <= signs; i++) - { - Field *fields = result->Fetch(); - uint64 plguid = fields[0].GetUInt64(); - - data << plguid; // Player GUID - data << (uint32)0; // there 0 ... - - result->NextRow(); - } - delete result; - SendPacket(&data); -} - -void WorldSession::HandlePetitionQueryOpcode(WorldPacket & recv_data) -{ - CHECK_PACKET_SIZE(recv_data, 4+8); - - sLog.outDebug("Received opcode CMSG_PETITION_QUERY"); // ok - //recv_data.hexlike(); - - uint32 guildguid; - uint64 petitionguid; - recv_data >> guildguid; // in mangos always same as GUID_LOPART(petitionguid) - recv_data >> petitionguid; // petition guid - sLog.outDebug("CMSG_PETITION_QUERY Petition GUID %u Guild GUID %u", GUID_LOPART(petitionguid), guildguid); - - SendPetitionQueryOpcode(petitionguid); -} - -void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid) -{ - uint64 ownerguid = 0; - uint32 type; - std::string name = "NO_NAME_FOR_GUID"; - uint8 signs = 0; - - QueryResult *result = CharacterDatabase.PQuery( - "SELECT ownerguid, name, " - " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs " - "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid)); - - if(result) - { - Field* fields = result->Fetch(); - ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); - name = fields[1].GetCppString(); - signs = fields[2].GetUInt8(); - delete result; - } - else - { - sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid)); - return; - } - - QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - - if(result2) - { - Field* fields = result2->Fetch(); - type = fields[0].GetUInt32(); - delete result2; - } - else - { - sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid)); - return; - } - - WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4+8+name.size()+1+1+4*13)); - data << GUID_LOPART(petitionguid); // guild/team guid (in mangos always same as GUID_LOPART(petition guid) - data << ownerguid; // charter owner guid - data << name; // name (guild/arena team) - data << uint8(0); // 1 - if(type == 9) - { - data << uint32(9); - data << uint32(9); - data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition - } - else - { - data << type-1; - data << type-1; - data << type; // bypass client - side limitation, a different value is needed here for each petition - } - data << uint32(0); // 5 - data << uint32(0); // 6 - data << uint32(0); // 7 - data << uint32(0); // 8 - data << uint16(0); // 9 2 bytes field - data << uint32(0); // 10 - data << uint32(0); // 11 - data << uint32(0); // 13 count of next strings? - data << uint32(0); // 14 - if(type == 9) - data << uint32(0); // 15 0 - guild, 1 - arena team - else - data << uint32(1); - SendPacket(&data); -} - -void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data) -{ - CHECK_PACKET_SIZE(recv_data, 8+1); - - sLog.outDebug("Received opcode MSG_PETITION_RENAME"); // ok - //recv_data.hexlike(); - - uint64 petitionguid; - uint32 type; - std::string newname; - - recv_data >> petitionguid; // guid - recv_data >> newname; // new name - - Item *item = _player->GetItemByGuid(petitionguid); - if(!item) - return; - - QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - - if(result2) - { - Field* fields = result2->Fetch(); - type = fields[0].GetUInt32(); - delete result2; - } - else - { - sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid)); - return; - } - - if(type == 9) - { - if(objmgr.GetGuildByName(newname)) - { - SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_EXISTS); - return; - } - if(objmgr.IsReservedName(newname)) - { - SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_INVALID); - return; - } - if(!ObjectMgr::IsValidCharterName(newname)) - { - SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_INVALID); - return; - } - } - else - { - if(objmgr.GetArenaTeamByName(newname)) - { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_EXISTS_S); - return; - } - if(objmgr.IsReservedName(newname)) - { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID); - return; - } - if(!ObjectMgr::IsValidCharterName(newname)) - { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID); - return; - } - } - - std::string db_newname = newname; - CharacterDatabase.escape_string(db_newname); - CharacterDatabase.PExecute("UPDATE petition SET name = '%s' WHERE petitionguid = '%u'", - db_newname.c_str(), GUID_LOPART(petitionguid)); - - sLog.outDebug("Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionguid), newname.c_str()); - WorldPacket data(MSG_PETITION_RENAME, (8+newname.size()+1)); - data << petitionguid; - data << newname; - SendPacket(&data); -} - -void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data) -{ - CHECK_PACKET_SIZE(recv_data, 8+1); - - sLog.outDebug("Received opcode CMSG_PETITION_SIGN"); // ok - //recv_data.hexlike(); - - Field *fields; - uint64 petitionguid; - uint32 type; - uint8 unk; - uint64 ownerguid; - recv_data >> petitionguid; // petition guid - recv_data >> unk; - - uint8 signs = 0; - - QueryResult *result = CharacterDatabase.PQuery( - "SELECT ownerguid, " - " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs " - "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid)); - - if(!result) - { - sLog.outError("any petition on server..."); - return; - } - - fields = result->Fetch(); - ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); - signs = fields[1].GetUInt8(); - - delete result; - - uint32 plguidlo = _player->GetGUIDLow(); - if(GUID_LOPART(ownerguid) == plguidlo) - return; - - // not let enemies sign guild charter - if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != objmgr.GetPlayerTeamByGUID(ownerguid)) - return; - - QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - - if(result2) - { - Field* fields = result2->Fetch(); - type = fields[0].GetUInt32(); - delete result2; - } - else - { - sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid)); - return; - } - - if(type != 9 && _player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) - { - // player is too low level to join an arena team - SendNotification("You must be level %u to join an arena team!",sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); - return; - } - - signs += 1; - if(signs > type) // client signs maximum - return; - - //client doesn't allow to sign petition two times by one character, but not check sign by another character from same account - //not allow sign another player from already sign player account - result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionguid)); - - if(result) - { - delete result; - WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4)); - data << petitionguid; - data << _player->GetGUID(); - data << (uint32)PETITION_SIGN_ALREADY_SIGNED; - - // close at signer side - SendPacket(&data); - - // update for owner if online - if(Player *owner = objmgr.GetPlayer(ownerguid)) - owner->GetSession()->SendPacket(&data); - return; - } - - CharacterDatabase.PExecute("INSERT INTO petition_sign (ownerguid,petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u','%u')", GUID_LOPART(ownerguid),GUID_LOPART(petitionguid), plguidlo,GetAccountId()); - - sLog.outDebug("PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionguid), _player->GetName(),plguidlo,GetAccountId()); - - WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4)); - data << petitionguid; - data << _player->GetGUID(); - data << (uint32)PETITION_SIGN_OK; - - // close at signer side - SendPacket(&data); - - // update signs count on charter, required testing... - //Item *item = _player->GetItemByGuid(petitionguid)); - //if(item) - // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs); - - // update for owner if online - if(Player *owner = objmgr.GetPlayer(ownerguid)) - owner->GetSession()->SendPacket(&data); -} - -void WorldSession::HandlePetitionDeclineOpcode(WorldPacket & recv_data) -{ - CHECK_PACKET_SIZE(recv_data, 8); - - sLog.outDebug("Received opcode MSG_PETITION_DECLINE"); // ok - //recv_data.hexlike(); - - uint64 petitionguid; - uint64 ownerguid; - recv_data >> petitionguid; // petition guid - sLog.outDebug("Petition %u declined by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow()); - - QueryResult *result = CharacterDatabase.PQuery("SELECT ownerguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - if(!result) - return; - - Field *fields = result->Fetch(); - ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER); - delete result; - - Player *owner = objmgr.GetPlayer(ownerguid); - if(owner) // petition owner online - { - WorldPacket data(MSG_PETITION_DECLINE, 8); - data << _player->GetGUID(); - owner->GetSession()->SendPacket(&data); - } -} - -void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data) -{ - CHECK_PACKET_SIZE(recv_data, 4+8+8); - - sLog.outDebug("Received opcode CMSG_OFFER_PETITION"); // ok - //recv_data.hexlike(); - - uint8 signs = 0; - uint64 petitionguid, plguid; - uint32 petitiontype; - Player *player; - recv_data >> petitiontype; // 2.0.8 - petition type? - recv_data >> petitionguid; // petition guid - recv_data >> plguid; // player guid - sLog.outDebug("OFFER PETITION: type %u, GUID1 %u, to player id: %u", petitiontype, GUID_LOPART(petitionguid), GUID_LOPART(plguid)); - - player = ObjectAccessor::FindPlayer(plguid); - if(!player || player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) - return; - - // not let offer to enemies - if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam() ) - return; - - QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - if(!result) - { - sLog.outError("any petition on server..."); - return; - } - - delete result; - - result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - // result==NULL also correct charter without signs - if(result) - signs = result->GetRowCount(); - - WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+signs+signs*12)); - data << petitionguid; // petition guid - data << _player->GetGUID(); // owner guid - data << GUID_LOPART(petitionguid); // guild guid (in mangos always same as GUID_LOPART(petition guid) - data << signs; // sign's count - - for(uint8 i = 1; i <= signs; i++) - { - Field *fields = result->Fetch(); - uint64 plguid = fields[0].GetUInt64(); - - data << plguid; // Player GUID - data << (uint32)0; // there 0 ... - - result->NextRow(); - } - - delete result; - player->GetSession()->SendPacket(&data); -} - -void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data) -{ - CHECK_PACKET_SIZE(recv_data, 8); - - sLog.outDebug("Received opcode CMSG_TURN_IN_PETITION"); // ok - //recv_data.hexlike(); - - WorldPacket data; - uint64 petitionguid; - - uint32 ownerguidlo; - uint32 type; - std::string name; - - recv_data >> petitionguid; - - sLog.outDebug("Petition %u turned in by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow()); - - // data - QueryResult *result = CharacterDatabase.PQuery("SELECT ownerguid, name, type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - if(result) - { - Field *fields = result->Fetch(); - ownerguidlo = fields[0].GetUInt32(); - name = fields[1].GetCppString(); - type = fields[2].GetUInt32(); - delete result; - } - else - { - sLog.outError("petition table has broken data!"); - return; - } - - if(type == 9) - { - if(_player->GetGuildId()) - { - data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); - data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild - _player->GetSession()->SendPacket(&data); - return; - } - } - else - { - uint8 slot = ArenaTeam::GetSlotByType(type); - if(slot >= MAX_ARENA_SLOT) - return; - - if(_player->GetArenaTeamId(slot)) - { - //data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); - //data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild - //_player->GetSession()->SendPacket(&data); - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM); - return; - } - } - - if(_player->GetGUIDLow() != ownerguidlo) - return; - - // signs - uint8 signs; - result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - if(result) - signs = result->GetRowCount(); - else - signs = 0; - - uint32 count; - //if(signs < sWorld.getConfig(CONFIG_MIN_PETITION_SIGNS)) - if(type == 9) - count = sWorld.getConfig(CONFIG_MIN_PETITION_SIGNS); - else - count = type-1; - if(signs < count) - { - data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); - data << (uint32)PETITION_TURN_NEED_MORE_SIGNATURES; // need more signatures... - SendPacket(&data); - delete result; - return; - } - - if(type == 9) - { - if(objmgr.GetGuildByName(name)) - { - SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_EXISTS); - delete result; - return; - } - } - else - { - if(objmgr.GetArenaTeamByName(name)) - { - SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S); - delete result; - return; - } - } - - // and at last charter item check - Item *item = _player->GetItemByGuid(petitionguid); - if(!item) - { - delete result; - return; - } - - // OK! - - // delete charter item - _player->DestroyItem(item->GetBagSlot(),item->GetSlot(), true); - - if(type == 9) // create guild - { - Guild* guild = new Guild; - if(!guild->create(_player->GetGUID(), name)) - { - delete guild; - delete result; - return; - } - - // register guild and add guildmaster - objmgr.AddGuild(guild); - - // add members - for(uint8 i = 0; i < signs; ++i) - { - Field* fields = result->Fetch(); - guild->AddMember(fields[0].GetUInt64(), guild->GetLowestRank()); - result->NextRow(); - } - } - else // or arena team - { - ArenaTeam* at = new ArenaTeam; - if(!at->create(_player->GetGUID(), type, name)) - { - sLog.outError("PetitionsHandler: arena team create failed."); - delete at; - delete result; - return; - } - - CHECK_PACKET_SIZE(recv_data, 8+5*4); - uint32 icon, iconcolor, border, bordercolor, backgroud; - recv_data >> backgroud >> icon >> iconcolor >> border >> bordercolor; - - at->SetEmblem(backgroud, icon, iconcolor, border, bordercolor); - - // register team and add captain - objmgr.AddArenaTeam(at); - sLog.outDebug("PetitonsHandler: arena team added to objmrg"); - - // add members - for(uint8 i = 0; i < signs; ++i) - { - Field* fields = result->Fetch(); - sLog.outDebug("PetitionsHandler: adding arena member %u", fields[0].GetUInt64()); - at->AddMember(fields[0].GetUInt64()); - result->NextRow(); - } - } - - delete result; - - CharacterDatabase.BeginTransaction(); - CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid)); - CharacterDatabase.CommitTransaction(); - - // created - sLog.outDebug("TURN IN PETITION GUID %u", GUID_LOPART(petitionguid)); - - data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); - data << (uint32)PETITION_TURN_OK; - SendPacket(&data); -} - -void WorldSession::HandlePetitionShowListOpcode(WorldPacket & recv_data) -{ - CHECK_PACKET_SIZE(recv_data, 8); - - sLog.outDebug("Received CMSG_PETITION_SHOWLIST"); // ok - //recv_data.hexlike(); - - uint64 guid; - recv_data >> guid; - - SendPetitionShowList(guid); -} - -void WorldSession::SendPetitionShowList(uint64 guid) -{ - Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_PETITIONER); - if (!pCreature) - { - sLog.outDebug("WORLD: HandlePetitionShowListOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid))); - return; - } - - // remove fake death - if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) - GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - - uint8 count = 0; - if(pCreature->isTabardDesigner()) - count = 1; - else - count = 3; - - WorldPacket data(SMSG_PETITION_SHOWLIST, 8+1+4*6); - data << guid; // npc guid - data << count; // count - if(count == 1) - { - data << uint32(1); // index - data << uint32(GUILD_CHARTER); // charter entry - data << uint32(16161); // charter display id - data << uint32(GUILD_CHARTER_COST); // charter cost - data << uint32(0); // unknown - data << uint32(9); // required signs? - } - else - { - // 2v2 - data << uint32(1); // index - data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry - data << uint32(16161); // charter display id - data << uint32(ARENA_TEAM_CHARTER_2v2_COST); // charter cost - data << uint32(2); // unknown - data << uint32(2); // required signs? - // 3v3 - data << uint32(2); // index - data << uint32(ARENA_TEAM_CHARTER_3v3); // charter entry - data << uint32(16161); // charter display id - data << uint32(ARENA_TEAM_CHARTER_3v3_COST); // charter cost - data << uint32(3); // unknown - data << uint32(3); // required signs? - // 5v5 - data << uint32(3); // index - data << uint32(ARENA_TEAM_CHARTER_5v5); // charter entry - data << uint32(16161); // charter display id - data << uint32(ARENA_TEAM_CHARTER_5v5_COST); // charter cost - data << uint32(5); // unknown - data << uint32(5); // required signs? - } - //for(uint8 i = 0; i < count; i++) - //{ - // data << uint32(i); // index - // data << uint32(GUILD_CHARTER); // charter entry - // data << uint32(16161); // charter display id - // data << uint32(GUILD_CHARTER_COST+i); // charter cost - // data << uint32(0); // unknown - // data << uint32(9); // required signs? - //} - SendPacket(&data); - sLog.outDebug("Sent SMSG_PETITION_SHOWLIST"); -} +/*
+ * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Common.h"
+#include "Language.h"
+#include "WorldPacket.h"
+#include "WorldSession.h"
+#include "World.h"
+#include "ObjectMgr.h"
+#include "Log.h"
+#include "Opcodes.h"
+#include "Guild.h"
+#include "ArenaTeam.h"
+#include "MapManager.h"
+#include "GossipDef.h"
+#include "SocialMgr.h"
+
+/*enum PetitionType // dbc data
+{
+ PETITION_TYPE_GUILD = 1,
+ PETITION_TYPE_ARENA_TEAM = 3
+};*/
+
+// Charters ID in item_template
+#define GUILD_CHARTER 5863
+#define GUILD_CHARTER_COST 1000 // 10 S
+#define ARENA_TEAM_CHARTER_2v2 23560
+#define ARENA_TEAM_CHARTER_2v2_COST 800000 // 80 G
+#define ARENA_TEAM_CHARTER_3v3 23561
+#define ARENA_TEAM_CHARTER_3v3_COST 1200000 // 120 G
+#define ARENA_TEAM_CHARTER_5v5 23562
+#define ARENA_TEAM_CHARTER_5v5_COST 2000000 // 200 G
+
+void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 8+8+4+1+5*8+2+1+4+4);
+
+ sLog.outDebug("Received opcode CMSG_PETITION_BUY");
+ //recv_data.hexlike();
+
+ uint64 guidNPC;
+ uint64 unk1, unk3, unk4, unk5, unk6, unk7;
+ uint32 unk2;
+ std::string name;
+ uint16 unk8;
+ uint8 unk9;
+ uint32 unk10; // selected index
+ uint32 unk11;
+ recv_data >> guidNPC; // NPC GUID
+ recv_data >> unk1; // 0
+ recv_data >> unk2; // 0
+ recv_data >> name; // name
+
+ // recheck
+ CHECK_PACKET_SIZE(recv_data, 8+8+4+(name.size()+1)+5*8+2+1+4+4);
+
+ recv_data >> unk3; // 0
+ recv_data >> unk4; // 0
+ recv_data >> unk5; // 0
+ recv_data >> unk6; // 0
+ recv_data >> unk7; // 0
+ recv_data >> unk8; // 0
+ recv_data >> unk9; // 0
+ recv_data >> unk10; // index
+ recv_data >> unk11; // 0
+ sLog.outDebug("Petitioner with GUID %u tried sell petition: name %s", GUID_LOPART(guidNPC), name.c_str());
+
+ // prevent cheating
+ Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guidNPC,UNIT_NPC_FLAG_PETITIONER);
+ if (!pCreature)
+ {
+ sLog.outDebug("WORLD: HandlePetitionBuyOpcode - Unit (GUID: %u) not found or you can't interact with him.", GUID_LOPART(guidNPC));
+ return;
+ }
+
+ // remove fake death
+ if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
+ GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+
+ uint32 charterid = 0;
+ uint32 cost = 0;
+ uint32 type = 0;
+ if(pCreature->isTabardDesigner())
+ {
+ // if tabard designer, then trying to buy a guild charter.
+ // do not let if already in guild.
+ if(_player->GetGuildId())
+ return;
+
+ charterid = GUILD_CHARTER;
+ cost = GUILD_CHARTER_COST;
+ type = 9;
+ }
+ else
+ {
+ // TODO: find correct opcode
+ if(_player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ SendNotification(LANG_ARENA_ONE_TOOLOW, 70);
+ return;
+ }
+
+ for(uint8 i = 0; i < MAX_ARENA_SLOT; i++)
+ {
+ if(_player->GetArenaTeamId(i) && (i == (unk10-1)))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM);
+ return;
+ }
+ }
+ switch(unk10)
+ {
+ case 1:
+ charterid = ARENA_TEAM_CHARTER_2v2;
+ cost = ARENA_TEAM_CHARTER_2v2_COST;
+ type = 2; // 2v2
+ break;
+ case 2:
+ charterid = ARENA_TEAM_CHARTER_3v3;
+ cost = ARENA_TEAM_CHARTER_3v3_COST;
+ type = 3; // 3v3
+ break;
+ case 3:
+ charterid = ARENA_TEAM_CHARTER_5v5;
+ cost = ARENA_TEAM_CHARTER_5v5_COST;
+ type = 5; // 5v5
+ break;
+ default:
+ sLog.outDebug("unknown selection at buy petition: %u", unk10);
+ return;
+ }
+ }
+
+ if(type == 9)
+ {
+ if(objmgr.GetGuildByName(name))
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_EXISTS);
+ return;
+ }
+ if(objmgr.IsReservedName(name))
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_INVALID);
+ return;
+ }
+ if(!ObjectMgr::IsValidCharterName(name))
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_INVALID);
+ return;
+ }
+ }
+ else
+ {
+ if(objmgr.GetArenaTeamByName(name))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
+ return;
+ }
+ if(objmgr.IsReservedName(name))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID);
+ return;
+ }
+ if(!ObjectMgr::IsValidCharterName(name))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_INVALID);
+ return;
+ }
+ }
+
+ ItemPrototype const *pProto = objmgr.GetItemPrototype(charterid);
+ if(!pProto)
+ {
+ _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, charterid, 0);
+ return;
+ }
+
+ if(_player->GetMoney() < cost)
+ { //player hasn't got enough money
+ _player->SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, pCreature, charterid, 0);
+ return;
+ }
+
+ ItemPosCountVec dest;
+ uint8 msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount );
+ if(msg != EQUIP_ERR_OK)
+ {
+ _player->SendBuyError(msg, pCreature, charterid, 0);
+ return;
+ }
+
+ _player->ModifyMoney(-(int32)cost);
+ Item *charter = _player->StoreNewItem(dest, charterid, true);
+ if(!charter)
+ return;
+
+ charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT, charter->GetGUIDLow());
+ // ITEM_FIELD_ENCHANTMENT is guild/arenateam id
+ // ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item)
+ charter->SetState(ITEM_CHANGED, _player);
+ _player->SendNewItem(charter, 1, true, false);
+
+ // a petition is invalid, if both the owner and the type matches
+ QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE ownerguid = '%u' AND type = '%u'", _player->GetGUIDLow(), type);
+
+ std::ostringstream ssInvalidPetitionGUIDs;
+
+ if (result)
+ {
+
+ do
+ {
+ Field *fields = result->Fetch();
+ ssInvalidPetitionGUIDs << "'" << fields[0].GetUInt32() << "' , ";
+ } while (result->NextRow());
+
+ delete result;
+ }
+
+ // delete petitions with the same guid as this one
+ ssInvalidPetitionGUIDs << "'" << charter->GetGUIDLow() << "'";
+
+ sLog.outDebug("Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str());
+ CharacterDatabase.escape_string(name);
+ CharacterDatabase.BeginTransaction();
+ CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid IN ( %s )", ssInvalidPetitionGUIDs.str().c_str());
+ CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid IN ( %s )", ssInvalidPetitionGUIDs.str().c_str());
+ CharacterDatabase.PExecute("INSERT INTO petition (ownerguid, petitionguid, name, type) VALUES ('%u', '%u', '%s', '%u')",
+ _player->GetGUIDLow(), charter->GetGUIDLow(), name.c_str(), type);
+ CharacterDatabase.CommitTransaction();
+}
+
+void WorldSession::HandlePetitionShowSignOpcode(WorldPacket & recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 8);
+
+ // ok
+ sLog.outDebug("Received opcode CMSG_PETITION_SHOW_SIGNATURES");
+ //recv_data.hexlike();
+
+ uint8 signs = 0;
+ uint64 petitionguid;
+ recv_data >> petitionguid; // petition guid
+
+ // solve (possible) some strange compile problems with explicit use GUID_LOPART(petitionguid) at some GCC versions (wrong code optimization in compiler?)
+ uint32 petitionguid_low = GUID_LOPART(petitionguid);
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid, type FROM petition WHERE petitionguid = '%u'", petitionguid_low);
+ if(!result)
+ {
+ sLog.outError("any petition on server...");
+ return;
+ }
+ Field *fields = result->Fetch();
+ uint32 type = fields[1].GetUInt32();
+ delete result;
+ // if guild petition and has guild => error, return;
+ if(type==9 && _player->GetGuildId())
+ return;
+
+ result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", petitionguid_low);
+
+ // result==NULL also correct in case no sign yet
+ if(result)
+ signs = result->GetRowCount();
+
+ sLog.outDebug("CMSG_PETITION_SHOW_SIGNATURES petition entry: '%u'", petitionguid_low);
+
+ WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+1+signs*12));
+ data << petitionguid; // petition guid
+ data << _player->GetGUID(); // owner guid
+ data << petitionguid_low; // guild guid (in mangos always same as GUID_LOPART(petitionguid)
+ data << signs; // sign's count
+
+ for(uint8 i = 1; i <= signs; i++)
+ {
+ Field *fields = result->Fetch();
+ uint64 plguid = fields[0].GetUInt64();
+
+ data << plguid; // Player GUID
+ data << (uint32)0; // there 0 ...
+
+ result->NextRow();
+ }
+ delete result;
+ SendPacket(&data);
+}
+
+void WorldSession::HandlePetitionQueryOpcode(WorldPacket & recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 4+8);
+
+ sLog.outDebug("Received opcode CMSG_PETITION_QUERY"); // ok
+ //recv_data.hexlike();
+
+ uint32 guildguid;
+ uint64 petitionguid;
+ recv_data >> guildguid; // in mangos always same as GUID_LOPART(petitionguid)
+ recv_data >> petitionguid; // petition guid
+ sLog.outDebug("CMSG_PETITION_QUERY Petition GUID %u Guild GUID %u", GUID_LOPART(petitionguid), guildguid);
+
+ SendPetitionQueryOpcode(petitionguid);
+}
+
+void WorldSession::SendPetitionQueryOpcode(uint64 petitionguid)
+{
+ uint64 ownerguid = 0;
+ uint32 type;
+ std::string name = "NO_NAME_FOR_GUID";
+ uint8 signs = 0;
+
+ QueryResult *result = CharacterDatabase.PQuery(
+ "SELECT ownerguid, name, "
+ " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs "
+ "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid));
+
+ if(result)
+ {
+ Field* fields = result->Fetch();
+ ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+ name = fields[1].GetCppString();
+ signs = fields[2].GetUInt8();
+ delete result;
+ }
+ else
+ {
+ sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid));
+ return;
+ }
+
+ QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+
+ if(result2)
+ {
+ Field* fields = result2->Fetch();
+ type = fields[0].GetUInt32();
+ delete result2;
+ }
+ else
+ {
+ sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid));
+ return;
+ }
+
+ WorldPacket data(SMSG_PETITION_QUERY_RESPONSE, (4+8+name.size()+1+1+4*13));
+ data << GUID_LOPART(petitionguid); // guild/team guid (in mangos always same as GUID_LOPART(petition guid)
+ data << ownerguid; // charter owner guid
+ data << name; // name (guild/arena team)
+ data << uint8(0); // 1
+ if(type == 9)
+ {
+ data << uint32(9);
+ data << uint32(9);
+ data << uint32(0); // bypass client - side limitation, a different value is needed here for each petition
+ }
+ else
+ {
+ data << type-1;
+ data << type-1;
+ data << type; // bypass client - side limitation, a different value is needed here for each petition
+ }
+ data << uint32(0); // 5
+ data << uint32(0); // 6
+ data << uint32(0); // 7
+ data << uint32(0); // 8
+ data << uint16(0); // 9 2 bytes field
+ data << uint32(0); // 10
+ data << uint32(0); // 11
+ data << uint32(0); // 13 count of next strings?
+ data << uint32(0); // 14
+ if(type == 9)
+ data << uint32(0); // 15 0 - guild, 1 - arena team
+ else
+ data << uint32(1);
+ SendPacket(&data);
+}
+
+void WorldSession::HandlePetitionRenameOpcode(WorldPacket & recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 8+1);
+
+ sLog.outDebug("Received opcode MSG_PETITION_RENAME"); // ok
+ //recv_data.hexlike();
+
+ uint64 petitionguid;
+ uint32 type;
+ std::string newname;
+
+ recv_data >> petitionguid; // guid
+ recv_data >> newname; // new name
+
+ Item *item = _player->GetItemByGuid(petitionguid);
+ if(!item)
+ return;
+
+ QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+
+ if(result2)
+ {
+ Field* fields = result2->Fetch();
+ type = fields[0].GetUInt32();
+ delete result2;
+ }
+ else
+ {
+ sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid));
+ return;
+ }
+
+ if(type == 9)
+ {
+ if(objmgr.GetGuildByName(newname))
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_EXISTS);
+ return;
+ }
+ if(objmgr.IsReservedName(newname))
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_INVALID);
+ return;
+ }
+ if(!ObjectMgr::IsValidCharterName(newname))
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, newname, GUILD_NAME_INVALID);
+ return;
+ }
+ }
+ else
+ {
+ if(objmgr.GetArenaTeamByName(newname))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
+ return;
+ }
+ if(objmgr.IsReservedName(newname))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID);
+ return;
+ }
+ if(!ObjectMgr::IsValidCharterName(newname))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, newname, "", ERR_ARENA_TEAM_NAME_INVALID);
+ return;
+ }
+ }
+
+ std::string db_newname = newname;
+ CharacterDatabase.escape_string(db_newname);
+ CharacterDatabase.PExecute("UPDATE petition SET name = '%s' WHERE petitionguid = '%u'",
+ db_newname.c_str(), GUID_LOPART(petitionguid));
+
+ sLog.outDebug("Petition (GUID: %u) renamed to '%s'", GUID_LOPART(petitionguid), newname.c_str());
+ WorldPacket data(MSG_PETITION_RENAME, (8+newname.size()+1));
+ data << petitionguid;
+ data << newname;
+ SendPacket(&data);
+}
+
+void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 8+1);
+
+ sLog.outDebug("Received opcode CMSG_PETITION_SIGN"); // ok
+ //recv_data.hexlike();
+
+ Field *fields;
+ uint64 petitionguid;
+ uint32 type;
+ uint8 unk;
+ uint64 ownerguid;
+ recv_data >> petitionguid; // petition guid
+ recv_data >> unk;
+
+ uint8 signs = 0;
+
+ QueryResult *result = CharacterDatabase.PQuery(
+ "SELECT ownerguid, "
+ " (SELECT COUNT(playerguid) FROM petition_sign WHERE petition_sign.petitionguid = '%u') AS signs "
+ "FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid), GUID_LOPART(petitionguid));
+
+ if(!result)
+ {
+ sLog.outError("any petition on server...");
+ return;
+ }
+
+ fields = result->Fetch();
+ ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+ signs = fields[1].GetUInt8();
+
+ delete result;
+
+ uint32 plguidlo = _player->GetGUIDLow();
+ if(GUID_LOPART(ownerguid) == plguidlo)
+ return;
+
+ // not let enemies sign guild charter
+ if(!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != objmgr.GetPlayerTeamByGUID(ownerguid))
+ return;
+
+ QueryResult *result2 = CharacterDatabase.PQuery("SELECT type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+
+ if(result2)
+ {
+ Field* fields = result2->Fetch();
+ type = fields[0].GetUInt32();
+ delete result2;
+ }
+ else
+ {
+ sLog.outDebug("CMSG_PETITION_QUERY failed for petition (GUID: %u)", GUID_LOPART(petitionguid));
+ return;
+ }
+
+ if(type != 9 && _player->getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL))
+ {
+ // player is too low level to join an arena team
+ SendNotification(LANG_YOUR_ARENA_LEVEL_REQ_ERROR,sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ return;
+ }
+
+ signs += 1;
+ if(signs > type) // client signs maximum
+ return;
+
+ //client doesn't allow to sign petition two times by one character, but not check sign by another character from same account
+ //not allow sign another player from already sign player account
+ result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE player_account = '%u' AND petitionguid = '%u'", GetAccountId(), GUID_LOPART(petitionguid));
+
+ if(result)
+ {
+ delete result;
+ WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4));
+ data << petitionguid;
+ data << _player->GetGUID();
+ data << (uint32)PETITION_SIGN_ALREADY_SIGNED;
+
+ // close at signer side
+ SendPacket(&data);
+
+ // update for owner if online
+ if(Player *owner = objmgr.GetPlayer(ownerguid))
+ owner->GetSession()->SendPacket(&data);
+ return;
+ }
+
+ CharacterDatabase.PExecute("INSERT INTO petition_sign (ownerguid,petitionguid, playerguid, player_account) VALUES ('%u', '%u', '%u','%u')", GUID_LOPART(ownerguid),GUID_LOPART(petitionguid), plguidlo,GetAccountId());
+
+ sLog.outDebug("PETITION SIGN: GUID %u by player: %s (GUID: %u Account: %u)", GUID_LOPART(petitionguid), _player->GetName(),plguidlo,GetAccountId());
+
+ WorldPacket data(SMSG_PETITION_SIGN_RESULTS, (8+8+4));
+ data << petitionguid;
+ data << _player->GetGUID();
+ data << (uint32)PETITION_SIGN_OK;
+
+ // close at signer side
+ SendPacket(&data);
+
+ // update signs count on charter, required testing...
+ //Item *item = _player->GetItemByGuid(petitionguid));
+ //if(item)
+ // item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs);
+
+ // update for owner if online
+ if(Player *owner = objmgr.GetPlayer(ownerguid))
+ owner->GetSession()->SendPacket(&data);
+}
+
+void WorldSession::HandlePetitionDeclineOpcode(WorldPacket & recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 8);
+
+ sLog.outDebug("Received opcode MSG_PETITION_DECLINE"); // ok
+ //recv_data.hexlike();
+
+ uint64 petitionguid;
+ uint64 ownerguid;
+ recv_data >> petitionguid; // petition guid
+ sLog.outDebug("Petition %u declined by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow());
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT ownerguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ if(!result)
+ return;
+
+ Field *fields = result->Fetch();
+ ownerguid = MAKE_NEW_GUID(fields[0].GetUInt32(), 0, HIGHGUID_PLAYER);
+ delete result;
+
+ Player *owner = objmgr.GetPlayer(ownerguid);
+ if(owner) // petition owner online
+ {
+ WorldPacket data(MSG_PETITION_DECLINE, 8);
+ data << _player->GetGUID();
+ owner->GetSession()->SendPacket(&data);
+ }
+}
+
+void WorldSession::HandleOfferPetitionOpcode(WorldPacket & recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 4+8+8);
+
+ sLog.outDebug("Received opcode CMSG_OFFER_PETITION"); // ok
+ //recv_data.hexlike();
+
+ uint8 signs = 0;
+ uint64 petitionguid, plguid;
+ uint32 petitiontype;
+ Player *player;
+ recv_data >> petitiontype; // 2.0.8 - petition type?
+ recv_data >> petitionguid; // petition guid
+ recv_data >> plguid; // player guid
+ sLog.outDebug("OFFER PETITION: type %u, GUID1 %u, to player id: %u", petitiontype, GUID_LOPART(petitionguid), GUID_LOPART(plguid));
+
+ player = ObjectAccessor::FindPlayer(plguid);
+ if(!player || player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow()))
+ return;
+
+ // not let offer to enemies
+ if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && GetPlayer()->GetTeam() != player->GetTeam() )
+ return;
+
+ QueryResult *result = CharacterDatabase.PQuery("SELECT petitionguid FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ if(!result)
+ {
+ sLog.outError("any petition on server...");
+ return;
+ }
+
+ delete result;
+
+ result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ // result==NULL also correct charter without signs
+ if(result)
+ signs = result->GetRowCount();
+
+ WorldPacket data(SMSG_PETITION_SHOW_SIGNATURES, (8+8+4+signs+signs*12));
+ data << petitionguid; // petition guid
+ data << _player->GetGUID(); // owner guid
+ data << GUID_LOPART(petitionguid); // guild guid (in mangos always same as GUID_LOPART(petition guid)
+ data << signs; // sign's count
+
+ for(uint8 i = 1; i <= signs; i++)
+ {
+ Field *fields = result->Fetch();
+ uint64 plguid = fields[0].GetUInt64();
+
+ data << plguid; // Player GUID
+ data << (uint32)0; // there 0 ...
+
+ result->NextRow();
+ }
+
+ delete result;
+ player->GetSession()->SendPacket(&data);
+}
+
+void WorldSession::HandleTurnInPetitionOpcode(WorldPacket & recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 8);
+
+ sLog.outDebug("Received opcode CMSG_TURN_IN_PETITION"); // ok
+ //recv_data.hexlike();
+
+ WorldPacket data;
+ uint64 petitionguid;
+
+ uint32 ownerguidlo;
+ uint32 type;
+ std::string name;
+
+ recv_data >> petitionguid;
+
+ sLog.outDebug("Petition %u turned in by %u", GUID_LOPART(petitionguid), _player->GetGUIDLow());
+
+ // data
+ QueryResult *result = CharacterDatabase.PQuery("SELECT ownerguid, name, type FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ if(result)
+ {
+ Field *fields = result->Fetch();
+ ownerguidlo = fields[0].GetUInt32();
+ name = fields[1].GetCppString();
+ type = fields[2].GetUInt32();
+ delete result;
+ }
+ else
+ {
+ sLog.outError("petition table has broken data!");
+ return;
+ }
+
+ if(type == 9)
+ {
+ if(_player->GetGuildId())
+ {
+ data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
+ data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild
+ _player->GetSession()->SendPacket(&data);
+ return;
+ }
+ }
+ else
+ {
+ uint8 slot = ArenaTeam::GetSlotByType(type);
+ if(slot >= MAX_ARENA_SLOT)
+ return;
+
+ if(_player->GetArenaTeamId(slot))
+ {
+ //data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
+ //data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; // already in guild
+ //_player->GetSession()->SendPacket(&data);
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ALREADY_IN_ARENA_TEAM);
+ return;
+ }
+ }
+
+ if(_player->GetGUIDLow() != ownerguidlo)
+ return;
+
+ // signs
+ uint8 signs;
+ result = CharacterDatabase.PQuery("SELECT playerguid FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ if(result)
+ signs = result->GetRowCount();
+ else
+ signs = 0;
+
+ uint32 count;
+ //if(signs < sWorld.getConfig(CONFIG_MIN_PETITION_SIGNS))
+ if(type == 9)
+ count = sWorld.getConfig(CONFIG_MIN_PETITION_SIGNS);
+ else
+ count = type-1;
+ if(signs < count)
+ {
+ data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
+ data << (uint32)PETITION_TURN_NEED_MORE_SIGNATURES; // need more signatures...
+ SendPacket(&data);
+ delete result;
+ return;
+ }
+
+ if(type == 9)
+ {
+ if(objmgr.GetGuildByName(name))
+ {
+ SendGuildCommandResult(GUILD_CREATE_S, name, GUILD_NAME_EXISTS);
+ delete result;
+ return;
+ }
+ }
+ else
+ {
+ if(objmgr.GetArenaTeamByName(name))
+ {
+ SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S, name, "", ERR_ARENA_TEAM_NAME_EXISTS_S);
+ delete result;
+ return;
+ }
+ }
+
+ // and at last charter item check
+ Item *item = _player->GetItemByGuid(petitionguid);
+ if(!item)
+ {
+ delete result;
+ return;
+ }
+
+ // OK!
+
+ // delete charter item
+ _player->DestroyItem(item->GetBagSlot(),item->GetSlot(), true);
+
+ if(type == 9) // create guild
+ {
+ Guild* guild = new Guild;
+ if(!guild->create(_player->GetGUID(), name))
+ {
+ delete guild;
+ delete result;
+ return;
+ }
+
+ // register guild and add guildmaster
+ objmgr.AddGuild(guild);
+
+ // add members
+ for(uint8 i = 0; i < signs; ++i)
+ {
+ Field* fields = result->Fetch();
+ guild->AddMember(fields[0].GetUInt64(), guild->GetLowestRank());
+ result->NextRow();
+ }
+ }
+ else // or arena team
+ {
+ ArenaTeam* at = new ArenaTeam;
+ if(!at->create(_player->GetGUID(), type, name))
+ {
+ sLog.outError("PetitionsHandler: arena team create failed.");
+ delete at;
+ delete result;
+ return;
+ }
+
+ CHECK_PACKET_SIZE(recv_data, 8+5*4);
+ uint32 icon, iconcolor, border, bordercolor, backgroud;
+ recv_data >> backgroud >> icon >> iconcolor >> border >> bordercolor;
+
+ at->SetEmblem(backgroud, icon, iconcolor, border, bordercolor);
+
+ // register team and add captain
+ objmgr.AddArenaTeam(at);
+ sLog.outDebug("PetitonsHandler: arena team added to objmrg");
+
+ // add members
+ for(uint8 i = 0; i < signs; ++i)
+ {
+ Field* fields = result->Fetch();
+ sLog.outDebug("PetitionsHandler: adding arena member %u", fields[0].GetUInt64());
+ at->AddMember(fields[0].GetUInt64());
+ result->NextRow();
+ }
+ }
+
+ delete result;
+
+ CharacterDatabase.BeginTransaction();
+ CharacterDatabase.PExecute("DELETE FROM petition WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE petitionguid = '%u'", GUID_LOPART(petitionguid));
+ CharacterDatabase.CommitTransaction();
+
+ // created
+ sLog.outDebug("TURN IN PETITION GUID %u", GUID_LOPART(petitionguid));
+
+ data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4);
+ data << (uint32)PETITION_TURN_OK;
+ SendPacket(&data);
+}
+
+void WorldSession::HandlePetitionShowListOpcode(WorldPacket & recv_data)
+{
+ CHECK_PACKET_SIZE(recv_data, 8);
+
+ sLog.outDebug("Received CMSG_PETITION_SHOWLIST"); // ok
+ //recv_data.hexlike();
+
+ uint64 guid;
+ recv_data >> guid;
+
+ SendPetitionShowList(guid);
+}
+
+void WorldSession::SendPetitionShowList(uint64 guid)
+{
+ Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*_player, guid, UNIT_NPC_FLAG_PETITIONER);
+ if (!pCreature)
+ {
+ sLog.outDebug("WORLD: HandlePetitionShowListOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)));
+ return;
+ }
+
+ // remove fake death
+ if(GetPlayer()->hasUnitState(UNIT_STAT_DIED))
+ GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+
+ uint8 count = 0;
+ if(pCreature->isTabardDesigner())
+ count = 1;
+ else
+ count = 3;
+
+ WorldPacket data(SMSG_PETITION_SHOWLIST, 8+1+4*6);
+ data << guid; // npc guid
+ data << count; // count
+ if(count == 1)
+ {
+ data << uint32(1); // index
+ data << uint32(GUILD_CHARTER); // charter entry
+ data << uint32(16161); // charter display id
+ data << uint32(GUILD_CHARTER_COST); // charter cost
+ data << uint32(0); // unknown
+ data << uint32(9); // required signs?
+ }
+ else
+ {
+ // 2v2
+ data << uint32(1); // index
+ data << uint32(ARENA_TEAM_CHARTER_2v2); // charter entry
+ data << uint32(16161); // charter display id
+ data << uint32(ARENA_TEAM_CHARTER_2v2_COST); // charter cost
+ data << uint32(2); // unknown
+ data << uint32(2); // required signs?
+ // 3v3
+ data << uint32(2); // index
+ data << uint32(ARENA_TEAM_CHARTER_3v3); // charter entry
+ data << uint32(16161); // charter display id
+ data << uint32(ARENA_TEAM_CHARTER_3v3_COST); // charter cost
+ data << uint32(3); // unknown
+ data << uint32(3); // required signs?
+ // 5v5
+ data << uint32(3); // index
+ data << uint32(ARENA_TEAM_CHARTER_5v5); // charter entry
+ data << uint32(16161); // charter display id
+ data << uint32(ARENA_TEAM_CHARTER_5v5_COST); // charter cost
+ data << uint32(5); // unknown
+ data << uint32(5); // required signs?
+ }
+ //for(uint8 i = 0; i < count; i++)
+ //{
+ // data << uint32(i); // index
+ // data << uint32(GUILD_CHARTER); // charter entry
+ // data << uint32(16161); // charter display id
+ // data << uint32(GUILD_CHARTER_COST+i); // charter cost
+ // data << uint32(0); // unknown
+ // data << uint32(9); // required signs?
+ //}
+ SendPacket(&data);
+ sLog.outDebug("Sent SMSG_PETITION_SHOWLIST");
+}
|