mirror of
https://github.com/EQEmu/Server.git
synced 2026-01-12 02:53:51 +00:00
Merge branch 'EQEmu:master' into master
This commit is contained in:
commit
ea3cc47ff6
49
CHANGELOG.md
49
CHANGELOG.md
@ -1,3 +1,52 @@
|
||||
## [23.9.1] 8/2/2025
|
||||
|
||||
### Hotfix
|
||||
|
||||
* Fix Quest Ownership Edge Case ([#4977](https://github.com/EQEmu/Server/pull/4977)) @Kinglykrab 2025-08-02
|
||||
|
||||
## [23.9.0] 8/2/2025
|
||||
|
||||
### Bots
|
||||
|
||||
* Fix FinishBuffing rule ([#4961](https://github.com/EQEmu/Server/pull/4961)) @nytmyr 2025-07-01
|
||||
* Fix ^cast resurrects ([#4958](https://github.com/EQEmu/Server/pull/4958)) @nytmyr 2025-06-29
|
||||
|
||||
### Build
|
||||
|
||||
* Fix Linking with GCC ([#4969](https://github.com/EQEmu/Server/pull/4969)) @solar984 2025-08-03
|
||||
* More Build Speed Improvements ([#4959](https://github.com/EQEmu/Server/pull/4959)) @Akkadius 2025-06-30
|
||||
|
||||
### Commands
|
||||
|
||||
* Add #show keyring Subcommand ([#4973](https://github.com/EQEmu/Server/pull/4973)) @Kinglykrab 2025-08-03
|
||||
|
||||
### Database
|
||||
|
||||
* Add Indexes to NPC's Spawns Loot ([#4972](https://github.com/EQEmu/Server/pull/4972)) @Akkadius 2025-07-30
|
||||
|
||||
### Feature
|
||||
|
||||
* Zone Scripting ([#4908](https://github.com/EQEmu/Server/pull/4908)) @Kinglykrab 2025-07-10
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add a missing Froglok starting area for Titanium Startzone. ([#4962](https://github.com/EQEmu/Server/pull/4962)) @regneq 2025-07-04
|
||||
* Fix Hero's Forge Ingame and Character Select ([#4966](https://github.com/EQEmu/Server/pull/4966)) @Kinglykrab 2025-07-30
|
||||
* Show player count on the server list status. ([#4971](https://github.com/EQEmu/Server/pull/4971)) @regneq 2025-07-30
|
||||
|
||||
### Loginserver
|
||||
|
||||
* Fix Legacy World When Using Local DB ([#4970](https://github.com/EQEmu/Server/pull/4970)) @solar984 2025-08-03
|
||||
|
||||
### Performance
|
||||
|
||||
* Clear Wearchange Deduplication Cache ([#4960](https://github.com/EQEmu/Server/pull/4960)) @Akkadius 2025-06-30
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GetMemberRole() to Perl/Lua ([#4963](https://github.com/EQEmu/Server/pull/4963)) @Barathos 2025-07-10
|
||||
* Add GetTimers() and GetPausedTimers() to Perl/Lua ([#4965](https://github.com/EQEmu/Server/pull/4965)) @Kinglykrab 2025-08-03
|
||||
|
||||
## [23.8.1] 6/28/2025
|
||||
|
||||
### Crash Fix
|
||||
|
||||
@ -104,9 +104,9 @@ SET(common_sources
|
||||
net/console_server.cpp
|
||||
net/console_server_connection.cpp
|
||||
net/crc32.cpp
|
||||
net/daybreak_connection.cpp
|
||||
net/eqstream.cpp
|
||||
net/packet.cpp
|
||||
net/reliable_stream_connection.cpp
|
||||
net/servertalk_client_connection.cpp
|
||||
net/servertalk_legacy_client_connection.cpp
|
||||
net/servertalk_server.cpp
|
||||
@ -671,13 +671,13 @@ SET(common_headers
|
||||
net/console_server.h
|
||||
net/console_server_connection.h
|
||||
net/crc32.h
|
||||
net/daybreak_connection.h
|
||||
net/daybreak_pooling.h
|
||||
net/daybreak_structs.h
|
||||
net/dns.h
|
||||
net/endian.h
|
||||
net/eqstream.h
|
||||
net/packet.h
|
||||
net/reliable_stream_connection.h
|
||||
net/reliable_stream_pooling.h
|
||||
net/reliable_stream_structs.h
|
||||
net/servertalk_client_connection.h
|
||||
net/servertalk_legacy_client_connection.h
|
||||
net/servertalk_common.h
|
||||
@ -743,10 +743,6 @@ SOURCE_GROUP(Net FILES
|
||||
net/console_server_connection.h
|
||||
net/crc32.cpp
|
||||
net/crc32.h
|
||||
net/daybreak_connection.cpp
|
||||
net/daybreak_connection.h
|
||||
net/daybreak_pooling.h
|
||||
net/daybreak_structs.h
|
||||
net/dns.h
|
||||
net/endian.h
|
||||
net/eqmq.cpp
|
||||
@ -755,6 +751,10 @@ SOURCE_GROUP(Net FILES
|
||||
net/eqstream.h
|
||||
net/packet.cpp
|
||||
net/packet.h
|
||||
net/reliable_stream_connection.cpp
|
||||
net/reliable_stream_connection.h
|
||||
net/reliable_stream_pooling.h
|
||||
net/reliable_stream_structs.h
|
||||
net/servertalk_client_connection.cpp
|
||||
net/servertalk_client_connection.h
|
||||
net/servertalk_legacy_client_connection.cpp
|
||||
|
||||
@ -7136,6 +7136,42 @@ ADD COLUMN `entity_variables` TEXT DEFAULT NULL AFTER `rezzable`;
|
||||
)",
|
||||
.content_schema_update = false
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9326,
|
||||
.description = "2025_07_27_add_indexes_npc_spawns_loot.sql",
|
||||
.check = "SHOW INDEX FROM npc_types",
|
||||
.condition = "missing",
|
||||
.match = "idx_npc_types_loottable_id",
|
||||
.sql = R"(
|
||||
ALTER TABLE npc_types
|
||||
ADD INDEX idx_npc_types_loottable_id (loottable_id);
|
||||
|
||||
ALTER TABLE spawnentry
|
||||
ADD INDEX idx_spawnentry_spawngroup_id (spawngroupID),
|
||||
ADD INDEX idx_spawnentry_npc_id (npcID);
|
||||
|
||||
ALTER TABLE lootdrop_entries
|
||||
ADD INDEX idx_lootdrop_entries_lootdrop_id (lootdrop_id),
|
||||
ADD INDEX idx_lootdrop_entries_item_id (item_id);
|
||||
|
||||
ALTER TABLE loottable_entries
|
||||
ADD INDEX idx_loottable_entries_lootdrop_id (lootdrop_id),
|
||||
ADD INDEX idx_loottable_entries_loottable_id (loottable_id);
|
||||
)",
|
||||
.content_schema_update = true
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9327,
|
||||
.description = "2025_08_13_character_stats_record_heal_amount.sql",
|
||||
.check = "SHOW COLUMNS FROM `character_stats_record` LIKE 'heal_amount'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
ALTER TABLE `character_stats_record`
|
||||
ADD COLUMN `heal_amount` int(11) NULL DEFAULT 0 AFTER `spell_damage`;
|
||||
)"
|
||||
},
|
||||
|
||||
// -- template; copy/paste this when you need to create a new entry
|
||||
// ManifestEntry{
|
||||
// .version = 9228,
|
||||
|
||||
@ -451,3 +451,23 @@ bool LDoNTheme::IsValid(uint32 theme_id)
|
||||
{
|
||||
return ldon_theme_names.find(theme_id) != ldon_theme_names.end();
|
||||
}
|
||||
|
||||
std::string PetCommand::GetName(uint8 pet_command)
|
||||
{
|
||||
return IsValid(pet_command) ? pet_commands[pet_command] : "UNKNOWN PET COMMAND";
|
||||
}
|
||||
|
||||
bool PetCommand::IsValid(uint8 pet_command)
|
||||
{
|
||||
return pet_commands.find(pet_command) != pet_commands.end();
|
||||
}
|
||||
|
||||
std::string PetType::GetName(uint8 pet_type)
|
||||
{
|
||||
return IsValid(pet_type) ? pet_types[pet_type] : "UNKNOWN PET TYPE";
|
||||
}
|
||||
|
||||
bool PetType::IsValid(uint8 pet_type)
|
||||
{
|
||||
return pet_types.find(pet_type) != pet_types.end();
|
||||
}
|
||||
|
||||
@ -792,4 +792,131 @@ namespace BookType {
|
||||
constexpr uint8 ItemInfo = 2;
|
||||
}
|
||||
|
||||
namespace PetButton {
|
||||
constexpr uint8 Sit = 0;
|
||||
constexpr uint8 Stop = 1;
|
||||
constexpr uint8 Regroup = 2;
|
||||
constexpr uint8 Follow = 3;
|
||||
constexpr uint8 Guard = 4;
|
||||
constexpr uint8 Taunt = 5;
|
||||
constexpr uint8 Hold = 6;
|
||||
constexpr uint8 GreaterHold = 7;
|
||||
constexpr uint8 Focus = 8;
|
||||
constexpr uint8 SpellHold = 9;
|
||||
}
|
||||
|
||||
namespace PetButtonState {
|
||||
constexpr uint8 Off = 0;
|
||||
constexpr uint8 On = 1;
|
||||
}
|
||||
|
||||
namespace PetCommand {
|
||||
constexpr uint8 HealthReport = 0; // /pet health or Pet Window
|
||||
constexpr uint8 Leader = 1; // /pet leader or Pet Window
|
||||
constexpr uint8 Attack = 2; // /pet attack or Pet Window
|
||||
constexpr uint8 QAttack = 3; // /pet qattack or Pet Window
|
||||
constexpr uint8 FollowMe = 4; // /pet follow or Pet Window
|
||||
constexpr uint8 GuardHere = 5; // /pet guard or Pet Window
|
||||
constexpr uint8 Sit = 6; // /pet sit or Pet Window
|
||||
constexpr uint8 SitDown = 7; // /pet sit on
|
||||
constexpr uint8 StandUp = 8; // /pet sit off
|
||||
constexpr uint8 Stop = 9; // /pet stop or Pet Window - Not implemented
|
||||
constexpr uint8 StopOn = 10; // /pet stop on - Not implemented
|
||||
constexpr uint8 StopOff = 11; // /pet stop off - Not implemented
|
||||
constexpr uint8 Taunt = 12; // /pet taunt or Pet Window
|
||||
constexpr uint8 TauntOn = 13; // /pet taunt on
|
||||
constexpr uint8 TauntOff = 14; // /pet taunt off
|
||||
constexpr uint8 Hold = 15; // /pet hold or Pet Window, won't add to hate list unless attacking
|
||||
constexpr uint8 HoldOn = 16; // /pet hold on
|
||||
constexpr uint8 HoldOff = 17; // /pet hold off
|
||||
constexpr uint8 GreaterHold = 18; // /pet ghold, will never add to hate list unless told to
|
||||
constexpr uint8 GreaterHoldOn = 19; // /pet ghold on
|
||||
constexpr uint8 GreaterHoldOff = 20; // /pet ghold off
|
||||
constexpr uint8 SpellHold = 21; // /pet no cast or /pet spellhold or Pet Window
|
||||
constexpr uint8 SpellHoldOn = 22; // /pet spellhold on
|
||||
constexpr uint8 SpellHoldOff = 23; // /pet spellhold off
|
||||
constexpr uint8 Focus = 24; // /pet focus or Pet Window
|
||||
constexpr uint8 FocusOn = 25; // /pet focus on
|
||||
constexpr uint8 FocusOff = 26; // /pet focus off
|
||||
constexpr uint8 Feign = 27; // /pet feign
|
||||
constexpr uint8 BackOff = 28; // /pet back off
|
||||
constexpr uint8 GetLost = 29; // /pet get lost
|
||||
constexpr uint8 GuardMe = 30; // Same as /pet follow, but different message in older clients
|
||||
constexpr uint8 Regroup = 31; // /pet regroup, acts like classic hold
|
||||
constexpr uint8 RegroupOn = 32; // /pet regroup on
|
||||
constexpr uint8 RegroupOff = 33; // /pet regroup off
|
||||
constexpr uint8 Max = 34;
|
||||
|
||||
static std::map<uint8, std::string> pet_commands = {
|
||||
{ PetCommand::HealthReport, "Health Report" },
|
||||
{ PetCommand::Leader, "Leader" },
|
||||
{ PetCommand::Attack, "Attack" },
|
||||
{ PetCommand::QAttack, "QAttack" },
|
||||
{ PetCommand::FollowMe, "Follow Me" },
|
||||
{ PetCommand::GuardHere, "Guard Here" },
|
||||
{ PetCommand::Sit, "Sit" },
|
||||
{ PetCommand::SitDown, "Sit Down" },
|
||||
{ PetCommand::StandUp, "Stand Up" },
|
||||
{ PetCommand::Stop, "Stop" },
|
||||
{ PetCommand::StopOn, "Stop On" },
|
||||
{ PetCommand::StopOff, "Stop Off" },
|
||||
{ PetCommand::Taunt, "Taunt" },
|
||||
{ PetCommand::TauntOn, "Taunt On" },
|
||||
{ PetCommand::TauntOff, "Taunt Off" },
|
||||
{ PetCommand::Hold, "Hold" },
|
||||
{ PetCommand::HoldOn, "Hold On" },
|
||||
{ PetCommand::HoldOff, "Hold Off" },
|
||||
{ PetCommand::GreaterHold, "Greater Hold" },
|
||||
{ PetCommand::GreaterHoldOn, "Greater Hold On" },
|
||||
{ PetCommand::GreaterHoldOff, "Greater Hold Off" },
|
||||
{ PetCommand::SpellHold, "Spell Hold" },
|
||||
{ PetCommand::SpellHoldOn, "Spell Hold On" },
|
||||
{ PetCommand::SpellHoldOff, "Spell Hold Off" },
|
||||
{ PetCommand::Focus, "Focus" },
|
||||
{ PetCommand::FocusOn, "Focus On" },
|
||||
{ PetCommand::FocusOff, "Focus Off" },
|
||||
{ PetCommand::Feign, "Feign" },
|
||||
{ PetCommand::BackOff, "Back Off" },
|
||||
{ PetCommand::GetLost, "Get Lost" },
|
||||
{ PetCommand::GuardMe, "Guard Me" },
|
||||
{ PetCommand::Regroup, "Regroup" },
|
||||
{ PetCommand::RegroupOn, "Regroup On" },
|
||||
{ PetCommand::RegroupOff, "Regroup Off" },
|
||||
{ PetCommand::Max, "Max" }
|
||||
};
|
||||
|
||||
std::string GetName(uint8 pet_command);
|
||||
bool IsValid(uint8 pet_command);
|
||||
}
|
||||
|
||||
namespace PetOrder {
|
||||
constexpr uint8 Follow = 0;
|
||||
constexpr uint8 Sit = 1;
|
||||
constexpr uint8 Guard = 2;
|
||||
constexpr uint8 Feign = 3;
|
||||
}
|
||||
|
||||
namespace PetType {
|
||||
constexpr uint8 Familiar = 0;
|
||||
constexpr uint8 Animation = 1;
|
||||
constexpr uint8 Normal = 2;
|
||||
constexpr uint8 Charmed = 3;
|
||||
constexpr uint8 Follow = 4;
|
||||
constexpr uint8 TargetLock = 5;
|
||||
constexpr uint8 None = 255;
|
||||
|
||||
static std::map<uint8, std::string> pet_types = {
|
||||
{ PetType::Familiar, "Familiar" },
|
||||
{ PetType::Animation, "Animation" },
|
||||
{ PetType::Normal, "Normal" },
|
||||
{ PetType::Charmed, "Charmed" },
|
||||
{ PetType::Follow, "Follow" },
|
||||
{ PetType::TargetLock, "Target Lock" },
|
||||
{ PetType::None, "None" }
|
||||
};
|
||||
|
||||
std::string GetName(uint8 pet_type);
|
||||
bool IsValid(uint8 pet_type);
|
||||
}
|
||||
|
||||
#endif /*COMMON_EMU_CONSTANTS_H*/
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include <string>
|
||||
#include "emu_versions.h"
|
||||
#include "eq_packet.h"
|
||||
#include "net/daybreak_connection.h"
|
||||
#include "net/reliable_stream_connection.h"
|
||||
|
||||
typedef enum {
|
||||
ESTABLISHED,
|
||||
@ -33,18 +33,18 @@ struct EQStreamManagerInterfaceOptions
|
||||
//Login I had trouble getting to recognize compression at all
|
||||
//but that might be because it was still a bit buggy when i was testing that.
|
||||
if (compressed) {
|
||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeCompression;
|
||||
reliable_stream_options.encode_passes[0] = EQ::Net::EncodeCompression;
|
||||
}
|
||||
else if (encoded) {
|
||||
daybreak_options.encode_passes[0] = EQ::Net::EncodeXOR;
|
||||
reliable_stream_options.encode_passes[0] = EQ::Net::EncodeXOR;
|
||||
}
|
||||
|
||||
daybreak_options.port = port;
|
||||
reliable_stream_options.port = port;
|
||||
}
|
||||
|
||||
int opcode_size;
|
||||
bool track_opcode_stats;
|
||||
EQ::Net::DaybreakConnectionManagerOptions daybreak_options;
|
||||
EQ::Net::ReliableStreamConnectionManagerOptions reliable_stream_options;
|
||||
};
|
||||
|
||||
class EQStreamManagerInterface
|
||||
@ -80,7 +80,7 @@ public:
|
||||
|
||||
struct Stats
|
||||
{
|
||||
EQ::Net::DaybreakConnectionStats DaybreakStats;
|
||||
EQ::Net::ReliableStreamConnectionStats ReliableStreamStats;
|
||||
int RecvCount[_maxEmuOpcode];
|
||||
int SentCount[_maxEmuOpcode];
|
||||
};
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
#include "eqstream.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
|
||||
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_daybreak(options.daybreak_options)
|
||||
EQ::Net::EQStreamManager::EQStreamManager(const EQStreamManagerInterfaceOptions &options) : EQStreamManagerInterface(options), m_reliable_stream(options.reliable_stream_options)
|
||||
{
|
||||
m_daybreak.OnNewConnection(std::bind(&EQStreamManager::DaybreakNewConnection, this, std::placeholders::_1));
|
||||
m_daybreak.OnConnectionStateChange(std::bind(&EQStreamManager::DaybreakConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
m_daybreak.OnPacketRecv(std::bind(&EQStreamManager::DaybreakPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||
m_reliable_stream.OnNewConnection(std::bind(&EQStreamManager::ReliableStreamNewConnection, this, std::placeholders::_1));
|
||||
m_reliable_stream.OnConnectionStateChange(std::bind(&EQStreamManager::ReliableStreamConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
m_reliable_stream.OnPacketRecv(std::bind(&EQStreamManager::ReliableStreamPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
EQ::Net::EQStreamManager::~EQStreamManager()
|
||||
@ -15,11 +15,11 @@ EQ::Net::EQStreamManager::~EQStreamManager()
|
||||
void EQ::Net::EQStreamManager::SetOptions(const EQStreamManagerInterfaceOptions &options)
|
||||
{
|
||||
m_options = options;
|
||||
auto &opts = m_daybreak.GetOptions();
|
||||
opts = options.daybreak_options;
|
||||
auto &opts = m_reliable_stream.GetOptions();
|
||||
opts = options.reliable_stream_options;
|
||||
}
|
||||
|
||||
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
|
||||
void EQ::Net::EQStreamManager::ReliableStreamNewConnection(std::shared_ptr<ReliableStreamConnection> connection)
|
||||
{
|
||||
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
|
||||
m_streams.emplace(std::make_pair(connection, stream));
|
||||
@ -28,7 +28,7 @@ void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakCon
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
|
||||
void EQ::Net::EQStreamManager::ReliableStreamConnectionStateChange(std::shared_ptr<ReliableStreamConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
|
||||
{
|
||||
auto iter = m_streams.find(connection);
|
||||
if (iter != m_streams.end()) {
|
||||
@ -42,7 +42,7 @@ void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<Day
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p)
|
||||
void EQ::Net::EQStreamManager::ReliableStreamPacketRecv(std::shared_ptr<ReliableStreamConnection> connection, const Packet &p)
|
||||
{
|
||||
auto iter = m_streams.find(connection);
|
||||
if (iter != m_streams.end()) {
|
||||
@ -53,7 +53,7 @@ void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnec
|
||||
}
|
||||
}
|
||||
|
||||
EQ::Net::EQStream::EQStream(EQStreamManagerInterface *owner, std::shared_ptr<DaybreakConnection> connection)
|
||||
EQ::Net::EQStream::EQStream(EQStreamManagerInterface *owner, std::shared_ptr<ReliableStreamConnection> connection)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_connection = connection;
|
||||
@ -235,7 +235,7 @@ EQStreamState EQ::Net::EQStream::GetState() {
|
||||
EQ::Net::EQStream::Stats EQ::Net::EQStream::GetStats() const
|
||||
{
|
||||
Stats ret;
|
||||
ret.DaybreakStats = m_connection->GetStats();
|
||||
ret.ReliableStreamStats = m_connection->GetStats();
|
||||
|
||||
for (int i = 0; i < _maxEmuOpcode; ++i) {
|
||||
ret.RecvCount[i] = 0;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
#include "../eq_packet.h"
|
||||
#include "../eq_stream_intf.h"
|
||||
#include "../opcodemgr.h"
|
||||
#include "daybreak_connection.h"
|
||||
#include "reliable_stream_connection.h"
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <unordered_map>
|
||||
@ -23,21 +23,21 @@ namespace EQ
|
||||
void OnNewConnection(std::function<void(std::shared_ptr<EQStream>)> func) { m_on_new_connection = func; }
|
||||
void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
||||
private:
|
||||
DaybreakConnectionManager m_daybreak;
|
||||
ReliableStreamConnectionManager m_reliable_stream;
|
||||
std::function<void(std::shared_ptr<EQStream>)> m_on_new_connection;
|
||||
std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||
std::map<std::shared_ptr<DaybreakConnection>, std::shared_ptr<EQStream>> m_streams;
|
||||
std::map<std::shared_ptr<ReliableStreamConnection>, std::shared_ptr<EQStream>> m_streams;
|
||||
|
||||
void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
|
||||
void DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
|
||||
void DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p);
|
||||
void ReliableStreamNewConnection(std::shared_ptr<ReliableStreamConnection> connection);
|
||||
void ReliableStreamConnectionStateChange(std::shared_ptr<ReliableStreamConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
|
||||
void ReliableStreamPacketRecv(std::shared_ptr<ReliableStreamConnection> connection, const Packet &p);
|
||||
friend class EQStream;
|
||||
};
|
||||
|
||||
class EQStream : public EQStreamInterface
|
||||
{
|
||||
public:
|
||||
EQStream(EQStreamManagerInterface *parent, std::shared_ptr<DaybreakConnection> connection);
|
||||
EQStream(EQStreamManagerInterface *parent, std::shared_ptr<ReliableStreamConnection> connection);
|
||||
~EQStream();
|
||||
|
||||
virtual void QueuePacket(const EQApplicationPacket *p, bool ack_req = true);
|
||||
@ -67,7 +67,7 @@ namespace EQ
|
||||
virtual EQStreamManagerInterface* GetManager() const;
|
||||
private:
|
||||
EQStreamManagerInterface *m_owner;
|
||||
std::shared_ptr<DaybreakConnection> m_connection;
|
||||
std::shared_ptr<ReliableStreamConnection> m_connection;
|
||||
OpcodeManager **m_opcode_manager;
|
||||
std::deque<std::unique_ptr<EQ::Net::Packet>> m_packet_queue;
|
||||
std::unordered_map<int, int> m_packet_recv_count;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#include "daybreak_connection.h"
|
||||
#include "reliable_stream_connection.h"
|
||||
#include "../event/event_loop.h"
|
||||
#include "../data_verification.h"
|
||||
#include "crc32.h"
|
||||
@ -12,7 +12,7 @@ constexpr size_t MAX_CLIENT_RECV_BYTES_PER_WINDOW = 140 * 1024;
|
||||
// buffer pools
|
||||
SendBufferPool send_buffer_pool;
|
||||
|
||||
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager()
|
||||
EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager()
|
||||
{
|
||||
m_attached = nullptr;
|
||||
memset(&m_timer, 0, sizeof(uv_timer_t));
|
||||
@ -21,7 +21,7 @@ EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager()
|
||||
Attach(EQ::EventLoop::Get().Handle());
|
||||
}
|
||||
|
||||
EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts)
|
||||
EQ::Net::ReliableStreamConnectionManager::ReliableStreamConnectionManager(const ReliableStreamConnectionManagerOptions &opts)
|
||||
{
|
||||
m_attached = nullptr;
|
||||
m_options = opts;
|
||||
@ -31,12 +31,12 @@ EQ::Net::DaybreakConnectionManager::DaybreakConnectionManager(const DaybreakConn
|
||||
Attach(EQ::EventLoop::Get().Handle());
|
||||
}
|
||||
|
||||
EQ::Net::DaybreakConnectionManager::~DaybreakConnectionManager()
|
||||
EQ::Net::ReliableStreamConnectionManager::~ReliableStreamConnectionManager()
|
||||
{
|
||||
Detach();
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
||||
void EQ::Net::ReliableStreamConnectionManager::Attach(uv_loop_t *loop)
|
||||
{
|
||||
if (!m_attached) {
|
||||
uv_timer_init(loop, &m_timer);
|
||||
@ -45,7 +45,7 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
||||
auto update_rate = (uint64_t)(1000.0 / m_options.tic_rate_hertz);
|
||||
|
||||
uv_timer_start(&m_timer, [](uv_timer_t *handle) {
|
||||
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
|
||||
ReliableStreamConnectionManager *c = (ReliableStreamConnectionManager*)handle->data;
|
||||
c->UpdateDataBudget();
|
||||
c->Process();
|
||||
c->ProcessResend();
|
||||
@ -71,7 +71,7 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
||||
buf->len = 65536;
|
||||
},
|
||||
[](uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) {
|
||||
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
|
||||
ReliableStreamConnectionManager *c = (ReliableStreamConnectionManager*)handle->data;
|
||||
if (nread < 0 || addr == nullptr) {
|
||||
return;
|
||||
}
|
||||
@ -90,7 +90,7 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::Detach()
|
||||
void EQ::Net::ReliableStreamConnectionManager::Detach()
|
||||
{
|
||||
if (m_attached) {
|
||||
uv_udp_recv_stop(&m_socket);
|
||||
@ -99,11 +99,11 @@ void EQ::Net::DaybreakConnectionManager::Detach()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int port)
|
||||
void EQ::Net::ReliableStreamConnectionManager::Connect(const std::string &addr, int port)
|
||||
{
|
||||
//todo dns resolution
|
||||
|
||||
auto connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, addr, port));
|
||||
auto connection = std::shared_ptr<ReliableStreamConnection>(new ReliableStreamConnection(this, addr, port));
|
||||
connection->m_self = connection;
|
||||
|
||||
if (m_on_new_connection) {
|
||||
@ -113,7 +113,7 @@ void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int po
|
||||
m_connections.emplace(std::make_pair(std::make_pair(addr, port), connection));
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::Process()
|
||||
void EQ::Net::ReliableStreamConnectionManager::Process()
|
||||
{
|
||||
auto now = Clock::now();
|
||||
auto iter = m_connections.begin();
|
||||
@ -177,7 +177,7 @@ void EQ::Net::DaybreakConnectionManager::Process()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::UpdateDataBudget()
|
||||
void EQ::Net::ReliableStreamConnectionManager::UpdateDataBudget()
|
||||
{
|
||||
auto outgoing_data_rate = m_options.outgoing_data_rate;
|
||||
if (outgoing_data_rate <= 0.0) {
|
||||
@ -196,7 +196,7 @@ void EQ::Net::DaybreakConnectionManager::UpdateDataBudget()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::ProcessResend()
|
||||
void EQ::Net::ReliableStreamConnectionManager::ProcessResend()
|
||||
{
|
||||
auto iter = m_connections.begin();
|
||||
while (iter != m_connections.end()) {
|
||||
@ -217,15 +217,15 @@ void EQ::Net::DaybreakConnectionManager::ProcessResend()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size)
|
||||
void EQ::Net::ReliableStreamConnectionManager::ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size)
|
||||
{
|
||||
if (m_options.simulated_in_packet_loss && m_options.simulated_in_packet_loss >= m_rand.Int(0, 100)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (size < DaybreakHeader::size()) {
|
||||
if (size < ReliableStreamHeader::size()) {
|
||||
if (m_on_error_message) {
|
||||
m_on_error_message(fmt::format("Packet of size {0} which is less than {1}", size, DaybreakHeader::size()));
|
||||
m_on_error_message(fmt::format("Packet of size {0} which is less than {1}", size, ReliableStreamHeader::size()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -239,9 +239,9 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
|
||||
else {
|
||||
if (data[0] == 0 && data[1] == OP_SessionRequest) {
|
||||
StaticPacket p((void*)data, size);
|
||||
auto request = p.GetSerialize<DaybreakConnect>(0);
|
||||
auto request = p.GetSerialize<ReliableStreamConnect>(0);
|
||||
|
||||
connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, request, endpoint, port));
|
||||
connection = std::shared_ptr<ReliableStreamConnection>(new ReliableStreamConnection(this, request, endpoint, port));
|
||||
connection->m_self = connection;
|
||||
|
||||
if (m_on_new_connection) {
|
||||
@ -262,7 +262,7 @@ void EQ::Net::DaybreakConnectionManager::ProcessPacket(const std::string &endpoi
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> EQ::Net::DaybreakConnectionManager::FindConnectionByEndpoint(std::string addr, int port)
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> EQ::Net::ReliableStreamConnectionManager::FindConnectionByEndpoint(std::string addr, int port)
|
||||
{
|
||||
auto p = std::make_pair(addr, port);
|
||||
auto iter = m_connections.find(p);
|
||||
@ -273,9 +273,9 @@ std::shared_ptr<EQ::Net::DaybreakConnection> EQ::Net::DaybreakConnectionManager:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnectionManager::SendDisconnect(const std::string &addr, int port)
|
||||
void EQ::Net::ReliableStreamConnectionManager::SendDisconnect(const std::string &addr, int port)
|
||||
{
|
||||
DaybreakDisconnect header;
|
||||
ReliableStreamDisconnect header;
|
||||
header.zero = 0;
|
||||
header.opcode = OP_OutOfSession;
|
||||
header.connect_code = 0;
|
||||
@ -300,7 +300,7 @@ void EQ::Net::DaybreakConnectionManager::SendDisconnect(const std::string &addr,
|
||||
}
|
||||
|
||||
//new connection made as server
|
||||
EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port)
|
||||
EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnectionManager *owner, const ReliableStreamConnect &connect, const std::string &endpoint, int port)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_last_send = Clock::now();
|
||||
@ -327,7 +327,7 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
||||
}
|
||||
|
||||
//new connection made as client
|
||||
EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port)
|
||||
EQ::Net::ReliableStreamConnection::ReliableStreamConnection(ReliableStreamConnectionManager *owner, const std::string &endpoint, int port)
|
||||
{
|
||||
m_owner = owner;
|
||||
m_last_send = Clock::now();
|
||||
@ -349,11 +349,11 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
||||
m_outgoing_budget = owner->m_options.outgoing_data_rate;
|
||||
}
|
||||
|
||||
EQ::Net::DaybreakConnection::~DaybreakConnection()
|
||||
EQ::Net::ReliableStreamConnection::~ReliableStreamConnection()
|
||||
{
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Close()
|
||||
void EQ::Net::ReliableStreamConnection::Close()
|
||||
{
|
||||
if (m_status != StatusDisconnected && m_status != StatusDisconnecting) {
|
||||
FlushBuffer();
|
||||
@ -367,17 +367,17 @@ void EQ::Net::DaybreakConnection::Close()
|
||||
ChangeStatus(StatusDisconnecting);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p)
|
||||
{
|
||||
QueuePacket(p, 0, true);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream)
|
||||
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p, int stream)
|
||||
{
|
||||
QueuePacket(p, stream, true);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream, bool reliable)
|
||||
void EQ::Net::ReliableStreamConnection::QueuePacket(Packet &p, int stream, bool reliable)
|
||||
{
|
||||
if (*(char*)p.Data() == 0) {
|
||||
DynamicPacket packet;
|
||||
@ -390,21 +390,21 @@ void EQ::Net::DaybreakConnection::QueuePacket(Packet &p, int stream, bool reliab
|
||||
InternalQueuePacket(p, stream, reliable);
|
||||
}
|
||||
|
||||
EQ::Net::DaybreakConnectionStats EQ::Net::DaybreakConnection::GetStats()
|
||||
EQ::Net::ReliableStreamConnectionStats EQ::Net::ReliableStreamConnection::GetStats()
|
||||
{
|
||||
EQ::Net::DaybreakConnectionStats ret = m_stats;
|
||||
EQ::Net::ReliableStreamConnectionStats ret = m_stats;
|
||||
ret.datarate_remaining = m_outgoing_budget;
|
||||
ret.avg_ping = m_rolling_ping;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ResetStats()
|
||||
void EQ::Net::ReliableStreamConnection::ResetStats()
|
||||
{
|
||||
m_stats.Reset();
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Process()
|
||||
void EQ::Net::ReliableStreamConnection::Process()
|
||||
{
|
||||
try {
|
||||
auto now = Clock::now();
|
||||
@ -422,7 +422,7 @@ void EQ::Net::DaybreakConnection::Process()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::ProcessPacket(Packet &p)
|
||||
{
|
||||
m_last_recv = Clock::now();
|
||||
m_stats.recv_packets++;
|
||||
@ -458,13 +458,13 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
||||
switch (m_encode_passes[i]) {
|
||||
case EncodeCompression:
|
||||
if(temp.GetInt8(0) == 0)
|
||||
Decompress(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
||||
Decompress(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
|
||||
else
|
||||
Decompress(temp, 1, temp.Length() - 1);
|
||||
break;
|
||||
case EncodeXOR:
|
||||
if (temp.GetInt8(0) == 0)
|
||||
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
||||
Decode(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
|
||||
else
|
||||
Decode(temp, 1, temp.Length() - 1);
|
||||
break;
|
||||
@ -483,7 +483,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
||||
switch (m_encode_passes[i]) {
|
||||
case EncodeXOR:
|
||||
if (temp.GetInt8(0) == 0)
|
||||
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
||||
Decode(temp, ReliableStreamHeader::size(), temp.Length() - ReliableStreamHeader::size());
|
||||
else
|
||||
Decode(temp, 1, temp.Length() - 1);
|
||||
break;
|
||||
@ -502,7 +502,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ProcessQueue()
|
||||
void EQ::Net::ReliableStreamConnection::ProcessQueue()
|
||||
{
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
auto stream = &m_streams[i];
|
||||
@ -521,7 +521,7 @@ void EQ::Net::DaybreakConnection::ProcessQueue()
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
|
||||
void EQ::Net::ReliableStreamConnection::RemoveFromQueue(int stream, uint16_t seq)
|
||||
{
|
||||
auto s = &m_streams[stream];
|
||||
auto iter = s->packet_queue.find(seq);
|
||||
@ -532,7 +532,7 @@ void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::AddToQueue(int stream, uint16_t seq, const Packet &p)
|
||||
{
|
||||
auto s = &m_streams[stream];
|
||||
auto iter = s->packet_queue.find(seq);
|
||||
@ -544,7 +544,7 @@ void EQ::Net::DaybreakConnection::AddToQueue(int stream, uint16_t seq, const Pac
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::ProcessDecodedPacket(const Packet &p)
|
||||
{
|
||||
if (p.GetInt8(0) == 0) {
|
||||
if (p.Length() < 2) {
|
||||
@ -628,13 +628,13 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
case OP_SessionRequest:
|
||||
{
|
||||
if (m_status == StatusConnected) {
|
||||
auto request = p.GetSerialize<DaybreakConnect>(0);
|
||||
auto request = p.GetSerialize<ReliableStreamConnect>(0);
|
||||
|
||||
if (NetworkToHost(request.connect_code) != m_connect_code) {
|
||||
return;
|
||||
}
|
||||
|
||||
DaybreakConnectReply reply;
|
||||
ReliableStreamConnectReply reply;
|
||||
reply.zero = 0;
|
||||
reply.opcode = OP_SessionResponse;
|
||||
reply.connect_code = HostToNetwork(m_connect_code);
|
||||
@ -656,13 +656,13 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
case OP_SessionResponse:
|
||||
{
|
||||
if (m_status == StatusConnecting) {
|
||||
auto reply = p.GetSerialize<DaybreakConnectReply>(0);
|
||||
auto reply = p.GetSerialize<ReliableStreamConnectReply>(0);
|
||||
|
||||
if (m_connect_code == reply.connect_code) {
|
||||
m_encode_key = reply.encode_key;
|
||||
m_crc_bytes = reply.crc_bytes;
|
||||
m_encode_passes[0] = (DaybreakEncodeType)reply.encode_pass1;
|
||||
m_encode_passes[1] = (DaybreakEncodeType)reply.encode_pass2;
|
||||
m_encode_passes[0] = (ReliableStreamEncodeType)reply.encode_pass1;
|
||||
m_encode_passes[1] = (ReliableStreamEncodeType)reply.encode_pass2;
|
||||
m_max_packet_size = reply.max_packet_size;
|
||||
ChangeStatus(StatusConnected);
|
||||
|
||||
@ -686,7 +686,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
return;
|
||||
}
|
||||
|
||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
||||
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||
auto sequence = NetworkToHost(header.sequence);
|
||||
auto stream_id = header.opcode - OP_Packet;
|
||||
auto stream = &m_streams[stream_id];
|
||||
@ -703,7 +703,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
RemoveFromQueue(stream_id, sequence);
|
||||
SendAck(stream_id, stream->sequence_in);
|
||||
stream->sequence_in++;
|
||||
StaticPacket next((char*)p.Data() + DaybreakReliableHeader::size(), p.Length() - DaybreakReliableHeader::size());
|
||||
StaticPacket next((char*)p.Data() + ReliableStreamReliableHeader::size(), p.Length() - ReliableStreamReliableHeader::size());
|
||||
ProcessDecodedPacket(next);
|
||||
}
|
||||
|
||||
@ -715,7 +715,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
case OP_Fragment3:
|
||||
case OP_Fragment4:
|
||||
{
|
||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
||||
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||
auto sequence = NetworkToHost(header.sequence);
|
||||
auto stream_id = header.opcode - OP_Fragment;
|
||||
auto stream = &m_streams[stream_id];
|
||||
@ -735,22 +735,22 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
stream->sequence_in++;
|
||||
|
||||
if (stream->fragment_total_bytes == 0) {
|
||||
auto fragheader = p.GetSerialize<DaybreakReliableFragmentHeader>(0);
|
||||
auto fragheader = p.GetSerialize<ReliableStreamReliableFragmentHeader>(0);
|
||||
stream->fragment_total_bytes = NetworkToHost(fragheader.total_size);
|
||||
stream->fragment_current_bytes = 0;
|
||||
stream->fragment_packet.Reserve(stream->fragment_total_bytes);
|
||||
stream->fragment_packet.PutData(
|
||||
stream->fragment_current_bytes,
|
||||
(char*)p.Data() + DaybreakReliableFragmentHeader::size(), p.Length() - DaybreakReliableFragmentHeader::size());
|
||||
(char*)p.Data() + ReliableStreamReliableFragmentHeader::size(), p.Length() - ReliableStreamReliableFragmentHeader::size());
|
||||
|
||||
stream->fragment_current_bytes += (uint32_t)(p.Length() - DaybreakReliableFragmentHeader::size());
|
||||
stream->fragment_current_bytes += (uint32_t)(p.Length() - ReliableStreamReliableFragmentHeader::size());
|
||||
}
|
||||
else {
|
||||
stream->fragment_packet.PutData(
|
||||
stream->fragment_current_bytes,
|
||||
(char*)p.Data() + DaybreakReliableHeader::size(), p.Length() - DaybreakReliableHeader::size());
|
||||
(char*)p.Data() + ReliableStreamReliableHeader::size(), p.Length() - ReliableStreamReliableHeader::size());
|
||||
|
||||
stream->fragment_current_bytes += (uint32_t)(p.Length() - DaybreakReliableHeader::size());
|
||||
stream->fragment_current_bytes += (uint32_t)(p.Length() - ReliableStreamReliableHeader::size());
|
||||
|
||||
if (stream->fragment_current_bytes >= stream->fragment_total_bytes) {
|
||||
ProcessDecodedPacket(stream->fragment_packet);
|
||||
@ -769,7 +769,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
case OP_Ack3:
|
||||
case OP_Ack4:
|
||||
{
|
||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
||||
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||
auto sequence = NetworkToHost(header.sequence);
|
||||
auto stream_id = header.opcode - OP_Ack;
|
||||
Ack(stream_id, sequence);
|
||||
@ -781,7 +781,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
case OP_OutOfOrderAck3:
|
||||
case OP_OutOfOrderAck4:
|
||||
{
|
||||
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
|
||||
auto header = p.GetSerialize<ReliableStreamReliableHeader>(0);
|
||||
auto sequence = NetworkToHost(header.sequence);
|
||||
auto stream_id = header.opcode - OP_OutOfOrderAck;
|
||||
OutOfOrderAck(stream_id, sequence);
|
||||
@ -815,13 +815,13 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
}
|
||||
case OP_SessionStatRequest:
|
||||
{
|
||||
auto request = p.GetSerialize<DaybreakSessionStatRequest>(0);
|
||||
auto request = p.GetSerialize<ReliableStreamSessionStatRequest>(0);
|
||||
m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(request.packets_sent);
|
||||
m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(request.packets_recv);
|
||||
m_stats.sync_sent_packets = m_stats.sent_packets;
|
||||
m_stats.sync_recv_packets = m_stats.recv_packets;
|
||||
|
||||
DaybreakSessionStatResponse response;
|
||||
ReliableStreamSessionStatResponse response;
|
||||
response.zero = 0;
|
||||
response.opcode = OP_SessionStatResponse;
|
||||
response.timestamp = request.timestamp;
|
||||
@ -836,7 +836,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
break;
|
||||
}
|
||||
case OP_SessionStatResponse: {
|
||||
auto response = p.GetSerialize<DaybreakSessionStatResponse>(0);
|
||||
auto response = p.GetSerialize<ReliableStreamSessionStatResponse>(0);
|
||||
m_stats.sync_remote_sent_packets = EQ::Net::NetworkToHost(response.server_sent);
|
||||
m_stats.sync_remote_recv_packets = EQ::Net::NetworkToHost(response.server_recv);
|
||||
m_stats.sync_sent_packets = m_stats.sent_packets;
|
||||
@ -858,7 +858,7 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
}
|
||||
}
|
||||
|
||||
bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
|
||||
bool EQ::Net::ReliableStreamConnection::ValidateCRC(Packet &p)
|
||||
{
|
||||
if (m_crc_bytes == 0U) {
|
||||
return true;
|
||||
@ -892,7 +892,7 @@ bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
|
||||
return false;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::AppendCRC(Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::AppendCRC(Packet &p)
|
||||
{
|
||||
if (m_crc_bytes == 0U) {
|
||||
return;
|
||||
@ -911,7 +911,7 @@ void EQ::Net::DaybreakConnection::AppendCRC(Packet &p)
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ChangeStatus(DbProtocolStatus new_status)
|
||||
void EQ::Net::ReliableStreamConnection::ChangeStatus(DbProtocolStatus new_status)
|
||||
{
|
||||
if (m_owner->m_on_connection_state_change) {
|
||||
if (auto self = m_self.lock()) {
|
||||
@ -922,7 +922,7 @@ void EQ::Net::DaybreakConnection::ChangeStatus(DbProtocolStatus new_status)
|
||||
m_status = new_status;
|
||||
}
|
||||
|
||||
bool EQ::Net::DaybreakConnection::PacketCanBeEncoded(Packet &p) const
|
||||
bool EQ::Net::ReliableStreamConnection::PacketCanBeEncoded(Packet &p) const
|
||||
{
|
||||
if (p.Length() < 2) {
|
||||
return false;
|
||||
@ -941,7 +941,7 @@ bool EQ::Net::DaybreakConnection::PacketCanBeEncoded(Packet &p) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Decode(Packet &p, size_t offset, size_t length)
|
||||
void EQ::Net::ReliableStreamConnection::Decode(Packet &p, size_t offset, size_t length)
|
||||
{
|
||||
int key = m_encode_key;
|
||||
char *buffer = (char*)p.Data() + offset;
|
||||
@ -961,7 +961,7 @@ void EQ::Net::DaybreakConnection::Decode(Packet &p, size_t offset, size_t length
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Encode(Packet &p, size_t offset, size_t length)
|
||||
void EQ::Net::ReliableStreamConnection::Encode(Packet &p, size_t offset, size_t length)
|
||||
{
|
||||
int key = m_encode_key;
|
||||
char *buffer = (char*)p.Data() + offset;
|
||||
@ -1050,7 +1050,7 @@ uint32_t Deflate(const uint8_t* in, uint32_t in_len, uint8_t* out, uint32_t out_
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Decompress(Packet &p, size_t offset, size_t length)
|
||||
void EQ::Net::ReliableStreamConnection::Decompress(Packet &p, size_t offset, size_t length)
|
||||
{
|
||||
if (length < 2) {
|
||||
return;
|
||||
@ -1075,7 +1075,7 @@ void EQ::Net::DaybreakConnection::Decompress(Packet &p, size_t offset, size_t le
|
||||
p.PutData(offset, new_buffer, new_length);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t length)
|
||||
void EQ::Net::ReliableStreamConnection::Compress(Packet &p, size_t offset, size_t length)
|
||||
{
|
||||
static thread_local uint8_t new_buffer[2048] = { 0 };
|
||||
uint8_t *buffer = (uint8_t*)p.Data() + offset;
|
||||
@ -1097,14 +1097,14 @@ void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t leng
|
||||
p.PutData(offset, new_buffer, new_length);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ProcessResend()
|
||||
void EQ::Net::ReliableStreamConnection::ProcessResend()
|
||||
{
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
ProcessResend(i);
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
void EQ::Net::ReliableStreamConnection::ProcessResend(int stream)
|
||||
{
|
||||
if (m_status == DbProtocolStatus::StatusDisconnected) {
|
||||
return;
|
||||
@ -1201,7 +1201,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
|
||||
auto &sp = e.second;
|
||||
auto &p = sp.packet;
|
||||
if (p.Length() >= DaybreakHeader::size()) {
|
||||
if (p.Length() >= ReliableStreamHeader::size()) {
|
||||
if (p.GetInt8(0) == 0 && p.GetInt8(1) >= OP_Fragment && p.GetInt8(1) <= OP_Fragment4) {
|
||||
m_stats.resent_fragments++;
|
||||
}
|
||||
@ -1232,7 +1232,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
m_last_ack = now;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
||||
void EQ::Net::ReliableStreamConnection::Ack(int stream, uint16_t seq)
|
||||
{
|
||||
auto now = Clock::now();
|
||||
auto s = &m_streams[stream];
|
||||
@ -1259,7 +1259,7 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
||||
m_last_ack = now;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq)
|
||||
void EQ::Net::ReliableStreamConnection::OutOfOrderAck(int stream, uint16_t seq)
|
||||
{
|
||||
auto now = Clock::now();
|
||||
auto s = &m_streams[stream];
|
||||
@ -1279,15 +1279,15 @@ void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq)
|
||||
m_last_ack = now;
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::UpdateDataBudget(double budget_add)
|
||||
void EQ::Net::ReliableStreamConnection::UpdateDataBudget(double budget_add)
|
||||
{
|
||||
auto outgoing_data_rate = m_owner->m_options.outgoing_data_rate;
|
||||
m_outgoing_budget = EQ::ClampUpper(m_outgoing_budget + budget_add, outgoing_data_rate);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
|
||||
void EQ::Net::ReliableStreamConnection::SendAck(int stream_id, uint16_t seq)
|
||||
{
|
||||
DaybreakReliableHeader ack;
|
||||
ReliableStreamReliableHeader ack;
|
||||
ack.zero = 0;
|
||||
ack.opcode = OP_Ack + stream_id;
|
||||
ack.sequence = HostToNetwork(seq);
|
||||
@ -1298,9 +1298,9 @@ void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
|
||||
InternalBufferedSend(p);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
|
||||
void EQ::Net::ReliableStreamConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
|
||||
{
|
||||
DaybreakReliableHeader ack;
|
||||
ReliableStreamReliableHeader ack;
|
||||
ack.zero = 0;
|
||||
ack.opcode = OP_OutOfOrderAck + stream_id;
|
||||
ack.sequence = HostToNetwork(seq);
|
||||
@ -1311,9 +1311,9 @@ void EQ::Net::DaybreakConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
|
||||
InternalBufferedSend(p);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::SendDisconnect()
|
||||
void EQ::Net::ReliableStreamConnection::SendDisconnect()
|
||||
{
|
||||
DaybreakDisconnect disconnect;
|
||||
ReliableStreamDisconnect disconnect;
|
||||
disconnect.zero = 0;
|
||||
disconnect.opcode = OP_SessionDisconnect;
|
||||
disconnect.connect_code = HostToNetwork(m_connect_code);
|
||||
@ -1322,7 +1322,7 @@ void EQ::Net::DaybreakConnection::SendDisconnect()
|
||||
InternalSend(out);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
|
||||
void EQ::Net::ReliableStreamConnection::InternalBufferedSend(Packet &p)
|
||||
{
|
||||
if (p.Length() > 0xFFU) {
|
||||
FlushBuffer();
|
||||
@ -1331,7 +1331,7 @@ void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
|
||||
}
|
||||
|
||||
//we could add this packet to a combined
|
||||
size_t raw_size = DaybreakHeader::size() + (size_t)m_crc_bytes + m_buffered_packets_length + m_buffered_packets.size() + 1 + p.Length();
|
||||
size_t raw_size = ReliableStreamHeader::size() + (size_t)m_crc_bytes + m_buffered_packets_length + m_buffered_packets.size() + 1 + p.Length();
|
||||
if (raw_size > m_max_packet_size) {
|
||||
FlushBuffer();
|
||||
}
|
||||
@ -1346,9 +1346,9 @@ void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::SendConnect()
|
||||
void EQ::Net::ReliableStreamConnection::SendConnect()
|
||||
{
|
||||
DaybreakConnect connect;
|
||||
ReliableStreamConnect connect;
|
||||
connect.zero = 0;
|
||||
connect.opcode = OP_SessionRequest;
|
||||
connect.protocol_version = HostToNetwork(3U);
|
||||
@ -1361,9 +1361,9 @@ void EQ::Net::DaybreakConnection::SendConnect()
|
||||
InternalSend(p);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::SendKeepAlive()
|
||||
void EQ::Net::ReliableStreamConnection::SendKeepAlive()
|
||||
{
|
||||
DaybreakHeader keep_alive;
|
||||
ReliableStreamHeader keep_alive;
|
||||
keep_alive.zero = 0;
|
||||
keep_alive.opcode = OP_KeepAlive;
|
||||
|
||||
@ -1373,7 +1373,7 @@ void EQ::Net::DaybreakConnection::SendKeepAlive()
|
||||
InternalSend(p);
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::InternalSend(Packet &p) {
|
||||
void EQ::Net::ReliableStreamConnection::InternalSend(Packet &p) {
|
||||
if (m_owner->m_options.outgoing_data_rate > 0.0) {
|
||||
auto new_budget = m_outgoing_budget - (p.Length() / 1024.0);
|
||||
if (new_budget <= 0.0) {
|
||||
@ -1409,14 +1409,14 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p) {
|
||||
switch (m_encode_passe) {
|
||||
case EncodeCompression:
|
||||
if (out.GetInt8(0) == 0) {
|
||||
Compress(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
|
||||
Compress(out, ReliableStreamHeader::size(), out.Length() - ReliableStreamHeader::size());
|
||||
} else {
|
||||
Compress(out, 1, out.Length() - 1);
|
||||
}
|
||||
break;
|
||||
case EncodeXOR:
|
||||
if (out.GetInt8(0) == 0) {
|
||||
Encode(out, DaybreakHeader::size(), out.Length() - DaybreakHeader::size());
|
||||
Encode(out, ReliableStreamHeader::size(), out.Length() - ReliableStreamHeader::size());
|
||||
} else {
|
||||
Encode(out, 1, out.Length() - 1);
|
||||
}
|
||||
@ -1466,7 +1466,7 @@ void EQ::Net::DaybreakConnection::InternalSend(Packet &p) {
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id, bool reliable)
|
||||
void EQ::Net::ReliableStreamConnection::InternalQueuePacket(Packet &p, int stream_id, bool reliable)
|
||||
{
|
||||
if (!reliable) {
|
||||
auto max_raw_size = 0xFFU - m_crc_bytes;
|
||||
@ -1480,23 +1480,23 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
}
|
||||
|
||||
auto stream = &m_streams[stream_id];
|
||||
auto max_raw_size = m_max_packet_size - m_crc_bytes - DaybreakReliableHeader::size() - 1; // -1 for compress flag
|
||||
auto max_raw_size = m_max_packet_size - m_crc_bytes - ReliableStreamReliableHeader::size() - 1; // -1 for compress flag
|
||||
size_t length = p.Length();
|
||||
if (length > max_raw_size) {
|
||||
DaybreakReliableFragmentHeader first_header;
|
||||
ReliableStreamReliableFragmentHeader first_header;
|
||||
first_header.reliable.zero = 0;
|
||||
first_header.reliable.opcode = OP_Fragment + stream_id;
|
||||
first_header.reliable.sequence = HostToNetwork(stream->sequence_out);
|
||||
first_header.total_size = (uint32_t)HostToNetwork((uint32_t)length);
|
||||
|
||||
size_t used = 0;
|
||||
size_t sublen = m_max_packet_size - m_crc_bytes - DaybreakReliableFragmentHeader::size() - 1; // -1 for compress flag
|
||||
size_t sublen = m_max_packet_size - m_crc_bytes - ReliableStreamReliableFragmentHeader::size() - 1; // -1 for compress flag
|
||||
DynamicPacket first_packet;
|
||||
first_packet.PutSerialize(0, first_header);
|
||||
first_packet.PutData(DaybreakReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
|
||||
first_packet.PutData(ReliableStreamReliableFragmentHeader::size(), (char*)p.Data() + used, sublen);
|
||||
used += sublen;
|
||||
|
||||
DaybreakSentPacket sent;
|
||||
ReliableStreamSentPacket sent;
|
||||
sent.packet.PutPacket(0, first_packet);
|
||||
sent.last_sent = Clock::now();
|
||||
sent.first_sent = Clock::now();
|
||||
@ -1513,22 +1513,22 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
while (used < length) {
|
||||
auto left = length - used;
|
||||
DynamicPacket packet;
|
||||
DaybreakReliableHeader header;
|
||||
ReliableStreamReliableHeader header;
|
||||
header.zero = 0;
|
||||
header.opcode = OP_Fragment + stream_id;
|
||||
header.sequence = HostToNetwork(stream->sequence_out);
|
||||
packet.PutSerialize(0, header);
|
||||
|
||||
if (left > max_raw_size) {
|
||||
packet.PutData(DaybreakReliableHeader::size(), (char*)p.Data() + used, max_raw_size);
|
||||
packet.PutData(ReliableStreamReliableHeader::size(), (char*)p.Data() + used, max_raw_size);
|
||||
used += max_raw_size;
|
||||
}
|
||||
else {
|
||||
packet.PutData(DaybreakReliableHeader::size(), (char*)p.Data() + used, left);
|
||||
packet.PutData(ReliableStreamReliableHeader::size(), (char*)p.Data() + used, left);
|
||||
used += left;
|
||||
}
|
||||
|
||||
DaybreakSentPacket sent;
|
||||
ReliableStreamSentPacket sent;
|
||||
sent.packet.PutPacket(0, packet);
|
||||
sent.last_sent = Clock::now();
|
||||
sent.first_sent = Clock::now();
|
||||
@ -1545,14 +1545,14 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
}
|
||||
else {
|
||||
DynamicPacket packet;
|
||||
DaybreakReliableHeader header;
|
||||
ReliableStreamReliableHeader header;
|
||||
header.zero = 0;
|
||||
header.opcode = OP_Packet + stream_id;
|
||||
header.sequence = HostToNetwork(stream->sequence_out);
|
||||
packet.PutSerialize(0, header);
|
||||
packet.PutPacket(DaybreakReliableHeader::size(), p);
|
||||
packet.PutPacket(ReliableStreamReliableHeader::size(), p);
|
||||
|
||||
DaybreakSentPacket sent;
|
||||
ReliableStreamSentPacket sent;
|
||||
sent.packet.PutPacket(0, packet);
|
||||
sent.last_sent = Clock::now();
|
||||
sent.first_sent = Clock::now();
|
||||
@ -1568,7 +1568,7 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
}
|
||||
}
|
||||
|
||||
void EQ::Net::DaybreakConnection::FlushBuffer()
|
||||
void EQ::Net::ReliableStreamConnection::FlushBuffer()
|
||||
{
|
||||
if (m_buffered_packets.empty()) {
|
||||
return;
|
||||
@ -1595,7 +1595,7 @@ void EQ::Net::DaybreakConnection::FlushBuffer()
|
||||
m_buffered_packets_length = 0;
|
||||
}
|
||||
|
||||
EQ::Net::SequenceOrder EQ::Net::DaybreakConnection::CompareSequence(uint16_t expected, uint16_t actual) const
|
||||
EQ::Net::SequenceOrder EQ::Net::ReliableStreamConnection::CompareSequence(uint16_t expected, uint16_t actual) const
|
||||
{
|
||||
int diff = (int)actual - (int)expected;
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
|
||||
#include "../random.h"
|
||||
#include "packet.h"
|
||||
#include "daybreak_structs.h"
|
||||
#include "daybreak_pooling.h"
|
||||
#include "reliable_stream_structs.h"
|
||||
#include "reliable_stream_pooling.h"
|
||||
#include <uv.h>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
@ -16,7 +16,7 @@ namespace EQ
|
||||
{
|
||||
namespace Net
|
||||
{
|
||||
enum DaybreakProtocolOpcode
|
||||
enum ReliableStreamProtocolOpcode
|
||||
{
|
||||
OP_Padding = 0x00,
|
||||
OP_SessionRequest = 0x01,
|
||||
@ -55,7 +55,7 @@ namespace EQ
|
||||
StatusDisconnected
|
||||
};
|
||||
|
||||
enum DaybreakEncodeType
|
||||
enum ReliableStreamEncodeType
|
||||
{
|
||||
EncodeNone = 0,
|
||||
EncodeCompression = 1,
|
||||
@ -72,9 +72,9 @@ namespace EQ
|
||||
typedef std::chrono::steady_clock::time_point Timestamp;
|
||||
typedef std::chrono::steady_clock Clock;
|
||||
|
||||
struct DaybreakConnectionStats
|
||||
struct ReliableStreamConnectionStats
|
||||
{
|
||||
DaybreakConnectionStats() {
|
||||
ReliableStreamConnectionStats() {
|
||||
recv_bytes = 0;
|
||||
sent_bytes = 0;
|
||||
recv_packets = 0;
|
||||
@ -134,14 +134,14 @@ namespace EQ
|
||||
uint64_t bytes_before_encode;
|
||||
};
|
||||
|
||||
class DaybreakConnectionManager;
|
||||
class DaybreakConnection;
|
||||
class DaybreakConnection
|
||||
class ReliableStreamConnectionManager;
|
||||
class ReliableStreamConnection;
|
||||
class ReliableStreamConnection
|
||||
{
|
||||
public:
|
||||
DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port);
|
||||
DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port);
|
||||
~DaybreakConnection();
|
||||
ReliableStreamConnection(ReliableStreamConnectionManager *owner, const ReliableStreamConnect &connect, const std::string &endpoint, int port);
|
||||
ReliableStreamConnection(ReliableStreamConnectionManager *owner, const std::string &endpoint, int port);
|
||||
~ReliableStreamConnection();
|
||||
|
||||
const std::string& RemoteEndpoint() const { return m_endpoint; }
|
||||
int RemotePort() const { return m_port; }
|
||||
@ -151,23 +151,23 @@ namespace EQ
|
||||
void QueuePacket(Packet &p, int stream);
|
||||
void QueuePacket(Packet &p, int stream, bool reliable);
|
||||
|
||||
DaybreakConnectionStats GetStats();
|
||||
ReliableStreamConnectionStats GetStats();
|
||||
void ResetStats();
|
||||
size_t GetRollingPing() const { return m_rolling_ping; }
|
||||
DbProtocolStatus GetStatus() const { return m_status; }
|
||||
|
||||
const DaybreakEncodeType* GetEncodePasses() const { return m_encode_passes; }
|
||||
const DaybreakConnectionManager* GetManager() const { return m_owner; }
|
||||
DaybreakConnectionManager* GetManager() { return m_owner; }
|
||||
const ReliableStreamEncodeType* GetEncodePasses() const { return m_encode_passes; }
|
||||
const ReliableStreamConnectionManager* GetManager() const { return m_owner; }
|
||||
ReliableStreamConnectionManager* GetManager() { return m_owner; }
|
||||
private:
|
||||
DaybreakConnectionManager *m_owner;
|
||||
ReliableStreamConnectionManager *m_owner;
|
||||
std::string m_endpoint;
|
||||
int m_port;
|
||||
uint32_t m_connect_code;
|
||||
uint32_t m_encode_key;
|
||||
uint32_t m_max_packet_size;
|
||||
uint32_t m_crc_bytes;
|
||||
DaybreakEncodeType m_encode_passes[2];
|
||||
ReliableStreamEncodeType m_encode_passes[2];
|
||||
|
||||
Timestamp m_last_send;
|
||||
Timestamp m_last_recv;
|
||||
@ -176,7 +176,7 @@ namespace EQ
|
||||
std::list<DynamicPacket> m_buffered_packets;
|
||||
size_t m_buffered_packets_length;
|
||||
std::unique_ptr<char[]> m_combined;
|
||||
DaybreakConnectionStats m_stats;
|
||||
ReliableStreamConnectionStats m_stats;
|
||||
Timestamp m_last_session_stats;
|
||||
size_t m_rolling_ping;
|
||||
Timestamp m_close_time;
|
||||
@ -188,7 +188,7 @@ namespace EQ
|
||||
bool m_acked_since_last_resend = false;
|
||||
Timestamp m_last_ack;
|
||||
|
||||
struct DaybreakSentPacket
|
||||
struct ReliableStreamSentPacket
|
||||
{
|
||||
DynamicPacket packet;
|
||||
Timestamp last_sent;
|
||||
@ -197,9 +197,9 @@ namespace EQ
|
||||
size_t resend_delay;
|
||||
};
|
||||
|
||||
struct DaybreakStream
|
||||
struct ReliableStream
|
||||
{
|
||||
DaybreakStream() {
|
||||
ReliableStream() {
|
||||
sequence_in = 0;
|
||||
sequence_out = 0;
|
||||
fragment_current_bytes = 0;
|
||||
@ -214,11 +214,11 @@ namespace EQ
|
||||
uint32_t fragment_current_bytes;
|
||||
uint32_t fragment_total_bytes;
|
||||
|
||||
std::map<uint16_t, DaybreakSentPacket> sent_packets;
|
||||
std::map<uint16_t, ReliableStreamSentPacket> sent_packets;
|
||||
};
|
||||
|
||||
DaybreakStream m_streams[4];
|
||||
std::weak_ptr<DaybreakConnection> m_self;
|
||||
ReliableStream m_streams[4];
|
||||
std::weak_ptr<ReliableStreamConnection> m_self;
|
||||
|
||||
void Process();
|
||||
void ProcessPacket(Packet &p);
|
||||
@ -251,12 +251,12 @@ namespace EQ
|
||||
void FlushBuffer();
|
||||
SequenceOrder CompareSequence(uint16_t expected, uint16_t actual) const;
|
||||
|
||||
friend class DaybreakConnectionManager;
|
||||
friend class ReliableStreamConnectionManager;
|
||||
};
|
||||
|
||||
struct DaybreakConnectionManagerOptions
|
||||
struct ReliableStreamConnectionManagerOptions
|
||||
{
|
||||
DaybreakConnectionManagerOptions() {
|
||||
ReliableStreamConnectionManagerOptions() {
|
||||
max_connection_count = 0;
|
||||
keepalive_delay_ms = 9000;
|
||||
resend_delay_ms = 30;
|
||||
@ -268,8 +268,8 @@ namespace EQ
|
||||
connect_stale_ms = 5000;
|
||||
crc_length = 2;
|
||||
max_packet_size = 512;
|
||||
encode_passes[0] = DaybreakEncodeType::EncodeNone;
|
||||
encode_passes[1] = DaybreakEncodeType::EncodeNone;
|
||||
encode_passes[0] = ReliableStreamEncodeType::EncodeNone;
|
||||
encode_passes[1] = ReliableStreamEncodeType::EncodeNone;
|
||||
port = 0;
|
||||
hold_size = 512;
|
||||
hold_length_ms = 50;
|
||||
@ -299,28 +299,28 @@ namespace EQ
|
||||
double tic_rate_hertz;
|
||||
size_t resend_timeout;
|
||||
size_t connection_close_time;
|
||||
DaybreakEncodeType encode_passes[2];
|
||||
ReliableStreamEncodeType encode_passes[2];
|
||||
int port;
|
||||
double outgoing_data_rate;
|
||||
};
|
||||
|
||||
class DaybreakConnectionManager
|
||||
class ReliableStreamConnectionManager
|
||||
{
|
||||
public:
|
||||
DaybreakConnectionManager();
|
||||
DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts);
|
||||
~DaybreakConnectionManager();
|
||||
ReliableStreamConnectionManager();
|
||||
ReliableStreamConnectionManager(const ReliableStreamConnectionManagerOptions &opts);
|
||||
~ReliableStreamConnectionManager();
|
||||
|
||||
void Connect(const std::string &addr, int port);
|
||||
void Process();
|
||||
void UpdateDataBudget();
|
||||
void ProcessResend();
|
||||
void OnNewConnection(std::function<void(std::shared_ptr<DaybreakConnection>)> func) { m_on_new_connection = func; }
|
||||
void OnConnectionStateChange(std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
||||
void OnPacketRecv(std::function<void(std::shared_ptr<DaybreakConnection>, const Packet &)> func) { m_on_packet_recv = func; }
|
||||
void OnNewConnection(std::function<void(std::shared_ptr<ReliableStreamConnection>)> func) { m_on_new_connection = func; }
|
||||
void OnConnectionStateChange(std::function<void(std::shared_ptr<ReliableStreamConnection>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
|
||||
void OnPacketRecv(std::function<void(std::shared_ptr<ReliableStreamConnection>, const Packet &)> func) { m_on_packet_recv = func; }
|
||||
void OnErrorMessage(std::function<void(const std::string&)> func) { m_on_error_message = func; }
|
||||
|
||||
DaybreakConnectionManagerOptions& GetOptions() { return m_options; }
|
||||
ReliableStreamConnectionManagerOptions& GetOptions() { return m_options; }
|
||||
private:
|
||||
void Attach(uv_loop_t *loop);
|
||||
void Detach();
|
||||
@ -329,18 +329,18 @@ namespace EQ
|
||||
uv_timer_t m_timer;
|
||||
uv_udp_t m_socket;
|
||||
uv_loop_t *m_attached;
|
||||
DaybreakConnectionManagerOptions m_options;
|
||||
std::function<void(std::shared_ptr<DaybreakConnection>)> m_on_new_connection;
|
||||
std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||
std::function<void(std::shared_ptr<DaybreakConnection>, const Packet&)> m_on_packet_recv;
|
||||
ReliableStreamConnectionManagerOptions m_options;
|
||||
std::function<void(std::shared_ptr<ReliableStreamConnection>)> m_on_new_connection;
|
||||
std::function<void(std::shared_ptr<ReliableStreamConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
|
||||
std::function<void(std::shared_ptr<ReliableStreamConnection>, const Packet&)> m_on_packet_recv;
|
||||
std::function<void(const std::string&)> m_on_error_message;
|
||||
std::map<std::pair<std::string, int>, std::shared_ptr<DaybreakConnection>> m_connections;
|
||||
std::map<std::pair<std::string, int>, std::shared_ptr<ReliableStreamConnection>> m_connections;
|
||||
|
||||
void ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size);
|
||||
std::shared_ptr<DaybreakConnection> FindConnectionByEndpoint(std::string addr, int port);
|
||||
std::shared_ptr<ReliableStreamConnection> FindConnectionByEndpoint(std::string addr, int port);
|
||||
void SendDisconnect(const std::string &addr, int port);
|
||||
|
||||
friend class DaybreakConnection;
|
||||
friend class ReliableStreamConnection;
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -8,7 +8,7 @@ namespace EQ
|
||||
{
|
||||
namespace Net
|
||||
{
|
||||
struct DaybreakHeader
|
||||
struct ReliableStreamHeader
|
||||
{
|
||||
static size_t size() { return 2; }
|
||||
uint8_t zero;
|
||||
@ -22,7 +22,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakConnect
|
||||
struct ReliableStreamConnect
|
||||
{
|
||||
static size_t size() { return 14; }
|
||||
uint8_t zero;
|
||||
@ -42,7 +42,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakConnectReply
|
||||
struct ReliableStreamConnectReply
|
||||
{
|
||||
static size_t size() { return 17; }
|
||||
uint8_t zero;
|
||||
@ -68,7 +68,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakDisconnect
|
||||
struct ReliableStreamDisconnect
|
||||
{
|
||||
static size_t size() { return 8; }
|
||||
uint8_t zero;
|
||||
@ -84,7 +84,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakReliableHeader
|
||||
struct ReliableStreamReliableHeader
|
||||
{
|
||||
static size_t size() { return 4; }
|
||||
uint8_t zero;
|
||||
@ -100,10 +100,10 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakReliableFragmentHeader
|
||||
struct ReliableStreamReliableFragmentHeader
|
||||
{
|
||||
static size_t size() { return 4 + DaybreakReliableHeader::size(); }
|
||||
DaybreakReliableHeader reliable;
|
||||
static size_t size() { return 4 + ReliableStreamReliableHeader::size(); }
|
||||
ReliableStreamReliableHeader reliable;
|
||||
uint32_t total_size;
|
||||
|
||||
template <class Archive>
|
||||
@ -114,7 +114,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakSessionStatRequest
|
||||
struct ReliableStreamSessionStatRequest
|
||||
{
|
||||
static size_t size() { return 40; }
|
||||
uint8_t zero;
|
||||
@ -144,7 +144,7 @@ namespace EQ
|
||||
}
|
||||
};
|
||||
|
||||
struct DaybreakSessionStatResponse
|
||||
struct ReliableStreamSessionStatResponse
|
||||
{
|
||||
static size_t size() { return 40; }
|
||||
uint8_t zero;
|
||||
@ -1059,7 +1059,7 @@ namespace Titanium
|
||||
OUT(spawnid);
|
||||
OUT_str(charname);
|
||||
|
||||
if (emu->race > 473)
|
||||
if (emu->race > 474)
|
||||
eq->race = 1;
|
||||
else
|
||||
OUT(race);
|
||||
@ -1840,7 +1840,7 @@ namespace Titanium
|
||||
emu_cse = (CharacterSelectEntry_Struct *)emu_ptr;
|
||||
|
||||
eq->Race[char_index] = emu_cse->Race;
|
||||
if (eq->Race[char_index] > 473)
|
||||
if (eq->Race[char_index] > 474)
|
||||
eq->Race[char_index] = 1;
|
||||
|
||||
for (int index = 0; index < EQ::textures::materialCount; ++index) {
|
||||
@ -2421,7 +2421,7 @@ namespace Titanium
|
||||
strcpy(eq->title, emu->title);
|
||||
// eq->unknown0274 = emu->unknown0274;
|
||||
eq->helm = emu->helm;
|
||||
if (emu->race > 473)
|
||||
if (emu->race > 474)
|
||||
eq->race = 1;
|
||||
else
|
||||
eq->race = emu->race;
|
||||
|
||||
@ -70,6 +70,7 @@ public:
|
||||
int32_t endurance_regen;
|
||||
int32_t shielding;
|
||||
int32_t spell_damage;
|
||||
int32_t heal_amount;
|
||||
int32_t spell_shielding;
|
||||
int32_t strikethrough;
|
||||
int32_t stun_resist;
|
||||
@ -154,6 +155,7 @@ public:
|
||||
"endurance_regen",
|
||||
"shielding",
|
||||
"spell_damage",
|
||||
"heal_amount",
|
||||
"spell_shielding",
|
||||
"strikethrough",
|
||||
"stun_resist",
|
||||
@ -234,6 +236,7 @@ public:
|
||||
"endurance_regen",
|
||||
"shielding",
|
||||
"spell_damage",
|
||||
"heal_amount",
|
||||
"spell_shielding",
|
||||
"strikethrough",
|
||||
"stun_resist",
|
||||
@ -348,6 +351,7 @@ public:
|
||||
e.endurance_regen = 0;
|
||||
e.shielding = 0;
|
||||
e.spell_damage = 0;
|
||||
e.heal_amount = 0;
|
||||
e.spell_shielding = 0;
|
||||
e.strikethrough = 0;
|
||||
e.stun_resist = 0;
|
||||
@ -458,29 +462,30 @@ public:
|
||||
e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0;
|
||||
e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0;
|
||||
e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0;
|
||||
e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.heal_amount = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.spell_shielding = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.strikethrough = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.stun_resist = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.backstab = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.wind = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.brass = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.string = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.percussion = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.singing = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.baking = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.alchemy = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.tailoring = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.blacksmithing = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.fletching = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.brewing = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.jewelry = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.pottery = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.research = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.alcohol = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.fishing = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.tinkering = row[72] ? static_cast<int32_t>(atoi(row[72])) : 0;
|
||||
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
|
||||
|
||||
return e;
|
||||
}
|
||||
@ -565,29 +570,30 @@ public:
|
||||
v.push_back(columns[48] + " = " + std::to_string(e.endurance_regen));
|
||||
v.push_back(columns[49] + " = " + std::to_string(e.shielding));
|
||||
v.push_back(columns[50] + " = " + std::to_string(e.spell_damage));
|
||||
v.push_back(columns[51] + " = " + std::to_string(e.spell_shielding));
|
||||
v.push_back(columns[52] + " = " + std::to_string(e.strikethrough));
|
||||
v.push_back(columns[53] + " = " + std::to_string(e.stun_resist));
|
||||
v.push_back(columns[54] + " = " + std::to_string(e.backstab));
|
||||
v.push_back(columns[55] + " = " + std::to_string(e.wind));
|
||||
v.push_back(columns[56] + " = " + std::to_string(e.brass));
|
||||
v.push_back(columns[57] + " = " + std::to_string(e.string));
|
||||
v.push_back(columns[58] + " = " + std::to_string(e.percussion));
|
||||
v.push_back(columns[59] + " = " + std::to_string(e.singing));
|
||||
v.push_back(columns[60] + " = " + std::to_string(e.baking));
|
||||
v.push_back(columns[61] + " = " + std::to_string(e.alchemy));
|
||||
v.push_back(columns[62] + " = " + std::to_string(e.tailoring));
|
||||
v.push_back(columns[63] + " = " + std::to_string(e.blacksmithing));
|
||||
v.push_back(columns[64] + " = " + std::to_string(e.fletching));
|
||||
v.push_back(columns[65] + " = " + std::to_string(e.brewing));
|
||||
v.push_back(columns[66] + " = " + std::to_string(e.jewelry));
|
||||
v.push_back(columns[67] + " = " + std::to_string(e.pottery));
|
||||
v.push_back(columns[68] + " = " + std::to_string(e.research));
|
||||
v.push_back(columns[69] + " = " + std::to_string(e.alcohol));
|
||||
v.push_back(columns[70] + " = " + std::to_string(e.fishing));
|
||||
v.push_back(columns[71] + " = " + std::to_string(e.tinkering));
|
||||
v.push_back(columns[72] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||
v.push_back(columns[73] + " = FROM_UNIXTIME(" + (e.updated_at > 0 ? std::to_string(e.updated_at) : "null") + ")");
|
||||
v.push_back(columns[51] + " = " + std::to_string(e.heal_amount));
|
||||
v.push_back(columns[52] + " = " + std::to_string(e.spell_shielding));
|
||||
v.push_back(columns[53] + " = " + std::to_string(e.strikethrough));
|
||||
v.push_back(columns[54] + " = " + std::to_string(e.stun_resist));
|
||||
v.push_back(columns[55] + " = " + std::to_string(e.backstab));
|
||||
v.push_back(columns[56] + " = " + std::to_string(e.wind));
|
||||
v.push_back(columns[57] + " = " + std::to_string(e.brass));
|
||||
v.push_back(columns[58] + " = " + std::to_string(e.string));
|
||||
v.push_back(columns[59] + " = " + std::to_string(e.percussion));
|
||||
v.push_back(columns[60] + " = " + std::to_string(e.singing));
|
||||
v.push_back(columns[61] + " = " + std::to_string(e.baking));
|
||||
v.push_back(columns[62] + " = " + std::to_string(e.alchemy));
|
||||
v.push_back(columns[63] + " = " + std::to_string(e.tailoring));
|
||||
v.push_back(columns[64] + " = " + std::to_string(e.blacksmithing));
|
||||
v.push_back(columns[65] + " = " + std::to_string(e.fletching));
|
||||
v.push_back(columns[66] + " = " + std::to_string(e.brewing));
|
||||
v.push_back(columns[67] + " = " + std::to_string(e.jewelry));
|
||||
v.push_back(columns[68] + " = " + std::to_string(e.pottery));
|
||||
v.push_back(columns[69] + " = " + std::to_string(e.research));
|
||||
v.push_back(columns[70] + " = " + std::to_string(e.alcohol));
|
||||
v.push_back(columns[71] + " = " + std::to_string(e.fishing));
|
||||
v.push_back(columns[72] + " = " + std::to_string(e.tinkering));
|
||||
v.push_back(columns[73] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||
v.push_back(columns[74] + " = FROM_UNIXTIME(" + (e.updated_at > 0 ? std::to_string(e.updated_at) : "null") + ")");
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@ -660,6 +666,7 @@ public:
|
||||
v.push_back(std::to_string(e.endurance_regen));
|
||||
v.push_back(std::to_string(e.shielding));
|
||||
v.push_back(std::to_string(e.spell_damage));
|
||||
v.push_back(std::to_string(e.heal_amount));
|
||||
v.push_back(std::to_string(e.spell_shielding));
|
||||
v.push_back(std::to_string(e.strikethrough));
|
||||
v.push_back(std::to_string(e.stun_resist));
|
||||
@ -763,6 +770,7 @@ public:
|
||||
v.push_back(std::to_string(e.endurance_regen));
|
||||
v.push_back(std::to_string(e.shielding));
|
||||
v.push_back(std::to_string(e.spell_damage));
|
||||
v.push_back(std::to_string(e.heal_amount));
|
||||
v.push_back(std::to_string(e.spell_shielding));
|
||||
v.push_back(std::to_string(e.strikethrough));
|
||||
v.push_back(std::to_string(e.stun_resist));
|
||||
@ -870,29 +878,30 @@ public:
|
||||
e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0;
|
||||
e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0;
|
||||
e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0;
|
||||
e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.heal_amount = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.spell_shielding = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.strikethrough = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.stun_resist = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.backstab = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.wind = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.brass = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.string = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.percussion = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.singing = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.baking = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.alchemy = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.tailoring = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.blacksmithing = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.fletching = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.brewing = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.jewelry = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.pottery = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.research = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.alcohol = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.fishing = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.tinkering = row[72] ? static_cast<int32_t>(atoi(row[72])) : 0;
|
||||
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -968,29 +977,30 @@ public:
|
||||
e.endurance_regen = row[48] ? static_cast<int32_t>(atoi(row[48])) : 0;
|
||||
e.shielding = row[49] ? static_cast<int32_t>(atoi(row[49])) : 0;
|
||||
e.spell_damage = row[50] ? static_cast<int32_t>(atoi(row[50])) : 0;
|
||||
e.spell_shielding = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.strikethrough = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.stun_resist = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.backstab = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.wind = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.brass = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.string = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.percussion = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.singing = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.baking = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.alchemy = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.tailoring = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.blacksmithing = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.fletching = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.brewing = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.jewelry = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.pottery = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.research = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.alcohol = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.fishing = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.tinkering = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.created_at = strtoll(row[72] ? row[72] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.heal_amount = row[51] ? static_cast<int32_t>(atoi(row[51])) : 0;
|
||||
e.spell_shielding = row[52] ? static_cast<int32_t>(atoi(row[52])) : 0;
|
||||
e.strikethrough = row[53] ? static_cast<int32_t>(atoi(row[53])) : 0;
|
||||
e.stun_resist = row[54] ? static_cast<int32_t>(atoi(row[54])) : 0;
|
||||
e.backstab = row[55] ? static_cast<int32_t>(atoi(row[55])) : 0;
|
||||
e.wind = row[56] ? static_cast<int32_t>(atoi(row[56])) : 0;
|
||||
e.brass = row[57] ? static_cast<int32_t>(atoi(row[57])) : 0;
|
||||
e.string = row[58] ? static_cast<int32_t>(atoi(row[58])) : 0;
|
||||
e.percussion = row[59] ? static_cast<int32_t>(atoi(row[59])) : 0;
|
||||
e.singing = row[60] ? static_cast<int32_t>(atoi(row[60])) : 0;
|
||||
e.baking = row[61] ? static_cast<int32_t>(atoi(row[61])) : 0;
|
||||
e.alchemy = row[62] ? static_cast<int32_t>(atoi(row[62])) : 0;
|
||||
e.tailoring = row[63] ? static_cast<int32_t>(atoi(row[63])) : 0;
|
||||
e.blacksmithing = row[64] ? static_cast<int32_t>(atoi(row[64])) : 0;
|
||||
e.fletching = row[65] ? static_cast<int32_t>(atoi(row[65])) : 0;
|
||||
e.brewing = row[66] ? static_cast<int32_t>(atoi(row[66])) : 0;
|
||||
e.jewelry = row[67] ? static_cast<int32_t>(atoi(row[67])) : 0;
|
||||
e.pottery = row[68] ? static_cast<int32_t>(atoi(row[68])) : 0;
|
||||
e.research = row[69] ? static_cast<int32_t>(atoi(row[69])) : 0;
|
||||
e.alcohol = row[70] ? static_cast<int32_t>(atoi(row[70])) : 0;
|
||||
e.fishing = row[71] ? static_cast<int32_t>(atoi(row[71])) : 0;
|
||||
e.tinkering = row[72] ? static_cast<int32_t>(atoi(row[72])) : 0;
|
||||
e.created_at = strtoll(row[73] ? row[73] : "-1", nullptr, 10);
|
||||
e.updated_at = strtoll(row[74] ? row[74] : "-1", nullptr, 10);
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@ -1116,6 +1126,7 @@ public:
|
||||
v.push_back(std::to_string(e.endurance_regen));
|
||||
v.push_back(std::to_string(e.shielding));
|
||||
v.push_back(std::to_string(e.spell_damage));
|
||||
v.push_back(std::to_string(e.heal_amount));
|
||||
v.push_back(std::to_string(e.spell_shielding));
|
||||
v.push_back(std::to_string(e.strikethrough));
|
||||
v.push_back(std::to_string(e.stun_resist));
|
||||
@ -1212,6 +1223,7 @@ public:
|
||||
v.push_back(std::to_string(e.endurance_regen));
|
||||
v.push_back(std::to_string(e.shielding));
|
||||
v.push_back(std::to_string(e.spell_damage));
|
||||
v.push_back(std::to_string(e.heal_amount));
|
||||
v.push_back(std::to_string(e.spell_shielding));
|
||||
v.push_back(std::to_string(e.strikethrough));
|
||||
v.push_back(std::to_string(e.stun_resist));
|
||||
|
||||
@ -49,6 +49,7 @@ public:
|
||||
// these are the base definitions for command_subsettings and can be over-ridden by the database
|
||||
std::vector<CommandSubsettingsRepository::CommandSubsettings> static_records = {
|
||||
{.parent_command = "find", .sub_command = "aa", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaa"},
|
||||
{.parent_command = "find", .sub_command = "account", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaccount"},
|
||||
{.parent_command = "find", .sub_command = "body_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbodytype"},
|
||||
{.parent_command = "find", .sub_command = "bug_category", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbugcategory"},
|
||||
{.parent_command = "find", .sub_command = "character", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcharacter"},
|
||||
@ -142,6 +143,7 @@ public:
|
||||
{.parent_command = "show", .sub_command = "hatelist", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "hatelist"},
|
||||
{.parent_command = "show", .sub_command = "inventory", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "peekinv"},
|
||||
{.parent_command = "show", .sub_command = "ip_lookup", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "iplookup"},
|
||||
{.parent_command = "show", .sub_command = "keyring", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "showkeyring"},
|
||||
{.parent_command = "show", .sub_command = "line_of_sight", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "checklos"},
|
||||
{.parent_command = "show", .sub_command = "network", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "network"},
|
||||
{.parent_command = "show", .sub_command = "network_stats", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "netstats"},
|
||||
|
||||
@ -1057,7 +1057,7 @@ typedef enum {
|
||||
} DmgShieldType;
|
||||
|
||||
//Spell Effect IDs
|
||||
// https://forums.daybreakgames.com/eq/index.php?threads/enumerated-spa-list.206288/
|
||||
// https://web.archive.org/web/20250816011656/https://forums.everquest.com/index.php?threads/enumerated-spa-list.206288/
|
||||
// mirror: http://pastebin.com/MYeQqGwe
|
||||
#define SE_CurrentHP 0 // implemented - Heals and nukes, repeates every tic if in a buff
|
||||
#define SE_ArmorClass 1 // implemented
|
||||
|
||||
@ -313,6 +313,12 @@ std::string Strings::Commify(const std::string &number)
|
||||
|
||||
auto string_length = static_cast<int>(number.length());
|
||||
|
||||
if (string_length == 3) {
|
||||
return number;
|
||||
} else if (string_length == 4 && number.starts_with("-")) {
|
||||
return number;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (i = string_length - 3; i >= 0; i -= 3) {
|
||||
if (i > 0) {
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
// Build variables
|
||||
// these get injected during the build pipeline
|
||||
#define CURRENT_VERSION "23.8.1-dev" // always append -dev to the current version for custom-builds
|
||||
#define CURRENT_VERSION "23.9.1-dev" // always append -dev to the current version for custom-builds
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
@ -42,7 +42,7 @@
|
||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9325
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9327
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9054
|
||||
#define CUSTOM_BINARY_DATABASE_VERSION 0
|
||||
|
||||
|
||||
20
hc/eq.cpp
20
hc/eq.cpp
@ -33,7 +33,7 @@ EverQuest::EverQuest(const std::string &host, int port, const std::string &user,
|
||||
}
|
||||
else {
|
||||
m_host = addr;
|
||||
m_login_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
|
||||
m_login_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager());
|
||||
|
||||
m_login_connection_manager->OnNewConnection(std::bind(&EverQuest::LoginOnNewConnection, this, std::placeholders::_1));
|
||||
m_login_connection_manager->OnConnectionStateChange(std::bind(&EverQuest::LoginOnStatusChangeReconnectEnabled, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
@ -48,13 +48,13 @@ EverQuest::~EverQuest()
|
||||
{
|
||||
}
|
||||
|
||||
void EverQuest::LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
|
||||
void EverQuest::LoginOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection)
|
||||
{
|
||||
m_login_connection = connection;
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting...");
|
||||
}
|
||||
|
||||
void EverQuest::LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void EverQuest::LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusConnected) {
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Login connected.");
|
||||
@ -70,14 +70,14 @@ void EverQuest::LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::Day
|
||||
}
|
||||
}
|
||||
|
||||
void EverQuest::LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void EverQuest::LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusDisconnected) {
|
||||
m_login_connection.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void EverQuest::LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet & p)
|
||||
void EverQuest::LoginOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet & p)
|
||||
{
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
@ -251,20 +251,20 @@ void EverQuest::LoginDisableReconnect()
|
||||
|
||||
void EverQuest::ConnectToWorld()
|
||||
{
|
||||
m_world_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
|
||||
m_world_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager());
|
||||
m_world_connection_manager->OnNewConnection(std::bind(&EverQuest::WorldOnNewConnection, this, std::placeholders::_1));
|
||||
m_world_connection_manager->OnConnectionStateChange(std::bind(&EverQuest::WorldOnStatusChangeReconnectEnabled, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
m_world_connection_manager->OnPacketRecv(std::bind(&EverQuest::WorldOnPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||
m_world_connection_manager->Connect(m_host, 9000);
|
||||
}
|
||||
|
||||
void EverQuest::WorldOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
|
||||
void EverQuest::WorldOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection)
|
||||
{
|
||||
m_world_connection = connection;
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting to world...");
|
||||
}
|
||||
|
||||
void EverQuest::WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void EverQuest::WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusConnected) {
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "World connected.");
|
||||
@ -278,14 +278,14 @@ void EverQuest::WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::Day
|
||||
}
|
||||
}
|
||||
|
||||
void EverQuest::WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void EverQuest::WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusDisconnected) {
|
||||
m_world_connection.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void EverQuest::WorldOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet & p)
|
||||
void EverQuest::WorldOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet & p)
|
||||
{
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
|
||||
26
hc/eq.h
26
hc/eq.h
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/net/daybreak_connection.h"
|
||||
#include "../common/net/reliable_stream_connection.h"
|
||||
#include "../common/event/timer.h"
|
||||
#include <openssl/des.h>
|
||||
#include <string>
|
||||
@ -26,10 +26,10 @@ public:
|
||||
|
||||
private:
|
||||
//Login
|
||||
void LoginOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
|
||||
void LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void LoginOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
|
||||
void LoginOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection);
|
||||
void LoginOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void LoginOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void LoginOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p);
|
||||
|
||||
void LoginSendSessionReady();
|
||||
void LoginSendLogin();
|
||||
@ -41,25 +41,25 @@ private:
|
||||
|
||||
void LoginDisableReconnect();
|
||||
|
||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_login_connection_manager;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> m_login_connection;
|
||||
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_login_connection_manager;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_login_connection;
|
||||
std::map<uint32_t, WorldServer> m_world_servers;
|
||||
|
||||
//World
|
||||
void ConnectToWorld();
|
||||
|
||||
void WorldOnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
|
||||
void WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void WorldOnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
|
||||
void WorldOnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection);
|
||||
void WorldOnStatusChangeReconnectEnabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void WorldOnStatusChangeReconnectDisabled(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void WorldOnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p);
|
||||
|
||||
void WorldSendClientAuth();
|
||||
void WorldSendEnterWorld(const std::string &character);
|
||||
|
||||
void WorldProcessCharacterSelect(const EQ::Net::Packet &p);
|
||||
|
||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_world_connection_manager;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> m_world_connection;
|
||||
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_world_connection_manager;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_world_connection;
|
||||
|
||||
//Variables
|
||||
std::string m_host;
|
||||
|
||||
10
hc/login.cpp
10
hc/login.cpp
@ -26,7 +26,7 @@ LoginConnection::LoginConnection(const std::string &username, const std::string
|
||||
m_host_port = host_port;
|
||||
m_server = server;
|
||||
|
||||
m_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
|
||||
m_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager());
|
||||
|
||||
m_connection_manager->OnNewConnection(std::bind(&LoginConnection::OnNewConnection, this, std::placeholders::_1));
|
||||
m_connection_manager->OnConnectionStateChange(std::bind(&LoginConnection::OnStatusChangeActive, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
@ -39,13 +39,13 @@ LoginConnection::~LoginConnection()
|
||||
{
|
||||
}
|
||||
|
||||
void LoginConnection::OnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
|
||||
void LoginConnection::OnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection)
|
||||
{
|
||||
m_connection = connection;
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting...");
|
||||
}
|
||||
|
||||
void LoginConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void LoginConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusConnected) {
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Login connected.");
|
||||
@ -61,7 +61,7 @@ void LoginConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConn
|
||||
}
|
||||
}
|
||||
|
||||
void LoginConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void LoginConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusDisconnected) {
|
||||
m_key.clear();
|
||||
@ -70,7 +70,7 @@ void LoginConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakCo
|
||||
}
|
||||
}
|
||||
|
||||
void LoginConnection::OnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p)
|
||||
void LoginConnection::OnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p)
|
||||
{
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
|
||||
14
hc/login.h
14
hc/login.h
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../common/net/daybreak_connection.h"
|
||||
#include "../common/net/reliable_stream_connection.h"
|
||||
#include "../common/event/timer.h"
|
||||
#include <map>
|
||||
|
||||
@ -23,10 +23,10 @@ public:
|
||||
|
||||
~LoginConnection();
|
||||
private:
|
||||
void OnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
|
||||
void OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
|
||||
void OnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection);
|
||||
void OnStatusChangeActive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnStatusChangeInactive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p);
|
||||
void Kill();
|
||||
void Start();
|
||||
|
||||
@ -38,8 +38,8 @@ private:
|
||||
void ProcessServerPacketList(const EQ::Net::Packet &p);
|
||||
void ProcessServerPlayResponse(const EQ::Net::Packet &p);
|
||||
|
||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_connection_manager;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> m_connection;
|
||||
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_connection_manager;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_connection;
|
||||
bool m_connecting;
|
||||
std::unique_ptr<EQ::Timer> m_connect_timer;
|
||||
|
||||
|
||||
10
hc/world.cpp
10
hc/world.cpp
@ -8,7 +8,7 @@ WorldConnection::WorldConnection(const std::string &key, uint32_t dbid, const st
|
||||
m_key = key;
|
||||
m_dbid = dbid;
|
||||
|
||||
m_connection_manager.reset(new EQ::Net::DaybreakConnectionManager());
|
||||
m_connection_manager.reset(new EQ::Net::ReliableStreamConnectionManager());
|
||||
m_connection_manager->OnNewConnection(std::bind(&WorldConnection::OnNewConnection, this, std::placeholders::_1));
|
||||
m_connection_manager->OnConnectionStateChange(std::bind(&WorldConnection::OnStatusChangeActive, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
|
||||
m_connection_manager->OnPacketRecv(std::bind(&WorldConnection::OnPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
|
||||
@ -18,13 +18,13 @@ WorldConnection::WorldConnection(const std::string &key, uint32_t dbid, const st
|
||||
WorldConnection::~WorldConnection() {
|
||||
}
|
||||
|
||||
void WorldConnection::OnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection)
|
||||
void WorldConnection::OnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection)
|
||||
{
|
||||
m_connection = connection;
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Connecting to world...");
|
||||
}
|
||||
|
||||
void WorldConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void WorldConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusConnected) {
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "World connected.");
|
||||
@ -38,14 +38,14 @@ void WorldConnection::OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConn
|
||||
}
|
||||
}
|
||||
|
||||
void WorldConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
void WorldConnection::OnStatusChangeInactive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to)
|
||||
{
|
||||
if (to == EQ::Net::StatusDisconnected) {
|
||||
m_connection.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void WorldConnection::OnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p)
|
||||
void WorldConnection::OnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p)
|
||||
{
|
||||
auto opcode = p.GetUInt16(0);
|
||||
Log.OutF(Logs::General, Logs::Headless_Client, "Packet in:\n{0}", p.ToString());
|
||||
|
||||
14
hc/world.h
14
hc/world.h
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../common/net/daybreak_connection.h"
|
||||
#include "../common/net/reliable_stream_connection.h"
|
||||
#include "../common/event/timer.h"
|
||||
#include <map>
|
||||
|
||||
@ -10,17 +10,17 @@ public:
|
||||
WorldConnection(const std::string &key, uint32_t dbid, const std::string &host);
|
||||
~WorldConnection();
|
||||
private:
|
||||
void OnNewConnection(std::shared_ptr<EQ::Net::DaybreakConnection> connection);
|
||||
void OnStatusChangeActive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnStatusChangeInactive(std::shared_ptr<EQ::Net::DaybreakConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnPacketRecv(std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p);
|
||||
void OnNewConnection(std::shared_ptr<EQ::Net::ReliableStreamConnection> connection);
|
||||
void OnStatusChangeActive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnStatusChangeInactive(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, EQ::Net::DbProtocolStatus from, EQ::Net::DbProtocolStatus to);
|
||||
void OnPacketRecv(std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p);
|
||||
void Kill();
|
||||
void Start();
|
||||
|
||||
void SendClientAuth();
|
||||
|
||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_connection_manager;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> m_connection;
|
||||
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_connection_manager;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_connection;
|
||||
bool m_connecting;
|
||||
std::unique_ptr<EQ::Timer> m_connect_timer;
|
||||
|
||||
|
||||
@ -124,18 +124,18 @@ uint64 AccountManagement::CheckExternalLoginserverUserCredentials(LoginAccountCo
|
||||
bool running = true;
|
||||
uint32 ret = 0;
|
||||
|
||||
EQ::Net::DaybreakConnectionManager mgr;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> conn;
|
||||
EQ::Net::ReliableStreamConnectionManager mgr;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> conn;
|
||||
|
||||
mgr.OnNewConnection(
|
||||
[&](std::shared_ptr<EQ::Net::DaybreakConnection> connection) {
|
||||
[&](std::shared_ptr<EQ::Net::ReliableStreamConnection> connection) {
|
||||
conn = connection;
|
||||
}
|
||||
);
|
||||
|
||||
mgr.OnConnectionStateChange(
|
||||
[&](
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> conn,
|
||||
EQ::Net::DbProtocolStatus from,
|
||||
EQ::Net::DbProtocolStatus to
|
||||
) {
|
||||
@ -152,7 +152,7 @@ uint64 AccountManagement::CheckExternalLoginserverUserCredentials(LoginAccountCo
|
||||
);
|
||||
|
||||
mgr.OnPacketRecv(
|
||||
[&](std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p) {
|
||||
[&](std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p) {
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
case 0x0017: //OP_ChatMessage
|
||||
@ -250,18 +250,18 @@ uint64 AccountManagement::HealthCheckUserLogin()
|
||||
bool running = true;
|
||||
uint64 ret = 0;
|
||||
|
||||
EQ::Net::DaybreakConnectionManager mgr;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> c;
|
||||
EQ::Net::ReliableStreamConnectionManager mgr;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> c;
|
||||
|
||||
mgr.OnNewConnection(
|
||||
[&](std::shared_ptr<EQ::Net::DaybreakConnection> connection) {
|
||||
[&](std::shared_ptr<EQ::Net::ReliableStreamConnection> connection) {
|
||||
c = connection;
|
||||
}
|
||||
);
|
||||
|
||||
mgr.OnConnectionStateChange(
|
||||
[&](
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> conn,
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> conn,
|
||||
EQ::Net::DbProtocolStatus from,
|
||||
EQ::Net::DbProtocolStatus to
|
||||
) {
|
||||
@ -278,7 +278,7 @@ uint64 AccountManagement::HealthCheckUserLogin()
|
||||
);
|
||||
|
||||
mgr.OnPacketRecv(
|
||||
[&](std::shared_ptr<EQ::Net::DaybreakConnection> conn, const EQ::Net::Packet &p) {
|
||||
[&](std::shared_ptr<EQ::Net::ReliableStreamConnection> conn, const EQ::Net::Packet &p) {
|
||||
auto opcode = p.GetUInt16(0);
|
||||
switch (opcode) {
|
||||
case 0x0017: //OP_ChatMessage
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include "../common/random.h"
|
||||
#include "../common/eq_stream_intf.h"
|
||||
#include "../common/net/dns.h"
|
||||
#include "../common/net/daybreak_connection.h"
|
||||
#include "../common/net/reliable_stream_connection.h"
|
||||
#include "login_types.h"
|
||||
#include "../common/repositories/login_accounts_repository.h"
|
||||
#include <memory>
|
||||
@ -54,8 +54,8 @@ private:
|
||||
unsigned int m_selected_play_server_id;
|
||||
unsigned int m_play_sequence_id;
|
||||
std::string m_key;
|
||||
std::unique_ptr<EQ::Net::DaybreakConnectionManager> m_login_connection_manager;
|
||||
std::shared_ptr<EQ::Net::DaybreakConnection> m_login_connection;
|
||||
std::unique_ptr<EQ::Net::ReliableStreamConnectionManager> m_login_connection_manager;
|
||||
std::shared_ptr<EQ::Net::ReliableStreamConnection> m_login_connection;
|
||||
LoginBaseMessage m_login_base_message;
|
||||
std::string m_stored_username;
|
||||
std::string m_stored_password;
|
||||
|
||||
@ -31,7 +31,7 @@ public:
|
||||
inline void DefaultLoginServerName(const std::string &v) { m_default_loginserver_name = v; }
|
||||
inline std::string GetDefaultLoginServerName() const { return m_default_loginserver_name; }
|
||||
inline bool IsShowPlayerCountEnabled() const { return m_show_player_count; }
|
||||
inline void SetShowPlayerCount(bool show_player_count) { show_player_count = show_player_count; }
|
||||
inline void SetShowPlayerCount(bool show_player_count) { m_show_player_count = show_player_count; }
|
||||
inline bool IsWorldDevTestServersListBottom() const { return m_world_dev_list_bottom; }
|
||||
inline void SetWorldDevTestServersListBottom(bool list_bottom) { m_world_dev_list_bottom = list_bottom; }
|
||||
inline bool IsWorldSpecialCharacterStartListBottom() const { return m_special_char_list_bottom; }
|
||||
|
||||
@ -155,7 +155,11 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
|
||||
auto *res = (UsertoWorldResponseLegacy *) packet.Data();
|
||||
|
||||
LogDebug("Trying to find client with user id of [{}]", res->lsaccountid);
|
||||
Client *c = server.client_manager->GetClient(res->lsaccountid, "eqemu");
|
||||
std::string db_loginserver = "local";
|
||||
if (std::getenv("LSPX")) {
|
||||
db_loginserver = "eqemu";
|
||||
}
|
||||
Client *c = server.client_manager->GetClient(res->lsaccountid, db_loginserver);
|
||||
if (c) {
|
||||
LogDebug(
|
||||
"Found client with user id of [{}] and account name of [{}]",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eqemu-server",
|
||||
"version": "23.8.1",
|
||||
"version": "23.9.1",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EQEmu/Server.git"
|
||||
|
||||
@ -469,11 +469,11 @@ static void ProcessCommandIgnore(Client *c, std::string Ignoree) {
|
||||
Clientlist::Clientlist(int ChatPort) {
|
||||
EQStreamManagerInterfaceOptions chat_opts(ChatPort, false, false);
|
||||
chat_opts.opcode_size = 1;
|
||||
chat_opts.daybreak_options.stale_connection_ms = 600000;
|
||||
chat_opts.daybreak_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
chat_opts.daybreak_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
chat_opts.daybreak_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
chat_opts.daybreak_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
chat_opts.reliable_stream_options.stale_connection_ms = 600000;
|
||||
chat_opts.reliable_stream_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
chat_opts.reliable_stream_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
chat_opts.reliable_stream_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
chat_opts.reliable_stream_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
|
||||
chatsf = new EQ::Net::EQStreamManager(chat_opts);
|
||||
|
||||
|
||||
@ -6,13 +6,10 @@ toolchain go1.23.5
|
||||
|
||||
require (
|
||||
github.com/google/go-github/v41 v41.0.0
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||
golang.org/x/oauth2 v0.27.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.3.2 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
)
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg=
|
||||
github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
@ -14,10 +14,9 @@ golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@ -27,5 +26,4 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
|
||||
@ -333,11 +333,11 @@ int main(int argc, char **argv)
|
||||
WorldBoot::CheckForPossibleConfigurationIssues();
|
||||
|
||||
EQStreamManagerInterfaceOptions opts(9000, false, false);
|
||||
opts.daybreak_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
opts.daybreak_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
opts.daybreak_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
opts.daybreak_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
opts.daybreak_options.outgoing_data_rate = RuleR(Network, ClientDataRate);
|
||||
opts.reliable_stream_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
opts.reliable_stream_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
opts.reliable_stream_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
opts.reliable_stream_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
opts.reliable_stream_options.outgoing_data_rate = RuleR(Network, ClientDataRate);
|
||||
|
||||
EQ::Net::EQStreamManager eqsm(opts);
|
||||
|
||||
|
||||
@ -901,9 +901,13 @@ bool WorldDatabase::GetCharSelInventory(
|
||||
inst->SetCustomDataString(e.custom_data);
|
||||
}
|
||||
|
||||
inst->SetOrnamentIcon(e.ornament_icon);
|
||||
inst->SetOrnamentationIDFile(e.ornament_idfile);
|
||||
inst->SetOrnamentHeroModel(e.ornament_hero_model);
|
||||
if (e.ornament_icon != 0 || e.ornament_idfile != 0 || e.ornament_hero_model != 0) {
|
||||
inst->SetOrnamentIcon(e.ornament_icon);
|
||||
inst->SetOrnamentationIDFile(e.ornament_idfile);
|
||||
inst->SetOrnamentHeroModel(e.ornament_hero_model);
|
||||
} else if (item->HerosForgeModel > 0) {
|
||||
inst->SetOrnamentHeroModel(item->HerosForgeModel);
|
||||
}
|
||||
|
||||
inv->PutItem(e.slot_id, *inst);
|
||||
|
||||
|
||||
@ -502,7 +502,7 @@ if (EQEMU_BUILD_STATIC AND PERL_LIBRARY)
|
||||
endif()
|
||||
|
||||
# link zone against common libraries
|
||||
target_link_libraries(zone PRIVATE ${ZONE_LIBS} lua_zone perl_zone gm_commands_zone)
|
||||
target_link_libraries(zone PRIVATE lua_zone perl_zone gm_commands_zone ${ZONE_LIBS})
|
||||
|
||||
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
|
||||
@ -82,7 +82,7 @@ Json::Value ApiGetPacketStatistics(EQ::Net::WebsocketServerConnection *connectio
|
||||
auto connection = client->Connection();
|
||||
auto opts = connection->GetManager()->GetOptions();
|
||||
auto eqs_stats = connection->GetStats();
|
||||
auto &stats = eqs_stats.DaybreakStats;
|
||||
auto &stats = eqs_stats.ReliableStreamStats;
|
||||
auto now = EQ::Net::Clock::now();
|
||||
auto sec_since_stats_reset = std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
now - stats.created
|
||||
|
||||
@ -401,8 +401,8 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
||||
*/
|
||||
|
||||
/* Order according to current (SoF+?) dev quotes:
|
||||
* https://forums.daybreakgames.com/eq/index.php?threads/test-update-06-10-15.223510/page-2#post-3261772
|
||||
* https://forums.daybreakgames.com/eq/index.php?threads/test-update-06-10-15.223510/page-2#post-3268227
|
||||
* https://web.archive.org/web/20250816014133/https://forums.everquest.com/index.php?threads/test-update-06-10-15.223510/page-2#post-3261772
|
||||
* https://web.archive.org/web/20250816014133/https://forums.everquest.com/index.php?threads/test-update-06-10-15.223510/page-2#post-3268227
|
||||
* Riposte 50, hDEX, must have weapon/fists, doesn't work on archery/throwing
|
||||
* Block 25, hDEX, works on archery/throwing, behind block done here if back to attacker base1 is chance
|
||||
* Parry 45, hDEX, doesn't work on throwing/archery, must be facing target
|
||||
@ -461,7 +461,7 @@ bool Mob::AvoidDamage(Mob *other, DamageHitInfo &hit)
|
||||
}
|
||||
|
||||
/* Heroic Strikethrough Implementation per Dev Quotes (2018):
|
||||
* https://forums.daybreakgames.com/eq/index.php?threads/illusions-benefit-neza-10-dodge.246757/#post-3622670
|
||||
* https://web.archive.org/web/20250816014810/https://forums.everquest.com/index.php?threads/illusions-benefit-neza-10-dodge.246757/#post-3622670
|
||||
* Step1 = HeroicStrikethrough(NPC)
|
||||
* Step2 = HeroicAgility / 25
|
||||
* Step3 = MIN( Step1, Step2 )
|
||||
@ -3039,6 +3039,25 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
||||
DispatchZoneControllerEvent(EVENT_DEATH_ZONE, owner_or_self, export_string, 0, &args);
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_DEATH_ZONE)) {
|
||||
const auto& export_string = fmt::format(
|
||||
"{} {} {} {} {} {} {} {} {}",
|
||||
killer_mob ? killer_mob->GetID() : 0,
|
||||
damage,
|
||||
spell,
|
||||
static_cast<int>(attack_skill),
|
||||
entity_id,
|
||||
m_combat_record.GetStartTime(),
|
||||
m_combat_record.GetEndTime(),
|
||||
m_combat_record.GetDamageReceived(),
|
||||
m_combat_record.GetHealingReceived()
|
||||
);
|
||||
|
||||
std::vector<std::any> args = { corpse, this, owner_or_self };
|
||||
|
||||
parse->EventZone(EVENT_DEATH_ZONE, zone, export_string, 0, &args);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3395,7 +3414,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
|
||||
uint8 Mob::GetWeaponDamageBonus(const EQ::ItemData *weapon, bool offhand)
|
||||
{
|
||||
// dev quote with old and new formulas
|
||||
// https://forums.daybreakgames.com/eq/index.php?threads/test-update-09-17-15.226618/page-5#post-3326194
|
||||
// https://web.archive.org/web/20250816013618/https://forums.everquest.com/index.php?threads/test-update-09-17-15.226618/page-5#post-3326194
|
||||
//
|
||||
// We assume that the level check is done before calling this function and sinister strikes is checked before
|
||||
// calling for offhand DB
|
||||
@ -4094,11 +4113,11 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
if (IsPet()) {
|
||||
Mob *owner = GetOwner();
|
||||
if (owner && owner->IsClient()) {
|
||||
if (GetPetOrder() == SPO_Sit) {
|
||||
if (GetPetOrder() == PetOrder::Sit) {
|
||||
SetPetOrder(GetPreviousPetOrder());
|
||||
}
|
||||
// fix GUI sit button to be unpressed and stop sitting regen
|
||||
owner->CastToClient()->SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
owner->CastToClient()->SetPetCommandState(PetButton::Sit, PetButtonState::Off);
|
||||
SetAppearance(eaStanding);
|
||||
}
|
||||
}
|
||||
@ -4128,12 +4147,12 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
if (IsClient() && !pet->IsPetStop()) {
|
||||
// if pet was sitting his new mode is previous setting of
|
||||
// follow or guard after the battle (live verified)
|
||||
if (pet->GetPetOrder() == SPO_Sit) {
|
||||
if (pet->GetPetOrder() == PetOrder::Sit) {
|
||||
pet->SetPetOrder(pet->GetPreviousPetOrder());
|
||||
}
|
||||
|
||||
// fix GUI sit button to be unpressed and stop sitting regen
|
||||
CastToClient()->SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
CastToClient()->SetPetCommandState(PetButton::Sit, PetButtonState::Off);
|
||||
pet->SetAppearance(eaStanding);
|
||||
}
|
||||
|
||||
|
||||
@ -1549,7 +1549,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
break;
|
||||
|
||||
case SE_AddPetCommand:
|
||||
if (base_value && limit_value < PET_MAXCOMMANDS)
|
||||
if (base_value && limit_value < PetCommand::Max)
|
||||
newbon->PetCommands[limit_value] = true;
|
||||
break;
|
||||
|
||||
@ -1557,7 +1557,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
if (newbon->FeignedMinionChance < base_value) {
|
||||
newbon->FeignedMinionChance = base_value;
|
||||
}
|
||||
newbon->PetCommands[PET_FEIGN] = true;
|
||||
newbon->PetCommands[PetCommand::Feign] = true;
|
||||
break;
|
||||
|
||||
case SE_AdditionalAura:
|
||||
|
||||
24
zone/bot.cpp
24
zone/bot.cpp
@ -99,7 +99,7 @@ Bot::Bot(NPCType *npcTypeData, Client* botOwner) : NPC(npcTypeData, nullptr, glm
|
||||
SetPullingFlag(false);
|
||||
SetReturningFlag(false);
|
||||
SetIsUsingItemClick(false);
|
||||
m_previous_pet_order = SPO_Guard;
|
||||
m_previous_pet_order = PetOrder::Guard;
|
||||
|
||||
rest_timer.Disable();
|
||||
m_ping_timer.Disable();
|
||||
@ -232,7 +232,7 @@ Bot::Bot(
|
||||
SetPullingFlag(false);
|
||||
SetReturningFlag(false);
|
||||
SetIsUsingItemClick(false);
|
||||
m_previous_pet_order = SPO_Guard;
|
||||
m_previous_pet_order = PetOrder::Guard;
|
||||
|
||||
rest_timer.Disable();
|
||||
m_ping_timer.Disable();
|
||||
@ -2313,7 +2313,7 @@ void Bot::AI_Process()
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
|
||||
@ -2569,7 +2569,7 @@ void Bot::DoOutOfCombatChecks(Client* bot_owner, Mob* follow_mob, float leash_di
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
}
|
||||
@ -3198,7 +3198,7 @@ bool Bot::IsValidTarget(
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
}
|
||||
@ -3233,7 +3233,7 @@ Mob* Bot::GetBotTarget(Client* bot_owner)
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
}
|
||||
@ -3269,7 +3269,7 @@ bool Bot::ReturningFlagChecks(Client* bot_owner, Mob* leash_owner, float fm_dist
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
|
||||
if (HasControllablePet(BotAnimEmpathy::BackOff)) {
|
||||
@ -3313,7 +3313,7 @@ bool Bot::PullingFlagChecks(Client* bot_owner) {
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
|
||||
@ -3494,7 +3494,7 @@ Client* Bot::SetLeashOwner(Client* bot_owner, Group* bot_group, Raid* raid, uint
|
||||
|
||||
void Bot::SetOwnerTarget(Client* bot_owner) {
|
||||
if (GetPet() && (PULLING_BOT || RETURNING_BOT)) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
}
|
||||
|
||||
SetAttackFlag(false);
|
||||
@ -3533,7 +3533,7 @@ void Bot::BotPullerProcess(Client* bot_owner, Raid* raid) {
|
||||
bot_owner->SetBotPulling(false);
|
||||
|
||||
if (GetPet()) {
|
||||
GetPet()->SetPetOrder(SPO_Follow);
|
||||
GetPet()->SetPetOrder(PetOrder::Follow);
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(true);
|
||||
}
|
||||
|
||||
@ -3562,7 +3562,7 @@ void Bot::BotPullerProcess(Client* bot_owner, Raid* raid) {
|
||||
if (HasControllablePet(BotAnimEmpathy::Guard)) {
|
||||
m_previous_pet_order = GetPet()->GetPetOrder();
|
||||
GetPet()->CastToNPC()->SaveGuardSpot(GetPosition());
|
||||
GetPet()->SetPetOrder(SPO_Guard);
|
||||
GetPet()->SetPetOrder(PetOrder::Guard);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13456,6 +13456,6 @@ bool Bot::HasControllablePet(uint8 ranks_required) {
|
||||
}
|
||||
|
||||
return GetClass() != Class::Enchanter ||
|
||||
GetPet()->GetPetType() != petAnimation ||
|
||||
GetPet()->GetPetType() != PetType::Animation ||
|
||||
GetAA(aaAnimationEmpathy) >= ranks_required;
|
||||
}
|
||||
|
||||
@ -4780,9 +4780,21 @@ bool Client::KeyRingClear()
|
||||
);
|
||||
}
|
||||
|
||||
void Client::KeyRingList()
|
||||
void Client::KeyRingList(Client* c)
|
||||
{
|
||||
Message(Chat::LightBlue, "Keys on Keyring:");
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string message = "Keys on Keyring:";
|
||||
if (c != this) {
|
||||
message = fmt::format(
|
||||
"Keys on Keyring for {}:",
|
||||
GetCleanName()
|
||||
);
|
||||
}
|
||||
|
||||
c->Message(Chat::LightBlue, message.c_str());
|
||||
|
||||
const EQ::ItemData *item = nullptr;
|
||||
|
||||
@ -4795,7 +4807,7 @@ void Client::KeyRingList()
|
||||
item->Name
|
||||
);
|
||||
|
||||
Message(Chat::LightBlue, item_string.c_str());
|
||||
c->Message(Chat::LightBlue, item_string.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6403,17 +6415,17 @@ void Client::SuspendMinion(int value)
|
||||
// TODO: These pet command states need to be synced ...
|
||||
// Will just fix them for now
|
||||
if (m_ClientVersionBit & EQ::versions::maskUFAndLater) {
|
||||
SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
SetPetCommandState(PET_BUTTON_FOLLOW, 1);
|
||||
SetPetCommandState(PET_BUTTON_GUARD, 0);
|
||||
SetPetCommandState(PetButton::Sit, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Stop, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Regroup, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Follow, PetButtonState::On);
|
||||
SetPetCommandState(PetButton::Guard, PetButtonState::Off);
|
||||
// Taunt saved on client side for logging on with pet
|
||||
// In our db for when we zone.
|
||||
SetPetCommandState(PET_BUTTON_HOLD, 0);
|
||||
SetPetCommandState(PET_BUTTON_GHOLD, 0);
|
||||
SetPetCommandState(PET_BUTTON_FOCUS, 0);
|
||||
SetPetCommandState(PET_BUTTON_SPELLHOLD, 0);
|
||||
SetPetCommandState(PetButton::Hold, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::GreaterHold, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::Focus, PetButtonState::Off);
|
||||
SetPetCommandState(PetButton::SpellHold, PetButtonState::Off);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -6894,9 +6906,9 @@ void Client::CheckLDoNHail(NPC* n)
|
||||
|
||||
auto pet = GetPet();
|
||||
if (pet) {
|
||||
if (pet->GetPetType() == petCharmed) {
|
||||
if (pet->GetPetType() == PetType::Charmed) {
|
||||
pet->BuffFadeByEffect(SE_Charm);
|
||||
} else if (pet->GetPetType() == petNPCFollow) {
|
||||
} else if (pet->GetPetType() == PetType::Follow) {
|
||||
pet->SetOwnerID(0);
|
||||
} else {
|
||||
pet->Depop();
|
||||
@ -9438,12 +9450,15 @@ void Client::ProcessAggroMeter()
|
||||
}
|
||||
}
|
||||
|
||||
void Client::SetPetCommandState(int button, int state)
|
||||
void Client::SetPetCommandState(uint8 button, uint8 state)
|
||||
{
|
||||
auto app = new EQApplicationPacket(OP_PetCommandState, sizeof(PetCommandState_Struct));
|
||||
auto pcs = (PetCommandState_Struct *)app->pBuffer;
|
||||
pcs->button_id = button;
|
||||
pcs->state = state;
|
||||
|
||||
auto s = (PetCommandState_Struct*) app->pBuffer;
|
||||
|
||||
s->button_id = button;
|
||||
s->state = state;
|
||||
|
||||
FastQueuePacket(&app);
|
||||
}
|
||||
|
||||
|
||||
@ -326,12 +326,13 @@ public:
|
||||
void TraderStartTrader(const EQApplicationPacket *app);
|
||||
// void TraderPriceUpdate(const EQApplicationPacket *app);
|
||||
uint8 WithCustomer(uint16 NewCustomer);
|
||||
std::vector<uint32> GetKeyRing() { return keyring; }
|
||||
void KeyRingLoad();
|
||||
bool KeyRingAdd(uint32 item_id);
|
||||
bool KeyRingCheck(uint32 item_id);
|
||||
bool KeyRingClear();
|
||||
bool KeyRingRemove(uint32 item_id);
|
||||
void KeyRingList();
|
||||
void KeyRingList(Client* c = nullptr);
|
||||
bool IsNameChangeAllowed();
|
||||
void InvokeChangeNameWindow(bool immediate = true);
|
||||
bool ClearNameChange();
|
||||
@ -523,7 +524,7 @@ public:
|
||||
inline const InspectMessage_Struct& GetInspectMessage() const { return m_inspect_message; }
|
||||
void ReloadExpansionProfileSetting();
|
||||
|
||||
void SetPetCommandState(int button, int state);
|
||||
void SetPetCommandState(uint8 button, uint8 state);
|
||||
|
||||
bool AutoAttackEnabled() const { return auto_attack; }
|
||||
bool AutoFireEnabled() const { return auto_fire; }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../common/spdat.h"
|
||||
#include "../common/emu_constants.h"
|
||||
|
||||
#include <cereal/cereal.hpp>
|
||||
|
||||
@ -45,55 +46,6 @@ namespace Archetype {
|
||||
//Maximum distance from a zone point if zone was specified
|
||||
#define ZONEPOINT_ZONE_RANGE 40000.0f
|
||||
|
||||
// Defines based on the RoF2 Client
|
||||
#define PET_HEALTHREPORT 0 // 0x00 - /pet health or Pet Window
|
||||
#define PET_LEADER 1 // 0x01 - /pet leader or Pet Window
|
||||
#define PET_ATTACK 2 // 0x02 - /pet attack or Pet Window
|
||||
#define PET_QATTACK 3 // 0x03 - /pet qattack or Pet Window
|
||||
#define PET_FOLLOWME 4 // 0x04 - /pet follow or Pet Window
|
||||
#define PET_GUARDHERE 5 // 0x05 - /pet guard or Pet Window
|
||||
#define PET_SIT 6 // 0x06 - /pet sit or Pet Window
|
||||
#define PET_SITDOWN 7 // 0x07 - /pet sit on
|
||||
#define PET_STANDUP 8 // 0x08 - /pet sit off
|
||||
#define PET_STOP 9 // 0x09 - /pet stop or Pet Window - Not implemented
|
||||
#define PET_STOP_ON 10 // 0x0a - /pet stop on - Not implemented
|
||||
#define PET_STOP_OFF 11 // 0x0b - /pet stop off - Not implemented
|
||||
#define PET_TAUNT 12 // 0x0c - /pet taunt or Pet Window
|
||||
#define PET_TAUNT_ON 13 // 0x0d - /pet taunt on
|
||||
#define PET_TAUNT_OFF 14 // 0x0e - /pet taunt off
|
||||
#define PET_HOLD 15 // 0x0f - /pet hold or Pet Window, won't add to hate list unless attacking
|
||||
#define PET_HOLD_ON 16 // 0x10 - /pet hold on
|
||||
#define PET_HOLD_OFF 17 // 0x11 - /pet hold off
|
||||
#define PET_GHOLD 18 // 0x12 - /pet ghold, will never add to hate list unless told to
|
||||
#define PET_GHOLD_ON 19 // 0x13 - /pet ghold on
|
||||
#define PET_GHOLD_OFF 20 // 0x14 - /pet ghold off
|
||||
#define PET_SPELLHOLD 21 // 0x15 - /pet no cast or /pet spellhold or Pet Window
|
||||
#define PET_SPELLHOLD_ON 22 // 0x16 - /pet spellhold on
|
||||
#define PET_SPELLHOLD_OFF 23 // 0x17 - /pet spellhold off
|
||||
#define PET_FOCUS 24 // 0x18 - /pet focus or Pet Window
|
||||
#define PET_FOCUS_ON 25 // 0x19 - /pet focus on
|
||||
#define PET_FOCUS_OFF 26 // 0x1a - /pet focus off
|
||||
#define PET_FEIGN 27 // 0x1b - /pet feign
|
||||
#define PET_BACKOFF 28 // 0x1c - /pet back off
|
||||
#define PET_GETLOST 29 // 0x1d - /pet get lost
|
||||
#define PET_GUARDME 30 // 0x1e - Same as /pet follow, but different message in older clients - define not from client /pet target in modern clients but doesn't send packet
|
||||
#define PET_REGROUP 31 // 0x1f - /pet regroup, acts like classic hold. Stops attack and moves back to guard/you but doesn't clear hate list
|
||||
#define PET_REGROUP_ON 32 // 0x20 - /pet regroup on, turns on regroup
|
||||
#define PET_REGROUP_OFF 33 // 0x21 - /pet regroup off, turns off regroup
|
||||
#define PET_MAXCOMMANDS PET_REGROUP_OFF + 1
|
||||
|
||||
// can change the state of these buttons with a packet
|
||||
#define PET_BUTTON_SIT 0
|
||||
#define PET_BUTTON_STOP 1
|
||||
#define PET_BUTTON_REGROUP 2
|
||||
#define PET_BUTTON_FOLLOW 3
|
||||
#define PET_BUTTON_GUARD 4
|
||||
#define PET_BUTTON_TAUNT 5
|
||||
#define PET_BUTTON_HOLD 6
|
||||
#define PET_BUTTON_GHOLD 7
|
||||
#define PET_BUTTON_FOCUS 8
|
||||
#define PET_BUTTON_SPELLHOLD 9
|
||||
|
||||
#define AURA_HARDCAP 2
|
||||
#define WEAPON_STANCE_TYPE_MAX 2
|
||||
|
||||
@ -617,7 +569,7 @@ struct StatBonuses {
|
||||
uint8 TradeSkillMastery; // Allow number of tradeskills to exceed 200 skill.
|
||||
int16 NoBreakAESneak; // Percent value
|
||||
int16 FeignedCastOnChance; // Percent Value
|
||||
bool PetCommands[PET_MAXCOMMANDS]; // SPA 267
|
||||
bool PetCommands[PetCommand::Max]; // SPA 267
|
||||
int FeignedMinionChance; // SPA 281 base1 = chance, just like normal FD
|
||||
int GrantForage; // affects max skill of forage as well as granting non-forage classes forage
|
||||
int aura_slots;
|
||||
@ -781,16 +733,6 @@ enum {
|
||||
GridRandomPath
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
petFamiliar, //only listens to /pet get lost
|
||||
petAnimation, //does not listen to any commands
|
||||
petOther,
|
||||
petCharmed,
|
||||
petNPCFollow,
|
||||
petTargetLock, //remain active as long something is on the hatelist. Don't listen to any commands
|
||||
petNone = 0xFF // not a pet
|
||||
} PetType;
|
||||
|
||||
typedef enum {
|
||||
SingleTarget, // causes effect to spell_target
|
||||
AETarget, // causes effect in aerange of target + target
|
||||
|
||||
@ -1586,6 +1586,21 @@ void Corpse::LootCorpseItem(Client *c, const EQApplicationPacket *app)
|
||||
}
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_LOOT_ZONE)) {
|
||||
const auto &export_string = fmt::format(
|
||||
"{} {} {} {}",
|
||||
inst->GetItem()->ID,
|
||||
inst->GetCharges(),
|
||||
EntityList::RemoveNumbers(corpse_name),
|
||||
GetID()
|
||||
);
|
||||
|
||||
std::vector<std::any> args = {inst, this, c};
|
||||
if (parse->EventZone(EVENT_LOOT_ZONE, zone, export_string, 0, &args) != 0) {
|
||||
prevent_loot = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (inst && PlayerEventLogs::Instance()->IsEventEnabled(PlayerEvent::LOOT_ITEM) && !IsPlayerCorpse()) {
|
||||
auto e = PlayerEvent::LootItemEvent{
|
||||
.item_id = inst->GetItem()->ID,
|
||||
|
||||
@ -207,6 +207,7 @@ const char* QuestEventSubroutines[_LargestEventID] = {
|
||||
"EVENT_AA_LOSS",
|
||||
"EVENT_SPELL_BLOCKED",
|
||||
"EVENT_READ_ITEM",
|
||||
"EVENT_PET_COMMAND",
|
||||
|
||||
// Add new events before these or Lua crashes
|
||||
"EVENT_SPELL_EFFECT_BOT",
|
||||
@ -222,6 +223,8 @@ PerlembParser::PerlembParser() : perl(nullptr)
|
||||
global_bot_quest_status_ = questUnloaded;
|
||||
merc_quest_status_ = questUnloaded;
|
||||
global_merc_quest_status_ = questUnloaded;
|
||||
zone_quest_status_ = questUnloaded;
|
||||
global_zone_quest_status_ = questUnloaded;
|
||||
}
|
||||
|
||||
PerlembParser::~PerlembParser()
|
||||
@ -265,6 +268,8 @@ void PerlembParser::ReloadQuests()
|
||||
global_bot_quest_status_ = questUnloaded;
|
||||
merc_quest_status_ = questUnloaded;
|
||||
global_merc_quest_status_ = questUnloaded;
|
||||
zone_quest_status_ = questUnloaded;
|
||||
global_zone_quest_status_ = questUnloaded;
|
||||
|
||||
item_quest_status_.clear();
|
||||
spell_quest_status_.clear();
|
||||
@ -278,6 +283,7 @@ int PerlembParser::EventCommon(
|
||||
EQ::ItemInstance* inst,
|
||||
const SPDat_Spell_Struct* spell,
|
||||
Mob* mob,
|
||||
Zone* zone,
|
||||
uint32 extra_data,
|
||||
bool is_global,
|
||||
std::vector<std::any>* extra_pointers
|
||||
@ -287,52 +293,22 @@ int PerlembParser::EventCommon(
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool is_player_quest = false;
|
||||
bool is_global_player_quest = false;
|
||||
bool is_global_npc_quest = false;
|
||||
bool is_bot_quest = false;
|
||||
bool is_global_bot_quest = false;
|
||||
bool is_merc_quest = false;
|
||||
bool is_global_merc_quest = false;
|
||||
bool is_item_quest = false;
|
||||
bool is_spell_quest = false;
|
||||
|
||||
std::string package_name;
|
||||
|
||||
GetQuestTypes(
|
||||
is_player_quest,
|
||||
is_global_player_quest,
|
||||
is_bot_quest,
|
||||
is_global_bot_quest,
|
||||
is_merc_quest,
|
||||
is_global_merc_quest,
|
||||
is_global_npc_quest,
|
||||
is_item_quest,
|
||||
is_spell_quest,
|
||||
QuestType quest_type = GetQuestTypes(
|
||||
event_id,
|
||||
npc_mob,
|
||||
inst,
|
||||
mob,
|
||||
zone,
|
||||
is_global
|
||||
);
|
||||
|
||||
GetQuestPackageName(
|
||||
is_player_quest,
|
||||
is_global_player_quest,
|
||||
is_bot_quest,
|
||||
is_global_bot_quest,
|
||||
is_merc_quest,
|
||||
is_global_merc_quest,
|
||||
is_global_npc_quest,
|
||||
is_item_quest,
|
||||
is_spell_quest,
|
||||
package_name,
|
||||
std::string package_name = GetQuestPackageName(
|
||||
quest_type,
|
||||
event_id,
|
||||
object_id,
|
||||
data,
|
||||
npc_mob,
|
||||
inst,
|
||||
is_global
|
||||
inst
|
||||
);
|
||||
|
||||
const std::string& sub_name = QuestEventSubroutines[event_id];
|
||||
@ -348,15 +324,7 @@ int PerlembParser::EventCommon(
|
||||
/* Check for QGlobal export event enable */
|
||||
if (parse->perl_event_export_settings[event_id].qglobals) {
|
||||
ExportQGlobals(
|
||||
is_player_quest,
|
||||
is_global_player_quest,
|
||||
is_bot_quest,
|
||||
is_global_bot_quest,
|
||||
is_merc_quest,
|
||||
is_global_merc_quest,
|
||||
is_global_npc_quest,
|
||||
is_item_quest,
|
||||
is_spell_quest,
|
||||
quest_type,
|
||||
package_name,
|
||||
npc_mob,
|
||||
mob,
|
||||
@ -367,15 +335,7 @@ int PerlembParser::EventCommon(
|
||||
/* Check for Mob export event enable */
|
||||
if (parse->perl_event_export_settings[event_id].mob) {
|
||||
ExportMobVariables(
|
||||
is_player_quest,
|
||||
is_global_player_quest,
|
||||
is_bot_quest,
|
||||
is_global_bot_quest,
|
||||
is_merc_quest,
|
||||
is_global_merc_quest,
|
||||
is_global_npc_quest,
|
||||
is_item_quest,
|
||||
is_spell_quest,
|
||||
quest_type,
|
||||
package_name,
|
||||
mob,
|
||||
npc_mob
|
||||
@ -397,19 +357,24 @@ int PerlembParser::EventCommon(
|
||||
ExportEventVariables(package_name, event_id, object_id, data, npc_mob, inst, mob, extra_data, extra_pointers);
|
||||
}
|
||||
|
||||
if (is_player_quest || is_global_player_quest) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, nullptr);
|
||||
} else if (is_bot_quest || is_global_bot_quest || is_merc_quest || is_global_merc_quest) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, nullptr);
|
||||
} else if (is_item_quest) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, inst, nullptr);
|
||||
} else if (is_spell_quest) {
|
||||
if (quest_type == QuestType::Player || quest_type == QuestType::PlayerGlobal) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, nullptr, nullptr);
|
||||
} else if (
|
||||
quest_type == QuestType::Bot ||
|
||||
quest_type == QuestType::BotGlobal ||
|
||||
quest_type == QuestType::Merc ||
|
||||
quest_type == QuestType::MercGlobal
|
||||
) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, nullptr, nullptr);
|
||||
} else if (quest_type == QuestType::Item || quest_type == QuestType::ItemGlobal) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, inst, nullptr, nullptr);
|
||||
} else if (quest_type == QuestType::Spell || quest_type == QuestType::SpellGlobal) {
|
||||
if (mob) {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, spell);
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, mob, mob, nullptr, spell, nullptr);
|
||||
} else {
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, spell);
|
||||
return SendCommands(package_name.c_str(), QuestEventSubroutines[event_id], 0, npc_mob, mob, nullptr, spell, nullptr);
|
||||
}
|
||||
} else {
|
||||
} else if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
|
||||
return SendCommands(
|
||||
package_name.c_str(),
|
||||
QuestEventSubroutines[event_id],
|
||||
@ -417,8 +382,20 @@ int PerlembParser::EventCommon(
|
||||
npc_mob,
|
||||
mob,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr
|
||||
);
|
||||
} else if (quest_type == QuestType::Zone || quest_type == QuestType::ZoneGlobal) {
|
||||
return SendCommands(
|
||||
package_name.c_str(),
|
||||
QuestEventSubroutines[event_id],
|
||||
0,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
zone
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -439,6 +416,7 @@ int PerlembParser::EventNPC(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -462,6 +440,7 @@ int PerlembParser::EventGlobalNPC(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
true,
|
||||
extra_pointers
|
||||
@ -484,6 +463,7 @@ int PerlembParser::EventPlayer(
|
||||
nullptr,
|
||||
nullptr,
|
||||
client,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -506,6 +486,7 @@ int PerlembParser::EventGlobalPlayer(
|
||||
nullptr,
|
||||
nullptr,
|
||||
client,
|
||||
nullptr,
|
||||
extra_data,
|
||||
true,
|
||||
extra_pointers
|
||||
@ -534,6 +515,7 @@ int PerlembParser::EventItem(
|
||||
inst,
|
||||
nullptr,
|
||||
client,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -558,6 +540,7 @@ int PerlembParser::EventSpell(
|
||||
nullptr,
|
||||
&spells[spell_id],
|
||||
client,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -1006,7 +989,8 @@ int PerlembParser::SendCommands(
|
||||
Mob* other,
|
||||
Mob* mob,
|
||||
EQ::ItemInstance* inst,
|
||||
const SPDat_Spell_Struct* spell
|
||||
const SPDat_Spell_Struct* spell,
|
||||
Zone* zone
|
||||
)
|
||||
{
|
||||
if (!perl) {
|
||||
@ -1014,12 +998,22 @@ int PerlembParser::SendCommands(
|
||||
}
|
||||
|
||||
int ret_value = 0;
|
||||
RunningQuest q;
|
||||
|
||||
q.owner = other;
|
||||
q.questitem = inst;
|
||||
q.questspell = spell;
|
||||
|
||||
if (mob && mob->IsClient()) {
|
||||
quest_manager.StartQuest(other, mob->CastToClient(), inst, spell);
|
||||
} else {
|
||||
quest_manager.StartQuest(other);
|
||||
q.initiator = mob->CastToClient();
|
||||
}
|
||||
|
||||
if (zone) {
|
||||
q.zone = zone;
|
||||
}
|
||||
|
||||
quest_manager.StartQuest(q);
|
||||
|
||||
try {
|
||||
perl->eval(fmt::format("package {};", prefix).c_str());
|
||||
|
||||
@ -1033,7 +1027,8 @@ int PerlembParser::SendCommands(
|
||||
"merc",
|
||||
"npc",
|
||||
"questitem",
|
||||
"spell"
|
||||
"spell",
|
||||
"zone"
|
||||
};
|
||||
|
||||
for (const auto& suffix : suffixes) {
|
||||
@ -1058,21 +1053,23 @@ int PerlembParser::SendCommands(
|
||||
sv_setsv(client, _empty_sv);
|
||||
}
|
||||
|
||||
if (other->IsBot()) {
|
||||
Bot* b = quest_manager.GetBot();
|
||||
buf = fmt::format("{}::bot", prefix);
|
||||
SV* bot = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(bot, "Bot", b);
|
||||
} else if (other->IsMerc()) {
|
||||
Merc* m = quest_manager.GetMerc();
|
||||
buf = fmt::format("{}::merc", prefix);
|
||||
SV* merc = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(merc, "Merc", m);
|
||||
} else if (other->IsNPC()) {
|
||||
NPC* n = quest_manager.GetNPC();
|
||||
buf = fmt::format("{}::npc", prefix);
|
||||
SV* npc = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(npc, "NPC", n);
|
||||
if (other) {
|
||||
if (other->IsBot()) {
|
||||
Bot* b = quest_manager.GetBot();
|
||||
buf = fmt::format("{}::bot", prefix);
|
||||
SV* bot = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(bot, "Bot", b);
|
||||
} else if (other->IsMerc()) {
|
||||
Merc* m = quest_manager.GetMerc();
|
||||
buf = fmt::format("{}::merc", prefix);
|
||||
SV* merc = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(merc, "Merc", m);
|
||||
} else if (other->IsNPC()) {
|
||||
NPC* n = quest_manager.GetNPC();
|
||||
buf = fmt::format("{}::npc", prefix);
|
||||
SV* npc = get_sv(buf.c_str(), true);
|
||||
sv_setref_pv(npc, "NPC", n);
|
||||
}
|
||||
}
|
||||
|
||||
//only export QuestItem if it's an inst quest
|
||||
@ -1110,7 +1107,8 @@ int PerlembParser::SendCommands(
|
||||
"merc",
|
||||
"npc",
|
||||
"questitem",
|
||||
"spell"
|
||||
"spell",
|
||||
"zone"
|
||||
};
|
||||
|
||||
for (const auto& suffix : suffixes) {
|
||||
@ -1192,20 +1190,12 @@ void PerlembParser::MapFunctions()
|
||||
#endif // EMBPERL_XS_CLASSES
|
||||
}
|
||||
|
||||
void PerlembParser::GetQuestTypes(
|
||||
bool& is_player_quest,
|
||||
bool& is_global_player_quest,
|
||||
bool& is_bot_quest,
|
||||
bool& is_global_bot_quest,
|
||||
bool& is_merc_quest,
|
||||
bool& is_global_merc_quest,
|
||||
bool& is_global_npc_quest,
|
||||
bool& is_item_quest,
|
||||
bool& is_spell_quest,
|
||||
QuestType PerlembParser::GetQuestTypes(
|
||||
QuestEventID event_id,
|
||||
Mob* npc_mob,
|
||||
EQ::ItemInstance* inst,
|
||||
Mob* mob,
|
||||
Zone* zone,
|
||||
bool is_global
|
||||
)
|
||||
{
|
||||
@ -1219,100 +1209,74 @@ void PerlembParser::GetQuestTypes(
|
||||
event_id == EVENT_SPELL_FADE ||
|
||||
event_id == EVENT_SPELL_EFFECT_TRANSLOCATE_COMPLETE
|
||||
) {
|
||||
is_spell_quest = true;
|
||||
return is_global ? QuestType::SpellGlobal : QuestType::Spell;
|
||||
} else {
|
||||
if (npc_mob) {
|
||||
if (!inst) {
|
||||
if (is_global) {
|
||||
if (npc_mob->IsBot()) {
|
||||
is_global_bot_quest = true;
|
||||
} else if (npc_mob->IsMerc()) {
|
||||
is_global_merc_quest = true;
|
||||
}
|
||||
} else {
|
||||
if (npc_mob->IsBot()) {
|
||||
is_bot_quest = true;
|
||||
} else if (npc_mob->IsMerc()) {
|
||||
is_merc_quest = true;
|
||||
}
|
||||
if (npc_mob->IsBot()) {
|
||||
return is_global ? QuestType::BotGlobal : QuestType::Bot;
|
||||
} else if (npc_mob->IsMerc()) {
|
||||
return is_global ? QuestType::MercGlobal : QuestType::Merc;
|
||||
} else if (npc_mob->IsNPC()) {
|
||||
return is_global ? QuestType::NPCGlobal : QuestType::NPC;
|
||||
}
|
||||
} else {
|
||||
is_item_quest = true;
|
||||
return is_global ? QuestType::ItemGlobal : QuestType::Item;
|
||||
}
|
||||
} else if (!npc_mob && mob) {
|
||||
if (!inst) {
|
||||
if (is_global) {
|
||||
if (mob->IsClient()) {
|
||||
is_global_player_quest = true;
|
||||
}
|
||||
} else {
|
||||
if (mob->IsClient()) {
|
||||
is_player_quest = true;
|
||||
}
|
||||
if (mob->IsClient()) {
|
||||
return is_global ? QuestType::PlayerGlobal : QuestType::Player;
|
||||
}
|
||||
} else {
|
||||
is_item_quest = true;
|
||||
return is_global ? QuestType::ItemGlobal : QuestType::Item;
|
||||
}
|
||||
} else if (zone) {
|
||||
return is_global ? QuestType::ZoneGlobal : QuestType::Zone;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PerlembParser::GetQuestPackageName(
|
||||
bool& is_player_quest,
|
||||
bool& is_global_player_quest,
|
||||
bool& is_bot_quest,
|
||||
bool& is_global_bot_quest,
|
||||
bool& is_merc_quest,
|
||||
bool& is_global_merc_quest,
|
||||
bool& is_global_npc_quest,
|
||||
bool& is_item_quest,
|
||||
bool& is_spell_quest,
|
||||
std::string& package_name,
|
||||
std::string PerlembParser::GetQuestPackageName(
|
||||
QuestType quest_type,
|
||||
QuestEventID event_id,
|
||||
uint32 object_id,
|
||||
const char* data,
|
||||
Mob* npc_mob,
|
||||
EQ::ItemInstance* inst,
|
||||
bool is_global
|
||||
EQ::ItemInstance* inst
|
||||
)
|
||||
{
|
||||
if (
|
||||
!is_player_quest &&
|
||||
!is_global_player_quest &&
|
||||
!is_bot_quest &&
|
||||
!is_global_bot_quest &&
|
||||
!is_merc_quest &&
|
||||
!is_global_merc_quest &&
|
||||
!is_item_quest &&
|
||||
!is_spell_quest
|
||||
) {
|
||||
if (is_global) {
|
||||
is_global_npc_quest = true;
|
||||
package_name = "qst_global_npc";
|
||||
} else {
|
||||
package_name = fmt::format("qst_npc_{}", npc_mob->GetNPCTypeID());
|
||||
}
|
||||
} else if (is_item_quest) {
|
||||
if (quest_type == QuestType::NPC) {
|
||||
return fmt::format("qst_npc_{}", npc_mob->GetNPCTypeID());
|
||||
} else if (quest_type == QuestType::NPCGlobal) {
|
||||
return "qst_global_npc";
|
||||
} else if (quest_type == QuestType::Item || quest_type == QuestType::ItemGlobal) {
|
||||
if (!inst) {
|
||||
return;
|
||||
return "";
|
||||
}
|
||||
|
||||
package_name = fmt::format("qst_item_{}", inst->GetID());
|
||||
} else if (is_player_quest) {
|
||||
package_name = "qst_player";
|
||||
} else if (is_global_player_quest) {
|
||||
package_name = "qst_global_player";
|
||||
} else if (is_bot_quest) {
|
||||
package_name = "qst_bot";
|
||||
} else if (is_global_bot_quest) {
|
||||
package_name = "qst_global_bot";
|
||||
} else if (is_merc_quest) {
|
||||
package_name = "qst_merc";
|
||||
} else if (is_global_merc_quest) {
|
||||
package_name = "qst_global_merc";
|
||||
} else {
|
||||
package_name = fmt::format("qst_spell_{}", object_id);
|
||||
return fmt::format("qst_item_{}", inst->GetID());
|
||||
} else if (quest_type == QuestType::Player) {
|
||||
return "qst_player";
|
||||
} else if (quest_type == QuestType::PlayerGlobal) {
|
||||
return "qst_global_player";
|
||||
} else if (quest_type == QuestType::Bot) {
|
||||
return "qst_bot";
|
||||
} else if (quest_type == QuestType::BotGlobal) {
|
||||
return "qst_global_bot";
|
||||
} else if (quest_type == QuestType::Merc) {
|
||||
return "qst_merc";
|
||||
} else if (quest_type == QuestType::MercGlobal) {
|
||||
return "qst_global_merc";
|
||||
} else if (quest_type == QuestType::Spell || quest_type == QuestType::SpellGlobal) {
|
||||
return fmt::format("qst_spell_{}", object_id);
|
||||
} else if (quest_type == QuestType::Zone) {
|
||||
return "qst_zone";
|
||||
} else if (quest_type == QuestType::ZoneGlobal) {
|
||||
return "qst_global_zone";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void PerlembParser::ExportCharID(const std::string& package_name, int& char_id, Mob* npc_mob, Mob* mob)
|
||||
@ -1331,15 +1295,7 @@ void PerlembParser::ExportCharID(const std::string& package_name, int& char_id,
|
||||
}
|
||||
|
||||
void PerlembParser::ExportQGlobals(
|
||||
bool is_player_quest,
|
||||
bool is_global_player_quest,
|
||||
bool is_bot_quest,
|
||||
bool is_global_bot_quest,
|
||||
bool is_merc_quest,
|
||||
bool is_global_merc_quest,
|
||||
bool is_global_npc_quest,
|
||||
bool is_item_quest,
|
||||
bool is_spell_quest,
|
||||
QuestType quest_type,
|
||||
std::string& package_name,
|
||||
Mob* npc_mob,
|
||||
Mob* mob,
|
||||
@ -1347,16 +1303,7 @@ void PerlembParser::ExportQGlobals(
|
||||
)
|
||||
{
|
||||
//NPC quest
|
||||
if (
|
||||
!is_player_quest &&
|
||||
!is_global_player_quest &&
|
||||
!is_bot_quest &&
|
||||
!is_global_bot_quest &&
|
||||
!is_merc_quest &&
|
||||
!is_global_merc_quest &&
|
||||
!is_item_quest &&
|
||||
!is_spell_quest
|
||||
) {
|
||||
if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
|
||||
//only export for npcs that are global enabled.
|
||||
if (npc_mob && npc_mob->GetQglobal()) {
|
||||
std::map<std::string, std::string> globhash;
|
||||
@ -1485,15 +1432,7 @@ void PerlembParser::ExportQGlobals(
|
||||
}
|
||||
|
||||
void PerlembParser::ExportMobVariables(
|
||||
bool is_player_quest,
|
||||
bool is_global_player_quest,
|
||||
bool is_bot_quest,
|
||||
bool is_global_bot_quest,
|
||||
bool is_merc_quest,
|
||||
bool is_global_merc_quest,
|
||||
bool is_global_npc_quest,
|
||||
bool is_item_quest,
|
||||
bool is_spell_quest,
|
||||
QuestType quest_type,
|
||||
std::string& package_name,
|
||||
Mob* mob,
|
||||
Mob* npc_mob
|
||||
@ -1511,15 +1450,7 @@ void PerlembParser::ExportMobVariables(
|
||||
ExportVar(package_name.c_str(), "bot_owner_char_id", mob->CastToBot()->GetBotOwnerCharacterID());
|
||||
}
|
||||
|
||||
if (
|
||||
!is_player_quest &&
|
||||
!is_global_player_quest &&
|
||||
!is_bot_quest &&
|
||||
!is_global_bot_quest &&
|
||||
!is_merc_quest &&
|
||||
!is_global_merc_quest &&
|
||||
!is_item_quest
|
||||
) {
|
||||
if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
|
||||
if (mob && mob->IsClient() && npc_mob && npc_mob->IsNPC()) {
|
||||
Client* c = mob->CastToClient();
|
||||
|
||||
@ -1543,16 +1474,7 @@ void PerlembParser::ExportMobVariables(
|
||||
ExportVar(package_name.c_str(), "userid", mob->GetID());
|
||||
}
|
||||
|
||||
if (
|
||||
!is_player_quest &&
|
||||
!is_global_player_quest &&
|
||||
!is_bot_quest &&
|
||||
!is_global_bot_quest &&
|
||||
!is_merc_quest &&
|
||||
!is_global_merc_quest &&
|
||||
!is_item_quest &&
|
||||
!is_spell_quest
|
||||
) {
|
||||
if (quest_type == QuestType::NPC || quest_type == QuestType::NPCGlobal) {
|
||||
if (npc_mob->IsNPC()) {
|
||||
ExportVar(package_name.c_str(), "mname", npc_mob->GetName());
|
||||
ExportVar(package_name.c_str(), "mobid", npc_mob->GetID());
|
||||
@ -1758,10 +1680,14 @@ void PerlembParser::ExportEventVariables(
|
||||
ExportVar(package_name.c_str(), "doorid", data);
|
||||
ExportVar(package_name.c_str(), "version", zone->GetInstanceVersion());
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||
ExportVar(package_name.c_str(), "door", "Doors", std::any_cast<Doors*>(extra_pointers->at(0)));
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 2) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(1)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1782,10 +1708,14 @@ void PerlembParser::ExportEventVariables(
|
||||
);
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 2) {
|
||||
if (extra_pointers && extra_pointers->size() >= 2) {
|
||||
ExportVar(package_name.c_str(), "corpse", "Corpse", std::any_cast<Corpse*>(extra_pointers->at(1)));
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 3) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(2)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1852,7 +1782,7 @@ void PerlembParser::ExportEventVariables(
|
||||
ExportVar(package_name.c_str(), "picked_up_id", data);
|
||||
ExportVar(package_name.c_str(), "picked_up_entity_id", extra_data);
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||
ExportVar(
|
||||
package_name.c_str(),
|
||||
"item",
|
||||
@ -1861,6 +1791,10 @@ void PerlembParser::ExportEventVariables(
|
||||
);
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 2) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(1)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1873,6 +1807,11 @@ void PerlembParser::ExportEventVariables(
|
||||
|
||||
case EVENT_POPUP_RESPONSE: {
|
||||
ExportVar(package_name.c_str(), "popupid", data);
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(0)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2036,10 +1975,14 @@ void PerlembParser::ExportEventVariables(
|
||||
ExportVar(package_name.c_str(), "objectid", data);
|
||||
ExportVar(package_name.c_str(), "clicker_id", extra_data);
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||
ExportVar(package_name.c_str(), "object", "Object", std::any_cast<Object*>(extra_pointers->at(0)));
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 2) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(1)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2115,6 +2058,13 @@ void PerlembParser::ExportEventVariables(
|
||||
ExportVar(package_name.c_str(), "killed_npc_id", !killed->IsMerc() && killed->IsNPC() ? killed->GetNPCTypeID() : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 3) {
|
||||
Mob* killer = std::any_cast<Mob*>(extra_pointers->at(2));
|
||||
if (killer) {
|
||||
ExportVar(package_name.c_str(), "killer", "Mob", killer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2142,10 +2092,21 @@ void PerlembParser::ExportEventVariables(
|
||||
}
|
||||
|
||||
case EVENT_SPAWN_ZONE: {
|
||||
ExportVar(package_name.c_str(), "spawned_entity_id", mob->GetID());
|
||||
ExportVar(package_name.c_str(), "spawned_bot_id", mob->IsBot() ? mob->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "spawned_npc_id", mob->IsNPC() ? mob->GetNPCTypeID() : 0);
|
||||
ExportVar(package_name.c_str(), "spawned", "Mob", mob);
|
||||
if (mob) {
|
||||
ExportVar(package_name.c_str(), "spawned", "Mob", mob);
|
||||
ExportVar(package_name.c_str(), "spawned_bot_id", mob->IsBot() ? mob->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "spawned_entity_id", mob->GetID());
|
||||
ExportVar(package_name.c_str(), "spawned_npc_id", mob->IsNPC() ? mob->GetNPCTypeID() : 0);
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
NPC* spawn_npc = std::any_cast<NPC*>(extra_pointers->at(0));
|
||||
ExportVar(package_name.c_str(), "spawned", "NPC", spawn_npc);
|
||||
ExportVar(package_name.c_str(), "spawned_bot_id", spawn_npc->IsBot() ? spawn_npc->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "spawned_entity_id", spawn_npc->GetID());
|
||||
ExportVar(package_name.c_str(), "spawned_npc_id", spawn_npc->IsNPC() ? spawn_npc->GetNPCTypeID() : 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2386,6 +2347,7 @@ void PerlembParser::ExportEventVariables(
|
||||
}
|
||||
|
||||
case EVENT_DESPAWN: {
|
||||
ExportVar(package_name.c_str(), "despawned", "Mob", npc_mob);
|
||||
ExportVar(package_name.c_str(), "despawned_entity_id", npc_mob->GetID());
|
||||
ExportVar(package_name.c_str(), "despawned_bot_id", npc_mob->IsBot() ? npc_mob->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "despawned_merc_id", npc_mob->IsMerc() ? npc_mob->CastToMerc()->GetMercenaryID() : 0);
|
||||
@ -2394,9 +2356,21 @@ void PerlembParser::ExportEventVariables(
|
||||
}
|
||||
|
||||
case EVENT_DESPAWN_ZONE: {
|
||||
ExportVar(package_name.c_str(), "despawned_entity_id", mob->GetID());
|
||||
ExportVar(package_name.c_str(), "despawned_bot_id", mob->IsBot() ? mob->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "despawned_npc_id", mob->IsNPC() ? mob->GetNPCTypeID() : 0);
|
||||
if (mob) {
|
||||
ExportVar(package_name.c_str(), "despawned", "Mob", mob);
|
||||
ExportVar(package_name.c_str(), "despawned_bot_id", mob->IsBot() ? mob->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "despawned_entity_id", mob->GetID());
|
||||
ExportVar(package_name.c_str(), "despawned_npc_id", mob->IsNPC() ? mob->GetNPCTypeID() : 0);
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
NPC* spawn_npc = std::any_cast<NPC*>(extra_pointers->at(0));
|
||||
ExportVar(package_name.c_str(), "despawned", "NPC", spawn_npc);
|
||||
ExportVar(package_name.c_str(), "despawned_bot_id", spawn_npc->IsBot() ? spawn_npc->CastToBot()->GetBotID() : 0);
|
||||
ExportVar(package_name.c_str(), "despawned_entity_id", spawn_npc->GetID());
|
||||
ExportVar(package_name.c_str(), "despawned_npc_id", spawn_npc->IsNPC() ? spawn_npc->GetNPCTypeID() : 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2551,6 +2525,20 @@ void PerlembParser::ExportEventVariables(
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_ENTER_ZONE: {
|
||||
if (extra_pointers && extra_pointers->size() == 1) {
|
||||
ExportVar(package_name.c_str(), "player", "Client", std::any_cast<Client*>(extra_pointers->at(0)));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EVENT_PET_COMMAND: {
|
||||
ExportVar(package_name.c_str(), "pet_command", extra_data);
|
||||
ExportVar(package_name.c_str(), "pet_command_name", data);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
@ -2648,6 +2636,7 @@ int PerlembParser::EventBot(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -2671,6 +2660,7 @@ int PerlembParser::EventGlobalBot(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
true,
|
||||
extra_pointers
|
||||
@ -2768,6 +2758,7 @@ int PerlembParser::EventMerc(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
@ -2791,6 +2782,127 @@ int PerlembParser::EventGlobalMerc(
|
||||
nullptr,
|
||||
nullptr,
|
||||
mob,
|
||||
nullptr,
|
||||
extra_data,
|
||||
true,
|
||||
extra_pointers
|
||||
);
|
||||
}
|
||||
|
||||
void PerlembParser::LoadZoneScript(std::string filename)
|
||||
{
|
||||
if (!perl || zone_quest_status_ != questUnloaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
perl->eval_file("qst_zone", filename.c_str());
|
||||
} catch (std::string e) {
|
||||
AddError(
|
||||
fmt::format(
|
||||
"Error Compiling Zone Quest File [{}] Error [{}]",
|
||||
filename,
|
||||
e
|
||||
)
|
||||
);
|
||||
|
||||
zone_quest_status_ = questFailedToLoad;
|
||||
return;
|
||||
}
|
||||
|
||||
zone_quest_status_ = questLoaded;
|
||||
}
|
||||
|
||||
void PerlembParser::LoadGlobalZoneScript(std::string filename)
|
||||
{
|
||||
if (!perl || global_zone_quest_status_ != questUnloaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
perl->eval_file("qst_global_zone", filename.c_str());
|
||||
} catch (std::string e) {
|
||||
AddError(
|
||||
fmt::format(
|
||||
"Error Compiling Global Zone Quest File [{}] Error [{}]",
|
||||
filename,
|
||||
e
|
||||
)
|
||||
);
|
||||
|
||||
global_zone_quest_status_ = questFailedToLoad;
|
||||
return;
|
||||
}
|
||||
|
||||
global_zone_quest_status_ = questLoaded;
|
||||
}
|
||||
|
||||
bool PerlembParser::ZoneHasQuestSub(QuestEventID event_id)
|
||||
{
|
||||
if (
|
||||
!perl ||
|
||||
zone_quest_status_ != questLoaded ||
|
||||
event_id >= _LargestEventID
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return perl->SubExists("qst_zone", QuestEventSubroutines[event_id]);
|
||||
}
|
||||
|
||||
bool PerlembParser::GlobalZoneHasQuestSub(QuestEventID event_id)
|
||||
{
|
||||
if (
|
||||
!perl ||
|
||||
global_zone_quest_status_ != questLoaded ||
|
||||
event_id >= _LargestEventID
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return perl->SubExists("qst_global_zone", QuestEventSubroutines[event_id]);
|
||||
}
|
||||
|
||||
int PerlembParser::EventZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
return EventCommon(
|
||||
event_id,
|
||||
0,
|
||||
data.c_str(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
zone,
|
||||
extra_data,
|
||||
false,
|
||||
extra_pointers
|
||||
);
|
||||
}
|
||||
|
||||
int PerlembParser::EventGlobalZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
return EventCommon(
|
||||
event_id,
|
||||
0,
|
||||
data.c_str(),
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
zone,
|
||||
extra_data,
|
||||
true,
|
||||
extra_pointers
|
||||
|
||||
@ -41,6 +41,23 @@ typedef enum {
|
||||
questFailedToLoad
|
||||
} PerlQuestStatus;
|
||||
|
||||
enum class QuestType {
|
||||
Bot,
|
||||
BotGlobal,
|
||||
Item,
|
||||
ItemGlobal,
|
||||
Merc,
|
||||
MercGlobal,
|
||||
NPC,
|
||||
NPCGlobal,
|
||||
Player,
|
||||
PlayerGlobal,
|
||||
Spell,
|
||||
SpellGlobal,
|
||||
Zone,
|
||||
ZoneGlobal
|
||||
};
|
||||
|
||||
class PerlembParser : public QuestInterface {
|
||||
public:
|
||||
PerlembParser();
|
||||
@ -136,6 +153,22 @@ public:
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
virtual int EventZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
virtual int EventGlobalZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
virtual bool HasQuestSub(uint32 npc_id, QuestEventID event_id);
|
||||
virtual bool HasGlobalQuestSub(QuestEventID event_id);
|
||||
virtual bool PlayerHasQuestSub(QuestEventID event_id);
|
||||
@ -146,6 +179,8 @@ public:
|
||||
virtual bool GlobalBotHasQuestSub(QuestEventID event_id);
|
||||
virtual bool MercHasQuestSub(QuestEventID event_id);
|
||||
virtual bool GlobalMercHasQuestSub(QuestEventID event_id);
|
||||
virtual bool ZoneHasQuestSub(QuestEventID event_id);
|
||||
virtual bool GlobalZoneHasQuestSub(QuestEventID event_id);
|
||||
|
||||
virtual void LoadNPCScript(std::string filename, int npc_id);
|
||||
virtual void LoadGlobalNPCScript(std::string filename);
|
||||
@ -157,6 +192,8 @@ public:
|
||||
virtual void LoadGlobalBotScript(std::string filename);
|
||||
virtual void LoadMercScript(std::string filename);
|
||||
virtual void LoadGlobalMercScript(std::string filename);
|
||||
virtual void LoadZoneScript(std::string filename);
|
||||
virtual void LoadGlobalZoneScript(std::string filename);
|
||||
|
||||
virtual void AddVar(std::string name, std::string val);
|
||||
virtual std::string GetVar(std::string name);
|
||||
@ -182,6 +219,7 @@ private:
|
||||
EQ::ItemInstance* inst,
|
||||
const SPDat_Spell_Struct* spell,
|
||||
Mob* mob,
|
||||
Zone* zone,
|
||||
uint32 extra_data,
|
||||
bool is_global,
|
||||
std::vector<std::any>* extra_pointers
|
||||
@ -194,59 +232,34 @@ private:
|
||||
Mob* other,
|
||||
Mob* mob,
|
||||
EQ::ItemInstance* inst,
|
||||
const SPDat_Spell_Struct* spell
|
||||
const SPDat_Spell_Struct* spell,
|
||||
Zone* zone
|
||||
);
|
||||
|
||||
void MapFunctions();
|
||||
|
||||
void GetQuestTypes(
|
||||
bool& is_player_quest,
|
||||
bool& is_global_player_quest,
|
||||
bool& is_bot_quest,
|
||||
bool& is_global_bot_quest,
|
||||
bool& is_merc_quest,
|
||||
bool& is_global_merc_quest,
|
||||
bool& is_global_npc_quest,
|
||||
bool& is_item_quest,
|
||||
bool& is_spell_quest,
|
||||
QuestType GetQuestTypes(
|
||||
QuestEventID event,
|
||||
Mob* npc_mob,
|
||||
EQ::ItemInstance* inst,
|
||||
Mob* mob,
|
||||
Zone* zone,
|
||||
bool is_global
|
||||
);
|
||||
|
||||
void GetQuestPackageName(
|
||||
bool& is_player_quest,
|
||||
bool& is_global_player_quest,
|
||||
bool& is_bot_quest,
|
||||
bool& is_global_bot_quest,
|
||||
bool& is_merc_quest,
|
||||
bool& is_global_merc_quest,
|
||||
bool& is_global_npc_quest,
|
||||
bool& is_item_quest,
|
||||
bool& is_spell_quest,
|
||||
std::string& package_name,
|
||||
std::string GetQuestPackageName(
|
||||
QuestType quest_type,
|
||||
QuestEventID event,
|
||||
uint32 object_id,
|
||||
const char* data,
|
||||
Mob* npc_mob,
|
||||
EQ::ItemInstance* inst,
|
||||
bool is_global
|
||||
EQ::ItemInstance* inst
|
||||
);
|
||||
|
||||
void ExportCharID(const std::string& package_name, int& char_id, Mob* npc_mob, Mob* mob);
|
||||
|
||||
void ExportQGlobals(
|
||||
bool is_player_quest,
|
||||
bool is_global_player_quest,
|
||||
bool is_bot_quest,
|
||||
bool is_global_bot_quest,
|
||||
bool is_merc_quest,
|
||||
bool is_global_merc_quest,
|
||||
bool is_global_npc_quest,
|
||||
bool is_item_quest,
|
||||
bool is_spell_quest,
|
||||
QuestType quest_type,
|
||||
std::string& package_name,
|
||||
Mob* npc_mob,
|
||||
Mob* mob,
|
||||
@ -254,15 +267,7 @@ private:
|
||||
);
|
||||
|
||||
void ExportMobVariables(
|
||||
bool is_player_quest,
|
||||
bool is_global_player_quest,
|
||||
bool is_bot_quest,
|
||||
bool is_global_bot_quest,
|
||||
bool is_merc_quest,
|
||||
bool is_global_merc_quest,
|
||||
bool is_global_npc_quest,
|
||||
bool is_item_quest,
|
||||
bool is_spell_quest,
|
||||
QuestType quest_type,
|
||||
std::string& package_name,
|
||||
Mob* mob,
|
||||
Mob* npc_mob
|
||||
@ -295,6 +300,8 @@ private:
|
||||
PerlQuestStatus global_bot_quest_status_;
|
||||
PerlQuestStatus merc_quest_status_;
|
||||
PerlQuestStatus global_merc_quest_status_;
|
||||
PerlQuestStatus zone_quest_status_;
|
||||
PerlQuestStatus global_zone_quest_status_;
|
||||
|
||||
SV* _empty_sv;
|
||||
|
||||
|
||||
@ -6005,6 +6005,50 @@ bool Perl__handin(perl::reference handin_ref)
|
||||
return quest_manager.handin(handin_map);
|
||||
}
|
||||
|
||||
perl::array Perl__get_paused_timers(Mob* m)
|
||||
{
|
||||
perl::array a;
|
||||
|
||||
const auto& l = quest_manager.GetPausedTimers(m);
|
||||
|
||||
if (!l.empty()) {
|
||||
a.reserve(l.size());
|
||||
|
||||
for (const auto& v : l) {
|
||||
a.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
perl::array Perl__get_timers(Mob* m)
|
||||
{
|
||||
perl::array a;
|
||||
|
||||
const auto& l = quest_manager.GetTimers(m);
|
||||
|
||||
if (!l.empty()) {
|
||||
a.reserve(l.size());
|
||||
|
||||
for (const auto& v: l) {
|
||||
a.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
std::string Perl__get_pet_command_name(uint8 pet_command)
|
||||
{
|
||||
return PetCommand::GetName(pet_command);
|
||||
}
|
||||
|
||||
std::string Perl__get_pet_type_name(uint8 pet_type)
|
||||
{
|
||||
return PetType::GetName(pet_type);
|
||||
}
|
||||
|
||||
void perl_register_quest()
|
||||
{
|
||||
perl::interpreter perl(PERL_GET_THX);
|
||||
@ -6694,6 +6738,9 @@ void perl_register_quest()
|
||||
package.add("getguildidbycharid", &Perl__getguildidbycharid);
|
||||
package.add("getgroupidbycharid", &Perl__getgroupidbycharid);
|
||||
package.add("getinventoryslotname", &Perl__getinventoryslotname);
|
||||
package.add("get_paused_timers", &Perl__get_paused_timers);
|
||||
package.add("get_pet_command_name", &Perl__get_pet_command_name);
|
||||
package.add("get_pet_type_name", &Perl__get_pet_type_name);
|
||||
package.add("getraididbycharid", &Perl__getraididbycharid);
|
||||
package.add("get_race_bitmask", &Perl__get_race_bitmask);
|
||||
package.add("get_recipe_component_item_ids", &Perl__GetRecipeComponentItemIDs);
|
||||
@ -6713,6 +6760,7 @@ void perl_register_quest()
|
||||
package.add("getspellstat", (int(*)(uint32, std::string))&Perl__getspellstat);
|
||||
package.add("getspellstat", (int(*)(uint32, std::string, uint8))&Perl__getspellstat);
|
||||
package.add("getskillname", &Perl__getskillname);
|
||||
package.add("get_timers", &Perl__get_timers);
|
||||
package.add("getlevel", &Perl__getlevel);
|
||||
package.add("getplayerburiedcorpsecount", &Perl__getplayerburiedcorpsecount);
|
||||
package.add("getplayercorpsecount", &Perl__getplayercorpsecount);
|
||||
|
||||
@ -743,6 +743,11 @@ void EntityList::AddNPC(NPC *npc, bool send_spawn_packet, bool dont_queue)
|
||||
npc->DispatchZoneControllerEvent(EVENT_SPAWN_ZONE, npc, "", 0, nullptr);
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_SPAWN_ZONE)) {
|
||||
std::vector<std::any> args = { npc };
|
||||
parse->EventZone(EVENT_SPAWN_ZONE, zone, "", 0, &args);
|
||||
}
|
||||
|
||||
if (zone->HasMap() && zone->HasWaterMap()) {
|
||||
npc->SetSpawnedInWater(false);
|
||||
if (zone->watermap->InLiquid(npc->GetPosition())) {
|
||||
|
||||
@ -145,6 +145,7 @@ typedef enum {
|
||||
EVENT_AA_LOSS,
|
||||
EVENT_SPELL_BLOCKED,
|
||||
EVENT_READ_ITEM,
|
||||
EVENT_PET_COMMAND,
|
||||
|
||||
// Add new events before these or Lua crashes
|
||||
EVENT_SPELL_EFFECT_BOT,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "../client.h"
|
||||
#include "find/aa.cpp"
|
||||
#include "find/account.cpp"
|
||||
#include "find/body_type.cpp"
|
||||
#include "find/bot.cpp"
|
||||
#include "find/bug_category.cpp"
|
||||
@ -38,6 +39,7 @@ void command_find(Client *c, const Seperator *sep)
|
||||
|
||||
std::vector<Cmd> commands = {
|
||||
Cmd{.cmd = "aa", .u = "aa [Search Criteria]", .fn = FindAA, .a = {"#findaa"}},
|
||||
Cmd{.cmd = "account", .u = "account [Search Criteria]", .fn = FindAccount, .a = {"#findaccount"}},
|
||||
Cmd{.cmd = "body_type", .u = "body_type [Search Criteria]", .fn = FindBodyType, .a = {"#findbodytype"}},
|
||||
Cmd{.cmd = "bug_category", .u = "bug_category [Search Criteria]", .fn = FindBugCategory, .a = {"#findbugcategory"}},
|
||||
Cmd{.cmd = "character", .u = "character [Search Criteria]", .fn = FindCharacter, .a = {"#findcharacter"}},
|
||||
@ -72,7 +74,7 @@ void command_find(Client *c, const Seperator *sep)
|
||||
commands.emplace_back(
|
||||
Cmd{.cmd = "bot", .u = "bot [Search Criteria]", .fn = FindBot, .a = {"#findbot"}}
|
||||
);
|
||||
|
||||
|
||||
std::sort(commands.begin(), commands.end(), [](const Cmd& a, const Cmd& b) {
|
||||
return a.cmd < b.cmd;
|
||||
});
|
||||
|
||||
50
zone/gm_commands/find/account.cpp
Normal file
50
zone/gm_commands/find/account.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include "../../client.h"
|
||||
#include "../../common/repositories/account_repository.h"
|
||||
|
||||
void FindAccount(Client *c, const Seperator *sep)
|
||||
{
|
||||
const uint16 arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
c->Message(Chat::White, "Usage: #find account [Character Name]");
|
||||
c->Message(Chat::White, "Note: Used to print the account ID and name of the account a character belongs to.");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& character_name = sep->arg[2];
|
||||
|
||||
const auto& e = CharacterDataRepository::FindByName(database, character_name);
|
||||
|
||||
if (!e.id) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Character '{}' does not exist.",
|
||||
character_name
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
auto a = AccountRepository::FindOne(database, e.account_id);
|
||||
|
||||
if (!a.id) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Character '{}' is not attached to an account.",
|
||||
character_name
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Account {} ({}) owns the character {}.",
|
||||
a.name,
|
||||
a.id,
|
||||
character_name
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
@ -110,6 +110,7 @@ void SendNPCEditSubCommands(Client *c)
|
||||
c->Message(Chat::White, "Usage: #npcedit setanimation [Animation ID] - Sets an NPC's Animation on Spawn (Stored in spawn2 table)");
|
||||
c->Message(Chat::White, "Usage: #npcedit respawntime [Respawn Time] - Sets an NPC's Respawn Timer in Seconds (Stored in spawn2 table)");
|
||||
c->Message(Chat::White, "Usage: #npcedit set_grid [Grid ID] - Sets an NPC's Grid ID");
|
||||
c->Message(Chat::White, "Usage: #npcedit npc_tint_id [NPC Tint ID] - Sets an NPC's Tint ID (0 to 78 for RoF2)");
|
||||
}
|
||||
|
||||
void command_npcedit(Client *c, const Seperator *sep)
|
||||
@ -1836,4 +1837,4 @@ void command_npcedit(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
c->Message(Chat::White, d.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "show/group_info.cpp"
|
||||
#include "show/hatelist.cpp"
|
||||
#include "show/inventory.cpp"
|
||||
#include "show/keyring.cpp"
|
||||
#include "show/ip_lookup.cpp"
|
||||
#include "show/line_of_sight.cpp"
|
||||
#include "show/network.cpp"
|
||||
@ -78,6 +79,7 @@ void command_show(Client *c, const Seperator *sep)
|
||||
Cmd{.cmd = "hatelist", .u = "hatelist", .fn = ShowHateList, .a = {"#hatelist"}},
|
||||
Cmd{.cmd = "inventory", .u = "inventory", .fn = ShowInventory, .a = {"#peekinv"}},
|
||||
Cmd{.cmd = "ip_lookup", .u = "ip_lookup", .fn = ShowIPLookup, .a = {"#iplookup"}},
|
||||
Cmd{.cmd = "keyring", .u = "keyring", .fn = ShowKeyring, .a = {"#showkeyring"}},
|
||||
Cmd{.cmd = "line_of_sight", .u = "line_of_sight", .fn = ShowLineOfSight, .a = {"#checklos"}},
|
||||
Cmd{.cmd = "network", .u = "network", .fn = ShowNetwork, .a = {"#network"}},
|
||||
Cmd{.cmd = "network_stats", .u = "network_stats", .fn = ShowNetworkStats, .a = {"#netstats"}},
|
||||
|
||||
12
zone/gm_commands/show/keyring.cpp
Normal file
12
zone/gm_commands/show/keyring.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include "../../client.h"
|
||||
#include "../../dialogue_window.h"
|
||||
|
||||
void ShowKeyring(Client *c, const Seperator *sep)
|
||||
{
|
||||
Client* t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
t = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
t->KeyRingList(c);
|
||||
}
|
||||
@ -16,17 +16,17 @@ void ShowNetwork(Client *c, const Seperator *sep)
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Max Packet Size") +
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.max_packet_size))
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.reliable_stream_options.max_packet_size))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Max Connection Count") +
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.max_connection_count))
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.reliable_stream_options.max_connection_count))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Keep Alive Delay") +
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.keepalive_delay_ms))
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.reliable_stream_options.keepalive_delay_ms))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
@ -34,64 +34,64 @@ void ShowNetwork(Client *c, const Seperator *sep)
|
||||
DialogueWindow::TableCell(
|
||||
fmt::format(
|
||||
"{:.2f}",
|
||||
opts.daybreak_options.resend_delay_factor
|
||||
opts.reliable_stream_options.resend_delay_factor
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Resend Delay") +
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.resend_delay_ms))
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.reliable_stream_options.resend_delay_ms))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Resend Delay Minimum") +
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.resend_delay_min))
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.reliable_stream_options.resend_delay_min))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Resend Delay Maximum") +
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.resend_delay_max))
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.reliable_stream_options.resend_delay_max))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Connect Delay") +
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.connect_delay_ms))
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.reliable_stream_options.connect_delay_ms))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Connect Stale") +
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.connect_stale_ms))
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.reliable_stream_options.connect_stale_ms))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Stale Connection") +
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.stale_connection_ms))
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.reliable_stream_options.stale_connection_ms))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("CRC Length") +
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.crc_length))
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.reliable_stream_options.crc_length))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Hold Size") +
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.hold_size))
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.reliable_stream_options.hold_size))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Hold Length") +
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.hold_length_ms))
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.reliable_stream_options.hold_length_ms))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Simulated In Packet Loss") +
|
||||
DialogueWindow::TableCell(std::to_string(opts.daybreak_options.simulated_in_packet_loss))
|
||||
DialogueWindow::TableCell(std::to_string(opts.reliable_stream_options.simulated_in_packet_loss))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Simulated Out Packet Loss") +
|
||||
DialogueWindow::TableCell(std::to_string(opts.daybreak_options.simulated_out_packet_loss))
|
||||
DialogueWindow::TableCell(std::to_string(opts.reliable_stream_options.simulated_out_packet_loss))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
@ -99,34 +99,34 @@ void ShowNetwork(Client *c, const Seperator *sep)
|
||||
DialogueWindow::TableCell(
|
||||
fmt::format(
|
||||
"{:.2f}",
|
||||
opts.daybreak_options.tic_rate_hertz
|
||||
opts.reliable_stream_options.tic_rate_hertz
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Resend Timeout") +
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.resend_timeout))
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.reliable_stream_options.resend_timeout))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Connection Close Time") +
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.daybreak_options.connection_close_time))
|
||||
DialogueWindow::TableCell(Strings::MillisecondsToTime(opts.reliable_stream_options.connection_close_time))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Encode Passes (1)") +
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.encode_passes[0]))
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.reliable_stream_options.encode_passes[0]))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Encode Passes (2)") +
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.encode_passes[1]))
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.reliable_stream_options.encode_passes[1]))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Port") +
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.daybreak_options.port))
|
||||
DialogueWindow::TableCell(Strings::Commify(opts.reliable_stream_options.port))
|
||||
);
|
||||
|
||||
popup_table = DialogueWindow::Table(popup_table);
|
||||
|
||||
@ -7,7 +7,7 @@ void ShowNetworkStats(Client *c, const Seperator *sep)
|
||||
const auto opts = connection->GetManager()->GetOptions();
|
||||
const auto eqs_stats = connection->GetStats();
|
||||
|
||||
const auto& stats = eqs_stats.DaybreakStats;
|
||||
const auto& stats = eqs_stats.ReliableStreamStats;
|
||||
|
||||
const auto sec_since_stats_reset = std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
EQ::Net::Clock::now() - stats.created
|
||||
@ -217,7 +217,7 @@ void ShowNetworkStats(Client *c, const Seperator *sep)
|
||||
)
|
||||
);
|
||||
|
||||
if (opts.daybreak_options.outgoing_data_rate > 0.0) {
|
||||
if (opts.reliable_stream_options.outgoing_data_rate > 0.0) {
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Outgoing Link Saturation") +
|
||||
DialogueWindow::TableCell(
|
||||
@ -229,14 +229,14 @@ void ShowNetworkStats(Client *c, const Seperator *sep)
|
||||
1.0 -
|
||||
(
|
||||
(
|
||||
opts.daybreak_options.outgoing_data_rate -
|
||||
opts.reliable_stream_options.outgoing_data_rate -
|
||||
stats.datarate_remaining
|
||||
) /
|
||||
opts.daybreak_options.outgoing_data_rate
|
||||
opts.reliable_stream_options.outgoing_data_rate
|
||||
)
|
||||
)
|
||||
),
|
||||
opts.daybreak_options.outgoing_data_rate
|
||||
opts.reliable_stream_options.outgoing_data_rate
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
@ -10,7 +10,7 @@ void ShowRecipe(Client *c, const Seperator *sep)
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16 recipe_id = static_cast<uint16>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
const uint32 recipe_id = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
|
||||
const auto& re = TradeskillRecipeEntriesRepository::GetWhere(
|
||||
content_db,
|
||||
|
||||
@ -2472,19 +2472,63 @@ bool Group::AmIPuller(const char *mob_name)
|
||||
return !((bool)PullerName.compare(mob_name));
|
||||
}
|
||||
|
||||
bool Group::HasRole(Mob *m, uint8 Role)
|
||||
bool Group::HasRole(Mob* m, uint8 Role)
|
||||
{
|
||||
if(!m)
|
||||
if (!m) {
|
||||
return false;
|
||||
|
||||
for(uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i)
|
||||
{
|
||||
if((m == members[i]) && (MemberRoles[i] & Role))
|
||||
return true;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
if (m == members[i] && MemberRoles[i] & Role) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8 Group::GetMemberRole(Mob* m)
|
||||
{
|
||||
if (!m) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
if (m == members[i]) {
|
||||
uint8 role = MemberRoles[i];
|
||||
|
||||
if (m == leader) {
|
||||
role |= RoleLeader;
|
||||
}
|
||||
|
||||
return role;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 Group::GetMemberRole(const char* name)
|
||||
{
|
||||
if (!name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
if (!strcasecmp(membername[i], name)) {
|
||||
uint8 role = MemberRoles[i];
|
||||
|
||||
if (leader && !strcasecmp(leader->GetName(), name)) {
|
||||
role |= RoleLeader;
|
||||
}
|
||||
|
||||
return role;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Group::QueueClients(Mob *sender, const EQApplicationPacket *app, bool ack_required /*= true*/, bool ignore_sender /*= true*/, float distance /*= 0*/) {
|
||||
if (sender && sender->IsClient()) {
|
||||
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
|
||||
@ -30,7 +30,12 @@ class Mob;
|
||||
|
||||
#define MAX_MARKED_NPCS 3
|
||||
|
||||
enum { RoleAssist = 1, RoleTank = 2, RolePuller = 4 };
|
||||
enum {
|
||||
RoleAssist = 1,
|
||||
RoleTank = 2,
|
||||
RolePuller = 4,
|
||||
RoleLeader = 8
|
||||
};
|
||||
|
||||
class GroupIDConsumer {
|
||||
public:
|
||||
@ -119,6 +124,8 @@ public:
|
||||
void SetGroupTankTarget(Mob *m);
|
||||
void SetGroupPullerTarget(Mob *m);
|
||||
bool HasRole(Mob *m, uint8 Role);
|
||||
uint8 GetMemberRole(Mob* m);
|
||||
uint8 GetMemberRole(const char* name);
|
||||
void NotifyAssistTarget(Client *c);
|
||||
void NotifyTankTarget(Client *c);
|
||||
void NotifyPullerTarget(Client *c);
|
||||
|
||||
@ -3575,7 +3575,13 @@ bool Lua_Client::KeyRingClear()
|
||||
void Lua_Client::KeyRingList()
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->KeyRingList();
|
||||
self->KeyRingList(self);
|
||||
}
|
||||
|
||||
void Lua_Client::KeyRingList(Lua_Client c)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->KeyRingList(self);
|
||||
}
|
||||
|
||||
bool Lua_Client::KeyRingRemove(uint32 item_id)
|
||||
@ -3602,6 +3608,22 @@ void Lua_Client::EnableTitleSet(uint32 title_set) {
|
||||
self->EnableTitle(title_set);
|
||||
}
|
||||
|
||||
luabind::object Lua_Client::GetKeyRing(lua_State* L)
|
||||
{
|
||||
auto lua_table = luabind::newtable(L);
|
||||
|
||||
if (d_) {
|
||||
auto self = reinterpret_cast<NativeType *>(d_);
|
||||
int index = 1;
|
||||
for (const uint32& item_id: self->GetKeyRing()) {
|
||||
lua_table[index] = item_id;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return lua_table;
|
||||
}
|
||||
|
||||
luabind::scope lua_register_client() {
|
||||
return luabind::class_<Lua_Client, Lua_Mob>("Client")
|
||||
.def(luabind::constructor<>())
|
||||
@ -3832,6 +3854,7 @@ luabind::scope lua_register_client() {
|
||||
.def("GetInvulnerableEnvironmentDamage", (bool(Lua_Client::*)(void))&Lua_Client::GetInvulnerableEnvironmentDamage)
|
||||
.def("GetItemIDAt", (int(Lua_Client::*)(int))&Lua_Client::GetItemIDAt)
|
||||
.def("GetItemCooldown", (uint32(Lua_Client::*)(uint32))&Lua_Client::GetItemCooldown)
|
||||
.def("GetKeyRing", (luabind::object(Lua_Client::*)(lua_State* L))&Lua_Client::GetKeyRing)
|
||||
.def("GetLDoNLosses", (int(Lua_Client::*)(void))&Lua_Client::GetLDoNLosses)
|
||||
.def("GetLDoNLossesTheme", (int(Lua_Client::*)(int))&Lua_Client::GetLDoNLossesTheme)
|
||||
.def("GetLDoNPointsTheme", (int(Lua_Client::*)(int))&Lua_Client::GetLDoNPointsTheme)
|
||||
@ -3932,6 +3955,7 @@ luabind::scope lua_register_client() {
|
||||
.def("KeyRingCheck", (bool(Lua_Client::*)(uint32))&Lua_Client::KeyRingCheck)
|
||||
.def("KeyRingClear", (bool(Lua_Client::*)(void))&Lua_Client::KeyRingClear)
|
||||
.def("KeyRingList", (void(Lua_Client::*)(void))&Lua_Client::KeyRingList)
|
||||
.def("KeyRingList", (void(Lua_Client::*)(Lua_Client))&Lua_Client::KeyRingList)
|
||||
.def("KeyRingRemove", (bool(Lua_Client::*)(uint32))&Lua_Client::KeyRingRemove)
|
||||
.def("Kick", (void(Lua_Client::*)(void))&Lua_Client::Kick)
|
||||
.def("LearnDisciplines", (uint16(Lua_Client::*)(uint8,uint8))&Lua_Client::LearnDisciplines)
|
||||
|
||||
@ -521,9 +521,11 @@ public:
|
||||
bool KeyRingCheck(uint32 item_id);
|
||||
bool KeyRingClear();
|
||||
void KeyRingList();
|
||||
void KeyRingList(Lua_Client c);
|
||||
bool KeyRingRemove(uint32 item_id);
|
||||
bool CompleteTask(int task_id);
|
||||
bool UncompleteTask(int task_id);
|
||||
luabind::object GetKeyRing(lua_State* L);
|
||||
|
||||
// account data buckets
|
||||
void SetAccountBucket(std::string bucket_name, std::string bucket_value);
|
||||
|
||||
@ -5675,6 +5675,42 @@ bool lua_handin(luabind::adl::object handin_table)
|
||||
return quest_manager.handin(handin_map);
|
||||
}
|
||||
|
||||
luabind::object lua_get_paused_timers(lua_State* L, Mob* m) {
|
||||
auto t = luabind::newtable(L);
|
||||
auto v = quest_manager.GetPausedTimers(m);
|
||||
int i = 1;
|
||||
|
||||
for (const auto& e : v) {
|
||||
t[i] = e;
|
||||
i++;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
luabind::object lua_get_timers(lua_State* L, Mob* m) {
|
||||
auto t = luabind::newtable(L);
|
||||
auto v = quest_manager.GetTimers(m);
|
||||
int i = 1;
|
||||
|
||||
for (const auto& e : v) {
|
||||
t[i] = e;
|
||||
i++;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
std::string lua_get_pet_command_name(uint8 pet_command)
|
||||
{
|
||||
return PetCommand::GetName(pet_command);
|
||||
}
|
||||
|
||||
std::string lua_get_pet_type_name(uint8 pet_type)
|
||||
{
|
||||
return PetType::GetName(pet_type);
|
||||
}
|
||||
|
||||
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
||||
cur = table[#name]; \
|
||||
if(luabind::type(cur) != LUA_TNIL) { \
|
||||
@ -6486,6 +6522,10 @@ luabind::scope lua_register_general() {
|
||||
luabind::def("spawn_grid", &lua_spawn_grid),
|
||||
luabind::def("get_zone", &lua_get_zone),
|
||||
luabind::def("handin", &lua_handin),
|
||||
luabind::def("get_paused_timers", &lua_get_paused_timers),
|
||||
luabind::def("get_timers", &lua_get_timers),
|
||||
luabind::def("get_pet_command_name", &lua_get_pet_command_name),
|
||||
luabind::def("get_pet_type_name", &lua_get_pet_type_name),
|
||||
/*
|
||||
Cross Zone
|
||||
*/
|
||||
@ -6951,7 +6991,8 @@ luabind::scope lua_register_events() {
|
||||
luabind::value("entity_variable_set", static_cast<int>(EVENT_ENTITY_VARIABLE_SET)),
|
||||
luabind::value("entity_variable_update", static_cast<int>(EVENT_ENTITY_VARIABLE_UPDATE)),
|
||||
luabind::value("aa_loss", static_cast<int>(EVENT_AA_LOSS)),
|
||||
luabind::value("read", static_cast<int>(EVENT_READ_ITEM))
|
||||
luabind::value("read", static_cast<int>(EVENT_READ_ITEM)),
|
||||
luabind::value("pet_command", static_cast<int>(EVENT_PET_COMMAND))
|
||||
)];
|
||||
}
|
||||
|
||||
|
||||
@ -122,6 +122,16 @@ Lua_Mob Lua_Group::GetMember(int member_index) {
|
||||
return self->members[member_index];
|
||||
}
|
||||
|
||||
uint8 Lua_Group::GetMemberRole(Lua_Mob member) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMemberRole(member);
|
||||
}
|
||||
|
||||
uint8 Lua_Group::GetMemberRole(const char* name) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMemberRole(name);
|
||||
}
|
||||
|
||||
bool Lua_Group::DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name)
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
@ -155,6 +165,8 @@ luabind::scope lua_register_group() {
|
||||
.def("GetLeaderName", (const char*(Lua_Group::*)(void))&Lua_Group::GetLeaderName)
|
||||
.def("GetLowestLevel", (uint32(Lua_Group::*)(void))&Lua_Group::GetLowestLevel)
|
||||
.def("GetMember", (Lua_Mob(Lua_Group::*)(int))&Lua_Group::GetMember)
|
||||
.def("GetMemberRole", (uint8(Lua_Group::*)(Lua_Mob))&Lua_Group::GetMemberRole)
|
||||
.def("GetMemberRole", (uint8(Lua_Group::*)(const char*))&Lua_Group::GetMemberRole)
|
||||
.def("GetTotalGroupDamage", (uint32(Lua_Group::*)(Lua_Mob))&Lua_Group::GetTotalGroupDamage)
|
||||
.def("GroupCount", (int(Lua_Group::*)(void))&Lua_Group::GroupCount)
|
||||
.def("GroupMessage", (void(Lua_Group::*)(Lua_Mob,const char*))&Lua_Group::GroupMessage)
|
||||
|
||||
@ -49,6 +49,8 @@ public:
|
||||
void TeleportGroup(Lua_Mob sender, uint32 zone_id, uint32 instance_id, float x, float y, float z, float h);
|
||||
int GetID();
|
||||
Lua_Mob GetMember(int member_index);
|
||||
uint8 GetMemberRole(Lua_Mob member);
|
||||
uint8 GetMemberRole(const char* name);
|
||||
bool DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name);
|
||||
bool DoesAnyMemberHaveExpeditionLockout(std::string expedition_name, std::string event_name, int max_check_count);
|
||||
};
|
||||
|
||||
@ -1241,12 +1241,12 @@ float Lua_Mob::GetAssistRange() {
|
||||
return self->GetAssistRange();
|
||||
}
|
||||
|
||||
void Lua_Mob::SetPetOrder(int order) {
|
||||
void Lua_Mob::SetPetOrder(uint8 pet_order) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetPetOrder(static_cast<Mob::eStandingPetOrder>(order));
|
||||
self->SetPetOrder(pet_order);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetPetOrder() {
|
||||
uint8 Lua_Mob::GetPetOrder() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetPetOrder();
|
||||
}
|
||||
@ -3482,6 +3482,54 @@ void Lua_Mob::BuffFadeSongs()
|
||||
self->BuffFadeSongs();
|
||||
}
|
||||
|
||||
luabind::object Lua_Mob::GetPausedTimers(lua_State* L) {
|
||||
auto t = luabind::newtable(L);
|
||||
if (d_) {
|
||||
auto self = reinterpret_cast<NativeType*>(d_);
|
||||
auto l = quest_manager.GetPausedTimers(self);
|
||||
int i = 1;
|
||||
for (const auto& v : l) {
|
||||
t[i] = v;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
luabind::object Lua_Mob::GetTimers(lua_State* L) {
|
||||
auto t = luabind::newtable(L);
|
||||
if (d_) {
|
||||
auto self = reinterpret_cast<NativeType*>(d_);
|
||||
auto l = quest_manager.GetTimers(self);
|
||||
int i = 1;
|
||||
for (const auto& v : l) {
|
||||
t[i] = v;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
uint8 Lua_Mob::GetPetType()
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetPetType();
|
||||
}
|
||||
|
||||
std::string Lua_Mob::GetPetTypeName()
|
||||
{
|
||||
Lua_Safe_Call_String();
|
||||
return PetType::GetName(self->GetPetType());
|
||||
}
|
||||
|
||||
void Lua_Mob::SetPetType(uint8 pet_type)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetPetType(pet_type);
|
||||
}
|
||||
|
||||
luabind::scope lua_register_mob() {
|
||||
return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
|
||||
.def(luabind::constructor<>())
|
||||
@ -3822,8 +3870,11 @@ luabind::scope lua_register_mob() {
|
||||
.def("GetOwner", &Lua_Mob::GetOwner)
|
||||
.def("GetOwnerID", &Lua_Mob::GetOwnerID)
|
||||
.def("GetPR", &Lua_Mob::GetPR)
|
||||
.def("GetPausedTimers", &Lua_Mob::GetPausedTimers)
|
||||
.def("GetPet", &Lua_Mob::GetPet)
|
||||
.def("GetPetOrder", (int(Lua_Mob::*)(void))&Lua_Mob::GetPetOrder)
|
||||
.def("GetPetOrder", (uint8(Lua_Mob::*)(void))&Lua_Mob::GetPetOrder)
|
||||
.def("GetPetType", &Lua_Mob::GetPetType)
|
||||
.def("GetPetTypeName", &Lua_Mob::GetPetTypeName)
|
||||
.def("GetPhR", &Lua_Mob::GetPhR)
|
||||
.def("GetRace", &Lua_Mob::GetRace)
|
||||
.def("GetRaceName", &Lua_Mob::GetRaceName)
|
||||
@ -3847,6 +3898,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("GetTarget", &Lua_Mob::GetTarget)
|
||||
.def("GetTexture", &Lua_Mob::GetTexture)
|
||||
.def("GetTimerDurationMS", &Lua_Mob::GetTimerDurationMS)
|
||||
.def("GetTimers", &Lua_Mob::GetTimers)
|
||||
.def("GetUltimateOwner", &Lua_Mob::GetUltimateOwner)
|
||||
.def("GetWIS", &Lua_Mob::GetWIS)
|
||||
.def("GetWalkspeed", &Lua_Mob::GetWalkspeed)
|
||||
@ -3908,7 +3960,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("IsPausedTimer", &Lua_Mob::IsPausedTimer)
|
||||
.def("IsPet", (bool(Lua_Mob::*)(void))&Lua_Mob::IsPet)
|
||||
.def("IsPetOwnerBot", &Lua_Mob::IsPetOwnerBot)
|
||||
.def("IsPetOwnerClient", &Lua_Mob::IsPetOwnerClient)
|
||||
.def("IsPetOwnerClient", &Lua_Mob::IsPetOwnerClient)
|
||||
.def("IsPetOwnerNPC", &Lua_Mob::IsPetOwnerNPC)
|
||||
.def("IsPetOwnerOfClientBot", &Lua_Mob::IsPetOwnerOfClientBot)
|
||||
.def("IsPureMeleeClass", &Lua_Mob::IsPureMeleeClass)
|
||||
@ -4017,7 +4069,8 @@ luabind::scope lua_register_mob() {
|
||||
.def("SetMana", &Lua_Mob::SetMana)
|
||||
.def("SetOOCRegen", (void(Lua_Mob::*)(int64))&Lua_Mob::SetOOCRegen)
|
||||
.def("SetPet", &Lua_Mob::SetPet)
|
||||
.def("SetPetOrder", (void(Lua_Mob::*)(int))&Lua_Mob::SetPetOrder)
|
||||
.def("SetPetOrder", (void(Lua_Mob::*)(uint8))&Lua_Mob::SetPetOrder)
|
||||
.def("SetPetType", &Lua_Mob::SetPetType)
|
||||
.def("SetPseudoRoot", (void(Lua_Mob::*)(bool))&Lua_Mob::SetPseudoRoot)
|
||||
.def("SetRace", (void(Lua_Mob::*)(uint16))&Lua_Mob::SetRace)
|
||||
.def("SetRunning", (void(Lua_Mob::*)(bool))&Lua_Mob::SetRunning)
|
||||
|
||||
@ -280,8 +280,8 @@ public:
|
||||
bool IsAIControlled();
|
||||
float GetAggroRange();
|
||||
float GetAssistRange();
|
||||
void SetPetOrder(int order);
|
||||
int GetPetOrder();
|
||||
void SetPetOrder(uint8 pet_order);
|
||||
uint8 GetPetOrder();
|
||||
bool IsRoamer();
|
||||
bool IsRooted();
|
||||
bool IsEngaged();
|
||||
@ -574,7 +574,7 @@ public:
|
||||
bool IsFamiliar();
|
||||
bool IsTargetLockPet();
|
||||
bool IsPetOwnerBot();
|
||||
bool IsPetOwnerClient();
|
||||
bool IsPetOwnerClient();
|
||||
bool IsPetOwnerNPC();
|
||||
bool IsPetOwnerOfClientBot();
|
||||
bool IsDestructibleObject();
|
||||
@ -612,6 +612,11 @@ public:
|
||||
void BuffFadeDetrimentalByCaster(Lua_Mob caster);
|
||||
void BuffFadeNonPersistDeath();
|
||||
void BuffFadeSongs();
|
||||
luabind::object GetPausedTimers(lua_State* L);
|
||||
luabind::object GetTimers(lua_State* L);
|
||||
uint8 GetPetType();
|
||||
std::string GetPetTypeName();
|
||||
void SetPetType(uint8 pet_type);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -945,10 +945,16 @@ bool Lua_NPC::IsResumedFromZoneSuspend()
|
||||
return self->IsResumedFromZoneSuspend();
|
||||
}
|
||||
|
||||
void Lua_NPC::SetNPCTintIndex(uint32 id)
|
||||
void Lua_NPC::SetNPCTintIndex(uint32 index)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->SendAppearancePacket(AppearanceType::NPCTintIndex, id);
|
||||
self->SetNPCTintIndex(index);
|
||||
}
|
||||
|
||||
uint32 Lua_NPC::GetNPCTintIndex()
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetNPCTintIndex();
|
||||
}
|
||||
|
||||
luabind::scope lua_register_npc() {
|
||||
@ -1018,6 +1024,7 @@ luabind::scope lua_register_npc() {
|
||||
.def("GetNPCSpellsEffectsID", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsEffectsID)
|
||||
.def("GetNPCSpellsID", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID)
|
||||
.def("GetNPCStat", (float(Lua_NPC::*)(std::string))&Lua_NPC::GetNPCStat)
|
||||
.def("GetNPCTintIndex", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetNPCTintIndex)
|
||||
.def("GetPetSpellID", (int(Lua_NPC::*)(void))&Lua_NPC::GetPetSpellID)
|
||||
.def("GetPlatinum", (uint32(Lua_NPC::*)(void))&Lua_NPC::GetPlatinum)
|
||||
.def("GetPrimSkill", (int(Lua_NPC::*)(void))&Lua_NPC::GetPrimSkill)
|
||||
|
||||
@ -200,6 +200,7 @@ public:
|
||||
Lua_Spawn GetSpawn(lua_State* L);
|
||||
bool IsResumedFromZoneSuspend();
|
||||
void SetNPCTintIndex(uint32 id);
|
||||
uint32 GetNPCTintIndex();
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -188,7 +188,8 @@ const char *LuaEvents[_LargestEventID] = {
|
||||
"event_entity_variable_update",
|
||||
"event_aa_loss",
|
||||
"event_spell_blocked",
|
||||
"event_read_item"
|
||||
"event_read_item",
|
||||
"event_pet_command"
|
||||
};
|
||||
|
||||
extern Zone *zone;
|
||||
@ -219,6 +220,7 @@ LuaParser::LuaParser() {
|
||||
SpellArgumentDispatch[i] = handle_spell_null;
|
||||
EncounterArgumentDispatch[i] = handle_encounter_null;
|
||||
BotArgumentDispatch[i] = handle_bot_null;
|
||||
ZoneArgumentDispatch[i] = handle_zone_null;
|
||||
}
|
||||
|
||||
NPCArgumentDispatch[EVENT_SAY] = handle_npc_event_say;
|
||||
@ -263,6 +265,7 @@ LuaParser::LuaParser() {
|
||||
NPCArgumentDispatch[EVENT_ENTITY_VARIABLE_SET] = handle_npc_entity_variable;
|
||||
NPCArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_npc_entity_variable;
|
||||
NPCArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_npc_spell_blocked;
|
||||
NPCArgumentDispatch[EVENT_PET_COMMAND] = handle_npc_pet_command;
|
||||
|
||||
PlayerArgumentDispatch[EVENT_SAY] = handle_player_say;
|
||||
PlayerArgumentDispatch[EVENT_ENVIRONMENTAL_DAMAGE] = handle_player_environmental_damage;
|
||||
@ -354,6 +357,7 @@ LuaParser::LuaParser() {
|
||||
PlayerArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_player_spell_blocked;
|
||||
PlayerArgumentDispatch[EVENT_READ_ITEM] = handle_player_read_item;
|
||||
PlayerArgumentDispatch[EVENT_CONNECT] = handle_player_connect;
|
||||
PlayerArgumentDispatch[EVENT_PET_COMMAND] = handle_player_pet_command;
|
||||
|
||||
ItemArgumentDispatch[EVENT_ITEM_CLICK] = handle_item_click;
|
||||
ItemArgumentDispatch[EVENT_ITEM_CLICK_CAST] = handle_item_click;
|
||||
@ -409,6 +413,23 @@ LuaParser::LuaParser() {
|
||||
BotArgumentDispatch[EVENT_ENTITY_VARIABLE_SET] = handle_bot_entity_variable;
|
||||
BotArgumentDispatch[EVENT_ENTITY_VARIABLE_UPDATE] = handle_bot_entity_variable;
|
||||
BotArgumentDispatch[EVENT_SPELL_BLOCKED] = handle_bot_spell_blocked;
|
||||
|
||||
ZoneArgumentDispatch[EVENT_CLICK_DOOR] = handle_zone_click_door;
|
||||
ZoneArgumentDispatch[EVENT_CLICK_OBJECT] = handle_zone_click_object;
|
||||
ZoneArgumentDispatch[EVENT_DEATH_ZONE] = handle_zone_death;
|
||||
ZoneArgumentDispatch[EVENT_DESPAWN_ZONE] = handle_zone_despawn;
|
||||
ZoneArgumentDispatch[EVENT_ENTER_ZONE] = handle_zone_enter;
|
||||
ZoneArgumentDispatch[EVENT_LOOT_ZONE] = handle_zone_loot;
|
||||
ZoneArgumentDispatch[EVENT_PAYLOAD] = handle_zone_payload;
|
||||
ZoneArgumentDispatch[EVENT_PLAYER_PICKUP] = handle_zone_pickup;
|
||||
ZoneArgumentDispatch[EVENT_POPUP_RESPONSE] = handle_zone_popup;
|
||||
ZoneArgumentDispatch[EVENT_SIGNAL] = handle_zone_signal;
|
||||
ZoneArgumentDispatch[EVENT_SPAWN_ZONE] = handle_zone_spawn;
|
||||
ZoneArgumentDispatch[EVENT_TIMER] = handle_zone_timer;
|
||||
ZoneArgumentDispatch[EVENT_TIMER_PAUSE] = handle_zone_timer_pause_resume_start;
|
||||
ZoneArgumentDispatch[EVENT_TIMER_RESUME] = handle_zone_timer_pause_resume_start;
|
||||
ZoneArgumentDispatch[EVENT_TIMER_START] = handle_zone_timer_pause_resume_start;
|
||||
ZoneArgumentDispatch[EVENT_TIMER_STOP] = handle_zone_timer_stop;
|
||||
#endif
|
||||
|
||||
L = nullptr;
|
||||
@ -489,7 +510,13 @@ int LuaParser::_EventNPC(std::string package_name, QuestEventID evt, NPC* npc, M
|
||||
arg_function(this, L, npc, init, data, extra_data, extra_pointers);
|
||||
Client *c = (init && init->IsClient()) ? init->CastToClient() : nullptr;
|
||||
|
||||
quest_manager.StartQuest(npc, c);
|
||||
RunningQuest q;
|
||||
|
||||
q.owner = npc;
|
||||
q.initiator = c;
|
||||
|
||||
quest_manager.StartQuest(q);
|
||||
|
||||
if(lua_pcall(L, 1, 1, start + 1)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -582,7 +609,13 @@ int LuaParser::_EventPlayer(std::string package_name, QuestEventID evt, Client *
|
||||
auto arg_function = PlayerArgumentDispatch[evt];
|
||||
arg_function(this, L, client, data, extra_data, extra_pointers);
|
||||
|
||||
quest_manager.StartQuest(client, client);
|
||||
RunningQuest q;
|
||||
|
||||
q.owner = client;
|
||||
q.initiator = client;
|
||||
|
||||
quest_manager.StartQuest(q);
|
||||
|
||||
if(lua_pcall(L, 1, 1, start + 1)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -666,7 +699,14 @@ int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *cl
|
||||
auto arg_function = ItemArgumentDispatch[evt];
|
||||
arg_function(this, L, client, item, mob, data, extra_data, extra_pointers);
|
||||
|
||||
quest_manager.StartQuest(client, client, item);
|
||||
RunningQuest q;
|
||||
|
||||
q.owner = client;
|
||||
q.initiator = client;
|
||||
q.questitem = item;
|
||||
|
||||
quest_manager.StartQuest(q);
|
||||
|
||||
if(lua_pcall(L, 1, 1, start + 1)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -748,7 +788,14 @@ int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, Mob* mob,
|
||||
auto arg_function = SpellArgumentDispatch[evt];
|
||||
arg_function(this, L, mob, client, spell_id, data, extra_data, extra_pointers);
|
||||
|
||||
quest_manager.StartQuest(mob, client, nullptr, const_cast<SPDat_Spell_Struct*>(&spells[spell_id]));
|
||||
RunningQuest q;
|
||||
|
||||
q.owner = client;
|
||||
q.initiator = client;
|
||||
q.questspell = const_cast<SPDat_Spell_Struct*>(&spells[spell_id]);
|
||||
|
||||
quest_manager.StartQuest(q);
|
||||
|
||||
if(lua_pcall(L, 1, 1, start + 1)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -814,7 +861,13 @@ int LuaParser::_EventEncounter(std::string package_name, QuestEventID evt, std::
|
||||
auto arg_function = EncounterArgumentDispatch[evt];
|
||||
arg_function(this, L, enc, data, extra_data, extra_pointers);
|
||||
|
||||
quest_manager.StartQuest(enc, nullptr, nullptr, nullptr, encounter_name);
|
||||
RunningQuest q;
|
||||
|
||||
q.owner = enc;
|
||||
q.encounter = encounter_name;
|
||||
|
||||
quest_manager.StartQuest(q);
|
||||
|
||||
if(lua_pcall(L, 1, 1, start + 1)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -1757,7 +1810,13 @@ int LuaParser::_EventBot(
|
||||
arg_function(this, L, bot, init, data, extra_data, extra_pointers);
|
||||
auto* c = (init && init->IsClient()) ? init->CastToClient() : nullptr;
|
||||
|
||||
quest_manager.StartQuest(bot, c);
|
||||
RunningQuest q;
|
||||
|
||||
q.owner = bot;
|
||||
q.initiator = c;
|
||||
|
||||
quest_manager.StartQuest(q);
|
||||
|
||||
if(lua_pcall(L, 1, 1, start + 1)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -1936,7 +1995,13 @@ int LuaParser::_EventMerc(
|
||||
arg_function(this, L, merc, init, data, extra_data, extra_pointers);
|
||||
auto* c = (init && init->IsClient()) ? init->CastToClient() : nullptr;
|
||||
|
||||
quest_manager.StartQuest(merc, c);
|
||||
RunningQuest q;
|
||||
|
||||
q.owner = merc;
|
||||
q.initiator = c;
|
||||
|
||||
quest_manager.StartQuest(q);
|
||||
|
||||
if(lua_pcall(L, 1, 1, start + 1)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
@ -2039,3 +2104,190 @@ void LuaParser::LoadMercScript(std::string filename) {
|
||||
void LuaParser::LoadGlobalMercScript(std::string filename) {
|
||||
LoadScript(filename, "global_merc");
|
||||
}
|
||||
|
||||
int LuaParser::EventZone(
|
||||
QuestEventID evt,
|
||||
Zone *zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
evt = ConvertLuaEvent(evt);
|
||||
if (evt >= _LargestEventID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!zone) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!ZoneHasQuestSub(evt)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _EventZone("zone", evt, zone, data, extra_data, extra_pointers);
|
||||
}
|
||||
|
||||
int LuaParser::EventGlobalZone(
|
||||
QuestEventID evt,
|
||||
Zone *zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
evt = ConvertLuaEvent(evt);
|
||||
if (evt >= _LargestEventID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!zone) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!GlobalZoneHasQuestSub(evt)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return _EventZone("global_zone", evt, zone, data, extra_data, extra_pointers);
|
||||
}
|
||||
|
||||
int LuaParser::_EventZone(
|
||||
std::string package_name,
|
||||
QuestEventID evt,
|
||||
Zone *zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers,
|
||||
luabind::adl::object *l_func
|
||||
) {
|
||||
const char *sub_name = LuaEvents[evt];
|
||||
int start = lua_gettop(L);
|
||||
|
||||
try {
|
||||
int npop = 2;
|
||||
PushErrorHandler(L);
|
||||
if(l_func != nullptr) {
|
||||
l_func->push(L);
|
||||
} else {
|
||||
lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str());
|
||||
lua_getfield(L, -1, sub_name);
|
||||
npop = 3;
|
||||
}
|
||||
|
||||
lua_createtable(L, 0, 0);
|
||||
//push self
|
||||
Lua_Zone l_zone(zone);
|
||||
luabind::adl::object l_zone_o = luabind::adl::object(L, l_zone);
|
||||
l_zone_o.push(L);
|
||||
lua_setfield(L, -2, "self");
|
||||
|
||||
auto arg_function = ZoneArgumentDispatch[evt];
|
||||
arg_function(this, L, zone, data, extra_data, extra_pointers);
|
||||
|
||||
RunningQuest q;
|
||||
|
||||
q.zone = zone;
|
||||
|
||||
quest_manager.StartQuest(q);
|
||||
|
||||
if(lua_pcall(L, 1, 1, start + 1)) {
|
||||
std::string error = lua_tostring(L, -1);
|
||||
AddError(error);
|
||||
quest_manager.EndQuest();
|
||||
lua_pop(L, npop);
|
||||
return 0;
|
||||
}
|
||||
quest_manager.EndQuest();
|
||||
|
||||
if(lua_isnumber(L, -1)) {
|
||||
int ret = static_cast<int>(lua_tointeger(L, -1));
|
||||
lua_pop(L, npop);
|
||||
return ret;
|
||||
}
|
||||
|
||||
lua_pop(L, npop);
|
||||
} catch(std::exception &ex) {
|
||||
AddError(
|
||||
fmt::format(
|
||||
"Lua Exception | [{}] for Zone [{}] in [{}]: {}",
|
||||
sub_name,
|
||||
zone->GetShortName(),
|
||||
package_name,
|
||||
ex.what()
|
||||
)
|
||||
);
|
||||
|
||||
//Restore our stack to the best of our ability
|
||||
int end = lua_gettop(L);
|
||||
int n = end - start;
|
||||
if(n > 0) {
|
||||
lua_pop(L, n);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaParser::DispatchEventZone(
|
||||
QuestEventID evt,
|
||||
Zone *zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
evt = ConvertLuaEvent(evt);
|
||||
if (evt >= _LargestEventID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string package_name = "zone";
|
||||
|
||||
auto iter = lua_encounter_events_registered.find(package_name);
|
||||
if (iter == lua_encounter_events_registered.end()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
auto riter = iter->second.begin();
|
||||
while (riter != iter->second.end()) {
|
||||
if (riter->event_id == evt) {
|
||||
package_name = fmt::format("encounter_{}", riter->encounter_name);
|
||||
int i = _EventZone(package_name, evt, zone, data, extra_data, extra_pointers, &riter->lua_reference);
|
||||
if (i != 0) {
|
||||
ret = i;
|
||||
}
|
||||
}
|
||||
|
||||
++riter;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool LuaParser::ZoneHasQuestSub(QuestEventID evt) {
|
||||
evt = ConvertLuaEvent(evt);
|
||||
if (evt >= _LargestEventID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *subname = LuaEvents[evt];
|
||||
return HasFunction(subname, "zone");
|
||||
}
|
||||
|
||||
bool LuaParser::GlobalZoneHasQuestSub(QuestEventID evt) {
|
||||
evt = ConvertLuaEvent(evt);
|
||||
if (evt >= _LargestEventID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *subname = LuaEvents[evt];
|
||||
return HasFunction(subname, "global_zone");
|
||||
}
|
||||
|
||||
void LuaParser::LoadZoneScript(std::string filename) {
|
||||
LoadScript(filename, "zone");
|
||||
}
|
||||
|
||||
void LuaParser::LoadGlobalZoneScript(std::string filename) {
|
||||
LoadScript(filename, "global_zone");
|
||||
}
|
||||
|
||||
@ -125,6 +125,20 @@ public:
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
virtual int EventZone(
|
||||
QuestEventID evt,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
virtual int EventGlobalZone(
|
||||
QuestEventID evt,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
virtual bool HasQuestSub(uint32 npc_id, QuestEventID evt);
|
||||
virtual bool HasGlobalQuestSub(QuestEventID evt);
|
||||
@ -138,6 +152,8 @@ public:
|
||||
virtual bool GlobalBotHasQuestSub(QuestEventID evt);
|
||||
virtual bool MercHasQuestSub(QuestEventID evt);
|
||||
virtual bool GlobalMercHasQuestSub(QuestEventID evt);
|
||||
virtual bool ZoneHasQuestSub(QuestEventID evt);
|
||||
virtual bool GlobalZoneHasQuestSub(QuestEventID evt);
|
||||
|
||||
virtual void LoadNPCScript(std::string filename, int npc_id);
|
||||
virtual void LoadGlobalNPCScript(std::string filename);
|
||||
@ -150,6 +166,8 @@ public:
|
||||
virtual void LoadGlobalBotScript(std::string filename);
|
||||
virtual void LoadMercScript(std::string filename);
|
||||
virtual void LoadGlobalMercScript(std::string filename);
|
||||
virtual void LoadZoneScript(std::string filename);
|
||||
virtual void LoadGlobalZoneScript(std::string filename);
|
||||
|
||||
virtual void AddVar(std::string name, std::string val);
|
||||
virtual std::string GetVar(std::string name);
|
||||
@ -207,6 +225,13 @@ public:
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
virtual int DispatchEventZone(
|
||||
QuestEventID evt,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
static LuaParser* Instance() {
|
||||
static LuaParser inst;
|
||||
@ -307,6 +332,15 @@ private:
|
||||
std::vector<std::any>* extra_pointers,
|
||||
luabind::adl::object* l_func = nullptr
|
||||
);
|
||||
int _EventZone(
|
||||
std::string package_name,
|
||||
QuestEventID evt,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers,
|
||||
luabind::adl::object* l_func = nullptr
|
||||
);
|
||||
|
||||
void LoadScript(std::string filename, std::string package_name);
|
||||
void MapFunctions(lua_State *L);
|
||||
@ -317,12 +351,13 @@ private:
|
||||
std::vector<LuaMod> mods_;
|
||||
lua_State *L;
|
||||
|
||||
NPCArgumentHandler NPCArgumentDispatch[_LargestEventID];
|
||||
PlayerArgumentHandler PlayerArgumentDispatch[_LargestEventID];
|
||||
ItemArgumentHandler ItemArgumentDispatch[_LargestEventID];
|
||||
SpellArgumentHandler SpellArgumentDispatch[_LargestEventID];
|
||||
NPCArgumentHandler NPCArgumentDispatch[_LargestEventID];
|
||||
PlayerArgumentHandler PlayerArgumentDispatch[_LargestEventID];
|
||||
ItemArgumentHandler ItemArgumentDispatch[_LargestEventID];
|
||||
SpellArgumentHandler SpellArgumentDispatch[_LargestEventID];
|
||||
EncounterArgumentHandler EncounterArgumentDispatch[_LargestEventID];
|
||||
BotArgumentHandler BotArgumentDispatch[_LargestEventID];
|
||||
BotArgumentHandler BotArgumentDispatch[_LargestEventID];
|
||||
ZoneArgumentHandler ZoneArgumentDispatch[_LargestEventID];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -668,6 +668,23 @@ void handle_npc_spell_blocked(
|
||||
lua_setfield(L, -2, "cast_spell");
|
||||
}
|
||||
|
||||
void handle_npc_pet_command(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
NPC* npc,
|
||||
Mob *init,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
)
|
||||
{
|
||||
lua_pushinteger(L, extra_data);
|
||||
lua_setfield(L, -2, "pet_command");
|
||||
|
||||
lua_pushstring(L, data.c_str());
|
||||
lua_setfield(L, -2, "pet_command_name");
|
||||
}
|
||||
|
||||
// Player
|
||||
void handle_player_say(
|
||||
QuestInterface *parse,
|
||||
@ -1829,6 +1846,22 @@ void handle_player_connect(
|
||||
lua_setfield(L, -2, "is_first_login");
|
||||
}
|
||||
|
||||
void handle_player_pet_command(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Client* client,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
)
|
||||
{
|
||||
lua_pushinteger(L, extra_data);
|
||||
lua_setfield(L, -2, "pet_command");
|
||||
|
||||
lua_pushstring(L, data.c_str());
|
||||
lua_setfield(L, -2, "pet_command_name");
|
||||
}
|
||||
|
||||
// Item
|
||||
void handle_item_click(
|
||||
QuestInterface *parse,
|
||||
@ -2873,4 +2906,293 @@ void handle_bot_spell_blocked(
|
||||
lua_setfield(L, -2, "cast_spell");
|
||||
}
|
||||
|
||||
// Zone
|
||||
|
||||
void handle_zone_null(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
}
|
||||
|
||||
void handle_zone_click_door(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Lua_Door l_door(std::any_cast<Doors*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_door_o = luabind::adl::object(L, l_door);
|
||||
l_door_o.push(L);
|
||||
lua_setfield(L, -2, "door");
|
||||
|
||||
Lua_Client l_client(std::any_cast<Client*>(extra_pointers->at(1)));
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
}
|
||||
|
||||
void handle_zone_click_object(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Lua_Object l_object(std::any_cast<Object*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_object_o = luabind::adl::object(L, l_object);
|
||||
l_object_o.push(L);
|
||||
lua_setfield(L, -2, "object");
|
||||
|
||||
Lua_Client l_client(std::any_cast<Client*>(extra_pointers->at(1)));
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
}
|
||||
|
||||
void handle_zone_death(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Seperator sep(data.c_str());
|
||||
|
||||
Lua_Mob l_mob(std::any_cast<Mob*>(extra_pointers->at(2)));
|
||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||
l_mob_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||
lua_setfield(L, -2, "killer_id");
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "damage");
|
||||
|
||||
const uint32 spell_id = Strings::ToUnsignedInt(sep.arg[2]);
|
||||
if (IsValidSpell(spell_id)) {
|
||||
Lua_Spell l_spell(&spells[spell_id]);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
l_spell_o.push(L);
|
||||
lua_setfield(L, -2, "spell");
|
||||
} else {
|
||||
Lua_Spell l_spell(nullptr);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
l_spell_o.push(L);
|
||||
lua_setfield(L, -2, "spell");
|
||||
}
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||
lua_setfield(L, -2, "skill_id");
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[4]));
|
||||
lua_setfield(L, -2, "killed_entity_id");
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[5]));
|
||||
lua_setfield(L, -2, "combat_start_time");
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[6]));
|
||||
lua_setfield(L, -2, "combat_end_time");
|
||||
|
||||
lua_pushinteger(L, Strings::ToBigInt(sep.arg[7]));
|
||||
lua_setfield(L, -2, "damage_received");
|
||||
|
||||
lua_pushinteger(L, Strings::ToBigInt(sep.arg[8]));
|
||||
lua_setfield(L, -2, "healing_received");
|
||||
|
||||
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||
Lua_Corpse l_corpse(std::any_cast<Corpse*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse);
|
||||
l_corpse_o.push(L);
|
||||
lua_setfield(L, -2, "corpse");
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() >= 2) {
|
||||
Lua_NPC l_npc(std::any_cast<NPC*>(extra_pointers->at(1)));
|
||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||
l_npc_o.push(L);
|
||||
lua_setfield(L, -2, "killed");
|
||||
}
|
||||
}
|
||||
|
||||
void handle_zone_despawn(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Lua_NPC l_npc(std::any_cast<NPC*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||
l_npc_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
}
|
||||
|
||||
void handle_zone_enter(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Lua_Client l_client(std::any_cast<Client*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
}
|
||||
|
||||
void handle_zone_loot(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Lua_Client l_client(std::any_cast<Client*>(extra_pointers->at(2)));
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
|
||||
Lua_ItemInst l_item(std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||
l_item_o.push(L);
|
||||
lua_setfield(L, -2, "item");
|
||||
|
||||
Lua_Corpse l_corpse(std::any_cast<Corpse*>(extra_pointers->at(1)));
|
||||
luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse);
|
||||
l_corpse_o.push(L);
|
||||
lua_setfield(L, -2, "corpse");
|
||||
}
|
||||
|
||||
void handle_zone_payload(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Seperator sep(data.c_str());
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||
lua_setfield(L, -2, "payload_id");
|
||||
|
||||
lua_pushstring(L, sep.argplus[1]);
|
||||
lua_setfield(L, -2, "payload_value");
|
||||
}
|
||||
|
||||
void handle_zone_pickup(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Lua_ItemInst l_item(std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_item_o = luabind::adl::object(L, l_item);
|
||||
l_item_o.push(L);
|
||||
lua_setfield(L, -2, "item");
|
||||
|
||||
Lua_Client l_client(std::any_cast<Client*>(extra_pointers->at(1)));
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
}
|
||||
|
||||
void handle_zone_popup(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
lua_pushinteger(L, Strings::ToInt(data));
|
||||
lua_setfield(L, -2, "popup_id");
|
||||
|
||||
Lua_Client l_client(std::any_cast<Client*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
}
|
||||
|
||||
void handle_zone_signal(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
lua_pushinteger(L, Strings::ToInt(data));
|
||||
lua_setfield(L, -2, "signal");
|
||||
}
|
||||
|
||||
void handle_zone_spawn(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Lua_NPC l_npc(std::any_cast<NPC*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||
l_npc_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
}
|
||||
|
||||
void handle_zone_timer(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
lua_pushstring(L, data.c_str());
|
||||
lua_setfield(L, -2, "timer");
|
||||
}
|
||||
|
||||
void handle_zone_timer_pause_resume_start(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
Seperator sep(data.c_str());
|
||||
|
||||
lua_pushstring(L, sep.arg[0]);
|
||||
lua_setfield(L, -2, "timer");
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "duration");
|
||||
}
|
||||
|
||||
void handle_zone_timer_stop(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
lua_pushstring(L, data.c_str());
|
||||
lua_setfield(L, -2, "timer");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -9,6 +9,7 @@ typedef void(*SpellArgumentHandler)(QuestInterface*, lua_State*, Mob*, Client*,
|
||||
typedef void(*EncounterArgumentHandler)(QuestInterface*, lua_State*, Encounter* encounter, std::string, uint32, std::vector<std::any>*);
|
||||
typedef void(*BotArgumentHandler)(QuestInterface*, lua_State*, Bot*, Mob*, std::string, uint32, std::vector<std::any>*);
|
||||
typedef void(*MercArgumentHandler)(QuestInterface*, lua_State*, Merc*, Mob*, std::string, uint32, std::vector<std::any>*);
|
||||
typedef void(*ZoneArgumentHandler)(QuestInterface*, lua_State*, Zone*, std::string, uint32, std::vector<std::any>*);
|
||||
|
||||
// NPC
|
||||
void handle_npc_event_say(
|
||||
@ -261,6 +262,16 @@ void handle_npc_spell_blocked(
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_npc_pet_command(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
NPC* npc,
|
||||
Mob *init,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
// Player
|
||||
void handle_player_say(
|
||||
QuestInterface *parse,
|
||||
@ -874,6 +885,15 @@ void handle_player_connect(
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_player_pet_command(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Client* client,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
// Item
|
||||
void handle_item_click(
|
||||
QuestInterface *parse,
|
||||
@ -1278,5 +1298,141 @@ void handle_bot_spell_blocked(
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
// Zone
|
||||
void handle_zone_null(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_click_door(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_click_object(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_death(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_despawn(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_enter(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_loot(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_payload(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_pickup(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_popup(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_signal(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_spawn(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_timer(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_timer_pause_resume_start(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
void handle_zone_timer_stop(
|
||||
QuestInterface *parse,
|
||||
lua_State* L,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -772,6 +772,102 @@ bool Lua_Zone::VariableExists(const std::string& variable_name)
|
||||
return self->VariableExists(variable_name);
|
||||
}
|
||||
|
||||
uint32 Lua_Zone::GetTimerDuration(std::string name)
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetTimerDuration(name);
|
||||
}
|
||||
|
||||
uint32 Lua_Zone::GetTimerRemainingTime(std::string name)
|
||||
{
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetTimerRemainingTime(name);
|
||||
}
|
||||
|
||||
bool Lua_Zone::HasTimer(std::string name)
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->HasTimer(name);
|
||||
}
|
||||
|
||||
bool Lua_Zone::IsPausedTimer(std::string name)
|
||||
{
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsPausedTimer(name);
|
||||
}
|
||||
|
||||
void Lua_Zone::PauseTimer(std::string name)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->PauseTimer(name);
|
||||
}
|
||||
|
||||
void Lua_Zone::ResumeTimer(std::string name)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->ResumeTimer(name);
|
||||
}
|
||||
|
||||
void Lua_Zone::SetTimer(std::string name, uint32 duration)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetTimer(name, duration);
|
||||
}
|
||||
|
||||
void Lua_Zone::StopTimer(std::string name)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->StopTimer(name);
|
||||
}
|
||||
|
||||
void Lua_Zone::StopAllTimers()
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->StopAllTimers();
|
||||
}
|
||||
|
||||
void Lua_Zone::SendPayload(int payload_id, std::string payload_value)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->SendPayload(payload_id, payload_value);
|
||||
}
|
||||
|
||||
void Lua_Zone::Signal(int signal_id)
|
||||
{
|
||||
Lua_Safe_Call_Void();
|
||||
self->Signal(signal_id);
|
||||
}
|
||||
|
||||
luabind::object Lua_Zone::GetPausedTimers(lua_State* L) {
|
||||
auto t = luabind::newtable(L);
|
||||
if (d_) {
|
||||
auto self = reinterpret_cast<NativeType*>(d_);
|
||||
auto l = self->GetPausedTimers();
|
||||
int i = 1;
|
||||
for (const auto& v : l) {
|
||||
t[i] = v;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
luabind::object Lua_Zone::GetTimers(lua_State* L) {
|
||||
auto t = luabind::newtable(L);
|
||||
if (d_) {
|
||||
auto self = reinterpret_cast<NativeType*>(d_);
|
||||
auto l = self->GetTimers();
|
||||
int i = 1;
|
||||
for (const auto& v : l) {
|
||||
t[i] = v;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
luabind::scope lua_register_zone() {
|
||||
return luabind::class_<Lua_Zone>("Zones")
|
||||
.def(luabind::constructor<>())
|
||||
@ -840,6 +936,7 @@ luabind::scope lua_register_zone() {
|
||||
.def("GetMinimumStatus", &Lua_Zone::GetMinimumStatus)
|
||||
.def("GetNote", &Lua_Zone::GetNote)
|
||||
.def("GetNPCMaximumAggroDistance", &Lua_Zone::GetNPCMaximumAggroDistance)
|
||||
.def("GetPausedTimers", &Lua_Zone::GetPausedTimers)
|
||||
.def("GetPEQZone", &Lua_Zone::GetPEQZone)
|
||||
.def("GetRainChance", (int(Lua_Zone::*)(void))&Lua_Zone::GetRainChance)
|
||||
.def("GetRainChance", (int(Lua_Zone::*)(uint8))&Lua_Zone::GetRainChance)
|
||||
@ -861,6 +958,9 @@ luabind::scope lua_register_zone() {
|
||||
.def("GetSnowDuration", (int(Lua_Zone::*)(uint8))&Lua_Zone::GetSnowDuration)
|
||||
.def("GetTimeType", &Lua_Zone::GetTimeType)
|
||||
.def("GetTimeZone", &Lua_Zone::GetTimeZone)
|
||||
.def("GetTimerDuration", &Lua_Zone::GetTimerDuration)
|
||||
.def("GetTimerRemainingTime", &Lua_Zone::GetTimerRemainingTime)
|
||||
.def("GetTimers", &Lua_Zone::GetTimers)
|
||||
.def("GetZoneDescription", &Lua_Zone::GetZoneDescription)
|
||||
.def("GetZoneID", &Lua_Zone::GetZoneID)
|
||||
.def("GetZoneType", &Lua_Zone::GetZoneType)
|
||||
@ -875,10 +975,12 @@ luabind::scope lua_register_zone() {
|
||||
.def("HasMap", &Lua_Zone::HasMap)
|
||||
.def("HasWaterMap", &Lua_Zone::HasWaterMap)
|
||||
.def("HasWeather", &Lua_Zone::HasWeather)
|
||||
.def("HasTimer", &Lua_Zone::HasTimer)
|
||||
.def("IsCity", &Lua_Zone::IsCity)
|
||||
.def("IsHotzone", &Lua_Zone::IsHotzone)
|
||||
.def("IsInstancePersistent", &Lua_Zone::IsInstancePersistent)
|
||||
.def("IsIdleWhenEmpty", &Lua_Zone::IsIdleWhenEmpty)
|
||||
.def("IsPausedTimer", &Lua_Zone::IsPausedTimer)
|
||||
.def("IsPVPZone", &Lua_Zone::IsPVPZone)
|
||||
.def("IsRaining", &Lua_Zone::IsRaining)
|
||||
.def("IsSnowing", &Lua_Zone::IsSnowing)
|
||||
@ -887,8 +989,11 @@ luabind::scope lua_register_zone() {
|
||||
.def("IsStaticZone", &Lua_Zone::IsStaticZone)
|
||||
.def("IsUCSServerAvailable", &Lua_Zone::IsUCSServerAvailable)
|
||||
.def("IsWaterZone", &Lua_Zone::IsWaterZone)
|
||||
.def("PauseTimer", &Lua_Zone::PauseTimer)
|
||||
.def("Repop", (void(Lua_Zone::*)(void))&Lua_Zone::Repop)
|
||||
.def("Repop", (void(Lua_Zone::*)(bool))&Lua_Zone::Repop)
|
||||
.def("ResumeTimer", &Lua_Zone::ResumeTimer)
|
||||
.def("SendPayload", &Lua_Zone::SendPayload)
|
||||
.def("SetAAEXPModifier", &Lua_Zone::SetAAEXPModifier)
|
||||
.def("SetAAEXPModifierByCharacterID", &Lua_Zone::SetAAEXPModifierByCharacterID)
|
||||
.def("SetBucket", (void(Lua_Zone::*)(const std::string&,const std::string&))&Lua_Zone::SetBucket)
|
||||
@ -898,8 +1003,12 @@ luabind::scope lua_register_zone() {
|
||||
.def("SetInstanceTimer", &Lua_Zone::SetInstanceTimer)
|
||||
.def("SetInstanceTimeRemaining", &Lua_Zone::SetInstanceTimeRemaining)
|
||||
.def("SetIsHotzone", &Lua_Zone::SetIsHotzone)
|
||||
.def("SetTimer", &Lua_Zone::SetTimer)
|
||||
.def("SetVariable", &Lua_Zone::SetVariable)
|
||||
.def("ShowZoneGlobalLoot", &Lua_Zone::ShowZoneGlobalLoot)
|
||||
.def("Signal", &Lua_Zone::Signal)
|
||||
.def("StopTimer", &Lua_Zone::StopTimer)
|
||||
.def("StopAllTimers", &Lua_Zone::StopAllTimers)
|
||||
.def("VariableExists", &Lua_Zone::VariableExists);
|
||||
}
|
||||
|
||||
|
||||
@ -147,6 +147,19 @@ public:
|
||||
luabind::object GetVariables(lua_State* L);
|
||||
void SetVariable(const std::string& variable_name, const std::string& variable_value);
|
||||
bool VariableExists(const std::string& variable_name);
|
||||
uint32 GetTimerDuration(std::string name);
|
||||
uint32 GetTimerRemainingTime(std::string name);
|
||||
bool HasTimer(std::string name);
|
||||
bool IsPausedTimer(std::string name);
|
||||
void PauseTimer(std::string name);
|
||||
void ResumeTimer(std::string name);
|
||||
void SetTimer(std::string name, uint32 duration);
|
||||
void StopTimer(std::string name);
|
||||
void StopAllTimers();
|
||||
void Signal(int signal_id);
|
||||
void SendPayload(int payload_id, std::string payload_value);
|
||||
luabind::object GetPausedTimers(lua_State* L);
|
||||
luabind::object GetTimers(lua_State* L);
|
||||
|
||||
// data buckets
|
||||
void SetBucket(const std::string& bucket_name, const std::string& bucket_value);
|
||||
|
||||
@ -555,11 +555,11 @@ int main(int argc, char **argv)
|
||||
LogInfo("Starting EQ Network server on port [{}]", Config->ZonePort);
|
||||
|
||||
EQStreamManagerInterfaceOptions opts(Config->ZonePort, false, RuleB(Network, CompressZoneStream));
|
||||
opts.daybreak_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
opts.daybreak_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
opts.daybreak_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
opts.daybreak_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
opts.daybreak_options.outgoing_data_rate = RuleR(Network, ClientDataRate);
|
||||
opts.reliable_stream_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
opts.reliable_stream_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
opts.reliable_stream_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
opts.reliable_stream_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
opts.reliable_stream_options.outgoing_data_rate = RuleR(Network, ClientDataRate);
|
||||
eqsm = std::make_unique<EQ::Net::EQStreamManager>(opts);
|
||||
eqsf_open = true;
|
||||
|
||||
|
||||
28
zone/mob.cpp
28
zone/mob.cpp
@ -392,7 +392,7 @@ Mob::Mob(
|
||||
spellbonuses.AssistRange = -1;
|
||||
SetPetID(0);
|
||||
SetOwnerID(0);
|
||||
SetPetType(petNone); // default to not a pet
|
||||
SetPetType(PetType::None); // default to not a pet
|
||||
SetPetPower(0);
|
||||
held = false;
|
||||
gheld = false;
|
||||
@ -454,8 +454,8 @@ Mob::Mob(
|
||||
weaponstance.itembonus_buff_spell_id = 0;
|
||||
weaponstance.aabonus_buff_spell_id = 0;
|
||||
|
||||
pStandingPetOrder = SPO_Follow;
|
||||
m_previous_pet_order = SPO_Follow;
|
||||
m_pet_order = PetOrder::Follow;
|
||||
m_previous_pet_order = PetOrder::Follow;
|
||||
pseudo_rooted = false;
|
||||
|
||||
nobuff_invisible = 0;
|
||||
@ -623,7 +623,7 @@ bool Mob::HasAnInvisibilityEffect() {
|
||||
|
||||
void Mob::BreakCharmPetIfConditionsMet() {
|
||||
auto pet = GetPet();
|
||||
if (pet && pet->GetPetType() == petCharmed && HasAnInvisibilityEffect()) {
|
||||
if (pet && pet->GetPetType() == PetType::Charmed && HasAnInvisibilityEffect()) {
|
||||
if (RuleB(Pets, LivelikeBreakCharmOnInvis) || IsInvisible(pet)) {
|
||||
pet->BuffFadeByEffect(SE_Charm);
|
||||
}
|
||||
@ -655,14 +655,14 @@ void Mob::CalcInvisibleLevel()
|
||||
BreakCharmPetIfConditionsMet();
|
||||
}
|
||||
|
||||
void Mob::SetPetOrder(eStandingPetOrder i) {
|
||||
if (i == SPO_Sit || i == SPO_FeignDeath) {
|
||||
if (pStandingPetOrder == SPO_Follow || pStandingPetOrder == SPO_Guard) {
|
||||
m_previous_pet_order = pStandingPetOrder;
|
||||
void Mob::SetPetOrder(uint8 pet_order) {
|
||||
if (pet_order == PetOrder::Sit || pet_order == PetOrder::Feign) {
|
||||
if (m_pet_order == PetOrder::Follow || m_pet_order == PetOrder::Guard) {
|
||||
m_previous_pet_order = m_pet_order;
|
||||
}
|
||||
}
|
||||
|
||||
pStandingPetOrder = i;
|
||||
m_pet_order = pet_order;
|
||||
}
|
||||
|
||||
void Mob::SetInvisible(uint8 state, bool set_on_bonus_calc) {
|
||||
@ -1317,7 +1317,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
ns->spawn.IsMercenary = IsMerc() ? 1 : 0;
|
||||
ns->spawn.targetable_with_hotkey = no_target_hotkey ? 0 : 1; // opposite logic!
|
||||
ns->spawn.untargetable = IsTargetable();
|
||||
|
||||
|
||||
ns->spawn.petOwnerId = ownerid;
|
||||
|
||||
ns->spawn.haircolor = haircolor;
|
||||
@ -2361,7 +2361,7 @@ void Mob::SendStatsWindow(Client* c, bool use_window)
|
||||
|
||||
// Attack 2
|
||||
final_string += fmt::format(
|
||||
"Offense: {}{} | {}{}",
|
||||
"Offense: {}{}{}{}",
|
||||
Strings::Commify(offense(skill)),
|
||||
(
|
||||
itembonuses.ATK ?
|
||||
@ -4567,8 +4567,8 @@ void Mob::SetOwnerID(uint16 new_owner_id) {
|
||||
if (
|
||||
!ownerid &&
|
||||
IsNPC() &&
|
||||
GetPetType() != petCharmed &&
|
||||
GetPetType() != petNone
|
||||
GetPetType() != PetType::Charmed &&
|
||||
GetPetType() != PetType::None
|
||||
) {
|
||||
Depop();
|
||||
}
|
||||
@ -8792,4 +8792,4 @@ bool Mob::LoadDataBucketsCache()
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
27
zone/mob.h
27
zone/mob.h
@ -98,7 +98,6 @@ class Mob : public Entity {
|
||||
public:
|
||||
enum CLIENT_CONN_STATUS { CLIENT_CONNECTING, CLIENT_CONNECTED, CLIENT_LINKDEAD,
|
||||
CLIENT_KICKED, DISCONNECTED, CLIENT_ERROR, CLIENT_CONNECTINGALL };
|
||||
enum eStandingPetOrder { SPO_Follow, SPO_Sit, SPO_Guard, SPO_FeignDeath };
|
||||
|
||||
struct MobSpecialAbility {
|
||||
MobSpecialAbility() {
|
||||
@ -601,7 +600,7 @@ public:
|
||||
inline const char* GetName() const { return name; }
|
||||
inline const char* GetOrigName() const { return orig_name; }
|
||||
inline const char* GetLastName() const { return lastname; }
|
||||
inline const eStandingPetOrder GetPreviousPetOrder() const { return m_previous_pet_order; }
|
||||
inline const uint8 GetPreviousPetOrder() const { return m_previous_pet_order; }
|
||||
const char *GetCleanName();
|
||||
virtual void SetName(const char *new_name = nullptr) { new_name ? strn0cpy(name, new_name, 64) :
|
||||
strn0cpy(name, GetName(), 64); return; };
|
||||
@ -1083,14 +1082,14 @@ public:
|
||||
Mob* GetUltimateOwner();
|
||||
void SetPetID(uint16 NewPetID);
|
||||
inline uint16 GetPetID() const { return petid; }
|
||||
inline PetType GetPetType() const { return type_of_pet; }
|
||||
void SetPetType(PetType p) { type_of_pet = p; }
|
||||
inline uint8 GetPetType() const { return type_of_pet; }
|
||||
void SetPetType(uint8 pet_type) { type_of_pet = pet_type; }
|
||||
inline int16 GetPetPower() const { return (petpower < 0) ? 0 : petpower; }
|
||||
void SetPetPower(int16 p) { if (p < 0) petpower = 0; else petpower = p; }
|
||||
bool IsFamiliar() const { return type_of_pet == petFamiliar; }
|
||||
bool IsAnimation() const { return type_of_pet == petAnimation; }
|
||||
bool IsCharmed() const { return type_of_pet == petCharmed; }
|
||||
bool IsTargetLockPet() const { return type_of_pet == petTargetLock; }
|
||||
bool IsFamiliar() const { return type_of_pet == PetType::Familiar; }
|
||||
bool IsAnimation() const { return type_of_pet == PetType::Animation; }
|
||||
bool IsCharmed() const { return type_of_pet == PetType::Charmed; }
|
||||
bool IsTargetLockPet() const { return type_of_pet == PetType::TargetLock; }
|
||||
inline uint32 GetPetTargetLockID() { return pet_targetlock_id; };
|
||||
inline void SetPetTargetLockID(uint32 value) { pet_targetlock_id = value; };
|
||||
void SetOwnerID(uint16 new_owner_id);
|
||||
@ -1212,8 +1211,8 @@ public:
|
||||
inline const float GetAssistRange() const { return (spellbonuses.AssistRange == -1) ? pAssistRange : spellbonuses.AssistRange; }
|
||||
|
||||
|
||||
void SetPetOrder(eStandingPetOrder i);
|
||||
inline const eStandingPetOrder GetPetOrder() const { return pStandingPetOrder; }
|
||||
void SetPetOrder(uint8 pet_order);
|
||||
inline const uint8 GetPetOrder() const { return m_pet_order; }
|
||||
inline void SetHeld(bool nState) { held = nState; }
|
||||
inline const bool IsHeld() const { return held; }
|
||||
inline void SetGHeld(bool nState) { gheld = nState; }
|
||||
@ -1300,7 +1299,7 @@ public:
|
||||
bool IsPetAggroExempt(Mob *pet_owner);
|
||||
|
||||
void InstillDoubt(Mob *who);
|
||||
bool Charmed() const { return type_of_pet == petCharmed; }
|
||||
bool Charmed() const { return type_of_pet == PetType::Charmed; }
|
||||
static uint32 GetLevelHP(uint8 tlevel);
|
||||
uint32 GetZoneID() const; //for perl
|
||||
uint16 GetInstanceVersion() const; //for perl
|
||||
@ -1596,7 +1595,7 @@ protected:
|
||||
StatBonuses aabonuses;
|
||||
uint16 petid;
|
||||
uint16 ownerid;
|
||||
PetType type_of_pet;
|
||||
uint8 type_of_pet;
|
||||
int16 petpower;
|
||||
uint32 follow_id;
|
||||
uint32 follow_dist;
|
||||
@ -1825,8 +1824,8 @@ protected:
|
||||
Timer viral_timer;
|
||||
|
||||
// MobAI stuff
|
||||
eStandingPetOrder pStandingPetOrder;
|
||||
eStandingPetOrder m_previous_pet_order;
|
||||
uint8 m_pet_order;
|
||||
uint8 m_previous_pet_order;
|
||||
uint32 minLastFightingDelayMoving;
|
||||
uint32 maxLastFightingDelayMoving;
|
||||
float pAggroRange = 0;
|
||||
|
||||
@ -1397,8 +1397,8 @@ void Mob::AI_Process() {
|
||||
else if (AI_movement_timer->Check() && !IsRooted()) {
|
||||
if (IsPet()) {
|
||||
// we're a pet, do as we're told
|
||||
switch (pStandingPetOrder) {
|
||||
case SPO_Follow: {
|
||||
switch (m_pet_order) {
|
||||
case PetOrder::Follow: {
|
||||
|
||||
Mob *owner = GetOwner();
|
||||
if (owner == nullptr) {
|
||||
@ -1447,18 +1447,18 @@ void Mob::AI_Process() {
|
||||
|
||||
break;
|
||||
}
|
||||
case SPO_Sit: {
|
||||
case PetOrder::Sit: {
|
||||
SetAppearance(eaSitting, false);
|
||||
break;
|
||||
}
|
||||
case SPO_Guard: {
|
||||
case PetOrder::Guard: {
|
||||
//only NPCs can guard stuff. (forced by where the guard movement code is in the AI)
|
||||
if (IsNPC()) {
|
||||
CastToNPC()->NextGuardPosition();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPO_FeignDeath: {
|
||||
case PetOrder::Feign: {
|
||||
SetAppearance(eaDead, false);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -286,8 +286,8 @@ uint32 Mob::GetHerosForgeModel(uint8 material_slot) const
|
||||
if (augment) {
|
||||
item = augment->GetItem();
|
||||
heros_forge_model = item->HerosForgeModel;
|
||||
} else if (inst->GetOrnamentHeroModel()) {
|
||||
heros_forge_model = inst->GetOrnamentHeroModel();
|
||||
} else if (inst->GetOrnamentHeroModel(material_slot)) {
|
||||
heros_forge_model = inst->GetOrnamentHeroModel(material_slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -421,7 +421,7 @@ void Mob::SendWearChange(uint8 material_slot, Client *one_client)
|
||||
return key;
|
||||
};
|
||||
|
||||
|
||||
|
||||
auto dedupe_key = build_key(*w);
|
||||
auto send_if_changed = [&](Client* client) {
|
||||
auto& last_key = m_last_seen_wearchange[client->GetID()][material_slot];
|
||||
|
||||
20
zone/npc.cpp
20
zone/npc.cpp
@ -864,6 +864,11 @@ void NPC::Depop(bool start_spawn_timer) {
|
||||
DispatchZoneControllerEvent(EVENT_DESPAWN_ZONE, this, "", 0, nullptr);
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_DESPAWN_ZONE)) {
|
||||
std::vector<std::any> args = { this };
|
||||
parse->EventZone(EVENT_DESPAWN_ZONE, zone, "", 0, &args);
|
||||
}
|
||||
|
||||
p_depop = true;
|
||||
if (respawn2) {
|
||||
if (start_spawn_timer) {
|
||||
@ -4009,7 +4014,7 @@ void NPC::SetTaunting(bool is_taunting) {
|
||||
taunting = is_taunting;
|
||||
|
||||
if (IsPet() && IsPetOwnerClient()) {
|
||||
GetOwner()->CastToClient()->SetPetCommandState(PET_BUTTON_TAUNT, is_taunting);
|
||||
GetOwner()->CastToClient()->SetPetCommandState(PetButton::Taunt, is_taunting);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4935,3 +4940,16 @@ void NPC::ResetMultiQuest() {
|
||||
|
||||
m_hand_in = {};
|
||||
}
|
||||
|
||||
void NPC::SetNPCTintIndex(uint32 index)
|
||||
{
|
||||
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||
auto* s = (SpawnAppearance_Struct*) outapp->pBuffer;
|
||||
|
||||
s->spawn_id = GetID();
|
||||
s->type = AppearanceType::NPCTintIndex;
|
||||
s->parameter = index;
|
||||
|
||||
entity_list.QueueClients(this, outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
@ -552,6 +552,9 @@ public:
|
||||
|
||||
void ScaleNPC(uint8 npc_level, bool always_scale = false, bool override_special_abilities = false);
|
||||
|
||||
uint32 GetNPCTintIndex() { return m_npc_tint_id; }
|
||||
void SetNPCTintIndex(uint32 index);
|
||||
|
||||
void RecalculateSkills();
|
||||
void ReloadSpells();
|
||||
|
||||
|
||||
@ -657,6 +657,30 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
||||
}
|
||||
}
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_PLAYER_PICKUP)) {
|
||||
std::vector<std::any> args = { m_inst, sender };
|
||||
|
||||
if (parse->EventZone(EVENT_PLAYER_PICKUP, zone, std::to_string(item->ID), GetID(), &args)) {
|
||||
auto outapp = new EQApplicationPacket(OP_ClickObject, sizeof(ClickObject_Struct));
|
||||
|
||||
memcpy(outapp->pBuffer, click_object, sizeof(ClickObject_Struct));
|
||||
|
||||
auto co = (ClickObject_Struct*) outapp->pBuffer;
|
||||
|
||||
co->drop_id = 0;
|
||||
|
||||
entity_list.QueueClients(nullptr, outapp, false);
|
||||
|
||||
safe_delete(outapp);
|
||||
|
||||
sender->SetTradeskillObject(nullptr);
|
||||
|
||||
user = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Transfer item to client
|
||||
sender->PutItemInInventory(EQ::invslot::slotCursor, *m_inst, false);
|
||||
sender->SendItemPacket(EQ::invslot::slotCursor, m_inst, ItemPacketTrade);
|
||||
|
||||
@ -3328,7 +3328,12 @@ bool Perl_Client_KeyRingClear(Client* self)
|
||||
|
||||
void Perl_Client_KeyRingList(Client* self)
|
||||
{
|
||||
self->KeyRingList();
|
||||
self->KeyRingList(self);
|
||||
}
|
||||
|
||||
void Perl_Client_KeyRingList(Client* self, Client* c)
|
||||
{
|
||||
self->KeyRingList(c);
|
||||
}
|
||||
|
||||
bool Perl_Client_KeyRingRemove(Client* self, uint32 item_id)
|
||||
@ -3346,6 +3351,18 @@ bool Perl_Client_UncompleteTask(Client* self, int task_id)
|
||||
return self->UncompleteTask(task_id);
|
||||
}
|
||||
|
||||
perl::array Perl_Client_GetKeyRing(Client* self)
|
||||
{
|
||||
perl::array result;
|
||||
const auto& v = self->GetKeyRing();
|
||||
|
||||
for (int i = 0; i < v.size(); ++i) {
|
||||
result.push_back(v[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void perl_register_client()
|
||||
{
|
||||
perl::interpreter perl(PERL_GET_THX);
|
||||
@ -3577,6 +3594,7 @@ void perl_register_client()
|
||||
package.add("GetItemCooldown", &Perl_Client_GetItemCooldown);
|
||||
package.add("GetItemIDAt", &Perl_Client_GetItemIDAt);
|
||||
package.add("GetItemInInventory", &Perl_Client_GetItemInInventory);
|
||||
package.add("GetKeyRing", &Perl_Client_GetKeyRing);
|
||||
package.add("GetLDoNLosses", &Perl_Client_GetLDoNLosses);
|
||||
package.add("GetLDoNLossesTheme", &Perl_Client_GetLDoNLossesTheme);
|
||||
package.add("GetLDoNPointsTheme", &Perl_Client_GetLDoNPointsTheme);
|
||||
@ -3675,7 +3693,8 @@ void perl_register_client()
|
||||
package.add("KeyRingAdd", &Perl_Client_KeyRingAdd);
|
||||
package.add("KeyRingCheck", &Perl_Client_KeyRingCheck);
|
||||
package.add("KeyRingClear", &Perl_Client_KeyRingClear);
|
||||
package.add("KeyRingList", &Perl_Client_KeyRingList);
|
||||
package.add("KeyRingList", (void(*)(Client*))&Perl_Client_KeyRingList);
|
||||
package.add("KeyRingList", (void(*)(Client*, Client*))&Perl_Client_KeyRingList);
|
||||
package.add("KeyRingRemove", &Perl_Client_KeyRingRemove);
|
||||
package.add("Kick", &Perl_Client_Kick);
|
||||
package.add("LearnDisciplines", &Perl_Client_LearnDisciplines);
|
||||
|
||||
@ -127,6 +127,16 @@ Client* Perl_Group_GetMember(Group* self, int member_index) // @categories Accou
|
||||
return member ? member->CastToClient() : nullptr;
|
||||
}
|
||||
|
||||
uint8_t Perl_Group_GetMemberRole(Group* self, Mob* member) // @categories Account and Character, Script Utility, Group
|
||||
{
|
||||
return self->GetMemberRole(member);
|
||||
}
|
||||
|
||||
uint8_t Perl_Group_GetMemberRole(Group* self, const char* name) // @categories Account and Character, Script Utility, Group
|
||||
{
|
||||
return self->GetMemberRole(name);
|
||||
}
|
||||
|
||||
bool Perl_Group_DoesAnyMemberHaveExpeditionLockout(Group* self, std::string expedition_name, std::string event_name)
|
||||
{
|
||||
return self->AnyMemberHasDzLockout(expedition_name, event_name);
|
||||
@ -163,6 +173,8 @@ void perl_register_group()
|
||||
package.add("GetLeaderName", &Perl_Group_GetLeaderName);
|
||||
package.add("GetLowestLevel", &Perl_Group_GetLowestLevel);
|
||||
package.add("GetMember", &Perl_Group_GetMember);
|
||||
package.add("GetMemberRole", (uint8_t(*)(Group*, Mob*))&Perl_Group_GetMemberRole);
|
||||
package.add("GetMemberRole", (uint8_t(*)(Group*, const char*))&Perl_Group_GetMemberRole);
|
||||
package.add("GetTotalGroupDamage", &Perl_Group_GetTotalGroupDamage);
|
||||
package.add("GroupCount", &Perl_Group_GroupCount);
|
||||
package.add("GroupMessage", (void(*)(Group*, Mob*, const char*))&Perl_Group_GroupMessage);
|
||||
|
||||
@ -1114,11 +1114,16 @@ uint16 Perl_Mob_GetOwnerID(Mob* self) // @categories Script Utility, Pet
|
||||
return self->GetOwnerID();
|
||||
}
|
||||
|
||||
int Perl_Mob_GetPetType(Mob* self) // @categories Script Utility, Pet
|
||||
uint8 Perl_Mob_GetPetType(Mob* self) // @categories Script Utility, Pet
|
||||
{
|
||||
return self->GetPetType();
|
||||
}
|
||||
|
||||
std::string Perl_Mob_GetPetTypeName(Mob* self) // @categories Script Utility, Pet
|
||||
{
|
||||
return PetType::GetName(self->GetPetType());
|
||||
}
|
||||
|
||||
int Perl_Mob_GetBodyType(Mob* self) // @categories Stats and Attributes
|
||||
{
|
||||
return self->GetBodyType();
|
||||
@ -1254,12 +1259,12 @@ float Perl_Mob_GetAssistRange(Mob* self) // @categories Stats and Attributes, Ha
|
||||
return self->GetAssistRange();
|
||||
}
|
||||
|
||||
void Perl_Mob_SetPetOrder(Mob* self, int order) // @categories Pet
|
||||
void Perl_Mob_SetPetOrder(Mob* self, uint8 pet_order) // @categories Pet
|
||||
{
|
||||
self->SetPetOrder(static_cast<Mob::eStandingPetOrder>(order));
|
||||
self->SetPetOrder(pet_order);
|
||||
}
|
||||
|
||||
int Perl_Mob_GetPetOrder(Mob* self) // @categories Script Utility, Pet
|
||||
uint8 Perl_Mob_GetPetOrder(Mob* self) // @categories Script Utility, Pet
|
||||
{
|
||||
return self->GetPetOrder();
|
||||
}
|
||||
@ -3573,6 +3578,35 @@ void Perl_Mob_BuffFadeSongs(Mob* self)
|
||||
self->BuffFadeSongs();
|
||||
}
|
||||
|
||||
perl::array Perl_Mob_GetPausedTimers(Mob* self)
|
||||
{
|
||||
perl::array a;
|
||||
|
||||
const auto& l = quest_manager.GetPausedTimers(self);
|
||||
for (const auto& v : l) {
|
||||
a.push_back(v);
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
perl::array Perl_Mob_GetTimers(Mob* self)
|
||||
{
|
||||
perl::array a;
|
||||
|
||||
const auto& l = quest_manager.GetTimers(self);
|
||||
for (const auto& v : l) {
|
||||
a.push_back(v);
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
void Perl_Mob_SetPetType(Mob* self, uint8 pet_type)
|
||||
{
|
||||
self->SetPetType(pet_type);
|
||||
}
|
||||
|
||||
void perl_register_mob()
|
||||
{
|
||||
perl::interpreter perl(PERL_GET_THX);
|
||||
@ -3897,10 +3931,12 @@ void perl_register_mob()
|
||||
package.add("GetOwner", &Perl_Mob_GetOwner);
|
||||
package.add("GetOwnerID", &Perl_Mob_GetOwnerID);
|
||||
package.add("GetPR", &Perl_Mob_GetPR);
|
||||
package.add("GetPausedTimers", &Perl_Mob_GetPausedTimers);
|
||||
package.add("GetPet", &Perl_Mob_GetPet);
|
||||
package.add("GetPetID", &Perl_Mob_GetPetID);
|
||||
package.add("GetPetOrder", &Perl_Mob_GetPetOrder);
|
||||
package.add("GetPetType", &Perl_Mob_GetPetType);
|
||||
package.add("GetPetTypeName", &Perl_Mob_GetPetTypeName);
|
||||
package.add("GetPhR", &Perl_Mob_GetPhR);
|
||||
package.add("GetRace", &Perl_Mob_GetRace);
|
||||
package.add("GetRaceName", &Perl_Mob_GetRaceName);
|
||||
@ -3927,6 +3963,7 @@ void perl_register_mob()
|
||||
package.add("GetTarget", &Perl_Mob_GetTarget);
|
||||
package.add("GetTexture", &Perl_Mob_GetTexture);
|
||||
package.add("GetTimerDurationMS", &Perl_Mob_GetTimerDurationMS);
|
||||
package.add("GetTimers", &Perl_Mob_GetTimers);
|
||||
package.add("GetUltimateOwner", &Perl_Mob_GetUltimateOwner);
|
||||
package.add("GetWIS", &Perl_Mob_GetWIS);
|
||||
package.add("GetWalkspeed", &Perl_Mob_GetWalkspeed);
|
||||
@ -4161,6 +4198,7 @@ void perl_register_mob()
|
||||
package.add("SetPet", &Perl_Mob_SetPet);
|
||||
package.add("SetPetID", &Perl_Mob_SetPetID);
|
||||
package.add("SetPetOrder", &Perl_Mob_SetPetOrder);
|
||||
package.add("SetPetType", &Perl_Mob_SetPetType);
|
||||
package.add("SetRace", &Perl_Mob_SetRace);
|
||||
package.add("SetRunAnimSpeed", &Perl_Mob_SetRunAnimSpeed);
|
||||
package.add("SetRunning", &Perl_Mob_SetRunning);
|
||||
|
||||
@ -885,9 +885,14 @@ Spawn2* Perl_NPC_GetSpawn(NPC* self)
|
||||
return self->GetSpawn();
|
||||
}
|
||||
|
||||
void Perl_NPC_SetNPCTintIndex(NPC* self, uint32 id)
|
||||
void Perl_NPC_SetNPCTintIndex(NPC* self, uint32 index)
|
||||
{
|
||||
return self->SendAppearancePacket(AppearanceType::NPCTintIndex, id);
|
||||
self->SetNPCTintIndex(index);
|
||||
}
|
||||
|
||||
uint32 Perl_NPC_GetNPCTintIndex(NPC* self)
|
||||
{
|
||||
return self->GetNPCTintIndex();
|
||||
}
|
||||
|
||||
void perl_register_npc()
|
||||
@ -959,6 +964,7 @@ void perl_register_npc()
|
||||
package.add("GetNPCSpellsEffectsID", &Perl_NPC_GetNPCSpellsEffectsID);
|
||||
package.add("GetNPCSpellsID", &Perl_NPC_GetNPCSpellsID);
|
||||
package.add("GetNPCStat", &Perl_NPC_GetNPCStat);
|
||||
package.add("GetNPCTintIndex", &Perl_NPC_GetNPCTintIndex);
|
||||
package.add("GetPetSpellID", &Perl_NPC_GetPetSpellID);
|
||||
package.add("GetPlatinum", &Perl_NPC_GetPlatinum);
|
||||
package.add("GetPrimSkill", &Perl_NPC_GetPrimSkill);
|
||||
|
||||
@ -598,6 +598,95 @@ bool Perl_Zone_VariableExists(Zone* self, const std::string variable_name)
|
||||
return self->VariableExists(variable_name);
|
||||
}
|
||||
|
||||
uint32 Perl_Zone_GetTimerDuration(Zone* self, std::string name)
|
||||
{
|
||||
return self->GetTimerDuration(name);
|
||||
}
|
||||
|
||||
uint32 Perl_Zone_GetTimerRemainingTime(Zone* self, std::string name)
|
||||
{
|
||||
return self->GetTimerRemainingTime(name);
|
||||
}
|
||||
|
||||
bool Perl_Zone_HasTimer(Zone* self, std::string name)
|
||||
{
|
||||
return self->HasTimer(name);
|
||||
}
|
||||
|
||||
bool Perl_Zone_IsPausedTimer(Zone* self, std::string name)
|
||||
{
|
||||
return self->IsPausedTimer(name);
|
||||
}
|
||||
|
||||
void Perl_Zone_PauseTimer(Zone* self, std::string name)
|
||||
{
|
||||
self->PauseTimer(name);
|
||||
}
|
||||
|
||||
void Perl_Zone_ResumeTimer(Zone* self, std::string name)
|
||||
{
|
||||
self->ResumeTimer(name);
|
||||
}
|
||||
|
||||
void Perl_Zone_SetTimer(Zone* self, std::string name, uint32 duration)
|
||||
{
|
||||
self->SetTimer(name, duration);
|
||||
}
|
||||
|
||||
void Perl_Zone_StopTimer(Zone* self, std::string name)
|
||||
{
|
||||
self->StopTimer(name);
|
||||
}
|
||||
|
||||
void Perl_Zone_StopAllTimers(Zone* self)
|
||||
{
|
||||
self->StopAllTimers();
|
||||
}
|
||||
|
||||
void Perl_Zone_SendPayload(Zone* self, int payload_id, std::string payload_value)
|
||||
{
|
||||
self->SendPayload(payload_id, payload_value);
|
||||
}
|
||||
|
||||
void Perl_Zone_Signal(Zone* self, int signal_id)
|
||||
{
|
||||
self->Signal(signal_id);
|
||||
}
|
||||
|
||||
perl::array Perl_Zone_GetPausedTimers(Zone* self)
|
||||
{
|
||||
perl::array a;
|
||||
|
||||
const auto& l = self->GetPausedTimers();
|
||||
|
||||
if (!l.empty()) {
|
||||
a.reserve(l.size());
|
||||
|
||||
for (const auto& v : l) {
|
||||
a.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
perl::array Perl_Zone_GetTimers(Zone* self)
|
||||
{
|
||||
perl::array a;
|
||||
|
||||
const auto& l = self->GetTimers();
|
||||
|
||||
if (!l.empty()) {
|
||||
a.reserve(l.size());
|
||||
|
||||
for (const auto& v : l) {
|
||||
a.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
void perl_register_zone()
|
||||
{
|
||||
perl::interpreter perl(PERL_GET_THX);
|
||||
@ -668,6 +757,7 @@ void perl_register_zone()
|
||||
package.add("GetMinimumStatus", &Perl_Zone_GetMinimumStatus);
|
||||
package.add("GetNote", &Perl_Zone_GetNote);
|
||||
package.add("GetNPCMaximumAggroDistance", &Perl_Zone_GetNPCMaximumAggroDistance);
|
||||
package.add("GetPausedTimers", &Perl_Zone_GetPausedTimers);
|
||||
package.add("GetPEQZone", &Perl_Zone_GetPEQZone);
|
||||
package.add("GetRainChance", (int(*)(Zone*))&Perl_Zone_GetRainChance);
|
||||
package.add("GetRainChance", (int(*)(Zone*, uint8))&Perl_Zone_GetRainChance);
|
||||
@ -689,6 +779,9 @@ void perl_register_zone()
|
||||
package.add("GetSnowDuration", (int(*)(Zone*, uint8))&Perl_Zone_GetSnowDuration);
|
||||
package.add("GetTimeType", &Perl_Zone_GetTimeType);
|
||||
package.add("GetTimeZone", &Perl_Zone_GetTimeZone);
|
||||
package.add("GetTimerDuration", &Perl_Zone_GetTimerDuration);
|
||||
package.add("GetTimerRemainingTime", &Perl_Zone_GetTimerRemainingTime);
|
||||
package.add("GetTimers", &Perl_Zone_GetTimers);
|
||||
package.add("GetZoneDescription", &Perl_Zone_GetZoneDescription);
|
||||
package.add("GetZoneID", &Perl_Zone_GetZoneID);
|
||||
package.add("GetZoneType", &Perl_Zone_GetZoneType);
|
||||
@ -701,12 +794,14 @@ void perl_register_zone()
|
||||
package.add("GetZoneTotalBlockedSpells", &Perl_Zone_GetZoneTotalBlockedSpells);
|
||||
package.add("HasGraveyard", &Perl_Zone_HasGraveyard);
|
||||
package.add("HasMap", &Perl_Zone_HasMap);
|
||||
package.add("HasTimer", &Perl_Zone_HasTimer);
|
||||
package.add("HasWaterMap", &Perl_Zone_HasWaterMap);
|
||||
package.add("HasWeather", &Perl_Zone_HasWeather);
|
||||
package.add("IsCity", &Perl_Zone_IsCity);
|
||||
package.add("IsHotzone", &Perl_Zone_IsHotzone);
|
||||
package.add("IsInstancePersistent", &Perl_Zone_IsInstancePersistent);
|
||||
package.add("IsIdleWhenEmpty", &Perl_Zone_IsIdleWhenEmpty);
|
||||
package.add("IsPausedTimer", &Perl_Zone_IsPausedTimer);
|
||||
package.add("IsPVPZone", &Perl_Zone_IsPVPZone);
|
||||
package.add("IsRaining", &Perl_Zone_IsRaining);
|
||||
package.add("IsSnowing", &Perl_Zone_IsSnowing);
|
||||
@ -715,8 +810,11 @@ void perl_register_zone()
|
||||
package.add("IsStaticZone", &Perl_Zone_IsStaticZone);
|
||||
package.add("IsUCSServerAvailable", &Perl_Zone_IsUCSServerAvailable);
|
||||
package.add("IsWaterZone", &Perl_Zone_IsWaterZone);
|
||||
package.add("PauseTimer", &Perl_Zone_PauseTimer);
|
||||
package.add("Repop", (void(*)(Zone*))&Perl_Zone_Repop);
|
||||
package.add("Repop", (void(*)(Zone*, bool))&Perl_Zone_Repop);
|
||||
package.add("ResumeTimer", &Perl_Zone_ResumeTimer);
|
||||
package.add("SendPayload", &Perl_Zone_SendPayload);
|
||||
package.add("SetAAEXPModifier", &Perl_Zone_SetAAEXPModifier);
|
||||
package.add("SetAAEXPModifierByCharacterID", &Perl_Zone_SetAAEXPModifierByCharacterID);
|
||||
package.add("SetBucket", (void(*)(Zone*, const std::string, const std::string))&Perl_Zone_SetBucket);
|
||||
@ -726,7 +824,11 @@ void perl_register_zone()
|
||||
package.add("SetInstanceTimer", &Perl_Zone_SetInstanceTimer);
|
||||
package.add("SetInstanceTimeRemaining", &Perl_Zone_SetInstanceTimeRemaining);
|
||||
package.add("SetIsHotzone", &Perl_Zone_SetIsHotzone);
|
||||
package.add("SetTimer", &Perl_Zone_SetTimer);
|
||||
package.add("SetVariable", &Perl_Zone_SetVariable);
|
||||
package.add("Signal", &Perl_Zone_Signal);
|
||||
package.add("StopTimer", &Perl_Zone_StopTimer);
|
||||
package.add("StopAllTimers", &Perl_Zone_StopAllTimers);
|
||||
package.add("ShowZoneGlobalLoot", &Perl_Zone_ShowZoneGlobalLoot);
|
||||
package.add("VariableExists", &Perl_Zone_VariableExists);
|
||||
}
|
||||
|
||||
@ -267,7 +267,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
}
|
||||
|
||||
//this takes ownership of the npc_type data
|
||||
auto npc = new Pet(npc_type, this, (PetType)record.petcontrol, spell_id, record.petpower);
|
||||
auto npc = new Pet(npc_type, this, record.petcontrol, spell_id, record.petpower);
|
||||
|
||||
// Now that we have an actual object to interact with, load
|
||||
// the base items for the pet. These are always loaded
|
||||
@ -295,7 +295,7 @@ void Mob::MakePoweredPet(uint16 spell_id, const char* pettype, int16 petpower,
|
||||
SetPetID(npc->GetID());
|
||||
// We need to handle PetType 5 (petHatelist), add the current target to the hatelist of the pet
|
||||
|
||||
if (record.petcontrol == petTargetLock)
|
||||
if (record.petcontrol == PetType::TargetLock)
|
||||
{
|
||||
Mob* m_target = GetTarget();
|
||||
|
||||
@ -341,7 +341,7 @@ void NPC::TryDepopTargetLockedPets(Mob* current_target) {
|
||||
return;
|
||||
}
|
||||
//Use when pets are given petype 5
|
||||
if (IsPet() && GetPetType() == petTargetLock && GetPetTargetLockID()) {
|
||||
if (IsPet() && GetPetType() == PetType::TargetLock && GetPetTargetLockID()) {
|
||||
CastSpell(SPELL_UNSUMMON_SELF, GetID()); //Live like behavior, damages self for 20K
|
||||
if (!HasDied()) {
|
||||
Kill(); //Ensure pet dies if over 20k HP.
|
||||
@ -356,11 +356,11 @@ void NPC::TryDepopTargetLockedPets(Mob* current_target) {
|
||||
/* This is why the pets ghost - pets were being spawned too far away from its npc owner and some
|
||||
into walls or objects (+10), this sometimes creates the "ghost" effect. I changed to +2 (as close as I
|
||||
could get while it still looked good). I also noticed this can happen if an NPC is spawned on the same spot of another or in a related bad spot.*/
|
||||
Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power)
|
||||
Pet::Pet(NPCType *type_data, Mob *owner, uint8 pet_type, uint16 spell_id, int16 power)
|
||||
: NPC(type_data, 0, owner->GetPosition() + glm::vec4(2.0f, 2.0f, 0.0f, 0.0f), GravityBehavior::Water)
|
||||
{
|
||||
GiveNPCTypeData(type_data);
|
||||
SetPetType(type);
|
||||
SetPetType(pet_type);
|
||||
SetPetPower(power);
|
||||
SetOwnerID(owner ? owner->GetID() : 0);
|
||||
SetPetSpellID(spell_id);
|
||||
@ -374,8 +374,8 @@ Pet::Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 po
|
||||
if (owner && owner->IsClient()) {
|
||||
if (!(owner->CastToClient()->ClientVersionBit() & EQ::versions::maskUFAndLater)) {
|
||||
if (
|
||||
(GetPetType() != petFamiliar && GetPetType() != petAnimation) ||
|
||||
aabonuses.PetCommands[PET_TAUNT]
|
||||
(GetPetType() != PetType::Familiar && GetPetType() != PetType::Animation) ||
|
||||
aabonuses.PetCommands[PetCommand::Taunt]
|
||||
) {
|
||||
SetTaunting(true);
|
||||
}
|
||||
@ -587,7 +587,7 @@ void NPC::SetPetState(SpellBuff_Struct *pet_buffs, uint32 *items) {
|
||||
|
||||
if (item2) {
|
||||
bool noDrop = (item2->NoDrop == 0); // Field is reverse logic
|
||||
bool petCanHaveNoDrop = (RuleB(Pets, CanTakeNoDrop) && _CLIENTPET(this) && GetPetType() <= petOther);
|
||||
bool petCanHaveNoDrop = (RuleB(Pets, CanTakeNoDrop) && _CLIENTPET(this) && GetPetType() <= PetType::Normal);
|
||||
|
||||
if (!noDrop || petCanHaveNoDrop) {
|
||||
AddLootDrop(item2, LootdropEntriesRepository::NewNpcEntity(), true);
|
||||
|
||||
@ -6,7 +6,7 @@ struct NPCType;
|
||||
|
||||
class Pet : public NPC {
|
||||
public:
|
||||
Pet(NPCType *type_data, Mob *owner, PetType type, uint16 spell_id, int16 power);
|
||||
Pet(NPCType *type_data, Mob *owner, uint8 pet_type, uint16 spell_id, int16 power);
|
||||
virtual bool CheckSpellLevelRestriction(Mob *caster, uint16 spell_id);
|
||||
|
||||
};
|
||||
|
||||
@ -163,6 +163,28 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int EventZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int EventGlobalZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual bool HasQuestSub(uint32 npc_id, QuestEventID event_id)
|
||||
{
|
||||
return false;
|
||||
@ -223,6 +245,16 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool ZoneHasQuestSub(QuestEventID event_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool GlobalZoneHasQuestSub(QuestEventID event_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void LoadNPCScript(std::string filename, int npc_id) { }
|
||||
virtual void LoadGlobalNPCScript(std::string filename) { }
|
||||
virtual void LoadPlayerScript(std::string filename) { }
|
||||
@ -234,6 +266,8 @@ public:
|
||||
virtual void LoadGlobalBotScript(std::string filename) { }
|
||||
virtual void LoadMercScript(std::string filename) { }
|
||||
virtual void LoadGlobalMercScript(std::string filename) { }
|
||||
virtual void LoadZoneScript(std::string filename) { }
|
||||
virtual void LoadGlobalZoneScript(std::string filename) { }
|
||||
|
||||
virtual int DispatchEventNPC(
|
||||
QuestEventID event_id,
|
||||
@ -308,6 +342,17 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual int DispatchEventZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void AddVar(std::string name, std::string val) { }
|
||||
virtual std::string GetVar(std::string name)
|
||||
{
|
||||
|
||||
@ -49,6 +49,8 @@ QuestParserCollection::QuestParserCollection()
|
||||
_global_bot_quest_status = QuestUnloaded;
|
||||
_merc_quest_status = QuestUnloaded;
|
||||
_global_merc_quest_status = QuestUnloaded;
|
||||
_zone_quest_status = QuestUnloaded;
|
||||
_global_zone_quest_status = QuestUnloaded;
|
||||
}
|
||||
|
||||
QuestParserCollection::~QuestParserCollection() { }
|
||||
@ -85,6 +87,7 @@ void QuestParserCollection::ReloadQuests(bool reset_timers)
|
||||
{
|
||||
if (reset_timers) {
|
||||
quest_manager.ClearAllTimers();
|
||||
zone->StopAllTimers();
|
||||
}
|
||||
|
||||
MapOpcodes();
|
||||
@ -98,6 +101,8 @@ void QuestParserCollection::ReloadQuests(bool reset_timers)
|
||||
_global_bot_quest_status = QuestUnloaded;
|
||||
_merc_quest_status = QuestUnloaded;
|
||||
_global_merc_quest_status = QuestUnloaded;
|
||||
_zone_quest_status = QuestUnloaded;
|
||||
_global_zone_quest_status = QuestUnloaded;
|
||||
|
||||
_spell_quest_status.clear();
|
||||
_item_quest_status.clear();
|
||||
@ -426,6 +431,49 @@ bool QuestParserCollection::MercHasQuestSub(QuestEventID event_id)
|
||||
return MercHasQuestSubLocal(event_id) || MercHasQuestSubGlobal(event_id);
|
||||
}
|
||||
|
||||
bool QuestParserCollection::ZoneHasQuestSubLocal(QuestEventID event_id)
|
||||
{
|
||||
if (_zone_quest_status == QuestUnloaded) {
|
||||
std::string filename;
|
||||
auto qi = GetQIByZoneQuest(filename);
|
||||
|
||||
if (qi) {
|
||||
_zone_quest_status = qi->GetIdentifier();
|
||||
qi->LoadZoneScript(filename);
|
||||
return qi->ZoneHasQuestSub(event_id);
|
||||
}
|
||||
} else if (_zone_quest_status != QuestFailedToLoad) {
|
||||
auto iter = _interfaces.find(_zone_quest_status);
|
||||
return iter->second->ZoneHasQuestSub(event_id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QuestParserCollection::ZoneHasQuestSubGlobal(QuestEventID event_id)
|
||||
{
|
||||
if (_global_zone_quest_status == QuestUnloaded) {
|
||||
std::string filename;
|
||||
auto qi = GetQIByGlobalZoneQuest(filename);
|
||||
|
||||
if (qi) {
|
||||
_global_zone_quest_status = qi->GetIdentifier();
|
||||
qi->LoadGlobalZoneScript(filename);
|
||||
return qi->GlobalZoneHasQuestSub(event_id);
|
||||
}
|
||||
} else if (_global_zone_quest_status != QuestFailedToLoad) {
|
||||
auto iter = _interfaces.find(_global_zone_quest_status);
|
||||
return iter->second->GlobalZoneHasQuestSub(event_id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QuestParserCollection::ZoneHasQuestSub(QuestEventID event_id)
|
||||
{
|
||||
return ZoneHasQuestSubLocal(event_id) || ZoneHasQuestSubGlobal(event_id);
|
||||
}
|
||||
|
||||
int QuestParserCollection::EventNPC(
|
||||
QuestEventID event_id,
|
||||
NPC* npc,
|
||||
@ -924,6 +972,83 @@ int QuestParserCollection::EventMercGlobal(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QuestParserCollection::EventZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
const int local_return = EventZoneLocal(event_id, zone, data, extra_data, extra_pointers);
|
||||
const int global_return = EventZoneGlobal(event_id, zone, data, extra_data, extra_pointers);
|
||||
const int default_return = DispatchEventZone(event_id, zone, data, extra_data, extra_pointers);
|
||||
|
||||
if (local_return != 0) {
|
||||
return local_return;
|
||||
} else if (global_return != 0) {
|
||||
return global_return;
|
||||
} else if (default_return != 0) {
|
||||
return default_return;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QuestParserCollection::EventZoneLocal(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
if (_zone_quest_status == QuestUnloaded) {
|
||||
std::string filename;
|
||||
auto qi = GetQIByZoneQuest(filename);
|
||||
|
||||
if (qi) {
|
||||
_zone_quest_status = qi->GetIdentifier();
|
||||
qi->LoadZoneScript(filename);
|
||||
return qi->EventZone(event_id, zone, data, extra_data, extra_pointers);
|
||||
}
|
||||
} else {
|
||||
if (_zone_quest_status != QuestFailedToLoad) {
|
||||
auto iter = _interfaces.find(_zone_quest_status);
|
||||
return iter->second->EventZone(event_id, zone, data, extra_data, extra_pointers);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int QuestParserCollection::EventZoneGlobal(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
if (_global_zone_quest_status == QuestUnloaded) {
|
||||
std::string filename;
|
||||
auto qi = GetQIByGlobalZoneQuest(filename);
|
||||
|
||||
if (qi) {
|
||||
_global_zone_quest_status = qi->GetIdentifier();
|
||||
qi->LoadGlobalZoneScript(filename);
|
||||
return qi->EventGlobalZone(event_id, zone, data, extra_data, extra_pointers);
|
||||
}
|
||||
} else {
|
||||
if (_global_zone_quest_status != QuestFailedToLoad) {
|
||||
auto iter = _interfaces.find(_global_zone_quest_status);
|
||||
return iter->second->EventGlobalZone(event_id, zone, data, extra_data, extra_pointers);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
QuestInterface* QuestParserCollection::GetQIByNPCQuest(uint32 npc_id, std::string& filename)
|
||||
{
|
||||
if (!zone) {
|
||||
@ -1425,6 +1550,86 @@ QuestInterface* QuestParserCollection::GetQIByGlobalMercQuest(std::string& filen
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QuestInterface* QuestParserCollection::GetQIByZoneQuest(std::string& filename)
|
||||
{
|
||||
if (!zone || !zone->IsLoaded()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string file_name;
|
||||
for (auto& dir: PathManager::Instance()->GetQuestPaths()) {
|
||||
const std::string& global_path = fmt::format(
|
||||
"{}/{}",
|
||||
dir,
|
||||
QUEST_GLOBAL_DIRECTORY
|
||||
);
|
||||
|
||||
const std::string& zone_path = fmt::format(
|
||||
"{}/{}",
|
||||
dir,
|
||||
zone->GetShortName()
|
||||
);
|
||||
|
||||
const std::string& zone_versioned_path = fmt::format(
|
||||
"{}/{}/v{}",
|
||||
dir,
|
||||
zone->GetShortName(),
|
||||
zone->GetInstanceVersion()
|
||||
);
|
||||
|
||||
std::vector<std::string> file_names = {
|
||||
fmt::format("{}/zone", zone_versioned_path), // Local versioned by Instance Version ./quests/zone/v0/zone.ext
|
||||
fmt::format("{}/zone_v{}", zone_path, zone->GetInstanceVersion()), // Local by Instance Version
|
||||
fmt::format("{}/zone", zone_path), // Local
|
||||
fmt::format("{}/zone", global_path) // Global
|
||||
};
|
||||
|
||||
for (auto& file: file_names) {
|
||||
for (auto* e: _load_precedence) {
|
||||
file_name = fmt::format(
|
||||
"{}.{}",
|
||||
file,
|
||||
_extensions.find(e->GetIdentifier())->second
|
||||
);
|
||||
|
||||
if (File::Exists(file_name)) {
|
||||
filename = file_name;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QuestInterface* QuestParserCollection::GetQIByGlobalZoneQuest(std::string& filename)
|
||||
{
|
||||
if (!zone) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string file_name;
|
||||
|
||||
for (auto& dir: PathManager::Instance()->GetQuestPaths()) {
|
||||
for (auto* e: _load_precedence) {
|
||||
file_name = fmt::format(
|
||||
"{}/{}/global_zone.{}",
|
||||
dir,
|
||||
QUEST_GLOBAL_DIRECTORY,
|
||||
_extensions.find(e->GetIdentifier())->second
|
||||
);
|
||||
|
||||
if (File::Exists(file_name)) {
|
||||
filename = file_name;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void QuestParserCollection::GetErrors(std::list<std::string>& quest_errors)
|
||||
{
|
||||
quest_errors.clear();
|
||||
@ -1561,6 +1766,26 @@ int QuestParserCollection::DispatchEventMerc(
|
||||
return ret;
|
||||
}
|
||||
|
||||
int QuestParserCollection::DispatchEventZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
for (const auto& e: _load_precedence) {
|
||||
int i = e->DispatchEventZone(event_id, zone, data, extra_data, extra_pointers);
|
||||
if (i != 0) {
|
||||
ret = i;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings* s)
|
||||
{
|
||||
for (int i = 0; i < _LargestEventID; i++) {
|
||||
|
||||
@ -72,6 +72,7 @@ public:
|
||||
bool ItemHasQuestSub(EQ::ItemInstance* inst, QuestEventID event_id);
|
||||
bool BotHasQuestSub(QuestEventID event_id);
|
||||
bool MercHasQuestSub(QuestEventID event_id);
|
||||
bool ZoneHasQuestSub(QuestEventID event_id);
|
||||
|
||||
int EventNPC(
|
||||
QuestEventID event_id,
|
||||
@ -172,6 +173,14 @@ public:
|
||||
std::vector<std::any>* extra_pointers = nullptr
|
||||
);
|
||||
|
||||
int EventZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data = 0,
|
||||
std::vector<std::any>* extra_pointers = nullptr
|
||||
);
|
||||
|
||||
void GetErrors(std::list<std::string> &quest_errors);
|
||||
|
||||
/*
|
||||
@ -209,6 +218,8 @@ private:
|
||||
bool BotHasQuestSubGlobal(QuestEventID event_id);
|
||||
bool MercHasQuestSubLocal(QuestEventID event_id);
|
||||
bool MercHasQuestSubGlobal(QuestEventID event_id);
|
||||
bool ZoneHasQuestSubLocal(QuestEventID event_id);
|
||||
bool ZoneHasQuestSubGlobal(QuestEventID event_id);
|
||||
|
||||
int EventNPCLocal(
|
||||
QuestEventID event_id,
|
||||
@ -280,6 +291,22 @@ private:
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
int EventZoneLocal(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
int EventZoneGlobal(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
QuestInterface* GetQIByNPCQuest(uint32 npc_id, std::string& filename);
|
||||
QuestInterface* GetQIByGlobalNPCQuest(std::string& filename);
|
||||
QuestInterface* GetQIByPlayerQuest(std::string& filename);
|
||||
@ -291,6 +318,8 @@ private:
|
||||
QuestInterface* GetQIByGlobalBotQuest(std::string& filename);
|
||||
QuestInterface* GetQIByMercQuest(std::string& filename);
|
||||
QuestInterface* GetQIByGlobalMercQuest(std::string& filename);
|
||||
QuestInterface* GetQIByZoneQuest(std::string& filename);
|
||||
QuestInterface* GetQIByGlobalZoneQuest(std::string& filename);
|
||||
|
||||
int DispatchEventNPC(
|
||||
QuestEventID event_id,
|
||||
@ -347,6 +376,14 @@ private:
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
int DispatchEventZone(
|
||||
QuestEventID event_id,
|
||||
Zone* zone,
|
||||
std::string data,
|
||||
uint32 extra_data,
|
||||
std::vector<std::any>* extra_pointers
|
||||
);
|
||||
|
||||
std::map<uint32, QuestInterface*> _interfaces;
|
||||
std::map<uint32, std::string> _extensions;
|
||||
std::list<QuestInterface*> _load_precedence;
|
||||
@ -359,6 +396,8 @@ private:
|
||||
uint32 _global_bot_quest_status;
|
||||
uint32 _merc_quest_status;
|
||||
uint32 _global_merc_quest_status;
|
||||
uint32 _zone_quest_status;
|
||||
uint32 _global_zone_quest_status;
|
||||
std::map<uint32, uint32> _spell_quest_status;
|
||||
std::map<uint32, uint32> _item_quest_status;
|
||||
std::map<std::string, uint32> _encounter_quest_status;
|
||||
|
||||
@ -64,10 +64,10 @@ QuestManager quest_manager;
|
||||
EQ::ItemInstance* questitem = nullptr; \
|
||||
const SPDat_Spell_Struct* questspell = nullptr; \
|
||||
bool depop_npc = false; \
|
||||
std::string encounter; \
|
||||
std::string encounter = ""; \
|
||||
do { \
|
||||
if(!quests_running_.empty()) { \
|
||||
running_quest e = quests_running_.top(); \
|
||||
if(!m_running_quests.empty()) { \
|
||||
RunningQuest e = m_running_quests.top(); \
|
||||
owner = e.owner; \
|
||||
initiator = e.initiator; \
|
||||
questitem = e.questitem; \
|
||||
@ -124,33 +124,30 @@ void QuestManager::Process() {
|
||||
}
|
||||
}
|
||||
|
||||
void QuestManager::StartQuest(Mob *_owner, Client *_initiator, EQ::ItemInstance* _questitem, const SPDat_Spell_Struct* _questspell, std::string encounter) {
|
||||
running_quest run;
|
||||
run.owner = _owner;
|
||||
run.initiator = _initiator;
|
||||
run.questitem = _questitem;
|
||||
run.questspell = _questspell;
|
||||
run.depop_npc = false;
|
||||
run.encounter = encounter;
|
||||
quests_running_.push(run);
|
||||
void QuestManager::StartQuest(const RunningQuest& q)
|
||||
{
|
||||
m_running_quests.push(q);
|
||||
}
|
||||
|
||||
void QuestManager::EndQuest() {
|
||||
running_quest run = quests_running_.top();
|
||||
if(run.depop_npc && run.owner->IsNPC()) {
|
||||
RunningQuest run = m_running_quests.top();
|
||||
|
||||
if (run.depop_npc && run.owner->IsNPC()) {
|
||||
//clear out any timers for them...
|
||||
std::list<QuestTimer>::iterator cur = QTimerList.begin(), end;
|
||||
|
||||
end = QTimerList.end();
|
||||
while (cur != end) {
|
||||
if (cur->mob == run.owner)
|
||||
if (cur->mob == run.owner) {
|
||||
cur = QTimerList.erase(cur);
|
||||
else
|
||||
} else {
|
||||
++cur;
|
||||
}
|
||||
}
|
||||
run.owner->Depop();
|
||||
}
|
||||
quests_running_.pop();
|
||||
|
||||
m_running_quests.pop();
|
||||
}
|
||||
|
||||
void QuestManager::ClearAllTimers() {
|
||||
@ -1098,18 +1095,18 @@ void QuestManager::depop(int npc_type) {
|
||||
tmp->CastToNPC()->Depop();
|
||||
}
|
||||
else {
|
||||
running_quest e = quests_running_.top();
|
||||
RunningQuest e = m_running_quests.top();
|
||||
e.depop_npc = true;
|
||||
quests_running_.pop();
|
||||
quests_running_.push(e);
|
||||
m_running_quests.pop();
|
||||
m_running_quests.push(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { //depop self
|
||||
running_quest e = quests_running_.top();
|
||||
RunningQuest e = m_running_quests.top();
|
||||
e.depop_npc = true;
|
||||
quests_running_.pop();
|
||||
quests_running_.push(e);
|
||||
m_running_quests.pop();
|
||||
m_running_quests.push(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1606,7 +1603,7 @@ void QuestManager::save() {
|
||||
|
||||
void QuestManager::faction(int faction_id, int faction_value, int temp) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
running_quest run = quests_running_.top();
|
||||
RunningQuest run = m_running_quests.top();
|
||||
if(run.owner->IsCharmed() == false && initiator) {
|
||||
if(faction_id != 0 && faction_value != 0) {
|
||||
initiator->SetFactionLevel2(
|
||||
@ -2077,10 +2074,10 @@ void QuestManager::respawn(int npcTypeID, int grid) {
|
||||
if (!owner || !owner->IsNPC())
|
||||
return;
|
||||
|
||||
running_quest e = quests_running_.top();
|
||||
RunningQuest e = m_running_quests.top();
|
||||
e.depop_npc = true;
|
||||
quests_running_.pop();
|
||||
quests_running_.push(e);
|
||||
m_running_quests.pop();
|
||||
m_running_quests.push(e);
|
||||
|
||||
const NPCType* npcType = nullptr;
|
||||
if ((npcType = content_db.LoadNPCTypesData(npcTypeID)))
|
||||
@ -3980,81 +3977,90 @@ void QuestManager::ReloadZoneStaticData()
|
||||
}
|
||||
}
|
||||
|
||||
Client *QuestManager::GetInitiator() const {
|
||||
if(!quests_running_.empty()) {
|
||||
running_quest e = quests_running_.top();
|
||||
Client* QuestManager::GetInitiator() const
|
||||
{
|
||||
if (!m_running_quests.empty()) {
|
||||
RunningQuest e = m_running_quests.top();
|
||||
return e.initiator;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NPC *QuestManager::GetNPC() const {
|
||||
if(!quests_running_.empty()) {
|
||||
running_quest e = quests_running_.top();
|
||||
NPC* QuestManager::GetNPC() const
|
||||
{
|
||||
if (!m_running_quests.empty()) {
|
||||
RunningQuest e = m_running_quests.top();
|
||||
return (e.owner && e.owner->IsNPC()) ? e.owner->CastToNPC() : nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Bot *QuestManager::GetBot() const {
|
||||
if (!quests_running_.empty()) {
|
||||
running_quest e = quests_running_.top();
|
||||
Bot* QuestManager::GetBot() const
|
||||
{
|
||||
if (!m_running_quests.empty()) {
|
||||
RunningQuest e = m_running_quests.top();
|
||||
return (e.owner && e.owner->IsBot()) ? e.owner->CastToBot() : nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Merc *QuestManager::GetMerc() const {
|
||||
if (!quests_running_.empty()) {
|
||||
running_quest e = quests_running_.top();
|
||||
Merc* QuestManager::GetMerc() const
|
||||
{
|
||||
if (!m_running_quests.empty()) {
|
||||
RunningQuest e = m_running_quests.top();
|
||||
return (e.owner && e.owner->IsMerc()) ? e.owner->CastToMerc() : nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Mob *QuestManager::GetOwner() const {
|
||||
if(!quests_running_.empty()) {
|
||||
running_quest e = quests_running_.top();
|
||||
Mob* QuestManager::GetOwner() const
|
||||
{
|
||||
if (!m_running_quests.empty()) {
|
||||
RunningQuest e = m_running_quests.top();
|
||||
return e.owner;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EQ::InventoryProfile *QuestManager::GetInventory() const {
|
||||
if(!quests_running_.empty()) {
|
||||
running_quest e = quests_running_.top();
|
||||
EQ::InventoryProfile* QuestManager::GetInventory() const
|
||||
{
|
||||
if (!m_running_quests.empty()) {
|
||||
RunningQuest e = m_running_quests.top();
|
||||
return &e.initiator->GetInv();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EQ::ItemInstance *QuestManager::GetQuestItem() const {
|
||||
if(!quests_running_.empty()) {
|
||||
running_quest e = quests_running_.top();
|
||||
EQ::ItemInstance* QuestManager::GetQuestItem() const
|
||||
{
|
||||
if (!m_running_quests.empty()) {
|
||||
RunningQuest e = m_running_quests.top();
|
||||
return e.questitem;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const SPDat_Spell_Struct *QuestManager::GetQuestSpell() {
|
||||
if(!quests_running_.empty()) {
|
||||
running_quest e = quests_running_.top();
|
||||
const SPDat_Spell_Struct* QuestManager::GetQuestSpell()
|
||||
{
|
||||
if (!m_running_quests.empty()) {
|
||||
RunningQuest e = m_running_quests.top();
|
||||
return e.questspell;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string QuestManager::GetEncounter() const {
|
||||
if(!quests_running_.empty()) {
|
||||
running_quest e = quests_running_.top();
|
||||
std::string QuestManager::GetEncounter() const
|
||||
{
|
||||
if (!m_running_quests.empty()) {
|
||||
RunningQuest e = m_running_quests.top();
|
||||
return e.encounter;
|
||||
}
|
||||
|
||||
@ -4661,3 +4667,33 @@ bool QuestManager::handin(std::map<std::string, uint32> required) {
|
||||
|
||||
return owner->CastToNPC()->CheckHandin(initiator, {}, required, {});
|
||||
}
|
||||
|
||||
std::vector<std::string> QuestManager::GetPausedTimers(Mob* m)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
if (m && !PTimerList.empty()) {
|
||||
for (auto e = PTimerList.begin(); e != PTimerList.end(); e++) {
|
||||
if (e->owner == m) {
|
||||
v.emplace_back(e->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
std::vector<std::string> QuestManager::GetTimers(Mob* m)
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
if (m && !QTimerList.empty()) {
|
||||
for (auto e = QTimerList.begin(); e != QTimerList.end(); e++) {
|
||||
if (e->mob == m) {
|
||||
v.emplace_back(e->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@ -33,15 +33,17 @@ namespace EQ
|
||||
class ItemInstance;
|
||||
}
|
||||
|
||||
struct RunningQuest {
|
||||
Mob* owner = nullptr;
|
||||
Client* initiator = nullptr;
|
||||
EQ::ItemInstance* questitem = nullptr;
|
||||
const SPDat_Spell_Struct* questspell = nullptr;
|
||||
bool depop_npc = false;
|
||||
std::string encounter = "";
|
||||
Zone* zone = nullptr;
|
||||
};
|
||||
|
||||
class QuestManager {
|
||||
struct running_quest {
|
||||
Mob *owner;
|
||||
Client *initiator;
|
||||
EQ::ItemInstance* questitem;
|
||||
const SPDat_Spell_Struct* questspell;
|
||||
bool depop_npc;
|
||||
std::string encounter;
|
||||
};
|
||||
|
||||
struct PausedTimer {
|
||||
Mob* owner;
|
||||
@ -49,12 +51,13 @@ class QuestManager {
|
||||
uint32 time;
|
||||
};
|
||||
public:
|
||||
|
||||
QuestManager();
|
||||
virtual ~QuestManager();
|
||||
|
||||
void StartQuest(Mob *_owner, Client *_initiator = nullptr, EQ::ItemInstance* _questitem = nullptr, const SPDat_Spell_Struct* _questspell = nullptr, std::string encounter = "");
|
||||
void StartQuest(const RunningQuest& q);
|
||||
void EndQuest();
|
||||
bool QuestsRunning() { return !quests_running_.empty(); }
|
||||
bool QuestsRunning() { return !m_running_quests.empty(); }
|
||||
|
||||
void Process();
|
||||
|
||||
@ -361,6 +364,8 @@ public:
|
||||
bool SetAutoLoginCharacterNameByAccountID(uint32 account_id, const std::string& character_name);
|
||||
void SpawnCircle(uint32 npc_id, glm::vec4 position, float radius, uint32 points);
|
||||
void SpawnGrid(uint32 npc_id, glm::vec4 position, float spacing, uint32 spawn_count);
|
||||
std::vector<std::string> GetPausedTimers(Mob* m);
|
||||
std::vector<std::string> GetTimers(Mob* m);
|
||||
|
||||
Bot *GetBot() const;
|
||||
Client *GetInitiator() const;
|
||||
@ -381,7 +386,7 @@ public:
|
||||
bool handin(std::map<std::string, uint32> required);
|
||||
|
||||
private:
|
||||
std::stack<running_quest> quests_running_;
|
||||
std::stack<RunningQuest> m_running_quests;
|
||||
|
||||
bool HaveProximitySays;
|
||||
|
||||
|
||||
@ -1907,7 +1907,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
||||
target->GetBodyType() != BodyType::Undead &&
|
||||
taunt_time &&
|
||||
type_of_pet &&
|
||||
type_of_pet != petTargetLock &&
|
||||
type_of_pet != PetType::TargetLock &&
|
||||
DistanceSquared(GetPosition(), target->GetPosition()) <= (RuleI(Pets, PetTauntRange) * RuleI(Pets, PetTauntRange))
|
||||
) {
|
||||
GetOwner()->MessageString(Chat::PetResponse, PET_TAUNTING);
|
||||
|
||||
@ -803,19 +803,19 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
|
||||
caster->SetPet(this);
|
||||
SetOwnerID(caster->GetID());
|
||||
SetPetOrder(SPO_Follow);
|
||||
SetPetOrder(PetOrder::Follow);
|
||||
SetAppearance(eaStanding);
|
||||
// Client has saved previous pet sit/stand - make all new pets
|
||||
// stand and follow on charm.
|
||||
if (caster->IsClient()) {
|
||||
Client *cpet = caster->CastToClient();
|
||||
cpet->SetPetCommandState(PET_BUTTON_SIT,0);
|
||||
cpet->SetPetCommandState(PET_BUTTON_FOLLOW, 1);
|
||||
cpet->SetPetCommandState(PET_BUTTON_GUARD, 0);
|
||||
cpet->SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
cpet->SetPetCommandState(PetButton::Sit, PetButtonState::Off);
|
||||
cpet->SetPetCommandState(PetButton::Follow, PetButtonState::On);
|
||||
cpet->SetPetCommandState(PetButton::Guard, PetButtonState::Off);
|
||||
cpet->SetPetCommandState(PetButton::Stop, PetButtonState::Off);
|
||||
}
|
||||
|
||||
SetPetType(petCharmed);
|
||||
SetPetType(PetType::Charmed);
|
||||
|
||||
// This was done in AddBuff, but we were not a pet yet, so
|
||||
// the target windows didn't get updated.
|
||||
@ -1308,18 +1308,18 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
if (IsClient() && pet) {
|
||||
auto c = CastToClient();
|
||||
if (c->ClientVersionBit() & EQ::versions::maskUFAndLater) {
|
||||
c->SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_STOP, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_REGROUP, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_FOLLOW, 1);
|
||||
c->SetPetCommandState(PET_BUTTON_GUARD, 0);
|
||||
c->SetPetCommandState(PetButton::Sit, PetButtonState::Off);
|
||||
c->SetPetCommandState(PetButton::Stop, PetButtonState::Off);
|
||||
c->SetPetCommandState(PetButton::Regroup, PetButtonState::Off);
|
||||
c->SetPetCommandState(PetButton::Follow, PetButtonState::On);
|
||||
c->SetPetCommandState(PetButton::Guard, PetButtonState::Off);
|
||||
// Creating pet from spell - taunt always false
|
||||
// If suspended pet - that will be restore there
|
||||
// If logging in, client will send toggle
|
||||
c->SetPetCommandState(PET_BUTTON_HOLD, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_GHOLD, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_FOCUS, 0);
|
||||
c->SetPetCommandState(PET_BUTTON_SPELLHOLD, 0);
|
||||
c->SetPetCommandState(PetButton::Hold, PetButtonState::Off);
|
||||
c->SetPetCommandState(PetButton::GreaterHold, PetButtonState::Off);
|
||||
c->SetPetCommandState(PetButton::Focus, PetButtonState::Off);
|
||||
c->SetPetCommandState(PetButton::SpellHold, PetButtonState::Off);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1618,7 +1618,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
GetOwnerID() && // I'm a pet
|
||||
caster && // there's a caster
|
||||
caster->GetID() == GetOwnerID() && // and it's my master
|
||||
GetPetType() != petCharmed
|
||||
GetPetType() != PetType::Charmed
|
||||
)
|
||||
{
|
||||
uint16 pet_spellid = CastToNPC()->GetPetSpellID();
|
||||
@ -4427,7 +4427,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
SendAppearancePacket(AppearanceType::Pet, 0, true, true);
|
||||
Mob* owner = GetOwner();
|
||||
SetOwnerID(0);
|
||||
SetPetType(petNone);
|
||||
SetPetType(PetType::None);
|
||||
SetHeld(false);
|
||||
SetGHeld(false);
|
||||
SetNoCast(false);
|
||||
|
||||
@ -1414,11 +1414,19 @@ void ClientTaskState::ShowClientTaskInfoMessage(ClientTaskInformation *task, Cli
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Task {} | Title: {} ID: {} Type: {}",
|
||||
"Task {} | Title: {} ID: {} Type: {} | {}",
|
||||
task->slot,
|
||||
task_data->title,
|
||||
task->task_id,
|
||||
Tasks::GetTaskTypeDescription(task_data->type)
|
||||
Tasks::GetTaskTypeDescription(task_data->type),
|
||||
Saylink::Create(
|
||||
fmt::format(
|
||||
"#task complete {}",
|
||||
task->task_id
|
||||
),
|
||||
false,
|
||||
"Complete"
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
c->Message(Chat::White, "------------------------------------------------");
|
||||
|
||||
284
zone/zone.cpp
284
zone/zone.cpp
@ -1693,6 +1693,25 @@ bool Zone::Process() {
|
||||
}
|
||||
}
|
||||
|
||||
const bool has_timer_event = parse->ZoneHasQuestSub(EVENT_TIMER);
|
||||
|
||||
for (auto e : zone_timers) {
|
||||
if (e.timer_.Enabled() && e.timer_.Check()) {
|
||||
if (has_timer_event) {
|
||||
parse->EventZone(EVENT_TIMER, this, e.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_zone_signals.empty()) {
|
||||
int signal_id = m_zone_signals.front();
|
||||
m_zone_signals.pop_front();
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_SIGNAL)) {
|
||||
parse->EventZone(EVENT_SIGNAL, this, std::to_string(signal_id), 0);
|
||||
}
|
||||
}
|
||||
|
||||
mMovementManager->Process();
|
||||
|
||||
return true;
|
||||
@ -1935,6 +1954,8 @@ void Zone::Repop(bool is_forced)
|
||||
|
||||
quest_manager.ClearAllTimers();
|
||||
|
||||
StopAllTimers();
|
||||
|
||||
LogInfo("Loading spawn groups");
|
||||
if (!content_db.LoadSpawnGroups(short_name, GetInstanceVersion(), &spawn_group_list)) {
|
||||
LogError("Loading spawn groups failed");
|
||||
@ -3301,4 +3322,267 @@ void Zone::ReloadMaps()
|
||||
pathing = IPathfinder::Load(map_name);
|
||||
}
|
||||
|
||||
uint32 Zone::GetTimerDuration(std::string name)
|
||||
{
|
||||
if (!IsLoaded() || zone_timers.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto& e = std::find_if(
|
||||
zone_timers.begin(),
|
||||
zone_timers.end(),
|
||||
[&name](ZoneTimer e) {
|
||||
return e.name == name;
|
||||
}
|
||||
);
|
||||
|
||||
return e != zone_timers.end() ? e->timer_.GetDuration() : 0;
|
||||
}
|
||||
|
||||
uint32 Zone::GetTimerRemainingTime(std::string name)
|
||||
{
|
||||
if (!IsLoaded() || zone_timers.empty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto& e = std::find_if(
|
||||
zone_timers.begin(),
|
||||
zone_timers.end(),
|
||||
[&name](ZoneTimer e) {
|
||||
return e.name == name;
|
||||
}
|
||||
);
|
||||
|
||||
return e != zone_timers.end() ? e->timer_.GetRemainingTime() : 0;
|
||||
}
|
||||
|
||||
bool Zone::HasTimer(std::string name)
|
||||
{
|
||||
if (!IsLoaded() || zone_timers.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& e = std::find_if(
|
||||
zone_timers.begin(),
|
||||
zone_timers.end(),
|
||||
[&name](ZoneTimer e) {
|
||||
return e.name == name;
|
||||
}
|
||||
);
|
||||
|
||||
return e != zone_timers.end();
|
||||
}
|
||||
|
||||
bool Zone::IsPausedTimer(std::string name)
|
||||
{
|
||||
if (!IsLoaded() || paused_zone_timers.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto& e = std::find_if(
|
||||
paused_zone_timers.begin(),
|
||||
paused_zone_timers.end(),
|
||||
[&name](PausedZoneTimer e) {
|
||||
return e.name == name;
|
||||
}
|
||||
);
|
||||
|
||||
return e != paused_zone_timers.end();
|
||||
}
|
||||
|
||||
void Zone::PauseTimer(std::string name)
|
||||
{
|
||||
if (
|
||||
!IsLoaded() ||
|
||||
zone_timers.empty() ||
|
||||
!HasTimer(name) ||
|
||||
IsPausedTimer(name)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 remaining_time = 0;
|
||||
|
||||
const bool has_pause_event = parse->ZoneHasQuestSub(EVENT_TIMER_PAUSE);
|
||||
|
||||
if (!zone_timers.empty()) {
|
||||
for (auto e = zone_timers.begin(); e != zone_timers.end(); e++) {
|
||||
if (e->name == name) {
|
||||
remaining_time = e->timer_.GetRemainingTime();
|
||||
|
||||
zone_timers.erase(e);
|
||||
|
||||
const std::string& export_string = fmt::format(
|
||||
"{} {}",
|
||||
name,
|
||||
remaining_time
|
||||
);
|
||||
|
||||
LogQuests(
|
||||
"Pausing timer [{}] with [{}] ms remaining",
|
||||
name,
|
||||
remaining_time
|
||||
);
|
||||
|
||||
paused_zone_timers.emplace_back(
|
||||
PausedZoneTimer{
|
||||
.name = name,
|
||||
.remaining_time = remaining_time
|
||||
}
|
||||
);
|
||||
|
||||
if (has_pause_event) {
|
||||
parse->EventZone(EVENT_TIMER_PAUSE, this, export_string);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::ResumeTimer(std::string name)
|
||||
{
|
||||
if (
|
||||
!IsLoaded() ||
|
||||
paused_zone_timers.empty() ||
|
||||
!IsPausedTimer(name)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 remaining_time = 0;
|
||||
|
||||
if (!paused_zone_timers.empty()) {
|
||||
for (auto e = paused_zone_timers.begin(); e != paused_zone_timers.end(); e++) {
|
||||
if (e->name == name) {
|
||||
remaining_time = e->remaining_time;
|
||||
|
||||
paused_zone_timers.erase(e);
|
||||
|
||||
if (!remaining_time) {
|
||||
LogQuests("Paused timer [{}] not found or has expired.", name);
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& export_string = fmt::format(
|
||||
"{} {}",
|
||||
name,
|
||||
remaining_time
|
||||
);
|
||||
|
||||
LogQuests(
|
||||
"Creating a new timer and resuming [{}] with [{}] ms remaining",
|
||||
name,
|
||||
remaining_time
|
||||
);
|
||||
|
||||
zone_timers.emplace_back(ZoneTimer(name, remaining_time));
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_TIMER_RESUME)) {
|
||||
parse->EventZone(EVENT_TIMER_RESUME, this, export_string);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::SetTimer(std::string name, uint32 duration)
|
||||
{
|
||||
if (!IsLoaded() || HasTimer(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
zone_timers.emplace_back(ZoneTimer(name, duration));
|
||||
|
||||
if (parse->ZoneHasQuestSub(EVENT_TIMER_START)) {
|
||||
const std::string& export_string = fmt::format("{} {}", name, duration);
|
||||
parse->EventZone(EVENT_TIMER_START, this, export_string);
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::StopTimer(std::string name)
|
||||
{
|
||||
if (
|
||||
!IsLoaded() ||
|
||||
zone_timers.empty() ||
|
||||
!HasTimer(name) ||
|
||||
IsPausedTimer(name)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool has_stop_event = parse->ZoneHasQuestSub(EVENT_TIMER_STOP);
|
||||
|
||||
for (auto e = zone_timers.begin(); e != zone_timers.end(); e++) {
|
||||
if (e->name == name) {
|
||||
if (has_stop_event) {
|
||||
parse->EventZone(EVENT_TIMER_STOP, this, name);
|
||||
}
|
||||
|
||||
zone_timers.erase(e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::StopAllTimers()
|
||||
{
|
||||
if (!IsLoaded() || zone_timers.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bool has_stop_event = parse->ZoneHasQuestSub(EVENT_TIMER_STOP);
|
||||
|
||||
for (auto e = zone_timers.begin(); e != zone_timers.end();) {
|
||||
if (has_stop_event) {
|
||||
parse->EventZone(EVENT_TIMER_STOP, this, e->name);
|
||||
}
|
||||
|
||||
e = zone_timers.erase(e);
|
||||
}
|
||||
}
|
||||
|
||||
void Zone::Signal(int signal_id)
|
||||
{
|
||||
m_zone_signals.push_back(signal_id);
|
||||
}
|
||||
|
||||
void Zone::SendPayload(int payload_id, std::string payload_value)
|
||||
{
|
||||
if (parse->ZoneHasQuestSub(EVENT_PAYLOAD)) {
|
||||
const auto& export_string = fmt::format("{} {}", payload_id, payload_value);
|
||||
|
||||
parse->EventZone(EVENT_PAYLOAD, this, export_string, 0);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> Zone::GetPausedTimers()
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
if (!paused_zone_timers.empty()) {
|
||||
for (auto e = paused_zone_timers.begin(); e != paused_zone_timers.end(); e++) {
|
||||
v.emplace_back(e->name);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
std::vector<std::string> Zone::GetTimers()
|
||||
{
|
||||
std::vector<std::string> v;
|
||||
|
||||
if (!zone_timers.empty()) {
|
||||
for (auto e = zone_timers.begin(); e != zone_timers.end(); e++) {
|
||||
v.emplace_back(e->name);
|
||||
}
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
#include "zone_loot.cpp"
|
||||
|
||||
32
zone/zone.h
32
zone/zone.h
@ -486,6 +486,26 @@ public:
|
||||
static void ClearZoneState(uint32 zone_id, uint32 instance_id);
|
||||
void ReloadMaps();
|
||||
|
||||
void Signal(int signal_id);
|
||||
void SendPayload(int payload_id, std::string payload_value);
|
||||
|
||||
struct PausedZoneTimer {
|
||||
std::string name;
|
||||
uint32 remaining_time;
|
||||
};
|
||||
|
||||
uint32 GetTimerDuration(std::string name);
|
||||
uint32 GetTimerRemainingTime(std::string name);
|
||||
bool HasTimer(std::string name);
|
||||
bool IsPausedTimer(std::string name);
|
||||
void PauseTimer(std::string name);
|
||||
void ResumeTimer(std::string name);
|
||||
void SetTimer(std::string name, uint32 duration);
|
||||
void StopTimer(std::string name);
|
||||
void StopAllTimers();
|
||||
std::vector<std::string> GetPausedTimers();
|
||||
std::vector<std::string> GetTimers();
|
||||
|
||||
private:
|
||||
bool allow_mercs;
|
||||
bool can_bind;
|
||||
@ -552,6 +572,18 @@ private:
|
||||
std::vector<BaseDataRepository::BaseData> m_base_data = { };
|
||||
|
||||
uint32_t m_zone_server_id = 0;
|
||||
|
||||
class ZoneTimer {
|
||||
public:
|
||||
inline ZoneTimer(std::string _name, uint32 duration)
|
||||
: name(_name), timer_(duration) { timer_.Start(duration, false); }
|
||||
std::string name;
|
||||
Timer timer_;
|
||||
};
|
||||
|
||||
std::vector<ZoneTimer> zone_timers;
|
||||
std::vector<PausedZoneTimer> paused_zone_timers;
|
||||
std::deque<int> m_zone_signals;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -709,7 +709,7 @@ void Client::ProcessMovePC(uint32 zoneID, uint32 instance_id, float x, float y,
|
||||
//if they have a pet and they are staying in zone, move with them
|
||||
Mob *p = GetPet();
|
||||
if(p != nullptr){
|
||||
p->SetPetOrder(SPO_Follow);
|
||||
p->SetPetOrder(PetOrder::Follow);
|
||||
p->GMMove(x+15, y, z); //so it dosent have to run across the map.
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user