WIP, porting old laurion changes to tob

This commit is contained in:
KimLS 2026-04-04 15:11:21 -07:00
parent 75ddf8dfc3
commit a2b3b36cf1
29 changed files with 8311 additions and 46 deletions

View File

@ -93,6 +93,8 @@ set(common_sources
patches/sod_limits.cpp patches/sod_limits.cpp
patches/sof.cpp patches/sof.cpp
patches/sof_limits.cpp patches/sof_limits.cpp
patches/steam_latest.cpp
patches/steam_latest_limits.cpp
patches/titanium.cpp patches/titanium.cpp
patches/titanium_limits.cpp patches/titanium_limits.cpp
patches/uf.cpp patches/uf.cpp
@ -674,6 +676,10 @@ set(common_headers
patches/sof_limits.h patches/sof_limits.h
patches/sof_ops.h patches/sof_ops.h
patches/sof_structs.h patches/sof_structs.h
patches/steam_latest.h
patches/steam_latest_limits.h
patches/steam_latest_ops.h
patches/steam_latest_structs.h
patches/ss_declare.h patches/ss_declare.h
patches/ss_define.h patches/ss_define.h
patches/ss_register.h patches/ss_register.h

View File

@ -50,6 +50,7 @@ public:
void WriteUInt8(uint8 value) { *(uint8 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint8); } void WriteUInt8(uint8 value) { *(uint8 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint8); }
void WriteUInt32(uint32 value) { *(uint32 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint32); } void WriteUInt32(uint32 value) { *(uint32 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint32); }
void WriteUInt64(uint64 value) { *(uint64 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint64); } void WriteUInt64(uint64 value) { *(uint64 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint64); }
void WriteSInt16(int32 value) { *(int16*)(pBuffer + _wpos) = value; _wpos += sizeof(int16); }
void WriteUInt16(uint32 value) { *(uint16 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint16); } void WriteUInt16(uint32 value) { *(uint16 *)(pBuffer + _wpos) = value; _wpos += sizeof(uint16); }
void WriteSInt32(int32 value) { *(int32 *)(pBuffer + _wpos) = value; _wpos += sizeof(int32); } void WriteSInt32(int32 value) { *(int32 *)(pBuffer + _wpos) = value; _wpos += sizeof(int32); }
void WriteFloat(float value) { *(float *)(pBuffer + _wpos) = value; _wpos += sizeof(float); } void WriteFloat(float value) { *(float *)(pBuffer + _wpos) = value; _wpos += sizeof(float); }

View File

@ -71,6 +71,9 @@ namespace Class {
constexpr uint8 FellowshipMaster = 69; constexpr uint8 FellowshipMaster = 69;
constexpr uint8 AlternateCurrencyMerchant = 70; constexpr uint8 AlternateCurrencyMerchant = 70;
constexpr uint8 MercenaryLiaison = 71; constexpr uint8 MercenaryLiaison = 71;
constexpr uint8 RealEstateMerchant = 72;
constexpr uint8 LoyaltyMerchant = 73;
constexpr uint8 TributeMaster2 = 74;
constexpr uint8 PLAYER_CLASS_COUNT = 16; constexpr uint8 PLAYER_CLASS_COUNT = 16;
constexpr uint16 ALL_CLASSES_BITMASK = 65535; constexpr uint16 ALL_CLASSES_BITMASK = 65535;

View File

@ -99,6 +99,24 @@ uint32 CRC32::GenerateNoFlip(const uint8* buf, uint32 bufsize) {
return Update(buf, bufsize); return Update(buf, bufsize);
} }
unsigned long CRC32::GetEQChecksum(uchar* in_data, uint32 in_length, uint32 start_at)
{
unsigned long data;
unsigned long check = 0xffffffff;
for (uint32 i = start_at; i < in_length; i++)
{
data = in_data[i];
data = data ^ (check);
data = data & 0x000000ff;
check = check >> 8;
data = CRC32Table[data];
check = check ^ data;
}
return check;
}
void CRC32::SetEQChecksum(uchar* in_data, uint32 in_length, uint32 start_at) void CRC32::SetEQChecksum(uchar* in_data, uint32 in_length, uint32 start_at)
{ {
unsigned long data; unsigned long data;

View File

@ -25,6 +25,7 @@ public:
static uint32 Generate(const uint8* buf, uint32 bufsize); static uint32 Generate(const uint8* buf, uint32 bufsize);
static uint32 GenerateNoFlip(const uint8* buf, uint32 bufsize); // Same as Generate(), but without the ~ static uint32 GenerateNoFlip(const uint8* buf, uint32 bufsize); // Same as Generate(), but without the ~
static void SetEQChecksum(uchar* in_data, uint32 in_length, uint32 start_at=4); static void SetEQChecksum(uchar* in_data, uint32 in_length, uint32 start_at=4);
static unsigned long GetEQChecksum(uchar* in_data, uint32 in_length, uint32 start_at = 4);
// Multiple buffer CRC32 // Multiple buffer CRC32
static uint32 Update(const uint8* buf, uint32 bufsize, uint32 crc32 = 0xFFFFFFFF); static uint32 Update(const uint8* buf, uint32 bufsize, uint32 crc32 = 0xFFFFFFFF);

View File

@ -18,8 +18,6 @@
// system use // system use
N(OP_ExploreUnknown), N(OP_ExploreUnknown),
// start (please add new opcodes in descending order and re-order any name changes where applicable) // start (please add new opcodes in descending order and re-order any name changes where applicable)
N(OP_0x0193),
N(OP_0x0347),
N(OP_AAAction), N(OP_AAAction),
N(OP_AAExpUpdate), N(OP_AAExpUpdate),
N(OP_AcceptNewTask), N(OP_AcceptNewTask),
@ -380,6 +378,7 @@ N(OP_MercenaryTimer),
N(OP_MercenaryTimerRequest), N(OP_MercenaryTimerRequest),
N(OP_MercenaryUnknown1), N(OP_MercenaryUnknown1),
N(OP_MercenaryUnsuspendResponse), N(OP_MercenaryUnsuspendResponse),
N(OP_MerchantBulkItems),
N(OP_MobEnduranceUpdate), N(OP_MobEnduranceUpdate),
N(OP_MobHealth), N(OP_MobHealth),
N(OP_MobManaUpdate), N(OP_MobManaUpdate),
@ -398,6 +397,7 @@ N(OP_MultiLineMsg),
N(OP_NewSpawn), N(OP_NewSpawn),
N(OP_NewTitlesAvailable), N(OP_NewTitlesAvailable),
N(OP_NewZone), N(OP_NewZone),
N(OP_NPCMoveUpdate),
N(OP_OnLevelMessage), N(OP_OnLevelMessage),
N(OP_OpenContainer), N(OP_OpenContainer),
N(OP_OpenDiscordMerchant), N(OP_OpenDiscordMerchant),

View File

@ -54,6 +54,8 @@ const char* EQ::versions::ClientVersionName(ClientVersion client_version)
return "RoF"; return "RoF";
case ClientVersion::RoF2: case ClientVersion::RoF2:
return "RoF2"; return "RoF2";
case ClientVersion::SteamLatest:
return "SteamLatest";
default: default:
return "Invalid Version"; return "Invalid Version";
}; };
@ -74,6 +76,8 @@ uint32 EQ::versions::ConvertClientVersionToClientVersionBit(ClientVersion client
return bitRoF; return bitRoF;
case ClientVersion::RoF2: case ClientVersion::RoF2:
return bitRoF2; return bitRoF2;
case ClientVersion::SteamLatest:
return bitSteamLatest;
default: default:
return bitUnknown; return bitUnknown;
} }
@ -94,6 +98,8 @@ EQ::versions::ClientVersion EQ::versions::ConvertClientVersionBitToClientVersion
return ClientVersion::RoF; return ClientVersion::RoF;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF2) - 1)) : case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::RoF2) - 1)) :
return ClientVersion::RoF2; return ClientVersion::RoF2;
case ((uint32)1 << (static_cast<unsigned int>(ClientVersion::SteamLatest) - 1)) :
return ClientVersion::SteamLatest;
default: default:
return ClientVersion::Unknown; return ClientVersion::Unknown;
} }
@ -182,6 +188,8 @@ const char* EQ::versions::MobVersionName(MobVersion mob_version)
return "RoF"; return "RoF";
case MobVersion::RoF2: case MobVersion::RoF2:
return "RoF2"; return "RoF2";
case MobVersion::SteamLatest:
return "SteamLatest";
case MobVersion::NPC: case MobVersion::NPC:
return "NPC"; return "NPC";
case MobVersion::NPCMerchant: case MobVersion::NPCMerchant:
@ -210,6 +218,8 @@ const char* EQ::versions::MobVersionName(MobVersion mob_version)
return "Offline RoF"; return "Offline RoF";
case MobVersion::OfflineRoF2: case MobVersion::OfflineRoF2:
return "Offline RoF2"; return "Offline RoF2";
case MobVersion::OfflineSteamLatest:
return "Offline Steam Latest";
default: default:
return "Invalid Version"; return "Invalid Version";
}; };
@ -233,6 +243,8 @@ EQ::versions::ClientVersion EQ::versions::ConvertMobVersionToClientVersion(MobVe
return ClientVersion::RoF; return ClientVersion::RoF;
case MobVersion::RoF2: case MobVersion::RoF2:
return ClientVersion::RoF2; return ClientVersion::RoF2;
case MobVersion::SteamLatest:
return ClientVersion::SteamLatest;
default: default:
return ClientVersion::Unknown; return ClientVersion::Unknown;
} }
@ -256,6 +268,8 @@ EQ::versions::MobVersion EQ::versions::ConvertClientVersionToMobVersion(ClientVe
return MobVersion::RoF; return MobVersion::RoF;
case ClientVersion::RoF2: case ClientVersion::RoF2:
return MobVersion::RoF2; return MobVersion::RoF2;
case ClientVersion::SteamLatest:
return MobVersion::SteamLatest;
default: default:
return MobVersion::Unknown; return MobVersion::Unknown;
} }
@ -276,6 +290,8 @@ EQ::versions::MobVersion EQ::versions::ConvertPCMobVersionToOfflinePCMobVersion(
return MobVersion::OfflineRoF; return MobVersion::OfflineRoF;
case MobVersion::RoF2: case MobVersion::RoF2:
return MobVersion::OfflineRoF2; return MobVersion::OfflineRoF2;
case MobVersion::SteamLatest:
return MobVersion::OfflineSteamLatest;
default: default:
return MobVersion::Unknown; return MobVersion::Unknown;
} }
@ -296,6 +312,8 @@ EQ::versions::MobVersion EQ::versions::ConvertOfflinePCMobVersionToPCMobVersion(
return MobVersion::RoF; return MobVersion::RoF;
case MobVersion::OfflineRoF2: case MobVersion::OfflineRoF2:
return MobVersion::RoF2; return MobVersion::RoF2;
case MobVersion::OfflineSteamLatest:
return MobVersion::SteamLatest;
default: default:
return MobVersion::Unknown; return MobVersion::Unknown;
} }
@ -316,6 +334,8 @@ EQ::versions::ClientVersion EQ::versions::ConvertOfflinePCMobVersionToClientVers
return ClientVersion::RoF; return ClientVersion::RoF;
case MobVersion::OfflineRoF2: case MobVersion::OfflineRoF2:
return ClientVersion::RoF2; return ClientVersion::RoF2;
case MobVersion::OfflineSteamLatest:
return ClientVersion::SteamLatest;
default: default:
return ClientVersion::Unknown; return ClientVersion::Unknown;
} }
@ -336,6 +356,8 @@ EQ::versions::MobVersion EQ::versions::ConvertClientVersionToOfflinePCMobVersion
return MobVersion::OfflineRoF; return MobVersion::OfflineRoF;
case ClientVersion::RoF2: case ClientVersion::RoF2:
return MobVersion::OfflineRoF2; return MobVersion::OfflineRoF2;
case ClientVersion::SteamLatest:
return MobVersion::OfflineSteamLatest;
default: default:
return MobVersion::Unknown; return MobVersion::Unknown;
} }
@ -386,6 +408,28 @@ const char* EQ::expansions::ExpansionName(Expansion expansion)
return "Rain of Fear"; return "Rain of Fear";
case Expansion::CotF: case Expansion::CotF:
return "Call of the Forsaken"; return "Call of the Forsaken";
case Expansion::TDS:
return "The Darkened Sea";
case Expansion::TBM:
return "The Broken Mirror";
case Expansion::EoK:
return "Empires of Kunark";
case Expansion::RoS:
return "Ring of Scale";
case Expansion::TBL:
return "The Burning Lands";
case Expansion::ToV:
return "Torment of Velious";
case Expansion::CoV:
return "Claws of Veeshan";
case Expansion::ToL:
return "Terror of Luclin";
case Expansion::NoS:
return "Night of Shadows";
case Expansion::LS:
return "Laurion's Song";
case Expansion::TOB:
return "The Outer Brood";
default: default:
return "Invalid Expansion"; return "Invalid Expansion";
} }
@ -439,6 +483,29 @@ uint32 EQ::expansions::ConvertExpansionToExpansionBit(Expansion expansion)
return bitRoF; return bitRoF;
case Expansion::CotF: case Expansion::CotF:
return bitCotF; return bitCotF;
case Expansion::TDS:
return bitTDS;
case Expansion::TBM:
return bitTBM;
case Expansion::EoK:
return bitEoK;
case Expansion::RoS:
return bitRoS;
case Expansion::TBL:
return bitTBL;
case Expansion::ToV:
return bitToV;
case Expansion::CoV:
return bitCoV;
case Expansion::ToL:
return bitToL;
case Expansion::NoS:
return bitNoS;
case Expansion::LS:
return bitLS;
case Expansion::TOB:
return bitTOB;
default: default:
return bitEverQuest; return bitEverQuest;
} }
@ -487,6 +554,28 @@ EQ::expansions::Expansion EQ::expansions::ConvertExpansionBitToExpansion(uint32
return Expansion::RoF; return Expansion::RoF;
case bitCotF: case bitCotF:
return Expansion::CotF; return Expansion::CotF;
case bitTDS:
return Expansion::TDS;
case bitTBM:
return Expansion::TBM;
case bitEoK:
return Expansion::EoK;
case bitRoS:
return Expansion::RoS;
case bitTBL:
return Expansion::TBL;
case bitToV:
return Expansion::ToV;
case bitCoV:
return Expansion::CoV;
case bitToL:
return Expansion::ToL;
case bitNoS:
return Expansion::NoS;
case bitLS:
return Expansion::LS;
case bitTOB:
return Expansion::TOB;
default: default:
return Expansion::EverQuest; return Expansion::EverQuest;
} }
@ -535,6 +624,28 @@ uint32 EQ::expansions::ConvertExpansionToExpansionsMask(Expansion expansion)
return maskRoF; return maskRoF;
case Expansion::CotF: case Expansion::CotF:
return maskCotF; return maskCotF;
case Expansion::TDS:
return maskTDS;
case Expansion::TBM:
return maskTBM;
case Expansion::EoK:
return maskEoK;
case Expansion::RoS:
return maskRoS;
case Expansion::TBL:
return maskTBL;
case Expansion::ToV:
return maskToV;
case Expansion::CoV:
return maskCoV;
case Expansion::ToL:
return maskToL;
case Expansion::NoS:
return maskNoS;
case Expansion::LS:
return maskLS;
case Expansion::TOB:
return maskTOB;
default: default:
return maskEverQuest; return maskEverQuest;
} }

