diff options
author | Neo2003 <none@none> | 2008-10-02 16:23:55 -0500 |
---|---|---|
committer | Neo2003 <none@none> | 2008-10-02 16:23:55 -0500 |
commit | 9b1c0e006f20091f28f3f468cfcab1feb51286bd (patch) | |
tree | b5d1ba94a656e6679f8737f9ea6bed1239b73b14 /src/game/PetitionsHandler.cpp |
[svn] * Proper SVN structureinit
--HG--
branch : trunk
Diffstat (limited to 'src/game/PetitionsHandler.cpp')
-rw-r--r-- | src/game/PetitionsHandler.cpp | 936 |
1 files changed, 936 insertions, 0 deletions
diff --git a/src/game/PetitionsHandler.cpp b/src/game/PetitionsHandler.cpp new file mode 100644 index 00000000000..6957634dc9e --- /dev/null +++ b/src/game/PetitionsHandler.cpp @@ -0,0 +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"); +} |