Merge remote-tracking branch 'refs/remotes/origin/develop' into v2features

This commit is contained in:
RektInator 2017-05-31 01:57:59 +02:00
commit fb6dd4a205
16 changed files with 114 additions and 70 deletions

2
deps/libtomcrypt vendored

@ -1 +1 @@
Subproject commit f1118b464773616c1f73862cc29baf99eeabe849 Subproject commit 1de3f2a1f61833428f27ff606f8e9b6dc91ad803

2
deps/protobuf vendored

@ -1 +1 @@
Subproject commit 1e86ef4e9f0b9c9e8bd8d62a61e141f139366920 Subproject commit e222997c5bb136b4f079d5fdb1c9852bfadb2b3a

View File

@ -307,7 +307,7 @@ namespace Assets
{ {
std::vector<Game::MaterialTextureDef> textureList; std::vector<Game::MaterialTextureDef> textureList;
for (auto texture : textures.array_items()) for (auto& texture : textures.array_items())
{ {
if (!texture.is_array()) continue; if (!texture.is_array()) continue;
if (textureList.size() >= 0xFF) break; if (textureList.size() >= 0xFF) break;

View File

@ -221,7 +221,7 @@ namespace Components
return false; return false;
} }
Utils::IO::CreateDir("usermaps/" + download->mod); if (download->isMap) Utils::IO::CreateDir("usermaps/" + download->mod);
Utils::IO::WriteFile(path, fDownload.buffer); Utils::IO::WriteFile(path, fDownload.buffer);
return true; return true;

View File

@ -442,11 +442,20 @@ namespace Components
return 0; return 0;
} }
int Maps::TriggerReconnectForMap(const char* mapname) void Maps::LoadNewMapCommand(char* buffer, size_t size, const char* /*format*/, const char* mapname, const char* gametype)
{
unsigned int hash = Maps::GetUsermapHash(mapname);
_snprintf_s(buffer, size, size, "loadingnewmap\n%s\n%s\n%d", mapname, gametype, hash);
}
int Maps::TriggerReconnectForMap(Game::msg_t* msg, const char* mapname)
{ {
Theatre::StopRecording(); Theatre::StopRecording();
if(!Maps::CheckMapInstalled(mapname, false, true)) char hashBuf[100] = { 0 };
unsigned int hash = atoi(Game::MSG_ReadStringLine(msg, hashBuf, sizeof hashBuf));
if(!Maps::CheckMapInstalled(mapname, false, true) || hash && hash != Maps::GetUsermapHash(mapname))
{ {
// Reconnecting forces the client to download the new map // Reconnecting forces the client to download the new map
Command::Execute("disconnect", false); Command::Execute("disconnect", false);
@ -468,8 +477,9 @@ namespace Components
pushad pushad
push [esp + 28h] push [esp + 28h]
push ebp
call Maps::TriggerReconnectForMap call Maps::TriggerReconnectForMap
add esp, 4h add esp, 8h
mov[esp + 20h], eax mov[esp + 20h], eax
@ -973,7 +983,7 @@ namespace Components
Utils::Hook(0x51B46A, Maps::LoadRawSun, HOOK_CALL).install()->quick(); Utils::Hook(0x51B46A, Maps::LoadRawSun, HOOK_CALL).install()->quick();
// Disable distortion on custom maps // Disable distortion on custom maps
Utils::Hook(0x50AA47, Maps::SetDistortionStub, HOOK_CALL).install()->quick(); //Utils::Hook(0x50AA47, Maps::SetDistortionStub, HOOK_CALL).install()->quick();
// Disable speculars on custom maps // Disable speculars on custom maps
Utils::Hook(0x525EA6, Maps::SetSpecularStub1, HOOK_CALL).install()->quick(); Utils::Hook(0x525EA6, Maps::SetSpecularStub1, HOOK_CALL).install()->quick();
@ -1000,6 +1010,11 @@ namespace Components
}, 6s); }, 6s);
}); });
if(Dedicated::IsEnabled())
{
Utils::Hook(0x4A7251, Maps::LoadNewMapCommand, HOOK_CALL).install()->quick();
}
// Download the map before a maprotation if necessary // Download the map before a maprotation if necessary
// Conflicts with Theater's SV map rotation check, but this one is safer! // Conflicts with Theater's SV map rotation check, but this one is safer!
Utils::Hook(0x5AA91C, Maps::RotateCheckStub, HOOK_CALL).install()->quick(); Utils::Hook(0x5AA91C, Maps::RotateCheckStub, HOOK_CALL).install()->quick();