View File

@ -32,7 +32,8 @@ namespace EQ
SoD, // Build: 'Dec 19 2008 15:22:49' SoD, // Build: 'Dec 19 2008 15:22:49'
UF, // Build: 'Jun 8 2010 16:44:32' UF, // Build: 'Jun 8 2010 16:44:32'
RoF, // Build: 'Dec 10 2012 17:35:44' RoF, // Build: 'Dec 10 2012 17:35:44'
RoF2 // Build: 'May 10 2013 23:30:08' RoF2, // Build: 'May 10 2013 23:30:08'
SteamLatest // Build: 'Sep 11 2025 11:54:10'
}; };
enum ClientVersionBitmask : uint32 { enum ClientVersionBitmask : uint32 {
@ -44,6 +45,7 @@ namespace EQ
bitUF = 0x00000010, bitUF = 0x00000010,
bitRoF = 0x00000020, bitRoF = 0x00000020,
bitRoF2 = 0x00000040, bitRoF2 = 0x00000040,
bitSteamLatest = 0x00000080,
maskUnknown = 0x00000000, maskUnknown = 0x00000000,
maskTitaniumAndEarlier = 0x00000003, maskTitaniumAndEarlier = 0x00000003,
maskSoFAndEarlier = 0x00000007, maskSoFAndEarlier = 0x00000007,
@ -55,10 +57,11 @@ namespace EQ
maskUFAndLater = 0xFFFFFFF0, maskUFAndLater = 0xFFFFFFF0,
maskRoFAndLater = 0xFFFFFFE0, maskRoFAndLater = 0xFFFFFFE0,
maskRoF2AndLater = 0xFFFFFFC0, maskRoF2AndLater = 0xFFFFFFC0,
maskSteamLatestAndLater = 0xFFFFFF80,
maskAllClients = 0xFFFFFFFF maskAllClients = 0xFFFFFFFF
}; };
const ClientVersion LastClientVersion = ClientVersion::RoF2; const ClientVersion LastClientVersion = ClientVersion::SteamLatest;
const size_t ClientVersionCount = (static_cast<size_t>(LastClientVersion) + 1); const size_t ClientVersionCount = (static_cast<size_t>(LastClientVersion) + 1);
bool IsValidClientVersion(ClientVersion client_version); bool IsValidClientVersion(ClientVersion client_version);
@ -76,6 +79,7 @@ namespace EQ
UF, UF,
RoF, RoF,
RoF2, RoF2,
SteamLatest
NPC, NPC,
NPCMerchant, NPCMerchant,
Merc, Merc,
@ -89,13 +93,14 @@ namespace EQ
OfflineSoD, OfflineSoD,
OfflineUF, OfflineUF,
OfflineRoF, OfflineRoF,
OfflineRoF2 OfflineRoF2,
OfflineSteamLatest
}; };
const MobVersion LastMobVersion = MobVersion::OfflineRoF2; const MobVersion LastMobVersion = MobVersion::OfflineSteamLatest;
const MobVersion LastPCMobVersion = MobVersion::RoF2; const MobVersion LastPCMobVersion = MobVersion::SteamLatest;
const MobVersion LastNonPCMobVersion = MobVersion::BotPet; const MobVersion LastNonPCMobVersion = MobVersion::BotPet;
const MobVersion LastOfflinePCMobVersion = MobVersion::OfflineRoF2; const MobVersion LastOfflinePCMobVersion = MobVersion::OfflineSteamLatest;
const size_t MobVersionCount = (static_cast<size_t>(LastMobVersion) + 1); const size_t MobVersionCount = (static_cast<size_t>(LastMobVersion) + 1);
bool IsValidMobVersion(MobVersion mob_version); bool IsValidMobVersion(MobVersion mob_version);
@ -127,7 +132,8 @@ namespace EQ
ucsSoDCombined = 'D', ucsSoDCombined = 'D',
ucsUFCombined = 'E', ucsUFCombined = 'E',
ucsRoFCombined = 'F', ucsRoFCombined = 'F',
ucsRoF2Combined = 'G' ucsRoF2Combined = 'G',
ucsSteamLatestCombined = 'H'
}; };
} /*versions*/ } /*versions*/
@ -154,7 +160,18 @@ namespace EQ
HoT, HoT,
VoA, VoA,
RoF, RoF,
CotF CotF,
TDS,
TBM,
EoK,
RoS,
TBL,
ToV,
CoV,
ToL,
NoS,
LS,
TOB
}; };
enum ExpansionBitmask : uint32 { enum ExpansionBitmask : uint32 {
@ -179,6 +196,17 @@ namespace EQ
bitVoA = 0x00020000, bitVoA = 0x00020000,
bitRoF = 0x00040000, bitRoF = 0x00040000,
bitCotF = 0x00080000, bitCotF = 0x00080000,
bitTDS = 0x00100000,
bitTBM = 0x00200000,
bitEoK = 0x00400000,
bitRoS = 0x00800000,
bitTBL = 0x01000000,
bitToV = 0x02000000,
bitCoV = 0x04000000,
bitToL = 0x08000000,
bitNoS = 0x10000000,
bitLS = 0x20000000,
bitTOB = 0x40000000,
maskEverQuest = 0x00000000, maskEverQuest = 0x00000000,
maskRoK = 0x00000001, maskRoK = 0x00000001,
maskSoV = 0x00000003, maskSoV = 0x00000003,
@ -200,6 +228,18 @@ namespace EQ
maskVoA = 0x0003FFFF, maskVoA = 0x0003FFFF,
maskRoF = 0x0007FFFF, maskRoF = 0x0007FFFF,
maskCotF = 0x000FFFFF maskCotF = 0x000FFFFF
maskCotF = 0x000FFFFF,
maskTDS = 0x001FFFFF,
maskTBM = 0x003FFFFF,
maskEoK = 0x007FFFFF,
maskRoS = 0x00FFFFFF,
maskTBL = 0x01FFFFFF,
maskToV = 0x03FFFFFF,
maskCoV = 0x07FFFFFF,
maskToL = 0x0FFFFFFF,
maskNoS = 0x1FFFFFFF,
maskLS = 0x3FFFFFFF,
maskTOB = 0x7FFFFFFF,
}; };
const char* ExpansionName(Expansion expansion); const char* ExpansionName(Expansion expansion);

View File

@ -759,6 +759,46 @@ typedef enum {
FilterStrikethrough = 26, //0=show, 1=hide // RoF2 Confirmed FilterStrikethrough = 26, //0=show, 1=hide // RoF2 Confirmed
FilterStuns = 27, //0=show, 1=hide // RoF2 Confirmed FilterStuns = 27, //0=show, 1=hide // RoF2 Confirmed
FilterBardSongsOnPets = 28, //0=show, 1=hide // RoF2 Confirmed FilterBardSongsOnPets = 28, //0=show, 1=hide // RoF2 Confirmed
FilterSwarmPetDeath = 29,
FilterFellowshipChat = 30,
FilterMercenaryMessages = 31,
FilterSpam = 32,
FilterAchievements = 33,
FilterPvPMessages = 34,
FilterSpellNameInCast = 35,
FilterRandomMine = 36,
FilterRandomGroupRaid = 37,
FilterRandomOthers = 38,
FilterEnvironmentalDamage = 39,
FilterMessages = 40,
FilterOverwriteDetrimental = 41,
FilterOverwriteBeneficial = 42,
FilterCantUseCommand = 43,
FilterCombatAbilityReuse = 44,
FilterAAAbilityReuse = 45,
FilterProcBeginCasting = 46,
FilterDestroyedItems = 47,
FilterYourAuras = 48,
FilterOtherAuras = 49,
FilterYourHeals = 50,
FilterOtherHeals = 51,
FilterYourDoTs = 52,
FilterOtherDoTs = 53,
FilterOtherDirectDamage = 54,
FilterSpellEmotes = 55,
FilterFactionMessages = 56,
FilterTauntMessages = 57,
FilterYourDisciplines = 58,
FilterOtherDisplines = 59,
FilterAchievementsOthers = 60,
FilterRaidVictory = 61,
FilterOtherDirectDamageCrits = 62,
FilterDoTYoursCritical = 63,
FilterDoTOthersCritical = 64,
FilterDoTDamageTaken = 65,
FilterHealsReceived = 66,
FilterHealsYoursCritical = 67,
FilterHealsOthersCritical = 68,
_FilterCount _FilterCount
} eqFilterType; } eqFilterType;

