mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-04 04:12:25 +00:00
Merge branch 'master' into nats
# Conflicts: # world/client.cpp # zone/attack.cpp # zone/map.cpp # zone/map.h # zone/spells.cpp
This commit is contained in:
commit
2270bd267d
@ -1,5 +1,25 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 03/07/2018 ==
|
||||||
|
Uleat: Added command '#ucs' to force a reconnect to UCS server.
|
||||||
|
- Works in place of client auto-reconnect packet in zones where feature is unsupported
|
||||||
|
- Currently, you will need to manually re-join channels
|
||||||
|
|
||||||
|
== 03/04/2018 ==
|
||||||
|
Uleat: Updated UCS versioning
|
||||||
|
- SoF and higher clients have a new opcode identified (update your *.conf files)
|
||||||
|
- Rework of previous ucs connectivity code
|
||||||
|
- Unrelated: Zone::weatherSend() now takes an optional parameter for singular updates (as in client entering zone)
|
||||||
|
-- prior to this, every client already in-zone received a weather update packet whenever a new client zoned in
|
||||||
|
|
||||||
|
== 02/18/2018 ==
|
||||||
|
Uleat: Bug reporting fix and overhaul.
|
||||||
|
- Fixed bug reporting for SoD+ clients
|
||||||
|
- Added ability to disable bug reporting (set rule 'Bugs:ReportingSystemActive' to 'false')
|
||||||
|
- Implemented a more detailed reporting system (set rule 'Bugs:UseOldReportingMethod' to 'false')
|
||||||
|
-- New system is not currently compatible with script-based monitoring
|
||||||
|
- Soft-removal of defunct 'Petition Bug' system
|
||||||
|
|
||||||
== 02/14/2018 ==
|
== 02/14/2018 ==
|
||||||
mackal: Fix Heading -- Quests broken
|
mackal: Fix Heading -- Quests broken
|
||||||
|
|
||||||
|
|||||||
@ -18,3 +18,68 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "emu_constants.h"
|
#include "emu_constants.h"
|
||||||
|
|
||||||
|
|
||||||
|
const char* EQEmu::bug::CategoryIDToCategoryName(CategoryID category_id) {
|
||||||
|
switch (category_id) {
|
||||||
|
case catVideo:
|
||||||
|
return "Video";
|
||||||
|
case catAudio:
|
||||||
|
return "Audio";
|
||||||
|
case catPathing:
|
||||||
|
return "Pathing";
|
||||||
|
case catQuest:
|
||||||
|
return "Quest";
|
||||||
|
case catTradeskills:
|
||||||
|
return "Tradeskills";
|
||||||
|
case catSpellStacking:
|
||||||
|
return "Spell stacking";
|
||||||
|
case catDoorsPortals:
|
||||||
|
return "Doors/Portals";
|
||||||
|
case catItems:
|
||||||
|
return "Items";
|
||||||
|
case catNPC:
|
||||||
|
return "NPC";
|
||||||
|
case catDialogs:
|
||||||
|
return "Dialogs";
|
||||||
|
case catLoNTCG:
|
||||||
|
return "LoN - TCG";
|
||||||
|
case catMercenaries:
|
||||||
|
return "Mercenaries";
|
||||||
|
case catOther:
|
||||||
|
default:
|
||||||
|
return "Other";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EQEmu::bug::CategoryID EQEmu::bug::CategoryNameToCategoryID(const char* category_name) {
|
||||||
|
if (!category_name)
|
||||||
|
return catOther;
|
||||||
|
|
||||||
|
if (!strcmp(category_name, "Video"))
|
||||||
|
return catVideo;
|
||||||
|
if (!strcmp(category_name, "Audio"))
|
||||||
|
return catAudio;
|
||||||
|
if (!strcmp(category_name, "Pathing"))
|
||||||
|
return catPathing;
|
||||||
|
if (!strcmp(category_name, "Quest"))
|
||||||
|
return catQuest;
|
||||||
|
if (!strcmp(category_name, "Tradeskills"))
|
||||||
|
return catTradeskills;
|
||||||
|
if (!strcmp(category_name, "Spell stacking"))
|
||||||
|
return catSpellStacking;
|
||||||
|
if (!strcmp(category_name, "Doors/Portals"))
|
||||||
|
return catDoorsPortals;
|
||||||
|
if (!strcmp(category_name, "Items"))
|
||||||
|
return catItems;
|
||||||
|
if (!strcmp(category_name, "NPC"))
|
||||||
|
return catNPC;
|
||||||
|
if (!strcmp(category_name, "Dialogs"))
|
||||||
|
return catDialogs;
|
||||||
|
if (!strcmp(category_name, "LoN - TCG"))
|
||||||
|
return catLoNTCG;
|
||||||
|
if (!strcmp(category_name, "Mercenaries"))
|
||||||
|
return catMercenaries;
|
||||||
|
|
||||||
|
return catOther;
|
||||||
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
#include "emu_legacy.h"
|
#include "emu_legacy.h"
|
||||||
#include "emu_versions.h"
|
#include "emu_versions.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
namespace EQEmu
|
namespace EQEmu
|
||||||
@ -114,7 +114,11 @@ namespace EQEmu
|
|||||||
const EQEmu::versions::ClientVersion CharacterCreationClient = EQEmu::versions::ClientVersion::RoF2;
|
const EQEmu::versions::ClientVersion CharacterCreationClient = EQEmu::versions::ClientVersion::RoF2;
|
||||||
const size_t CharacterCreationMax = RoF2::constants::CharacterCreationLimit;
|
const size_t CharacterCreationMax = RoF2::constants::CharacterCreationLimit;
|
||||||
|
|
||||||
|
const size_t SayLinkOpenerSize = 1;
|
||||||
const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize;
|
const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize;
|
||||||
|
const size_t SayLinkTextSize = 256; // this may be varied until it breaks something (tested:374) - the others are constant
|
||||||
|
const size_t SayLinkCloserSize = 1;
|
||||||
|
const size_t SayLinkMaximumSize = (SayLinkOpenerSize + SayLinkBodySize + SayLinkTextSize + SayLinkCloserSize);
|
||||||
|
|
||||||
const int LongBuffs = RoF2::constants::LongBuffs;
|
const int LongBuffs = RoF2::constants::LongBuffs;
|
||||||
const int ShortBuffs = RoF2::constants::ShortBuffs;
|
const int ShortBuffs = RoF2::constants::ShortBuffs;
|
||||||
@ -126,6 +130,37 @@ namespace EQEmu
|
|||||||
|
|
||||||
} /*constants*/
|
} /*constants*/
|
||||||
|
|
||||||
|
namespace bug {
|
||||||
|
enum CategoryID : uint32 {
|
||||||
|
catOther = 0,
|
||||||
|
catVideo,
|
||||||
|
catAudio,
|
||||||
|
catPathing,
|
||||||
|
catQuest,
|
||||||
|
catTradeskills,
|
||||||
|
catSpellStacking,
|
||||||
|
catDoorsPortals,
|
||||||
|
catItems,
|
||||||
|
catNPC,
|
||||||
|
catDialogs,
|
||||||
|
catLoNTCG,
|
||||||
|
catMercenaries
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OptionalInfoFlag : uint32 {
|
||||||
|
infoNoOptionalInfo = 0x0,
|
||||||
|
infoCanDuplicate = 0x1,
|
||||||
|
infoCrashBug = 0x2,
|
||||||
|
infoTargetInfo = 0x4,
|
||||||
|
infoCharacterFlags = 0x8,
|
||||||
|
infoUnknownValue = 0xFFFFFFF0
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* CategoryIDToCategoryName(CategoryID category_id);
|
||||||
|
CategoryID CategoryNameToCategoryID(const char* category_name);
|
||||||
|
|
||||||
|
} // namespace bug
|
||||||
|
|
||||||
enum class CastingSlot : uint32 {
|
enum class CastingSlot : uint32 {
|
||||||
Gem1 = 0,
|
Gem1 = 0,
|
||||||
Gem2 = 1,
|
Gem2 = 1,
|
||||||
|
|||||||
@ -175,8 +175,6 @@ namespace EQEmu
|
|||||||
|
|
||||||
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
|
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
|
||||||
static const size_t POTION_BELT_ITEM_COUNT = 5;
|
static const size_t POTION_BELT_ITEM_COUNT = 5;
|
||||||
|
|
||||||
static const size_t TEXT_LINK_BODY_LENGTH = 56;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -393,6 +393,7 @@ N(OP_PVPLeaderBoardReply),
|
|||||||
N(OP_PVPLeaderBoardRequest),
|
N(OP_PVPLeaderBoardRequest),
|
||||||
N(OP_PVPStats),
|
N(OP_PVPStats),
|
||||||
N(OP_QueryResponseThing),
|
N(OP_QueryResponseThing),
|
||||||
|
N(OP_QueryUCSServerStatus),
|
||||||
N(OP_RaidInvite),
|
N(OP_RaidInvite),
|
||||||
N(OP_RaidJoin),
|
N(OP_RaidJoin),
|
||||||
N(OP_RaidUpdate),
|
N(OP_RaidUpdate),
|
||||||
|
|||||||
@ -28,7 +28,7 @@
|
|||||||
namespace EQEmu
|
namespace EQEmu
|
||||||
{
|
{
|
||||||
namespace versions {
|
namespace versions {
|
||||||
enum class ClientVersion {
|
enum class ClientVersion : uint32 {
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
Client62, // Build: 'Aug 4 2005 15:40:59'
|
Client62, // Build: 'Aug 4 2005 15:40:59'
|
||||||
Titanium, // Build: 'Oct 31 2005 10:33:37'
|
Titanium, // Build: 'Oct 31 2005 10:33:37'
|
||||||
@ -72,7 +72,7 @@ namespace EQEmu
|
|||||||
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
|
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
|
||||||
|
|
||||||
|
|
||||||
enum class MobVersion {
|
enum class MobVersion : uint32 {
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
Client62,
|
Client62,
|
||||||
Titanium,
|
Titanium,
|
||||||
@ -121,6 +121,20 @@ namespace EQEmu
|
|||||||
ClientVersion ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version);
|
ClientVersion ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version);
|
||||||
MobVersion ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version);
|
MobVersion ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version);
|
||||||
|
|
||||||
|
|
||||||
|
enum UCSVersion : char {
|
||||||
|
ucsUnknown = '\0',
|
||||||
|
ucsClient62Chat = 'A',
|
||||||
|
ucsClient62Mail = 'a',
|
||||||
|
ucsTitaniumChat = 'B',
|
||||||
|
ucsTitaniumMail = 'b',
|
||||||
|
ucsSoFCombined = 'C',
|
||||||
|
ucsSoDCombined = 'D',
|
||||||
|
ucsUFCombined = 'E',
|
||||||
|
ucsRoFCombined = 'F',
|
||||||
|
ucsRoF2Combined = 'G'
|
||||||
|
};
|
||||||
|
|
||||||
} /*versions*/
|
} /*versions*/
|
||||||
|
|
||||||
} /*EQEmu*/
|
} /*EQEmu*/
|
||||||
|
|||||||
@ -280,7 +280,7 @@ union
|
|||||||
// horse: 0=brown, 1=white, 2=black, 3=tan
|
// horse: 0=brown, 1=white, 2=black, 3=tan
|
||||||
};
|
};
|
||||||
/*0340*/ uint32 spawnId; // Spawn Id
|
/*0340*/ uint32 spawnId; // Spawn Id
|
||||||
/*0344*/ uint8 unknown0344[3];
|
/*0344*/ float bounding_radius; // used in melee, overrides calc
|
||||||
/*0347*/ uint8 IsMercenary;
|
/*0347*/ uint8 IsMercenary;
|
||||||
/*0348*/ EQEmu::TintProfile equipment_tint;
|
/*0348*/ EQEmu::TintProfile equipment_tint;
|
||||||
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
|
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
|
||||||
@ -1253,21 +1253,22 @@ struct Action_Struct
|
|||||||
{
|
{
|
||||||
/* 00 */ uint16 target; // id of target
|
/* 00 */ uint16 target; // id of target
|
||||||
/* 02 */ uint16 source; // id of caster
|
/* 02 */ uint16 source; // id of caster
|
||||||
/* 04 */ uint16 level; // level of caster
|
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/* 06 */ uint16 instrument_mod;
|
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||||
/* 08 */ uint32 bard_focus_id;
|
/* 10 */ float force;
|
||||||
/* 12 */ uint16 unknown16;
|
/* 14 */ float hit_heading;
|
||||||
// some kind of sequence that's the same in both actions
|
/* 18 */ float hit_pitch;
|
||||||
// as well as the combat damage, to tie em together?
|
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/* 14 */ uint32 sequence;
|
/* 23 */ uint16 unknown23; // OSX says min_damage
|
||||||
/* 18 */ uint32 unknown18;
|
/* 25 */ uint16 unknown25; // OSX says tohit
|
||||||
/* 22 */ uint8 type; // 231 (0xE7) for spells
|
|
||||||
/* 23 */ uint32 unknown23;
|
|
||||||
/* 27 */ uint16 spell; // spell id being cast
|
/* 27 */ uint16 spell; // spell id being cast
|
||||||
/* 29 */ uint8 unknown29;
|
/* 29 */ uint8 spell_level;
|
||||||
// this field seems to be some sort of success flag, if it's 4
|
// this field seems to be some sort of success flag, if it's 4
|
||||||
/* 30 */ uint8 buff_unknown; // if this is 4, a buff icon is made
|
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||||
/* 31 */
|
// newer clients have some data for setting LaunchSpellData when effect_flag & 4
|
||||||
|
// /* 31 */ uint8 spell_gem;
|
||||||
|
// /* 32 */ uint32 inventory_slot;
|
||||||
|
// /* 36 */ uint32 item_cast_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
// this is what prints the You have been struck. and the regular
|
// this is what prints the You have been struck. and the regular
|
||||||
@ -1277,12 +1278,12 @@ struct CombatDamage_Struct
|
|||||||
{
|
{
|
||||||
/* 00 */ uint16 target;
|
/* 00 */ uint16 target;
|
||||||
/* 02 */ uint16 source;
|
/* 02 */ uint16 source;
|
||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells, skill
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ uint32 damage;
|
/* 07 */ uint32 damage;
|
||||||
/* 11 */ float force;
|
/* 11 */ float force;
|
||||||
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
/* 15 */ float hit_heading; // see above notes in Action_Struct
|
||||||
/* 19 */ float meleepush_z;
|
/* 19 */ float hit_pitch;
|
||||||
/* 23 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
/* 23 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3323,23 +3324,32 @@ struct GuildMakeLeader{
|
|||||||
char target[64];
|
char target[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BugStruct{
|
struct BugReport_Struct {
|
||||||
/*0000*/ char chartype[64];
|
/*0000*/ uint32 category_id;
|
||||||
/*0064*/ char name[96];
|
/*0004*/ char category_name[64];
|
||||||
/*0160*/ char ui[128];
|
/*0068*/ char reporter_name[64];
|
||||||
/*0288*/ float x;
|
/*0132*/ char unused_0132[32];
|
||||||
/*0292*/ float y;
|
/*0164*/ char ui_path[128];
|
||||||
/*0296*/ float z;
|
/*0292*/ float pos_x;
|
||||||
/*0300*/ float heading;
|
/*0296*/ float pos_y;
|
||||||
/*0304*/ uint32 unknown304;
|
/*0300*/ float pos_z;
|
||||||
/*0308*/ char unknown308[160];
|
/*0304*/ uint32 heading;
|
||||||
/*0468*/ char target_name[64];
|
/*0308*/ uint32 unused_0308;
|
||||||
/*0532*/ uint32 type;
|
/*0312*/ uint32 time_played;
|
||||||
/*0536*/ char unknown536[2052];
|
/*0316*/ char padding_0316[8];
|
||||||
/*2584*/ char bug[2048];
|
/*0324*/ uint32 target_id;
|
||||||
/*4632*/ char unknown4632[6];
|
/*0328*/ char padding_0328[140];
|
||||||
/*4638*/ char system_info[4094];
|
/*0468*/ uint32 unknown_0468; // seems to always be '0'
|
||||||
|
/*0472*/ char target_name[64];
|
||||||
|
/*0536*/ uint32 optional_info_mask;
|
||||||
|
|
||||||
|
// this looks like a butchered 8k buffer with 2 trailing dword fields
|
||||||
|
/*0540*/ char unused_0540[2052];
|
||||||
|
/*2592*/ char bug_report[2050];
|
||||||
|
/*4642*/ char system_info[4098];
|
||||||
|
/*8740*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||||
uint8 level;
|
uint8 level;
|
||||||
uint8 class_;
|
uint8 class_;
|
||||||
@ -3366,20 +3376,21 @@ struct Ground_Spawn{
|
|||||||
struct Ground_Spawns {
|
struct Ground_Spawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
struct PetitionBug_Struct{
|
|
||||||
uint32 petition_number;
|
//struct PetitionBug_Struct{
|
||||||
uint32 unknown4;
|
// uint32 petition_number;
|
||||||
char accountname[64];
|
// uint32 unknown4;
|
||||||
uint32 zoneid;
|
// char accountname[64];
|
||||||
char name[64];
|
// uint32 zoneid;
|
||||||
uint32 level;
|
// char name[64];
|
||||||
uint32 class_;
|
// uint32 level;
|
||||||
uint32 race;
|
// uint32 class_;
|
||||||
uint32 unknown152[3];
|
// uint32 race;
|
||||||
uint32 time;
|
// uint32 unknown152[3];
|
||||||
uint32 unknown168;
|
// uint32 time;
|
||||||
char text[1028];
|
// uint32 unknown168;
|
||||||
};
|
// char text[1028];
|
||||||
|
//};
|
||||||
|
|
||||||
struct ApproveZone_Struct {
|
struct ApproveZone_Struct {
|
||||||
char name[64];
|
char name[64];
|
||||||
@ -5356,6 +5367,23 @@ struct AuraDestory_Struct {
|
|||||||
};
|
};
|
||||||
// I think we can assume it's just action for 2, client doesn't seem to do anything with the rest of the data in that case
|
// I think we can assume it's just action for 2, client doesn't seem to do anything with the rest of the data in that case
|
||||||
|
|
||||||
|
struct SayLinkBodyFrame_Struct {
|
||||||
|
/*000*/ char ActionID[1];
|
||||||
|
/*001*/ char ItemID[5];
|
||||||
|
/*006*/ char Augment1[5];
|
||||||
|
/*011*/ char Augment2[5];
|
||||||
|
/*016*/ char Augment3[5];
|
||||||
|
/*021*/ char Augment4[5];
|
||||||
|
/*026*/ char Augment5[5];
|
||||||
|
/*031*/ char Augment6[5];
|
||||||
|
/*036*/ char IsEvolving[1];
|
||||||
|
/*037*/ char EvolveGroup[4];
|
||||||
|
/*041*/ char EvolveLevel[2];
|
||||||
|
/*043*/ char OrnamentIcon[5];
|
||||||
|
/*048*/ char Hash[8];
|
||||||
|
/*056*/
|
||||||
|
};
|
||||||
|
|
||||||
// Restore structure packing to default
|
// Restore structure packing to default
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
|||||||
@ -219,6 +219,9 @@ enum { //some random constants
|
|||||||
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
|
//the square of the maximum range at whihc you could possibly use NPC services (shop, tribute, etc)
|
||||||
#define USE_NPC_RANGE2 200*200 //arbitrary right now
|
#define USE_NPC_RANGE2 200*200 //arbitrary right now
|
||||||
|
|
||||||
|
// Squared range for rampage 75.0 * 75.0 for now
|
||||||
|
#define NPC_RAMPAGE_RANGE2 5625.0f
|
||||||
|
|
||||||
//the formula for experience for killing a mob.
|
//the formula for experience for killing a mob.
|
||||||
//level is the only valid variable to use
|
//level is the only valid variable to use
|
||||||
#define EXP_FORMULA level*level*75*35/10
|
#define EXP_FORMULA level*level*75*35/10
|
||||||
|
|||||||
@ -242,6 +242,24 @@ int FloatToEQSpeedRun(float d)
|
|||||||
return static_cast<int>(d * 40.0f);
|
return static_cast<int>(d * 40.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float FixHeading(float in)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
if (in >= 512.0f) {
|
||||||
|
do {
|
||||||
|
in -= 512.0f;
|
||||||
|
} while (in >= 512.0f && i++ <= 5);
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
if (in < 0.0f) {
|
||||||
|
do {
|
||||||
|
in += 512.0f;
|
||||||
|
} while (in < 0.0f && i++ <= 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Heading of 0 points in the pure positive Y direction
|
Heading of 0 points in the pure positive Y direction
|
||||||
|
|
||||||
|
|||||||
@ -66,6 +66,9 @@ int FloatToEQ10(float d);
|
|||||||
float EQSpeedRunToFloat(int d);
|
float EQSpeedRunToFloat(int d);
|
||||||
int FloatToEQSpeedRun(float d);
|
int FloatToEQSpeedRun(float d);
|
||||||
|
|
||||||
|
// brings heading back into EQ angles range
|
||||||
|
float FixHeading(float in);
|
||||||
|
|
||||||
uint32 SwapBits21and22(uint32 mask);
|
uint32 SwapBits21and22(uint32 mask);
|
||||||
uint32 Catch22(uint32 mask);
|
uint32 Catch22(uint32 mask);
|
||||||
|
|
||||||
|
|||||||
@ -165,7 +165,7 @@ void EQ::Net::DaybreakConnectionManager::ProcessResend()
|
|||||||
{
|
{
|
||||||
auto iter = m_connections.begin();
|
auto iter = m_connections.begin();
|
||||||
while (iter != m_connections.end()) {
|
while (iter != m_connections.end()) {
|
||||||
auto connection = iter->second;
|
auto &connection = iter->second;
|
||||||
auto status = connection->m_status;
|
auto status = connection->m_status;
|
||||||
|
|
||||||
switch (status)
|
switch (status)
|
||||||
@ -1397,4 +1397,4 @@ EQ::Net::SequenceOrder EQ::Net::DaybreakConnection::CompareSequence(uint16_t exp
|
|||||||
}
|
}
|
||||||
|
|
||||||
return SequencePast;
|
return SequencePast;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,11 +57,11 @@ namespace RoF
|
|||||||
static inline uint32 RoFToServerTypelessSlot(structs::TypelessInventorySlot_Struct rofSlot);
|
static inline uint32 RoFToServerTypelessSlot(structs::TypelessInventorySlot_Struct rofSlot);
|
||||||
static inline uint32 RoFToServerCorpseSlot(uint32 rofCorpseSlot);
|
static inline uint32 RoFToServerCorpseSlot(uint32 rofCorpseSlot);
|
||||||
|
|
||||||
// server to client text link converter
|
// server to client say link converter
|
||||||
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink);
|
static inline void ServerToRoFSayLink(std::string& rofSayLink, const std::string& serverSayLink);
|
||||||
|
|
||||||
// client to server text link converter
|
// client to server say link converter
|
||||||
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink);
|
static inline void RoFToServerSayLink(std::string& serverSayLink, const std::string& rofSayLink);
|
||||||
|
|
||||||
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot);
|
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot);
|
||||||
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot);
|
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot);
|
||||||
@ -163,22 +163,23 @@ namespace RoF
|
|||||||
OUT(level);
|
OUT(level);
|
||||||
eq->unknown06 = 0;
|
eq->unknown06 = 0;
|
||||||
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
|
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
|
||||||
eq->bard_focus_id = emu->bard_focus_id;
|
OUT(force);
|
||||||
eq->knockback_angle = emu->sequence;
|
OUT(hit_heading);
|
||||||
eq->unknown22 = 0;
|
OUT(hit_pitch);
|
||||||
OUT(type);
|
OUT(type);
|
||||||
eq->damage = 0;
|
eq->damage = 0;
|
||||||
eq->unknown31 = 0;
|
eq->unknown31 = 0;
|
||||||
OUT(spell);
|
OUT(spell);
|
||||||
eq->level2 = eq->level;
|
OUT(spell_level);
|
||||||
eq->effect_flag = emu->buff_unknown;
|
OUT(effect_flag);
|
||||||
eq->unknown39 = 14;
|
eq->spell_gem = 0;
|
||||||
eq->unknown43 = 0;
|
eq->slot.Type = INVALID_INDEX;
|
||||||
eq->unknown44 = 17;
|
eq->slot.Unknown02 = 0;
|
||||||
eq->unknown45 = 0;
|
eq->slot.Slot = INVALID_INDEX;
|
||||||
eq->unknown46 = -1;
|
eq->slot.SubIndex = INVALID_INDEX;
|
||||||
eq->unknown50 = 0;
|
eq->slot.AugIndex = INVALID_INDEX;
|
||||||
eq->unknown54 = 0;
|
eq->slot.Unknown01 = 0;
|
||||||
|
eq->item_cast_type = 0;
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -520,7 +521,7 @@ namespace RoF
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToRoFTextLink(new_message, old_message);
|
ServerToRoFSayLink(new_message, old_message);
|
||||||
|
|
||||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||||
@ -659,8 +660,8 @@ namespace RoF
|
|||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
OUT(force);
|
OUT(force);
|
||||||
OUT(meleepush_xy);
|
OUT(hit_heading);
|
||||||
OUT(meleepush_z);
|
OUT(hit_pitch);
|
||||||
OUT(special);
|
OUT(special);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -847,7 +848,7 @@ namespace RoF
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToRoFTextLink(new_message, old_message);
|
ServerToRoFSayLink(new_message, old_message);
|
||||||
|
|
||||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||||
// new_message = new_message.substr(0, 512);
|
// new_message = new_message.substr(0, 512);
|
||||||
@ -899,7 +900,7 @@ namespace RoF
|
|||||||
|
|
||||||
for (int i = 0; i < 9; ++i) {
|
for (int i = 0; i < 9; ++i) {
|
||||||
if (old_message_array[i].length() == 0) { break; }
|
if (old_message_array[i].length() == 0) { break; }
|
||||||
ServerToRoFTextLink(new_message_array[i], old_message_array[i]);
|
ServerToRoFSayLink(new_message_array[i], old_message_array[i]);
|
||||||
new_message_size += new_message_array[i].length() + 1;
|
new_message_size += new_message_array[i].length() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3295,7 +3296,7 @@ namespace RoF
|
|||||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
|
|
||||||
ServerToRoFTextLink(new_message, old_message);
|
ServerToRoFSayLink(new_message, old_message);
|
||||||
|
|
||||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||||
@ -3369,7 +3370,7 @@ namespace RoF
|
|||||||
|
|
||||||
std::string old_message = InBuffer; // start 'Reward' as string
|
std::string old_message = InBuffer; // start 'Reward' as string
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToRoFTextLink(new_message, old_message);
|
ServerToRoFSayLink(new_message, old_message);
|
||||||
|
|
||||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
||||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
||||||
@ -4355,7 +4356,7 @@ namespace RoF
|
|||||||
|
|
||||||
std::string old_message = InBuffer;
|
std::string old_message = InBuffer;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
RoFToServerTextLink(new_message, old_message);
|
RoFToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||||
@ -4466,7 +4467,7 @@ namespace RoF
|
|||||||
IN(type);
|
IN(type);
|
||||||
IN(spellid);
|
IN(spellid);
|
||||||
IN(damage);
|
IN(damage);
|
||||||
IN(meleepush_xy);
|
IN(hit_heading);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -4489,7 +4490,7 @@ namespace RoF
|
|||||||
|
|
||||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
RoFToServerTextLink(new_message, old_message);
|
RoFToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
__packet->size = sizeof(Emote_Struct);
|
__packet->size = sizeof(Emote_Struct);
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
__packet->pBuffer = new unsigned char[__packet->size];
|
||||||
@ -5916,19 +5917,19 @@ namespace RoF
|
|||||||
return (rofCorpseSlot - 1);
|
return (rofCorpseSlot - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink)
|
static inline void ServerToRoFSayLink(std::string& rofSayLink, const std::string& serverSayLink)
|
||||||
{
|
{
|
||||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||||
rofTextLink = serverTextLink;
|
rofSayLink = serverSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(serverTextLink, '\x12');
|
auto segments = SplitString(serverSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||||
rofTextLink.append(segments[segment_iter]);
|
rofSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -5938,36 +5939,36 @@ namespace RoF
|
|||||||
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
||||||
// Diff: ^
|
// Diff: ^
|
||||||
|
|
||||||
rofTextLink.push_back('\x12');
|
rofSayLink.push_back('\x12');
|
||||||
rofTextLink.append(segments[segment_iter].substr(0, 41));
|
rofSayLink.append(segments[segment_iter].substr(0, 41));
|
||||||
|
|
||||||
if (segments[segment_iter][41] == '0')
|
if (segments[segment_iter][41] == '0')
|
||||||
rofTextLink.push_back(segments[segment_iter][42]);
|
rofSayLink.push_back(segments[segment_iter][42]);
|
||||||
else
|
else
|
||||||
rofTextLink.push_back('F');
|
rofSayLink.push_back('F');
|
||||||
|
|
||||||
rofTextLink.append(segments[segment_iter].substr(43));
|
rofSayLink.append(segments[segment_iter].substr(43));
|
||||||
rofTextLink.push_back('\x12');
|
rofSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rofTextLink.append(segments[segment_iter]);
|
rofSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink)
|
static inline void RoFToServerSayLink(std::string& serverSayLink, const std::string& rofSayLink)
|
||||||
{
|
{
|
||||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (rofTextLink.find('\x12') == std::string::npos)) {
|
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (rofSayLink.find('\x12') == std::string::npos)) {
|
||||||
serverTextLink = rofTextLink;
|
serverSayLink = rofSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(rofTextLink, '\x12');
|
auto segments = SplitString(rofSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -5977,14 +5978,14 @@ namespace RoF
|
|||||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
// Diff: ^
|
// Diff: ^
|
||||||
|
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
serverTextLink.append(segments[segment_iter].substr(0, 41));
|
serverSayLink.append(segments[segment_iter].substr(0, 41));
|
||||||
serverTextLink.push_back('0');
|
serverSayLink.push_back('0');
|
||||||
serverTextLink.append(segments[segment_iter].substr(41));
|
serverSayLink.append(segments[segment_iter].substr(41));
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,11 +57,11 @@ namespace RoF2
|
|||||||
static inline uint32 RoF2ToServerTypelessSlot(structs::TypelessInventorySlot_Struct rof2Slot);
|
static inline uint32 RoF2ToServerTypelessSlot(structs::TypelessInventorySlot_Struct rof2Slot);
|
||||||
static inline uint32 RoF2ToServerCorpseSlot(uint32 rof2CorpseSlot);
|
static inline uint32 RoF2ToServerCorpseSlot(uint32 rof2CorpseSlot);
|
||||||
|
|
||||||
// server to client text link converter
|
// server to client say link converter
|
||||||
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink);
|
static inline void ServerToRoF2SayLink(std::string& rof2SayLink, const std::string& serverSayLink);
|
||||||
|
|
||||||
// client to server text link converter
|
// client to server say link converter
|
||||||
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink);
|
static inline void RoF2ToServerSayLink(std::string& serverSayLink, const std::string& rof2SayLink);
|
||||||
|
|
||||||
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot);
|
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot);
|
||||||
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot);
|
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot);
|
||||||
@ -232,22 +232,23 @@ namespace RoF2
|
|||||||
OUT(level);
|
OUT(level);
|
||||||
eq->unknown06 = 0;
|
eq->unknown06 = 0;
|
||||||
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
|
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
|
||||||
eq->bard_focus_id = emu->bard_focus_id;
|
OUT(force);
|
||||||
eq->knockback_angle = emu->sequence;
|
OUT(hit_heading);
|
||||||
eq->unknown22 = 0;
|
OUT(hit_pitch);
|
||||||
OUT(type);
|
OUT(type);
|
||||||
eq->damage = 0;
|
eq->damage = 0;
|
||||||
eq->unknown31 = 0;
|
eq->unknown31 = 0;
|
||||||
OUT(spell);
|
OUT(spell);
|
||||||
eq->level2 = eq->level;
|
OUT(spell_level);
|
||||||
eq->effect_flag = emu->buff_unknown;
|
OUT(effect_flag);
|
||||||
eq->unknown39 = 14;
|
eq->spell_gem = 0;
|
||||||
eq->unknown43 = 0;
|
eq->slot.Type = INVALID_INDEX;
|
||||||
eq->unknown44 = 17;
|
eq->slot.Unknown02 = 0;
|
||||||
eq->unknown45 = 0;
|
eq->slot.Slot = INVALID_INDEX;
|
||||||
eq->unknown46 = -1;
|
eq->slot.SubIndex = INVALID_INDEX;
|
||||||
eq->unknown50 = 0;
|
eq->slot.AugIndex = INVALID_INDEX;
|
||||||
eq->unknown54 = 0;
|
eq->slot.Unknown01 = 0;
|
||||||
|
eq->item_cast_type = 0;
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -588,7 +589,7 @@ namespace RoF2
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToRoF2TextLink(new_message, old_message);
|
ServerToRoF2SayLink(new_message, old_message);
|
||||||
|
|
||||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||||
@ -727,8 +728,8 @@ namespace RoF2
|
|||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
OUT(force);
|
OUT(force);
|
||||||
OUT(meleepush_xy);
|
OUT(hit_heading);
|
||||||
OUT(meleepush_z);
|
OUT(hit_pitch);
|
||||||
OUT(special);
|
OUT(special);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -915,7 +916,7 @@ namespace RoF2
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToRoF2TextLink(new_message, old_message);
|
ServerToRoF2SayLink(new_message, old_message);
|
||||||
|
|
||||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||||
// new_message = new_message.substr(0, 512);
|
// new_message = new_message.substr(0, 512);
|
||||||
@ -967,7 +968,7 @@ namespace RoF2
|
|||||||
|
|
||||||
for (int i = 0; i < 9; ++i) {
|
for (int i = 0; i < 9; ++i) {
|
||||||
if (old_message_array[i].length() == 0) { break; }
|
if (old_message_array[i].length() == 0) { break; }
|
||||||
ServerToRoF2TextLink(new_message_array[i], old_message_array[i]);
|
ServerToRoF2SayLink(new_message_array[i], old_message_array[i]);
|
||||||
new_message_size += new_message_array[i].length() + 1;
|
new_message_size += new_message_array[i].length() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3364,7 +3365,7 @@ namespace RoF2
|
|||||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
|
|
||||||
ServerToRoF2TextLink(new_message, old_message);
|
ServerToRoF2SayLink(new_message, old_message);
|
||||||
|
|
||||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||||
@ -3438,7 +3439,7 @@ namespace RoF2
|
|||||||
|
|
||||||
std::string old_message = InBuffer; // start 'Reward' as string
|
std::string old_message = InBuffer; // start 'Reward' as string
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToRoF2TextLink(new_message, old_message);
|
ServerToRoF2SayLink(new_message, old_message);
|
||||||
|
|
||||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
||||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
||||||
@ -4595,7 +4596,7 @@ namespace RoF2
|
|||||||
|
|
||||||
std::string old_message = InBuffer;
|
std::string old_message = InBuffer;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
RoF2ToServerTextLink(new_message, old_message);
|
RoF2ToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||||
@ -4706,7 +4707,7 @@ namespace RoF2
|
|||||||
IN(type);
|
IN(type);
|
||||||
IN(spellid);
|
IN(spellid);
|
||||||
IN(damage);
|
IN(damage);
|
||||||
IN(meleepush_xy);
|
IN(hit_heading);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -4729,7 +4730,7 @@ namespace RoF2
|
|||||||
|
|
||||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
RoF2ToServerTextLink(new_message, old_message);
|
RoF2ToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
__packet->size = sizeof(Emote_Struct);
|
__packet->size = sizeof(Emote_Struct);
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
__packet->pBuffer = new unsigned char[__packet->size];
|
||||||
@ -6233,19 +6234,19 @@ namespace RoF2
|
|||||||
return (rof2CorpseSlot + EQEmu::legacy::CORPSE_BEGIN - 1);
|
return (rof2CorpseSlot + EQEmu::legacy::CORPSE_BEGIN - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink)
|
static inline void ServerToRoF2SayLink(std::string& rof2SayLink, const std::string& serverSayLink)
|
||||||
{
|
{
|
||||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||||
rof2TextLink = serverTextLink;
|
rof2SayLink = serverSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(serverTextLink, '\x12');
|
auto segments = SplitString(serverSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||||
rof2TextLink.append(segments[segment_iter]);
|
rof2SayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -6255,29 +6256,29 @@ namespace RoF2
|
|||||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
// Diff:
|
// Diff:
|
||||||
|
|
||||||
rof2TextLink.push_back('\x12');
|
rof2SayLink.push_back('\x12');
|
||||||
rof2TextLink.append(segments[segment_iter]);
|
rof2SayLink.append(segments[segment_iter]);
|
||||||
rof2TextLink.push_back('\x12');
|
rof2SayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rof2TextLink.append(segments[segment_iter]);
|
rof2SayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink)
|
static inline void RoF2ToServerSayLink(std::string& serverSayLink, const std::string& rof2SayLink)
|
||||||
{
|
{
|
||||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (rof2TextLink.find('\x12') == std::string::npos)) {
|
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (rof2SayLink.find('\x12') == std::string::npos)) {
|
||||||
serverTextLink = rof2TextLink;
|
serverSayLink = rof2SayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(rof2TextLink, '\x12');
|
auto segments = SplitString(rof2SayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -6287,12 +6288,12 @@ namespace RoF2
|
|||||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
// Diff:
|
// Diff:
|
||||||
|
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -430,7 +430,7 @@ struct Spawn_Struct
|
|||||||
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
||||||
/*0064*/ uint32 spawnId;
|
/*0064*/ uint32 spawnId;
|
||||||
/*0068*/ uint8 level;
|
/*0068*/ uint8 level;
|
||||||
/*0069*/ float unknown1;
|
/*0069*/ float bounding_radius; // used in melee, overrides calc
|
||||||
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||||
Spawn_Struct_Bitfields Bitfields;
|
Spawn_Struct_Bitfields Bitfields;
|
||||||
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
||||||
@ -1462,17 +1462,17 @@ struct Action_Struct
|
|||||||
{
|
{
|
||||||
/*00*/ uint16 target; // id of target
|
/*00*/ uint16 target; // id of target
|
||||||
/*02*/ uint16 source; // id of caster
|
/*02*/ uint16 source; // id of caster
|
||||||
/*04*/ uint16 level; // level of caster - Seen 0
|
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/*06*/ uint32 unknown06;
|
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||||
/*10*/ float instrument_mod;
|
/*10*/ float instrument_mod;
|
||||||
/*14*/ uint32 bard_focus_id; // seen 0
|
/*14*/ float force;
|
||||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
/*18*/ float hit_heading;
|
||||||
/*22*/ uint32 unknown22;
|
/*22*/ float hit_pitch;
|
||||||
/*26*/ uint8 type;
|
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/*27*/ uint32 damage;
|
/*27*/ uint32 damage; // OSX says min_damage
|
||||||
/*31*/ uint16 unknown31;
|
/*31*/ uint16 unknown31; // OSX says tohit
|
||||||
/*33*/ uint32 spell; // spell id being cast
|
/*33*/ uint32 spell; // spell id being cast
|
||||||
/*37*/ uint8 level2; // level of caster again? Or maybe the castee
|
/*37*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||||
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||||
/*39*/
|
/*39*/
|
||||||
};
|
};
|
||||||
@ -1484,25 +1484,21 @@ struct ActionAlt_Struct
|
|||||||
{
|
{
|
||||||
/*00*/ uint16 target; // id of target
|
/*00*/ uint16 target; // id of target
|
||||||
/*02*/ uint16 source; // id of caster
|
/*02*/ uint16 source; // id of caster
|
||||||
/*04*/ uint16 level; // level of caster - Seen 0
|
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/*06*/ uint32 unknown06;
|
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||||
/*10*/ float instrument_mod;
|
/*10*/ float instrument_mod;
|
||||||
/*14*/ uint32 bard_focus_id; // seen 0
|
/*14*/ float force;
|
||||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
/*18*/ float hit_heading;
|
||||||
/*22*/ uint32 unknown22;
|
/*22*/ float hit_pitch;
|
||||||
/*26*/ uint8 type;
|
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/*27*/ uint32 damage;
|
/*27*/ uint32 damage; // OSX says min_damage
|
||||||
/*31*/ uint16 unknown31;
|
/*31*/ uint16 unknown31; // OSX says tohit
|
||||||
/*33*/ uint32 spell; // spell id being cast
|
/*33*/ uint32 spell; // spell id being cast
|
||||||
/*37*/ uint8 level2; // level of caster again? Or maybe the castee
|
/*37*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||||
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||||
/*39*/ uint32 unknown39; // New field to Underfoot - Seen 14
|
/*39*/ uint8 spell_gem;
|
||||||
/*43*/ uint8 unknown43; // New field to Underfoot - Seen 0
|
/*40*/ InventorySlot_Struct slot;
|
||||||
/*44*/ uint8 unknown44; // New field to Underfoot - Seen 17
|
/*52*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
|
||||||
/*45*/ uint8 unknown45; // New field to Underfoot - Seen 0
|
|
||||||
/*46*/ int32 unknown46; // New field to Underfoot - Seen -1
|
|
||||||
/*50*/ uint32 unknown50; // New field to Underfoot - Seen 0
|
|
||||||
/*54*/ uint16 unknown54; // New field to Underfoot - Seen 0
|
|
||||||
/*56*/
|
/*56*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1517,9 +1513,9 @@ struct CombatDamage_Struct
|
|||||||
/* 05 */ uint32 spellid;
|
/* 05 */ uint32 spellid;
|
||||||
/* 09 */ int32 damage;
|
/* 09 */ int32 damage;
|
||||||
/* 13 */ float force; // cd cc cc 3d
|
/* 13 */ float force; // cd cc cc 3d
|
||||||
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
|
/* 17 */ float hit_heading; // see above notes in Action_Struct
|
||||||
/* 21 */ float meleepush_z;
|
/* 21 */ float hit_pitch;
|
||||||
/* 25 */ uint8 unknown25; // was [9]
|
/* 25 */ uint8 secondary; // 0 for primary hand, 1 for secondary
|
||||||
/* 26 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
/* 26 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
||||||
/* 30 */
|
/* 30 */
|
||||||
};
|
};
|
||||||
@ -3605,21 +3601,6 @@ struct GuildSetRank_Struct
|
|||||||
/*80*/
|
/*80*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BugStruct{
|
|
||||||
/*0000*/ char chartype[64];
|
|
||||||
/*0064*/ char name[96];
|
|
||||||
/*0160*/ char ui[128];
|
|
||||||
/*0288*/ float x;
|
|
||||||
/*0292*/ float y;
|
|
||||||
/*0296*/ float z;
|
|
||||||
/*0300*/ float heading;
|
|
||||||
/*0304*/ uint32 unknown304;
|
|
||||||
/*0308*/ uint32 type;
|
|
||||||
/*0312*/ char unknown312[2144];
|
|
||||||
/*2456*/ char bug[1024];
|
|
||||||
/*3480*/ char placeholder[2];
|
|
||||||
/*3482*/ char system_info[4098];
|
|
||||||
};
|
|
||||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||||
uint8 level;
|
uint8 level;
|
||||||
uint8 class_;
|
uint8 class_;
|
||||||
@ -3646,20 +3627,21 @@ struct Ground_Spawn{
|
|||||||
struct Ground_Spawns {
|
struct Ground_Spawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
struct PetitionBug_Struct{
|
|
||||||
uint32 petition_number;
|
//struct PetitionBug_Struct{
|
||||||
uint32 unknown4;
|
// uint32 petition_number;
|
||||||
char accountname[64];
|
// uint32 unknown4;
|
||||||
uint32 zoneid;
|
// char accountname[64];
|
||||||
char name[64];
|
// uint32 zoneid;
|
||||||
uint32 level;
|
// char name[64];
|
||||||
uint32 class_;
|
// uint32 level;
|
||||||
uint32 race;
|
// uint32 class_;
|
||||||
uint32 unknown152[3];
|
// uint32 race;
|
||||||
uint32 time;
|
// uint32 unknown152[3];
|
||||||
uint32 unknown168;
|
// uint32 time;
|
||||||
char text[1028];
|
// uint32 unknown168;
|
||||||
};
|
// char text[1028];
|
||||||
|
//};
|
||||||
|
|
||||||
struct ApproveZone_Struct {
|
struct ApproveZone_Struct {
|
||||||
char name[64];
|
char name[64];
|
||||||
@ -5103,6 +5085,23 @@ struct CrystalCountUpdate_Struct
|
|||||||
/*012*/ uint32 CareerEbonCrystals;
|
/*012*/ uint32 CareerEbonCrystals;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SayLinkBodyFrame_Struct {
|
||||||
|
/*000*/ char ActionID[1];
|
||||||
|
/*001*/ char ItemID[5];
|
||||||
|
/*006*/ char Augment1[5];
|
||||||
|
/*011*/ char Augment2[5];
|
||||||
|
/*016*/ char Augment3[5];
|
||||||
|
/*021*/ char Augment4[5];
|
||||||
|
/*026*/ char Augment5[5];
|
||||||
|
/*031*/ char Augment6[5];
|
||||||
|
/*036*/ char IsEvolving[1];
|
||||||
|
/*037*/ char EvolveGroup[4];
|
||||||
|
/*041*/ char EvolveLevel[2];
|
||||||
|
/*043*/ char OrnamentIcon[5];
|
||||||
|
/*048*/ char Hash[8];
|
||||||
|
/*056*/
|
||||||
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|
||||||
}; /*RoF2*/
|
}; /*RoF2*/
|
||||||
|
|||||||
@ -408,7 +408,7 @@ struct Spawn_Struct
|
|||||||
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
||||||
/*0064*/ uint32 spawnId;
|
/*0064*/ uint32 spawnId;
|
||||||
/*0068*/ uint8 level;
|
/*0068*/ uint8 level;
|
||||||
/*0069*/ float unknown1;
|
/*0069*/ float bounding_radius; // used in melee, overrides calc
|
||||||
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||||
Spawn_Struct_Bitfields Bitfields;
|
Spawn_Struct_Bitfields Bitfields;
|
||||||
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
||||||
@ -1450,17 +1450,17 @@ struct Action_Struct
|
|||||||
{
|
{
|
||||||
/*00*/ uint16 target; // id of target
|
/*00*/ uint16 target; // id of target
|
||||||
/*02*/ uint16 source; // id of caster
|
/*02*/ uint16 source; // id of caster
|
||||||
/*04*/ uint16 level; // level of caster - Seen 0
|
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/*06*/ uint32 unknown06;
|
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||||
/*10*/ float instrument_mod;
|
/*10*/ float instrument_mod;
|
||||||
/*14*/ uint32 bard_focus_id; // seen 0
|
/*14*/ float force;
|
||||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
/*18*/ float hit_heading;
|
||||||
/*22*/ uint32 unknown22;
|
/*22*/ float hit_pitch;
|
||||||
/*26*/ uint8 type;
|
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/*27*/ uint32 damage;
|
/*27*/ uint32 damage; // OSX says min_damage
|
||||||
/*31*/ uint16 unknown31;
|
/*31*/ uint16 unknown31; // OSX says tohit
|
||||||
/*33*/ uint32 spell; // spell id being cast
|
/*33*/ uint32 spell; // spell id being cast
|
||||||
/*37*/ uint8 level2; // level of caster again? Or maybe the castee
|
/*37*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||||
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||||
/*39*/
|
/*39*/
|
||||||
};
|
};
|
||||||
@ -1472,25 +1472,21 @@ struct ActionAlt_Struct
|
|||||||
{
|
{
|
||||||
/*00*/ uint16 target; // id of target
|
/*00*/ uint16 target; // id of target
|
||||||
/*02*/ uint16 source; // id of caster
|
/*02*/ uint16 source; // id of caster
|
||||||
/*04*/ uint16 level; // level of caster - Seen 0
|
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/*06*/ uint32 unknown06;
|
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||||
/*10*/ float instrument_mod;
|
/*10*/ float instrument_mod;
|
||||||
/*14*/ uint32 bard_focus_id; // seen 0
|
/*14*/ float force;
|
||||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
/*18*/ float hit_heading;
|
||||||
/*22*/ uint32 unknown22;
|
/*22*/ float hit_pitch;
|
||||||
/*26*/ uint8 type;
|
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/*27*/ uint32 damage;
|
/*27*/ uint32 damage; // OSX says min_damage
|
||||||
/*31*/ uint16 unknown31;
|
/*31*/ uint16 unknown31; // OSX says tohit
|
||||||
/*33*/ uint32 spell; // spell id being cast
|
/*33*/ uint32 spell; // spell id being cast
|
||||||
/*37*/ uint8 level2; // level of caster again? Or maybe the castee
|
/*37*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||||
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
/*38*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||||
/*39*/ uint32 unknown39; // New field to Underfoot - Seen 14
|
/*39*/ uint8 spell_gem;
|
||||||
/*43*/ uint8 unknown43; // New field to Underfoot - Seen 0
|
/*40*/ InventorySlot_Struct slot;
|
||||||
/*44*/ uint8 unknown44; // New field to Underfoot - Seen 17
|
/*52*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
|
||||||
/*45*/ uint8 unknown45; // New field to Underfoot - Seen 0
|
|
||||||
/*46*/ int32 unknown46; // New field to Underfoot - Seen -1
|
|
||||||
/*50*/ uint32 unknown50; // New field to Underfoot - Seen 0
|
|
||||||
/*54*/ uint16 unknown54; // New field to Underfoot - Seen 0
|
|
||||||
/*56*/
|
/*56*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1505,9 +1501,9 @@ struct CombatDamage_Struct
|
|||||||
/* 05 */ uint32 spellid;
|
/* 05 */ uint32 spellid;
|
||||||
/* 09 */ int32 damage;
|
/* 09 */ int32 damage;
|
||||||
/* 13 */ float force; // cd cc cc 3d
|
/* 13 */ float force; // cd cc cc 3d
|
||||||
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
|
/* 17 */ float hit_heading; // see above notes in Action_Struct
|
||||||
/* 21 */ float meleepush_z;
|
/* 21 */ float hit_pitch;
|
||||||
/* 25 */ uint8 unknown25; // was [9]
|
/* 25 */ uint8 secondary; // 0 for primary hand, 1 for secondary
|
||||||
/* 26 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
/* 26 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
||||||
/* 30 */
|
/* 30 */
|
||||||
};
|
};
|
||||||
@ -3545,21 +3541,6 @@ struct GuildSetRank_Struct
|
|||||||
/*80*/
|
/*80*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BugStruct{
|
|
||||||
/*0000*/ char chartype[64];
|
|
||||||
/*0064*/ char name[96];
|
|
||||||
/*0160*/ char ui[128];
|
|
||||||
/*0288*/ float x;
|
|
||||||
/*0292*/ float y;
|
|
||||||
/*0296*/ float z;
|
|
||||||
/*0300*/ float heading;
|
|
||||||
/*0304*/ uint32 unknown304;
|
|
||||||
/*0308*/ uint32 type;
|
|
||||||
/*0312*/ char unknown312[2144];
|
|
||||||
/*2456*/ char bug[1024];
|
|
||||||
/*3480*/ char placeholder[2];
|
|
||||||
/*3482*/ char system_info[4098];
|
|
||||||
};
|
|
||||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||||
uint8 level;
|
uint8 level;
|
||||||
uint8 class_;
|
uint8 class_;
|
||||||
@ -3586,20 +3567,21 @@ struct Ground_Spawn{
|
|||||||
struct Ground_Spawns {
|
struct Ground_Spawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
struct PetitionBug_Struct{
|
|
||||||
uint32 petition_number;
|
//struct PetitionBug_Struct{
|
||||||
uint32 unknown4;
|
// uint32 petition_number;
|
||||||
char accountname[64];
|
// uint32 unknown4;
|
||||||
uint32 zoneid;
|
// char accountname[64];
|
||||||
char name[64];
|
// uint32 zoneid;
|
||||||
uint32 level;
|
// char name[64];
|
||||||
uint32 class_;
|
// uint32 level;
|
||||||
uint32 race;
|
// uint32 class_;
|
||||||
uint32 unknown152[3];
|
// uint32 race;
|
||||||
uint32 time;
|
// uint32 unknown152[3];
|
||||||
uint32 unknown168;
|
// uint32 time;
|
||||||
char text[1028];
|
// uint32 unknown168;
|
||||||
};
|
// char text[1028];
|
||||||
|
//};
|
||||||
|
|
||||||
struct ApproveZone_Struct {
|
struct ApproveZone_Struct {
|
||||||
char name[64];
|
char name[64];
|
||||||
@ -5020,6 +5002,23 @@ struct MercenaryMerchantRequest_Struct {
|
|||||||
struct MercenaryMerchantResponse_Struct {
|
struct MercenaryMerchantResponse_Struct {
|
||||||
/*0000*/ uint32 ResponseType;
|
/*0000*/ uint32 ResponseType;
|
||||||
/*0004*/
|
/*0004*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SayLinkBodyFrame_Struct {
|
||||||
|
/*000*/ char ActionID[1];
|
||||||
|
/*001*/ char ItemID[5];
|
||||||
|
/*006*/ char Augment1[5];
|
||||||
|
/*011*/ char Augment2[5];
|
||||||
|
/*016*/ char Augment3[5];
|
||||||
|
/*021*/ char Augment4[5];
|
||||||
|
/*026*/ char Augment5[5];
|
||||||
|
/*031*/ char Augment6[5];
|
||||||
|
/*036*/ char IsEvolving[1];
|
||||||
|
/*037*/ char EvolveGroup[4];
|
||||||
|
/*041*/ char EvolveLevel[1];
|
||||||
|
/*042*/ char OrnamentIcon[5];
|
||||||
|
/*047*/ char Hash[8];
|
||||||
|
/*055*/
|
||||||
};
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|||||||
@ -53,11 +53,11 @@ namespace SoD
|
|||||||
static inline uint32 SoDToServerSlot(uint32 sodSlot);
|
static inline uint32 SoDToServerSlot(uint32 sodSlot);
|
||||||
static inline uint32 SoDToServerCorpseSlot(uint32 sodCorpseSlot);
|
static inline uint32 SoDToServerCorpseSlot(uint32 sodCorpseSlot);
|
||||||
|
|
||||||
// server to client text link converter
|
// server to client say link converter
|
||||||
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink);
|
static inline void ServerToSoDSayLink(std::string& sodSayLink, const std::string& serverSayLink);
|
||||||
|
|
||||||
// client to server text link converter
|
// client to server say link converter
|
||||||
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink);
|
static inline void SoDToServerSayLink(std::string& serverSayLink, const std::string& sodSayLink);
|
||||||
|
|
||||||
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot);
|
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot);
|
||||||
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot);
|
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot);
|
||||||
@ -161,15 +161,14 @@ namespace SoD
|
|||||||
OUT(source);
|
OUT(source);
|
||||||
OUT(level);
|
OUT(level);
|
||||||
OUT(instrument_mod);
|
OUT(instrument_mod);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force);
|
||||||
|
OUT(hit_heading);
|
||||||
|
OUT(hit_pitch);
|
||||||
OUT(type);
|
OUT(type);
|
||||||
//OUT(damage);
|
//OUT(damage);
|
||||||
OUT(spell);
|
OUT(spell);
|
||||||
eq->level2 = emu->level;
|
OUT(spell_level);
|
||||||
OUT(buff_unknown); // if this is 4, a buff icon is made
|
OUT(effect_flag); // if this is 4, a buff icon is made
|
||||||
//eq->unknown0036 = -1;
|
|
||||||
//eq->unknown0040 = -1;
|
|
||||||
//eq->unknown0044 = -1;
|
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -346,7 +345,7 @@ namespace SoD
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToSoDTextLink(new_message, old_message);
|
ServerToSoDSayLink(new_message, old_message);
|
||||||
|
|
||||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||||
|
|
||||||
@ -458,8 +457,8 @@ namespace SoD
|
|||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
OUT(force);
|
OUT(force);
|
||||||
OUT(meleepush_xy);
|
OUT(hit_heading);
|
||||||
OUT(meleepush_z);
|
OUT(hit_pitch);
|
||||||
OUT(special);
|
OUT(special);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -625,7 +624,7 @@ namespace SoD
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToSoDTextLink(new_message, old_message);
|
ServerToSoDSayLink(new_message, old_message);
|
||||||
|
|
||||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||||
// new_message = new_message.substr(0, 512);
|
// new_message = new_message.substr(0, 512);
|
||||||
@ -677,7 +676,7 @@ namespace SoD
|
|||||||
|
|
||||||
for (int i = 0; i < 9; ++i) {
|
for (int i = 0; i < 9; ++i) {
|
||||||
if (old_message_array[i].length() == 0) { break; }
|
if (old_message_array[i].length() == 0) { break; }
|
||||||
ServerToSoDTextLink(new_message_array[i], old_message_array[i]);
|
ServerToSoDSayLink(new_message_array[i], old_message_array[i]);
|
||||||
new_message_size += new_message_array[i].length() + 1;
|
new_message_size += new_message_array[i].length() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2156,7 +2155,7 @@ namespace SoD
|
|||||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
|
|
||||||
ServerToSoDTextLink(new_message, old_message);
|
ServerToSoDSayLink(new_message, old_message);
|
||||||
|
|
||||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||||
@ -2252,7 +2251,7 @@ namespace SoD
|
|||||||
|
|
||||||
std::string old_message = InBuffer; // start 'Reward' as string
|
std::string old_message = InBuffer; // start 'Reward' as string
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToSoDTextLink(new_message, old_message);
|
ServerToSoDSayLink(new_message, old_message);
|
||||||
|
|
||||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
||||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
||||||
@ -2933,25 +2932,6 @@ namespace SoD
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
DECODE(OP_Bug)
|
|
||||||
{
|
|
||||||
DECODE_LENGTH_EXACT(structs::BugStruct);
|
|
||||||
SETUP_DIRECT_DECODE(BugStruct, structs::BugStruct);
|
|
||||||
|
|
||||||
strn0cpy(emu->chartype, eq->chartype, sizeof(emu->chartype));
|
|
||||||
strn0cpy(emu->name, eq->name, sizeof(emu->name));
|
|
||||||
strn0cpy(emu->ui, eq->ui, sizeof(emu->ui));
|
|
||||||
IN(x);
|
|
||||||
IN(y);
|
|
||||||
IN(z);
|
|
||||||
IN(heading);
|
|
||||||
strn0cpy(emu->target_name, eq->target_name, sizeof(emu->target_name));
|
|
||||||
strn0cpy(emu->bug, eq->bug, sizeof(emu->bug));
|
|
||||||
strn0cpy(emu->system_info, eq->system_info, sizeof(emu->system_info));
|
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
|
||||||
}
|
|
||||||
|
|
||||||
DECODE(OP_CastSpell)
|
DECODE(OP_CastSpell)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
|
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
|
||||||
@ -2972,7 +2952,7 @@ namespace SoD
|
|||||||
|
|
||||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
SoDToServerTextLink(new_message, old_message);
|
SoDToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
__packet->pBuffer = new unsigned char[__packet->size];
|
||||||
@ -3086,7 +3066,7 @@ namespace SoD
|
|||||||
|
|
||||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
SoDToServerTextLink(new_message, old_message);
|
SoDToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
__packet->size = sizeof(Emote_Struct);
|
__packet->size = sizeof(Emote_Struct);
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
__packet->pBuffer = new unsigned char[__packet->size];
|
||||||
@ -3936,19 +3916,19 @@ namespace SoD
|
|||||||
return (sodCorpseSlot - 1);
|
return (sodCorpseSlot - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink)
|
static inline void ServerToSoDSayLink(std::string& sodSayLink, const std::string& serverSayLink)
|
||||||
{
|
{
|
||||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||||
sodTextLink = serverTextLink;
|
sodSayLink = serverSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(serverTextLink, '\x12');
|
auto segments = SplitString(serverSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||||
sodTextLink.append(segments[segment_iter]);
|
sodSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3958,37 +3938,37 @@ namespace SoD
|
|||||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||||
// Diff: ^^^^^ ^
|
// Diff: ^^^^^ ^
|
||||||
|
|
||||||
sodTextLink.push_back('\x12');
|
sodSayLink.push_back('\x12');
|
||||||
sodTextLink.append(segments[segment_iter].substr(0, 31));
|
sodSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
sodTextLink.append(segments[segment_iter].substr(36, 5));
|
sodSayLink.append(segments[segment_iter].substr(36, 5));
|
||||||
|
|
||||||
if (segments[segment_iter][41] == '0')
|
if (segments[segment_iter][41] == '0')
|
||||||
sodTextLink.push_back(segments[segment_iter][42]);
|
sodSayLink.push_back(segments[segment_iter][42]);
|
||||||
else
|
else
|
||||||
sodTextLink.push_back('F');
|
sodSayLink.push_back('F');
|
||||||
|
|
||||||
sodTextLink.append(segments[segment_iter].substr(43));
|
sodSayLink.append(segments[segment_iter].substr(43));
|
||||||
sodTextLink.push_back('\x12');
|
sodSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sodTextLink.append(segments[segment_iter]);
|
sodSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink)
|
static inline void SoDToServerSayLink(std::string& serverSayLink, const std::string& sodSayLink)
|
||||||
{
|
{
|
||||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (sodTextLink.find('\x12') == std::string::npos)) {
|
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (sodSayLink.find('\x12') == std::string::npos)) {
|
||||||
serverTextLink = sodTextLink;
|
serverSayLink = sodSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(sodTextLink, '\x12');
|
auto segments = SplitString(sodSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3998,16 +3978,16 @@ namespace SoD
|
|||||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
// Diff: ^^^^^ ^
|
// Diff: ^^^^^ ^
|
||||||
|
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
serverTextLink.append(segments[segment_iter].substr(0, 31));
|
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
serverTextLink.append("00000");
|
serverSayLink.append("00000");
|
||||||
serverTextLink.append(segments[segment_iter].substr(31, 5));
|
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||||
serverTextLink.push_back('0');
|
serverSayLink.push_back('0');
|
||||||
serverTextLink.append(segments[segment_iter].substr(36));
|
serverSayLink.append(segments[segment_iter].substr(36));
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -104,7 +104,6 @@ D(OP_AugmentInfo)
|
|||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
D(OP_BazaarSearch)
|
D(OP_BazaarSearch)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
D(OP_Bug)
|
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_ChannelMessage)
|
D(OP_ChannelMessage)
|
||||||
D(OP_CharacterCreate)
|
D(OP_CharacterCreate)
|
||||||
|
|||||||
@ -292,7 +292,7 @@ struct Spawn_Struct
|
|||||||
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
||||||
/*0064*/ uint32 spawnId;
|
/*0064*/ uint32 spawnId;
|
||||||
/*0068*/ uint8 level;
|
/*0068*/ uint8 level;
|
||||||
/*0069*/ float unknown1;
|
/*0069*/ float bounding_radius; // used in melee, overrides calc
|
||||||
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||||
Spawn_Struct_Bitfields Bitfields;
|
Spawn_Struct_Bitfields Bitfields;
|
||||||
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
||||||
@ -1215,20 +1215,18 @@ struct Action_Struct
|
|||||||
{
|
{
|
||||||
/* 00 */ uint16 target; // id of target
|
/* 00 */ uint16 target; // id of target
|
||||||
/* 02 */ uint16 source; // id of caster
|
/* 02 */ uint16 source; // id of caster
|
||||||
/* 04 */ uint16 level; // level of caster
|
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/* 06 */ uint16 instrument_mod; // seems to be fixed to 0x0A
|
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||||
/* 08 */ uint32 unknown08;
|
/* 10 */ float force;
|
||||||
/* 12 */ uint16 unknown16;
|
/* 14 */ float hit_heading;
|
||||||
// some kind of sequence that's the same in both actions
|
/* 18 */ float hit_pitch;
|
||||||
// as well as the combat damage, to tie em together?
|
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/* 14 */ float sequence; // was uint32
|
/* 23 */ uint16 unknown23; // OSX says min_damage
|
||||||
/* 18 */ uint32 unknown18;
|
/* 25 */ uint16 unknown25; // OSX says tohit
|
||||||
/* 22 */ uint8 type; // 231 (0xE7) for spells
|
|
||||||
/* 23 */ uint32 unknown23;
|
|
||||||
/* 27 */ uint16 spell; // spell id being cast
|
/* 27 */ uint16 spell; // spell id being cast
|
||||||
/* 29 */ uint8 level2; // level of caster again? Or maybe the castee
|
/* 29 */ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||||
// this field seems to be some sort of success flag, if it's 4
|
// this field seems to be some sort of success flag, if it's 4
|
||||||
/* 30 */ uint8 buff_unknown; // if this is 4, a buff icon is made
|
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||||
/* 31 */
|
/* 31 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1237,26 +1235,23 @@ struct Action_Struct
|
|||||||
// has to do with buff blocking??
|
// has to do with buff blocking??
|
||||||
struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
|
struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
|
||||||
{
|
{
|
||||||
/*0000*/ uint16 target; // Target ID
|
/*0000*/ uint16 target; // id of target
|
||||||
/*0002*/ uint16 source; // SourceID
|
/*0002*/ uint16 source; // id of caster
|
||||||
/*0004*/ uint16 level; // level of caster
|
/*0004*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/*0006*/ uint16 instrument_mod; // seems to be fixed to 0x0A
|
/*0006*/ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||||
/*0008*/ uint32 unknown08;
|
/*0010*/ float force;
|
||||||
/*0012*/ uint16 unknown16;
|
/*0014*/ float hit_heading;
|
||||||
/*0014*/ uint32 sequence;
|
/*0018*/ float hit_pitch;
|
||||||
/*0018*/ uint32 unknown18;
|
/*0022*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/*0022*/ uint8 type; // Casts, Falls, Bashes, etc...
|
/*0023*/ uint16 unknown23; // OSX says min_damage
|
||||||
/*0023*/ uint32 damage; // Amount of Damage
|
/*0025*/ uint16 unknown25; // OSX says tohit
|
||||||
/*0027*/ uint16 spell; // SpellID
|
/*0027*/ uint16 spell; // spell id being cast
|
||||||
/*0029*/ uint8 unknown29;
|
/*0029*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||||
/*0030*/ uint8 buff_unknown; // if this is 4, a buff icon is made
|
// this field seems to be some sort of success flag, if it's 4
|
||||||
/*0031*/ uint32 unknown0031; // seen 00 00 00 00
|
/*0030*/ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||||
/*0035*/ uint8 unknown0035; // seen 00
|
/*0031*/ uint8 spell_slot;
|
||||||
/*0036*/ uint32 unknown0036; // seen ff ff ff ff
|
/*0032*/ uint32 slot[5];
|
||||||
/*0040*/ uint32 unknown0040; // seen ff ff ff ff
|
/*0052*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
|
||||||
/*0044*/ uint32 unknown0044; // seen ff ff ff ff
|
|
||||||
/*0048*/ uint32 unknown0048; // seen 00 00 00 00
|
|
||||||
/*0052*/ uint32 unknown0052; // seen 00 00 00 00
|
|
||||||
/*0056*/
|
/*0056*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1271,9 +1266,9 @@ struct CombatDamage_Struct
|
|||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ int32 damage;
|
/* 07 */ int32 damage;
|
||||||
/* 11 */ float force; // cd cc cc 3d
|
/* 11 */ float force; // cd cc cc 3d
|
||||||
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
/* 15 */ float hit_heading; // see above notes in Action_Struct
|
||||||
/* 19 */ float meleepush_z;
|
/* 19 */ float hit_pitch;
|
||||||
/* 23 */ uint8 unknown23; // was [9]
|
/* 23 */ uint8 secondary; // 0 for primary hand, 1 for secondary
|
||||||
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
||||||
/* 28 */
|
/* 28 */
|
||||||
};
|
};
|
||||||
@ -3008,24 +3003,6 @@ struct GuildMakeLeader{
|
|||||||
char target[64];
|
char target[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BugStruct{
|
|
||||||
/*0000*/ uint32 type1; //seems to be just a different way of seeing type; seems to be ordered completely differently
|
|
||||||
/*0004*/ char chartype[64];
|
|
||||||
/*0068*/ char name[96];
|
|
||||||
/*0164*/ char ui[128];
|
|
||||||
/*0292*/ float x;
|
|
||||||
/*0296*/ float y;
|
|
||||||
/*0300*/ float z;
|
|
||||||
/*0304*/ float heading;
|
|
||||||
/*0308*/ uint32 unknown304;
|
|
||||||
/*0312*/ char unknown308[160];
|
|
||||||
/*0472*/ char target_name[64];
|
|
||||||
/*0536*/ uint32 type;
|
|
||||||
/*0540*/ char unknown536[2052];
|
|
||||||
/*2588*/ char bug[2048];
|
|
||||||
/*4636*/ char unknown4632[6];
|
|
||||||
/*4642*/ char system_info[4094];
|
|
||||||
};
|
|
||||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||||
uint8 level;
|
uint8 level;
|
||||||
uint8 class_;
|
uint8 class_;
|
||||||
@ -3052,20 +3029,21 @@ struct Ground_Spawn{
|
|||||||
struct Ground_Spawns {
|
struct Ground_Spawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
struct PetitionBug_Struct{
|
|
||||||
uint32 petition_number;
|
//struct PetitionBug_Struct{
|
||||||
uint32 unknown4;
|
// uint32 petition_number;
|
||||||
char accountname[64];
|
// uint32 unknown4;
|
||||||
uint32 zoneid;
|
// char accountname[64];
|
||||||
char name[64];
|
// uint32 zoneid;
|
||||||
uint32 level;
|
// char name[64];
|
||||||
uint32 class_;
|
// uint32 level;
|
||||||
uint32 race;
|
// uint32 class_;
|
||||||
uint32 unknown152[3];
|
// uint32 race;
|
||||||
uint32 time;
|
// uint32 unknown152[3];
|
||||||
uint32 unknown168;
|
// uint32 time;
|
||||||
char text[1028];
|
// uint32 unknown168;
|
||||||
};
|
// char text[1028];
|
||||||
|
//};
|
||||||
|
|
||||||
struct ApproveZone_Struct {
|
struct ApproveZone_Struct {
|
||||||
char name[64];
|
char name[64];
|
||||||
@ -4402,6 +4380,22 @@ struct MercenaryAssign_Struct {
|
|||||||
/*0004*/ uint32 MercUnk01; //
|
/*0004*/ uint32 MercUnk01; //
|
||||||
/*0008*/ uint32 MercUnk02; //
|
/*0008*/ uint32 MercUnk02; //
|
||||||
/*0012*/
|
/*0012*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SayLinkBodyFrame_Struct {
|
||||||
|
/*000*/ char ActionID[1];
|
||||||
|
/*001*/ char ItemID[5];
|
||||||
|
/*006*/ char Augment1[5];
|
||||||
|
/*011*/ char Augment2[5];
|
||||||
|
/*016*/ char Augment3[5];
|
||||||
|
/*021*/ char Augment4[5];
|
||||||
|
/*026*/ char Augment5[5];
|
||||||
|
/*031*/ char IsEvolving[1];
|
||||||
|
/*032*/ char EvolveGroup[4];
|
||||||
|
/*036*/ char EvolveLevel[1];
|
||||||
|
/*037*/ char OrnamentIcon[5];
|
||||||
|
/*042*/ char Hash[8];
|
||||||
|
/*050*/
|
||||||
};
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|||||||
@ -53,11 +53,11 @@ namespace SoF
|
|||||||
static inline uint32 SoFToServerSlot(uint32 sofSlot);
|
static inline uint32 SoFToServerSlot(uint32 sofSlot);
|
||||||
static inline uint32 SoFToServerCorpseSlot(uint32 sofCorpseSlot);
|
static inline uint32 SoFToServerCorpseSlot(uint32 sofCorpseSlot);
|
||||||
|
|
||||||
// server to client text link converter
|
// server to client say link converter
|
||||||
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink);
|
static inline void ServerToSoFSayLink(std::string& sofSayLink, const std::string& serverSayLink);
|
||||||
|
|
||||||
// client to server text link converter
|
// client to server say link converter
|
||||||
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink);
|
static inline void SoFToServerSayLink(std::string& serverSayLink, const std::string& sofSayLink);
|
||||||
|
|
||||||
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot);
|
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot);
|
||||||
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
|
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
|
||||||
@ -161,15 +161,14 @@ namespace SoF
|
|||||||
OUT(source);
|
OUT(source);
|
||||||
OUT(level);
|
OUT(level);
|
||||||
OUT(instrument_mod);
|
OUT(instrument_mod);
|
||||||
eq->sequence = emu->sequence;
|
OUT(force);
|
||||||
|
OUT(hit_heading);
|
||||||
|
OUT(hit_pitch);
|
||||||
OUT(type);
|
OUT(type);
|
||||||
//OUT(damage);
|
//OUT(damage);
|
||||||
OUT(spell);
|
OUT(spell);
|
||||||
eq->level2 = emu->level;
|
OUT(spell_level);
|
||||||
OUT(buff_unknown); // if this is 4, a buff icon is made
|
OUT(effect_flag); // if this is 4, a buff icon is made
|
||||||
//eq->unknown0036 = -1;
|
|
||||||
//eq->unknown0040 = -1;
|
|
||||||
//eq->unknown0044 = -1;
|
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -328,7 +327,7 @@ namespace SoF
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToSoFTextLink(new_message, old_message);
|
ServerToSoFSayLink(new_message, old_message);
|
||||||
|
|
||||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||||
|
|
||||||
@ -440,8 +439,8 @@ namespace SoF
|
|||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
OUT(force);
|
OUT(force);
|
||||||
OUT(meleepush_xy);
|
OUT(hit_heading);
|
||||||
OUT(meleepush_z);
|
OUT(hit_pitch);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -613,7 +612,7 @@ namespace SoF
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToSoFTextLink(new_message, old_message);
|
ServerToSoFSayLink(new_message, old_message);
|
||||||
|
|
||||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||||
// new_message = new_message.substr(0, 512);
|
// new_message = new_message.substr(0, 512);
|
||||||
@ -665,7 +664,7 @@ namespace SoF
|
|||||||
|
|
||||||
for (int i = 0; i < 9; ++i) {
|
for (int i = 0; i < 9; ++i) {
|
||||||
if (old_message_array[i].length() == 0) { break; }
|
if (old_message_array[i].length() == 0) { break; }
|
||||||
ServerToSoFTextLink(new_message_array[i], old_message_array[i]);
|
ServerToSoFSayLink(new_message_array[i], old_message_array[i]);
|
||||||
new_message_size += new_message_array[i].length() + 1;
|
new_message_size += new_message_array[i].length() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1814,7 +1813,7 @@ namespace SoF
|
|||||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
|
|
||||||
ServerToSoFTextLink(new_message, old_message);
|
ServerToSoFSayLink(new_message, old_message);
|
||||||
|
|
||||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||||
@ -1882,7 +1881,7 @@ namespace SoF
|
|||||||
|
|
||||||
std::string old_message = InBuffer; // start 'Reward' as string
|
std::string old_message = InBuffer; // start 'Reward' as string
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToSoFTextLink(new_message, old_message);
|
ServerToSoFSayLink(new_message, old_message);
|
||||||
|
|
||||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
||||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
||||||
@ -2385,6 +2384,17 @@ namespace SoF
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_Bug)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::BugReport_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BugReport_Struct, structs::BugReport_Struct);
|
||||||
|
|
||||||
|
emu->category_id = EQEmu::bug::CategoryNameToCategoryID(eq->category_name);
|
||||||
|
memcpy(emu->category_name, eq, sizeof(structs::BugReport_Struct));
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_CastSpell)
|
DECODE(OP_CastSpell)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
|
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
|
||||||
@ -2404,7 +2414,7 @@ namespace SoF
|
|||||||
|
|
||||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
SoFToServerTextLink(new_message, old_message);
|
SoFToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
__packet->pBuffer = new unsigned char[__packet->size];
|
||||||
@ -2518,7 +2528,7 @@ namespace SoF
|
|||||||
|
|
||||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
SoFToServerTextLink(new_message, old_message);
|
SoFToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
__packet->size = sizeof(Emote_Struct);
|
__packet->size = sizeof(Emote_Struct);
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
__packet->pBuffer = new unsigned char[__packet->size];
|
||||||
@ -3305,19 +3315,19 @@ namespace SoF
|
|||||||
return (sofCorpseSlot - 1);
|
return (sofCorpseSlot - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink)
|
static inline void ServerToSoFSayLink(std::string& sofSayLink, const std::string& serverSayLink)
|
||||||
{
|
{
|
||||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||||
sofTextLink = serverTextLink;
|
sofSayLink = serverSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(serverTextLink, '\x12');
|
auto segments = SplitString(serverSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||||
sofTextLink.append(segments[segment_iter]);
|
sofSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3327,37 +3337,37 @@ namespace SoF
|
|||||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||||
// Diff: ^^^^^ ^
|
// Diff: ^^^^^ ^
|
||||||
|
|
||||||
sofTextLink.push_back('\x12');
|
sofSayLink.push_back('\x12');
|
||||||
sofTextLink.append(segments[segment_iter].substr(0, 31));
|
sofSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
sofTextLink.append(segments[segment_iter].substr(36, 5));
|
sofSayLink.append(segments[segment_iter].substr(36, 5));
|
||||||
|
|
||||||
if (segments[segment_iter][41] == '0')
|
if (segments[segment_iter][41] == '0')
|
||||||
sofTextLink.push_back(segments[segment_iter][42]);
|
sofSayLink.push_back(segments[segment_iter][42]);
|
||||||
else
|
else
|
||||||
sofTextLink.push_back('F');
|
sofSayLink.push_back('F');
|
||||||
|
|
||||||
sofTextLink.append(segments[segment_iter].substr(43));
|
sofSayLink.append(segments[segment_iter].substr(43));
|
||||||
sofTextLink.push_back('\x12');
|
sofSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sofTextLink.append(segments[segment_iter]);
|
sofSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink)
|
static inline void SoFToServerSayLink(std::string& serverSayLink, const std::string& sofSayLink)
|
||||||
{
|
{
|
||||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (sofTextLink.find('\x12') == std::string::npos)) {
|
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (sofSayLink.find('\x12') == std::string::npos)) {
|
||||||
serverTextLink = sofTextLink;
|
serverSayLink = sofSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(sofTextLink, '\x12');
|
auto segments = SplitString(sofSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -3367,16 +3377,16 @@ namespace SoF
|
|||||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
// Diff: ^^^^^ ^
|
// Diff: ^^^^^ ^
|
||||||
|
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
serverTextLink.append(segments[segment_iter].substr(0, 31));
|
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
serverTextLink.append("00000");
|
serverSayLink.append("00000");
|
||||||
serverTextLink.append(segments[segment_iter].substr(31, 5));
|
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||||
serverTextLink.push_back('0');
|
serverSayLink.push_back('0');
|
||||||
serverTextLink.append(segments[segment_iter].substr(36));
|
serverSayLink.append(segments[segment_iter].substr(36));
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -95,6 +95,7 @@ D(OP_ApplyPoison)
|
|||||||
D(OP_AugmentInfo)
|
D(OP_AugmentInfo)
|
||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
|
D(OP_Bug)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_ChannelMessage)
|
D(OP_ChannelMessage)
|
||||||
D(OP_CharacterCreate)
|
D(OP_CharacterCreate)
|
||||||
|
|||||||
@ -326,7 +326,8 @@ union
|
|||||||
/*0725*/ uint8 targetable; // 1 = Targetable 0 = Not Targetable (is_npc?)
|
/*0725*/ uint8 targetable; // 1 = Targetable 0 = Not Targetable (is_npc?)
|
||||||
/*0726*/ uint8 unknown0726[4];
|
/*0726*/ uint8 unknown0726[4];
|
||||||
/*0730*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
/*0730*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||||
/*0731*/ uint8 unknown0731[11];
|
/*0731*/ float bounding_radius; // used in melee, overrides calc
|
||||||
|
/*0735*/ uint8 unknown0731[7];
|
||||||
/*0742*/ uint8 targetable_with_hotkey;
|
/*0742*/ uint8 targetable_with_hotkey;
|
||||||
/*0743*/ signed padding00:12; // ***Placeholder
|
/*0743*/ signed padding00:12; // ***Placeholder
|
||||||
signed x:19; // x coord
|
signed x:19; // x coord
|
||||||
@ -1214,20 +1215,18 @@ struct Action_Struct
|
|||||||
{
|
{
|
||||||
/* 00 */ uint16 target; // id of target
|
/* 00 */ uint16 target; // id of target
|
||||||
/* 02 */ uint16 source; // id of caster
|
/* 02 */ uint16 source; // id of caster
|
||||||
/* 04 */ uint16 level; // level of caster
|
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/* 06 */ uint16 instrument_mod; // seems to be fixed to 0x0A
|
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||||
/* 08 */ uint32 unknown08;
|
/* 10 */ float force;
|
||||||
/* 12 */ uint16 unknown16;
|
/* 14 */ float hit_heading;
|
||||||
// some kind of sequence that's the same in both actions
|
/* 18 */ float hit_pitch;
|
||||||
// as well as the combat damage, to tie em together?
|
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/* 14 */ float sequence; // was uint32
|
/* 23 */ uint16 unknown23; // OSX says min_damage
|
||||||
/* 18 */ uint32 unknown18;
|
/* 25 */ uint16 unknown25; // OSX says tohit
|
||||||
/* 22 */ uint8 type; // 231 (0xE7) for spells
|
|
||||||
/* 23 */ uint32 unknown23;
|
|
||||||
/* 27 */ uint16 spell; // spell id being cast
|
/* 27 */ uint16 spell; // spell id being cast
|
||||||
/* 29 */ uint8 level2; // level of caster again? Or maybe the castee
|
/* 29 */ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||||
// this field seems to be some sort of success flag, if it's 4
|
// this field seems to be some sort of success flag, if it's 4
|
||||||
/* 30 */ uint8 buff_unknown; // if this is 4, a buff icon is made
|
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||||
/* 31 */
|
/* 31 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1236,26 +1235,23 @@ struct Action_Struct
|
|||||||
// has to do with buff blocking??
|
// has to do with buff blocking??
|
||||||
struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
|
struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
|
||||||
{
|
{
|
||||||
/*0000*/ uint16 target; // Target ID
|
/*0000*/ uint16 target; // id of target
|
||||||
/*0002*/ uint16 source; // SourceID
|
/*0002*/ uint16 source; // id of caster
|
||||||
/*0004*/ uint16 level; // level of caster
|
/*0004*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/*0006*/ uint16 instrument_mod; // seems to be fixed to 0x0A
|
/*0006*/ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||||
/*0008*/ uint32 unknown08;
|
/*0010*/ float force;
|
||||||
/*0012*/ uint16 unknown16;
|
/*0014*/ float hit_heading;
|
||||||
/*0014*/ uint32 sequence;
|
/*0018*/ float hit_pitch;
|
||||||
/*0018*/ uint32 unknown18;
|
/*0022*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/*0022*/ uint8 type; // Casts, Falls, Bashes, etc...
|
/*0023*/ uint16 unknown23; // OSX says min_damage
|
||||||
/*0023*/ uint32 damage; // Amount of Damage
|
/*0025*/ uint16 unknown25; // OSX says tohit
|
||||||
/*0027*/ uint16 spell; // SpellID
|
/*0027*/ uint16 spell; // spell id being cast
|
||||||
/*0029*/ uint8 unknown29;
|
/*0029*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||||
/*0030*/ uint8 buff_unknown; // if this is 4, a buff icon is made
|
// this field seems to be some sort of success flag, if it's 4
|
||||||
/*0031*/ uint32 unknown0031; // seen 00 00 00 00
|
/*0030*/ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||||
/*0035*/ uint8 unknown0035; // seen 00
|
/*0031*/ uint8 spell_slot;
|
||||||
/*0036*/ uint32 unknown0036; // seen ff ff ff ff
|
/*0032*/ uint32 slot[5];
|
||||||
/*0040*/ uint32 unknown0040; // seen ff ff ff ff
|
/*0052*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
|
||||||
/*0044*/ uint32 unknown0044; // seen ff ff ff ff
|
|
||||||
/*0048*/ uint32 unknown0048; // seen 00 00 00 00
|
|
||||||
/*0052*/ uint32 unknown0052; // seen 00 00 00 00
|
|
||||||
/*0056*/
|
/*0056*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1270,9 +1266,10 @@ struct CombatDamage_Struct
|
|||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ int32 damage;
|
/* 07 */ int32 damage;
|
||||||
/* 11 */ float force; // cd cc cc 3d
|
/* 11 */ float force; // cd cc cc 3d
|
||||||
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
/* 15 */ float hit_heading; // see above notes in Action_Struct
|
||||||
/* 19 */ float meleepush_z;
|
/* 19 */ float hit_pitch;
|
||||||
/* 23 */ uint8 unknown23[5]; // was [9] this appears unrelated to the stuff the other clients do here?
|
/* 23 */ uint8 secondary; // 0 for primary hand, 1 for secondary
|
||||||
|
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage, Report function doesn't seem to check this :P
|
||||||
/* 28 */
|
/* 28 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2906,23 +2903,31 @@ struct GuildMakeLeader{
|
|||||||
char target[64];
|
char target[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BugReport_Struct {
|
||||||
|
/*0000*/ char category_name[64];
|
||||||
|
/*0064*/ char character_name[64];
|
||||||
|
/*0128*/ char unused_0128[32];
|
||||||
|
/*0160*/ char ui_path[128];
|
||||||
|
/*0288*/ float pos_x;
|
||||||
|
/*0292*/ float pos_y;
|
||||||
|
/*0296*/ float pos_z;
|
||||||
|
/*0300*/ uint32 heading;
|
||||||
|
/*0304*/ uint32 unused_0304;
|
||||||
|
/*0308*/ uint32 time_played;
|
||||||
|
/*0312*/ char padding_0312[8];
|
||||||
|
/*0320*/ uint32 target_id;
|
||||||
|
/*0324*/ char padding_0324[140];
|
||||||
|
/*0464*/ uint32 unknown_0464; // seems to always be '0'
|
||||||
|
/*0468*/ char target_name[64];
|
||||||
|
/*0532*/ uint32 optional_info_mask;
|
||||||
|
|
||||||
|
// this looks like a butchered 8k buffer with 2 trailing dword fields
|
||||||
struct BugStruct{
|
/*0536*/ char unused_0536[2052];
|
||||||
/*0000*/ char chartype[64];
|
/*2588*/ char bug_report[2050];
|
||||||
/*0064*/ char name[96];
|
/*4638*/ char system_info[4098];
|
||||||
/*0160*/ char ui[128];
|
/*8736*/
|
||||||
/*0288*/ float x;
|
|
||||||
/*0292*/ float y;
|
|
||||||
/*0296*/ float z;
|
|
||||||
/*0300*/ float heading;
|
|
||||||
/*0304*/ uint32 unknown304;
|
|
||||||
/*0308*/ uint32 type;
|
|
||||||
/*0312*/ char unknown312[2144];
|
|
||||||
/*2456*/ char bug[1024];
|
|
||||||
/*3480*/ char placeholder[2];
|
|
||||||
/*3482*/ char system_info[4098];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||||
uint8 level;
|
uint8 level;
|
||||||
uint8 class_;
|
uint8 class_;
|
||||||
@ -2949,20 +2954,21 @@ struct Ground_Spawn{
|
|||||||
struct Ground_Spawns {
|
struct Ground_Spawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
struct PetitionBug_Struct{
|
|
||||||
uint32 petition_number;
|
//struct PetitionBug_Struct{
|
||||||
uint32 unknown4;
|
// uint32 petition_number;
|
||||||
char accountname[64];
|
// uint32 unknown4;
|
||||||
uint32 zoneid;
|
// char accountname[64];
|
||||||
char name[64];
|
// uint32 zoneid;
|
||||||
uint32 level;
|
// char name[64];
|
||||||
uint32 class_;
|
// uint32 level;
|
||||||
uint32 race;
|
// uint32 class_;
|
||||||
uint32 unknown152[3];
|
// uint32 race;
|
||||||
uint32 time;
|
// uint32 unknown152[3];
|
||||||
uint32 unknown168;
|
// uint32 time;
|
||||||
char text[1028];
|
// uint32 unknown168;
|
||||||
};
|
// char text[1028];
|
||||||
|
//};
|
||||||
|
|
||||||
struct ApproveZone_Struct {
|
struct ApproveZone_Struct {
|
||||||
char name[64];
|
char name[64];
|
||||||
@ -4146,6 +4152,22 @@ struct AltCurrencySellItem_Struct {
|
|||||||
/*004*/ uint32 slot_id;
|
/*004*/ uint32 slot_id;
|
||||||
/*006*/ uint32 charges;
|
/*006*/ uint32 charges;
|
||||||
/*010*/ uint32 cost;
|
/*010*/ uint32 cost;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SayLinkBodyFrame_Struct {
|
||||||
|
/*000*/ char ActionID[1];
|
||||||
|
/*001*/ char ItemID[5];
|
||||||
|
/*006*/ char Augment1[5];
|
||||||
|
/*011*/ char Augment2[5];
|
||||||
|
/*016*/ char Augment3[5];
|
||||||
|
/*021*/ char Augment4[5];
|
||||||
|
/*026*/ char Augment5[5];
|
||||||
|
/*031*/ char IsEvolving[1];
|
||||||
|
/*032*/ char EvolveGroup[4];
|
||||||
|
/*036*/ char EvolveLevel[1];
|
||||||
|
/*037*/ char OrnamentIcon[5];
|
||||||
|
/*042*/ char Hash[8];
|
||||||
|
/*050*/
|
||||||
};
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|||||||
@ -52,11 +52,11 @@ namespace Titanium
|
|||||||
static inline uint32 TitaniumToServerSlot(int16 titaniumSlot);
|
static inline uint32 TitaniumToServerSlot(int16 titaniumSlot);
|
||||||
static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot);
|
static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot);
|
||||||
|
|
||||||
// server to client text link converter
|
// server to client say link converter
|
||||||
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink);
|
static inline void ServerToTitaniumSayLink(std::string& titaniumSayLink, const std::string& serverSayLink);
|
||||||
|
|
||||||
// client to server text link converter
|
// client to server say link converter
|
||||||
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink);
|
static inline void TitaniumToServerSayLink(std::string& serverSayLink, const std::string& titaniumSayLink);
|
||||||
|
|
||||||
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot);
|
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot);
|
||||||
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
|
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
|
||||||
@ -164,11 +164,14 @@ namespace Titanium
|
|||||||
OUT(source);
|
OUT(source);
|
||||||
OUT(level);
|
OUT(level);
|
||||||
OUT(instrument_mod);
|
OUT(instrument_mod);
|
||||||
OUT(sequence);
|
OUT(force);
|
||||||
|
OUT(hit_heading);
|
||||||
|
OUT(hit_pitch);
|
||||||
OUT(type);
|
OUT(type);
|
||||||
//OUT(damage);
|
//OUT(damage);
|
||||||
OUT(spell);
|
OUT(spell);
|
||||||
OUT(buff_unknown); // if this is 4, a buff icon is made
|
OUT(spell_level);
|
||||||
|
OUT(effect_flag); // if this is 4, a buff icon is made
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -290,7 +293,7 @@ namespace Titanium
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToTitaniumTextLink(new_message, old_message);
|
ServerToTitaniumSayLink(new_message, old_message);
|
||||||
|
|
||||||
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||||
|
|
||||||
@ -358,8 +361,8 @@ namespace Titanium
|
|||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
OUT(force);
|
OUT(force);
|
||||||
OUT(meleepush_xy);
|
OUT(hit_heading);
|
||||||
OUT(meleepush_z);
|
OUT(hit_pitch);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -532,7 +535,7 @@ namespace Titanium
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToTitaniumTextLink(new_message, old_message);
|
ServerToTitaniumSayLink(new_message, old_message);
|
||||||
|
|
||||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||||
// new_message = new_message.substr(0, 512);
|
// new_message = new_message.substr(0, 512);
|
||||||
@ -574,7 +577,7 @@ namespace Titanium
|
|||||||
|
|
||||||
for (int i = 0; i < 9; ++i) {
|
for (int i = 0; i < 9; ++i) {
|
||||||
if (old_message_array[i].length() == 0) { break; }
|
if (old_message_array[i].length() == 0) { break; }
|
||||||
ServerToTitaniumTextLink(new_message_array[i], old_message_array[i]);
|
ServerToTitaniumSayLink(new_message_array[i], old_message_array[i]);
|
||||||
new_message_size += new_message_array[i].length() + 1;
|
new_message_size += new_message_array[i].length() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1402,7 +1405,7 @@ namespace Titanium
|
|||||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
|
|
||||||
ServerToTitaniumTextLink(new_message, old_message);
|
ServerToTitaniumSayLink(new_message, old_message);
|
||||||
|
|
||||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||||
@ -1458,7 +1461,7 @@ namespace Titanium
|
|||||||
|
|
||||||
std::string old_message = InBuffer; // start 'Reward' as string
|
std::string old_message = InBuffer; // start 'Reward' as string
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToTitaniumTextLink(new_message, old_message);
|
ServerToTitaniumSayLink(new_message, old_message);
|
||||||
|
|
||||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct) +
|
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct) +
|
||||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct) +
|
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct) +
|
||||||
@ -1789,6 +1792,17 @@ namespace Titanium
|
|||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECODE(OP_Bug)
|
||||||
|
{
|
||||||
|
DECODE_LENGTH_EXACT(structs::BugReport_Struct);
|
||||||
|
SETUP_DIRECT_DECODE(BugReport_Struct, structs::BugReport_Struct);
|
||||||
|
|
||||||
|
emu->category_id = EQEmu::bug::CategoryNameToCategoryID(eq->category_name);
|
||||||
|
memcpy(emu->category_name, eq, sizeof(structs::BugReport_Struct));
|
||||||
|
|
||||||
|
FINISH_DIRECT_DECODE();
|
||||||
|
}
|
||||||
|
|
||||||
DECODE(OP_CastSpell)
|
DECODE(OP_CastSpell)
|
||||||
{
|
{
|
||||||
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
|
DECODE_LENGTH_EXACT(structs::CastSpell_Struct);
|
||||||
@ -1808,7 +1822,7 @@ namespace Titanium
|
|||||||
|
|
||||||
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
TitaniumToServerTextLink(new_message, old_message);
|
TitaniumToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
__packet->pBuffer = new unsigned char[__packet->size];
|
||||||
@ -1880,7 +1894,7 @@ namespace Titanium
|
|||||||
|
|
||||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
TitaniumToServerTextLink(new_message, old_message);
|
TitaniumToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
__packet->size = sizeof(Emote_Struct);
|
__packet->size = sizeof(Emote_Struct);
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
__packet->pBuffer = new unsigned char[__packet->size];
|
||||||
@ -2474,19 +2488,19 @@ namespace Titanium
|
|||||||
return titaniumCorpseSlot;
|
return titaniumCorpseSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink)
|
static inline void ServerToTitaniumSayLink(std::string& titaniumSayLink, const std::string& serverSayLink)
|
||||||
{
|
{
|
||||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||||
titaniumTextLink = serverTextLink;
|
titaniumSayLink = serverSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(serverTextLink, '\x12');
|
auto segments = SplitString(serverSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||||
titaniumTextLink.append(segments[segment_iter]);
|
titaniumSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2496,37 +2510,37 @@ namespace Titanium
|
|||||||
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
||||||
// Diff: ^^^^^ ^ ^^^^^
|
// Diff: ^^^^^ ^ ^^^^^
|
||||||
|
|
||||||
titaniumTextLink.push_back('\x12');
|
titaniumSayLink.push_back('\x12');
|
||||||
titaniumTextLink.append(segments[segment_iter].substr(0, 31));
|
titaniumSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
titaniumTextLink.append(segments[segment_iter].substr(36, 5));
|
titaniumSayLink.append(segments[segment_iter].substr(36, 5));
|
||||||
|
|
||||||
if (segments[segment_iter][41] == '0')
|
if (segments[segment_iter][41] == '0')
|
||||||
titaniumTextLink.push_back(segments[segment_iter][42]);
|
titaniumSayLink.push_back(segments[segment_iter][42]);
|
||||||
else
|
else
|
||||||
titaniumTextLink.push_back('F');
|
titaniumSayLink.push_back('F');
|
||||||
|
|
||||||
titaniumTextLink.append(segments[segment_iter].substr(48));
|
titaniumSayLink.append(segments[segment_iter].substr(48));
|
||||||
titaniumTextLink.push_back('\x12');
|
titaniumSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
titaniumTextLink.append(segments[segment_iter]);
|
titaniumSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink)
|
static inline void TitaniumToServerSayLink(std::string& serverSayLink, const std::string& titaniumSayLink)
|
||||||
{
|
{
|
||||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (titaniumTextLink.find('\x12') == std::string::npos)) {
|
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (titaniumSayLink.find('\x12') == std::string::npos)) {
|
||||||
serverTextLink = titaniumTextLink;
|
serverSayLink = titaniumSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(titaniumTextLink, '\x12');
|
auto segments = SplitString(titaniumSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -2536,18 +2550,18 @@ namespace Titanium
|
|||||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
// Diff: ^^^^^ ^ ^^^^^
|
// Diff: ^^^^^ ^ ^^^^^
|
||||||
|
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
serverTextLink.append(segments[segment_iter].substr(0, 31));
|
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
serverTextLink.append("00000");
|
serverSayLink.append("00000");
|
||||||
serverTextLink.append(segments[segment_iter].substr(31, 5));
|
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||||
serverTextLink.push_back('0');
|
serverSayLink.push_back('0');
|
||||||
serverTextLink.push_back(segments[segment_iter][36]);
|
serverSayLink.push_back(segments[segment_iter][36]);
|
||||||
serverTextLink.append("00000");
|
serverSayLink.append("00000");
|
||||||
serverTextLink.append(segments[segment_iter].substr(37));
|
serverSayLink.append(segments[segment_iter].substr(37));
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,6 +78,7 @@ D(OP_AdventureMerchantSell)
|
|||||||
D(OP_ApplyPoison)
|
D(OP_ApplyPoison)
|
||||||
D(OP_AugmentItem)
|
D(OP_AugmentItem)
|
||||||
D(OP_Buff)
|
D(OP_Buff)
|
||||||
|
D(OP_Bug)
|
||||||
D(OP_CastSpell)
|
D(OP_CastSpell)
|
||||||
D(OP_ChannelMessage)
|
D(OP_ChannelMessage)
|
||||||
D(OP_CharacterCreate)
|
D(OP_CharacterCreate)
|
||||||
|
|||||||
@ -327,7 +327,7 @@ union
|
|||||||
// horse: 0=brown, 1=white, 2=black, 3=tan
|
// horse: 0=brown, 1=white, 2=black, 3=tan
|
||||||
};
|
};
|
||||||
/*0340*/ uint32 spawnId; // Spawn Id
|
/*0340*/ uint32 spawnId; // Spawn Id
|
||||||
/*0344*/ uint8 unknown0344[4];
|
/*0344*/ float bounding_radius; // used in melee, overrides calc
|
||||||
/*0348*/ TintProfile equipment_tint;
|
/*0348*/ TintProfile equipment_tint;
|
||||||
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
|
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
|
||||||
/*0385*/
|
/*0385*/
|
||||||
@ -1119,20 +1119,18 @@ struct Action_Struct
|
|||||||
{
|
{
|
||||||
/* 00 */ uint16 target; // id of target
|
/* 00 */ uint16 target; // id of target
|
||||||
/* 02 */ uint16 source; // id of caster
|
/* 02 */ uint16 source; // id of caster
|
||||||
/* 04 */ uint16 level; // level of caster
|
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/* 06 */ uint16 instrument_mod;
|
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
|
||||||
/* 08 */ uint32 unknown08;
|
/* 10 */ float force;
|
||||||
/* 12 */ uint16 unknown16;
|
/* 14 */ float hit_heading;
|
||||||
// some kind of sequence that's the same in both actions
|
/* 18 */ float hit_pitch;
|
||||||
// as well as the combat damage, to tie em together?
|
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/* 14 */ uint32 sequence;
|
/* 23 */ uint16 unknown23; // OSX says min_damage
|
||||||
/* 18 */ uint32 unknown18;
|
/* 25 */ uint16 unknown25; // OSX says tohit
|
||||||
/* 22 */ uint8 type; // 231 (0xE7) for spells
|
|
||||||
/* 23 */ uint32 unknown23;
|
|
||||||
/* 27 */ uint16 spell; // spell id being cast
|
/* 27 */ uint16 spell; // spell id being cast
|
||||||
/* 29 */ uint8 unknown29;
|
/* 29 */ uint8 spell_level;
|
||||||
// this field seems to be some sort of success flag, if it's 4
|
// this field seems to be some sort of success flag, if it's 4
|
||||||
/* 30 */ uint8 buff_unknown; // if this is 4, a buff icon is made
|
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
|
||||||
/* 31 */
|
/* 31 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1143,12 +1141,12 @@ struct CombatDamage_Struct
|
|||||||
{
|
{
|
||||||
/* 00 */ uint16 target;
|
/* 00 */ uint16 target;
|
||||||
/* 02 */ uint16 source;
|
/* 02 */ uint16 source;
|
||||||
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells
|
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells, skill
|
||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ uint32 damage;
|
/* 07 */ uint32 damage;
|
||||||
/* 11 */ float force;
|
/* 11 */ float force;
|
||||||
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
/* 15 */ float hit_heading; // see above notes in Action_Struct
|
||||||
/* 19 */ float meleepush_z;
|
/* 19 */ float hit_pitch;
|
||||||
/* 23 */
|
/* 23 */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2571,21 +2569,32 @@ struct GuildMakeLeader{
|
|||||||
char name[64];
|
char name[64];
|
||||||
char target[64];
|
char target[64];
|
||||||
};
|
};
|
||||||
struct BugStruct{
|
|
||||||
/*0000*/ char chartype[64];
|
struct BugReport_Struct {
|
||||||
/*0064*/ char name[96];
|
/*0000*/ char category_name[64];
|
||||||
/*0160*/ char ui[128];
|
/*0064*/ char character_name[64];
|
||||||
/*0288*/ float x;
|
/*0128*/ char unused_0128[32];
|
||||||
/*0292*/ float y;
|
/*0160*/ char ui_path[128];
|
||||||
/*0296*/ float z;
|
/*0288*/ float pos_x;
|
||||||
/*0300*/ float heading;
|
/*0292*/ float pos_y;
|
||||||
/*0304*/ uint32 unknown304;
|
/*0296*/ float pos_z;
|
||||||
/*0308*/ uint32 type;
|
/*0300*/ uint32 heading;
|
||||||
/*0312*/ char unknown312[2144];
|
/*0304*/ uint32 unused_0304;
|
||||||
/*2456*/ char bug[1024];
|
/*0308*/ uint32 time_played;
|
||||||
/*3480*/ char placeholder[2];
|
/*0312*/ char padding_0312[8];
|
||||||
/*3482*/ char system_info[4098];
|
/*0320*/ uint32 target_id;
|
||||||
|
/*0324*/ char padding_0324[140];
|
||||||
|
/*0464*/ uint32 unknown_0464; // seems to always be '0'
|
||||||
|
/*0468*/ char target_name[64];
|
||||||
|
/*0532*/ uint32 optional_info_mask;
|
||||||
|
|
||||||
|
// this looks like a butchered 8k buffer with 2 trailing dword fields
|
||||||
|
/*0536*/ char unused_0536[2052];
|
||||||
|
/*2588*/ char bug_report[2050];
|
||||||
|
/*4638*/ char system_info[4098];
|
||||||
|
/*8736*/
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||||
uint8 level;
|
uint8 level;
|
||||||
uint8 class_;
|
uint8 class_;
|
||||||
@ -2612,20 +2621,21 @@ struct Ground_Spawn{
|
|||||||
struct Ground_Spawns {
|
struct Ground_Spawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
struct PetitionBug_Struct{
|
|
||||||
uint32 petition_number;
|
//struct PetitionBug_Struct{
|
||||||
uint32 unknown4;
|
// uint32 petition_number;
|
||||||
char accountname[64];
|
// uint32 unknown4;
|
||||||
uint32 zoneid;
|
// char accountname[64];
|
||||||
char name[64];
|
// uint32 zoneid;
|
||||||
uint32 level;
|
// char name[64];
|
||||||
uint32 class_;
|
// uint32 level;
|
||||||
uint32 race;
|
// uint32 class_;
|
||||||
uint32 unknown152[3];
|
// uint32 race;
|
||||||
uint32 time;
|
// uint32 unknown152[3];
|
||||||
uint32 unknown168;
|
// uint32 time;
|
||||||
char text[1028];
|
// uint32 unknown168;
|
||||||
};
|
// char text[1028];
|
||||||
|
//};
|
||||||
|
|
||||||
struct ApproveZone_Struct {
|
struct ApproveZone_Struct {
|
||||||
char name[64];
|
char name[64];
|
||||||
@ -3553,6 +3563,21 @@ struct LFGuild_GuildToggle_Struct
|
|||||||
// char ScrollName; // '0'
|
// char ScrollName; // '0'
|
||||||
//};
|
//};
|
||||||
|
|
||||||
|
struct SayLinkBodyFrame_Struct {
|
||||||
|
/*000*/ char ActionID[1];
|
||||||
|
/*001*/ char ItemID[5];
|
||||||
|
/*006*/ char Augment1[5];
|
||||||
|
/*011*/ char Augment2[5];
|
||||||
|
/*016*/ char Augment3[5];
|
||||||
|
/*021*/ char Augment4[5];
|
||||||
|
/*026*/ char Augment5[5];
|
||||||
|
/*031*/ char IsEvolving[1];
|
||||||
|
/*032*/ char EvolveGroup[4];
|
||||||
|
/*036*/ char EvolveLevel[1];
|
||||||
|
/*037*/ char Hash[8];
|
||||||
|
/*045*/
|
||||||
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|
||||||
}; /*Titanium*/
|
}; /*Titanium*/
|
||||||
|
|||||||
@ -53,11 +53,11 @@ namespace UF
|
|||||||
static inline uint32 UFToServerSlot(uint32 ufSlot);
|
static inline uint32 UFToServerSlot(uint32 ufSlot);
|
||||||
static inline uint32 UFToServerCorpseSlot(uint32 ufCorpseSlot);
|
static inline uint32 UFToServerCorpseSlot(uint32 ufCorpseSlot);
|
||||||
|
|
||||||
// server to client text link converter
|
// server to client say link converter
|
||||||
static inline void ServerToUFTextLink(std::string& ufTextLink, const std::string& serverTextLink);
|
static inline void ServerToUFSayLink(std::string& ufSayLink, const std::string& serverSayLink);
|
||||||
|
|
||||||
// client to server text link converter
|
// client to server say link converter
|
||||||
static inline void UFToServerTextLink(std::string& serverTextLink, const std::string& ufTextLink);
|
static inline void UFToServerSayLink(std::string& serverSayLink, const std::string& ufSayLink);
|
||||||
|
|
||||||
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot);
|
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot);
|
||||||
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot);
|
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot);
|
||||||
@ -161,29 +161,20 @@ namespace UF
|
|||||||
OUT(source);
|
OUT(source);
|
||||||
OUT(level);
|
OUT(level);
|
||||||
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
|
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
|
||||||
eq->knockback_angle = emu->sequence;
|
OUT(force);
|
||||||
|
OUT(hit_heading);
|
||||||
|
OUT(hit_pitch);
|
||||||
OUT(type);
|
OUT(type);
|
||||||
OUT(spell);
|
OUT(spell);
|
||||||
eq->level2 = eq->level;
|
OUT(spell_level);
|
||||||
eq->effect_flag = emu->buff_unknown;
|
OUT(effect_flag);
|
||||||
eq->unknown37 = 0x01;
|
eq->spell_gem = 0;
|
||||||
eq->unknown44 = 0xFFFFFFFF;
|
eq->slot[0] = -1; // type
|
||||||
eq->unknown48 = 0xFFFFFFFF;
|
eq->slot[1] = -1; // slot
|
||||||
eq->unknown52 = 0xFFFFFFFF;
|
eq->slot[2] = -1; // sub index
|
||||||
|
eq->slot[3] = -1; // aug index
|
||||||
/*OUT(target);
|
eq->slot[4] = -1; // unknown
|
||||||
OUT(source);
|
eq->item_cast_type = 0;
|
||||||
OUT(level);
|
|
||||||
OUT(instrument_mod);
|
|
||||||
eq->sequence = emu->sequence;
|
|
||||||
OUT(type);
|
|
||||||
//OUT(damage);
|
|
||||||
OUT(spell);
|
|
||||||
eq->level2 = emu->level;
|
|
||||||
OUT(buff_unknown); // if this is 4, a buff icon is made
|
|
||||||
//eq->unknown0036 = -1;
|
|
||||||
//eq->unknown0040 = -1;
|
|
||||||
//eq->unknown0044 = -1;*/
|
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
}
|
}
|
||||||
@ -463,7 +454,7 @@ namespace UF
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToUFTextLink(new_message, old_message);
|
ServerToUFSayLink(new_message, old_message);
|
||||||
|
|
||||||
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
//in->size = strlen(emu->sender) + 1 + strlen(emu->targetname) + 1 + strlen(emu->message) + 1 + 36;
|
||||||
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
in->size = strlen(emu->sender) + strlen(emu->targetname) + new_message.length() + 39;
|
||||||
@ -586,8 +577,8 @@ namespace UF
|
|||||||
OUT(spellid);
|
OUT(spellid);
|
||||||
OUT(damage);
|
OUT(damage);
|
||||||
OUT(force);
|
OUT(force);
|
||||||
OUT(meleepush_xy);
|
OUT(hit_heading);
|
||||||
OUT(meleepush_z);
|
OUT(hit_pitch);
|
||||||
OUT(special);
|
OUT(special);
|
||||||
|
|
||||||
FINISH_ENCODE();
|
FINISH_ENCODE();
|
||||||
@ -762,7 +753,7 @@ namespace UF
|
|||||||
|
|
||||||
std::string old_message = emu->message;
|
std::string old_message = emu->message;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToUFTextLink(new_message, old_message);
|
ServerToUFSayLink(new_message, old_message);
|
||||||
|
|
||||||
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
//if (new_message.length() > 512) // length restricted in packet building function due vari-length name size (no nullterm)
|
||||||
// new_message = new_message.substr(0, 512);
|
// new_message = new_message.substr(0, 512);
|
||||||
@ -814,7 +805,7 @@ namespace UF
|
|||||||
|
|
||||||
for (int i = 0; i < 9; ++i) {
|
for (int i = 0; i < 9; ++i) {
|
||||||
if (old_message_array[i].length() == 0) { break; }
|
if (old_message_array[i].length() == 0) { break; }
|
||||||
ServerToUFTextLink(new_message_array[i], old_message_array[i]);
|
ServerToUFSayLink(new_message_array[i], old_message_array[i]);
|
||||||
new_message_size += new_message_array[i].length() + 1;
|
new_message_size += new_message_array[i].length() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2469,7 +2460,7 @@ namespace UF
|
|||||||
std::string old_message = &emu->message[strlen(emu->sayer)];
|
std::string old_message = &emu->message[strlen(emu->sayer)];
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
|
|
||||||
ServerToUFTextLink(new_message, old_message);
|
ServerToUFSayLink(new_message, old_message);
|
||||||
|
|
||||||
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
//in->size = 3 + 4 + 4 + strlen(emu->sayer) + 1 + 12 + new_message.length() + 1;
|
||||||
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
in->size = strlen(emu->sayer) + new_message.length() + 25;
|
||||||
@ -2539,7 +2530,7 @@ namespace UF
|
|||||||
|
|
||||||
std::string old_message = InBuffer; // start 'Reward' as string
|
std::string old_message = InBuffer; // start 'Reward' as string
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
ServerToUFTextLink(new_message, old_message);
|
ServerToUFSayLink(new_message, old_message);
|
||||||
|
|
||||||
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
|
||||||
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
|
||||||
@ -3287,7 +3278,7 @@ namespace UF
|
|||||||
|
|
||||||
std::string old_message = InBuffer;
|
std::string old_message = InBuffer;
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
UFToServerTextLink(new_message, old_message);
|
UFToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
//__packet->size = sizeof(ChannelMessage_Struct)+strlen(InBuffer) + 1;
|
||||||
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
|
||||||
@ -3398,7 +3389,7 @@ namespace UF
|
|||||||
IN(type);
|
IN(type);
|
||||||
IN(spellid);
|
IN(spellid);
|
||||||
IN(damage);
|
IN(damage);
|
||||||
IN(meleepush_xy);
|
IN(hit_heading);
|
||||||
|
|
||||||
FINISH_DIRECT_DECODE();
|
FINISH_DIRECT_DECODE();
|
||||||
}
|
}
|
||||||
@ -3421,7 +3412,7 @@ namespace UF
|
|||||||
|
|
||||||
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
|
||||||
std::string new_message;
|
std::string new_message;
|
||||||
UFToServerTextLink(new_message, old_message);
|
UFToServerSayLink(new_message, old_message);
|
||||||
|
|
||||||
__packet->size = sizeof(Emote_Struct);
|
__packet->size = sizeof(Emote_Struct);
|
||||||
__packet->pBuffer = new unsigned char[__packet->size];
|
__packet->pBuffer = new unsigned char[__packet->size];
|
||||||
@ -4290,19 +4281,19 @@ namespace UF
|
|||||||
return (ufCorpseSlot - 1);
|
return (ufCorpseSlot - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ServerToUFTextLink(std::string& ufTextLink, const std::string& serverTextLink)
|
static inline void ServerToUFSayLink(std::string& ufSayLink, const std::string& serverSayLink)
|
||||||
{
|
{
|
||||||
if ((constants::SayLinkBodySize == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) || (serverTextLink.find('\x12') == std::string::npos)) {
|
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
|
||||||
ufTextLink = serverTextLink;
|
ufSayLink = serverSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(serverTextLink, '\x12');
|
auto segments = SplitString(serverSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
|
||||||
ufTextLink.append(segments[segment_iter]);
|
ufSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -4312,37 +4303,37 @@ namespace UF
|
|||||||
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||||
// Diff: ^^^^^ ^
|
// Diff: ^^^^^ ^
|
||||||
|
|
||||||
ufTextLink.push_back('\x12');
|
ufSayLink.push_back('\x12');
|
||||||
ufTextLink.append(segments[segment_iter].substr(0, 31));
|
ufSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
ufTextLink.append(segments[segment_iter].substr(36, 5));
|
ufSayLink.append(segments[segment_iter].substr(36, 5));
|
||||||
|
|
||||||
if (segments[segment_iter][41] == '0')
|
if (segments[segment_iter][41] == '0')
|
||||||
ufTextLink.push_back(segments[segment_iter][42]);
|
ufSayLink.push_back(segments[segment_iter][42]);
|
||||||
else
|
else
|
||||||
ufTextLink.push_back('F');
|
ufSayLink.push_back('F');
|
||||||
|
|
||||||
ufTextLink.append(segments[segment_iter].substr(43));
|
ufSayLink.append(segments[segment_iter].substr(43));
|
||||||
ufTextLink.push_back('\x12');
|
ufSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ufTextLink.append(segments[segment_iter]);
|
ufSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void UFToServerTextLink(std::string& serverTextLink, const std::string& ufTextLink)
|
static inline void UFToServerSayLink(std::string& serverSayLink, const std::string& ufSayLink)
|
||||||
{
|
{
|
||||||
if ((EQEmu::legacy::TEXT_LINK_BODY_LENGTH == constants::SayLinkBodySize) || (ufTextLink.find('\x12') == std::string::npos)) {
|
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (ufSayLink.find('\x12') == std::string::npos)) {
|
||||||
serverTextLink = ufTextLink;
|
serverSayLink = ufSayLink;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto segments = SplitString(ufTextLink, '\x12');
|
auto segments = SplitString(ufSayLink, '\x12');
|
||||||
|
|
||||||
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
if (segment_iter & 1) {
|
if (segment_iter & 1) {
|
||||||
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
// TODO: log size mismatch error
|
// TODO: log size mismatch error
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -4352,16 +4343,16 @@ namespace UF
|
|||||||
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
// Diff: ^^^^^ ^
|
// Diff: ^^^^^ ^
|
||||||
|
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
serverTextLink.append(segments[segment_iter].substr(0, 31));
|
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
serverTextLink.append("00000");
|
serverSayLink.append("00000");
|
||||||
serverTextLink.append(segments[segment_iter].substr(31, 5));
|
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||||
serverTextLink.push_back('0');
|
serverSayLink.push_back('0');
|
||||||
serverTextLink.append(segments[segment_iter].substr(36));
|
serverSayLink.append(segments[segment_iter].substr(36));
|
||||||
serverTextLink.push_back('\x12');
|
serverSayLink.push_back('\x12');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
serverTextLink.append(segments[segment_iter]);
|
serverSayLink.append(segments[segment_iter]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -292,7 +292,7 @@ struct Spawn_Struct
|
|||||||
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
/*0000*/ //uint8 nullterm1; // hack to null terminate name
|
||||||
/*0064*/ uint32 spawnId;
|
/*0064*/ uint32 spawnId;
|
||||||
/*0068*/ uint8 level;
|
/*0068*/ uint8 level;
|
||||||
/*0069*/ float unknown1;
|
/*0069*/ float bounding_radius; // used in melee, overrides calc
|
||||||
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
/*0073*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse
|
||||||
Spawn_Struct_Bitfields Bitfields;
|
Spawn_Struct_Bitfields Bitfields;
|
||||||
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
|
||||||
@ -1252,19 +1252,19 @@ struct Action_Struct
|
|||||||
{
|
{
|
||||||
/*00*/ uint16 target; // id of target
|
/*00*/ uint16 target; // id of target
|
||||||
/*02*/ uint16 source; // id of caster
|
/*02*/ uint16 source; // id of caster
|
||||||
/*04*/ uint16 level; // level of caster - Seen 0
|
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/*06*/ uint32 unknown06;
|
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||||
/*10*/ uint16 instrument_focus;
|
/*10*/ float instrument_mod;
|
||||||
/*12*/ uint16 unknown12; // seems to always be set to something and it doesn't change between casts except in special cases like changing instrument mods
|
/*14*/ float force;
|
||||||
/*14*/ uint32 unknown14; // seen 0
|
/*18*/ float hit_heading;
|
||||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
/*22*/ float hit_pitch;
|
||||||
/*22*/ uint32 unknown22;
|
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/*26*/ uint8 type;
|
/*27*/ uint32 damage; // OSX says min_damage
|
||||||
/*27*/ uint32 damage;
|
/*31*/ uint16 unknown31; // OSX says tohit
|
||||||
/*31*/ uint16 unknown31;
|
|
||||||
/*33*/ uint16 spell; // spell id being cast
|
/*33*/ uint16 spell; // spell id being cast
|
||||||
/*35*/ uint8 level2; // level of caster again? Or maybe the castee
|
/*35*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||||
/*36*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
/*36*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||||
|
/*37*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1276,27 +1276,22 @@ struct ActionAlt_Struct
|
|||||||
{
|
{
|
||||||
/*00*/ uint16 target; // id of target
|
/*00*/ uint16 target; // id of target
|
||||||
/*02*/ uint16 source; // id of caster
|
/*02*/ uint16 source; // id of caster
|
||||||
/*04*/ uint16 level; // level of caster - Seen 0
|
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
|
||||||
/*06*/ uint32 unknown06;
|
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
|
||||||
/*10*/ float instrument_mod;
|
/*10*/ float instrument_mod;
|
||||||
/*14*/ uint32 unknown14; // seen 0
|
/*14*/ float force;
|
||||||
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
|
/*18*/ float hit_heading;
|
||||||
/*22*/ uint32 unknown22;
|
/*22*/ float hit_pitch;
|
||||||
/*26*/ uint8 type;
|
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
|
||||||
/*27*/ uint32 damage;
|
/*27*/ uint32 damage; // OSX says min_damage
|
||||||
/*31*/ uint16 unknown31;
|
/*31*/ uint16 unknown31; // OSX says tohit
|
||||||
/*33*/ uint16 spell; // spell id being cast
|
/*33*/ uint16 spell; // spell id being cast
|
||||||
/*35*/ uint8 level2; // level of caster again? Or maybe the castee
|
/*35*/ uint8 spell_level; // level of caster again? Or maybe the castee
|
||||||
/*36*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
/*36*/ uint8 effect_flag; // if this is 4, the effect is valid: or if two are sent at the same time?
|
||||||
/*37*/ uint32 unknown37; // New field to Underfoot - Seen 14
|
/*37*/ uint8 spell_gem;
|
||||||
/*41*/ uint8 unknown41; // New field to Underfoot - Seen 0
|
/*38*/ uint8 padding38[2];
|
||||||
/*42*/ uint8 unknown42; // New field to Underfoot - Seen 0
|
/*40*/ uint32 slot[5];
|
||||||
/*43*/ uint8 unknown43; // New field to Underfoot - Seen 0
|
/*60*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
|
||||||
/*44*/ uint32 unknown44; // New field to Underfoot - Seen 23
|
|
||||||
/*48*/ uint32 unknown48; // New field to Underfoot - Seen -1
|
|
||||||
/*52*/ uint32 unknown52; // New field to Underfoot - Seen -1
|
|
||||||
/*56*/ uint32 unknown56; // New field to Underfoot - Seen 0
|
|
||||||
/*60*/ uint32 unknown60; // New field to Underfoot - Seen 0
|
|
||||||
/*64*/
|
/*64*/
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1311,9 +1306,9 @@ struct CombatDamage_Struct
|
|||||||
/* 05 */ uint16 spellid;
|
/* 05 */ uint16 spellid;
|
||||||
/* 07 */ int32 damage;
|
/* 07 */ int32 damage;
|
||||||
/* 11 */ float force; // cd cc cc 3d
|
/* 11 */ float force; // cd cc cc 3d
|
||||||
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
|
/* 15 */ float hit_heading; // see above notes in Action_Struct
|
||||||
/* 19 */ float meleepush_z;
|
/* 19 */ float hit_pitch;
|
||||||
/* 23 */ uint8 unknown23; // was [9]
|
/* 23 */ uint8 secondary; // 0 for primary hand, 1 for secondary
|
||||||
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
|
||||||
/* 28 */
|
/* 28 */
|
||||||
};
|
};
|
||||||
@ -3060,23 +3055,6 @@ struct GuildMakeLeader{
|
|||||||
char target[64];
|
char target[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct BugStruct{
|
|
||||||
/*0000*/ char chartype[64];
|
|
||||||
/*0064*/ char name[96];
|
|
||||||
/*0160*/ char ui[128];
|
|
||||||
/*0288*/ float x;
|
|
||||||
/*0292*/ float y;
|
|
||||||
/*0296*/ float z;
|
|
||||||
/*0300*/ float heading;
|
|
||||||
/*0304*/ uint32 unknown304;
|
|
||||||
/*0308*/ uint32 type;
|
|
||||||
/*0312*/ char unknown312[2144];
|
|
||||||
/*2456*/ char bug[1024];
|
|
||||||
/*3480*/ char placeholder[2];
|
|
||||||
/*3482*/ char system_info[4098];
|
|
||||||
};
|
|
||||||
struct Make_Pet_Struct { //Simple struct for getting pet info
|
struct Make_Pet_Struct { //Simple struct for getting pet info
|
||||||
uint8 level;
|
uint8 level;
|
||||||
uint8 class_;
|
uint8 class_;
|
||||||
@ -3103,20 +3081,21 @@ struct Ground_Spawn{
|
|||||||
struct Ground_Spawns {
|
struct Ground_Spawns {
|
||||||
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
struct Ground_Spawn spawn[50]; //Assigned max number to allow
|
||||||
};
|
};
|
||||||
struct PetitionBug_Struct{
|
|
||||||
uint32 petition_number;
|
//struct PetitionBug_Struct{
|
||||||
uint32 unknown4;
|
// uint32 petition_number;
|
||||||
char accountname[64];
|
// uint32 unknown4;
|
||||||
uint32 zoneid;
|
// char accountname[64];
|
||||||
char name[64];
|
// uint32 zoneid;
|
||||||
uint32 level;
|
// char name[64];
|
||||||
uint32 class_;
|
// uint32 level;
|
||||||
uint32 race;
|
// uint32 class_;
|
||||||
uint32 unknown152[3];
|
// uint32 race;
|
||||||
uint32 time;
|
// uint32 unknown152[3];
|
||||||
uint32 unknown168;
|
// uint32 time;
|
||||||
char text[1028];
|
// uint32 unknown168;
|
||||||
};
|
// char text[1028];
|
||||||
|
//};
|
||||||
|
|
||||||
struct ApproveZone_Struct {
|
struct ApproveZone_Struct {
|
||||||
char name[64];
|
char name[64];
|
||||||
@ -4505,6 +4484,22 @@ struct MercenaryAssign_Struct {
|
|||||||
/*0004*/ uint32 MercUnk01; //
|
/*0004*/ uint32 MercUnk01; //
|
||||||
/*0008*/ uint32 MercUnk02; //
|
/*0008*/ uint32 MercUnk02; //
|
||||||
/*0012*/
|
/*0012*/
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SayLinkBodyFrame_Struct {
|
||||||
|
/*000*/ char ActionID[1];
|
||||||
|
/*001*/ char ItemID[5];
|
||||||
|
/*006*/ char Augment1[5];
|
||||||
|
/*011*/ char Augment2[5];
|
||||||
|
/*016*/ char Augment3[5];
|
||||||
|
/*021*/ char Augment4[5];
|
||||||
|
/*026*/ char Augment5[5];
|
||||||
|
/*031*/ char IsEvolving[1];
|
||||||
|
/*032*/ char EvolveGroup[4];
|
||||||
|
/*036*/ char EvolveLevel[1];
|
||||||
|
/*037*/ char OrnamentIcon[5];
|
||||||
|
/*042*/ char Hash[8];
|
||||||
|
/*050*/
|
||||||
};
|
};
|
||||||
|
|
||||||
}; /*structs*/
|
}; /*structs*/
|
||||||
|
|||||||
@ -156,6 +156,7 @@ RULE_BOOL(Character, UseOldBindWound, false) // Uses the original bind wound beh
|
|||||||
RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Target leadership AA on character creation
|
RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Target leadership AA on character creation
|
||||||
RULE_BOOL(Character, UseOldConSystem, false) // Grant Health of Target's Target leadership AA on character creation
|
RULE_BOOL(Character, UseOldConSystem, false) // Grant Health of Target's Target leadership AA on character creation
|
||||||
RULE_BOOL(Character, OPClientUpdateVisualDebug, false) // Shows a pulse and forward directional particle each time the client sends its position to server
|
RULE_BOOL(Character, OPClientUpdateVisualDebug, false) // Shows a pulse and forward directional particle each time the client sends its position to server
|
||||||
|
RULE_BOOL(Character, PetsUseReagents, true) //Pets use reagent on spells
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Mercs)
|
RULE_CATEGORY(Mercs)
|
||||||
@ -233,6 +234,7 @@ RULE_INT(World, TitaniumStartZoneID, -1) //Sets the Starting Zone for Titanium C
|
|||||||
RULE_INT(World, ExpansionSettings, 16383) // Sets the expansion settings for the server, This is sent on login to world and affects client expansion settings. Defaults to all expansions enabled up to TSS.
|
RULE_INT(World, ExpansionSettings, 16383) // Sets the expansion settings for the server, This is sent on login to world and affects client expansion settings. Defaults to all expansions enabled up to TSS.
|
||||||
RULE_BOOL(World, UseClientBasedExpansionSettings, true) // if true it will overrule World, ExpansionSettings and set someone's expansion based on the client they're using
|
RULE_BOOL(World, UseClientBasedExpansionSettings, true) // if true it will overrule World, ExpansionSettings and set someone's expansion based on the client they're using
|
||||||
RULE_INT(World, PVPSettings, 0) // Sets the PVP settings for the server, 1 = Rallos Zek RuleSet, 2 = Tallon/Vallon Zek Ruleset, 4 = Sullon Zek Ruleset, 6 = Discord Ruleset, anything above 6 is the Discord Ruleset without the no-drop restrictions removed. TODO: Edit IsAttackAllowed in Zone to accomodate for these rules.
|
RULE_INT(World, PVPSettings, 0) // Sets the PVP settings for the server, 1 = Rallos Zek RuleSet, 2 = Tallon/Vallon Zek Ruleset, 4 = Sullon Zek Ruleset, 6 = Discord Ruleset, anything above 6 is the Discord Ruleset without the no-drop restrictions removed. TODO: Edit IsAttackAllowed in Zone to accomodate for these rules.
|
||||||
|
RULE_INT(World, PVPMinLevel, 0) // minimum level to pvp
|
||||||
RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
|
RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
|
||||||
RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items.
|
RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items.
|
||||||
RULE_BOOL (World, IPLimitDisconnectAll, false)
|
RULE_BOOL (World, IPLimitDisconnectAll, false)
|
||||||
@ -400,6 +402,7 @@ RULE_BOOL(Spells, IgnoreSpellDmgLvlRestriction, false) // ignore the 5 level spr
|
|||||||
RULE_BOOL(Spells, AllowItemTGB, false) // TGB doesn't work with items on live, custom servers want it though
|
RULE_BOOL(Spells, AllowItemTGB, false) // TGB doesn't work with items on live, custom servers want it though
|
||||||
RULE_BOOL(Spells, NPCInnateProcOverride, true) // NPC innate procs override the target type to single target.
|
RULE_BOOL(Spells, NPCInnateProcOverride, true) // NPC innate procs override the target type to single target.
|
||||||
RULE_BOOL(Spells, OldRainTargets, false) // use old incorrectly implemented max targets for rains
|
RULE_BOOL(Spells, OldRainTargets, false) // use old incorrectly implemented max targets for rains
|
||||||
|
RULE_BOOL(Spells, NPCSpellPush, false) // enable spell push on NPCs
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Combat)
|
RULE_CATEGORY(Combat)
|
||||||
@ -720,6 +723,12 @@ RULE_BOOL(Client, UseLiveFactionMessage, false) // Allows players to see faction
|
|||||||
RULE_BOOL(Client, UseLiveBlockedMessage, false) // Allows players to see faction adjustments like Live
|
RULE_BOOL(Client, UseLiveBlockedMessage, false) // Allows players to see faction adjustments like Live
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
|
RULE_CATEGORY(Bugs)
|
||||||
|
RULE_BOOL(Bugs, ReportingSystemActive, true) // Activates bug reporting
|
||||||
|
RULE_BOOL(Bugs, UseOldReportingMethod, true) // Forces the use of the old bug reporting system
|
||||||
|
RULE_BOOL(Bugs, DumpTargetEntity, false) // Dumps the target entity, if one is provided
|
||||||
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
#undef RULE_CATEGORY
|
#undef RULE_CATEGORY
|
||||||
#undef RULE_INT
|
#undef RULE_INT
|
||||||
#undef RULE_REAL
|
#undef RULE_REAL
|
||||||
|
|||||||
@ -29,10 +29,10 @@
|
|||||||
bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct, const std::string& say_link_body)
|
bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct, const std::string& say_link_body)
|
||||||
{
|
{
|
||||||
memset(&say_link_body_struct, 0, sizeof(say_link_body_struct));
|
memset(&say_link_body_struct, 0, sizeof(say_link_body_struct));
|
||||||
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH)
|
if (say_link_body.length() != EQEmu::constants::SayLinkBodySize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
say_link_body_struct.unknown_1 = (uint8)strtol(say_link_body.substr(0, 1).c_str(), nullptr, 16);
|
say_link_body_struct.action_id = (uint8)strtol(say_link_body.substr(0, 1).c_str(), nullptr, 16);
|
||||||
say_link_body_struct.item_id = (uint32)strtol(say_link_body.substr(1, 5).c_str(), nullptr, 16);
|
say_link_body_struct.item_id = (uint32)strtol(say_link_body.substr(1, 5).c_str(), nullptr, 16);
|
||||||
say_link_body_struct.augment_1 = (uint32)strtol(say_link_body.substr(6, 5).c_str(), nullptr, 16);
|
say_link_body_struct.augment_1 = (uint32)strtol(say_link_body.substr(6, 5).c_str(), nullptr, 16);
|
||||||
say_link_body_struct.augment_2 = (uint32)strtol(say_link_body.substr(11, 5).c_str(), nullptr, 16);
|
say_link_body_struct.augment_2 = (uint32)strtol(say_link_body.substr(11, 5).c_str(), nullptr, 16);
|
||||||
@ -44,7 +44,7 @@ bool EQEmu::saylink::DegenerateLinkBody(SayLinkBody_Struct& say_link_body_struct
|
|||||||
say_link_body_struct.evolve_group = (uint32)strtol(say_link_body.substr(37, 4).c_str(), nullptr, 16);
|
say_link_body_struct.evolve_group = (uint32)strtol(say_link_body.substr(37, 4).c_str(), nullptr, 16);
|
||||||
say_link_body_struct.evolve_level = (uint8)strtol(say_link_body.substr(41, 2).c_str(), nullptr, 16);
|
say_link_body_struct.evolve_level = (uint8)strtol(say_link_body.substr(41, 2).c_str(), nullptr, 16);
|
||||||
say_link_body_struct.ornament_icon = (uint32)strtol(say_link_body.substr(43, 5).c_str(), nullptr, 16);
|
say_link_body_struct.ornament_icon = (uint32)strtol(say_link_body.substr(43, 5).c_str(), nullptr, 16);
|
||||||
say_link_body_struct.hash = (int)strtol(say_link_body.substr(48, 8).c_str(), nullptr, 16);
|
say_link_body_struct.hash = (uint32)strtol(say_link_body.substr(48, 8).c_str(), nullptr, 16);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@ bool EQEmu::saylink::GenerateLinkBody(std::string& say_link_body, const SayLinkB
|
|||||||
{
|
{
|
||||||
say_link_body = StringFormat(
|
say_link_body = StringFormat(
|
||||||
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
|
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
|
||||||
(0x0F & say_link_body_struct.unknown_1),
|
(0x0F & say_link_body_struct.action_id),
|
||||||
(0x000FFFFF & say_link_body_struct.item_id),
|
(0x000FFFFF & say_link_body_struct.item_id),
|
||||||
(0x000FFFFF & say_link_body_struct.augment_1),
|
(0x000FFFFF & say_link_body_struct.augment_1),
|
||||||
(0x000FFFFF & say_link_body_struct.augment_2),
|
(0x000FFFFF & say_link_body_struct.augment_2),
|
||||||
@ -68,7 +68,7 @@ bool EQEmu::saylink::GenerateLinkBody(std::string& say_link_body, const SayLinkB
|
|||||||
(0xFFFFFFFF & say_link_body_struct.hash)
|
(0xFFFFFFFF & say_link_body_struct.hash)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH)
|
if (say_link_body.length() != EQEmu::constants::SayLinkBodySize)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -79,7 +79,7 @@ EQEmu::SayLinkEngine::SayLinkEngine()
|
|||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EQEmu::SayLinkEngine::GenerateLink()
|
const std::string& EQEmu::SayLinkEngine::GenerateLink()
|
||||||
{
|
{
|
||||||
m_Link.clear();
|
m_Link.clear();
|
||||||
m_LinkBody.clear();
|
m_LinkBody.clear();
|
||||||
@ -88,18 +88,26 @@ std::string EQEmu::SayLinkEngine::GenerateLink()
|
|||||||
generate_body();
|
generate_body();
|
||||||
generate_text();
|
generate_text();
|
||||||
|
|
||||||
if ((m_LinkBody.length() == EQEmu::legacy::TEXT_LINK_BODY_LENGTH) && (m_LinkText.length() > 0)) {
|
if ((m_LinkBody.length() == EQEmu::constants::SayLinkBodySize) && (m_LinkText.length() > 0)) {
|
||||||
m_Link.push_back(0x12);
|
m_Link.push_back(0x12);
|
||||||
m_Link.append(m_LinkBody);
|
m_Link.append(m_LinkBody);
|
||||||
m_Link.append(m_LinkText);
|
m_Link.append(m_LinkText);
|
||||||
m_Link.push_back(0x12);
|
m_Link.push_back(0x12);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_Link.length() == 0) || (m_Link.length() > 250)) {
|
if ((m_Link.length() == 0) || (m_Link.length() > (EQEmu::constants::SayLinkMaximumSize))) {
|
||||||
m_Error = true;
|
m_Error = true;
|
||||||
m_Link = "<LINKER ERROR>";
|
m_Link = "<LINKER ERROR>";
|
||||||
Log(Logs::General, Logs::Error, "TextLink::GenerateLink() failed to generate a useable text link (LinkType: %i, Lengths: {link: %u, body: %u, text: %u})",
|
Log(Logs::General, Logs::Error, "SayLinkEngine::GenerateLink() failed to generate a useable say link");
|
||||||
m_LinkType, m_Link.length(), m_LinkBody.length(), m_LinkText.length());
|
Log(Logs::General, Logs::Error, ">> LinkType: %i, Lengths: {link: %u(%u), body: %u(%u), text: %u(%u)}",
|
||||||
|
m_LinkType,
|
||||||
|
m_Link.length(),
|
||||||
|
EQEmu::constants::SayLinkMaximumSize,
|
||||||
|
m_LinkBody.length(),
|
||||||
|
EQEmu::constants::SayLinkBodySize,
|
||||||
|
m_LinkText.length(),
|
||||||
|
EQEmu::constants::SayLinkTextSize
|
||||||
|
);
|
||||||
Log(Logs::General, Logs::Error, ">> LinkBody: %s", m_LinkBody.c_str());
|
Log(Logs::General, Logs::Error, ">> LinkBody: %s", m_LinkBody.c_str());
|
||||||
Log(Logs::General, Logs::Error, ">> LinkText: %s", m_LinkText.c_str());
|
Log(Logs::General, Logs::Error, ">> LinkText: %s", m_LinkText.c_str());
|
||||||
}
|
}
|
||||||
@ -113,20 +121,10 @@ void EQEmu::SayLinkEngine::Reset()
|
|||||||
m_ItemData = nullptr;
|
m_ItemData = nullptr;
|
||||||
m_LootData = nullptr;
|
m_LootData = nullptr;
|
||||||
m_ItemInst = nullptr;
|
m_ItemInst = nullptr;
|
||||||
m_Proxy_unknown_1 = 0;
|
|
||||||
m_ProxyItemID = 0;
|
memset(&m_LinkBodyStruct, 0, sizeof(SayLinkBody_Struct));
|
||||||
m_ProxyAugment1ID = 0;
|
memset(&m_LinkProxyStruct, 0, sizeof(SayLinkProxy_Struct));
|
||||||
m_ProxyAugment2ID = 0;
|
|
||||||
m_ProxyAugment3ID = 0;
|
|
||||||
m_ProxyAugment4ID = 0;
|
|
||||||
m_ProxyAugment5ID = 0;
|
|
||||||
m_ProxyAugment6ID = 0;
|
|
||||||
m_ProxyIsEvolving = 0;
|
|
||||||
m_ProxyEvolveGroup = 0;
|
|
||||||
m_ProxyEvolveLevel = 0;
|
|
||||||
m_ProxyOrnamentIcon = 0;
|
|
||||||
m_ProxyHash = 0;
|
|
||||||
m_ProxyText = nullptr;
|
|
||||||
m_TaskUse = false;
|
m_TaskUse = false;
|
||||||
m_Link.clear();
|
m_Link.clear();
|
||||||
m_LinkBody.clear();
|
m_LinkBody.clear();
|
||||||
@ -194,32 +192,32 @@ void EQEmu::SayLinkEngine::generate_body()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_Proxy_unknown_1)
|
if (m_LinkProxyStruct.action_id)
|
||||||
m_LinkBodyStruct.unknown_1 = m_Proxy_unknown_1;
|
m_LinkBodyStruct.action_id = m_LinkProxyStruct.action_id;
|
||||||
if (m_ProxyItemID)
|
if (m_LinkProxyStruct.item_id)
|
||||||
m_LinkBodyStruct.item_id = m_ProxyItemID;
|
m_LinkBodyStruct.item_id = m_LinkProxyStruct.item_id;
|
||||||
if (m_ProxyAugment1ID)
|
if (m_LinkProxyStruct.augment_1)
|
||||||
m_LinkBodyStruct.augment_1 = m_ProxyAugment1ID;
|
m_LinkBodyStruct.augment_1 = m_LinkProxyStruct.augment_1;
|
||||||
if (m_ProxyAugment2ID)
|
if (m_LinkProxyStruct.augment_2)
|
||||||
m_LinkBodyStruct.augment_2 = m_ProxyAugment2ID;
|
m_LinkBodyStruct.augment_2 = m_LinkProxyStruct.augment_2;
|
||||||
if (m_ProxyAugment3ID)
|
if (m_LinkProxyStruct.augment_3)
|
||||||
m_LinkBodyStruct.augment_3 = m_ProxyAugment3ID;
|
m_LinkBodyStruct.augment_3 = m_LinkProxyStruct.augment_3;
|
||||||
if (m_ProxyAugment4ID)
|
if (m_LinkProxyStruct.augment_4)
|
||||||
m_LinkBodyStruct.augment_4 = m_ProxyAugment4ID;
|
m_LinkBodyStruct.augment_4 = m_LinkProxyStruct.augment_4;
|
||||||
if (m_ProxyAugment5ID)
|
if (m_LinkProxyStruct.augment_5)
|
||||||
m_LinkBodyStruct.augment_5 = m_ProxyAugment5ID;
|
m_LinkBodyStruct.augment_5 = m_LinkProxyStruct.augment_5;
|
||||||
if (m_ProxyAugment6ID)
|
if (m_LinkProxyStruct.augment_6)
|
||||||
m_LinkBodyStruct.augment_6 = m_ProxyAugment6ID;
|
m_LinkBodyStruct.augment_6 = m_LinkProxyStruct.augment_6;
|
||||||
if (m_ProxyIsEvolving)
|
if (m_LinkProxyStruct.is_evolving)
|
||||||
m_LinkBodyStruct.is_evolving = m_ProxyIsEvolving;
|
m_LinkBodyStruct.is_evolving = m_LinkProxyStruct.is_evolving;
|
||||||
if (m_ProxyEvolveGroup)
|
if (m_LinkProxyStruct.evolve_group)
|
||||||
m_LinkBodyStruct.evolve_group = m_ProxyEvolveGroup;
|
m_LinkBodyStruct.evolve_group = m_LinkProxyStruct.evolve_group;
|
||||||
if (m_ProxyEvolveLevel)
|
if (m_LinkProxyStruct.evolve_level)
|
||||||
m_LinkBodyStruct.evolve_level = m_ProxyEvolveLevel;
|
m_LinkBodyStruct.evolve_level = m_LinkProxyStruct.evolve_level;
|
||||||
if (m_ProxyOrnamentIcon)
|
if (m_LinkProxyStruct.ornament_icon)
|
||||||
m_LinkBodyStruct.ornament_icon = m_ProxyOrnamentIcon;
|
m_LinkBodyStruct.ornament_icon = m_LinkProxyStruct.ornament_icon;
|
||||||
if (m_ProxyHash)
|
if (m_LinkProxyStruct.hash)
|
||||||
m_LinkBodyStruct.hash = m_ProxyHash;
|
m_LinkBodyStruct.hash = m_LinkProxyStruct.hash;
|
||||||
|
|
||||||
|
|
||||||
if (m_TaskUse)
|
if (m_TaskUse)
|
||||||
@ -227,7 +225,7 @@ void EQEmu::SayLinkEngine::generate_body()
|
|||||||
|
|
||||||
m_LinkBody = StringFormat(
|
m_LinkBody = StringFormat(
|
||||||
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
|
"%1X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%05X" "%1X" "%04X" "%02X" "%05X" "%08X",
|
||||||
(0x0F & m_LinkBodyStruct.unknown_1),
|
(0x0F & m_LinkBodyStruct.action_id),
|
||||||
(0x000FFFFF & m_LinkBodyStruct.item_id),
|
(0x000FFFFF & m_LinkBodyStruct.item_id),
|
||||||
(0x000FFFFF & m_LinkBodyStruct.augment_1),
|
(0x000FFFFF & m_LinkBodyStruct.augment_1),
|
||||||
(0x000FFFFF & m_LinkBodyStruct.augment_2),
|
(0x000FFFFF & m_LinkBodyStruct.augment_2),
|
||||||
@ -245,8 +243,8 @@ void EQEmu::SayLinkEngine::generate_body()
|
|||||||
|
|
||||||
void EQEmu::SayLinkEngine::generate_text()
|
void EQEmu::SayLinkEngine::generate_text()
|
||||||
{
|
{
|
||||||
if (m_ProxyText != nullptr) {
|
if (m_LinkProxyStruct.text != nullptr) {
|
||||||
m_LinkText = m_ProxyText;
|
m_LinkText = m_LinkProxyStruct.text;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,7 @@ namespace EQEmu
|
|||||||
} /*saylink*/
|
} /*saylink*/
|
||||||
|
|
||||||
struct SayLinkBody_Struct {
|
struct SayLinkBody_Struct {
|
||||||
uint8 unknown_1; /* %1X */
|
uint8 action_id; /* %1X */
|
||||||
uint32 item_id; /* %05X */
|
uint32 item_id; /* %05X */
|
||||||
uint32 augment_1; /* %05X */
|
uint32 augment_1; /* %05X */
|
||||||
uint32 augment_2; /* %05X */
|
uint32 augment_2; /* %05X */
|
||||||
@ -56,13 +56,18 @@ namespace EQEmu
|
|||||||
uint32 augment_5; /* %05X */
|
uint32 augment_5; /* %05X */
|
||||||
uint32 augment_6; /* %05X */
|
uint32 augment_6; /* %05X */
|
||||||
uint8 is_evolving; /* %1X */
|
uint8 is_evolving; /* %1X */
|
||||||
uint32 evolve_group; /* %05X */
|
uint32 evolve_group; /* %04X */
|
||||||
uint8 evolve_level; /* %02X */
|
uint8 evolve_level; /* %02X */
|
||||||
uint32 ornament_icon; /* %05X */
|
uint32 ornament_icon; /* %05X */
|
||||||
int hash; /* %08X */
|
uint32 hash; /* %08X */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SayLinkProxy_Struct : SayLinkBody_Struct {
|
||||||
|
const char* text;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SayLinkEngine {
|
class SayLinkEngine {
|
||||||
|
// TODO: consider methods for direct 'saylink' assignments
|
||||||
public:
|
public:
|
||||||
SayLinkEngine();
|
SayLinkEngine();
|
||||||
|
|
||||||
@ -72,29 +77,29 @@ namespace EQEmu
|
|||||||
void SetItemInst(const ItemInstance* item_inst) { m_ItemInst = item_inst; }
|
void SetItemInst(const ItemInstance* item_inst) { m_ItemInst = item_inst; }
|
||||||
|
|
||||||
// mainly for saylinks..but, not limited to
|
// mainly for saylinks..but, not limited to
|
||||||
void SetProxyUnknown1(uint8 proxy_unknown_1) { m_Proxy_unknown_1 = proxy_unknown_1; }
|
void SetProxyActionID(uint8 proxy_action_id) { m_LinkProxyStruct.action_id = proxy_action_id; } // should always be '0'
|
||||||
void SetProxyItemID(uint32 proxy_item_id) { m_ProxyItemID = proxy_item_id; }
|
void SetProxyItemID(uint32 proxy_item_id) { m_LinkProxyStruct.item_id = proxy_item_id; }
|
||||||
void SetProxyAugment1ID(uint32 proxy_augment_id) { m_ProxyAugment1ID = proxy_augment_id; }
|
void SetProxyAugment1ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_1 = proxy_augment_id; }
|
||||||
void SetProxyAugment2ID(uint32 proxy_augment_id) { m_ProxyAugment2ID = proxy_augment_id; }
|
void SetProxyAugment2ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_2 = proxy_augment_id; }
|
||||||
void SetProxyAugment3ID(uint32 proxy_augment_id) { m_ProxyAugment3ID = proxy_augment_id; }
|
void SetProxyAugment3ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_3 = proxy_augment_id; }
|
||||||
void SetProxyAugment4ID(uint32 proxy_augment_id) { m_ProxyAugment4ID = proxy_augment_id; }
|
void SetProxyAugment4ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_4 = proxy_augment_id; }
|
||||||
void SetProxyAugment5ID(uint32 proxy_augment_id) { m_ProxyAugment5ID = proxy_augment_id; }
|
void SetProxyAugment5ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_5 = proxy_augment_id; }
|
||||||
void SetProxyAugment6ID(uint32 proxy_augment_id) { m_ProxyAugment6ID = proxy_augment_id; }
|
void SetProxyAugment6ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_6 = proxy_augment_id; }
|
||||||
void SetProxyIsEvolving(uint8 proxy_is_evolving) { m_ProxyIsEvolving = proxy_is_evolving; }
|
void SetProxyIsEvolving(uint8 proxy_is_evolving) { m_LinkProxyStruct.is_evolving = proxy_is_evolving; }
|
||||||
void SetProxyEvolveGroup(uint32 proxy_evolve_group) { m_ProxyEvolveGroup = proxy_evolve_group; }
|
void SetProxyEvolveGroup(uint32 proxy_evolve_group) { m_LinkProxyStruct.evolve_group = proxy_evolve_group; }
|
||||||
void SetProxyEvolveLevel(uint8 proxy_evolve_level) { m_ProxyEvolveLevel = proxy_evolve_level; }
|
void SetProxyEvolveLevel(uint8 proxy_evolve_level) { m_LinkProxyStruct.evolve_level = proxy_evolve_level; }
|
||||||
void SetProxyOrnamentIcon(uint32 proxy_ornament_icon) { m_ProxyOrnamentIcon = proxy_ornament_icon; }
|
void SetProxyOrnamentIcon(uint32 proxy_ornament_icon) { m_LinkProxyStruct.ornament_icon = proxy_ornament_icon; }
|
||||||
void SetProxyHash(int proxy_hash) { m_ProxyHash = proxy_hash; }
|
void SetProxyHash(uint32 proxy_hash) { m_LinkProxyStruct.hash = proxy_hash; }
|
||||||
|
|
||||||
void SetProxyText(const char* proxy_text) { m_ProxyText = proxy_text; } // overrides standard text use
|
void SetProxyText(const char* proxy_text) { m_LinkProxyStruct.text = proxy_text; } // overrides standard text use
|
||||||
void SetTaskUse() { m_TaskUse = true; }
|
void SetTaskUse() { m_TaskUse = true; }
|
||||||
|
|
||||||
std::string GenerateLink();
|
const std::string& GenerateLink();
|
||||||
bool LinkError() { return m_Error; }
|
bool LinkError() { return m_Error; }
|
||||||
|
|
||||||
std::string Link() { return m_Link; } // contains full string format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
|
const std::string& Link() { return m_Link; } // contains full string format: '\x12' '<LinkBody>' '<LinkText>' '\x12'
|
||||||
std::string LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
|
const std::string& LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
|
||||||
std::string LinkText() { return m_LinkText; } // contains string format: '<LinkText>'
|
const std::string& LinkText() { return m_LinkText; } // contains string format: '<LinkText>'
|
||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
@ -106,23 +111,9 @@ namespace EQEmu
|
|||||||
const ItemData* m_ItemData;
|
const ItemData* m_ItemData;
|
||||||
const ServerLootItem_Struct* m_LootData;
|
const ServerLootItem_Struct* m_LootData;
|
||||||
const ItemInstance* m_ItemInst;
|
const ItemInstance* m_ItemInst;
|
||||||
|
|
||||||
uint8 m_Proxy_unknown_1;
|
|
||||||
uint32 m_ProxyItemID;
|
|
||||||
uint32 m_ProxyAugment1ID;
|
|
||||||
uint32 m_ProxyAugment2ID;
|
|
||||||
uint32 m_ProxyAugment3ID;
|
|
||||||
uint32 m_ProxyAugment4ID;
|
|
||||||
uint32 m_ProxyAugment5ID;
|
|
||||||
uint32 m_ProxyAugment6ID;
|
|
||||||
uint8 m_ProxyIsEvolving;
|
|
||||||
uint32 m_ProxyEvolveGroup;
|
|
||||||
uint8 m_ProxyEvolveLevel;
|
|
||||||
uint32 m_ProxyOrnamentIcon;
|
|
||||||
int m_ProxyHash;
|
|
||||||
const char* m_ProxyText;
|
|
||||||
bool m_TaskUse;
|
|
||||||
SayLinkBody_Struct m_LinkBodyStruct;
|
SayLinkBody_Struct m_LinkBodyStruct;
|
||||||
|
SayLinkProxy_Struct m_LinkProxyStruct;
|
||||||
|
bool m_TaskUse;
|
||||||
std::string m_Link;
|
std::string m_Link;
|
||||||
std::string m_LinkBody;
|
std::string m_LinkBody;
|
||||||
std::string m_LinkText;
|
std::string m_LinkText;
|
||||||
|
|||||||
@ -190,6 +190,8 @@
|
|||||||
#define ServerOP_ReloadLogs 0x4010
|
#define ServerOP_ReloadLogs 0x4010
|
||||||
#define ServerOP_ReloadPerlExportSettings 0x4011
|
#define ServerOP_ReloadPerlExportSettings 0x4011
|
||||||
#define ServerOP_CZSetEntityVariableByClientName 0x4012
|
#define ServerOP_CZSetEntityVariableByClientName 0x4012
|
||||||
|
#define ServerOP_UCSServerStatusRequest 0x4013
|
||||||
|
#define ServerOP_UCSServerStatusReply 0x4014
|
||||||
/* Query Server OP Codes */
|
/* Query Server OP Codes */
|
||||||
#define ServerOP_QSPlayerLogTrades 0x5010
|
#define ServerOP_QSPlayerLogTrades 0x5010
|
||||||
#define ServerOP_QSPlayerLogHandins 0x5011
|
#define ServerOP_QSPlayerLogHandins 0x5011
|
||||||
@ -1278,6 +1280,17 @@ struct ServerRequestTellQueue_Struct {
|
|||||||
char name[64];
|
char name[64];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UCSServerStatus_Struct {
|
||||||
|
uint8 available; // non-zero=true, 0=false
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint16 port;
|
||||||
|
uint16 unused;
|
||||||
|
};
|
||||||
|
uint32 timestamp;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -110,6 +110,41 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
|
|||||||
return EntitledTime;
|
return EntitledTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SharedDatabase::SetMailKey(int CharID, int IPAddress, int MailKey)
|
||||||
|
{
|
||||||
|
char MailKeyString[17];
|
||||||
|
|
||||||
|
if (RuleB(Chat, EnableMailKeyIPVerification) == true)
|
||||||
|
sprintf(MailKeyString, "%08X%08X", IPAddress, MailKey);
|
||||||
|
else
|
||||||
|
sprintf(MailKeyString, "%08X", MailKey);
|
||||||
|
|
||||||
|
std::string query = StringFormat("UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
|
||||||
|
MailKeyString, CharID);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
Log(Logs::General, Logs::Error, "SharedDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, results.ErrorMessage().c_str());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SharedDatabase::GetMailKey(int CharID, bool key_only)
|
||||||
|
{
|
||||||
|
std::string query = StringFormat("SELECT `mailkey` FROM `character_data` WHERE `id`='%i' LIMIT 1", CharID);
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
Log(Logs::Detail, Logs::MySQLError, "Error retrieving mailkey from database: %s", results.ErrorMessage().c_str());
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
std::string mail_key = row[0];
|
||||||
|
|
||||||
|
if (mail_key.length() > 8 && key_only)
|
||||||
|
return mail_key.substr(8);
|
||||||
|
else
|
||||||
|
return mail_key;
|
||||||
|
}
|
||||||
|
|
||||||
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<EQEmu::ItemInstance*>::const_iterator &start, std::list<EQEmu::ItemInstance*>::const_iterator &end)
|
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<EQEmu::ItemInstance*>::const_iterator &start, std::list<EQEmu::ItemInstance*>::const_iterator &end)
|
||||||
{
|
{
|
||||||
// Delete cursor items
|
// Delete cursor items
|
||||||
|
|||||||
@ -72,6 +72,8 @@ class SharedDatabase : public Database
|
|||||||
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message);
|
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message);
|
||||||
bool GetCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &command_settings);
|
bool GetCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &command_settings);
|
||||||
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
|
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
|
||||||
|
void SetMailKey(int CharID, int IPAddress, int MailKey);
|
||||||
|
std::string GetMailKey(int CharID, bool key_only = false);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Character InventoryProfile
|
Character InventoryProfile
|
||||||
|
|||||||
@ -972,7 +972,6 @@ bool IsCastWhileInvis(uint16 spell_id);
|
|||||||
bool IsEffectIgnoredInStacking(int spa);
|
bool IsEffectIgnoredInStacking(int spa);
|
||||||
|
|
||||||
int CalcPetHp(int levelb, int classb, int STA = 75);
|
int CalcPetHp(int levelb, int classb, int STA = 75);
|
||||||
const char *GetRandPetName();
|
|
||||||
int GetSpellEffectDescNum(uint16 spell_id);
|
int GetSpellEffectDescNum(uint16 spell_id);
|
||||||
DmgShieldType GetDamageShieldType(uint16 spell_id, int32 DSType = 0);
|
DmgShieldType GetDamageShieldType(uint16 spell_id, int32 DSType = 0);
|
||||||
bool DetrimentalSpellAllowsRest(uint16 spell_id);
|
bool DetrimentalSpellAllowsRest(uint16 spell_id);
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9120
|
#define CURRENT_BINARY_DATABASE_VERSION 9122
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9018
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9018
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -28,6 +28,10 @@
|
|||||||
extern Database database;
|
extern Database database;
|
||||||
extern uint32 ChatMessagesSent;
|
extern uint32 ChatMessagesSent;
|
||||||
|
|
||||||
|
void ServerToClient45SayLink(std::string& clientSayLink, const std::string& serverSayLink);
|
||||||
|
void ServerToClient50SayLink(std::string& clientSayLink, const std::string& serverSayLink);
|
||||||
|
void ServerToClient55SayLink(std::string& clientSayLink, const std::string& serverSayLink);
|
||||||
|
|
||||||
ChatChannel::ChatChannel(std::string inName, std::string inOwner, std::string inPassword, bool inPermanent, int inMinimumStatus) :
|
ChatChannel::ChatChannel(std::string inName, std::string inOwner, std::string inPassword, bool inPermanent, int inMinimumStatus) :
|
||||||
DeleteTimer(0) {
|
DeleteTimer(0) {
|
||||||
|
|
||||||
@ -384,6 +388,8 @@ void ChatChannel::SendMessageToChannel(std::string Message, Client* Sender) {
|
|||||||
|
|
||||||
if(!Sender) return;
|
if(!Sender) return;
|
||||||
|
|
||||||
|
std::string cv_messages[EQEmu::versions::ClientVersionCount];
|
||||||
|
|
||||||
ChatMessagesSent++;
|
ChatMessagesSent++;
|
||||||
|
|
||||||
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
LinkedListIterator<Client*> iterator(ClientsInChannel);
|
||||||
@ -398,7 +404,28 @@ void ChatChannel::SendMessageToChannel(std::string Message, Client* Sender) {
|
|||||||
{
|
{
|
||||||
Log(Logs::Detail, Logs::UCS_Server, "Sending message to %s from %s",
|
Log(Logs::Detail, Logs::UCS_Server, "Sending message to %s from %s",
|
||||||
ChannelClient->GetName().c_str(), Sender->GetName().c_str());
|
ChannelClient->GetName().c_str(), Sender->GetName().c_str());
|
||||||
ChannelClient->SendChannelMessage(Name, Message, Sender);
|
|
||||||
|
if (cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())].length() == 0) {
|
||||||
|
switch (ChannelClient->GetClientVersion()) {
|
||||||
|
case EQEmu::versions::ClientVersion::Titanium:
|
||||||
|
ServerToClient45SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::SoF:
|
||||||
|
case EQEmu::versions::ClientVersion::SoD:
|
||||||
|
case EQEmu::versions::ClientVersion::UF:
|
||||||
|
ServerToClient50SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::RoF:
|
||||||
|
ServerToClient55SayLink(cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Message);
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::RoF2:
|
||||||
|
default:
|
||||||
|
cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())] = Message;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelClient->SendChannelMessage(Name, cv_messages[static_cast<uint32>(ChannelClient->GetClientVersion())], Sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator.Advance();
|
iterator.Advance();
|
||||||
@ -655,3 +682,118 @@ std::string CapitaliseName(std::string inString) {
|
|||||||
return NormalisedName;
|
return NormalisedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerToClient45SayLink(std::string& clientSayLink, const std::string& serverSayLink) {
|
||||||
|
if (serverSayLink.find('\x12') == std::string::npos) {
|
||||||
|
clientSayLink = serverSayLink;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto segments = SplitString(serverSayLink, '\x12');
|
||||||
|
|
||||||
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
|
if (segment_iter & 1) {
|
||||||
|
if (segments[segment_iter].length() <= 56) {
|
||||||
|
clientSayLink.append(segments[segment_iter]);
|
||||||
|
// TODO: log size mismatch error
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||||
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
|
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
||||||
|
// Diff: ^^^^^ ^ ^^^^^
|
||||||
|
|
||||||
|
clientSayLink.push_back('\x12');
|
||||||
|
clientSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
|
clientSayLink.append(segments[segment_iter].substr(36, 5));
|
||||||
|
|
||||||
|
if (segments[segment_iter][41] == '0')
|
||||||
|
clientSayLink.push_back(segments[segment_iter][42]);
|
||||||
|
else
|
||||||
|
clientSayLink.push_back('F');
|
||||||
|
|
||||||
|
clientSayLink.append(segments[segment_iter].substr(48));
|
||||||
|
clientSayLink.push_back('\x12');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clientSayLink.append(segments[segment_iter]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerToClient50SayLink(std::string& clientSayLink, const std::string& serverSayLink) {
|
||||||
|
if (serverSayLink.find('\x12') == std::string::npos) {
|
||||||
|
clientSayLink = serverSayLink;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto segments = SplitString(serverSayLink, '\x12');
|
||||||
|
|
||||||
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
|
if (segment_iter & 1) {
|
||||||
|
if (segments[segment_iter].length() <= 56) {
|
||||||
|
clientSayLink.append(segments[segment_iter]);
|
||||||
|
// TODO: log size mismatch error
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||||
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
|
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||||
|
// Diff: ^^^^^ ^
|
||||||
|
|
||||||
|
clientSayLink.push_back('\x12');
|
||||||
|
clientSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
|
clientSayLink.append(segments[segment_iter].substr(36, 5));
|
||||||
|
|
||||||
|
if (segments[segment_iter][41] == '0')
|
||||||
|
clientSayLink.push_back(segments[segment_iter][42]);
|
||||||
|
else
|
||||||
|
clientSayLink.push_back('F');
|
||||||
|
|
||||||
|
clientSayLink.append(segments[segment_iter].substr(43));
|
||||||
|
clientSayLink.push_back('\x12');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clientSayLink.append(segments[segment_iter]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerToClient55SayLink(std::string& clientSayLink, const std::string& serverSayLink) {
|
||||||
|
if (serverSayLink.find('\x12') == std::string::npos) {
|
||||||
|
clientSayLink = serverSayLink;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto segments = SplitString(serverSayLink, '\x12');
|
||||||
|
|
||||||
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
|
if (segment_iter & 1) {
|
||||||
|
if (segments[segment_iter].length() <= 56) {
|
||||||
|
clientSayLink.append(segments[segment_iter]);
|
||||||
|
// TODO: log size mismatch error
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Idx: 0 1 6 11 16 21 26 31 36 37 41 43 48 (Source)
|
||||||
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
|
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
||||||
|
// Diff: ^
|
||||||
|
|
||||||
|
clientSayLink.push_back('\x12');
|
||||||
|
clientSayLink.append(segments[segment_iter].substr(0, 41));
|
||||||
|
|
||||||
|
if (segments[segment_iter][41] == '0')
|
||||||
|
clientSayLink.push_back(segments[segment_iter][42]);
|
||||||
|
else
|
||||||
|
clientSayLink.push_back('F');
|
||||||
|
|
||||||
|
clientSayLink.append(segments[segment_iter].substr(43));
|
||||||
|
clientSayLink.push_back('\x12');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clientSayLink.append(segments[segment_iter]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -513,6 +513,7 @@ Client::Client(std::shared_ptr<EQStreamInterface> eqs) {
|
|||||||
GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS));
|
GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS));
|
||||||
|
|
||||||
TypeOfConnection = ConnectionTypeUnknown;
|
TypeOfConnection = ConnectionTypeUnknown;
|
||||||
|
ClientVersion_ = EQEmu::versions::ClientVersion::Unknown;
|
||||||
|
|
||||||
UnderfootOrLater = false;
|
UnderfootOrLater = false;
|
||||||
}
|
}
|
||||||
@ -681,6 +682,7 @@ void Clientlist::Process()
|
|||||||
it = ClientChatConnections.erase(it);
|
it = ClientChatConnections.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2134,34 +2136,62 @@ void Client::SetConnectionType(char c) {
|
|||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'S':
|
case EQEmu::versions::ucsTitaniumChat:
|
||||||
{
|
|
||||||
TypeOfConnection = ConnectionTypeCombined;
|
|
||||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (SoF/SoD)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'U':
|
|
||||||
{
|
|
||||||
TypeOfConnection = ConnectionTypeCombined;
|
|
||||||
UnderfootOrLater = true;
|
|
||||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (Underfoot+)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'M':
|
|
||||||
{
|
|
||||||
TypeOfConnection = ConnectionTypeMail;
|
|
||||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Mail (6.2 or Titanium client)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'C':
|
|
||||||
{
|
{
|
||||||
TypeOfConnection = ConnectionTypeChat;
|
TypeOfConnection = ConnectionTypeChat;
|
||||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Chat (6.2 or Titanium client)");
|
ClientVersion_ = EQEmu::versions::ClientVersion::Titanium;
|
||||||
|
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Chat (Titanium)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EQEmu::versions::ucsTitaniumMail:
|
||||||
|
{
|
||||||
|
TypeOfConnection = ConnectionTypeMail;
|
||||||
|
ClientVersion_ = EQEmu::versions::ClientVersion::Titanium;
|
||||||
|
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Mail (Titanium)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EQEmu::versions::ucsSoFCombined:
|
||||||
|
{
|
||||||
|
TypeOfConnection = ConnectionTypeCombined;
|
||||||
|
ClientVersion_ = EQEmu::versions::ClientVersion::SoF;
|
||||||
|
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (SoF)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EQEmu::versions::ucsSoDCombined:
|
||||||
|
{
|
||||||
|
TypeOfConnection = ConnectionTypeCombined;
|
||||||
|
ClientVersion_ = EQEmu::versions::ClientVersion::SoD;
|
||||||
|
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (SoD)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EQEmu::versions::ucsUFCombined:
|
||||||
|
{
|
||||||
|
TypeOfConnection = ConnectionTypeCombined;
|
||||||
|
ClientVersion_ = EQEmu::versions::ClientVersion::UF;
|
||||||
|
UnderfootOrLater = true;
|
||||||
|
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (Underfoot)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EQEmu::versions::ucsRoFCombined:
|
||||||
|
{
|
||||||
|
TypeOfConnection = ConnectionTypeCombined;
|
||||||
|
ClientVersion_ = EQEmu::versions::ClientVersion::RoF;
|
||||||
|
UnderfootOrLater = true;
|
||||||
|
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (RoF)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EQEmu::versions::ucsRoF2Combined:
|
||||||
|
{
|
||||||
|
TypeOfConnection = ConnectionTypeCombined;
|
||||||
|
ClientVersion_ = EQEmu::versions::ClientVersion::RoF2;
|
||||||
|
UnderfootOrLater = true;
|
||||||
|
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (RoF2)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
TypeOfConnection = ConnectionTypeUnknown;
|
TypeOfConnection = ConnectionTypeUnknown;
|
||||||
|
ClientVersion_ = EQEmu::versions::ClientVersion::Unknown;
|
||||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is unknown.");
|
Log(Logs::Detail, Logs::UCS_Server, "Connection type is unknown.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -139,8 +139,11 @@ public:
|
|||||||
std::string MailBoxName();
|
std::string MailBoxName();
|
||||||
int GetMailBoxNumber() { return CurrentMailBox; }
|
int GetMailBoxNumber() { return CurrentMailBox; }
|
||||||
int GetMailBoxNumber(std::string CharacterName);
|
int GetMailBoxNumber(std::string CharacterName);
|
||||||
|
|
||||||
void SetConnectionType(char c);
|
void SetConnectionType(char c);
|
||||||
ConnectionType GetConnectionType() { return TypeOfConnection; }
|
ConnectionType GetConnectionType() { return TypeOfConnection; }
|
||||||
|
EQEmu::versions::ClientVersion GetClientVersion() { return ClientVersion_; }
|
||||||
|
|
||||||
inline bool IsMailConnection() { return (TypeOfConnection == ConnectionTypeMail) || (TypeOfConnection == ConnectionTypeCombined); }
|
inline bool IsMailConnection() { return (TypeOfConnection == ConnectionTypeMail) || (TypeOfConnection == ConnectionTypeCombined); }
|
||||||
void SendNotification(int MailBoxNumber, std::string From, std::string Subject, int MessageID);
|
void SendNotification(int MailBoxNumber, std::string From, std::string Subject, int MessageID);
|
||||||
void ChangeMailBox(int NewMailBox);
|
void ChangeMailBox(int NewMailBox);
|
||||||
@ -167,7 +170,9 @@ private:
|
|||||||
Timer *GlobalChatLimiterTimer; //60 seconds
|
Timer *GlobalChatLimiterTimer; //60 seconds
|
||||||
int AttemptedMessages;
|
int AttemptedMessages;
|
||||||
bool ForceDisconnect;
|
bool ForceDisconnect;
|
||||||
|
|
||||||
ConnectionType TypeOfConnection;
|
ConnectionType TypeOfConnection;
|
||||||
|
EQEmu::versions::ClientVersion ClientVersion_;
|
||||||
bool UnderfootOrLater;
|
bool UnderfootOrLater;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -183,7 +188,6 @@ public:
|
|||||||
void ProcessOPMailCommand(Client *c, std::string CommandString);
|
void ProcessOPMailCommand(Client *c, std::string CommandString);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
EQ::Net::EQStreamManager *chatsf;
|
EQ::Net::EQStreamManager *chatsf;
|
||||||
|
|
||||||
std::list<Client*> ClientChatConnections;
|
std::list<Client*> ClientChatConnections;
|
||||||
|
|||||||
@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "../common/misc_functions.h"
|
#include "../common/misc_functions.h"
|
||||||
#include "../common/packet_functions.h"
|
#include "../common/packet_functions.h"
|
||||||
#include "../common/md5.h"
|
#include "../common/md5.h"
|
||||||
|
#include "../common/string_util.h"
|
||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
#include "clientlist.h"
|
#include "clientlist.h"
|
||||||
#include "ucsconfig.h"
|
#include "ucsconfig.h"
|
||||||
@ -41,6 +42,10 @@ extern Database database;
|
|||||||
|
|
||||||
void ProcessMailTo(Client *c, std::string from, std::string subject, std::string message);
|
void ProcessMailTo(Client *c, std::string from, std::string subject, std::string message);
|
||||||
|
|
||||||
|
void Client45ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink);
|
||||||
|
void Client50ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink);
|
||||||
|
void Client55ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink);
|
||||||
|
|
||||||
WorldServer::WorldServer()
|
WorldServer::WorldServer()
|
||||||
{
|
{
|
||||||
m_connection.reset(new EQ::Net::ServertalkClient(Config->WorldIP, Config->WorldTCPPort, false, "UCS", Config->SharedKey));
|
m_connection.reset(new EQ::Net::ServertalkClient(Config->WorldIP, Config->WorldTCPPort, false, "UCS", Config->SharedKey));
|
||||||
@ -94,7 +99,26 @@ void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
|
|||||||
|
|
||||||
if (Message[0] == ';')
|
if (Message[0] == ';')
|
||||||
{
|
{
|
||||||
c->SendChannelMessageByNumber(Message.substr(1, std::string::npos));
|
std::string new_message;
|
||||||
|
switch (c->GetClientVersion()) {
|
||||||
|
case EQEmu::versions::ClientVersion::Titanium:
|
||||||
|
Client45ToServerSayLink(new_message, Message.substr(1, std::string::npos));
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::SoF:
|
||||||
|
case EQEmu::versions::ClientVersion::SoD:
|
||||||
|
case EQEmu::versions::ClientVersion::UF:
|
||||||
|
Client50ToServerSayLink(new_message, Message.substr(1, std::string::npos));
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::RoF:
|
||||||
|
Client55ToServerSayLink(new_message, Message.substr(1, std::string::npos));
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::RoF2:
|
||||||
|
default:
|
||||||
|
new_message = Message.substr(1, std::string::npos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->SendChannelMessageByNumber(new_message);
|
||||||
}
|
}
|
||||||
else if (Message[0] == '[')
|
else if (Message[0] == '[')
|
||||||
{
|
{
|
||||||
@ -116,3 +140,108 @@ void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client45ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink) {
|
||||||
|
if (clientSayLink.find('\x12') == std::string::npos) {
|
||||||
|
serverSayLink = clientSayLink;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto segments = SplitString(clientSayLink, '\x12');
|
||||||
|
|
||||||
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
|
if (segment_iter & 1) {
|
||||||
|
if (segments[segment_iter].length() <= 45) {
|
||||||
|
serverSayLink.append(segments[segment_iter]);
|
||||||
|
// TODO: log size mismatch error
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Idx: 0 1 6 11 16 21 26 31 32 36 37 (Source)
|
||||||
|
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
|
||||||
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
|
// Diff: ^^^^^ ^ ^^^^^
|
||||||
|
|
||||||
|
serverSayLink.push_back('\x12');
|
||||||
|
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
|
serverSayLink.append("00000");
|
||||||
|
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||||
|
serverSayLink.push_back('0');
|
||||||
|
serverSayLink.push_back(segments[segment_iter][36]);
|
||||||
|
serverSayLink.append("00000");
|
||||||
|
serverSayLink.append(segments[segment_iter].substr(37));
|
||||||
|
serverSayLink.push_back('\x12');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
serverSayLink.append(segments[segment_iter]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client50ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink) {
|
||||||
|
if (clientSayLink.find('\x12') == std::string::npos) {
|
||||||
|
serverSayLink = clientSayLink;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto segments = SplitString(clientSayLink, '\x12');
|
||||||
|
|
||||||
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
|
if (segment_iter & 1) {
|
||||||
|
if (segments[segment_iter].length() <= 50) {
|
||||||
|
serverSayLink.append(segments[segment_iter]);
|
||||||
|
// TODO: log size mismatch error
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Idx: 0 1 6 11 16 21 26 31 32 36 37 42 (Source)
|
||||||
|
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
|
||||||
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
|
// Diff: ^^^^^ ^
|
||||||
|
|
||||||
|
serverSayLink.push_back('\x12');
|
||||||
|
serverSayLink.append(segments[segment_iter].substr(0, 31));
|
||||||
|
serverSayLink.append("00000");
|
||||||
|
serverSayLink.append(segments[segment_iter].substr(31, 5));
|
||||||
|
serverSayLink.push_back('0');
|
||||||
|
serverSayLink.append(segments[segment_iter].substr(36));
|
||||||
|
serverSayLink.push_back('\x12');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
serverSayLink.append(segments[segment_iter]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client55ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink) {
|
||||||
|
if (clientSayLink.find('\x12') == std::string::npos) {
|
||||||
|
serverSayLink = clientSayLink;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto segments = SplitString(clientSayLink, '\x12');
|
||||||
|
|
||||||
|
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
|
||||||
|
if (segment_iter & 1) {
|
||||||
|
if (segments[segment_iter].length() <= 55) {
|
||||||
|
serverSayLink.append(segments[segment_iter]);
|
||||||
|
// TODO: log size mismatch error
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Idx: 0 1 6 11 16 21 26 31 36 37 41 42 47 (Source)
|
||||||
|
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
|
||||||
|
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
|
||||||
|
// Diff: ^
|
||||||
|
|
||||||
|
serverSayLink.push_back('\x12');
|
||||||
|
serverSayLink.append(segments[segment_iter].substr(0, 41));
|
||||||
|
serverSayLink.push_back('0');
|
||||||
|
serverSayLink.append(segments[segment_iter].substr(41));
|
||||||
|
serverSayLink.push_back('\x12');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
serverSayLink.append(segments[segment_iter]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -165,6 +165,7 @@ OP_GMNameChange=0x3077 # Was 0x4434
|
|||||||
OP_GMLastName=0x4dd7 # Was 0x3077
|
OP_GMLastName=0x4dd7 # Was 0x3077
|
||||||
|
|
||||||
# Misc Opcodes
|
# Misc Opcodes
|
||||||
|
OP_QueryUCSServerStatus=0x6964
|
||||||
OP_InspectRequest=0x23f1
|
OP_InspectRequest=0x23f1
|
||||||
OP_InspectAnswer=0x5794
|
OP_InspectAnswer=0x5794
|
||||||
OP_InspectMessageUpdate=0x3064
|
OP_InspectMessageUpdate=0x3064
|
||||||
|
|||||||
@ -164,6 +164,7 @@ OP_GMNameChange=0x035f
|
|||||||
OP_GMLastName=0x46ce
|
OP_GMLastName=0x46ce
|
||||||
|
|
||||||
# Misc Opcodes
|
# Misc Opcodes
|
||||||
|
OP_QueryUCSServerStatus=0x398f
|
||||||
OP_InspectRequest=0x57bc
|
OP_InspectRequest=0x57bc
|
||||||
OP_InspectAnswer=0x71ac
|
OP_InspectAnswer=0x71ac
|
||||||
OP_InspectMessageUpdate=0x4d25
|
OP_InspectMessageUpdate=0x4d25
|
||||||
|
|||||||
@ -165,6 +165,7 @@ OP_GMKill=0x6685 # C
|
|||||||
OP_GMNameChange=0x565d # C
|
OP_GMNameChange=0x565d # C
|
||||||
OP_GMLastName=0x3563 # C
|
OP_GMLastName=0x3563 # C
|
||||||
|
|
||||||
|
OP_QueryUCSServerStatus=0x4036
|
||||||
OP_InspectAnswer=0x4938 # C
|
OP_InspectAnswer=0x4938 # C
|
||||||
OP_Action2=0x7e4d # C OP_Damage?
|
OP_Action2=0x7e4d # C OP_Damage?
|
||||||
OP_BeginCast=0x0d5a # C
|
OP_BeginCast=0x0d5a # C
|
||||||
|
|||||||
@ -168,6 +168,7 @@ OP_GMKill=0x799c # C
|
|||||||
OP_GMNameChange=0x0f48 # C
|
OP_GMNameChange=0x0f48 # C
|
||||||
OP_GMLastName=0x7bfb # C
|
OP_GMLastName=0x7bfb # C
|
||||||
|
|
||||||
|
OP_QueryUCSServerStatus=0x4481
|
||||||
OP_InspectAnswer=0x0c2b # C
|
OP_InspectAnswer=0x0c2b # C
|
||||||
OP_BeginCast=0x0d5a # C
|
OP_BeginCast=0x0d5a # C
|
||||||
OP_ColoredText=0x71bf # C
|
OP_ColoredText=0x71bf # C
|
||||||
|
|||||||
@ -121,17 +121,13 @@ if [[ "$OS" == "Debian" ]]; then
|
|||||||
apt-get $apt_options install libsodium18
|
apt-get $apt_options install libsodium18
|
||||||
apt-get $apt_options install libjson-perl
|
apt-get $apt_options install libjson-perl
|
||||||
|
|
||||||
# If libsodium18 isn't installed (Debian), let's download both that and the dev package and install them.
|
# Install libsodium
|
||||||
if dpkg-query -s "libsodium18" 1>/dev/null 2>&1; then
|
wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium-dev_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium-dev.deb
|
||||||
echo "Sodium library already installed."
|
wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium18_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium18.deb
|
||||||
else
|
dpkg -i /home/eqemu/libsodium*.deb
|
||||||
wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium-dev_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium-dev.deb
|
# Cleanup after ourselves
|
||||||
wget http://ftp.us.debian.org/debian/pool/main/libs/libsodium/libsodium18_1.0.11-1~bpo8+1_amd64.deb -O /home/eqemu/libsodium18.deb
|
rm -f /home/eqemu/libsodium-dev.deb
|
||||||
dpkg -i /home/eqemu/libsodium*.deb
|
rm -f /home/eqemu/libsodium18.deb
|
||||||
# Cleanup after ourselves
|
|
||||||
rm -f /home/eqemu/libsodium-dev.deb
|
|
||||||
rm -f /home/eqemu/libsodium18.deb
|
|
||||||
fi
|
|
||||||
|
|
||||||
#::: Install FTP for remote FTP access
|
#::: Install FTP for remote FTP access
|
||||||
echo "proftpd-basic shared/proftpd/inetd_or_standalone select standalone" | debconf-set-selections
|
echo "proftpd-basic shared/proftpd/inetd_or_standalone select standalone" | debconf-set-selections
|
||||||
|
|||||||
@ -374,6 +374,8 @@
|
|||||||
9118|2018_02_04_Charm_Stats.sql|SHOW COLUMNS FROM `npc_types` LIKE 'charm_ac'|empty|
|
9118|2018_02_04_Charm_Stats.sql|SHOW COLUMNS FROM `npc_types` LIKE 'charm_ac'|empty|
|
||||||
9119|2018_02_10_GlobalLoot.sql|SHOW TABLES LIKE 'global_loot'|empty|
|
9119|2018_02_10_GlobalLoot.sql|SHOW TABLES LIKE 'global_loot'|empty|
|
||||||
9120|2018_02_13_Heading.sql|SELECT value FROM variables WHERE varname = 'fixed_heading'|empty|
|
9120|2018_02_13_Heading.sql|SELECT value FROM variables WHERE varname = 'fixed_heading'|empty|
|
||||||
|
9121|2018_02_18_bug_reports.sql|SHOW TABLES LIKE 'bug_reports'|empty|
|
||||||
|
9122|2018_03_07_ucs_command.sql|SELECT * FROM `command_settings` WHERE `command` LIKE 'ucs'|empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
UPDATE spawn2 SET heading = heading * 8.0 / 4.0;
|
UPDATE spawn2 SET heading = heading * 8.0 / 4.0;
|
||||||
UPDATE grid_entries SET heading = heading * 8.0 / 4.0 WHERE heading <> -1;
|
UPDATE grid_entries SET heading = heading * 8.0 / 4.0 WHERE heading <> -1;
|
||||||
INSERT INTO variables (varname, value) VALUES ('fixed_heading', 1); -- hack
|
INSERT INTO variables (varname, value, information) VALUES ('fixed_heading', 1, 'manifest heading fix hack'); -- hack
|
||||||
|
|||||||
44
utils/sql/git/required/2018_02_18_bug_reports.sql
Normal file
44
utils/sql/git/required/2018_02_18_bug_reports.sql
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
CREATE TABLE `bug_reports` (
|
||||||
|
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`zone` VARCHAR(32) NOT NULL DEFAULT 'Unknown',
|
||||||
|
`client_version_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`client_version_name` VARCHAR(24) NOT NULL DEFAULT 'Unknown',
|
||||||
|
`account_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`character_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`character_name` VARCHAR(64) NOT NULL DEFAULT 'Unknown',
|
||||||
|
`reporter_spoof` TINYINT(1) NOT NULL DEFAULT '1',
|
||||||
|
`category_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`category_name` VARCHAR(64) NOT NULL DEFAULT 'Other',
|
||||||
|
`reporter_name` VARCHAR(64) NOT NULL DEFAULT 'Unknown',
|
||||||
|
`ui_path` VARCHAR(128) NOT NULL DEFAULT 'Unknown',
|
||||||
|
`pos_x` FLOAT NOT NULL DEFAULT '0',
|
||||||
|
`pos_y` FLOAT NOT NULL DEFAULT '0',
|
||||||
|
`pos_z` FLOAT NOT NULL DEFAULT '0',
|
||||||
|
`heading` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`time_played` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`target_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`target_name` VARCHAR(64) NOT NULL DEFAULT 'Unknown',
|
||||||
|
`optional_info_mask` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`_can_duplicate` TINYINT(1) NOT NULL DEFAULT '0',
|
||||||
|
`_crash_bug` TINYINT(1) NOT NULL DEFAULT '0',
|
||||||
|
`_target_info` TINYINT(1) NOT NULL DEFAULT '0',
|
||||||
|
`_character_flags` TINYINT(1) NOT NULL DEFAULT '0',
|
||||||
|
`_unknown_value` TINYINT(1) NOT NULL DEFAULT '0',
|
||||||
|
`bug_report` VARCHAR(1024) NOT NULL DEFAULT '',
|
||||||
|
`system_info` VARCHAR(1024) NOT NULL DEFAULT '',
|
||||||
|
`report_datetime` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`bug_status` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`last_review` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`last_reviewer` VARCHAR(64) NOT NULL DEFAULT 'None',
|
||||||
|
`reviewer_notes` VARCHAR(1024) NOT NULL DEFAULT '',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE INDEX `id` (`id`)
|
||||||
|
)
|
||||||
|
COLLATE='utf8_general_ci'
|
||||||
|
ENGINE=InnoDB
|
||||||
|
;
|
||||||
|
|
||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES
|
||||||
|
(1, 'Bugs:ReportingSystemActive', 'true', 'Activates bug reporting'),
|
||||||
|
(1, 'Bugs:UseOldReportingMethod', 'true', 'Forces the use of the old bug reporting system'),
|
||||||
|
(1, 'Bugs:DumpTargetEntity', 'false', 'Dumps the target entity, if one is provided');
|
||||||
1
utils/sql/git/required/2018_03_07_ucs_command.sql
Normal file
1
utils/sql/git/required/2018_03_07_ucs_command.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `command_settings` VALUES ('ucs', '0', '');
|
||||||
106
world/client.cpp
106
world/client.cpp
@ -84,8 +84,9 @@ extern LoginServerList loginserverlist;
|
|||||||
extern ClientList client_list;
|
extern ClientList client_list;
|
||||||
extern EQEmu::Random emu_random;
|
extern EQEmu::Random emu_random;
|
||||||
extern uint32 numclients;
|
extern uint32 numclients;
|
||||||
extern volatile bool RunLoops;
|
|
||||||
extern NatsManager nats;
|
extern NatsManager nats;
|
||||||
|
extern volatile bool RunLoops;
|
||||||
|
extern volatile bool UCSServerAvailable_;
|
||||||
|
|
||||||
Client::Client(EQStreamInterface* ieqs)
|
Client::Client(EQStreamInterface* ieqs)
|
||||||
: autobootup_timeout(RuleI(World, ZoneAutobootTimeoutMS)),
|
: autobootup_timeout(RuleI(World, ZoneAutobootTimeoutMS)),
|
||||||
@ -894,53 +895,84 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
}
|
}
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
// set mailkey - used for duration of character session
|
||||||
int MailKey = emu_random.Int(1, INT_MAX);
|
int MailKey = emu_random.Int(1, INT_MAX);
|
||||||
|
|
||||||
database.SetMailKey(charid, GetIP(), MailKey);
|
database.SetMailKey(charid, GetIP(), MailKey);
|
||||||
|
if (UCSServerAvailable_) {
|
||||||
|
const WorldConfig *Config = WorldConfig::get();
|
||||||
|
std::string buffer;
|
||||||
|
|
||||||
char ConnectionType;
|
EQEmu::versions::UCSVersion ConnectionType = EQEmu::versions::ucsUnknown;
|
||||||
|
|
||||||
if (m_ClientVersionBit & EQEmu::versions::bit_UFAndLater)
|
// chat server packet
|
||||||
ConnectionType = 'U';
|
switch (GetClientVersion()) {
|
||||||
else if (m_ClientVersionBit & EQEmu::versions::bit_SoFAndLater)
|
case EQEmu::versions::ClientVersion::Titanium:
|
||||||
ConnectionType = 'S';
|
ConnectionType = EQEmu::versions::ucsTitaniumChat;
|
||||||
else
|
break;
|
||||||
ConnectionType = 'C';
|
case EQEmu::versions::ClientVersion::SoF:
|
||||||
|
ConnectionType = EQEmu::versions::ucsSoFCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::SoD:
|
||||||
|
ConnectionType = EQEmu::versions::ucsSoDCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::UF:
|
||||||
|
ConnectionType = EQEmu::versions::ucsUFCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::RoF:
|
||||||
|
ConnectionType = EQEmu::versions::ucsRoFCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::RoF2:
|
||||||
|
ConnectionType = EQEmu::versions::ucsRoF2Combined;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ConnectionType = EQEmu::versions::ucsUnknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
auto outapp2 = new EQApplicationPacket(OP_SetChatServer);
|
buffer = StringFormat("%s,%i,%s.%s,%c%08X",
|
||||||
char buffer[112];
|
Config->ChatHost.c_str(),
|
||||||
|
Config->ChatPort,
|
||||||
|
Config->ShortName.c_str(),
|
||||||
|
GetCharName(),
|
||||||
|
ConnectionType,
|
||||||
|
MailKey
|
||||||
|
);
|
||||||
|
|
||||||
const WorldConfig *Config = WorldConfig::get();
|
outapp = new EQApplicationPacket(OP_SetChatServer, (buffer.length() + 1));
|
||||||
|
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
|
||||||
|
outapp->pBuffer[buffer.length()] = '\0';
|
||||||
|
|
||||||
sprintf(buffer,"%s,%i,%s.%s,%c%08X",
|
QueuePacket(outapp);
|
||||||
Config->ChatHost.c_str(),
|
safe_delete(outapp);
|
||||||
Config->ChatPort,
|
|
||||||
Config->ShortName.c_str(),
|
|
||||||
this->GetCharName(), ConnectionType, MailKey
|
|
||||||
);
|
|
||||||
outapp2->size=strlen(buffer)+1;
|
|
||||||
outapp2->pBuffer = new uchar[outapp2->size];
|
|
||||||
memcpy(outapp2->pBuffer,buffer,outapp2->size);
|
|
||||||
QueuePacket(outapp2);
|
|
||||||
safe_delete(outapp2);
|
|
||||||
|
|
||||||
outapp2 = new EQApplicationPacket(OP_SetChatServer2);
|
// mail server packet
|
||||||
|
switch (GetClientVersion()) {
|
||||||
|
case EQEmu::versions::ClientVersion::Titanium:
|
||||||
|
ConnectionType = EQEmu::versions::ucsTitaniumMail;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// retain value from previous switch
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_ClientVersionBit & EQEmu::versions::bit_TitaniumAndEarlier)
|
buffer = StringFormat("%s,%i,%s.%s,%c%08X",
|
||||||
ConnectionType = 'M';
|
Config->MailHost.c_str(),
|
||||||
|
Config->MailPort,
|
||||||
|
Config->ShortName.c_str(),
|
||||||
|
GetCharName(),
|
||||||
|
ConnectionType,
|
||||||
|
MailKey
|
||||||
|
);
|
||||||
|
|
||||||
sprintf(buffer,"%s,%i,%s.%s,%c%08X",
|
outapp = new EQApplicationPacket(OP_SetChatServer2, (buffer.length() + 1));
|
||||||
Config->MailHost.c_str(),
|
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
|
||||||
Config->MailPort,
|
outapp->pBuffer[buffer.length()] = '\0';
|
||||||
Config->ShortName.c_str(),
|
|
||||||
this->GetCharName(), ConnectionType, MailKey
|
QueuePacket(outapp);
|
||||||
);
|
safe_delete(outapp);
|
||||||
outapp2->size=strlen(buffer)+1;
|
}
|
||||||
outapp2->pBuffer = new uchar[outapp2->size];
|
|
||||||
memcpy(outapp2->pBuffer,buffer,outapp2->size);
|
|
||||||
QueuePacket(outapp2);
|
|
||||||
safe_delete(outapp2);
|
|
||||||
|
|
||||||
EnterWorld();
|
EnterWorld();
|
||||||
|
|
||||||
|
|||||||
@ -68,6 +68,7 @@ public:
|
|||||||
inline const char* GetLSKey() { if (cle) { return cle->GetLSKey(); } return "NOKEY"; }
|
inline const char* GetLSKey() { if (cle) { return cle->GetLSKey(); } return "NOKEY"; }
|
||||||
inline uint32 GetCharID() { return charid; }
|
inline uint32 GetCharID() { return charid; }
|
||||||
inline const char* GetCharName() { return char_name; }
|
inline const char* GetCharName() { return char_name; }
|
||||||
|
inline EQEmu::versions::ClientVersion GetClientVersion() { return m_ClientVersion; }
|
||||||
inline ClientListEntry* GetCLE() { return cle; }
|
inline ClientListEntry* GetCLE() { return cle; }
|
||||||
inline void SetCLE(ClientListEntry* iCLE) { cle = iCLE; }
|
inline void SetCLE(ClientListEntry* iCLE) { cle = iCLE; }
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -465,6 +465,8 @@ int main(int argc, char** argv) {
|
|||||||
connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID());
|
connection->Handle()->RemoteIP(), connection->Handle()->RemotePort(), connection->GetUUID());
|
||||||
|
|
||||||
UCSLink.SetConnection(connection);
|
UCSLink.SetConnection(connection);
|
||||||
|
|
||||||
|
zoneserver_list.UpdateUCSServerAvailable();
|
||||||
});
|
});
|
||||||
|
|
||||||
server_connection->OnConnectionRemoved("UCS", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
server_connection->OnConnectionRemoved("UCS", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
||||||
@ -472,6 +474,8 @@ int main(int argc, char** argv) {
|
|||||||
connection->GetUUID());
|
connection->GetUUID());
|
||||||
|
|
||||||
UCSLink.SetConnection(nullptr);
|
UCSLink.SetConnection(nullptr);
|
||||||
|
|
||||||
|
zoneserver_list.UpdateUCSServerAvailable(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
server_connection->OnConnectionIdentified("WebInterface", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
server_connection->OnConnectionIdentified("WebInterface", [](std::shared_ptr<EQ::Net::ServertalkServerConnection> connection) {
|
||||||
|
|||||||
@ -516,23 +516,6 @@ void WorldDatabase::GetLauncherList(std::vector<std::string> &rl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WorldDatabase::SetMailKey(int CharID, int IPAddress, int MailKey)
|
|
||||||
{
|
|
||||||
char MailKeyString[17];
|
|
||||||
|
|
||||||
if(RuleB(Chat, EnableMailKeyIPVerification) == true)
|
|
||||||
sprintf(MailKeyString, "%08X%08X", IPAddress, MailKey);
|
|
||||||
else
|
|
||||||
sprintf(MailKeyString, "%08X", MailKey);
|
|
||||||
|
|
||||||
std::string query = StringFormat("UPDATE character_data SET mailkey = '%s' WHERE id = '%i'",
|
|
||||||
MailKeyString, CharID);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
if (!results.Success())
|
|
||||||
Log(Logs::General, Logs::Error, "WorldDatabase::SetMailKey(%i, %s) : %s", CharID, MailKeyString, results.ErrorMessage().c_str());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WorldDatabase::GetCharacterLevel(const char *name, int &level)
|
bool WorldDatabase::GetCharacterLevel(const char *name, int &level)
|
||||||
{
|
{
|
||||||
std::string query = StringFormat("SELECT level FROM character_data WHERE name = '%s'", name);
|
std::string query = StringFormat("SELECT level FROM character_data WHERE name = '%s'", name);
|
||||||
|
|||||||
@ -34,7 +34,6 @@ public:
|
|||||||
int MoveCharacterToBind(int CharID, uint8 bindnum = 0);
|
int MoveCharacterToBind(int CharID, uint8 bindnum = 0);
|
||||||
|
|
||||||
void GetLauncherList(std::vector<std::string> &result);
|
void GetLauncherList(std::vector<std::string> &result);
|
||||||
void SetMailKey(int CharID, int IPAddress, int MailKey);
|
|
||||||
bool GetCharacterLevel(const char *name, int &level);
|
bool GetCharacterLevel(const char *name, int &level);
|
||||||
|
|
||||||
bool LoadCharacterCreateAllocations();
|
bool LoadCharacterCreateAllocations();
|
||||||
|
|||||||
@ -32,6 +32,7 @@ extern uint32 numzones;
|
|||||||
extern bool holdzones;
|
extern bool holdzones;
|
||||||
extern EQEmu::Random emu_random;
|
extern EQEmu::Random emu_random;
|
||||||
extern WebInterfaceList web_interface;
|
extern WebInterfaceList web_interface;
|
||||||
|
volatile bool UCSServerAvailable_ = false;
|
||||||
void CatchSignal(int sig_num);
|
void CatchSignal(int sig_num);
|
||||||
|
|
||||||
ZSList::ZSList()
|
ZSList::ZSList()
|
||||||
@ -669,6 +670,16 @@ void ZSList::GetZoneIDList(std::vector<uint32> &zones) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZSList::UpdateUCSServerAvailable(bool ucss_available) {
|
||||||
|
UCSServerAvailable_ = ucss_available;
|
||||||
|
auto outapp = new ServerPacket(ServerOP_UCSServerStatusReply, sizeof(UCSServerStatus_Struct));
|
||||||
|
auto ucsss = (UCSServerStatus_Struct*)outapp->pBuffer;
|
||||||
|
ucsss->available = (ucss_available ? 1 : 0);
|
||||||
|
ucsss->timestamp = Timer::GetCurrentTime();
|
||||||
|
SendPacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
}
|
||||||
|
|
||||||
void ZSList::WorldShutDown(uint32 time, uint32 interval)
|
void ZSList::WorldShutDown(uint32 time, uint32 interval)
|
||||||
{
|
{
|
||||||
if (time > 0) {
|
if (time > 0) {
|
||||||
|
|||||||
@ -54,7 +54,8 @@ public:
|
|||||||
Timer* reminder;
|
Timer* reminder;
|
||||||
void NextGroupIDs(uint32 &start, uint32 &end);
|
void NextGroupIDs(uint32 &start, uint32 &end);
|
||||||
void SendLSZones();
|
void SendLSZones();
|
||||||
uint16 GetAvailableZonePort();
|
uint16 GetAvailableZonePort();
|
||||||
|
void UpdateUCSServerAvailable(bool ucss_available = true);
|
||||||
|
|
||||||
int GetZoneCount();
|
int GetZoneCount();
|
||||||
void GetZoneIDList(std::vector<uint32> &zones);
|
void GetZoneIDList(std::vector<uint32> &zones);
|
||||||
|
|||||||
@ -42,6 +42,7 @@ extern GroupLFPList LFPGroupList;
|
|||||||
extern ZSList zoneserver_list;
|
extern ZSList zoneserver_list;
|
||||||
extern LoginServerList loginserverlist;
|
extern LoginServerList loginserverlist;
|
||||||
extern volatile bool RunLoops;
|
extern volatile bool RunLoops;
|
||||||
|
extern volatile bool UCSServerAvailable_;
|
||||||
extern AdventureManager adventure_manager;
|
extern AdventureManager adventure_manager;
|
||||||
extern UCSConnection UCSLink;
|
extern UCSConnection UCSLink;
|
||||||
extern QueryServConnection QSLink;
|
extern QueryServConnection QSLink;
|
||||||
@ -1271,6 +1272,24 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
|||||||
UCSLink.SendPacket(pack);
|
UCSLink.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ServerOP_UCSServerStatusRequest:
|
||||||
|
{
|
||||||
|
auto ucsss = (UCSServerStatus_Struct*)pack->pBuffer;
|
||||||
|
auto zs = zoneserver_list.FindByPort(ucsss->port);
|
||||||
|
if (!zs)
|
||||||
|
break;
|
||||||
|
|
||||||
|
auto outapp = new ServerPacket(ServerOP_UCSServerStatusReply, sizeof(UCSServerStatus_Struct));
|
||||||
|
ucsss = (UCSServerStatus_Struct*)outapp->pBuffer;
|
||||||
|
ucsss->available = (UCSServerAvailable_ ? 1 : 0);
|
||||||
|
ucsss->timestamp = Timer::GetCurrentTime();
|
||||||
|
zs->SendPacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ServerOP_QSSendQuery:
|
case ServerOP_QSSendQuery:
|
||||||
case ServerOP_QueryServGeneric:
|
case ServerOP_QueryServGeneric:
|
||||||
case ServerOP_Speech:
|
case ServerOP_Speech:
|
||||||
|
|||||||
@ -28,6 +28,7 @@ SET(zone_sources
|
|||||||
encounter.cpp
|
encounter.cpp
|
||||||
entity.cpp
|
entity.cpp
|
||||||
exp.cpp
|
exp.cpp
|
||||||
|
fastmath.cpp
|
||||||
fearpath.cpp
|
fearpath.cpp
|
||||||
forage.cpp
|
forage.cpp
|
||||||
groups.cpp
|
groups.cpp
|
||||||
@ -159,6 +160,7 @@ SET(zone_headers
|
|||||||
entity.h
|
entity.h
|
||||||
errmsg.h
|
errmsg.h
|
||||||
event_codes.h
|
event_codes.h
|
||||||
|
fastmath.h
|
||||||
forage.h
|
forage.h
|
||||||
global_loot_manager.h
|
global_loot_manager.h
|
||||||
groups.h
|
groups.h
|
||||||
|
|||||||
@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
#include "lua_parser.h"
|
#include "lua_parser.h"
|
||||||
#include "nats_manager.h"
|
#include "nats_manager.h"
|
||||||
|
#include "fastmath.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -44,6 +45,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
|
|
||||||
extern QueryServ* QServ;
|
extern QueryServ* QServ;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
|
extern FastMath g_Math;
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
@ -3614,26 +3616,35 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const
|
|||||||
a->special = 2;
|
a->special = 2;
|
||||||
else
|
else
|
||||||
a->special = 0;
|
a->special = 0;
|
||||||
a->meleepush_xy = attacker ? attacker->GetHeading() : 0.0f;
|
a->hit_heading = attacker ? attacker->GetHeading() : 0.0f;
|
||||||
if (RuleB(Combat, MeleePush) && damage > 0 && !IsRooted() &&
|
if (RuleB(Combat, MeleePush) && damage > 0 && !IsRooted() &&
|
||||||
(IsClient() || zone->random.Roll(RuleI(Combat, MeleePushChance)))) {
|
(IsClient() || zone->random.Roll(RuleI(Combat, MeleePushChance)))) {
|
||||||
a->force = EQEmu::skills::GetSkillMeleePushForce(skill_used);
|
a->force = EQEmu::skills::GetSkillMeleePushForce(skill_used);
|
||||||
|
if (IsNPC()) {
|
||||||
|
if (attacker->IsNPC())
|
||||||
|
a->force = 0.0f; // 2013 change that disabled NPC vs NPC push
|
||||||
|
else
|
||||||
|
a->force *= 0.10f; // force against NPCs is divided by 10 I guess? ex bash is 0.3, parsed 0.03 against an NPC
|
||||||
|
}
|
||||||
// update NPC stuff
|
// update NPC stuff
|
||||||
auto new_pos = glm::vec3(m_Position.x + (a->force * std::cos(a->meleepush_xy) + m_Delta.x),
|
if (a->force != 0.0f) {
|
||||||
m_Position.y + (a->force * std::sin(a->meleepush_xy) + m_Delta.y), m_Position.z);
|
auto new_pos = glm::vec3(
|
||||||
if (zone->zonemap && zone->zonemap->CheckLoS(glm::vec3(m_Position), new_pos)) { // If we have LoS on the new loc it should be reachable.
|
m_Position.x + (a->force * g_Math.FastSin(a->hit_heading) + m_Delta.x),
|
||||||
if (IsNPC()) {
|
m_Position.y + (a->force * g_Math.FastCos(a->hit_heading) + m_Delta.y), m_Position.z);
|
||||||
// Is this adequate?
|
if ((!IsNPC() || position_update_melee_push_timer.Check()) && zone->zonemap &&
|
||||||
|
zone->zonemap->CheckLoS(
|
||||||
|
glm::vec3(m_Position),
|
||||||
|
new_pos)) { // If we have LoS on the new loc it should be reachable.
|
||||||
|
if (IsNPC()) {
|
||||||
|
// Is this adequate?
|
||||||
|
|
||||||
Teleport(new_pos);
|
Teleport(new_pos);
|
||||||
if (position_update_melee_push_timer.Check()) {
|
|
||||||
SendPositionUpdate();
|
SendPositionUpdate();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
a->force = 0.0f; // we couldn't move there, so lets not
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
a->force = 0.0f; // we couldn't move there, so lets not
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Note: if players can become pets, they will not receive damage messages of their own
|
//Note: if players can become pets, they will not receive damage messages of their own
|
||||||
|
|||||||
@ -616,6 +616,7 @@ bool Aura::Process()
|
|||||||
it = spawned_for.erase(it);
|
it = spawned_for.erase(it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
safe_delete(app);
|
||||||
}
|
}
|
||||||
// TODO: waypoints?
|
// TODO: waypoints?
|
||||||
|
|
||||||
@ -757,6 +758,8 @@ void Mob::MakeAura(uint16 spell_id)
|
|||||||
|
|
||||||
auto npc = new Aura(npc_type, this, record);
|
auto npc = new Aura(npc_type, this, record);
|
||||||
npc->SetAuraID(spell_id);
|
npc->SetAuraID(spell_id);
|
||||||
|
if (trap)
|
||||||
|
npc->TryMoveAlong(5.0f, 0.0f, false); // try to place 5 units in front
|
||||||
entity_list.AddNPC(npc, false);
|
entity_list.AddNPC(npc, false);
|
||||||
|
|
||||||
if (trap)
|
if (trap)
|
||||||
|
|||||||
26
zone/bot.cpp
26
zone/bot.cpp
@ -3053,7 +3053,7 @@ void Bot::Depop() {
|
|||||||
NPC::Depop(false);
|
NPC::Depop(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bot::Spawn(Client* botCharacterOwner) {
|
bool Bot::Spawn(Client* botCharacterOwner) {
|
||||||
if(GetBotID() > 0 && _botOwnerCharacterID > 0 && botCharacterOwner && botCharacterOwner->CharacterID() == _botOwnerCharacterID) {
|
if(GetBotID() > 0 && _botOwnerCharacterID > 0 && botCharacterOwner && botCharacterOwner->CharacterID() == _botOwnerCharacterID) {
|
||||||
// Rename the bot name to make sure that Mob::GetName() matches Mob::GetCleanName() so we dont have a bot named "Jesuschrist001"
|
// Rename the bot name to make sure that Mob::GetName() matches Mob::GetCleanName() so we dont have a bot named "Jesuschrist001"
|
||||||
strcpy(name, GetCleanName());
|
strcpy(name, GetCleanName());
|
||||||
@ -3097,7 +3097,11 @@ void Bot::Spawn(Client* botCharacterOwner) {
|
|||||||
this->SendWearChange(materialFromSlot);
|
this->SendWearChange(materialFromSlot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deletes the inventory record for the specified item from the database for this bot.
|
// Deletes the inventory record for the specified item from the database for this bot.
|
||||||
@ -3246,16 +3250,20 @@ void Bot::LoadAndSpawnAllZonedBots(Client* botOwner) {
|
|||||||
if(!ActiveBots.empty()) {
|
if(!ActiveBots.empty()) {
|
||||||
for(std::list<uint32>::iterator itr = ActiveBots.begin(); itr != ActiveBots.end(); ++itr) {
|
for(std::list<uint32>::iterator itr = ActiveBots.begin(); itr != ActiveBots.end(); ++itr) {
|
||||||
Bot* activeBot = Bot::LoadBot(*itr);
|
Bot* activeBot = Bot::LoadBot(*itr);
|
||||||
|
if (!activeBot)
|
||||||
|
continue;
|
||||||
|
|
||||||
if(activeBot) {
|
if (!activeBot->Spawn(botOwner)) {
|
||||||
activeBot->Spawn(botOwner);
|
safe_delete(activeBot);
|
||||||
g->UpdatePlayer(activeBot);
|
continue;
|
||||||
// follow the bot owner, not the group leader we just zoned with our owner.
|
|
||||||
if(g->IsGroupMember(botOwner) && g->IsGroupMember(activeBot))
|
|
||||||
activeBot->SetFollowID(botOwner->GetID());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(activeBot && !botOwner->HasGroup())
|
g->UpdatePlayer(activeBot);
|
||||||
|
// follow the bot owner, not the group leader we just zoned with our owner.
|
||||||
|
if (g->IsGroupMember(botOwner) && g->IsGroupMember(activeBot))
|
||||||
|
activeBot->SetFollowID(botOwner->GetID());
|
||||||
|
|
||||||
|
if(!botOwner->HasGroup())
|
||||||
database.SetGroupID(activeBot->GetCleanName(), 0, activeBot->GetBotID());
|
database.SetGroupID(activeBot->GetCleanName(), 0, activeBot->GetBotID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -8886,6 +8894,8 @@ bool Bot::DyeArmor(int16 slot_id, uint32 rgb, bool all_flag, bool save_flag)
|
|||||||
|
|
||||||
std::string Bot::CreateSayLink(Client* c, const char* message, const char* name)
|
std::string Bot::CreateSayLink(Client* c, const char* message, const char* name)
|
||||||
{
|
{
|
||||||
|
// TODO: review
|
||||||
|
|
||||||
int saylink_size = strlen(message);
|
int saylink_size = strlen(message);
|
||||||
char* escaped_string = new char[saylink_size * 2];
|
char* escaped_string = new char[saylink_size * 2];
|
||||||
|
|
||||||
|
|||||||
@ -275,7 +275,7 @@ public:
|
|||||||
static bool IsValidRaceClassCombo(uint16 r, uint8 c);
|
static bool IsValidRaceClassCombo(uint16 r, uint8 c);
|
||||||
bool IsValidName();
|
bool IsValidName();
|
||||||
static bool IsValidName(std::string& name);
|
static bool IsValidName(std::string& name);
|
||||||
void Spawn(Client* botCharacterOwner);
|
bool Spawn(Client* botCharacterOwner);
|
||||||
virtual void SetLevel(uint8 in_level, bool command = false);
|
virtual void SetLevel(uint8 in_level, bool command = false);
|
||||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||||
virtual bool Process();
|
virtual bool Process();
|
||||||
|
|||||||
@ -5049,7 +5049,11 @@ void bot_subcommand_bot_spawn(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
my_bot->Spawn(c);
|
if (!my_bot->Spawn(c)) {
|
||||||
|
c->Message(m_fail, "Failed to spawn bot '%s' (id: %i)", bot_name.c_str(), bot_id);
|
||||||
|
safe_delete(my_bot);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static const char* bot_spawn_message[16] = {
|
static const char* bot_spawn_message[16] = {
|
||||||
"A solid weapon is my ally!", // WARRIOR / 'generic'
|
"A solid weapon is my ally!", // WARRIOR / 'generic'
|
||||||
@ -5805,18 +5809,22 @@ void bot_subcommand_botgroup_load(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!leader_id) {
|
if (!leader_id) {
|
||||||
c->Message(m_fail, "Can not locate bot-group leader id for '%s'", botgroup_name_arg.c_str());
|
c->Message(m_fail, "Cannot locate bot-group leader id for '%s'", botgroup_name_arg.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto botgroup_leader = Bot::LoadBot(leader_id);
|
auto botgroup_leader = Bot::LoadBot(leader_id);
|
||||||
if (!botgroup_leader) {
|
if (!botgroup_leader) {
|
||||||
c->Message(m_fail, "Could not spawn bot-group leader for '%s'", botgroup_name_arg.c_str());
|
c->Message(m_fail, "Could not load bot-group leader for '%s'", botgroup_name_arg.c_str());
|
||||||
safe_delete(botgroup_leader);
|
safe_delete(botgroup_leader);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
botgroup_leader->Spawn(c);
|
if (!botgroup_leader->Spawn(c)) {
|
||||||
|
c->Message(m_fail, "Could not spawn bot-group leader %s for '%s'", botgroup_leader->GetName(), botgroup_name_arg.c_str());
|
||||||
|
safe_delete(botgroup_leader);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Group* group_inst = new Group(botgroup_leader);
|
Group* group_inst = new Group(botgroup_leader);
|
||||||
|
|
||||||
@ -5835,7 +5843,12 @@ void bot_subcommand_botgroup_load(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
botgroup_member->Spawn(c);
|
if (!botgroup_member->Spawn(c)) {
|
||||||
|
c->Message(m_fail, "Could not spawn bot '%s' (id: %i)", botgroup_member->GetName(), member_iter);
|
||||||
|
safe_delete(botgroup_member);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Bot::AddBotToGroup(botgroup_member, group_inst);
|
Bot::AddBotToGroup(botgroup_member, group_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7072,7 +7085,6 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep)
|
|||||||
const EQEmu::ItemData* item = nullptr;
|
const EQEmu::ItemData* item = nullptr;
|
||||||
bool is2Hweapon = false;
|
bool is2Hweapon = false;
|
||||||
|
|
||||||
std::string item_link;
|
|
||||||
EQEmu::SayLinkEngine linker;
|
EQEmu::SayLinkEngine linker;
|
||||||
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
||||||
|
|
||||||
@ -7093,8 +7105,7 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
linker.SetItemInst(inst);
|
linker.SetItemInst(inst);
|
||||||
item_link = linker.GenerateLink();
|
c->Message(m_message, "Using %s in my %s (slot %i)", linker.GenerateLink().c_str(), GetBotEquipSlotName(i), (i == 22 ? EQEmu::inventory::slotPowerSource : i));
|
||||||
c->Message(m_message, "Using %s in my %s (slot %i)", item_link.c_str(), GetBotEquipSlotName(i), (i == 22 ? EQEmu::inventory::slotPowerSource : i));
|
|
||||||
|
|
||||||
++inventory_count;
|
++inventory_count;
|
||||||
}
|
}
|
||||||
@ -7237,8 +7248,8 @@ void bot_subcommand_inventory_window(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
std::string window_text;
|
std::string window_text;
|
||||||
//std::string item_link;
|
//std::string item_link;
|
||||||
//Client::TextLink linker;
|
//EQEmu::SayLinkEngine linker;
|
||||||
//linker.SetLinkType(linker.linkItemInst);
|
//linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
||||||
|
|
||||||
for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= (EQEmu::legacy::EQUIPMENT_END + 1); ++i) {
|
for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= (EQEmu::legacy::EQUIPMENT_END + 1); ++i) {
|
||||||
const EQEmu::ItemData* item = nullptr;
|
const EQEmu::ItemData* item = nullptr;
|
||||||
|
|||||||
@ -273,7 +273,10 @@ bool BotDatabase::LoadBotID(const uint32 owner_id, const std::string& bot_name,
|
|||||||
if (!owner_id || bot_name.empty())
|
if (!owner_id || bot_name.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
query = StringFormat("SELECT `bot_id` FROM `bot_data` WHERE `name` = '%s' LIMIT 1", bot_name.c_str());
|
query = StringFormat(
|
||||||
|
"SELECT `bot_id` FROM `bot_data` WHERE `owner_id` = '%u' AND `name` = '%s' LIMIT 1",
|
||||||
|
owner_id, bot_name.c_str()
|
||||||
|
);
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -254,7 +254,7 @@ Client::Client(EQStreamInterface* ieqs)
|
|||||||
mercSlot = 0;
|
mercSlot = 0;
|
||||||
InitializeMercInfo();
|
InitializeMercInfo();
|
||||||
SetMerc(0);
|
SetMerc(0);
|
||||||
|
if (RuleI(World, PVPMinLevel) > 0 && level >= RuleI(World, PVPMinLevel) && m_pp.pvp == 0) SetPVP(true, false);
|
||||||
logging_enabled = CLIENT_DEFAULT_LOGGING_ENABLED;
|
logging_enabled = CLIENT_DEFAULT_LOGGING_ENABLED;
|
||||||
|
|
||||||
//for good measure:
|
//for good measure:
|
||||||
@ -337,6 +337,7 @@ Client::Client(EQStreamInterface* ieqs)
|
|||||||
m_pp.InnateSkills[i] = InnateDisabled;
|
m_pp.InnateSkills[i] = InnateDisabled;
|
||||||
|
|
||||||
temp_pvp = false;
|
temp_pvp = false;
|
||||||
|
is_client_moving = false;
|
||||||
|
|
||||||
AI_Init();
|
AI_Init();
|
||||||
}
|
}
|
||||||
@ -7907,7 +7908,7 @@ void Client::GarbleMessage(char *message, uint8 variance)
|
|||||||
for (size_t i = 0; i < strlen(message); i++) {
|
for (size_t i = 0; i < strlen(message); i++) {
|
||||||
// Client expects hex values inside of a text link body
|
// Client expects hex values inside of a text link body
|
||||||
if (message[i] == delimiter) {
|
if (message[i] == delimiter) {
|
||||||
if (!(delimiter_count & 1)) { i += EQEmu::legacy::TEXT_LINK_BODY_LENGTH; }
|
if (!(delimiter_count & 1)) { i += EQEmu::constants::SayLinkBodySize; }
|
||||||
++delimiter_count;
|
++delimiter_count;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,6 +75,7 @@ extern NatsManager nats;
|
|||||||
|
|
||||||
typedef void (Client::*ClientPacketProc)(const EQApplicationPacket *app);
|
typedef void (Client::*ClientPacketProc)(const EQApplicationPacket *app);
|
||||||
|
|
||||||
|
|
||||||
//Use a map for connecting opcodes since it dosent get used a lot and is sparse
|
//Use a map for connecting opcodes since it dosent get used a lot and is sparse
|
||||||
std::map<uint32, ClientPacketProc> ConnectingOpcodes;
|
std::map<uint32, ClientPacketProc> ConnectingOpcodes;
|
||||||
//Use a static array for connected, for speed
|
//Use a static array for connected, for speed
|
||||||
@ -318,6 +319,7 @@ void MapOpcodes()
|
|||||||
ConnectedOpcodes[OP_PurchaseLeadershipAA] = &Client::Handle_OP_PurchaseLeadershipAA;
|
ConnectedOpcodes[OP_PurchaseLeadershipAA] = &Client::Handle_OP_PurchaseLeadershipAA;
|
||||||
ConnectedOpcodes[OP_PVPLeaderBoardDetailsRequest] = &Client::Handle_OP_PVPLeaderBoardDetailsRequest;
|
ConnectedOpcodes[OP_PVPLeaderBoardDetailsRequest] = &Client::Handle_OP_PVPLeaderBoardDetailsRequest;
|
||||||
ConnectedOpcodes[OP_PVPLeaderBoardRequest] = &Client::Handle_OP_PVPLeaderBoardRequest;
|
ConnectedOpcodes[OP_PVPLeaderBoardRequest] = &Client::Handle_OP_PVPLeaderBoardRequest;
|
||||||
|
ConnectedOpcodes[OP_QueryUCSServerStatus] = &Client::Handle_OP_QueryUCSServerStatus;
|
||||||
ConnectedOpcodes[OP_RaidInvite] = &Client::Handle_OP_RaidCommand;
|
ConnectedOpcodes[OP_RaidInvite] = &Client::Handle_OP_RaidCommand;
|
||||||
ConnectedOpcodes[OP_RandomReq] = &Client::Handle_OP_RandomReq;
|
ConnectedOpcodes[OP_RandomReq] = &Client::Handle_OP_RandomReq;
|
||||||
ConnectedOpcodes[OP_ReadBook] = &Client::Handle_OP_ReadBook;
|
ConnectedOpcodes[OP_ReadBook] = &Client::Handle_OP_ReadBook;
|
||||||
@ -794,7 +796,7 @@ void Client::CompleteConnect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zone)
|
if (zone)
|
||||||
zone->weatherSend();
|
zone->weatherSend(this);
|
||||||
|
|
||||||
TotalKarma = database.GetKarma(AccountID());
|
TotalKarma = database.GetKarma(AccountID());
|
||||||
SendDisciplineTimers();
|
SendDisciplineTimers();
|
||||||
@ -2866,41 +2868,60 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app)
|
|||||||
DumpPacket(app);
|
DumpPacket(app);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 ApplyPoisonSuccessResult = 0;
|
uint32 ApplyPoisonSuccessResult = 0;
|
||||||
ApplyPoison_Struct* ApplyPoisonData = (ApplyPoison_Struct*)app->pBuffer;
|
ApplyPoison_Struct* ApplyPoisonData = (ApplyPoison_Struct*)app->pBuffer;
|
||||||
const EQEmu::ItemInstance* PrimaryWeapon = GetInv().GetItem(EQEmu::inventory::slotPrimary);
|
const EQEmu::ItemInstance* PrimaryWeapon = GetInv().GetItem(EQEmu::inventory::slotPrimary);
|
||||||
const EQEmu::ItemInstance* SecondaryWeapon = GetInv().GetItem(EQEmu::inventory::slotSecondary);
|
const EQEmu::ItemInstance* SecondaryWeapon = GetInv().GetItem(EQEmu::inventory::slotSecondary);
|
||||||
const EQEmu::ItemInstance* PoisonItemInstance = GetInv()[ApplyPoisonData->inventorySlot];
|
const EQEmu::ItemInstance* PoisonItemInstance = GetInv()[ApplyPoisonData->inventorySlot];
|
||||||
|
const EQEmu::ItemData* poison=PoisonItemInstance->GetItem();
|
||||||
|
const EQEmu::ItemData* primary=nullptr;
|
||||||
|
const EQEmu::ItemData* secondary=nullptr;
|
||||||
|
bool IsPoison = PoisonItemInstance &&
|
||||||
|
(poison->ItemType == EQEmu::item::ItemTypePoison);
|
||||||
|
|
||||||
bool IsPoison = PoisonItemInstance && (PoisonItemInstance->GetItem()->ItemType == EQEmu::item::ItemTypePoison);
|
if (PrimaryWeapon) {
|
||||||
|
primary=PrimaryWeapon->GetItem();
|
||||||
if (!IsPoison)
|
|
||||||
{
|
|
||||||
Log(Logs::Detail, Logs::Spells, "Item used to cast spell effect from a poison item was missing from inventory slot %d "
|
|
||||||
"after casting, or is not a poison!", ApplyPoisonData->inventorySlot);
|
|
||||||
|
|
||||||
Message(0, "Error: item not found for inventory slot #%i or is not a poison", ApplyPoisonData->inventorySlot);
|
|
||||||
}
|
}
|
||||||
else if (GetClass() == ROGUE)
|
|
||||||
{
|
if (SecondaryWeapon) {
|
||||||
if ((PrimaryWeapon && PrimaryWeapon->GetItem()->ItemType == EQEmu::item::ItemType1HPiercing) ||
|
secondary=SecondaryWeapon->GetItem();
|
||||||
(SecondaryWeapon && SecondaryWeapon->GetItem()->ItemType == EQEmu::item::ItemType1HPiercing)) {
|
}
|
||||||
float SuccessChance = (GetSkill(EQEmu::skills::SkillApplyPoison) + GetLevel()) / 400.0f;
|
|
||||||
|
if (IsPoison && GetClass() == ROGUE) {
|
||||||
|
|
||||||
|
// Live always checks for skillup, even when poison is too high
|
||||||
|
CheckIncreaseSkill(EQEmu::skills::SkillApplyPoison, nullptr, 10);
|
||||||
|
|
||||||
|
if (poison->Proc.Level2 > GetLevel()) {
|
||||||
|
// Poison is too high to apply.
|
||||||
|
Message_StringID(clientMessageTradeskill, POISON_TOO_HIGH);
|
||||||
|
}
|
||||||
|
else if ((primary &&
|
||||||
|
primary->ItemType == EQEmu::item::ItemType1HPiercing) ||
|
||||||
|
(secondary &&
|
||||||
|
secondary->ItemType == EQEmu::item::ItemType1HPiercing)) {
|
||||||
|
|
||||||
double ChanceRoll = zone->random.Real(0, 1);
|
double ChanceRoll = zone->random.Real(0, 1);
|
||||||
|
|
||||||
CheckIncreaseSkill(EQEmu::skills::SkillApplyPoison, nullptr, 10);
|
// Poisons that use this skill (old world poisons) almost
|
||||||
|
// never fail to apply. I did 25 applies of a trivial 120+
|
||||||
|
// poison with an apply skill of 48 and they all worked.
|
||||||
|
// Also did 25 straight poisons at apply skill 248 for very
|
||||||
|
// high end and they never failed.
|
||||||
|
// Apply poison ranging from 1-9, 28/30 worked for a level 18..
|
||||||
|
// Poisons that don't proc until a level higher than the
|
||||||
|
// rogue simply won't apply at all, no skill check done.
|
||||||
|
|
||||||
if (ChanceRoll < SuccessChance) {
|
if (ChanceRoll < (.9 + GetLevel()/1000)) {
|
||||||
ApplyPoisonSuccessResult = 1;
|
ApplyPoisonSuccessResult = 1;
|
||||||
// NOTE: Someone may want to tweak the chance to proc the poison effect that is added to the weapon here.
|
AddProcToWeapon(poison->Proc.Effect, false,
|
||||||
// My thinking was that DEX should be apart of the calculation.
|
(GetDEX() / 100) + 103);
|
||||||
AddProcToWeapon(PoisonItemInstance->GetItem()->Proc.Effect, false, (GetDEX() / 100) + 103);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DeleteItemInInventory(ApplyPoisonData->inventorySlot, 1, true);
|
|
||||||
|
|
||||||
Log(Logs::General, Logs::None, "Chance to Apply Poison was %f. Roll was %f. Result is %u.", SuccessChance, ChanceRoll, ApplyPoisonSuccessResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Live always deletes the item, success or failure. Even if too high.
|
||||||
|
DeleteItemInInventory(ApplyPoisonData->inventorySlot, 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_ApplyPoison, nullptr, sizeof(ApplyPoison_Struct));
|
auto outapp = new EQApplicationPacket(OP_ApplyPoison, nullptr, sizeof(ApplyPoison_Struct));
|
||||||
@ -3965,12 +3986,23 @@ void Client::Handle_OP_BuffRemoveRequest(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
void Client::Handle_OP_Bug(const EQApplicationPacket *app)
|
void Client::Handle_OP_Bug(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
if (app->size != sizeof(BugStruct))
|
if (!RuleB(Bugs, ReportingSystemActive)) {
|
||||||
printf("Wrong size of BugStruct got %d expected %zu!\n", app->size, sizeof(BugStruct));
|
Message(0, "Bug reporting is disabled on this server.");
|
||||||
else {
|
return;
|
||||||
BugStruct* bug = (BugStruct*)app->pBuffer;
|
|
||||||
database.UpdateBug(bug);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (app->size != sizeof(BugReport_Struct)) {
|
||||||
|
printf("Wrong size of BugReport_Struct got %d expected %zu!\n", app->size, sizeof(BugReport_Struct));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
BugReport_Struct* bug_report = (BugReport_Struct*)app->pBuffer;
|
||||||
|
|
||||||
|
if (RuleB(Bugs, UseOldReportingMethod))
|
||||||
|
database.RegisterBug(bug_report);
|
||||||
|
else
|
||||||
|
database.RegisterBug(this, bug_report);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6716,7 +6748,11 @@ void Client::Handle_OP_GroupFollow2(const EQApplicationPacket *app)
|
|||||||
// Inviter and Invitee are in the same zone
|
// Inviter and Invitee are in the same zone
|
||||||
if (inviter != nullptr && inviter->IsClient())
|
if (inviter != nullptr && inviter->IsClient())
|
||||||
{
|
{
|
||||||
if (GroupFollow(inviter->CastToClient()))
|
if (!inviter->CastToClient()->Connected())
|
||||||
|
{
|
||||||
|
Log(Logs::General, Logs::Error, "%s attempted to join group while leader %s was zoning.", GetName(), inviter->GetName());
|
||||||
|
}
|
||||||
|
else if (GroupFollow(inviter->CastToClient()))
|
||||||
{
|
{
|
||||||
strn0cpy(gf->name1, inviter->GetName(), sizeof(gf->name1));
|
strn0cpy(gf->name1, inviter->GetName(), sizeof(gf->name1));
|
||||||
strn0cpy(gf->name2, GetName(), sizeof(gf->name2));
|
strn0cpy(gf->name2, GetName(), sizeof(gf->name2));
|
||||||
@ -10573,11 +10609,8 @@ void Client::Handle_OP_Petition(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
void Client::Handle_OP_PetitionBug(const EQApplicationPacket *app)
|
void Client::Handle_OP_PetitionBug(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
if (app->size != sizeof(PetitionBug_Struct))
|
Message(0, "Petition Bugs are not supported, please use /bug.");
|
||||||
printf("Wrong size of BugStruct! Expected: %zu, Got: %i\n", sizeof(PetitionBug_Struct), app->size);
|
|
||||||
else {
|
|
||||||
Message(0, "Petition Bugs are not supported, please use /bug.");
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -10997,6 +11030,84 @@ void Client::Handle_OP_PVPLeaderBoardRequest(const EQApplicationPacket *app)
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::Handle_OP_QueryUCSServerStatus(const EQApplicationPacket *app)
|
||||||
|
{
|
||||||
|
if (zone->IsUCSServerAvailable()) {
|
||||||
|
EQApplicationPacket* outapp = nullptr;
|
||||||
|
std::string buffer;
|
||||||
|
|
||||||
|
std::string MailKey = database.GetMailKey(CharacterID(), true);
|
||||||
|
EQEmu::versions::UCSVersion ConnectionType = EQEmu::versions::ucsUnknown;
|
||||||
|
|
||||||
|
// chat server packet
|
||||||
|
switch (ClientVersion()) {
|
||||||
|
case EQEmu::versions::ClientVersion::Titanium:
|
||||||
|
ConnectionType = EQEmu::versions::ucsTitaniumChat;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::SoF:
|
||||||
|
ConnectionType = EQEmu::versions::ucsSoFCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::SoD:
|
||||||
|
ConnectionType = EQEmu::versions::ucsSoDCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::UF:
|
||||||
|
ConnectionType = EQEmu::versions::ucsUFCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::RoF:
|
||||||
|
ConnectionType = EQEmu::versions::ucsRoFCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::RoF2:
|
||||||
|
ConnectionType = EQEmu::versions::ucsRoF2Combined;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ConnectionType = EQEmu::versions::ucsUnknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = StringFormat("%s,%i,%s.%s,%c%s",
|
||||||
|
Config->ChatHost.c_str(),
|
||||||
|
Config->ChatPort,
|
||||||
|
Config->ShortName.c_str(),
|
||||||
|
GetName(),
|
||||||
|
ConnectionType,
|
||||||
|
MailKey.c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
outapp = new EQApplicationPacket(OP_SetChatServer, (buffer.length() + 1));
|
||||||
|
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
|
||||||
|
outapp->pBuffer[buffer.length()] = '\0';
|
||||||
|
|
||||||
|
QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
// mail server packet
|
||||||
|
switch (ClientVersion()) {
|
||||||
|
case EQEmu::versions::ClientVersion::Titanium:
|
||||||
|
ConnectionType = EQEmu::versions::ucsTitaniumMail;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// retain value from previous switch
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = StringFormat("%s,%i,%s.%s,%c%s",
|
||||||
|
Config->MailHost.c_str(),
|
||||||
|
Config->MailPort,
|
||||||
|
Config->ShortName.c_str(),
|
||||||
|
GetName(),
|
||||||
|
ConnectionType,
|
||||||
|
MailKey.c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
outapp = new EQApplicationPacket(OP_SetChatServer2, (buffer.length() + 1));
|
||||||
|
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
|
||||||
|
outapp->pBuffer[buffer.length()] = '\0';
|
||||||
|
|
||||||
|
QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
if (app->size < sizeof(RaidGeneral_Struct)) {
|
if (app->size < sizeof(RaidGeneral_Struct)) {
|
||||||
|
|||||||
@ -228,6 +228,7 @@
|
|||||||
void Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app);
|
void Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app);
|
||||||
void Handle_OP_PVPLeaderBoardDetailsRequest(const EQApplicationPacket *app);
|
void Handle_OP_PVPLeaderBoardDetailsRequest(const EQApplicationPacket *app);
|
||||||
void Handle_OP_PVPLeaderBoardRequest(const EQApplicationPacket *app);
|
void Handle_OP_PVPLeaderBoardRequest(const EQApplicationPacket *app);
|
||||||
|
void Handle_OP_QueryUCSServerStatus(const EQApplicationPacket *app);
|
||||||
void Handle_OP_RaidCommand(const EQApplicationPacket *app);
|
void Handle_OP_RaidCommand(const EQApplicationPacket *app);
|
||||||
void Handle_OP_RandomReq(const EQApplicationPacket *app);
|
void Handle_OP_RandomReq(const EQApplicationPacket *app);
|
||||||
void Handle_OP_ReadBook(const EQApplicationPacket *app);
|
void Handle_OP_ReadBook(const EQApplicationPacket *app);
|
||||||
|
|||||||
188
zone/command.cpp
188
zone/command.cpp
@ -391,6 +391,7 @@ int command_init(void)
|
|||||||
command_add("traindisc", "[level] - Trains all the disciplines usable by the target, up to level specified. (may freeze client for a few seconds)", 150, command_traindisc) ||
|
command_add("traindisc", "[level] - Trains all the disciplines usable by the target, up to level specified. (may freeze client for a few seconds)", 150, command_traindisc) ||
|
||||||
command_add("trapinfo", "- Gets infomation about the traps currently spawned in the zone.", 81, command_trapinfo) ||
|
command_add("trapinfo", "- Gets infomation about the traps currently spawned in the zone.", 81, command_trapinfo) ||
|
||||||
command_add("tune", "Calculate ideal statical values related to combat.", 100, command_tune) ||
|
command_add("tune", "Calculate ideal statical values related to combat.", 100, command_tune) ||
|
||||||
|
command_add("ucs", "- Attempts to reconnect to the UCS server", 0, command_ucs) ||
|
||||||
command_add("undyeme", "- Remove dye from all of your armor slots", 0, command_undyeme) ||
|
command_add("undyeme", "- Remove dye from all of your armor slots", 0, command_undyeme) ||
|
||||||
command_add("unfreeze", "- Unfreeze your target", 80, command_unfreeze) ||
|
command_add("unfreeze", "- Unfreeze your target", 80, command_unfreeze) ||
|
||||||
command_add("unlock", "- Unlock the worldserver", 150, command_unlock) ||
|
command_add("unlock", "- Unlock the worldserver", 150, command_unlock) ||
|
||||||
@ -2326,14 +2327,18 @@ void command_race(Client *c, const Seperator *sep)
|
|||||||
{
|
{
|
||||||
Mob *t=c->CastToMob();
|
Mob *t=c->CastToMob();
|
||||||
|
|
||||||
// Need to figure out max race for LoY/LDoN: going with upper bound of 500 now for testing
|
if (sep->IsNumber(1)) {
|
||||||
if (sep->IsNumber(1) && atoi(sep->arg[1]) >= 0 && atoi(sep->arg[1]) <= 724) {
|
auto race = atoi(sep->arg[1]);
|
||||||
if ((c->GetTarget()) && c->Admin() >= commandRaceOthers)
|
if ((race >= 0 && race <= 732) || (race >= 2253 && race <= 2259)) {
|
||||||
t=c->GetTarget();
|
if ((c->GetTarget()) && c->Admin() >= commandRaceOthers)
|
||||||
t->SendIllusionPacket(atoi(sep->arg[1]));
|
t = c->GetTarget();
|
||||||
|
t->SendIllusionPacket(race);
|
||||||
|
} else {
|
||||||
|
c->Message(0, "Usage: #race [0-732, 2253-2259] (0 for back to normal)");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c->Message(0, "Usage: #race [0-732, 2253-2259] (0 for back to normal)");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
c->Message(0, "Usage: #race [0-724] (0 for back to normal)");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void command_gender(Client *c, const Seperator *sep)
|
void command_gender(Client *c, const Seperator *sep)
|
||||||
@ -2553,7 +2558,7 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
const EQEmu::ItemInstance* inst_main = nullptr;
|
const EQEmu::ItemInstance* inst_main = nullptr;
|
||||||
const EQEmu::ItemInstance* inst_sub = nullptr;
|
const EQEmu::ItemInstance* inst_sub = nullptr;
|
||||||
const EQEmu::ItemData* item_data = nullptr;
|
const EQEmu::ItemData* item_data = nullptr;
|
||||||
std::string item_link;
|
|
||||||
EQEmu::SayLinkEngine linker;
|
EQEmu::SayLinkEngine linker;
|
||||||
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
||||||
|
|
||||||
@ -2565,10 +2570,8 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
||||||
linker.SetItemInst(inst_main);
|
linker.SetItemInst(inst_main);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((scopeWhere & peekWorn) && (targetClient->ClientVersion() >= EQEmu::versions::ClientVersion::SoF)) {
|
if ((scopeWhere & peekWorn) && (targetClient->ClientVersion() >= EQEmu::versions::ClientVersion::SoF)) {
|
||||||
@ -2576,10 +2579,8 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
||||||
linker.SetItemInst(inst_main);
|
linker.SetItemInst(inst_main);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
EQEmu::inventory::slotPowerSource, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
EQEmu::inventory::slotPowerSource, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// inv
|
// inv
|
||||||
@ -2588,20 +2589,16 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
||||||
linker.SetItemInst(inst_main);
|
linker.SetItemInst(inst_main);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "InvSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "InvSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
||||||
inst_sub = inst_main->GetItem(indexSub);
|
inst_sub = inst_main->GetItem(indexSub);
|
||||||
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
||||||
linker.SetItemInst(inst_sub);
|
linker.SetItemInst(inst_sub);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2610,10 +2607,8 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
if (targetClient->GetInv().CursorEmpty()) {
|
if (targetClient->GetInv().CursorEmpty()) {
|
||||||
linker.SetItemInst(nullptr);
|
linker.SetItemInst(nullptr);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message(1, "CursorSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message(1, "CursorSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
EQEmu::inventory::slotCursor, 0, item_link.c_str(), 0);
|
EQEmu::inventory::slotCursor, 0, linker.GenerateLink().c_str(), 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int cursorDepth = 0;
|
int cursorDepth = 0;
|
||||||
@ -2622,20 +2617,16 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
||||||
linker.SetItemInst(inst_main);
|
linker.SetItemInst(inst_main);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i",
|
||||||
EQEmu::inventory::slotCursor, cursorDepth, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
EQEmu::inventory::slotCursor, cursorDepth, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = EQEmu::inventory::containerBegin; (cursorDepth == 0) && inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
for (uint8 indexSub = EQEmu::inventory::containerBegin; (cursorDepth == 0) && inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
||||||
inst_sub = inst_main->GetItem(indexSub);
|
inst_sub = inst_main->GetItem(indexSub);
|
||||||
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
||||||
linker.SetItemInst(inst_sub);
|
linker.SetItemInst(inst_sub);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
EQEmu::InventoryProfile::CalcSlotId(EQEmu::inventory::slotCursor, indexSub), EQEmu::inventory::slotCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
EQEmu::InventoryProfile::CalcSlotId(EQEmu::inventory::slotCursor, indexSub), EQEmu::inventory::slotCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2647,10 +2638,8 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
||||||
linker.SetItemInst(inst_main);
|
linker.SetItemInst(inst_main);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "TributeSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "TributeSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// bank
|
// bank
|
||||||
@ -2659,20 +2648,16 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
||||||
linker.SetItemInst(inst_main);
|
linker.SetItemInst(inst_main);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "BankSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "BankSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
||||||
inst_sub = inst_main->GetItem(indexSub);
|
inst_sub = inst_main->GetItem(indexSub);
|
||||||
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
||||||
linker.SetItemInst(inst_sub);
|
linker.SetItemInst(inst_sub);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2681,20 +2666,16 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
||||||
linker.SetItemInst(inst_main);
|
linker.SetItemInst(inst_main);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "SharedBankSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "SharedBankSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
||||||
inst_sub = inst_main->GetItem(indexSub);
|
inst_sub = inst_main->GetItem(indexSub);
|
||||||
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
||||||
linker.SetItemInst(inst_sub);
|
linker.SetItemInst(inst_sub);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2704,20 +2685,16 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
||||||
linker.SetItemInst(inst_main);
|
linker.SetItemInst(inst_main);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "TradeSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "TradeSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
||||||
inst_sub = inst_main->GetItem(indexSub);
|
inst_sub = inst_main->GetItem(indexSub);
|
||||||
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
||||||
linker.SetItemInst(inst_sub);
|
linker.SetItemInst(inst_sub);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2736,20 +2713,16 @@ void command_peekinv(Client *c, const Seperator *sep)
|
|||||||
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
|
||||||
linker.SetItemInst(inst_main);
|
linker.SetItemInst(inst_main);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), "WorldSlot: %i, Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), "WorldSlot: %i, Item: %i (%s), Charges: %i",
|
||||||
(EQEmu::legacy::WORLD_BEGIN + indexMain), ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
(EQEmu::legacy::WORLD_BEGIN + indexMain), ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
|
||||||
|
|
||||||
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsType(EQEmu::item::ItemClassBag) && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsType(EQEmu::item::ItemClassBag) && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
|
||||||
inst_sub = inst_main->GetItem(indexSub);
|
inst_sub = inst_main->GetItem(indexSub);
|
||||||
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
|
||||||
linker.SetItemInst(inst_sub);
|
linker.SetItemInst(inst_sub);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
|
||||||
|
|
||||||
c->Message((item_data == nullptr), " WorldBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
c->Message((item_data == nullptr), " WorldBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
|
||||||
INVALID_INDEX, indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
INVALID_INDEX, indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), linker.GenerateLink().c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4404,9 +4377,7 @@ void command_iteminfo(Client *c, const Seperator *sep)
|
|||||||
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
||||||
linker.SetItemInst(inst);
|
linker.SetItemInst(inst);
|
||||||
|
|
||||||
auto item_link = linker.GenerateLink();
|
c->Message(0, "*** Item Info for [%s] ***", linker.GenerateLink().c_str());
|
||||||
|
|
||||||
c->Message(0, "*** Item Info for [%s] ***", item_link.c_str());
|
|
||||||
c->Message(0, ">> ID: %u, ItemUseType: %u, ItemClassType: %u", item->ID, item->ItemType, item->ItemClass);
|
c->Message(0, ">> ID: %u, ItemUseType: %u, ItemClassType: %u", item->ID, item->ItemType, item->ItemClass);
|
||||||
c->Message(0, ">> IDFile: '%s', IconID: %u", item->IDFile, item->Icon);
|
c->Message(0, ">> IDFile: '%s', IconID: %u", item->IDFile, item->Icon);
|
||||||
c->Message(0, ">> Size: %u, Weight: %u, Price: %u, LDoNPrice: %u", item->Size, item->Weight, item->Price, item->LDoNPrice);
|
c->Message(0, ">> Size: %u, Weight: %u, Price: %u, LDoNPrice: %u", item->Size, item->Weight, item->Price, item->LDoNPrice);
|
||||||
@ -5550,9 +5521,9 @@ void command_summonitem(Client *c, const Seperator *sep)
|
|||||||
std::string cmd_msg = sep->msg;
|
std::string cmd_msg = sep->msg;
|
||||||
size_t link_open = cmd_msg.find('\x12');
|
size_t link_open = cmd_msg.find('\x12');
|
||||||
size_t link_close = cmd_msg.find_last_of('\x12');
|
size_t link_close = cmd_msg.find_last_of('\x12');
|
||||||
if (link_open != link_close && (cmd_msg.length() - link_open) > EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
|
if (link_open != link_close && (cmd_msg.length() - link_open) > EQEmu::constants::SayLinkBodySize) {
|
||||||
EQEmu::SayLinkBody_Struct link_body;
|
EQEmu::SayLinkBody_Struct link_body;
|
||||||
EQEmu::saylink::DegenerateLinkBody(link_body, cmd_msg.substr(link_open + 1, EQEmu::legacy::TEXT_LINK_BODY_LENGTH));
|
EQEmu::saylink::DegenerateLinkBody(link_body, cmd_msg.substr(link_open + 1, EQEmu::constants::SayLinkBodySize));
|
||||||
itemid = link_body.item_id;
|
itemid = link_body.item_id;
|
||||||
}
|
}
|
||||||
else if (!sep->IsNumber(1)) {
|
else if (!sep->IsNumber(1)) {
|
||||||
@ -5661,7 +5632,6 @@ void command_itemsearch(Client *c, const Seperator *sep)
|
|||||||
const char *search_criteria=sep->argplus[1];
|
const char *search_criteria=sep->argplus[1];
|
||||||
|
|
||||||
const EQEmu::ItemData* item = nullptr;
|
const EQEmu::ItemData* item = nullptr;
|
||||||
std::string item_link;
|
|
||||||
EQEmu::SayLinkEngine linker;
|
EQEmu::SayLinkEngine linker;
|
||||||
linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
|
linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
|
||||||
|
|
||||||
@ -5670,9 +5640,7 @@ void command_itemsearch(Client *c, const Seperator *sep)
|
|||||||
if (item) {
|
if (item) {
|
||||||
linker.SetItemData(item);
|
linker.SetItemData(item);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
c->Message(0, "%u: %s", item->ID, linker.GenerateLink().c_str());
|
||||||
|
|
||||||
c->Message(0, "%u: %s", item->ID, item_link.c_str());
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c->Message(0, "Item #%s not found", search_criteria);
|
c->Message(0, "Item #%s not found", search_criteria);
|
||||||
@ -5695,9 +5663,7 @@ void command_itemsearch(Client *c, const Seperator *sep)
|
|||||||
if (pdest != nullptr) {
|
if (pdest != nullptr) {
|
||||||
linker.SetItemData(item);
|
linker.SetItemData(item);
|
||||||
|
|
||||||
item_link = linker.GenerateLink();
|
c->Message(0, "%u: %s", item->ID, linker.GenerateLink().c_str());
|
||||||
|
|
||||||
c->Message(0, "%u: %s", item->ID, item_link.c_str());
|
|
||||||
|
|
||||||
++count;
|
++count;
|
||||||
}
|
}
|
||||||
@ -7201,6 +7167,90 @@ void command_undye(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void command_ucs(Client *c, const Seperator *sep)
|
||||||
|
{
|
||||||
|
if (!c)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Log(Logs::Detail, Logs::UCS_Server, "Character %s attempting ucs reconnect while ucs server is %savailable",
|
||||||
|
c->GetName(), (zone->IsUCSServerAvailable() ? "" : "un"));
|
||||||
|
|
||||||
|
if (zone->IsUCSServerAvailable()) {
|
||||||
|
EQApplicationPacket* outapp = nullptr;
|
||||||
|
std::string buffer;
|
||||||
|
|
||||||
|
std::string MailKey = database.GetMailKey(c->CharacterID(), true);
|
||||||
|
EQEmu::versions::UCSVersion ConnectionType = EQEmu::versions::ucsUnknown;
|
||||||
|
|
||||||
|
// chat server packet
|
||||||
|
switch (c->ClientVersion()) {
|
||||||
|
case EQEmu::versions::ClientVersion::Titanium:
|
||||||
|
ConnectionType = EQEmu::versions::ucsTitaniumChat;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::SoF:
|
||||||
|
ConnectionType = EQEmu::versions::ucsSoFCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::SoD:
|
||||||
|
ConnectionType = EQEmu::versions::ucsSoDCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::UF:
|
||||||
|
ConnectionType = EQEmu::versions::ucsUFCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::RoF:
|
||||||
|
ConnectionType = EQEmu::versions::ucsRoFCombined;
|
||||||
|
break;
|
||||||
|
case EQEmu::versions::ClientVersion::RoF2:
|
||||||
|
ConnectionType = EQEmu::versions::ucsRoF2Combined;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ConnectionType = EQEmu::versions::ucsUnknown;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = StringFormat("%s,%i,%s.%s,%c%s",
|
||||||
|
Config->ChatHost.c_str(),
|
||||||
|
Config->ChatPort,
|
||||||
|
Config->ShortName.c_str(),
|
||||||
|
c->GetName(),
|
||||||
|
ConnectionType,
|
||||||
|
MailKey.c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
outapp = new EQApplicationPacket(OP_SetChatServer, (buffer.length() + 1));
|
||||||
|
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
|
||||||
|
outapp->pBuffer[buffer.length()] = '\0';
|
||||||
|
|
||||||
|
c->QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
|
||||||
|
// mail server packet
|
||||||
|
switch (c->ClientVersion()) {
|
||||||
|
case EQEmu::versions::ClientVersion::Titanium:
|
||||||
|
ConnectionType = EQEmu::versions::ucsTitaniumMail;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// retain value from previous switch
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = StringFormat("%s,%i,%s.%s,%c%s",
|
||||||
|
Config->MailHost.c_str(),
|
||||||
|
Config->MailPort,
|
||||||
|
Config->ShortName.c_str(),
|
||||||
|
c->GetName(),
|
||||||
|
ConnectionType,
|
||||||
|
MailKey.c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
outapp = new EQApplicationPacket(OP_SetChatServer2, (buffer.length() + 1));
|
||||||
|
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
|
||||||
|
outapp->pBuffer[buffer.length()] = '\0';
|
||||||
|
|
||||||
|
c->QueuePacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void command_undyeme(Client *c, const Seperator *sep)
|
void command_undyeme(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
if(c) {
|
if(c) {
|
||||||
@ -10839,7 +10889,7 @@ void command_hotfix(Client *c, const Seperator *sep) {
|
|||||||
}
|
}
|
||||||
worldserver.SendPacket(&pack);
|
worldserver.SendPacket(&pack);
|
||||||
|
|
||||||
c->Message(0, "Hotfix applied");
|
if (c) c->Message(0, "Hotfix applied");
|
||||||
});
|
});
|
||||||
|
|
||||||
t1.detach();
|
t1.detach();
|
||||||
|
|||||||
@ -302,6 +302,7 @@ void command_titlesuffix(Client *c, const Seperator *sep);
|
|||||||
void command_traindisc(Client *c, const Seperator *sep);
|
void command_traindisc(Client *c, const Seperator *sep);
|
||||||
void command_trapinfo(Client* c, const Seperator *sep);
|
void command_trapinfo(Client* c, const Seperator *sep);
|
||||||
void command_tune(Client *c, const Seperator *sep);
|
void command_tune(Client *c, const Seperator *sep);
|
||||||
|
void command_ucs(Client *c, const Seperator *sep);
|
||||||
void command_undye(Client *c, const Seperator *sep);
|
void command_undye(Client *c, const Seperator *sep);
|
||||||
void command_undyeme(Client *c, const Seperator *sep);
|
void command_undyeme(Client *c, const Seperator *sep);
|
||||||
void command_unfreeze(Client *c, const Seperator *sep);
|
void command_unfreeze(Client *c, const Seperator *sep);
|
||||||
|
|||||||
@ -1253,20 +1253,20 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
|||||||
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
|
||||||
linker.SetItemInst(inst);
|
linker.SetItemInst(inst);
|
||||||
|
|
||||||
auto item_link = linker.GenerateLink();
|
linker.GenerateLink();
|
||||||
|
|
||||||
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, item_link.c_str());
|
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, linker.Link().c_str());
|
||||||
|
|
||||||
if (!IsPlayerCorpse()) {
|
if (!IsPlayerCorpse()) {
|
||||||
Group *g = client->GetGroup();
|
Group *g = client->GetGroup();
|
||||||
if (g != nullptr) {
|
if (g != nullptr) {
|
||||||
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE,
|
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE,
|
||||||
client->GetName(), item_link.c_str());
|
client->GetName(), linker.Link().c_str());
|
||||||
} else {
|
} else {
|
||||||
Raid *r = client->GetRaid();
|
Raid *r = client->GetRaid();
|
||||||
if (r != nullptr) {
|
if (r != nullptr) {
|
||||||
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE,
|
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE,
|
||||||
client->GetName(), item_link.c_str());
|
client->GetName(), linker.Link().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -831,6 +831,8 @@ void Client::SetLevel(uint8 set_level, bool command)
|
|||||||
SetHP(CalcMaxHP()); // Why not, lets give them a free heal
|
SetHP(CalcMaxHP()); // Why not, lets give them a free heal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (RuleI(World, PVPMinLevel) > 0 && level >= RuleI(World, PVPMinLevel) && m_pp.pvp == 0) SetPVP(true);
|
||||||
|
|
||||||
DoTributeUpdate();
|
DoTributeUpdate();
|
||||||
SendHPUpdate();
|
SendHPUpdate();
|
||||||
SetMana(CalcMaxMana());
|
SetMana(CalcMaxMana());
|
||||||
|
|||||||
35
zone/fastmath.cpp
Normal file
35
zone/fastmath.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#endif
|
||||||
|
#include <cmath>
|
||||||
|
#include "fastmath.h"
|
||||||
|
|
||||||
|
FastMath g_Math;
|
||||||
|
|
||||||
|
// This should match EQ's sin/cos LUTs
|
||||||
|
// Some values didn't match on linux, but they were the "same" float :P
|
||||||
|
FastMath::FastMath()
|
||||||
|
{
|
||||||
|
int ci = 0;
|
||||||
|
int si = 128;
|
||||||
|
float res;
|
||||||
|
do {
|
||||||
|
res = std::cos(static_cast<float>(ci) * M_PI * 2 / 512);
|
||||||
|
lut_cos[ci] = res;
|
||||||
|
if (si == 512)
|
||||||
|
si = 0;
|
||||||
|
lut_sin[si] = res;
|
||||||
|
++ci;
|
||||||
|
++si;
|
||||||
|
} while (ci < 512);
|
||||||
|
|
||||||
|
lut_sin[0] = 0.0f;
|
||||||
|
lut_sin[128] = 1.0f;
|
||||||
|
lut_sin[256] = 0.0f;
|
||||||
|
lut_sin[384] = -1.0f;
|
||||||
|
|
||||||
|
lut_cos[0] = 1.0f;
|
||||||
|
lut_cos[128] = 0.0f;
|
||||||
|
lut_cos[384] = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
18
zone/fastmath.h
Normal file
18
zone/fastmath.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef FASTMATH_H
|
||||||
|
#define FASTMATH_H
|
||||||
|
|
||||||
|
class FastMath
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float lut_cos[512];
|
||||||
|
float lut_sin[512];
|
||||||
|
|
||||||
|
public:
|
||||||
|
FastMath();
|
||||||
|
|
||||||
|
inline float FastSin(float a) { return lut_sin[static_cast<int>(a) & 0x1ff]; }
|
||||||
|
inline float FastCos(float a) { return lut_cos[static_cast<int>(a) & 0x1ff]; }
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* !FASTMATH_H */
|
||||||
@ -1329,7 +1329,7 @@ int Client::GetItemLinkHash(const EQEmu::ItemInstance* inst) {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This appears to still be in use... The core of this should be incorporated into class Client::TextLink
|
// This appears to still be in use... The core of this should be incorporated into class EQEmu::SayLinkEngine
|
||||||
void Client::SendItemLink(const EQEmu::ItemInstance* inst, bool send_to_all)
|
void Client::SendItemLink(const EQEmu::ItemInstance* inst, bool send_to_all)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -282,6 +282,16 @@ void Lua_Mob::GMMove(double x, double y, double z, double heading, bool send_upd
|
|||||||
self->GMMove(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(heading), send_update);
|
self->GMMove(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z), static_cast<float>(heading), send_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lua_Mob::TryMoveAlong(float distance, float angle) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->TryMoveAlong(distance, angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_Mob::TryMoveAlong(float distance, float angle, bool send) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->TryMoveAlong(distance, angle, send);
|
||||||
|
}
|
||||||
|
|
||||||
bool Lua_Mob::HasProcs() {
|
bool Lua_Mob::HasProcs() {
|
||||||
Lua_Safe_Call_Bool();
|
Lua_Safe_Call_Bool();
|
||||||
return self->HasProcs();
|
return self->HasProcs();
|
||||||
@ -2197,6 +2207,8 @@ luabind::scope lua_register_mob() {
|
|||||||
.def("GMMove", (void(Lua_Mob::*)(double,double,double))&Lua_Mob::GMMove)
|
.def("GMMove", (void(Lua_Mob::*)(double,double,double))&Lua_Mob::GMMove)
|
||||||
.def("GMMove", (void(Lua_Mob::*)(double,double,double,double))&Lua_Mob::GMMove)
|
.def("GMMove", (void(Lua_Mob::*)(double,double,double,double))&Lua_Mob::GMMove)
|
||||||
.def("GMMove", (void(Lua_Mob::*)(double,double,double,double,bool))&Lua_Mob::GMMove)
|
.def("GMMove", (void(Lua_Mob::*)(double,double,double,double,bool))&Lua_Mob::GMMove)
|
||||||
|
.def("TryMoveAlong", (void(Lua_Mob::*)(float,float))&Lua_Mob::TryMoveAlong)
|
||||||
|
.def("TryMoveAlong", (void(Lua_Mob::*)(float,float,bool))&Lua_Mob::TryMoveAlong)
|
||||||
.def("HasProcs", &Lua_Mob::HasProcs)
|
.def("HasProcs", &Lua_Mob::HasProcs)
|
||||||
.def("IsInvisible", (bool(Lua_Mob::*)(void))&Lua_Mob::IsInvisible)
|
.def("IsInvisible", (bool(Lua_Mob::*)(void))&Lua_Mob::IsInvisible)
|
||||||
.def("IsInvisible", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsInvisible)
|
.def("IsInvisible", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsInvisible)
|
||||||
|
|||||||
@ -74,6 +74,8 @@ public:
|
|||||||
void GMMove(double x, double y, double z);
|
void GMMove(double x, double y, double z);
|
||||||
void GMMove(double x, double y, double z, double heading);
|
void GMMove(double x, double y, double z, double heading);
|
||||||
void GMMove(double x, double y, double z, double heading, bool send_update);
|
void GMMove(double x, double y, double z, double heading, bool send_update);
|
||||||
|
void TryMoveAlong(float distance, float heading);
|
||||||
|
void TryMoveAlong(float distance, float heading, bool send);
|
||||||
bool HasProcs();
|
bool HasProcs();
|
||||||
bool IsInvisible();
|
bool IsInvisible();
|
||||||
bool IsInvisible(Lua_Mob other);
|
bool IsInvisible(Lua_Mob other);
|
||||||
|
|||||||
2065
zone/map.cpp
2065
zone/map.cpp
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@
|
|||||||
#define BEST_Z_INVALID -99999
|
#define BEST_Z_INVALID -99999
|
||||||
|
|
||||||
extern const ZoneConfig *Config;
|
extern const ZoneConfig *Config;
|
||||||
namespace EQEmu
|
namespace EQEmu
|
||||||
{
|
{
|
||||||
class Map
|
class Map
|
||||||
{
|
{
|
||||||
@ -43,6 +43,7 @@ namespace EQEmu
|
|||||||
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
|
bool LineIntersectsZone(glm::vec3 start, glm::vec3 end, float step, glm::vec3 *result) const;
|
||||||
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
|
bool LineIntersectsZoneNoZLeaps(glm::vec3 start, glm::vec3 end, float step_mag, glm::vec3 *result) const;
|
||||||
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
|
bool CheckLoS(glm::vec3 myloc, glm::vec3 oloc) const;
|
||||||
|
bool DoCollisionCheck(glm::vec3 myloc, glm::vec3 oloc, glm::vec3 &outnorm, float &distance) const;
|
||||||
|
|
||||||
#ifdef USE_MAP_MMFS
|
#ifdef USE_MAP_MMFS
|
||||||
bool Load(std::string filename, bool force_mmf_overwrite = false);
|
bool Load(std::string filename, bool force_mmf_overwrite = false);
|
||||||
@ -67,4 +68,4 @@ namespace EQEmu
|
|||||||
impl *imp;
|
impl *imp;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -117,7 +117,7 @@ Mob::Mob(const char* in_name,
|
|||||||
fix_z_timer(300),
|
fix_z_timer(300),
|
||||||
fix_z_timer_engaged(100),
|
fix_z_timer_engaged(100),
|
||||||
attack_anim_timer(1000),
|
attack_anim_timer(1000),
|
||||||
position_update_melee_push_timer(1000),
|
position_update_melee_push_timer(500),
|
||||||
mHateListCleanup(6000)
|
mHateListCleanup(6000)
|
||||||
{
|
{
|
||||||
targeted = 0;
|
targeted = 0;
|
||||||
@ -395,6 +395,7 @@ Mob::Mob(const char* in_name,
|
|||||||
permarooted = (runspeed > 0) ? false : true;
|
permarooted = (runspeed > 0) ? false : true;
|
||||||
|
|
||||||
movetimercompleted = false;
|
movetimercompleted = false;
|
||||||
|
ForcedMovement = 0;
|
||||||
roamer = false;
|
roamer = false;
|
||||||
rooted = false;
|
rooted = false;
|
||||||
charmed = false;
|
charmed = false;
|
||||||
|
|||||||
@ -50,6 +50,8 @@ struct AuraRecord;
|
|||||||
struct NewSpawn_Struct;
|
struct NewSpawn_Struct;
|
||||||
struct PlayerPositionUpdateServer_Struct;
|
struct PlayerPositionUpdateServer_Struct;
|
||||||
|
|
||||||
|
const int COLLISION_BOX_SIZE = 4;
|
||||||
|
|
||||||
namespace EQEmu
|
namespace EQEmu
|
||||||
{
|
{
|
||||||
struct ItemData;
|
struct ItemData;
|
||||||
@ -578,6 +580,8 @@ public:
|
|||||||
void SetFlyMode(uint8 flymode);
|
void SetFlyMode(uint8 flymode);
|
||||||
inline void Teleport(glm::vec3 NewPosition) { m_Position.x = NewPosition.x; m_Position.y = NewPosition.y;
|
inline void Teleport(glm::vec3 NewPosition) { m_Position.x = NewPosition.x; m_Position.y = NewPosition.y;
|
||||||
m_Position.z = NewPosition.z; };
|
m_Position.z = NewPosition.z; };
|
||||||
|
void TryMoveAlong(float distance, float angle, bool send = true);
|
||||||
|
void ProcessForcedMovement();
|
||||||
|
|
||||||
//AI
|
//AI
|
||||||
static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel);
|
static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel);
|
||||||
@ -1313,6 +1317,9 @@ protected:
|
|||||||
char lastname[64];
|
char lastname[64];
|
||||||
|
|
||||||
glm::vec4 m_Delta;
|
glm::vec4 m_Delta;
|
||||||
|
// just locs around them to double check, if we do expand collision this should be cached on movement
|
||||||
|
// ideally we should use real models, but this should be quick and work mostly
|
||||||
|
glm::vec4 m_CollisionBox[COLLISION_BOX_SIZE];
|
||||||
|
|
||||||
EQEmu::LightSourceProfile m_Light;
|
EQEmu::LightSourceProfile m_Light;
|
||||||
|
|
||||||
@ -1423,6 +1430,7 @@ protected:
|
|||||||
std::unique_ptr<Timer> AI_movement_timer;
|
std::unique_ptr<Timer> AI_movement_timer;
|
||||||
std::unique_ptr<Timer> AI_target_check_timer;
|
std::unique_ptr<Timer> AI_target_check_timer;
|
||||||
bool movetimercompleted;
|
bool movetimercompleted;
|
||||||
|
int8 ForcedMovement; // push
|
||||||
bool permarooted;
|
bool permarooted;
|
||||||
std::unique_ptr<Timer> AI_scan_area_timer;
|
std::unique_ptr<Timer> AI_scan_area_timer;
|
||||||
std::unique_ptr<Timer> AI_walking_timer;
|
std::unique_ptr<Timer> AI_walking_timer;
|
||||||
|
|||||||
124
zone/mob_ai.cpp
124
zone/mob_ai.cpp
@ -29,12 +29,16 @@
|
|||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
#include "string_ids.h"
|
#include "string_ids.h"
|
||||||
#include "water_map.h"
|
#include "water_map.h"
|
||||||
|
#include "fastmath.h"
|
||||||
|
|
||||||
|
#include <glm/gtx/projection.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
extern EntityList entity_list;
|
extern EntityList entity_list;
|
||||||
|
extern FastMath g_Math;
|
||||||
|
|
||||||
extern Zone *zone;
|
extern Zone *zone;
|
||||||
|
|
||||||
@ -918,29 +922,26 @@ void Client::AI_Process()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsPet())
|
if (IsPet()) {
|
||||||
{
|
Mob *owner = GetOwner();
|
||||||
Mob* owner = GetOwner();
|
if (owner == nullptr)
|
||||||
if(owner == nullptr)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float dist = DistanceSquared(m_Position, owner->GetPosition());
|
float dist = DistanceSquared(m_Position, owner->GetPosition());
|
||||||
if (dist >= 400)
|
if (dist >= 202500) { // >= 450 distance
|
||||||
{
|
Teleport(static_cast<glm::vec3>(owner->GetPosition()));
|
||||||
if(AI_movement_timer->Check())
|
SendPositionUpdate(); // this shouldn't happen a lot (and hard to make it) so lets not rate limit
|
||||||
{
|
} else if (dist >= 400) { // >=20
|
||||||
int nspeed = (dist >= 5625 ? GetRunspeed() : GetWalkspeed());
|
if (AI_movement_timer->Check()) {
|
||||||
|
int nspeed = (dist >= 1225 ? GetRunspeed() : GetWalkspeed()); // >= 35
|
||||||
animation = nspeed;
|
animation = nspeed;
|
||||||
nspeed *= 2;
|
nspeed *= 2;
|
||||||
SetCurrentSpeed(nspeed);
|
SetCurrentSpeed(nspeed);
|
||||||
|
|
||||||
CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), nspeed);
|
CalculateNewPosition2(owner->GetX(), owner->GetY(), owner->GetZ(), nspeed);
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if (moved) {
|
||||||
{
|
|
||||||
if(moved)
|
|
||||||
{
|
|
||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
moved = false;
|
moved = false;
|
||||||
}
|
}
|
||||||
@ -949,6 +950,71 @@ void Client::AI_Process()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mob::ProcessForcedMovement()
|
||||||
|
{
|
||||||
|
// we are being pushed, we will hijack this movement timer
|
||||||
|
// this also needs to be done before casting to have a chance to interrupt
|
||||||
|
// this flag won't be set if the mob can't be pushed (rooted etc)
|
||||||
|
if (AI_movement_timer->Check()) {
|
||||||
|
bool bPassed = true;
|
||||||
|
auto z_off = GetZOffset();
|
||||||
|
glm::vec3 normal;
|
||||||
|
glm::vec3 new_pos = m_Position + m_Delta;
|
||||||
|
|
||||||
|
// no zone map = fucked
|
||||||
|
if (zone->HasMap()) {
|
||||||
|
// in front
|
||||||
|
m_CollisionBox[0].x = m_Position.x + 3.0f * g_Math.FastSin(0.0f);
|
||||||
|
m_CollisionBox[0].y = m_Position.y + 3.0f * g_Math.FastCos(0.0f);
|
||||||
|
m_CollisionBox[0].z = m_Position.z + z_off;
|
||||||
|
|
||||||
|
// to right
|
||||||
|
m_CollisionBox[1].x = m_Position.x + 3.0f * g_Math.FastSin(128.0f);
|
||||||
|
m_CollisionBox[1].y = m_Position.y + 3.0f * g_Math.FastCos(128.0f);
|
||||||
|
m_CollisionBox[1].z = m_Position.z + z_off;
|
||||||
|
|
||||||
|
// behind
|
||||||
|
m_CollisionBox[2].x = m_Position.x + 3.0f * g_Math.FastSin(256.0f);
|
||||||
|
m_CollisionBox[2].y = m_Position.y + 3.0f * g_Math.FastCos(256.0f);
|
||||||
|
m_CollisionBox[2].z = m_Position.z + z_off;
|
||||||
|
|
||||||
|
// to left
|
||||||
|
m_CollisionBox[3].x = m_Position.x + 3.0f * g_Math.FastSin(384.0f);
|
||||||
|
m_CollisionBox[3].y = m_Position.y + 3.0f * g_Math.FastCos(384.0f);
|
||||||
|
m_CollisionBox[3].z = m_Position.z + z_off;
|
||||||
|
|
||||||
|
// collision happened, need to move along the wall
|
||||||
|
float distance = 0.0f, shortest = std::numeric_limits<float>::infinity();
|
||||||
|
glm::vec3 tmp_nrm;
|
||||||
|
for (auto &vec : m_CollisionBox) {
|
||||||
|
if (zone->zonemap->DoCollisionCheck(vec, new_pos, tmp_nrm, distance)) {
|
||||||
|
bPassed = false; // lets try with new projection next pass
|
||||||
|
if (distance < shortest) {
|
||||||
|
normal = tmp_nrm;
|
||||||
|
shortest = distance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bPassed) {
|
||||||
|
ForcedMovement = 0;
|
||||||
|
m_Delta = glm::vec4();
|
||||||
|
Teleport(new_pos);
|
||||||
|
SendPositionUpdate();
|
||||||
|
pLastChange = Timer::GetCurrentTime();
|
||||||
|
FixZ(); // so we teleport to the ground locally, we want the client to interpolate falling etc
|
||||||
|
} else if (--ForcedMovement) {
|
||||||
|
auto proj = glm::proj(static_cast<glm::vec3>(m_Delta), normal);
|
||||||
|
m_Delta.x -= proj.x;
|
||||||
|
m_Delta.y -= proj.y;
|
||||||
|
m_Delta.z -= proj.z;
|
||||||
|
} else {
|
||||||
|
m_Delta = glm::vec4(); // well, we failed to find a spot to be forced to, lets give up
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Mob::AI_Process() {
|
void Mob::AI_Process() {
|
||||||
if (!IsAIControlled())
|
if (!IsAIControlled())
|
||||||
return;
|
return;
|
||||||
@ -956,6 +1022,7 @@ void Mob::AI_Process() {
|
|||||||
if (!(AI_think_timer->Check() || attack_timer.Check(false)))
|
if (!(AI_think_timer->Check() || attack_timer.Check(false)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
||||||
if (IsCasting())
|
if (IsCasting())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1428,10 +1495,10 @@ void Mob::AI_Process() {
|
|||||||
if (dist >= 400 || distz > 100)
|
if (dist >= 400 || distz > 100)
|
||||||
{
|
{
|
||||||
int speed = GetWalkspeed();
|
int speed = GetWalkspeed();
|
||||||
if (dist >= 5625)
|
if (dist >= 1225) // 35
|
||||||
speed = GetRunspeed();
|
speed = GetRunspeed();
|
||||||
|
|
||||||
if (distz > 100)
|
if (dist >= 202500 || distz > 100) // dist >= 450
|
||||||
{
|
{
|
||||||
m_Position = ownerPos;
|
m_Position = ownerPos;
|
||||||
SendPositionUpdate();
|
SendPositionUpdate();
|
||||||
@ -2074,15 +2141,34 @@ bool Mob::Rampage(ExtraAttackOptions *opts)
|
|||||||
if (m_target) {
|
if (m_target) {
|
||||||
if (m_target == GetTarget())
|
if (m_target == GetTarget())
|
||||||
continue;
|
continue;
|
||||||
if (CombatRange(m_target)) {
|
if (DistanceSquaredNoZ(GetPosition(), m_target->GetPosition()) <= NPC_RAMPAGE_RANGE2) {
|
||||||
ProcessAttackRounds(m_target, opts);
|
ProcessAttackRounds(m_target, opts);
|
||||||
index_hit++;
|
index_hit++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RuleB(Combat, RampageHitsTarget) && index_hit < rampage_targets)
|
if (RuleB(Combat, RampageHitsTarget)) {
|
||||||
ProcessAttackRounds(GetTarget(), opts);
|
if (index_hit < rampage_targets)
|
||||||
|
ProcessAttackRounds(GetTarget(), opts);
|
||||||
|
} else { // let's do correct behavior here, if they set above rule we can assume they want non-live like behavior
|
||||||
|
if (index_hit < rampage_targets) {
|
||||||
|
// so we go over in reverse order and skip range check
|
||||||
|
// lets do it this way to still support non-live-like >1 rampage targets
|
||||||
|
// likely live is just a fall through of the last valid mob
|
||||||
|
for (auto i = RampageArray.crbegin(); i != RampageArray.crend(); ++i) {
|
||||||
|
if (index_hit >= rampage_targets)
|
||||||
|
break;
|
||||||
|
auto m_target = entity_list.GetMob(*i);
|
||||||
|
if (m_target) {
|
||||||
|
if (m_target == GetTarget())
|
||||||
|
continue;
|
||||||
|
ProcessAttackRounds(m_target, opts);
|
||||||
|
index_hit++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_specialattacks = eSpecialAttacks::None;
|
m_specialattacks = eSpecialAttacks::None;
|
||||||
|
|
||||||
|
|||||||
@ -679,7 +679,6 @@ void NatsManager::OnSpawnEvent(const EmuOpcode op, uint32 entity_id, Spawn_Struc
|
|||||||
event.set_equip_chest2(spawn->equip_chest2);
|
event.set_equip_chest2(spawn->equip_chest2);
|
||||||
event.set_mount_color(spawn->mount_color);
|
event.set_mount_color(spawn->mount_color);
|
||||||
event.set_spawnid(spawn->spawnId);
|
event.set_spawnid(spawn->spawnId);
|
||||||
event.set_unknown0344(*spawn->unknown0344);
|
|
||||||
event.set_ismercenary(spawn->IsMercenary);
|
event.set_ismercenary(spawn->IsMercenary);
|
||||||
//event.set_equipment_tint(spawn->equipment_tint);
|
//event.set_equipment_tint(spawn->equipment_tint);
|
||||||
event.set_lfg(spawn->lfg);
|
event.set_lfg(spawn->lfg);
|
||||||
@ -800,8 +799,8 @@ void NatsManager::OnDamageEvent(uint32 entity_id, CombatDamage_Struct *cd) {
|
|||||||
event.set_spellid(cd->spellid);
|
event.set_spellid(cd->spellid);
|
||||||
event.set_damage(cd->damage);
|
event.set_damage(cd->damage);
|
||||||
event.set_force(cd->force);
|
event.set_force(cd->force);
|
||||||
event.set_meleepush_xy(cd->meleepush_xy);
|
event.set_meleepush_xy(cd->hit_heading);
|
||||||
event.set_meleepush_z(cd->meleepush_z);
|
event.set_meleepush_z(cd->hit_pitch);
|
||||||
|
|
||||||
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
if (!event.SerializeToString(&pubMessage)) { Log(Logs::General, Logs::NATS, "Failed to serialize message to string"); return; }
|
||||||
auto finalEvent = eqproto::Event();
|
auto finalEvent = eqproto::Event();
|
||||||
|
|||||||
@ -583,9 +583,7 @@ void NPC::QueryLoot(Client* to)
|
|||||||
linker.SetLinkType(EQEmu::saylink::SayLinkLootItem);
|
linker.SetLinkType(EQEmu::saylink::SayLinkLootItem);
|
||||||
linker.SetLootData(*cur);
|
linker.SetLootData(*cur);
|
||||||
|
|
||||||
auto item_link = linker.GenerateLink();
|
to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", linker.GenerateLink().c_str(), (*cur)->item_id, (*cur)->min_level, (*cur)->max_level);
|
||||||
|
|
||||||
to->Message(0, "%s, ID: %u, Level: (min: %u, max: %u)", item_link.c_str(), (*cur)->item_id, (*cur)->min_level, (*cur)->max_level);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
to->Message(0, "%i items on %s.", x, GetName());
|
to->Message(0, "%i items on %s.", x, GetName());
|
||||||
@ -764,6 +762,10 @@ bool NPC::Process()
|
|||||||
reface_timer->Disable();
|
reface_timer->Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// needs to be done before mez and stun
|
||||||
|
if (ForcedMovement)
|
||||||
|
ProcessForcedMovement();
|
||||||
|
|
||||||
if (IsMezzed())
|
if (IsMezzed())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@ -560,7 +560,8 @@ void PathManager::SpawnPathNodes()
|
|||||||
sprintf(npc_type->lastname, "%i", PathNodes[i].id);
|
sprintf(npc_type->lastname, "%i", PathNodes[i].id);
|
||||||
npc_type->cur_hp = 4000000;
|
npc_type->cur_hp = 4000000;
|
||||||
npc_type->max_hp = 4000000;
|
npc_type->max_hp = 4000000;
|
||||||
npc_type->race = 151;
|
npc_type->race = 2253;
|
||||||
|
npc_type->size = 3.0f;
|
||||||
npc_type->gender = 2;
|
npc_type->gender = 2;
|
||||||
npc_type->class_ = 9;
|
npc_type->class_ = 9;
|
||||||
npc_type->deity= 1;
|
npc_type->deity= 1;
|
||||||
@ -1377,7 +1378,7 @@ void PathManager::ShowPathNodeNeighbours(Client *c)
|
|||||||
Mob *m = entity_list.GetMob(Name);
|
Mob *m = entity_list.GetMob(Name);
|
||||||
|
|
||||||
if(m)
|
if(m)
|
||||||
m->SendIllusionPacket(151);
|
m->ChangeSize(3.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stringstream Neighbours;
|
std::stringstream Neighbours;
|
||||||
@ -1401,7 +1402,7 @@ void PathManager::ShowPathNodeNeighbours(Client *c)
|
|||||||
Mob *m = entity_list.GetMob(Name);
|
Mob *m = entity_list.GetMob(Name);
|
||||||
|
|
||||||
if(m)
|
if(m)
|
||||||
m->SendIllusionPacket(46);
|
m->ChangeSize(5.0f);
|
||||||
}
|
}
|
||||||
c->Message(0, "Neighbours: %s", Neighbours.str().c_str());
|
c->Message(0, "Neighbours: %s", Neighbours.str().c_str());
|
||||||
}
|
}
|
||||||
@ -1560,7 +1561,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
|||||||
sprintf(npc_type->lastname, "%i", new_id);
|
sprintf(npc_type->lastname, "%i", new_id);
|
||||||
npc_type->cur_hp = 4000000;
|
npc_type->cur_hp = 4000000;
|
||||||
npc_type->max_hp = 4000000;
|
npc_type->max_hp = 4000000;
|
||||||
npc_type->race = 151;
|
npc_type->race = 2253;
|
||||||
|
npc_type->size = 3.0f;
|
||||||
npc_type->gender = 2;
|
npc_type->gender = 2;
|
||||||
npc_type->class_ = 9;
|
npc_type->class_ = 9;
|
||||||
npc_type->deity= 1;
|
npc_type->deity= 1;
|
||||||
@ -1621,7 +1623,8 @@ int32 PathManager::AddNode(float x, float y, float z, float best_z, int32 reques
|
|||||||
sprintf(npc_type->lastname, "%i", new_id);
|
sprintf(npc_type->lastname, "%i", new_id);
|
||||||
npc_type->cur_hp = 4000000;
|
npc_type->cur_hp = 4000000;
|
||||||
npc_type->max_hp = 4000000;
|
npc_type->max_hp = 4000000;
|
||||||
npc_type->race = 151;
|
npc_type->race = 2253;
|
||||||
|
npc_type->size = 3.0f;
|
||||||
npc_type->gender = 2;
|
npc_type->gender = 2;
|
||||||
npc_type->class_ = 9;
|
npc_type->class_ = 9;
|
||||||
npc_type->deity= 1;
|
npc_type->deity= 1;
|
||||||
|
|||||||
114
zone/pets.cpp
114
zone/pets.cpp
@ -28,6 +28,8 @@
|
|||||||
#include "pets.h"
|
#include "pets.h"
|
||||||
#include "zonedb.h"
|
#include "zonedb.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
#endif
|
#endif
|
||||||
@ -38,82 +40,42 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
const char *GetRandPetName()
|
// need to pass in a char array of 64 chars
|
||||||
|
void GetRandPetName(char *name)
|
||||||
{
|
{
|
||||||
static const char *petnames[] = { "Gabaner","Gabann","Gabantik","Gabarab","Gabarer","Gabarn","Gabartik",
|
std::string temp;
|
||||||
"Gabekab","Gabeker","Gabekn","Gaber","Gabn","Gabobab","Gabobn","Gabtik",
|
temp.reserve(64);
|
||||||
"Ganer","Gann","Gantik","Garab","Garaner","Garann","Garantik","Gararn",
|
// note these orders are used to make the exclusions cheap :P
|
||||||
"Garekn","Garer","Garn","Gartik","Gasaner","Gasann","Gasantik","Gasarer",
|
static const char *part1[] = {"G", "J", "K", "L", "V", "X", "Z"};
|
||||||
"Gasartik","Gasekn","Gaser","Gebann","Gebantik","Gebarer","Gebarn","Gebartik",
|
static const char *part2[] = {nullptr, "ab", "ar", "as", "eb", "en", "ib", "ob", "on"};
|
||||||
"Gebeker","Gebekn","Gebn","Gekab","Geker","Gekn","Genaner","Genann","Genantik",
|
static const char *part3[] = {nullptr, "an", "ar", "ek", "ob"};
|
||||||
"Genarer","Genarn","Gener","Genn","Genobtik","Gibaner","Gibann","Gibantik",
|
static const char *part4[] = {"er", "ab", "n", "tik"};
|
||||||
"Gibarn","Gibartik","Gibekn","Giber","Gibn","Gibobtik","Gibtik","Gobaber",
|
|
||||||
"Gobaner","Gobann","Gobarn","Gobartik","Gober","Gobn","Gobober","Gobobn",
|
const char *first = part1[zone->random.Int(0, (sizeof(part1) / sizeof(const char *)) - 1)];
|
||||||
"Gobobtik","Gobtik","Gonaner","Gonann","Gonantik","Gonarab","Gonarer",
|
const char *second = part2[zone->random.Int(0, (sizeof(part2) / sizeof(const char *)) - 1)];
|
||||||
"Gonarn","Gonartik","Gonekab","Gonekn","Goner","Gonobtik","Gontik","Gotik",
|
const char *third = part3[zone->random.Int(0, (sizeof(part3) / sizeof(const char *)) - 1)];
|
||||||
"Jabaner","Jabann","Jabantik","Jabarab","Jabarer","Jabarn","Jabartik",
|
const char *fourth = part4[zone->random.Int(0, (sizeof(part4) / sizeof(const char *)) - 1)];
|
||||||
"Jabekab","Jabeker","Jabekn","Jaber","Jabn","Jabobtik","Jabtik","Janab",
|
|
||||||
"Janer","Jann","Jantik","Jarab","Jaranab","Jaraner","Jararer","Jararn",
|
// if both of these are empty, we would get an illegally short name
|
||||||
"Jarartik","Jareker","Jarekn","Jarer","Jarn","Jarobn","Jarobtik","Jartik",
|
if (second == nullptr && third == nullptr)
|
||||||
"Jasab","Jasaner","Jasantik","Jasarer","Jasartik","Jasekab","Jaseker",
|
fourth = part4[(sizeof(part4) / sizeof(const char *)) - 1];
|
||||||
"Jasekn","Jaser","Jasn","Jasobab","Jasober","Jastik","Jebanab","Jebann",
|
|
||||||
"Jebantik","Jebarab","Jebarar","Jebarer","Jebarn","Jebartik","Jebeker",
|
// "ektik" isn't allowed either I guess?
|
||||||
"Jebekn","Jeber","Jebobn","Jebtik","Jekab","Jeker","Jekn","Jenann",
|
if (third == part3[3] && fourth == part4[3])
|
||||||
"Jenantik","Jenarer","Jeneker","Jenekn","Jentik","Jibaner","Jibann",
|
fourth = part4[zone->random.Int(0, (sizeof(part4) / sizeof(const char *)) - 2)];
|
||||||
"Jibantik","Jibarer","Jibarn","Jibartik","Jibeker","Jibn","Jibobn",
|
|
||||||
"Jibtik","Jobab","Jobaner","Jobann","Jobantik","Jobarn","Jobartik",
|
// "Laser" isn't allowed either I guess?
|
||||||
"Jobekab","Jobeker","Jober","Jobn","Jobtik","Jonanab","Jonaner",
|
if (first == part1[3] && second == part2[3] && third == nullptr && fourth == part4[0])
|
||||||
"Jonann","Jonantik","Jonarer","Jonarn","Jonartik","Jonekab","Joneker",
|
fourth = part4[zone->random.Int(1, (sizeof(part4) / sizeof(const char *)) - 2)];
|
||||||
"Jonekn","Joner","Jonn","Jonnarn","Jonober","Jonobn","Jonobtik","Jontik",
|
|
||||||
"Kabanab","Kabaner","Kabann","Kabantik","Kabarer","Kabarn","Kabartik",
|
temp += first;
|
||||||
"Kabeker","Kabekn","Kaber","Kabn","Kabober","Kabobn","Kabobtik","Kabtik",
|
if (second != nullptr)
|
||||||
"Kanab","Kaner","Kann","Kantik","Karab","Karanab","Karaner","Karann",
|
temp += second;
|
||||||
"Karantik","Kararer","Karartik","Kareker","Karer","Karn","Karobab","Karobn",
|
if (third != nullptr)
|
||||||
"Kartik","Kasaner","Kasann","Kasarer","Kasartik","Kaseker","Kasekn","Kaser",
|
temp += third;
|
||||||
"Kasn","Kasober","Kastik","Kebann","Kebantik","Kebarab","Kebartik","Kebeker",
|
temp += fourth;
|
||||||
"Kebekn","Kebn","Kebobab","Kebtik","Kekab","Keker","Kekn","Kenab","Kenaner",
|
|
||||||
"Kenantik","Kenarer","Kenarn","Keneker","Kener","Kenn","Kenobn","Kenobtik",
|
strn0cpy(name, temp.c_str(), 64);
|
||||||
"Kentik","Kibab","Kibaner","Kibantik","Kibarn","Kibartik","Kibekab","Kibeker",
|
|
||||||
"Kibekn","Kibn","Kibobn","Kibobtik","Kobab","Kobanab","Kobaner","Kobann",
|
|
||||||
"Kobantik","Kobarer","Kobarn","Kobartik","Kobeker","Kobekn","Kober","Kobn",
|
|
||||||
"Kobober","Kobobn","Kobtik","Konanab","Konaner","Konann","Konantik","Konarab",
|
|
||||||
"Konarer","Konarn","Konekab","Koneker","Konekn","Koner","Konn","Konobn",
|
|
||||||
"Konobtik","Kontik","Labanab","Labaner","Labann","Labarab","Labarer",
|
|
||||||
"Labarn","Labartik","Labeker","Labekn","Laner","Lann","Larab","Larantik",
|
|
||||||
"Lararer","Lararn","Larartik","Lareker","Larer","Larn","Lartik","Lasaner",
|
|
||||||
"Lasann","Lasarer","Laseker","Laser","Lasik","Lasn","Lastik","Lebaner",
|
|
||||||
"Lebarer","Lebartik","Lebekn","Lebtik","Lekab","Lekn","Lenanab","Lenaner",
|
|
||||||
"Lenann","Lenartik","Lenekab","Leneker","Lenekn","Lentik","Libab","Libaner",
|
|
||||||
"Libann","Libantik","Libarer","Libarn","Libartik","Libeker","Libekn","Lobann",
|
|
||||||
"Lobarab","Lobarn","Lobartik","Lobekn","Lobn","Lobober","Lobobn","Lobtik",
|
|
||||||
"Lonaner","Lonann","Lonantik","Lonarab","Lonarer","Lonarn","Lonartik","Lonekn",
|
|
||||||
"Loner","Lonobtik","Lontik","Vabanab","Vabaner","Vabann","Vabantik","Vabarer",
|
|
||||||
"Vabarn","Vabartik","Vabeker","Vabekn","Vabtik","Vanikk","Vann","Varartik","Varn",
|
|
||||||
"Vartik","Vasann","Vasantik","Vasarab","Vasarer","Vaseker","Vebaner","Vebantik",
|
|
||||||
"Vebarab","Vebeker","Vebekn","Vebobn","Vekab","Veker","Venaner","Venantik","Venar",
|
|
||||||
"Venarn","Vener","Ventik","Vibann","Vibantik","Viber","Vibobtik","Vobann",
|
|
||||||
"Vobarer","Vobartik","Vobekn","Vober","Vobn","Vobtik","Vonaner","Vonann",
|
|
||||||
"Vonantik","Vonarab","Vonarn","Vonartik","Voneker","Vonn","Xabanab","Xabaner",
|
|
||||||
"Xabarer","Xabarn","Xabartik","Xabekab","Xabeker","Xabekn","Xaber","Xabober",
|
|
||||||
"Xaner","Xann","Xarab","Xaranab","Xarann","Xarantik","Xararer","Xarartik","Xarer",
|
|
||||||
"Xarn","Xartik","Xasaner","Xasann","Xasarab","Xasarn","Xasekab","Xaseker",
|
|
||||||
"Xebarer","Xebarn","Xebeker","Xeber","Xebober","Xebtik","Xekab","Xeker",
|
|
||||||
"Xekn","Xenann","Xenantik","Xenarer","Xenartik","Xenekn","Xener","Xenober",
|
|
||||||
"Xentik","Xibantik","Xibarer","Xibekab","Xibeker","Xibobab","Xibober","Xibobn",
|
|
||||||
"Xobaner","Xobann","Xobarab","Xobarn","Xobekab","Xobeker","Xobekn","Xober",
|
|
||||||
"Xobn","Xobobn","Xobtik","Xonaner","Xonann","Xonantik","Xonarer","Xonartik",
|
|
||||||
"Xonekab","Xoneker","Xonekn","Xoner","Xonober","Xtik","Zabaner","Zabantik",
|
|
||||||
"Zabarab","Zabekab","Zabekn","Zaber","Zabn","Zabobab","Zabober","Zabtik",
|
|
||||||
"Zaner","Zantik","Zarann","Zarantik","Zararn","Zarartik","Zareker","Zarekn",
|
|
||||||
"Zarer","Zarn","Zarober","Zartik","Zasaner","Zasarer","Zaseker","Zasekn","Zasn",
|
|
||||||
"Zebantik","Zebarer","Zebarn","Zebartik","Zebobab","Zekab","Zekn","Zenann",
|
|
||||||
"Zenantik","Zenarer","Zenarn","Zenekab","Zeneker","Zenobtik","Zibanab","Zibaner",
|
|
||||||
"Zibann","Zibarer","Zibartik","Zibekn","Zibn","Zibobn","Zobaner","Zobann",
|
|
||||||
"Zobarn","Zober","Zobn","Zonanab","Zonaner","Zonann","Zonantik","Zonarer",
|
|
||||||
"Zonartik","Zonobn","Zonobtik","Zontik","Ztik" };
|
|
||||||
int r = zone->random.Int(0, (sizeof(petnames)/sizeof(const char *))-1);
|
|
||||||
printf("Pet being created: %s\n",petnames[r]); // DO NOT COMMENT THIS OUT!
|
|
||||||
return petnames[r];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//not used anymore
|
//not used anymore
|
||||||
@ -325,7 +287,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
|||||||
} else if (record.petnaming == 4) {
|
} else if (record.petnaming == 4) {
|
||||||
// Keep the DB name
|
// Keep the DB name
|
||||||
} else if (record.petnaming == 3 && IsClient()) {
|
} else if (record.petnaming == 3 && IsClient()) {
|
||||||
strcpy(npc_type->name, GetRandPetName());
|
GetRandPetName(npc_type->name);
|
||||||
} else if (record.petnaming == 5 && IsClient()) {
|
} else if (record.petnaming == 5 && IsClient()) {
|
||||||
strcpy(npc_type->name, this->GetName());
|
strcpy(npc_type->name, this->GetName());
|
||||||
npc_type->name[24] = '\0';
|
npc_type->name[24] = '\0';
|
||||||
|
|||||||
@ -1319,9 +1319,7 @@ void QuestManager::itemlink(int item_id) {
|
|||||||
linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
|
linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
|
||||||
linker.SetItemData(item);
|
linker.SetItemData(item);
|
||||||
|
|
||||||
auto item_link = linker.GenerateLink();
|
initiator->Message(0, "%s tells you, %s", owner->GetCleanName(), linker.GenerateLink().c_str());
|
||||||
|
|
||||||
initiator->Message(0, "%s tells you, %s", owner->GetCleanName(), item_link.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1989,8 +1987,8 @@ void QuestManager::npcfeature(char *feature, int setting)
|
|||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
uint16 Race = owner->GetRace();
|
uint16 Race = owner->GetRace();
|
||||||
uint8 Gender = owner->GetGender();
|
uint8 Gender = owner->GetGender();
|
||||||
uint8 Texture = 0xFF;
|
uint8 Texture = owner->GetTexture();
|
||||||
uint8 HelmTexture = 0xFF;
|
uint8 HelmTexture = owner->GetHelmTexture();
|
||||||
uint8 HairColor = owner->GetHairColor();
|
uint8 HairColor = owner->GetHairColor();
|
||||||
uint8 BeardColor = owner->GetBeardColor();
|
uint8 BeardColor = owner->GetBeardColor();
|
||||||
uint8 EyeColor1 = owner->GetEyeColor1();
|
uint8 EyeColor1 = owner->GetEyeColor1();
|
||||||
@ -2549,9 +2547,8 @@ const char* QuestManager::varlink(char* perltext, int item_id) {
|
|||||||
linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
|
linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
|
||||||
linker.SetItemData(item);
|
linker.SetItemData(item);
|
||||||
|
|
||||||
auto item_link = linker.GenerateLink();
|
strcpy(perltext, linker.GenerateLink().c_str());
|
||||||
strcpy(perltext, item_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink()
|
|
||||||
|
|
||||||
return perltext;
|
return perltext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2773,8 +2770,7 @@ const char* QuestManager::saylink(char* Phrase, bool silent, const char* LinkNam
|
|||||||
linker.SetProxyAugment1ID(sayid);
|
linker.SetProxyAugment1ID(sayid);
|
||||||
linker.SetProxyText(LinkName);
|
linker.SetProxyText(LinkName);
|
||||||
|
|
||||||
auto say_link = linker.GenerateLink();
|
strcpy(Phrase, linker.GenerateLink().c_str());
|
||||||
strcpy(Phrase, say_link.c_str()); // link length is currently ranged from 1 to 250 in TextLink::GenerateLink()
|
|
||||||
|
|
||||||
return Phrase;
|
return Phrase;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1443,7 +1443,7 @@ void Mob::SendItemAnimation(Mob *to, const EQEmu::ItemData *item, EQEmu::skills:
|
|||||||
|
|
||||||
//these angle and tilt used together seem to make the arrow/knife throw as straight as I can make it
|
//these angle and tilt used together seem to make the arrow/knife throw as straight as I can make it
|
||||||
|
|
||||||
as->launch_angle = CalculateHeadingToTarget(to->GetX(), to->GetY()) * 2;
|
as->launch_angle = CalculateHeadingToTarget(to->GetX(), to->GetY());
|
||||||
as->tilt = 125;
|
as->tilt = 125;
|
||||||
as->arc = 50;
|
as->arc = 50;
|
||||||
|
|
||||||
|
|||||||
@ -915,16 +915,16 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
action->source = caster ? caster->GetID() : GetID();
|
action->source = caster ? caster->GetID() : GetID();
|
||||||
action->level = 65;
|
action->level = 65;
|
||||||
action->instrument_mod = 10;
|
action->instrument_mod = 10;
|
||||||
action->sequence = static_cast<uint32>((GetHeading() * 12345 / 2));
|
action->hit_heading = GetHeading();
|
||||||
action->type = 231;
|
action->type = 231;
|
||||||
action->spell = spell_id;
|
action->spell = spell_id;
|
||||||
action->buff_unknown = 4;
|
action->effect_flag = 4;
|
||||||
|
|
||||||
cd->target = action->target;
|
cd->target = action->target;
|
||||||
cd->source = action->source;
|
cd->source = action->source;
|
||||||
cd->type = action->type;
|
cd->type = action->type;
|
||||||
cd->spellid = action->spell;
|
cd->spellid = action->spell;
|
||||||
cd->meleepush_xy = action->sequence;
|
cd->hit_heading = action->hit_heading;
|
||||||
|
|
||||||
CastToClient()->QueuePacket(action_packet);
|
CastToClient()->QueuePacket(action_packet);
|
||||||
if(caster && caster->IsClient() && caster != this)
|
if(caster && caster->IsClient() && caster != this)
|
||||||
@ -967,16 +967,16 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
action->source = caster ? caster->GetID() : GetID();
|
action->source = caster ? caster->GetID() : GetID();
|
||||||
action->level = 65;
|
action->level = 65;
|
||||||
action->instrument_mod = 10;
|
action->instrument_mod = 10;
|
||||||
action->sequence = static_cast<uint32>((GetHeading() * 12345 / 2));
|
action->hit_heading = GetHeading();
|
||||||
action->type = 231;
|
action->type = 231;
|
||||||
action->spell = spell_id;
|
action->spell = spell_id;
|
||||||
action->buff_unknown = 4;
|
action->effect_flag = 4;
|
||||||
|
|
||||||
cd->target = action->target;
|
cd->target = action->target;
|
||||||
cd->source = action->source;
|
cd->source = action->source;
|
||||||
cd->type = action->type;
|
cd->type = action->type;
|
||||||
cd->spellid = action->spell;
|
cd->spellid = action->spell;
|
||||||
cd->meleepush_xy = action->sequence;
|
cd->hit_heading = action->hit_heading;
|
||||||
|
|
||||||
CastToClient()->QueuePacket(action_packet);
|
CastToClient()->QueuePacket(action_packet);
|
||||||
if(caster->IsClient() && caster != this)
|
if(caster->IsClient() && caster != this)
|
||||||
@ -1006,16 +1006,16 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
action->source = caster ? caster->GetID() : GetID();
|
action->source = caster ? caster->GetID() : GetID();
|
||||||
action->level = 65;
|
action->level = 65;
|
||||||
action->instrument_mod = 10;
|
action->instrument_mod = 10;
|
||||||
action->sequence = static_cast<uint32>((GetHeading() * 12345 / 2));
|
action->hit_heading = GetHeading();
|
||||||
action->type = 231;
|
action->type = 231;
|
||||||
action->spell = spell_id;
|
action->spell = spell_id;
|
||||||
action->buff_unknown = 4;
|
action->effect_flag = 4;
|
||||||
|
|
||||||
cd->target = action->target;
|
cd->target = action->target;
|
||||||
cd->source = action->source;
|
cd->source = action->source;
|
||||||
cd->type = action->type;
|
cd->type = action->type;
|
||||||
cd->spellid = action->spell;
|
cd->spellid = action->spell;
|
||||||
cd->meleepush_xy = action->sequence;
|
cd->hit_heading = action->hit_heading;
|
||||||
|
|
||||||
CastToClient()->QueuePacket(action_packet);
|
CastToClient()->QueuePacket(action_packet);
|
||||||
if(caster->IsClient() && caster != this)
|
if(caster->IsClient() && caster != this)
|
||||||
@ -2080,61 +2080,9 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
|||||||
#ifdef SPELL_EFFECT_SPAM
|
#ifdef SPELL_EFFECT_SPAM
|
||||||
snprintf(effect_desc, _EDLEN, "Toss Up: %d", effect_value);
|
snprintf(effect_desc, _EDLEN, "Toss Up: %d", effect_value);
|
||||||
#endif
|
#endif
|
||||||
double toss_amt = (double)spells[spell_id].base[i];
|
if (IsNPC()) {
|
||||||
if(toss_amt < 0)
|
Damage(caster, std::abs(effect_value), spell_id, spell.skill, false, buffslot, false);
|
||||||
toss_amt = -toss_amt;
|
|
||||||
|
|
||||||
if(IsNPC())
|
|
||||||
{
|
|
||||||
Stun(static_cast<int>(toss_amt));
|
|
||||||
}
|
}
|
||||||
toss_amt = sqrt(toss_amt)-2.0;
|
|
||||||
|
|
||||||
if(toss_amt < 0.0)
|
|
||||||
toss_amt = 0.0;
|
|
||||||
|
|
||||||
if(toss_amt > 20.0)
|
|
||||||
toss_amt = 20.0;
|
|
||||||
|
|
||||||
if(IsClient())
|
|
||||||
{
|
|
||||||
CastToClient()->SetKnockBackExemption(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
double look_heading = GetHeading();
|
|
||||||
look_heading /= 256;
|
|
||||||
look_heading *= 360;
|
|
||||||
look_heading += 180;
|
|
||||||
if(look_heading > 360)
|
|
||||||
look_heading -= 360;
|
|
||||||
|
|
||||||
//x and y are crossed mkay
|
|
||||||
double new_x = spells[spell_id].pushback * sin(double(look_heading * 3.141592 / 180.0));
|
|
||||||
double new_y = spells[spell_id].pushback * cos(double(look_heading * 3.141592 / 180.0));
|
|
||||||
|
|
||||||
auto outapp_push =
|
|
||||||
new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
|
||||||
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp_push->pBuffer;
|
|
||||||
|
|
||||||
spu->spawn_id = GetID();
|
|
||||||
spu->x_pos = FloatToEQ19(GetX());
|
|
||||||
spu->y_pos = FloatToEQ19(GetY());
|
|
||||||
spu->z_pos = FloatToEQ19(GetZ());
|
|
||||||
spu->delta_x = FloatToEQ13(new_x);
|
|
||||||
spu->delta_y = FloatToEQ13(new_y);
|
|
||||||
spu->delta_z = FloatToEQ13(toss_amt);
|
|
||||||
spu->heading = FloatToEQ12(GetHeading());
|
|
||||||
spu->padding0002 =0;
|
|
||||||
spu->padding0006 =7;
|
|
||||||
spu->padding0014 =0x7f;
|
|
||||||
spu->padding0018 =0x5df27;
|
|
||||||
spu->animation = 0;
|
|
||||||
spu->delta_heading = FloatToEQ10(0);
|
|
||||||
outapp_push->priority = 5;
|
|
||||||
entity_list.QueueClients(this, outapp_push, true);
|
|
||||||
if(IsClient())
|
|
||||||
CastToClient()->FastQueuePacket(&outapp_push);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
122
zone/spells.cpp
122
zone/spells.cpp
@ -82,6 +82,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
|||||||
#include "string_ids.h"
|
#include "string_ids.h"
|
||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
#include "nats_manager.h"
|
#include "nats_manager.h"
|
||||||
|
#include "fastmath.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -106,6 +107,7 @@ extern Zone* zone;
|
|||||||
extern volatile bool is_zone_loaded;
|
extern volatile bool is_zone_loaded;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
extern NatsManager nats;
|
extern NatsManager nats;
|
||||||
|
extern FastMath g_Math;
|
||||||
|
|
||||||
using EQEmu::CastingSlot;
|
using EQEmu::CastingSlot;
|
||||||
|
|
||||||
@ -1213,7 +1215,10 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo
|
|||||||
|
|
||||||
// handle the components for traditional casters
|
// handle the components for traditional casters
|
||||||
else {
|
else {
|
||||||
if(c->GetInv().HasItem(component, component_count, invWhereWorn|invWherePersonal) == -1) // item not found
|
if (!RuleB(Character, PetsUseReagents) && IsEffectInSpell(spell_id, SE_SummonPet)) {
|
||||||
|
//bypass reagent cost
|
||||||
|
}
|
||||||
|
else if(c->GetInv().HasItem(component, component_count, invWhereWorn|invWherePersonal) == -1) // item not found
|
||||||
{
|
{
|
||||||
if (!missingreags)
|
if (!missingreags)
|
||||||
{
|
{
|
||||||
@ -1243,6 +1248,9 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!RuleB(Character, PetsUseReagents) && IsEffectInSpell(spell_id, SE_SummonPet)) {
|
||||||
|
//bypass reagent cost
|
||||||
|
}
|
||||||
else if (!bard_song_mode)
|
else if (!bard_song_mode)
|
||||||
{
|
{
|
||||||
int noexpend;
|
int noexpend;
|
||||||
@ -2651,20 +2659,18 @@ void Mob::BardPulse(uint16 spell_id, Mob *caster) {
|
|||||||
action->source = caster->GetID();
|
action->source = caster->GetID();
|
||||||
action->target = GetID();
|
action->target = GetID();
|
||||||
action->spell = spell_id;
|
action->spell = spell_id;
|
||||||
action->sequence = (uint32) (GetHeading()); // just some random number
|
action->force = spells[spell_id].pushback;
|
||||||
|
action->hit_heading = GetHeading();
|
||||||
|
action->hit_pitch = spells[spell_id].pushup;
|
||||||
action->instrument_mod = caster->GetInstrumentMod(spell_id);
|
action->instrument_mod = caster->GetInstrumentMod(spell_id);
|
||||||
action->buff_unknown = 0;
|
action->effect_flag = 0;
|
||||||
action->level = buffs[buffs_i].casterlevel;
|
action->spell_level = action->level = buffs[buffs_i].casterlevel;
|
||||||
action->type = DamageTypeSpell;
|
action->type = DamageTypeSpell;
|
||||||
entity_list.QueueCloseClients(this, packet, false, RuleI(Range, SongMessages), 0, true, IsClient() ? FilterPCSpells : FilterNPCSpells);
|
entity_list.QueueCloseClients(this, packet, false, RuleI(Range, SongMessages), 0, true, IsClient() ? FilterPCSpells : FilterNPCSpells);
|
||||||
|
|
||||||
action->buff_unknown = 4;
|
action->effect_flag = 4;
|
||||||
|
|
||||||
if(IsEffectInSpell(spell_id, SE_TossUp))
|
if(spells[spell_id].pushback != 0.0f || spells[spell_id].pushup != 0.0f)
|
||||||
{
|
|
||||||
action->buff_unknown = 0;
|
|
||||||
}
|
|
||||||
else if(spells[spell_id].pushback > 0 || spells[spell_id].pushup > 0)
|
|
||||||
{
|
{
|
||||||
if(IsClient())
|
if(IsClient())
|
||||||
{
|
{
|
||||||
@ -2672,38 +2678,6 @@ void Mob::BardPulse(uint16 spell_id, Mob *caster) {
|
|||||||
{
|
{
|
||||||
CastToClient()->SetKnockBackExemption(true);
|
CastToClient()->SetKnockBackExemption(true);
|
||||||
|
|
||||||
action->buff_unknown = 0;
|
|
||||||
auto outapp_push = new EQApplicationPacket(
|
|
||||||
OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
|
||||||
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp_push->pBuffer;
|
|
||||||
|
|
||||||
double look_heading = caster->CalculateHeadingToTarget(GetX(), GetY());
|
|
||||||
look_heading /= 256;
|
|
||||||
look_heading *= 360;
|
|
||||||
if(look_heading > 360)
|
|
||||||
look_heading -= 360;
|
|
||||||
|
|
||||||
//x and y are crossed mkay
|
|
||||||
double new_x = spells[spell_id].pushback * sin(double(look_heading * 3.141592 / 180.0));
|
|
||||||
double new_y = spells[spell_id].pushback * cos(double(look_heading * 3.141592 / 180.0));
|
|
||||||
|
|
||||||
spu->spawn_id = GetID();
|
|
||||||
spu->x_pos = FloatToEQ19(GetX());
|
|
||||||
spu->y_pos = FloatToEQ19(GetY());
|
|
||||||
spu->z_pos = FloatToEQ19(GetZ());
|
|
||||||
spu->delta_x = FloatToEQ13(new_x);
|
|
||||||
spu->delta_y = FloatToEQ13(new_y);
|
|
||||||
spu->delta_z = FloatToEQ13(spells[spell_id].pushup);
|
|
||||||
spu->heading = FloatToEQ12(GetHeading());
|
|
||||||
spu->padding0002 =0;
|
|
||||||
spu->padding0006 =7;
|
|
||||||
spu->padding0014 =0x7f;
|
|
||||||
spu->padding0018 =0x5df27;
|
|
||||||
spu->animation = 0;
|
|
||||||
spu->delta_heading = FloatToEQ10(0);
|
|
||||||
outapp_push->priority = 6;
|
|
||||||
entity_list.QueueClients(this, outapp_push, true);
|
|
||||||
CastToClient()->FastQueuePacket(&outapp_push);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2724,7 +2698,9 @@ void Mob::BardPulse(uint16 spell_id, Mob *caster) {
|
|||||||
cd->source = action->source;
|
cd->source = action->source;
|
||||||
cd->type = DamageTypeSpell;
|
cd->type = DamageTypeSpell;
|
||||||
cd->spellid = action->spell;
|
cd->spellid = action->spell;
|
||||||
cd->meleepush_xy = action->sequence;
|
cd->force = action->force;
|
||||||
|
cd->hit_heading = action->hit_heading;
|
||||||
|
cd->hit_pitch = action->hit_pitch;
|
||||||
cd->damage = 0;
|
cd->damage = 0;
|
||||||
if(!IsEffectInSpell(spell_id, SE_BindAffinity))
|
if(!IsEffectInSpell(spell_id, SE_BindAffinity))
|
||||||
{
|
{
|
||||||
@ -3532,12 +3508,14 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
|||||||
action->target = spelltar->GetID();
|
action->target = spelltar->GetID();
|
||||||
}
|
}
|
||||||
|
|
||||||
action->level = caster_level; // caster level, for animation only
|
action->spell_level = action->level = caster_level; // caster level, for animation only
|
||||||
action->type = 231; // 231 means a spell
|
action->type = 231; // 231 means a spell
|
||||||
action->spell = spell_id;
|
action->spell = spell_id;
|
||||||
action->sequence = (uint32) (GetHeading()); // just some random number
|
action->force = spells[spell_id].pushback;
|
||||||
|
action->hit_heading = GetHeading();
|
||||||
|
action->hit_pitch = spells[spell_id].pushup;
|
||||||
action->instrument_mod = GetInstrumentMod(spell_id);
|
action->instrument_mod = GetInstrumentMod(spell_id);
|
||||||
action->buff_unknown = 0;
|
action->effect_flag = 0;
|
||||||
|
|
||||||
if(spelltar != this && spelltar->IsClient()) // send to target
|
if(spelltar != this && spelltar->IsClient()) // send to target
|
||||||
spelltar->CastToClient()->QueuePacket(action_packet);
|
spelltar->CastToClient()->QueuePacket(action_packet);
|
||||||
@ -3964,53 +3942,21 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
|||||||
// NOTE: this is what causes the buff icon to appear on the client, if
|
// NOTE: this is what causes the buff icon to appear on the client, if
|
||||||
// this is a buff - but it sortof relies on the first packet.
|
// this is a buff - but it sortof relies on the first packet.
|
||||||
// the complete sequence is 2 actions and 1 damage message
|
// the complete sequence is 2 actions and 1 damage message
|
||||||
action->buff_unknown = 0x04; // this is a success flag
|
action->effect_flag = 0x04; // this is a success flag
|
||||||
|
|
||||||
if(IsEffectInSpell(spell_id, SE_TossUp))
|
if(spells[spell_id].pushback != 0.0f || spells[spell_id].pushup != 0.0f)
|
||||||
{
|
|
||||||
action->buff_unknown = 0;
|
|
||||||
}
|
|
||||||
else if(spells[spell_id].pushback > 0 || spells[spell_id].pushup > 0)
|
|
||||||
{
|
{
|
||||||
if(spelltar->IsClient())
|
if(spelltar->IsClient())
|
||||||
{
|
{
|
||||||
if(!IsBuffSpell(spell_id))
|
if(!IsBuffSpell(spell_id))
|
||||||
{
|
{
|
||||||
spelltar->CastToClient()->SetKnockBackExemption(true);
|
spelltar->CastToClient()->SetKnockBackExemption(true);
|
||||||
|
|
||||||
action->buff_unknown = 0;
|
|
||||||
auto outapp_push =
|
|
||||||
new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
|
||||||
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp_push->pBuffer;
|
|
||||||
|
|
||||||
double look_heading = CalculateHeadingToTarget(spelltar->GetX(), spelltar->GetY());
|
|
||||||
look_heading /= 256;
|
|
||||||
look_heading *= 360;
|
|
||||||
if(look_heading > 360)
|
|
||||||
look_heading -= 360;
|
|
||||||
|
|
||||||
//x and y are crossed mkay
|
|
||||||
double new_x = spells[spell_id].pushback * sin(double(look_heading * 3.141592 / 180.0));
|
|
||||||
double new_y = spells[spell_id].pushback * cos(double(look_heading * 3.141592 / 180.0));
|
|
||||||
|
|
||||||
spu->spawn_id = spelltar->GetID();
|
|
||||||
spu->x_pos = FloatToEQ19(spelltar->GetX());
|
|
||||||
spu->y_pos = FloatToEQ19(spelltar->GetY());
|
|
||||||
spu->z_pos = FloatToEQ19(spelltar->GetZ());
|
|
||||||
spu->delta_x = FloatToEQ13(new_x);
|
|
||||||
spu->delta_y = FloatToEQ13(new_y);
|
|
||||||
spu->delta_z = FloatToEQ13(spells[spell_id].pushup);
|
|
||||||
spu->heading = FloatToEQ12(spelltar->GetHeading());
|
|
||||||
spu->padding0002 =0;
|
|
||||||
spu->padding0006 =7;
|
|
||||||
spu->padding0014 =0x7f;
|
|
||||||
spu->padding0018 =0x5df27;
|
|
||||||
spu->animation = 0;
|
|
||||||
spu->delta_heading = FloatToEQ10(0);
|
|
||||||
outapp_push->priority = 6;
|
|
||||||
entity_list.QueueClients(this, outapp_push, true);
|
|
||||||
spelltar->CastToClient()->FastQueuePacket(&outapp_push);
|
|
||||||
}
|
}
|
||||||
|
} else if (RuleB(Spells, NPCSpellPush) && !spelltar->IsRooted() && spelltar->ForcedMovement == 0) {
|
||||||
|
spelltar->m_Delta.x += action->force * g_Math.FastSin(action->hit_heading);
|
||||||
|
spelltar->m_Delta.y += action->force * g_Math.FastCos(action->hit_heading);
|
||||||
|
spelltar->m_Delta.z += action->hit_pitch;
|
||||||
|
spelltar->ForcedMovement = 6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4038,7 +3984,9 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r
|
|||||||
cd->source = action->source;
|
cd->source = action->source;
|
||||||
cd->type = action->type;
|
cd->type = action->type;
|
||||||
cd->spellid = action->spell;
|
cd->spellid = action->spell;
|
||||||
cd->meleepush_xy = action->sequence;
|
cd->force = action->force;
|
||||||
|
cd->hit_heading = action->hit_heading;
|
||||||
|
cd->hit_pitch = action->hit_pitch;
|
||||||
cd->damage = 0;
|
cd->damage = 0;
|
||||||
if(!IsEffectInSpell(spell_id, SE_BindAffinity)){
|
if(!IsEffectInSpell(spell_id, SE_BindAffinity)){
|
||||||
entity_list.QueueCloseClients(
|
entity_list.QueueCloseClients(
|
||||||
@ -5722,7 +5670,7 @@ void Client::SendSpellAnim(uint16 targetid, uint16 spell_id)
|
|||||||
a->source = this->GetID();
|
a->source = this->GetID();
|
||||||
a->type = 231;
|
a->type = 231;
|
||||||
a->spell = spell_id;
|
a->spell = spell_id;
|
||||||
a->sequence = 231;
|
a->hit_heading = GetHeading();
|
||||||
|
|
||||||
app.priority = 1;
|
app.priority = 1;
|
||||||
entity_list.QueueCloseClients(this, &app, false, RuleI(Range, SpellParticles));
|
entity_list.QueueCloseClients(this, &app, false, RuleI(Range, SpellParticles));
|
||||||
|
|||||||
@ -120,6 +120,7 @@
|
|||||||
#define FAIL_DISARM_DETECTED_TRAP 370 //You fail to disarm the detected trap.
|
#define FAIL_DISARM_DETECTED_TRAP 370 //You fail to disarm the detected trap.
|
||||||
#define LOOT_LORE_ERROR 371 //You cannot loot this Lore Item. You already have one.
|
#define LOOT_LORE_ERROR 371 //You cannot loot this Lore Item. You already have one.
|
||||||
#define PICK_LORE 379 //You cannot pick up a lore item you already possess.
|
#define PICK_LORE 379 //You cannot pick up a lore item you already possess.
|
||||||
|
#define POISON_TOO_HIGH 382 // This poison is too high level for you to apply.
|
||||||
#define CONSENT_DENIED 390 //You do not have consent to summon that corpse.
|
#define CONSENT_DENIED 390 //You do not have consent to summon that corpse.
|
||||||
#define DISCIPLINE_RDY 393 //You are ready to use a new discipline now.
|
#define DISCIPLINE_RDY 393 //You are ready to use a new discipline now.
|
||||||
#define CONSENT_INVALID_NAME 397 //Not a valid consent name.
|
#define CONSENT_INVALID_NAME 397 //Not a valid consent name.
|
||||||
|
|||||||
@ -2804,8 +2804,7 @@ void TaskManager::SendActiveTaskDescription(Client *c, int TaskID, int SequenceN
|
|||||||
if (strlen(Tasks[TaskID]->Reward) != 0)
|
if (strlen(Tasks[TaskID]->Reward) != 0)
|
||||||
linker.SetProxyText(Tasks[TaskID]->Reward);
|
linker.SetProxyText(Tasks[TaskID]->Reward);
|
||||||
|
|
||||||
auto reward_link = linker.GenerateLink();
|
reward_text.append(linker.GenerateLink());
|
||||||
reward_text.append(reward_link);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
reward_text.append(Tasks[TaskID]->Reward);
|
reward_text.append(Tasks[TaskID]->Reward);
|
||||||
|
|||||||
@ -218,7 +218,7 @@ void Trap::Trigger(Mob* trigger)
|
|||||||
int dmg = zone->random.Int(effectvalue, effectvalue2);
|
int dmg = zone->random.Int(effectvalue, effectvalue2);
|
||||||
trigger->SetHP(trigger->GetHP() - dmg);
|
trigger->SetHP(trigger->GetHP() - dmg);
|
||||||
a->damage = dmg;
|
a->damage = dmg;
|
||||||
a->meleepush_xy = zone->random.Int(0, 1234567);
|
a->hit_heading = 0.0f;
|
||||||
a->source = GetHiddenTrigger()!=nullptr ? GetHiddenTrigger()->GetID() : trigger->GetID();
|
a->source = GetHiddenTrigger()!=nullptr ? GetHiddenTrigger()->GetID() : trigger->GetID();
|
||||||
a->spellid = 0;
|
a->spellid = 0;
|
||||||
a->target = trigger->GetID();
|
a->target = trigger->GetID();
|
||||||
|
|||||||
@ -29,10 +29,13 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include "npc.h"
|
#include "npc.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
#include "water_map.h"
|
#include "water_map.h"
|
||||||
|
#include "fastmath.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern FastMath g_Math;
|
||||||
|
|
||||||
struct wp_distance
|
struct wp_distance
|
||||||
{
|
{
|
||||||
float dist;
|
float dist;
|
||||||
@ -990,6 +993,35 @@ float Mob::GetZOffset() const {
|
|||||||
return 0.2 * GetSize() * offset;
|
return 0.2 * GetSize() * offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function will try to move the mob along the relative angle a set distance
|
||||||
|
// if it can't be moved, it will lower the distance and try again
|
||||||
|
// If we want to move on like say a spawn, we can pass send as false
|
||||||
|
void Mob::TryMoveAlong(float distance, float angle, bool send)
|
||||||
|
{
|
||||||
|
angle += GetHeading();
|
||||||
|
angle = FixHeading(angle);
|
||||||
|
|
||||||
|
glm::vec3 tmp_pos;
|
||||||
|
glm::vec3 new_pos = GetPosition();
|
||||||
|
new_pos.x += distance * g_Math.FastSin(angle);
|
||||||
|
new_pos.y += distance * g_Math.FastCos(angle);
|
||||||
|
new_pos.z += GetZOffset();
|
||||||
|
|
||||||
|
if (zone->HasMap()) {
|
||||||
|
auto new_z = zone->zonemap->FindClosestZ(new_pos, nullptr);
|
||||||
|
if (new_z != BEST_Z_INVALID)
|
||||||
|
new_pos.z = new_z;
|
||||||
|
|
||||||
|
if (zone->zonemap->LineIntersectsZone(GetPosition(), new_pos, 0.0f, &tmp_pos))
|
||||||
|
new_pos = tmp_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_pos.z = GetFixedZ(new_pos);
|
||||||
|
Teleport(new_pos);
|
||||||
|
if (send)
|
||||||
|
SendPositionUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
int ZoneDatabase::GetHighestGrid(uint32 zoneid) {
|
int ZoneDatabase::GetHighestGrid(uint32 zoneid) {
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT COALESCE(MAX(id), 0) FROM grid WHERE zoneid = %i", zoneid);
|
std::string query = StringFormat("SELECT COALESCE(MAX(id), 0) FROM grid WHERE zoneid = %i", zoneid);
|
||||||
|
|||||||
@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
@ -1813,6 +1814,13 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_UCSServerStatusReply:
|
||||||
|
{
|
||||||
|
auto ucsss = (UCSServerStatus_Struct*)pack->pBuffer;
|
||||||
|
if (zone)
|
||||||
|
zone->SetUCSServerAvailable((ucsss->available != 0), ucsss->timestamp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ServerOP_CZSetEntityVariableByNPCTypeID:
|
case ServerOP_CZSetEntityVariableByNPCTypeID:
|
||||||
{
|
{
|
||||||
CZSetEntVarByNPCTypeID_Struct* CZM = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer;
|
CZSetEntVarByNPCTypeID_Struct* CZM = (CZSetEntVarByNPCTypeID_Struct*)pack->pBuffer;
|
||||||
|
|||||||
@ -146,6 +146,8 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
|
|||||||
UpdateWindowTitle();
|
UpdateWindowTitle();
|
||||||
zone->GetTimeSync();
|
zone->GetTimeSync();
|
||||||
|
|
||||||
|
zone->RequestUCSServerStatus();
|
||||||
|
|
||||||
/* Set Logging */
|
/* Set Logging */
|
||||||
|
|
||||||
LogSys.StartFileLogs(StringFormat("%s_version_%u_inst_id_%u_port_%u", zone->GetShortName(), zone->GetInstanceVersion(), zone->GetInstanceID(), ZoneConfig::get()->ZonePort));
|
LogSys.StartFileLogs(StringFormat("%s_version_%u_inst_id_%u_port_%u", zone->GetShortName(), zone->GetInstanceVersion(), zone->GetInstanceID(), ZoneConfig::get()->ZonePort));
|
||||||
@ -847,6 +849,9 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name)
|
|||||||
GuildBanks = new GuildBankManager;
|
GuildBanks = new GuildBankManager;
|
||||||
else
|
else
|
||||||
GuildBanks = nullptr;
|
GuildBanks = nullptr;
|
||||||
|
|
||||||
|
m_ucss_available = false;
|
||||||
|
m_last_ucss_update = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zone::~Zone() {
|
Zone::~Zone() {
|
||||||
@ -1863,14 +1868,17 @@ bool ZoneDatabase::GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Zone::weatherSend()
|
void Zone::weatherSend(Client* client)
|
||||||
{
|
{
|
||||||
auto outapp = new EQApplicationPacket(OP_Weather, 8);
|
auto outapp = new EQApplicationPacket(OP_Weather, 8);
|
||||||
if(zone_weather>0)
|
if(zone_weather>0)
|
||||||
outapp->pBuffer[0] = zone_weather-1;
|
outapp->pBuffer[0] = zone_weather-1;
|
||||||
if(zone_weather>0)
|
if(zone_weather>0)
|
||||||
outapp->pBuffer[4] = zone->weather_intensity;
|
outapp->pBuffer[4] = zone->weather_intensity;
|
||||||
entity_list.QueueClients(0, outapp);
|
if (client)
|
||||||
|
client->QueuePacket(outapp);
|
||||||
|
else
|
||||||
|
entity_list.QueueClients(0, outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2336,3 +2344,22 @@ void Zone::UpdateHotzone()
|
|||||||
is_hotzone = atoi(row[0]) == 0 ? false: true;
|
is_hotzone = atoi(row[0]) == 0 ? false: true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Zone::RequestUCSServerStatus() {
|
||||||
|
auto outapp = new ServerPacket(ServerOP_UCSServerStatusRequest, sizeof(UCSServerStatus_Struct));
|
||||||
|
auto ucsss = (UCSServerStatus_Struct*)outapp->pBuffer;
|
||||||
|
ucsss->available = 0;
|
||||||
|
ucsss->port = Config->ZonePort;
|
||||||
|
ucsss->unused = 0;
|
||||||
|
worldserver.SendPacket(outapp);
|
||||||
|
safe_delete(outapp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Zone::SetUCSServerAvailable(bool ucss_available, uint32 update_timestamp) {
|
||||||
|
if (m_last_ucss_update == update_timestamp && m_ucss_available != ucss_available) {
|
||||||
|
m_ucss_available = false;
|
||||||
|
RequestUCSServerStatus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_last_ucss_update < update_timestamp)
|
||||||
|
m_ucss_available = ucss_available;
|
||||||
|
}
|
||||||
|
|||||||
@ -224,7 +224,7 @@ public:
|
|||||||
void SetDate(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute);
|
void SetDate(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute);
|
||||||
void SetTime(uint8 hour, uint8 minute, bool update_world = true);
|
void SetTime(uint8 hour, uint8 minute, bool update_world = true);
|
||||||
|
|
||||||
void weatherSend();
|
void weatherSend(Client* client = nullptr);
|
||||||
bool CanBind() const { return(can_bind); }
|
bool CanBind() const { return(can_bind); }
|
||||||
bool IsCity() const { return(is_city); }
|
bool IsCity() const { return(is_city); }
|
||||||
bool CanDoCombat() const { return(can_combat); }
|
bool CanDoCombat() const { return(can_combat); }
|
||||||
@ -275,6 +275,10 @@ public:
|
|||||||
inline void ShowZoneGlobalLoot(Client *to) { m_global_loot.ShowZoneGlobalLoot(to); }
|
inline void ShowZoneGlobalLoot(Client *to) { m_global_loot.ShowZoneGlobalLoot(to); }
|
||||||
inline void ShowNPCGlobalLoot(Client *to, NPC *who) { m_global_loot.ShowNPCGlobalLoot(to, who); }
|
inline void ShowNPCGlobalLoot(Client *to, NPC *who) { m_global_loot.ShowNPCGlobalLoot(to, who); }
|
||||||
|
|
||||||
|
void RequestUCSServerStatus();
|
||||||
|
void SetUCSServerAvailable(bool ucss_available, uint32 update_timestamp);
|
||||||
|
bool IsUCSServerAvailable() { return m_ucss_available; }
|
||||||
|
|
||||||
// random object that provides random values for the zone
|
// random object that provides random values for the zone
|
||||||
EQEmu::Random random;
|
EQEmu::Random random;
|
||||||
|
|
||||||
@ -355,6 +359,9 @@ private:
|
|||||||
Timer hotzone_timer;
|
Timer hotzone_timer;
|
||||||
|
|
||||||
GlobalLootManager m_global_loot;
|
GlobalLootManager m_global_loot;
|
||||||
|
|
||||||
|
bool m_ucss_available;
|
||||||
|
uint32 m_last_ucss_update;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
291
zone/zonedb.cpp
291
zone/zonedb.cpp
@ -325,62 +325,260 @@ bool ZoneDatabase::logevents(const char* accountname,uint32 accountid,uint8 stat
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZoneDatabase::RegisterBug(BugReport_Struct* bug_report) {
|
||||||
|
if (!bug_report)
|
||||||
|
return;
|
||||||
|
|
||||||
void ZoneDatabase::UpdateBug(BugStruct* bug) {
|
size_t len = 0;
|
||||||
|
char* name_ = nullptr;
|
||||||
uint32 len = strlen(bug->bug);
|
char* ui_ = nullptr;
|
||||||
char* bugtext = nullptr;
|
char* type_ = nullptr;
|
||||||
if(len > 0)
|
char* target_ = nullptr;
|
||||||
{
|
char* bug_ = nullptr;
|
||||||
bugtext = new char[2*len+1];
|
|
||||||
memset(bugtext, 0, 2*len+1);
|
len = strlen(bug_report->reporter_name);
|
||||||
DoEscapeString(bugtext, bug->bug, len);
|
if (len) {
|
||||||
|
if (len > 63) // check against db column size
|
||||||
|
len = 63;
|
||||||
|
name_ = new char[(2 * len + 1)];
|
||||||
|
memset(name_, 0, (2 * len + 1));
|
||||||
|
DoEscapeString(name_, bug_report->reporter_name, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(bug->ui);
|
len = strlen(bug_report->ui_path);
|
||||||
char* uitext = nullptr;
|
if (len) {
|
||||||
if(len > 0)
|
if (len > 127)
|
||||||
{
|
len = 127;
|
||||||
uitext = new char[2*len+1];
|
ui_ = new char[(2 * len + 1)];
|
||||||
memset(uitext, 0, 2*len+1);
|
memset(ui_, 0, (2 * len + 1));
|
||||||
DoEscapeString(uitext, bug->ui, len);
|
DoEscapeString(ui_, bug_report->ui_path, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(bug->target_name);
|
len = strlen(bug_report->category_name);
|
||||||
char* targettext = nullptr;
|
if (len) {
|
||||||
if(len > 0)
|
if (len > 63)
|
||||||
{
|
len = 63;
|
||||||
targettext = new char[2*len+1];
|
type_ = new char[(2 * len + 1)];
|
||||||
memset(targettext, 0, 2*len+1);
|
memset(type_, 0, (2 * len + 1));
|
||||||
DoEscapeString(targettext, bug->target_name, len);
|
DoEscapeString(type_, bug_report->category_name, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
//x and y are intentionally swapped because eq is inversexy coords
|
len = strlen(bug_report->target_name);
|
||||||
std::string query = StringFormat("INSERT INTO bugs (zone, name, ui, x, y, z, type, flag, target, bug, date) "
|
if (len) {
|
||||||
|
if (len > 63)
|
||||||
|
len = 63;
|
||||||
|
target_ = new char[(2 * len + 1)];
|
||||||
|
memset(target_, 0, (2 * len + 1));
|
||||||
|
DoEscapeString(target_, bug_report->target_name, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(bug_report->bug_report);
|
||||||
|
if (len) {
|
||||||
|
if (len > 1023)
|
||||||
|
len = 1023;
|
||||||
|
bug_ = new char[(2 * len + 1)];
|
||||||
|
memset(bug_, 0, (2 * len + 1));
|
||||||
|
DoEscapeString(bug_, bug_report->bug_report, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
//x and y are intentionally swapped because eq is inversexy coords //is this msg out-of-date or are the parameters wrong?
|
||||||
|
std::string query = StringFormat(
|
||||||
|
"INSERT INTO `bugs` (`zone`, `name`, `ui`, `x`, `y`, `z`, `type`, `flag`, `target`, `bug`, `date`) "
|
||||||
"VALUES('%s', '%s', '%s', '%.2f', '%.2f', '%.2f', '%s', %d, '%s', '%s', CURDATE())",
|
"VALUES('%s', '%s', '%s', '%.2f', '%.2f', '%.2f', '%s', %d, '%s', '%s', CURDATE())",
|
||||||
zone->GetShortName(), bug->name, uitext == nullptr ? "": uitext,
|
zone->GetShortName(),
|
||||||
bug->x, bug->y, bug->z, bug->chartype, bug->type, targettext == nullptr? "Unknown Target": targettext,
|
(name_ ? name_ : ""),
|
||||||
bugtext==nullptr?"":bugtext);
|
(ui_ ? ui_ : ""),
|
||||||
safe_delete_array(bugtext);
|
bug_report->pos_x,
|
||||||
safe_delete_array(uitext);
|
bug_report->pos_y,
|
||||||
safe_delete_array(targettext);
|
bug_report->pos_z,
|
||||||
|
(type_ ? type_ : ""),
|
||||||
|
bug_report->optional_info_mask,
|
||||||
|
(target_ ? target_ : "Unknown Target"),
|
||||||
|
(bug_ ? bug_ : "")
|
||||||
|
);
|
||||||
|
safe_delete_array(name_);
|
||||||
|
safe_delete_array(ui_);
|
||||||
|
safe_delete_array(type_);
|
||||||
|
safe_delete_array(target_);
|
||||||
|
safe_delete_array(bug_);
|
||||||
|
|
||||||
QueryDatabase(query);
|
QueryDatabase(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneDatabase::UpdateBug(PetitionBug_Struct* bug){
|
void ZoneDatabase::RegisterBug(Client* client, BugReport_Struct* bug_report) {
|
||||||
|
if (!client || !bug_report)
|
||||||
|
return;
|
||||||
|
|
||||||
uint32 len = strlen(bug->text);
|
size_t len = 0;
|
||||||
auto bugtext = new char[2 * len + 1];
|
char* category_name_ = nullptr;
|
||||||
memset(bugtext, 0, 2*len+1);
|
char* reporter_name_ = nullptr;
|
||||||
DoEscapeString(bugtext, bug->text, len);
|
char* ui_path_ = nullptr;
|
||||||
|
char* target_name_ = nullptr;
|
||||||
|
char* bug_report_ = nullptr;
|
||||||
|
char* system_info_ = nullptr;
|
||||||
|
|
||||||
std::string query = StringFormat("INSERT INTO bugs (type, name, bugtext, flag) "
|
len = strlen(bug_report->category_name);
|
||||||
"VALUES('%s', '%s', '%s', %i)",
|
if (len) {
|
||||||
"Petition", bug->name, bugtext, 25);
|
if (len > 63) // check against db column size
|
||||||
safe_delete_array(bugtext);
|
len = 63;
|
||||||
QueryDatabase(query);
|
category_name_ = new char[(2 * len + 1)];
|
||||||
|
memset(category_name_, 0, (2 * len + 1));
|
||||||
|
DoEscapeString(category_name_, bug_report->category_name, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(bug_report->reporter_name);
|
||||||
|
if (len) {
|
||||||
|
if (len > 63)
|
||||||
|
len = 63;
|
||||||
|
reporter_name_ = new char[(2 * len + 1)];
|
||||||
|
memset(reporter_name_, 0, (2 * len + 1));
|
||||||
|
DoEscapeString(reporter_name_, bug_report->reporter_name, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(bug_report->ui_path);
|
||||||
|
if (len) {
|
||||||
|
if (len > 127)
|
||||||
|
len = 127;
|
||||||
|
ui_path_ = new char[(2 * len + 1)];
|
||||||
|
memset(ui_path_, 0, (2 * len + 1));
|
||||||
|
DoEscapeString(ui_path_, bug_report->ui_path, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(bug_report->target_name);
|
||||||
|
if (len) {
|
||||||
|
if (len > 63)
|
||||||
|
len = 63;
|
||||||
|
target_name_ = new char[(2 * len + 1)];
|
||||||
|
memset(target_name_, 0, (2 * len + 1));
|
||||||
|
DoEscapeString(target_name_, bug_report->target_name, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(bug_report->bug_report);
|
||||||
|
if (len) {
|
||||||
|
if (len > 1023)
|
||||||
|
len = 1023;
|
||||||
|
bug_report_ = new char[(2 * len + 1)];
|
||||||
|
memset(bug_report_, 0, (2 * len + 1));
|
||||||
|
DoEscapeString(bug_report_, bug_report->bug_report, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = strlen(bug_report->system_info);
|
||||||
|
if (len) {
|
||||||
|
if (len > 1023)
|
||||||
|
len = 1023;
|
||||||
|
system_info_ = new char[(2 * len + 1)];
|
||||||
|
memset(system_info_, 0, (2 * len + 1));
|
||||||
|
DoEscapeString(system_info_, bug_report->system_info, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string query = StringFormat(
|
||||||
|
"INSERT INTO `bug_reports` "
|
||||||
|
"(`zone`,"
|
||||||
|
" `client_version_id`,"
|
||||||
|
" `client_version_name`,"
|
||||||
|
" `account_id`,"
|
||||||
|
" `character_id`,"
|
||||||
|
" `character_name`,"
|
||||||
|
" `reporter_spoof`,"
|
||||||
|
" `category_id`,"
|
||||||
|
" `category_name`,"
|
||||||
|
" `reporter_name`,"
|
||||||
|
" `ui_path`,"
|
||||||
|
" `pos_x`,"
|
||||||
|
" `pos_y`,"
|
||||||
|
" `pos_z`,"
|
||||||
|
" `heading`,"
|
||||||
|
" `time_played`,"
|
||||||
|
" `target_id`,"
|
||||||
|
" `target_name`,"
|
||||||
|
" `optional_info_mask`,"
|
||||||
|
" `_can_duplicate`,"
|
||||||
|
" `_crash_bug`,"
|
||||||
|
" `_target_info`,"
|
||||||
|
" `_character_flags`,"
|
||||||
|
" `_unknown_value`,"
|
||||||
|
" `bug_report`,"
|
||||||
|
" `system_info`) "
|
||||||
|
"VALUES "
|
||||||
|
"('%s',"
|
||||||
|
" '%u',"
|
||||||
|
" '%s',"
|
||||||
|
" '%u',"
|
||||||
|
" '%u',"
|
||||||
|
" '%s',"
|
||||||
|
" '%u',"
|
||||||
|
" '%u',"
|
||||||
|
" '%s',"
|
||||||
|
" '%s',"
|
||||||
|
" '%s',"
|
||||||
|
" '%1.1f',"
|
||||||
|
" '%1.1f',"
|
||||||
|
" '%1.1f',"
|
||||||
|
" '%u',"
|
||||||
|
" '%u',"
|
||||||
|
" '%u',"
|
||||||
|
" '%s',"
|
||||||
|
" '%u',"
|
||||||
|
" '%u',"
|
||||||
|
" '%u',"
|
||||||
|
" '%u',"
|
||||||
|
" '%u',"
|
||||||
|
" '%u',"
|
||||||
|
" '%s',"
|
||||||
|
" '%s')",
|
||||||
|
zone->GetShortName(),
|
||||||
|
client->ClientVersion(),
|
||||||
|
EQEmu::versions::ClientVersionName(client->ClientVersion()),
|
||||||
|
client->AccountID(),
|
||||||
|
client->CharacterID(),
|
||||||
|
client->GetName(),
|
||||||
|
(strcmp(client->GetName(), reporter_name_) != 0 ? 1 : 0),
|
||||||
|
bug_report->category_id,
|
||||||
|
(category_name_ ? category_name_ : ""),
|
||||||
|
(reporter_name_ ? reporter_name_ : ""),
|
||||||
|
(ui_path_ ? ui_path_ : ""),
|
||||||
|
bug_report->pos_x,
|
||||||
|
bug_report->pos_y,
|
||||||
|
bug_report->pos_z,
|
||||||
|
bug_report->heading,
|
||||||
|
bug_report->time_played,
|
||||||
|
bug_report->target_id,
|
||||||
|
(target_name_ ? target_name_ : ""),
|
||||||
|
bug_report->optional_info_mask,
|
||||||
|
((bug_report->optional_info_mask & EQEmu::bug::infoCanDuplicate) != 0 ? 1 : 0),
|
||||||
|
((bug_report->optional_info_mask & EQEmu::bug::infoCrashBug) != 0 ? 1 : 0),
|
||||||
|
((bug_report->optional_info_mask & EQEmu::bug::infoTargetInfo) != 0 ? 1 : 0),
|
||||||
|
((bug_report->optional_info_mask & EQEmu::bug::infoCharacterFlags) != 0 ? 1 : 0),
|
||||||
|
((bug_report->optional_info_mask & EQEmu::bug::infoUnknownValue) != 0 ? 1 : 0),
|
||||||
|
(bug_report_ ? bug_report_ : ""),
|
||||||
|
(system_info_ ? system_info_ : "")
|
||||||
|
);
|
||||||
|
safe_delete_array(category_name_);
|
||||||
|
safe_delete_array(reporter_name_);
|
||||||
|
safe_delete_array(ui_path_);
|
||||||
|
safe_delete_array(target_name_);
|
||||||
|
safe_delete_array(bug_report_);
|
||||||
|
safe_delete_array(system_info_);
|
||||||
|
|
||||||
|
auto result = QueryDatabase(query);
|
||||||
|
|
||||||
|
// TODO: Entity dumping [RuleB(Bugs, DumpTargetEntity)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//void ZoneDatabase::UpdateBug(PetitionBug_Struct* bug) {
|
||||||
|
//
|
||||||
|
// uint32 len = strlen(bug->text);
|
||||||
|
// auto bugtext = new char[2 * len + 1];
|
||||||
|
// memset(bugtext, 0, 2 * len + 1);
|
||||||
|
// DoEscapeString(bugtext, bug->text, len);
|
||||||
|
//
|
||||||
|
// std::string query = StringFormat("INSERT INTO bugs (type, name, bugtext, flag) "
|
||||||
|
// "VALUES('%s', '%s', '%s', %i)",
|
||||||
|
// "Petition", bug->name, bugtext, 25);
|
||||||
|
// safe_delete_array(bugtext);
|
||||||
|
// QueryDatabase(query);
|
||||||
|
//}
|
||||||
|
|
||||||
bool ZoneDatabase::SetSpecialAttkFlag(uint8 id, const char* flag) {
|
bool ZoneDatabase::SetSpecialAttkFlag(uint8 id, const char* flag) {
|
||||||
|
|
||||||
std::string query = StringFormat("UPDATE npc_types SET npcspecialattks='%s' WHERE id = %i;", flag, id);
|
std::string query = StringFormat("UPDATE npc_types SET npcspecialattks='%s' WHERE id = %i;", flag, id);
|
||||||
@ -1425,6 +1623,8 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla
|
|||||||
if (account_id <= 0)
|
if (account_id <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
std::string mail_key = database.GetMailKey(character_id);
|
||||||
|
|
||||||
clock_t t = std::clock(); /* Function timer start */
|
clock_t t = std::clock(); /* Function timer start */
|
||||||
std::string query = StringFormat(
|
std::string query = StringFormat(
|
||||||
"REPLACE INTO `character_data` ("
|
"REPLACE INTO `character_data` ("
|
||||||
@ -1521,7 +1721,8 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla
|
|||||||
" e_aa_effects, "
|
" e_aa_effects, "
|
||||||
" e_percent_to_aa, "
|
" e_percent_to_aa, "
|
||||||
" e_expended_aa_spent, "
|
" e_expended_aa_spent, "
|
||||||
" e_last_invsnapshot "
|
" e_last_invsnapshot, "
|
||||||
|
" mailkey "
|
||||||
") "
|
") "
|
||||||
"VALUES ("
|
"VALUES ("
|
||||||
"%u," // id " id, "
|
"%u," // id " id, "
|
||||||
@ -1617,7 +1818,8 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla
|
|||||||
"%u," // e_aa_effects
|
"%u," // e_aa_effects
|
||||||
"%u," // e_percent_to_aa
|
"%u," // e_percent_to_aa
|
||||||
"%u," // e_expended_aa_spent
|
"%u," // e_expended_aa_spent
|
||||||
"%u" // e_last_invsnapshot
|
"%u," // e_last_invsnapshot
|
||||||
|
"'%s'" // mailkey mail_key
|
||||||
")",
|
")",
|
||||||
character_id, // " id, "
|
character_id, // " id, "
|
||||||
account_id, // " account_id, "
|
account_id, // " account_id, "
|
||||||
@ -1712,7 +1914,8 @@ bool ZoneDatabase::SaveCharacterData(uint32 character_id, uint32 account_id, Pla
|
|||||||
m_epp->aa_effects,
|
m_epp->aa_effects,
|
||||||
m_epp->perAA,
|
m_epp->perAA,
|
||||||
m_epp->expended_aa,
|
m_epp->expended_aa,
|
||||||
m_epp->last_invsnapshot_time
|
m_epp->last_invsnapshot_time,
|
||||||
|
mail_key.c_str()
|
||||||
);
|
);
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
Log(Logs::General, Logs::None, "ZoneDatabase::SaveCharacterData %i, done... Took %f seconds", character_id, ((float)(std::clock() - t)) / CLOCKS_PER_SEC);
|
Log(Logs::General, Logs::None, "ZoneDatabase::SaveCharacterData %i, done... Took %f seconds", character_id, ((float)(std::clock() - t)) / CLOCKS_PER_SEC);
|
||||||
|
|||||||
@ -442,8 +442,9 @@ public:
|
|||||||
bool DeleteMerc(uint32 merc_id);
|
bool DeleteMerc(uint32 merc_id);
|
||||||
|
|
||||||
/* Petitions */
|
/* Petitions */
|
||||||
void UpdateBug(BugStruct* bug);
|
void RegisterBug(BugReport_Struct* bug_report); // old method
|
||||||
void UpdateBug(PetitionBug_Struct* bug);
|
void RegisterBug(Client* client, BugReport_Struct* bug_report); // new method
|
||||||
|
//void UpdateBug(PetitionBug_Struct* bug);
|
||||||
void DeletePetitionFromDB(Petition* wpet);
|
void DeletePetitionFromDB(Petition* wpet);
|
||||||
void UpdatePetitionToDB(Petition* wpet);
|
void UpdatePetitionToDB(Petition* wpet);
|
||||||
void InsertPetitionToDB(Petition* wpet);
|
void InsertPetitionToDB(Petition* wpet);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user