Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions codxe.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@

<ClCompile Include="src\game\iw4\mp_tu6\components\cg.cpp" />
<ClCompile Include="src\game\iw4\mp_tu6\components\clipmap.cpp" />
<ClCompile Include="src\game\iw4\mp_tu6\components\cmds.cpp" />
<ClCompile Include="src\game\iw4\mp_tu6\components\console.cpp" />
<ClCompile Include="src\game\iw4\mp_tu6\components\events.cpp" />
<ClCompile Include="src\game\iw4\mp_tu6\components\g_client_fields.cpp" />
Expand Down Expand Up @@ -256,6 +257,7 @@

<ClInclude Include="src\game\iw4\mp_tu6\components\cg.h" />
<ClInclude Include="src\game\iw4\mp_tu6\components\clipmap.h" />
<ClInclude Include="src\game\iw4\mp_tu6\components\cmds.h" />
<ClInclude Include="src\game\iw4\mp_tu6\components\console.h" />
<ClInclude Include="src\game\iw4\mp_tu6\components\events.h" />
<ClInclude Include="src\game\iw4\mp_tu6\components\g_client_fields.h" />
Expand Down
90 changes: 90 additions & 0 deletions src/game/iw4/mp_tu6/components/cmds.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include "pch.h"
#include "cmds.h"

namespace iw4
{
namespace mp_tu6
{
namespace
{

Detour ClientCommand_Detour;

void SendCommandMessage(int clientNum, const char *message)
{
const char *commandString = va("%c \"%s\"", 101, message);

SV_GameSendServerCommand(clientNum, SV_CMD_CAN_IGNORE, commandString);
}

bool ToggleFlag(int &flags, int flag)
{
const bool enableFlag = (flags & flag) == 0;

if (enableFlag)
flags |= flag;
else
flags &= ~flag;

return enableFlag;
}

void Cmd_Noclip_f(int clientNum, gentity_s *ent)
{
const bool enabled = ToggleFlag(ent->client->flags, CF_NOCLIP);
SendCommandMessage(clientNum, enabled ? "GAME_NOCLIPON" : "GAME_NOCLIPOFF");
}

void Cmd_UFO_f(int clientNum, gentity_s *ent)
{
const bool enabled = ToggleFlag(ent->client->flags, CF_UFO);
SendCommandMessage(clientNum, enabled ? "GAME_UFOON" : "GAME_UFOOFF");
}

void Cmd_God_f(int clientNum, gentity_s *ent)
{
const bool enabled = ToggleFlag(ent->flags, FL_GODMODE);
SendCommandMessage(clientNum, enabled ? "GAME_GODMODE_ON" : "GAME_GODMODE_OFF");
}

void Cmd_DemiGod_f(int clientNum, gentity_s *ent)
{
const bool enabled = ToggleFlag(ent->flags, FL_DEMI_GODMODE);
SendCommandMessage(clientNum, enabled ? "GAME_DEMI_GODMODE_ON" : "GAME_DEMI_GODMODE_OFF");
}

void ClientCommand_Hook(int clientNum)
{
assert(clientNum >= 0 && clientNum < IW4_MAX_CLIENTS);

gentity_s *ent = &g_entities[clientNum];
assert(ent->client);

char cmd[1024] = {};
SV_Cmd_ArgvBuffer(0, cmd, static_cast<int>(sizeof(cmd)));

if (I_stricmp(cmd, "god") == 0)
Cmd_God_f(clientNum, ent);
else if (I_stricmp(cmd, "demigod") == 0)
Cmd_DemiGod_f(clientNum, ent);
else if (I_stricmp(cmd, "noclip") == 0)
Cmd_Noclip_f(clientNum, ent);
else if (I_stricmp(cmd, "ufo") == 0)
Cmd_UFO_f(clientNum, ent);
else
ClientCommand_Detour.GetOriginal<decltype(ClientCommand)>()(clientNum);
}
} // namespace

cmds::cmds()
{
ClientCommand_Detour = Detour(ClientCommand, ClientCommand_Hook);
ClientCommand_Detour.Install();
}

cmds::~cmds()
{
ClientCommand_Detour.Remove();
}
} // namespace mp_tu6
} // namespace iw4
21 changes: 21 additions & 0 deletions src/game/iw4/mp_tu6/components/cmds.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#pragma once

#include "pch.h"

namespace iw4
{
namespace mp_tu6
{
class cmds : public Module
{
public:
cmds();
~cmds();

const char *get_name() override
{
return "cmds";
};
};
} // namespace mp_tu6
} // namespace iw4
2 changes: 2 additions & 0 deletions src/game/iw4/mp_tu6/main.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "pch.h"
#include "components/cg.h"
#include "components/clipmap.h"
#include "components/cmds.h"
#include "components/console.h"
#include "components/events.h"
#include "components/g_client_fields.h"
Expand All @@ -25,6 +26,7 @@ IW4_MP_TU6_Plugin::IW4_MP_TU6_Plugin()
RegisterModule(new Events()); // Must be registered first to ensure hooks are in place
RegisterModule(new cg());
RegisterModule(new clipmap());
RegisterModule(new cmds());
RegisterModule(new console());
RegisterModule(new g_client_fields());
RegisterModule(new g_scr_main());
Expand Down
44 changes: 43 additions & 1 deletion src/game/iw4/mp_tu6/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ enum DvarFlags : std::uint16_t
DVAR_FLAG_SERVERINFO = 0x10,
};

