mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 12:41:30 +00:00
[Logging] Netcode Logging Unify (#2443)
* [Logging] Unify netcode logging * More tweaks, generator * Exclude OP_SpecialMesg at callback level * Consolidate packet loggers * Log at EQStream level instead of proxy * Fix C->S * Server to server logging * C-S for Loginserver * Hook UCS for C->S * Update eqemu_logsys.h * World C->S logging * Translate opcodes through patch system for client to server * Additional logging requests * Add detailed opcode translation logging * vStringFormat resiliency * Translate loginserver C->S * Simplify out message string (reduce copies) and ignore legacy formats * Update eqemu_logsys.cpp * Log file format * Handle deprecated categories
This commit is contained in:
parent
9d766bf5dc
commit
19791195e5
@ -218,13 +218,13 @@ class EQStream : public EQStreamInterface {
|
||||
|
||||
void init(bool resetSession=true);
|
||||
public:
|
||||
EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED;
|
||||
StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2;
|
||||
bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0;
|
||||
EQStream() { init(); remote_ip = 0; remote_port = 0; State = UNESTABLISHED;
|
||||
StreamType = UnknownStream; compressed = true; encoded = false; app_opcode_size = 2;
|
||||
bytes_sent = 0; bytes_recv = 0; create_time = Timer::GetTimeSeconds(); sessionAttempts = 0;
|
||||
streamactive = false; }
|
||||
EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr;
|
||||
remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream;
|
||||
compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0;
|
||||
EQStream(sockaddr_in addr) { init(); remote_ip = addr.sin_addr.s_addr;
|
||||
remote_port = addr.sin_port; State = UNESTABLISHED; StreamType = UnknownStream;
|
||||
compressed = true; encoded = false; app_opcode_size = 2; bytes_sent = 0; bytes_recv = 0;
|
||||
create_time = Timer::GetTimeSeconds(); }
|
||||
virtual ~EQStream() { RemoveData(); SetState(CLOSED); }
|
||||
void SetMaxLen(uint32 length) { MaxLen=length; }
|
||||
@ -243,6 +243,11 @@ class EQStream : public EQStreamInterface {
|
||||
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm) { OpMgr = opm; }
|
||||
|
||||
virtual OpcodeManager* GetOpcodeManager() const
|
||||
{
|
||||
return (*OpMgr);
|
||||
};
|
||||
|
||||
void CheckTimeout(uint32 now, uint32 timeout=30);
|
||||
bool HasOutgoingData();
|
||||
void Process(const unsigned char *data, const uint32 length);
|
||||
|
||||
@ -30,7 +30,7 @@ struct EQStreamManagerInterfaceOptions
|
||||
|
||||
//World seems to support both compression and xor zone supports one or the others.
|
||||
//Enforce one or the other in the convienence construct
|
||||
//Login I had trouble getting to recognize compression at all
|
||||
//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;
|
||||
@ -100,6 +100,7 @@ public:
|
||||
virtual MatchState CheckSignature(const Signature *sig) { return MatchFailed; }
|
||||
virtual EQStreamState GetState() = 0;
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm) = 0;
|
||||
virtual OpcodeManager* GetOpcodeManager() const = 0;
|
||||
virtual const EQ::versions::ClientVersion ClientVersion() const { return EQ::versions::ClientVersion::Unknown; }
|
||||
virtual Stats GetStats() const = 0;
|
||||
virtual void ResetStats() = 0;
|
||||
|
||||
@ -38,12 +38,8 @@ void EQStreamProxy::SetOpcodeManager(OpcodeManager **opm)
|
||||
}
|
||||
|
||||
void EQStreamProxy::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
||||
if(p == nullptr)
|
||||
if (p == nullptr) {
|
||||
return;
|
||||
|
||||
if (p->GetOpcode() != OP_SpecialMesg) {
|
||||
Log(Logs::General, Logs::PacketServerClient, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size());
|
||||
Log(Logs::General, Logs::PacketServerClientWithDump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(p->GetOpcode()), p->GetOpcode(), p->Size(), DumpPacketToString(p).c_str());
|
||||
}
|
||||
|
||||
EQApplicationPacket *newp = p->Copy();
|
||||
@ -112,3 +108,8 @@ bool EQStreamProxy::CheckState(EQStreamState state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OpcodeManager *EQStreamProxy::GetOpcodeManager() const
|
||||
{
|
||||
return (*m_opcodes);
|
||||
}
|
||||
|
||||
|
||||
@ -34,13 +34,15 @@ public:
|
||||
virtual Stats GetStats() const;
|
||||
virtual void ResetStats();
|
||||
virtual EQStreamManagerInterface* GetManager() const;
|
||||
virtual OpcodeManager* GetOpcodeManager() const;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<EQStreamInterface> const m_stream; //we own this stream object.
|
||||
const StructStrategy *const m_structs; //we do not own this object.
|
||||
//this is a pointer to a pointer to make it less likely that a packet will
|
||||
//reference an invalid opcode manager when they are being reloaded.
|
||||
OpcodeManager **const m_opcodes; //we do not own this object.
|
||||
OpcodeManager **const m_opcodes;
|
||||
//we do not own this object.
|
||||
};
|
||||
|
||||
#endif /*EQSTREAMPROXY_H_*/
|
||||
|
||||
@ -212,21 +212,6 @@ bool EQEmuLogSys::IsRfc5424LogCategory(uint16 log_category)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param log_category
|
||||
* @param in_message
|
||||
* @return
|
||||
*/
|
||||
std::string EQEmuLogSys::FormatOutMessageString(
|
||||
uint16 log_category,
|
||||
const std::string &in_message
|
||||
)
|
||||
{
|
||||
std::string return_string = "[" + GetPlatformName() + "] ";
|
||||
|
||||
return return_string + "[" + Logs::LogCategoryName[log_category] + "] " + in_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param debug_level
|
||||
* @param log_category
|
||||
@ -423,24 +408,10 @@ void EQEmuLogSys::Out(
|
||||
...
|
||||
)
|
||||
{
|
||||
bool log_to_console = log_settings[log_category].log_to_console > 0 &&
|
||||
log_settings[log_category].log_to_console >= debug_level;
|
||||
bool log_to_file = log_settings[log_category].log_to_file > 0 &&
|
||||
log_settings[log_category].log_to_file >= debug_level;
|
||||
bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0 &&
|
||||
log_settings[log_category].log_to_gmsay >= debug_level &&
|
||||
log_category != Logs::LogCategory::Netcode &&
|
||||
(EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone ||
|
||||
EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld);
|
||||
bool log_to_discord = EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone &&
|
||||
log_settings[log_category].log_to_discord > 0 &&
|
||||
log_settings[log_category].log_to_discord >= debug_level &&
|
||||
log_settings[log_category].discord_webhook_id > 0 &&
|
||||
log_settings[log_category].discord_webhook_id < MAX_DISCORD_WEBHOOK_ID;
|
||||
auto l = GetLogsEnabled(debug_level, log_category);
|
||||
|
||||
// bail out if nothing to log
|
||||
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay && !log_to_discord;
|
||||
if (nothing_to_log) {
|
||||
if (!l.log_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -449,23 +420,39 @@ void EQEmuLogSys::Out(
|
||||
prefix = fmt::format("[{0}::{1}:{2}] ", base_file_name(file), func, line);
|
||||
}
|
||||
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
std::string output_message = vStringFormat(message, args);
|
||||
va_end(args);
|
||||
// remove this when we remove all legacy logs
|
||||
bool ignore_log_legacy_format = (
|
||||
log_category == Logs::Netcode ||
|
||||
log_category == Logs::PacketServerClient ||
|
||||
log_category == Logs::PacketClientServer ||
|
||||
log_category == Logs::PacketServerToServer
|
||||
);
|
||||
|
||||
std::string output_debug_message = EQEmuLogSys::FormatOutMessageString(log_category, prefix + output_message);
|
||||
|
||||
if (log_to_console) {
|
||||
EQEmuLogSys::ProcessConsoleMessage(log_category, output_debug_message);
|
||||
// remove this when we remove all legacy logs
|
||||
std::string output_message = message;
|
||||
if (!ignore_log_legacy_format) {
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
output_message = vStringFormat(message, args);
|
||||
va_end(args);
|
||||
}
|
||||
if (log_to_gmsay) {
|
||||
|
||||
if (l.log_to_console_enabled) {
|
||||
EQEmuLogSys::ProcessConsoleMessage(
|
||||
log_category,
|
||||
fmt::format("[{}] [{}] {}", GetPlatformName(), Logs::LogCategoryName[log_category], prefix + output_message)
|
||||
);
|
||||
}
|
||||
if (l.log_to_gmsay_enabled) {
|
||||
m_on_log_gmsay_hook(log_category, output_message);
|
||||
}
|
||||
if (log_to_file) {
|
||||
EQEmuLogSys::ProcessLogWrite(log_category, output_debug_message);
|
||||
if (l.log_to_file_enabled) {
|
||||
EQEmuLogSys::ProcessLogWrite(
|
||||
log_category,
|
||||
fmt::format("[{}] [{}] {}", GetPlatformName(), Logs::LogCategoryName[log_category], prefix + output_message)
|
||||
);
|
||||
}
|
||||
if (log_to_discord && m_on_log_discord_hook) {
|
||||
if (l.log_to_discord_enabled && m_on_log_discord_hook) {
|
||||
m_on_log_discord_hook(log_category, log_settings[log_category].discord_webhook_id, output_message);
|
||||
}
|
||||
}
|
||||
@ -479,7 +466,7 @@ void EQEmuLogSys::SetCurrentTimeStamp(char *time_stamp)
|
||||
struct tm *time_info;
|
||||
time(&raw_time);
|
||||
time_info = localtime(&raw_time);
|
||||
strftime(time_stamp, 80, "[%m-%d-%Y :: %H:%M:%S]", time_info);
|
||||
strftime(time_stamp, 80, "[%m-%d-%Y %H:%M:%S]", time_info);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -642,10 +629,19 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
||||
|
||||
// Auto inject categories that don't exist in the database...
|
||||
for (int i = Logs::AA; i != Logs::MaxCategoryID; i++) {
|
||||
if (std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end()) {
|
||||
|
||||
bool is_missing_in_database = std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end();
|
||||
bool is_deprecated_category = Strings::Contains(fmt::format("{}", Logs::LogCategoryName[i]), "Deprecated");
|
||||
if (!is_missing_in_database && is_deprecated_category) {
|
||||
LogInfo("Logging category [{}] ({}) is now deprecated, deleting from database", Logs::LogCategoryName[i], i);
|
||||
LogsysCategoriesRepository::DeleteOne(*m_database, i);
|
||||
}
|
||||
|
||||
if (is_missing_in_database && !is_deprecated_category) {
|
||||
LogInfo(
|
||||
"Automatically adding new log category [{0}]",
|
||||
Logs::LogCategoryName[i]
|
||||
"Automatically adding new log category [{}] ({})",
|
||||
Logs::LogCategoryName[i],
|
||||
i
|
||||
);
|
||||
|
||||
auto new_category = LogsysCategoriesRepository::NewEntity();
|
||||
@ -696,13 +692,13 @@ void EQEmuLogSys::InjectTablesIfNotExist()
|
||||
CREATE TABLE discord_webhooks
|
||||
(
|
||||
id INT auto_increment primary key NULL,
|
||||
webhook_name varchar(100) NULL,
|
||||
webhook_url varchar(255) NULL,
|
||||
created_at DATETIME NULL,
|
||||
deleted_at DATETIME NULL
|
||||
) ENGINE=InnoDB
|
||||
DEFAULT CHARSET=utf8mb4
|
||||
COLLATE=utf8mb4_general_ci;
|
||||
webhook_name varchar(100) NULL,
|
||||
webhook_url varchar(255) NULL,
|
||||
created_at DATETIME NULL,
|
||||
deleted_at DATETIME NULL
|
||||
) ENGINE=InnoDB
|
||||
DEFAULT CHARSET=utf8mb4
|
||||
COLLATE=utf8mb4_general_ci;
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -713,15 +709,15 @@ void EQEmuLogSys::InjectTablesIfNotExist()
|
||||
m_database->QueryDatabase(
|
||||
SQL(
|
||||
CREATE TABLE `logsys_categories` (
|
||||
`log_category_id` int(11) NOT NULL,
|
||||
`log_category_description` varchar(150) DEFAULT NULL,
|
||||
`log_to_console` smallint(11) DEFAULT 0,
|
||||
`log_to_file` smallint(11) DEFAULT 0,
|
||||
`log_to_gmsay` smallint(11) DEFAULT 0,
|
||||
`log_to_discord` smallint(11) DEFAULT 0,
|
||||
`discord_webhook_id` int(11) DEFAULT 0,
|
||||
PRIMARY KEY (`log_category_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
`log_category_id` int(11) NOT NULL,
|
||||
`log_category_description` varchar(150) DEFAULT NULL,
|
||||
`log_to_console` smallint(11) DEFAULT 0,
|
||||
`log_to_file` smallint(11) DEFAULT 0,
|
||||
`log_to_gmsay` smallint(11) DEFAULT 0,
|
||||
`log_to_discord` smallint(11) DEFAULT 0,
|
||||
`discord_webhook_id` int(11) DEFAULT 0,
|
||||
PRIMARY KEY (`log_category_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
)
|
||||
);
|
||||
}
|
||||
@ -732,3 +728,31 @@ const EQEmuLogSys::DiscordWebhooks *EQEmuLogSys::GetDiscordWebhooks() const
|
||||
return m_discord_webhooks;
|
||||
}
|
||||
|
||||
EQEmuLogSys::LogEnabled EQEmuLogSys::GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category)
|
||||
{
|
||||
auto e = LogEnabled{};
|
||||
|
||||
e.log_to_console_enabled = log_settings[log_category].log_to_console > 0 &&
|
||||
log_settings[log_category].log_to_console >= debug_level;
|
||||
e.log_to_file_enabled = log_settings[log_category].log_to_file > 0 &&
|
||||
log_settings[log_category].log_to_file >= debug_level;
|
||||
e.log_to_gmsay_enabled = log_settings[log_category].log_to_gmsay > 0 &&
|
||||
log_settings[log_category].log_to_gmsay >= debug_level &&
|
||||
log_category != Logs::LogCategory::Netcode &&
|
||||
(EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone ||
|
||||
EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformWorld);
|
||||
e.log_to_discord_enabled = EQEmuLogSys::m_log_platform == EQEmuExePlatform::ExePlatformZone &&
|
||||
log_settings[log_category].log_to_discord > 0 &&
|
||||
log_settings[log_category].log_to_discord >= debug_level &&
|
||||
log_settings[log_category].discord_webhook_id > 0 &&
|
||||
log_settings[log_category].discord_webhook_id < MAX_DISCORD_WEBHOOK_ID;
|
||||
e.log_enabled =
|
||||
e.log_to_console_enabled || e.log_to_file_enabled || e.log_to_gmsay_enabled || e.log_to_discord_enabled;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
bool EQEmuLogSys::IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category)
|
||||
{
|
||||
return GetLogsEnabled(debug_level, log_category).log_enabled;
|
||||
}
|
||||
|
||||
@ -54,7 +54,7 @@ namespace Logs {
|
||||
AI,
|
||||
Aggro,
|
||||
Attack,
|
||||
PacketClientServer,
|
||||
DeprecatedCS,
|
||||
Combat,
|
||||
Commands,
|
||||
Crash,
|
||||
@ -88,10 +88,10 @@ namespace Logs {
|
||||
MySQLQuery,
|
||||
Mercenaries,
|
||||
QuestDebug,
|
||||
PacketServerClient,
|
||||
PacketClientServerUnhandled,
|
||||
PacketServerClientWithDump,
|
||||
PacketClientServerWithDump,
|
||||
DeprecatedSC,
|
||||
DeprecatedCSU,
|
||||
DeprecatedSCD,
|
||||
DeprecatedCSD,
|
||||
Loginserver,
|
||||
ClientLogin,
|
||||
HeadlessClient,
|
||||
@ -132,6 +132,9 @@ namespace Logs {
|
||||
Hate,
|
||||
Discord,
|
||||
Faction,
|
||||
PacketServerClient,
|
||||
PacketClientServer,
|
||||
PacketServerToServer,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@ -144,7 +147,7 @@ namespace Logs {
|
||||
"AI",
|
||||
"Aggro",
|
||||
"Attack",
|
||||
"Packet :: Client -> Server",
|
||||
"Deprecated",
|
||||
"Combat",
|
||||
"Commands",
|
||||
"Crash",
|
||||
@ -178,10 +181,10 @@ namespace Logs {
|
||||
"MySQL Query",
|
||||
"Mercenaries",
|
||||
"Quest Debug",
|
||||
"Packet :: Server -> Client",
|
||||
"Packet :: Client -> Server Unhandled",
|
||||
"Packet :: Server -> Client (Dump)",
|
||||
"Packet :: Client -> Server (Dump)",
|
||||
"Deprecated",
|
||||
"Deprecated",
|
||||
"Deprecated",
|
||||
"Deprecated",
|
||||
"Login Server",
|
||||
"Client Login",
|
||||
"Headless Client",
|
||||
@ -222,6 +225,9 @@ namespace Logs {
|
||||
"Hate",
|
||||
"Discord",
|
||||
"Faction",
|
||||
"Packet-S->C",
|
||||
"Packet-C->S",
|
||||
"Packet-S->S"
|
||||
};
|
||||
}
|
||||
|
||||
@ -313,6 +319,17 @@ public:
|
||||
*/
|
||||
LogSettings log_settings[Logs::LogCategory::MaxCategoryID]{};
|
||||
|
||||
struct LogEnabled {
|
||||
bool log_to_file_enabled;
|
||||
bool log_to_console_enabled;
|
||||
bool log_to_gmsay_enabled;
|
||||
bool log_to_discord_enabled;
|
||||
bool log_enabled;
|
||||
};
|
||||
|
||||
LogEnabled GetLogsEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
|
||||
bool IsLogEnabled(const Logs::DebugLevel &debug_level, const uint16 &log_category);
|
||||
|
||||
struct DiscordWebhooks {
|
||||
int id;
|
||||
std::string webhook_name;
|
||||
@ -361,7 +378,6 @@ private:
|
||||
int m_log_platform = 0;
|
||||
std::string m_platform_file_name;
|
||||
|
||||
std::string FormatOutMessageString(uint16 log_category, const std::string &in_message);
|
||||
std::string GetLinuxConsoleColorFromCategory(uint16 log_category);
|
||||
uint16 GetWindowsConsoleColorFromCategory(uint16 log_category);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,7 @@
|
||||
#include "../event/task.h"
|
||||
#include "../data_verification.h"
|
||||
#include "crc32.h"
|
||||
#include "../eqemu_logsys.h"
|
||||
#include <zlib.h>
|
||||
#include <fmt/format.h>
|
||||
#include <sstream>
|
||||
@ -308,6 +309,8 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
||||
m_combined[1] = OP_Combined;
|
||||
m_last_session_stats = Clock::now();
|
||||
m_outgoing_budget = owner->m_options.outgoing_data_rate;
|
||||
|
||||
LogNetcode("New session [{}] with encode key [{}]", m_connect_code, HostToNetwork(m_encode_key));
|
||||
}
|
||||
|
||||
//new connection made as client
|
||||
@ -466,7 +469,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
||||
for (int i = 1; i >= 0; --i) {
|
||||
switch (m_encode_passes[i]) {
|
||||
case EncodeXOR:
|
||||
if (temp.GetInt8(0) == 0)
|
||||
if (temp.GetInt8(0) == 0)
|
||||
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
|
||||
else
|
||||
Decode(temp, 1, temp.Length() - 1);
|
||||
@ -630,6 +633,8 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
DynamicPacket p;
|
||||
p.PutSerialize(0, reply);
|
||||
InternalSend(p);
|
||||
|
||||
LogNetcode("[OP_SessionRequest] Session [{}] started with encode key [{}]", m_connect_code, HostToNetwork(m_encode_key));
|
||||
}
|
||||
|
||||
break;
|
||||
@ -647,6 +652,12 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
m_encode_passes[1] = (DaybreakEncodeType)reply.encode_pass2;
|
||||
m_max_packet_size = reply.max_packet_size;
|
||||
ChangeStatus(StatusConnected);
|
||||
|
||||
LogNetcode(
|
||||
"[OP_SessionResponse] Session [{}] refresh with encode key [{}]",
|
||||
m_connect_code,
|
||||
HostToNetwork(m_encode_key)
|
||||
);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -771,6 +782,12 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
|
||||
SendDisconnect();
|
||||
}
|
||||
|
||||
LogNetcode(
|
||||
"[OP_SessionDisconnect] Session [{}] disconnect with encode key [{}]",
|
||||
m_connect_code,
|
||||
HostToNetwork(m_encode_key)
|
||||
);
|
||||
|
||||
ChangeStatus(StatusDisconnecting);
|
||||
break;
|
||||
}
|
||||
@ -835,6 +852,7 @@ bool EQ::Net::DaybreakConnection::ValidateCRC(Packet &p)
|
||||
}
|
||||
|
||||
if (p.Length() < (size_t)m_crc_bytes) {
|
||||
LogNetcode("Session [{}] ignored packet (crc bytes invalid on session)", m_connect_code);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1078,7 +1096,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
if (m_status == DbProtocolStatus::StatusDisconnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto resends = 0;
|
||||
auto now = Clock::now();
|
||||
auto s = &m_streams[stream];
|
||||
@ -1113,7 +1131,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if ((size_t)time_since_last_send.count() > entry.second.resend_delay) {
|
||||
auto &p = entry.second.packet;
|
||||
if (p.Length() >= DaybreakHeader::size()) {
|
||||
@ -1406,8 +1424,8 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
||||
sent.first_sent = Clock::now();
|
||||
sent.times_resent = 0;
|
||||
sent.resend_delay = EQ::Clamp(
|
||||
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
|
||||
m_owner->m_options.resend_delay_min,
|
||||
static_cast<size_t>((m_rolling_ping * m_owner->m_options.resend_delay_factor) + m_owner->m_options.resend_delay_ms),
|
||||
m_owner->m_options.resend_delay_min,
|
||||
m_owner->m_options.resend_delay_max);
|
||||
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
|
||||
stream->sequence_out++;
|
||||
|
||||
@ -65,6 +65,15 @@ EQ::Net::EQStream::~EQStream()
|
||||
}
|
||||
|
||||
void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p, bool ack_req) {
|
||||
|
||||
LogPacketServerClient(
|
||||
"[{}] [{:#06x}] Size [{}] {}",
|
||||
OpcodeManager::EmuToName(p->GetOpcode()),
|
||||
(*m_opcode_manager)->EmuToEQ(p->GetOpcode()),
|
||||
p->Size(),
|
||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerClient) ? DumpPacketToString(p) : "")
|
||||
);
|
||||
|
||||
if (m_opcode_manager && *m_opcode_manager) {
|
||||
uint16 opcode = 0;
|
||||
if (p->GetOpcodeBypass() != 0) {
|
||||
|
||||
@ -57,6 +57,10 @@ namespace EQ
|
||||
virtual void SetOpcodeManager(OpcodeManager **opm) {
|
||||
m_opcode_manager = opm;
|
||||
}
|
||||
virtual OpcodeManager * GetOpcodeManager() const
|
||||
{
|
||||
return (*m_opcode_manager);
|
||||
};
|
||||
|
||||
virtual Stats GetStats() const;
|
||||
virtual void ResetStats();
|
||||
|
||||
@ -135,7 +135,7 @@ void EQ::Net::ServertalkServerConnection::ProcessReadBuffer()
|
||||
auto leg_opcode = *(uint16_t*)&m_buffer[current];
|
||||
auto leg_size = *(uint16_t*)&m_buffer[current + 2] - 4;
|
||||
|
||||
//this creates a small edge case where the exact size of a
|
||||
//this creates a small edge case where the exact size of a
|
||||
//packet from the modern protocol can't be "43061256"
|
||||
//so in send we pad it one byte if that's the case
|
||||
if (leg_opcode == ServerOP_NewLSInfo && leg_size == sizeof(ServerNewLSInfo_Struct)) {
|
||||
@ -319,6 +319,16 @@ void EQ::Net::ServertalkServerConnection::ProcessMessage(EQ::Net::Packet &p)
|
||||
size_t message_len = length;
|
||||
EQ::Net::StaticPacket packet(&data[0], message_len);
|
||||
|
||||
const auto is_detail_enabled = LogSys.IsLogEnabled(Logs::Detail, Logs::PacketServerToServer);
|
||||
if (opcode != ServerOP_KeepAlive || is_detail_enabled) {
|
||||
LogPacketServerToServer(
|
||||
"[{:#06x}] Size [{}] {}",
|
||||
opcode,
|
||||
packet.Length(),
|
||||
(is_detail_enabled ? "\n" + packet.ToString() : "")
|
||||
);
|
||||
}
|
||||
|
||||
auto cb = m_message_callbacks.find(opcode);
|
||||
if (cb != m_message_callbacks.end()) {
|
||||
cb->second(opcode, packet);
|
||||
|
||||
@ -184,6 +184,9 @@ uint16 RegularOpcodeManager::EmuToEQ(const EmuOpcode emu_op) {
|
||||
MOpcodes.lock();
|
||||
res = emu_to_eq[emu_op];
|
||||
MOpcodes.unlock();
|
||||
|
||||
LogNetcodeDetail("[Opcode Manager] Translate emu [{}] ({:#06x}) eq [{:#06x}]", OpcodeNames[emu_op], emu_op, res);
|
||||
|
||||
#ifdef DEBUG_TRANSLATE
|
||||
fprintf(stderr, "M Translate Emu %s (%d) to EQ 0x%.4x\n", OpcodeNames[emu_op], emu_op, res);
|
||||
#endif
|
||||
|
||||
@ -26,13 +26,13 @@ bool Client::Process()
|
||||
{
|
||||
EQApplicationPacket *app = m_connection->PopPacket();
|
||||
while (app) {
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug("Application packet received from client (size {0})", app->Size());
|
||||
}
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(app);
|
||||
}
|
||||
LogPacketClientServer(
|
||||
"[{}] [{:#06x}] Size [{}] {}",
|
||||
OpcodeManager::EmuToName(app->GetOpcode()),
|
||||
m_connection->GetOpcodeManager()->EmuToEQ(app->GetOpcode()),
|
||||
app->Size(),
|
||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
||||
);
|
||||
|
||||
if (m_client_status == cs_failed_to_login) {
|
||||
delete app;
|
||||
@ -42,9 +42,7 @@ bool Client::Process()
|
||||
|
||||
switch (app->GetOpcode()) {
|
||||
case OP_SessionReady: {
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogInfo("Session ready received from client");
|
||||
}
|
||||
LogInfo("Session ready received from client account {}", GetClientDescription());
|
||||
Handle_SessionReady((const char *) app->pBuffer, app->Size());
|
||||
break;
|
||||
}
|
||||
@ -54,9 +52,7 @@ bool Client::Process()
|
||||
break;
|
||||
}
|
||||
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogInfo("Login received from client");
|
||||
}
|
||||
LogInfo("Login received from client {}", GetClientDescription());
|
||||
|
||||
Handle_Login((const char *) app->pBuffer, app->Size());
|
||||
break;
|
||||
@ -67,9 +63,7 @@ bool Client::Process()
|
||||
break;
|
||||
}
|
||||
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug("Server list request received from client");
|
||||
}
|
||||
LogInfo("Server list request received from client {}", GetClientDescription());
|
||||
|
||||
SendServerListPacket(*(uint32_t *) app->pBuffer);
|
||||
break;
|
||||
@ -84,11 +78,9 @@ bool Client::Process()
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (LogSys.log_settings[Logs::PacketClientServerUnhandled].is_category_enabled == 1) {
|
||||
char dump[64];
|
||||
app->build_header_dump(dump);
|
||||
LogError("Recieved unhandled application packet from the client: [{}]", dump);
|
||||
}
|
||||
char dump[64];
|
||||
app->build_header_dump(dump);
|
||||
LogError("Received unhandled application packet from the client: [{}]", dump);
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,10 +120,6 @@ void Client::Handle_SessionReady(const char *data, unsigned int size)
|
||||
buf->base_reply.success = true;
|
||||
buf->base_reply.error_str_id = 0x65; // 101 "No Error"
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(outapp);
|
||||
}
|
||||
|
||||
m_connection->QueuePacket(outapp);
|
||||
delete outapp;
|
||||
}
|
||||
@ -290,14 +278,12 @@ void Client::Handle_Play(const char *data)
|
||||
auto server_id_in = (unsigned int) play->server_number;
|
||||
auto sequence_in = (unsigned int) play->base_header.sequence;
|
||||
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogInfo(
|
||||
"Play received from client [{0}] server number {1} sequence {2}",
|
||||
GetAccountName(),
|
||||
server_id_in,
|
||||
sequence_in
|
||||
);
|
||||
}
|
||||
LogInfo(
|
||||
"[Handle_Play] Play received from client [{}] server number [{}] sequence [{}]",
|
||||
GetAccountName(),
|
||||
server_id_in,
|
||||
sequence_in
|
||||
);
|
||||
|
||||
m_play_server_id = (unsigned int) play->server_number;
|
||||
m_play_sequence_id = sequence_in;
|
||||
@ -310,21 +296,14 @@ void Client::Handle_Play(const char *data)
|
||||
*/
|
||||
void Client::SendServerListPacket(uint32 seq)
|
||||
{
|
||||
auto outapp = server.server_manager->CreateServerListPacket(this, seq);
|
||||
auto app = server.server_manager->CreateServerListPacket(this, seq);
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(outapp.get());
|
||||
}
|
||||
|
||||
m_connection->QueuePacket(outapp.get());
|
||||
m_connection->QueuePacket(app.get());
|
||||
}
|
||||
|
||||
void Client::SendPlayResponse(EQApplicationPacket *outapp)
|
||||
{
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug("Sending play response for {0}", GetAccountName());
|
||||
// server_log->LogPacket(log_network_trace, (const char*)outapp->pBuffer, outapp->size);
|
||||
}
|
||||
LogInfo("Sending play response for {}", GetClientDescription());
|
||||
m_connection->QueuePacket(outapp);
|
||||
}
|
||||
|
||||
@ -422,10 +401,6 @@ void Client::DoFailedLogin()
|
||||
outapp.WriteData(&base_header, sizeof(base_header));
|
||||
outapp.WriteData(&encrypted_buffer, sizeof(encrypted_buffer));
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(&outapp);
|
||||
}
|
||||
|
||||
m_connection->QueuePacket(&outapp);
|
||||
m_client_status = cs_failed_to_login;
|
||||
}
|
||||
@ -576,10 +551,6 @@ void Client::DoSuccessfulLogin(
|
||||
outapp->WriteData(&base_header, sizeof(base_header));
|
||||
outapp->WriteData(&encrypted_buffer, sizeof(encrypted_buffer));
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(outapp.get());
|
||||
}
|
||||
|
||||
m_connection->QueuePacket(outapp.get());
|
||||
|
||||
m_client_status = cs_logged_in;
|
||||
@ -596,7 +567,7 @@ void Client::SendExpansionPacketData(PlayerLoginReply_Struct& plrs)
|
||||
|
||||
|
||||
if (server.options.IsDisplayExpansions()) {
|
||||
|
||||
|
||||
int32_t expansion = server.options.GetMaxExpansions();
|
||||
int32_t owned_expansion = (expansion << 1) | 1;
|
||||
|
||||
@ -839,3 +810,17 @@ bool Client::ProcessHealthCheck(std::string username)
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string Client::GetClientDescription()
|
||||
{
|
||||
in_addr in{};
|
||||
in.s_addr = GetConnection()->GetRemoteIP();
|
||||
std::string client_ip = inet_ntoa(in);
|
||||
|
||||
return fmt::format(
|
||||
"account_name [{}] account_id ({}) ip_address [{}]",
|
||||
GetAccountName(),
|
||||
GetAccountID(),
|
||||
client_ip
|
||||
);
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ public:
|
||||
* @param size
|
||||
*/
|
||||
void Handle_Login(const char *data, unsigned int size);
|
||||
|
||||
|
||||
/**
|
||||
* Sends the expansion data packet
|
||||
*
|
||||
@ -111,6 +111,12 @@ public:
|
||||
*/
|
||||
std::string GetAccountName() const { return m_account_name; }
|
||||
|
||||
/**
|
||||
* Returns a description for the client for logging
|
||||
* @return std::string
|
||||
*/
|
||||
std::string GetClientDescription();
|
||||
|
||||
/**
|
||||
* Gets the key generated at login for this client
|
||||
*
|
||||
|
||||
@ -45,15 +45,6 @@ void LoadServerConfig()
|
||||
server.config = EQ::JsonConfigFile::Load("login.json");
|
||||
LogInfo("Config System Init");
|
||||
|
||||
|
||||
/**
|
||||
* Logging
|
||||
*/
|
||||
server.options.Trace(server.config.GetVariableBool("logging", "trace", false));
|
||||
server.options.WorldTrace(server.config.GetVariableBool("logging", "world_trace", false));
|
||||
server.options.DumpInPackets(server.config.GetVariableBool("logging", "dump_packets_in", false));
|
||||
server.options.DumpOutPackets(server.config.GetVariableBool("logging", "dump_packets_out", false));
|
||||
|
||||
/**
|
||||
* Worldservers
|
||||
*/
|
||||
@ -63,7 +54,7 @@ void LoadServerConfig()
|
||||
"reject_duplicate_servers",
|
||||
false
|
||||
)
|
||||
);
|
||||
);
|
||||
server.options.SetShowPlayerCount(server.config.GetVariableBool("worldservers", "show_player_count", false));
|
||||
server.options.AllowUnregistered(
|
||||
server.config.GetVariableBool(
|
||||
@ -90,8 +81,18 @@ void LoadServerConfig()
|
||||
/**
|
||||
* Expansion Display Settings
|
||||
*/
|
||||
server.options.DisplayExpansions(server.config.GetVariableBool("client_configuration", "display_expansions", false)); //disable by default
|
||||
server.options.MaxExpansions(server.config.GetVariableInt("client_configuration", "max_expansions_mask", 67108863)); //enable display of all expansions
|
||||
server.options.DisplayExpansions(
|
||||
server.config.GetVariableBool(
|
||||
"client_configuration",
|
||||
"display_expansions",
|
||||
false
|
||||
)); //disable by default
|
||||
server.options.MaxExpansions(
|
||||
server.config.GetVariableInt(
|
||||
"client_configuration",
|
||||
"max_expansions_mask",
|
||||
67108863
|
||||
)); //enable display of all expansions
|
||||
|
||||
/**
|
||||
* Account
|
||||
@ -181,7 +182,7 @@ int main(int argc, char **argv)
|
||||
LoadDatabaseConnection();
|
||||
|
||||
LogSys.LoadLogSettingsDefaults();
|
||||
LogSys.log_settings[Logs::Debug].log_to_console = static_cast<uint8>(Logs::General);
|
||||
LogSys.log_settings[Logs::Debug].log_to_console = static_cast<uint8>(Logs::General);
|
||||
LogSys.log_settings[Logs::Debug].is_category_enabled = 1;
|
||||
|
||||
LoginserverCommandHandler::CommandHandler(argc, argv);
|
||||
@ -258,10 +259,6 @@ int main(int argc, char **argv)
|
||||
web_api_thread.detach();
|
||||
}
|
||||
|
||||
LogInfo("[Config] [Logging] IsTraceOn [{0}]", server.options.IsTraceOn());
|
||||
LogInfo("[Config] [Logging] IsWorldTraceOn [{0}]", server.options.IsWorldTraceOn());
|
||||
LogInfo("[Config] [Logging] IsDumpInPacketsOn [{0}]", server.options.IsDumpInPacketsOn());
|
||||
LogInfo("[Config] [Logging] IsDumpOutPacketsOn [{0}]", server.options.IsDumpOutPacketsOn());
|
||||
LogInfo("[Config] [Account] CanAutoCreateAccounts [{0}]", server.options.CanAutoCreateAccounts());
|
||||
LogInfo("[Config] [Client_Configuration] DisplayExpansions [{0}]", server.options.IsDisplayExpansions());
|
||||
LogInfo("[Config] [Client_Configuration] MaxExpansions [{0}]", server.options.GetMaxExpansions());
|
||||
|
||||
@ -13,9 +13,6 @@ public:
|
||||
*/
|
||||
Options() :
|
||||
allow_unregistered(true),
|
||||
trace(false),
|
||||
dump_in_packets(false),
|
||||
dump_out_packets(false),
|
||||
display_expansions(false),
|
||||
max_expansions_mask(0),
|
||||
encryption_mode(5),
|
||||
@ -42,46 +39,6 @@ public:
|
||||
*/
|
||||
inline bool IsUnregisteredAllowed() const { return allow_unregistered; }
|
||||
|
||||
/**
|
||||
* Sets trace.
|
||||
*/
|
||||
inline void Trace(bool b) { trace = b; }
|
||||
|
||||
/**
|
||||
* Returns the value of trace.
|
||||
*/
|
||||
inline bool IsTraceOn() const { return trace; }
|
||||
|
||||
/**
|
||||
* Sets trace.
|
||||
*/
|
||||
inline void WorldTrace(bool b) { world_trace = b; }
|
||||
|
||||
/**
|
||||
* Returns the value of trace.
|
||||
*/
|
||||
inline bool IsWorldTraceOn() const { return world_trace; }
|
||||
|
||||
/**
|
||||
* Sets dump_in_packets.
|
||||
*/
|
||||
inline void DumpInPackets(bool b) { dump_in_packets = b; }
|
||||
|
||||
/**
|
||||
* Returns the value of dump_in_packets.
|
||||
*/
|
||||
inline bool IsDumpInPacketsOn() const { return dump_in_packets; }
|
||||
|
||||
/**
|
||||
* Sets dump_out_packets.
|
||||
*/
|
||||
inline void DumpOutPackets(bool b) { dump_out_packets = b; }
|
||||
|
||||
/**
|
||||
* Returns the value of dump_out_packets.
|
||||
*/
|
||||
inline bool IsDumpOutPacketsOn() const { return dump_out_packets; }
|
||||
|
||||
/**
|
||||
* Sets encryption_mode.
|
||||
*/
|
||||
@ -148,10 +105,6 @@ public:
|
||||
|
||||
private:
|
||||
bool allow_unregistered;
|
||||
bool trace;
|
||||
bool world_trace;
|
||||
bool dump_in_packets;
|
||||
bool dump_out_packets;
|
||||
bool display_expansions;
|
||||
bool reject_duplicate_servers;
|
||||
bool world_dev_test_servers_list_bottom;
|
||||
|
||||
@ -180,21 +180,23 @@ void ServerManager::SendUserToWorldRequest(
|
||||
EQ::Net::DynamicPacket outapp;
|
||||
outapp.Resize(sizeof(UsertoWorldRequest_Struct));
|
||||
|
||||
auto *user_to_world_request = (UsertoWorldRequest_Struct *) outapp.Data();
|
||||
user_to_world_request->worldid = server_id;
|
||||
user_to_world_request->lsaccountid = client_account_id;
|
||||
strncpy(user_to_world_request->login, &client_loginserver[0], 64);
|
||||
auto *r = (UsertoWorldRequest_Struct *) outapp.Data();
|
||||
r->worldid = server_id;
|
||||
r->lsaccountid = client_account_id;
|
||||
strncpy(r->login, &client_loginserver[0], 64);
|
||||
(*iter)->GetConnection()->Send(ServerOP_UsertoWorldReq, outapp);
|
||||
found = true;
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
LogInfo("{0}", outapp.ToString());
|
||||
}
|
||||
LogNetcode(
|
||||
"[UsertoWorldRequest] [Size: {}]\n{}",
|
||||
outapp.Length(),
|
||||
outapp.ToString()
|
||||
);
|
||||
}
|
||||
++iter;
|
||||
}
|
||||
|
||||
if (!found && server.options.IsTraceOn()) {
|
||||
if (!found) {
|
||||
LogError("Client requested a user to world but supplied an invalid id of {0}", server_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,17 +79,12 @@ void WorldServer::Reset()
|
||||
*/
|
||||
void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packet)
|
||||
{
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"Application packet received from server: [{0}], (size {1})",
|
||||
opcode,
|
||||
packet.Length()
|
||||
);
|
||||
}
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(opcode, packet);
|
||||
}
|
||||
LogNetcode(
|
||||
"[ProcessNewLSInfo] Application packet received from server [{:#04x}] [Size: {}]\n{}",
|
||||
opcode,
|
||||
packet.Length(),
|
||||
packet.ToString()
|
||||
);
|
||||
|
||||
if (packet.Length() < sizeof(ServerNewLSInfo_Struct)) {
|
||||
LogError(
|
||||
@ -129,18 +124,13 @@ void WorldServer::ProcessNewLSInfo(uint16_t opcode, const EQ::Net::Packet &packe
|
||||
*/
|
||||
void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet)
|
||||
{
|
||||
Log(
|
||||
Logs::Detail,
|
||||
Logs::Netcode,
|
||||
"Application packet received from server: 0x%.4X, (size %u)",
|
||||
LogNetcode(
|
||||
"[ProcessLSStatus] Application packet received from server [{:#04x}] [Size: {}]\n{}",
|
||||
opcode,
|
||||
packet.Length()
|
||||
packet.Length(),
|
||||
packet.ToString()
|
||||
);
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(opcode, packet);
|
||||
}
|
||||
|
||||
if (packet.Length() < sizeof(ServerLSStatus_Struct)) {
|
||||
LogError(
|
||||
"Received application packet from server that had opcode ServerOP_LSStatus, but was too small. Discarded to avoid buffer overrun"
|
||||
@ -151,15 +141,13 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet
|
||||
|
||||
auto *ls_status = (ServerLSStatus_Struct *) packet.Data();
|
||||
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]",
|
||||
GetServerLongName(),
|
||||
ls_status->status,
|
||||
ls_status->num_players,
|
||||
ls_status->num_zones
|
||||
);
|
||||
}
|
||||
LogDebug(
|
||||
"World Server Status Update Received | Server [{0}] Status [{1}] Players [{2}] Zones [{3}]",
|
||||
GetServerLongName(),
|
||||
ls_status->status,
|
||||
ls_status->num_players,
|
||||
ls_status->num_zones
|
||||
);
|
||||
|
||||
Handle_LSStatus(ls_status);
|
||||
}
|
||||
@ -170,17 +158,12 @@ void WorldServer::ProcessLSStatus(uint16_t opcode, const EQ::Net::Packet &packet
|
||||
*/
|
||||
void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Net::Packet &packet)
|
||||
{
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"Application packet received from server: [{0}], (size {1})",
|
||||
opcode,
|
||||
packet.Length()
|
||||
);
|
||||
}
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(opcode, packet);
|
||||
}
|
||||
LogNetcode(
|
||||
"[ProcessUserToWorldResponseLegacy] Application packet received from server [{:#04x}] [Size: {}]\n{}",
|
||||
opcode,
|
||||
packet.Length(),
|
||||
packet.ToString()
|
||||
);
|
||||
|
||||
if (packet.Length() < sizeof(UsertoWorldResponseLegacy_Struct)) {
|
||||
LogError(
|
||||
@ -191,19 +174,11 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
|
||||
return;
|
||||
}
|
||||
|
||||
//I don't use world trace for this and here is why:
|
||||
//Because this is a part of the client login procedure it makes tracking client errors
|
||||
//While keeping world server spam with multiple servers connected almost impossible.
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug("User-To-World Response received");
|
||||
}
|
||||
|
||||
auto *r = (UsertoWorldResponseLegacy_Struct *) packet.Data();
|
||||
|
||||
LogDebug("Trying to find client with user id of [{0}]", r->lsaccountid);
|
||||
Client *client = server.client_manager->GetClient(r->lsaccountid, "eqemu");
|
||||
if (client) {
|
||||
|
||||
LogDebug(
|
||||
"Found client with user id of [{0}] and account name of [{1}]",
|
||||
r->lsaccountid,
|
||||
@ -254,21 +229,13 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
|
||||
break;
|
||||
}
|
||||
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"Sending play response: allowed [{0}] sequence [{1}] server number [{2}] message [{3}]",
|
||||
per->base_reply.success,
|
||||
per->base_header.sequence,
|
||||
per->server_number,
|
||||
per->base_reply.error_str_id
|
||||
);
|
||||
|
||||
LogDebug("[Size: [{0}]] {1}", outapp->size, DumpPacketToString(outapp));
|
||||
}
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(outapp);
|
||||
}
|
||||
LogDebug(
|
||||
"Sending play response: allowed [{0}] sequence [{1}] server number [{2}] message [{3}]",
|
||||
per->base_reply.success,
|
||||
per->base_header.sequence,
|
||||
per->server_number,
|
||||
per->base_reply.error_str_id
|
||||
);
|
||||
|
||||
client->SendPlayResponse(outapp);
|
||||
delete outapp;
|
||||
@ -287,17 +254,12 @@ void WorldServer::ProcessUserToWorldResponseLegacy(uint16_t opcode, const EQ::Ne
|
||||
*/
|
||||
void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Packet &packet)
|
||||
{
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"Application packet received from server: 0x%.4X, (size %u)",
|
||||
opcode,
|
||||
packet.Length()
|
||||
);
|
||||
}
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(opcode, packet);
|
||||
}
|
||||
LogNetcode(
|
||||
"[ProcessUserToWorldResponse] Application packet received from server [{:#04x}] [Size: {}]\n{}",
|
||||
opcode,
|
||||
packet.Length(),
|
||||
packet.ToString()
|
||||
);
|
||||
|
||||
if (packet.Length() < sizeof(UsertoWorldResponse_Struct)) {
|
||||
LogError(
|
||||
@ -308,25 +270,18 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac
|
||||
return;
|
||||
}
|
||||
|
||||
//I don't use world trace for this and here is why:
|
||||
//Because this is a part of the client login procedure it makes tracking client errors
|
||||
//While keeping world server spam with multiple servers connected almost impossible.
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug("User-To-World Response received");
|
||||
}
|
||||
|
||||
auto user_to_world_response = (UsertoWorldResponse_Struct *) packet.Data();
|
||||
LogDebug("Trying to find client with user id of [{0}]", user_to_world_response->lsaccountid);
|
||||
|
||||
Client *client = server.client_manager->GetClient(
|
||||
Client *c = server.client_manager->GetClient(
|
||||
user_to_world_response->lsaccountid,
|
||||
user_to_world_response->login
|
||||
);
|
||||
|
||||
if (client) {
|
||||
if (c) {
|
||||
LogDebug("Found client with user id of [{0}] and account name of {1}",
|
||||
user_to_world_response->lsaccountid,
|
||||
client->GetAccountName().c_str()
|
||||
c->GetAccountName().c_str()
|
||||
);
|
||||
|
||||
auto *outapp = new EQApplicationPacket(
|
||||
@ -334,69 +289,62 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac
|
||||
sizeof(PlayEverquestResponse_Struct)
|
||||
);
|
||||
|
||||
auto *per = (PlayEverquestResponse_Struct *) outapp->pBuffer;
|
||||
per->base_header.sequence = client->GetPlaySequence();
|
||||
per->server_number = client->GetPlayServerID();
|
||||
auto *r = (PlayEverquestResponse_Struct *) outapp->pBuffer;
|
||||
r->base_header.sequence = c->GetPlaySequence();
|
||||
r->server_number = c->GetPlayServerID();
|
||||
|
||||
LogDebug(
|
||||
"Found sequence and play of [{0}] [{1}]",
|
||||
client->GetPlaySequence(),
|
||||
client->GetPlayServerID()
|
||||
c->GetPlaySequence(),
|
||||
c->GetPlayServerID()
|
||||
);
|
||||
|
||||
LogDebug("[Size: [{0}]] {1}", outapp->size, DumpPacketToString(outapp));
|
||||
|
||||
if (user_to_world_response->response > 0) {
|
||||
per->base_reply.success = true;
|
||||
r->base_reply.success = true;
|
||||
SendClientAuth(
|
||||
client->GetConnection()->GetRemoteAddr(),
|
||||
client->GetAccountName(),
|
||||
client->GetKey(),
|
||||
client->GetAccountID(),
|
||||
client->GetLoginServerName()
|
||||
c->GetConnection()->GetRemoteAddr(),
|
||||
c->GetAccountName(),
|
||||
c->GetKey(),
|
||||
c->GetAccountID(),
|
||||
c->GetLoginServerName()
|
||||
);
|
||||
}
|
||||
|
||||
switch (user_to_world_response->response) {
|
||||
case UserToWorldStatusSuccess:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_NONE;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_NONE;
|
||||
break;
|
||||
case UserToWorldStatusWorldUnavail:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_SERVER_UNAVAILABLE;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_SERVER_UNAVAILABLE;
|
||||
break;
|
||||
case UserToWorldStatusSuspended:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_ACCOUNT_SUSPENDED;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_ACCOUNT_SUSPENDED;
|
||||
break;
|
||||
case UserToWorldStatusBanned:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_ACCOUNT_BANNED;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_ACCOUNT_BANNED;
|
||||
break;
|
||||
case UserToWorldStatusWorldAtCapacity:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_WORLD_MAX_CAPACITY;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_WORLD_MAX_CAPACITY;
|
||||
break;
|
||||
case UserToWorldStatusAlreadyOnline:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_ACTIVE_CHARACTER;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_ACTIVE_CHARACTER;
|
||||
break;
|
||||
default:
|
||||
per->base_reply.error_str_id = LS::ErrStr::ERROR_UNKNOWN;
|
||||
r->base_reply.error_str_id = LS::ErrStr::ERROR_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (server.options.IsTraceOn()) {
|
||||
LogDebug(
|
||||
"Sending play response with following data, allowed [{0}], sequence {1}, server number {2}, message {3}",
|
||||
per->base_reply.success,
|
||||
per->base_header.sequence,
|
||||
per->server_number,
|
||||
per->base_reply.error_str_id
|
||||
);
|
||||
LogDebug("[Size: [{0}]] {1}", outapp->size, DumpPacketToString(outapp));
|
||||
}
|
||||
LogDebug(
|
||||
"Sending play response with following data, allowed [{0}], sequence {1}, server number {2}, message {3}",
|
||||
r->base_reply.success,
|
||||
r->base_header.sequence,
|
||||
r->server_number,
|
||||
r->base_reply.error_str_id
|
||||
);
|
||||
|
||||
if (server.options.IsDumpOutPacketsOn()) {
|
||||
DumpPacket(outapp);
|
||||
}
|
||||
|
||||
client->SendPlayResponse(outapp);
|
||||
c->SendPlayResponse(outapp);
|
||||
delete outapp;
|
||||
}
|
||||
else {
|
||||
@ -413,17 +361,12 @@ void WorldServer::ProcessUserToWorldResponse(uint16_t opcode, const EQ::Net::Pac
|
||||
*/
|
||||
void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet &packet)
|
||||
{
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug(
|
||||
"Application packet received from server: [{0}], (size {1})",
|
||||
opcode,
|
||||
packet.Length()
|
||||
);
|
||||
}
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(opcode, packet);
|
||||
}
|
||||
LogNetcode(
|
||||
"[ProcessLSAccountUpdate] Application packet received from server [{:#04x}] [Size: {}]\n{}",
|
||||
opcode,
|
||||
packet.Length(),
|
||||
packet.ToString()
|
||||
);
|
||||
|
||||
if (packet.Length() < sizeof(ServerLSAccountUpdate_Struct)) {
|
||||
LogError(
|
||||
@ -434,9 +377,7 @@ void WorldServer::ProcessLSAccountUpdate(uint16_t opcode, const EQ::Net::Packet
|
||||
return;
|
||||
}
|
||||
|
||||
if (server.options.IsWorldTraceOn()) {
|
||||
LogDebug("ServerOP_LSAccountUpdate packet received from [{0}]", m_short_name);
|
||||
}
|
||||
LogDebug("ServerOP_LSAccountUpdate packet received from [{0}]", m_short_name);
|
||||
|
||||
auto *loginserver_update = (ServerLSAccountUpdate_Struct *) packet.Data();
|
||||
if (IsServerTrusted()) {
|
||||
@ -607,34 +548,34 @@ void WorldServer::SendClientAuth(
|
||||
)
|
||||
{
|
||||
EQ::Net::DynamicPacket outapp;
|
||||
ClientAuth_Struct client_auth{};
|
||||
ClientAuth_Struct a{};
|
||||
|
||||
client_auth.loginserver_account_id = account_id;
|
||||
a.loginserver_account_id = account_id;
|
||||
|
||||
strncpy(client_auth.account_name, account.c_str(), 30);
|
||||
strncpy(client_auth.key, key.c_str(), 30);
|
||||
strncpy(a.account_name, account.c_str(), 30);
|
||||
strncpy(a.key, key.c_str(), 30);
|
||||
|
||||
client_auth.lsadmin = 0;
|
||||
client_auth.is_world_admin = 0;
|
||||
client_auth.ip = inet_addr(ip.c_str());
|
||||
strncpy(client_auth.loginserver_name, &loginserver_name[0], 64);
|
||||
a.lsadmin = 0;
|
||||
a.is_world_admin = 0;
|
||||
a.ip = inet_addr(ip.c_str());
|
||||
strncpy(a.loginserver_name, &loginserver_name[0], 64);
|
||||
|
||||
const std::string &client_address(ip);
|
||||
std::string world_address(m_connection->Handle()->RemoteIP());
|
||||
|
||||
if (client_address == world_address) {
|
||||
client_auth.is_client_from_local_network = 1;
|
||||
a.is_client_from_local_network = 1;
|
||||
}
|
||||
else if (IpUtil::IsIpInPrivateRfc1918(client_address)) {
|
||||
LogInfo("Client is authenticating from a local address [{0}]", client_address);
|
||||
client_auth.is_client_from_local_network = 1;
|
||||
a.is_client_from_local_network = 1;
|
||||
}
|
||||
else {
|
||||
client_auth.is_client_from_local_network = 0;
|
||||
a.is_client_from_local_network = 0;
|
||||
}
|
||||
|
||||
struct in_addr ip_addr{};
|
||||
ip_addr.s_addr = client_auth.ip;
|
||||
ip_addr.s_addr = a.ip;
|
||||
|
||||
LogInfo(
|
||||
"Client authentication response: world_address [{0}] client_address [{1}]",
|
||||
@ -645,22 +586,25 @@ void WorldServer::SendClientAuth(
|
||||
LogInfo(
|
||||
"Sending Client Authentication Response ls_account_id [{0}] ls_name [{1}] name [{2}] key [{3}] ls_admin [{4}] "
|
||||
"world_admin [{5}] ip [{6}] local [{7}]",
|
||||
client_auth.loginserver_account_id,
|
||||
client_auth.loginserver_name,
|
||||
client_auth.account_name,
|
||||
client_auth.key,
|
||||
client_auth.lsadmin,
|
||||
client_auth.is_world_admin,
|
||||
a.loginserver_account_id,
|
||||
a.loginserver_name,
|
||||
a.account_name,
|
||||
a.key,
|
||||
a.lsadmin,
|
||||
a.is_world_admin,
|
||||
inet_ntoa(ip_addr),
|
||||
client_auth.is_client_from_local_network
|
||||
a.is_client_from_local_network
|
||||
);
|
||||
|
||||
outapp.PutSerialize(0, client_auth);
|
||||
outapp.PutSerialize(0, a);
|
||||
m_connection->Send(ServerOP_LSClientAuth, outapp);
|
||||
|
||||
if (server.options.IsDumpInPacketsOn()) {
|
||||
DumpPacket(ServerOP_LSClientAuth, outapp);
|
||||
}
|
||||
LogNetcode(
|
||||
"[ServerOP_LSClientAuth] Sending [{:#04x}] [Size: {}]\n{}",
|
||||
ServerOP_LSClientAuth,
|
||||
outapp.Length(),
|
||||
outapp.ToString()
|
||||
);
|
||||
}
|
||||
|
||||
constexpr static int MAX_ACCOUNT_NAME_LENGTH = 30;
|
||||
|
||||
@ -615,6 +615,14 @@ void Clientlist::Process()
|
||||
while (KeyValid && !(*it)->GetForceDisconnect() && (app = (*it)->ClientStream->PopPacket())) {
|
||||
EmuOpcode opcode = app->GetOpcode();
|
||||
|
||||
LogPacketClientServer(
|
||||
"[{}] [{:#06x}] Size [{}] {}",
|
||||
OpcodeManager::EmuToName(app->GetOpcode()),
|
||||
(*it)->ClientStream->GetOpcodeManager()->EmuToEQ(app->GetOpcode()),
|
||||
app->Size(),
|
||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
||||
);
|
||||
|
||||
switch (opcode) {
|
||||
case OP_MailLogin: {
|
||||
char *PacketBuffer = (char *)app->pBuffer + 1;
|
||||
|
||||
53
utils/scripts/generators/log-alias-generator.pl
Executable file
53
utils/scripts/generators/log-alias-generator.pl
Executable file
@ -0,0 +1,53 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
|
||||
my $filename = './common/eqemu_logsys.h';
|
||||
open(my $fh, '<:encoding(UTF-8)', $filename)
|
||||
or die "Could not open file '$filename' $!";
|
||||
|
||||
my $contents = "";
|
||||
while (my $row = <$fh>) {
|
||||
chomp $row;
|
||||
$contents .= $row . "\n";
|
||||
}
|
||||
|
||||
my @enum = split('enum LogCategory \{', $contents);
|
||||
|
||||
if (scalar(@enum) > 0) {
|
||||
# print $enum[1];
|
||||
my @second_split = split('};', $enum[1]);
|
||||
if (scalar(@second_split) > 0) {
|
||||
my $categories = $second_split[0];
|
||||
$categories =~ s/^\s+//;
|
||||
$categories =~ s/\s+$//;
|
||||
$categories =~ s/ //g;
|
||||
$categories =~ s/ //g;
|
||||
$categories =~ s/\n//g;
|
||||
$categories =~ s/None=0,//g;
|
||||
$categories =~ s/,MaxCategoryID//g;
|
||||
$categories =~ s/\/\*//g;
|
||||
$categories =~ s/\*\///g;
|
||||
$categories =~ s/Don'tRemovethis//g;
|
||||
|
||||
my @cats = split(',', $categories);
|
||||
|
||||
foreach my $cat (@cats) {
|
||||
print "#define Log" . $cat . "(message, ...) do {\\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::" . $cat . "))\\
|
||||
OutF(LogSys, Logs::General, Logs::" . $cat . ", __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\\
|
||||
} while (0)
|
||||
|
||||
#define Log" . $cat . "Detail(message, ...) do {\\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::" . $cat . "))\\
|
||||
OutF(LogSys, Logs::Detail, Logs::" . $cat . ", __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\\
|
||||
} while (0)
|
||||
|
||||
";
|
||||
# print "$cat\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
close $fh;
|
||||
@ -1,241 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Author: Akkadius
|
||||
# @file: lua-doc-parser.pl
|
||||
# @description: Script meant to parse the source code to build the LUA API list
|
||||
|
||||
use File::Find;
|
||||
use Data::Dumper;
|
||||
|
||||
sub usage() {
|
||||
print "Usage:\n";
|
||||
print " --client - Prints methods for just client class methods\n";
|
||||
print " --mob - Prints methods for just mob class methods\n";
|
||||
print " --npc - Prints methods for just npc class methods\n";
|
||||
print " --entity - Prints methods for just entity class methods\n";
|
||||
print " --entity_list - Prints methods for just entity_list class methods\n";
|
||||
print " --door - Prints methods for just door class methods\n";
|
||||
print " --object - Prints methods for just object class methods\n";
|
||||
print " --group - Prints methods for just group class methods\n";
|
||||
print " --raid - Prints methods for just raid class methods\n";
|
||||
print " --item - Prints methods for just item class methods\n";
|
||||
print " --iteminst - Prints methods for just iteminst class methods\n";
|
||||
print " --inventory - Prints methods for just inventory class methods\n";
|
||||
print " --corpse - Prints methods for just corpse class methods\n";
|
||||
print " --hate_entry - Prints methods for just hate_entry class methods\n";
|
||||
print " --quest - Prints methods for just quest class methods\n";
|
||||
print " --spell - Prints methods for just spell class methods\n";
|
||||
print " --spawn - Prints methods for just spawn class methods\n";
|
||||
print " --packet - Prints methods for just packet class methods\n";
|
||||
print " --stat_bonuses - Prints methods for just stat_bonuses class methods\n";
|
||||
print " --all - Prints methods for all classes\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if($#ARGV < 0) {
|
||||
usage();
|
||||
}
|
||||
|
||||
#::: Open File
|
||||
my $filename = 'lua-api.md';
|
||||
open(my $fh, '>', $filename) or die "Could not open file '$filename' $!";
|
||||
|
||||
my $export = $ARGV[0];
|
||||
$export=~s/--//g;
|
||||
|
||||
my $export_file_search = $export;
|
||||
|
||||
if ($export eq "quest") {
|
||||
$export_file_search = "lua_general";
|
||||
}
|
||||
|
||||
my @files;
|
||||
my $start_dir = "zone/";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
|
||||
#::: Skip non lua.cpp files
|
||||
if($file!~/lua_/i || $file!~/cpp/i){
|
||||
next;
|
||||
}
|
||||
|
||||
#::: If we are specifying a specific class type, skip everything else
|
||||
if ($export ne "all" && $export ne "") {
|
||||
if ($file!~/$export_file_search\.cpp/i) {
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
@methods = ();
|
||||
$split_key = "";
|
||||
$object_prefix = "";
|
||||
|
||||
#::: Client Export
|
||||
if ($export=~/all|client/i && $file=~/_client/i) {
|
||||
$split_key = "Client::";
|
||||
$object_prefix = "client:";
|
||||
}
|
||||
|
||||
#::: Mob Export
|
||||
if ($export=~/all|mob/i && $file=~/_mob/i) {
|
||||
$split_key = "Mob::";
|
||||
$object_prefix = "mob:";
|
||||
}
|
||||
|
||||
#::: NPC Export
|
||||
if ($export=~/all|npc/i && $file=~/_npc/i) {
|
||||
$split_key = "NPC::";
|
||||
$object_prefix = "npc:";
|
||||
}
|
||||
|
||||
#::: Object Export
|
||||
if ($export=~/all|object/i && $file=~/_object/i) {
|
||||
$split_key = "Object::";
|
||||
$object_prefix = "object:";
|
||||
}
|
||||
|
||||
#::: Door Export
|
||||
if ($export=~/all|door/i && $file=~/_door/i) {
|
||||
$split_key = "Door::";
|
||||
$object_prefix = "door:";
|
||||
}
|
||||
|
||||
#::: Entity Export
|
||||
if ($export=~/all|entity/i && $file=~/_entity/i) {
|
||||
$split_key = "Entity::";
|
||||
$object_prefix = "entity:";
|
||||
}
|
||||
|
||||
#::: Entity List Export
|
||||
if ($export=~/all|entity_list/i && $file=~/_entity_list/i) {
|
||||
$split_key = "EntityList::";
|
||||
$object_prefix = "entity_list:";
|
||||
}
|
||||
|
||||
#::: Group
|
||||
if ($export=~/all|group/i && $file=~/_group/i) {
|
||||
$split_key = "Group::";
|
||||
$object_prefix = "group:";
|
||||
}
|
||||
|
||||
#::: Raid
|
||||
if ($export=~/all|raid/i && $file=~/_raid/i) {
|
||||
$split_key = "Raid::";
|
||||
$object_prefix = "raid:";
|
||||
}
|
||||
|
||||
#::: Corpse
|
||||
if ($export=~/all|corpse/i && $file=~/_corpse/i) {
|
||||
$split_key = "Corpse::";
|
||||
$object_prefix = "corpse:";
|
||||
}
|
||||
|
||||
#::: Hateentry
|
||||
if ($export=~/all|hate_entry/i && $file=~/_hate_entry/i) {
|
||||
$split_key = "HateEntry::";
|
||||
$object_prefix = "hate_entry:";
|
||||
}
|
||||
|
||||
#::: Spell
|
||||
if ($export=~/all|spell/i && $file=~/_spell/i) {
|
||||
$split_key = "Spell::";
|
||||
$object_prefix = "spell:";
|
||||
}
|
||||
|
||||
#::: Spawn
|
||||
if ($export=~/all|spawn/i && $file=~/_spawn/i) {
|
||||
$split_key = "Spawn::";
|
||||
$object_prefix = "spawn:";
|
||||
}
|
||||
|
||||
#::: StatBonuses
|
||||
if ($export=~/all|stat_bonuses/i && $file=~/stat_bonuses/i) {
|
||||
$split_key = "StatBonuses::";
|
||||
$object_prefix = "statbonuses:";
|
||||
}
|
||||
|
||||
#::: Item
|
||||
if ($export=~/all|item/i && $file=~/_item/i) {
|
||||
$split_key = "Item::";
|
||||
$object_prefix = "item:";
|
||||
}
|
||||
|
||||
#::: ItemInst
|
||||
if ($export=~/all|iteminst/i && $file=~/_iteminst/i) {
|
||||
$split_key = "ItemInst::";
|
||||
$object_prefix = "iteminst:";
|
||||
}
|
||||
|
||||
#::: Inventory
|
||||
if ($export=~/all|inventory/i && $file=~/_inventory/i) {
|
||||
$split_key = "Inventory::";
|
||||
$object_prefix = "inventory:";
|
||||
}
|
||||
|
||||
#::: Packet
|
||||
if ($export=~/all|packet/i && $file=~/_packet/i) {
|
||||
$split_key = "Packet::";
|
||||
$object_prefix = "packet:";
|
||||
}
|
||||
|
||||
#::: Quest
|
||||
if ($export=~/all|quest/i && $file=~/lua_general/i) {
|
||||
$split_key = " lua_";
|
||||
$object_prefix = "eq.";
|
||||
}
|
||||
|
||||
#::: Open File
|
||||
print "\nOpening '" . $file . "'\n";
|
||||
|
||||
if ($split_key eq "") {
|
||||
next;
|
||||
}
|
||||
|
||||
open (FILE, $file);
|
||||
while (<FILE>) {
|
||||
chomp;
|
||||
$line = $_;
|
||||
|
||||
@data = split(" ", $line);
|
||||
|
||||
if ((lc(substr($data[1], 0, 4)) eq "lua_") && $line!~/luabind/i && $line!~/return |#ifdef|struct /i) {
|
||||
#::: Get return type
|
||||
$return_type = trim($data[0]);
|
||||
|
||||
@method_split = split($split_key, $line);
|
||||
@method_end = split("{", $method_split[1]);
|
||||
|
||||
$method = $object_prefix . trim($method_end[0]) . "; -- " . $return_type . "\n";
|
||||
|
||||
push @methods, $method;
|
||||
}
|
||||
}
|
||||
|
||||
#::: Header
|
||||
$header = $split_key;
|
||||
$header =~s/:://g;
|
||||
|
||||
print $fh "# " . $header . "\n";
|
||||
print $fh "```lua\n";
|
||||
|
||||
@methods = sort @methods;
|
||||
foreach $method (@methods) {
|
||||
print $fh $method;
|
||||
print $method;
|
||||
}
|
||||
|
||||
print $fh "```\n\n";
|
||||
}
|
||||
|
||||
close $fh;
|
||||
|
||||
#::: Trim Whitespaces
|
||||
sub trim {
|
||||
my $string = $_[0];
|
||||
$string =~ s/^\s+//;
|
||||
$string =~ s/\s+$//;
|
||||
return $string;
|
||||
}
|
||||
@ -1,179 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
# Author: Akkadius
|
||||
# @file: perl-doc-parser.pl
|
||||
# @description: Script meant to parse the source code to build the Perl API list
|
||||
|
||||
use File::Find;
|
||||
use Data::Dumper;
|
||||
|
||||
sub usage() {
|
||||
print "Usage:\n";
|
||||
print " --client - Prints methods for just client class methods\n";
|
||||
print " --mob - Prints methods for just mob class methods\n";
|
||||
print " --npc - Prints methods for just npc class methods\n";
|
||||
print " --entity - Prints methods for just entity class methods\n";
|
||||
print " --door - Prints methods for just door class methods\n";
|
||||
print " --object - Prints methods for just object class methods\n";
|
||||
print " --group - Prints methods for just group class methods\n";
|
||||
print " --raid - Prints methods for just raid class methods\n";
|
||||
print " --questitem - Prints methods for just questitem class methods\n";
|
||||
print " --corpse - Prints methods for just corpse class methods\n";
|
||||
print " --hateentry - Prints methods for just hateentry class methods\n";
|
||||
print " --quest - Prints methods for just quest class methods\n";
|
||||
print " --all - Prints methods for all classes\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if($#ARGV < 0) {
|
||||
usage();
|
||||
}
|
||||
|
||||
my $export = $ARGV[0];
|
||||
$export=~s/--//g;
|
||||
|
||||
my $export_file_search = $export;
|
||||
|
||||
if ($export eq "quest") {
|
||||
$export_file_search = "embparser_api";
|
||||
}
|
||||
|
||||
my @files;
|
||||
my $start_dir = "zone/";
|
||||
find(
|
||||
sub { push @files, $File::Find::name unless -d; },
|
||||
$start_dir
|
||||
);
|
||||
for my $file (@files) {
|
||||
|
||||
#::: Skip non Perl files
|
||||
if($file!~/perl_|embparser_api/i){
|
||||
next;
|
||||
}
|
||||
|
||||
#::: If we are specifying a specific class type, skip everything else
|
||||
if ($export ne "all" && $export ne "") {
|
||||
if ($file!~/$export_file_search/i) {
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
@methods = ();
|
||||
$split_key = "";
|
||||
$object_prefix = "";
|
||||
|
||||
#::: Open File
|
||||
print "\nOpening '" . $file . "'\n";
|
||||
open (FILE, $file);
|
||||
while (<FILE>) {
|
||||
chomp;
|
||||
$line = $_;
|
||||
|
||||
if ($line=~/Perl_croak/i && $line=~/Usa/i && $line=~/::/i && $line!~/::new/i) {
|
||||
|
||||
#::: Client export
|
||||
if ($export=~/all|client/i && $line=~/Client::/i) {
|
||||
$split_key = "Client::";
|
||||
$object_prefix = "\$client->";
|
||||
}
|
||||
|
||||
#::: Mob export
|
||||
if ($export=~/all|mob/i && $line=~/Mob::/i) {
|
||||
$split_key = "Mob::";
|
||||
$object_prefix = "\$mob->";
|
||||
}
|
||||
|
||||
#::: NPC export
|
||||
if ($export=~/all|npc/i && $line=~/NPC::/i) {
|
||||
$split_key = "NPC::";
|
||||
$object_prefix = "\$npc->";
|
||||
}
|
||||
|
||||
#::: Corpse export
|
||||
if ($export=~/all|corpse/i && $line=~/Corpse::/i) {
|
||||
$split_key = "Corpse::";
|
||||
$object_prefix = "\$corpse->";
|
||||
}
|
||||
|
||||
#::: Entity export
|
||||
if ($export=~/all|entity/i && $line=~/EntityList::/i) {
|
||||
$split_key = "EntityList::";
|
||||
$object_prefix = "\$entity_list->";
|
||||
}
|
||||
|
||||
#::: Doors export
|
||||
if ($export=~/all|door/i && $line=~/Doors::/i) {
|
||||
$split_key = "Doors::";
|
||||
$object_prefix = "\$door->";
|
||||
}
|
||||
|
||||
#::: Object export
|
||||
if ($export=~/all|object/i && $line=~/Object::/i) {
|
||||
$split_key = "Object::";
|
||||
$object_prefix = "\$object->";
|
||||
}
|
||||
|
||||
#::: Group export
|
||||
if ($export=~/all|group/i && $line=~/Group::/i) {
|
||||
$split_key = "Group::";
|
||||
$object_prefix = "\$group->";
|
||||
}
|
||||
|
||||
#::: Raid export
|
||||
if ($export=~/all|raid/i && $line=~/Raid::/i) {
|
||||
$split_key = "Raid::";
|
||||
$object_prefix = "\$raid->";
|
||||
}
|
||||
|
||||
#::: Hateentry export
|
||||
if ($export=~/all|hateentry/i && $line=~/HateEntry::/i) {
|
||||
$split_key = "HateEntry::";
|
||||
$object_prefix = "\$hate_entry->";
|
||||
}
|
||||
|
||||
#::: Questitem export
|
||||
if ($export=~/all|questitem/i && $line=~/QuestItem::/i) {
|
||||
$split_key = "QuestItem::";
|
||||
$object_prefix = "\$quest_item->";
|
||||
}
|
||||
|
||||
#::: Quest:: exports
|
||||
if ($export=~/all|quest/i && $line=~/quest::/i) {
|
||||
$split_key = "quest::";
|
||||
$object_prefix = "\quest::";
|
||||
}
|
||||
|
||||
#::: Split on croak usage
|
||||
@data = split($split_key, $line);
|
||||
$usage = trim($data[1]);
|
||||
|
||||
#::: Split out param borders and get method name
|
||||
@params_begin = split('\(', $usage);
|
||||
$method_name = trim($params_begin[0]);
|
||||
|
||||
#::: Get params string built
|
||||
@params_end = split('\)', $params_begin[1]);
|
||||
$params_string = trim($params_end[0]);
|
||||
$params_string =~s/THIS\,//g;
|
||||
$params_string =~s/THIS//g;
|
||||
$params_string = trim($params_string);
|
||||
|
||||
$method = $object_prefix . $method_name . "(" . lc($params_string) . ")\n";
|
||||
|
||||
push @methods, $method;
|
||||
}
|
||||
}
|
||||
|
||||
@methods = sort @methods;
|
||||
foreach $method (@methods) {
|
||||
print $method;
|
||||
}
|
||||
}
|
||||
|
||||
#::: Trim Whitespaces
|
||||
sub trim {
|
||||
my $string = $_[0];
|
||||
$string =~ s/^\s+//;
|
||||
$string =~ s/\s+$//;
|
||||
return $string;
|
||||
}
|
||||
@ -35,6 +35,7 @@
|
||||
#include "../common/emu_versions.h"
|
||||
#include "../common/random.h"
|
||||
#include "../common/shareddb.h"
|
||||
#include "../common/opcodemgr.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "worlddb.h"
|
||||
@ -1009,7 +1010,13 @@ bool Client::HandlePacket(const EQApplicationPacket *app) {
|
||||
|
||||
EmuOpcode opcode = app->GetOpcode();
|
||||
|
||||
LogNetcode("Received EQApplicationPacket [{:#04x}]", opcode);
|
||||
LogPacketClientServer(
|
||||
"[{}] [{:#06x}] Size [{}] {}",
|
||||
OpcodeManager::EmuToName(app->GetOpcode()),
|
||||
eqs->GetOpcodeManager()->EmuToEQ(app->GetOpcode()),
|
||||
app->Size(),
|
||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
||||
);
|
||||
|
||||
if (!eqs->CheckState(ESTABLISHED)) {
|
||||
LogInfo("Client disconnected (net inactive on send)");
|
||||
|
||||
@ -31,6 +31,11 @@ extern WorldConfig Config;
|
||||
|
||||
void WorldBoot::GMSayHookCallBackProcessWorld(uint16 log_category, std::string message)
|
||||
{
|
||||
// we don't want to loop up with chat messages
|
||||
if (message.find("OP_SpecialMesg") != std::string::npos) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cut messages down to 4000 max to prevent client crash
|
||||
if (!message.empty()) {
|
||||
message = message.substr(0, 4000);
|
||||
|
||||
@ -788,7 +788,6 @@ bool Client::SendAllPackets() {
|
||||
if(eqs)
|
||||
eqs->FastQueuePacket((EQApplicationPacket **)&cp->app, cp->ack_req);
|
||||
clientpackets.pop_front();
|
||||
Log(Logs::Moderate, Logs::PacketClientServer, "Transmitting a packet");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -447,17 +447,13 @@ void ClearMappedOpcode(EmuOpcode op)
|
||||
// client methods
|
||||
int Client::HandlePacket(const EQApplicationPacket *app)
|
||||
{
|
||||
if (LogSys.log_settings[Logs::LogCategory::Netcode].is_category_enabled == 1) {
|
||||
char buffer[64];
|
||||
app->build_header_dump(buffer);
|
||||
Log(Logs::Detail, Logs::PacketClientServer, "Dispatch opcode: %s", buffer);
|
||||
}
|
||||
|
||||
if (LogSys.log_settings[Logs::PacketClientServer].is_category_enabled == 1)
|
||||
Log(Logs::General, Logs::PacketClientServer, "[%s - 0x%04x] [Size: %u]", OpcodeManager::EmuToName(app->GetOpcode()), app->GetOpcode(), app->Size());
|
||||
|
||||
if (LogSys.log_settings[Logs::PacketClientServerWithDump].is_category_enabled == 1)
|
||||
Log(Logs::General, Logs::PacketClientServerWithDump, "[%s - 0x%04x] [Size: %u] %s", OpcodeManager::EmuToName(app->GetOpcode()), app->GetOpcode(), app->Size(), DumpPacketToString(app).c_str());
|
||||
LogPacketClientServer(
|
||||
"[{}] [{:#06x}] Size [{}] {}",
|
||||
OpcodeManager::EmuToName(app->GetOpcode()),
|
||||
eqs->GetOpcodeManager()->EmuToEQ(app->GetOpcode()),
|
||||
app->Size(),
|
||||
(LogSys.IsLogEnabled(Logs::Detail, Logs::PacketClientServer) ? DumpPacketToString(app) : "")
|
||||
);
|
||||
|
||||
EmuOpcode opcode = app->GetOpcode();
|
||||
if (opcode == OP_AckPacket) {
|
||||
@ -500,11 +496,6 @@ int Client::HandlePacket(const EQApplicationPacket *app)
|
||||
args.push_back(const_cast<EQApplicationPacket*>(app));
|
||||
parse->EventPlayer(EVENT_UNHANDLED_OPCODE, this, "", 0, &args);
|
||||
|
||||
if (LogSys.log_settings[Logs::PacketClientServerUnhandled].is_category_enabled == 1) {
|
||||
char buffer[64];
|
||||
app->build_header_dump(buffer);
|
||||
Log(Logs::General, Logs::PacketClientServerUnhandled, "%s %s", buffer, DumpPacketToString(app).c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -71,6 +71,11 @@ void command_logs(Client *c, const Seperator *sep)
|
||||
break;
|
||||
}
|
||||
|
||||
bool is_deprecated_category = Strings::Contains(fmt::format("{}", Logs::LogCategoryName[index]), "Deprecated");
|
||||
if (is_deprecated_category) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<std::string> gmsay;
|
||||
for (int i = 0; i <= 3; i++) {
|
||||
if (i == 2) {
|
||||
|
||||
@ -322,6 +322,11 @@ public:
|
||||
*/
|
||||
static void GMSayHookCallBackProcess(uint16 log_category, std::string message)
|
||||
{
|
||||
// we don't want to loop up with chat messages
|
||||
if (message.find("OP_SpecialMesg") != std::string::npos) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cut messages down to 4000 max to prevent client crash
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user