Split playlist data (+fixed issue)
TODO: Test with sensitive connections and unstable network drives.
This commit is contained in:
parent
1e1a415125
commit
ca5d823efd
@ -53,6 +53,23 @@ namespace Components
|
||||
Network::Send(Game::netsrc_t::NS_CLIENT, target, data);
|
||||
}
|
||||
|
||||
void Network::SendRaw(Game::netsrc_t type, Address target, std::string data)
|
||||
{
|
||||
DWORD header = 0xFFFFFFFF;
|
||||
|
||||
std::string rawData;
|
||||
rawData.append(reinterpret_cast<char*>(&header), 4);
|
||||
rawData.append(data.begin(), data.end());
|
||||
rawData.append("\0", 1);
|
||||
|
||||
Game::OOBPrintRaw(type, *target.Get(), rawData.data(), rawData.size());
|
||||
}
|
||||
|
||||
void Network::SendRaw(Address target, std::string data)
|
||||
{
|
||||
Network::SendRaw(Game::netsrc_t::NS_CLIENT, target, data);
|
||||
}
|
||||
|
||||
int Network::PacketInterceptionHandler(const char* packet)
|
||||
{
|
||||
// Check if custom handler exists
|
||||
@ -74,7 +91,13 @@ namespace Components
|
||||
if (Network::PacketHandlers.find(Network::SelectedPacket) != Network::PacketHandlers.end())
|
||||
{
|
||||
size_t offset = Network::SelectedPacket.size() + 4 + 1;
|
||||
Network::PacketHandlers[Network::SelectedPacket](from, std::string(msg->data + offset, msg->cursize - offset));
|
||||
|
||||
std::string data(msg->data + offset, msg->cursize - offset);
|
||||
|
||||
// Remove trailing 0x00 byte
|
||||
if (data.size() && !data[data.size() - 1]) data.pop_back();
|
||||
|
||||
Network::PacketHandlers[Network::SelectedPacket](from, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -35,9 +35,15 @@ namespace Components
|
||||
const char* GetName() { return "Network"; };
|
||||
|
||||
static void Handle(std::string packet, Callback callback);
|
||||
|
||||
// Only non-binary data
|
||||
static void Send(Address target, std::string data);
|
||||
static void Send(Game::netsrc_t type, Address target, std::string data);
|
||||
|
||||
// Allows sending binary data
|
||||
static void SendRaw(Address target, std::string data);
|
||||
static void SendRaw(Game::netsrc_t type, Address target, std::string data);
|
||||
|
||||
private:
|
||||
static std::string SelectedPacket;
|
||||
static std::map<std::string, Callback> PacketHandlers;
|
||||
|
@ -97,6 +97,14 @@ namespace Components
|
||||
if (Party::LobbyMap.size() <= 1) Game::Steam_JoinLobby(id, 0);
|
||||
}
|
||||
|
||||
void Party::PlaylistError(std::string error)
|
||||
{
|
||||
Party::Container.Valid = false;
|
||||
Party::Container.AwaitingPlaylist = false;
|
||||
|
||||
Party::ConnectError(error);
|
||||
}
|
||||
|
||||
DWORD Party::UIDvarIntStub(char* dvar)
|
||||
{
|
||||
if (!_stricmp(dvar, "onlinegame"))
|
||||
@ -313,6 +321,13 @@ namespace Components
|
||||
Party::Container.RequestTime = Game::Com_Milliseconds();
|
||||
Party::Container.AwaitingPlaylist = true;
|
||||
Network::Send(address, "getplaylist\n");
|
||||
|
||||
// This is not a safe method
|
||||
// TODO: Fix actual error!
|
||||
if (Game::CL_IsCgameInitialized())
|
||||
{
|
||||
Command::Execute("disconnect", true);
|
||||
}
|
||||
}
|
||||
else if (matchType == 2) // Match
|
||||
{
|
||||
@ -326,7 +341,6 @@ namespace Components
|
||||
}
|
||||
else
|
||||
{
|
||||
Dvar::Var("xblive_privatematch").Set(1);
|
||||
Game::Menus_CloseAll(Game::uiContext);
|
||||
|
||||
char xnaddr[32];
|
||||
|
@ -14,6 +14,7 @@ namespace Components
|
||||
|
||||
static bool PlaylistAwaiting();
|
||||
static void PlaylistContinue();
|
||||
static void PlaylistError(std::string error);
|
||||
|
||||
private:
|
||||
struct JoinContainer
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Components
|
||||
{
|
||||
std::string Playlist::CurrentPlaylistBuffer;
|
||||
std::string Playlist::ReceivedPlaylistBuffer;
|
||||
|
||||
void Playlist::LoadPlaylist()
|
||||
{
|
||||
@ -33,7 +34,23 @@ namespace Components
|
||||
void Playlist::PlaylistRequest(Network::Address address, std::string data)
|
||||
{
|
||||
Logger::Print("Received playlist request, sending currently stored buffer.\n");
|
||||
Network::Send(address, std::string("playlistresponse\n") + Playlist::CurrentPlaylistBuffer);
|
||||
|
||||
// Split playlist data
|
||||
unsigned int maxBytes = Playlist::CurrentPlaylistBuffer.size();
|
||||
|
||||
for (unsigned int i = 0; i < maxBytes; i += 2000)
|
||||
{
|
||||
unsigned int sendBytes = min(2000, maxBytes - i);
|
||||
unsigned int sentBytes = i + sendBytes;
|
||||
|
||||
std::string data;
|
||||
data.append(reinterpret_cast<char*>(&sentBytes), 4); // Sent bytes
|
||||
data.append(reinterpret_cast<char*>(&maxBytes), 4); // Max bytes
|
||||
|
||||
data.append(Playlist::CurrentPlaylistBuffer.data() + i, sendBytes);
|
||||
|
||||
Network::SendRaw(address, std::string("playlistresponse\n") + data);
|
||||
}
|
||||
}
|
||||
|
||||
void Playlist::PlaylistReponse(Network::Address address, std::string data)
|
||||
@ -42,9 +59,43 @@ namespace Components
|
||||
{
|
||||
if (address == Party::Target())
|
||||
{
|
||||
Logger::Print("Received playlist response, loading and continuing connection.\n");
|
||||
Game::Live_ParsePlaylists(data.data());
|
||||
Party::PlaylistContinue();
|
||||
if (data.size() <= 8)
|
||||
{
|
||||
Party::PlaylistError(Utils::VA("Received playlist response, but it is invalid."));
|
||||
Playlist::ReceivedPlaylistBuffer.clear();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int sentBytes = *(unsigned int*)(data.data() + 0);
|
||||
unsigned int maxBytes = *(unsigned int*)(data.data() + 4);
|
||||
|
||||
// Clear current buffer, if we receive a new packet
|
||||
if (data.size() - 8 == sentBytes) Playlist::ReceivedPlaylistBuffer.clear();
|
||||
|
||||
// Append received data
|
||||
Playlist::ReceivedPlaylistBuffer.append(data.data() + 8, data.size() - 8);
|
||||
|
||||
if (Playlist::ReceivedPlaylistBuffer.size() != sentBytes)
|
||||
{
|
||||
Party::PlaylistError(Utils::VA("Received playlist data, but it seems invalid: %d != %d", sentBytes, Playlist::ReceivedPlaylistBuffer.size()));
|
||||
Playlist::ReceivedPlaylistBuffer.clear();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::Print("Received playlist data: %d/%d (%d%%)\n", sentBytes, maxBytes, ((100 * sentBytes) / maxBytes));
|
||||
}
|
||||
|
||||
if (Playlist::ReceivedPlaylistBuffer.size() == maxBytes)
|
||||
{
|
||||
Logger::Print("Received playlist response, loading and continuing connection.\n");
|
||||
Game::Live_ParsePlaylists(Playlist::ReceivedPlaylistBuffer.data());
|
||||
Party::PlaylistContinue();
|
||||
|
||||
Playlist::ReceivedPlaylistBuffer.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -99,5 +150,6 @@ namespace Components
|
||||
Playlist::~Playlist()
|
||||
{
|
||||
Playlist::CurrentPlaylistBuffer.clear();
|
||||
Playlist::ReceivedPlaylistBuffer.clear();
|
||||
}
|
||||
}
|
||||
|
@ -11,9 +11,10 @@ namespace Components
|
||||
|
||||
static void LoadPlaylist();
|
||||
|
||||
static std::string ReceivedPlaylistBuffer;
|
||||
|
||||
private:
|
||||
static std::string CurrentPlaylistBuffer;
|
||||
|
||||
static DWORD StorePlaylistStub(const char** buffer);
|
||||
|
||||
static void PlaylistRequest(Network::Address address, std::string data);
|
||||
|
@ -70,8 +70,9 @@ namespace Components
|
||||
// splash logo
|
||||
Utils::Hook::Set<char*>(0x475F9E, "data/images/splash.bmp");
|
||||
|
||||
// Numeric ping
|
||||
// Numerical ping (cg_scoreboardPingText 1)
|
||||
Utils::Hook::Set<BYTE>(0x45888E, 1);
|
||||
Utils::Hook::Set<BYTE>(0x45888C, Game::dvar_flag::DVAR_FLAG_CHEAT);
|
||||
|
||||
// increase font sizes for chat on higher resolutions
|
||||
static float float13 = 13.0f;
|
||||
|
@ -74,6 +74,7 @@ namespace Game
|
||||
LocalizeMapString_t LocalizeMapString = (LocalizeMapString_t)0x44BB30;
|
||||
|
||||
sendOOB_t OOBPrint = (sendOOB_t)0x4AEF00;
|
||||
sendOOBRaw_t OOBPrintRawData = (sendOOBRaw_t)0x60FDC0;
|
||||
|
||||
PC_ReadToken_t PC_ReadToken = (PC_ReadToken_t)0x4ACCD0;
|
||||
PC_ReadTokenHandle_t PC_ReadTokenHandle = (PC_ReadTokenHandle_t)0x4D2060;
|
||||
@ -151,6 +152,13 @@ namespace Game
|
||||
OOBPrint(type, *adr, *(adr + 1), *(adr + 2), 0xFFFFFFFF, *(adr + 4), message);
|
||||
}
|
||||
|
||||
void OOBPrintRaw(int type, netadr_t netadr, const char* message, size_t length)
|
||||
{
|
||||
int* adr = (int*)&netadr;
|
||||
|
||||
OOBPrintRawData(type, length, message, *adr, *(adr + 1), *(adr + 2), 0xFFFFFFFF, *(adr + 4));
|
||||
}
|
||||
|
||||
const char* UI_LocalizeMapName(const char* mapName)
|
||||
{
|
||||
for (int i = 0; i < *arenaCount; i++)
|
||||
|
@ -169,6 +169,9 @@ namespace Game
|
||||
typedef void(__cdecl* sendOOB_t)(int, int, int, int, int, int, const char*);
|
||||
extern sendOOB_t OOBPrint;
|
||||
|
||||
typedef void(__cdecl* sendOOBRaw_t)(int, size_t, const char*, int, int, int, int, int);
|
||||
extern sendOOBRaw_t OOBPrintRawData;
|
||||
|
||||
typedef int(__cdecl * PC_ReadToken_t)(source_t*, token_t*);
|
||||
extern PC_ReadToken_t PC_ReadToken;
|
||||
|
||||
@ -244,6 +247,7 @@ 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);
|
||||
void OOBPrintRaw(int type, netadr_t netadr, const char* message, size_t length);
|
||||
const char* UI_LocalizeMapName(const char* mapName);
|
||||
const char* UI_LocalizeGameType(const char* gameType);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user