Skip to content

Commit 62f983d

Browse files
committed
feat(scripting): Fake Convars
1 parent ab87465 commit 62f983d

File tree

11 files changed

+470
-155
lines changed

11 files changed

+470
-155
lines changed

src/common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ void PLUGIN_PRINTF(std::string category, std::string str, ...);
5757
PRINTF(FORMAT_STR, __VA_ARGS__); \
5858
return RET; \
5959
}
60-
#define CLIENT_PRINT(SLOT, FORMAT_STR) g_SMAPI->ClientConPrintf(SLOT, std::string(PREFIX).append(" [").append(__FUNCTION_NAME__).append("] ").append(FORMAT_STR).c_str())
61-
#define CLIENT_PRINTF(SLOT, FORMAT_STR, ...) g_SMAPI->ClientConPrintf(SLOT, std::string(PREFIX).append(" [").append(__FUNCTION_NAME__).append("] ").append(FORMAT_STR).c_str(), __VA_ARGS__)
60+
#define CLIENT_PRINT(SLOT, CATEGORY, FORMAT_STR) g_SMAPI->ClientConPrint(SLOT, std::string(PREFIX).append(" [").append(CATEGORY).append("] ").append(FORMAT_STR).c_str())
61+
#define CLIENT_PRINTF(SLOT, CATEGORY, FORMAT_STR, ...) g_SMAPI->ClientConPrintf(SLOT, std::string(PREFIX).append(" [").append(CATEGORY).append("] ").append(FORMAT_STR).c_str(), __VA_ARGS__)
6262

6363
#ifndef SWIFTLY_DEBUG
6464
#define DEBUG_PRINTF(FORMAT_STR, ...)

src/convars/convars.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#ifndef _convars_h
2+
#define _convars_h
3+
4+
#include <any>
5+
#include <string>
6+
#include <map>
7+
#include "../entrypoint.h"
8+
#include "../common.h"
9+
#include "../utils/utils.h"
10+
11+
ConVar* FetchCVar(std::string cvarname);
12+
std::any FetchCVarValue(std::string cvarname);
13+
EConVarType FetchCVarType(std::string cvarname);
14+
15+
class FakeConVar
16+
{
17+
private:
18+
std::any m_value;
19+
EConVarType m_type;
20+
std::string m_name;
21+
22+
public:
23+
FakeConVar(std::string name, EConVarType type, std::any defaultValue, bool prot);
24+
~FakeConVar();
25+
26+
EConVarType GetType();
27+
void SetValue(std::any value);
28+
std::any GetValue();
29+
};
30+
31+
extern std::map<std::string, FakeConVar*> fakeConvars;
32+
33+
#endif