View File

@ -112,8 +112,9 @@ namespace Components
static void SpawnServerStub(); static void SpawnServerStub();
static void LoadMapLoadscreenStub(); static void LoadMapLoadscreenStub();
static int TriggerReconnectForMap(const char* mapname); static int TriggerReconnectForMap(Game::msg_t* msg, const char* mapname);
static void RotateCheckStub(); static void RotateCheckStub();
static void LoadNewMapCommand(char* buffer, size_t size, const char* format, const char* mapname, const char* gametype);
static const char* LoadArenaFileStub(const char* name, char* buffer, int size); static const char* LoadArenaFileStub(const char* name, char* buffer, int size);

View File

@ -14,7 +14,7 @@ namespace Components
if (nodes.empty()) return; if (nodes.empty()) return;
auto nodeList = Utils::String::Explode(nodes, '\n'); auto nodeList = Utils::String::Explode(nodes, '\n');
for (auto node : nodeList) for (auto& node : nodeList)
{ {
Utils::String::Replace(node, "\r", ""); Utils::String::Replace(node, "\r", "");
node = Utils::String::Trim(node); node = Utils::String::Trim(node);
@ -71,7 +71,7 @@ namespace Components
//list.set_is_dedi(Dedicated::IsDedicated()); //list.set_is_dedi(Dedicated::IsDedicated());
std::lock_guard<std::recursive_mutex> _(Node::NodeMutex); std::lock_guard<std::recursive_mutex> _(Node::NodeMutex);
for (auto node : Node::Nodes) for (auto& node : Node::Nodes)
{ {
if (node.state == Node::STATE_VALID && node.registered) if (node.state == Node::STATE_VALID && node.registered)
{ {
@ -114,7 +114,7 @@ namespace Components
unsigned int count = 0; unsigned int count = 0;
std::lock_guard<std::recursive_mutex> _(Node::NodeMutex); std::lock_guard<std::recursive_mutex> _(Node::NodeMutex);
for (auto node : Node::Nodes) for (auto& node : Node::Nodes)
{ {
if (node.state == Node::STATE_VALID) if (node.state == Node::STATE_VALID)
{ {
@ -416,7 +416,7 @@ namespace Components
packet.set_signature(Utils::Cryptography::ECC::SignMessage(Node::SignatureKey, challenge)); packet.set_signature(Utils::Cryptography::ECC::SignMessage(Node::SignatureKey, challenge));
std::lock_guard<std::recursive_mutex> _(Node::NodeMutex); std::lock_guard<std::recursive_mutex> _(Node::NodeMutex);
for (auto node : Node::Nodes) for (auto& node : Node::Nodes)
{ {
Network::SendCommand(node.address, "nodeDeregister", packet.SerializeAsString()); Network::SendCommand(node.address, "nodeDeregister", packet.SerializeAsString());
} }
@ -846,7 +846,7 @@ namespace Components
Logger::Print("Nodes: %d (%d)\n", Node::Nodes.size(), Node::GetValidNodeCount()); Logger::Print("Nodes: %d (%d)\n", Node::Nodes.size(), Node::GetValidNodeCount());
std::lock_guard<std::recursive_mutex> _(Node::NodeMutex); std::lock_guard<std::recursive_mutex> _(Node::NodeMutex);
for (auto node : Node::Nodes) for (auto& node : Node::Nodes)
{ {
Logger::Print("%s\t(%s)\n", node.address.getCString(), Node::GetStateName(node.state)); Logger::Print("%s\t(%s)\n", node.address.getCString(), Node::GetStateName(node.state));
} }
@ -872,7 +872,17 @@ namespace Components
{ {
Logger::Print("Resynchronizing nodes...\n"); Logger::Print("Resynchronizing nodes...\n");
Node::LoadNodeRemotePreset(); static bool threadRunning = false;
if (!threadRunning)
{
threadRunning = true;
std::thread([]()
{
Node::LoadNodeRemotePreset();
threadRunning = false;
}).detach();
}
std::lock_guard<std::recursive_mutex> _(Node::NodeMutex); std::lock_guard<std::recursive_mutex> _(Node::NodeMutex);
for (auto& node : Node::Nodes) for (auto& node : Node::Nodes)
@ -894,6 +904,33 @@ namespace Components
Node::LoadNodeRemotePreset(); Node::LoadNodeRemotePreset();
}).detach(); }).detach();
}); });
if (Dedicated::IsEnabled())
{
Network::Handle("getServersRequest", [](Network::Address target, std::string)
{
std::string data;
{
std::lock_guard<std::recursive_mutex> _(Node::NodeMutex);
for (auto& node : Node::Nodes)
{
if (node.state == Node::STATE_VALID && node.isDedi)
{
Game::netIP_t ip = node.address.getIP();
unsigned short port = htons(node.address.getPort());
data.append(reinterpret_cast<char*>(&ip.full), 4);
data.append(reinterpret_cast<char*>(&port), 2);
data.append("\\");
}
}
data.append("EOT");
}
Network::SendCommand(target, "getServersResponse", data);
});
}
} }
Node::~Node() Node::~Node()

View File

@ -184,7 +184,7 @@ namespace Components
ServerList::RefreshContainer.sendCount = 0; ServerList::RefreshContainer.sendCount = 0;
ServerList::RefreshContainer.sentCount = 0; ServerList::RefreshContainer.sentCount = 0;
for (auto server : tempList) for (auto& server : tempList)
{ {
ServerList::InsertRequest(server.addr); ServerList::InsertRequest(server.addr);
} }
@ -255,11 +255,13 @@ namespace Components
if (list) list->clear(); if (list) list->clear();
ServerList::VisibleList.clear(); ServerList::VisibleList.clear();
ServerList::RefreshContainer.mutex.lock();
ServerList::RefreshContainer.servers.clear(); {
ServerList::RefreshContainer.sendCount = 0; std::lock_guard<std::recursive_mutex> _(ServerList::RefreshContainer.mutex);
ServerList::RefreshContainer.sentCount = 0; ServerList::RefreshContainer.servers.clear();
ServerList::RefreshContainer.mutex.unlock(); ServerList::RefreshContainer.sendCount = 0;
ServerList::RefreshContainer.sentCount = 0;
}
if (ServerList::IsOfflineList()) if (ServerList::IsOfflineList())
{ {
@ -417,7 +419,7 @@ namespace Components
auto list = ServerList::GetList(); auto list = ServerList::GetList();
if (list) if (list)
{ {
for (auto server : *list) for (auto& server : *list)
{ {
if (server.addr == container.target) if (server.addr == container.target)
{ {
@ -604,8 +606,7 @@ namespace Components
void ServerList::Frame() void ServerList::Frame()
{ {
// This is bad practice and might even cause undefined behaviour! std::lock_guard<std::recursive_mutex> _(ServerList::RefreshContainer.mutex);
if (!ServerList::RefreshContainer.mutex.try_lock()) return;
if (ServerList::RefreshContainer.awatingList) if (ServerList::RefreshContainer.awatingList)
{ {
@ -644,8 +645,6 @@ namespace Components
} }
ServerList::UpdateVisibleInfo(); ServerList::UpdateVisibleInfo();
ServerList::RefreshContainer.mutex.unlock();
} }
void ServerList::UpdateSource() void ServerList::UpdateSource()
@ -865,9 +864,10 @@ namespace Components
ServerList::FavouriteList.clear(); ServerList::FavouriteList.clear();
ServerList::VisibleList.clear(); ServerList::VisibleList.clear();
ServerList::RefreshContainer.mutex.lock(); {
ServerList::RefreshContainer.awatingList = false; std::lock_guard<std::recursive_mutex> _(ServerList::RefreshContainer.mutex);
ServerList::RefreshContainer.servers.clear(); ServerList::RefreshContainer.awatingList = false;
ServerList::RefreshContainer.mutex.unlock(); ServerList::RefreshContainer.servers.clear();
}
} }
} }

View File

@ -157,6 +157,7 @@ namespace Game
MSG_ReadShort_t MSG_ReadShort = MSG_ReadShort_t(0x40BDD0); MSG_ReadShort_t MSG_ReadShort = MSG_ReadShort_t(0x40BDD0);
MSG_ReadInt64_t MSG_ReadInt64 = MSG_ReadInt64_t(0x4F1850); MSG_ReadInt64_t MSG_ReadInt64 = MSG_ReadInt64_t(0x4F1850);
MSG_ReadString_t MSG_ReadString = MSG_ReadString_t(0x60E2B0); MSG_ReadString_t MSG_ReadString = MSG_ReadString_t(0x60E2B0);
MSG_ReadStringLine_t MSG_ReadStringLine = MSG_ReadStringLine_t(0x4FEF30);
MSG_WriteByte_t MSG_WriteByte = MSG_WriteByte_t(0x48C520); MSG_WriteByte_t MSG_WriteByte = MSG_WriteByte_t(0x48C520);
MSG_WriteData_t MSG_WriteData = MSG_WriteData_t(0x4F4120); MSG_WriteData_t MSG_WriteData = MSG_WriteData_t(0x4F4120);
MSG_WriteLong_t MSG_WriteLong = MSG_WriteLong_t(0x41CA20); MSG_WriteLong_t MSG_WriteLong = MSG_WriteLong_t(0x41CA20);

View File

@ -397,6 +397,9 @@ namespace Game
typedef char* (__cdecl * MSG_ReadString_t)(msg_t* msg); typedef char* (__cdecl * MSG_ReadString_t)(msg_t* msg);
extern MSG_ReadString_t MSG_ReadString; extern MSG_ReadString_t MSG_ReadString;
typedef char* (__cdecl * MSG_ReadStringLine_t)(msg_t *msg, char *string, unsigned int maxChars);
extern MSG_ReadStringLine_t MSG_ReadStringLine;
typedef int(__cdecl * MSG_ReadByte_t)(msg_t* msg); typedef int(__cdecl * MSG_ReadByte_t)(msg_t* msg);
extern MSG_ReadByte_t MSG_ReadByte; extern MSG_ReadByte_t MSG_ReadByte;

View File

@ -3945,19 +3945,22 @@ namespace Game
}; };
#pragma pack(pop) #pragma pack(pop)
// Probably incomplete or wrong!
#pragma pack(push, 4) #pragma pack(push, 4)
struct usercmd_s struct usercmd_s
{ {
int serverTime; int serverTime;
int buttons; int buttons;
char weapon;
char offHandIndex;
int angles[3]; int angles[3];
unsigned __int16 weapon;
unsigned __int16 primaryWeaponForAltMode;
unsigned __int16 offHandIndex;
char forwardmove; char forwardmove;
char rightmove; char rightmove;
float meleeChargeYaw; float meleeChargeYaw;
char meleeChargeDist; char meleeChargeDist;
char selectedLoc[2];
char selectedLocAngle;
char remoteControlAngles[2];
}; };
#pragma pack(pop) #pragma pack(pop)

View File

@ -2,8 +2,6 @@
namespace Main namespace Main
{ {
Utils::Hook EntryPointHook;
void SetEnvironment() void SetEnvironment()
{ {
wchar_t exeName[512]; wchar_t exeName[512];
@ -17,8 +15,6 @@ namespace Main
void Initialize() void Initialize()
{ {
Main::EntryPointHook.uninstall();
Main::SetEnvironment(); Main::SetEnvironment();
Utils::Cryptography::Initialize(); Utils::Cryptography::Initialize();
Components::Loader::Initialize(); Components::Loader::Initialize();
@ -44,6 +40,20 @@ namespace Main
Utils::Cache::Uninitialize(); Utils::Cache::Uninitialize();
google::protobuf::ShutdownProtobufLibrary(); google::protobuf::ShutdownProtobufLibrary();
} }
__declspec(naked) void EntryPoint()
{
__asm
{
pushad
call Main::Initialize
popad
push 6BAC14h // Continue init routine
push 6CA062h // ___security_init_cookie
retn
}
}
} }
BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/) BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)
@ -56,10 +66,7 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l
Steam::Proxy::RunMod(); Steam::Proxy::RunMod();
// Ensure we're working with our desired binary // Ensure we're working with our desired binary
if (Utils::Hook::Get<DWORD>(0x4C0FFF) != 0x6824748B) if (Utils::Hook::Get<DWORD>(0x4C0FFF) != 0x6824748B) return FALSE;
{
return FALSE;
}
#ifndef DISABLE_ANTICHEAT #ifndef DISABLE_ANTICHEAT
[]() []()
@ -73,21 +80,8 @@ BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*l
//VirtualProtect(module, 0x6C73000, PAGE_EXECUTE_READWRITE, &oldProtect); // Unprotect the entire process //VirtualProtect(module, 0x6C73000, PAGE_EXECUTE_READWRITE, &oldProtect); // Unprotect the entire process
VirtualProtect(module + 0x1000, 0x2D6000, PAGE_EXECUTE_READ, &oldProtect); // Protect the .text segment VirtualProtect(module + 0x1000, 0x2D6000, PAGE_EXECUTE_READ, &oldProtect); // Protect the .text segment
Main::EntryPointHook.initialize(0x6BAC0F, [] () // Install entry point hook
{ Utils::Hook(0x6BAC0F, Main::EntryPoint, HOOK_JUMP).install()->quick();
__asm
{
pushad
// This has to be called, otherwise the hook is not uninstalled and we're looping into infinity
call Main::Initialize
popad
push 6BAC0Fh
retn
}
})->install();
} }
else if (ul_reason_for_call == DLL_PROCESS_DETACH) else if (ul_reason_for_call == DLL_PROCESS_DETACH)
{ {

View File

@ -10,16 +10,6 @@ namespace Utils
CSV::~CSV() CSV::~CSV()
{ {
for (auto row : this->dataMap)
{
for (auto entry : row)
{
entry.clear();
}
row.clear();
}
this->dataMap.clear(); this->dataMap.clear();
} }
@ -84,7 +74,7 @@ namespace Utils
{ {
auto rows = Utils::String::Explode(buffer, '\n'); auto rows = Utils::String::Explode(buffer, '\n');
for (auto row : rows) for (auto& row : rows)
{ {
this->parseRow(row, allowComments); this->parseRow(row, allowComments);
} }

View File

@ -34,7 +34,7 @@ namespace Utils
this->refMemory.clear(); this->refMemory.clear();
for (auto data : this->pool) for (auto& data : this->pool)
{ {
Memory::Free(data); Memory::Free(data);
} }

View File

@ -92,7 +92,7 @@ namespace Utils
std::vector<Slot<T>> copiedSlots; std::vector<Slot<T>> copiedSlots;
Utils::Merge(&copiedSlots, this->slots); Utils::Merge(&copiedSlots, this->slots);
for (auto slot : copiedSlots) for (auto& slot : copiedSlots)
{ {
if (slot) if (slot)
{ {

View File

@ -435,7 +435,7 @@ namespace Utils
for (auto file : list) this->deleteFile(file); for (auto file : list) this->deleteFile(file);
this->listDirectories(".", list); this->listDirectories(".", list);
for (auto dir : list) this->deleteDirectory(dir); for (auto& dir : list) this->deleteDirectory(dir);
this->setDirectory(tempDir); this->setDirectory(tempDir);