*Merge after backout.

--HG--
branch : trunk
This commit is contained in:
QAston
2009-07-31 13:21:32 +02:00
64 changed files with 1913 additions and 1614 deletions
+26 -21
View File
@@ -241,10 +241,11 @@ void ReadLiquidTypeTableDBC()
#define MAP_MAGIC 'SPAM'
#define MAP_VERSION_MAGIC '0.1w'
#define MAP_AREA_MAGIC 'AERA'
#define MAP_HEIGTH_MAGIC 'TGHM'
#define MAP_HEIGHT_MAGIC 'TGHM'
#define MAP_LIQUID_MAGIC 'QILM'
struct map_fileheader{
struct map_fileheader
{
uint32 mapMagic;
uint32 versionMagic;
uint32 areaMapOffset;
@@ -256,17 +257,20 @@ struct map_fileheader{
};
#define MAP_AREA_NO_AREA 0x0001
struct map_areaHeader{
struct map_areaHeader
{
uint32 fourcc;
uint16 flags;
uint16 gridArea;
};
#define MAP_HEIGHT_NO_HIGHT 0x0001
#define MAP_HEIGHT_NO_HEIGHT 0x0001
#define MAP_HEIGHT_AS_INT16 0x0002
#define MAP_HEIGHT_AS_INT8 0x0004
struct map_heightHeader{
struct map_heightHeader
{
uint32 fourcc;
uint32 flags;
float gridHeight;
@@ -284,9 +288,10 @@ struct map_heightHeader{
#define MAP_LIQUID_NO_TYPE 0x0001
#define MAP_LIQUID_NO_HIGHT 0x0002
#define MAP_LIQUID_NO_HEIGHT 0x0002
struct map_liquidHeader{
struct map_liquidHeader
{
uint32 fourcc;
uint16 flags;
uint16 liquidType;
@@ -511,20 +516,20 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x)
map.heightMapSize = sizeof(map_heightHeader);
map_heightHeader heightHeader;
heightHeader.fourcc = MAP_HEIGTH_MAGIC;
heightHeader.fourcc = MAP_HEIGHT_MAGIC;
heightHeader.flags = 0;
heightHeader.gridHeight = minHeight;
heightHeader.gridMaxHeight = maxHeight;
if (maxHeight == minHeight)
heightHeader.flags |=MAP_HEIGHT_NO_HIGHT;
heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT;
// Not need store if flat surface
if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_height_delta_limit)
heightHeader.flags |=MAP_HEIGHT_NO_HIGHT;
heightHeader.flags |= MAP_HEIGHT_NO_HEIGHT;
// Try store as packed in uint16 or uint8 values
if (!(heightHeader.flags&MAP_HEIGHT_NO_HIGHT))
if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT))
{
float step;
// Try Store as uint values
@@ -756,22 +761,22 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x)
liquidHeader.liquidLevel = minHeight;
if (maxHeight == minHeight)
liquidHeader.flags|=MAP_LIQUID_NO_HIGHT;
liquidHeader.flags |= MAP_LIQUID_NO_HEIGHT;
// Not need store if flat surface
if (CONF_allow_float_to_int && (maxHeight - minHeight) < CONF_flat_liquid_delta_limit)
liquidHeader.flags|=MAP_LIQUID_NO_HIGHT;
liquidHeader.flags |= MAP_LIQUID_NO_HEIGHT;
if (!fullType)
liquidHeader.flags|=MAP_LIQUID_NO_TYPE;
liquidHeader.flags |= MAP_LIQUID_NO_TYPE;
if (liquidHeader.flags&MAP_LIQUID_NO_TYPE)
if (liquidHeader.flags & MAP_LIQUID_NO_TYPE)
liquidHeader.liquidType = type;
else
map.liquidMapSize+=sizeof(liquid_type);
if (!(liquidHeader.flags&MAP_LIQUID_NO_HIGHT))
map.liquidMapSize+=sizeof(float)*liquidHeader.width*liquidHeader.height;
if (!(liquidHeader.flags & MAP_LIQUID_NO_HEIGHT))
map.liquidMapSize += sizeof(float)*liquidHeader.width*liquidHeader.height;
}
// Ok all data prepared - store it
@@ -789,14 +794,14 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x)
// Store height data
fwrite(&heightHeader, sizeof(heightHeader), 1, output);
if (!(heightHeader.flags&MAP_HEIGHT_NO_HIGHT))
if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT))
{
if (heightHeader.flags&MAP_HEIGHT_AS_INT16)
if (heightHeader.flags & MAP_HEIGHT_AS_INT16)
{
fwrite(uint16_V9, sizeof(uint16_V9), 1, output);
fwrite(uint16_V8, sizeof(uint16_V8), 1, output);
}
else if (heightHeader.flags&MAP_HEIGHT_AS_INT8)
else if (heightHeader.flags & MAP_HEIGHT_AS_INT8)
{
fwrite(uint8_V9, sizeof(uint8_V9), 1, output);
fwrite(uint8_V8, sizeof(uint8_V8), 1, output);
@@ -814,7 +819,7 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x)
fwrite(&liquidHeader, sizeof(liquidHeader), 1, output);
if (!(liquidHeader.flags&MAP_LIQUID_NO_TYPE))
fwrite(liquid_type, sizeof(liquid_type), 1, output);
if (!(liquidHeader.flags&MAP_LIQUID_NO_HIGHT))
if (!(liquidHeader.flags&MAP_LIQUID_NO_HEIGHT))
{
for (int y=0; y<liquidHeader.height;y++)
fwrite(&liquid_height[y+liquidHeader.offsetY][liquidHeader.offsetX], sizeof(float), liquidHeader.width, output);
+33 -21
View File
@@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
`required_8247_01_mangos_spell_bonus_data` bit(1) default NULL
`required_8254_01_mangos_spell_proc_event` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
@@ -15376,7 +15376,7 @@ INSERT INTO spell_chain VALUES
(27219,11700,689,7,0),
(27220,27219,689,8,0),
(47857,27220,689,9,0),
/*DrainSoul*/
/*Drain Soul*/
(1120,0,1120,1,0),
(8288,1120,1120,2,0),
(8289,8288,1120,3,0),
@@ -15392,14 +15392,20 @@ INSERT INTO spell_chain VALUES
(59161,48181,48181,2,0),
(59163,59161,48181,3,0),
(59164,59163,48181,4,0),
/*HowlofTerror*/
/*Howl of Terror*/
(5484,0,5484,1,0),
(17928,5484,5484,2,0),
/*SeedofCorruption*/
/*Seed of Corruption*/
(27243,0,27243,1,0),
(47835,27243,27243,2,0),
(47836,47835,27243,3,0),
/*UnstableAffliction*/
/* Shadow embrace */
(32385,0,32385,1,0),
(32387,32385,32385,2,0),
(32392,32387,32385,3,0),
(32393,32392,32385,4,0),
(32394,32393,32385,5,0),
/*Unstable Affliction*/
(30108,0,30108,1,0),
(30404,30108,30108,2,0),
(30405,30404,30108,3,0),
@@ -15486,6 +15492,12 @@ INSERT INTO spell_chain VALUES
(25472,25469,324,9,0),
(49280,25472,324,10,0),
(49281,49280,324,11,0),
/*Maelstrom Weapon*/
(51528,0,51528,1,0),
(51529,51528,51528,2,0),
(51530,51529,51528,3,0),
(51531,51530,51528,4,0),
(51532,51531,51528,5,0),
/*Nature Resistance Totem*/
(10595,0,10595,1,0),
(10600,10595,10595,2,0),
@@ -16924,7 +16936,7 @@ INSERT INTO `spell_proc_event` VALUES
(12999, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 4.000000, 0.000000, 0),
(13000, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 6.000000, 0.000000, 0),
(13001, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 8.000000, 0.000000, 0),
(13002, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 10.000000, 0.000000, 0),
(13002, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,10.000000, 0.000000, 0),
(13045, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(13046, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(13047, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
@@ -17023,8 +17035,8 @@ INSERT INTO `spell_proc_event` VALUES
(20131, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(20132, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(20164, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 5.000000, 0.000000, 0),
(20165, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 20.000000, 0.000000, 0),
(20166, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 20.000000, 0.000000, 0),
(20165, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,20.000000, 0.000000, 0),
(20166, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,15.000000, 0.000000, 0),
(20182, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(20210, 0x00000000, 10, 0xC0000000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(20212, 0x00000000, 10, 0xC0000000, 0x00010000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
@@ -17065,7 +17077,7 @@ INSERT INTO `spell_proc_event` VALUES
(24389, 0x00000000, 3, 0x00C00017, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(24398, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3),
(24658, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00014110, 0x00000000, 0.000000, 0.000000, 0),
(24905, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 15.000000, 0.000000, 0),
(24905, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002,15.000000, 0.000000, 0),
(24932, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 6),
(25050, 0x00000004, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(25296, 0x00000000, 9, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
@@ -17168,7 +17180,7 @@ INSERT INTO `spell_proc_event` VALUES
(31570, 0x00000000, 3, 0x00010000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(31785, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00008800, 0x00000000, 0.000000, 0.000000, 0),
(31794, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(31801, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 20.000000, 0.000000, 0),
(31801, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,20.000000, 0.000000, 0),
(31833, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(31835, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(31836, 0x00000000, 10, 0x80000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
@@ -17178,11 +17190,7 @@ INSERT INTO `spell_proc_event` VALUES
(31877, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000008, 0x00004110, 0x00000000, 0.000000, 0.000000, 0),
(31878, 0x00000000, 10, 0x00800000, 0x00000000, 0x00000008, 0x00004110, 0x00000000, 0.000000, 0.000000, 0),
(31904, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(32385, 0x00000000, 5, 0x00000402, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32387, 0x00000000, 5, 0x00000402, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32392, 0x00000000, 5, 0x00000402, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32393, 0x00000000, 5, 0x00000402, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32394, 0x00000000, 5, 0x00000402, 0x00000011, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32385, 0x00000000, 5, 0x00000001, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32409, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(32587, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000040, 0.000000, 0.000000, 0),
(32593, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3),
@@ -17476,6 +17484,7 @@ INSERT INTO `spell_proc_event` VALUES
(51483, 0x00000001, 11, 0x20000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0),
(51485, 0x00000001, 11, 0x20000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0),
(51486, 0x00000001, 11, 0x20000000, 0x00000000, 0x00000000, 0x00004000, 0x00000000, 0.000000, 0.000000, 0),
(51528, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,12.500000, 0.000000, 0),
(51556, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(51557, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(51558, 0x00000000, 11, 0x000000C0, 0x00000000, 0x00000010, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
@@ -17505,12 +17514,12 @@ INSERT INTO `spell_proc_event` VALUES
(51698, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1),
(51700, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1),
(51701, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 1),
(51940, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
(51989, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
(52004, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
(52005, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
(52007, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
(52008, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 20.000000, 0),
(51940, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(51989, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(52004, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(52005, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(52007, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(52008, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000,20.000000, 0),
(52020, 0x00000000, 7, 0x00008000, 0x00100000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(52127, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3),
(52129, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 3),
@@ -17586,6 +17595,7 @@ INSERT INTO `spell_proc_event` VALUES
(55677, 0x00000000, 6, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(55680, 0x00000000, 6, 0x00000200, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(55689, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
(55747, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(55768, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(55776, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(56218, 0x00000000, 5, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
@@ -17634,6 +17644,8 @@ INSERT INTO `spell_proc_event` VALUES
(60132, 0x00000000, 15, 0x00000000, 0x08020000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(60170, 0x00000000, 5, 0x00000006, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(60172, 0x00000000, 5, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0x00010000, 0.000000, 0.000000, 0),
(60436, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(60442, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(60493, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(60503, 0x00000000, 4, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0),
(60537, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0.000000, 0.000000, 0),
+2
View File
@@ -229,6 +229,8 @@ INSERT INTO spell_check (spellid,SpellFamilyName,SpellFamilyMaskA,SpellFamilyMas
(45030, 0, -1, -1, -1, -1, -1, 3, -1,-1,'Impale Emissary', 'Spell::EffectDummy'),
(45088,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Emissary of Hate Credit', 'Spell::EffectDummy'),
(45150, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor Slash', 'Spell::EffectSchoolDMG'),
(64422, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor Slash', 'Spell::EffectSchoolDMG'),
(64688, 0, -1, -1, -1, -1, -1, 2, -1,-1,'Meteor Slash', 'Spell::EffectSchoolDMG'),
(45182,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Cheat Death', 'Spell::EffectDummy'),
(46014,-1, -1, -1, -1, -1, -1, -1, -1,-1,'Knocked Up', 'Spell::EffectDummy'),
(47540, 6,0x0080000000000000,0x00000000, -1, -1, -1, 3, -1,-1,'Penance', 'Spell::EffectDummy'),
@@ -0,0 +1,21 @@
ALTER TABLE db_version CHANGE COLUMN required_8253_01_mangos_spell_chain required_8253_02_mangos_spell_proc_event bit;
/*Bandit's Insignia*/
DELETE FROM `spell_proc_event` WHERE entry IN (60442);
INSERT INTO spell_proc_event VALUES
(60442, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45);
/*Seal of wisdom*/
DELETE FROM `spell_proc_event` WHERE `entry` IN (20166);
INSERT INTO `spell_proc_event` VALUES
(20166, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,15.000000, 0.000000, 0);
/*Shadow embrace*/
DELETE FROM `spell_proc_event` WHERE `entry` IN (32385);
INSERT INTO `spell_proc_event` VALUES
(32385, 0x00000000, 5, 0x00000001, 0x00040000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 0);
/*Maelstrom Weapon*/
DELETE FROM `spell_proc_event` WHERE `entry` IN (51528);
INSERT INTO `spell_proc_event` VALUES
(51528, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,12.500000, 0.000000, 0);
@@ -0,0 +1,6 @@
ALTER TABLE db_version CHANGE COLUMN required_8253_02_mangos_spell_proc_event required_8254_01_mangos_spell_proc_event bit;
DELETE FROM `spell_proc_event` WHERE `entry` IN (55747,60436);
INSERT INTO `spell_proc_event` VALUES
(55747, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45),
(60436, 0x00000000, 0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0.000000, 0.000000, 45);
+24 -24
View File
@@ -26,7 +26,7 @@
#include "Player.h"
#include "Util.h"
extern DatabaseType LoginDatabase;
extern DatabaseType loginDatabase;
INSTANTIATE_SINGLETON_1(AccountMgr);
@@ -44,26 +44,26 @@ AccountOpResult AccountMgr::CreateAccount(std::string username, std::string pass
normalizeString(username);
normalizeString(password);
LoginDatabase.escape_string(username);
LoginDatabase.escape_string(password);
loginDatabase.escape_string(username);
loginDatabase.escape_string(password);
QueryResult *result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'", username.c_str());
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE username = '%s'", username.c_str());
if(result)
{
delete result;
return AOR_NAME_ALREDY_EXIST; // username does already exist
}
if(!LoginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s',SHA1(CONCAT('%s',':','%s')),NOW())", username.c_str(), username.c_str(), password.c_str()))
if(!loginDatabase.PExecute("INSERT INTO account(username,sha_pass_hash,joindate) VALUES('%s',SHA1(CONCAT('%s',':','%s')),NOW())", username.c_str(), username.c_str(), password.c_str()))
return AOR_DB_INTERNAL_ERROR; // unexpected error
LoginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist,account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL");
loginDatabase.Execute("INSERT INTO realmcharacters (realmid, acctid, numchars) SELECT realmlist.id, account.id, 0 FROM realmlist,account LEFT JOIN realmcharacters ON acctid=account.id WHERE acctid IS NULL");
return AOR_OK; // everything's fine
}
AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
{
QueryResult *result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
if(!result)
return AOR_NAME_NOT_EXIST; // account doesn't exist
delete result;
@@ -94,13 +94,13 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
// table realm specific but common for all characters of account for realm
CharacterDatabase.PExecute("DELETE FROM character_tutorial WHERE account = '%u'",accid);
LoginDatabase.BeginTransaction();
loginDatabase.BeginTransaction();
bool res =
LoginDatabase.PExecute("DELETE FROM account WHERE id='%d'", accid) &&
LoginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid);
loginDatabase.PExecute("DELETE FROM account WHERE id='%d'", accid) &&
loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid='%d'", accid);
LoginDatabase.CommitTransaction();
loginDatabase.CommitTransaction();
if(!res)
return AOR_DB_INTERNAL_ERROR; // unexpected error;
@@ -110,7 +110,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid)
AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname, std::string new_passwd)
{
QueryResult *result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
if(!result)
return AOR_NAME_NOT_EXIST; // account doesn't exist
delete result;
@@ -124,9 +124,9 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname,
normalizeString(new_uname);
normalizeString(new_passwd);
LoginDatabase.escape_string(new_uname);
LoginDatabase.escape_string(new_passwd);
if(!LoginDatabase.PExecute("UPDATE account SET username='%s',sha_pass_hash=SHA1(CONCAT('%s',':','%s')) WHERE id='%d'", new_uname.c_str(), new_uname.c_str(), new_passwd.c_str(), accid))
loginDatabase.escape_string(new_uname);
loginDatabase.escape_string(new_passwd);
if(!loginDatabase.PExecute("UPDATE account SET username='%s',sha_pass_hash=SHA1(CONCAT('%s',':','%s')) WHERE id='%d'", new_uname.c_str(), new_uname.c_str(), new_passwd.c_str(), accid))
return AOR_DB_INTERNAL_ERROR; // unexpected error
return AOR_OK;
@@ -134,7 +134,7 @@ AccountOpResult AccountMgr::ChangeUsername(uint32 accid, std::string new_uname,
AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
{
QueryResult *result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d'", accid);
if(!result)
return AOR_NAME_NOT_EXIST; // account doesn't exist
delete result;
@@ -144,8 +144,8 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
normalizeString(new_passwd);
LoginDatabase.escape_string(new_passwd);
if(!LoginDatabase.PExecute("UPDATE account SET sha_pass_hash=SHA1(CONCAT(username,':','%s')) WHERE id='%d'", new_passwd.c_str(), accid))
loginDatabase.escape_string(new_passwd);
if(!loginDatabase.PExecute("UPDATE account SET sha_pass_hash=SHA1(CONCAT(username,':','%s')) WHERE id='%d'", new_passwd.c_str(), accid))
return AOR_DB_INTERNAL_ERROR; // unexpected error
return AOR_OK;
@@ -153,8 +153,8 @@ AccountOpResult AccountMgr::ChangePassword(uint32 accid, std::string new_passwd)
uint32 AccountMgr::GetId(std::string username)
{
LoginDatabase.escape_string(username);
QueryResult *result = LoginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", username.c_str());
loginDatabase.escape_string(username);
QueryResult *result = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'", username.c_str());
if(!result)
return 0;
else
@@ -167,7 +167,7 @@ uint32 AccountMgr::GetId(std::string username)
uint32 AccountMgr::GetSecurity(uint32 acc_id)
{
QueryResult *result = LoginDatabase.PQuery("SELECT gmlevel FROM account WHERE id = '%u'", acc_id);
QueryResult *result = loginDatabase.PQuery("SELECT gmlevel FROM account WHERE id = '%u'", acc_id);
if(result)
{
uint32 sec = (*result)[0].GetUInt32();
@@ -180,7 +180,7 @@ uint32 AccountMgr::GetSecurity(uint32 acc_id)
bool AccountMgr::GetName(uint32 acc_id, std::string &name)
{
QueryResult *result = LoginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", acc_id);
QueryResult *result = loginDatabase.PQuery("SELECT username FROM account WHERE id = '%u'", acc_id);
if(result)
{
name = (*result)[0].GetCppString();
@@ -194,9 +194,9 @@ bool AccountMgr::GetName(uint32 acc_id, std::string &name)
bool AccountMgr::CheckPassword(uint32 accid, std::string passwd)
{
normalizeString(passwd);
LoginDatabase.escape_string(passwd);
loginDatabase.escape_string(passwd);
QueryResult *result = LoginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash=SHA1(CONCAT(username,':','%s'))", accid, passwd.c_str());
QueryResult *result = loginDatabase.PQuery("SELECT 1 FROM account WHERE id='%d' AND sha_pass_hash=SHA1(CONCAT(username,':','%s'))", accid, passwd.c_str());
if (result)
{
delete result;
+66 -10
View File
@@ -36,6 +36,8 @@
#include "SpellMgr.h"
#include "MapManager.h"
#include "BattleGround.h"
#include "BattleGroundAB.h"
INSTANTIATE_SINGLETON_1(AchievementGlobalMgr);
@@ -81,6 +83,7 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
switch(criteria->requiredType)
{
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: // only hardcoded list
case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING:
@@ -233,6 +236,8 @@ bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
return false;
}
return true;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE:
return true; // not check correctness node indexes
default:
sLog.outErrorDb( "Table `achievement_criteria_data` (Entry: %u Type: %u) have data for not supported data type (%u), ignore.", criteria->ID, criteria->requiredType,dataType);
return false;
@@ -301,6 +306,13 @@ bool AchievementCriteriaData::Meets(Player const* source, Unit const* target, ui
return Player::GetDrunkenstateByValue(source->GetDrunkValue()) >= drunk.state;
case ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY:
return IsHolidayActive(HolidayIds(holiday.id));
case ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE:
{
BattleGround* bg = source->GetBattleGround();
if(!bg)
return false;
return bg->IsTeamScoreInRange(source->GetTeam()==ALLIANCE ? HORDE : ALLIANCE,bg_loss_team_score.min_score,bg_loss_team_score.max_score);
}
}
return false;
}
@@ -720,6 +732,54 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
// specialized cases
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
{
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
if (!miscvalue1)
continue;
if (achievementCriteria->win_bg.bgMapID != GetPlayer()->GetMapId())
continue;
if (achievementCriteria->win_bg.additionalRequirement1_type)
{
// those requirements couldn't be found in the dbc
AchievementCriteriaDataSet const* data = achievementmgr.GetCriteriaDataSet(achievementCriteria);
if (!data || !data->Meets(GetPlayer(),unit))
continue;
}
// some hardcoded requirements
else
{
BattleGround* bg = GetPlayer()->GetBattleGround();
if (!bg)
continue;
switch(achievementCriteria->referredAchievement)
{
case 161: // AB, Overcome a 500 resource disadvantage
{
if (bg->GetTypeID() != BATTLEGROUND_AB)
continue;
if(!((BattleGroundAB*)bg)->IsTeamScores500disadvantage(GetPlayer()->GetTeam()))
continue;
break;
}
case 156: // AB, win while controlling all 5 flags (all nodes)
case 784: // EY, win while holding 4 bases (all nodes)
{
if(!bg->IsAllNodesConrolledByTeam(GetPlayer()->GetTeam()))
continue;
break;
}
case 1762: // SA, win without losing any siege vehicles
case 2192: // SA, win without losing any siege vehicles
continue; // not implemented
}
}
SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_ACCUMULATE);
break;
}
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
{
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
@@ -790,14 +850,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui
continue;
SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
if(!miscvalue1)
continue;
if(GetPlayer()->GetMapId() != achievementCriteria->win_bg.bgMapID)
continue;
SetCriteriaProgress(achievementCriteria, miscvalue1, PROGRESS_ACCUMULATE);
break;
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
// AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case
if(!miscvalue1)
@@ -1347,6 +1399,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
switch(achievementCriteria->requiredType)
{
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
return progress->counter >= achievementCriteria->win_bg.winCount;
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
return progress->counter >= achievementCriteria->kill_creature.creatureCount;
case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL:
@@ -1438,8 +1492,6 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve
return progress->counter >= achievementCriteria->learn_skill_line.spellCount;
case ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL:
return progress->counter >= achievementCriteria->honorable_kill.killCount;
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
return progress->counter >= achievementCriteria->win_bg.winCount;
// handle all statistic-only criteria here
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND:
case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP:
@@ -1853,6 +1905,10 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
switch(criteria->requiredType)
{
case ACHIEVEMENT_CRITERIA_TYPE_WIN_BG:
if(!criteria->win_bg.additionalRequirement1_type)
continue;
break;
case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE:
break; // any cases
case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST:
+10 -3
View File
@@ -59,9 +59,10 @@ enum AchievementCriteriaDataType
ACHIEVEMENT_CRITERIA_DATA_TYPE_T_TEAM = 14,// team HORDE(67), ALLIANCE(469)
ACHIEVEMENT_CRITERIA_DATA_TYPE_S_DRUNK = 15,// drunken_state 0 (enum DrunkenState) of player
ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16,// holiday_id 0 event in holiday time
ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE = 17,// min_score max_score player's team win bg and opposition team have team score in range
};
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 17 // maximum value in AchievementCriteriaDataType enum
#define MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE 18 // maximum value in AchievementCriteriaDataType enum
class Player;
class Unit;
@@ -141,11 +142,17 @@ struct AchievementCriteriaData
{
uint32 state;
} drunk;
// ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY
// ACHIEVEMENT_CRITERIA_DATA_TYPE_HOLIDAY = 16
struct
{
uint16 id;
uint32 id;
} holiday;
// ACHIEVEMENT_CRITERIA_DATA_TYPE_BG_LOSS_TEAM_SCORE= 17
struct
{
uint32 min_score;
uint32 max_score;
} bg_loss_team_score;
// ...
struct
{
+118 -119
View File
@@ -33,24 +33,24 @@ void ArenaTeamMember::ModifyPersonalRating(Player* plr, int32 mod, uint32 slot)
ArenaTeam::ArenaTeam()
{
Id = 0;
Type = 0;
Name = "";
CaptainGuid = 0;
BackgroundColor = 0; // background
EmblemStyle = 0; // icon
EmblemColor = 0; // icon color
BorderStyle = 0; // border
BorderColor = 0; // border color
stats.games_week = 0;
stats.games_season = 0;
stats.rank = 0;
m_TeamId = 0;
m_Type = 0;
m_Name = "";
m_CaptainGuid = 0;
m_BackgroundColor = 0; // background
m_EmblemStyle = 0; // icon
m_EmblemColor = 0; // icon color
m_BorderStyle = 0; // border
m_BorderColor = 0; // border color
m_stats.games_week = 0;
m_stats.games_season = 0;
m_stats.rank = 0;
if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
stats.rating = 0;
m_stats.rating = 0;
else
stats.rating = 1500;
stats.wins_week = 0;
stats.wins_season = 0;
m_stats.rating = 1500;
m_stats.wins_week = 0;
m_stats.wins_season = 0;
}
ArenaTeam::~ArenaTeam()
@@ -66,27 +66,27 @@ bool ArenaTeam::Create(uint64 captainGuid, uint32 type, std::string ArenaTeamNam
sLog.outDebug("GUILD: creating arena team %s to leader: %u", ArenaTeamName.c_str(), GUID_LOPART(captainGuid));
CaptainGuid = captainGuid;
Name = ArenaTeamName;
Type = type;
m_CaptainGuid = captainGuid;
m_Name = ArenaTeamName;
m_Type = type;
Id = objmgr.GenerateArenaTeamId();
m_TeamId = objmgr.GenerateArenaTeamId();
// ArenaTeamName already assigned to ArenaTeam::name, use it to encode string for DB
CharacterDatabase.escape_string(ArenaTeamName);
CharacterDatabase.BeginTransaction();
// CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", Id); - MAX(arenateam)+1 not exist
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", Id);
// CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid='%u'", m_TeamId); - MAX(arenateam)+1 not exist
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid='%u'", m_TeamId);
CharacterDatabase.PExecute("INSERT INTO arena_team (arenateamid,name,captainguid,type,BackgroundColor,EmblemStyle,EmblemColor,BorderStyle,BorderColor) "
"VALUES('%u','%s','%u','%u','%u','%u','%u','%u','%u')",
Id, ArenaTeamName.c_str(), GUID_LOPART(CaptainGuid), Type, BackgroundColor, EmblemStyle, EmblemColor, BorderStyle, BorderColor);
m_TeamId, ArenaTeamName.c_str(), GUID_LOPART(m_CaptainGuid), m_Type, m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor);
CharacterDatabase.PExecute("INSERT INTO arena_team_stats (arenateamid, rating, games, wins, played, wins2, rank) VALUES "
"('%u', '%u', '%u', '%u', '%u', '%u', '%u')", Id, stats.rating, stats.games_week, stats.wins_week, stats.games_season, stats.wins_season, stats.rank);
"('%u', '%u', '%u', '%u', '%u', '%u', '%u')", m_TeamId, m_stats.rating, m_stats.games_week, m_stats.wins_week, m_stats.games_season, m_stats.wins_season, m_stats.rank);
CharacterDatabase.CommitTransaction();
AddMember(CaptainGuid);
AddMember(m_CaptainGuid);
sLog.outArena("New ArenaTeam created [Id: %u] [Type: %u] [Captain GUID: %u]", GetId(), GetType(), GetCaptain());
return true;
}
@@ -145,8 +145,8 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
newmember.wins_week = 0;
if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
{
if (stats.rating < 1000)
newmember.personal_rating = stats.rating;
if (m_stats.rating < 1000)
newmember.personal_rating = m_stats.rating;
else
newmember.personal_rating = 1000;
}
@@ -154,18 +154,18 @@ bool ArenaTeam::AddMember(const uint64& PlayerGuid)
{
newmember.personal_rating = 1500;
}
members.push_back(newmember);
m_members.push_back(newmember);
CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid, guid, personal_rating) VALUES ('%u', '%u', '%u')", Id, GUID_LOPART(newmember.guid), newmember.personal_rating );
CharacterDatabase.PExecute("INSERT INTO arena_team_member (arenateamid, guid, personal_rating) VALUES ('%u', '%u', '%u')", m_TeamId, GUID_LOPART(newmember.guid), newmember.personal_rating );
if(pl)
{
pl->SetInArenaTeam(Id, GetSlot());
pl->SetInArenaTeam(m_TeamId, GetSlot());
pl->SetArenaTeamIdInvited(0);
pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot()*6) + 5, newmember.personal_rating );
// hide promote/remove buttons
if(CaptainGuid != PlayerGuid)
if(m_CaptainGuid != PlayerGuid)
pl->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (GetSlot() * 6) + 1, 1);
sLog.outArena("Player: %s [GUID: %u] joined arena team type: %u [Id: %u].", pl->GetName(), pl->GetGUIDLow(), GetType(), GetId());
}
@@ -181,15 +181,15 @@ bool ArenaTeam::LoadArenaTeamFromDB(uint32 ArenaTeamId)
Field *fields = result->Fetch();
Id = fields[0].GetUInt32();
Name = fields[1].GetCppString();
CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
Type = fields[3].GetUInt32();
BackgroundColor = fields[4].GetUInt32();
EmblemStyle = fields[5].GetUInt32();
EmblemColor = fields[6].GetUInt32();
BorderStyle = fields[7].GetUInt32();
BorderColor = fields[8].GetUInt32();
m_TeamId = fields[0].GetUInt32();
m_Name = fields[1].GetCppString();
m_CaptainGuid = MAKE_NEW_GUID(fields[2].GetUInt32(), 0, HIGHGUID_PLAYER);
m_Type = fields[3].GetUInt32();
m_BackgroundColor = fields[4].GetUInt32();
m_EmblemStyle = fields[5].GetUInt32();
m_EmblemColor = fields[6].GetUInt32();
m_BorderStyle = fields[7].GetUInt32();
m_BorderColor = fields[8].GetUInt32();
delete result;
@@ -221,12 +221,12 @@ void ArenaTeam::LoadStatsFromDB(uint32 ArenaTeamId)
Field *fields = result->Fetch();
stats.rating = fields[0].GetUInt32();
stats.games_week = fields[1].GetUInt32();
stats.wins_week = fields[2].GetUInt32();
stats.games_season = fields[3].GetUInt32();
stats.wins_season = fields[4].GetUInt32();
stats.rank = fields[5].GetUInt32();
m_stats.rating = fields[0].GetUInt32();
m_stats.games_week = fields[1].GetUInt32();
m_stats.wins_week = fields[2].GetUInt32();
m_stats.games_season = fields[3].GetUInt32();
m_stats.wins_season = fields[4].GetUInt32();
m_stats.rank = fields[5].GetUInt32();
delete result;
}
@@ -253,7 +253,7 @@ void ArenaTeam::LoadMembersFromDB(uint32 ArenaTeamId)
newmember.personal_rating = fields[5].GetUInt32();
newmember.name = fields[6].GetCppString();
newmember.Class = fields[7].GetUInt8();
members.push_back(newmember);
m_members.push_back(newmember);
}while( result->NextRow() );
delete result;
}
@@ -266,10 +266,10 @@ void ArenaTeam::SetCaptain(const uint64& guid)
oldcaptain->SetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + 1 + (GetSlot() * 6), 1);
// set new captain
CaptainGuid = guid;
m_CaptainGuid = guid;
// update database
CharacterDatabase.PExecute("UPDATE arena_team SET captainguid = '%u' WHERE arenateamid = '%u'", GUID_LOPART(guid), Id);
CharacterDatabase.PExecute("UPDATE arena_team SET captainguid = '%u' WHERE arenateamid = '%u'", GUID_LOPART(guid), m_TeamId);
// enable remove/promote buttons
Player *newcaptain = objmgr.GetPlayer(guid);
@@ -282,11 +282,11 @@ void ArenaTeam::SetCaptain(const uint64& guid)
void ArenaTeam::DelMember(uint64 guid)
{
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
if (itr->guid == guid)
{
members.erase(itr);
m_members.erase(itr);
break;
}
}
@@ -314,21 +314,21 @@ void ArenaTeam::Disband(WorldSession *session)
session->BuildArenaTeamEventPacket(&data, ERR_ARENA_TEAM_DISBANDED_S, 2, session->GetPlayerName(), GetName(), "");
BroadcastPacket(&data);
while (!members.empty())
while (!m_members.empty())
{
// Removing from members is done in DelMember.
DelMember(members.front().guid);
DelMember(m_members.front().guid);
}
if(Player *player = session->GetPlayer())
sLog.outArena("Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u].", player->GetName(), player->GetGUIDLow(), GetType(), GetId());
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", Id);
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", Id); //< this should be alredy done by calling DelMember(memberGuids[j]); for each member
CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", Id);
CharacterDatabase.PExecute("DELETE FROM arena_team WHERE arenateamid = '%u'", m_TeamId);
CharacterDatabase.PExecute("DELETE FROM arena_team_member WHERE arenateamid = '%u'", m_TeamId); //< this should be alredy done by calling DelMember(memberGuids[j]); for each member
CharacterDatabase.PExecute("DELETE FROM arena_team_stats WHERE arenateamid = '%u'", m_TeamId);
CharacterDatabase.CommitTransaction();
objmgr.RemoveArenaTeam(Id);
objmgr.RemoveArenaTeam(m_TeamId);
}
void ArenaTeam::Roster(WorldSession *session)
@@ -338,12 +338,12 @@ void ArenaTeam::Roster(WorldSession *session)
uint8 unk308 = 0;
WorldPacket data(SMSG_ARENA_TEAM_ROSTER, 100);
data << uint32(GetId()); // arena team id
data << uint32(GetId()); // team id
data << uint8(unk308); // 308 unknown value but affect packet structure
data << uint32(GetMembersSize()); // members count
data << uint32(GetType()); // arena team type?
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
pl = objmgr.GetPlayer(itr->guid);
@@ -375,11 +375,11 @@ void ArenaTeam::Query(WorldSession *session)
data << uint32(GetId()); // team id
data << GetName(); // team name
data << uint32(GetType()); // arena team type (2=2x2, 3=3x3 or 5=5x5)
data << uint32(BackgroundColor); // background color
data << uint32(EmblemStyle); // emblem style
data << uint32(EmblemColor); // emblem color
data << uint32(BorderStyle); // border style
data << uint32(BorderColor); // border color
data << uint32(m_BackgroundColor); // background color
data << uint32(m_EmblemStyle); // emblem style
data << uint32(m_EmblemColor); // emblem color
data << uint32(m_BorderStyle); // border style
data << uint32(m_BorderColor); // border color
session->SendPacket(&data);
sLog.outDebug("WORLD: Sent SMSG_ARENA_TEAM_QUERY_RESPONSE");
}
@@ -387,13 +387,13 @@ void ArenaTeam::Query(WorldSession *session)
void ArenaTeam::Stats(WorldSession *session)
{
WorldPacket data(SMSG_ARENA_TEAM_STATS, 4*7);
data << uint32(GetId()); // arena team id
data << uint32(stats.rating); // rating
data << uint32(stats.games_week); // games this week
data << uint32(stats.wins_week); // wins this week
data << uint32(stats.games_season); // played this season
data << uint32(stats.wins_season); // wins this season
data << uint32(stats.rank); // rank
data << uint32(GetId()); // team id
data << uint32(m_stats.rating); // rating
data << uint32(m_stats.games_week); // games this week
data << uint32(m_stats.wins_week); // wins this week
data << uint32(m_stats.games_season); // played this season
data << uint32(m_stats.wins_season); // wins this season
data << uint32(m_stats.rank); // rank
session->SendPacket(&data);
}
@@ -401,7 +401,7 @@ void ArenaTeam::NotifyStatsChanged()
{
// this is called after a rated match ended
// updates arena team stats for every member of the team (not only the ones who participated!)
for(MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
for(MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
Player * plr = objmgr.GetPlayer(itr->guid);
if(plr)
@@ -419,9 +419,9 @@ void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
data << uint64(guid); // player guid
data << uint8(GetSlot()); // slot (0...2)
data << uint32(GetId()); // arena team id
data << uint32(stats.rating); // rating
data << uint32(stats.games_season); // season played
data << uint32(stats.wins_season); // season wins
data << uint32(m_stats.rating); // rating
data << uint32(m_stats.games_season); // season played
data << uint32(m_stats.wins_season); // season wins
data << uint32(member->games_season); // played (count of all games, that the inspected member participated...)
data << uint32(member->personal_rating); // personal rating
session->SendPacket(&data);
@@ -429,13 +429,13 @@ void ArenaTeam::InspectStats(WorldSession *session, uint64 guid)
void ArenaTeam::SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor)
{
BackgroundColor = backgroundColor;
EmblemStyle = emblemStyle;
EmblemColor = emblemColor;
BorderStyle = borderStyle;
BorderColor = borderColor;
m_BackgroundColor = backgroundColor;
m_EmblemStyle = emblemStyle;
m_EmblemColor = emblemColor;
m_BorderStyle = borderStyle;
m_BorderColor = borderColor;
CharacterDatabase.PExecute("UPDATE arena_team SET BackgroundColor='%u', EmblemStyle='%u', EmblemColor='%u', BorderStyle='%u', BorderColor='%u' WHERE arenateamid='%u'", BackgroundColor, EmblemStyle, EmblemColor, BorderStyle, BorderColor, Id);
CharacterDatabase.PExecute("UPDATE arena_team SET BackgroundColor='%u', EmblemStyle='%u', EmblemColor='%u', BorderStyle='%u', BorderColor='%u' WHERE arenateamid='%u'", m_BackgroundColor, m_EmblemStyle, m_EmblemColor, m_BorderStyle, m_BorderColor, m_TeamId);
}
void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
@@ -443,27 +443,27 @@ void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
switch(stat_type)
{
case STAT_TYPE_RATING:
stats.rating = value;
m_stats.rating = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u' WHERE arenateamid = '%u'", value, GetId());
break;
case STAT_TYPE_GAMES_WEEK:
stats.games_week = value;
m_stats.games_week = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET games = '%u' WHERE arenateamid = '%u'", value, GetId());
break;
case STAT_TYPE_WINS_WEEK:
stats.wins_week = value;
m_stats.wins_week = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins = '%u' WHERE arenateamid = '%u'", value, GetId());
break;
case STAT_TYPE_GAMES_SEASON:
stats.games_season = value;
m_stats.games_season = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET played = '%u' WHERE arenateamid = '%u'", value, GetId());
break;
case STAT_TYPE_WINS_SEASON:
stats.wins_season = value;
m_stats.wins_season = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET wins2 = '%u' WHERE arenateamid = '%u'", value, GetId());
break;
case STAT_TYPE_RANK:
stats.rank = value;
m_stats.rank = value;
CharacterDatabase.PExecute("UPDATE arena_team_stats SET rank = '%u' WHERE arenateamid = '%u'", value, GetId());
break;
default:
@@ -474,7 +474,7 @@ void ArenaTeam::SetStats(uint32 stat_type, uint32 value)
void ArenaTeam::BroadcastPacket(WorldPacket *packet)
{
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
Player *player = objmgr.GetPlayer(itr->guid);
if(player)
@@ -498,7 +498,7 @@ uint8 ArenaTeam::GetSlotByType( uint32 type )
bool ArenaTeam::HaveMember( const uint64& guid ) const
{
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if(itr->guid == guid)
return true;
@@ -510,7 +510,7 @@ uint32 ArenaTeam::GetPoints(uint32 MemberRating)
// returns how many points would be awarded with this team type with this rating
float points;
uint32 rating = MemberRating + 150 < stats.rating ? MemberRating : stats.rating;
uint32 rating = MemberRating + 150 < m_stats.rating ? MemberRating : m_stats.rating;
if(rating<=1500)
// points = (float)1500 * 0.22f + 14.0f;
@@ -519,9 +519,9 @@ uint32 ArenaTeam::GetPoints(uint32 MemberRating)
points = 1511.26f / (1.0f + 1639.28f * exp(-0.00412f * (float)rating));
// type penalties for <5v5 teams
if(Type == ARENA_TEAM_2v2)
if(m_Type == ARENA_TEAM_2v2)
points *= 0.76f;
else if(Type == ARENA_TEAM_3v3)
else if(m_Type == ARENA_TEAM_3v3)
points *= 0.88f;
return (uint32) points;
@@ -535,26 +535,25 @@ float ArenaTeam::GetChanceAgainst(uint32 own_rating, uint32 enemy_rating)
if (sWorld.getConfig(CONFIG_ARENA_SEASON_ID) >= 6)
if (enemy_rating < 1300)
enemy_rating = 1300;
return 1.0f/(1.0f+exp(log(10.0f)*(float)((float)enemy_rating - (float)own_rating)/400.0f));
}
void ArenaTeam::FinishGame(int32 mod)
{
if (int32(stats.rating) + mod < 0)
stats.rating = 0;
if (int32(m_stats.rating) + mod < 0)
m_stats.rating = 0;
else
stats.rating += mod;
m_stats.rating += mod;
stats.games_week += 1;
stats.games_season += 1;
m_stats.games_week += 1;
m_stats.games_season += 1;
// update team's rank
stats.rank = 1;
m_stats.rank = 1;
ObjectMgr::ArenaTeamMap::const_iterator i = objmgr.GetArenaTeamMapBegin();
for ( ; i != objmgr.GetArenaTeamMapEnd(); ++i)
{
if (i->second->GetType() == this->Type && i->second->GetStats().rating > stats.rating)
++stats.rank;
if (i->second->GetType() == m_Type && i->second->GetStats().rating > m_stats.rating)
++m_stats.rank;
}
}
@@ -562,13 +561,13 @@ int32 ArenaTeam::WonAgainst(uint32 againstRating)
{
// called when the team has won
//'chance' calculation - to beat the opponent
float chance = GetChanceAgainst(stats.rating, againstRating);
float chance = GetChanceAgainst(m_stats.rating, againstRating);
// calculate the rating modification (ELO system with k=32)
int32 mod = (int32)floor(32.0f * (1.0f - chance));
// modify the team stats accordingly
FinishGame(mod);
stats.wins_week += 1;
stats.wins_season += 1;
m_stats.wins_week += 1;
m_stats.wins_season += 1;
// return the rating change, used to display it on the results screen
return mod;
@@ -578,7 +577,7 @@ int32 ArenaTeam::LostAgainst(uint32 againstRating)
{
// called when the team has lost
//'chance' calculation - to loose to the opponent
float chance = GetChanceAgainst(stats.rating, againstRating);
float chance = GetChanceAgainst(m_stats.rating, againstRating);
// calculate the rating modification (ELO system with k=32)
int32 mod = (int32)ceil(32.0f * (0.0f - chance));
// modify the team stats accordingly
@@ -591,7 +590,7 @@ int32 ArenaTeam::LostAgainst(uint32 againstRating)
void ArenaTeam::MemberLost(Player * plr, uint32 againstRating)
{
// called for each participant of a match after losing
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
for(MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
if(itr->guid == plr->GetGUID())
{
@@ -613,7 +612,7 @@ void ArenaTeam::MemberLost(Player * plr, uint32 againstRating)
void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating)
{
// called for offline player after ending rated arena match!
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
for(MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
if(itr->guid == guid)
{
@@ -635,7 +634,7 @@ void ArenaTeam::OfflineMemberLost(uint64 guid, uint32 againstRating)
void ArenaTeam::MemberWon(Player * plr, uint32 againstRating)
{
// called for each participant after winning a match
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
for(MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
if(itr->guid == plr->GetGUID())
{
@@ -661,17 +660,17 @@ void ArenaTeam::UpdateArenaPointsHelper(std::map<uint32, uint32>& PlayerPoints)
// called after a match has ended and the stats are already modified
// helper function for arena point distribution (this way, when distributing, no actual calculation is required, just a few comparisons)
// 10 played games per week is a minimum
if (stats.games_week < 10)
if (m_stats.games_week < 10)
return;
// to get points, a player has to participate in at least 30% of the matches
uint32 min_plays = (uint32) ceil(stats.games_week * 0.3);
for(MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
uint32 min_plays = (uint32) ceil(m_stats.games_week * 0.3);
for(MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
// the player participated in enough games, update his points
uint32 points_to_add = 0;
if (itr->games_week >= min_plays)
points_to_add = GetPoints(itr->personal_rating);
// OBSOLETE : CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, Id, itr->guid);
// OBSOLETE : CharacterDatabase.PExecute("UPDATE arena_team_member SET points_to_add = '%u' WHERE arenateamid = '%u' AND guid = '%u'", points_to_add, m_TeamId, itr->guid);
std::map<uint32, uint32>::iterator plr_itr = PlayerPoints.find(GUID_LOPART(itr->guid));
if (plr_itr != PlayerPoints.end())
@@ -690,19 +689,19 @@ void ArenaTeam::SaveToDB()
// save team and member stats to db
// called after a match has ended, or when calculating arena_points
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", stats.rating, stats.games_week, stats.games_season, stats.rank, stats.wins_week, stats.wins_season, GetId());
for(MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
CharacterDatabase.PExecute("UPDATE arena_team_stats SET rating = '%u',games = '%u',played = '%u',rank = '%u',wins = '%u',wins2 = '%u' WHERE arenateamid = '%u'", m_stats.rating, m_stats.games_week, m_stats.games_season, m_stats.rank, m_stats.wins_week, m_stats.wins_season, GetId());
for(MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
CharacterDatabase.PExecute("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u', personal_rating = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, itr->personal_rating, Id, GUID_LOPART(itr->guid));
CharacterDatabase.PExecute("UPDATE arena_team_member SET played_week = '%u', wons_week = '%u', played_season = '%u', wons_season = '%u', personal_rating = '%u' WHERE arenateamid = '%u' AND guid = '%u'", itr->games_week, itr->wins_week, itr->games_season, itr->wins_season, itr->personal_rating, m_TeamId, GUID_LOPART(itr->guid));
}
CharacterDatabase.CommitTransaction();
}
void ArenaTeam::FinishWeek()
{
stats.games_week = 0; // played this week
stats.wins_week = 0; // wins this week
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
m_stats.games_week = 0; // played this week
m_stats.wins_week = 0; // wins this week
for(MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
itr->games_week = 0;
itr->wins_week = 0;
@@ -711,7 +710,7 @@ void ArenaTeam::FinishWeek()
bool ArenaTeam::IsFighting() const
{
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
for (MemberList::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
if (Player *p = objmgr.GetPlayer(itr->guid))
{
+29 -29
View File
@@ -117,26 +117,26 @@ class ArenaTeam
ArenaTeam();
~ArenaTeam();
bool Create(uint64 CaptainGuid, uint32 type, std::string ArenaTeamName);
bool Create(uint64 captainGuid, uint32 type, std::string ArenaTeamName);
void Disband(WorldSession *session);
typedef std::list<ArenaTeamMember> MemberList;
uint32 GetId() const { return Id; }
uint32 GetType() const { return Type; }
uint32 GetId() const { return m_TeamId; }
uint32 GetType() const { return m_Type; }
uint8 GetSlot() const { return GetSlotByType(GetType()); }
static uint8 GetSlotByType(uint32 type);
const uint64& GetCaptain() const { return CaptainGuid; }
std::string GetName() const { return Name; }
const ArenaTeamStats& GetStats() const { return stats; }
const uint64& GetCaptain() const { return m_CaptainGuid; }
std::string GetName() const { return m_Name; }
const ArenaTeamStats& GetStats() const { return m_stats; }
void SetStats(uint32 stat_type, uint32 value);
uint32 GetRating() const { return stats.rating; }
uint32 GetRating() const { return m_stats.rating; }
uint32 GetEmblemStyle() const { return EmblemStyle; }
uint32 GetEmblemColor() const { return EmblemColor; }
uint32 GetBorderStyle() const { return BorderStyle; }
uint32 GetBorderColor() const { return BorderColor; }
uint32 GetBackgroundColor() const { return BackgroundColor; }
uint32 GetEmblemStyle() const { return m_EmblemStyle; }
uint32 GetEmblemColor() const { return m_EmblemColor; }
uint32 GetBorderStyle() const { return m_BorderStyle; }
uint32 GetBorderColor() const { return m_BorderColor; }
uint32 GetBackgroundColor() const { return m_BackgroundColor; }
void SetCaptain(const uint64& guid);
bool AddMember(const uint64& PlayerGuid);
@@ -147,15 +147,15 @@ class ArenaTeam
void SetEmblem(uint32 backgroundColor, uint32 emblemStyle, uint32 emblemColor, uint32 borderStyle, uint32 borderColor);
size_t GetMembersSize() const { return members.size(); }
bool Empty() const { return members.empty(); }
MemberList::iterator membersBegin() { return members.begin(); }
MemberList::iterator membersEnd() { return members.end(); }
size_t GetMembersSize() const { return m_members.size(); }
bool Empty() const { return m_members.empty(); }
MemberList::iterator m_membersBegin() { return m_members.begin(); }
MemberList::iterator m_membersEnd() { return m_members.end(); }
bool HaveMember(const uint64& guid) const;
ArenaTeamMember* GetMember(const uint64& guid)
{
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if(itr->guid == guid)
return &(*itr);
@@ -164,7 +164,7 @@ class ArenaTeam
ArenaTeamMember* GetMember(const std::string& name)
{
for (MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
for (MemberList::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
if(itr->name == name)
return &(*itr);
@@ -203,19 +203,19 @@ class ArenaTeam
protected:
uint32 Id;
uint32 Type;
std::string Name;
uint64 CaptainGuid;
uint32 m_TeamId;
uint32 m_Type;
std::string m_Name;
uint64 m_CaptainGuid;
uint32 BackgroundColor; // ARGB format
uint32 EmblemStyle; // icon id
uint32 EmblemColor; // ARGB format
uint32 BorderStyle; // border image id
uint32 BorderColor; // ARGB format
uint32 m_BackgroundColor; // ARGB format
uint32 m_EmblemStyle; // icon id
uint32 m_EmblemColor; // ARGB format
uint32 m_BorderStyle; // border image id
uint32 m_BorderColor; // ARGB format
MemberList members;
ArenaTeamStats stats;
MemberList m_members;
ArenaTeamStats m_stats;
};
#endif
+10 -1
View File
@@ -182,6 +182,9 @@ BattleGround::BattleGround()
m_PlayersCount[BG_TEAM_ALLIANCE] = 0;
m_PlayersCount[BG_TEAM_HORDE] = 0;
m_TeamScores[BG_TEAM_ALLIANCE] = 0;
m_TeamScores[BG_TEAM_HORDE] = 0;
m_PrematureCountDown = false;
m_PrematureCountDown = 0;
@@ -473,7 +476,7 @@ void BattleGround::Update(uint32 diff)
void BattleGround::SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O)
{
uint8 idx = GetTeamIndexByTeamId(TeamID);
BattleGroundTeamId idx = GetTeamIndexByTeamId(TeamID);
m_TeamStartLocX[idx] = X;
m_TeamStartLocY[idx] = Y;
m_TeamStartLocZ[idx] = Z;
@@ -1875,3 +1878,9 @@ WorldSafeLocsEntry const* BattleGround::GetClosestGraveYard( Player* player )
{
return objmgr.GetClosestGraveYard( player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam() );
}
bool BattleGround::IsTeamScoreInRange(uint32 team, uint32 minScore, uint32 maxScore) const
{
BattleGroundTeamId team_idx = GetTeamIndexByTeamId(team);
return m_TeamScores[team_idx] >= minScore && m_TeamScores[team_idx] <= maxScore;
}
+9 -2
View File
@@ -298,6 +298,10 @@ class BattleGround
virtual void StartingEventCloseDoors() {}
virtual void StartingEventOpenDoors() {}
/* achievement req. */
virtual bool IsAllNodesConrolledByTeam(uint32 /*team*/) const { return false; }
bool IsTeamScoreInRange(uint32 team, uint32 minScore, uint32 maxScore) const;
/* Battleground */
// Get methods:
char const* GetName() const { return m_Name; }
@@ -397,7 +401,7 @@ class BattleGround
void SetTeamStartLoc(uint32 TeamID, float X, float Y, float Z, float O);
void GetTeamStartLoc(uint32 TeamID, float &X, float &Y, float &Z, float &O) const
{
uint8 idx = GetTeamIndexByTeamId(TeamID);
BattleGroundTeamId idx = GetTeamIndexByTeamId(TeamID);
X = m_TeamStartLocX[idx];
Y = m_TeamStartLocY[idx];
Z = m_TeamStartLocZ[idx];
@@ -441,7 +445,7 @@ class BattleGround
virtual void UpdatePlayerScore(Player *Source, uint32 type, uint32 value);
uint8 GetTeamIndexByTeamId(uint32 Team) const { return Team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; }
static BattleGroundTeamId GetTeamIndexByTeamId(uint32 Team) { return Team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE; }
uint32 GetPlayersCountByTeam(uint32 Team) const { return m_PlayersCount[GetTeamIndexByTeamId(Team)]; }
uint32 GetAlivePlayersCountByTeam(uint32 Team) const; // used in arenas to correctly handle death in spirit of redemption / last stand etc. (killer = killed) cases
void UpdatePlayersCountByTeam(uint32 Team, bool remove)
@@ -514,6 +518,9 @@ class BattleGround
void SetDeleteThis() {m_SetDeleteThis = true;}
/* virtual score-array - get's used in bg-subclasses */
int32 m_TeamScores[BG_TEAMS_COUNT];
protected:
//this method is called, when BG cannot spawn its own spirit guide, or something is wrong, It correctly ends BattleGround
void EndNow();
+33 -9
View File
@@ -161,6 +161,18 @@ void BattleGroundAB::Update(uint32 diff)
}
}
// achievements flags
if (m_TeamScores[BG_TEAM_ALLIANCE] > m_TeamScores[BG_TEAM_HORDE])
{
if (m_TeamScores[BG_TEAM_ALLIANCE] - m_TeamScores[BG_TEAM_HORDE] >= 500)
m_TeamScores500disadvantage[BG_TEAM_HORDE] = true;
}
else
{
if (m_TeamScores[BG_TEAM_HORDE] - m_TeamScores[BG_TEAM_ALLIANCE] >= 500)
m_TeamScores500disadvantage[BG_TEAM_ALLIANCE] = true;
}
// Test win condition
if (m_TeamScores[BG_TEAM_ALLIANCE] >= BG_AB_MAX_TEAM_SCORE)
EndBattleGround(ALLIANCE);
@@ -428,7 +440,7 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
return;
}
uint8 teamIndex = GetTeamIndexByTeamId(source->GetTeam());
BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(source->GetTeam());
// Check if player really could use this banner, not cheated
if (!(m_Nodes[node] == 0 || teamIndex == m_Nodes[node]%2))
@@ -474,7 +486,7 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
// FIXME: node names not localized
if (teamIndex == 0)
if (teamIndex == BG_TEAM_ALLIANCE)
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
else
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
@@ -491,15 +503,15 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
_CreateBanner(node, BG_AB_NODE_TYPE_OCCUPIED, teamIndex, true);
_SendNodeUpdate(node);
m_NodeTimers[node] = 0;
_NodeOccupied(node,(teamIndex == 0) ? ALLIANCE:HORDE);
_NodeOccupied(node,(teamIndex == BG_TEAM_ALLIANCE) ? ALLIANCE:HORDE);
// FIXME: node names not localized
if (teamIndex == 0)
if (teamIndex == BG_TEAM_ALLIANCE)
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
else
SendMessage2ToAll(LANG_BG_AB_NODE_DEFENDED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
}
sound = (teamIndex == 0) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
}
// If node is occupied, change to enemy-contested
else
@@ -516,19 +528,19 @@ void BattleGroundAB::EventPlayerClickedOnFlag(Player *source, GameObject* /*targ
m_NodeTimers[node] = BG_AB_FLAG_CAPTURING_TIME;
// FIXME: node names not localized
if (teamIndex == 0)
if (teamIndex == BG_TEAM_ALLIANCE)
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_ALLIANCE, source, _GetNodeNameId(node));
else
SendMessage2ToAll(LANG_BG_AB_NODE_ASSAULTED,CHAT_MSG_BG_SYSTEM_HORDE, source, _GetNodeNameId(node));
sound = (teamIndex == 0) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
sound = (teamIndex == BG_TEAM_ALLIANCE) ? BG_AB_SOUND_NODE_ASSAULTED_ALLIANCE : BG_AB_SOUND_NODE_ASSAULTED_HORDE;
}
// If node is occupied again, send "X has taken the Y" msg.
if (m_Nodes[node] >= BG_AB_NODE_TYPE_OCCUPIED)
{
// FIXME: team and node names not localized
if (teamIndex == 0)
if (teamIndex == BG_TEAM_ALLIANCE)
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, LANG_BG_AB_ALLY, _GetNodeNameId(node));
else
SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN,CHAT_MSG_BG_SYSTEM_HORDE, NULL, LANG_BG_AB_HORDE, _GetNodeNameId(node));
@@ -591,6 +603,8 @@ void BattleGroundAB::Reset()
bool isBGWeekend = false; //TODO FIXME - call sBattleGroundMgr.IsBGWeekend(m_TypeID); - you must also implement that call!
m_HonorTics = (isBGWeekend) ? BG_AB_ABBGWeekendHonorTicks : BG_AB_NotABBGWeekendHonorTicks;
m_ReputationTics = (isBGWeekend) ? BG_AB_ABBGWeekendReputationTicks : BG_AB_NotABBGWeekendReputationTicks;
m_TeamScores500disadvantage[BG_TEAM_ALLIANCE] = false;
m_TeamScores500disadvantage[BG_TEAM_HORDE] = false;
for (uint8 i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
{
@@ -621,7 +635,7 @@ void BattleGroundAB::EndBattleGround(uint32 winner)
WorldSafeLocsEntry const* BattleGroundAB::GetClosestGraveYard(Player* player)
{
uint8 teamIndex = GetTeamIndexByTeamId(player->GetTeam());
BattleGroundTeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam());
// Is there any occupied node for this team?
std::vector<uint8> nodes;
@@ -679,3 +693,13 @@ void BattleGroundAB::UpdatePlayerScore(Player *Source, uint32 type, uint32 value
}
}
bool BattleGroundAB::IsAllNodesConrolledByTeam(uint32 team) const
{
uint32 count = 0;
for(int i = 0; i < BG_AB_DYNAMIC_NODES_COUNT; ++i)
if (team == ALLIANCE && m_Nodes[i] == BG_AB_NODE_STATUS_ALLY_OCCUPIED ||
team == HORDE && m_Nodes[i] == BG_AB_NODE_STATUS_HORDE_OCCUPIED)
++count;
return count == BG_AB_DYNAMIC_NODES_COUNT;
}
+5 -3
View File
@@ -262,6 +262,9 @@ class BattleGroundAB : public BattleGround
/* Nodes occupying */
virtual void EventPlayerClickedOnFlag(Player *source, GameObject* target_obj);
/* achievement req. */
bool IsAllNodesConrolledByTeam(uint32 team) const; // overwrited
bool IsTeamScores500disadvantage(uint32 team) const { return m_TeamScores500disadvantage[GetTeamIndexByTeamId(team)]; }
private:
/* Gameobject spawning/despawning */
void _CreateBanner(uint8 node, uint8 type, uint8 teamIndex, bool delay);
@@ -285,15 +288,14 @@ class BattleGroundAB : public BattleGround
uint8 m_prevNodes[BG_AB_DYNAMIC_NODES_COUNT];
BG_AB_BannerTimer m_BannerTimers[BG_AB_DYNAMIC_NODES_COUNT];
uint32 m_NodeTimers[BG_AB_DYNAMIC_NODES_COUNT];
uint32 m_TeamScores[BG_TEAMS_COUNT];
uint32 m_lastTick[BG_TEAMS_COUNT];
uint32 m_HonorScoreTics[BG_TEAMS_COUNT];
uint32 m_ReputationScoreTics[BG_TEAMS_COUNT];
bool m_IsInformedNearVictory;
uint32 m_HonorTics;
uint32 m_ReputationTics;
// need for achievements
bool m_TeamScores500disadvantage[BG_TEAMS_COUNT];
};
#endif
+10 -1
View File
@@ -128,7 +128,7 @@ void BattleGroundEY::StartingEventOpenDoors()
void BattleGroundEY::AddPoints(uint32 Team, uint32 Points)
{
uint8 team_index = GetTeamIndexByTeamId(Team);
BattleGroundTeamId team_index = GetTeamIndexByTeamId(Team);
m_TeamScores[team_index] += Points;
m_HonorScoreTics[team_index] += Points;
if (m_HonorScoreTics[team_index] >= m_HonorTics )
@@ -908,3 +908,12 @@ WorldSafeLocsEntry const *BattleGroundEY::GetClosestGraveYard(Player* player)
return nearestEntry;
}
bool BattleGroundEY::IsAllNodesConrolledByTeam(uint32 team) const
{
uint32 count = 0;
for(int i = 0; i < EY_POINTS_MAX; ++i)
if (m_PointOwnedByTeam[i] == team && m_PointState[i] == EY_POINT_UNDER_CONTROL)
++count;
return count == EY_POINTS_MAX;
}
+2 -1
View File
@@ -350,6 +350,8 @@ class BattleGroundEY : public BattleGround
virtual void EventPlayerClickedOnFlag(Player *Source, GameObject* target_obj);
virtual void EventPlayerDroppedFlag(Player *Source);
/* achievement req. */
bool IsAllNodesConrolledByTeam(uint32 team) const;
private:
void EventPlayerCapturedFlag(Player *Source, uint32 BgObjectType);
void EventTeamCapturedPoint(Player *Source, uint32 Point);
@@ -369,7 +371,6 @@ class BattleGroundEY : public BattleGround
void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; }
void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; }
uint32 m_TeamScores[2];
uint32 m_HonorScoreTics[2];
uint32 m_TeamPointsCount[2];
-2
View File
@@ -200,12 +200,10 @@ class BattleGroundWS : public BattleGround
void AddPoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] += Points; }
void SetTeamPoint(uint32 TeamID, uint32 Points = 0) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] = Points; }
void RemovePoint(uint32 TeamID, uint32 Points = 1) { m_TeamScores[GetTeamIndexByTeamId(TeamID)] -= Points; }
private:
uint64 m_FlagKeepers[2]; // 0 - alliance, 1 - horde
uint64 m_DroppedFlagGUID[2];
uint8 m_FlagState[2]; // for checking flag state
uint32 m_TeamScores[2];
int32 m_FlagsTimer[2];
int32 m_FlagsDropTimer[2];
-3
View File
@@ -24,9 +24,6 @@
#include "ObjectMgr.h" // for normalizePlayerName
#include "ChannelMgr.h"
INSTANTIATE_SINGLETON_1( AllianceChannelMgr );
INSTANTIATE_SINGLETON_1( HordeChannelMgr );
void WorldSession::HandleJoinChannel(WorldPacket& recvPacket)
{
sLog.outDebug("Opcode %u", recvPacket.GetOpcode());
+97
View File
@@ -0,0 +1,97 @@
/*
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* 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 "ChannelMgr.h"
#include "Policies/SingletonImp.h"
#include "World.h"
INSTANTIATE_SINGLETON_1( AllianceChannelMgr );
INSTANTIATE_SINGLETON_1( HordeChannelMgr );
ChannelMgr* channelMgr(uint32 team)
{
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
return &MaNGOS::Singleton<AllianceChannelMgr>::Instance(); // cross-faction
if(team == ALLIANCE)
return &MaNGOS::Singleton<AllianceChannelMgr>::Instance();
if(team == HORDE)
return &MaNGOS::Singleton<HordeChannelMgr>::Instance();
return NULL;
}
ChannelMgr::~ChannelMgr()
{
for(ChannelMap::iterator itr = channels.begin();itr!=channels.end(); ++itr)
delete itr->second;
channels.clear();
}
Channel *ChannelMgr::GetJoinChannel(std::string name, uint32 channel_id)
{
if (channels.find(name) == channels.end())
{
Channel *nchan = new Channel(name,channel_id, team);
channels[name] = nchan;
}
return channels[name];
}
Channel *ChannelMgr::GetChannel(std::string name, Player *p, bool pkt)
{
ChannelMap::const_iterator i = channels.find(name);
if(i == channels.end())
{
if(pkt)
{
WorldPacket data;
MakeNotOnPacket(&data,name);
p->GetSession()->SendPacket(&data);
}
return NULL;
}
else
return i->second;
}
void ChannelMgr::LeftChannel(std::string name)
{
ChannelMap::const_iterator i = channels.find(name);
if(i == channels.end())
return;
Channel* channel = i->second;
if(channel->GetNumPlayers() == 0 && !channel->IsConstant())
{
channels.erase(name);
delete channel;
}
}
void ChannelMgr::MakeNotOnPacket(WorldPacket *data, std::string name)
{
data->Initialize(SMSG_CHANNEL_NOTIFY, (1+10)); // we guess size
(*data) << (uint8)0x05 << name;
}
+12 -61
View File
@@ -17,8 +17,12 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef TRINITYCORE_CHANNELMGR_H
#define TRINITYCORE_CHANNELMGR_H
#ifndef MANGOSSERVER_CHANNELMGR_H
#define MANGOSSERVER_CHANNELMGR_H
#include "Common.h"
#include "Channel.h"
#include "Policies/Singleton.h"
#include <map>
#include <string>
@@ -34,73 +38,20 @@ class ChannelMgr
uint32 team;
typedef std::map<std::string,Channel *> ChannelMap;
ChannelMgr() {team = 0;}
~ChannelMgr()
{
for(ChannelMap::const_iterator itr = channels.begin();itr!=channels.end(); ++itr)
delete itr->second;
channels.clear();
}
Channel *GetJoinChannel(const std::string& name, uint32 channel_id)
{
if (channels.find(name) == channels.end())
{
Channel *nchan = new Channel(name,channel_id, team);
channels[name] = nchan;
}
return channels[name];
}
Channel *GetChannel(const std::string& name, Player *p)
{
ChannelMap::const_iterator i = channels.find(name);
~ChannelMgr();
if(i == channels.end())
{
WorldPacket data;
MakeNotOnPacket(&data,name);
p->GetSession()->SendPacket(&data);
return NULL;
}
else
return i->second;
}
void LeftChannel(const std::string& name)
{
ChannelMap::const_iterator i = channels.find(name);
if(i == channels.end())
return;
Channel* channel = i->second;
if(channel->GetNumPlayers() == 0 && !channel->IsConstant())
{
channels.erase(name);
delete channel;
}
}
Channel *GetJoinChannel(std::string name, uint32 channel_id);
Channel *GetChannel(std::string name, Player *p, bool pkt = true);
void LeftChannel(std::string name);
private:
ChannelMap channels;
void MakeNotOnPacket(WorldPacket *data, const std::string& name)
{
data->Initialize(SMSG_CHANNEL_NOTIFY, (1+10)); // we guess size
(*data) << (uint8)0x05 << name;
}
void MakeNotOnPacket(WorldPacket *data, std::string name);
};
class AllianceChannelMgr : public ChannelMgr {};
class HordeChannelMgr : public ChannelMgr {};
inline ChannelMgr* channelMgr(uint32 team)
{
if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL))
//For Test,No Seprate Faction
return &Trinity::Singleton<AllianceChannelMgr>::Instance();
ChannelMgr* channelMgr(uint32 team);
if(team==ALLIANCE)
return &Trinity::Singleton<AllianceChannelMgr>::Instance();
if(team==HORDE)
return &Trinity::Singleton<HordeChannelMgr>::Instance();
return NULL;
}
#endif
+5 -5
View File
@@ -123,7 +123,7 @@ class CharacterHandler
void WorldSession::HandleCharEnum(QueryResult * result)
{
// keys can be non cleared if player open realm list and close it by 'cancel'
LoginDatabase.PExecute("UPDATE account SET v = '0', s = '0' WHERE id = '%u'", GetAccountId());
loginDatabase.PExecute("UPDATE account SET v = '0', s = '0' WHERE id = '%u'", GetAccountId());
WorldPacket data(SMSG_CHAR_ENUM, 100); // we guess size
@@ -280,7 +280,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
return;
}
QueryResult *resultacct = LoginDatabase.PQuery("SELECT SUM(numchars) FROM realmcharacters WHERE acctid = '%d'", GetAccountId());
QueryResult *resultacct = loginDatabase.PQuery("SELECT SUM(numchars) FROM realmcharacters WHERE acctid = '%d'", GetAccountId());
if (resultacct)
{
Field *fields=resultacct->Fetch();
@@ -461,8 +461,8 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
pNewChar->SaveToDB();
charcount+=1;
LoginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", GetAccountId(), realmID);
LoginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)", charcount, GetAccountId(), realmID);
loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", GetAccountId(), realmID);
loginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)", charcount, GetAccountId(), realmID);
delete pNewChar; // created only to call SaveToDB()
@@ -736,7 +736,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)
pCurrChar->SendInitialPacketsAfterAddToMap();
CharacterDatabase.PExecute("UPDATE characters SET online = 1 WHERE guid = '%u'", pCurrChar->GetGUIDLow());
LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = '%u'", GetAccountId());
loginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = '%u'", GetAccountId());
pCurrChar->SetInGameTime( getMSTime() );
// announce group about member online (must be after add to player list to receive announce to self)
+1 -1
View File
@@ -1810,4 +1810,4 @@ LocaleConstant CliHandler::GetSessionDbcLocale() const
int CliHandler::GetSessionDbLocaleIndex() const
{
return objmgr.GetDBCLocaleIndex();
}
}
+5 -5
View File
@@ -39,7 +39,7 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Texts()
objmgr.LoadTrinityStrings(WorldDatabase,"creature_ai_texts",MIN_CREATURE_AI_TEXT_STRING_ID,MAX_CREATURE_AI_TEXT_STRING_ID);
// Gather Additional data from EventAI Texts
QueryResult *result = WorldDatabase.PQuery("SELECT entry, sound, type, language, emote FROM creature_ai_texts");
QueryResult *result = WorldDatabase.Query("SELECT entry, sound, type, language, emote FROM creature_ai_texts");
sLog.outString("Loading EventAI Texts additional data...");
if (result)
@@ -117,8 +117,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Summons()
//Drop Existing EventSummon Map
m_CreatureEventAI_Summon_Map.clear();
//Gather additional data for EventAI
QueryResult *result = WorldDatabase.PQuery("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM creature_ai_summons");
// Gather additional data for EventAI
QueryResult *result = WorldDatabase.Query("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM creature_ai_summons");
if (result)
{
barGoLink bar(result->GetRowCount());
@@ -169,8 +169,8 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
//Drop Existing EventAI List
m_CreatureEventAI_Event_Map.clear();
//Gather event data
QueryResult *result = WorldDatabase.PQuery("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, "
// Gather event data
QueryResult *result = WorldDatabase.Query("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, "
"event_param1, event_param2, event_param3, event_param4, "
"action1_type, action1_param1, action1_param2, action1_param3, "
"action2_type, action2_param1, action2_param2, action2_param3, "
+4 -1
View File
@@ -84,11 +84,14 @@ struct AchievementCriteriaEntry
} kill_creature;
// ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1
// TODO: there are further criterias instead just winning
struct
{
uint32 bgMapID; // 3
uint32 winCount; // 4
uint32 additionalRequirement1_type; // 5 additional requirement 1 type
uint32 additionalRequirement1_value; // 6 additional requirement 1 value
uint32 additionalRequirement2_type; // 7 additional requirement 2 type
uint32 additionalRequirement2_value; // 8 additional requirement 1 value
} win_bg;
// ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5
+3 -3
View File
@@ -949,7 +949,7 @@ void GameObject::Use(Unit* user)
UseDoorOrButton();
// activate script
sWorld.ScriptsStart(sGameObjectScripts, GetDBTableGUIDLow(), spellCaster, this);
GetMap()->ScriptsStart(sGameObjectScripts, GetDBTableGUIDLow(), spellCaster, this);
return;
case GAMEOBJECT_TYPE_QUESTGIVER: //2
@@ -1045,7 +1045,7 @@ void GameObject::Use(Unit* user)
player->CastedCreatureOrGO(info->id, GetGUID(), 0);
if (info->goober.eventId)
sWorld.ScriptsStart(sEventScripts, info->goober.eventId, player, this);
GetMap()->ScriptsStart(sEventScripts, info->goober.eventId, player, this);
}
// cast this spell later if provided
@@ -1068,7 +1068,7 @@ void GameObject::Use(Unit* user)
player->SendCinematicStart(info->camera.cinematicId);
if (info->camera.eventID)
sWorld.ScriptsStart(sEventScripts, info->camera.eventID, player, this);
GetMap()->ScriptsStart(sEventScripts, info->camera.eventID, player, this);
return;
}
+2 -2
View File
@@ -245,14 +245,14 @@ bool ChatHandler::HandleAccountLockCommand(const char* args)
std::string argstr = (char*)args;
if (argstr == "on")
{
LoginDatabase.PExecute( "UPDATE account SET locked = '1' WHERE id = '%d'",m_session->GetAccountId());
loginDatabase.PExecute( "UPDATE account SET locked = '1' WHERE id = '%d'",m_session->GetAccountId());
PSendSysMessage(LANG_COMMAND_ACCLOCKLOCKED);
return true;
}
if (argstr == "off")
{
LoginDatabase.PExecute( "UPDATE account SET locked = '0' WHERE id = '%d'",m_session->GetAccountId());
loginDatabase.PExecute( "UPDATE account SET locked = '0' WHERE id = '%d'",m_session->GetAccountId());
PSendSysMessage(LANG_COMMAND_ACCLOCKUNLOCKED);
return true;
}
+1 -1
View File
@@ -499,7 +499,7 @@ bool ChatHandler::HandleGMTicketAssignToCommand(const char* args)
}
uint64 tarGUID = objmgr.GetPlayerGUIDByName(targm.c_str());
uint64 accid = objmgr.GetPlayerAccountIdByGUID(tarGUID);
QueryResult *result = LoginDatabase.PQuery("SELECT `gmlevel` FROM `account` WHERE `id` = '%u'", accid);
QueryResult *result = loginDatabase.PQuery("SELECT `gmlevel` FROM `account` WHERE `id` = '%u'", accid);
if(!tarGUID|| !result || result->Fetch()->GetUInt32() < SEC_MODERATOR)
{
SendSysMessage(LANG_COMMAND_TICKETASSIGNERROR_A);
+9 -9
View File
@@ -84,7 +84,7 @@ bool ChatHandler::HandleMuteCommand(const char* args)
if (target)
target->GetSession()->m_muteTime = mutetime;
LoginDatabase.PExecute("UPDATE account SET mutetime = " UI64FMTD " WHERE id = '%u'",uint64(mutetime), account_id );
loginDatabase.PExecute("UPDATE account SET mutetime = " UI64FMTD " WHERE id = '%u'",uint64(mutetime), account_id );
if(target)
ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_DISABLED, notspeaktime, mutereasonstr.c_str());
@@ -130,7 +130,7 @@ bool ChatHandler::HandleUnmuteCommand(const char* args)
target->GetSession()->m_muteTime = 0;
}
LoginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id );
loginDatabase.PExecute("UPDATE account SET mutetime = '0' WHERE id = '%u'", account_id );
if(target)
ChatHandler(target).PSendSysMessage(LANG_YOUR_CHAT_ENABLED);
@@ -2189,7 +2189,7 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
uint32 security = 0;
std::string last_login = GetTrinityString(LANG_ERROR);
QueryResult* result = LoginDatabase.PQuery("SELECT username,gmlevel,email,last_ip,last_login FROM account WHERE id = '%u'",accId);
QueryResult* result = loginDatabase.PQuery("SELECT username,gmlevel,email,last_ip,last_login FROM account WHERE id = '%u'",accId);
if(result)
{
Field* fields = result->Fetch();
@@ -3933,9 +3933,9 @@ bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
char* limit_str = strtok (NULL, " ");
int32 limit = limit_str ? atoi (limit_str) : -1;
LoginDatabase.escape_string (ip);
loginDatabase.escape_string (ip);
QueryResult* result = LoginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ());
QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE last_ip = '%s'", ip.c_str ());
return LookupPlayerSearchCommand (result,limit);
}
@@ -3952,9 +3952,9 @@ bool ChatHandler::HandleLookupPlayerAccountCommand(const char* args)
if (!AccountMgr::normalizeString (account))
return false;
LoginDatabase.escape_string (account);
loginDatabase.escape_string (account);
QueryResult* result = LoginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ());
QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE username = '%s'", account.c_str ());
return LookupPlayerSearchCommand (result,limit);
}
@@ -3969,9 +3969,9 @@ bool ChatHandler::HandleLookupPlayerEmailCommand(const char* args)
char* limit_str = strtok (NULL, " ");
int32 limit = limit_str ? atoi (limit_str) : -1;
LoginDatabase.escape_string (email);
loginDatabase.escape_string (email);
QueryResult* result = LoginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ());
QueryResult* result = loginDatabase.PQuery ("SELECT id,username FROM account WHERE email = '%s'", email.c_str ());
return LookupPlayerSearchCommand (result,limit);
}
+19 -19
View File
@@ -1415,7 +1415,7 @@ bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
PSendSysMessage(LANG_YOURS_SECURITY_CHANGED, m_session->GetPlayer()->GetName(), gm);
}
LoginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE id = '%u'", gm, targetAccountId);
loginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE id = '%u'", gm, targetAccountId);
return true;
}else
{
@@ -1456,7 +1456,7 @@ bool ChatHandler::HandleAccountSetGmLevelCommand(const char* args)
}
PSendSysMessage(LANG_YOU_CHANGE_SECURITY, targetAccountName.c_str(), gm);
LoginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE id = '%u'", gm, targetAccountId);
loginDatabase.PExecute("UPDATE account SET gmlevel = '%d' WHERE id = '%u'", gm, targetAccountId);
return true;
}
}
@@ -5909,7 +5909,7 @@ bool ChatHandler::HandleBanInfoCharacterCommand(const char* args)
bool ChatHandler::HandleBanInfoHelper(uint32 accountid, char const* accountname)
{
QueryResult *result = LoginDatabase.PQuery("SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate,banreason,bannedby FROM account_banned WHERE id = '%u' ORDER BY bandate ASC",accountid);
QueryResult *result = loginDatabase.PQuery("SELECT FROM_UNIXTIME(bandate), unbandate-bandate, active, unbandate,banreason,bannedby FROM account_banned WHERE id = '%u' ORDER BY bandate ASC",accountid);
if(!result)
{
PSendSysMessage(LANG_BANINFO_NOACCOUNTBAN, accountname);
@@ -5949,8 +5949,8 @@ bool ChatHandler::HandleBanInfoIPCommand(const char* args)
std::string IP = cIP;
LoginDatabase.escape_string(IP);
QueryResult *result = LoginDatabase.PQuery("SELECT ip, FROM_UNIXTIME(bandate), FROM_UNIXTIME(unbandate), unbandate-UNIX_TIMESTAMP(), banreason,bannedby,unbandate-bandate FROM ip_banned WHERE ip = '%s'",IP.c_str());
loginDatabase.escape_string(IP);
QueryResult *result = loginDatabase.PQuery("SELECT ip, FROM_UNIXTIME(bandate), FROM_UNIXTIME(unbandate), unbandate-UNIX_TIMESTAMP(), banreason,bannedby,unbandate-bandate FROM ip_banned WHERE ip = '%s'",IP.c_str());
if(!result)
{
PSendSysMessage(LANG_BANINFO_NOIP);
@@ -5968,14 +5968,14 @@ bool ChatHandler::HandleBanInfoIPCommand(const char* args)
bool ChatHandler::HandleBanListCharacterCommand(const char* args)
{
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
char* cFilter = strtok ((char*)args, " ");
if(!cFilter)
return false;
std::string filter = cFilter;
LoginDatabase.escape_string(filter);
loginDatabase.escape_string(filter);
QueryResult* result = CharacterDatabase.PQuery("SELECT account FROM characters WHERE name "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'"),filter.c_str());
if (!result)
{
@@ -5988,22 +5988,22 @@ bool ChatHandler::HandleBanListCharacterCommand(const char* args)
bool ChatHandler::HandleBanListAccountCommand(const char* args)
{
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
char* cFilter = strtok((char*)args, " ");
std::string filter = cFilter ? cFilter : "";
LoginDatabase.escape_string(filter);
loginDatabase.escape_string(filter);
QueryResult* result;
if(filter.empty())
{
result = LoginDatabase.Query("SELECT account.id, username FROM account, account_banned"
result = loginDatabase.Query("SELECT account.id, username FROM account, account_banned"
" WHERE account.id = account_banned.id AND active = 1 GROUP BY account.id");
}
else
{
result = LoginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
result = loginDatabase.PQuery("SELECT account.id, username FROM account, account_banned"
" WHERE account.id = account_banned.id AND active = 1 AND username "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")" GROUP BY account.id",
filter.c_str());
}
@@ -6029,7 +6029,7 @@ bool ChatHandler::HandleBanListHelper(QueryResult* result)
Field* fields = result->Fetch();
uint32 accountid = fields[0].GetUInt32();
QueryResult* banresult = LoginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
QueryResult* banresult = loginDatabase.PQuery("SELECT account.username FROM account,account_banned WHERE account_banned.id='%u' AND account_banned.id=account.id",accountid);
if(banresult)
{
Field* fields2 = banresult->Fetch();
@@ -6060,7 +6060,7 @@ bool ChatHandler::HandleBanListHelper(QueryResult* result)
accmgr.GetName (account_id,account_name);
// No SQL injection. id is uint32.
QueryResult *banInfo = LoginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
QueryResult *banInfo = loginDatabase.PQuery("SELECT bandate,unbandate,bannedby,banreason FROM account_banned WHERE id = %u ORDER BY unbandate", account_id);
if (banInfo)
{
Field *fields2 = banInfo->Fetch();
@@ -6097,23 +6097,23 @@ bool ChatHandler::HandleBanListHelper(QueryResult* result)
bool ChatHandler::HandleBanListIPCommand(const char* args)
{
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
char* cFilter = strtok((char*)args, " ");
std::string filter = cFilter ? cFilter : "";
LoginDatabase.escape_string(filter);
loginDatabase.escape_string(filter);
QueryResult* result;
if(filter.empty())
{
result = LoginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
result = loginDatabase.Query ("SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
" WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP())"
" ORDER BY unbandate" );
}
else
{
result = LoginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
result = loginDatabase.PQuery( "SELECT ip,bandate,unbandate,bannedby,banreason FROM ip_banned"
" WHERE (bandate=unbandate OR unbandate>UNIX_TIMESTAMP()) AND ip "_LIKE_" "_CONCAT3_("'%%'","'%s'","'%%'")
" ORDER BY unbandate",filter.c_str() );
}
@@ -6882,7 +6882,7 @@ bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
bool ChatHandler::HandleGMListFullCommand(const char* /*args*/)
{
///- Get the accounts with GM Level >0
QueryResult *result = LoginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
QueryResult *result = loginDatabase.Query( "SELECT username,gmlevel FROM account WHERE gmlevel > 0" );
if(result)
{
SendSysMessage(LANG_GMLIST);
@@ -6991,7 +6991,7 @@ bool ChatHandler::HandleAccountSetAddonCommand(const char* args)
return false;
// No SQL injection
LoginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
loginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'",lev,account_id);
PSendSysMessage(LANG_ACCOUNT_SETADDON,account_name.c_str(),account_id,lev);
return true;
}
+2 -4
View File
@@ -624,6 +624,7 @@ libmangosgame_a_SOURCES = \
Channel.cpp \
Channel.h \
ChannelHandler.cpp \
ChannelMgr.cpp \
ChannelMgr.h \
CharacterHandler.cpp \
Chat.cpp \
@@ -840,11 +841,8 @@ libmangosgame_a_SOURCES = \
GroupRefManager.h
>>>>>>> 5a6594330caefc0dc00a5fe792dcb0e344b457cb:src/game/Makefile.am
## Link against shared library
libmangosgame_a_LIBADD = ../shared/libmangosshared.a ../shared/Auth/libmangosauth.a ../shared/Config/libmangosconfig.a ../shared/Database/libmangosdatabase.a ../shared/vmap/libmangosvmaps.a
## Additional files to include when running 'make dist'
# Precompiled Headers for WIN
EXTRA_DIST = \
pchdef.cpp \
pchdef.h
pchdef.h
+860 -13
View File
@@ -20,6 +20,7 @@
#include "MapManager.h"
#include "Player.h"
#include "Vehicle.h"
#include "GridNotifiers.h"
#include "Log.h"
#include "GridStates.h"
@@ -36,6 +37,7 @@
#include "Group.h"
#include "MapRefManager.h"
#include "Vehicle.h"
#include "WaypointManager.h"
#include "MapInstanced.h"
#include "InstanceSaveMgr.h"
@@ -46,9 +48,20 @@
GridState* si_GridStates[MAX_GRID_STATE];
struct ScriptAction
{
uint64 sourceGUID;
uint64 targetGUID;
uint64 ownerGUID; // owner of source if source is item
ScriptInfo const* script; // pointer to static script data
};
Map::~Map()
{
UnloadAll();
if(!m_scriptSchedule.empty())
sWorld.DecreaseScheduledScriptCount(m_scriptSchedule.size());
}
bool Map::ExistMap(uint32 mapid,int gx,int gy)
@@ -780,17 +793,21 @@ void Map::Update(const uint32 &t_diff)
// Don't unload grids if it's battleground, since we may have manually added GOs,creatures, those doesn't load from DB at grid re-load !
// This isn't really bother us, since as soon as we have instanced BG-s, the whole map unloads as the BG gets ended
if (IsBattleGroundOrArena())
return;
for (GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); )
if (!IsBattleGroundOrArena())
{
NGridType *grid = i->getSource();
GridInfo *info = i->getSource()->getGridInfoRef();
++i; // The update might delete the map and we need the next map before the iterator gets invalid
assert(grid->GetGridState() >= 0 && grid->GetGridState() < MAX_GRID_STATE);
si_GridStates[grid->GetGridState()]->Update(*this, *grid, *info, grid->getX(), grid->getY(), t_diff);
for (GridRefManager<NGridType>::iterator i = GridRefManager<NGridType>::begin(); i != GridRefManager<NGridType>::end(); )
{
NGridType *grid = i->getSource();
GridInfo *info = i->getSource()->getGridInfoRef();
++i; // The update might delete the map and we need the next map before the iterator gets invalid
assert(grid->GetGridState() >= 0 && grid->GetGridState() < MAX_GRID_STATE);
si_GridStates[grid->GetGridState()]->Update(*this, *grid, *info, grid->getX(), grid->getY(), t_diff);
}
}
///- Process necessary scripts
if (!m_scriptSchedule.empty())
ScriptsProcess();
}
void Map::Remove(Player *player, bool remove)
@@ -1312,11 +1329,11 @@ bool GridMap::loadHeihgtData(FILE *in, uint32 offset, uint32 size)
map_heightHeader header;
fseek(in, offset, SEEK_SET);
fread(&header, sizeof(header), 1, in);
if (header.fourcc != uint32(MAP_HEIGTH_MAGIC))
if (header.fourcc != uint32(MAP_HEIGHT_MAGIC))
return false;
m_gridHeight = header.gridHeight;
if (!(header.flags & MAP_HEIGHT_NO_HIGHT))
if (!(header.flags & MAP_HEIGHT_NO_HEIGHT))
{
if ((header.flags & MAP_HEIGHT_AS_INT16))
{
@@ -1365,12 +1382,12 @@ bool GridMap::loadLiquidData(FILE *in, uint32 offset, uint32 size)
m_liquid_height= header.height;
m_liquidLevel = header.liquidLevel;
if (!(header.flags&MAP_LIQUID_NO_TYPE))
if (!(header.flags & MAP_LIQUID_NO_TYPE))
{
m_liquid_type = new uint8 [16*16];
fread(m_liquid_type, sizeof(uint8), 16*16, in);
}
if (!(header.flags&MAP_LIQUID_NO_HIGHT))
if (!(header.flags & MAP_LIQUID_NO_HEIGHT))
{
m_liquid_map = new float [m_liquid_width*m_liquid_height];
fread(m_liquid_map, sizeof(float), m_liquid_width*m_liquid_height, in);
@@ -2745,6 +2762,836 @@ void BattleGroundMap::UnloadAll()
Map::UnloadAll();
}
/// Put scripts in the execution queue
void Map::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, Object* target)
{
///- Find the script map
ScriptMapMap::const_iterator s = scripts.find(id);
if (s == scripts.end())
return;
// prepare static data
uint64 sourceGUID = source ? source->GetGUID() : (uint64)0; //some script commands doesn't have source
uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
uint64 ownerGUID = (source->GetTypeId()==TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
///- Schedule script execution for all scripts in the script map
ScriptMap const *s2 = &(s->second);
bool immedScript = false;
for (ScriptMap::const_iterator iter = s2->begin(); iter != s2->end(); ++iter)
{
ScriptAction sa;
sa.sourceGUID = sourceGUID;
sa.targetGUID = targetGUID;
sa.ownerGUID = ownerGUID;
sa.script = &iter->second;
m_scriptSchedule.insert(std::pair<time_t, ScriptAction>(time_t(sWorld.GetGameTime() + iter->first), sa));
if (iter->first == 0)
immedScript = true;
sWorld.IncreaseScheduledScriptsCount();
}
///- If one of the effects should be immediate, launch the script execution
if (/*start &&*/ immedScript)
ScriptsProcess();
}
void Map::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target)
{
// NOTE: script record _must_ exist until command executed
// prepare static data
uint64 sourceGUID = source ? source->GetGUID() : (uint64)0;
uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
uint64 ownerGUID = (source->GetTypeId()==TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
ScriptAction sa;
sa.sourceGUID = sourceGUID;
sa.targetGUID = targetGUID;
sa.ownerGUID = ownerGUID;
sa.script = &script;
m_scriptSchedule.insert(std::pair<time_t, ScriptAction>(time_t(sWorld.GetGameTime() + delay), sa));
sWorld.IncreaseScheduledScriptsCount();
///- If effects should be immediate, launch the script execution
if(delay == 0)
ScriptsProcess();
}
/// Process queued scripts
void Map::ScriptsProcess()
{
if (m_scriptSchedule.empty())
return;
///- Process overdue queued scripts
std::multimap<time_t, ScriptAction>::iterator iter = m_scriptSchedule.begin();
// ok as multimap is a *sorted* associative container
while (!m_scriptSchedule.empty() && (iter->first <= sWorld.GetGameTime()))
{
ScriptAction const& step = iter->second;
Object* source = NULL;
if(step.sourceGUID)
{
switch(GUID_HIPART(step.sourceGUID))
{
case HIGHGUID_ITEM:
// case HIGHGUID_CONTAINER: ==HIGHGUID_ITEM
{
Player* player = HashMapHolder<Player>::Find(step.ownerGUID);
if(player)
source = player->GetItemByGuid(step.sourceGUID);
break;
}
case HIGHGUID_UNIT:
source = HashMapHolder<Creature>::Find(step.sourceGUID);
break;
case HIGHGUID_PET:
source = HashMapHolder<Pet>::Find(step.sourceGUID);
break;
case HIGHGUID_VEHICLE:
source = HashMapHolder<Vehicle>::Find(step.sourceGUID);
break;
case HIGHGUID_PLAYER:
source = HashMapHolder<Player>::Find(step.sourceGUID);
break;
case HIGHGUID_GAMEOBJECT:
source = HashMapHolder<GameObject>::Find(step.sourceGUID);
break;
case HIGHGUID_CORPSE:
source = HashMapHolder<Corpse>::Find(step.sourceGUID);
break;
case HIGHGUID_MO_TRANSPORT:
for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
{
if((*iter)->GetGUID() == step.sourceGUID)
{
source = reinterpret_cast<Object*>(*iter);
break;
}
}
break;
default:
sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.sourceGUID));
break;
}
}
//if(source && !source->IsInWorld()) source = NULL;
Object* target = NULL;
if(step.targetGUID)
{
switch(GUID_HIPART(step.targetGUID))
{
case HIGHGUID_UNIT:
target = HashMapHolder<Creature>::Find(step.targetGUID);
break;
case HIGHGUID_PET:
target = HashMapHolder<Pet>::Find(step.targetGUID);
break;
case HIGHGUID_VEHICLE:
target = HashMapHolder<Vehicle>::Find(step.targetGUID);
break;
case HIGHGUID_PLAYER: // empty GUID case also
target = HashMapHolder<Player>::Find(step.targetGUID);
break;
case HIGHGUID_GAMEOBJECT:
target = HashMapHolder<GameObject>::Find(step.targetGUID);
break;
case HIGHGUID_CORPSE:
target = HashMapHolder<Corpse>::Find(step.targetGUID);
break;
default:
sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.targetGUID));
break;
}
}
//if(target && !target->IsInWorld()) target = NULL;
switch (step.script->command)
{
case SCRIPT_COMMAND_TALK:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_TALK call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_TALK call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
if(step.script->datalong > 3)
{
sLog.outError("SCRIPT_COMMAND_TALK invalid chat type (%u), skipping.",step.script->datalong);
break;
}
uint64 unit_target = target ? target->GetGUID() : 0;
//datalong 0=normal say, 1=whisper, 2=yell, 3=emote text
switch(step.script->datalong)
{
case 0: // Say
((Creature *)source)->Say(step.script->dataint, LANG_UNIVERSAL, unit_target);
break;
case 1: // Whisper
if(!unit_target)
{
sLog.outError("SCRIPT_COMMAND_TALK attempt to whisper (%u) NULL, skipping.",step.script->datalong);
break;
}
((Creature *)source)->Whisper(step.script->dataint,unit_target);
break;
case 2: // Yell
((Creature *)source)->Yell(step.script->dataint, LANG_UNIVERSAL, unit_target);
break;
case 3: // Emote text
((Creature *)source)->TextEmote(step.script->dataint, unit_target);
break;
default:
break; // must be already checked at load
}
break;
}
case SCRIPT_COMMAND_EMOTE:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_EMOTE call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_EMOTE call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
((Creature *)source)->HandleEmoteCommand(step.script->datalong);
break;
case SCRIPT_COMMAND_FIELD_SET:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FIELD_SET call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FIELD_SET call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->SetUInt32Value(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_MOVE_TO:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_MOVE_TO call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_MOVE_TO call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
((Creature*)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, step.script->datalong2 );
((Creature*)source)->GetMap()->CreatureRelocation(((Creature*)source), step.script->x, step.script->y, step.script->z, 0);
break;
case SCRIPT_COMMAND_FLAG_SET:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FLAG_SET call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FLAG_SET call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->SetFlag(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_FLAG_REMOVE:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->RemoveFlag(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_TELEPORT_TO:
{
// accept player in any one from target/source arg
if (!target && !source)
{
sLog.outError("SCRIPT_COMMAND_TELEPORT_TO call for NULL object.");
break;
}
// must be only Player
if((!target || target->GetTypeId() != TYPEID_PLAYER) && (!source || source->GetTypeId() != TYPEID_PLAYER))
{
sLog.outError("SCRIPT_COMMAND_TELEPORT_TO call for non-player (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0);
break;
}
Player* pSource = target && target->GetTypeId() == TYPEID_PLAYER ? (Player*)target : (Player*)source;
pSource->TeleportTo(step.script->datalong, step.script->x, step.script->y, step.script->z, step.script->o);
break;
}
case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE:
{
if(!step.script->datalong) // creature not specified
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for NULL creature.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for NULL world object.");
break;
}
WorldObject* summoner = dynamic_cast<WorldObject*>(source);
if(!summoner)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for non-WorldObject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
float x = step.script->x;
float y = step.script->y;
float z = step.script->z;
float o = step.script->o;
Creature* pCreature = summoner->SummonCreature(step.script->datalong, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,step.script->datalong2);
if (!pCreature)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON failed for creature (entry: %u).",step.script->datalong);
break;
}
break;
}
case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT:
{
if(!step.script->datalong) // gameobject not specified
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for NULL gameobject.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for NULL world object.");
break;
}
WorldObject* summoner = dynamic_cast<WorldObject*>(source);
if(!summoner)
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for non-WorldObject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
GameObject *go = NULL;
int32 time_to_despawn = step.script->datalong2<5 ? 5 : (int32)step.script->datalong2;
CellPair p(MaNGOS::ComputeCellPair(summoner->GetPositionX(), summoner->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*summoner,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(summoner, go,go_check);
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *summoner->GetMap());
if ( !go )
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if( go->GetGoType()==GAMEOBJECT_TYPE_FISHINGNODE ||
go->GetGoType()==GAMEOBJECT_TYPE_DOOR ||
go->GetGoType()==GAMEOBJECT_TYPE_BUTTON ||
go->GetGoType()==GAMEOBJECT_TYPE_TRAP )
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT can not be used with gameobject of type %u (guid: %u).", uint32(go->GetGoType()), step.script->datalong);
break;
}
if( go->isSpawned() )
break; //gameobject already spawned
go->SetLootState(GO_READY);
go->SetRespawnTime(time_to_despawn); //despawn object in ? seconds
go->GetMap()->Add(go);
break;
}
case SCRIPT_COMMAND_OPEN_DOOR:
{
if(!step.script->datalong) // door not specified
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for NULL door.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for NULL unit.");
break;
}
if(!source->isType(TYPEMASK_UNIT)) // must be any Unit (creature or player)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for non-unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *door = NULL;
int32 time_to_close = step.script->datalong2 < 15 ? 15 : (int32)step.script->datalong2;
CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *caster->GetMap());
if (!door)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if (door->GetGoType() != GAMEOBJECT_TYPE_DOOR)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for non-door(GoType: %u).", door->GetGoType());
break;
}
if (door->GetGoState() != GO_STATE_READY)
break; //door already open
door->UseDoorOrButton(time_to_close);
if(target && target->isType(TYPEMASK_GAMEOBJECT) && ((GameObject*)target)->GetGoType()==GAMEOBJECT_TYPE_BUTTON)
((GameObject*)target)->UseDoorOrButton(time_to_close);
break;
}
case SCRIPT_COMMAND_CLOSE_DOOR:
{
if(!step.script->datalong) // guid for door not specified
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for NULL door.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for NULL unit.");
break;
}
if(!source->isType(TYPEMASK_UNIT)) // must be any Unit (creature or player)
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for non-unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *door = NULL;
int32 time_to_open = step.script->datalong2 < 15 ? 15 : (int32)step.script->datalong2;
CellPair p(MaNGOS::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *caster->GetMap());
if ( !door )
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if ( door->GetGoType() != GAMEOBJECT_TYPE_DOOR )
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR failed for non-door(GoType: %u).", door->GetGoType());
break;
}
if( door->GetGoState() == GO_STATE_READY )
break; //door already closed
door->UseDoorOrButton(time_to_open);
if(target && target->isType(TYPEMASK_GAMEOBJECT) && ((GameObject*)target)->GetGoType()==GAMEOBJECT_TYPE_BUTTON)
((GameObject*)target)->UseDoorOrButton(time_to_open);
break;
}
case SCRIPT_COMMAND_QUEST_EXPLORED:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for NULL source.");
break;
}
if(!target)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for NULL target.");
break;
}
// when script called for item spell casting then target == (unit or GO) and source is player
WorldObject* worldObject;
Player* player;
if(target->GetTypeId()==TYPEID_PLAYER)
{
if(source->GetTypeId()!=TYPEID_UNIT && source->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-creature and non-gameobject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
worldObject = (WorldObject*)source;
player = (Player*)target;
}
else
{
if(target->GetTypeId()!=TYPEID_UNIT && target->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-creature and non-gameobject (TypeId: %u), skipping.",target->GetTypeId());
break;
}
if(source->GetTypeId()!=TYPEID_PLAYER)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-player(TypeId: %u), skipping.",source->GetTypeId());
break;
}
worldObject = (WorldObject*)target;
player = (Player*)source;
}
// quest id and flags checked at script loading
if( (worldObject->GetTypeId()!=TYPEID_UNIT || ((Unit*)worldObject)->isAlive()) &&
(step.script->datalong2==0 || worldObject->IsWithinDistInMap(player,float(step.script->datalong2))) )
player->AreaExploredOrEventHappens(step.script->datalong);
else
player->FailQuest(step.script->datalong);
break;
}
case SCRIPT_COMMAND_ACTIVATE_OBJECT:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT must have source caster.");
break;
}
if(!source->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT source caster isn't unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
if(!target)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT call for NULL gameobject.");
break;
}
if(target->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT call for non-gameobject (TypeId: %u), skipping.",target->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *go = (GameObject*)target;
go->Use(caster);
break;
}
case SCRIPT_COMMAND_REMOVE_AURA:
{
Object* cmdTarget = step.script->datalong2 ? source : target;
if(!cmdTarget)
{
sLog.outError("SCRIPT_COMMAND_REMOVE_AURA call for NULL %s.",step.script->datalong2 ? "source" : "target");
break;
}
if(!cmdTarget->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_REMOVE_AURA %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 ? "source" : "target",cmdTarget->GetTypeId());
break;
}
((Unit*)cmdTarget)->RemoveAurasDueToSpell(step.script->datalong);
break;
}
case SCRIPT_COMMAND_CAST_SPELL:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL must have source caster.");
break;
}
Object* cmdTarget = step.script->datalong2 & 0x01 ? source : target;
if(!cmdTarget)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 & 0x01 ? "source" : "target");
break;
}
if(!cmdTarget->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 & 0x01 ? "source" : "target",cmdTarget->GetTypeId());
break;
}
Unit* spellTarget = (Unit*)cmdTarget;
Object* cmdSource = step.script->datalong2 & 0x02 ? target : source;
if(!cmdSource)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 & 0x02 ? "target" : "source");
break;
}
if(!cmdSource->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 & 0x02 ? "target" : "source", cmdSource->GetTypeId());
break;
}
Unit* spellSource = (Unit*)cmdSource;
//TODO: when GO cast implemented, code below must be updated accordingly to also allow GO spell cast
spellSource->CastSpell(spellTarget,step.script->datalong,false);
break;
}
case SCRIPT_COMMAND_LOAD_PATH:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_START_MOVE is tried to apply to NON-existing unit.");
break;
}
if(!source->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_START_MOVE source mover isn't unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
if(!WaypointMgr.GetPath(step.script->datalong))
{
sLog.outError("SCRIPT_COMMAND_START_MOVE source mover has an invallid path, skipping.", step.script->datalong2);
break;
}
dynamic_cast<Unit*>(source)->GetMotionMaster()->MovePath(step.script->datalong, step.script->datalong2);
break;
}
case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT:
{
if(!step.script->datalong || !step.script->datalong2)
{
sLog.outError("SCRIPT_COMMAND_CALLSCRIPT calls invallid db_script_id or lowguid not present: skipping.");
break;
}
//our target
Creature* target = NULL;
if(source) //using grid searcher
{
CellPair p(Trinity::ComputeCellPair(((Unit*)source)->GetPositionX(), ((Unit*)source)->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
//sLog.outDebug("Attempting to find Creature: Db GUID: %i", step.script->datalong);
Trinity::CreatureWithDbGUIDCheck target_check(((Unit*)source), step.script->datalong);
Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(((Unit*)source), target, target_check);
TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, unit_checker, *(((Unit*)source)->GetMap()));
}
else //check hashmap holders
{
if(CreatureData const* data = objmgr.GetCreatureData(step.script->datalong))
target = ObjectAccessor::GetObjectInWorld<Creature>(data->mapid, data->posX, data->posY, MAKE_NEW_GUID(step.script->datalong, data->id, HIGHGUID_UNIT), target);
}
//sLog.outDebug("attempting to pass target...");
if(!target)
break;
//sLog.outDebug("target passed");
//Lets choose our ScriptMap map
ScriptMapMap *datamap = NULL;
switch(step.script->dataint)
{
case 1://QUEST END SCRIPTMAP
datamap = &sQuestEndScripts;
break;
case 2://QUEST START SCRIPTMAP
datamap = &sQuestStartScripts;
break;
case 3://SPELLS SCRIPTMAP
datamap = &sSpellScripts;
break;
case 4://GAMEOBJECTS SCRIPTMAP
datamap = &sGameObjectScripts;
break;
case 5://EVENTS SCRIPTMAP
datamap = &sEventScripts;
break;
case 6://WAYPOINTS SCRIPTMAP
datamap = &sWaypointScripts;
break;
default:
sLog.outError("SCRIPT_COMMAND_CALLSCRIPT ERROR: no scriptmap present... ignoring");
break;
}
//if no scriptmap present...
if(!datamap)
break;
uint32 script_id = step.script->datalong2;
//insert script into schedule but do not start it
ScriptsStart(*datamap, script_id, target, NULL/*, false*/);
break;
}
case SCRIPT_COMMAND_KILL:
{
if(!source || ((Creature*)source)->isDead())
break;
((Creature*)source)->DealDamage(((Creature*)source), ((Creature*)source)->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
switch(step.script->dataint)
{
case 0: break; //return false not remove corpse
case 1: ((Creature*)source)->RemoveCorpse(); break;
}
break;
}
case SCRIPT_COMMAND_PLAY_SOUND:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND call for NULL creature.");
break;
}
WorldObject* pSource = dynamic_cast<WorldObject*>(source);
if(!pSource)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND call for non-world object (TypeId: %u), skipping.",source->GetTypeId());
break;
}
// bitmask: 0/1=anyone/target, 0/2=with distance dependent
Player* pTarget = NULL;
if(step.script->datalong2 & 1)
{
if(!target)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND in targeted mode call for NULL target.");
break;
}
if(target->GetTypeId()!=TYPEID_PLAYER)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND in targeted mode call for non-player (TypeId: %u), skipping.",target->GetTypeId());
break;
}
pTarget = (Player*)target;
}
// bitmask: 0/1=anyone/target, 0/2=with distance dependent
if(step.script->datalong2 & 2)
pSource->PlayDistanceSound(step.script->datalong,pTarget);
else
pSource->PlayDirectSound(step.script->datalong,pTarget);
break;
}
default:
sLog.outError("Unknown script command %u called.",step.script->command);
break;
}
m_scriptSchedule.erase(iter);
sWorld.DecreaseScheduledScriptCount();
iter = m_scriptSchedule.begin();
}
return;
}
Creature*
Map::GetCreature(uint64 guid)
{
+26 -9
View File
@@ -43,9 +43,12 @@ class WorldPacket;
class InstanceData;
class Group;
class InstanceSave;
class Object;
class WorldObject;
class TempSummon;
class CreatureGroup;
struct ScriptInfo;
struct ScriptAction;
typedef ACE_RW_Thread_Mutex GridRWLock;
@@ -74,10 +77,11 @@ typedef MaNGOS::SingleThreaded<GridRWLock>::Lock NullGuard;
#define MAP_MAGIC 'SPAM'
#define MAP_VERSION_MAGIC '0.1w'
#define MAP_AREA_MAGIC 'AERA'
#define MAP_HEIGTH_MAGIC 'TGHM'
#define MAP_HEIGHT_MAGIC 'TGHM'
#define MAP_LIQUID_MAGIC 'QILM'
struct map_fileheader{
struct map_fileheader
{
uint32 mapMagic;
uint32 versionMagic;
uint32 areaMapOffset;
@@ -89,17 +93,20 @@ struct map_fileheader{
};
#define MAP_AREA_NO_AREA 0x0001
struct map_areaHeader{
struct map_areaHeader
{
uint32 fourcc;
uint16 flags;
uint16 gridArea;
};
#define MAP_HEIGHT_NO_HIGHT 0x0001
#define MAP_HEIGHT_NO_HEIGHT 0x0001
#define MAP_HEIGHT_AS_INT16 0x0002
#define MAP_HEIGHT_AS_INT8 0x0004
struct map_heightHeader{
struct map_heightHeader
{
uint32 fourcc;
uint32 flags;
float gridHeight;
@@ -107,8 +114,10 @@ struct map_heightHeader{
};
#define MAP_LIQUID_NO_TYPE 0x0001
#define MAP_LIQUID_NO_HIGHT 0x0002
struct map_liquidHeader{
#define MAP_LIQUID_NO_HEIGHT 0x0002
struct map_liquidHeader
{
uint32 fourcc;
uint16 flags;
uint16 liquidType;
@@ -119,7 +128,8 @@ struct map_liquidHeader{
float liquidLevel;
};
enum ZLiquidStatus{
enum ZLiquidStatus
{
LIQUID_MAP_NO_WATER = 0x00000000,
LIQUID_MAP_ABOVE_WATER = 0x00000001,
LIQUID_MAP_WATER_WALK = 0x00000002,
@@ -138,7 +148,8 @@ enum ZLiquidStatus{
#define MAP_LIQUID_TYPE_DARK_WATER 0x10
#define MAP_LIQUID_TYPE_WMO_WATER 0x20
struct LiquidData{
struct LiquidData
{
uint32 type;
float level;
float depth_level;
@@ -398,6 +409,10 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
typedef MapRefManager PlayerList;
PlayerList const& GetPlayers() const { return m_mapRefManager; }
//per-map script storage
void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo> > const& scripts, uint32 id, Object* source, Object* target);
void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
// must called with AddToWorld
template<class T>
void AddToActive(T* obj) { AddToActiveHelper(obj); }
@@ -467,6 +482,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
void setGridObjectDataLoaded(bool pLoaded, uint32 x, uint32 y) { getNGrid(x,y)->setGridObjectDataLoaded(pLoaded); }
void setNGrid(NGridType* grid, uint32 x, uint32 y);
void ScriptsProcess();
void UpdateActiveCells(const float &x, const float &y, const uint32 &t_diff);
protected:
@@ -508,6 +524,7 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
std::vector<Unit*> i_unitsToNotify;
std::set<WorldObject *> i_objectsToRemove;
std::map<WorldObject*, bool> i_objectsToSwitch;
std::multimap<time_t, ScriptAction> m_scriptSchedule;
// Type specific code for add/remove to/from grid
template<class T>
+10 -8
View File
@@ -1216,15 +1216,17 @@ void WorldSession::HandleWardenDataOpcode(WorldPacket& /*recv_data*/)
*/
}
void WorldSession::HandlePlayedTime(WorldPacket& /*recv_data*/)
void WorldSession::HandlePlayedTime(WorldPacket& recv_data)
{
uint32 TotalTimePlayed = GetPlayer()->GetTotalPlayedTime();
uint32 LevelPlayedTime = GetPlayer()->GetLevelPlayedTime();
CHECK_PACKET_SIZE(recv_data, 1);
WorldPacket data(SMSG_PLAYED_TIME, 9);
data << TotalTimePlayed;
data << LevelPlayedTime;
data << uint8(0);
uint8 unk1;
recv_data >> unk1; // 0 or 1 expected
WorldPacket data(SMSG_PLAYED_TIME, 4 + 4 + 1);
data << uint32(_player->GetTotalPlayedTime());
data << uint32(_player->GetLevelPlayedTime());
data << uint8(unk1); // 0 - will not show in chat frame
SendPacket(&data);
}
@@ -1356,7 +1358,7 @@ void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data)
uint32 accid = plr->GetSession()->GetAccountId();
QueryResult *result = LoginDatabase.PQuery("SELECT username,email,last_ip FROM account WHERE id=%u", accid);
QueryResult *result = loginDatabase.PQuery("SELECT username,email,last_ip FROM account WHERE id=%u", accid);
if(!result)
{
SendNotification(LANG_ACCOUNT_FOR_PLAYER_NOT_FOUND, charname.c_str());
+3 -3
View File
@@ -4110,7 +4110,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
CharacterDatabase.PExecute("DELETE FROM character_equipmentsets WHERE guid = '%u'",guid);
CharacterDatabase.CommitTransaction();
//LoginDatabase.PExecute("UPDATE realmcharacters SET numchars = numchars - 1 WHERE acctid = %d AND realmid = %d", accountId, realmID);
//loginDatabase.PExecute("UPDATE realmcharacters SET numchars = numchars - 1 WHERE acctid = %d AND realmid = %d", accountId, realmID);
if(updateRealmChars) sWorld.UpdateRealmCharCount(accountId);
}
@@ -12882,7 +12882,7 @@ void Player::AddQuest( Quest const *pQuest, Object *questGiver )
//starting initial quest script
if(questGiver && pQuest->GetQuestStartScript()!=0)
sWorld.ScriptsStart(sQuestStartScripts, pQuest->GetQuestStartScript(), questGiver, this);
GetMap()->ScriptsStart(sQuestStartScripts, pQuest->GetQuestStartScript(), questGiver, this);
// Some spells applied at quest activation
SpellAreaForQuestMapBounds saBounds = spellmgr.GetSpellAreaForQuestMapBounds(quest_id,true);
@@ -14142,7 +14142,7 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive
GetSession()->SendPacket( &data );
if (pQuest->GetQuestCompleteScript() != 0)
sWorld.ScriptsStart(sQuestEndScripts, pQuest->GetQuestCompleteScript(), questGiver, this);
GetMap()->ScriptsStart(sQuestEndScripts, pQuest->GetQuestCompleteScript(), questGiver, this);
}
void Player::SendQuestFailed( uint32 quest_id )
-1
View File
@@ -30,7 +30,6 @@ template<class T>
void PointMovementGenerator<T>::Initialize(T &unit)
{
unit.StopMoving();
unit.clearUnitState(UNIT_STAT_MOVING);
Traveller<T> traveller(unit);
// knockback effect has UNIT_STAT_JUMPING set,so if here we disable sentmonstermove there will be creature position sync problem between client and server
i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z, true /* !unit.hasUnitState(UNIT_STAT_JUMPING)*/);
+1 -1
View File
@@ -475,4 +475,4 @@ void ReputationMgr::UpdateRankCounters( ReputationRank old_rank, ReputationRank
++m_reveredFactionCount;
if(new_rank >= REP_HONORED)
++m_honoredFactionCount;
}
}
+194 -184
View File
@@ -703,190 +703,194 @@ enum SpellEffects
enum SpellCastResult
{
SPELL_FAILED_AFFECTING_COMBAT = 0,
SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 1,
SPELL_FAILED_ALREADY_AT_FULL_MANA = 2,
SPELL_FAILED_ALREADY_AT_FULL_POWER = 3,
SPELL_FAILED_ALREADY_BEING_TAMED = 4,
SPELL_FAILED_ALREADY_HAVE_CHARM = 5,
SPELL_FAILED_ALREADY_HAVE_SUMMON = 6,
SPELL_FAILED_ALREADY_OPEN = 7,
SPELL_FAILED_AURA_BOUNCED = 8,
SPELL_FAILED_AUTOTRACK_INTERRUPTED = 9,
SPELL_FAILED_BAD_IMPLICIT_TARGETS = 10,
SPELL_FAILED_BAD_TARGETS = 11,
SPELL_FAILED_CANT_BE_CHARMED = 12,
SPELL_FAILED_CANT_BE_DISENCHANTED = 13,
SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 14,
SPELL_FAILED_CANT_BE_MILLED = 15,
SPELL_FAILED_CANT_BE_PROSPECTED = 16,
SPELL_FAILED_CANT_CAST_ON_TAPPED = 17,
SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 18,
SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 19,
SPELL_FAILED_CANT_STEALTH = 20,
SPELL_FAILED_CASTER_AURASTATE = 21,
SPELL_FAILED_CASTER_DEAD = 22,
SPELL_FAILED_CHARMED = 23,
SPELL_FAILED_CHEST_IN_USE = 24,
SPELL_FAILED_CONFUSED = 25,
SPELL_FAILED_DONT_REPORT = 26,
SPELL_FAILED_EQUIPPED_ITEM = 27,
SPELL_FAILED_EQUIPPED_ITEM_CLASS = 28,
SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 29,
SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 30,
SPELL_FAILED_ERROR = 31,
SPELL_FAILED_FIZZLE = 32,
SPELL_FAILED_FLEEING = 33,
SPELL_FAILED_FOOD_LOWLEVEL = 34,
SPELL_FAILED_HIGHLEVEL = 35,
SPELL_FAILED_HUNGER_SATIATED = 36,
SPELL_FAILED_IMMUNE = 37,
SPELL_FAILED_INCORRECT_AREA = 38,
SPELL_FAILED_INTERRUPTED = 39,
SPELL_FAILED_INTERRUPTED_COMBAT = 40,
SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 41,
SPELL_FAILED_ITEM_GONE = 42,
SPELL_FAILED_ITEM_NOT_FOUND = 43,
SPELL_FAILED_ITEM_NOT_READY = 44,
SPELL_FAILED_LEVEL_REQUIREMENT = 45,
SPELL_FAILED_LINE_OF_SIGHT = 46,
SPELL_FAILED_LOWLEVEL = 47,
SPELL_FAILED_LOW_CASTLEVEL = 48,
SPELL_FAILED_MAINHAND_EMPTY = 49,
SPELL_FAILED_MOVING = 50,
SPELL_FAILED_NEED_AMMO = 51,
SPELL_FAILED_NEED_AMMO_POUCH = 52,
SPELL_FAILED_NEED_EXOTIC_AMMO = 53,
SPELL_FAILED_NEED_MORE_ITEMS = 54,
SPELL_FAILED_NOPATH = 55,
SPELL_FAILED_NOT_BEHIND = 56,
SPELL_FAILED_NOT_FISHABLE = 57,
SPELL_FAILED_NOT_FLYING = 58,
SPELL_FAILED_NOT_HERE = 59,
SPELL_FAILED_NOT_INFRONT = 60,
SPELL_FAILED_NOT_IN_CONTROL = 61,
SPELL_FAILED_NOT_KNOWN = 62,
SPELL_FAILED_NOT_MOUNTED = 63,
SPELL_FAILED_NOT_ON_TAXI = 64,
SPELL_FAILED_NOT_ON_TRANSPORT = 65,
SPELL_FAILED_NOT_READY = 66,
SPELL_FAILED_NOT_SHAPESHIFT = 67,
SPELL_FAILED_NOT_STANDING = 68,
SPELL_FAILED_NOT_TRADEABLE = 69,
SPELL_FAILED_NOT_TRADING = 70,
SPELL_FAILED_NOT_UNSHEATHED = 71,
SPELL_FAILED_NOT_WHILE_GHOST = 72,
SPELL_FAILED_NOT_WHILE_LOOTING = 73,
SPELL_FAILED_NO_AMMO = 74,
SPELL_FAILED_NO_CHARGES_REMAIN = 75,
SPELL_FAILED_NO_CHAMPION = 76,
SPELL_FAILED_NO_COMBO_POINTS = 77,
SPELL_FAILED_NO_DUELING = 78,
SPELL_FAILED_NO_ENDURANCE = 79,
SPELL_FAILED_NO_FISH = 80,
SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 81,
SPELL_FAILED_NO_MOUNTS_ALLOWED = 82,
SPELL_FAILED_NO_PET = 83,
SPELL_FAILED_NO_POWER = 84,
SPELL_FAILED_NOTHING_TO_DISPEL = 85,
SPELL_FAILED_NOTHING_TO_STEAL = 86,
SPELL_FAILED_ONLY_ABOVEWATER = 87,
SPELL_FAILED_ONLY_DAYTIME = 88,
SPELL_FAILED_ONLY_INDOORS = 89,
SPELL_FAILED_ONLY_MOUNTED = 90,
SPELL_FAILED_ONLY_NIGHTTIME = 91,
SPELL_FAILED_ONLY_OUTDOORS = 92,
SPELL_FAILED_ONLY_SHAPESHIFT = 93,
SPELL_FAILED_ONLY_STEALTHED = 94,
SPELL_FAILED_ONLY_UNDERWATER = 95,
SPELL_FAILED_OUT_OF_RANGE = 96,
SPELL_FAILED_PACIFIED = 97,
SPELL_FAILED_POSSESSED = 98,
SPELL_FAILED_REAGENTS = 99,
SPELL_FAILED_REQUIRES_AREA = 100,
SPELL_FAILED_REQUIRES_SPELL_FOCUS = 101,
SPELL_FAILED_ROOTED = 102,
SPELL_FAILED_SILENCED = 103,
SPELL_FAILED_SPELL_IN_PROGRESS = 104,
SPELL_FAILED_SPELL_LEARNED = 105,
SPELL_FAILED_SPELL_UNAVAILABLE = 106,
SPELL_FAILED_STUNNED = 107,
SPELL_FAILED_TARGETS_DEAD = 108,
SPELL_FAILED_TARGET_AFFECTING_COMBAT = 109,
SPELL_FAILED_TARGET_AURASTATE = 110,
SPELL_FAILED_TARGET_DUELING = 111,
SPELL_FAILED_TARGET_ENEMY = 112,
SPELL_FAILED_TARGET_ENRAGED = 113,
SPELL_FAILED_TARGET_FRIENDLY = 114,
SPELL_FAILED_TARGET_IN_COMBAT = 115,
SPELL_FAILED_TARGET_IS_PLAYER = 116,
SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 117,
SPELL_FAILED_TARGET_NOT_DEAD = 118,
SPELL_FAILED_TARGET_NOT_IN_PARTY = 119,
SPELL_FAILED_TARGET_NOT_LOOTED = 120,
SPELL_FAILED_TARGET_NOT_PLAYER = 121,
SPELL_FAILED_TARGET_NO_POCKETS = 122,
SPELL_FAILED_TARGET_NO_WEAPONS = 123,
SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 124,
SPELL_FAILED_TARGET_UNSKINNABLE = 125,
SPELL_FAILED_THIRST_SATIATED = 126,
SPELL_FAILED_TOO_CLOSE = 127,
SPELL_FAILED_TOO_MANY_OF_ITEM = 128,
SPELL_FAILED_TOTEM_CATEGORY = 129,
SPELL_FAILED_TOTEMS = 130,
SPELL_FAILED_TRY_AGAIN = 131,
SPELL_FAILED_UNIT_NOT_BEHIND = 132,
SPELL_FAILED_UNIT_NOT_INFRONT = 133,
SPELL_FAILED_WRONG_PET_FOOD = 134,
SPELL_FAILED_NOT_WHILE_FATIGUED = 135,
SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 136,
SPELL_FAILED_NOT_WHILE_TRADING = 137,
SPELL_FAILED_TARGET_NOT_IN_RAID = 138,
SPELL_FAILED_TARGET_FREEFORALL = 139,
SPELL_FAILED_NO_EDIBLE_CORPSES = 140,
SPELL_FAILED_ONLY_BATTLEGROUNDS = 141,
SPELL_FAILED_TARGET_NOT_GHOST = 142,
SPELL_FAILED_TRANSFORM_UNUSABLE = 143,
SPELL_FAILED_WRONG_WEATHER = 144,
SPELL_FAILED_DAMAGE_IMMUNE = 145,
SPELL_FAILED_PREVENTED_BY_MECHANIC = 146,
SPELL_FAILED_PLAY_TIME = 147,
SPELL_FAILED_REPUTATION = 148,
SPELL_FAILED_MIN_SKILL = 149,
SPELL_FAILED_NOT_IN_ARENA = 150,
SPELL_FAILED_NOT_ON_SHAPESHIFT = 151,
SPELL_FAILED_NOT_ON_STEALTHED = 152,
SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 153,
SPELL_FAILED_NOT_ON_MOUNTED = 154,
SPELL_FAILED_TOO_SHALLOW = 155,
SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 156,
SPELL_FAILED_TARGET_IS_TRIVIAL = 157,
SPELL_FAILED_BM_OR_INVISGOD = 158,
SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 159,
SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 160,
SPELL_FAILED_NOT_IDLE = 161,
SPELL_FAILED_NOT_INACTIVE = 162,
SPELL_FAILED_PARTIAL_PLAYTIME = 163,
SPELL_FAILED_NO_PLAYTIME = 164,
SPELL_FAILED_NOT_IN_BATTLEGROUND = 165,
SPELL_FAILED_NOT_IN_RAID_INSTANCE = 166,
SPELL_FAILED_ONLY_IN_ARENA = 167,
SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 168,
SPELL_FAILED_ON_USE_ENCHANT = 169,
SPELL_FAILED_NOT_ON_GROUND = 170,
SPELL_FAILED_CUSTOM_ERROR = 171,
SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 172,
SPELL_FAILED_TOO_MANY_SOCKETS = 173,
SPELL_FAILED_INVALID_GLYPH = 174,
SPELL_FAILED_UNIQUE_GLYPH = 175,
SPELL_FAILED_GLYPH_SOCKET_LOCKED = 176,
SPELL_FAILED_NO_VALID_TARGETS = 177,
SPELL_FAILED_ITEM_AT_MAX_CHARGES = 178,
SPELL_FAILED_NOT_IN_BARBERSHOP = 179,
SPELL_FAILED_FISHING_TOO_LOW = 180,
SPELL_FAILED_UNKNOWN = 181,
SPELL_FAILED_AFFECTING_COMBAT = 0x00,
SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 0x01,
SPELL_FAILED_ALREADY_AT_FULL_MANA = 0x02,
SPELL_FAILED_ALREADY_AT_FULL_POWER = 0x03,
SPELL_FAILED_ALREADY_BEING_TAMED = 0x04,
SPELL_FAILED_ALREADY_HAVE_CHARM = 0x05,
SPELL_FAILED_ALREADY_HAVE_SUMMON = 0x06,
SPELL_FAILED_ALREADY_OPEN = 0x07,
SPELL_FAILED_AURA_BOUNCED = 0x08,
SPELL_FAILED_AUTOTRACK_INTERRUPTED = 0x09,
SPELL_FAILED_BAD_IMPLICIT_TARGETS = 0x0A,
SPELL_FAILED_BAD_TARGETS = 0x0B,
SPELL_FAILED_CANT_BE_CHARMED = 0x0C,
SPELL_FAILED_CANT_BE_DISENCHANTED = 0x0D,
SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 0x0E,
SPELL_FAILED_CANT_BE_MILLED = 0x0F,
SPELL_FAILED_CANT_BE_PROSPECTED = 0x10,
SPELL_FAILED_CANT_CAST_ON_TAPPED = 0x11,
SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 0x12,
SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 0x13,
SPELL_FAILED_CANT_STEALTH = 0x14,
SPELL_FAILED_CASTER_AURASTATE = 0x15,
SPELL_FAILED_CASTER_DEAD = 0x16,
SPELL_FAILED_CHARMED = 0x17,
SPELL_FAILED_CHEST_IN_USE = 0x18,
SPELL_FAILED_CONFUSED = 0x19,
SPELL_FAILED_DONT_REPORT = 0x1A,
SPELL_FAILED_EQUIPPED_ITEM = 0x1B,
SPELL_FAILED_EQUIPPED_ITEM_CLASS = 0x1C,
SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 0x1D,
SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 0x1E,
SPELL_FAILED_ERROR = 0x1F,
SPELL_FAILED_FIZZLE = 0x20,
SPELL_FAILED_FLEEING = 0x21,
SPELL_FAILED_FOOD_LOWLEVEL = 0x22,
SPELL_FAILED_HIGHLEVEL = 0x23,
SPELL_FAILED_HUNGER_SATIATED = 0x24,
SPELL_FAILED_IMMUNE = 0x25,
SPELL_FAILED_INCORRECT_AREA = 0x26,
SPELL_FAILED_INTERRUPTED = 0x27,
SPELL_FAILED_INTERRUPTED_COMBAT = 0x28,
SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 0x29,
SPELL_FAILED_ITEM_GONE = 0x2A,
SPELL_FAILED_ITEM_NOT_FOUND = 0x2B,
SPELL_FAILED_ITEM_NOT_READY = 0x2C,
SPELL_FAILED_LEVEL_REQUIREMENT = 0x2D,
SPELL_FAILED_LINE_OF_SIGHT = 0x2E,
SPELL_FAILED_LOWLEVEL = 0x2F,
SPELL_FAILED_LOW_CASTLEVEL = 0x30,
SPELL_FAILED_MAINHAND_EMPTY = 0x31,
SPELL_FAILED_MOVING = 0x32,
SPELL_FAILED_NEED_AMMO = 0x33,
SPELL_FAILED_NEED_AMMO_POUCH = 0x34,
SPELL_FAILED_NEED_EXOTIC_AMMO = 0x35,
SPELL_FAILED_NEED_MORE_ITEMS = 0x36,
SPELL_FAILED_NOPATH = 0x37,
SPELL_FAILED_NOT_BEHIND = 0x38,
SPELL_FAILED_NOT_FISHABLE = 0x39,
SPELL_FAILED_NOT_FLYING = 0x3A,
SPELL_FAILED_NOT_HERE = 0x3B,
SPELL_FAILED_NOT_INFRONT = 0x3C,
SPELL_FAILED_NOT_IN_CONTROL = 0x3D,
SPELL_FAILED_NOT_KNOWN = 0x3E,
SPELL_FAILED_NOT_MOUNTED = 0x3F,
SPELL_FAILED_NOT_ON_TAXI = 0x40,
SPELL_FAILED_NOT_ON_TRANSPORT = 0x41,
SPELL_FAILED_NOT_READY = 0x42,
SPELL_FAILED_NOT_SHAPESHIFT = 0x43,
SPELL_FAILED_NOT_STANDING = 0x44,
SPELL_FAILED_NOT_TRADEABLE = 0x45,
SPELL_FAILED_NOT_TRADING = 0x46,
SPELL_FAILED_NOT_UNSHEATHED = 0x47,
SPELL_FAILED_NOT_WHILE_GHOST = 0x48,
SPELL_FAILED_NOT_WHILE_LOOTING = 0x49,
SPELL_FAILED_NO_AMMO = 0x4A,
SPELL_FAILED_NO_CHARGES_REMAIN = 0x4B,
SPELL_FAILED_NO_CHAMPION = 0x4C,
SPELL_FAILED_NO_COMBO_POINTS = 0x4D,
SPELL_FAILED_NO_DUELING = 0x4E,
SPELL_FAILED_NO_ENDURANCE = 0x4F,
SPELL_FAILED_NO_FISH = 0x50,
SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 0x51,
SPELL_FAILED_NO_MOUNTS_ALLOWED = 0x52,
SPELL_FAILED_NO_PET = 0x53,
SPELL_FAILED_NO_POWER = 0x54,
SPELL_FAILED_NOTHING_TO_DISPEL = 0x55,
SPELL_FAILED_NOTHING_TO_STEAL = 0x56,
SPELL_FAILED_ONLY_ABOVEWATER = 0x57,
SPELL_FAILED_ONLY_DAYTIME = 0x58,
SPELL_FAILED_ONLY_INDOORS = 0x59,
SPELL_FAILED_ONLY_MOUNTED = 0x5A,
SPELL_FAILED_ONLY_NIGHTTIME = 0x5B,
SPELL_FAILED_ONLY_OUTDOORS = 0x5C,
SPELL_FAILED_ONLY_SHAPESHIFT = 0x5D,
SPELL_FAILED_ONLY_STEALTHED = 0x5E,
SPELL_FAILED_ONLY_UNDERWATER = 0x5F,
SPELL_FAILED_OUT_OF_RANGE = 0x60,
SPELL_FAILED_PACIFIED = 0x61,
SPELL_FAILED_POSSESSED = 0x62,
SPELL_FAILED_REAGENTS = 0x63,
SPELL_FAILED_REQUIRES_AREA = 0x64,
SPELL_FAILED_REQUIRES_SPELL_FOCUS = 0x65,
SPELL_FAILED_ROOTED = 0x66,
SPELL_FAILED_SILENCED = 0x67,
SPELL_FAILED_SPELL_IN_PROGRESS = 0x68,
SPELL_FAILED_SPELL_LEARNED = 0x69,
SPELL_FAILED_SPELL_UNAVAILABLE = 0x6A,
SPELL_FAILED_STUNNED = 0x6B,
SPELL_FAILED_TARGETS_DEAD = 0x6C,
SPELL_FAILED_TARGET_AFFECTING_COMBAT = 0x6D,
SPELL_FAILED_TARGET_AURASTATE = 0x6E,
SPELL_FAILED_TARGET_DUELING = 0x6F,
SPELL_FAILED_TARGET_ENEMY = 0x70,
SPELL_FAILED_TARGET_ENRAGED = 0x71,
SPELL_FAILED_TARGET_FRIENDLY = 0x72,
SPELL_FAILED_TARGET_IN_COMBAT = 0x73,
SPELL_FAILED_TARGET_IS_PLAYER = 0x74,
SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 0x75,
SPELL_FAILED_TARGET_NOT_DEAD = 0x76,
SPELL_FAILED_TARGET_NOT_IN_PARTY = 0x77,
SPELL_FAILED_TARGET_NOT_LOOTED = 0x78,
SPELL_FAILED_TARGET_NOT_PLAYER = 0x79,
SPELL_FAILED_TARGET_NO_POCKETS = 0x7A,
SPELL_FAILED_TARGET_NO_WEAPONS = 0x7B,
SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 0x7C,
SPELL_FAILED_TARGET_UNSKINNABLE = 0x7D,
SPELL_FAILED_THIRST_SATIATED = 0x7E,
SPELL_FAILED_TOO_CLOSE = 0x7F,
SPELL_FAILED_TOO_MANY_OF_ITEM = 0x80,
SPELL_FAILED_TOTEM_CATEGORY = 0x81,
SPELL_FAILED_TOTEMS = 0x82,
SPELL_FAILED_TRY_AGAIN = 0x83,
SPELL_FAILED_UNIT_NOT_BEHIND = 0x84,
SPELL_FAILED_UNIT_NOT_INFRONT = 0x85,
SPELL_FAILED_WRONG_PET_FOOD = 0x86,
SPELL_FAILED_NOT_WHILE_FATIGUED = 0x87,
SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 0x88,
SPELL_FAILED_NOT_WHILE_TRADING = 0x89,
SPELL_FAILED_TARGET_NOT_IN_RAID = 0x8A,
SPELL_FAILED_TARGET_FREEFORALL = 0x8B,
SPELL_FAILED_NO_EDIBLE_CORPSES = 0x8C,
SPELL_FAILED_ONLY_BATTLEGROUNDS = 0x8D,
SPELL_FAILED_TARGET_NOT_GHOST = 0x8E,
SPELL_FAILED_TRANSFORM_UNUSABLE = 0x8F,
SPELL_FAILED_WRONG_WEATHER = 0x90,
SPELL_FAILED_DAMAGE_IMMUNE = 0x91,
SPELL_FAILED_PREVENTED_BY_MECHANIC = 0x92,
SPELL_FAILED_PLAY_TIME = 0x93,
SPELL_FAILED_REPUTATION = 0x94,
SPELL_FAILED_MIN_SKILL = 0x95,
SPELL_FAILED_NOT_IN_ARENA = 0x96,
SPELL_FAILED_NOT_ON_SHAPESHIFT = 0x97,
SPELL_FAILED_NOT_ON_STEALTHED = 0x98,
SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 0x99,
SPELL_FAILED_NOT_ON_MOUNTED = 0x9A,
SPELL_FAILED_TOO_SHALLOW = 0x9B,
SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 0x9C,
SPELL_FAILED_TARGET_IS_TRIVIAL = 0x9D,
SPELL_FAILED_BM_OR_INVISGOD = 0x9E,
SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 0x9F,
SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 0xA0,
SPELL_FAILED_NOT_IDLE = 0xA1,
SPELL_FAILED_NOT_INACTIVE = 0xA2,
SPELL_FAILED_PARTIAL_PLAYTIME = 0xA3,
SPELL_FAILED_NO_PLAYTIME = 0xA4,
SPELL_FAILED_NOT_IN_BATTLEGROUND = 0xA5,
SPELL_FAILED_NOT_IN_RAID_INSTANCE = 0xA6,
SPELL_FAILED_ONLY_IN_ARENA = 0xA7,
SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA8,
SPELL_FAILED_ON_USE_ENCHANT = 0xA9,
SPELL_FAILED_NOT_ON_GROUND = 0xAA,
SPELL_FAILED_CUSTOM_ERROR = 0xAB,
SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 0xAC,
SPELL_FAILED_TOO_MANY_SOCKETS = 0xAD,
SPELL_FAILED_INVALID_GLYPH = 0xAE,
SPELL_FAILED_UNIQUE_GLYPH = 0xAF,
SPELL_FAILED_GLYPH_SOCKET_LOCKED = 0xB0,
SPELL_FAILED_NO_VALID_TARGETS = 0xB1,
SPELL_FAILED_ITEM_AT_MAX_CHARGES = 0xB2,
SPELL_FAILED_NOT_IN_BARBERSHOP = 0xB3,
SPELL_FAILED_FISHING_TOO_LOW = 0xB4,
SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW = 0xB5,
SPELL_FAILED_SUMMON_PENDING = 0xB6,
SPELL_FAILED_MAX_SOCKETS = 0xB7,
SPELL_FAILED_PET_CAN_RENAME = 0xB8,
SPELL_FAILED_UNKNOWN = 0xB9,
SPELL_CAST_OK = 255 //custom value, don't must be send to client
SPELL_CAST_OK = 0xFF // custom value, don't must be send to client
};
// Spell aura states
@@ -970,7 +974,13 @@ enum Mechanics
(1<<MECHANIC_SHACKLE )|(1<<MECHANIC_TURN )|(1<<MECHANIC_HORROR)| \
(1<<MECHANIC_DAZE )|(1<<MECHANIC_SAPPED ) )
// Spell dispel type
// Daze and all croud control spells except polymorph are not removed
#define MECHANIC_NOT_REMOVED_BY_SHAPESHIFT ( \
(1<<MECHANIC_CHARM )|(1<<MECHANIC_DISORIENTED)|(1<<MECHANIC_FEAR )|(1<<MECHANIC_PACIFY )| \
(1<<MECHANIC_STUN )|(1<<MECHANIC_FREEZE )|(1<<MECHANIC_BANISH)|(1<<MECHANIC_SHACKLE)| \
(1<<MECHANIC_HORROR)|(1<<MECHANIC_TURN )|(1<<MECHANIC_DAZE )|(1<<MECHANIC_SAPPED ) )
// Spell dispell type
enum DispelType
{
DISPEL_NONE = 0,
+1
View File
@@ -2222,6 +2222,7 @@ void Spell::SetTargetMap(uint32 i, uint32 cur)
case TARGET_UNIT_AREA_ENEMY_DST:
case TARGET_UNIT_CONE_ENEMY:
case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
case TARGET_UNIT_AREA_PATH:
radius = GetSpellRadius(m_spellInfo, i, false);
targetType = SPELL_TARGETS_ENEMY;
break;
+24
View File
@@ -3235,13 +3235,37 @@ void AuraEffect::HandleAuraModShapeshift(bool apply, bool Real, bool changeAmoun
case FORM_FLIGHT_EPIC:
case FORM_FLIGHT:
case FORM_MOONKIN:
{
// remove movement affects
m_target->RemoveMovementImpairingAuras();
/*
m_target->RemoveSpellsCausingAura(SPELL_AURA_MOD_ROOT);
Unit::AuraList const& slowingAuras = m_target->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
for (Unit::AuraList::const_iterator iter = slowingAuras.begin(); iter != slowingAuras.end();)
{
SpellEntry const* aurSpellInfo = (*iter)->GetSpellProto();
// If spell that caused this aura has Croud Control or Daze effect
if((GetAllSpellMechanicMask(aurSpellInfo) & MECHANIC_NOT_REMOVED_BY_SHAPESHIFT) ||
// some Daze spells have these parameters instead of MECHANIC_DAZE
(aurSpellInfo->SpellIconID == 15 && aurSpellInfo->Dispel == 0))
{
++iter;
continue;
}
// All OK, remove aura now
m_target->RemoveAurasDueToSpellByCancel(aurSpellInfo->Id);
iter = slowingAuras.begin();
}
*/
// and polymorphic affects
if(m_target->IsPolymorphed())
m_target->RemoveAurasDueToSpell(m_target->getTransForm());
break;
}
default:
break;
}
+18 -18
View File
@@ -2483,7 +2483,7 @@ void Spell::EffectSendEvent(uint32 EffectIndex)
we do not handle a flag dropping or clicking on flag in battleground by sendevent system
*/
sLog.outDebug("Spell ScriptStart %u for spellid %u in EffectSendEvent ", m_spellInfo->EffectMiscValue[EffectIndex], m_spellInfo->Id);
sWorld.ScriptsStart(sEventScripts, m_spellInfo->EffectMiscValue[EffectIndex], m_caster, focusObject);
m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->EffectMiscValue[EffectIndex], m_caster, focusObject);
}
void Spell::EffectPowerBurn(uint32 i)
@@ -2880,31 +2880,31 @@ void Spell::EffectEnergize(uint32 i)
Powers power = Powers(m_spellInfo->EffectMiscValue[i]);
// Some level depends spells
int multiplier = 0;
int level_multiplier = 0;
int level_diff = 0;
switch (m_spellInfo->Id)
{
// Restore Energy
case 9512:
case 9512: // Restore Energy
level_diff = m_caster->getLevel() - 40;
multiplier = 2;
level_multiplier = 2;
break;
// Blood Fury
case 24571:
case 24571: // Blood Fury
level_diff = m_caster->getLevel() - 60;
multiplier = 10;
level_multiplier = 10;
break;
// Burst of Energy
case 24532:
case 24532: // Burst of Energy
level_diff = m_caster->getLevel() - 60;
multiplier = 4;
level_multiplier = 4;
break;
case 31930: // Judgements of the Wise
case 63375: // Improved Stormstrike
damage = damage * unitTarget->GetCreateMana() / 100;
default:
break;
}
if (level_diff > 0)
damage -= multiplier * level_diff;
damage -= level_multiplier * level_diff;
if(damage < 0)
return;
@@ -2999,7 +2999,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
case GAMEOBJECT_TYPE_DOOR:
case GAMEOBJECT_TYPE_BUTTON:
gameObjTarget->UseDoorOrButton();
sWorld.ScriptsStart(sGameObjectScripts, gameObjTarget->GetDBTableGUIDLow(), player, gameObjTarget);
player->GetMap()->ScriptsStart(sGameObjectScripts, gameObjTarget->GetDBTableGUIDLow(), player, gameObjTarget);
return;
case GAMEOBJECT_TYPE_QUESTGIVER:
@@ -3019,7 +3019,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
if (gameObjTarget->GetGOInfo()->goober.eventId)
{
sLog.outDebug("Goober ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->goober.eventId,gameObjTarget->GetDBTableGUIDLow());
sWorld.ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->goober.eventId, player, gameObjTarget);
player->GetMap()->ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->goober.eventId, player, gameObjTarget);
gameObjTarget->EventInform(gameObjTarget->GetGOInfo()->goober.eventId);
}
@@ -3030,7 +3030,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
return;
Script->GOHello(player, gameObjTarget);
sWorld.ScriptsStart(sGameObjectScripts, gameObjTarget->GetDBTableGUIDLow(), player, gameObjTarget);
gameObjTarget->GetMap()->ScriptsStart(sGameObjectScripts, gameObjTarget->GetDBTableGUIDLow(), player, gameObjTarget);
gameObjTarget->AddUniqueUse(player);
gameObjTarget->SetLootState(GO_JUST_DEACTIVATED);
@@ -3052,7 +3052,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
if (gameObjTarget->GetGOInfo()->chest.eventId)
{
sLog.outDebug("Chest ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->chest.eventId,gameObjTarget->GetDBTableGUIDLow());
sWorld.ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->chest.eventId, player, gameObjTarget);
player->GetMap()->ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->chest.eventId, player, gameObjTarget);
}
// triggering linked GO
@@ -5501,7 +5501,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
// normal DB scripted effect
sLog.outDebug("Spell ScriptStart spellid %u in EffectScriptEffect ", m_spellInfo->Id);
sWorld.ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget);
m_caster->GetMap()->ScriptsStart(sSpellScripts, m_spellInfo->Id, m_caster, unitTarget);
}
void Spell::EffectSanctuary(uint32 /*i*/)
@@ -5703,7 +5703,7 @@ void Spell::EffectActivateObject(uint32 effect_idx)
int32 delay_secs = m_spellInfo->EffectMiscValue[effect_idx];
sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);
gameObjTarget->GetMap()->ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);
}
void Spell::EffectApplyGlyph(uint32 i)
+3
View File
@@ -147,6 +147,7 @@ SpellMgr::SpellMgr()
case TARGET_UNIT_CONE_ALLY:
case TARGET_UNIT_CONE_ENTRY:
case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
case TARGET_UNIT_AREA_PATH:
SpellTargetType[i] = TARGET_TYPE_AREA_CONE;
break;
case TARGET_DST_CASTER:
@@ -226,6 +227,7 @@ SpellMgr::SpellMgr()
case TARGET_UNIT_CONE_ENEMY:
case TARGET_UNIT_CONE_ALLY:
case TARGET_UNIT_CONE_ENEMY_UNKNOWN:
case TARGET_UNIT_AREA_PATH:
case TARGET_UNIT_RAID_CASTER:
IsAreaEffectTarget[i] = true;
break;
@@ -3846,6 +3848,7 @@ void SpellMgr::LoadSpellCustomAttr()
case 40810: case 43267: case 43268: // Saber Lash
case 42384: // Brutal Swipe
case 45150: // Meteor Slash
case 64422: case 64688: // Sonic Screech
mSpellCustomAttr[i] |= SPELL_ATTR_CU_SHARE_DAMAGE;
break;
case 59725: // Improved Spell Reflection - aoe aura
+1 -1
View File
@@ -487,7 +487,7 @@ void Transport::CheckForEvent(uint32 entry, uint32 wp_id)
{
uint32 key = entry*100+wp_id;
if(objmgr.TransportEventMap.find(key) != objmgr.TransportEventMap.end())
sWorld.ScriptsStart(sEventScripts, objmgr.TransportEventMap[key], this, NULL);
GetMap()->ScriptsStart(sEventScripts, objmgr.TransportEventMap[key], this, NULL);
}
void Transport::Update(uint32 /*p_time*/)
+9 -4
View File
@@ -6202,8 +6202,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
// Judgements of the Wise
if (dummySpell->SpellIconID == 3017)
{
// hardcoded amount
basepoints0 = 25 * GetCreatePowers(POWER_MANA)/100;
target = this;
triggered_spell_id = 31930;
// replenishment
@@ -7052,6 +7050,7 @@ bool Unit::HandleObsModEnergyAuraProc(Unit *pVictim, uint32 damage, AuraEffect*
SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id);
// Try handle unknown trigger spells
if(!triggerEntry)
{
sLog.outError("Unit::HandleObsModEnergyAuraProc: Spell %u have not existed triggered spell %u",dummySpell->Id,triggered_spell_id);
@@ -7872,9 +7871,15 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
((Player*)this)->RemoveSpellCategoryCooldown(1209, true);
break;
}
case 63375: // Improved Stormstrike
// Maelstrom Weapon
case 53817:
{
basepoints0 = GetCreateMana() * 0.20f;
// have rank dependent proc chance, ignore too often cases
// PPM = 2.5 * (rank of talent),
uint32 rank = spellmgr.GetSpellRank(auraSpellInfo->Id);
// 5 rank -> 100% 4 rank -> 80% and etc from full rate
if(!roll_chance_i(20*rank))
return false;
break;
}
// Brain Freeze
+1 -1
View File
@@ -198,7 +198,7 @@ WaypointMovementGenerator<Creature>::Update(Creature &unit, const uint32 &diff)
//note: disable "start" for mtmap
if(node->event_id && rand()%100 < node->event_chance)
sWorld.ScriptsStart(sWaypointScripts, node->event_id, &unit, NULL, false);
unit.GetMap()->ScriptsStart(sWaypointScripts, node->event_id, &unit, NULL/*, false*/);
MovementInform(unit);
unit.UpdateWaypointID(i_currentNode);
+20 -861
View File
@@ -63,7 +63,6 @@
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
#include "InstanceSaveMgr.h"
#include "WaypointManager.h"
#include "Util.h"
#include "Language.h"
#include "CreatureGroups.h"
@@ -83,14 +82,6 @@ float World::m_MaxVisibleDistanceInFlight = DEFAULT_VISIBILITY_DISTANCE;
float World::m_VisibleUnitGreyDistance = 0;
float World::m_VisibleObjectGreyDistance = 0;
struct ScriptAction
{
uint64 sourceGUID;
uint64 targetGUID;
uint64 ownerGUID; // owner of source if source is item
ScriptInfo const* script; // pointer to static script data
};
/// World constructor
World::World()
{
@@ -106,6 +97,7 @@ World::World()
m_MaxPlayerCount = 0;
m_resultQueue = NULL;
m_NextDailyQuestReset = 0;
m_scheduledScripts = 0;
m_defaultDbcLocale = LOCALE_enUS;
m_availableDbcLocaleMask = 0;
@@ -268,7 +260,7 @@ World::AddSession_ (WorldSession* s)
float popu = GetActiveSessionCount (); //updated number of users on the server
popu /= pLimit;
popu *= 2;
LoginDatabase.PExecute ("UPDATE realmlist SET population = '%f' WHERE id = '%d'", popu, realmID);
loginDatabase.PExecute ("UPDATE realmlist SET population = '%f' WHERE id = '%d'", popu, realmID);
sLog.outDetail ("Server Population (%f).", popu);
}
}
@@ -1180,7 +1172,7 @@ void World::SetInitialWorldSettings()
// not send custom type REALM_FFA_PVP to realm list
uint32 server_type = IsFFAPvPRealm() ? REALM_TYPE_PVP : getConfig(CONFIG_GAME_TYPE);
uint32 realm_zone = getConfig(CONFIG_REALM_ZONE);
LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID);
loginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID);
///- Remove the bones after a restart
CharacterDatabase.PExecute("DELETE FROM corpse WHERE corpse_type = '0'");
@@ -1535,7 +1527,7 @@ void World::SetInitialWorldSettings()
sprintf( isoDate, "%04d-%02d-%02d %02d:%02d:%02d",
local.tm_year+1900, local.tm_mon+1, local.tm_mday, local.tm_hour, local.tm_min, local.tm_sec);
LoginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, startstring, uptime) VALUES('%u', " UI64FMTD ", '%s', 0)",
loginDatabase.PExecute("INSERT INTO uptime (realmid, starttime, startstring, uptime) VALUES('%u', " UI64FMTD ", '%s', 0)",
realmID, uint64(m_startTime), isoDate);
m_timers[WUPDATE_OBJECTS].SetInterval(IN_MILISECONDS/2);
@@ -1586,7 +1578,7 @@ void World::SetInitialWorldSettings()
objmgr.LoadTransportEvents();
sLog.outString("Deleting expired bans..." );
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
sLog.outString("Calculate next daily quest reset time..." );
InitDailyQuestResetTime();
@@ -1769,7 +1761,7 @@ void World::Update(uint32 diff)
uint32 maxClientsNum = GetMaxActiveSessionCount();
m_timers[WUPDATE_UPTIME].Reset();
LoginDatabase.PExecute("UPDATE uptime SET uptime = %u, maxplayers = %u WHERE realmid = %u AND starttime = " UI64FMTD, tmpDiff, maxClientsNum, realmID, uint64(m_startTime));
loginDatabase.PExecute("UPDATE uptime SET uptime = %u, maxplayers = %u WHERE realmid = %u AND starttime = " UI64FMTD, tmpDiff, maxClientsNum, realmID, uint64(m_startTime));
}
/// <li> Clean logs table
@@ -1781,7 +1773,7 @@ void World::Update(uint32 diff)
uint32 maxClientsNum = sWorld.GetMaxActiveSessionCount();
m_timers[WUPDATE_CLEANDB].Reset();
LoginDatabase.PExecute("DELETE FROM logs WHERE (time + %u) < "UI64FMTD";",
loginDatabase.PExecute("DELETE FROM logs WHERE (time + %u) < "UI64FMTD";",
sWorld.getConfig(CONFIG_LOGDB_CLEARTIME), uint64(time(0)));
}
}
@@ -1796,14 +1788,6 @@ void World::Update(uint32 diff)
MapManager::Instance().DoDelayedMovesAndRemoves();
}*/
///- Process necessary scripts
if (!m_scriptSchedule.empty())
{
RecordTimeDiff(NULL);
ScriptsProcess();
RecordTimeDiff("UpdateScriptsProcess");
}
sBattleGroundMgr.Update(diff);
RecordTimeDiff("UpdateBattleGroundMgr");
@@ -1848,831 +1832,6 @@ void World::ForceGameEventUpdate()
m_timers[WUPDATE_EVENTS].Reset();
}
/// Put scripts in the execution queue
void World::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, Object* target, bool start)
{
///- Find the script map
ScriptMapMap::const_iterator s = scripts.find(id);
if (s == scripts.end())
return;
// prepare static data
uint64 sourceGUID = source ? source->GetGUID() : (uint64)0; //some script commands doesn't have source
uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
uint64 ownerGUID = (source->GetTypeId()==TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
///- Schedule script execution for all scripts in the script map
ScriptMap const *s2 = &(s->second);
bool immedScript = false;
for (ScriptMap::const_iterator iter = s2->begin(); iter != s2->end(); ++iter)
{
ScriptAction sa;
sa.sourceGUID = sourceGUID;
sa.targetGUID = targetGUID;
sa.ownerGUID = ownerGUID;
sa.script = &iter->second;
m_scriptSchedule.insert(std::pair<time_t, ScriptAction>(m_gameTime + iter->first, sa));
if (iter->first == 0)
immedScript = true;
}
///- If one of the effects should be immediate, launch the script execution
if (start && immedScript)
ScriptsProcess();
}
void World::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target)
{
// NOTE: script record _must_ exist until command executed
// prepare static data
uint64 sourceGUID = source ? source->GetGUID() : (uint64)0;
uint64 targetGUID = target ? target->GetGUID() : (uint64)0;
uint64 ownerGUID = (source->GetTypeId()==TYPEID_ITEM) ? ((Item*)source)->GetOwnerGUID() : (uint64)0;
ScriptAction sa;
sa.sourceGUID = sourceGUID;
sa.targetGUID = targetGUID;
sa.ownerGUID = ownerGUID;
sa.script = &script;
m_scriptSchedule.insert(std::pair<time_t, ScriptAction>(m_gameTime + delay, sa));
///- If effects should be immediate, launch the script execution
if(delay == 0)
ScriptsProcess();
}
/// Process queued scripts
void World::ScriptsProcess()
{
if (m_scriptSchedule.empty())
return;
///- Process overdue queued scripts
std::multimap<time_t, ScriptAction>::iterator iter = m_scriptSchedule.begin();
// ok as multimap is a *sorted* associative container
while (!m_scriptSchedule.empty() && (iter->first <= m_gameTime))
{
ScriptAction const& step = iter->second;
Object* source = NULL;
if(step.sourceGUID)
{
switch(GUID_HIPART(step.sourceGUID))
{
case HIGHGUID_ITEM:
// case HIGHGUID_CONTAINER: ==HIGHGUID_ITEM
{
Player* player = HashMapHolder<Player>::Find(step.ownerGUID);
if(player)
source = player->GetItemByGuid(step.sourceGUID);
break;
}
case HIGHGUID_UNIT:
source = HashMapHolder<Creature>::Find(step.sourceGUID);
break;
case HIGHGUID_PET:
source = HashMapHolder<Pet>::Find(step.sourceGUID);
break;
case HIGHGUID_VEHICLE:
source = HashMapHolder<Vehicle>::Find(step.sourceGUID);
break;
case HIGHGUID_PLAYER:
source = HashMapHolder<Player>::Find(step.sourceGUID);
break;
case HIGHGUID_GAMEOBJECT:
source = HashMapHolder<GameObject>::Find(step.sourceGUID);
break;
case HIGHGUID_CORPSE:
source = HashMapHolder<Corpse>::Find(step.sourceGUID);
break;
case HIGHGUID_MO_TRANSPORT:
for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
{
if((*iter)->GetGUID() == step.sourceGUID)
{
source = reinterpret_cast<Object*>(*iter);
break;
}
}
break;
default:
sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.sourceGUID));
break;
}
}
//if(source && !source->IsInWorld()) source = NULL;
Object* target = NULL;
if(step.targetGUID)
{
switch(GUID_HIPART(step.targetGUID))
{
case HIGHGUID_UNIT:
target = HashMapHolder<Creature>::Find(step.targetGUID);
break;
case HIGHGUID_PET:
target = HashMapHolder<Pet>::Find(step.targetGUID);
break;
case HIGHGUID_VEHICLE:
target = HashMapHolder<Vehicle>::Find(step.targetGUID);
break;
case HIGHGUID_PLAYER: // empty GUID case also
target = HashMapHolder<Player>::Find(step.targetGUID);
break;
case HIGHGUID_GAMEOBJECT:
target = HashMapHolder<GameObject>::Find(step.targetGUID);
break;
case HIGHGUID_CORPSE:
target = HashMapHolder<Corpse>::Find(step.targetGUID);
break;
default:
sLog.outError("*_script source with unsupported high guid value %u",GUID_HIPART(step.targetGUID));
break;
}
}
//if(target && !target->IsInWorld()) target = NULL;
switch (step.script->command)
{
case SCRIPT_COMMAND_TALK:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_TALK call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_TALK call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
if(step.script->datalong > 3)
{
sLog.outError("SCRIPT_COMMAND_TALK invalid chat type (%u), skipping.",step.script->datalong);
break;
}
uint64 unit_target = target ? target->GetGUID() : 0;
//datalong 0=normal say, 1=whisper, 2=yell, 3=emote text
switch(step.script->datalong)
{
case 0: // Say
((Creature *)source)->Say(step.script->dataint, LANG_UNIVERSAL, unit_target);
break;
case 1: // Whisper
if(!unit_target)
{
sLog.outError("SCRIPT_COMMAND_TALK attempt to whisper (%u) NULL, skipping.",step.script->datalong);
break;
}
((Creature *)source)->Whisper(step.script->dataint,unit_target);
break;
case 2: // Yell
((Creature *)source)->Yell(step.script->dataint, LANG_UNIVERSAL, unit_target);
break;
case 3: // Emote text
((Creature *)source)->TextEmote(step.script->dataint, unit_target);
break;
default:
break; // must be already checked at load
}
break;
}
case SCRIPT_COMMAND_EMOTE:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_EMOTE call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_EMOTE call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
((Creature *)source)->HandleEmoteCommand(step.script->datalong);
break;
case SCRIPT_COMMAND_FIELD_SET:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FIELD_SET call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FIELD_SET call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->SetUInt32Value(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_MOVE_TO:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_MOVE_TO call for NULL creature.");
break;
}
if(source->GetTypeId()!=TYPEID_UNIT)
{
sLog.outError("SCRIPT_COMMAND_MOVE_TO call for non-creature (TypeId: %u), skipping.",source->GetTypeId());
break;
}
((Creature*)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, step.script->datalong2 );
((Creature*)source)->GetMap()->CreatureRelocation(((Creature*)source), step.script->x, step.script->y, step.script->z, 0);
break;
case SCRIPT_COMMAND_FLAG_SET:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FLAG_SET call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FLAG_SET call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->SetFlag(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_FLAG_REMOVE:
if(!source)
{
sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE call for NULL object.");
break;
}
if(step.script->datalong <= OBJECT_FIELD_ENTRY || step.script->datalong >= source->GetValuesCount())
{
sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE call for wrong field %u (max count: %u) in object (TypeId: %u).",
step.script->datalong,source->GetValuesCount(),source->GetTypeId());
break;
}
source->RemoveFlag(step.script->datalong, step.script->datalong2);
break;
case SCRIPT_COMMAND_TELEPORT_TO:
{
// accept player in any one from target/source arg
if (!target && !source)
{
sLog.outError("SCRIPT_COMMAND_TELEPORT_TO call for NULL object.");
break;
}
// must be only Player
if((!target || target->GetTypeId() != TYPEID_PLAYER) && (!source || source->GetTypeId() != TYPEID_PLAYER))
{
sLog.outError("SCRIPT_COMMAND_TELEPORT_TO call for non-player (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0);
break;
}
Player* pSource = target && target->GetTypeId() == TYPEID_PLAYER ? (Player*)target : (Player*)source;
pSource->TeleportTo(step.script->datalong, step.script->x, step.script->y, step.script->z, step.script->o);
break;
}
case SCRIPT_COMMAND_TEMP_SUMMON_CREATURE:
{
if(!step.script->datalong) // creature not specified
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for NULL creature.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for NULL world object.");
break;
}
WorldObject* summoner = dynamic_cast<WorldObject*>(source);
if(!summoner)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON_CREATURE call for non-WorldObject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
float x = step.script->x;
float y = step.script->y;
float z = step.script->z;
float o = step.script->o;
Creature* pCreature = summoner->SummonCreature(step.script->datalong, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,step.script->datalong2);
if (!pCreature)
{
sLog.outError("SCRIPT_COMMAND_TEMP_SUMMON failed for creature (entry: %u).",step.script->datalong);
break;
}
break;
}
case SCRIPT_COMMAND_RESPAWN_GAMEOBJECT:
{
if(!step.script->datalong) // gameobject not specified
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for NULL gameobject.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for NULL world object.");
break;
}
WorldObject* summoner = dynamic_cast<WorldObject*>(source);
if(!summoner)
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT call for non-WorldObject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
GameObject *go = NULL;
int32 time_to_despawn = step.script->datalong2<5 ? 5 : (int32)step.script->datalong2;
CellPair p(Trinity::ComputeCellPair(summoner->GetPositionX(), summoner->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*summoner,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(summoner, go,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *summoner->GetMap());
if ( !go )
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if( go->GetGoType()==GAMEOBJECT_TYPE_FISHINGNODE ||
go->GetGoType()==GAMEOBJECT_TYPE_DOOR ||
go->GetGoType()==GAMEOBJECT_TYPE_BUTTON ||
go->GetGoType()==GAMEOBJECT_TYPE_TRAP )
{
sLog.outError("SCRIPT_COMMAND_RESPAWN_GAMEOBJECT can not be used with gameobject of type %u (guid: %u).", uint32(go->GetGoType()), step.script->datalong);
break;
}
if( go->isSpawned() )
break; //gameobject already spawned
go->SetLootState(GO_READY);
go->SetRespawnTime(time_to_despawn); //despawn object in ? seconds
go->GetMap()->Add(go);
break;
}
case SCRIPT_COMMAND_OPEN_DOOR:
{
if(!step.script->datalong) // door not specified
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for NULL door.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for NULL unit.");
break;
}
if(!source->isType(TYPEMASK_UNIT)) // must be any Unit (creature or player)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR call for non-unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *door = NULL;
int32 time_to_close = step.script->datalong2 < 15 ? 15 : (int32)step.script->datalong2;
CellPair p(Trinity::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *caster->GetMap());
if (!door)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if (door->GetGoType() != GAMEOBJECT_TYPE_DOOR)
{
sLog.outError("SCRIPT_COMMAND_OPEN_DOOR failed for non-door(GoType: %u).", door->GetGoType());
break;
}
if (door->GetGoState() != GO_STATE_READY)
break; //door already open
door->UseDoorOrButton(time_to_close);
if(target && target->isType(TYPEMASK_GAMEOBJECT) && ((GameObject*)target)->GetGoType()==GAMEOBJECT_TYPE_BUTTON)
((GameObject*)target)->UseDoorOrButton(time_to_close);
break;
}
case SCRIPT_COMMAND_CLOSE_DOOR:
{
if(!step.script->datalong) // guid for door not specified
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for NULL door.");
break;
}
if(!source)
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for NULL unit.");
break;
}
if(!source->isType(TYPEMASK_UNIT)) // must be any Unit (creature or player)
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR call for non-unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *door = NULL;
int32 time_to_open = step.script->datalong2 < 15 ? 15 : (int32)step.script->datalong2;
CellPair p(Trinity::ComputeCellPair(caster->GetPositionX(), caster->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
MaNGOS::GameObjectWithDbGUIDCheck go_check(*caster,step.script->datalong);
MaNGOS::GameObjectSearcher<MaNGOS::GameObjectWithDbGUIDCheck> checker(caster,door,go_check);
TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, object_checker, *caster->GetMap());
if ( !door )
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR failed for gameobject(guid: %u).", step.script->datalong);
break;
}
if ( door->GetGoType() != GAMEOBJECT_TYPE_DOOR )
{
sLog.outError("SCRIPT_COMMAND_CLOSE_DOOR failed for non-door(GoType: %u).", door->GetGoType());
break;
}
if( door->GetGoState() == GO_STATE_READY )
break; //door already closed
door->UseDoorOrButton(time_to_open);
if(target && target->isType(TYPEMASK_GAMEOBJECT) && ((GameObject*)target)->GetGoType()==GAMEOBJECT_TYPE_BUTTON)
((GameObject*)target)->UseDoorOrButton(time_to_open);
break;
}
case SCRIPT_COMMAND_QUEST_EXPLORED:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for NULL source.");
break;
}
if(!target)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for NULL target.");
break;
}
// when script called for item spell casting then target == (unit or GO) and source is player
WorldObject* worldObject;
Player* player;
if(target->GetTypeId()==TYPEID_PLAYER)
{
if(source->GetTypeId()!=TYPEID_UNIT && source->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-creature and non-gameobject (TypeId: %u), skipping.",source->GetTypeId());
break;
}
worldObject = (WorldObject*)source;
player = (Player*)target;
}
else
{
if(target->GetTypeId()!=TYPEID_UNIT && target->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-creature and non-gameobject (TypeId: %u), skipping.",target->GetTypeId());
break;
}
if(source->GetTypeId()!=TYPEID_PLAYER)
{
sLog.outError("SCRIPT_COMMAND_QUEST_EXPLORED call for non-player(TypeId: %u), skipping.",source->GetTypeId());
break;
}
worldObject = (WorldObject*)target;
player = (Player*)source;
}
// quest id and flags checked at script loading
if( (worldObject->GetTypeId()!=TYPEID_UNIT || ((Unit*)worldObject)->isAlive()) &&
(step.script->datalong2==0 || worldObject->IsWithinDistInMap(player,float(step.script->datalong2))) )
player->AreaExploredOrEventHappens(step.script->datalong);
else
player->FailQuest(step.script->datalong);
break;
}
case SCRIPT_COMMAND_ACTIVATE_OBJECT:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT must have source caster.");
break;
}
if(!source->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT source caster isn't unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
if(!target)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT call for NULL gameobject.");
break;
}
if(target->GetTypeId()!=TYPEID_GAMEOBJECT)
{
sLog.outError("SCRIPT_COMMAND_ACTIVATE_OBJECT call for non-gameobject (TypeId: %u), skipping.",target->GetTypeId());
break;
}
Unit* caster = (Unit*)source;
GameObject *go = (GameObject*)target;
go->Use(caster);
break;
}
case SCRIPT_COMMAND_REMOVE_AURA:
{
Object* cmdTarget = step.script->datalong2 ? source : target;
if(!cmdTarget)
{
sLog.outError("SCRIPT_COMMAND_REMOVE_AURA call for NULL %s.",step.script->datalong2 ? "source" : "target");
break;
}
if(!cmdTarget->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_REMOVE_AURA %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 ? "source" : "target",cmdTarget->GetTypeId());
break;
}
((Unit*)cmdTarget)->RemoveAurasDueToSpell(step.script->datalong);
break;
}
case SCRIPT_COMMAND_CAST_SPELL:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL must have source caster.");
break;
}
Object* cmdTarget = step.script->datalong2 & 0x01 ? source : target;
if(!cmdTarget)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 & 0x01 ? "source" : "target");
break;
}
if(!cmdTarget->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 & 0x01 ? "source" : "target",cmdTarget->GetTypeId());
break;
}
Unit* spellTarget = (Unit*)cmdTarget;
Object* cmdSource = step.script->datalong2 & 0x02 ? target : source;
if(!cmdSource)
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL call for NULL %s.",step.script->datalong2 & 0x02 ? "target" : "source");
break;
}
if(!cmdSource->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_CAST_SPELL %s isn't unit (TypeId: %u), skipping.",step.script->datalong2 & 0x02 ? "target" : "source", cmdSource->GetTypeId());
break;
}
Unit* spellSource = (Unit*)cmdSource;
//TODO: when GO cast implemented, code below must be updated accordingly to also allow GO spell cast
spellSource->CastSpell(spellTarget,step.script->datalong,false);
break;
}
case SCRIPT_COMMAND_LOAD_PATH:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_START_MOVE is tried to apply to NON-existing unit.");
break;
}
if(!source->isType(TYPEMASK_UNIT))
{
sLog.outError("SCRIPT_COMMAND_START_MOVE source mover isn't unit (TypeId: %u), skipping.",source->GetTypeId());
break;
}
if(!WaypointMgr.GetPath(step.script->datalong))
{
sLog.outError("SCRIPT_COMMAND_START_MOVE source mover has an invallid path, skipping.", step.script->datalong2);
break;
}
dynamic_cast<Unit*>(source)->GetMotionMaster()->MovePath(step.script->datalong, step.script->datalong2);
break;
}
case SCRIPT_COMMAND_CALLSCRIPT_TO_UNIT:
{
if(!step.script->datalong || !step.script->datalong2)
{
sLog.outError("SCRIPT_COMMAND_CALLSCRIPT calls invallid db_script_id or lowguid not present: skipping.");
break;
}
//our target
Creature* target = NULL;
if(source) //using grid searcher
{
CellPair p(Trinity::ComputeCellPair(((Unit*)source)->GetPositionX(), ((Unit*)source)->GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
//sLog.outDebug("Attempting to find Creature: Db GUID: %i", step.script->datalong);
Trinity::CreatureWithDbGUIDCheck target_check(((Unit*)source), step.script->datalong);
Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(((Unit*)source), target, target_check);
TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker);
CellLock<GridReadGuard> cell_lock(cell, p);
cell_lock->Visit(cell_lock, unit_checker, *(((Unit*)source)->GetMap()));
}
else //check hashmap holders
{
if(CreatureData const* data = objmgr.GetCreatureData(step.script->datalong))
target = ObjectAccessor::GetObjectInWorld<Creature>(data->mapid, data->posX, data->posY, MAKE_NEW_GUID(step.script->datalong, data->id, HIGHGUID_UNIT), target);
}
//sLog.outDebug("attempting to pass target...");
if(!target)
break;
//sLog.outDebug("target passed");
//Lets choose our ScriptMap map
ScriptMapMap *datamap = NULL;
switch(step.script->dataint)
{
case 1://QUEST END SCRIPTMAP
datamap = &sQuestEndScripts;
break;
case 2://QUEST START SCRIPTMAP
datamap = &sQuestStartScripts;
break;
case 3://SPELLS SCRIPTMAP
datamap = &sSpellScripts;
break;
case 4://GAMEOBJECTS SCRIPTMAP
datamap = &sGameObjectScripts;
break;
case 5://EVENTS SCRIPTMAP
datamap = &sEventScripts;
break;
case 6://WAYPOINTS SCRIPTMAP
datamap = &sWaypointScripts;
break;
default:
sLog.outError("SCRIPT_COMMAND_CALLSCRIPT ERROR: no scriptmap present... ignoring");
break;
}
//if no scriptmap present...
if(!datamap)
break;
uint32 script_id = step.script->datalong2;
//insert script into schedule but do not start it
ScriptsStart(*datamap, script_id, target, NULL, false);
break;
}
case SCRIPT_COMMAND_KILL:
{
if(!source || ((Creature*)source)->isDead())
break;
((Creature*)source)->DealDamage(((Creature*)source), ((Creature*)source)->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
switch(step.script->dataint)
{
case 0: break; //return false not remove corpse
case 1: ((Creature*)source)->RemoveCorpse(); break;
}
break;
}
case SCRIPT_COMMAND_PLAY_SOUND:
{
if(!source)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND call for NULL creature.");
break;
}
WorldObject* pSource = dynamic_cast<WorldObject*>(source);
if(!pSource)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND call for non-world object (TypeId: %u), skipping.",source->GetTypeId());
break;
}
// bitmask: 0/1=anyone/target, 0/2=with distance dependent
Player* pTarget = NULL;
if(step.script->datalong2 & 1)
{
if(!target)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND in targeted mode call for NULL target.");
break;
}
if(target->GetTypeId()!=TYPEID_PLAYER)
{
sLog.outError("SCRIPT_COMMAND_PLAY_SOUND in targeted mode call for non-player (TypeId: %u), skipping.",target->GetTypeId());
break;
}
pTarget = (Player*)target;
}
// bitmask: 0/1=anyone/target, 0/2=with distance dependent
if(step.script->datalong2 & 2)
pSource->PlayDistanceSound(step.script->datalong,pTarget);
else
pSource->PlayDirectSound(step.script->datalong,pTarget);
break;
}
default:
sLog.outError("Unknown script command %u called.",step.script->command);
break;
}
m_scriptSchedule.erase(iter);
iter = m_scriptSchedule.begin();
}
return;
}
/// Send a packet to all players (except self if mentioned)
void World::SendGlobalMessage(WorldPacket *packet, WorldSession *self, uint32 team)
{
@@ -2872,10 +2031,10 @@ void World::KickAllLess(AccountTypes sec)
/// Ban an account or ban an IP address, duration will be parsed using TimeStringToSecs if it is positive, otherwise permban
BanReturn World::BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author)
{
LoginDatabase.escape_string(nameOrIP);
LoginDatabase.escape_string(reason);
loginDatabase.escape_string(nameOrIP);
loginDatabase.escape_string(reason);
std::string safe_author=author;
LoginDatabase.escape_string(safe_author);
loginDatabase.escape_string(safe_author);
uint32 duration_secs = TimeStringToSecs(duration);
QueryResult *resultAccounts = NULL; //used for kicking
@@ -2885,12 +2044,12 @@ BanReturn World::BanAccount(BanMode mode, std::string nameOrIP, std::string dura
{
case BAN_IP:
//No SQL injection as strings are escaped
resultAccounts = LoginDatabase.PQuery("SELECT id FROM account WHERE last_ip = '%s'",nameOrIP.c_str());
LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+%u,'%s','%s')",nameOrIP.c_str(),duration_secs,safe_author.c_str(),reason.c_str());
resultAccounts = loginDatabase.PQuery("SELECT id FROM account WHERE last_ip = '%s'",nameOrIP.c_str());
loginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+%u,'%s','%s')",nameOrIP.c_str(),duration_secs,safe_author.c_str(),reason.c_str());
break;
case BAN_ACCOUNT:
//No SQL injection as string is escaped
resultAccounts = LoginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'",nameOrIP.c_str());
resultAccounts = loginDatabase.PQuery("SELECT id FROM account WHERE username = '%s'",nameOrIP.c_str());
break;
case BAN_CHARACTER:
//No SQL injection as string is escaped
@@ -2917,7 +2076,7 @@ BanReturn World::BanAccount(BanMode mode, std::string nameOrIP, std::string dura
if(mode!=BAN_IP)
{
//No SQL injection as strings are escaped
LoginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+%u, '%s', '%s', '1')",
loginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u', UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+%u, '%s', '%s', '1')",
account,duration_secs,safe_author.c_str(),reason.c_str());
}
@@ -2936,8 +2095,8 @@ bool World::RemoveBanAccount(BanMode mode, std::string nameOrIP)
{
if (mode == BAN_IP)
{
LoginDatabase.escape_string(nameOrIP);
LoginDatabase.PExecute("DELETE FROM ip_banned WHERE ip = '%s'",nameOrIP.c_str());
loginDatabase.escape_string(nameOrIP);
loginDatabase.PExecute("DELETE FROM ip_banned WHERE ip = '%s'",nameOrIP.c_str());
}
else
{
@@ -2951,7 +2110,7 @@ bool World::RemoveBanAccount(BanMode mode, std::string nameOrIP)
return false;
//NO SQL injection as account is uint32
LoginDatabase.PExecute("UPDATE account_banned SET active = '0' WHERE id = '%u'",account);
loginDatabase.PExecute("UPDATE account_banned SET active = '0' WHERE id = '%u'",account);
}
return true;
}
@@ -3149,8 +2308,8 @@ void World::_UpdateRealmCharCount(QueryResult *resultCharCount, uint32 accountId
Field *fields = resultCharCount->Fetch();
uint32 charCount = fields[0].GetUInt32();
delete resultCharCount;
LoginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", accountId, realmID);
LoginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)", charCount, accountId, realmID);
loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", accountId, realmID);
loginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)", charCount, accountId, realmID);
}
}
@@ -3213,7 +2372,7 @@ void World::SetPlayerLimit( int32 limit, bool needUpdate )
m_playerLimit = limit;
if(db_update_need)
LoginDatabase.PExecute("UPDATE realmlist SET allowedSecurityLevel = '%u' WHERE id = '%d'",uint8(GetPlayerSecurityLimit()),realmID);
loginDatabase.PExecute("UPDATE realmlist SET allowedSecurityLevel = '%u' WHERE id = '%d'",uint8(GetPlayerSecurityLimit()),realmID);
}
void World::UpdateMaxSessionCounters()
+8 -6
View File
@@ -29,6 +29,7 @@
#include "Timer.h"
#include "Policies/Singleton.h"
#include "SharedDefines.h"
#include "ace/Atomic_Op.h"
#include <map>
#include <set>
@@ -553,9 +554,10 @@ class World
BanReturn BanAccount(BanMode mode, std::string nameOrIP, std::string duration, std::string reason, std::string author);
bool RemoveBanAccount(BanMode mode, std::string nameOrIP);
void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo> > const& scripts, uint32 id, Object* source, Object* target, bool start = true);
void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
bool IsScriptScheduled() const { return !m_scriptSchedule.empty(); }
uint32 IncreaseScheduledScriptsCount() { return (uint32)++m_scheduledScripts; }
uint32 DecreaseScheduledScriptCount() { return (uint32)--m_scheduledScripts; }
uint32 DecreaseScheduledScriptCount(size_t count) { return (uint32)(m_scheduledScripts -= count); }
bool IsScriptScheduled() const { return m_scheduledScripts > 0; }
bool IsAllowedMap(uint32 mapid) { return m_forbiddenMapIds.count(mapid) == 0 ;}
@@ -592,7 +594,6 @@ class World
void RecordTimeDiff(const char * text, ...);
protected:
void _UpdateGameTime();
void ScriptsProcess();
// callback for UpdateRealmCharacters
void _UpdateRealmCharCount(QueryResult *resultCharCount, uint32 accountId);
@@ -606,6 +607,9 @@ class World
bool m_isClosed;
//atomic op counter for active scripts amount
ACE_Atomic_Op<ACE_Thread_Mutex, long> m_scheduledScripts;
time_t m_startTime;
time_t m_gameTime;
IntervalTimer m_timers[WUPDATE_COUNT];
@@ -626,8 +630,6 @@ class World
uint32 m_PlayerCount;
uint32 m_MaxPlayerCount;
std::multimap<time_t, ScriptAction> m_scriptSchedule;
std::string m_newCharString;
float rate_values[MAX_RATES];
+2 -2
View File
@@ -53,7 +53,7 @@ m_latency(0), m_TutorialsChanged(false)
{
m_Address = sock->GetRemoteAddress ();
sock->AddReference ();
LoginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId());
loginDatabase.PExecute("UPDATE account SET online = 1 WHERE id = %u;", GetAccountId());
}
}
@@ -78,7 +78,7 @@ WorldSession::~WorldSession()
WorldPacket *packet = _recvQueue.next ();
delete packet;
}
LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = %u;", GetAccountId());
loginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = %u;", GetAccountId());
CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = %u;", GetAccountId());
}
+10 -9
View File
@@ -678,7 +678,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
BigNumber K;
if (recvPacket.size () < (4 + 4 + 1 + 4 + 20))
if (recvPacket.size () < (4 + 4 + 1 + 4 + 4 + 20))
{
sLog.outError ("WorldSocket::HandleAuthSession: wrong packet size");
return -1;
@@ -700,7 +700,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
recvPacket >> account;
recvPacket >> unk3;
if (recvPacket.size () < (4 + 4 + (account.size () + 1) + 4 + 20))
if (recvPacket.size () < (4 + 4 + (account.size () + 1) + 4 + 4 + 20))
{
sLog.outError ("WorldSocket::HandleAuthSession: wrong packet size second check");
return -1;
@@ -709,19 +709,20 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
recvPacket >> clientSeed;
recvPacket.read (digest, 20);
DEBUG_LOG ("WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, clientseed %u",
DEBUG_LOG ("WorldSocket::HandleAuthSession: client %u, unk2 %u, account %s, unk3 %u, clientseed %u",
BuiltNumberClient,
unk2,
account.c_str (),
unk3,
clientSeed);
// Get the account information from the realmd database
std::string safe_account = account; // Duplicate, else will screw the SHA hash verification below
LoginDatabase.escape_string (safe_account);
loginDatabase.escape_string (safe_account);
// No SQL injection, username escaped.
QueryResult *result =
LoginDatabase.PQuery ("SELECT "
loginDatabase.PQuery ("SELECT "
"id, " //0
"gmlevel, " //1
"sessionkey, " //2
@@ -786,7 +787,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
vold,
vStr);
LoginDatabase.PExecute ("UPDATE account "
loginDatabase.PExecute ("UPDATE account "
"SET "
"v = '0', "
"s = '0' "
@@ -843,7 +844,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
// Re-check account ban (same check as in realmd)
QueryResult *banresult =
LoginDatabase.PQuery ("SELECT "
loginDatabase.PQuery ("SELECT "
"bandate, "
"unbandate "
"FROM account_banned "
@@ -909,9 +910,9 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)
// Update the last_ip in the database
// No SQL injection, username escaped.
LoginDatabase.escape_string (address);
loginDatabase.escape_string (address);
LoginDatabase.PExecute ("UPDATE account "
loginDatabase.PExecute ("UPDATE account "
"SET last_ip = '%s' "
"WHERE username = '%s'",
address.c_str (),
+1 -1
View File
@@ -50,7 +50,7 @@ typedef DatabaseMysql DatabaseType;
extern DatabaseType WorldDatabase;
extern DatabaseType CharacterDatabase;
extern DatabaseType LoginDatabase;
extern DatabaseType loginDatabase;
#endif
+2 -2
View File
@@ -359,9 +359,9 @@ void Log::outDB( LogTypes type, const char * str )
std::string new_str(str);
if (new_str.empty())
return;
LoginDatabase.escape_string(new_str);
loginDatabase.escape_string(new_str);
LoginDatabase.PExecute("INSERT INTO logs (time, realm, type, string) "
loginDatabase.PExecute("INSERT INTO logs (time, realm, type, string) "
"VALUES (" UI64FMTD ", %u, %u, '%s');", uint64(time(0)), realm, type, new_str.c_str());
}
+1 -1
View File
@@ -446,7 +446,7 @@ namespace VMAP
//=========================================================
/**
get height or INVALID_HEIGHT if to hight was calculated
get height or INVALID_HEIGHT if to height was calculated
*/
//int gGetHeightCounter = 0;
+2 -2
View File
@@ -19,12 +19,12 @@
## CPP flags for includes, defines, etc.
AM_CPPFLAGS = -I$(srcdir)
## Build world list daemon as standalone program
## Build as standalone program
bin_PROGRAMS = genrevision
genrevision_SOURCES = \
genrevision.cpp
## Link world daemon against the shared library
## Link against the shared library
genrevision_LDADD =
genrevision_LDFLAGS = -L$(libdir)
+1 -1
View File
@@ -239,7 +239,7 @@ bool ChatHandler::HandleAccountOnlineListCommand(const char* /*args*/)
///- Get the username, last IP and GM level of each account
// No SQL injection. account is uint32.
// 0 1 2 3
QueryResult *resultLogin = LoginDatabase.PQuery("SELECT username, last_ip, gmlevel, expansion FROM account WHERE id = '%u'",account);
QueryResult *resultLogin = loginDatabase.PQuery("SELECT username, last_ip, gmlevel, expansion FROM account WHERE id = '%u'",account);
if(resultLogin)
{
+1 -1
View File
@@ -59,7 +59,7 @@ int m_ServiceStatus = -1;
DatabaseType WorldDatabase; ///< Accessor to the world database
DatabaseType CharacterDatabase; ///< Accessor to the character database
DatabaseType LoginDatabase; ///< Accessor to the realm/login database
DatabaseType loginDatabase; ///< Accessor to the realm/login database
uint32 realmID; ///< Id of the realm
+7 -7
View File
@@ -136,7 +136,7 @@ public:
loopCounter = 0;
sLog.outDetail ("Ping MySQL to keep connection alive");
delete WorldDatabase.Query ("SELECT 1 FROM command LIMIT 1");
delete LoginDatabase.Query ("SELECT 1 FROM realmlist LIMIT 1");
delete loginDatabase.Query ("SELECT 1 FROM realmlist LIMIT 1");
delete CharacterDatabase.Query ("SELECT 1 FROM bugreport LIMIT 1");
}
}
@@ -242,7 +242,7 @@ int Master::Run()
t.setPriority ((ACE_Based::Priority )2);
// set server online
LoginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID);
loginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID);
#ifdef WIN32
if (sConfig.GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/)
@@ -333,7 +333,7 @@ int Master::Run()
sWorldSocketMgr->Wait ();
// set server offline
LoginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID);
loginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID);
///- Remove signal handling before leaving
_UnhookSignals();
@@ -349,7 +349,7 @@ int Master::Run()
///- Wait for delay threads to end
CharacterDatabase.HaltDelayThread();
WorldDatabase.HaltDelayThread();
LoginDatabase.HaltDelayThread();
loginDatabase.HaltDelayThread();
sLog.outString( "Halting process..." );
@@ -438,7 +438,7 @@ bool Master::_StartDB()
}
///- Get login database info from configuration file
dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", "");
dbstring = sConfig.GetStringDefault("loginDatabaseInfo", "");
if(dbstring.empty())
{
sLog.outError("Login database not specified in configuration file");
@@ -446,7 +446,7 @@ bool Master::_StartDB()
}
///- Initialise the login database
if(!LoginDatabase.Initialize(dbstring.c_str()))
if(!loginDatabase.Initialize(dbstring.c_str()))
{
sLog.outError("Cannot connect to login database %s",dbstring.c_str());
return false;
@@ -494,7 +494,7 @@ void Master::clearOnlineAccounts()
{
// Cleanup online status for characters hosted at current realm
/// \todo Only accounts with characters logged on *this* realm should have online status reset. Move the online column from 'account' to 'realmcharacters'?
LoginDatabase.PExecute(
loginDatabase.PExecute(
"UPDATE account SET online = 0 WHERE online > 0 "
"AND id IN (SELECT acctid FROM realmcharacters WHERE realmid = '%d')",realmID);
+5 -5
View File
@@ -152,9 +152,9 @@ void RASocket::OnRead()
AccountMgr::normalizeString(login);
///- Escape the Login to allow quotes in names
LoginDatabase.escape_string(login);
loginDatabase.escape_string(login);
QueryResult* result = LoginDatabase.PQuery("SELECT gmlevel FROM account WHERE username = '%s'",login.c_str());
QueryResult* result = loginDatabase.PQuery("SELECT gmlevel FROM account WHERE username = '%s'",login.c_str());
///- If the user is not found, deny access
if(!result)
@@ -193,10 +193,10 @@ void RASocket::OnRead()
AccountMgr::normalizeString(login);
AccountMgr::normalizeString(pw);
LoginDatabase.escape_string(login);
LoginDatabase.escape_string(pw);
loginDatabase.escape_string(login);
loginDatabase.escape_string(pw);
QueryResult *check = LoginDatabase.PQuery(
QueryResult *check = loginDatabase.PQuery(
"SELECT 1 FROM account WHERE username = '%s' AND sha_pass_hash=SHA1(CONCAT('%s',':','%s'))",
login.c_str(), login.c_str(), pw.c_str());
+2 -2
View File
@@ -50,7 +50,7 @@ void WorldRunnable::run()
///- Init new SQL thread for the world database
WorldDatabase.ThreadStart(); // let thread do safe mySQL requests (one connection call enough)
CharacterDatabase.ThreadStart();
LoginDatabase.ThreadStart();
loginDatabase.ThreadStart();
sWorld.InitResultQueue();
uint32 realCurrTime = 0;
@@ -100,5 +100,5 @@ void WorldRunnable::run()
///- End the database thread
WorldDatabase.ThreadEnd(); // free mySQL thread resources
CharacterDatabase.ThreadStart();
LoginDatabase.ThreadEnd();
loginDatabase.ThreadEnd();
}
+1 -1
View File
@@ -70,6 +70,6 @@ enum LoginResult
// others will not and opposite
// will only support WoW, WoW:TBC and WoW:WotLK 3.1.3 client build 9947...
#define EXPECTED_TRINITY_CLIENT_BUILD {9947, 0}
#define EXPECTED_MANGOS_CLIENT_BUILD {9947, 0}
#endif
+117 -101
View File
@@ -36,7 +36,7 @@
extern RealmList m_realmList;
extern DatabaseType LoginDatabase;
extern DatabaseType loginDatabase;
#define ChunkSize 2048
@@ -112,7 +112,7 @@ typedef struct AUTH_LOGON_PROOF_C
uint8 M1[20];
uint8 crc_hash[20];
uint8 number_of_keys;
uint8 unk; // Added in 1.12.x client branch
uint8 securityFlags; // 0x00-0x04
} sAuthLogonProof_C;
/*
typedef struct
@@ -264,17 +264,11 @@ void AuthSocket::OnRead()
///- Get the command out of it
ibuf.SoftRead((char *)&_cmd, 1); // UQ1: No longer exists in new net code ???
//ibuf.Read((char *)&_cmd, 1);
/*char *command = (char *)malloc(1);
ibuf.Read(command, 1);
_cmd = (uint8)command;*/
// assert(0);
size_t i;
///- Circle through known commands and call the correct command handler
for (i=0;i<AUTH_TOTAL_COMMANDS; i++)
for (i = 0; i < AUTH_TOTAL_COMMANDS; ++i)
{
if ((uint8)table[i].cmd == _cmd &&
(table[i].status == STATUS_CONNECTED ||
@@ -292,7 +286,7 @@ void AuthSocket::OnRead()
}
///- Report unknown commands in the debug log
if (i==AUTH_TOTAL_COMMANDS)
if (i == AUTH_TOTAL_COMMANDS)
{
DEBUG_LOG("[Auth] got unknown packet %u", (uint32)_cmd);
return;
@@ -306,13 +300,13 @@ void AuthSocket::_SetVSFields(const std::string& rI)
BigNumber I;
I.SetHexStr(rI.c_str());
//In case of leading zeroes in the rI hash, restore them
// In case of leading zeros in the rI hash, restore them
uint8 mDigest[SHA_DIGEST_LENGTH];
memset(mDigest,0,SHA_DIGEST_LENGTH);
memset(mDigest, 0, SHA_DIGEST_LENGTH);
if (I.GetNumBytes() <= SHA_DIGEST_LENGTH)
memcpy(mDigest,I.AsByteArray(),I.GetNumBytes());
memcpy(mDigest, I.AsByteArray(), I.GetNumBytes());
std::reverse(mDigest,mDigest+SHA_DIGEST_LENGTH);
std::reverse(mDigest, mDigest + SHA_DIGEST_LENGTH);
Sha1Hash sha;
sha.UpdateData(s.AsByteArray(), s.GetNumBytes());
@@ -325,7 +319,7 @@ void AuthSocket::_SetVSFields(const std::string& rI)
const char *v_hex, *s_hex;
v_hex = v.AsHexStr();
s_hex = s.AsHexStr();
LoginDatabase.PExecute("UPDATE account SET v = '%s', s = '%s' WHERE username = '%s'",v_hex,s_hex, _safelogin.c_str() );
loginDatabase.PExecute("UPDATE account SET v = '%s', s = '%s' WHERE username = '%s'", v_hex, s_hex, _safelogin.c_str() );
OPENSSL_free((void*)v_hex);
OPENSSL_free((void*)s_hex);
}
@@ -380,19 +374,19 @@ bool AuthSocket::_HandleLogonChallenge()
//Escape the user login to avoid further SQL injection
//Memory will be freed on AuthSocket object destruction
_safelogin=_login;
LoginDatabase.escape_string(_safelogin);
_safelogin = _login;
loginDatabase.escape_string(_safelogin);
pkt << (uint8) AUTH_LOGON_CHALLENGE;
pkt << (uint8) 0x00;
///- Verify that this IP is not in the ip_banned table
// No SQL injection possible (paste the IP address as passed by the socket)
LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
loginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
std::string address = GetRemoteAddress();
LoginDatabase.escape_string(address);
QueryResult *result = LoginDatabase.PQuery( "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str());
loginDatabase.escape_string(address);
QueryResult *result = loginDatabase.PQuery( "SELECT * FROM ip_banned WHERE ip = '%s'",address.c_str());
if(result)
{
pkt << (uint8)REALM_AUTH_ACCOUNT_BANNED;
@@ -404,7 +398,7 @@ bool AuthSocket::_HandleLogonChallenge()
///- Get the account details from the account table
// No SQL injection (escaped user name)
result = LoginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ());
result = loginDatabase.PQuery("SELECT sha_pass_hash,id,locked,last_ip,gmlevel FROM account WHERE username = '%s'",_safelogin.c_str ());
if( result )
{
///- If the IP is 'locked', check that the player comes indeed from the correct IP address
@@ -432,9 +426,9 @@ bool AuthSocket::_HandleLogonChallenge()
if (!locked)
{
//set expired bans to inactive
LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
loginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate");
///- If the account is banned, reject the logon attempt
QueryResult *banresult = LoginDatabase.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32());
QueryResult *banresult = loginDatabase.PQuery("SELECT bandate,unbandate FROM account_banned WHERE id = %u AND active = 1", (*result)[1].GetUInt32());
if(banresult)
{
if((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64())
@@ -457,35 +451,56 @@ bool AuthSocket::_HandleLogonChallenge()
_SetVSFields(rI);
b.SetRand(19 * 8);
BigNumber gmod=g.ModExp(b, N);
BigNumber gmod = g.ModExp(b, N);
B = ((v * 3) + gmod) % N;
ASSERT(gmod.GetNumBytes() <= 32);
BigNumber unk3;
unk3.SetRand(16*8);
unk3.SetRand(16 * 8);
///- Fill the response packet with the result
pkt << (uint8)REALM_AUTH_SUCCESS;
pkt << uint8(REALM_AUTH_SUCCESS);
// B may be calculated < 32B so we force minnimal length to 32B
pkt.append(B.AsByteArray(32), 32); // 32 bytes
pkt << (uint8)1;
// B may be calculated < 32B so we force minimal length to 32B
pkt.append(B.AsByteArray(32), 32); // 32 bytes
pkt << uint8(1);
pkt.append(g.AsByteArray(), 1);
pkt << (uint8)32;
pkt << uint8(32);
pkt.append(N.AsByteArray(), 32);
pkt.append(s.AsByteArray(), s.GetNumBytes()); // 32 bytes
pkt.append(unk3.AsByteArray(), 16);
pkt << (uint8)0; // Added in 1.12.x client branch
uint8 securityFlags = 0;
pkt << uint8(securityFlags); // security flags (0x0...0x04)
if(securityFlags & 0x01) // PIN input
{
pkt << uint32(0);
pkt << uint64(0) << uint64(0); // 16 bytes hash?
}
if(securityFlags & 0x02) // Matrix input
{
pkt << uint8(0);
pkt << uint8(0);
pkt << uint8(0);
pkt << uint8(0);
pkt << uint64(0);
}
if(securityFlags & 0x04) // Security token input
{
pkt << uint8(1);
}
uint8 secLevel = (*result)[4].GetUInt8();
_accountSecurityLevel = secLevel <= SEC_ADMINISTRATOR ? AccountTypes(secLevel) : SEC_ADMINISTRATOR;
_localizationName.resize(4);
for(int i = 0; i <4; ++i)
for(int i = 0; i < 4; ++i)
_localizationName[i] = ch->country[4-i-1];
sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3],ch->country[2],ch->country[1],ch->country[0], GetLocaleByName(_localizationName));
sLog.outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName));
}
}
delete result;
@@ -510,13 +525,13 @@ bool AuthSocket::_HandleLogonProof()
ibuf.Read((char *)&lp, sizeof(sAuthLogonProof_C));
///- Check if the client has one of the expected version numbers
bool valid_version=false;
int accepted_versions[]=EXPECTED_TRINITY_CLIENT_BUILD;
for(int i=0;accepted_versions[i];i++)
bool valid_version = false;
int accepted_versions[] = EXPECTED_MANGOS_CLIENT_BUILD;
for(int i = 0; accepted_versions[i]; ++i)
{
if(_build==accepted_versions[i])
if(_build == accepted_versions[i])
{
valid_version=true;
valid_version = true;
break;
}
}
@@ -529,9 +544,9 @@ bool AuthSocket::_HandleLogonProof()
// 24 = len("./patches/65535enGB.mpq")+1
char tmp[24];
// No buffer overflow (fixed length of arguments)
sprintf(tmp,"./patches/%d%s.mpq",_build, _localizationName.c_str());
// This will be closed at the destruction of the AuthSocket (client deconnection)
FILE *pFile=fopen(tmp,"rb");
sprintf(tmp, "./patches/%d%s.mpq", _build, _localizationName.c_str());
// This will be closed at the destruction of the AuthSocket (client disconnection)
FILE *pFile = fopen(tmp, "rb");
if(!pFile)
{
@@ -540,37 +555,37 @@ bool AuthSocket::_HandleLogonProof()
pkt << (uint8) 0x00;
pkt << (uint8) REALM_AUTH_WRONG_BUILD_NUMBER;
DEBUG_LOG("[AuthChallenge] %u is not a valid client version!", _build);
DEBUG_LOG("[AuthChallenge] Patch %s not found",tmp);
DEBUG_LOG("[AuthChallenge] Patch %s not found", tmp);
SendBuf((char const*)pkt.contents(), pkt.size());
return true;
}
else // have patch
{
pPatch=pFile;
pPatch = pFile;
XFER_INIT xferh;
///- Get the MD5 hash of the patch file (get it from preloaded Patcher cache or calculate it)
if(PatchesCache.GetHash(tmp,(uint8*)&xferh.md5))
if(PatchesCache.GetHash(tmp, (uint8*)&xferh.md5))
{
DEBUG_LOG("\n[AuthChallenge] Found precached patch info for patch %s",tmp);
DEBUG_LOG("\n[AuthChallenge] Found precached patch info for patch %s", tmp);
}
else
{ //calculate patch md5
printf("\n[AuthChallenge] Patch info for %s was not cached.",tmp);
{ // calculate patch md5
printf("\n[AuthChallenge] Patch info for %s was not cached.", tmp);
PatchesCache.LoadPatchMD5(tmp);
PatchesCache.GetHash(tmp,(uint8*)&xferh.md5);
PatchesCache.GetHash(tmp, (uint8*)&xferh.md5);
}
///- Send a packet to the client with the file length and MD5 hash
uint8 data[2]={AUTH_LOGON_PROOF,REALM_AUTH_UPDATE_CLIENT};
SendBuf((const char*)data,sizeof(data));
uint8 data[2] = { AUTH_LOGON_PROOF, REALM_AUTH_UPDATE_CLIENT };
SendBuf((const char*)data, sizeof(data));
memcpy(&xferh,"0\x05Patch",7);
xferh.cmd=XFER_INITIATE;
fseek(pPatch,0,SEEK_END);
xferh.file_size=ftell(pPatch);
memcpy(&xferh, "0\x05Patch", 7);
xferh.cmd = XFER_INITIATE;
fseek(pPatch, 0, SEEK_END);
xferh.file_size = ftell(pPatch);
SendBuf((const char*)&xferh,sizeof(xferh));
SendBuf((const char*)&xferh, sizeof(xferh));
return true;
}
}
@@ -591,27 +606,27 @@ bool AuthSocket::_HandleLogonProof()
uint8 t1[16];
uint8 vK[40];
memcpy(t, S.AsByteArray(), 32);
for (int i = 0; i < 16; i++)
for (int i = 0; i < 16; ++i)
{
t1[i] = t[i*2];
t1[i] = t[i * 2];
}
sha.Initialize();
sha.UpdateData(t1, 16);
sha.Finalize();
for (int i = 0; i < 20; i++)
for (int i = 0; i < 20; ++i)
{
vK[i*2] = sha.GetDigest()[i];
vK[i * 2] = sha.GetDigest()[i];
}
for (int i = 0; i < 16; i++)
for (int i = 0; i < 16; ++i)
{
t1[i] = t[i*2+1];
t1[i] = t[i * 2 + 1];
}
sha.Initialize();
sha.UpdateData(t1, 16);
sha.Finalize();
for (int i = 0; i < 20; i++)
for (int i = 0; i < 20; ++i)
{
vK[i*2+1] = sha.GetDigest()[i];
vK[i * 2 + 1] = sha.GetDigest()[i];
}
K.SetBinary(vK, 40);
@@ -624,7 +639,7 @@ bool AuthSocket::_HandleLogonProof()
sha.Initialize();
sha.UpdateBigNumbers(&g, NULL);
sha.Finalize();
for (int i = 0; i < 20; i++)
for (int i = 0; i < 20; ++i)
{
hash[i] ^= sha.GetDigest()[i];
}
@@ -653,7 +668,7 @@ bool AuthSocket::_HandleLogonProof()
///- Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
// No SQL injection (escaped user name) and IP address as received by socket
const char* K_hex = K.AsHexStr();
LoginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '%s'", K_hex, GetRemoteAddress().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str() );
loginDatabase.PExecute("UPDATE account SET sessionkey = '%s', last_ip = '%s', last_login = NOW(), locale = '%u', failed_logins = 0 WHERE username = '%s'", K_hex, GetRemoteAddress().c_str(), GetLocaleByName(_localizationName), _safelogin.c_str() );
OPENSSL_free((void*)K_hex);
///- Finish SRP6 and send the final result to the client
@@ -676,17 +691,17 @@ bool AuthSocket::_HandleLogonProof()
}
else
{
char data[4]={AUTH_LOGON_PROOF,REALM_AUTH_NO_MATCH,3,0};
SendBuf(data,sizeof(data));
char data[4]= { AUTH_LOGON_PROOF, REALM_AUTH_NO_MATCH, 3, 0};
SendBuf(data, sizeof(data));
sLog.outBasic("[AuthChallenge] account %s tried to login with wrong password!",_login.c_str ());
uint32 MaxWrongPassCount = sConfig.GetIntDefault("WrongPass.MaxCount", 0);
if(MaxWrongPassCount > 0)
{
//Increment number of failed logins by one and if it reaches the limit temporarily ban that account or IP
LoginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '%s'",_safelogin.c_str());
loginDatabase.PExecute("UPDATE account SET failed_logins = failed_logins + 1 WHERE username = '%s'",_safelogin.c_str());
if(QueryResult *loginfail = LoginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '%s'", _safelogin.c_str()))
if(QueryResult *loginfail = loginDatabase.PQuery("SELECT id, failed_logins FROM account WHERE username = '%s'", _safelogin.c_str()))
{
Field* fields = loginfail->Fetch();
uint32 failed_logins = fields[1].GetUInt32();
@@ -699,7 +714,7 @@ bool AuthSocket::_HandleLogonProof()
if(WrongPassBanType)
{
uint32 acc_id = fields[0].GetUInt32();
LoginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban',1)",
loginDatabase.PExecute("INSERT INTO account_banned VALUES ('%u',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban',1)",
acc_id, WrongPassBanTime);
sLog.outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
_login.c_str(), WrongPassBanTime, failed_logins);
@@ -707,8 +722,8 @@ bool AuthSocket::_HandleLogonProof()
else
{
std::string current_ip = GetRemoteAddress();
LoginDatabase.escape_string(current_ip);
LoginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban')",
loginDatabase.escape_string(current_ip);
loginDatabase.PExecute("INSERT INTO ip_banned VALUES ('%s',UNIX_TIMESTAMP(),UNIX_TIMESTAMP()+'%u','Trinity realmd','Failed login autoban')",
current_ip.c_str(), WrongPassBanTime);
sLog.outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
current_ip.c_str(), WrongPassBanTime, _login.c_str(), failed_logins);
@@ -754,7 +769,7 @@ bool AuthSocket::_HandleReconnectChallenge()
_login = (const char*)ch->I;
_safelogin = _login;
QueryResult *result = LoginDatabase.PQuery ("SELECT sessionkey FROM account WHERE username = '%s'", _safelogin.c_str ());
QueryResult *result = loginDatabase.PQuery ("SELECT sessionkey FROM account WHERE username = '%s'", _safelogin.c_str ());
// Stop if the account is not found
if (!result)
@@ -772,7 +787,7 @@ bool AuthSocket::_HandleReconnectChallenge()
ByteBuffer pkt;
pkt << (uint8) AUTH_RECONNECT_CHALLENGE;
pkt << (uint8) 0x00;
_reconnectProof.SetRand(16*8);
_reconnectProof.SetRand(16 * 8);
pkt.append(_reconnectProof.AsByteBuffer()); // 16 bytes random
pkt << (uint64) 0x00 << (uint64) 0x00; // 16 bytes zeros
SendBuf((char const*)pkt.contents(), pkt.size());
@@ -834,7 +849,7 @@ bool AuthSocket::_HandleRealmList()
///- Get the user id (else close the connection)
// No SQL injection (escaped user name)
QueryResult *result = LoginDatabase.PQuery("SELECT id,sha_pass_hash FROM account WHERE username = '%s'",_safelogin.c_str());
QueryResult *result = loginDatabase.PQuery("SELECT id,sha_pass_hash FROM account WHERE username = '%s'",_safelogin.c_str());
if(!result)
{
sLog.outError("[ERROR] user %s tried to login and we cannot find him in the database.",_login.c_str());
@@ -854,12 +869,12 @@ bool AuthSocket::_HandleRealmList()
pkt << (uint32) 0;
pkt << (uint16) m_realmList.size();
RealmList::RealmMap::const_iterator i;
for( i = m_realmList.begin(); i != m_realmList.end(); i++ )
for( i = m_realmList.begin(); i != m_realmList.end(); ++i )
{
uint8 AmountOfCharacters;
// No SQL injection. id of realm is controlled by the database.
result = LoginDatabase.PQuery( "SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'",i->second.m_ID,id);
result = loginDatabase.PQuery( "SELECT numchars FROM realmcharacters WHERE realmid = '%d' AND acctid='%u'",i->second.m_ID,id);
if( result )
{
Field *fields = result->Fetch();
@@ -901,7 +916,7 @@ bool AuthSocket::_HandleXferResume()
{
DEBUG_LOG("Entering _HandleXferResume");
///- Check packet length and patch existence
if (ibuf.GetLength()<9 || !pPatch)
if (ibuf.GetLength() < 9 || !pPatch)
{
sLog.outError("Error while resuming patch transfer (wrong packet)");
return false;
@@ -911,7 +926,7 @@ bool AuthSocket::_HandleXferResume()
uint64 start;
ibuf.Remove(1);
ibuf.Read((char*)&start,sizeof(start));
fseek(pPatch,start,0);
fseek(pPatch, start, 0);
ACE_Based::Thread u(*new PatcherRunnable(this));
return true;
@@ -942,9 +957,9 @@ bool AuthSocket::_HandleXferAccept()
return false;
}
///- Launch a PatcherRunnable thread, starting at the begining of the patch file
ibuf.Remove(1); //clear input buffer
fseek(pPatch,0,0);
///- Launch a PatcherRunnable thread, starting at the beginning of the patch file
ibuf.Remove(1); // clear input buffer
fseek(pPatch, 0, 0);
ACE_Based::Thread u(*new PatcherRunnable(this));
return true;
@@ -953,12 +968,12 @@ bool AuthSocket::_HandleXferAccept()
/// Check if there is lag on the connection to the client
bool AuthSocket::IsLag()
{
return (TCP_BUFSIZE_READ-GetOutputLength()< 2*ChunkSize);
return (TCP_BUFSIZE_READ-GetOutputLength() < 2 * ChunkSize);
}
PatcherRunnable::PatcherRunnable(class AuthSocket * as)
{
mySocket=as;
mySocket = as;
}
/// Send content of patch file to the client
@@ -977,8 +992,8 @@ void PatcherRunnable::run()
ACE_Based::Thread::Sleep(1);
}
///- And send content of the patch file to the client
xfdata.data_size=fread(&xfdata.data,1,ChunkSize,mySocket->pPatch);
mySocket->SendBuf((const char*)&xfdata,xfdata.data_size +(sizeof(XFER_DATA_STRUCT)-ChunkSize));
xfdata.data_size = fread(&xfdata.data, 1, ChunkSize, mySocket->pPatch);
mySocket->SendBuf((const char*)&xfdata, xfdata.data_size + (sizeof(XFER_DATA_STRUCT) - ChunkSize));
}
}
@@ -999,8 +1014,9 @@ void Patcher::LoadPatchesInfo()
errno = 0;
if ((dp = readdir(dirp)) != NULL)
{
int l=strlen(dp->d_name);
if(l<8)continue;
int l = strlen(dp->d_name);
if(l < 8)
continue;
if(!memcmp(&dp->d_name[l-4],".mpq",4))
LoadPatchMD5(dp->d_name);
}
@@ -1023,15 +1039,15 @@ void Patcher::LoadPatchesInfo()
void Patcher::LoadPatchesInfo()
{
WIN32_FIND_DATA fil;
HANDLE hFil=FindFirstFile("./patches/*.mpq",&fil);
if(hFil==INVALID_HANDLE_VALUE)
return; //no patches were found
HANDLE hFil=FindFirstFile("./patches/*.mpq", &fil);
if(hFil == INVALID_HANDLE_VALUE)
return; // no patches were found
do
{
LoadPatchMD5(fil.cFileName);
}
while(FindNextFile(hFil,&fil));
while(FindNextFile(hFil, &fil));
}
#endif
@@ -1041,11 +1057,11 @@ void Patcher::LoadPatchMD5(char * szFileName)
///- Try to open the patch file
std::string path = "./patches/";
path += szFileName;
FILE * pPatch=fopen(path.c_str(),"rb");
sLog.outDebug("Loading patch info from %s\n",path.c_str());
FILE *pPatch = fopen(path.c_str(), "rb");
sLog.outDebug("Loading patch info from %s\n", path.c_str());
if(!pPatch)
{
sLog.outError("Error loading patch %s\n",path.c_str());
sLog.outError("Error loading patch %s\n", path.c_str());
return;
}
@@ -1064,16 +1080,16 @@ void Patcher::LoadPatchMD5(char * szFileName)
///- Store the result in the internal patch hash map
_patches[path] = new PATCH_INFO;
MD5_Final((uint8 *)&_patches[path]->md5 , &ctx);
MD5_Final((uint8 *)&_patches[path]->md5, &ctx);
}
/// Get cached MD5 hash for a given patch file
bool Patcher::GetHash(char * pat,uint8 mymd5[16])
bool Patcher::GetHash(char * pat, uint8 mymd5[16])
{
for( Patches::iterator i = _patches.begin(); i != _patches.end(); i++ )
if(!stricmp(pat,i->first.c_str () ))
for( Patches::iterator i = _patches.begin(); i != _patches.end(); ++i )
if(!stricmp(pat, i->first.c_str()))
{
memcpy(mymd5,i->second->md5,16);
memcpy(mymd5, i->second->md5, 16);
return true;
}
@@ -1089,6 +1105,6 @@ Patcher::Patcher()
/// Empty and delete the patch map on termination
Patcher::~Patcher()
{
for(Patches::iterator i = _patches.begin(); i != _patches.end(); i++ )
for(Patches::iterator i = _patches.begin(); i != _patches.end(); ++i )
delete i->second;
}
+7 -7
View File
@@ -66,7 +66,7 @@ void HookSignals();
bool stopEvent = false; ///< Setting it to true stops the server
RealmList m_realmList; ///< Holds the list of realms for this server
DatabaseType LoginDatabase; ///< Accessor to the realm server database
DatabaseType loginDatabase; ///< Accessor to the realm server database
/// Print out the usage string for this program on the console.
void usage(const char *prog)
@@ -304,7 +304,7 @@ extern int main(int argc, char **argv)
{
loopCounter = 0;
sLog.outDetail("Ping MySQL to keep connection alive");
delete LoginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1");
delete loginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1");
}
#ifdef WIN32
if (m_ServiceStatus == 0) stopEvent = true;
@@ -313,8 +313,8 @@ extern int main(int argc, char **argv)
}
///- Wait for the delay thread to exit
LoginDatabase.ThreadEnd();
LoginDatabase.HaltDelayThread();
loginDatabase.ThreadEnd();
loginDatabase.HaltDelayThread();
///- Remove signal handling before leaving
UnhookSignals();
@@ -346,19 +346,19 @@ void OnSignal(int s)
/// Initialize connection to the database
bool StartDB()
{
std::string dbstring = sConfig.GetStringDefault("LoginDatabaseInfo", "");
std::string dbstring = sConfig.GetStringDefault("loginDatabaseInfo", "");
if(dbstring.empty())
{
sLog.outError("Database not specified");
return false;
}
if(!LoginDatabase.Initialize(dbstring.c_str()))
if(!loginDatabase.Initialize(dbstring.c_str()))
{
sLog.outError("Cannot connect to database");
return false;
}
LoginDatabase.ThreadStart();
loginDatabase.ThreadStart();
return true;
}
+2 -2
View File
@@ -29,7 +29,7 @@
INSTANTIATE_SINGLETON_1( RealmList );
extern DatabaseType LoginDatabase;
extern DatabaseType loginDatabase;
RealmList::RealmList( ) : m_UpdateInterval(0), m_NextUpdateTime(time(NULL))
{
@@ -82,7 +82,7 @@ void RealmList::UpdateRealms(bool init)
{
sLog.outDetail("Updating Realm List...");
QueryResult *result = LoginDatabase.Query( "SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population FROM realmlist WHERE color <> 3 ORDER BY name" );
QueryResult *result = loginDatabase.Query( "SELECT id, name, address, port, icon, color, timezone, allowedSecurityLevel, population FROM realmlist WHERE color <> 3 ORDER BY name" );
///- Circle through results and add them to the realm map
if(result)
+1
View File
@@ -370,6 +370,7 @@
<ClCompile Include="..\..\src\game\CalendarHandler.cpp" />
<ClCompile Include="..\..\src\game\Channel.cpp" />
<ClCompile Include="..\..\src\game\ChannelHandler.cpp" />
<ClCompile Include="..\..\src\game\ChannelMgr.cpp" />
<ClCompile Include="..\..\src\game\CharacterHandler.cpp" />
<ClCompile Include="..\..\src\game\Chat.cpp" />
<ClCompile Include="..\..\src\game\ChatHandler.cpp" />
+4
View File
@@ -673,6 +673,10 @@
RelativePath="..\..\src\game\ChannelHandler.cpp"
>
</File>
<File
RelativePath="..\..\src\game\ChannelMgr.cpp"
>
</File>
<File
RelativePath="..\..\src\game\ChannelMgr.h"
>
+4
View File
@@ -674,6 +674,10 @@
RelativePath="..\..\src\game\ChannelHandler.cpp"
>
</File>
<File
RelativePath="..\..\src\game\ChannelMgr.cpp"
>
</File>
<File
RelativePath="..\..\src\game\ChannelMgr.h"
>