src/convars/fake_convars.cpp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#include "convars.h"
2+
3+
static void convarsCallback(const CCommandContext& context, const CCommand& args);
4+
std::map<std::string, bool> convarCreated;
5+
6+
FakeConVar::FakeConVar(std::string name, EConVarType type, std::any defaultValue, bool prot)
7+
{
8+
if (convarCreated.find(name) == convarCreated.end())
9+
{
10+
convarCreated.insert({ name, true });
11+
12+
ConCommandRefAbstract convarRef;
13+
new ConCommand(&convarRef, name.c_str(), convarsCallback, "Swiftly ConVar", FCVAR_LINKED_CONCOMMAND | FCVAR_SPONLY | (prot ? FCVAR_PROTECTED : FCVAR_NONE));
14+
}
15+
16+
m_value = defaultValue;
17+
m_type = type;
18+
m_name = name;
19+
}
20+
21+
FakeConVar::~FakeConVar()
22+
{
23+
}
24+
25+
EConVarType FakeConVar::GetType()
26+
{
27+
return this->m_type;
28+
}
29+
30+
void FakeConVar::SetValue(std::any value)
31+
{
32+
this->m_value = value;
33+
}
34+
35+
std::any FakeConVar::GetValue()
36+
{
37+
return this->m_value;
38+
}
39+
40+
static void convarsCallback(const CCommandContext& context, const CCommand& args)
41+
{
42+
CCommand tokenizedArgs;
43+
tokenizedArgs.Tokenize(args.GetCommandString());
44+
45+
std::string cvar = tokenizedArgs[0];
46+
if (fakeConvars.find(cvar) == fakeConvars.end()) return;
47+
48+
auto convar = fakeConvars.at(cvar);
49+
50+
if (args.ArgC() < 2) {
51+
std::string convarOutput = string_format("%s {VALUE}\n", cvar.c_str());
52+
std::string value = "";
53+
if (convar->GetType() == EConVarType_Int16)
54+
value = std::to_string(std::any_cast<int16_t>(convar->GetValue()));
55+
else if (convar->GetType() == EConVarType_UInt16)
56+
value = std::to_string(std::any_cast<uint16_t>(convar->GetValue()));
57+
else if (convar->GetType() == EConVarType_UInt32)
58+
value = std::to_string(std::any_cast<uint32_t>(convar->GetValue()));
59+
else if (convar->GetType() == EConVarType_Int32)
60+
value = std::to_string(std::any_cast<int32_t>(convar->GetValue()));
61+
else if (convar->GetType() == EConVarType_UInt64)
62+
value = std::to_string(std::any_cast<uint64_t>(convar->GetValue()));
63+
else if (convar->GetType() == EConVarType_Int64)
64+
value = std::to_string(std::any_cast<int64_t>(convar->GetValue()));
65+
else if (convar->GetType() == EConVarType_Bool)
66+
value = (std::any_cast<bool>(convar->GetValue()) ? "true" : "false");
67+
else if (convar->GetType() == EConVarType_Float32)
68+
value = std::to_string(std::any_cast<float>(convar->GetValue()));
69+
else if (convar->GetType() == EConVarType_Float64)
70+
value = std::to_string(std::any_cast<double>(convar->GetValue()));
71+
else if (convar->GetType() == EConVarType_String)
72+
value = std::any_cast<std::string>(convar->GetValue());
73+
else if (convar->GetType() == EConVarType_Color) {
74+
Color col = std::any_cast<Color>(convar->GetValue());
75+
value = string_format("%d,%d,%d,%d", col.r(), col.g(), col.b(), col.a());
76+
}
77+
else if (convar->GetType() == EConVarType_Vector2) {
78+
Vector2D vec = std::any_cast<Vector2D>(convar->GetValue());
79+
value = string_format("%f,%f", vec.x, vec.y);
80+
}
81+
else if (convar->GetType() == EConVarType_Vector3) {
82+
Vector vec = std::any_cast<Vector>(convar->GetValue());
83+
value = string_format("%f,%f,%f", vec.x, vec.y, vec.z);
84+
}
85+
else if (convar->GetType() == EConVarType_Vector4) {
86+
Vector4D vec = std::any_cast<Vector4D>(convar->GetValue());
87+
value = string_format("%f,%f,%f,%f", vec.x, vec.y, vec.z, vec.w);
88+
}
89+
else if (convar->GetType() == EConVarType_Qangle) {
90+
QAngle ang = std::any_cast<QAngle>(convar->GetValue());
91+
value = string_format("%f,%f,%f", ang.x, ang.y, ang.z);
92+
}
93+
else {
94+
value = "(null)";
95+
}
96+
97+
PLUGIN_PRINTF("ConVar", "%s %s\n", cvar.c_str(), value.c_str());
98+
}
99+
else {
100+
if (convar->GetType() == EConVarType_Int16)
101+
convar->SetValue(V_StringToInt16(tokenizedArgs[1], std::any_cast<int16_t>(convar->GetValue())));
102+
else if (convar->GetType() == EConVarType_UInt16)
103+
convar->SetValue(V_StringToUint16(tokenizedArgs[1], std::any_cast<uint16_t>(convar->GetValue())));
104+
else if (convar->GetType() == EConVarType_UInt32)
105+
convar->SetValue(V_StringToUint32(tokenizedArgs[1], std::any_cast<uint32_t>(convar->GetValue())));
106+
else if (convar->GetType() == EConVarType_Int32)
107+
convar->SetValue(V_StringToInt32(tokenizedArgs[1], std::any_cast<int32_t>(convar->GetValue())));
108+
else if (convar->GetType() == EConVarType_UInt64)
109+
convar->SetValue(V_StringToUint64(tokenizedArgs[1], std::any_cast<uint64_t>(convar->GetValue())));
110+
else if (convar->GetType() == EConVarType_Int64)
111+
convar->SetValue(V_StringToInt64(tokenizedArgs[1], std::any_cast<int64_t>(convar->GetValue())));
112+
else if (convar->GetType() == EConVarType_Bool)
113+
convar->SetValue(V_StringToBool(tokenizedArgs[1], std::any_cast<bool>(convar->GetValue())));
114+
else if (convar->GetType() == EConVarType_Float32)
115+
convar->SetValue(V_StringToFloat32(tokenizedArgs[1], std::any_cast<float>(convar->GetValue())));
116+
else if (convar->GetType() == EConVarType_Float64)
117+
convar->SetValue(V_StringToFloat64(tokenizedArgs[1], std::any_cast<double>(convar->GetValue())));
118+
else if (convar->GetType() == EConVarType_String)
119+
convar->SetValue(std::string(tokenizedArgs[1]));
120+
else if (convar->GetType() == EConVarType_Color) {
121+
Color col = std::any_cast<Color>(convar->GetValue());
122+
V_StringToColor(tokenizedArgs[1], col);
123+
convar->SetValue(col);
124+
}
125+
else if (convar->GetType() == EConVarType_Vector2) {
126+
Vector2D vec = std::any_cast<Vector2D>(convar->GetValue());
127+
V_StringToVector2D(tokenizedArgs[1], vec);
128+
convar->SetValue(vec);
129+
}
130+
else if (convar->GetType() == EConVarType_Vector3) {
131+
Vector vec = std::any_cast<Vector>(convar->GetValue());
132+
V_StringToVector(tokenizedArgs[1], vec);
133+
convar->SetValue(vec);
134+
}
135+
else if (convar->GetType() == EConVarType_Vector4) {
136+
Vector4D vec = std::any_cast<Vector4D>(convar->GetValue());
137+
V_StringToVector4D(tokenizedArgs[1], vec);
138+
convar->SetValue(vec);
139+
}
140+
else if (convar->GetType() == EConVarType_Qangle) {
141+
QAngle ang = std::any_cast<QAngle>(convar->GetValue());
142+
V_StringToQAngle(tokenizedArgs[1], ang);
143+
convar->SetValue(ang);
144+
}
145+
}
146+
}