View File

@ -110,6 +110,14 @@ static const EQ::constants::LookupEntry constants_static_lookup_entries[EQ::vers
RoF2::constants::CHARACTER_CREATION_LIMIT, RoF2::constants::CHARACTER_CREATION_LIMIT,
RoF2::constants::SAY_LINK_BODY_SIZE, RoF2::constants::SAY_LINK_BODY_SIZE,
RoF2::constants::MAX_BAZAAR_TRADERS RoF2::constants::MAX_BAZAAR_TRADERS
),
/*[ClientVersion::SteamLatest] =*/
EQ::constants::LookupEntry(
SteamLatest::constants::EXPANSION,
SteamLatest::constants::EXPANSION_BIT,
SteamLatest::constants::EXPANSIONS_MASK,
SteamLatest::constants::CHARACTER_CREATION_LIMIT,
SteamLatest::constants::SAY_LINK_BODY_SIZE
) )
}; };
@ -376,6 +384,34 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
RoF2::inventory::ConcatenateInvTypeLimbo, RoF2::inventory::ConcatenateInvTypeLimbo,
RoF2::inventory::AllowOverLevelEquipment RoF2::inventory::AllowOverLevelEquipment
), ),
/*[MobVersion::SteamLatest] =*/
//SteamLatestTodo: These need to be set to the latest values not just use RoF2
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
EQ::invtype::POSSESSIONS_SIZE, RoF2::invtype::BANK_SIZE, RoF2::invtype::SHARED_BANK_SIZE,
RoF2::invtype::TRADE_SIZE, RoF2::invtype::WORLD_SIZE, RoF2::invtype::LIMBO_SIZE,
RoF2::invtype::TRIBUTE_SIZE, RoF2::invtype::TROPHY_TRIBUTE_SIZE, RoF2::invtype::GUILD_TRIBUTE_SIZE,
RoF2::invtype::MERCHANT_SIZE, RoF2::invtype::DELETED_SIZE, RoF2::invtype::CORPSE_SIZE,
RoF2::invtype::BAZAAR_SIZE, RoF2::invtype::INSPECT_SIZE, RoF2::invtype::REAL_ESTATE_SIZE,
RoF2::invtype::VIEW_MOD_PC_SIZE, RoF2::invtype::VIEW_MOD_BANK_SIZE, RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE,
RoF2::invtype::VIEW_MOD_LIMBO_SIZE, RoF2::invtype::ALT_STORAGE_SIZE, RoF2::invtype::ARCHIVED_SIZE,
RoF2::invtype::MAIL_SIZE, RoF2::invtype::GUILD_TROPHY_TRIBUTE_SIZE, RoF2::invtype::KRONO_SIZE,
RoF2::invtype::OTHER_SIZE
),
RoF2::invslot::EQUIPMENT_BITMASK,
RoF2::invslot::GENERAL_BITMASK,
RoF2::invslot::CURSOR_BITMASK,
RoF2::invslot::POSSESSIONS_BITMASK,
RoF2::invslot::CORPSE_BITMASK,
RoF2::invbag::SLOT_COUNT,
RoF2::invaug::SOCKET_COUNT,
RoF2::inventory::AllowEmptyBagInBag,
RoF2::inventory::AllowClickCastFromBag,
RoF2::inventory::ConcatenateInvTypeLimbo,
RoF2::inventory::AllowOverLevelEquipment
),
/*[MobVersion::NPC] =*/ /*[MobVersion::NPC] =*/
EQ::inventory::LookupEntry( EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct( EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
@ -748,6 +784,35 @@ static const EQ::inventory::LookupEntry inventory_static_lookup_entries[EQ::vers
RoF2::INULL, RoF2::INULL,
RoF2::invbag::SLOT_COUNT, RoF2::invbag::SLOT_COUNT,
RoF2::invaug::SOCKET_COUNT, RoF2::invaug::SOCKET_COUNT,
false,
false,
false,
false
),
/*[MobVersion::OfflineSteamLatest] =*/
//SteamLatestTodo: Need to use their own values instead of RoF2
EQ::inventory::LookupEntry(
EQ::inventory::LookupEntry::InventoryTypeSize_Struct(
RoF2::INULL, RoF2::INULL, RoF2::INULL,
RoF2::invtype::TRADE_SIZE, RoF2::INULL, RoF2::INULL,
RoF2::INULL, RoF2::INULL, RoF2::INULL,
RoF2::invtype::MERCHANT_SIZE, RoF2::INULL, RoF2::INULL,
RoF2::invtype::BAZAAR_SIZE, RoF2::invtype::INSPECT_SIZE, RoF2::INULL,
RoF2::invtype::VIEW_MOD_PC_SIZE, RoF2::invtype::VIEW_MOD_BANK_SIZE, RoF2::invtype::VIEW_MOD_SHARED_BANK_SIZE,
RoF2::invtype::VIEW_MOD_LIMBO_SIZE, RoF2::INULL, RoF2::INULL,
RoF2::INULL, RoF2::INULL, RoF2::INULL,
RoF2::INULL
),
RoF2::INULL,
RoF2::INULL,
RoF2::INULL,
RoF2::INULL,
RoF2::INULL,
RoF2::invbag::SLOT_COUNT,
RoF2::invaug::SOCKET_COUNT,
false, false,
false, false,
@ -1000,6 +1065,11 @@ static const EQ::behavior::LookupEntry behavior_static_lookup_entries[EQ::versio
EQ::behavior::LookupEntry( EQ::behavior::LookupEntry(
RoF2::behavior::CoinHasWeight RoF2::behavior::CoinHasWeight
), ),
/*[MobVersion::SteamLatest] =*/
//SteamLatestTodo: We need this value set properly
EQ::behavior::LookupEntry(
RoF2::behavior::CoinHasWeight
),
/*[MobVersion::NPC] =*/ /*[MobVersion::NPC] =*/
EQ::behavior::LookupEntry( EQ::behavior::LookupEntry(
EQ::behavior::CoinHasWeight EQ::behavior::CoinHasWeight
@ -1053,6 +1123,11 @@ static const EQ::behavior::LookupEntry behavior_static_lookup_entries[EQ::versio
RoF::behavior::CoinHasWeight RoF::behavior::CoinHasWeight
), ),
/*[MobVersion::OfflineRoF2] =*/ /*[MobVersion::OfflineRoF2] =*/
EQ::behavior::LookupEntry(
RoF2::behavior::CoinHasWeight
),
/*[MobVersion::OfflineSteamLatest] =*/
//SteamLatestTodo: We need this value set properly
EQ::behavior::LookupEntry( EQ::behavior::LookupEntry(
RoF2::behavior::CoinHasWeight RoF2::behavior::CoinHasWeight
) )
@ -1209,6 +1284,19 @@ static const EQ::spells::LookupEntry spells_static_lookup_entries[EQ::versions::
RoF2::spells::PET_BUFFS, RoF2::spells::PET_BUFFS,
RoF2::spells::MERC_BUFFS RoF2::spells::MERC_BUFFS
) )
/*[ClientVersion::SteamLatest] =*/
EQ::spells::LookupEntry(
SteamLatest::spells::SPELL_ID_MAX,
SteamLatest::spells::SPELLBOOK_SIZE,
UF::spells::SPELL_GEM_COUNT, // client translators are setup to allow the max value a client supports..however, the top 4 indices are not valid in this case
SteamLatest::spells::LONG_BUFFS,
SteamLatest::spells::SHORT_BUFFS,
SteamLatest::spells::DISC_BUFFS,
SteamLatest::spells::TOTAL_BUFFS,
SteamLatest::spells::NPC_BUFFS,
SteamLatest::spells::PET_BUFFS,
SteamLatest::spells::MERC_BUFFS
)
}; };
static bool spells_dictionary_init = false; static bool spells_dictionary_init = false;

View File

@ -23,6 +23,7 @@
#include "common/patches/rof2_limits.h" #include "common/patches/rof2_limits.h"
#include "common/patches/sod_limits.h" #include "common/patches/sod_limits.h"
#include "common/patches/sof_limits.h" #include "common/patches/sof_limits.h"
#include "common/patches/steam_latest_limits.h"
#include "common/patches/titanium_limits.h" #include "common/patches/titanium_limits.h"
#include "common/patches/uf_limits.h" #include "common/patches/uf_limits.h"
#include "common/types.h" #include "common/types.h"

View File

@ -47,6 +47,13 @@ static const uint32 ADVANCED_LORE_LENGTH = 8192;
#pragma pack(push) #pragma pack(push)
#pragma pack(1) #pragma pack(1)
struct EqGuid
{
uint32_t Id;
uint16_t WorldId;
uint16_t Reserved;
};
struct LoginInfo { struct LoginInfo {
/*000*/ char login_info[64]; /*000*/ char login_info[64];
/*064*/ uint8 unknown064[124]; /*064*/ uint8 unknown064[124];
@ -326,6 +333,7 @@ union
bool buyer; bool buyer;
bool untargetable; bool untargetable;
uint32 npc_tint_id; uint32 npc_tint_id;
EqGuid CharacterGuid;
}; };
struct PlayerState_Struct { struct PlayerState_Struct {

View File

@ -21,6 +21,7 @@
#include "common/patches/rof2.h" #include "common/patches/rof2.h"
#include "common/patches/sod.h" #include "common/patches/sod.h"
#include "common/patches/sof.h" #include "common/patches/sof.h"
#include "common/patches/steam_latest.h"
#include "common/patches/titanium.h" #include "common/patches/titanium.h"
#include "common/patches/uf.h" #include "common/patches/uf.h"
@ -33,6 +34,7 @@ void RegisterAllPatches(EQStreamIdentifier &into)
UF::Register(into); UF::Register(into);
RoF::Register(into); RoF::Register(into);
RoF2::Register(into); RoF2::Register(into);
SteamLatest::Register(into);
} }
void ReloadAllPatches() void ReloadAllPatches()
@ -43,4 +45,5 @@ void ReloadAllPatches()
UF::Reload(); UF::Reload();
RoF::Reload(); RoF::Reload();
RoF2::Reload(); RoF2::Reload();
SteamLatest::Reload();
} }

File diff suppressed because it is too large Load Diff

View File

View File

View File

