[Vote] Add vote/callvote (#447)
This commit is contained in:
parent
44dec50c4a
commit
ba34f1ea7c
@ -113,6 +113,7 @@ namespace Components
|
||||
Loader::Register(new UserInfo());
|
||||
Loader::Register(new Events());
|
||||
Loader::Register(new Voice());
|
||||
Loader::Register(new Vote());
|
||||
|
||||
Loader::Register(new GSC());
|
||||
|
||||
|
@ -144,5 +144,6 @@ namespace Components
|
||||
#include "Modules/UserInfo.hpp"
|
||||
#include "Modules/Events.hpp"
|
||||
#include "Modules/Voice.hpp"
|
||||
#include "Modules/Vote.hpp"
|
||||
|
||||
#include "Modules/GSC/GSC.hpp"
|
||||
|
@ -38,7 +38,7 @@ namespace Components
|
||||
if (IsMuted(player))
|
||||
{
|
||||
SendChat = false;
|
||||
Game::SV_GameSendServerCommand(player->s.number, Game::SV_CMD_CAN_IGNORE,
|
||||
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE,
|
||||
Utils::String::VA("%c \"You are muted\"", 0x65));
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ namespace Components
|
||||
if (sv_disableChat.get<bool>())
|
||||
{
|
||||
SendChat = false;
|
||||
Game::SV_GameSendServerCommand(player->s.number, Game::SV_CMD_CAN_IGNORE,
|
||||
Game::SV_GameSendServerCommand(player - Game::g_entities, Game::SV_CMD_CAN_IGNORE,
|
||||
Utils::String::VA("%c \"Chat is disabled\"", 0x65));
|
||||
}
|
||||
|
||||
@ -236,7 +236,7 @@ namespace Components
|
||||
|
||||
bool Chat::IsMuted(const Game::gentity_s* ent)
|
||||
{
|
||||
const auto clientNum = ent->s.number;
|
||||
const auto clientNum = ent - Game::g_entities;
|
||||
const auto xuid = Game::svs_clients[clientNum].steamID;
|
||||
|
||||
const auto result = MutedList.access<bool>([&](muteList& clients)
|
||||
@ -368,7 +368,7 @@ namespace Components
|
||||
|
||||
int Chat::ChatCallback(Game::gentity_s* self, const char* codePos, const char* message, int mode)
|
||||
{
|
||||
const auto entityId = Game::Scr_GetEntityId(self->s.number, 0);
|
||||
const auto entityId = Game::Scr_GetEntityId(self - Game::g_entities, 0);
|
||||
|
||||
Scripting::StackIsolation _;
|
||||
Game::Scr_AddInt(mode);
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
namespace Components
|
||||
{
|
||||
std::unordered_map<std::string, std::function<void(Game::gentity_s*, Command::ServerParams*)>> ClientCommand::HandlersSV;
|
||||
std::unordered_map<std::string, std::function<void(Game::gentity_s*, const Command::ServerParams*)>> ClientCommand::HandlersSV;
|
||||
|
||||
bool ClientCommand::CheatsOk(const Game::gentity_s* ent)
|
||||
{
|
||||
@ -26,7 +26,7 @@ namespace Components
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClientCommand::Add(const char* name, const std::function<void(Game::gentity_s*, Command::ServerParams*)>& callback)
|
||||
void ClientCommand::Add(const char* name, const std::function<void(Game::gentity_s*, const Command::ServerParams*)>& callback)
|
||||
{
|
||||
const auto command = Utils::String::ToLower(name);
|
||||
|
||||
@ -57,7 +57,7 @@ namespace Components
|
||||
|
||||
void ClientCommand::AddCheatCommands()
|
||||
{
|
||||
ClientCommand::Add("noclip", [](Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("noclip", [](Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
@ -71,7 +71,7 @@ namespace Components
|
||||
(ent->client->flags & Game::PLAYER_FLAG_NOCLIP) ? "GAME_NOCLIPON" : "GAME_NOCLIPOFF"));
|
||||
});
|
||||
|
||||
ClientCommand::Add("ufo", [](Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("ufo", [](Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
@ -85,7 +85,7 @@ namespace Components
|
||||
(ent->client->flags & Game::PLAYER_FLAG_UFO) ? "GAME_UFOON" : "GAME_UFOOFF"));
|
||||
});
|
||||
|
||||
ClientCommand::Add("god", [](Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("god", [](Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
@ -99,7 +99,7 @@ namespace Components
|
||||
(ent->flags & Game::FL_GODMODE) ? "GAME_GODMODE_ON" : "GAME_GODMODE_OFF"));
|
||||
});
|
||||
|
||||
ClientCommand::Add("demigod", [](Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("demigod", [](Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
@ -113,7 +113,7 @@ namespace Components
|
||||
(ent->flags & Game::FL_DEMI_GODMODE) ? "GAME_DEMI_GODMODE_ON" : "GAME_DEMI_GODMODE_OFF"));
|
||||
});
|
||||
|
||||
ClientCommand::Add("notarget", [](Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("notarget", [](Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
@ -127,7 +127,7 @@ namespace Components
|
||||
(ent->flags & Game::FL_NOTARGET) ? "GAME_NOTARGETON" : "GAME_NOTARGETOFF"));
|
||||
});
|
||||
|
||||
ClientCommand::Add("setviewpos", [](Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("setviewpos", [](Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
assert(ent != nullptr);
|
||||
|
||||
@ -163,7 +163,7 @@ namespace Components
|
||||
Game::TeleportPlayer(ent, origin, angles);
|
||||
});
|
||||
|
||||
ClientCommand::Add("give", [](Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("give", [](Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
if (!ClientCommand::CheatsOk(ent))
|
||||
return;
|
||||
@ -246,28 +246,28 @@ namespace Components
|
||||
|
||||
void ClientCommand::AddDevelopmentCommands()
|
||||
{
|
||||
ClientCommand::Add("dropallbots", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("dropallbots", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
Game::SV_DropAllBots();
|
||||
});
|
||||
|
||||
ClientCommand::Add("entitylist", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("entitylist", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
Game::Svcmd_EntityList_f();
|
||||
});
|
||||
|
||||
ClientCommand::Add("printentities", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("printentities", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
Game::G_PrintEntities();
|
||||
});
|
||||
|
||||
ClientCommand::Add("entitycount", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("entitycount", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
Logger::Print("Entity count = {}\n", Game::level->num_entities);
|
||||
});
|
||||
|
||||
// Also known as: "vis"
|
||||
ClientCommand::Add("visionsetnaked", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("visionsetnaked", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
if (params->size() < 2)
|
||||
{
|
||||
@ -295,7 +295,7 @@ namespace Components
|
||||
Utils::String::VA("%c \"%s\" %i", Game::MY_CMDS[visMode], name, duration));
|
||||
});
|
||||
|
||||
ClientCommand::Add("visionsetnight", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("visionsetnight", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
if (params->size() < 2)
|
||||
{
|
||||
@ -323,7 +323,7 @@ namespace Components
|
||||
Utils::String::VA("%c \"%s\" %i", Game::MY_CMDS[visMode], name, duration));
|
||||
});
|
||||
|
||||
ClientCommand::Add("g_testCmd", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("g_testCmd", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
assert(ent != nullptr);
|
||||
|
||||
@ -331,7 +331,7 @@ namespace Components
|
||||
Logger::Debug("playerState_s.stunTime is {}", ent->client->ps.stunTime);
|
||||
});
|
||||
|
||||
ClientCommand::Add("kill", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] Command::ServerParams* params)
|
||||
ClientCommand::Add("kill", []([[maybe_unused]] Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
assert(ent->client != nullptr);
|
||||
assert(ent->client->sess.connected != Game::CON_DISCONNECTED);
|
||||
|
@ -7,11 +7,11 @@ namespace Components
|
||||
public:
|
||||
ClientCommand();
|
||||
|
||||
static void Add(const char* name, const std::function<void(Game::gentity_s*, Command::ServerParams*)>& callback);
|
||||
static void Add(const char* name, const std::function<void(Game::gentity_s*, const Command::ServerParams*)>& callback);
|
||||
static bool CheatsOk(const Game::gentity_s* ent);
|
||||
|
||||
private:
|
||||
static std::unordered_map<std::string, std::function<void(Game::gentity_s*, Command::ServerParams*)>> HandlersSV;
|
||||
static std::unordered_map<std::string, std::function<void(Game::gentity_s*, const Command::ServerParams*)>> HandlersSV;
|
||||
|
||||
static void ClientCommandStub(int clientNum);
|
||||
static void AddCheatCommands();
|
||||
|
@ -5,7 +5,7 @@ namespace Components
|
||||
std::unordered_map<std::string, std::function<void(Command::Params*)>> Command::FunctionMap;
|
||||
std::unordered_map<std::string, std::function<void(Command::Params*)>> Command::FunctionMapSV;
|
||||
|
||||
std::string Command::Params::join(const int index)
|
||||
std::string Command::Params::join(const int index) const
|
||||
{
|
||||
std::string result;
|
||||
|
||||
@ -24,12 +24,12 @@ namespace Components
|
||||
assert(Game::cmd_args->nesting < Game::CMD_MAX_NESTING);
|
||||
}
|
||||
|
||||
int Command::ClientParams::size()
|
||||
int Command::ClientParams::size() const
|
||||
{
|
||||
return Game::cmd_args->argc[this->nesting_];
|
||||
}
|
||||
|
||||
const char* Command::ClientParams::get(const int index)
|
||||
const char* Command::ClientParams::get(const int index) const
|
||||
{
|
||||
if (index >= this->size())
|
||||
{
|
||||
@ -45,12 +45,12 @@ namespace Components
|
||||
assert(Game::sv_cmd_args->nesting < Game::CMD_MAX_NESTING);
|
||||
}
|
||||
|
||||
int Command::ServerParams::size()
|
||||
int Command::ServerParams::size() const
|
||||
{
|
||||
return Game::sv_cmd_args->argc[this->nesting_];
|
||||
}
|
||||
|
||||
const char* Command::ServerParams::get(const int index)
|
||||
const char* Command::ServerParams::get(const int index) const
|
||||
{
|
||||
if (index >= this->size())
|
||||
{
|
||||
|
@ -13,9 +13,9 @@ namespace Components
|
||||
Params() = default;
|
||||
virtual ~Params() = default;
|
||||
|
||||
virtual int size() = 0;
|
||||
virtual const char* get(int index) = 0;
|
||||
virtual std::string join(int index);
|
||||
[[nodiscard]] virtual int size() const = 0;
|
||||
[[nodiscard]] virtual const char* get(int index) const = 0;
|
||||
[[nodiscard]] virtual std::string join(int index) const;
|
||||
|
||||
virtual const char* operator[](const int index)
|
||||
{
|
||||
@ -28,8 +28,8 @@ namespace Components
|
||||
public:
|
||||
ClientParams();
|
||||
|
||||
int size() override;
|
||||
const char* get(int index) override;
|
||||
[[nodiscard]] int size() const override;
|
||||
[[nodiscard]] const char* get(int index) const override;
|
||||
|
||||
private:
|
||||
int nesting_;
|
||||
@ -40,8 +40,8 @@ namespace Components
|
||||
public:
|
||||
ServerParams();
|
||||
|
||||
int size() override;
|
||||
const char* get(int index) override;
|
||||
[[nodiscard]] int size() const override;
|
||||
[[nodiscard]] const char* get(int index) const override;
|
||||
|
||||
private:
|
||||
int nesting_;
|
||||
|
276
src/Components/Modules/Vote.cpp
Normal file
276
src/Components/Modules/Vote.cpp
Normal file
@ -0,0 +1,276 @@
|
||||
#include <STDInclude.hpp>
|
||||
|
||||
using namespace Utils::String;
|
||||
|
||||
namespace Components
|
||||
{
|
||||
std::unordered_map<std::string, Vote::CommandHandler> Vote::VoteCommands =
|
||||
{
|
||||
{"map_restart", HandleMapRestart},
|
||||
{"map_rotate", HandleMapRotate},
|
||||
{"typemap", HandleTypemap},
|
||||
{"map", HandleMap},
|
||||
{"g_gametype", HandleGametype},
|
||||
};
|
||||
|
||||
void Vote::DisplayVote(const Game::gentity_s* ent)
|
||||
{
|
||||
Game::SV_GameSendServerCommand(-1, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_CALLEDAVOTE\x15%s\"", 0x65, ent->client->sess.cs.name));
|
||||
Game::level->voteNo = 0;
|
||||
Game::level->voteYes = 1;
|
||||
Game::level->voteTime = Game::level->time + 30000;
|
||||
|
||||
for (auto i = 0; i < Game::level->maxclients; ++i)
|
||||
{
|
||||
Game::level->clients[i].ps.eFlags &= ~Game::EF_VOTED;
|
||||
}
|
||||
|
||||
ent->client->ps.eFlags |= Game::EF_VOTED;
|
||||
Game::SV_SetConfigstring(Game::CS_VOTE_TIME, VA("%i %i", Game::level->voteTime, *Game::sv_serverId_value));
|
||||
Game::SV_SetConfigstring(Game::CS_VOTE_STRING, Game::level->voteDisplayString);
|
||||
Game::SV_SetConfigstring(Game::CS_VOTE_YES, VA("%i", Game::level->voteYes));
|
||||
Game::SV_SetConfigstring(Game::CS_VOTE_NO, VA("%i", Game::level->voteNo));
|
||||
}
|
||||
|
||||
bool Vote::IsInvalidVoteString(const std::string& input)
|
||||
{
|
||||
static const char* separators[] = { "\n", "\r", ";" };
|
||||
|
||||
return std::ranges::any_of(separators,
|
||||
[&](const std::string& str) { return input.find(str) != std::string::npos; });
|
||||
}
|
||||
|
||||
bool Vote::HandleMapRestart([[maybe_unused]] const Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
sprintf_s(Game::level->voteString, "fast_restart");
|
||||
sprintf_s(Game::level->voteDisplayString, "GAME_VOTE_MAPRESTART");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vote::HandleMapRotate([[maybe_unused]] const Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
sprintf_s(Game::level->voteString, "%s", params->get(1));
|
||||
sprintf_s(Game::level->voteDisplayString, "GAME_VOTE_NEXTMAP");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vote::HandleTypemap([[maybe_unused]] const Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
char arg2[0x100]{};
|
||||
char arg3[0x100]{};
|
||||
|
||||
strncpy_s(arg2, params->get(2), _TRUNCATE);
|
||||
strncpy_s(arg3, params->get(3), _TRUNCATE);
|
||||
|
||||
if (!Game::Scr_IsValidGameType(arg2))
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_INVALIDGAMETYPE\"", 0x65));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!std::strcmp(arg2, (*Game::g_gametype)->current.string))
|
||||
{
|
||||
arg2[0] = '\0';
|
||||
}
|
||||
|
||||
const auto* mapname = Game::Dvar_RegisterString("mapname", "", Game::DVAR_ROM | Game::DVAR_SERVERINFO, "Current map name");
|
||||
if (!std::strcmp(arg3, mapname->current.string))
|
||||
{
|
||||
arg3[0] = '\0';
|
||||
}
|
||||
|
||||
if (!arg2[0] && !arg3[0])
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_TYPEMAP_NOCHANGE\"", 0x65));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arg3[0])
|
||||
{
|
||||
if (arg2[0])
|
||||
{
|
||||
sprintf_s(Game::level->voteString, "g_gametype %s; map %s", arg2, arg3);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(Game::level->voteString, "map %s", arg3);
|
||||
}
|
||||
|
||||
if (arg2[0])
|
||||
{
|
||||
sprintf_s(Game::level->voteDisplayString, "GAME_VOTE_GAMETYPE\x14%s\x15 - \x14GAME_VOTE_MAP\x15%s", Game::Scr_GetGameTypeNameForScript(arg2), arg3);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(Game::level->voteDisplayString, "GAME_VOTE_MAP\x15%s", arg3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf_s(Game::level->voteString, "g_gametype %s; map_restart", arg2);
|
||||
sprintf_s(Game::level->voteDisplayString, "GAME_VOTE_GAMETYPE\x14%s", Game::Scr_GetGameTypeNameForScript(arg2));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vote::HandleMap([[maybe_unused]] const Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
sprintf_s(Game::level->voteString, "%s %s", params->get(1), params->get(2));
|
||||
sprintf_s(Game::level->voteDisplayString, "GAME_VOTE_MAP\x15%s", params->get(2));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Vote::HandleGametype([[maybe_unused]] const Game::gentity_s* ent, [[maybe_unused]] const Command::ServerParams* params)
|
||||
{
|
||||
if (!Game::Scr_IsValidGameType(params->get(2)))
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_INVALIDGAMETYPE\"", 0x65));
|
||||
return false;
|
||||
}
|
||||
|
||||
sprintf_s(Game::level->voteString, "%s %s; map_restart", params->get(2), params->get(3));
|
||||
sprintf_s(Game::level->voteDisplayString, "GAME_VOTE_GAMETYPE\x14%s", Game::Scr_GetGameTypeNameForScript(params->get(2)));
|
||||
return true;
|
||||
}
|
||||
|
||||
void Vote::Scr_VoteCalled(Game::gentity_s* self, const char* command, const char* param1, const char* param2)
|
||||
{
|
||||
Game::Scr_AddString(param2);
|
||||
Game::Scr_AddString(param1);
|
||||
Game::Scr_AddString(command);
|
||||
Game::Scr_Notify(self, Game::scr_const->call_vote, 3);
|
||||
}
|
||||
|
||||
void Vote::Scr_PlayerVote(Game::gentity_s* self, const char* option)
|
||||
{
|
||||
Game::Scr_AddString(option);
|
||||
Game::Scr_Notify(self, Game::scr_const->vote, 1);
|
||||
}
|
||||
|
||||
void Vote::Cmd_CallVote_f(Game::gentity_s* ent, const Command::ServerParams* params)
|
||||
{
|
||||
if (!(*Game::g_allowVote)->current.enabled)
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_VOTINGNOTENABLED\"", 0x65));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::level->numConnectedClients < 2)
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_VOTINGNOTENOUGHPLAYERS\"", 0x65));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((*Game::g_oldVoting)->current.enabled)
|
||||
{
|
||||
if (Game::level->voteTime)
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_VOTEALREADYINPROGRESS\"", 0x65));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->client->sess.voteCount >= 3)
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_MAXVOTESCALLED\"", 0x65));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->client->sess.cs.team == Game::TEAM_SPECTATOR)
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_NOSPECTATORCALLVOTE\"", 0x65));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsInvalidVoteString(params->get(1)) ||
|
||||
IsInvalidVoteString(params->get(2)) ||
|
||||
IsInvalidVoteString(params->get(3)))
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_INVALIDVOTESTRING\"", 0x65));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(*Game::g_oldVoting)->current.enabled)
|
||||
{
|
||||
Scr_VoteCalled(ent, params->get(1), params->get(2), params->get(3));
|
||||
return;
|
||||
}
|
||||
|
||||
const auto got = VoteCommands.find(params->get(1));
|
||||
if (got == VoteCommands.end())
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_INVALIDVOTESTRING\"", 0x65));
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA(CallVoteDesc, 0x65));
|
||||
return;
|
||||
}
|
||||
|
||||
if (Game::level->voteExecuteTime)
|
||||
{
|
||||
Game::level->voteExecuteTime = 0;
|
||||
Game::Cbuf_AddText(0, VA("%s\n", Game::level->voteString));
|
||||
}
|
||||
|
||||
const auto shouldDisplay = got->second(ent, params);
|
||||
if (shouldDisplay)
|
||||
{
|
||||
DisplayVote(ent);
|
||||
}
|
||||
}
|
||||
|
||||
void Vote::Cmd_Vote_f(Game::gentity_s* ent, const Command::ServerParams* params)
|
||||
{
|
||||
char arg1[0x100]{};
|
||||
|
||||
if ((*Game::g_oldVoting)->current.enabled)
|
||||
{
|
||||
if (!Game::level->voteTime)
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_NOVOTEINPROGRESS\"", 0x65));
|
||||
return;
|
||||
}
|
||||
|
||||
if ((ent->client->ps.eFlags & Game::EF_VOTED) != 0)
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_VOTEALREADYCAST\"", 0x65));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ent->client->sess.cs.team == Game::TEAM_SPECTATOR)
|
||||
{
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_NOSPECTATORVOTE\"", 0x65));
|
||||
return;
|
||||
}
|
||||
|
||||
Game::SV_GameSendServerCommand(ent - Game::g_entities, Game::SV_CMD_CAN_IGNORE, VA("%c \"GAME_VOTECAST\"", 0x65));
|
||||
ent->client->ps.eFlags |= Game::EF_VOTED;
|
||||
}
|
||||
|
||||
strncpy_s(arg1, params->get(1), _TRUNCATE);
|
||||
if (arg1[0] == 'y' || arg1[0] == 'Y' || arg1[0] == '1')
|
||||
{
|
||||
if ((*Game::g_oldVoting)->current.enabled)
|
||||
{
|
||||
Game::SV_SetConfigstring(Game::CS_VOTE_YES, VA("%i", ++Game::level->voteYes));
|
||||
}
|
||||
else
|
||||
{
|
||||
Scr_PlayerVote(ent, "yes");
|
||||
}
|
||||
}
|
||||
else if ((*Game::g_oldVoting)->current.enabled)
|
||||
{
|
||||
Game::SV_SetConfigstring(Game::CS_VOTE_NO, VA("%i", ++Game::level->voteNo));
|
||||
}
|
||||
else
|
||||
{
|
||||
Scr_PlayerVote(ent, "no");
|
||||
}
|
||||
}
|
||||
|
||||
Vote::Vote()
|
||||
{
|
||||
ClientCommand::Add("callvote", Cmd_CallVote_f);
|
||||
ClientCommand::Add("vote", Cmd_Vote_f);
|
||||
}
|
||||
}
|
31
src/Components/Modules/Vote.hpp
Normal file
31
src/Components/Modules/Vote.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
namespace Components
|
||||
{
|
||||
class Vote : public Component
|
||||
{
|
||||
public:
|
||||
Vote();
|
||||
|
||||
private:
|
||||
using CommandHandler = std::function<bool(const Game::gentity_s* ent, const Command::ServerParams* params)>;
|
||||
static std::unordered_map<std::string, CommandHandler> VoteCommands;
|
||||
|
||||
static constexpr auto* CallVoteDesc = "%c \"GAME_VOTECOMMANDSARE\x15 map_restart, map_rotate, map <mapname>, g_gametype <typename>, typemap <typename> <mapname>\"";
|
||||
|
||||
static void DisplayVote(const Game::gentity_s* ent);
|
||||
static bool IsInvalidVoteString(const std::string& input);
|
||||
|
||||
static bool HandleMapRestart(const Game::gentity_s* ent, const Command::ServerParams* params);
|
||||
static bool HandleMapRotate(const Game::gentity_s* ent, const Command::ServerParams* params);
|
||||
static bool HandleTypemap(const Game::gentity_s* ent, const Command::ServerParams* params);
|
||||
static bool HandleMap(const Game::gentity_s* ent, const Command::ServerParams* params);
|
||||
static bool HandleGametype(const Game::gentity_s* ent, const Command::ServerParams* params);
|
||||
|
||||
static void Scr_VoteCalled(Game::gentity_s* self, const char* command, const char* param1, const char* param2);
|
||||
static void Scr_PlayerVote(Game::gentity_s* self, const char* option);
|
||||
|
||||
static void Cmd_CallVote_f(Game::gentity_s* ent, const Command::ServerParams* params);
|
||||
static void Cmd_Vote_f(Game::gentity_s* ent, const Command::ServerParams* params);
|
||||
};
|
||||
}
|
@ -27,6 +27,9 @@ namespace Game
|
||||
|
||||
const dvar_t** g_cheats = reinterpret_cast<const dvar_t**>(0x1A45D54);
|
||||
const dvar_t** g_deadChat = reinterpret_cast<const dvar_t**>(0x19BD5DC);
|
||||
const dvar_t** g_allowVote = reinterpret_cast<const dvar_t**>(0x19BD644);
|
||||
const dvar_t** g_oldVoting = reinterpret_cast<const dvar_t**>(0x1A45DEC);
|
||||
const dvar_t** g_gametype = reinterpret_cast<const dvar_t**>(0x1A45DC8);
|
||||
|
||||
const dvar_t** version = reinterpret_cast<const dvar_t**>(0x1AD7930);
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ namespace Game
|
||||
|
||||
extern const dvar_t** g_cheats;
|
||||
extern const dvar_t** g_deadChat;
|
||||
extern const dvar_t** g_allowVote;
|
||||
extern const dvar_t** g_oldVoting;
|
||||
extern const dvar_t** g_gametype;
|
||||
|
||||
extern const dvar_t** version;
|
||||
}
|
||||
|
@ -292,6 +292,8 @@ namespace Game
|
||||
|
||||
RemoveRefToObject_t RemoveRefToObject = RemoveRefToObject_t(0x437190);
|
||||
|
||||
Scr_GetGameTypeNameForScript_t Scr_GetGameTypeNameForScript = Scr_GetGameTypeNameForScript_t(0x462460);
|
||||
Scr_IsValidGameType_t Scr_IsValidGameType = Scr_IsValidGameType_t(0x4F1B60);
|
||||
Scr_LoadGameType_t Scr_LoadGameType = Scr_LoadGameType_t(0x4D9520);
|
||||
Scr_StartupGameType_t Scr_StartupGameType = Scr_StartupGameType_t(0x438720);
|
||||
|
||||
@ -484,6 +486,7 @@ namespace Game
|
||||
Z_VirtualAlloc_t Z_VirtualAlloc = Z_VirtualAlloc_t(0x4CFBA0);
|
||||
|
||||
I_strncpyz_t I_strncpyz = I_strncpyz_t(0x4D6F80);
|
||||
I_CleanStr_t I_CleanStr = I_CleanStr_t(0x4AD470);
|
||||
|
||||
XNAddrToString_t XNAddrToString = XNAddrToString_t(0x452690);
|
||||
|
||||
@ -505,6 +508,7 @@ namespace Game
|
||||
float* cgameFOVSensitivityScale = reinterpret_cast<float*>(0xB2F884);
|
||||
|
||||
int* svs_time = reinterpret_cast<int*>(0x31D9384);
|
||||
int* sv_serverId_value = reinterpret_cast<int*>(0x2089DC0);
|
||||
int* svs_clientCount = reinterpret_cast<int*>(0x31D938C);
|
||||
client_t* svs_clients = reinterpret_cast<client_t*>(0x31D9390);
|
||||
|
||||
|
@ -771,6 +771,12 @@ namespace Game
|
||||
typedef void(__cdecl * Scr_ShutdownAllocNode_t)();
|
||||
extern Scr_ShutdownAllocNode_t Scr_ShutdownAllocNode;
|
||||
|
||||
typedef char*(__cdecl * Scr_GetGameTypeNameForScript_t)(const char* pszGameTypeScript);
|
||||
extern Scr_GetGameTypeNameForScript_t Scr_GetGameTypeNameForScript;
|
||||
|
||||
typedef int(__cdecl * Scr_IsValidGameType_t)(const char* pszGameType);
|
||||
extern Scr_IsValidGameType_t Scr_IsValidGameType;
|
||||
|
||||
typedef void(__cdecl * Scr_LoadGameType_t)();
|
||||
extern Scr_LoadGameType_t Scr_LoadGameType;
|
||||
|
||||
@ -1170,6 +1176,9 @@ namespace Game
|
||||
typedef void(__cdecl * I_strncpyz_t)(char* dest, const char* src, int destsize);
|
||||
extern I_strncpyz_t I_strncpyz;
|
||||
|
||||
typedef char*(__cdecl * I_CleanStr_t)(char* string);
|
||||
extern I_CleanStr_t I_CleanStr;
|
||||
|
||||
typedef void(__cdecl * XNAddrToString_t)(const XNADDR* xnaddr, char* str);
|
||||
extern XNAddrToString_t XNAddrToString;
|
||||
|
||||
@ -1196,6 +1205,7 @@ namespace Game
|
||||
extern float* cgameFOVSensitivityScale;
|
||||
|
||||
extern int* svs_time;
|
||||
extern int* sv_serverId_value;
|
||||
extern int* svs_clientCount;
|
||||
extern client_t* svs_clients;
|
||||
|
||||
|
@ -220,7 +220,7 @@ namespace Game
|
||||
DVAR_SOURCE_DEVGUI = 0x3,
|
||||
};
|
||||
|
||||
typedef enum : char
|
||||
enum dvar_type : char
|
||||
{
|
||||
DVAR_TYPE_BOOL = 0x0,
|
||||
DVAR_TYPE_FLOAT = 0x1,
|
||||
@ -233,7 +233,7 @@ namespace Game
|
||||
DVAR_TYPE_COLOR = 0x8,
|
||||
DVAR_TYPE_FLOAT_3_COLOR = 0x9,
|
||||
DVAR_TYPE_COUNT = 0xA,
|
||||
} dvar_type;
|
||||
};
|
||||
|
||||
enum clientState_t
|
||||
{
|
||||
@ -264,6 +264,17 @@ namespace Game
|
||||
ERR_MAPLOADERRORSUMMARY = 0x7
|
||||
};
|
||||
|
||||
enum ConfigString
|
||||
{
|
||||
CS_VOTE_TIME = 0x11,
|
||||
CS_VOTE_STRING = 0x12,
|
||||
CS_VOTE_YES = 0x13,
|
||||
CS_VOTE_NO = 0x14,
|
||||
CS_VOTE_MAPNAME = 0x15,
|
||||
CS_VOTE_GAMETYPE = 0x16,
|
||||
CS_ITEMS = 0x102A,
|
||||
}; // Incomplete
|
||||
|
||||
enum conChannel_t
|
||||
{
|
||||
CON_CHANNEL_DONT_FILTER,
|
||||
@ -1258,13 +1269,7 @@ namespace Game
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct $3EB5F037EADAEE8E2FA2A1F9FFF31312
|
||||
{
|
||||
hudelem_s current[31];
|
||||
hudelem_s archival[31];
|
||||
};
|
||||
|
||||
enum playerStateFlag
|
||||
enum
|
||||
{
|
||||
PMF_PRONE = 1 << 0,
|
||||
PMF_DUCKED = 1 << 1,
|
||||
@ -1291,7 +1296,7 @@ namespace Game
|
||||
PMF_DIVING = 1 << 22,
|
||||
};
|
||||
|
||||
enum playerStateOtherFlag
|
||||
enum
|
||||
{
|
||||
POF_INVULNERABLE = 1 << 0,
|
||||
POF_REMOTE_EYES = 1 << 1,
|
||||
@ -1327,7 +1332,7 @@ namespace Game
|
||||
PM_DEAD_LINKED = 0x9,
|
||||
};
|
||||
|
||||
enum playerEFlag
|
||||
enum
|
||||
{
|
||||
EF_NONSOLID_BMODEL = 1 << 0,
|
||||
EF_TELEPORT_BIT = 1 << 1,
|
||||
@ -1355,14 +1360,14 @@ namespace Game
|
||||
EF_SOFT = 1 << 23,
|
||||
};
|
||||
|
||||
enum playerLinkFlag
|
||||
enum
|
||||
{
|
||||
PLF_ANGLES_LOCKED = 1 << 0,
|
||||
PLF_USES_OFFSET = 1 << 1,
|
||||
PLF_WEAPONVIEW_ONLY = 1 << 2,
|
||||
};
|
||||
|
||||
enum playerWeaponFlag
|
||||
enum
|
||||
{
|
||||
PWF_USE_RELOAD = 1 << 0,
|
||||
PWF_USING_OFFHAND = 1 << 1,
|
||||
@ -1497,14 +1502,18 @@ namespace Game
|
||||
int killCamEntity;
|
||||
int killCamLookAtEntity;
|
||||
int killCamClientNum;
|
||||
$3EB5F037EADAEE8E2FA2A1F9FFF31312 hud;
|
||||
struct
|
||||
{
|
||||
hudelem_s current[31];
|
||||
hudelem_s archival[31];
|
||||
} hud;
|
||||
unsigned int partBits[6];
|
||||
int recoilScale;
|
||||
int diveDirection;
|
||||
int stunTime;
|
||||
};
|
||||
|
||||
static_assert(sizeof(Game::playerState_s) == 0x311C);
|
||||
static_assert(sizeof(playerState_s) == 0x311C);
|
||||
|
||||
enum LocSelInputState
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user