diff --git a/common/eq_stream_intf.h b/common/eq_stream_intf.h index c65ae9348..5ca760628 100644 --- a/common/eq_stream_intf.h +++ b/common/eq_stream_intf.h @@ -6,6 +6,7 @@ #include #include "emu_versions.h" #include "eq_packet.h" +#include "net/daybreak_connection.h" typedef enum { ESTABLISHED, @@ -56,6 +57,8 @@ public: virtual const uint32 GetBytesSentPerSecond() const { return 0; } virtual const uint32 GetBytesRecvPerSecond() const { return 0; } virtual const EQEmu::versions::ClientVersion ClientVersion() const { return EQEmu::versions::ClientVersion::Unknown; } + + virtual std::shared_ptr GetRawConnection() = 0; }; #endif /*EQSTREAMINTF_H_*/ diff --git a/common/eq_stream_proxy.cpp b/common/eq_stream_proxy.cpp index 6a3cc6ced..20f9b6f5e 100644 --- a/common/eq_stream_proxy.cpp +++ b/common/eq_stream_proxy.cpp @@ -110,6 +110,10 @@ void EQStreamProxy::RemoveData() { m_stream->RemoveData(); } +std::shared_ptr EQStreamProxy::GetRawConnection() { + return m_stream->GetRawConnection(); +} + bool EQStreamProxy::CheckState(EQStreamState state) { if(m_stream) return(m_stream->CheckState(state)); diff --git a/common/eq_stream_proxy.h b/common/eq_stream_proxy.h index 5e01c8cf0..1dda126b4 100644 --- a/common/eq_stream_proxy.h +++ b/common/eq_stream_proxy.h @@ -37,6 +37,8 @@ public: virtual const uint32 GetBytesSentPerSecond() const; virtual const uint32 GetBytesRecvPerSecond() const; + virtual std::shared_ptr GetRawConnection(); + protected: std::shared_ptr const m_stream; //we own this stream object. const StructStrategy *const m_structs; //we do not own this object. diff --git a/common/net/eqstream.h b/common/net/eqstream.h index 4a3098651..e25761bd5 100644 --- a/common/net/eqstream.h +++ b/common/net/eqstream.h @@ -84,6 +84,10 @@ namespace EQ m_opcode_manager = opm; } + virtual std::shared_ptr GetRawConnection() { + return m_connection; + } + const std::string& RemoteEndpoint() const { return m_connection->RemoteEndpoint(); } const DaybreakConnectionStats& GetStats() const { return m_connection->GetStats(); } void ResetStats() { m_connection->ResetStats(); } @@ -96,4 +100,4 @@ namespace EQ friend class EQStreamManager; }; } -} \ No newline at end of file +} diff --git a/zone/command.cpp b/zone/command.cpp index 149c970d2..ad0b1c989 100755 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -52,7 +52,7 @@ #include "../common/rulesys.h" #include "../common/serverinfo.h" #include "../common/string_util.h" -#include "../say_link.h" +#include "../common/say_link.h" #include "../common/eqemu_logsys.h" #include "../common/profanity_manager.h" @@ -278,6 +278,7 @@ int command_init(void) command_add("mystats", "- Show details about you or your pet", 50, command_mystats) || command_add("name", "[newname] - Rename your player target", 150, command_name) || command_add("netstats", "- Gets the network stats for a stream.", 200, command_netstats) || + command_add("network", "- Admin commands for the udp network interface.", 250, command_network) || command_add("npccast", "[targetname/entityid] [spellid] - Causes NPC target to cast spellid on targetname/entityid", 80, command_npccast) || command_add("npcedit", "[column] [value] - Mega NPC editing command", 100, command_npcedit) || command_add("npcemote", "[message] - Make your NPC target emote a message.", 150, command_npcemote) || @@ -12160,6 +12161,169 @@ void command_who(Client *c, const Seperator *sep) c->Message(5, message.c_str()); } +void command_network(Client *c, const Seperator *sep) +{ + if (!strcasecmp(sep->arg[1], "getopt")) + { + auto eqsi = c->Connection(); + auto dbc = eqsi->GetRawConnection(); + auto manager = dbc->GetManager(); + auto &opts = manager->GetOptions(); + + if (!strcasecmp(sep->arg[2], "all")) + { + c->Message(0, "max_packet_size: %llu", opts.max_packet_size); + c->Message(0, "max_connection_count: %llu", opts.max_connection_count); + c->Message(0, "keepalive_delay_ms: %llu", opts.keepalive_delay_ms); + c->Message(0, "resend_delay_factor: %.2f", opts.resend_delay_factor); + c->Message(0, "resend_delay_ms: %llu", opts.resend_delay_ms); + c->Message(0, "resend_delay_min: %llu", opts.resend_delay_min); + c->Message(0, "resend_delay_max: %llu", opts.resend_delay_max); + c->Message(0, "connect_delay_ms: %llu", opts.connect_delay_ms); + c->Message(0, "connect_stale_ms: %llu", opts.connect_stale_ms); + c->Message(0, "stale_connection_ms: %llu", opts.stale_connection_ms); + c->Message(0, "crc_length: %llu", opts.crc_length); + c->Message(0, "hold_size: %llu", opts.hold_size); + c->Message(0, "hold_length_ms: %llu", opts.hold_length_ms); + c->Message(0, "simulated_in_packet_loss: %llu", opts.simulated_in_packet_loss); + c->Message(0, "simulated_out_packet_loss: %llu", opts.simulated_out_packet_loss); + c->Message(0, "tic_rate_hertz: %.2f", opts.tic_rate_hertz); + c->Message(0, "resend_timeout: %llu", opts.resend_timeout); + c->Message(0, "connection_close_time: %llu", opts.connection_close_time); + c->Message(0, "encode_passes[0]: %llu", opts.encode_passes[0]); + c->Message(0, "encode_passes[1]: %llu", opts.encode_passes[1]); + c->Message(0, "port: %llu", opts.port); + } + else { + c->Message(0, "Unknown get option: %s", sep->arg[2]); + c->Message(0, "Available options:"); + //Todo the rest of these when im less lazy. + //c->Message(0, "max_packet_size"); + //c->Message(0, "max_connection_count"); + //c->Message(0, "keepalive_delay_ms"); + //c->Message(0, "resend_delay_factor"); + //c->Message(0, "resend_delay_ms"); + //c->Message(0, "resend_delay_min"); + //c->Message(0, "resend_delay_max"); + //c->Message(0, "connect_delay_ms"); + //c->Message(0, "connect_stale_ms"); + //c->Message(0, "stale_connection_ms"); + //c->Message(0, "crc_length"); + //c->Message(0, "hold_size"); + //c->Message(0, "hold_length_ms"); + //c->Message(0, "simulated_in_packet_loss"); + //c->Message(0, "simulated_out_packet_loss"); + //c->Message(0, "tic_rate_hertz"); + //c->Message(0, "resend_timeout"); + //c->Message(0, "connection_close_time"); + //c->Message(0, "encode_passes[0]"); + //c->Message(0, "encode_passes[1]"); + //c->Message(0, "port"); + c->Message(0, "all"); + } + } + else if (!strcasecmp(sep->arg[1], "setopt")) + { + auto eqsi = c->Connection(); + auto dbc = eqsi->GetRawConnection(); + auto manager = dbc->GetManager(); + auto &opts = manager->GetOptions(); + + if (!strcasecmp(sep->arg[3], "")) + { + c->Message(0, "Missing value for set"); + return; + } + + std::string value = sep->arg[3]; + if (!strcasecmp(sep->arg[2], "max_connection_count")) + { + opts.max_connection_count = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "keepalive_delay_ms")) + { + opts.keepalive_delay_ms = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "resend_delay_factor")) + { + opts.resend_delay_factor = std::stod(value); + } + else if (!strcasecmp(sep->arg[2], "resend_delay_ms")) + { + opts.resend_delay_ms = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "resend_delay_min")) + { + opts.resend_delay_min = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "resend_delay_max")) + { + opts.resend_delay_max = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "connect_delay_ms")) + { + opts.connect_delay_ms = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "connect_stale_ms")) + { + opts.connect_stale_ms = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "stale_connection_ms")) + { + opts.stale_connection_ms = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "hold_size")) + { + opts.hold_size = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "hold_length_ms")) + { + opts.hold_length_ms = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "simulated_in_packet_loss")) + { + opts.simulated_in_packet_loss = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "simulated_out_packet_loss")) + { + opts.simulated_out_packet_loss = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "resend_timeout")) + { + opts.resend_timeout = std::stoull(value); + } + else if (!strcasecmp(sep->arg[2], "connection_close_time")) + { + opts.connection_close_time = std::stoull(value); + } + else { + c->Message(0, "Unknown set option: %s", sep->arg[2]); + c->Message(0, "Available options:"); + c->Message(0, "max_connection_count"); + c->Message(0, "keepalive_delay_ms"); + c->Message(0, "resend_delay_factor"); + c->Message(0, "resend_delay_ms"); + c->Message(0, "resend_delay_min"); + c->Message(0, "resend_delay_max"); + c->Message(0, "connect_delay_ms"); + c->Message(0, "connect_stale_ms"); + c->Message(0, "stale_connection_ms"); + c->Message(0, "hold_size"); + c->Message(0, "hold_length_ms"); + c->Message(0, "simulated_in_packet_loss"); + c->Message(0, "simulated_out_packet_loss"); + c->Message(0, "resend_timeout"); + c->Message(0, "connection_close_time"); + } + } + else { + c->Message(0, "Unknown command: %s", sep->arg[1]); + c->Message(0, "Network commands avail:"); + c->Message(0, "getopt optname - Retrieve the current option value set."); + c->Message(0, "setopt optname - Set the current option allowed."); + } +} + // All new code added to command.cpp should be BEFORE this comment line. Do no append code to this file below the BOTS code block. #ifdef BOTS #include "bot_command.h" diff --git a/zone/command.h b/zone/command.h index 9efeddcc7..e11b7bcfb 100644 --- a/zone/command.h +++ b/zone/command.h @@ -179,6 +179,7 @@ void command_mysqltest(Client *c, const Seperator *sep); void command_mystats(Client *c, const Seperator *sep); void command_name(Client *c, const Seperator *sep); void command_netstats(Client *c, const Seperator *sep); +void command_network(Client *c, const Seperator *sep); void command_npccast(Client *c, const Seperator *sep); void command_npcedit(Client *c, const Seperator *sep); void command_npcemote(Client *c, const Seperator *sep);