@ -0,0 +1,336 @@
#ifndef COMMON_LAURION_LIMITS_H
#define COMMON_LAURION_LIMITS_H
#include "../types.h"
#include "../emu_versions.h"
#include "../skills.h"
namespace SteamLatest
{
const int16 IINVALID = -1;
const int16 INULL = 0;
namespace inventory {
inline EQ::versions::ClientVersion GetInventoryRef() { return EQ::versions::ClientVersion::SteamLatest; }
const bool ConcatenateInvTypeLimbo = false;
const bool AllowOverLevelEquipment = true;
const bool AllowEmptyBagInBag = true;
const bool AllowClickCastFromBag = true;
} /*inventory*/
namespace invtype {
inline EQ::versions::ClientVersion GetInvTypeRef() { return EQ::versions::ClientVersion::SteamLatest; }
namespace enum_ {
enum InventoryTypes : int16 {
typePossessions = INULL,
typeBank,
typeSharedBank,
typeTrade,
typeWorld,
typeLimbo,
typeTribute,
typeTrophyTribute,
typeGuildTribute,
typeMerchant,
typeDeleted,
typeCorpse,
typeBazaar,
typeInspect,
typeRealEstate,
typeViewMODPC,
typeViewMODBank,
typeViewMODSharedBank,
typeViewMODLimbo,
typeAltStorage,
typeArchived,
typeMail,
typeGuildTrophyTribute,
typeKrono,
typeOther,
typeMercenaryItems,
typeViewModMercenaryItems,
typeMountKeyRingItems,
typeViewModMountKeyRingItems,
typeIllusionKeyRingItems,
typeViewModIllusionKeyRingItems,
typeFamiliarKeyRingItems,
typeViewModFamiliarKeyRingItems,
typeHeroForgeKeyRingItems,
typeViewModHeroForgeKeyRingItems,
typeTeleportationKeyRingItems,
typeViewModTeleportationKeyRingItems,
typeOverflow,
typeDragonHoard,
typeTradeskillDepot,
typeGuildTradeskillDepot
};
} // namespace enum_
using namespace enum_;
const int16 POSSESSIONS_SIZE = 34;
const int16 BANK_SIZE = 24;
const int16 SHARED_BANK_SIZE = 2;
const int16 TRADE_SIZE = 8;
const int16 WORLD_SIZE = 10;
const int16 LIMBO_SIZE = 36;
const int16 TRIBUTE_SIZE = 5;
const int16 TROPHY_TRIBUTE_SIZE = 0;//unknown
const int16 GUILD_TRIBUTE_SIZE = 2;//unverified
const int16 MERCHANT_SIZE = 200;
const int16 DELETED_SIZE = 0;//unknown - "Recovery Tab"
const int16 CORPSE_SIZE = POSSESSIONS_SIZE;
const int16 BAZAAR_SIZE = 200;
const int16 INSPECT_SIZE = 23;
const int16 REAL_ESTATE_SIZE = 0;//unknown
const int16 VIEW_MOD_PC_SIZE = POSSESSIONS_SIZE;
const int16 VIEW_MOD_BANK_SIZE = BANK_SIZE;
const int16 VIEW_MOD_SHARED_BANK_SIZE = SHARED_BANK_SIZE;
const int16 VIEW_MOD_LIMBO_SIZE = LIMBO_SIZE;
const int16 ALT_STORAGE_SIZE = 0;//unknown - "Shroud Bank"
const int16 ARCHIVED_SIZE = 0;//unknown
const int16 MAIL_SIZE = 0;//unknown
const int16 GUILD_TROPHY_TRIBUTE_SIZE = 0;//unknown
const int16 KRONO_SIZE = 0;//unknown
const int16 OTHER_SIZE = 0;//unknown
const int16 TRADE_NPC_SIZE = 4; // defined by implication
const int16 TYPE_INVALID = IINVALID;
const int16 TYPE_BEGIN = typePossessions;
const int16 TYPE_END = typeOther;
const int16 TYPE_COUNT = (TYPE_END - TYPE_BEGIN) + 1;
int16 GetInvTypeSize(int16 inv_type);
const char* GetInvTypeName(int16 inv_type);
bool IsInvTypePersistent(int16 inv_type);
} /*invtype*/
namespace invslot {
inline EQ::versions::ClientVersion GetInvSlotRef() { return EQ::versions::ClientVersion::SteamLatest; }
namespace enum_ {
enum InventorySlots : int16 {
slotCharm = INULL,
slotEar1,
slotHead,
slotFace,
slotEar2,
slotNeck,
slotShoulders,
slotArms,
slotBack,
slotWrist1,
slotWrist2,
slotRange,
slotHands,
slotPrimary,
slotSecondary,
slotFinger1,
slotFinger2,
slotChest,
slotLegs,
slotFeet,
slotWaist,
slotPowerSource,
slotAmmo,
slotGeneral1,
slotGeneral2,
slotGeneral3,
slotGeneral4,
slotGeneral5,
slotGeneral6,
slotGeneral7,
slotGeneral8,
slotGeneral9,
slotGeneral10,
slotGeneral11,
slotGeneral12,
slotCursor
};
constexpr int16 format_as(InventorySlots slot) { return static_cast<int16>(slot); }
} // namespace enum_
using namespace enum_;
const int16 SLOT_INVALID = IINVALID;
const int16 SLOT_BEGIN = INULL;
const int16 POSSESSIONS_BEGIN = slotCharm;
const int16 POSSESSIONS_END = slotCursor;
const int16 POSSESSIONS_COUNT = (POSSESSIONS_END - POSSESSIONS_BEGIN) + 1;
const int16 EQUIPMENT_BEGIN = slotCharm;
const int16 EQUIPMENT_END = slotAmmo;
const int16 EQUIPMENT_COUNT = (EQUIPMENT_END - EQUIPMENT_BEGIN) + 1;
//We support more if enabled but for now lets leave it at the 10 slots
const int16 GENERAL_BEGIN = slotGeneral1;
const int16 GENERAL_END = slotGeneral10;
const int16 GENERAL_COUNT = (GENERAL_END - GENERAL_BEGIN) + 1;
const int16 BONUS_BEGIN = invslot::slotCharm;
const int16 BONUS_STAT_END = invslot::slotPowerSource;
const int16 BONUS_SKILL_END = invslot::slotAmmo;
const int16 CORPSE_BEGIN = invslot::slotGeneral1;
const int16 CORPSE_END = invslot::slotGeneral1 + invslot::slotCursor;
const uint64 EQUIPMENT_BITMASK = 0x00000000007FFFFF;
const uint64 GENERAL_BITMASK = 0x00000007FF800000;
const uint64 CURSOR_BITMASK = 0x0000000800000000;
const uint64 POSSESSIONS_BITMASK = (EQUIPMENT_BITMASK | GENERAL_BITMASK | CURSOR_BITMASK); // based on 36-slot count (SteamLatest+)
const uint64 CORPSE_BITMASK = (GENERAL_BITMASK | CURSOR_BITMASK | (EQUIPMENT_BITMASK << 36)); // based on 36-slot count (SteamLatest+)
const char* GetInvPossessionsSlotName(int16 inv_slot);
const char* GetInvSlotName(int16 inv_type, int16 inv_slot);
} /*invslot*/
namespace invbag {
inline EQ::versions::ClientVersion GetInvBagRef() { return EQ::versions::ClientVersion::SteamLatest; }
const int16 SLOT_INVALID = IINVALID;
const int16 SLOT_BEGIN = INULL;
const int16 SLOT_END = 9; //254;
const int16 SLOT_COUNT = 10; //255; // server Size will be 255..unsure what actual client is (test)
const char* GetInvBagIndexName(int16 bag_index);
} /*invbag*/
namespace invaug {
inline EQ::versions::ClientVersion GetInvAugRef() { return EQ::versions::ClientVersion::SteamLatest; }
const int16 SOCKET_INVALID = IINVALID;
const int16 SOCKET_BEGIN = INULL;
const int16 SOCKET_END = 5;
const int16 SOCKET_COUNT = 6;
const char* GetInvAugIndexName(int16 aug_index);
} /*invaug*/
namespace item {
inline EQ::versions::ClientVersion GetItemRef() { return EQ::versions::ClientVersion::SteamLatest; }
//enum Unknown : int { // looks like item class..but, RoF has it too - nothing in UF-
// Unknown1 = 0,
// Unknown2 = 1,
// Unknown3 = 2,
// Unknown4 = 5 // krono?
//};
enum ItemPacketType : int {
ItemPacketMerchant = 0x64,
ItemPacketTradeView = 0x65,
ItemPacketLoot = 0x66,
ItemPacketTrade = 0x67,
//looks like they added something at 0x68 that didn't exist before and shifted everything after it up by 1
ItemPacketUnknown068 = 0x68, //Not sure but it seems to deal with the cursor somehow.
ItemPacketCharInventory = 0x6A, //Rof 0x69 -> Larion 0x6a (requires translation)
ItemPacketLimbo = 0x6B, //0x6A -> 0x6B
ItemPacketWorldContainer = 0x6C,
ItemPacketTributeItem = 0x6D,
ItemPacketGuildTribute = 0x6E,
ItemPacketCharmUpdate = 0x6f,
ItemPacketRecovery = 0x72,
ItemPacketParcel = 0x74,
ItemPacketUnknown075 = 0x75, //Not sure but uses a lot of the same logic as the trade and char inventory types
ItemPacketOverflow = 0x76,
ItemPacketDragonHoard = 0x77,
ItemPacketTradeskill = 0x78,
ItemPacketTradeskillDepot = 0x79,
ItemPacketInvalid = 0xFF
};
} /*item*/
namespace profile {
inline EQ::versions::ClientVersion GetProfileRef() { return EQ::versions::ClientVersion::SteamLatest; }
const int16 BANDOLIERS_SIZE = 20; // number of bandolier instances
const int16 BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
const int16 POTION_BELT_SIZE = 5;
const int16 SKILL_ARRAY_SIZE = 100;
} /*profile*/
namespace constants {
inline EQ::versions::ClientVersion GetConstantsRef() { return EQ::versions::ClientVersion::SteamLatest; }
const EQ::expansions::Expansion EXPANSION = EQ::expansions::Expansion::LS;
const uint32 EXPANSION_BIT = EQ::expansions::bitLS;
const uint32 EXPANSIONS_MASK = EQ::expansions::maskLS;
const size_t CHARACTER_CREATION_LIMIT = 12;
const size_t SAY_LINK_BODY_SIZE = 56;
const uint32 MAX_GUILD_ID = 50000;
} /*constants*/
namespace behavior {
inline EQ::versions::ClientVersion GetBehaviorRef() { return EQ::versions::ClientVersion::SteamLatest; }
const bool CoinHasWeight = false;
} /*behavior*/
namespace skills {
inline EQ::versions::ClientVersion GetSkillsRef() { return EQ::versions::ClientVersion::SteamLatest; }
const size_t LastUsableSkill = EQ::skills::Skill2HPiercing;
} /*skills*/
namespace spells {
inline EQ::versions::ClientVersion GetSkillsRef() { return EQ::versions::ClientVersion::SteamLatest; }
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
Gem3 = 2,
Gem4 = 3,
Gem5 = 4,
Gem6 = 5,
Gem7 = 6,
Gem8 = 7,
Gem9 = 8,
Gem10 = 9,
Gem11 = 10,
Gem12 = 11,
MaxGems = 18, // fallacy..only 12 slot are useable...
Item = 12,
Discipline = 13,
AltAbility = 0xFF
};
const int SPELL_ID_MAX = 71999;
const int SPELLBOOK_SIZE = 1120;
const int SPELL_GEM_COUNT = static_cast<uint32>(CastingSlot::MaxGems);
const int SPELL_GEM_RECAST_TIMER = 15;
const int LONG_BUFFS = 42;
const int SHORT_BUFFS = 30;
const int DISC_BUFFS = 1;
const int TOTAL_BUFFS = LONG_BUFFS + SHORT_BUFFS + DISC_BUFFS;
const int NPC_BUFFS = 400;
const int PET_BUFFS = NPC_BUFFS;
const int MERC_BUFFS = LONG_BUFFS;
} /*spells*/
}; /* SteamLatest */
#endif /*COMMON_LAURION_LIMITS_H*/

