Basic networking component.

This commit is contained in:
momo5502 2015-12-24 16:55:38 +01:00
parent a981d3b2ff
commit 5f6a06fe5b
9 changed files with 249 additions and 0 deletions

View File

@ -13,6 +13,7 @@ namespace Components
Loader::Register(new Window());
Loader::Register(new Command());
Loader::Register(new Console());
Loader::Register(new Network());
Loader::Register(new RawFiles());
Loader::Register(new Renderer());
Loader::Register(new FastFiles());

View File

@ -27,6 +27,7 @@ namespace Components
#include "Window.hpp"
#include "Command.hpp"
#include "Console.hpp"
#include "Network.hpp"
#include "RawFiles.hpp"
#include "Renderer.hpp"
#include "FastFiles.hpp"

134
iw4/Components/Network.cpp Normal file
View File

@ -0,0 +1,134 @@
#include "..\STDInclude.hpp"
namespace Components
{
std::string Network::SelectedPacket;
std::map<std::string, Network::Callback> Network::PacketHandlers;
Network::Address::Address(std::string addrString)
{
Game::NET_StringToAdr(addrString.data(), &this->address);
}
bool Network::Address::operator==(const Network::Address &obj)
{
return Game::NET_CompareAdr(this->address, obj.address);
}
void Network::Address::SetPort(unsigned short port)
{
this->address.port = port;
};
unsigned short Network::Address::GetPort()
{
return this->address.port;
}
Game::netadr_t* Network::Address::Get()
{
return &this->address;
}
const char* Network::Address::GetString()
{
return Game::NET_AdrToString(this->address);
}
void Network::Handle(std::string packet, Network::Callback callback)
{
Network::PacketHandlers[Utils::StrToLower(packet)] = callback;
}
void Network::Send(Game::netsrc_t type, Address target, std::string data)
{
Game::OOBPrintT(type, *target.Get(), data.data());
}
int Network::PacketInterceptionHandler(const char* packet)
{
// Check if custom handler exists
for (auto i = Network::PacketHandlers.begin(); i != Network::PacketHandlers.end(); i++)
{
if (!_strnicmp(i->first.data(), packet, i->first.size()))
{
Network::SelectedPacket = i->first;
return 0;
}
}
// No interception
return 1;
}
void Network::DeployPacket(Game::netadr_t from, Game::msg_t* msg)
{
if (Network::PacketHandlers.find(Network::SelectedPacket) != Network::PacketHandlers.end())
{
Network::PacketHandlers[Network::SelectedPacket](from, msg);
}
else
{
Logger::Print("Error: Network packet intercepted, but handler is missing!\n");
}
}
void __declspec(naked) Network::DeployPacketStub()
{
__asm
{
push ebp //C54
// esp = C54h?
mov eax, [esp + 0C54h + 14h]
push eax
mov eax, [esp + 0C58h + 10h]
push eax
mov eax, [esp + 0C5Ch + 0Ch]
push eax
mov eax, [esp + 0C60h + 08h]
push eax
mov eax, [esp + 0C64h + 04h]
push eax
call Network::DeployPacket
add esp, 14h
add esp, 4h
mov al, 1
//C50
pop edi //C4C
pop esi //C48
pop ebp //C44
pop ebx //C40
add esp, 0C40h
retn
}
}
Network::Network()
{
// maximum size in NET_OutOfBandPrint
Utils::Hook::Set<DWORD>(0x4AEF08, 0x1FFFC);
Utils::Hook::Set<DWORD>(0x4AEFA3, 0x1FFFC);
// Install interception handler
Utils::Hook(0x5AA709, Network::PacketInterceptionHandler, HOOK_CALL).Install()->Quick();
// Install packet deploy hook
Utils::Hook::Set<int>(0x5AA715, (DWORD)Network::DeployPacketStub - 0x5AA713 - 6);
// Network::Handle("infoResponse", [] (Address address, Game::msg_t* message)
// {
// OutputDebugStringA(Utils::VA("Inforesponse received: %s!", address.GetString()));
// });
//
// Network::Handle("getInfo", [] (Address address, Game::msg_t* message)
// {
// OutputDebugStringA(Utils::VA("getinfo received: %s!", address.GetString()));
// });
//
// Command::Add("zob", [] (Command::Params params)
// {
// Network::Send(Game::NS_CLIENT, Network::Address("localhost:28960"), "getinfo xxx\n");
// });
}
Network::~Network()
{
Network::SelectedPacket.clear();
Network::PacketHandlers.clear();
}
}

View File

@ -0,0 +1,43 @@
namespace Components
{
class Network : public Component
{
public:
class Address
{
public:
Address() {};
Address(std::string addrString);
Address(Game::netadr_t addr) : address(addr) {}
Address(Game::netadr_t* addr) : Address(*addr) {}
Address(const Address& obj) { this->address = obj.address; };
bool operator!=(const Address &obj) { return !(*this == obj); };
bool operator==(const Address &obj);
void SetPort(unsigned short port);
unsigned short GetPort();
Game::netadr_t* Get();
const char* GetString();
private:
Game::netadr_t address;
};
typedef void(*Callback)(Address address, Game::msg_t* message);
Network();
~Network();
const char* GetName() { return "Network"; };
static void Handle(std::string packet, Callback callback);
static void Send(Game::netsrc_t type, Address target, std::string data);
private:
static std::string SelectedPacket;
static std::map<std::string, Callback> PacketHandlers;
static int PacketInterceptionHandler(const char* packet);
static void DeployPacket(Game::netadr_t from, Game::msg_t* msg);
static void DeployPacketStub();
};
}