src/convars/shared_convars.cpp

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
#include "convars.h"
2+
3+
ConVar* FetchCVar(std::string cvarname)
4+
{
5+
if (!g_pCVar)
6+
return nullptr;
7+
8+
ConVarHandle cvarHandle = g_pCVar->FindConVar(cvarname.c_str());
9+
if (!cvarHandle.IsValid())
10+
return nullptr;
11+
12+
return g_pCVar->GetConVar(cvarHandle);
13+
}
14+
15+
std::any FetchCVarValue(std::string cvarname)
16+
{
17+
ConVar* cvar = FetchCVar(cvarname);
18+
if (cvar) {
19+
if (cvar->m_eVarType == EConVarType_Int16)
20+
{
21+
int16_t val;
22+
memcpy(&val, &cvar->values, sizeof(val));
23+
return val;
24+
}
25+
else if (cvar->m_eVarType == EConVarType_UInt16)
26+
{
27+
uint16_t val;
28+
memcpy(&val, &cvar->values, sizeof(val));
29+
return val;
30+
}
31+
else if (cvar->m_eVarType == EConVarType_UInt32)
32+
{
33+
uint32_t val;
34+
memcpy(&val, &cvar->values, sizeof(val));
35+
return val;
36+
}
37+
else if (cvar->m_eVarType == EConVarType_Int32)
38+
{
39+
int32_t val;
40+
memcpy(&val, &cvar->values, sizeof(val));
41+
return val;
42+
}
43+
else if (cvar->m_eVarType == EConVarType_UInt64)
44+
{
45+
uint64_t val;
46+
memcpy(&val, &cvar->values, sizeof(val));
47+
return val;
48+
}
49+
else if (cvar->m_eVarType == EConVarType_Int64)
50+
{
51+
int64_t val;
52+
memcpy(&val, &cvar->values, sizeof(val));
53+
return val;
54+
}
55+
else if (cvar->m_eVarType == EConVarType_Bool)
56+
{
57+
bool val;
58+
memcpy(&val, &cvar->values, sizeof(val));
59+
return val;
60+
}
61+
else if (cvar->m_eVarType == EConVarType_Float32)
62+
{
63+
float val;
64+
memcpy(&val, &cvar->values, sizeof(val));
65+
return val;
66+
}
67+
else if (cvar->m_eVarType == EConVarType_Float64)
68+
{
69+
double val;
70+
memcpy(&val, &cvar->values, sizeof(val));
71+
return val;
72+
}
73+
else if (cvar->m_eVarType == EConVarType_String)
74+
{
75+
char* val;
76+
memcpy(&val, &cvar->values, sizeof(val));
77+
return val;
78+
}
79+
else if (cvar->m_eVarType == EConVarType_Color)
80+
{
81+
Color val;
82+
memcpy(&val, &cvar->values, sizeof(val));
83+
return val;
84+
}
85+
else if (cvar->m_eVarType == EConVarType_Vector2)
86+
{
87+
Vector2D val;
88+
memcpy(&val, &cvar->values, sizeof(val));
89+
return val;
90+
}
91+
else if (cvar->m_eVarType == EConVarType_Vector3)
92+
{
93+
Vector val;
94+
memcpy(&val, &cvar->values, sizeof(val));
95+
return val;
96+
}
97+
else if (cvar->m_eVarType == EConVarType_Vector4)
98+
{
99+
Vector4D val;
100+
memcpy(&val, &cvar->values, sizeof(val));
101+
return val;
102+
}
103+
else if (cvar->m_eVarType == EConVarType_Qangle)
104+
{
105+
QAngle val;
106+
memcpy(&val, &cvar->values, sizeof(val));
107+
return val;
108+
}
109+
else {
110+
PRINTF("Unsupported ConVar type: %d. Returning null.\n", (int)cvar->m_eVarType);
111+
return nullptr;
112+
}
113+
}
114+
else if (fakeConvars.find(cvarname) != fakeConvars.end())
115+
return fakeConvars.at(cvarname)->GetValue();
116+
117+
return nullptr;
118+
}
119+
120+
EConVarType FetchCVarType(std::string cvarname)
121+
{
122+
ConVar* cvar = FetchCVar(cvarname);
123+
124+
if (cvar) return cvar->m_eVarType;
125+
else if (fakeConvars.find(cvarname) != fakeConvars.end()) return fakeConvars.at(cvarname)->GetType();
126+
else return EConVarType_Invalid;
127+
}