View File

@ -0,0 +1,95 @@
//list of packets we need to encode on the way out:
E(OP_Action)
E(OP_Animation)
E(OP_ApplyPoison)
E(OP_AugmentInfo)
E(OP_BeginCast)
E(OP_BlockedBuffs)
E(OP_Buff)
E(OP_BuffCreate)
E(OP_CancelTrade)
E(OP_CastSpell)
E(OP_ChannelMessage)
E(OP_CharInventory)
E(OP_ClickObjectAction)
E(OP_ClientUpdate)
E(OP_Consider)
E(OP_Damage)
E(OP_Death)
E(OP_DeleteCharge)
E(OP_DeleteItem)
E(OP_DeleteSpawn)
E(OP_DisciplineUpdate)
E(OP_ExpansionInfo)
E(OP_ExpUpdate)
E(OP_FormattedMessage)
E(OP_GMTraining)
E(OP_GMTrainSkillConfirm)
E(OP_GroundSpawn)
E(OP_HPUpdate)
E(OP_Illusion)
E(OP_ItemPacket)
E(OP_LogServer)
E(OP_ManaChange)
E(OP_MobHealth)
E(OP_MoneyOnCorpse)
E(OP_MoveItem)
E(OP_NewSpawn)
E(OP_NewZone)
E(OP_OnLevelMessage)
E(OP_PlayerProfile)
E(OP_RemoveBlockedBuffs)
E(OP_RespondAA)
E(OP_RequestClientZoneChange)
E(OP_RecipeAutoCombine)
E(OP_SendAATable)
E(OP_SendCharInfo)
E(OP_SendMaxCharacters)
E(OP_SendMembership)
E(OP_SendMembershipDetails)
E(OP_SendZonepoints)
E(OP_ShopPlayerBuy)
E(OP_ShopPlayerSell)
E(OP_ShopRequest)
E(OP_SkillUpdate)
E(OP_SpecialMesg)
E(OP_SpawnAppearance)
E(OP_SpawnDoor)
E(OP_Stun)
E(OP_WearChange)
E(OP_ZoneChange)
E(OP_ZoneEntry)
E(OP_ZonePlayerToBind)
E(OP_ZoneSpawns)
//list of packets we need to decode on the way in:
D(OP_Animation)
D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_BlockedBuffs)
D(OP_CastSpell)
D(OP_ChannelMessage)
D(OP_ClientUpdate)
D(OP_ClickDoor)
D(OP_Consider)
D(OP_ConsiderCorpse)
D(OP_DeleteItem)
D(OP_EnterWorld)
D(OP_GMTraining)
D(OP_GroupDisband)
D(OP_GroupInvite)
D(OP_GroupInvite2)
D(OP_MoveItem)
D(OP_RemoveBlockedBuffs)
D(OP_SetServerFilter)
D(OP_ShopPlayerBuy)
D(OP_ShopPlayerSell)
D(OP_ShopRequest)
D(OP_SpawnAppearance)
D(OP_TradeSkillCombine)
D(OP_WearChange)
D(OP_ZoneEntry)
D(OP_ZoneChange)
#undef E
#undef D

File diff suppressed because it is too large Load Diff

View File

