[Console]: Allow the client console to be opened (#695)

This commit is contained in:
Edo 2023-01-03 12:16:44 +00:00 committed by GitHub
parent 406499d919
commit 7a438e3409
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 163 additions and 107 deletions

View File

@ -1,4 +1,5 @@
#include <STDInclude.hpp>
#include <Utils/InfoString.hpp>
#include "Modules/Bans.hpp"
#include "Modules/Bots.hpp"
@ -17,12 +18,14 @@
#include "Modules/Discovery.hpp"
#include "Modules/Download.hpp"
#include "Modules/Elevators.hpp"
#include "Modules/FastFiles.hpp"
#include "Modules/Gamepad.hpp"
#include "Modules/Lean.hpp"
#include "Modules/MapDump.hpp"
#include "Modules/MapRotation.hpp"
#include "Modules/NetworkDebug.hpp"
#include "Modules/News.hpp"
#include "Modules/Party.hpp"
#include "Modules/PlayerMovement.hpp"
#include "Modules/PlayerName.hpp"
#include "Modules/Playlist.hpp"

View File

@ -77,7 +77,6 @@ namespace Components
#include "Modules/AssetHandler.hpp"
#include "Modules/Dedicated.hpp"
#include "Modules/Events.hpp"
#include "Modules/FastFiles.hpp"
#include "Modules/FileSystem.hpp"
#include "Modules/Friends.hpp"
#include "Modules/IPCPipe.hpp"
@ -88,7 +87,6 @@ namespace Components
#include "Modules/ModList.hpp"
#include "Modules/ModelSurfs.hpp"
#include "Modules/Node.hpp"
#include "Modules/Party.hpp"
#include "Modules/Renderer.hpp"
#include "Modules/Scheduler.hpp"
#include "Modules/TextRenderer.hpp"

View File

@ -1,4 +1,5 @@
#include <STDInclude.hpp>
#include "FastFiles.hpp"
#include "Weapon.hpp"
#include "AssetInterfaces/IFont_s.hpp"

View File

@ -4,6 +4,8 @@
#define STB_TRUETYPE_IMPLEMENTATION
#include <stb_truetype.h>
#include <json.hpp>
namespace Assets
{
namespace

View File

@ -1,6 +1,8 @@
#include <STDInclude.hpp>
#include "IGameWorldMp.hpp"
#include <json.hpp>
#define IW4X_GAMEWORLD_VERSION 1
namespace Assets

View File

@ -1,6 +1,8 @@
#include <STDInclude.hpp>
#include "ILocalizeEntry.hpp"
#include <json.hpp>
namespace Assets
{
void ILocalizeEntry::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder)

View File

@ -1,6 +1,8 @@
#include <STDInclude.hpp>
#include "IMaterial.hpp"
#include <Utils/Json.hpp>
#define IW4X_MAT_BIN_VERSION "1"
#define IW4X_MAT_JSON_VERSION 1

View File

@ -1,6 +1,8 @@
#include <STDInclude.hpp>
#include "IMaterialTechniqueSet.hpp"
#include <Utils/Json.hpp>
#define IW4X_TECHSET_VERSION 1
namespace Assets

View File

@ -1,6 +1,8 @@
#include <STDInclude.hpp>
#include "IRawFile.hpp"
#include <Utils/Compression.hpp>
namespace Assets
{
void IRawFile::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder)

View File

@ -1,6 +1,8 @@
#include <STDInclude.hpp>
#include "Isnd_alias_list_t.hpp"
#include <Utils/Json.hpp>
namespace Assets
{
void Isnd_alias_list_t::load(Game::XAssetHeader* header, const std::string& name, Components::ZoneBuilder::Zone* builder)

View File

@ -1,4 +1,8 @@
#include <STDInclude.hpp>
#include <Utils/InfoString.hpp>
#include <proto/auth.pb.h>
#include "Bans.hpp"
namespace Components

View File

@ -1,6 +1,8 @@
#include <STDInclude.hpp>
#include "Bans.hpp"
#include <json.hpp>
namespace Components
{
// Have only one instance of IW4x read/write the file

View File

@ -871,6 +871,9 @@ namespace Components
Utils::Hook(0x4F690C, Con_ToggleConsole, HOOK_CALL).install()->quick();
Utils::Hook(0x4F65A5, Con_ToggleConsole, HOOK_JUMP).install()->quick();
// Allow the client console to always be opened (sv_allowClientConsole)
Utils::Hook::Nop(0x4F68EC, 2);
// Patch safearea for ingame-console
Utils::Hook(0x5A50EF, DrawSolidConsoleStub, HOOK_CALL).install()->quick();
@ -944,7 +947,7 @@ namespace Components
if (type != FILE_TYPE_CHAR)
{
MessageBoxA(nullptr, "Console not supported, please use '-stdout' or '-console' flag!", "ERRROR", MB_ICONERROR);
TerminateProcess(GetCurrentProcess(), 1);
TerminateProcess(GetCurrentProcess(), EXIT_FAILURE);
}
Utils::Hook::Nop(0x60BB58, 11);

View File

@ -1,4 +1,6 @@
#include <STDInclude.hpp>
#include <Utils/InfoString.hpp>
#include "CardTitles.hpp"
#include "ClanTags.hpp"
#include "ServerCommands.hpp"

View File

@ -1,4 +1,6 @@
#include <STDInclude.hpp>
#include <Utils/InfoString.hpp>
#include "Discovery.hpp"
#include "ServerList.hpp"

View File

@ -1,5 +1,8 @@
#include <STDInclude.hpp>
#include <Utils/InfoString.hpp>
#include "Download.hpp"
#include "Party.hpp"
#include "ServerInfo.hpp"
#include <mongoose.h>

View File

@ -1,5 +1,9 @@
#include <STDInclude.hpp>
#include <zlib.h>
#include "FastFiles.hpp"
namespace Components
{
FastFiles::Key FastFiles::CurrentKey;
@ -390,7 +394,7 @@ namespace Components
return Utils::Hook::Call<int(unsigned char*, int, unsigned char*)>(0x5BA240)(buffer, length, ivValue);
}
int FastFiles::InflateInitDecrypt(z_streamp strm, const char *version, int stream_size)
static int InflateInitDecrypt(z_streamp strm, const char *version, int stream_size)
{
if (Zones::Version() >= 319)
{
@ -398,7 +402,6 @@ namespace Components
}
return Utils::Hook::Call<int(z_streamp, const char*, int)>(0x4D8090)(strm, version, stream_size);
//return inflateInit_(strm, version, stream_size);
}
void FastFiles::AuthLoadInflateDecryptBaseFunc(unsigned char* buffer)
@ -547,7 +550,7 @@ namespace Components
Utils::Hook(0x4D02F0, FastFiles::AuthLoadInitCrypto, HOOK_CALL).install()->quick();
// Initial stage decryption
Utils::Hook(0x4D0306, FastFiles::InflateInitDecrypt, HOOK_CALL).install()->quick();
Utils::Hook(0x4D0306, InflateInitDecrypt, HOOK_CALL).install()->quick();
// Hash bit decryption
Utils::Hook(0x5B9958, FastFiles::AuthLoadInflateCompare, HOOK_CALL).install()->quick();

View File

@ -18,6 +18,8 @@ namespace Components
static unsigned char ZoneKey[1191];
static symmetric_CTR CurrentCTR;
private:
union Key
{
@ -39,7 +41,6 @@ namespace Components
static char LastByteRead;
static Key CurrentKey;
static symmetric_CTR CurrentCTR;
static std::vector<std::string> ZonePaths;
static const char* GetZoneLocation(const char* file);
static void LoadInitialZones(Game::XZoneInfo *zoneInfo, unsigned int zoneCount, int sync);
@ -55,7 +56,6 @@ namespace Components
static int AuthLoadInflateCompare(unsigned char* buffer, int length, unsigned char* ivValue);
static void AuthLoadInflateDecryptBase();
static void AuthLoadInflateDecryptBaseFunc(unsigned char* buffer);
static int InflateInitDecrypt(z_streamp strm, const char *version, int stream_size);
static void LoadZonesStub(Game::XZoneInfo *zoneInfo, unsigned int zoneCount);

View File

@ -1,4 +1,11 @@
#include <STDInclude.hpp>
#pragma warning(push)
#pragma warning(disable: 4100)
#include <proto/friends.pb.h>
#pragma warning(pop)
#include "Party.hpp"
#include "UIFeeder.hpp"
namespace Components

View File

@ -1,4 +1,7 @@
#include <STDInclude.hpp>
#include <json.hpp>
#include "ScriptStorage.hpp"
#include "Script.hpp"

View File

@ -1,4 +1,5 @@
#include <STDInclude.hpp>
#include <proto/ipc.pb.h>
namespace Components
{

View File

@ -72,33 +72,6 @@ namespace Components
});
}
nlohmann::json MapRotation::RotationData::to_json() const
{
std::vector<std::string> mapVector;
std::vector<std::string> gametypeVector;
for (const auto& [key, val] : this->rotationEntries_)
{
if (key == "map"s)
{
mapVector.emplace_back(val);
}
else if (key == "gametype"s)
{
gametypeVector.emplace_back(val);
}
}
auto mapRotationJson = nlohmann::json
{
{"maps", mapVector},
{"gametypes", gametypeVector},
};
return mapRotationJson;
}
void MapRotation::LoadRotation(const std::string& data)
{
static auto loaded = false;

View File

@ -38,8 +38,6 @@ namespace Components
[[nodiscard]] bool empty() const noexcept;
[[nodiscard]] bool contains(const std::string& key, const std::string& value) const;
[[nodiscard]] nlohmann::json to_json() const;
private:
std::vector<rotationEntry> rotationEntries_;

View File

@ -1,8 +1,11 @@
#include <STDInclude.hpp>
#include <json.hpp>
#include "FastFiles.hpp"
#include "RawFiles.hpp"
#include "StartupMessages.hpp"
#include "Theatre.hpp"
#include "UIFeeder.hpp"
namespace Components
{

View File

@ -1,4 +1,5 @@
#include <STDInclude.hpp>
#include "Party.hpp"
namespace Components
{

View File

@ -1,4 +1,9 @@
#include <STDInclude.hpp>
#include <Utils/Compression.hpp>
#include <Utils/InfoString.hpp>
#include <proto/node.pb.h>
#include "ServerList.hpp"
#include "Session.hpp"

View File

@ -1,6 +1,9 @@
#include <STDInclude.hpp>
#include <Utils/InfoString.hpp>
#include "Download.hpp"
#include "Gamepad.hpp"
#include "Party.hpp"
#include "ServerList.hpp"
#include "Stats.hpp"
#include "Voice.hpp"
@ -9,8 +12,25 @@
namespace Components
{
Party::JoinContainer Party::Container;
std::map<uint64_t, Network::Address> Party::LobbyMap;
class JoinContainer
{
public:
Network::Address target;
std::string challenge;
std::string motd;
DWORD joinTime;
bool valid;
int matchType;
Utils::InfoString info;
// Party-specific stuff
DWORD requestTime;
bool awaitingPlaylist;
};
static JoinContainer Container;
std::map<std::uint64_t, Network::Address> Party::LobbyMap;
Dvar::Var Party::PartyEnable;
@ -401,15 +421,15 @@ namespace Components
const Utils::InfoString info(data);
// Handle connection
if (Party::Container.valid)
if (Container.valid)
{
if (Party::Container.target == address)
if (Container.target == address)
{
// Invalidate handler for future packets
Party::Container.valid = false;
Party::Container.info = info;
Container.valid = false;
Container.info = info;
Party::Container.matchType = atoi(info.get("matchtype").data());
Container.matchType = atoi(info.get("matchtype").data());
auto securityLevel = static_cast<std::uint32_t>(atoi(info.get("securityLevel").data()));
bool isUsermap = !info.get("usermaphash").empty();
auto usermapHash = static_cast<std::uint32_t>(atoi(info.get("usermaphash").data()));
@ -428,30 +448,30 @@ namespace Components
Download::SV_wwwBaseUrl.set("");
}
if (info.get("challenge") != Party::Container.challenge)
if (info.get("challenge") != Container.challenge)
{
Party::ConnectError("Invalid join response: Challenge mismatch.");
ConnectError("Invalid join response: Challenge mismatch.");
}
else if (securityLevel > Auth::GetSecurityLevel())
{
Command::Execute("closemenu popup_reconnectingtoparty");
Auth::IncreaseSecurityLevel(securityLevel, "reconnect");
}
else if (!Party::Container.matchType)
else if (!Container.matchType)
{
Party::ConnectError("Server is not hosting a match.");
ConnectError("Server is not hosting a match.");
}
else if (Party::Container.matchType > 2 || Party::Container.matchType < 0)
else if (Container.matchType > 2 || Container.matchType < 0)
{
Party::ConnectError("Invalid join response: Unknown matchtype");
ConnectError("Invalid join response: Unknown matchtype");
}
else if (Party::Container.info.get("mapname").empty() || Party::Container.info.get("gametype").empty())
else if (Container.info.get("mapname").empty() || Container.info.get("gametype").empty())
{
Party::ConnectError("Invalid map or gametype.");
ConnectError("Invalid map or gametype.");
}
else if (Party::Container.info.get("isPrivate") == "1"s && !Dvar::Var("password").get<std::string>().length())
else if (Container.info.get("isPrivate") == "1"s && !Dvar::Var("password").get<std::string>().length())
{
Party::ConnectError("A password is required to join this server! Set it at the bottom of the serverlist.");
ConnectError("A password is required to join this server! Set it at the bottom of the serverlist.");
}
else if (isUsermap && usermapHash != Maps::GetUsermapHash(info.get("mapname")))
{
@ -476,16 +496,16 @@ namespace Components
}
else
{
if (!Maps::CheckMapInstalled(Party::Container.info.get("mapname"), true)) return;
if (!Maps::CheckMapInstalled(Container.info.get("mapname"), true)) return;
Party::Container.motd = info.get("sv_motd");
Container.motd = info.get("sv_motd");
if (Party::Container.matchType == 1) // Party
if (Container.matchType == 1) // Party
{
// Send playlist request
Party::Container.requestTime = Game::Sys_Milliseconds();
Party::Container.awaitingPlaylist = true;
Network::SendCommand(Party::Container.target, "getplaylist", Dvar::Var("password").get<std::string>());
Container.requestTime = Game::Sys_Milliseconds();
Container.awaitingPlaylist = true;
Network::SendCommand(Container.target, "getplaylist", Dvar::Var("password").get<std::string>());
// This is not a safe method
// TODO: Fix actual error!
@ -494,7 +514,7 @@ namespace Components
Command::Execute("disconnect", true);
}
}
else if (Party::Container.matchType == 2) // Match
else if (Container.matchType == 2) // Match
{
int clients;
int maxClients;
@ -521,7 +541,7 @@ namespace Components
Game::Menus_CloseAll(Game::uiContext);
Game::_XSESSION_INFO hostInfo;
Game::CL_ConnectFromParty(0, &hostInfo, *Party::Container.target.get(), 0, 0, Party::Container.info.get("mapname").data(), Party::Container.info.get("gametype").data());
Game::CL_ConnectFromParty(0, &hostInfo, *Container.target.get(), 0, 0, Container.info.get("mapname").data(), Container.info.get("gametype").data());
}
}
}

View File

@ -26,25 +26,7 @@ namespace Components
static std::string GetMotd();
private:
class JoinContainer
{
public:
Network::Address target;
std::string challenge;
std::string motd;
DWORD joinTime;
bool valid;
int matchType;
Utils::InfoString info;
// Party-specific stuff
DWORD requestTime;
bool awaitingPlaylist;
};
static JoinContainer Container;
static std::map<uint64_t, Network::Address> LobbyMap;
static std::map<std::uint64_t, Network::Address> LobbyMap;
static Dvar::Var PartyEnable;

View File

@ -1,4 +1,9 @@
#include <STDInclude.hpp>
#include <Utils/Compression.hpp>
#include <proto/party.pb.h>
#include "Party.hpp"
#include "Playlist.hpp"
namespace Components

View File

@ -1,4 +1,6 @@
#include <STDInclude.hpp>
#include <Utils/Compression.hpp>
#include "QuickPatch.hpp"
namespace Components

View File

@ -1,5 +1,8 @@
#include <STDInclude.hpp>
#include <proto/rcon.pb.h>
#include "RCon.hpp"
#include "Party.hpp"
namespace Components
{

View File

@ -1,5 +1,8 @@
#include <STDInclude.hpp>
#include <Utils/InfoString.hpp>
#include "Gamepad.hpp"
#include "Party.hpp"
#include "ServerInfo.hpp"
#include "ServerList.hpp"
#include "UIFeeder.hpp"

View File

@ -1,5 +1,8 @@
#include <STDInclude.hpp>
#include <Utils/InfoString.hpp>
#include "Discovery.hpp"
#include "Party.hpp"
#include "ServerList.hpp"
#include "UIFeeder.hpp"

View File

@ -1,4 +1,6 @@
#include <STDInclude.hpp>
#include <proto/session.pb.h>
#include "Session.hpp"
namespace Components

View File

@ -1,6 +1,8 @@
#include <STDInclude.hpp>
#include "StructuredData.hpp"
#include <json.hpp>
namespace Components
{
Utils::Memory::Allocator StructuredData::MemAllocator;

View File

@ -1,4 +1,7 @@
#include <STDInclude.hpp>
#include <json.hpp>
#include "Theatre.hpp"
#include "UIFeeder.hpp"

View File

@ -20,7 +20,7 @@ namespace Components
int length;
std::time_t timeStamp;
nlohmann::json to_json() const
[[nodiscard]] nlohmann::json to_json() const
{
return nlohmann::json
{
@ -28,7 +28,7 @@ namespace Components
{ "gametype", gametype },
{ "author", author },
{ "length", length },
{ "timestamp", Utils::String::VA("%lld", timeStamp) } //Ugly, but prevents information loss
{ "timestamp", Utils::String::VA("%lld", timeStamp) } // Ugly, but prevents information loss
};
}
};

View File

@ -1,4 +1,6 @@
#include <STDInclude.hpp>
#include <Utils/InfoString.hpp>
#include "UserInfo.hpp"
#include "GSC/Script.hpp"

View File

@ -1,5 +1,7 @@
#include <STDInclude.hpp>
#include "FastFiles.hpp"
namespace Components
{
Dvar::Var Window::NoBorder;

View File

@ -1,5 +1,10 @@
#include <STDInclude.hpp>
#include <Utils/Compression.hpp>
#include "Console.hpp"
#include "FastFiles.hpp"
#include <json.hpp>
#include <version.hpp>

View File

@ -1,5 +1,9 @@
#include <STDInclude.hpp>
#include <zlib.h>
#include "FastFiles.hpp"
#pragma optimize( "", off )
namespace Components
{

View File

@ -26,7 +26,6 @@ namespace Main
void Uninitialize()
{
Components::Loader::Uninitialize();
google::protobuf::ShutdownProtobufLibrary();
}
__declspec(naked) void EntryPoint()

View File

@ -46,7 +46,10 @@
#include <sstream>
#include <thread>
#include <type_traits>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#pragma warning(pop)
@ -80,7 +83,6 @@
#include <gsl/gsl>
#include <tomcrypt.h>
#include <zlib.h>
// Enable additional literals
using namespace std::literals;
@ -93,12 +95,6 @@ using namespace std::literals;
#undef min
#endif
// Needs to be included after the nominmax above ^
#ifdef snprintf
#undef snprintf
#endif
#include <json.hpp>
#define AssertSize(x, size) \
static_assert(sizeof(x) == (size), \
"Structure has an invalid size. " #x " must be " #size " bytes")
@ -111,30 +107,18 @@ using namespace std::literals;
#define AssertUnreachable assert(0 && "unreachable")
// Protobuf
#include "proto/session.pb.h"
#include "proto/party.pb.h"
#include "proto/auth.pb.h"
#include "proto/node.pb.h"
#include "proto/rcon.pb.h"
#include "proto/ipc.pb.h"
#include "proto/friends.pb.h"
#pragma warning(pop)
#include "Utils/Memory.hpp" // Breaks order on purpose
#include "Utils/Cache.hpp"
#include "Utils/Chain.hpp"
#include "Utils/Compression.hpp"
#include "Utils/Concurrency.hpp"
#include "Utils/Cryptography.hpp"
#include "Utils/CSV.hpp"
#include "Utils/Entities.hpp"
#include "Utils/Hooking.hpp"
#include "Utils/InfoString.hpp"
#include "Utils/IO.hpp"
#include "Utils/Json.hpp"
#include "Utils/Library.hpp"
#include "Utils/Maths.hpp"
#include "Utils/NamedMutex.hpp"

View File

@ -1,4 +1,5 @@
#include <STDInclude.hpp>
#include <Components/Modules/Party.hpp>
STEAM_IGNORE_WARNINGS_START

View File

@ -1,4 +1,7 @@
#include <STDInclude.hpp>
#include <zlib.h>
#include "Compression.hpp"
namespace Utils::Compression
{

View File

@ -1,4 +1,5 @@
#include <STDInclude.hpp>
#include "InfoString.hpp"
namespace Utils
{

View File

@ -1,4 +1,5 @@
#pragma once
#include <json.hpp>
namespace Utils
{

View File

@ -1,6 +1,8 @@
#include <STDInclude.hpp>
#include <bitset>
#include "Json.hpp"
namespace Utils::Json
{
std::string TypeToString(const nlohmann::json::value_t type)
@ -33,7 +35,7 @@ namespace Utils::Json
}
}
unsigned long ReadFlags(const std::string binaryFlags, size_t size)
unsigned long ReadFlags(const std::string binaryFlags, std::size_t size)
{
std::bitset<64> input;
const auto binarySize = size * 8;
@ -53,7 +55,7 @@ namespace Utils::Json
break;
}
bool isOne = bit == '1';
auto isOne = bit == '1';
input.set(i--, isOne);
}

View File

@ -1,8 +1,9 @@
#pragma once
#include <json.hpp>
namespace Utils::Json
{
std::string TypeToString(nlohmann::json::value_t type);
unsigned long ReadFlags(const std::string binaryFlags, size_t size);
unsigned long ReadFlags(std::string binaryFlags, size_t size);
}