enum svscmd_type : __int32
{
SV_CMD_CAN_IGNORE = 0x0,
SV_CMD_RELIABLE = 0x1,
};

struct dvar_t
{
const char *name;
Expand Down Expand Up @@ -826,6 +832,37 @@ struct blend_ent_t
float totalTime;
};

enum entityFlag_t : uint32_t
{
FL_GODMODE = 0x1,
FL_DEMI_GODMODE = 0x2,
FL_NOTARGET = 0x4,
FL_NO_KNOCKBACK = 0x8,
FL_NO_RADIUS_DAMAGE = 0x10,
FL_SUPPORTS_LINKTO = 0x1000,
FL_NO_AUTO_ANIM_UPDATE = 0x2000,
FL_GRENADE_TOUCH_DAMAGE = 0x4000,
FL_STABLE_MISSILES = 0x20000,
FL_REPEAT_ANIM_UPDATE = 0x40000,
FL_VEHICLE_TARGET = 0x80000,
FL_GROUND_ENT = 0x100000,
FL_CURSOR_HINT = 0x200000,
FL_MISSILE_ATTRACTOR = 0x800000,
FL_WEAPON_BEING_GRABBED = 0x1000000,
FL_DELETE = 0x2000000,
FL_BOUNCE = 0x4000000,
FL_MOVER_SLIDE = 0x8000000,
};

enum clientFlag_t : uint32_t
{
CF_NOCLIP = 1u << 0,
CF_UFO = 1u << 1,
CF_FROZEN = 1u << 2,
CF_DISABLE_USABILITY = 1u << 3,
CF_NO_KNOCKBACK = 1u << 4,
};

struct gentity_s
{
entityState_s s;
Expand Down Expand Up @@ -1772,7 +1809,12 @@ enum XAssetType : __int32

struct cplane_s;
struct cStaticModel_s;
struct ClipMaterial;
struct ClipMaterial
{
const char *name;
int surfaceFlags;
int contentFlags;
};
struct cbrushside_t;
struct cNode_t;
struct cLeaf_t;
Expand Down
12 changes: 12 additions & 0 deletions src/game/iw4/mp_tu6/symbols.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ static auto Hunk_AllocateTempMemoryHighInternal = reinterpret_cast<void *(*)(int

static auto Cbuf_AddText = reinterpret_cast<void (*)(int localClientNum, const char *text)>(0x82275C60);

typedef void (*ClientCommand_t)(int clientNum);
static ClientCommand_t ClientCommand = reinterpret_cast<ClientCommand_t>(0x822266D0);

typedef void (*CL_CharEvent_t)(int localClientNum, int key);
static CL_CharEvent_t CL_CharEvent = reinterpret_cast<CL_CharEvent_t>(0x82182EC8);

Expand Down Expand Up @@ -53,6 +56,9 @@ static Com_Printf_t Com_Printf = reinterpret_cast<Com_Printf_t>(0x8227F448);
typedef void (*Com_PrintMessage_t)(int channel, const char *msg, int error);
static Com_PrintMessage_t Com_PrintMessage = reinterpret_cast<Com_PrintMessage_t>(0x8227F370);

typedef int (*I_stricmp_t)(const char *s0, const char *s1);
static I_stricmp_t I_stricmp = reinterpret_cast<I_stricmp_t>(0x82315B70);

typedef void (*Info_SetValueForKey_t)(char *s, const char *key, const char *value);
static Info_SetValueForKey_t Info_SetValueForKey = reinterpret_cast<Info_SetValueForKey_t>(0x823167D8);

Expand Down Expand Up @@ -216,6 +222,12 @@ static SV_IsClientBot_t SV_IsClientBot = reinterpret_cast<SV_IsClientBot_t>(0x82
typedef gentity_s *(*SV_AddTestClient_t)();
static SV_AddTestClient_t SV_AddTestClient = reinterpret_cast<SV_AddTestClient_t>(0x822BDCB8);

typedef void (*SV_Cmd_ArgvBuffer_t)(int arg, char *buffer, int bufferLength);
static SV_Cmd_ArgvBuffer_t SV_Cmd_ArgvBuffer = reinterpret_cast<SV_Cmd_ArgvBuffer_t>(0x822760C8);

typedef void (*SV_GameSendServerCommand_t)(int clientNum, svscmd_type type, const char *text);
static SV_GameSendServerCommand_t SV_GameSendServerCommand = reinterpret_cast<SV_GameSendServerCommand_t>(0x822BDF00);

typedef void (*SV_UserinfoChanged_t)(client_t *cl);
static SV_UserinfoChanged_t SV_UserinfoChanged = reinterpret_cast<SV_UserinfoChanged_t>(0x822BBED8);

Expand Down
Loading