@ -354,6 +354,7 @@ RULE_STRING(World, CustomFilesKey, "", "Enable if the server requires custom fil
RULE_STRING(World, CustomFilesUrl, "github.com/knervous/eqnexus/releases", "URL to display at character select if client is missing custom files") RULE_STRING(World, CustomFilesUrl, "github.com/knervous/eqnexus/releases", "URL to display at character select if client is missing custom files")
RULE_INT(World, CustomFilesAdminLevel, 20, "Admin level at which custom file key is not required when CustomFilesKey is specified") RULE_INT(World, CustomFilesAdminLevel, 20, "Admin level at which custom file key is not required when CustomFilesKey is specified")
RULE_BOOL(World, RealTimeCalculateGuilds, false, "(Temp feature flag) If true, guilds will be calculated in real time instead of at zone boot. This is a performance hit but allows for more dynamic guilds.") RULE_BOOL(World, RealTimeCalculateGuilds, false, "(Temp feature flag) If true, guilds will be calculated in real time instead of at zone boot. This is a performance hit but allows for more dynamic guilds.")
RULE_INT(World, Id, 100, "Used by later clients to create GUIDs, expected to be Unique to the world but ultimately not that important")
RULE_CATEGORY_END() RULE_CATEGORY_END()
RULE_CATEGORY(Zone) RULE_CATEGORY(Zone)

View File

@ -0,0 +1,699 @@
# ShowEQ Import Notes:
# ZERO THE FILE first
# perl -pi -e 's/0x[0-9a-fA-F]{4}/0x0000/g' opcodes.conf
# Unknown Mapping:
# OP_Action2 -> OP_Damage
# OP_EnvDamage -> OP_Damage ---> might have been a one time mistake
# Name Differences:
# OP_CancelInvite -> OP_GroupCancelInvite
# OP_GMFind -> OP_FindPersonRequest
# OP_CommonMessage -> OP_ChannelMessage
OP_Unknown=0x0000
OP_ExploreUnknown=0x0000 # used for unknown explorer
# world packets
# Required to reach Char Select:
OP_SendLoginInfo=0x2fca
OP_ApproveWorld=0x0000
OP_LogServer=0x6d4d
OP_SendCharInfo=0x832
OP_ExpansionInfo=0x066d
OP_EnterWorld=0x6691
OP_PostEnterWorld=0x2062
OP_World_Client_CRC1=0x74c8
OP_World_Client_CRC2=0x3984
OP_World_Client_CRC3=0x6516
OP_SendSpellChecksum=0x0000
OP_SendSkillCapsChecksum=0x0000
# Character Select Related:
OP_SendMaxCharacters=0x13af
OP_SendMembership=0x2aca
OP_SendMembershipDetails=0x2608
OP_CharacterCreateRequest=0x2df4
OP_CharacterCreate=0x6a3c
OP_DeleteCharacter=x67d7
OP_RandomNameGenerator=0x49d9
OP_ApproveName=0x11e5
OP_MOTD=0x0be4
OP_SetChatServer=0x0000
OP_SetChatServer2=0x2726
OP_ZoneServerInfo=0x2273
OP_WorldComplete=0x195c
OP_WorldUnknown001=0x2049
OP_FloatListThing=0x66fd
# Reasons for Disconnect:
OP_ZoneUnavail=0x582d
OP_WorldClientReady=0x7ed8
OP_CharacterStillInZone=0x0000
OP_WorldChecksumFailure=0x0000
OP_WorldLoginFailed=0x0000
OP_WorldLogout=0x0000
OP_WorldLevelTooHigh=0x0000
OP_CharInacessable=0x0000
OP_UserCompInfo=0x0000
OP_SendExeChecksum=0x0000
OP_SendBaseDataChecksum=0x0000
# Zone in opcodes
OP_AckPacket=0x77c9
OP_ZoneEntry=0x784a
OP_ReqNewZone=0x3895
OP_NewZone=0x4341
OP_ZoneSpawns=0x17d9
OP_PlayerProfile=0x1c76
OP_TimeOfDay=0x3736
OP_LevelUpdate=0x0eb2
OP_Stamina=0x1563
OP_RequestClientZoneChange=0x0191
OP_ZoneChange=0x17a3
OP_LockoutTimerInfo=0x0000
OP_ZoneServerReady=0x0000
OP_ZoneInUnknown=0x0000
OP_LogoutReply=0x0000
OP_PreLogoutReply=0x0000
# Required to fully log in
OP_SpawnAppearance=0x4eb0
OP_ChangeSize=0x2fdc
OP_Weather=0x6fe6
OP_ReqClientSpawn=0x6732
OP_SpawnDoor=0x4273
OP_GroundSpawn=0x49c5
OP_SendZonepoints=0x279f
OP_BlockedBuffs=0x4fdb
OP_RemoveBlockedBuffs=0x53cd
OP_ClearBlockedBuffs=0x5752
OP_WorldObjectsSent=0x2879
OP_SendExpZonein=0x02b4
OP_SendAATable=0x5f30
OP_ClearAA=0x3498
OP_ClearLeadershipAbilities=0x0000 #removed; leadership abilities are baked in and always on
OP_RespondAA=0x4c67
OP_UpdateAA=0x3b30
OP_SendAAStats=0x7d65 #i'll be honest i think this was removed at some point but this is the op at the spot in the list
OP_AAExpUpdate=0x642f #need to look into whether this has changed; exp did
OP_ExpUpdate=0x611d
OP_HPUpdate=0x775c
OP_ManaChange=0x700f
OP_TGB=0x0000 #removed; tgb is baked in and always on
OP_SpecialMesg=0x7d93
OP_CharInventory=0x21d6
OP_WearChange=0x44c0
OP_ClientUpdate=0x3a4b
OP_ClientReady=0x0831
OP_SetServerFilter=0x6b7f
# Guild Opcodes
OP_GuildsList=0x0000
OP_GuildMemberList=0x0000
OP_GuildMOTD=0x0000
OP_GetGuildMOTD=0x0000
OP_GetGuildMOTDReply=0x0000
OP_GuildMemberUpdate=0x0000
OP_GuildInvite=0x0000
OP_GuildRemove=0x0000
OP_GuildPeace=0x0000
OP_SetGuildMOTD=0x0000
OP_GuildWar=0x0000
OP_GuildLeader=0x0000
OP_GuildDelete=0x0000
OP_GuildInviteAccept=0x0000
OP_GuildDemote=0x0000
OP_GuildPromote=0x0000
OP_GuildPublicNote=0x0000
OP_GuildManageBanker=0x0000
OP_GuildBank=0x0000
OP_GuildBankItemList=0x0000
OP_SetGuildRank=0x0000
OP_GuildUpdate=0x0000
OP_GuildStatus=0x0000
OP_GuildCreate=0x0000
OP_GuildOpenGuildWindow=0x0000
OP_GuildMemberLevel=0x0000
OP_GuildMemberRankAltBanker=0x0000
OP_GuildMemberPublicNote=0x0000
OP_GuildMemberAdd=0x0000
OP_GuildMemberRename=0x0000
OP_GuildMemberDelete=0x0000
OP_GuildMemberDetails=0x0000
OP_GuildRenameGuild=0x0000
OP_LFGuild=0x0000
OP_GuildDeleteGuild=0x0000
# GM/Guide Opcodes
OP_GMServers=0x0000
OP_GMBecomeNPC=0x0000
OP_GMZoneRequest=0x0000
OP_GMZoneRequest2=0x0000
OP_GMGoto=0x0000
OP_GMSearchCorpse=0x0000
OP_GMHideMe=0x0000
OP_GMDelCorpse=0x0000
OP_GMApproval=0x0000
OP_GMToggle=0x0000
OP_GMSummon=0x0000
OP_GMEmoteZone=0x0000
OP_GMEmoteWorld=0x0000
OP_GMFind=0x0000
OP_GMKick=0x0000
OP_GMKill=0x0000
OP_GMNameChange=0x0000
OP_GMLastName=0x0000
# Misc Opcodes
OP_QueryUCSServerStatus=0x2570
OP_InspectRequest=0x0000
OP_InspectAnswer=0x0000
OP_InspectMessageUpdate=0x0000
OP_BeginCast=0x31f9
OP_ColoredText=0x0f3c
OP_ConsentResponse=0x3229
OP_MemorizeSpell=0x1d31
OP_LinkedReuse=0x7a8e
OP_SwapSpell=0x63c7
OP_CastSpell=0x325b
OP_Consider=0x53e3
OP_FormattedMessage=0x7f7f
OP_SimpleMessage=0x1943
OP_Buff=0x6ce5
OP_Illusion=0x5a3f
OP_MoneyOnCorpse=0x39d3
OP_RandomReply=0x6603
OP_DenyResponse=0x3f2c
OP_SkillUpdate=0x6735
OP_GMTrainSkillConfirm=0x6fbc
OP_RandomReq=0x528a
OP_Death=0x429a
OP_GMTraining=0x7c7a
OP_GMEndTraining=0x3ec6
OP_GMTrainSkill=0x54e1
OP_Animation=0x79c7
OP_Begging=0x7ded
OP_Consent=0x44fc
OP_ConsentDeny=0x3df9
OP_AutoFire=0x5280
OP_PetCommands=0x0000
OP_PetCommandState=0x0000
OP_PetHoTT=0x0000
OP_DeleteSpell=0x4281
OP_Surname=0x0000
OP_ClearSurname=0x0000
OP_FaceChange=0x0000
OP_SetFace=0x0000
OP_SenseHeading=0x6fcf
OP_Action=0x4c13
OP_ConsiderCorpse=0x6092
OP_HideCorpse=0x3f5c
OP_CorpseDrag=0x234d
OP_CorpseDrop=0x4342
OP_Bug=0x770b
OP_Feedback=0x0000
OP_Report=0x5bcf
OP_Damage=0x7d07
OP_ChannelMessage=0x6adc
OP_Assist=0x51f1
OP_AssistGroup=0x3f23
OP_MoveCoin=0x4e6a
OP_ZonePlayerToBind=0x5643
OP_KeyRing=0x0000
OP_WhoAllRequest=0x2a09
OP_WhoAllResponse=0x6404
OP_FriendsWho=0x75a2
OP_ConfirmDelete=0x4dd0
OP_Logout=0x771d
OP_Rewind=0x2b19
OP_TargetCommand=0x3b18
OP_Hide=0x1cdf
OP_Jump=0x6fa0
OP_Camp=0x326f
OP_Emote=0x0000
OP_SetRunMode=0x1449
OP_BankerChange=0x2a33
OP_TargetMouse=0x5741
OP_MobHealth=0x5b77
OP_InitialMobHealth=0x0000 # Unused?
OP_TargetHoTT=0x0000
OP_TargetBuffs=0x0000
OP_XTargetResponse=0x0000
OP_XTargetRequest=0x0000
OP_XTargetAutoAddHaters=0x0000
OP_XTargetOpen=0x0000
OP_XTargetOpenResponse=0x0000
OP_BuffCreate=0x27a1
OP_BuffRemoveRequest=0x4507
OP_DeleteSpawn=0x7712
OP_AutoAttack=0x3f03
OP_AutoAttack2=0x1c31
OP_Consume=0x5ef7
OP_MoveItem=0x11e3
OP_MoveMultipleItems=0x5205
OP_DeleteItem=0x0150
OP_DeleteCharge=0x1b7e
OP_ItemPacket=0x7d43
OP_ItemLinkResponse=0x0000
OP_ItemLinkClick=0x0000
OP_ItemPreview=0x0000
OP_NewSpawn=0x3ea8
OP_Track=0x5351
OP_TrackTarget=0x611a
OP_TrackUnknown=0x2c7a
OP_ClickDoor=0x733c
OP_MoveDoor=0x567c
OP_RemoveAllDoors=0x73e8
OP_EnvDamage=0x1ffd
OP_BoardBoat=0x7015
OP_LeaveBoat=0x2486
OP_ControlBoat=0x166f
OP_Forage=0x4c52
OP_SafeFallSuccess=0x6690
OP_RezzComplete=0x0000
OP_RezzRequest=0x0000
OP_RezzAnswer=0x0000
OP_Shielding=0x0000
OP_RequestDuel=0x0000
OP_MobRename=0x0000
OP_AugmentItem=0x3a1b
OP_WeaponEquip1=0x0000
OP_PlayerStateAdd=0x2178
OP_PlayerStateRemove=0x178e
OP_ApplyPoison=0x55b9
OP_Save=0x6da2
OP_TestBuff=0x0000
OP_CustomTitles=0x0000
OP_Split=0x7f6e
OP_YellForHelp=0x5fc9
OP_LoadSpellSet=0x0000
OP_Bandolier=0x0000
OP_PotionBelt=0x0000
OP_DuelDecline=0x0000
OP_DuelAccept=0x0000
OP_SaveOnZoneReq=0x3bfe
OP_ReadBook=0x51af
OP_Dye=0x0000
OP_InterruptCast=0x1d71
OP_AAAction=0x71BB
OP_LeadershipExpToggle=0x0000 #removed, these act as if all purchased now
OP_LeadershipExpUpdate=0x0000 #removed, these act as if all purchased now
OP_PurchaseLeadershipAA=0x0000 #removed, these act as if all purchased now
OP_UpdateLeadershipAA=0x0000 #removed, these act as if all purchased now
OP_MarkNPC=0x0000
OP_ClearNPCMarks=0x0000
OP_DelegateAbility=0x0000
OP_SetGroupTarget=0x0000
OP_Charm=0x66bb
OP_Stun=0x34be
OP_SendFindableNPCs=0x0000
OP_FindPersonRequest=0x0000
OP_FindPersonReply=0x0000
OP_Sound=0x2fa8
OP_CashReward=0x5e23
OP_PetBuffWindow=0x0000
OP_LevelAppearance=0x5d24
OP_Translocate=0x2772
OP_Sacrifice=0x2cbf
OP_PopupResponse=0x6be9
OP_OnLevelMessage=0x2a41
OP_AugmentInfo=0x2e11
OP_Petition=0x0000
OP_SomeItemPacketMaybe=0x0000
OP_PVPStats=0x0000
OP_PVPLeaderBoardRequest=0x0000
OP_PVPLeaderBoardReply=0x0000
OP_PVPLeaderBoardDetailsRequest=0x0000
OP_PVPLeaderBoardDetailsReply=0x0000
OP_RestState=0x0a92
OP_RespawnWindow=0x55ed
OP_LDoNButton=0x0000
OP_SetStartCity=0x0000
OP_VoiceMacroIn=0x703f
OP_VoiceMacroOut=0x72d1
OP_ItemViewUnknown=0x0000
OP_VetRewardsAvaliable=0x0000
OP_VetClaimRequest=0x0000
OP_VetClaimReply=0x0000
OP_DisciplineUpdate=0x6ce4
OP_DisciplineTimer=0x7436
OP_BecomeCorpse=0x0000 # Unused?
OP_Action2=0x0000 # Unused?
OP_MobUpdate=0x0000
OP_NPCMoveUpdate=0x0000
OP_CameraEffect=0x2f01
OP_SpellEffect=0x7378
OP_AddNimbusEffect=0x069f
OP_RemoveNimbusEffect=0x19ee
OP_AltCurrency=0x0000
OP_AltCurrencyMerchantRequest=0x0000
OP_AltCurrencyMerchantReply=0x0000
OP_AltCurrencyPurchase=0x0000
OP_AltCurrencySell=0x0000
OP_AltCurrencySellSelection=0x0000
OP_AltCurrencyReclaim=0x0000
OP_CrystalCountUpdate=0x0000
OP_CrystalCreate=0x0000
OP_CrystalReclaim=0x0000
OP_Untargetable=0x026f
OP_IncreaseStats=0x1005
OP_Weblink=0x16a3
OP_OpenContainer=0x6758
OP_Marquee=0x6bca
OP_ItemRecastDelay=0x547a
#OP_OpenInventory=0x0000 # Likely does not exist in RoF -U
OP_ResetAA=0x53c0
OP_Fling=0x3731
OP_CancelSneakHide=0x7452
OP_AggroMeterLockTarget=0x0000
OP_AggroMeterTargetInfo=0x0000
OP_AggroMeterUpdate=0x0000
OP_UnderWorld=0x4ca9 # clients sends up when they detect an underworld issue, might be useful for cheat detection
OP_KickPlayers=0x7154
OP_BookButton=0x014d
# Expeditions
OP_DzQuit=0x0000
OP_DzListTimers=0x0000
OP_DzAddPlayer=0x0000
OP_DzRemovePlayer=0x0000
OP_DzSwapPlayer=0x0000
OP_DzMakeLeader=0x0000
OP_DzPlayerList=0x0000
OP_DzExpeditionInvite=0x0000
OP_DzExpeditionInviteResponse=0x0000
OP_DzExpeditionInfo=0x0000
OP_DzExpeditionLockoutTimers=0x0000
OP_DzMemberList=0x0000
OP_DzMemberListName=0x0000
OP_DzMemberListStatus=0x0000
OP_DzSetLeaderName=0x0000
OP_DzExpeditionEndsWarning=0x0000
OP_DzCompass=0x0000
OP_DzChooseZone=0x0000
OP_DzChooseZoneReply=0x0000
# New Opcodes
OP_SpawnPositionUpdate=0x0000 # Actually OP_MobUpdate ?
OP_ManaUpdate=0x0000
OP_EnduranceUpdate=0x0000
OP_MobManaUpdate=0x0000
OP_MobEnduranceUpdate=0x0000
# Mercenary Opcodes
OP_MercenaryDataUpdateRequest=0x0000
OP_MercenaryDataUpdate=0x0000
OP_MercenaryDataRequest=0x0000
OP_MercenaryDataResponse=0x0000
OP_MercenaryHire=0x0000
OP_MercenaryDismiss=0x0000
OP_MercenaryTimerRequest=0x0000
OP_MercenaryTimer=0x0000
OP_MercenaryUnknown1=0x0000
OP_MercenaryCommand=0x0000
OP_MercenarySuspendRequest=0x0000
OP_MercenarySuspendResponse=0x0000
OP_MercenaryUnsuspendResponse=0x0000
# Looting
OP_LootRequest=0x60e5
OP_EndLootRequest=0x35f6
OP_LootItem=0x0856
OP_LootComplete=0x1f5e
# bazaar trader stuff:
OP_BazaarSearch=0x0000
OP_TraderDelItem=0x0000
OP_BecomeTrader=0x0000
OP_TraderShop=0x0000
OP_TraderBulkSend=0x0000
OP_Trader=0x0000
OP_Barter=0x0000
OP_BuyerItems=0x0000
OP_TraderBuy=0x0000
OP_ShopItem=0x0000
OP_BazaarInspect=0x0000
OP_Bazaar=0x0000
OP_TraderItemUpdate=0x0000
# pc/npc trading
OP_TradeRequest=0x7066
OP_TradeAcceptClick=0x34ad
OP_TradeRequestAck=0x1c6b
OP_TradeCoins=0x44fe
OP_FinishTrade=0x0ec6
OP_CancelTrade=0x5839
OP_TradeMoneyUpdate=0x5fb3
OP_MoneyUpdate=0x70bb
OP_TradeBusy=0x109f
# Sent after canceling trade or after closing tradeskill object
OP_FinishWindow=0x50d4
OP_FinishWindow2=0x6b03
# Sent on Live for what seems to be item existance verification
# Ex. Before Right Click Effect happens from items
OP_ItemVerifyRequest=0x2003
OP_ItemVerifyReply=0x43d0
OP_ItemAdvancedLoreText=0x0000
# merchant stuff
OP_ShopPlayerSell=0x6489
OP_ShopRequest=0x840
OP_ShopEnd=0x74bb
OP_ShopEndConfirm=0x2ed1
OP_ShopPlayerBuy=0x625e
OP_ShopDelItem=0x4ce4
OP_ShopSendParcel=0x0f16
OP_ShopDeleteParcel=0x4e2a
OP_ShopRetrieveParcel=0x27d1
OP_ShopParcelIcon=0x4f27
# tradeskill stuff:
OP_ClickObject=0x687e
OP_ClickObjectAction=0x110f
OP_ClearObject=0x6155
OP_RecipeDetails=0x01e7
OP_RecipesFavorite=0x0495
OP_RecipesSearch=0x2f4e
OP_RecipeReply=0x2cd2
OP_RecipeAutoCombine=0x5dba
OP_TradeSkillCombine=0x4ed8
# Tribute Packets:
OP_TributeUpdate=0x0000
OP_TributeTimer=0x0000
OP_SendTributes=0x0000
OP_RequestGuildTributes=0x0000
OP_TributeInfo=0x0000
OP_OpenTributeMaster=0x0000
OP_SelectTribute=0x0000
OP_TributeItem=0x0000
OP_TributeMoney=0x0000
OP_TributeToggle=0x0000
OP_TributePointUpdate=0x0000
OP_TributeNPC=0x0000
OP_GuildTributeInfo=0x0000
OP_OpenTributeReply=0x0000
OP_GuildTributeStatus=0x0000
OP_GuildSaveActiveTributes=0x0000
OP_GuildSendActiveTributes=0x0000
OP_GuildTributeToggleReq=0x0000
OP_GuildTributeToggleReply=0x0000
OP_GuildTributeFavorAndTimer=0x0000
OP_GuildTributeDonateItem=0x0000
OP_GuildTributeDonatePlat=0x0000
OP_GuildSelectTribute=0x0000
OP_GuildModifyBenefits=0x0000
OP_GuildOptInOut=0x0000
OP_SendGuildTributes=0x0000
OP_OpenGuildTributeMaster=0x0000
# Adventure packets:
OP_LeaveAdventure=0x0000
OP_AdventureFinish=0x0000
OP_AdventureInfoRequest=0x0000
OP_AdventureInfo=0x0000
OP_AdventureRequest=0x0000
OP_AdventureDetails=0x0000
OP_AdventureData=0x0000
OP_AdventureUpdate=0x0000
OP_AdventureMerchantRequest=0x0000
OP_AdventureMerchantResponse=0x0000
OP_AdventureMerchantPurchase=0x0000
OP_AdventureMerchantSell=0x0000
OP_AdventurePointsUpdate=0x0000
OP_AdventureStatsRequest=0x0000
OP_AdventureStatsReply=0x0000
OP_AdventureLeaderboardRequest=0x0000
OP_AdventureLeaderboardReply=0x0000
# Group Opcodes
OP_GroupDisband=0x78ef
OP_GroupInvite=0x1d90
OP_GroupFollow=0x0000
OP_GroupUpdate=0x0000
OP_GroupUpdateB=0x0000
OP_GroupCancelInvite=0x0000
OP_GroupAcknowledge=0x0000
OP_GroupDelete=0x0000
OP_CancelInvite=0x0000
OP_GroupFollow2=0x0000
OP_GroupInvite2=0x1e7e
OP_GroupDisbandYou=0x0000
OP_GroupDisbandOther=0x0000
OP_GroupLeaderChange=0x0000
OP_GroupRoles=0x0000
OP_GroupMakeLeader=0x0000
OP_DoGroupLeadershipAbility=0x0000
OP_GroupLeadershipAAUpdate=0x0000 # removed these act as if you have always purchased them
OP_GroupMentor=0x0000
OP_InspectBuffs=0x0000
# LFG/LFP Opcodes
OP_LFGCommand=0x0000
OP_LFGGetMatchesRequest=0x0000
OP_LFGGetMatchesResponse=0x0000
OP_LFPGetMatchesRequest=0x0000
OP_LFPGetMatchesResponse=0x0000
OP_LFPCommand=0x0000
OP_LFGAppearance=0x0000
OP_LFGResponse=0x0000
# Raid Opcodes
OP_RaidInvite=0x0000
OP_RaidUpdate=0x0000
OP_RaidJoin=0x0000
OP_RaidDelegateAbility=0x0000
OP_MarkRaidNPC=0x0000
OP_RaidClearNPCMarks=0x0000
# Button-push commands
OP_Taunt=0x5064
OP_CombatAbility=0xbf
OP_SenseTraps=0x579c
OP_PickPocket=0x53d1
OP_DisarmTraps=0x21bf
OP_Disarm=0x31e9
OP_Sneak=0x78a7
OP_Fishing=0x57cc
OP_InstillDoubt=0x57cc
OP_FeignDeath=0x14b8
OP_Mend=0x6b8
OP_Bind_Wound=0x650e
OP_LDoNOpen=0x448
OP_LDoNPickLock=0x61c8
OP_LDoNInspect=0xc1c
# Task packets
OP_TaskDescription=0x0000
OP_TaskActivity=0x0000
OP_CompletedTasks=0x0000
OP_TaskActivityComplete=0x0000
OP_AcceptNewTask=0x0000
OP_CancelTask=0x0000
OP_AvaliableTask=0x0000
OP_TaskHistoryRequest=0x0000
OP_TaskHistoryReply=0x0000
OP_DeclineAllTasks=0x0000
OP_TaskRequestTimer=0x0000
OP_TaskSelectWindow=0x0000
# Shared Tasks
OP_SharedTaskMemberList=0x0000 #
OP_SharedTaskRemovePlayer=0x0000 # /taskremoveplayer
OP_SharedTaskAddPlayer=0x0000 # /taskaddplayer
OP_SharedTaskMakeLeader=0x0000 # /taskmakeleader
OP_SharedTaskInvite=0x0000 # Dialog window
OP_SharedTaskInviteResponse=0x0000 # Dialog window response
OP_SharedTaskAcceptNew=0x0000 #
OP_SharedTaskMemberChange=0x0000 #
OP_TaskTimers=0x0000 # /tasktimers
OP_SharedTaskQuit=0x0000 # /taskquit
OP_SharedTaskSelectWindow=0x0000
OP_SharedTaskPlayerList=0x0000 # /taskplayerlist
# Title opcodes
OP_NewTitlesAvailable=0x0000
OP_RequestTitles=0x0000
OP_SendTitleList=0x0000
OP_SetTitle=0x0000
OP_SetTitleReply=0x0000
# mail opcodes
OP_Command=0x0000
OP_MailboxHeader=0x0000
OP_MailHeader=0x0000
OP_MailBody=0x0000
OP_NewMail=0x0000
OP_SentConfirm=0x0000
########### Below this point should not be needed ###########
# This section are all unknown in Titanium
OP_ForceFindPerson=0x0000
OP_LocInfo=0x0000
OP_ReloadUI=0x0000
OP_ItemName=0x0000
OP_ItemLinkText=0x0000
OP_MultiLineMsg=0x0000
OP_MendHPUpdate=0x0000
OP_TargetReject=0x0000
OP_SafePoint=0x0000
OP_ApproveZone=0x0000
OP_ZoneComplete=0x0000
OP_ClientError=0x0000
OP_DumpName=0x0000
OP_Heartbeat=0x0000
OP_CrashDump=0x0000
OP_LoginComplete=0x0000
# discovered opcodes not yet used:
OP_PickLockSuccess=0x0000
OP_PlayMP3=0x6451
OP_ReclaimCrystals=0x0000
OP_DynamicWall=0x0000
OP_OpenDiscordMerchant=0x0000
OP_DiscordMerchantInventory=0x0000
OP_GiveMoney=0x0000
OP_RequestKnowledgeBase=0x0000
OP_KnowledgeBase=0x0000
OP_SlashAdventure=0x0000 # /adventure
OP_BecomePVPPrompt=0x0000
OP_MoveLogRequest=0x0000 # gone I think
OP_MoveLogDisregard=0x0000 # gone I think
# named unknowns, to make looking for real unknown easier
OP_AnnoyingZoneUnknown=0x0000
OP_Some6ByteHPUpdate=0x0000 #seems to happen when you target group members
OP_QueryResponseThing=0x0000
# realityincarnate: these are just here to stop annoying several thousand byte packet dumps
#OP_LoginUnknown1=0x0000 # OP_SendSpellChecksum
#OP_LoginUnknown2=0x0000 # OP_SendSkillCapsChecksum
# Petition Opcodes
OP_PetitionSearch=0x0000 #search term for petition
OP_PetitionSearchResults=0x0000 #(list of?) matches from search
OP_PetitionSearchText=0x0000 #text results of search
OP_PetitionUpdate=0x0000
OP_PetitionCheckout=0x0000
OP_PetitionCheckIn=0x0000
OP_PetitionQue=0x0000
OP_PetitionUnCheckout=0x0000
OP_PetitionDelete=0x0000
OP_DeletePetition=0x0000
OP_PetitionResolve=0x0000
OP_PDeletePetition=0x0000
OP_PetitionBug=0x0000
OP_PetitionRefresh=0x0000
OP_PetitionCheckout2=0x0000
OP_PetitionViewPetition=0x0000
#aura related
OP_UpdateAura=0x0000
OP_RemoveTrap=0x0000
OP_Fingerprint=0x7a5b

View File

@ -1223,8 +1223,10 @@ bool Client::Process() {
} }
if(connect.Check()){ if(connect.Check()){
SendGuildList();// Send OPCode: OP_GuildsList if (!(m_ClientVersionBit & EQ::versions::maskLaurionAndLater)) {
SendApproveWorld(); SendGuildList();// Send OPCode: OP_GuildsList
SendApproveWorld();
}
connect.Disable(); connect.Disable();
} }

