Basic serverlist.
This commit is contained in:
parent
2473ce8119
commit
601d4d063e
@ -276,8 +276,6 @@ namespace Components
|
|||||||
|
|
||||||
// some thing overwriting feeder 2's data
|
// some thing overwriting feeder 2's data
|
||||||
Utils::Hook::Set<BYTE>(0x4A06A9, 0xEB);
|
Utils::Hook::Set<BYTE>(0x4A06A9, 0xEB);
|
||||||
|
|
||||||
Feeder::Add(2.0f, [] () { return 10; }, [] (int index, int column) { return Utils::VA("%d : %d", index, column); }, [] (int index){});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Feeder::~Feeder()
|
Feeder::~Feeder()
|
||||||
|
@ -26,6 +26,7 @@ namespace Components
|
|||||||
Loader::Register(new Singleton());
|
Loader::Register(new Singleton());
|
||||||
Loader::Register(new FileSystem());
|
Loader::Register(new FileSystem());
|
||||||
Loader::Register(new QuickPatch());
|
Loader::Register(new QuickPatch());
|
||||||
|
Loader::Register(new ServerList());
|
||||||
Loader::Register(new AssetHandler());
|
Loader::Register(new AssetHandler());
|
||||||
Loader::Register(new Localization());
|
Loader::Register(new Localization());
|
||||||
Loader::Register(new MusicalTalent());
|
Loader::Register(new MusicalTalent());
|
||||||
|
@ -39,6 +39,7 @@ namespace Components
|
|||||||
#include "Singleton.hpp"
|
#include "Singleton.hpp"
|
||||||
#include "FileSystem.hpp"
|
#include "FileSystem.hpp"
|
||||||
#include "QuickPatch.hpp"
|
#include "QuickPatch.hpp"
|
||||||
|
#include "ServerList.hpp"
|
||||||
#include "AssetHandler.hpp"
|
#include "AssetHandler.hpp"
|
||||||
#include "Localization.hpp"
|
#include "Localization.hpp"
|
||||||
#include "MusicalTalent.hpp"
|
#include "MusicalTalent.hpp"
|
||||||
|
@ -21,6 +21,14 @@ namespace Components
|
|||||||
{
|
{
|
||||||
return this->address.port;
|
return this->address.port;
|
||||||
}
|
}
|
||||||
|
void Network::Address::SetIP(DWORD ip)
|
||||||
|
{
|
||||||
|
*(DWORD*)this->address.ip = ip;
|
||||||
|
}
|
||||||
|
DWORD Network::Address::GetIP()
|
||||||
|
{
|
||||||
|
return *(DWORD*)this->address.ip;
|
||||||
|
}
|
||||||
Game::netadr_t* Network::Address::Get()
|
Game::netadr_t* Network::Address::Get()
|
||||||
{
|
{
|
||||||
return &this->address;
|
return &this->address;
|
||||||
@ -40,6 +48,11 @@ namespace Components
|
|||||||
Game::OOBPrintT(type, *target.Get(), data.data());
|
Game::OOBPrintT(type, *target.Get(), data.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Network::Send(Address target, std::string data)
|
||||||
|
{
|
||||||
|
Network::Send(Game::netsrc_t::NS_CLIENT, target, data);
|
||||||
|
}
|
||||||
|
|
||||||
int Network::PacketInterceptionHandler(const char* packet)
|
int Network::PacketInterceptionHandler(const char* packet)
|
||||||
{
|
{
|
||||||
// Check if custom handler exists
|
// Check if custom handler exists
|
||||||
|
@ -16,6 +16,10 @@ namespace Components
|
|||||||
|
|
||||||
void SetPort(unsigned short port);
|
void SetPort(unsigned short port);
|
||||||
unsigned short GetPort();
|
unsigned short GetPort();
|
||||||
|
|
||||||
|
void SetIP(DWORD ip);
|
||||||
|
DWORD GetIP();
|
||||||
|
|
||||||
Game::netadr_t* Get();
|
Game::netadr_t* Get();
|
||||||
const char* GetString();
|
const char* GetString();
|
||||||
|
|
||||||
@ -31,6 +35,7 @@ namespace Components
|
|||||||
const char* GetName() { return "Network"; };
|
const char* GetName() { return "Network"; };
|
||||||
|
|
||||||
static void Handle(std::string packet, Callback callback);
|
static void Handle(std::string packet, Callback callback);
|
||||||
|
static void Send(Address target, std::string data);
|
||||||
static void Send(Game::netsrc_t type, Address target, std::string data);
|
static void Send(Game::netsrc_t type, Address target, std::string data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -24,7 +24,7 @@ namespace Components
|
|||||||
Party::Container.Target = target;
|
Party::Container.Target = target;
|
||||||
Party::Container.Challenge = Utils::VA("%X", Party::Container.JoinTime);
|
Party::Container.Challenge = Utils::VA("%X", Party::Container.JoinTime);
|
||||||
|
|
||||||
Network::Send(Game::NS_CLIENT, Party::Container.Target, Utils::VA("getinfo %s\n", Party::Container.Challenge.data()));
|
Network::Send(Party::Container.Target, Utils::VA("getinfo %s\n", Party::Container.Challenge.data()));
|
||||||
|
|
||||||
Command::Execute("openmenu popup_reconnectingtoparty");
|
Command::Execute("openmenu popup_reconnectingtoparty");
|
||||||
}
|
}
|
||||||
@ -177,11 +177,14 @@ namespace Components
|
|||||||
info.Set("matchtype", "0");
|
info.Set("matchtype", "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
Network::Send(Game::NS_CLIENT, address, Utils::VA("infoResponse\n%s\n", info.Build().data()));
|
Network::Send(address, Utils::VA("infoResponse\n%s\n", info.Build().data()));
|
||||||
});
|
});
|
||||||
|
|
||||||
Network::Handle("infoResponse", [] (Network::Address address, std::string data)
|
Network::Handle("infoResponse", [] (Network::Address address, std::string data)
|
||||||
{
|
{
|
||||||
|
OutputDebugStringA(data.data());
|
||||||
|
Utils::InfoString info(data);
|
||||||
|
|
||||||
// Handle connection
|
// Handle connection
|
||||||
if (Party::Container.Valid)
|
if (Party::Container.Valid)
|
||||||
{
|
{
|
||||||
@ -190,8 +193,6 @@ namespace Components
|
|||||||
// Invalidate handler for future packets
|
// Invalidate handler for future packets
|
||||||
Party::Container.Valid = false;
|
Party::Container.Valid = false;
|
||||||
|
|
||||||
Utils::InfoString info(data);
|
|
||||||
|
|
||||||
int matchType = atoi(info.Get("matchtype").data());
|
int matchType = atoi(info.Get("matchtype").data());
|
||||||
|
|
||||||
if (info.Get("challenge") != Party::Container.Challenge)
|
if (info.Get("challenge") != Party::Container.Challenge)
|
||||||
@ -246,6 +247,8 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ServerList::Insert(address, info);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
195
iw4/Components/ServerList.cpp
Normal file
195
iw4/Components/ServerList.cpp
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
#include "..\STDInclude.hpp"
|
||||||
|
|
||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
int ServerList::CurrentServer = 0;
|
||||||
|
ServerList::Container ServerList::RefreshContainer;
|
||||||
|
std::vector<ServerList::ServerInfo> ServerList::OnlineList;
|
||||||
|
|
||||||
|
int ServerList::GetServerCount()
|
||||||
|
{
|
||||||
|
return ServerList::OnlineList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* ServerList::GetServerText(int index, int column)
|
||||||
|
{
|
||||||
|
if (index >= (int)ServerList::OnlineList.size()) return "";
|
||||||
|
|
||||||
|
ServerList::ServerInfo* Server = &ServerList::OnlineList[index];
|
||||||
|
|
||||||
|
switch (column)
|
||||||
|
{
|
||||||
|
case Column::Password:
|
||||||
|
{
|
||||||
|
return (Server->Password ? "X" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
case Column::Hostname:
|
||||||
|
{
|
||||||
|
return Server->Hostname.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
case Column::Mapname:
|
||||||
|
{
|
||||||
|
return Game::UI_LocalizeMapName(Server->Mapname.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
case Column::Players:
|
||||||
|
{
|
||||||
|
return Utils::VA("%i (%i)", Server->Clients, Server->MaxClients);
|
||||||
|
}
|
||||||
|
|
||||||
|
case Column::Gametype:
|
||||||
|
{
|
||||||
|
if (Server->Mod != "")
|
||||||
|
{
|
||||||
|
return (Server->Mod.data() + 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Game::UI_LocalizeGameType(Server->Gametype.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
case Column::Ping:
|
||||||
|
{
|
||||||
|
return Utils::VA("%i", Server->Ping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerList::SelectServer(int index)
|
||||||
|
{
|
||||||
|
ServerList::CurrentServer = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerList::Refresh()
|
||||||
|
{
|
||||||
|
ServerList::OnlineList.clear();
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.Mutex.lock();
|
||||||
|
ServerList::RefreshContainer.Servers.clear();
|
||||||
|
ServerList::RefreshContainer.Mutex.unlock();
|
||||||
|
|
||||||
|
int masterPort = Dvar::Var("masterPort").Get<int>();
|
||||||
|
const char* masterServerName = Dvar::Var("masterServerName").Get<const char*>();
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.Host = Network::Address(Utils::VA("%s:%u", masterServerName, masterPort));
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.AwaitingList = true;
|
||||||
|
|
||||||
|
Network::Send(ServerList::RefreshContainer.Host, "getservers IW4 145 full empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerList::Insert(Network::Address address, Utils::InfoString info)
|
||||||
|
{
|
||||||
|
// Do not enter any new servers, if we are awaiting a new list from the master
|
||||||
|
if (ServerList::RefreshContainer.AwaitingList) return;
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.Mutex.lock();
|
||||||
|
|
||||||
|
for (auto i = ServerList::RefreshContainer.Servers.begin(); i != ServerList::RefreshContainer.Servers.end(); i++)
|
||||||
|
{
|
||||||
|
// Our desired server
|
||||||
|
if (i->Target == address)
|
||||||
|
{
|
||||||
|
// Challenge did not match
|
||||||
|
if (i->Challenge != info.Get("challenge"))
|
||||||
|
{
|
||||||
|
// Shall we remove the server from the queue?
|
||||||
|
// Better not, it might send a second response with the correct challenge.
|
||||||
|
// This might happen when users refresh twice (or more often) in a short period of time
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Implement deeper check like version and game
|
||||||
|
ServerInfo server;
|
||||||
|
server.Hostname = info.Get("hostname");
|
||||||
|
server.Mapname = info.Get("mapname");
|
||||||
|
server.Gametype = info.Get("gametype");
|
||||||
|
server.Mod = info.Get("fs_game");
|
||||||
|
server.MatchType = atoi(info.Get("matchtype").data());
|
||||||
|
server.Clients = atoi(info.Get("clients").data());
|
||||||
|
server.MaxClients = atoi(info.Get("sv_maxclients").data());
|
||||||
|
server.Password = 0; // No info yet
|
||||||
|
server.Ping = (Game::Com_Milliseconds() - i->SendTime);
|
||||||
|
|
||||||
|
ServerList::OnlineList.push_back(server);
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.Servers.erase(i);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.Mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerList::ServerList()
|
||||||
|
{
|
||||||
|
ServerList::OnlineList.clear();
|
||||||
|
|
||||||
|
// Add server list feeder
|
||||||
|
Feeder::Add(2.0f, ServerList::GetServerCount, ServerList::GetServerText, ServerList::SelectServer);
|
||||||
|
|
||||||
|
Network::Handle("getServersResponse", [] (Network::Address address, std::string data)
|
||||||
|
{
|
||||||
|
if (!ServerList::RefreshContainer.AwaitingList) return; // Only parse if we are awaiting a list
|
||||||
|
if (ServerList::RefreshContainer.Host != address) return; // Only parse from host we sent to
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.AwaitingList = false;
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.Mutex.lock();
|
||||||
|
|
||||||
|
// Is this safe? If server ip/port is encoded as '\', it might fail
|
||||||
|
// TODO: Rather parse six bytes and skip the seventh
|
||||||
|
auto servers = Utils::Explode(data, '\\');
|
||||||
|
|
||||||
|
if (servers.size())
|
||||||
|
{
|
||||||
|
if (servers[servers.size() - 1] == "EOT")
|
||||||
|
{
|
||||||
|
Logger::Print("We got an invalid response from the master. Trying to parse it anyways...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < servers.size() - 1; i++)
|
||||||
|
{
|
||||||
|
const char* server = servers[i].data();
|
||||||
|
|
||||||
|
DWORD ip = *(DWORD*)server;
|
||||||
|
uint16_t port = *(uint16_t*)(server + 4);
|
||||||
|
|
||||||
|
Network::Address serverAddr = address;
|
||||||
|
serverAddr.SetIP(ip);
|
||||||
|
serverAddr.SetPort(port);
|
||||||
|
serverAddr.Get()->type = Game::NA_IP;
|
||||||
|
|
||||||
|
ServerList::Container::ServerContainer container;
|
||||||
|
container.SendTime = Game::Com_Milliseconds();
|
||||||
|
container.Challenge = Utils::VA("%d", container.SendTime);
|
||||||
|
container.Sent = true;
|
||||||
|
container.Target = serverAddr;
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.Servers.push_back(container);
|
||||||
|
|
||||||
|
Network::Send(container.Target, Utils::VA("getinfo %s\n", container.Challenge.data()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerList::RefreshContainer.Mutex.unlock();
|
||||||
|
});
|
||||||
|
|
||||||
|
Command::Add("refreshList", [] (Command::Params params)
|
||||||
|
{
|
||||||
|
ServerList::Refresh();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Temporary overwriting
|
||||||
|
strcpy((char*)0x6D9CBC, "localhost");
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerList::~ServerList()
|
||||||
|
{
|
||||||
|
ServerList::OnlineList.clear();
|
||||||
|
}
|
||||||
|
}
|
64
iw4/Components/ServerList.hpp
Normal file
64
iw4/Components/ServerList.hpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
namespace Components
|
||||||
|
{
|
||||||
|
class ServerList : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct ServerInfo
|
||||||
|
{
|
||||||
|
Network::Address Addr;
|
||||||
|
bool Visible;
|
||||||
|
std::string Hostname;
|
||||||
|
std::string Mapname;
|
||||||
|
std::string Gametype;
|
||||||
|
std::string Mod;
|
||||||
|
int Clients;
|
||||||
|
int MaxClients;
|
||||||
|
bool Password;
|
||||||
|
int Ping;
|
||||||
|
int MatchType;
|
||||||
|
bool Hardcore;
|
||||||
|
};
|
||||||
|
|
||||||
|
ServerList();
|
||||||
|
~ServerList();
|
||||||
|
const char* GetName() { return "ServerList"; };
|
||||||
|
|
||||||
|
static void Refresh();
|
||||||
|
static void Insert(Network::Address address, Utils::InfoString info);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum Column
|
||||||
|
{
|
||||||
|
Password,
|
||||||
|
Hostname,
|
||||||
|
Mapname,
|
||||||
|
Players,
|
||||||
|
Gametype,
|
||||||
|
Ping,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Container
|
||||||
|
{
|
||||||
|
struct ServerContainer
|
||||||
|
{
|
||||||
|
bool Sent;
|
||||||
|
int SendTime;
|
||||||
|
std::string Challenge;
|
||||||
|
Network::Address Target;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool AwaitingList;
|
||||||
|
Network::Address Host;
|
||||||
|
std::vector<ServerContainer> Servers;
|
||||||
|
std::mutex Mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int GetServerCount();
|
||||||
|
static const char* GetServerText(int index, int column);
|
||||||
|
static void SelectServer(int index);
|
||||||
|
|
||||||
|
static int CurrentServer;
|
||||||
|
static Container RefreshContainer;
|
||||||
|
static std::vector<ServerInfo> OnlineList;
|
||||||
|
};
|
||||||
|
}
|
@ -66,6 +66,9 @@ namespace Game
|
|||||||
LoadInitialFF_t LoadInitialFF = (LoadInitialFF_t)0x506AC0;
|
LoadInitialFF_t LoadInitialFF = (LoadInitialFF_t)0x506AC0;
|
||||||
LoadModdableRawfile_t LoadModdableRawfile = (LoadModdableRawfile_t)0x61ABC0;
|
LoadModdableRawfile_t LoadModdableRawfile = (LoadModdableRawfile_t)0x61ABC0;
|
||||||
|
|
||||||
|
LocalizeString_t LocalizeString = (LocalizeString_t)0x4FB010;
|
||||||
|
LocalizeMapString_t LocalizeMapString = (LocalizeMapString_t)0x44BB30;
|
||||||
|
|
||||||
sendOOB_t OOBPrint = (sendOOB_t)0x4AEF00;
|
sendOOB_t OOBPrint = (sendOOB_t)0x4AEF00;
|
||||||
|
|
||||||
PC_ReadToken_t PC_ReadToken = (PC_ReadToken_t)0x4ACCD0;
|
PC_ReadToken_t PC_ReadToken = (PC_ReadToken_t)0x4ACCD0;
|
||||||
@ -101,6 +104,12 @@ namespace Game
|
|||||||
|
|
||||||
UiContext *uiContext = (UiContext *)0x62E2858;
|
UiContext *uiContext = (UiContext *)0x62E2858;
|
||||||
|
|
||||||
|
int* arenaCount = (int*)0x62E6930;
|
||||||
|
mapArena_t* arenas = (mapArena_t*)0x62E6934;
|
||||||
|
|
||||||
|
int* gameTypeCount = (int*)0x62E50A0;
|
||||||
|
gameTypeName_t* gameTypes = (gameTypeName_t*)0x62E50A4;
|
||||||
|
|
||||||
void* ReallocateAssetPool(XAssetType type, unsigned int newSize)
|
void* ReallocateAssetPool(XAssetType type, unsigned int newSize)
|
||||||
{
|
{
|
||||||
int elSize = DB_GetXAssetSizeHandlers[type]();
|
int elSize = DB_GetXAssetSizeHandlers[type]();
|
||||||
@ -126,4 +135,43 @@ namespace Game
|
|||||||
|
|
||||||
OOBPrint(type, *adr, *(adr + 1), *(adr + 2), 0xFFFFFFFF, *(adr + 4), message);
|
OOBPrint(type, *adr, *(adr + 1), *(adr + 2), 0xFFFFFFFF, *(adr + 4), message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* UI_LocalizeMapName(const char* mapName)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < *arenaCount; i++)
|
||||||
|
{
|
||||||
|
if (!_stricmp(arenas[i].mapName, mapName))
|
||||||
|
{
|
||||||
|
char* uiName = &arenas[i].uiName[0];
|
||||||
|
if ((uiName[0] == 'M' && uiName[1] == 'P') || (uiName[0] == 'P' && uiName[1] == 'A')) // MPUI/PATCH
|
||||||
|
{
|
||||||
|
char* name = LocalizeMapString(uiName);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uiName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* UI_LocalizeGameType(const char* gameType)
|
||||||
|
{
|
||||||
|
if (gameType == 0 || *gameType == '\0')
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < *gameTypeCount; i++)
|
||||||
|
{
|
||||||
|
if (!_stricmp(gameTypes[i].gameType, gameType))
|
||||||
|
{
|
||||||
|
char* name = LocalizeMapString(gameTypes[i].uiName);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return gameType;
|
||||||
|
}
|
||||||
}
|
}
|
@ -148,6 +148,12 @@ namespace Game
|
|||||||
typedef void* (__cdecl * LoadModdableRawfile_t)(int a1, const char* filename);
|
typedef void* (__cdecl * LoadModdableRawfile_t)(int a1, const char* filename);
|
||||||
extern LoadModdableRawfile_t LoadModdableRawfile;
|
extern LoadModdableRawfile_t LoadModdableRawfile;
|
||||||
|
|
||||||
|
typedef char* (__cdecl * LocalizeString_t)(char*, char*);
|
||||||
|
extern LocalizeString_t LocalizeString;
|
||||||
|
|
||||||
|
typedef char* (__cdecl * LocalizeMapString_t)(char*);
|
||||||
|
extern LocalizeMapString_t LocalizeMapString;
|
||||||
|
|
||||||
typedef void(__cdecl* sendOOB_t)(int, int, int, int, int, int, const char*);
|
typedef void(__cdecl* sendOOB_t)(int, int, int, int, int, int, const char*);
|
||||||
extern sendOOB_t OOBPrint;
|
extern sendOOB_t OOBPrint;
|
||||||
|
|
||||||
@ -199,7 +205,15 @@ namespace Game
|
|||||||
|
|
||||||
extern UiContext *uiContext;
|
extern UiContext *uiContext;
|
||||||
|
|
||||||
|
extern int* arenaCount;
|
||||||
|
extern mapArena_t* arenas;
|
||||||
|
|
||||||
|
extern int* gameTypeCount;
|
||||||
|
extern gameTypeName_t* gameTypes;
|
||||||
|
|
||||||
void* ReallocateAssetPool(XAssetType type, unsigned int newSize);
|
void* ReallocateAssetPool(XAssetType type, unsigned int newSize);
|
||||||
void Menu_FreeItemMemory(Game::itemDef_t* item);
|
void Menu_FreeItemMemory(Game::itemDef_t* item);
|
||||||
void OOBPrintT(int type, netadr_t netadr, const char* message);
|
void OOBPrintT(int type, netadr_t netadr, const char* message);
|
||||||
|
const char* UI_LocalizeMapName(const char* mapName);
|
||||||
|
const char* UI_LocalizeGameType(const char* gameType);
|
||||||
}
|
}
|
||||||
|
@ -922,4 +922,17 @@ namespace Game
|
|||||||
XNADDR hostAddress;
|
XNADDR hostAddress;
|
||||||
XNKEY keyExchangeKey;
|
XNKEY keyExchangeKey;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mapArena_t
|
||||||
|
{
|
||||||
|
char uiName[32];
|
||||||
|
char mapName[16];
|
||||||
|
char pad[2768];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gameTypeName_t
|
||||||
|
{
|
||||||
|
char gameType[12];
|
||||||
|
char uiName[32];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,6 @@ namespace Steam
|
|||||||
|
|
||||||
void Callbacks::RegisterCallResult(uint64_t call, Callbacks::Base* result)
|
void Callbacks::RegisterCallResult(uint64_t call, Callbacks::Base* result)
|
||||||
{
|
{
|
||||||
OutputDebugStringA(::Utils::VA("Registering result: %d", result->GetICallback()));
|
|
||||||
|
|
||||||
Callbacks::ResultHandlers[call] = result;
|
Callbacks::ResultHandlers[call] = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +37,15 @@ namespace Utils
|
|||||||
|
|
||||||
for (std::string token; std::getline(iss, token, delim);)
|
for (std::string token; std::getline(iss, token, delim);)
|
||||||
{
|
{
|
||||||
result.push_back(std::move(token));
|
std::string _entry = std::move(token);
|
||||||
|
|
||||||
|
// Remove trailing 0x0 bytes
|
||||||
|
while (_entry.size() && !_entry[_entry.size() - 1])
|
||||||
|
{
|
||||||
|
_entry = _entry.substr(0, _entry.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push_back(_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -114,6 +122,11 @@ namespace Utils
|
|||||||
|
|
||||||
void InfoString::Parse(std::string buffer)
|
void InfoString::Parse(std::string buffer)
|
||||||
{
|
{
|
||||||
|
if (buffer[0] == '\\')
|
||||||
|
{
|
||||||
|
buffer = buffer.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> KeyValues = Utils::Explode(buffer, '\\');
|
std::vector<std::string> KeyValues = Utils::Explode(buffer, '\\');
|
||||||
|
|
||||||
for (unsigned int i = 0; i < (KeyValues.size() - 1); i+=2)
|
for (unsigned int i = 0; i < (KeyValues.size() - 1); i+=2)
|
||||||
|
@ -12,6 +12,7 @@ namespace Utils
|
|||||||
public:
|
public:
|
||||||
InfoString() {};
|
InfoString() {};
|
||||||
InfoString(std::string buffer) :InfoString() { this->Parse(buffer); };
|
InfoString(std::string buffer) :InfoString() { this->Parse(buffer); };
|
||||||
|
InfoString(const InfoString &obj) { this->KeyValuePairs = obj.KeyValuePairs; };
|
||||||
|
|
||||||
void Set(std::string key, std::string value);
|
void Set(std::string key, std::string value);
|
||||||
std::string Get(std::string key);
|
std::string Get(std::string key);
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Normal|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Normal|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<TargetName>iw4m</TargetName>
|
<TargetName>iw4x</TargetName>
|
||||||
<OutDir>$(SolutionDir)$(Configuration)\Bin\</OutDir>
|
<OutDir>$(SolutionDir)$(Configuration)\Bin\</OutDir>
|
||||||
<IntDir>$(SolutionDir)$(Configuration)\Obj\</IntDir>
|
<IntDir>$(SolutionDir)$(Configuration)\Obj\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -75,6 +75,7 @@
|
|||||||
<ClInclude Include="Components\QuickPatch.hpp" />
|
<ClInclude Include="Components\QuickPatch.hpp" />
|
||||||
<ClInclude Include="Components\RawFiles.hpp" />
|
<ClInclude Include="Components\RawFiles.hpp" />
|
||||||
<ClInclude Include="Components\Renderer.hpp" />
|
<ClInclude Include="Components\Renderer.hpp" />
|
||||||
|
<ClInclude Include="Components\ServerList.hpp" />
|
||||||
<ClInclude Include="Components\Singleton.hpp" />
|
<ClInclude Include="Components\Singleton.hpp" />
|
||||||
<ClInclude Include="Components\Window.hpp" />
|
<ClInclude Include="Components\Window.hpp" />
|
||||||
<ClInclude Include="Game\Functions.hpp" />
|
<ClInclude Include="Game\Functions.hpp" />
|
||||||
@ -114,6 +115,7 @@
|
|||||||
<ClCompile Include="Components\QuickPatch.cpp" />
|
<ClCompile Include="Components\QuickPatch.cpp" />
|
||||||
<ClCompile Include="Components\RawFiles.cpp" />
|
<ClCompile Include="Components\RawFiles.cpp" />
|
||||||
<ClCompile Include="Components\Renderer.cpp" />
|
<ClCompile Include="Components\Renderer.cpp" />
|
||||||
|
<ClCompile Include="Components\ServerList.cpp" />
|
||||||
<ClCompile Include="Components\Singleton.cpp" />
|
<ClCompile Include="Components\Singleton.cpp" />
|
||||||
<ClCompile Include="Components\Window.cpp" />
|
<ClCompile Include="Components\Window.cpp" />
|
||||||
<ClCompile Include="Game\Functions.cpp" />
|
<ClCompile Include="Game\Functions.cpp" />
|
||||||
|
@ -137,6 +137,9 @@
|
|||||||
<ClCompile Include="Components\Feeder.cpp">
|
<ClCompile Include="Components\Feeder.cpp">
|
||||||
<Filter>Source\Components\Modules</Filter>
|
<Filter>Source\Components\Modules</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Components\ServerList.cpp">
|
||||||
|
<Filter>Source\Components\Modules</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Steam\Interfaces\SteamUser.hpp">
|
<ClInclude Include="Steam\Interfaces\SteamUser.hpp">
|
||||||
@ -250,5 +253,8 @@
|
|||||||
<ClInclude Include="Components\Feeder.hpp">
|
<ClInclude Include="Components\Feeder.hpp">
|
||||||
<Filter>Source\Components\Modules</Filter>
|
<Filter>Source\Components\Modules</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Components\ServerList.hpp">
|
||||||
|
<Filter>Source\Components\Modules</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
x
Reference in New Issue
Block a user