Merge and compile fixes (non-bot, will do bots later)

This commit is contained in:
KimLS
2018-04-16 14:15:08 -07:00
184 changed files with 11873 additions and 4474 deletions
+2 -2
View File
@@ -24,8 +24,8 @@ struct BaseDataStruct
double base_hp;
double base_mana;
double base_end;
double unk1;
double unk2;
double hp_regen;
double end_regen;
double hp_factor;
double mana_factor;
double endurance_factor;
-10
View File
@@ -472,16 +472,6 @@ bool Database::CheckDatabaseConversions() {
CheckDatabaseConvertPPDeblob();
CheckDatabaseConvertCorpseDeblob();
/* Fetch EQEmu Server script */
if (!std::ifstream("eqemu_server.pl")){
std::cout << "Pulling down automatic database upgrade script..." << std::endl;
#ifdef _WIN32
system("perl -MLWP::UserAgent -e \"require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->env_proxy; my $response = $ua->get('https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl'); if ($response->is_success){ open(FILE, '> eqemu_server.pl'); print FILE $response->decoded_content; close(FILE); }\"");
#else
system("wget --no-check-certificate -O eqemu_server.pl https://raw.githubusercontent.com/EQEmu/Server/master/utils/scripts/eqemu_server.pl");
#endif
}
/* Run EQEmu Server script (Checks for database updates) */
system("perl eqemu_server.pl ran_from_world");
+65
View File
@@ -18,3 +18,68 @@
*/
#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;
}
+36 -1
View File
@@ -24,7 +24,7 @@
#include "emu_legacy.h"
#include "emu_versions.h"
#include <string>
#include <string.h>
namespace EQEmu
@@ -114,7 +114,11 @@ namespace EQEmu
const EQEmu::versions::ClientVersion CharacterCreationClient = EQEmu::versions::ClientVersion::RoF2;
const size_t CharacterCreationMax = RoF2::constants::CharacterCreationLimit;
const size_t SayLinkOpenerSize = 1;
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 ShortBuffs = RoF2::constants::ShortBuffs;
@@ -126,6 +130,37 @@ namespace EQEmu
} /*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 {
Gem1 = 0,
Gem2 = 1,
+2 -2
View File
@@ -78,6 +78,8 @@ namespace EQEmu
SLOT_CURSOR_BAG_END = 340,
SLOT_TRIBUTE_BEGIN = 400,
SLOT_TRIBUTE_END = 404,
SLOT_GUILD_TRIBUTE_BEGIN = 450,
SLOT_GUILD_TRIBUTE_END = 451,
SLOT_BANK_BEGIN = 2000,
SLOT_BANK_END = 2023,
SLOT_BANK_BAGS_BEGIN = 2031,
@@ -173,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?)
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 56;
}
}
+3
View File
@@ -9,6 +9,7 @@ N(OP_AcceptNewTask),
N(OP_AckPacket),
N(OP_Action),
N(OP_Action2),
N(OP_AddNimbusEffect),
N(OP_AdventureData),
N(OP_AdventureDetails),
N(OP_AdventureFinish),
@@ -339,6 +340,7 @@ N(OP_MOTD),
N(OP_MoveCoin),
N(OP_MoveDoor),
N(OP_MoveItem),
N(OP_MoveMultipleItems),
N(OP_MoveLogDisregard),
N(OP_MoveLogRequest),
N(OP_MultiLineMsg),
@@ -391,6 +393,7 @@ N(OP_PVPLeaderBoardReply),
N(OP_PVPLeaderBoardRequest),
N(OP_PVPStats),
N(OP_QueryResponseThing),
N(OP_QueryUCSServerStatus),
N(OP_RaidInvite),
N(OP_RaidJoin),
N(OP_RaidUpdate),
+16 -2
View File
@@ -28,7 +28,7 @@
namespace EQEmu
{
namespace versions {
enum class ClientVersion {
enum class ClientVersion : uint32 {
Unknown = 0,
Client62, // Build: 'Aug 4 2005 15:40:59'
Titanium, // Build: 'Oct 31 2005 10:33:37'
@@ -72,7 +72,7 @@ namespace EQEmu
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
enum class MobVersion {
enum class MobVersion : uint32 {
Unknown = 0,
Client62,
Titanium,
@@ -121,6 +121,20 @@ namespace EQEmu
ClientVersion ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_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*/
} /*EQEmu*/
+81 -48
View File
@@ -280,7 +280,7 @@ union
// horse: 0=brown, 1=white, 2=black, 3=tan
};
/*0340*/ uint32 spawnId; // Spawn Id
/*0344*/ uint8 unknown0344[3];
/*0344*/ float bounding_radius; // used in melee, overrides calc
/*0347*/ uint8 IsMercenary;
/*0348*/ EQEmu::TintProfile equipment_tint;
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
@@ -551,6 +551,7 @@ struct BlockedBuffs_Struct
/*86*/ uint16 Flags;
};
// same for adding
struct RemoveNimbusEffect_Struct
{
/*00*/ uint32 spawnid; // Spawn ID
@@ -854,6 +855,7 @@ static const uint32 MAX_PP_REF_SPELLBOOK = 480; // Set for Player Profile size r
static const uint32 MAX_PP_REF_MEMSPELL = 9; // Set for Player Profile size retain
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 240;
static const uint32 MAX_GROUP_MEMBERS = 6;
static const uint32 MAX_RECAST_TYPES = 20;
@@ -993,7 +995,8 @@ struct PlayerProfile_Struct
/*4768*/ int32 platinum_shared; // Platinum shared between characters
/*4772*/ uint8 unknown4808[24];
/*4796*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
/*5196*/ uint8 unknown5132[184];
/*5196*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
/*5296*/ uint8 unknown5132[84];
/*5380*/ uint32 pvp2; //
/*5384*/ uint32 unknown5420; //
/*5388*/ uint32 pvptype; //
@@ -1250,21 +1253,22 @@ struct Action_Struct
{
/* 00 */ uint16 target; // id of target
/* 02 */ uint16 source; // id of caster
/* 04 */ uint16 level; // level of caster
/* 06 */ uint16 instrument_mod;
/* 08 */ uint32 bard_focus_id;
/* 12 */ uint16 unknown16;
// some kind of sequence that's the same in both actions
// as well as the combat damage, to tie em together?
/* 14 */ uint32 sequence;
/* 18 */ uint32 unknown18;
/* 22 */ uint8 type; // 231 (0xE7) for spells
/* 23 */ uint32 unknown23;
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
/* 10 */ float force;
/* 14 */ float hit_heading;
/* 18 */ float hit_pitch;
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
/* 23 */ uint16 unknown23; // OSX says min_damage
/* 25 */ uint16 unknown25; // OSX says tohit
/* 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
/* 30 */ uint8 buff_unknown; // if this is 4, a buff icon is made
/* 31 */
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
// 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
@@ -1274,12 +1278,12 @@ struct CombatDamage_Struct
{
/* 00 */ uint16 target;
/* 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;
/* 07 */ uint32 damage;
/* 11 */ float force;
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 15 */ float hit_heading; // see above notes in Action_Struct
/* 19 */ float hit_pitch;
/* 23 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
};
@@ -3320,23 +3324,32 @@ struct GuildMakeLeader{
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*/ char unknown308[160];
/*0468*/ char target_name[64];
/*0532*/ uint32 type;
/*0536*/ char unknown536[2052];
/*2584*/ char bug[2048];
/*4632*/ char unknown4632[6];
/*4638*/ char system_info[4094];
struct BugReport_Struct {
/*0000*/ uint32 category_id;
/*0004*/ char category_name[64];
/*0068*/ char reporter_name[64];
/*0132*/ char unused_0132[32];
/*0164*/ char ui_path[128];
/*0292*/ float pos_x;
/*0296*/ float pos_y;
/*0300*/ float pos_z;
/*0304*/ uint32 heading;
/*0308*/ uint32 unused_0308;
/*0312*/ uint32 time_played;
/*0316*/ char padding_0316[8];
/*0324*/ uint32 target_id;
/*0328*/ char padding_0328[140];
/*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
uint8 level;
uint8 class_;
@@ -3363,20 +3376,21 @@ struct Ground_Spawn{
struct Ground_Spawns {
struct Ground_Spawn spawn[50]; //Assigned max number to allow
};
struct PetitionBug_Struct{
uint32 petition_number;
uint32 unknown4;
char accountname[64];
uint32 zoneid;
char name[64];
uint32 level;
uint32 class_;
uint32 race;
uint32 unknown152[3];
uint32 time;
uint32 unknown168;
char text[1028];
};
//struct PetitionBug_Struct{
// uint32 petition_number;
// uint32 unknown4;
// char accountname[64];
// uint32 zoneid;
// char name[64];
// uint32 level;
// uint32 class_;
// uint32 race;
// uint32 unknown152[3];
// uint32 time;
// uint32 unknown168;
// char text[1028];
//};
struct ApproveZone_Struct {
char name[64];
@@ -4764,6 +4778,7 @@ struct BuffIconEntry_Struct
uint32 spell_id;
int32 tics_remaining;
uint32 num_hits;
char caster[64];
};
struct BuffIcon_Struct
@@ -4773,6 +4788,7 @@ struct BuffIcon_Struct
uint16 count;
uint8 type; // 0 = self buff window, 1 = self target window, 4 = group, 5 = PC, 7 = NPC
int32 tic_timer;
int32 name_lengths; // so ahh we kind of do these packets hacky, this is the total length of all the names to make creating the real packets in the translators easier
BuffIconEntry_Struct entries[0];
};
@@ -5351,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
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
#pragma pack()
+96 -336
View File
@@ -23,351 +23,112 @@
#include <iostream>
#include <sstream>
std::string EQEmuConfig::ConfigFile = "eqemu_config.xml";
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
EQEmuConfig *EQEmuConfig::_config = nullptr;
void EQEmuConfig::do_world(TiXmlElement *ele)
{
const char *text;
TiXmlElement * sub_ele;;
text = ParseTextBlock(ele, "shortname");
if (text) {
ShortName = text;
}
text = ParseTextBlock(ele, "longname");
if (text) {
LongName = text;
}
text = ParseTextBlock(ele, "address", true);
if (text) {
WorldAddress = text;
}
text = ParseTextBlock(ele, "localaddress", true);
if (text) {
LocalAddress = text;
}
text = ParseTextBlock(ele, "maxclients", true);
if (text) {
MaxClients = atoi(text);
}
// Get the <key> element
text = ParseTextBlock(ele, "key", true);
if (text) {
SharedKey = text;
}
// Get the <loginserver> element
sub_ele = ele->FirstChildElement("loginserver");
if (sub_ele) {
text = ParseTextBlock(sub_ele, "host", true);
if (text) {
LoginHost = text;
}
text = ParseTextBlock(sub_ele, "port", true);
if (text) {
LoginPort = atoi(text);
}
text = ParseTextBlock(sub_ele, "legacy", true);
if (text) {
LoginLegacy = atoi(text) > 0 ? true : false;
}
text = ParseTextBlock(sub_ele, "account", true);
if (text) {
LoginAccount = text;
}
text = ParseTextBlock(sub_ele, "password", true);
if (text) {
LoginPassword = text;
}
void EQEmuConfig::parse_config() {
ShortName = _root["server"]["world"].get("shortname", "").asString();
LongName = _root["server"]["world"].get("longname", "").asString();
WorldAddress = _root["server"]["world"].get("address", "").asString();
LocalAddress = _root["server"]["world"].get("localaddress", "").asString();
MaxClients = atoi(_root["server"]["world"].get("maxclients", "-1").asString().c_str());
SharedKey = _root["server"]["world"].get("key", "").asString();
LoginCount = 0;
if (_root["server"]["world"]["loginserver"].isObject()) {
LoginHost = _root["server"]["world"]["loginserver"].get("host", "login.eqemulator.net").asString();
LoginPort = atoi(_root["server"]["world"]["loginserver"].get("port", "5998").asString().c_str());
LoginLegacy = false;
if (_root["server"]["world"]["loginserver"].get("legacy", "0").asString() == "1") LoginLegacy = true;
LoginAccount = _root["server"]["world"]["loginserver"].get("account", "").asString();
LoginPassword = _root["server"]["world"]["loginserver"].get("password", "").asString();
} else {
char str[32];
char str[32];
loginlist.Clear();
do {
sprintf(str, "loginserver%i", ++LoginCount);
sub_ele = ele->FirstChildElement(str);
if (sub_ele) {
auto loginconfig = new LoginConfig;
text = ParseTextBlock(sub_ele, "host", true);
if (text) {
loginconfig->LoginHost = text;
}
text = ParseTextBlock(sub_ele, "port", true);
if (text) {
loginconfig->LoginPort = atoi(text);
}
text = ParseTextBlock(sub_ele, "legacy", true);
if (text) {
loginconfig->LoginLegacy = atoi(text) > 0 ? true : false;
}
text = ParseTextBlock(sub_ele, "account", true);
if (text) {
loginconfig->LoginAccount = text;
}
text = ParseTextBlock(sub_ele, "password", true);
if (text) {
loginconfig->LoginPassword = text;
}
loginlist.Insert(loginconfig);
if (!_root["server"]["world"][str].isObject()) {
break;
}
} while (sub_ele);
}
// Check for locked
sub_ele = ele->FirstChildElement("locked");
if (sub_ele != nullptr) {
Locked = true;
}
// Get the <tcp> element
sub_ele = ele->FirstChildElement("tcp");
if (sub_ele != nullptr) {
text = sub_ele->Attribute("ip");
if (text) {
WorldIP = text;
}
text = sub_ele->Attribute("port");
if (text) {
WorldTCPPort = atoi(text);
}
}
sub_ele = ele->FirstChildElement("telnet");
if (sub_ele != nullptr) {
text = sub_ele->Attribute("ip");
if (text) {
TelnetIP = text;
}
text = sub_ele->Attribute("port");
if (text) {
TelnetTCPPort = atoi(text);
}
text = sub_ele->Attribute("enabled");
if (text && !strcasecmp(text, "true")) {
TelnetEnabled = true;
}
}
auto loginconfig = new LoginConfig;
loginconfig->LoginHost = _root["server"]["world"][str].get("host", "login.eqemulator.net").asString();
loginconfig->LoginPort = atoi(_root["server"]["world"][str].get("port", "5998").asString().c_str());
loginconfig->LoginAccount = _root["server"]["world"][str].get("account", "").asString();
loginconfig->LoginPassword = _root["server"]["world"][str].get("password", "").asString();
// Get the <http> element
sub_ele = ele->FirstChildElement("http");
if (sub_ele != nullptr) {
// text = sub_ele->Attribute("ip");
// if (text)
// WorldIP=text;
text = sub_ele->Attribute("mimefile");
if (text) {
WorldHTTPMimeFile = text;
}
text = sub_ele->Attribute("port");
if (text) {
WorldHTTPPort = atoi(text);
}
text = sub_ele->Attribute("enabled");
if (text && !strcasecmp(text, "true")) {
WorldHTTPEnabled = true;
}
loginconfig->LoginLegacy = false;
if (_root["server"]["world"][str].get("legacy", "0").asString() == "1") loginconfig->LoginLegacy = true;
loginlist.Insert(loginconfig);
} while (LoginCount < 100);
}
//<locked> from xml converts to json as locked: "", so i default to "false".
//The only way to enable locked is by switching to true, meaning this value is always false until manually set true
Locked = false;
if (_root["server"]["world"].get("locked", "false").asString() == "true") Locked = true;
WorldIP = _root["server"]["world"]["tcp"].get("host", "127.0.0.1").asString();
WorldTCPPort = atoi(_root["server"]["world"]["tcp"].get("port", "9000").asString().c_str());
TelnetIP = _root["server"]["world"]["telnet"].get("ip", "127.0.0.1").asString();
TelnetTCPPort = atoi(_root["server"]["world"]["telnet"].get("port", "9001").asString().c_str());
TelnetEnabled = false;
if (_root["server"]["world"]["telnet"].get("enabled", "false").asString() == "true") TelnetEnabled = true;
WorldHTTPMimeFile = _root["server"]["world"]["http"].get("mimefile", "mime.types").asString();
WorldHTTPPort = atoi(_root["server"]["world"]["http"].get("port", "9080").asString().c_str());
WorldHTTPEnabled = false;
if (_root["server"]["world"]["http"].get("enabled", "false").asString() == "true") WorldHTTPEnabled = true;
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
ChatPort = atoi(_root["server"]["chatserver"].get("port", "7778").asString().c_str());
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
MailPort = atoi(_root["server"]["mailserver"].get("port", "7778").asString().c_str());
DatabaseUsername = _root["server"]["database"].get("username", "eq").asString();
DatabasePassword = _root["server"]["database"].get("password", "eq").asString();
DatabaseHost = _root["server"]["database"].get("host", "localhost").asString();
DatabasePort = atoi(_root["server"]["database"].get("port", "3306").asString().c_str());
DatabaseDB = _root["server"]["database"].get("db", "eq").asString();
QSDatabaseHost = _root["server"]["qsdatabase"].get("host", "localhost").asString();
QSDatabasePort = atoi(_root["server"]["qsdatabase"].get("port", "3306").asString().c_str());
QSDatabaseUsername = _root["server"]["qsdatabase"].get("username", "eq").asString();
QSDatabasePassword = _root["server"]["qsdatabase"].get("password", "eq").asString();
QSDatabaseDB = _root["server"]["qsdatabase"].get("db", "eq").asString();
DefaultStatus = atoi(_root["server"]["zones"].get("defaultstatus", 0).asString().c_str());
ZonePortLow = atoi(_root["server"]["zones"]["ports"].get("low", "7000").asString().c_str());
ZonePortHigh = atoi(_root["server"]["zones"]["ports"].get("high", "7999").asString().c_str());
SpellsFile = _root["server"]["files"].get("spells", "spells_us.txt").asString();
OpCodesFile = _root["server"]["files"].get("opcodes", "opcodes.conf").asString();
PluginPlFile = _root["server"]["files"].get("plugin.pl", "plugin.pl").asString();
MapDir = _root["server"]["directories"].get("maps", "Maps/").asString();
QuestDir = _root["server"]["directories"].get("quests", "quests/").asString();
PluginDir = _root["server"]["directories"].get("plugins", "plugins/").asString();
LuaModuleDir = _root["server"]["directories"].get("lua_modules", "lua_modules/").asString();
PatchDir = _root["server"]["directories"].get("patches", "./").asString();
SharedMemDir = _root["server"]["directories"].get("shared_memory", "shared/").asString();
LogDir = _root["server"]["directories"].get("logs", "logs/").asString();
LogPrefix = _root["server"]["launcher"].get("logprefix", "logs/zone-").asString();
LogSuffix = _root["server"]["launcher"].get("logsuffix", ".log").asString();
RestartWait = atoi(_root["server"]["launcher"]["timers"].get("restart", "10000").asString().c_str());
TerminateWait = atoi(_root["server"]["launcher"]["timers"].get("reterminate", "10000").asString().c_str());
InitialBootWait = atoi(_root["server"]["launcher"]["timers"].get("initial", "20000").asString().c_str());
ZoneBootInterval = atoi(_root["server"]["launcher"]["timers"].get("interval", "2000").asString().c_str());
#ifdef WIN32
ZoneExe = _root["server"]["launcher"].get("exe", "zone.exe").asString();
#else
ZoneExe = _root["server"]["launcher"].get("exe", "./zone").asString();
#endif
}
void EQEmuConfig::do_chatserver(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
ChatHost = text;
}
text = ParseTextBlock(ele, "port", true);
if (text) {
ChatPort = atoi(text);
}
}
void EQEmuConfig::do_mailserver(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
MailHost = text;
}
text = ParseTextBlock(ele, "port", true);
if (text) {
MailPort = atoi(text);
}
}
void EQEmuConfig::do_database(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
DatabaseHost = text;
}
text = ParseTextBlock(ele, "port", true);
if (text) {
DatabasePort = atoi(text);
}
text = ParseTextBlock(ele, "username", true);
if (text) {
DatabaseUsername = text;
}
text = ParseTextBlock(ele, "password", true);
if (text) {
DatabasePassword = text;
}
text = ParseTextBlock(ele, "db", true);
if (text) {
DatabaseDB = text;
}
}
void EQEmuConfig::do_qsdatabase(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "host", true);
if (text) {
QSDatabaseHost = text;
}
text = ParseTextBlock(ele, "port", true);
if (text) {
QSDatabasePort = atoi(text);
}
text = ParseTextBlock(ele, "username", true);
if (text) {
QSDatabaseUsername = text;
}
text = ParseTextBlock(ele, "password", true);
if (text) {
QSDatabasePassword = text;
}
text = ParseTextBlock(ele, "db", true);
if (text) {
QSDatabaseDB = text;
}
}
void EQEmuConfig::do_zones(TiXmlElement *ele)
{
const char *text;
TiXmlElement *sub_ele;
// TiXmlNode *node,*sub_node;
text = ParseTextBlock(ele, "defaultstatus", true);
if (text) {
DefaultStatus = atoi(text);
}
// Get the <ports> element
sub_ele = ele->FirstChildElement("ports");
if (sub_ele != nullptr) {
text = sub_ele->Attribute("low");
if (text) {
ZonePortLow = atoi(text);
};
text = sub_ele->Attribute("high");
if (text) {
ZonePortHigh = atoi(text);
}
}
}
void EQEmuConfig::do_files(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "spells", true);
if (text) {
SpellsFile = text;
}
text = ParseTextBlock(ele, "opcodes", true);
if (text) {
OpCodesFile = text;
}
text = ParseTextBlock(ele, "plugin.pl", true);
if (text) {
PluginPlFile = text;
}
}
void EQEmuConfig::do_directories(TiXmlElement *ele)
{
const char *text;
text = ParseTextBlock(ele, "maps", true);
if (text) {
MapDir = text;
if ( MapDir.back() != '/' )
MapDir += '/';
}
text = ParseTextBlock(ele, "quests", true);
if (text) {
QuestDir = text;
if ( QuestDir.back() != '/' )
QuestDir += '/';
}
text = ParseTextBlock(ele, "plugins", true);
if (text) {
PluginDir = text;
if ( PluginDir.back() != '/' )
PluginDir += '/';
}
text = ParseTextBlock(ele, "lua_modules", true);
if (text) {
LuaModuleDir = text;
if ( LuaModuleDir.back() != '/' )
LuaModuleDir += '/';
}
text = ParseTextBlock(ele, "patches", true);
if (text) {
PatchDir = text;
if ( PatchDir.back() != '/' )
PatchDir += '/';
}
text = ParseTextBlock(ele, "shared_memory", true);
if (text) {
SharedMemDir = text;
if ( SharedMemDir.back() != '/' )
SharedMemDir += '/';
}
//Not Fully Implemented yet LogDir
text = ParseTextBlock(ele, "logs", true);
if (text) {
LogDir = text;
if ( LogDir.back() != '/' )
LogDir += '/';
}
}
void EQEmuConfig::do_launcher(TiXmlElement *ele)
{
const char *text;
TiXmlElement *sub_ele;
text = ParseTextBlock(ele, "logprefix", true);
if (text) {
LogPrefix = text;
}
text = ParseTextBlock(ele, "logsuffix", true);
if (text) {
LogSuffix = text;
}
// Get the <exe> element
text = ParseTextBlock(ele, "exe", true);
if (text) {
ZoneExe = text;
}
// Get the <timers> element
sub_ele = ele->FirstChildElement("timers");
if (sub_ele != nullptr) {
text = sub_ele->Attribute("restart");
if (text) {
RestartWait = atoi(text);
}
text = sub_ele->Attribute("reterminate");
if (text) {
TerminateWait = atoi(text);
}
text = sub_ele->Attribute("initial");
if (text) {
InitialBootWait = atoi(text);
}
text = sub_ele->Attribute("interval");
if (text) {
ZoneBootInterval = atoi(text);
}
}
}
std::string EQEmuConfig::GetByName(const std::string &var_name) const
{
if (var_name == "ShortName") {
@@ -564,4 +325,3 @@ void EQEmuConfig::Dump() const
std::cout << "DefaultStatus = " << (int)DefaultStatus << std::endl;
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
}
+27 -84
View File
@@ -18,8 +18,9 @@
#ifndef __EQEmuConfig_H
#define __EQEmuConfig_H
#include "xml_parser.h"
#include "json/json.h"
#include "linked_list.h"
#include <fstream>
struct LoginConfig {
std::string LoginHost;
@@ -29,7 +30,7 @@ struct LoginConfig {
bool LoginLegacy;
};
class EQEmuConfig : public XMLParser
class EQEmuConfig
{
public:
virtual std::string GetByName(const std::string &var_name) const;
@@ -115,88 +116,14 @@ class EQEmuConfig : public XMLParser
protected:
static EQEmuConfig *_config;
Json::Value _root;
static std::string ConfigFile;
#define ELEMENT(name) \
void do_##name(TiXmlElement *ele);
#include "eqemu_config_elements.h"
void parse_config();
EQEmuConfig()
{
// import the needed handler prototypes
#define ELEMENT(name) \
Handlers[#name]=(ElementHandler)&EQEmuConfig::do_##name;
#include "eqemu_config_elements.h"
// Set sane defaults
// Login server
LoginHost = "login.eqemulator.net";
LoginPort = 5998;
LoginLegacy = false;
// World
Locked = false;
WorldTCPPort = 9000;
TelnetTCPPort = 9001;
TelnetEnabled = false;
WorldHTTPEnabled = false;
WorldHTTPPort = 9080;
WorldHTTPMimeFile = "mime.types";
SharedKey = ""; //blank disables authentication
// Mail
ChatHost = "eqchat.eqemulator.net";
ChatPort = 7778;
// Mail
MailHost = "eqmail.eqemulator.net";
MailPort = 7779;
// Mysql
DatabaseHost = "localhost";
DatabasePort = 3306;
DatabaseUsername = "eq";
DatabasePassword = "eq";
DatabaseDB = "eq";
// QueryServ Database
QSDatabaseHost = "localhost";
QSDatabasePort = 3306;
QSDatabaseUsername = "eq";
QSDatabasePassword = "eq";
QSDatabaseDB = "eq";
// Files
SpellsFile = "spells_us.txt";
OpCodesFile = "opcodes.conf";
PluginPlFile = "plugin.pl";
// Dirs
MapDir = "Maps/";
QuestDir = "quests/";
PluginDir = "plugins/";
LuaModuleDir = "lua_modules/";
PatchDir = "./";
SharedMemDir = "shared/";
LogDir = "logs/";
{
// Launcher
LogPrefix = "logs/zone-";
LogSuffix = ".log";
RestartWait = 10000; //milliseconds
TerminateWait = 10000; //milliseconds
InitialBootWait = 20000; //milliseconds
ZoneBootInterval = 2000; //milliseconds
#ifdef WIN32
ZoneExe = "zone.exe";
#else
ZoneExe = "./zone";
#endif
// Zones
ZonePortLow = 7000;
ZonePortHigh = 7999;
DefaultStatus = 0;
// For where zones need to connect to.
WorldIP = "127.0.0.1";
TelnetIP = "127.0.0.1";
// Dynamics to start
//DynamicCount=5;
MaxClients = -1;
LoginCount = 0;
}
virtual ~EQEmuConfig() {}
@@ -205,9 +132,7 @@ class EQEmuConfig : public XMLParser
// Produce a const singleton
static const EQEmuConfig *get()
{
if (_config == nullptr) {
LoadConfig();
}
LoadConfig();
return (_config);
}
@@ -221,10 +146,28 @@ class EQEmuConfig : public XMLParser
static bool LoadConfig()
{
if (_config != nullptr) {
delete _config;
return true;
}
_config = new EQEmuConfig;
return _config->ParseFile(EQEmuConfig::ConfigFile.c_str(), "server");
return parseFile();
}
// Load config file and parse data
static bool parseFile() {
if (_config == nullptr) {
return LoadConfig();
}
std::ifstream fconfig(EQEmuConfig::ConfigFile, std::ifstream::binary);
try {
fconfig >> _config->_root;
_config->parse_config();
}
catch (std::exception) {
return false;
}
return true;
}
void Dump() const;
+3 -1
View File
@@ -89,6 +89,7 @@ enum LogCategory {
HP_Update,
FixZ,
Food,
Traps,
MaxCategoryID /* Don't Remove this*/
};
@@ -142,7 +143,8 @@ static const char* LogCategoryName[LogCategory::MaxCategoryID] = {
"Headless Client",
"HP Update",
"FixZ",
"Food"
"Food",
"Traps"
};
}
+8
View File
@@ -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)
#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.
//level is the only valid variable to use
#define EXP_FORMULA level*level*75*35/10
@@ -276,6 +279,11 @@ enum {
#define SAYLINK_ITEM_ID 0xFFFFF
// consumption timers for food/drink here instead of rules because the client
// uses these. Times in ms.
#define CONSUMPTION_TIMER 46000
#define CONSUMPTION_MNK_TIMER 92000
/*
Developer configuration
+4 -1
View File
@@ -111,7 +111,8 @@
#define GLM_COMPILER_GCC70 0x02000A00
#define GLM_COMPILER_GCC71 0x02000B00
#define GLM_COMPILER_GCC72 0x02000C00
#define GLM_COMPILER_GCC80 0x02000D00
#define GLM_COMPILER_GCC73 0x02000D00
#define GLM_COMPILER_GCC80 0x02000E00
// CUDA
#define GLM_COMPILER_CUDA 0x10000000
@@ -283,6 +284,8 @@
# define GLM_COMPILER (GLM_COMPILER_GCC71)
# elif (__GNUC__ == 7) && (__GNUC_MINOR__ == 2)
# define GLM_COMPILER (GLM_COMPILER_GCC72)
# elif (__GNUC__ == 7) && (__GNUC_MINOR__ == 3)
# define GLM_COMPILER (GLM_COMPILER_GCC73)
# elif (__GNUC__ >= 8)
# define GLM_COMPILER (GLM_COMPILER_GCC80)
# else
+52 -14
View File
@@ -194,32 +194,70 @@ uint32 rnd_hash( time_t t, clock_t c )
float EQ13toFloat(int d)
{
return ( float(d)/float(1<<2));
}
float NewEQ13toFloat(int d)
{
return ( float(d)/float(1<<6));
return static_cast<float>(d) / 64.0f;
}
float EQ19toFloat(int d)
{
return ( float(d)/float(1<<3));
return static_cast<float>(d) / 8.0f;
}
int FloatToEQ13(float d)
{
return int(d*float(1<<2));
}
int NewFloatToEQ13(float d)
{
return int(d*float(1<<6));
return static_cast<int>(d * 64.0f);
}
int FloatToEQ19(float d)
{
return int(d*float(1<<3));
return static_cast<int>(d * 8.0f);
}
float EQ12toFloat(int d)
{
return static_cast<float>(d) / 4.0f;
}
int FloatToEQ12(float d)
{
return static_cast<int>((d + 2048.0f) * 4.0f) % 2048;
}
float EQ10toFloat(int d)
{
return static_cast<float>(d) / 20.0f;
}
int FloatToEQ10(float d)
{
return static_cast<int>(d * 20.0f);
}
float EQSpeedRunToFloat(int d)
{
return static_cast<float>(d) / 40.0f;
}
int FloatToEQSpeedRun(float d)
{
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;
}
/*
+14 -2
View File
@@ -50,13 +50,25 @@ uint32 ResolveIP(const char* hostname, char* errbuf = 0);
bool ParseAddress(const char* iAddress, uint32* oIP, uint16* oPort, char* errbuf = 0);
void CoutTimestamp(bool ms = true);
float EQ13toFloat(int d);
float NewEQ13toFloat(int d);
float EQ19toFloat(int d);
float EQHtoFloat(int d);
int FloatToEQ13(float d);
int NewFloatToEQ13(float d);
int FloatToEQ19(float d);
int FloatToEQH(float d);
float EQ12toFloat(int d);
int FloatToEQ12(float d);
float EQ10toFloat(int d);
int FloatToEQ10(float d);
// this is also a 10 bit float
float EQSpeedRunToFloat(int d);
int FloatToEQSpeedRun(float d);
// brings heading back into EQ angles range
float FixHeading(float in);
uint32 SwapBits21and22(uint32 mask);
uint32 Catch22(uint32 mask);
+2 -2
View File
@@ -165,7 +165,7 @@ void EQ::Net::DaybreakConnectionManager::ProcessResend()
{
auto iter = m_connections.begin();
while (iter != m_connections.end()) {
auto connection = iter->second;
auto &connection = iter->second;
auto status = connection->m_status;
switch (status)
@@ -1397,4 +1397,4 @@ EQ::Net::SequenceOrder EQ::Net::DaybreakConnection::CompareSequence(uint16_t exp
}
return SequencePast;
}
}
+60 -56
View File
@@ -57,11 +57,11 @@ namespace RoF
static inline uint32 RoFToServerTypelessSlot(structs::TypelessInventorySlot_Struct rofSlot);
static inline uint32 RoFToServerCorpseSlot(uint32 rofCorpseSlot);
// server to client text link converter
static inline void ServerToRoFTextLink(std::string& rofTextLink, const std::string& serverTextLink);
// server to client say link converter
static inline void ServerToRoFSayLink(std::string& rofSayLink, const std::string& serverSayLink);
// client to server text link converter
static inline void RoFToServerTextLink(std::string& serverTextLink, const std::string& rofTextLink);
// client to server say link converter
static inline void RoFToServerSayLink(std::string& serverSayLink, const std::string& rofSayLink);
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot);
@@ -163,22 +163,23 @@ namespace RoF
OUT(level);
eq->unknown06 = 0;
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
eq->bard_focus_id = emu->bard_focus_id;
eq->knockback_angle = emu->sequence;
eq->unknown22 = 0;
OUT(force);
OUT(hit_heading);
OUT(hit_pitch);
OUT(type);
eq->damage = 0;
eq->unknown31 = 0;
OUT(spell);
eq->level2 = eq->level;
eq->effect_flag = emu->buff_unknown;
eq->unknown39 = 14;
eq->unknown43 = 0;
eq->unknown44 = 17;
eq->unknown45 = 0;
eq->unknown46 = -1;
eq->unknown50 = 0;
eq->unknown54 = 0;
OUT(spell_level);
OUT(effect_flag);
eq->spell_gem = 0;
eq->slot.Type = INVALID_INDEX;
eq->slot.Unknown02 = 0;
eq->slot.Slot = INVALID_INDEX;
eq->slot.SubIndex = INVALID_INDEX;
eq->slot.AugIndex = INVALID_INDEX;
eq->slot.Unknown01 = 0;
eq->item_cast_type = 0;
FINISH_ENCODE();
}
@@ -460,7 +461,7 @@ namespace RoF
{
SETUP_VAR_ENCODE(BuffIcon_Struct);
uint32 sz = 12 + (17 * emu->count);
uint32 sz = 12 + (17 * emu->count) + emu->name_lengths; // 17 includes nullterm
__packet->size = sz;
__packet->pBuffer = new unsigned char[sz];
memset(__packet->pBuffer, 0, sz);
@@ -476,7 +477,7 @@ namespace RoF
__packet->WriteUInt32(emu->entries[i].spell_id);
__packet->WriteUInt32(emu->entries[i].tics_remaining);
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
__packet->WriteString("");
__packet->WriteString(emu->entries[i].caster);
}
__packet->WriteUInt8(emu->type); // Unknown
@@ -520,7 +521,7 @@ namespace RoF
std::string old_message = emu->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) + strlen(emu->targetname) + new_message.length() + 39;
@@ -659,8 +660,8 @@ namespace RoF
OUT(spellid);
OUT(damage);
OUT(force);
OUT(meleepush_xy);
OUT(meleepush_z);
OUT(hit_heading);
OUT(hit_pitch);
OUT(special);
FINISH_ENCODE();
@@ -847,7 +848,7 @@ namespace RoF
std::string old_message = emu->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)
// new_message = new_message.substr(0, 512);
@@ -899,7 +900,7 @@ namespace RoF
for (int i = 0; i < 9; ++i) {
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;
}
@@ -2184,11 +2185,11 @@ namespace RoF
outapp->WriteUInt32(emu->skills[r]);
}
outapp->WriteUInt32(25); // Unknown count
outapp->WriteUInt32(structs::MAX_PP_INNATE_SKILL); // Innate Skills count
for (uint32 r = 0; r < 25; r++)
for (uint32 r = 0; r < structs::MAX_PP_INNATE_SKILL; r++)
{
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(emu->InnateSkills[r]); // Innate Skills (regen, slam, etc)
}
outapp->WriteUInt32(structs::MAX_PP_DISCIPLINES); // Discipline count
@@ -3295,7 +3296,7 @@ namespace RoF
std::string old_message = &emu->message[strlen(emu->sayer)];
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 = strlen(emu->sayer) + new_message.length() + 25;
@@ -3369,7 +3370,7 @@ namespace RoF
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToRoFTextLink(new_message, old_message);
ServerToRoFSayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
@@ -3847,9 +3848,12 @@ namespace RoF
OUT(y);
OUT(x);
OUT(z)
OUT(zone_reason);
OUT(zone_reason);
OUT(success);
if (eq->success < 0)
eq->success -= 1;
FINISH_ENCODE();
}
@@ -4352,7 +4356,7 @@ namespace RoF
std::string old_message = InBuffer;
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) + new_message.length() + 1;
@@ -4463,7 +4467,7 @@ namespace RoF
IN(type);
IN(spellid);
IN(damage);
IN(meleepush_xy);
IN(hit_heading);
FINISH_DIRECT_DECODE();
}
@@ -4486,7 +4490,7 @@ namespace RoF
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
RoFToServerTextLink(new_message, old_message);
RoFToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
@@ -5913,19 +5917,19 @@ namespace RoF
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)) {
rofTextLink = serverTextLink;
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
rofSayLink = serverSayLink;
return;
}
auto segments = SplitString(serverTextLink, '\x12');
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() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
rofTextLink.append(segments[segment_iter]);
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
rofSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -5935,36 +5939,36 @@ namespace RoF
// RoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (55)
// Diff: ^
rofTextLink.push_back('\x12');
rofTextLink.append(segments[segment_iter].substr(0, 41));
rofSayLink.push_back('\x12');
rofSayLink.append(segments[segment_iter].substr(0, 41));
if (segments[segment_iter][41] == '0')
rofTextLink.push_back(segments[segment_iter][42]);
rofSayLink.push_back(segments[segment_iter][42]);
else
rofTextLink.push_back('F');
rofSayLink.push_back('F');
rofTextLink.append(segments[segment_iter].substr(43));
rofTextLink.push_back('\x12');
rofSayLink.append(segments[segment_iter].substr(43));
rofSayLink.push_back('\x12');
}
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)) {
serverTextLink = rofTextLink;
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (rofSayLink.find('\x12') == std::string::npos)) {
serverSayLink = rofSayLink;
return;
}
auto segments = SplitString(rofTextLink, '\x12');
auto segments = SplitString(rofSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -5974,14 +5978,14 @@ namespace RoF
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// Diff: ^
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 41));
serverTextLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(41));
serverTextLink.push_back('\x12');
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 {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
}
}
}
+55 -51
View File
@@ -57,11 +57,11 @@ namespace RoF2
static inline uint32 RoF2ToServerTypelessSlot(structs::TypelessInventorySlot_Struct rof2Slot);
static inline uint32 RoF2ToServerCorpseSlot(uint32 rof2CorpseSlot);
// server to client text link converter
static inline void ServerToRoF2TextLink(std::string& rof2TextLink, const std::string& serverTextLink);
// server to client say link converter
static inline void ServerToRoF2SayLink(std::string& rof2SayLink, const std::string& serverSayLink);
// client to server text link converter
static inline void RoF2ToServerTextLink(std::string& serverTextLink, const std::string& rof2TextLink);
// client to server say link converter
static inline void RoF2ToServerSayLink(std::string& serverSayLink, const std::string& rof2SayLink);
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot);
@@ -232,22 +232,23 @@ namespace RoF2
OUT(level);
eq->unknown06 = 0;
eq->instrument_mod = 1.0f + (emu->instrument_mod - 10) / 10.0f;
eq->bard_focus_id = emu->bard_focus_id;
eq->knockback_angle = emu->sequence;
eq->unknown22 = 0;
OUT(force);
OUT(hit_heading);
OUT(hit_pitch);
OUT(type);
eq->damage = 0;
eq->unknown31 = 0;
OUT(spell);
eq->level2 = eq->level;
eq->effect_flag = emu->buff_unknown;
eq->unknown39 = 14;
eq->unknown43 = 0;
eq->unknown44 = 17;
eq->unknown45 = 0;
eq->unknown46 = -1;
eq->unknown50 = 0;
eq->unknown54 = 0;
OUT(spell_level);
OUT(effect_flag);
eq->spell_gem = 0;
eq->slot.Type = INVALID_INDEX;
eq->slot.Unknown02 = 0;
eq->slot.Slot = INVALID_INDEX;
eq->slot.SubIndex = INVALID_INDEX;
eq->slot.AugIndex = INVALID_INDEX;
eq->slot.Unknown01 = 0;
eq->item_cast_type = 0;
FINISH_ENCODE();
}
@@ -528,7 +529,7 @@ namespace RoF2
{
SETUP_VAR_ENCODE(BuffIcon_Struct);
uint32 sz = 12 + (17 * emu->count);
uint32 sz = 12 + (17 * emu->count) + emu->name_lengths; // 17 includes nullterm
__packet->size = sz;
__packet->pBuffer = new unsigned char[sz];
memset(__packet->pBuffer, 0, sz);
@@ -544,7 +545,7 @@ namespace RoF2
__packet->WriteUInt32(emu->entries[i].spell_id);
__packet->WriteUInt32(emu->entries[i].tics_remaining);
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
__packet->WriteString("");
__packet->WriteString(emu->entries[i].caster);
}
__packet->WriteUInt8(emu->type); // Unknown
@@ -588,7 +589,7 @@ namespace RoF2
std::string old_message = emu->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) + strlen(emu->targetname) + new_message.length() + 39;
@@ -727,8 +728,8 @@ namespace RoF2
OUT(spellid);
OUT(damage);
OUT(force);
OUT(meleepush_xy);
OUT(meleepush_z);
OUT(hit_heading);
OUT(hit_pitch);
OUT(special);
FINISH_ENCODE();
@@ -915,7 +916,7 @@ namespace RoF2
std::string old_message = emu->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)
// new_message = new_message.substr(0, 512);
@@ -967,7 +968,7 @@ namespace RoF2
for (int i = 0; i < 9; ++i) {
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;
}
@@ -2261,11 +2262,11 @@ namespace RoF2
outapp->WriteUInt32(emu->skills[r]);
}
outapp->WriteUInt32(25); // Unknown count
outapp->WriteUInt32(structs::MAX_PP_INNATE_SKILL); // Innate Skills count
for (uint32 r = 0; r < 25; r++)
for (uint32 r = 0; r < structs::MAX_PP_INNATE_SKILL; r++)
{
outapp->WriteUInt32(0); // Unknown
outapp->WriteUInt32(emu->InnateSkills[r]); // Innate Skills (regen, slam, etc)
}
outapp->WriteUInt32(structs::MAX_PP_DISCIPLINES); // Discipline count
@@ -3364,7 +3365,7 @@ namespace RoF2
std::string old_message = &emu->message[strlen(emu->sayer)];
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 = strlen(emu->sayer) + new_message.length() + 25;
@@ -3438,7 +3439,7 @@ namespace RoF2
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToRoF2TextLink(new_message, old_message);
ServerToRoF2SayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
@@ -3991,9 +3992,12 @@ namespace RoF2
OUT(y);
OUT(x);
OUT(z)
OUT(zone_reason);
OUT(zone_reason);
OUT(success);
if (eq->success < 0)
eq->success -= 1;
FINISH_ENCODE();
}
@@ -4592,7 +4596,7 @@ namespace RoF2
std::string old_message = InBuffer;
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) + new_message.length() + 1;
@@ -4703,7 +4707,7 @@ namespace RoF2
IN(type);
IN(spellid);
IN(damage);
IN(meleepush_xy);
IN(hit_heading);
FINISH_DIRECT_DECODE();
}
@@ -4726,7 +4730,7 @@ namespace RoF2
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
RoF2ToServerTextLink(new_message, old_message);
RoF2ToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
@@ -6230,19 +6234,19 @@ namespace RoF2
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)) {
rof2TextLink = serverTextLink;
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
rof2SayLink = serverSayLink;
return;
}
auto segments = SplitString(serverTextLink, '\x12');
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() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
rof2TextLink.append(segments[segment_iter]);
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
rof2SayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -6252,29 +6256,29 @@ namespace RoF2
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// Diff:
rof2TextLink.push_back('\x12');
rof2TextLink.append(segments[segment_iter]);
rof2TextLink.push_back('\x12');
rof2SayLink.push_back('\x12');
rof2SayLink.append(segments[segment_iter]);
rof2SayLink.push_back('\x12');
}
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)) {
serverTextLink = rof2TextLink;
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (rof2SayLink.find('\x12') == std::string::npos)) {
serverSayLink = rof2SayLink;
return;
}
auto segments = SplitString(rof2TextLink, '\x12');
auto segments = SplitString(rof2SayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -6284,12 +6288,12 @@ namespace RoF2
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// Diff:
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter]);
serverTextLink.push_back('\x12');
serverSayLink.push_back('\x12');
serverSayLink.append(segments[segment_iter]);
serverSayLink.push_back('\x12');
}
else {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
}
}
}
+1 -1
View File
@@ -164,7 +164,7 @@ namespace RoF2
ItemPacket11 = 111,
ItemPacket12 = 112,
ItemPacketRecovery = 113,
ItemPacket14 = 115
ItemPacket14 = 115 // Parcel? adds to merchant window too
};
} /*item*/
+76 -62
View File
@@ -131,6 +131,7 @@ static const uint32 MAX_PP_LANGUAGE = 32; // was 25
static const uint32 MAX_PP_SPELLBOOK = 720; // was 480
static const uint32 MAX_PP_MEMSPELL = 16; // was 12
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 300;
static const uint32 MAX_PP_DISCIPLINES = 300; // was 200
static const uint32 MAX_GROUP_MEMBERS = 6;
@@ -399,7 +400,7 @@ struct Spawn_Struct_Position
struct Spawn_Struct_Position
{
signed padding0000:12;
signed angle:12; // pitch of camera?
signed y:19;
signed padding0001:1;
@@ -415,7 +416,7 @@ struct Spawn_Struct_Position
signed z:19;
signed padding0020:3;
signed animation:10; // animation
signed animation:10; // SpeedRun
signed deltaY:13;
signed padding0023:9;
};
@@ -429,7 +430,7 @@ struct Spawn_Struct
/*0000*/ //uint8 nullterm1; // hack to null terminate name
/*0064*/ uint32 spawnId;
/*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
Spawn_Struct_Bitfields Bitfields;
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
@@ -1155,8 +1156,8 @@ union
/*01012*/ AA_Array aa_array[MAX_PP_AA_ARRAY]; // [300] 3600 bytes - AAs 12 bytes each
/*04612*/ uint32 skill_count; // Seen 100
/*04616*/ uint32 skills[MAX_PP_SKILL]; // [100] 400 bytes - List of skills
/*05016*/ uint32 unknown15_count; // Seen 25
/*05020*/ uint32 unknown_rof15[25]; // Most are 255 or 0
/*05016*/ uint32 InnateSkills_count; // Seen 25
/*05020*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL]; // Most are 255 or 0
/*05120*/ uint32 discipline_count; // Seen 200
/*05124*/ Disciplines_Struct disciplines; // [200] 800 bytes Known disciplines
/*05924*/ uint32 timestamp_count; // Seen 20
@@ -1461,17 +1462,17 @@ struct Action_Struct
{
/*00*/ uint16 target; // id of target
/*02*/ uint16 source; // id of caster
/*04*/ uint16 level; // level of caster - Seen 0
/*06*/ uint32 unknown06;
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
/*10*/ float instrument_mod;
/*14*/ uint32 bard_focus_id; // seen 0
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
/*22*/ uint32 unknown22;
/*26*/ uint8 type;
/*27*/ uint32 damage;
/*31*/ uint16 unknown31;
/*14*/ float force;
/*18*/ float hit_heading;
/*22*/ float hit_pitch;
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
/*27*/ uint32 damage; // OSX says min_damage
/*31*/ uint16 unknown31; // OSX says tohit
/*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?
/*39*/
};
@@ -1483,25 +1484,21 @@ struct ActionAlt_Struct
{
/*00*/ uint16 target; // id of target
/*02*/ uint16 source; // id of caster
/*04*/ uint16 level; // level of caster - Seen 0
/*06*/ uint32 unknown06;
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
/*10*/ float instrument_mod;
/*14*/ uint32 bard_focus_id; // seen 0
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
/*22*/ uint32 unknown22;
/*26*/ uint8 type;
/*27*/ uint32 damage;
/*31*/ uint16 unknown31;
/*14*/ float force;
/*18*/ float hit_heading;
/*22*/ float hit_pitch;
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
/*27*/ uint32 damage; // OSX says min_damage
/*31*/ uint16 unknown31; // OSX says tohit
/*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?
/*39*/ uint32 unknown39; // New field to Underfoot - Seen 14
/*43*/ uint8 unknown43; // New field to Underfoot - Seen 0
/*44*/ uint8 unknown44; // New field to Underfoot - Seen 17
/*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
/*39*/ uint8 spell_gem;
/*40*/ InventorySlot_Struct slot;
/*52*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
/*56*/
};
@@ -1516,9 +1513,9 @@ struct CombatDamage_Struct
/* 05 */ uint32 spellid;
/* 09 */ int32 damage;
/* 13 */ float force; // cd cc cc 3d
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
/* 21 */ float meleepush_z;
/* 25 */ uint8 unknown25; // was [9]
/* 17 */ float hit_heading; // see above notes in Action_Struct
/* 21 */ float hit_pitch;
/* 25 */ uint8 secondary; // 0 for primary hand, 1 for secondary
/* 26 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
/* 30 */
};
@@ -1826,6 +1823,20 @@ struct MoveItem_Struct
/*0028*/
};
struct MultiMoveItemSub_Struct
{
/*0000*/ InventorySlot_Struct from_slot;
/*0012*/ InventorySlot_Struct to_slot;
/*0024*/ uint32 number_in_stack;
/*0028*/ uint8 unknown[8];
};
struct MultiMoveItem_Struct
{
/*0000*/ uint32 count;
/*0004*/ MultiMoveItemSub_Struct moves[0];
};
//
// from_slot/to_slot
// -1 - destroy
@@ -3590,21 +3601,6 @@ struct GuildSetRank_Struct
/*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
uint8 level;
uint8 class_;
@@ -3631,20 +3627,21 @@ struct Ground_Spawn{
struct Ground_Spawns {
struct Ground_Spawn spawn[50]; //Assigned max number to allow
};
struct PetitionBug_Struct{
uint32 petition_number;
uint32 unknown4;
char accountname[64];
uint32 zoneid;
char name[64];
uint32 level;
uint32 class_;
uint32 race;
uint32 unknown152[3];
uint32 time;
uint32 unknown168;
char text[1028];
};
//struct PetitionBug_Struct{
// uint32 petition_number;
// uint32 unknown4;
// char accountname[64];
// uint32 zoneid;
// char name[64];
// uint32 level;
// uint32 class_;
// uint32 race;
// uint32 unknown152[3];
// uint32 time;
// uint32 unknown168;
// char text[1028];
//};
struct ApproveZone_Struct {
char name[64];
@@ -5088,6 +5085,23 @@ struct CrystalCountUpdate_Struct
/*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*/
}; /*RoF2*/
+60 -60
View File
@@ -131,6 +131,7 @@ static const uint32 MAX_PP_LANGUAGE = 32; // was 25
static const uint32 MAX_PP_SPELLBOOK = 720; // was 480
static const uint32 MAX_PP_MEMSPELL = 16; // was 12
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 300;
static const uint32 MAX_PP_DISCIPLINES = 200; // was 100
static const uint32 MAX_GROUP_MEMBERS = 6;
@@ -407,7 +408,7 @@ struct Spawn_Struct
/*0000*/ //uint8 nullterm1; // hack to null terminate name
/*0064*/ uint32 spawnId;
/*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
Spawn_Struct_Bitfields Bitfields;
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
@@ -1096,8 +1097,8 @@ union
/*01012*/ AA_Array aa_array[MAX_PP_AA_ARRAY]; // [300] 3600 bytes - AAs 12 bytes each
/*04612*/ uint32 skill_count; // Seen 100
/*04616*/ uint32 skills[MAX_PP_SKILL]; // [100] 400 bytes - List of skills
/*05016*/ uint32 unknown15_count; // Seen 25
/*05020*/ uint32 unknown_rof15[25]; // Most are 255 or 0
/*05016*/ uint32 InnateSkills_count; // Seen 25
/*05020*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL]; // Most are 255 or 0
/*05120*/ uint32 discipline_count; // Seen 200
/*05124*/ Disciplines_Struct disciplines; // [200] 800 bytes Known disciplines
/*05924*/ uint32 timestamp_count; // Seen 20
@@ -1449,17 +1450,17 @@ struct Action_Struct
{
/*00*/ uint16 target; // id of target
/*02*/ uint16 source; // id of caster
/*04*/ uint16 level; // level of caster - Seen 0
/*06*/ uint32 unknown06;
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
/*10*/ float instrument_mod;
/*14*/ uint32 bard_focus_id; // seen 0
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
/*22*/ uint32 unknown22;
/*26*/ uint8 type;
/*27*/ uint32 damage;
/*31*/ uint16 unknown31;
/*14*/ float force;
/*18*/ float hit_heading;
/*22*/ float hit_pitch;
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
/*27*/ uint32 damage; // OSX says min_damage
/*31*/ uint16 unknown31; // OSX says tohit
/*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?
/*39*/
};
@@ -1471,25 +1472,21 @@ struct ActionAlt_Struct
{
/*00*/ uint16 target; // id of target
/*02*/ uint16 source; // id of caster
/*04*/ uint16 level; // level of caster - Seen 0
/*06*/ uint32 unknown06;
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
/*10*/ float instrument_mod;
/*14*/ uint32 bard_focus_id; // seen 0
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
/*22*/ uint32 unknown22;
/*26*/ uint8 type;
/*27*/ uint32 damage;
/*31*/ uint16 unknown31;
/*14*/ float force;
/*18*/ float hit_heading;
/*22*/ float hit_pitch;
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
/*27*/ uint32 damage; // OSX says min_damage
/*31*/ uint16 unknown31; // OSX says tohit
/*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?
/*39*/ uint32 unknown39; // New field to Underfoot - Seen 14
/*43*/ uint8 unknown43; // New field to Underfoot - Seen 0
/*44*/ uint8 unknown44; // New field to Underfoot - Seen 17
/*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
/*39*/ uint8 spell_gem;
/*40*/ InventorySlot_Struct slot;
/*52*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
/*56*/
};
@@ -1504,9 +1501,9 @@ struct CombatDamage_Struct
/* 05 */ uint32 spellid;
/* 09 */ int32 damage;
/* 13 */ float force; // cd cc cc 3d
/* 17 */ float meleepush_xy; // see above notes in Action_Struct
/* 21 */ float meleepush_z;
/* 25 */ uint8 unknown25; // was [9]
/* 17 */ float hit_heading; // see above notes in Action_Struct
/* 21 */ float hit_pitch;
/* 25 */ uint8 secondary; // 0 for primary hand, 1 for secondary
/* 26 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
/* 30 */
};
@@ -3544,21 +3541,6 @@ struct GuildSetRank_Struct
/*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
uint8 level;
uint8 class_;
@@ -3585,20 +3567,21 @@ struct Ground_Spawn{
struct Ground_Spawns {
struct Ground_Spawn spawn[50]; //Assigned max number to allow
};
struct PetitionBug_Struct{
uint32 petition_number;
uint32 unknown4;
char accountname[64];
uint32 zoneid;
char name[64];
uint32 level;
uint32 class_;
uint32 race;
uint32 unknown152[3];
uint32 time;
uint32 unknown168;
char text[1028];
};
//struct PetitionBug_Struct{
// uint32 petition_number;
// uint32 unknown4;
// char accountname[64];
// uint32 zoneid;
// char name[64];
// uint32 level;
// uint32 class_;
// uint32 race;
// uint32 unknown152[3];
// uint32 time;
// uint32 unknown168;
// char text[1028];
//};
struct ApproveZone_Struct {
char name[64];
@@ -5019,6 +5002,23 @@ struct MercenaryMerchantRequest_Struct {
struct MercenaryMerchantResponse_Struct {
/*0000*/ uint32 ResponseType;
/*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*/
+46 -65
View File
@@ -53,11 +53,11 @@ namespace SoD
static inline uint32 SoDToServerSlot(uint32 sodSlot);
static inline uint32 SoDToServerCorpseSlot(uint32 sodCorpseSlot);
// server to client text link converter
static inline void ServerToSoDTextLink(std::string& sodTextLink, const std::string& serverTextLink);
// server to client say link converter
static inline void ServerToSoDSayLink(std::string& sodSayLink, const std::string& serverSayLink);
// client to server text link converter
static inline void SoDToServerTextLink(std::string& serverTextLink, const std::string& sodTextLink);
// client to server say link converter
static inline void SoDToServerSayLink(std::string& serverSayLink, const std::string& sodSayLink);
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot);
@@ -161,15 +161,14 @@ namespace SoD
OUT(source);
OUT(level);
OUT(instrument_mod);
eq->sequence = emu->sequence;
OUT(force);
OUT(hit_heading);
OUT(hit_pitch);
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;
OUT(spell_level);
OUT(effect_flag); // if this is 4, a buff icon is made
FINISH_ENCODE();
}
@@ -346,7 +345,7 @@ namespace SoD
std::string old_message = emu->message;
std::string new_message;
ServerToSoDTextLink(new_message, old_message);
ServerToSoDSayLink(new_message, old_message);
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
@@ -458,8 +457,8 @@ namespace SoD
OUT(spellid);
OUT(damage);
OUT(force);
OUT(meleepush_xy);
OUT(meleepush_z);
OUT(hit_heading);
OUT(hit_pitch);
OUT(special);
FINISH_ENCODE();
@@ -625,7 +624,7 @@ namespace SoD
std::string old_message = emu->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)
// new_message = new_message.substr(0, 512);
@@ -677,7 +676,7 @@ namespace SoD
for (int i = 0; i < 9; ++i) {
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;
}
@@ -1605,6 +1604,7 @@ namespace SoD
OUT(copper_cursor);
OUT_array(skills, structs::MAX_PP_SKILL); // 1:1 direct copy (100 dword)
OUT_array(InnateSkills, structs::MAX_PP_INNATE_SKILL); // 1:1 direct copy (25 dword)
// OUT(unknown04760[236]);
OUT(toxicity);
@@ -2155,7 +2155,7 @@ namespace SoD
std::string old_message = &emu->message[strlen(emu->sayer)];
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 = strlen(emu->sayer) + new_message.length() + 25;
@@ -2251,7 +2251,7 @@ namespace SoD
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToSoDTextLink(new_message, old_message);
ServerToSoDSayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
@@ -2932,25 +2932,6 @@ namespace SoD
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_LENGTH_EXACT(structs::CastSpell_Struct);
@@ -2971,7 +2952,7 @@ namespace SoD
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
std::string new_message;
SoDToServerTextLink(new_message, old_message);
SoDToServerSayLink(new_message, old_message);
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
__packet->pBuffer = new unsigned char[__packet->size];
@@ -3085,7 +3066,7 @@ namespace SoD
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
SoDToServerTextLink(new_message, old_message);
SoDToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
@@ -3935,19 +3916,19 @@ namespace SoD
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)) {
sodTextLink = serverTextLink;
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
sodSayLink = serverSayLink;
return;
}
auto segments = SplitString(serverTextLink, '\x12');
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() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
sodTextLink.append(segments[segment_iter]);
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
sodSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -3957,37 +3938,37 @@ namespace SoD
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
// Diff: ^^^^^ ^
sodTextLink.push_back('\x12');
sodTextLink.append(segments[segment_iter].substr(0, 31));
sodTextLink.append(segments[segment_iter].substr(36, 5));
sodSayLink.push_back('\x12');
sodSayLink.append(segments[segment_iter].substr(0, 31));
sodSayLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter][41] == '0')
sodTextLink.push_back(segments[segment_iter][42]);
sodSayLink.push_back(segments[segment_iter][42]);
else
sodTextLink.push_back('F');
sodSayLink.push_back('F');
sodTextLink.append(segments[segment_iter].substr(43));
sodTextLink.push_back('\x12');
sodSayLink.append(segments[segment_iter].substr(43));
sodSayLink.push_back('\x12');
}
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)) {
serverTextLink = sodTextLink;
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (sodSayLink.find('\x12') == std::string::npos)) {
serverSayLink = sodSayLink;
return;
}
auto segments = SplitString(sodTextLink, '\x12');
auto segments = SplitString(sodSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -3997,16 +3978,16 @@ namespace SoD
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// Diff: ^^^^^ ^
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(36));
serverTextLink.push_back('\x12');
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 {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
}
}
}
-1
View File
@@ -104,7 +104,6 @@ D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_BazaarSearch)
D(OP_Buff)
D(OP_Bug)
D(OP_CastSpell)
D(OP_ChannelMessage)
D(OP_CharacterCreate)
+65 -69
View File
@@ -292,7 +292,7 @@ struct Spawn_Struct
/*0000*/ //uint8 nullterm1; // hack to null terminate name
/*0064*/ uint32 spawnId;
/*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
Spawn_Struct_Bitfields Bitfields;
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
@@ -818,6 +818,7 @@ static const uint32 MAX_PP_LANGUAGE = 25; //
static const uint32 MAX_PP_SPELLBOOK = 480; // Confirmed 60 pages on Live now
static const uint32 MAX_PP_MEMSPELL = 10; //was 9 now 10 on Live
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
static const uint32 MAX_GROUP_MEMBERS = 6;
static const uint32 MAX_RECAST_TYPES = 20;
@@ -923,7 +924,8 @@ struct PlayerProfile_Struct
/*06488*/ uint32 silver_cursor; // Silver Pieces on cursor
/*06492*/ uint32 copper_cursor; // Copper Pieces on cursor
/*06496*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
/*06896*/ uint8 unknown04760[136];
/*06896*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
/*06996*/ uint8 unknown04760[36];
/*07032*/ uint32 toxicity; // Potion Toxicity (15=too toxic, each potion adds 3)
/*07036*/ uint32 thirst_level; // Drink (ticks till next drink)
/*07040*/ uint32 hunger_level; // Food (ticks till next eat)
@@ -1213,20 +1215,18 @@ struct Action_Struct
{
/* 00 */ uint16 target; // id of target
/* 02 */ uint16 source; // id of caster
/* 04 */ uint16 level; // level of caster
/* 06 */ uint16 instrument_mod; // seems to be fixed to 0x0A
/* 08 */ uint32 unknown08;
/* 12 */ uint16 unknown16;
// some kind of sequence that's the same in both actions
// as well as the combat damage, to tie em together?
/* 14 */ float sequence; // was uint32
/* 18 */ uint32 unknown18;
/* 22 */ uint8 type; // 231 (0xE7) for spells
/* 23 */ uint32 unknown23;
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
/* 10 */ float force;
/* 14 */ float hit_heading;
/* 18 */ float hit_pitch;
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
/* 23 */ uint16 unknown23; // OSX says min_damage
/* 25 */ uint16 unknown25; // OSX says tohit
/* 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
/* 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 */
};
@@ -1235,26 +1235,23 @@ struct Action_Struct
// has to do with buff blocking??
struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
{
/*0000*/ uint16 target; // Target ID
/*0002*/ uint16 source; // SourceID
/*0004*/ uint16 level; // level of caster
/*0006*/ uint16 instrument_mod; // seems to be fixed to 0x0A
/*0008*/ uint32 unknown08;
/*0012*/ uint16 unknown16;
/*0014*/ uint32 sequence;
/*0018*/ uint32 unknown18;
/*0022*/ uint8 type; // Casts, Falls, Bashes, etc...
/*0023*/ uint32 damage; // Amount of Damage
/*0027*/ uint16 spell; // SpellID
/*0029*/ uint8 unknown29;
/*0030*/ uint8 buff_unknown; // if this is 4, a buff icon is made
/*0031*/ uint32 unknown0031; // seen 00 00 00 00
/*0035*/ uint8 unknown0035; // seen 00
/*0036*/ uint32 unknown0036; // seen ff ff ff ff
/*0040*/ uint32 unknown0040; // seen ff ff ff ff
/*0044*/ uint32 unknown0044; // seen ff ff ff ff
/*0048*/ uint32 unknown0048; // seen 00 00 00 00
/*0052*/ uint32 unknown0052; // seen 00 00 00 00
/*0000*/ uint16 target; // id of target
/*0002*/ uint16 source; // id of caster
/*0004*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/*0006*/ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
/*0010*/ float force;
/*0014*/ float hit_heading;
/*0018*/ float hit_pitch;
/*0022*/ uint8 type; // 231 (0xE7) for spells, skill
/*0023*/ uint16 unknown23; // OSX says min_damage
/*0025*/ uint16 unknown25; // OSX says tohit
/*0027*/ uint16 spell; // spell id being cast
/*0029*/ 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
/*0030*/ uint8 effect_flag; // if this is 4, a buff icon is made
/*0031*/ uint8 spell_slot;
/*0032*/ uint32 slot[5];
/*0052*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
/*0056*/
};
@@ -1269,9 +1266,9 @@ struct CombatDamage_Struct
/* 05 */ uint16 spellid;
/* 07 */ int32 damage;
/* 11 */ float force; // cd cc cc 3d
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */ uint8 unknown23; // was [9]
/* 15 */ float hit_heading; // see above notes in Action_Struct
/* 19 */ float hit_pitch;
/* 23 */ uint8 secondary; // 0 for primary hand, 1 for secondary
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
/* 28 */
};
@@ -3006,24 +3003,6 @@ struct GuildMakeLeader{
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
uint8 level;
uint8 class_;
@@ -3050,20 +3029,21 @@ struct Ground_Spawn{
struct Ground_Spawns {
struct Ground_Spawn spawn[50]; //Assigned max number to allow
};
struct PetitionBug_Struct{
uint32 petition_number;
uint32 unknown4;
char accountname[64];
uint32 zoneid;
char name[64];
uint32 level;
uint32 class_;
uint32 race;
uint32 unknown152[3];
uint32 time;
uint32 unknown168;
char text[1028];
};
//struct PetitionBug_Struct{
// uint32 petition_number;
// uint32 unknown4;
// char accountname[64];
// uint32 zoneid;
// char name[64];
// uint32 level;
// uint32 class_;
// uint32 race;
// uint32 unknown152[3];
// uint32 time;
// uint32 unknown168;
// char text[1028];
//};
struct ApproveZone_Struct {
char name[64];
@@ -4400,6 +4380,22 @@ struct MercenaryAssign_Struct {
/*0004*/ uint32 MercUnk01; //
/*0008*/ uint32 MercUnk02; //
/*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*/
+57 -46
View File
@@ -53,11 +53,11 @@ namespace SoF
static inline uint32 SoFToServerSlot(uint32 sofSlot);
static inline uint32 SoFToServerCorpseSlot(uint32 sofCorpseSlot);
// server to client text link converter
static inline void ServerToSoFTextLink(std::string& sofTextLink, const std::string& serverTextLink);
// server to client say link converter
static inline void ServerToSoFSayLink(std::string& sofSayLink, const std::string& serverSayLink);
// client to server text link converter
static inline void SoFToServerTextLink(std::string& serverTextLink, const std::string& sofTextLink);
// client to server say link converter
static inline void SoFToServerSayLink(std::string& serverSayLink, const std::string& sofSayLink);
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
@@ -161,15 +161,14 @@ namespace SoF
OUT(source);
OUT(level);
OUT(instrument_mod);
eq->sequence = emu->sequence;
OUT(force);
OUT(hit_heading);
OUT(hit_pitch);
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;
OUT(spell_level);
OUT(effect_flag); // if this is 4, a buff icon is made
FINISH_ENCODE();
}
@@ -328,7 +327,7 @@ namespace SoF
std::string old_message = emu->message;
std::string new_message;
ServerToSoFTextLink(new_message, old_message);
ServerToSoFSayLink(new_message, old_message);
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
@@ -440,8 +439,8 @@ namespace SoF
OUT(spellid);
OUT(damage);
OUT(force);
OUT(meleepush_xy);
OUT(meleepush_z);
OUT(hit_heading);
OUT(hit_pitch);
FINISH_ENCODE();
}
@@ -613,7 +612,7 @@ namespace SoF
std::string old_message = emu->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)
// new_message = new_message.substr(0, 512);
@@ -665,7 +664,7 @@ namespace SoF
for (int i = 0; i < 9; ++i) {
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;
}
@@ -1276,6 +1275,7 @@ namespace SoF
OUT(copper_cursor);
OUT_array(skills, structs::MAX_PP_SKILL); // 1:1 direct copy (100 dword)
OUT_array(InnateSkills, structs::MAX_PP_INNATE_SKILL); // 1:1 direct copy (25 dword)
// OUT(unknown04760[236]);
OUT(toxicity);
@@ -1813,7 +1813,7 @@ namespace SoF
std::string old_message = &emu->message[strlen(emu->sayer)];
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 = strlen(emu->sayer) + new_message.length() + 25;
@@ -1881,7 +1881,7 @@ namespace SoF
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToSoFTextLink(new_message, old_message);
ServerToSoFSayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
@@ -2384,6 +2384,17 @@ namespace SoF
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_LENGTH_EXACT(structs::CastSpell_Struct);
@@ -2403,7 +2414,7 @@ namespace SoF
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
std::string new_message;
SoFToServerTextLink(new_message, old_message);
SoFToServerSayLink(new_message, old_message);
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
__packet->pBuffer = new unsigned char[__packet->size];
@@ -2517,7 +2528,7 @@ namespace SoF
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
SoFToServerTextLink(new_message, old_message);
SoFToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
@@ -3304,19 +3315,19 @@ namespace SoF
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)) {
sofTextLink = serverTextLink;
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
sofSayLink = serverSayLink;
return;
}
auto segments = SplitString(serverTextLink, '\x12');
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() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
sofTextLink.append(segments[segment_iter]);
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
sofSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -3326,37 +3337,37 @@ namespace SoF
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
// Diff: ^^^^^ ^
sofTextLink.push_back('\x12');
sofTextLink.append(segments[segment_iter].substr(0, 31));
sofTextLink.append(segments[segment_iter].substr(36, 5));
sofSayLink.push_back('\x12');
sofSayLink.append(segments[segment_iter].substr(0, 31));
sofSayLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter][41] == '0')
sofTextLink.push_back(segments[segment_iter][42]);
sofSayLink.push_back(segments[segment_iter][42]);
else
sofTextLink.push_back('F');
sofSayLink.push_back('F');
sofTextLink.append(segments[segment_iter].substr(43));
sofTextLink.push_back('\x12');
sofSayLink.append(segments[segment_iter].substr(43));
sofSayLink.push_back('\x12');
}
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)) {
serverTextLink = sofTextLink;
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (sofSayLink.find('\x12') == std::string::npos)) {
serverSayLink = sofSayLink;
return;
}
auto segments = SplitString(sofTextLink, '\x12');
auto segments = SplitString(sofSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -3366,16 +3377,16 @@ namespace SoF
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// Diff: ^^^^^ ^
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(36));
serverTextLink.push_back('\x12');
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 {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
}
}
}
+1
View File
@@ -95,6 +95,7 @@ D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_Buff)
D(OP_Bug)
D(OP_CastSpell)
D(OP_ChannelMessage)
D(OP_CharacterCreate)
+122 -66
View File
@@ -52,6 +52,25 @@ struct EnterWorld_Struct {
struct WorldObjectsSent_Struct {
};
// yep, even SoF had a version of the new inventory system, used by OP_MoveMultipleItems
struct InventorySlot_Struct
{
/*000*/ int32 Type; // Worn and Normal inventory = 0, Bank = 1, Shared Bank = 2, Trade = 3, World = 4, Limbo = 5
/*004*/ int32 Slot;
/*008*/ int32 SubIndex;
/*012*/ int32 AugIndex;
/*016*/ int32 Unknown01;
};
// unsure if they have a version of this, completeness though
struct TypelessInventorySlot_Struct
{
/*000*/ int32 Slot;
/*004*/ int32 SubIndex;
/*008*/ int32 AugIndex;
/*012*/ int32 Unknown01;
};
/* Name Approval Struct */
/* Len: */
/* Opcode: 0x8B20*/
@@ -307,7 +326,8 @@ union
/*0725*/ uint8 targetable; // 1 = Targetable 0 = Not Targetable (is_npc?)
/*0726*/ uint8 unknown0726[4];
/*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;
/*0743*/ signed padding00:12; // ***Placeholder
signed x:19; // x coord
@@ -799,6 +819,7 @@ static const uint32 MAX_PP_LANGUAGE = 25; //
static const uint32 MAX_PP_SPELLBOOK = 480; // Confirmed 60 pages on Live now
static const uint32 MAX_PP_MEMSPELL = 10; //was 9 now 10 on Live
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
static const uint32 MAX_GROUP_MEMBERS = 6;
static const uint32 MAX_RECAST_TYPES = 20;
@@ -903,7 +924,8 @@ struct PlayerProfile_Struct //23576 Octets
/*06488*/ uint32 silver_cursor; // Silver Pieces on cursor
/*06492*/ uint32 copper_cursor; // Copper Pieces on cursor
/*06496*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
/*06896*/ uint8 unknown04760[136];
/*06896*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
/*06996*/ uint8 unknown04760[36];
/*07032*/ uint32 toxicity; // Potion Toxicity (15=too toxic, each potion adds 3)
/*07036*/ uint32 thirst_level; // Drink (ticks till next drink)
/*07040*/ uint32 hunger_level; // Food (ticks till next eat)
@@ -1193,20 +1215,18 @@ struct Action_Struct
{
/* 00 */ uint16 target; // id of target
/* 02 */ uint16 source; // id of caster
/* 04 */ uint16 level; // level of caster
/* 06 */ uint16 instrument_mod; // seems to be fixed to 0x0A
/* 08 */ uint32 unknown08;
/* 12 */ uint16 unknown16;
// some kind of sequence that's the same in both actions
// as well as the combat damage, to tie em together?
/* 14 */ float sequence; // was uint32
/* 18 */ uint32 unknown18;
/* 22 */ uint8 type; // 231 (0xE7) for spells
/* 23 */ uint32 unknown23;
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
/* 10 */ float force;
/* 14 */ float hit_heading;
/* 18 */ float hit_pitch;
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
/* 23 */ uint16 unknown23; // OSX says min_damage
/* 25 */ uint16 unknown25; // OSX says tohit
/* 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
/* 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 */
};
@@ -1215,26 +1235,23 @@ struct Action_Struct
// has to do with buff blocking??
struct ActionAlt_Struct // ActionAlt_Struct - Size: 56 bytes
{
/*0000*/ uint16 target; // Target ID
/*0002*/ uint16 source; // SourceID
/*0004*/ uint16 level; // level of caster
/*0006*/ uint16 instrument_mod; // seems to be fixed to 0x0A
/*0008*/ uint32 unknown08;
/*0012*/ uint16 unknown16;
/*0014*/ uint32 sequence;
/*0018*/ uint32 unknown18;
/*0022*/ uint8 type; // Casts, Falls, Bashes, etc...
/*0023*/ uint32 damage; // Amount of Damage
/*0027*/ uint16 spell; // SpellID
/*0029*/ uint8 unknown29;
/*0030*/ uint8 buff_unknown; // if this is 4, a buff icon is made
/*0031*/ uint32 unknown0031; // seen 00 00 00 00
/*0035*/ uint8 unknown0035; // seen 00
/*0036*/ uint32 unknown0036; // seen ff ff ff ff
/*0040*/ uint32 unknown0040; // seen ff ff ff ff
/*0044*/ uint32 unknown0044; // seen ff ff ff ff
/*0048*/ uint32 unknown0048; // seen 00 00 00 00
/*0052*/ uint32 unknown0052; // seen 00 00 00 00
/*0000*/ uint16 target; // id of target
/*0002*/ uint16 source; // id of caster
/*0004*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/*0006*/ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
/*0010*/ float force;
/*0014*/ float hit_heading;
/*0018*/ float hit_pitch;
/*0022*/ uint8 type; // 231 (0xE7) for spells, skill
/*0023*/ uint16 unknown23; // OSX says min_damage
/*0025*/ uint16 unknown25; // OSX says tohit
/*0027*/ uint16 spell; // spell id being cast
/*0029*/ 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
/*0030*/ uint8 effect_flag; // if this is 4, a buff icon is made
/*0031*/ uint8 spell_slot;
/*0032*/ uint32 slot[5];
/*0052*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
/*0056*/
};
@@ -1249,9 +1266,10 @@ struct CombatDamage_Struct
/* 05 */ uint16 spellid;
/* 07 */ int32 damage;
/* 11 */ float force; // cd cc cc 3d
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */ uint8 unknown23[5]; // was [9] this appears unrelated to the stuff the other clients do here?
/* 15 */ float hit_heading; // see above notes in Action_Struct
/* 19 */ float hit_pitch;
/* 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 */
};
@@ -1555,6 +1573,19 @@ struct MoveItem_Struct
/*0012*/
};
struct MultiMoveItemSub_Struct
{
/*0000*/ InventorySlot_Struct from_slot;
/*0020*/ uint32 number_in_stack; // so the amount we are moving from the source
/*0024*/ InventorySlot_Struct to_slot;
};
struct MultiMoveItem_Struct
{
/*0000*/ uint32 count;
/*0004*/ MultiMoveItemSub_Struct moves[0];
};
//
// from_slot/to_slot
// -1 - destroy
@@ -2872,23 +2903,31 @@ struct GuildMakeLeader{
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;
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];
// 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
uint8 level;
uint8 class_;
@@ -2915,20 +2954,21 @@ struct Ground_Spawn{
struct Ground_Spawns {
struct Ground_Spawn spawn[50]; //Assigned max number to allow
};
struct PetitionBug_Struct{
uint32 petition_number;
uint32 unknown4;
char accountname[64];
uint32 zoneid;
char name[64];
uint32 level;
uint32 class_;
uint32 race;
uint32 unknown152[3];
uint32 time;
uint32 unknown168;
char text[1028];
};
//struct PetitionBug_Struct{
// uint32 petition_number;
// uint32 unknown4;
// char accountname[64];
// uint32 zoneid;
// char name[64];
// uint32 level;
// uint32 class_;
// uint32 race;
// uint32 unknown152[3];
// uint32 time;
// uint32 unknown168;
// char text[1028];
//};
struct ApproveZone_Struct {
char name[64];
@@ -4112,6 +4152,22 @@ struct AltCurrencySellItem_Struct {
/*004*/ uint32 slot_id;
/*006*/ uint32 charges;
/*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*/
+59 -44
View File
@@ -52,11 +52,11 @@ namespace Titanium
static inline uint32 TitaniumToServerSlot(int16 titaniumSlot);
static inline uint32 TitaniumToServerCorpseSlot(int16 titaniumCorpseSlot);
// server to client text link converter
static inline void ServerToTitaniumTextLink(std::string& titaniumTextLink, const std::string& serverTextLink);
// server to client say link converter
static inline void ServerToTitaniumSayLink(std::string& titaniumSayLink, const std::string& serverSayLink);
// client to server text link converter
static inline void TitaniumToServerTextLink(std::string& serverTextLink, const std::string& titaniumTextLink);
// client to server say link converter
static inline void TitaniumToServerSayLink(std::string& serverSayLink, const std::string& titaniumSayLink);
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
@@ -164,11 +164,14 @@ namespace Titanium
OUT(source);
OUT(level);
OUT(instrument_mod);
OUT(sequence);
OUT(force);
OUT(hit_heading);
OUT(hit_pitch);
OUT(type);
//OUT(damage);
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();
}
@@ -290,7 +293,7 @@ namespace Titanium
std::string old_message = emu->message;
std::string new_message;
ServerToTitaniumTextLink(new_message, old_message);
ServerToTitaniumSayLink(new_message, old_message);
in->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
@@ -358,8 +361,8 @@ namespace Titanium
OUT(spellid);
OUT(damage);
OUT(force);
OUT(meleepush_xy);
OUT(meleepush_z);
OUT(hit_heading);
OUT(hit_pitch);
FINISH_ENCODE();
}
@@ -532,7 +535,7 @@ namespace Titanium
std::string old_message = emu->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)
// new_message = new_message.substr(0, 512);
@@ -574,7 +577,7 @@ namespace Titanium
for (int i = 0; i < 9; ++i) {
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;
}
@@ -1020,6 +1023,7 @@ namespace Titanium
OUT(copper_cursor);
OUT_array(skills, structs::MAX_PP_SKILL); // 1:1 direct copy (100 dword)
OUT_array(InnateSkills, structs::MAX_PP_INNATE_SKILL); // 1:1 direct copy (25 dword)
// OUT(unknown04760[236]);
OUT(toxicity);
@@ -1401,7 +1405,7 @@ namespace Titanium
std::string old_message = &emu->message[strlen(emu->sayer)];
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 = strlen(emu->sayer) + new_message.length() + 25;
@@ -1457,7 +1461,7 @@ namespace Titanium
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToTitaniumTextLink(new_message, old_message);
ServerToTitaniumSayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct) +
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct) +
@@ -1788,6 +1792,17 @@ namespace Titanium
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_LENGTH_EXACT(structs::CastSpell_Struct);
@@ -1807,7 +1822,7 @@ namespace Titanium
std::string old_message = (char *)&__eq_buffer[sizeof(ChannelMessage_Struct)];
std::string new_message;
TitaniumToServerTextLink(new_message, old_message);
TitaniumToServerSayLink(new_message, old_message);
__packet->size = sizeof(ChannelMessage_Struct) + new_message.length() + 1;
__packet->pBuffer = new unsigned char[__packet->size];
@@ -1879,7 +1894,7 @@ namespace Titanium
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
TitaniumToServerTextLink(new_message, old_message);
TitaniumToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
@@ -2473,19 +2488,19 @@ namespace Titanium
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)) {
titaniumTextLink = serverTextLink;
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
titaniumSayLink = serverSayLink;
return;
}
auto segments = SplitString(serverTextLink, '\x12');
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() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
titaniumTextLink.append(segments[segment_iter]);
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
titaniumSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -2495,37 +2510,37 @@ namespace Titanium
// 6.2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXXXXX (45)
// Diff: ^^^^^ ^ ^^^^^
titaniumTextLink.push_back('\x12');
titaniumTextLink.append(segments[segment_iter].substr(0, 31));
titaniumTextLink.append(segments[segment_iter].substr(36, 5));
titaniumSayLink.push_back('\x12');
titaniumSayLink.append(segments[segment_iter].substr(0, 31));
titaniumSayLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter][41] == '0')
titaniumTextLink.push_back(segments[segment_iter][42]);
titaniumSayLink.push_back(segments[segment_iter][42]);
else
titaniumTextLink.push_back('F');
titaniumSayLink.push_back('F');
titaniumTextLink.append(segments[segment_iter].substr(48));
titaniumTextLink.push_back('\x12');
titaniumSayLink.append(segments[segment_iter].substr(48));
titaniumSayLink.push_back('\x12');
}
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)) {
serverTextLink = titaniumTextLink;
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (titaniumSayLink.find('\x12') == std::string::npos)) {
serverSayLink = titaniumSayLink;
return;
}
auto segments = SplitString(titaniumTextLink, '\x12');
auto segments = SplitString(titaniumSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -2535,18 +2550,18 @@ namespace Titanium
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// Diff: ^^^^^ ^ ^^^^^
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0');
serverTextLink.push_back(segments[segment_iter][36]);
serverTextLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(37));
serverTextLink.push_back('\x12');
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 {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
}
}
}
+1
View File
@@ -78,6 +78,7 @@ D(OP_AdventureMerchantSell)
D(OP_ApplyPoison)
D(OP_AugmentItem)
D(OP_Buff)
D(OP_Bug)
D(OP_CastSpell)
D(OP_ChannelMessage)
D(OP_CharacterCreate)
+102 -45
View File
@@ -48,6 +48,23 @@ struct EnterWorld_Struct {
/*068*/ uint32 return_home; // 01 on "Return Home", 00 if not
};
// yep, even tit had a version of the new inventory system, used by OP_MoveMultipleItems
struct InventorySlot_Struct
{
/*000*/ int32 Type; // Worn and Normal inventory = 0, Bank = 1, Shared Bank = 2, Trade = 3, World = 4, Limbo = 5
/*004*/ int32 Slot;
/*008*/ int32 SubIndex; // no aug index in Tit
/*012*/ int32 Unknown01;
};
// unsure if they have a version of this, completeness though
struct TypelessInventorySlot_Struct
{
/*000*/ int32 Slot;
/*004*/ int32 SubIndex; // no aug index in Tit
/*008*/ int32 Unknown01;
};
/* Name Approval Struct */
/* Len: */
/* Opcode: 0x8B20*/
@@ -310,7 +327,7 @@ union
// horse: 0=brown, 1=white, 2=black, 3=tan
};
/*0340*/ uint32 spawnId; // Spawn Id
/*0344*/ uint8 unknown0344[4];
/*0344*/ float bounding_radius; // used in melee, overrides calc
/*0348*/ TintProfile equipment_tint;
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
/*0385*/
@@ -740,6 +757,7 @@ static const uint32 MAX_PP_LANGUAGE = 28;
static const uint32 MAX_PP_SPELLBOOK = 400;
static const uint32 MAX_PP_MEMSPELL = 9;
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 240;
static const uint32 MAX_GROUP_MEMBERS = 6;
static const uint32 MAX_RECAST_TYPES = 20;
@@ -844,7 +862,8 @@ struct PlayerProfile_Struct
/*04452*/ uint32 silver_cursor; // Silver Pieces on cursor
/*04456*/ uint32 copper_cursor; // Copper Pieces on cursor
/*04460*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
/*04860*/ uint8 unknown04760[136];
/*04860*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
/*04960*/ uint8 unknown04760[36];
/*04996*/ uint32 toxicity; // Potion Toxicity (15=too toxic, each potion adds 3)
/*05000*/ uint32 thirst_level; // Drink (ticks till next drink)
/*05004*/ uint32 hunger_level; // Food (ticks till next eat)
@@ -1100,20 +1119,18 @@ struct Action_Struct
{
/* 00 */ uint16 target; // id of target
/* 02 */ uint16 source; // id of caster
/* 04 */ uint16 level; // level of caster
/* 06 */ uint16 instrument_mod;
/* 08 */ uint32 unknown08;
/* 12 */ uint16 unknown16;
// some kind of sequence that's the same in both actions
// as well as the combat damage, to tie em together?
/* 14 */ uint32 sequence;
/* 18 */ uint32 unknown18;
/* 22 */ uint8 type; // 231 (0xE7) for spells
/* 23 */ uint32 unknown23;
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
/* 10 */ float force;
/* 14 */ float hit_heading;
/* 18 */ float hit_pitch;
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
/* 23 */ uint16 unknown23; // OSX says min_damage
/* 25 */ uint16 unknown25; // OSX says tohit
/* 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
/* 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 */
};
@@ -1124,12 +1141,12 @@ struct CombatDamage_Struct
{
/* 00 */ uint16 target;
/* 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;
/* 07 */ uint32 damage;
/* 11 */ float force;
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 15 */ float hit_heading; // see above notes in Action_Struct
/* 19 */ float hit_pitch;
/* 23 */
};
@@ -1327,6 +1344,19 @@ struct MoveItem_Struct
/*0012*/
};
struct MultiMoveItemSub_Struct
{
/*0000*/ InventorySlot_Struct from_slot;
/*0016*/ uint32 number_in_stack; // so the amount we are moving from the source
/*0020*/ InventorySlot_Struct to_slot;
};
struct MultiMoveItem_Struct
{
/*0000*/ uint32 count;
/*0004*/ MultiMoveItemSub_Struct moves[0];
};
//
// from_slot/to_slot
// -1 - destroy
@@ -2539,21 +2569,32 @@ struct GuildMakeLeader{
char name[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 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
/*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
uint8 level;
uint8 class_;
@@ -2580,20 +2621,21 @@ struct Ground_Spawn{
struct Ground_Spawns {
struct Ground_Spawn spawn[50]; //Assigned max number to allow
};
struct PetitionBug_Struct{
uint32 petition_number;
uint32 unknown4;
char accountname[64];
uint32 zoneid;
char name[64];
uint32 level;
uint32 class_;
uint32 race;
uint32 unknown152[3];
uint32 time;
uint32 unknown168;
char text[1028];
};
//struct PetitionBug_Struct{
// uint32 petition_number;
// uint32 unknown4;
// char accountname[64];
// uint32 zoneid;
// char name[64];
// uint32 level;
// uint32 class_;
// uint32 race;
// uint32 unknown152[3];
// uint32 time;
// uint32 unknown168;
// char text[1028];
//};
struct ApproveZone_Struct {
char name[64];
@@ -3521,6 +3563,21 @@ struct LFGuild_GuildToggle_Struct
// 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*/
}; /*Titanium*/
+56 -64
View File
@@ -53,11 +53,11 @@ namespace UF
static inline uint32 UFToServerSlot(uint32 ufSlot);
static inline uint32 UFToServerCorpseSlot(uint32 ufCorpseSlot);
// server to client text link converter
static inline void ServerToUFTextLink(std::string& ufTextLink, const std::string& serverTextLink);
// server to client say link converter
static inline void ServerToUFSayLink(std::string& ufSayLink, const std::string& serverSayLink);
// client to server text link converter
static inline void UFToServerTextLink(std::string& serverTextLink, const std::string& ufTextLink);
// client to server say link converter
static inline void UFToServerSayLink(std::string& serverSayLink, const std::string& ufSayLink);
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot);
@@ -161,29 +161,20 @@ namespace UF
OUT(source);
OUT(level);
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(spell);
eq->level2 = eq->level;
eq->effect_flag = emu->buff_unknown;
eq->unknown37 = 0x01;
eq->unknown44 = 0xFFFFFFFF;
eq->unknown48 = 0xFFFFFFFF;
eq->unknown52 = 0xFFFFFFFF;
/*OUT(target);
OUT(source);
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;*/
OUT(spell_level);
OUT(effect_flag);
eq->spell_gem = 0;
eq->slot[0] = -1; // type
eq->slot[1] = -1; // slot
eq->slot[2] = -1; // sub index
eq->slot[3] = -1; // aug index
eq->slot[4] = -1; // unknown
eq->item_cast_type = 0;
FINISH_ENCODE();
}
@@ -391,7 +382,7 @@ namespace UF
{
SETUP_VAR_ENCODE(BuffIcon_Struct);
uint32 sz = 12 + (17 * emu->count);
uint32 sz = 12 + (17 * emu->count) + emu->name_lengths; // 17 includes nullterm
__packet->size = sz;
__packet->pBuffer = new unsigned char[sz];
memset(__packet->pBuffer, 0, sz);
@@ -407,7 +398,7 @@ namespace UF
__packet->WriteUInt32(emu->entries[i].spell_id);
__packet->WriteUInt32(emu->entries[i].tics_remaining);
__packet->WriteUInt32(emu->entries[i].num_hits);
__packet->WriteString("");
__packet->WriteString(emu->entries[i].caster);
}
__packet->WriteUInt8(emu->type);
@@ -463,7 +454,7 @@ namespace UF
std::string old_message = emu->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) + strlen(emu->targetname) + new_message.length() + 39;
@@ -586,8 +577,8 @@ namespace UF
OUT(spellid);
OUT(damage);
OUT(force);
OUT(meleepush_xy);
OUT(meleepush_z);
OUT(hit_heading);
OUT(hit_pitch);
OUT(special);
FINISH_ENCODE();
@@ -762,7 +753,7 @@ namespace UF
std::string old_message = emu->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)
// new_message = new_message.substr(0, 512);
@@ -814,7 +805,7 @@ namespace UF
for (int i = 0; i < 9; ++i) {
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;
}
@@ -1850,6 +1841,7 @@ namespace UF
OUT(copper_cursor);
OUT_array(skills, structs::MAX_PP_SKILL); // 1:1 direct copy (100 dword)
OUT_array(InnateSkills, structs::MAX_PP_INNATE_SKILL); // 1:1 direct copy (25 dword)
// OUT(unknown04760[236]);
OUT(toxicity);
@@ -2468,7 +2460,7 @@ namespace UF
std::string old_message = &emu->message[strlen(emu->sayer)];
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 = strlen(emu->sayer) + new_message.length() + 25;
@@ -2538,7 +2530,7 @@ namespace UF
std::string old_message = InBuffer; // start 'Reward' as string
std::string new_message;
ServerToUFTextLink(new_message, old_message);
ServerToUFSayLink(new_message, old_message);
in->size = sizeof(TaskDescriptionHeader_Struct) + sizeof(TaskDescriptionData1_Struct)+
sizeof(TaskDescriptionData2_Struct) + sizeof(TaskDescriptionTrailer_Struct)+
@@ -3286,7 +3278,7 @@ namespace UF
std::string old_message = InBuffer;
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) + new_message.length() + 1;
@@ -3397,7 +3389,7 @@ namespace UF
IN(type);
IN(spellid);
IN(damage);
IN(meleepush_xy);
IN(hit_heading);
FINISH_DIRECT_DECODE();
}
@@ -3420,7 +3412,7 @@ namespace UF
std::string old_message = (char *)&__eq_buffer[4]; // unknown01 offset
std::string new_message;
UFToServerTextLink(new_message, old_message);
UFToServerSayLink(new_message, old_message);
__packet->size = sizeof(Emote_Struct);
__packet->pBuffer = new unsigned char[__packet->size];
@@ -4289,19 +4281,19 @@ namespace UF
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)) {
ufTextLink = serverTextLink;
if ((constants::SayLinkBodySize == EQEmu::constants::SayLinkBodySize) || (serverSayLink.find('\x12') == std::string::npos)) {
ufSayLink = serverSayLink;
return;
}
auto segments = SplitString(serverTextLink, '\x12');
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() <= EQEmu::legacy::TEXT_LINK_BODY_LENGTH) {
ufTextLink.append(segments[segment_iter]);
if (segments[segment_iter].length() <= EQEmu::constants::SayLinkBodySize) {
ufSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -4311,37 +4303,37 @@ namespace UF
// SoF: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX X XXXXX XXXXXXXX (50)
// Diff: ^^^^^ ^
ufTextLink.push_back('\x12');
ufTextLink.append(segments[segment_iter].substr(0, 31));
ufTextLink.append(segments[segment_iter].substr(36, 5));
ufSayLink.push_back('\x12');
ufSayLink.append(segments[segment_iter].substr(0, 31));
ufSayLink.append(segments[segment_iter].substr(36, 5));
if (segments[segment_iter][41] == '0')
ufTextLink.push_back(segments[segment_iter][42]);
ufSayLink.push_back(segments[segment_iter][42]);
else
ufTextLink.push_back('F');
ufSayLink.push_back('F');
ufTextLink.append(segments[segment_iter].substr(43));
ufTextLink.push_back('\x12');
ufSayLink.append(segments[segment_iter].substr(43));
ufSayLink.push_back('\x12');
}
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)) {
serverTextLink = ufTextLink;
if ((EQEmu::constants::SayLinkBodySize == constants::SayLinkBodySize) || (ufSayLink.find('\x12') == std::string::npos)) {
serverSayLink = ufSayLink;
return;
}
auto segments = SplitString(ufTextLink, '\x12');
auto segments = SplitString(ufSayLink, '\x12');
for (size_t segment_iter = 0; segment_iter < segments.size(); ++segment_iter) {
if (segment_iter & 1) {
if (segments[segment_iter].length() <= constants::SayLinkBodySize) {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
// TODO: log size mismatch error
continue;
}
@@ -4351,16 +4343,16 @@ namespace UF
// RoF2: X XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX XXXXX X XXXX XX XXXXX XXXXXXXX (56)
// Diff: ^^^^^ ^
serverTextLink.push_back('\x12');
serverTextLink.append(segments[segment_iter].substr(0, 31));
serverTextLink.append("00000");
serverTextLink.append(segments[segment_iter].substr(31, 5));
serverTextLink.push_back('0');
serverTextLink.append(segments[segment_iter].substr(36));
serverTextLink.push_back('\x12');
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 {
serverTextLink.append(segments[segment_iter]);
serverSayLink.append(segments[segment_iter]);
}
}
}
+62 -65
View File
@@ -292,7 +292,7 @@ struct Spawn_Struct
/*0000*/ //uint8 nullterm1; // hack to null terminate name
/*0064*/ uint32 spawnId;
/*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
Spawn_Struct_Bitfields Bitfields;
/*0000*/ uint8 otherData; // & 4 - has title, & 8 - has suffix, & 1 - it's a chest or untargetable
@@ -848,6 +848,7 @@ static const uint32 MAX_PP_LANGUAGE = 25; //
static const uint32 MAX_PP_SPELLBOOK = 720; // Confirmed 60 pages on Underfoot now
static const uint32 MAX_PP_MEMSPELL = 12; //was 9 now 10 on Underfoot
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 300; //was 299
static const uint32 MAX_GROUP_MEMBERS = 6;
static const uint32 MAX_RECAST_TYPES = 20;
@@ -954,7 +955,8 @@ struct PlayerProfile_Struct
/*07336*/ uint32 silver_cursor; // Silver Pieces on cursor
/*07340*/ uint32 copper_cursor; // Copper Pieces on cursor
/*07344*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
/*07744*/ uint8 unknown07644[136];
/*07744*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
/*07844*/ uint8 unknown07644[36];
/*07880*/ uint32 toxicity; // Potion Toxicity (15=too toxic, each potion adds 3)
/*07884*/ uint32 thirst_level; // Drink (ticks till next drink)
/*07888*/ uint32 hunger_level; // Food (ticks till next eat)
@@ -1250,19 +1252,19 @@ struct Action_Struct
{
/*00*/ uint16 target; // id of target
/*02*/ uint16 source; // id of caster
/*04*/ uint16 level; // level of caster - Seen 0
/*06*/ uint32 unknown06;
/*10*/ uint16 instrument_focus;
/*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*/ uint32 unknown14; // seen 0
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
/*22*/ uint32 unknown22;
/*26*/ uint8 type;
/*27*/ uint32 damage;
/*31*/ uint16 unknown31;
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
/*10*/ float instrument_mod;
/*14*/ float force;
/*18*/ float hit_heading;
/*22*/ float hit_pitch;
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
/*27*/ uint32 damage; // OSX says min_damage
/*31*/ uint16 unknown31; // OSX says tohit
/*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?
/*37*/
};
@@ -1274,27 +1276,22 @@ struct ActionAlt_Struct
{
/*00*/ uint16 target; // id of target
/*02*/ uint16 source; // id of caster
/*04*/ uint16 level; // level of caster - Seen 0
/*06*/ uint32 unknown06;
/*04*/ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/*06*/ uint32 unknown06; // OSX dump says base_damage, was used for bard mod too, this is 0'd :(
/*10*/ float instrument_mod;
/*14*/ uint32 unknown14; // seen 0
/*18*/ float knockback_angle; //seems to go from 0-512 then it rolls over again
/*22*/ uint32 unknown22;
/*26*/ uint8 type;
/*27*/ uint32 damage;
/*31*/ uint16 unknown31;
/*14*/ float force;
/*18*/ float hit_heading;
/*22*/ float hit_pitch;
/*26*/ uint8 type; // 231 (0xE7) for spells, skill
/*27*/ uint32 damage; // OSX says min_damage
/*31*/ uint16 unknown31; // OSX says tohit
/*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?
/*37*/ uint32 unknown37; // New field to Underfoot - Seen 14
/*41*/ uint8 unknown41; // New field to Underfoot - Seen 0
/*42*/ uint8 unknown42; // New field to Underfoot - Seen 0
/*43*/ uint8 unknown43; // New field to Underfoot - Seen 0
/*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
/*37*/ uint8 spell_gem;
/*38*/ uint8 padding38[2];
/*40*/ uint32 slot[5];
/*60*/ uint32 item_cast_type; // ItemSpellTypes enum from MQ2
/*64*/
};
@@ -1309,9 +1306,9 @@ struct CombatDamage_Struct
/* 05 */ uint16 spellid;
/* 07 */ int32 damage;
/* 11 */ float force; // cd cc cc 3d
/* 15 */ float meleepush_xy; // see above notes in Action_Struct
/* 19 */ float meleepush_z;
/* 23 */ uint8 unknown23; // was [9]
/* 15 */ float hit_heading; // see above notes in Action_Struct
/* 19 */ float hit_pitch;
/* 23 */ uint8 secondary; // 0 for primary hand, 1 for secondary
/* 24 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
/* 28 */
};
@@ -3058,23 +3055,6 @@ struct GuildMakeLeader{
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
uint8 level;
uint8 class_;
@@ -3101,20 +3081,21 @@ struct Ground_Spawn{
struct Ground_Spawns {
struct Ground_Spawn spawn[50]; //Assigned max number to allow
};
struct PetitionBug_Struct{
uint32 petition_number;
uint32 unknown4;
char accountname[64];
uint32 zoneid;
char name[64];
uint32 level;
uint32 class_;
uint32 race;
uint32 unknown152[3];
uint32 time;
uint32 unknown168;
char text[1028];
};
//struct PetitionBug_Struct{
// uint32 petition_number;
// uint32 unknown4;
// char accountname[64];
// uint32 zoneid;
// char name[64];
// uint32 level;
// uint32 class_;
// uint32 race;
// uint32 unknown152[3];
// uint32 time;
// uint32 unknown168;
// char text[1028];
//};
struct ApproveZone_Struct {
char name[64];
@@ -4503,6 +4484,22 @@ struct MercenaryAssign_Struct {
/*0004*/ uint32 MercUnk01; //
/*0008*/ uint32 MercUnk02; //
/*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*/
+116
View File
@@ -1488,6 +1488,122 @@ uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit)
}
}
float GetRaceGenderDefaultHeight(int race, int gender)
{
static float male_height[] = {
6.0f, 6.0f, 7.0f, 6.0f, 5.0f, 6.0f, 5.0f, 5.5f, 4.0f, 8.0f, 9.0f, 3.5f, 3.0f, 6.0f, 6.0f,
2.0f, 8.5f, 8.0f, 21.0f, 20.0f, 6.0f, 6.0f, 3.5f, 3.0f, 6.0f, 2.0f, 5.0f, 5.0f, 6.0f, 6.0f,
6.0f, 7.5f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 5.0f, 6.0f, 6.0f, 7.0f, 4.0f, 4.7f, 6.0f,
8.0f, 3.0f, 12.0f, 5.0f, 21.0f, 6.0f, 6.0f, 3.0f, 9.0f, 6.0f, 6.0f, 2.0f, 6.0f, 3.0f, 6.0f,
4.0f, 20.0f, 5.0f, 5.0f, 6.0f, 9.0f, 25.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f, 6.0f, 2.5f,
7.0f, 6.0f, 5.0f, 6.0f, 1.5f, 1.0f, 3.5f, 7.0f, 6.0f, 6.0f, 6.0f, 6.0f, 7.0f, 3.0f, 3.0f,
7.0f, 12.0f, 8.0f, 9.0f, 4.0f, 11.5f, 8.0f, 6.0f, 6.0f, 12.0f, 6.0f, 6.0f, 6.0f, 20.0f, 10.0f,
6.5f, 6.0f, 17.0f, 1.0f, 4.0f, 6.0f, 8.0f, 5.0f, 1.0f, 6.0f, 6.0f, 5.0f, 5.0f, 5.0f, 9.0f,
3.0f, 8.0f, 2.0f, 24.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f, 3.0f, 7.0f, 9.0f, 6.0f, 11.0f, 2.5f,
14.0f, 8.0f, 7.0f, 12.0f, 6.0f, 27.0f, 6.0f, 6.0f, 6.0f, 6.0f, 2.0f, 9.0f, 9.0f, 6.0f, 9.0f,
3.0f, 3.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 15.0f, 15.0f, 9.0f, 7.0f, 6.0f, 6.0f, 7.0f, 8.0f,
3.0f, 3.0f, 6.0f, 7.0f, 13.0f, 6.0f, 6.0f, 9.0f, 5.0f, 7.0f, 9.0f, 6.0f, 6.0f, 8.0f, 6.0f,
6.0f, 5.5f, 6.0f, 4.0f, 25.0f, 6.0f, 6.0f, 6.0f, 22.0f, 20.0f, 6.0f, 10.0f, 13.5f, 12.0f, 3.0f,
30.0f, 6.0f, 6.0f, 35.0f, 1.5f, 8.0f, 3.0f, 6.0f, 2.0f, 6.0f, 6.0f, 5.0f, 2.0f, 7.0f, 6.0f,
6.0f, 6.0f, 6.0f, 4.0f, 6.0f, 6.0f, 6.0f, 8.0f, 8.0f, 7.0f, 8.0f, 6.0f, 7.0f, 6.0f, 7.0f,
6.0f, 10.0f, 3.0f, 6.0f, 8.0f, 9.0f, 15.0f, 5.0f, 10.0f, 7.0f, 6.0f, 7.0f, 6.0f, 7.0f, 7.0f,
12.0f, 6.0f, 4.0f, 6.0f, 5.0f, 3.0f, 30.0f, 30.0f, 15.0f, 20.0f, 6.0f, 10.0f, 6.0f, 14.0f, 14.0f,
16.0f, 15.0f, 30.0f, 15.0f, 7.5f, 5.0f, 4.0f, 6.0f, 15.0f, 6.5f, 3.0f, 12.0f, 10.0f, 10.5f, 10.0f,
7.5f, 6.0f, 6.0f, 12.5f, 9.0f, 20.0f, 2.0f, 10.0f, 25.0f, 8.0f, 6.0f, 6.0f, 10.0f, 18.0f, 45.0f,
13.0f, 15.0f, 8.0f, 30.0f, 25.0f, 25.0f, 10.0f, 13.0f, 5.0f, 3.5f, 15.0f, 35.0f, 11.0f, 15.0f, 50.0f,
13.0f, 6.0f, 7.0f, 6.0f, 60.0f, 6.0f, 22.0f, 22.0f, 21.0f, 22.0f, 15.0f, 25.0f, 23.0f, 8.0f, 15.0f,
10.0f, 6.0f, 7.0f, 6.0f, 12.0f, 9.5f, 6.0f, 12.0f, 12.0f, 12.0f, 15.0f, 4.0f, 5.0f, 105.0f, 20.0f,
5.0f, 10.0f, 10.0f, 10.0f, 20.0f, 13.5f, 8.0f, 10.0f, 3.0f, 5.0f, 9.0f, 6.0f, 6.0f, 6.0f, 10.0f,
8.0f, 8.0f, 8.0f, 6.0f, 6.0f, 5.0f, 5.0f, 5.0f, 9.0f, 9.0f, 9.0f, 6.0f, 8.5f, 6.0f, 7.0f,
8.0f, 7.0f, 11.0f, 6.0f, 7.0f, 9.0f, 8.0f, 6.0f, 8.0f, 6.0f, 6.0f, 6.0f, 6.0f, 9.0f, 10.0f,
6.0f, 3.0f, 4.0f, 3.0f, 3.0f, 4.0f, 10.0f, 10.0f, 2.0f, 8.0f, 6.0f, 6.0f, 14.0f, 7.0f, 5.0f,
9.0f, 7.0f, 7.0f, 10.0f, 10.0f, 12.0f, 9.0f, 7.0f, 12.0f, 13.0f, 16.0f, 6.0f, 9.0f, 6.0f, 6.0f,
10.0f, 25.0f, 15.0f, 6.0f, 25.0f, 6.0f, 6.0f, 8.0f, 11.0f, 6.0f, 9.0f, 2.0f, 6.0f, 5.0f, 4.0f,
8.5f, 6.0f, 6.0f, 6.0f, 4.0f, 6.0f, 15.0f, 1.0f, 2.0f, 6.0f, 40.0f, 8.0f, 12.0f, 3.0f, 8.0f,
99.0f, 9.0f, 100.0f, 100.0f, 10.0f, 6.0f, 27.5f, 20.0f, 6.0f, 6.0f, 5.0f, 6.0f, 8.0f, 5.0f, 3.0f,
11.5f, 25.0f, 80.0f, 20.0f, 9.0f, 8.0f, 5.0f, 4.0f, 7.0f, 10.0f, 6.0f, 11.0f, 8.0f, 5.0f, 6.0f,
6.0f, 30.0f, 7.0f, 15.0f, 9.0f, 6.0f, 9.0f, 6.0f, 3.0f, 32.5f, 15.0f, 7.5f, 10.0f, 10.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 9.0f, 20.0f, 6.0f, 6.0f, 6.0f, 25.0f, 12.0f, 6.0f, 8.0f, 6.0f,
6.0f, 20.0f, 10.0f, 8.0f, 12.0f, 8.0f, 2.0f, 6.0f, 3.0f, 6.0f, 7.0f, 1.5f, 6.0f, 3.0f, 3.0f,
3.0f, 3.0f, 2.0f, 3.0f, 3.0f, 6.0f, 6.0f, 6.0f, 4.5f, 7.0f, 6.0f, 7.0f, 6.0f, 22.0f, 8.0f,
15.0f, 22.0f, 8.0f, 15.0f, 6.0f, 80.0f, 150.0f, 7.0f, 6.0f, 6.0f, 6.0f, 12.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 35.0f, 20.0f, 9.0f, 6.0f, 6.0f, 6.0f, 20.0f, 20.0f,
20.0f, 20.0f, 20.0f, 9.0f, 4.0f, 4.0f, 10.0f, 5.0f, 8.0f, 6.0f, 10.0f, 6.0f, 6.0f, 2.0f, 36.0f,
14.0f, 7.0f, 250.0f, 6.0f, 9.0f, 6.0f, 7.0f, 4.0f, 6.0f, 8.0f, 6.0f, 23.0f, 6.0f, 6.0f, 6.0f,
70.0f, 6.0f, 7.0f, 6.0f, 6.0f, 6.0f, 20.0f, 6.0f, 6.0f, 6.0f, 5.0f, 1.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
4.0f, 4.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 7.0f, 7.0f, 7.0f, 7.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 8.0f,
6.0f, 6.0f, 6.0f, 7.0f, 6.0f, 6.0f, 6.0f, 7.5f, 6.0f, 6.0f, 4.0f, 6.0f, 3.0f, 6.0f, 6.0f,
1.0f, 9.0f, 7.0f, 8.0f, 7.0f, 8.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 8.0f,
};
static float female_height[] = {
6.0f, 6.0f, 7.0f, 6.0f, 5.0f, 6.0f, 5.0f, 5.5f, 4.0f, 8.0f, 9.0f, 3.5f, 3.0f, 6.0f, 6.0f,
2.0f, 8.5f, 8.0f, 21.0f, 20.0f, 6.0f, 6.0f, 3.5f, 3.0f, 6.0f, 2.0f, 5.0f, 5.0f, 6.0f, 6.0f,
6.0f, 7.5f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 5.0f, 6.0f, 6.0f, 7.0f, 4.0f, 4.7f, 6.0f,
8.0f, 3.0f, 12.0f, 5.0f, 21.0f, 6.0f, 6.0f, 3.0f, 9.0f, 6.0f, 6.0f, 2.0f, 6.0f, 3.0f, 6.0f,
4.0f, 20.0f, 5.0f, 5.0f, 6.0f, 9.0f, 25.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f, 6.0f, 2.5f,
7.0f, 6.0f, 5.0f, 6.0f, 1.5f, 1.0f, 3.5f, 7.0f, 6.0f, 6.0f, 6.0f, 6.0f, 7.0f, 3.0f, 3.0f,
7.0f, 12.0f, 8.0f, 9.0f, 4.0f, 11.5f, 8.0f, 6.0f, 6.0f, 12.0f, 6.0f, 6.0f, 6.0f, 20.0f, 10.0f,
6.5f, 6.0f, 17.0f, 1.0f, 4.0f, 6.0f, 8.0f, 5.0f, 1.0f, 6.0f, 6.0f, 5.0f, 5.0f, 5.0f, 9.0f,
3.0f, 8.0f, 2.0f, 24.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f, 3.0f, 7.0f, 9.0f, 6.0f, 11.0f, 2.5f,
14.0f, 8.0f, 7.0f, 12.0f, 6.0f, 27.0f, 6.0f, 6.0f, 6.0f, 6.0f, 2.0f, 9.0f, 9.0f, 6.0f, 9.0f,
3.0f, 3.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 15.0f, 15.0f, 9.0f, 7.0f, 6.0f, 6.0f, 7.0f, 8.0f,
3.0f, 3.0f, 6.0f, 7.0f, 13.0f, 6.0f, 6.0f, 9.0f, 5.0f, 7.0f, 9.0f, 6.0f, 6.0f, 8.0f, 6.0f,
6.0f, 5.5f, 6.0f, 4.0f, 25.0f, 6.0f, 6.0f, 6.0f, 22.0f, 20.0f, 6.0f, 10.0f, 13.5f, 12.0f, 3.0f,
30.0f, 6.0f, 6.0f, 35.0f, 1.5f, 8.0f, 3.0f, 6.0f, 2.0f, 6.0f, 6.0f, 5.0f, 2.0f, 7.0f, 6.0f,
6.0f, 6.0f, 6.0f, 4.0f, 6.0f, 6.0f, 6.0f, 8.0f, 8.0f, 7.0f, 8.0f, 6.0f, 7.0f, 6.0f, 7.0f,
6.0f, 10.0f, 3.0f, 6.0f, 8.0f, 9.0f, 15.0f, 5.0f, 10.0f, 7.0f, 6.0f, 7.0f, 6.0f, 7.0f, 7.0f,
12.0f, 6.0f, 4.0f, 6.0f, 5.0f, 3.0f, 30.0f, 30.0f, 15.0f, 20.0f, 6.0f, 10.0f, 6.0f, 14.0f, 14.0f,
16.0f, 15.0f, 30.0f, 15.0f, 7.5f, 5.0f, 4.0f, 6.0f, 15.0f, 6.5f, 3.0f, 12.0f, 10.0f, 10.5f, 10.0f,
7.5f, 6.0f, 6.0f, 12.5f, 9.0f, 20.0f, 2.0f, 10.0f, 25.0f, 8.0f, 6.0f, 6.0f, 10.0f, 18.0f, 45.0f,
13.0f, 15.0f, 8.0f, 30.0f, 25.0f, 25.0f, 10.0f, 13.0f, 5.0f, 3.5f, 15.0f, 35.0f, 11.0f, 15.0f, 50.0f,
13.0f, 6.0f, 7.0f, 6.0f, 60.0f, 6.0f, 22.0f, 22.0f, 21.0f, 22.0f, 15.0f, 25.0f, 23.0f, 8.0f, 15.0f,
10.0f, 6.0f, 7.0f, 6.0f, 12.0f, 9.5f, 6.0f, 12.0f, 12.0f, 12.0f, 15.0f, 4.0f, 5.0f, 105.0f, 20.0f,
5.0f, 10.0f, 10.0f, 10.0f, 20.0f, 13.5f, 8.0f, 10.0f, 3.0f, 5.0f, 9.0f, 6.0f, 6.0f, 6.0f, 10.0f,
8.0f, 8.0f, 8.0f, 6.0f, 6.0f, 5.0f, 5.0f, 5.0f, 9.0f, 9.0f, 9.0f, 6.0f, 8.5f, 6.0f, 7.0f,
8.0f, 7.0f, 11.0f, 6.0f, 7.0f, 9.0f, 8.0f, 6.0f, 8.0f, 6.0f, 6.0f, 6.0f, 6.0f, 9.0f, 10.0f,
6.0f, 3.0f, 4.0f, 3.0f, 3.0f, 4.0f, 10.0f, 10.0f, 2.0f, 8.0f, 6.0f, 6.0f, 14.0f, 7.0f, 5.0f,
9.0f, 7.0f, 7.0f, 10.0f, 10.0f, 12.0f, 9.0f, 7.0f, 12.0f, 13.0f, 16.0f, 6.0f, 9.0f, 6.0f, 6.0f,
10.0f, 25.0f, 15.0f, 6.0f, 25.0f, 6.0f, 6.0f, 8.0f, 11.0f, 6.0f, 9.0f, 2.0f, 6.0f, 5.0f, 4.0f,
8.5f, 6.0f, 6.0f, 6.0f, 4.0f, 6.0f, 15.0f, 1.0f, 2.0f, 6.0f, 40.0f, 8.0f, 12.0f, 3.0f, 8.0f,
99.0f, 9.0f, 100.0f, 100.0f, 10.0f, 6.0f, 27.5f, 20.0f, 6.0f, 6.0f, 5.0f, 6.0f, 8.0f, 5.0f, 3.0f,
11.5f, 25.0f, 80.0f, 20.0f, 9.0f, 8.0f, 5.0f, 4.0f, 7.0f, 10.0f, 6.0f, 11.0f, 8.0f, 5.0f, 6.0f,
6.0f, 30.0f, 7.0f, 15.0f, 9.0f, 6.0f, 9.0f, 6.0f, 3.0f, 32.5f, 15.0f, 7.5f, 10.0f, 10.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 9.0f, 20.0f, 6.0f, 6.0f, 6.0f, 25.0f, 12.0f, 6.0f, 8.0f, 6.0f,
6.0f, 20.0f, 9.0f, 8.0f, 12.0f, 8.0f, 2.0f, 6.0f, 3.0f, 6.0f, 7.0f, 1.5f, 6.0f, 3.0f, 3.0f,
3.0f, 3.0f, 2.0f, 3.0f, 3.0f, 6.0f, 6.0f, 6.0f, 4.5f, 7.0f, 6.0f, 7.0f, 5.7f, 22.0f, 8.0f,
15.0f, 22.0f, 8.0f, 15.0f, 6.0f, 80.0f, 150.0f, 7.0f, 6.0f, 6.0f, 6.0f, 12.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 35.0f, 20.0f, 9.0f, 6.0f, 6.0f, 6.0f, 20.0f, 20.0f,
20.0f, 20.0f, 20.0f, 9.0f, 4.0f, 4.0f, 10.0f, 5.0f, 8.0f, 6.0f, 10.0f, 5.7f, 6.0f, 2.0f, 36.0f,
14.0f, 7.0f, 250.0f, 6.0f, 9.0f, 6.0f, 7.0f, 4.0f, 6.0f, 8.0f, 6.0f, 23.0f, 6.0f, 6.0f, 6.0f,
70.0f, 6.0f, 7.0f, 6.0f, 6.0f, 6.0f, 20.0f, 6.0f, 6.0f, 6.0f, 5.0f, 1.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
4.0f, 4.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 10.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 7.0f, 7.0f, 7.0f, 7.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 8.0f,
6.0f, 6.0f, 6.0f, 7.0f, 6.0f, 6.0f, 6.0f, 7.5f, 6.0f, 6.0f, 4.0f, 6.0f, 3.0f, 6.0f, 6.0f,
1.0f, 9.0f, 7.0f, 8.0f, 7.0f, 8.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 8.0f,
};
const auto size = sizeof(male_height) / sizeof(male_height[0]);
if (race > size)
return 6.0f;
if (gender == 1)
return female_height[race];
return male_height[race];
}
// PlayerAppearance prep
#define HUMAN_MALE ((HUMAN << 8) | MALE)
+2
View File
@@ -858,6 +858,8 @@ uint32 GetPlayerRaceBit(uint16 race_id);
uint16 GetRaceIDFromPlayerRaceValue(uint32 player_race_value);
uint16 GetRaceIDFromPlayerRaceBit(uint32 player_race_bit);
float GetRaceGenderDefaultHeight(int race, int gender);
// player race-/gender-based model feature validators
namespace PlayerAppearance
+27 -11
View File
@@ -44,6 +44,7 @@ RULE_INT(Character, DeathExpLossMaxLevel, 255) // Any level greater than this wi
RULE_INT(Character, DeathItemLossLevel, 10)
RULE_INT(Character, DeathExpLossMultiplier, 3) //Adjust how much exp is lost
RULE_BOOL(Character, UseDeathExpLossMult, false) //Adjust to use the above multiplier or to use code default.
RULE_BOOL(Character, UseOldRaceRezEffects, false) // older clients had ID 757 for races with high starting STR, but it doesn't seem used anymore
RULE_INT(Character, CorpseDecayTimeMS, 10800000)
RULE_INT(Character, CorpseResTimeMS, 10800000) // time before cant res corpse(3 hours)
RULE_BOOL(Character, LeaveCorpses, true)
@@ -66,11 +67,12 @@ RULE_INT(Character, AutosaveIntervalS, 300) //0=disabled
RULE_INT(Character, HPRegenMultiplier, 100)
RULE_INT(Character, ManaRegenMultiplier, 100)
RULE_INT(Character, EnduranceRegenMultiplier, 100)
RULE_BOOL(Character, OldMinMana, false) // this is used for servers that want to follow older skill cap formulas so they can still have some regen w/o mediate
RULE_INT(Character, ConsumptionMultiplier, 100) //item's hunger restored = this value * item's food level, 100 = normal, 50 = people eat 2x as fast, 200 = people eat 2x as slow
RULE_BOOL(Character, HealOnLevel, false)
RULE_BOOL(Character, FeignKillsPet, false)
RULE_INT(Character, ItemManaRegenCap, 15)
RULE_INT(Character, ItemHealthRegenCap, 35)
RULE_INT(Character, ItemHealthRegenCap, 30)
RULE_INT(Character, ItemDamageShieldCap, 30)
RULE_INT(Character, ItemAccuracyCap, 150)
RULE_INT(Character, ItemAvoidanceCap, 100)
@@ -91,10 +93,12 @@ RULE_INT(Character, HasteCap, 100) // Haste cap for non-v3(overhaste) haste.
RULE_INT(Character, SkillUpModifier, 100) //skill ups are at 100%
RULE_BOOL(Character, SharedBankPlat, false) //off by default to prevent duping for now
RULE_BOOL(Character, BindAnywhere, false)
RULE_INT(Character, RestRegenPercent, 0) // Set to >0 to enable rest state bonus HP and mana regen.
RULE_BOOL(Character, RestRegenEnabled, true) // Enable OOC Regen
RULE_INT(Character, RestRegenHP, 180) // seconds until full from 0. this is actually zone setable, but most or all zones are 180
RULE_INT(Character, RestRegenMana, 180) // seconds until full from 0. this is actually zone setable, but most or all zones are 180
RULE_INT(Character, RestRegenEnd, 180) // seconds until full from 0. this is actually zone setable, but most or all zones are 180
RULE_INT(Character, RestRegenTimeToActivate, 30) // Time in seconds for rest state regen to kick in.
RULE_INT(Character, RestRegenRaidTimeToActivate, 300) // Time in seconds for rest state regen to kick in with a raid target.
RULE_BOOL(Character, RestRegenEndurance, false) // Whether rest regen will work for endurance or not.
RULE_INT(Character, KillsPerGroupLeadershipAA, 250) // Number of dark blues or above per Group Leadership AA
RULE_INT(Character, KillsPerRaidLeadershipAA, 250) // Number of dark blues or above per Raid Leadership AA
RULE_INT(Character, MaxFearDurationForPlayerCharacter, 4) //4 tics, each tic calculates every 6 seconds.
@@ -117,7 +121,8 @@ RULE_BOOL(Character, EnableDiscoveredItems, true) // If enabled, it enables EVEN
RULE_BOOL(Character, EnableXTargetting, true) // Enable Extended Targetting Window, for users with UF and later clients.
RULE_BOOL(Character, EnableAggroMeter, true) // Enable Aggro Meter, for users with RoF and later clients.
RULE_BOOL(Character, KeepLevelOverMax, false) // Don't delevel a character that has somehow gone over the level cap
RULE_INT(Character, FoodLossPerUpdate, 35) // How much food/water you lose per stamina update
RULE_INT(Character, FoodLossPerUpdate, 32) // How much food/water you lose per stamina update
RULE_BOOL(Character, EnableHungerPenalties, false) // being hungry/thirsty has negative effects -- it does appear normal live servers do not have penalties
RULE_INT(Character, BaseInstrumentSoftCap, 36) // Softcap for instrument mods, 36 commonly referred to as "3.6" as well.
RULE_BOOL(Character, UseSpellFileSongCap, true) // When they removed the AA that increased the cap they removed the above and just use the spell field
RULE_INT(Character, BaseRunSpeedCap, 158) // Base Run Speed Cap, on live it's 158% which will give you a runspeed of 1.580 hard capped to 225.
@@ -152,6 +157,7 @@ RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Targe
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, AllowCrossClassTrainers, false)
RULE_BOOL(Character, PetsUseReagents, true) //Pets use reagent on spells
RULE_CATEGORY_END()
RULE_CATEGORY(Mercs)
@@ -187,12 +193,14 @@ RULE_INT(Skills, MaxTrainSpecializations, 50) // Max level a GM trainer will tra
RULE_INT(Skills, SwimmingStartValue, 100)
RULE_BOOL(Skills, TrainSenseHeading, false)
RULE_INT(Skills, SenseHeadingStartValue, 200)
RULE_BOOL(Skills, SelfLanguageLearning, true)
RULE_CATEGORY_END()
RULE_CATEGORY(Pets)
RULE_REAL(Pets, AttackCommandRange, 150)
RULE_BOOL(Pets, UnTargetableSwarmPet, false)
RULE_REAL(Pets, PetPowerLevelCap, 10) // Max number of levels your pet can go up with pet power
RULE_BOOL(Pets, CanTakeNoDrop, false) // Can everyone trade nodrop gear to pets
RULE_CATEGORY_END()
RULE_CATEGORY(GM)
@@ -227,6 +235,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_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, PVPMinLevel, 0) // minimum level to pvp
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_BOOL (World, IPLimitDisconnectAll, false)
@@ -269,17 +278,10 @@ RULE_INT(Zone, GlobalLootMultiplier, 1) // Sets Global Loot drop multiplier for
RULE_CATEGORY_END()
RULE_CATEGORY(Map)
//enable these to help prevent mob hopping when they are pathing
RULE_BOOL(Map, FixPathingZWhenLoading, true) //increases zone boot times a bit to reduce hopping.
RULE_BOOL(Map, FixPathingZAtWaypoints, false) //alternative to `WhenLoading`, accomplishes the same thing but does it at each waypoint instead of once at boot time.
RULE_BOOL(Map, FixPathingZWhenMoving, false) //very CPU intensive, but helps hopping with widely spaced waypoints.
RULE_BOOL(Map, FixPathingZOnSendTo, false) //try to repair Z coords in the SendTo routine as well.
RULE_BOOL(Map, FixZWhenMoving, true) // Automatically fix NPC Z coordinates when moving/pathing/engaged (Far less CPU intensive than its predecessor)
RULE_BOOL(Map, MobZVisualDebug, false) // Displays spell effects determining whether or not NPC is hitting Best Z calcs (blue for hit, red for miss)
RULE_REAL(Map, FixPathingZMaxDeltaMoving, 20) //at runtime while pathing: max change in Z to allow the BestZ code to apply.
RULE_REAL(Map, FixPathingZMaxDeltaWaypoint, 20) //at runtime at each waypoint: max change in Z to allow the BestZ code to apply.
RULE_REAL(Map, FixPathingZMaxDeltaSendTo, 20) //at runtime in SendTo: max change in Z to allow the BestZ code to apply.
RULE_REAL(Map, FixPathingZMaxDeltaLoading, 45) //while loading each waypoint: max change in Z to allow the BestZ code to apply.
RULE_INT(Map, FindBestZHeightAdjust, 1) // Adds this to the current Z before seeking the best Z position
RULE_CATEGORY_END()
@@ -401,6 +403,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, 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, NPCSpellPush, false) // enable spell push on NPCs
RULE_CATEGORY_END()
RULE_CATEGORY(Combat)
@@ -503,6 +506,7 @@ RULE_INT(Combat, NPCAssistCapTimer, 6000) // Time in milliseconds a NPC will tak
RULE_BOOL(Combat, UseRevampHandToHand, false) // use h2h revamped dmg/delays I believe this was implemented during SoF
RULE_BOOL(Combat, ClassicMasterWu, false) // classic master wu uses a random special, modern doesn't
RULE_INT(Combat, LevelToStopDamageCaps, 0) // 1 will effectively disable them, 20 should give basically same results as old incorrect system
RULE_BOOL(Combat, ClassicNPCBackstab, false) // true disables npc facestab - npcs get normal attack if not behind
RULE_CATEGORY_END()
RULE_CATEGORY(NPC)
@@ -669,6 +673,12 @@ RULE_CATEGORY_END()
RULE_CATEGORY(AA)
RULE_INT(AA, ExpPerPoint, 23976503) //Amount of exp per AA. Is the same as the amount of exp to go from level 51 to level 52.
RULE_BOOL(AA, Stacking, true) //Allow AA that belong to the same group to stack on SOF+ clients.
RULE_BOOL(AA, NormalizedAAEnabled, false) // TSS+ change to AA that normalizes AA XP to a fixed # of white con kills independent of level.
RULE_INT(AA, NormalizedAANumberOfWhiteConPerAA, 25) // The number of white con kills per AA point.
RULE_BOOL(AA, ModernAAScalingEnabled, false) // Are we linearly scaling AA XP based on total # of earned AA?
RULE_REAL(AA, ModernAAScalingStartPercent, 1000) // 1000% or 10x AA XP at the start of the scaling range
RULE_INT(AA, ModernAAScalingAAMinimum, 0) // The minimum number of earned AA before AA XP scaling begins.
RULE_INT(AA, ModernAAScalingAALimit, 4000) // The number of earned AA when AA XP scaling ends
RULE_CATEGORY_END()
RULE_CATEGORY(Console)
@@ -714,6 +724,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_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_INT
#undef RULE_REAL
+51 -53
View File
@@ -29,10 +29,10 @@
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));
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH)
if (say_link_body.length() != EQEmu::constants::SayLinkBodySize)
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.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);
@@ -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_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.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;
}
@@ -53,7 +53,7 @@ bool EQEmu::saylink::GenerateLinkBody(std::string& say_link_body, const SayLinkB
{
say_link_body = StringFormat(
"%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.augment_1),
(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)
);
if (say_link_body.length() != EQEmu::legacy::TEXT_LINK_BODY_LENGTH)
if (say_link_body.length() != EQEmu::constants::SayLinkBodySize)
return false;
return true;
@@ -79,7 +79,7 @@ EQEmu::SayLinkEngine::SayLinkEngine()
Reset();
}
std::string EQEmu::SayLinkEngine::GenerateLink()
const std::string& EQEmu::SayLinkEngine::GenerateLink()
{
m_Link.clear();
m_LinkBody.clear();
@@ -88,18 +88,26 @@ std::string EQEmu::SayLinkEngine::GenerateLink()
generate_body();
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.append(m_LinkBody);
m_Link.append(m_LinkText);
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_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})",
m_LinkType, m_Link.length(), m_LinkBody.length(), m_LinkText.length());
Log(Logs::General, Logs::Error, "SayLinkEngine::GenerateLink() failed to generate a useable say link");
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, ">> LinkText: %s", m_LinkText.c_str());
}
@@ -113,20 +121,10 @@ void EQEmu::SayLinkEngine::Reset()
m_ItemData = nullptr;
m_LootData = nullptr;
m_ItemInst = nullptr;
m_Proxy_unknown_1 = 0;
m_ProxyItemID = 0;
m_ProxyAugment1ID = 0;
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;
memset(&m_LinkBodyStruct, 0, sizeof(SayLinkBody_Struct));
memset(&m_LinkProxyStruct, 0, sizeof(SayLinkProxy_Struct));
m_TaskUse = false;
m_Link.clear();
m_LinkBody.clear();
@@ -194,32 +192,32 @@ void EQEmu::SayLinkEngine::generate_body()
break;
}
if (m_Proxy_unknown_1)
m_LinkBodyStruct.unknown_1 = m_Proxy_unknown_1;
if (m_ProxyItemID)
m_LinkBodyStruct.item_id = m_ProxyItemID;
if (m_ProxyAugment1ID)
m_LinkBodyStruct.augment_1 = m_ProxyAugment1ID;
if (m_ProxyAugment2ID)
m_LinkBodyStruct.augment_2 = m_ProxyAugment2ID;
if (m_ProxyAugment3ID)
m_LinkBodyStruct.augment_3 = m_ProxyAugment3ID;
if (m_ProxyAugment4ID)
m_LinkBodyStruct.augment_4 = m_ProxyAugment4ID;
if (m_ProxyAugment5ID)
m_LinkBodyStruct.augment_5 = m_ProxyAugment5ID;
if (m_ProxyAugment6ID)
m_LinkBodyStruct.augment_6 = m_ProxyAugment6ID;
if (m_ProxyIsEvolving)
m_LinkBodyStruct.is_evolving = m_ProxyIsEvolving;
if (m_ProxyEvolveGroup)
m_LinkBodyStruct.evolve_group = m_ProxyEvolveGroup;
if (m_ProxyEvolveLevel)
m_LinkBodyStruct.evolve_level = m_ProxyEvolveLevel;
if (m_ProxyOrnamentIcon)
m_LinkBodyStruct.ornament_icon = m_ProxyOrnamentIcon;
if (m_ProxyHash)
m_LinkBodyStruct.hash = m_ProxyHash;
if (m_LinkProxyStruct.action_id)
m_LinkBodyStruct.action_id = m_LinkProxyStruct.action_id;
if (m_LinkProxyStruct.item_id)
m_LinkBodyStruct.item_id = m_LinkProxyStruct.item_id;
if (m_LinkProxyStruct.augment_1)
m_LinkBodyStruct.augment_1 = m_LinkProxyStruct.augment_1;
if (m_LinkProxyStruct.augment_2)
m_LinkBodyStruct.augment_2 = m_LinkProxyStruct.augment_2;
if (m_LinkProxyStruct.augment_3)
m_LinkBodyStruct.augment_3 = m_LinkProxyStruct.augment_3;
if (m_LinkProxyStruct.augment_4)
m_LinkBodyStruct.augment_4 = m_LinkProxyStruct.augment_4;
if (m_LinkProxyStruct.augment_5)
m_LinkBodyStruct.augment_5 = m_LinkProxyStruct.augment_5;
if (m_LinkProxyStruct.augment_6)
m_LinkBodyStruct.augment_6 = m_LinkProxyStruct.augment_6;
if (m_LinkProxyStruct.is_evolving)
m_LinkBodyStruct.is_evolving = m_LinkProxyStruct.is_evolving;
if (m_LinkProxyStruct.evolve_group)
m_LinkBodyStruct.evolve_group = m_LinkProxyStruct.evolve_group;
if (m_LinkProxyStruct.evolve_level)
m_LinkBodyStruct.evolve_level = m_LinkProxyStruct.evolve_level;
if (m_LinkProxyStruct.ornament_icon)
m_LinkBodyStruct.ornament_icon = m_LinkProxyStruct.ornament_icon;
if (m_LinkProxyStruct.hash)
m_LinkBodyStruct.hash = m_LinkProxyStruct.hash;
if (m_TaskUse)
@@ -227,7 +225,7 @@ void EQEmu::SayLinkEngine::generate_body()
m_LinkBody = StringFormat(
"%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.augment_1),
(0x000FFFFF & m_LinkBodyStruct.augment_2),
@@ -245,8 +243,8 @@ void EQEmu::SayLinkEngine::generate_body()
void EQEmu::SayLinkEngine::generate_text()
{
if (m_ProxyText != nullptr) {
m_LinkText = m_ProxyText;
if (m_LinkProxyStruct.text != nullptr) {
m_LinkText = m_LinkProxyStruct.text;
return;
}
+28 -37
View File
@@ -47,7 +47,7 @@ namespace EQEmu
} /*saylink*/
struct SayLinkBody_Struct {
uint8 unknown_1; /* %1X */
uint8 action_id; /* %1X */
uint32 item_id; /* %05X */
uint32 augment_1; /* %05X */
uint32 augment_2; /* %05X */
@@ -56,13 +56,18 @@ namespace EQEmu
uint32 augment_5; /* %05X */
uint32 augment_6; /* %05X */
uint8 is_evolving; /* %1X */
uint32 evolve_group; /* %05X */
uint32 evolve_group; /* %04X */
uint8 evolve_level; /* %02X */
uint32 ornament_icon; /* %05X */
int hash; /* %08X */
uint32 hash; /* %08X */
};
struct SayLinkProxy_Struct : SayLinkBody_Struct {
const char* text;
};
class SayLinkEngine {
// TODO: consider methods for direct 'saylink' assignments
public:
SayLinkEngine();
@@ -72,29 +77,29 @@ namespace EQEmu
void SetItemInst(const ItemInstance* item_inst) { m_ItemInst = item_inst; }
// mainly for saylinks..but, not limited to
void SetProxyUnknown1(uint8 proxy_unknown_1) { m_Proxy_unknown_1 = proxy_unknown_1; }
void SetProxyItemID(uint32 proxy_item_id) { m_ProxyItemID = proxy_item_id; }
void SetProxyAugment1ID(uint32 proxy_augment_id) { m_ProxyAugment1ID = proxy_augment_id; }
void SetProxyAugment2ID(uint32 proxy_augment_id) { m_ProxyAugment2ID = proxy_augment_id; }
void SetProxyAugment3ID(uint32 proxy_augment_id) { m_ProxyAugment3ID = proxy_augment_id; }
void SetProxyAugment4ID(uint32 proxy_augment_id) { m_ProxyAugment4ID = proxy_augment_id; }
void SetProxyAugment5ID(uint32 proxy_augment_id) { m_ProxyAugment5ID = proxy_augment_id; }
void SetProxyAugment6ID(uint32 proxy_augment_id) { m_ProxyAugment6ID = proxy_augment_id; }
void SetProxyIsEvolving(uint8 proxy_is_evolving) { m_ProxyIsEvolving = proxy_is_evolving; }
void SetProxyEvolveGroup(uint32 proxy_evolve_group) { m_ProxyEvolveGroup = proxy_evolve_group; }
void SetProxyEvolveLevel(uint8 proxy_evolve_level) { m_ProxyEvolveLevel = proxy_evolve_level; }
void SetProxyOrnamentIcon(uint32 proxy_ornament_icon) { m_ProxyOrnamentIcon = proxy_ornament_icon; }
void SetProxyHash(int proxy_hash) { m_ProxyHash = proxy_hash; }
void SetProxyActionID(uint8 proxy_action_id) { m_LinkProxyStruct.action_id = proxy_action_id; } // should always be '0'
void SetProxyItemID(uint32 proxy_item_id) { m_LinkProxyStruct.item_id = proxy_item_id; }
void SetProxyAugment1ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_1 = proxy_augment_id; }
void SetProxyAugment2ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_2 = proxy_augment_id; }
void SetProxyAugment3ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_3 = proxy_augment_id; }
void SetProxyAugment4ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_4 = proxy_augment_id; }
void SetProxyAugment5ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_5 = proxy_augment_id; }
void SetProxyAugment6ID(uint32 proxy_augment_id) { m_LinkProxyStruct.augment_6 = proxy_augment_id; }
void SetProxyIsEvolving(uint8 proxy_is_evolving) { m_LinkProxyStruct.is_evolving = proxy_is_evolving; }
void SetProxyEvolveGroup(uint32 proxy_evolve_group) { m_LinkProxyStruct.evolve_group = proxy_evolve_group; }
void SetProxyEvolveLevel(uint8 proxy_evolve_level) { m_LinkProxyStruct.evolve_level = proxy_evolve_level; }
void SetProxyOrnamentIcon(uint32 proxy_ornament_icon) { m_LinkProxyStruct.ornament_icon = proxy_ornament_icon; }
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; }
std::string GenerateLink();
const std::string& GenerateLink();
bool LinkError() { return m_Error; }
std::string Link() { return m_Link; } // contains full string format: '/12x' '<LinkBody>' '<LinkText>' '/12x'
std::string LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
std::string LinkText() { return m_LinkText; } // contains string format: '<LinkText>'
const std::string& Link() { return m_Link; } // contains full string format: '\x12' '<LinkBody>' '<LinkText>' '\x12'
const std::string& LinkBody() { return m_LinkBody; } // contains string format: '<LinkBody>'
const std::string& LinkText() { return m_LinkText; } // contains string format: '<LinkText>'
void Reset();
@@ -106,23 +111,9 @@ namespace EQEmu
const ItemData* m_ItemData;
const ServerLootItem_Struct* m_LootData;
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;
SayLinkProxy_Struct m_LinkProxyStruct;
bool m_TaskUse;
std::string m_Link;
std::string m_LinkBody;
std::string m_LinkText;
+13
View File
@@ -190,6 +190,8 @@
#define ServerOP_ReloadLogs 0x4010
#define ServerOP_ReloadPerlExportSettings 0x4011
#define ServerOP_CZSetEntityVariableByClientName 0x4012
#define ServerOP_UCSServerStatusRequest 0x4013
#define ServerOP_UCSServerStatusReply 0x4014
/* Query Server OP Codes */
#define ServerOP_QSPlayerLogTrades 0x5010
#define ServerOP_QSPlayerLogHandins 0x5011
@@ -1278,6 +1280,17 @@ struct ServerRequestTellQueue_Struct {
char name[64];
};
struct UCSServerStatus_Struct {
uint8 available; // non-zero=true, 0=false
union {
struct {
uint16 port;
uint16 unused;
};
uint32 timestamp;
};
};
#pragma pack()
#endif
+37 -2
View File
@@ -110,6 +110,41 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
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)
{
// Delete cursor items
@@ -1817,8 +1852,8 @@ void SharedDatabase::LoadBaseData(void *data, int max_level) {
bd->base_hp = atof(row[2]);
bd->base_mana = atof(row[3]);
bd->base_end = atof(row[4]);
bd->unk1 = atof(row[5]);
bd->unk2 = atof(row[6]);
bd->hp_regen = atof(row[5]);
bd->end_regen = atof(row[6]);
bd->hp_factor = atof(row[7]);
bd->mana_factor = atof(row[8]);
bd->endurance_factor = atof(row[9]);
+2
View File
@@ -72,6 +72,8 @@ class SharedDatabase : public Database
void SaveCharacterInspectMessage(uint32 character_id, const InspectMessage_Struct* message);
bool GetCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &command_settings);
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
void SetMailKey(int CharID, int IPAddress, int MailKey);
std::string GetMailKey(int CharID, bool key_only = false);
/*
Character InventoryProfile
+7 -1
View File
@@ -73,6 +73,8 @@ enum SpellTypes : uint32
SpellTypes_Detrimental = (SpellType_Nuke | SpellType_Root | SpellType_Lifetap | SpellType_Snare | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Charm | SpellType_Debuff | SpellType_Slow),
SpellTypes_Beneficial = (SpellType_Heal | SpellType_Buff | SpellType_Escape | SpellType_Pet | SpellType_InCombatBuff | SpellType_Cure | SpellType_HateRedux | SpellType_InCombatBuffSong | SpellType_OutOfCombatBuffSong | SpellType_PreCombatBuff | SpellType_PreCombatBuffSong),
SpellTypes_Innate = (SpellType_Nuke | SpellType_Lifetap | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Slow | SpellType_Debuff | SpellType_Charm | SpellType_Root),
SpellType_Any = 0xFFFFFFFF
};
@@ -131,6 +133,11 @@ enum SpellAffectIndex {
SAI_NPC_Special_80 = 80,
SAI_Trap_Lock = 88
};
enum class GlobalGroup {
Lich = 46,
};
enum RESISTTYPE
{
RESIST_NONE = 0,
@@ -965,7 +972,6 @@ bool IsCastWhileInvis(uint16 spell_id);
bool IsEffectIgnoredInStacking(int spa);
int CalcPetHp(int levelb, int classb, int STA = 75);
const char *GetRandPetName();
int GetSpellEffectDescNum(uint16 spell_id);
DmgShieldType GetDamageShieldType(uint16 spell_id, int32 DSType = 0);
bool DetrimentalSpellAllowsRest(uint16 spell_id);
+2 -2
View File
@@ -30,9 +30,9 @@
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9114
#define CURRENT_BINARY_DATABASE_VERSION 9122
#ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9017
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9018
#else
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
#endif