View File

@ -40,8 +40,14 @@ namespace Game
Menus_CloseAll_t Menus_CloseAll = (Menus_CloseAll_t)0x4BA5B0;
Menus_OpenByName_t Menus_OpenByName = (Menus_OpenByName_t)0x4CCE60;
NET_AdrToString_t NET_AdrToString = (NET_AdrToString_t)0x469880;
NET_CompareAdr_t NET_CompareAdr = (NET_CompareAdr_t)0x4D0AA0;
NET_StringToAdr_t NET_StringToAdr = (NET_StringToAdr_t)0x409010;
LoadModdableRawfile_t LoadModdableRawfile = (LoadModdableRawfile_t)0x61ABC0;
sendOOB_t OOBPrint = (sendOOB_t)0x4AEF00;
PC_ReadToken_t PC_ReadToken = (PC_ReadToken_t)0x4ACCD0;
PC_SourceError_t PC_SourceError = (PC_SourceError_t)0x467A00;
@ -79,4 +85,11 @@ namespace Game
call eax
}
}
void OOBPrintT(int type, netadr_t netadr, const char* message)
{
int* adr = (int*)&netadr;
OOBPrint(type, *adr, *(adr + 1), *(adr + 2), 0xFFFFFFFF, *(adr + 4), message);
}
}

View File

@ -81,9 +81,21 @@ namespace Game
typedef int(__cdecl * Menus_OpenByName_t)(/*UiContext **/int dc, const char *p);
extern Menus_OpenByName_t Menus_OpenByName;
typedef const char* (__cdecl * NET_AdrToString_t)(netadr_t adr);
extern NET_AdrToString_t NET_AdrToString;
typedef bool(__cdecl * NET_CompareAdr_t)(netadr_t, netadr_t);
extern NET_CompareAdr_t NET_CompareAdr;
typedef bool(__cdecl * NET_StringToAdr_t)(const char*, netadr_t*);
extern NET_StringToAdr_t NET_StringToAdr;
typedef void* (__cdecl * LoadModdableRawfile_t)(int a1, const char* filename);
extern LoadModdableRawfile_t LoadModdableRawfile;
typedef void(__cdecl* sendOOB_t)(int, int, int, int, int, int, const char*);
extern sendOOB_t OOBPrint;
typedef int(__cdecl * PC_ReadToken_t)(source_t*, token_t*);
extern PC_ReadToken_t PC_ReadToken;
@ -114,4 +126,5 @@ namespace Game
void* ReallocateAssetPool(XAssetType type, unsigned int newSize);
void Menu_FreeItemMemory(Game::itemDef_t* item);
void OOBPrintT(int type, netadr_t netadr, const char* message);
}

View File

@ -602,6 +602,42 @@ namespace Game
menuDef_t **menus;
};
typedef enum
{
NA_BOT,
NA_BAD, // an address lookup failed
NA_LOOPBACK,
NA_BROADCAST,
NA_IP,
NA_IP6, // custom type
} netadrtype_t;
typedef enum
{
NS_CLIENT,
NS_SERVER
} netsrc_t;
typedef struct
{
netadrtype_t type;
BYTE ip[4];
unsigned short port;
BYTE ipx[10];
} netadr_t;
typedef struct
{
int unknown1;
int unknown2;
char* data;
int unknown3;
int maxsize; // 16
int cursize;
int unknown4;
int readcount; // 28
} msg_t;
// Q3TA precompiler code
//undef if binary numbers of the form 0b... or 0B... are not allowed

View File

@ -63,6 +63,7 @@
<ClInclude Include="Components\Materials.hpp" />
<ClInclude Include="Components\Menus.hpp" />
<ClInclude Include="Components\MusicalTalent.hpp" />
<ClInclude Include="Components\Network.hpp" />
<ClInclude Include="Components\QuickPatch.hpp" />
<ClInclude Include="Components\RawFiles.hpp" />
<ClInclude Include="Components\Renderer.hpp" />
@ -95,6 +96,7 @@
<ClCompile Include="Components\Materials.cpp" />
<ClCompile Include="Components\Menus.cpp" />
<ClCompile Include="Components\MusicalTalent.cpp" />
<ClCompile Include="Components\Network.cpp" />
<ClCompile Include="Components\QuickPatch.cpp" />
<ClCompile Include="Components\RawFiles.cpp" />
<ClCompile Include="Components\Renderer.cpp" />

View File

@ -116,6 +116,9 @@
<ClCompile Include="Components\FileSystem.cpp">
<Filter>Source\Components\Modules</Filter>
</ClCompile>
<ClCompile Include="Components\Network.cpp">
<Filter>Source\Components\Modules</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Steam\Interfaces\SteamUser.hpp">
@ -208,5 +211,8 @@
<ClInclude Include="Components\FileSystem.hpp">
<Filter>Source\Components\Modules</Filter>
</ClInclude>
<ClInclude Include="Components\Network.hpp">
<Filter>Source\Components\Modules</Filter>
</ClInclude>
</ItemGroup>
</Project>