Merge commit 'origin/master' into 320

Conflicts:
	src/game/MovementHandler.cpp
This commit is contained in:
tomrus88 2009-08-20 16:24:37 +04:00
commit fec1a1954c
27 changed files with 439 additions and 253 deletions

View file

@ -22,7 +22,9 @@ AC_CONFIG_SRCDIR([src/shared/Base.cpp])
## Prelude, basic settings for Automake
# Turn on all warnings and error messages, and enforce GNU
# standards for the package.
AM_INIT_AUTOMAKE([-Wall -Werror gnu tar-pax])
AM_INIT_AUTOMAKE([foreign -Wall -Werror gnu tar-pax])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
AM_MAINTAINER_MODE
## Prevent the configure script from continuing any further if
@ -69,6 +71,7 @@ AC_PROG_CXX
AM_PROG_CC_C_O
AC_PROG_LIBTOOL
AC_PROG_INSTALL
PKG_PROG_PKG_CONFIG
# Check for doxygen
AC_ARG_ENABLE(doxygen, AC_HELP_STRING([--enable-doxygen], [turn on generating documentation]))
@ -94,7 +97,7 @@ AC_CHECK_LIB( pthread, pthread_create, [],
])
AC_CHECK_LIB( z, compress, [ZLIB=-lz],[AC_MSG_ERROR([Missing zlib])] )
AC_CHECK_LIB( compat, ftime, [COMPATLIB=-lcompat] )
AC_CHECK_LIB( crypto, SHA1_Init, [SSLLIB=-lssl], [AC_MSG_ERROR([Missing openssl])])
PKG_CHECK_MODULES(OPENSSL, [openssl], [], [AC_MSG_ERROR([Missing openssl])])
AC_ARG_WITH(postgresql,
[ --with-postgresql Use PostgreSQL as a backend (default: no)],
@ -121,7 +124,7 @@ AC_MSG_CHECKING(whether to build/link POSTGRESQL)
if test "x$DO_POSTGRESQL" = "xyes"; then
DO_MYSQL=no
POSTGRE_INCLUDES="-I/usr/include/postgresql $POSTGRE_INCLUDES"
POSTGRE_LIBS="-L/usr/lib/postresql -lpq -lz -lpthread -lcrypt -lnsl -lm -lpthread -L/usr/lib -lssl -lcrypto $POSTGRE_LIBS "
POSTGRE_LIBS="-L/usr/lib/postresql -lpq -lz -lpthread -lcrypt -lnsl -lm -lpthread -L/usr/lib $OPENSSL_LIBS $POSTGRE_LIBS "
CXXFLAGS="-DDO_POSTGRESQL $CXXFLAGS"
fi
AC_MSG_RESULT($DO_POSTGRESQL)
@ -174,7 +177,6 @@ AC_HEADER_DIRENT
AC_CHECK_HEADERS([ arpa/inet.h fcntl.h limits.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h strings.h sys/ioctl.h sys/param.h sys/socket.h sys/timeb.h sys/time.h termios.h unistd.h ])
AC_CHECK_HEADERS([pthread.h])
AC_CHECK_HEADERS([openssl/md5.h openssl/rand.h openssl/ssl.h openssl/sha.h openssl/bn.h])
AC_CHECK_HEADERS([mysql.h mysql/mysql.h])
AC_CHECK_HEADERS([libpq-fe.h])
AC_CHECK_HEADERS([zlib.h])
@ -199,36 +201,10 @@ AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS([atexit ftime gethostbyaddr gethostbyname gethostname gettimeofday memmove memset pow realpath select socket sqrt strchr strdup strerror strstr])
## Check what to do with ACE library
AC_LANG_PUSH([C++])
AC_CHECK_HEADER([ace/Reactor.h], [have_ace_headers=yes], [have_ace_headers=no])
AC_CHECK_LIB([ACE], [main], [have_ace_lib=yes], [have_ace_lib=no])
AC_LANG_POP([C++])
AC_MSG_CHECKING([whether to build ACE])
if test X$have_ace_headers = Xyes -a X$have_ace_lib = Xyes;
then
need_to_build_ace=no
AC_MSG_RESULT([no])
else
if test X$have_ace_headers = Xno -a X$have_ace_lib = Xno; then
need_to_build_ace=yes
AC_MSG_RESULT([yes])
else
if test X$have_ace_headers = Xyes; then
AC_MSG_ERROR([looks like you have ACE headers, but you do not have ACE libs installed])
else
need_to_build_ace=yes
AC_MSG_RESULT([yes, over-install])
fi
fi
fi
if test X$need_to_build_ace = Xyes; then
MANGOS_INCLUDES="-I\$(top_srcdir)/dep/ACE_wrappers -I\$(top_builddir)/dep/ACE_wrappers $MANGOS_INCLUDES"
MANGOS_LIBS="\$(top_builddir)/dep/ACE_wrappers/ace/libACE.la $MANGOS_LIBS"
else
MANGOS_LIBS="-lACE $MANGOS_LIBS"
PKG_CHECK_MODULES(ACE, [ACE >= 5.5.2], [need_to_build_ace=no], [need_to_build_ace=yes])
if test X$need_to_build_ace = Xyes ; then
ACE_INCLUDES="-I\$(top_srcdir)/dep/ACE_wrappers -I\$(top_builddir)/dep/ACE_wrappers"
ACE_LIBS="\$(top_builddir)/dep/ACE_wrappers/ace/libACE.la"
fi
AM_CONDITIONAL([MANGOS_BUILD_ACE], [test X$need_to_build_ace = Xyes])
@ -238,8 +214,8 @@ AC_CHECK_HEADERS([ace/Stack_Trace.h])
## Unify all additional includes/libs in one variable.
# TODO this looks kinda ugly, but when we add m4 folder I will make it look very pritey ( by Derex ).
MANGOS_INCLUDES="$POSTGRE_INCLUDES $MYSQL_INCLUDES $MANGOS_INCLUDES"
MANGOS_LIBS="$POSTGRE_LIBS $MYSQL_LIBS $ZLIB $COMPATLIB $SSLLIB $MANGOS_LIBS"
MANGOS_INCLUDES="$ACE_INCLUDES $POSTGRE_INCLUDES $MYSQL_INCLUDES $OPENSSL_INCLUDES $MANGOS_INCLUDES"
MANGOS_LIBS="$ACE_LIBS $POSTGRE_LIBS $MYSQL_LIBS $ZLIB $COMPATLIB $OPENSSL_LIBS $MANGOS_LIBS"
## Export defined variables
AC_SUBST(DOXYGEN)

View file

@ -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_8377_01_mangos_spell_area` bit(1) default NULL
`required_8394_01_mangos_spell_proc_event` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@ -14413,6 +14413,9 @@ INSERT INTO spell_chain VALUES
(63625,0,63625,1,0),
(63626,63625,63625,2,0),
(63627,63626,63625,3,0),
/*Improved Shadowform*/
(47569,0,47569,1,0),
(47570,47569,47569,2,0),
/*Mind Blast*/
(8092,0,8092,1,0),
(8102,8092,8092,2,0),
@ -17727,6 +17730,7 @@ INSERT INTO `spell_proc_event` VALUES
(47515, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(47516, 0x00000000, 6, 0x00001800, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(47517, 0x00000000, 6, 0x00001800, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(47569, 0x00000000, 6, 0x00004000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0),
(47580, 0x00000000, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(47581, 0x00000000, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(47582, 0x00000000, 6, 0x00000000, 0x00000000, 0x00000040, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
@ -17865,6 +17869,7 @@ INSERT INTO `spell_proc_event` VALUES
(54488, 0x00000000, 0, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(54489, 0x00000000, 0, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(54490, 0x00000000, 0, 0x20000021, 0x00009000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(54646, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00015400, 0x00000002, 0.000000, 0.000000, 0),
(54738, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(54747, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(54749, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),

View file

@ -0,0 +1,5 @@
ALTER TABLE db_version CHANGE COLUMN required_8377_01_mangos_spell_area required_8392_01_mangos_spell_proc_event bit;
DELETE FROM `spell_proc_event` WHERE `entry` IN (47569);
INSERT INTO `spell_proc_event` VALUES
(47569, 0x00000000, 6, 0x00004000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0);

View file

@ -0,0 +1,7 @@
ALTER TABLE db_version CHANGE COLUMN required_8392_01_mangos_spell_proc_event required_8392_02_mangos_spell_chain bit;
DELETE FROM `spell_chain` WHERE `spell_id` IN (47569,47570);
INSERT INTO `spell_chain` (`spell_id`, `prev_spell`, `first_spell`, `rank`, `req_spell`) VALUES
/*Improved Shadowform*/
(47569,0,47569,1,0),
(47570,47569,47569,2,0);

View file

@ -0,0 +1,5 @@
ALTER TABLE db_version CHANGE COLUMN required_8392_02_mangos_spell_chain required_8394_01_mangos_spell_proc_event bit;
DELETE FROM `spell_proc_event` WHERE `entry` IN (54646);
INSERT INTO `spell_proc_event` VALUES
(54646, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00015400, 0x00000002, 0.000000, 0.000000, 0);

View file

@ -83,6 +83,9 @@ pkgdata_DATA = \
8361_01_mangos_spell_bonus_data.sql \
8364_01_mangos_db_version.sql \
8377_01_mangos_spell_area.sql \
8392_01_mangos_spell_proc_event.sql \
8392_02_mangos_spell_chain.sql \
8394_01_mangos_spell_proc_event.sql \
README
## Additional files to include when running 'make dist'
@ -146,4 +149,7 @@ EXTRA_DIST = \
8361_01_mangos_spell_bonus_data.sql \
8364_01_mangos_db_version.sql \
8377_01_mangos_spell_area.sql \
8392_01_mangos_spell_proc_event.sql \
8392_02_mangos_spell_chain.sql \
8394_01_mangos_spell_proc_event.sql \
README

View file

@ -576,6 +576,8 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
recv_data >> auctionSlotID >> auctionMainCategory >> auctionSubCategory;
recv_data >> quality >> usable;
recv_data.read_skip(16); // unknown 16 bytes: 00 07 01 00 00 01 05 00 06 00 09 01 08 00 03 00
Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid,UNIT_NPC_FLAG_AUCTIONEER);
if (!pCreature)
{
@ -618,7 +620,8 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )
void WorldSession::HandleAuctionListPendingSales( WorldPacket & recv_data )
{
sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES");
recv_data.hexlike();
recv_data.read_skip<uint64>(); // auctioner guid
uint32 count = 0;

View file

@ -96,6 +96,7 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_ADD_EVENT");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//std::string unk1, unk2;
//recv_data >> (std::string)unk1;
@ -131,6 +132,7 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_UPDATE_EVENT");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
@ -149,6 +151,7 @@ void WorldSession::HandleCalendarRemoveEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_REMOVE_EVENT");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
@ -160,6 +163,7 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_COPY_EVENT");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
@ -171,6 +175,7 @@ void WorldSession::HandleCalendarEventInvite(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_INVITE");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
@ -184,6 +189,7 @@ void WorldSession::HandleCalendarEventRsvp(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_RSVP");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64
@ -195,6 +201,7 @@ void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_REMOVE_INVITE");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data.readPackGUID(guid)
//recv_data >> uint64
@ -206,6 +213,7 @@ void WorldSession::HandleCalendarEventStatus(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_STATUS");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data.readPackGUID(guid)
//recv_data >> uint64
@ -218,6 +226,7 @@ void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_MODERATOR_STATUS");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data.readPackGUID(guid)
//recv_data >> uint64
@ -230,6 +239,7 @@ void WorldSession::HandleCalendarComplain(WorldPacket &recv_data)
{
sLog.outDebug("WORLD: CMSG_CALENDAR_COMPLAIN");
recv_data.hexlike();
recv_data.rpos(recv_data.wpos()); // set to end to avoid warnings spam
//recv_data >> uint64
//recv_data >> uint64

View file

@ -84,15 +84,15 @@ void WorldSession::HandleGMTicketCreateOpcode( WorldPacket & recv_data )
uint32 map;
float x, y, z;
std::string ticketText = "";
uint32 unk1, unk2;
recv_data >> map >> x >> y >> z; // last check 2.4.3
recv_data >> ticketText;
recv_data >> unk1 >> unk2;
// note: the packet might contain more data, but the exact structure of that is unknown
recv_data.read_skip<uint32>(); // unk1, 0
recv_data.read_skip<uint32>(); // unk2, 1
recv_data.read_skip<uint32>(); // unk3, 0
sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s, unk1 %u, unk2 %u", map, x, y, z, ticketText.c_str(), unk1, unk2);
sLog.outDebug("TicketCreate: map %u, x %f, y %f, z %f, text %s", map, x, y, z, ticketText.c_str());
if(ticketmgr.GetGMTicket(GetPlayer()->GetGUIDLow()))
{

View file

@ -614,12 +614,14 @@ void WorldSession::HandleGuildRankOpcode(WorldPacket& recvPacket)
guild = objmgr.GetGuildById(GetPlayer()->GetGuildId());
if(!guild)
{
recvPacket.rpos(recvPacket.wpos()); // set to end to avoid warnings spam
SendGuildCommandResult(GUILD_CREATE_S, "", GUILD_PLAYER_NOT_IN_GUILD);
return;
}
else if(GetPlayer()->GetGUID() != guild->GetLeader())
{
recvPacket.rpos(recvPacket.wpos()); // set to end to avoid warnings spam
SendGuildCommandResult(GUILD_INVITE_S, "", GUILD_PERMISSIONS);
return;
}
@ -1026,9 +1028,14 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
uint64 GoGuid;
uint8 BankToBank;
uint8 BankTab, BankTabSlot, AutoStore, AutoStoreCount, PlayerSlot, PlayerBag, SplitedAmount = 0;
uint8 BankTabDst, BankTabSlotDst, unk2, ToChar = 1;
uint8 BankTab, BankTabSlot, AutoStore;
uint8 PlayerSlot = NULL_SLOT;
uint8 PlayerBag = NULL_BAG;
uint8 BankTabDst, BankTabSlotDst, unk2;
uint8 ToChar = 1;
uint32 ItemEntry, unk1;
uint32 AutoStoreCount = 0;
uint32 SplitedAmount = 0;
recv_data >> GoGuid >> BankToBank;
if (BankToBank)
@ -1042,10 +1049,11 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
recv_data >> unk2; // always 0
recv_data >> SplitedAmount;
if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS)
return;
if (BankTabDst == BankTab && BankTabSlotDst == BankTabSlot)
if (BankTabSlotDst >= GUILD_BANK_MAX_SLOTS || BankTabDst == BankTab && BankTabSlotDst == BankTabSlot)
{
recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
return;
}
}
else
{
@ -1056,17 +1064,22 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
if (AutoStore)
{
recv_data >> AutoStoreCount;
recv_data.read_skip<uint8>(); // ToChar (?), always and expected to be 1 (autostore only triggered in guild->ToChar)
recv_data.read_skip<uint32>(); // unknown, always 0
}
recv_data >> PlayerBag;
recv_data >> PlayerSlot;
if (!AutoStore)
else
{
recv_data >> PlayerBag;
recv_data >> PlayerSlot;
recv_data >> ToChar;
recv_data >> SplitedAmount;
}
if (BankTabSlot >= GUILD_BANK_MAX_SLOTS && BankTabSlot != 0xFF)
{
recv_data.rpos(recv_data.wpos()); // prevent additional spam at rejected packet
return;
}
}
if (!GetPlayer()->GetGameObjectIfCanInteractWith(GoGuid, GAMEOBJECT_TYPE_GUILD_BANK))
@ -1201,14 +1214,6 @@ void WorldSession::HandleGuildBankSwapItems( WorldPacket & recv_data )
// Player <-> Bank
// char->bank autostore click return BankTabSlot = 255 = NULL_SLOT
// do similar for bank->char
if(AutoStore && ToChar)
{
PlayerBag = NULL_BAG;
PlayerSlot = NULL_SLOT;
}
// allow work with inventory only
if(!Player::IsInventoryPos(PlayerBag,PlayerSlot) && !(PlayerBag == NULL_BAG && PlayerSlot == NULL_SLOT) )
{

View file

@ -30,7 +30,8 @@
void WorldSession::HandleSplitItemOpcode( WorldPacket & recv_data )
{
//sLog.outDebug("WORLD: CMSG_SPLIT_ITEM");
uint8 srcbag, srcslot, dstbag, dstslot, count;
uint8 srcbag, srcslot, dstbag, dstslot;
uint32 count;
recv_data >> srcbag >> srcslot >> dstbag >> dstslot >> count;
//sLog.outDebug("STORAGE: receive srcbag = %u, srcslot = %u, dstbag = %u, dstslot = %u, count = %u", srcbag, srcslot, dstbag, dstslot, count);
@ -489,12 +490,9 @@ void WorldSession::HandleSellItemOpcode( WorldPacket & recv_data )
{
sLog.outDebug( "WORLD: Received CMSG_SELL_ITEM" );
uint64 vendorguid, itemguid;
uint8 _count;
uint32 count;
recv_data >> vendorguid >> itemguid >> _count;
// prevent possible overflow, as mangos uses uint32 for item count
uint32 count = _count;
recv_data >> vendorguid >> itemguid >> count;
if(!itemguid)
return;
@ -970,6 +968,8 @@ void WorldSession::HandleItemNameQueryOpcode(WorldPacket & recv_data)
{
uint32 itemid;
recv_data >> itemid;
recv_data.read_skip<uint64>(); // guid
sLog.outDebug("WORLD: CMSG_ITEM_NAME_QUERY %u", itemid);
ItemPrototype const *pProto = objmgr.GetItemPrototype( itemid );
if( pProto )

View file

@ -634,7 +634,7 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)
if(corpse->GetGhostTime() + GetPlayer()->GetCorpseReclaimDelay(corpse->GetType()==CORPSE_RESURRECTABLE_PVP) > time(NULL))
return;
if (!corpse->IsWithinDist(GetPlayer(),CORPSE_RECLAIM_RADIUS,false))
if (!corpse->IsWithinDist(GetPlayer(), CORPSE_RECLAIM_RADIUS, true))
return;
uint64 guid;
@ -721,21 +721,31 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
else
{
// we have only extent
float dx = pl->GetPositionX() - atEntry->x;
float dy = pl->GetPositionY() - atEntry->y;
float dz = pl->GetPositionZ() - atEntry->z;
double es = sin(atEntry->box_orientation);
double ec = cos(atEntry->box_orientation);
// calc rotated vector based on extent axis
double rotateDx = dx*ec - dy*es;
double rotateDy = dx*es + dy*ec;
if( (fabs(rotateDx) > atEntry->box_x/2 + delta) ||
(fabs(rotateDy) > atEntry->box_y/2 + delta) ||
// rotate the players position instead of rotating the whole cube, that way we can make a simplified
// is-in-cube check and we have to calculate only one point instead of 4
// 2PI = 360°, keep in mind that ingame orientation is counter-clockwise
double rotation = 2*M_PI-atEntry->box_orientation;
double sinVal = sin(rotation);
double cosVal = cos(rotation);
float playerBoxDistX = pl->GetPositionX() - atEntry->x;
float playerBoxDistY = pl->GetPositionY() - atEntry->y;
float rotPlayerX = atEntry->x + playerBoxDistX * cosVal - playerBoxDistY*sinVal;
float rotPlayerY = atEntry->y + playerBoxDistY * cosVal + playerBoxDistX*sinVal;
// box edges are parallel to coordiante axis, so we can treat every dimension independently :D
float dz = pl->GetPositionZ() - atEntry->z;
float dx = rotPlayerX - atEntry->x;
float dy = rotPlayerY - atEntry->y;
if( (fabs(dx) > atEntry->box_x/2 + delta) ||
(fabs(dy) > atEntry->box_y/2 + delta) ||
(fabs(dz) > atEntry->box_z/2 + delta) )
{
sLog.outDebug("Player '%s' (GUID: %u) too far (1/2 box X: %f 1/2 box Y: %f 1/2 box Z: %f rotate dX: %f rotate dY: %f dZ:%f), ignore Area Trigger ID: %u",
pl->GetName(), pl->GetGUIDLow(), atEntry->box_x/2, atEntry->box_y/2, atEntry->box_z/2, rotateDx, rotateDy, dz, Trigger_ID);
sLog.outDebug("Player '%s' (GUID: %u) too far (1/2 box X: %f 1/2 box Y: %f 1/2 box Z: %f rotatedPlayerX: %f rotatedPlayerY: %f dZ:%f), ignore Area Trigger ID: %u",
pl->GetName(), pl->GetGUIDLow(), atEntry->box_x/2, atEntry->box_y/2, atEntry->box_z/2, rotPlayerX, rotPlayerY, dz, Trigger_ID);
return;
}
}
@ -868,6 +878,7 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
if(decompressedSize > 0xFFFF)
{
recv_data.rpos(recv_data.wpos()); // unnneded warning spam in this case
sLog.outError("UAD: Account data packet too big, size %u", decompressedSize);
return;
}
@ -878,10 +889,13 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
uLongf realSize = decompressedSize;
if(uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) != Z_OK)
{
recv_data.rpos(recv_data.wpos()); // unnneded warning spam in this case
sLog.outError("UAD: Failed to decompress account data");
return;
}
recv_data.rpos(recv_data.wpos()); // uncompress read (recv_data.size() - recv_data.rpos())
std::string adata;
dest >> adata;
@ -987,7 +1001,8 @@ void WorldSession::HandleMoveTimeSkippedOpcode( WorldPacket & recv_data )
/* WorldSession::Update( getMSTime() );*/
DEBUG_LOG( "WORLD: Time Lag/Synchronization Resent/Update" );
recv_data.read_skip2<uint64,uint32>();
recv_data.read_skip<uint64>();
recv_data.read_skip<uint32>();
/*
uint64 guid;
uint32 time_skipped;
@ -1010,76 +1025,50 @@ void WorldSession::HandleFeatherFallAck(WorldPacket &/*recv_data*/)
void WorldSession::HandleMoveUnRootAck(WorldPacket& recv_data)
{
// no used
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
/*
uint64 guid;
recv_data >> guid;
// now can skip not our packet
if(_player->GetGUID() != guid)
{
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
return;
}
sLog.outDebug( "WORLD: CMSG_FORCE_MOVE_UNROOT_ACK" );
recv_data.read_skip<uint64>(); // guid
recv_data.read_skip<uint64>(); // unknown1
recv_data.read_skip<uint32>(); // unknown2
recv_data.read_skip<float>(); // PositionX
recv_data.read_skip<float>(); // PositionY
recv_data.read_skip<float>(); // PositionZ
recv_data.read_skip<float>(); // Orientation
recv_data.read_skip<uint32>(); // unk
/*
recv_data.hexlike();
recv_data >> guid;
recv_data >> unknown1;
recv_data >> unknown2;
recv_data >> PositionX;
recv_data >> PositionY;
recv_data >> PositionZ;
recv_data >> Orientation;
// TODO for later may be we can use for anticheat
DEBUG_LOG("Guid " UI64FMTD,guid);
DEBUG_LOG("unknown1 " UI64FMTD,unknown1);
DEBUG_LOG("unknown2 %u",unknown2);
DEBUG_LOG("X %f",PositionX);
DEBUG_LOG("Y %f",PositionY);
DEBUG_LOG("Z %f",PositionZ);
DEBUG_LOG("O %f",Orientation);
*/
MovementInfo movementInfo;
ReadMovementInfo(recv_data, &movementInfo);
*/
}
void WorldSession::HandleMoveRootAck(WorldPacket& recv_data)
{
recv_data.read_skip<uint64>(); // guid
recv_data.read_skip<uint64>(); // unknown1
recv_data.read_skip<uint32>(); // unknown2
recv_data.read_skip<float>(); // PositionX
recv_data.read_skip<float>(); // PositionY
recv_data.read_skip<float>(); // PositionZ
recv_data.read_skip<float>(); // Orientation
// no used
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
/*
uint64 guid;
recv_data >> guid;
/*
sLog.outDebug( "WORLD: CMSG_FORCE_MOVE_ROOT_ACK" );
recv_data.hexlike();
uint64 guid;
uint64 unknown1;
uint32 unknown2;
float PositionX;
float PositionY;
float PositionZ;
float Orientation;
// now can skip not our packet
if(_player->GetGUID() != guid)
{
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
return;
}
recv_data >> guid;
recv_data >> unknown1;
recv_data >> unknown2;
recv_data >> PositionX;
recv_data >> PositionY;
recv_data >> PositionZ;
recv_data >> Orientation;
sLog.outDebug( "WORLD: CMSG_FORCE_MOVE_ROOT_ACK" );
// for later may be we can use for anticheat
DEBUG_LOG("Guid " UI64FMTD,guid);
DEBUG_LOG("unknown1 " UI64FMTD,unknown1);
DEBUG_LOG("unknown1 %u",unknown2);
DEBUG_LOG("X %f",PositionX);
DEBUG_LOG("Y %f",PositionY);
DEBUG_LOG("Z %f",PositionZ);
DEBUG_LOG("O %f",Orientation);
*/
recv_data.read_skip<uint32>(); // unk
MovementInfo movementInfo;
ReadMovementInfo(recv_data, &movementInfo);
*/
}
void WorldSession::HandleSetActionBarToggles(WorldPacket& recv_data)

View file

@ -218,7 +218,10 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
// ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
if(plMover && plMover->IsBeingTeleported())
{
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
return;
}
/* extract packet */
uint64 guid;
@ -231,6 +234,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )
ReadMovementInfo(recv_data, &movementInfo);
/*----------------*/
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
if (!MaNGOS::IsValidMapCoord(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o))
return;
@ -353,7 +357,10 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
// now can skip not our packet
if(_player->GetGUID() != guid)
{
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
return;
}
// continue parse packet
recv_data >> unk1; // counter or moveEvent
@ -442,6 +449,7 @@ void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)
if(_player->m_mover->GetGUID() == old_mover_guid)
{
sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is " I64FMT " and should be " I64FMT " instead of " I64FMT, _player->m_mover->GetGUID(), _player->GetGUID(), old_mover_guid);
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
return;
}
@ -460,7 +468,10 @@ void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data)
uint64 vehicleGUID = _player->GetCharmGUID();
if(!vehicleGUID) // something wrong here...
{
recv_data.rpos(recv_data.wpos()); // prevent warnings spam
return;
}
uint64 guid;

View file

@ -491,7 +491,7 @@ void ObjectMgr::LoadCreatureTemplates()
CreatureInfo const* heroicInfo = GetCreatureTemplate(cInfo->HeroicEntry);
if (!heroicInfo)
{
sLog.outErrorDb("Creature (Entry: %u) have `heroic_entry`=%u but creature entry %u not exist.",cInfo->HeroicEntry,cInfo->HeroicEntry);
sLog.outErrorDb("Creature (Entry: %u) have `heroic_entry`=%u but creature entry %u not exist.", i, cInfo->HeroicEntry, cInfo->HeroicEntry);
continue;
}

View file

@ -3859,19 +3859,34 @@ SpellCastResult Spell::CheckCast(bool strict)
}
}
}
else if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster
else if (m_caster == target)
{
// Additional check for some spells
// If 0 spell effect empty - client not send target data (need use selection)
// TODO: check it on next client version
if (m_targets.m_targetMask == TARGET_FLAG_SELF &&
m_spellInfo->EffectImplicitTargetA[1] == TARGET_CHAIN_DAMAGE)
if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster
{
if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection()))
m_targets.setUnitTarget(target);
else
return SPELL_FAILED_BAD_TARGETS;
// Additional check for some spells
// If 0 spell effect empty - client not send target data (need use selection)
// TODO: check it on next client version
if (m_targets.m_targetMask == TARGET_FLAG_SELF &&
m_spellInfo->EffectImplicitTargetA[1] == TARGET_CHAIN_DAMAGE)
{
if (target = m_caster->GetUnit(*m_caster, ((Player *)m_caster)->GetSelection()))
m_targets.setUnitTarget(target);
else
return SPELL_FAILED_BAD_TARGETS;
}
}
// Some special spells with non-caster only mode
// Fire Shield
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK &&
m_spellInfo->SpellIconID == 16)
return SPELL_FAILED_BAD_TARGETS;
// Focus Magic (main spell)
if (m_spellInfo->Id == 54646)
return SPELL_FAILED_BAD_TARGETS;
}
// check pet presents
@ -4679,7 +4694,12 @@ SpellCastResult Spell::CheckPetCast(Unit* target)
bool need = false;
for(uint32 i = 0; i < 3; ++i)
{
if(m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_DAMAGE || m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND || m_spellInfo->EffectImplicitTargetA[i] == TARGET_DUELVSPLAYER || m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_PARTY || m_spellInfo->EffectImplicitTargetA[i] == TARGET_CURRENT_ENEMY_COORDINATES)
if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_CHAIN_DAMAGE ||
m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND ||
m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_FRIEND_2 ||
m_spellInfo->EffectImplicitTargetA[i] == TARGET_DUELVSPLAYER ||
m_spellInfo->EffectImplicitTargetA[i] == TARGET_SINGLE_PARTY ||
m_spellInfo->EffectImplicitTargetA[i] == TARGET_CURRENT_ENEMY_COORDINATES)
{
need = true;
if(!target)

View file

@ -5438,7 +5438,7 @@ void Aura::HandleNoReagentUseAura(bool /*Apply*/, bool Real)
void Aura::HandleShapeshiftBoosts(bool apply)
{
uint32 spellId = 0;
uint32 spellId1 = 0;
uint32 spellId2 = 0;
uint32 HotWSpellId = 0;
uint32 MasterShaperSpellId = 0;
@ -5448,87 +5448,92 @@ void Aura::HandleShapeshiftBoosts(bool apply)
switch(form)
{
case FORM_CAT:
spellId = 3025;
spellId1 = 3025;
HotWSpellId = 24900;
MasterShaperSpellId = 48420;
break;
case FORM_TREE:
spellId = 5420;
spellId1 = 5420;
spellId2 = 34123;
MasterShaperSpellId = 48422;
break;
case FORM_TRAVEL:
spellId = 5419;
spellId1 = 5419;
break;
case FORM_AQUA:
spellId = 5421;
spellId1 = 5421;
break;
case FORM_BEAR:
spellId = 1178;
spellId1 = 1178;
spellId2 = 21178;
HotWSpellId = 24899;
MasterShaperSpellId = 48418;
break;
case FORM_DIREBEAR:
spellId = 9635;
spellId1 = 9635;
spellId2 = 21178;
HotWSpellId = 24899;
MasterShaperSpellId = 48418;
break;
case FORM_BATTLESTANCE:
spellId = 21156;
spellId1 = 21156;
break;
case FORM_DEFENSIVESTANCE:
spellId = 7376;
spellId1 = 7376;
break;
case FORM_BERSERKERSTANCE:
spellId = 7381;
spellId1 = 7381;
break;
case FORM_MOONKIN:
spellId = 24905;
spellId1 = 24905;
// aura from effect trigger spell
spellId2 = 24907;
MasterShaperSpellId = 48421;
break;
case FORM_FLIGHT:
spellId = 33948;
spellId1 = 33948;
spellId2 = 34764;
break;
case FORM_FLIGHT_EPIC:
spellId = 40122;
spellId1 = 40122;
spellId2 = 40121;
break;
case FORM_METAMORPHOSIS:
spellId = 54817;
spellId1 = 54817;
spellId2 = 54879;
break;
case FORM_SPIRITOFREDEMPTION:
spellId = 27792;
spellId1 = 27792;
spellId2 = 27795; // must be second, this important at aura remove to prevent to early iterator invalidation.
break;
case FORM_SHADOW:
spellId1 = 49868;
if(m_target->GetTypeId() == TYPEID_PLAYER) // Spell 49868 have same category as main form spell and share cooldown
((Player*)m_target)->RemoveSpellCooldown(49868);
break;
case FORM_GHOSTWOLF:
case FORM_AMBIENT:
case FORM_GHOUL:
case FORM_SHADOW:
case FORM_STEALTH:
case FORM_CREATURECAT:
case FORM_CREATUREBEAR:
spellId = 0;
spellId1 = 0;
break;
}
if(apply)
{
if (spellId) m_target->CastSpell(m_target, spellId, true, NULL, this );
if (spellId1) m_target->CastSpell(m_target, spellId1, true, NULL, this );
if (spellId2) m_target->CastSpell(m_target, spellId2, true, NULL, this);
if(m_target->GetTypeId() == TYPEID_PLAYER)
if (m_target->GetTypeId() == TYPEID_PLAYER)
{
const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
{
if(itr->second->state == PLAYERSPELL_REMOVED) continue;
if(itr->first==spellId || itr->first==spellId2) continue;
if (itr->second->state == PLAYERSPELL_REMOVED) continue;
if (itr->first==spellId1 || itr->first==spellId2) continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR_PASSIVE | (1<<7))))
continue;
@ -5611,7 +5616,7 @@ void Aura::HandleShapeshiftBoosts(bool apply)
}
else
{
m_target->RemoveAurasDueToSpell(spellId);
m_target->RemoveAurasDueToSpell(spellId1);
m_target->RemoveAurasDueToSpell(spellId2);
m_target->RemoveAurasDueToSpell(MasterShaperSpellId);

View file

@ -4524,6 +4524,68 @@ bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
return true;
}
bool Unit::HandleSpellCritChanceAuraProc(Unit *pVictim, uint32 /*damage*/, Aura* triggeredByAura, SpellEntry const * /*procSpell*/, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown)
{
SpellEntry const *triggeredByAuraSpell = triggeredByAura->GetSpellProto();
Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER
? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
Unit* target = pVictim;
int32 basepoints0 = 0;
switch(triggeredByAuraSpell->SpellFamilyName)
{
case SPELLFAMILY_MAGE:
{
switch(triggeredByAuraSpell->Id)
{
// Focus Magic
case 54646:
{
Unit* caster = triggeredByAura->GetCaster();
if(!caster)
return false;
triggered_spell_id = 54648;
target = caster;
break;
}
}
}
}
// processed charge only counting case
if(!triggered_spell_id)
return true;
SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id);
if(!triggerEntry)
{
sLog.outError("Unit::HandleHasteAuraProc: Spell %u have not existed triggered spell %u",triggeredByAuraSpell->Id,triggered_spell_id);
return false;
}
// default case
if(!target || target!=this && !target->isAlive())
return false;
if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id))
return false;
if(basepoints0)
CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
else
CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura);
if( cooldown && GetTypeId()==TYPEID_PLAYER )
((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown);
return true;
}
bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown)
{
SpellEntry const *dummySpell = triggeredByAura->GetSpellProto ();
@ -5223,6 +5285,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
pVictim->CastSpell(pVictim,57669,true,castItem,triggeredByAura);
return true; // no hidden cooldown
}
// Divine Aegis
if (dummySpell->SpellIconID == 2820)
{
@ -5230,6 +5293,17 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
triggered_spell_id = 47753;
break;
}
// Improved Shadowform
else if (dummySpell->SpellIconID == 217)
{
if(!roll_chance_i(triggerAmount))
return false;
RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
RemoveSpellsCausingAura(SPELL_AURA_MOD_DECREASE_SPEED);
break;
}
switch(dummySpell->Id)
{
// Vampiric Embrace
@ -11130,6 +11204,12 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag
triggeredByAura->SetInUse(false);
continue;
}
sLog.outDebug("ProcDamageAndSpell: casting spell id %u (triggered by %s spell crit chance aura of spell %u)", spellInfo->Id,(isVictim?"a victim's":"an attacker's"), triggeredByAura->GetId());
if (!HandleSpellCritChanceAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag, procExtra, cooldown))
{
triggeredByAura->SetInUse(false);
continue;
}
break;
default:
// nothing do, just charges counter

View file

@ -1551,6 +1551,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const*& spellProcEvent );
bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleSpellCritChanceAuraProc( Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, Aura* triggredByAura, SpellEntry const *procSpell, uint32 cooldown);
bool HandleMendingAuraProc(Aura* triggeredByAura);

View file

@ -26,7 +26,8 @@ void WorldSession::HandleVoiceSessionEnableOpcode( WorldPacket & recv_data )
{
sLog.outDebug("WORLD: CMSG_VOICE_SESSION_ENABLE");
// uint8 isVoiceEnabled, uint8 isMicrophoneEnabled
recv_data.read_skip2<uint8,uint8>();
recv_data.read_skip<uint8>();
recv_data.read_skip<uint8>();
recv_data.hexlike();
}

View file

@ -141,7 +141,7 @@ void WorldSession::QueuePacket(WorldPacket* new_packet)
}
/// Logging helper for unexpected opcodes
void WorldSession::logUnexpectedOpcode(WorldPacket* packet, const char *reason)
void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char *reason)
{
sLog.outError( "SESSION: received unexpected opcode %s (0x%.4X) %s",
LookupOpcodeName(packet->GetOpcode()),
@ -149,6 +149,15 @@ void WorldSession::logUnexpectedOpcode(WorldPacket* packet, const char *reason)
reason);
}
/// Logging helper for unexpected opcodes
void WorldSession::LogUnprocessedTail(WorldPacket *packet)
{
sLog.outError( "SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",
LookupOpcodeName(packet->GetOpcode()),
packet->GetOpcode(),
packet->rpos(),packet->wpos());
}
/// Update the WorldSession (triggered by World update)
bool WorldSession::Update(uint32 /*diff*/)
{
@ -182,30 +191,40 @@ bool WorldSession::Update(uint32 /*diff*/)
{
// skip STATUS_LOGGEDIN opcode unexpected errors if player logout sometime ago - this can be network lag delayed packets
if(!m_playerRecentlyLogout)
logUnexpectedOpcode(packet, "the player has not logged in yet");
LogUnexpectedOpcode(packet, "the player has not logged in yet");
}
else if(_player->IsInWorld())
{
(this->*opHandle.handler)(*packet);
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
LogUnprocessedTail(packet);
}
// lag can cause STATUS_LOGGEDIN opcodes to arrive after the player started a transfer
break;
case STATUS_TRANSFER:
if(!_player)
logUnexpectedOpcode(packet, "the player has not logged in yet");
LogUnexpectedOpcode(packet, "the player has not logged in yet");
else if(_player->IsInWorld())
logUnexpectedOpcode(packet, "the player is still in world");
LogUnexpectedOpcode(packet, "the player is still in world");
else
{
(this->*opHandle.handler)(*packet);
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
LogUnprocessedTail(packet);
}
break;
case STATUS_AUTHED:
// prevent cheating with skip queue wait
if(m_inQueue)
{
logUnexpectedOpcode(packet, "the player not pass queue yet");
LogUnexpectedOpcode(packet, "the player not pass queue yet");
break;
}
m_playerRecentlyLogout = false;
(this->*opHandle.handler)(*packet);
if (sLog.IsOutDebug() && packet->rpos() < packet->wpos())
LogUnprocessedTail(packet);
break;
case STATUS_NEVER:
sLog.outError( "SESSION: received not allowed opcode %s (0x%.4X)",
@ -214,7 +233,7 @@ bool WorldSession::Update(uint32 /*diff*/)
break;
}
}
catch(ByteBufferException &exception)
catch(ByteBufferException &)
{
sLog.outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());

View file

@ -733,7 +733,8 @@ class MANGOS_DLL_SPEC WorldSession
void moveItems(Item* myItems[], Item* hisItems[]);
// logging helper
void logUnexpectedOpcode(WorldPacket *packet, const char * reason);
void LogUnexpectedOpcode(WorldPacket *packet, const char * reason);
void LogUnprocessedTail(WorldPacket *packet);
Player *_player;
WorldSocket *m_Socket;

View file

@ -737,7 +737,7 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
}
}
}
catch(ByteBufferException &exception)
catch(ByteBufferException &)
{
sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.",
opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetAccountId():-1);

View file

@ -27,15 +27,16 @@
class ByteBufferException
{
public:
ByteBufferException(bool add, size_t pos, size_t esize, size_t size):add(add), pos(pos), esize(esize), size(size)
ByteBufferException(bool _add, size_t _pos, size_t _esize, size_t _size)
: add(_add), pos(_pos), esize(_esize), size(_size)
{
PrintPosError();
}
void PrintPosError() const
{
sLog.outError("ERROR: Attempted to %s in ByteBuffer (pos: %lu size: %lu) value with size: %lu",(add ? "put" : "get"),(unsigned long)pos, (unsigned long)size, (unsigned long)esize);
sLog.outError("ERROR: Attempted to %s in ByteBuffer (pos: " SIZEFMTD " size: "SIZEFMTD") value with size: " SIZEFMTD,
(add ? "put" : "get"), pos, size, esize);
}
private:
bool add;
@ -262,22 +263,6 @@ class ByteBuffer
template<typename T>
void read_skip() { read_skip(sizeof(T)); }
template<typename T1, typename T2>
void read_skip2() { read_skip(sizeof(T1)+sizeof(T2)); }
template<>
void read_skip<char*>()
{
uint8 size = read<uint8>();
read_skip(size);
}
template<>
void read_skip<char const*>() { read_skip<char*>(); }
template<>
void read_skip<std::string>() { read_skip<char*>(); }
void read_skip(size_t skip)
{
if(_rpos + skip > size())
@ -512,7 +497,8 @@ class ByteBuffer
std::vector<uint8> _storage;
};
template <typename T> ByteBuffer &operator<<(ByteBuffer &b, std::vector<T> v)
template <typename T>
inline ByteBuffer &operator<<(ByteBuffer &b, std::vector<T> v)
{
b << (uint32)v.size();
for (typename std::vector<T>::iterator i = v.begin(); i != v.end(); ++i)
@ -522,7 +508,8 @@ template <typename T> ByteBuffer &operator<<(ByteBuffer &b, std::vector<T> v)
return b;
}
template <typename T> ByteBuffer &operator>>(ByteBuffer &b, std::vector<T> &v)
template <typename T>
inline ByteBuffer &operator>>(ByteBuffer &b, std::vector<T> &v)
{
uint32 vsize;
b >> vsize;
@ -536,7 +523,8 @@ template <typename T> ByteBuffer &operator>>(ByteBuffer &b, std::vector<T> &v)
return b;
}
template <typename T> ByteBuffer &operator<<(ByteBuffer &b, std::list<T> v)
template <typename T>
inline ByteBuffer &operator<<(ByteBuffer &b, std::list<T> v)
{
b << (uint32)v.size();
for (typename std::list<T>::iterator i = v.begin(); i != v.end(); ++i)
@ -546,7 +534,8 @@ template <typename T> ByteBuffer &operator<<(ByteBuffer &b, std::list<T> v)
return b;
}
template <typename T> ByteBuffer &operator>>(ByteBuffer &b, std::list<T> &v)
template <typename T>
inline ByteBuffer &operator>>(ByteBuffer &b, std::list<T> &v)
{
uint32 vsize;
b >> vsize;
@ -560,7 +549,8 @@ template <typename T> ByteBuffer &operator>>(ByteBuffer &b, std::list<T> &v)
return b;
}
template <typename K, typename V> ByteBuffer &operator<<(ByteBuffer &b, std::map<K, V> &m)
template <typename K, typename V>
inline ByteBuffer &operator<<(ByteBuffer &b, std::map<K, V> &m)
{
b << (uint32)m.size();
for (typename std::map<K, V>::iterator i = m.begin(); i != m.end(); ++i)
@ -570,7 +560,8 @@ template <typename K, typename V> ByteBuffer &operator<<(ByteBuffer &b, std::map
return b;
}
template <typename K, typename V> ByteBuffer &operator>>(ByteBuffer &b, std::map<K, V> &m)
template <typename K, typename V>
inline ByteBuffer &operator>>(ByteBuffer &b, std::map<K, V> &m)
{
uint32 msize;
b >> msize;
@ -584,4 +575,23 @@ template <typename K, typename V> ByteBuffer &operator>>(ByteBuffer &b, std::map
}
return b;
}
template<>
inline void ByteBuffer::read_skip<char*>()
{
std::string temp;
*this >> temp;
}
template<>
inline void ByteBuffer::read_skip<char const*>()
{
read_skip<char*>();
}
template<>
inline void ByteBuffer::read_skip<std::string>()
{
read_skip<char*>();
}
#endif

View file

@ -369,7 +369,11 @@ void Log::outString( const char * str, ... )
if(m_includeTime)
outTime();
UTF8PRINTF(stdout,str,);
va_list ap;
va_start(ap, str);
vutf8printf(stdout, str, &ap);
va_end(ap);
if(m_colored)
ResetColor(true);
@ -379,7 +383,6 @@ void Log::outString( const char * str, ... )
{
outTimestamp(logfile);
va_list ap;
va_start(ap, str);
vfprintf(logfile, str, ap);
fprintf(logfile, "\n" );
@ -401,7 +404,11 @@ void Log::outError( const char * err, ... )
if(m_includeTime)
outTime();
UTF8PRINTF(stderr,err,);
va_list ap;
va_start(ap, err);
vutf8printf(stderr, err, &ap);
va_end(ap);
if(m_colored)
ResetColor(false);
@ -412,7 +419,6 @@ void Log::outError( const char * err, ... )
outTimestamp(logfile);
fprintf(logfile, "ERROR:" );
va_list ap;
va_start(ap, err);
vfprintf(logfile, err, ap);
va_end(ap);
@ -434,7 +440,11 @@ void Log::outErrorDb( const char * err, ... )
if(m_includeTime)
outTime();
UTF8PRINTF(stderr,err,);
va_list ap;
va_start(ap, err);
vutf8printf(stderr, err, &ap);
va_end(ap);
if(m_colored)
ResetColor(false);
@ -446,7 +456,6 @@ void Log::outErrorDb( const char * err, ... )
outTimestamp(logfile);
fprintf(logfile, "ERROR:" );
va_list ap;
va_start(ap, err);
vfprintf(logfile, err, ap);
va_end(ap);
@ -483,7 +492,10 @@ void Log::outBasic( const char * str, ... )
if(m_includeTime)
outTime();
UTF8PRINTF(stdout,str,);
va_list ap;
va_start(ap, str);
vutf8printf(stdout, str, &ap);
va_end(ap);
if(m_colored)
ResetColor(true);
@ -518,7 +530,10 @@ void Log::outDetail( const char * str, ... )
if(m_includeTime)
outTime();
UTF8PRINTF(stdout,str,);
va_list ap;
va_start(ap, str);
vutf8printf(stdout, str, &ap);
va_end(ap);
if(m_colored)
ResetColor(true);
@ -527,12 +542,14 @@ void Log::outDetail( const char * str, ... )
}
if(logfile && m_logFileLevel > 1)
{
va_list ap;
outTimestamp(logfile);
va_list ap;
va_start(ap, str);
vfprintf(logfile, str, ap);
fprintf(logfile, "\n" );
va_end(ap);
fprintf(logfile, "\n" );
fflush(logfile);
}
@ -548,7 +565,10 @@ void Log::outDebugInLine( const char * str, ... )
if(m_colored)
SetColor(true,m_colors[LogDebug]);
UTF8PRINTF(stdout,str,);
va_list ap;
va_start(ap, str);
vutf8printf(stdout, str, &ap);
va_end(ap);
if(m_colored)
ResetColor(true);
@ -574,7 +594,10 @@ void Log::outDebug( const char * str, ... )
if(m_includeTime)
outTime();
UTF8PRINTF(stdout,str,);
va_list ap;
va_start(ap, str);
vutf8printf(stdout, str, &ap);
va_end(ap);
if(m_colored)
ResetColor(true);
@ -609,7 +632,10 @@ void Log::outCommand( uint32 account, const char * str, ... )
if(m_includeTime)
outTime();
UTF8PRINTF(stdout,str,);
va_list ap;
va_start(ap, str);
vutf8printf(stdout, str, &ap);
va_end(ap);
if(m_colored)
ResetColor(true);
@ -691,7 +717,11 @@ void Log::outMenu( const char * str, ... )
if(m_includeTime)
outTime();
UTF8PRINTF(stdout,str,);
va_list ap;
va_start(ap, str);
vutf8printf(stdout, str, &ap);
va_end(ap);
ResetColor(true);
@ -699,7 +729,6 @@ void Log::outMenu( const char * str, ... )
{
outTimestamp(logfile);
va_list ap;
va_start(ap, str);
vfprintf(logfile, str, ap);
va_end(ap);

View file

@ -135,12 +135,8 @@ uint32 TimeStringToSecs(const std::string& timestring)
{
if(isdigit(*itr))
{
std::string str; //very complicated typecast char->const char*; is there no better way?
str += *itr;
const char* tmp = str.c_str();
buffer*=10;
buffer+=atoi(tmp);
buffer+= (*itr)-'0';
}
else
{
@ -419,3 +415,29 @@ bool Utf8FitTo(const std::string& str, std::wstring search)
return true;
}
void utf8printf(FILE *out, const char *str, ...)
{
va_list ap;
va_start(ap, str);
vutf8printf(stdout, str, &ap);
va_end(ap);
}
void vutf8printf(FILE *out, const char *str, va_list* ap)
{
#if PLATFORM == PLATFORM_WINDOWS
char temp_buf[32*1024];
wchar_t wtemp_buf[32*1024];
size_t temp_len = vsnprintf(temp_buf, 32*1024, str, *ap);
size_t wtemp_len = 32*1024-1;
Utf8toWStr(temp_buf, temp_len, wtemp_buf, wtemp_len);
CharToOemBuffW(&wtemp_buf[0], &temp_buf[0], wtemp_len+1);
fprintf(out, temp_buf);
#else
vfprintf(out, str, *ap);
#endif
}

View file

@ -283,32 +283,8 @@ std::wstring GetMainPartOfName(std::wstring wname, uint32 declension);
bool utf8ToConsole(const std::string& utf8str, std::string& conStr);
bool consoleToUtf8(const std::string& conStr,std::string& utf8str);
bool Utf8FitTo(const std::string& str, std::wstring search);
#if PLATFORM == PLATFORM_WINDOWS
#define UTF8PRINTF(OUT,FRM,RESERR) \
{ \
char temp_buf[32*1024]; \
va_list ap; \
va_start(ap, FRM); \
size_t temp_len = vsnprintf(temp_buf,32*1024,FRM,ap); \
va_end(ap); \
\
wchar_t wtemp_buf[32*1024]; \
size_t wtemp_len = 32*1024-1; \
if(!Utf8toWStr(temp_buf,temp_len,wtemp_buf,wtemp_len)) \
return RESERR; \
CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1);\
fprintf(OUT,temp_buf); \
}
#else
#define UTF8PRINTF(OUT,FRM,RESERR) \
{ \
va_list ap; \
va_start(ap, FRM); \
vfprintf(OUT, FRM, ap ); \
va_end(ap); \
}
#endif
void utf8printf(FILE *out, const char *str, ...);
void vutf8printf(FILE *out, const char *str, va_list* ap);
bool IsIPAddress(char const* ipaddress);
uint32 CreatePIDFile(const std::string& filename);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8383"
#define REVISION_NR "8396"
#endif // __REVISION_NR_H__