Skip to content

Commit c3317b7

Browse files
committed
add missing convar_class.inc
1 parent 93ce3a7 commit c3317b7

1 file changed

Lines changed: 332 additions & 0 deletions

File tree

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,332 @@
1+
/*
2+
MIT License
3+
4+
Copyright (c) 2019-2020 KiD Fearless
5+
Copyright (c) 2021-2022 rtldg
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in all
15+
copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
SOFTWARE.
24+
*/
25+
26+
#if defined _convar_class_included
27+
#endinput
28+
#endif
29+
#define _convar_class_included
30+
31+
// todo: track previous default values
32+
33+
static ArrayList _ConvarList;
34+
35+
enum struct convar_t
36+
{
37+
char name[255];
38+
ConVar cvar;
39+
char description[512];
40+
char defValue[512];
41+
42+
bool GetMin(float& input)
43+
{
44+
return this.cvar.GetBounds(ConVarBound_Lower, input);
45+
}
46+
bool GetMax(float& input)
47+
{
48+
return this.cvar.GetBounds(ConVarBound_Upper, input);
49+
}
50+
void SetMin(bool set, float& input = 0.0)
51+
{
52+
this.cvar.SetBounds(ConVarBound_Lower, set, input);
53+
}
54+
void SetMax(bool set, float& input = 0.0)
55+
{
56+
this.cvar.SetBounds(ConVarBound_Upper, set, input);
57+
}
58+
}
59+
60+
methodmap Convar < ConVar
61+
{
62+
public Convar(const char[] name, const char[] defaultValue, const char[] description = "",
63+
int flags = 0, bool hasMin = false, float min = 0.0, bool hasMax = false, float max = 0.0, convar_t convar = {})
64+
{
65+
if(_ConvarList == null)
66+
{
67+
_ConvarList = new ArrayList(sizeof(convar_t));
68+
}
69+
70+
ConVar cvar = CreateConVar(name, defaultValue, description, flags, hasMin, min, hasMax, max);
71+
72+
convar_t savedValue;
73+
savedValue.cvar = cvar;
74+
strcopy(savedValue.name, sizeof(savedValue.name), name);
75+
strcopy(savedValue.description, 512, description);
76+
strcopy(savedValue.defValue, sizeof(savedValue.defValue), defaultValue);
77+
78+
// Can't set default values :T
79+
savedValue.SetMin(hasMin, min);
80+
savedValue.SetMax(hasMax, max);
81+
82+
// Have to do it this way instead of `convar = savedValue;` because SM 1.12 is a whiny bitch.
83+
convar.name = savedValue.name;
84+
convar.cvar = savedValue.cvar;
85+
convar.description = savedValue.description;
86+
convar.defValue = convar.defValue;
87+
88+
_ConvarList.PushArray(savedValue);
89+
90+
return view_as<Convar>(cvar);
91+
}
92+
93+
public static bool CreateConfig(const char[] fileName = "", const char[] folder = "sourcemod", const bool clearWhenDone = true)
94+
{
95+
char localFolder[PLATFORM_MAX_PATH];
96+
FormatEx(localFolder, PLATFORM_MAX_PATH, "cfg/%s", folder);
97+
if(!DirExists(localFolder))
98+
{
99+
if(!CreateDirectory(localFolder, 755))
100+
{
101+
LogError("Error: Failed to create folder '%s'", localFolder);
102+
}
103+
}
104+
105+
if(_ConvarList == null)
106+
{
107+
LogError("Error: No convars found. did you run .CreateConfig() before adding convars?");
108+
return false;
109+
}
110+
111+
_ConvarList.Sort(Sort_Ascending, Sort_String);
112+
113+
// Check if the file exists.
114+
char local[PLATFORM_MAX_PATH];
115+
if(fileName[0] == 0)
116+
{
117+
char pluginName[PLATFORM_MAX_PATH];
118+
GetPluginFilename(GetMyHandle(), pluginName, PLATFORM_MAX_PATH);
119+
120+
ReplaceString(pluginName, PLATFORM_MAX_PATH, ".smx", "");
121+
ReplaceString(pluginName, PLATFORM_MAX_PATH, "\\", "/");
122+
123+
int start = FindCharInString(pluginName, '/', true);
124+
125+
FormatEx(local, PLATFORM_MAX_PATH, "cfg/%s/plugin.%s.cfg", folder, pluginName[start+1]);
126+
}
127+
else
128+
{
129+
FormatEx(local, sizeof(local), "cfg/%s/%s.cfg", folder, fileName);
130+
}
131+
bool fileExists = FileExists(local);
132+
if (!fileExists)
133+
{
134+
// Create first time file
135+
File file = OpenFile(local, "wt");
136+
if (file != null)
137+
{
138+
fileExists = true;
139+
140+
// get the plugin name
141+
char pluginName[64];
142+
GetPluginFilename(GetMyHandle(), pluginName, 64);
143+
144+
// Write warning
145+
file.WriteLine("// This file was auto-generated by KiD's Convar Class. Only plugin convars are allowed.");
146+
file.WriteLine("// ConVars for plugin \"%s\"\n\n", pluginName);
147+
148+
// Loop through all of our convars
149+
for (int i = 0; i < _ConvarList.Length; ++i)
150+
{
151+
// get the current convar and description
152+
convar_t convar;
153+
_ConvarList.GetArray(i, convar);
154+
155+
// don't write to file if flag is set
156+
if (convar.cvar.Flags & FCVAR_DONTRECORD != 0)
157+
{
158+
continue;
159+
}
160+
161+
// format newlines as comments
162+
ReplaceString(convar.description, 512, "\n", "\n// ");
163+
164+
// write the values and bounds to the file if they exist
165+
file.WriteLine("// %s", convar.description);
166+
167+
file.WriteLine("// -");
168+
file.WriteLine("// Default: \"%s\"", convar.defValue);
169+
float x;
170+
if (convar.GetMin(x))
171+
{
172+
file.WriteLine("// Minimum: \"%02f\"", x);
173+
}
174+
if (convar.GetMax(x))
175+
{
176+
file.WriteLine("// Maximum: \"%02f\"", x);
177+
}
178+
file.WriteLine("%s \"%s\"\n", convar.name, convar.defValue);
179+
}
180+
// end with newline
181+
file.WriteLine("");
182+
delete file;
183+
}
184+
else
185+
{
186+
// writing failed, notify developer.
187+
char pluginName[64];
188+
GetPluginFilename(GetMyHandle(), pluginName, 64);
189+
LogError("Failed to auto generate config for %s at '%s', make sure the directory has write permission.", pluginName, local);
190+
if(clearWhenDone)
191+
{
192+
delete _ConvarList;
193+
}
194+
return false;
195+
}
196+
}
197+
// file already exists, just update the description and defaults
198+
else
199+
{
200+
// open the file for reading
201+
File file = OpenFile(local, "r");
202+
// create a stringmap to hold our current convars.
203+
StringMap convars = new StringMap();
204+
205+
char line[512];
206+
int currentLine = 0;
207+
while(!file.EndOfFile() && file.ReadLine(line, 512))
208+
{
209+
TrimString(line);
210+
211+
++currentLine;
212+
// check if the line contains a valid statement
213+
if(line[0] != '/' && line[0] != '\n' && line[0] != 0)
214+
{
215+
char buffers[2][512];
216+
// only convars should be in here. which should contain convar [space] value.
217+
if(ExplodeString(line, " ", buffers, 2, 512, true) == 2)
218+
{
219+
// remove any trailing whitespace. should be none
220+
TrimString(buffers[0]);
221+
TrimString(buffers[1]);
222+
// remove the quotes from the values
223+
StripQuotes(buffers[0]);
224+
StripQuotes(buffers[1]);
225+
226+
// since convars are only ever strings we store it as strings.
227+
convars.SetString(buffers[0], buffers[1]);
228+
}
229+
else
230+
{
231+
// someone put something in there that shouldn't be. Yell at the dev for doing stupid stuff.
232+
LogError("Error exploding convar string: '%s' on line: %i", line, currentLine);
233+
}
234+
}
235+
}
236+
// close our file
237+
delete file;
238+
// yay duplicate code
239+
// rewrite the cfg with old convars removed and new convars added.
240+
/* Attempt to recreate it */
241+
DeleteFile(local);
242+
file = OpenFile(local, "wt");
243+
if (file != null)
244+
{
245+
fileExists = true;
246+
247+
char pluginName[64];
248+
GetPluginFilename(GetMyHandle(), pluginName, 64);
249+
250+
file.WriteLine("// This file was auto-generated by KiD's Convar Class. Only plugin convars are allowed.");
251+
file.WriteLine("// ConVars for plugin \"%s\"\n\n", pluginName);
252+
253+
float x;
254+
for (int i = 0; i < _ConvarList.Length; ++i)
255+
{
256+
convar_t convar;
257+
_ConvarList.GetArray(i, convar);
258+
259+
if (convar.cvar.Flags & FCVAR_DONTRECORD != 0)
260+
{
261+
continue;
262+
}
263+
264+
ReplaceString(convar.description, 512, "\n", "\n// ");
265+
file.WriteLine("// %s", convar.description);
266+
267+
file.WriteLine("// -");
268+
file.WriteLine("// Default: \"%s\"", convar.defValue);
269+
if (convar.GetMin(x))
270+
{
271+
file.WriteLine("// Minimum: \"%02f\"", x);
272+
}
273+
if (convar.GetMax(x))
274+
{
275+
file.WriteLine("// Maximum: \"%02f\"", x);
276+
}
277+
278+
// only difference is that now we check for a stored value.
279+
char storedValue[512];
280+
if(convars.GetString(convar.name, storedValue, 512))
281+
{
282+
file.WriteLine("%s \"%s\"\n", convar.name, storedValue);
283+
}
284+
else
285+
{
286+
file.WriteLine("%s \"%s\"\n", convar.name, convar.defValue);
287+
}
288+
}
289+
file.WriteLine("");
290+
delete file;
291+
}
292+
else
293+
{
294+
char pluginName[64];
295+
GetPluginFilename(GetMyHandle(), pluginName, 64);
296+
LogError("Failed to auto generate config for %s, make sure the directory has write permission.", pluginName);
297+
298+
if(clearWhenDone)
299+
{
300+
delete _ConvarList;
301+
}
302+
303+
delete convars;
304+
return false;
305+
}
306+
307+
delete convars;
308+
}
309+
if(fileExists)
310+
{
311+
ServerCommand("exec \"%s\"", local[4]);
312+
}
313+
if(clearWhenDone)
314+
{
315+
delete _ConvarList;
316+
}
317+
return true;
318+
}
319+
320+
public static void AutoExecConfig(const char[] fileName = "", const char[] folder = "sourcemod", const bool clearWhenDone = true)
321+
{
322+
if(Convar.CreateConfig(fileName, folder, clearWhenDone))
323+
{
324+
AutoExecConfig(false, fileName, folder);
325+
}
326+
}
327+
328+
public void Close()
329+
{
330+
delete _ConvarList;
331+
}
332+
}

0 commit comments

Comments
 (0)