View File

@ -1205,7 +1205,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
LogDebug("Client::ChannelMessageReceived() Channel:[{}] message:[{}]", chan_num, message); LogDebug("Client::ChannelMessageReceived() Channel:[{}] message:[{}]", chan_num, message);
if (RuleB(Chat, AlwaysCaptureCommandText)) { if (RuleB(Chat, AlwaysCaptureCommandText)) {
if (message[0] == COMMAND_CHAR) { if (message[0] == COMMAND_CHAR || message[0] == COMMAND_CHAR_NON_HASH) {
if (command_dispatch(this, message, false) == -2) { if (command_dispatch(this, message, false) == -2) {
if (parse->PlayerHasQuestSub(EVENT_COMMAND)) { if (parse->PlayerHasQuestSub(EVENT_COMMAND)) {
int i = parse->EventPlayer(EVENT_COMMAND, this, message, 0); int i = parse->EventPlayer(EVENT_COMMAND, this, message, 0);
@ -1538,7 +1538,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
} }
} }
if (message[0] == COMMAND_CHAR) { if (message[0] == COMMAND_CHAR || message[0] == COMMAND_CHAR_NON_HASH) {
if (command_dispatch(this, message, false) == -2) { if (command_dispatch(this, message, false) == -2) {
if (parse->PlayerHasQuestSub(EVENT_COMMAND)) { if (parse->PlayerHasQuestSub(EVENT_COMMAND)) {
int i = parse->EventPlayer(EVENT_COMMAND, this, message, 0); int i = parse->EventPlayer(EVENT_COMMAND, this, message, 0);
@ -8083,7 +8083,7 @@ void Client::GarbleMessage(char *message, uint8 variance)
int delimiter_count = 0; int delimiter_count = 0;
// Don't garble # commands // Don't garble # commands
if (message[0] == COMMAND_CHAR || message[0] == BOT_COMMAND_CHAR) { if (message[0] == COMMAND_CHAR || message[0] == COMMAND_CHAR_NON_HASH || message[0] == BOT_COMMAND_CHAR) {
return; return;
} }
@ -9158,6 +9158,44 @@ void Client::SendHPUpdateMarquee(){
SendMarqueeMessage(Chat::Yellow, 510, 0, 3000, 3000, health_update_notification); SendMarqueeMessage(Chat::Yellow, 510, 0, 3000, 3000, health_update_notification);
} }
void Client::SendMembership() {
if (m_ClientVersion >= EQ::versions::ClientVersion::Laurion) {
auto outapp = new EQApplicationPacket(OP_SendMembership, sizeof(Membership_Struct));
Membership_Struct* mc = (Membership_Struct*)outapp->pBuffer;
mc->membership = 2; //Hardcode to gold for now. We don't use anything else.
mc->races = 0x1ffff; // Available Races (4110 for silver)
mc->classes = 0x1ffff; // Available Classes (4614 for silver) - Was 0x101ffff
mc->entrysize = 21; // Number of membership setting entries below
mc->entries[0] = 0xffffffff; // Max AA Restriction
mc->entries[1] = 0xffffffff; // Max Level Restriction
mc->entries[2] = 0xffffffff; // Max Char Slots per Account (not used by client?)
mc->entries[3] = 0xffffffff; // 1 for Silver
mc->entries[4] = 0xffffffff; // Main Inventory Size (0xffffffff on Live for Gold, but limiting to 8 until 10 is supported)
mc->entries[5] = 0xffffffff; // Max Platinum per level
mc->entries[6] = 1; // 0 for Silver
mc->entries[7] = 1; // 0 for Silver
mc->entries[8] = 1; // 1 for Silver
mc->entries[9] = 0xffffffff; // Unknown - Maybe Loyalty Points every 12 hours? 60 per week for Silver
mc->entries[10] = 1; // 1 for Silver
mc->entries[11] = 0xffffffff; // Shared Bank Slots
mc->entries[12] = 0xffffffff; // Unknown - Maybe Max Active Tasks?
mc->entries[13] = 1; // 1 for Silver
mc->entries[14] = 1; // 0 for Silver
mc->entries[15] = 1; // 0 for Silver
mc->entries[16] = 1; // 1 for Silver
mc->entries[17] = 1; // 0 for Silver
mc->entries[18] = 1; // 0 for Silver
mc->entries[19] = 0xffffffff; // 0 for Silver
mc->entries[20] = 0xffffffff; // 0 for Silver
mc->exit_url_length = 0;
//mc->exit_url = 0; // Used on Live: "http://www.everquest.com/free-to-play/exit-silver"
QueuePacket(outapp);
safe_delete(outapp);
}
}
uint32 Client::GetMoney(uint8 type, uint8 subtype) { uint32 Client::GetMoney(uint8 type, uint8 subtype) {
uint32 value = 0; uint32 value = 0;

View File

@ -1856,6 +1856,7 @@ public:
void ResetHPUpdateTimer() { hpupdate_timer.Start(); } void ResetHPUpdateTimer() { hpupdate_timer.Start(); }
void SendHPUpdateMarquee(); void SendHPUpdateMarquee();
void SendMembership();
void CheckRegionTypeChanges(); void CheckRegionTypeChanges();

View File

@ -105,7 +105,6 @@ void MapOpcodes()
ConnectingOpcodes[OP_ZoneEntry] = &Client::Handle_Connect_OP_ZoneEntry; ConnectingOpcodes[OP_ZoneEntry] = &Client::Handle_Connect_OP_ZoneEntry;
// connected opcode handler assignments: // connected opcode handler assignments:
ConnectedOpcodes[OP_0x0193] = &Client::Handle_0x0193;
ConnectedOpcodes[OP_AAAction] = &Client::Handle_OP_AAAction; ConnectedOpcodes[OP_AAAction] = &Client::Handle_OP_AAAction;
ConnectedOpcodes[OP_AcceptNewTask] = &Client::Handle_OP_AcceptNewTask; ConnectedOpcodes[OP_AcceptNewTask] = &Client::Handle_OP_AcceptNewTask;
ConnectedOpcodes[OP_AdventureInfoRequest] = &Client::Handle_OP_AdventureInfoRequest; ConnectedOpcodes[OP_AdventureInfoRequest] = &Client::Handle_OP_AdventureInfoRequest;
@ -1704,10 +1703,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
if ((m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate)) && (m_pp.RestTimer > RuleI(Character, RestRegenRaidTimeToActivate))) if ((m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate)) && (m_pp.RestTimer > RuleI(Character, RestRegenRaidTimeToActivate)))
m_pp.RestTimer = 0; m_pp.RestTimer = 0;
/* This checksum should disappear once dynamic structs are in... each struct strategy will do it */ // looks to be in place now SendMembership();
//CRC32::SetEQChecksum((unsigned char*)&m_pp, sizeof(PlayerProfile_Struct) - sizeof(m_pp.m_player_profile_version) - 4);
// m_pp.checksum = 0; // All server out-bound player profile packets are now translated - no need to waste cycles calculating this...
outapp = new EQApplicationPacket(OP_PlayerProfile, sizeof(PlayerProfile_Struct)); outapp = new EQApplicationPacket(OP_PlayerProfile, sizeof(PlayerProfile_Struct));
/* The entityid field in the Player Profile is used by the Client in relation to Group Leadership AA */ /* The entityid field in the Player Profile is used by the Client in relation to Group Leadership AA */
@ -1881,16 +1878,6 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
return; return;
} }
// connected opcode handlers
void Client::Handle_0x0193(const EQApplicationPacket *app)
{
// Not sure what this opcode does. It started being sent when OP_ClientUpdate was
// changed to pump OP_ClientUpdate back out instead of OP_MobUpdate
// 2 bytes: 00 00
return;
}
void Client::Handle_OP_AAAction(const EQApplicationPacket *app) void Client::Handle_OP_AAAction(const EQApplicationPacket *app)
{ {
LogAA("Received OP_AAAction"); LogAA("Received OP_AAAction");
@ -4276,21 +4263,30 @@ void Client::Handle_OP_Camp(const EQApplicationPacket *app)
if (IsLFP()) if (IsLFP())
worldserver.StopLFP(CharacterID()); worldserver.StopLFP(CharacterID());
if (GetGM()) if (ClientVersion() >= EQ::versions::ClientVersion::SteamLatest) {
{ if (!GetGM()) {
if (RuleB(Character, EnableHackedFastCampForGM)) camp_timer.Start(29000, true);
{
camp_timer.Start(100, true);
}
else {
OnDisconnect(true);
} }
return; auto outapp = new EQApplicationPacket(OP_Camp, 1);
FastQueuePacket(&outapp);
} }
else {
if (GetGM())
{
if (RuleB(Character, EnableHackedFastCampForGM))
{
camp_timer.Start(100, true);
}
else {
OnDisconnect(true);
}
return;
}
camp_timer.Start(29000, true); camp_timer.Start(29000, true);
}
if (RuleB(Bots, Enabled)) { if (RuleB(Bots, Enabled)) {
bot_camp_timer.Start((RuleI(Bots, CampTimer) * 1000), true); bot_camp_timer.Start((RuleI(Bots, CampTimer) * 1000), true);
@ -14568,7 +14564,10 @@ void Client::Handle_OP_ShopRequest(const EQApplicationPacket *app)
mco->rate = 1 / buy_cost_mod; mco->rate = 1 / buy_cost_mod;
} }
outapp->priority = 6; if (m_ClientVersion >= EQ::versions::ClientVersion::SteamLatest) {
mco->player_id = GetID();
}
QueuePacket(outapp); QueuePacket(outapp);
safe_delete(outapp); safe_delete(outapp);

View File

@ -38,8 +38,6 @@
void Handle_Connect_OP_ZoneComplete(const EQApplicationPacket *app); void Handle_Connect_OP_ZoneComplete(const EQApplicationPacket *app);
void Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app); void Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app);
/* Connected opcode handlers*/ /* Connected opcode handlers*/
void Handle_0x0193(const EQApplicationPacket *app);
void Handle_0x01e7(const EQApplicationPacket *app);
void Handle_OP_AAAction(const EQApplicationPacket *app); void Handle_OP_AAAction(const EQApplicationPacket *app);
void Handle_OP_AcceptNewTask(const EQApplicationPacket *app); void Handle_OP_AcceptNewTask(const EQApplicationPacket *app);
void Handle_OP_AdventureInfoRequest(const EQApplicationPacket *app); void Handle_OP_AdventureInfoRequest(const EQApplicationPacket *app);

View File

@ -25,6 +25,7 @@ class Client;
class Seperator; class Seperator;
#define COMMAND_CHAR '#' #define COMMAND_CHAR '#'
#define COMMAND_CHAR_NON_HASH '$'
typedef void (*CmdFuncPtr)(Client *, const Seperator *); typedef void (*CmdFuncPtr)(Client *, const Seperator *);

View File

@ -693,8 +693,6 @@ luabind::scope lua_register_packet_opcodes() {
luabind::value("ShopEndConfirm", static_cast<int>(OP_ShopEndConfirm)), luabind::value("ShopEndConfirm", static_cast<int>(OP_ShopEndConfirm)),
luabind::value("AdventureMerchantRequest", static_cast<int>(OP_AdventureMerchantRequest)), luabind::value("AdventureMerchantRequest", static_cast<int>(OP_AdventureMerchantRequest)),
luabind::value("Sound", static_cast<int>(OP_Sound)), luabind::value("Sound", static_cast<int>(OP_Sound)),
luabind::value("0x0193", static_cast<int>(OP_0x0193)),
luabind::value("0x0347", static_cast<int>(OP_0x0347)),
luabind::value("WorldComplete", static_cast<int>(OP_WorldComplete)), luabind::value("WorldComplete", static_cast<int>(OP_WorldComplete)),
luabind::value("MobRename", static_cast<int>(OP_MobRename)), luabind::value("MobRename", static_cast<int>(OP_MobRename)),
luabind::value("TaskDescription", static_cast<int>(OP_TaskDescription)), luabind::value("TaskDescription", static_cast<int>(OP_TaskDescription)),

View File

@ -1284,6 +1284,14 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
strcpy(ns->spawn.name, name); strcpy(ns->spawn.name, name);
if(IsClient()) { if(IsClient()) {
strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName)); strn0cpy(ns->spawn.lastName, lastname, sizeof(ns->spawn.lastName));
ns->spawn.CharacterGuid.Id = CastToClient()->CharacterID();
ns->spawn.CharacterGuid.WorldId = RuleI(World, Id);
ns->spawn.CharacterGuid.Reserved = 0;
}
else {
ns->spawn.CharacterGuid.Id = 0;
ns->spawn.CharacterGuid.WorldId = 0;
ns->spawn.CharacterGuid.Reserved = 0;
} }
ns->spawn.heading = FloatToEQ12(m_Position.w); ns->spawn.heading = FloatToEQ12(m_Position.w);