mirror of
https://github.com/diamante0018/MW3ServerFreezer.git
synced 2025-05-14 08:24:51 +00:00
116 lines
3.0 KiB
C++
116 lines
3.0 KiB
C++
#include <std_include.hpp>
|
|
#include "loader/component_loader.hpp"
|
|
|
|
#include <utils/hook.hpp>
|
|
#include <utils/string.hpp>
|
|
|
|
#include "component/console.hpp"
|
|
|
|
#include "network.hpp"
|
|
|
|
namespace network {
|
|
namespace {
|
|
std::unordered_map<std::string, callback>& get_callbacks() {
|
|
static std::unordered_map<std::string, callback> network_callbacks{};
|
|
return network_callbacks;
|
|
}
|
|
|
|
bool handle_command(game::netadr_s* address, const char* command,
|
|
game::msg_t* msg) {
|
|
const auto cmd_string = utils::string::to_lower(command);
|
|
auto& callbacks = get_callbacks();
|
|
|
|
const auto handler = callbacks.find(cmd_string);
|
|
const auto offset = cmd_string.size() + 5;
|
|
|
|
if (static_cast<unsigned int>(msg->cursize) < offset ||
|
|
handler == callbacks.end()) {
|
|
return false;
|
|
}
|
|
|
|
const std::string data(reinterpret_cast<char*>(msg->data) + offset,
|
|
msg->cursize - offset);
|
|
|
|
handler->second(*address, data);
|
|
return true;
|
|
}
|
|
|
|
int packet_interception_handler(game::netadr_s* from, const char* command,
|
|
game::msg_t* message) {
|
|
if (!handle_command(from, command, message)) {
|
|
return utils::hook::invoke<int>(0x525730, from, command, message);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
} // namespace
|
|
|
|
void send(const game::netadr_s& address, const std::string& command,
|
|
const std::string& data, const char separator) {
|
|
std::string packet = "\xFF\xFF\xFF\xFF";
|
|
packet.append(command);
|
|
packet.push_back(separator);
|
|
packet.append(data);
|
|
|
|
send_data(address, packet);
|
|
}
|
|
|
|
void send_data(const game::netadr_s& address, const std::string& data) {
|
|
auto size = static_cast<int>(data.size());
|
|
|
|
if (address.type == game::NA_LOOPBACK) {
|
|
// TODO: Fix this for loopback
|
|
if (size > 1280) {
|
|
console::info("Packet was too long. Truncated!\n");
|
|
size = 1280;
|
|
}
|
|
|
|
game::NET_SendLoopPacket(game::NS_CLIENT1, size, data.data(), address);
|
|
} else {
|
|
game::Sys_SendPacket(size, data.data(), address);
|
|
}
|
|
}
|
|
|
|
void on_packet(const std::string& command, const callback& callback) {
|
|
get_callbacks()[utils::string::to_lower(command)] = callback;
|
|
}
|
|
|
|
const char* net_adr_to_string(const game::netadr_s& a) {
|
|
if (a.type == game::netadrtype_t::NA_LOOPBACK) {
|
|
return "loopback";
|
|
}
|
|
|
|
if (a.type == game::netadrtype_t::NA_BOT) {
|
|
return "bot";
|
|
}
|
|
|
|
if (a.type == game::netadrtype_t::NA_IP ||
|
|
a.type == game::netadrtype_t::NA_BROADCAST) {
|
|
if (a.port) {
|
|
return utils::string::va("%u.%u.%u.%u:%u", a.ip[0], a.ip[1], a.ip[2],
|
|
a.ip[3], htons(a.port));
|
|
}
|
|
|
|
return utils::string::va("%u.%u.%u.%u", a.ip[0], a.ip[1], a.ip[2], a.ip[3]);
|
|
}
|
|
|
|
return "bad";
|
|
}
|
|
|
|
class network final : public component_interface {
|
|
public:
|
|
void post_unpack() override {
|
|
add_network_commands();
|
|
|
|
utils::hook(0x5B27E1, HOOK_CAST(packet_interception_handler), HOOK_CALL)
|
|
.install() // hook*
|
|
->quick();
|
|
}
|
|
|
|
private:
|
|
static void add_network_commands() {}
|
|
};
|
|
} // namespace network
|
|
|
|
REGISTER_COMPONENT(network::network)
|