src/core/commands.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "../entrypoint.h"
77
#include "../common.h"
88
#include "../addons/addons.h"
9+
#include "../convars/convars.h"
910
#include "../utils/utils.h"
1011
#include "../player/PlayerManager.h"
1112
#include "../filters/ConsoleFilter.h"
@@ -112,6 +113,32 @@ void SwiftlyStatus(CPlayerSlot slot, CCommandContext context)
112113
PrintToClientOrConsole(slot, "Status", "end of status\n");
113114
}
114115

116+
void SwiftlyConvarsManager(CPlayerSlot slot, CCommandContext context, int page)
117+
{
118+
PrintToClientOrConsole(slot, "Convars", "There are %d convars created by plugins.\n", fakeConvars.size());
119+
PrintToClientOrConsole(slot, "Convars", "Below will be shown a list of all the convars:\n");
120+
121+
if (page < 1)
122+
page = 1;
123+
else if (static_cast<unsigned int>(page) * 10 > fakeConvars.size())
124+
page = int(ceil(double(fakeConvars.size()) / 10.0));
125+
126+
auto it = fakeConvars.begin();
127+
for (int i = 0; i < (page - 1) * 10; i++)
128+
++it;
129+
130+
for (uint32 i = 0; i < 10; i++)
131+
{
132+
if (it == fakeConvars.end())
133+
break;
134+
PrintToClientOrConsole(slot, "Convars", "%s\n", it->first.c_str());
135+
++it;
136+
}
137+
138+
if (static_cast<unsigned int>(page) * 10 < fakeConvars.size())
139+
PrintToClientOrConsole(slot, "Convars", "To see more please use swiftly cvars %d\n", page + 1);
140+
}
141+
115142
void ShowSwiftlyCommands(CPlayerSlot slot, CCommandContext context, int page)
116143
{
117144
std::map<std::string, Command*> cmds = g_commandsManager->GetCommands();
@@ -151,6 +178,7 @@ void ShowSwiftlyCommandHelp(CPlayerSlot slot, CCommandContext context)
151178
if (slot.Get() == -1)
152179
{
153180
PrintToClientOrConsole(slot, "Commands", " addons - Addons Management Menu\n");
181+
PrintToClientOrConsole(slot, "Commands", " cvars - List all convars created by plugins\n");
154182
PrintToClientOrConsole(slot, "Commands", " confilter - Console Filtering Menu\n");
155183
PrintToClientOrConsole(slot, "Commands", " plugins - Plugin Management Menu\n");
156184
PrintToClientOrConsole(slot, "Commands", " resmon - Resource Monitor Menu\n");
@@ -813,7 +841,7 @@ void SwiftlyCommand(const CCommandContext& context, const CCommand& args)
813841
if (subcmd == "credits")
814842
ShowSwiftlyCredits(slot, context);
815843
else if (subcmd == "cmds")
816-
ShowSwiftlyCommands(slot, context, args[2] == nullptr ? 1 : atoi(args[2]));
844+
ShowSwiftlyCommands(slot, context, V_StringToInt32(args[2], 1));
817845
else if (subcmd == "help")
818846
ShowSwiftlyCommandHelp(slot, context);
819847
else if (subcmd == "version")
@@ -824,6 +852,8 @@ void SwiftlyCommand(const CCommandContext& context, const CCommand& args)
824852
SwiftlyConFilterManager(slot, context, args[2]);
825853
else if (subcmd == "addons")
826854
SwiftlyAddonsManager(slot, context, args[2]);
855+
else if (subcmd == "cvars")
856+
SwiftlyConvarsManager(slot, context, V_StringToInt32(args[2], 1));
827857
else if (subcmd == "translations")
828858
SwiftlyTranslationManager(slot, context, args[2]);
829859
else if (subcmd == "plugins")

0 commit comments

Comments
 (0)