bhoptimer/addons/sourcemod/scripting/include/convar_class.inc

316 lines
7.9 KiB
SourcePawn

#if defined _convar_class_included
#endinput
#endif
#define _convar_class_included
// todo: track previous default values
static ArrayList _ConvarList;
enum struct convar_t
{
ConVar cvar;
char description[512];
char defValue[64];
char name[255];
bool GetMin(float& input)
{
return this.cvar.GetBounds(ConVarBound_Lower, input);
}
bool GetMax(float& input)
{
return this.cvar.GetBounds(ConVarBound_Upper, input);
}
void SetMin(bool set, float& input = 0.0)
{
this.cvar.SetBounds(ConVarBound_Lower, set, input);
}
void SetMax(bool set, float& input = 0.0)
{
this.cvar.SetBounds(ConVarBound_Upper, set, input);
}
}
methodmap Convar < ConVar
{
public Convar(const char[] name, const char[] defaultValue, const char[] description = "",
int flags = 0, bool hasMin = false, float min = 0.0, bool hasMax = false, float max = 0.0, convar_t convar = {})
{
if(_ConvarList == null)
{
_ConvarList = new ArrayList(sizeof(convar_t));
}
ConVar cvar = CreateConVar(name, defaultValue, description, flags, hasMin, min, hasMax, max);
convar_t savedValue;
savedValue.cvar = cvar;
strcopy(savedValue.description, 512, description);
strcopy(savedValue.defValue, 64, defaultValue);
// Can't set default values :T
savedValue.SetMin(hasMin, min);
savedValue.SetMax(hasMax, max);
convar = savedValue;
_ConvarList.PushArray(savedValue);
return view_as<Convar>(cvar);
}
public static bool CreateConfig(const char[] fileName = "", const char[] folder = "sourcemod", const bool clearWhenDone = true)
{
char localFolder[PLATFORM_MAX_PATH];
FormatEx(localFolder, PLATFORM_MAX_PATH, "cfg/%s", folder);
if(!DirExists(localFolder))
{
if(!CreateDirectory(localFolder, 755))
{
LogError("Error: Failed to create folder '%s'", localFolder);
}
}
if(_ConvarList == null)
{
LogError("Error: No convars found. did you run .CreateConfig() before adding convars?");
return false;
}
// Check if the file exists.
char local[PLATFORM_MAX_PATH];
if(fileName[0] == 0)
{
char pluginName[PLATFORM_MAX_PATH];
GetPluginFilename(GetMyHandle(), pluginName, PLATFORM_MAX_PATH);
ReplaceString(pluginName, PLATFORM_MAX_PATH, ".smx", "");
ReplaceString(pluginName, PLATFORM_MAX_PATH, "\\", "/");
int start = FindCharInString(pluginName, '/', true);
FormatEx(local, PLATFORM_MAX_PATH, "cfg/%s/plugin.%s.cfg", folder, pluginName[start+1]);
}
else
{
FormatEx(local, sizeof(local), "cfg/%s/%s.cfg", folder, fileName);
}
bool fileExists = FileExists(local);
if (!fileExists)
{
// Create first time file
File file = OpenFile(local, "wt");
if (file != null)
{
fileExists = true;
// get the plugin name
char pluginName[64];
GetPluginFilename(GetMyHandle(), pluginName, 64);
// Write warning
file.WriteLine("// This file was auto-generated by KiD's Convar Class. Only plugin convars are allowed.");
file.WriteLine("// ConVars for plugin \"%s\"\n\n", pluginName);
// Loop through all of our convars
for (int i = 0; i < _ConvarList.Length; ++i)
{
// get the current convar and description
convar_t convar;
_ConvarList.GetArray(i, convar);
// don't write to file if flag is set
if (convar.cvar.Flags & FCVAR_DONTRECORD != 0)
{
continue;
}
// make a copy of our description
char descr[512];
descr = convar.description;
// format newlines as comments
ReplaceString(descr, 512, "\n", "\n// ");
// write the values and bounds to the file if they exist
file.WriteLine("// %s", descr);
// get the convar name and default value to write to file
char name[64];
convar.cvar.GetName(name, 64);
file.WriteLine("// -");
file.WriteLine("// Default: \"%s\"", convar.defValue);
float x;
if (convar.GetMin(x))
{
file.WriteLine("// Minimum: \"%02f\"", x);
}
if (convar.GetMax(x))
{
file.WriteLine("// Maximum: \"%02f\"", x);
}
file.WriteLine("%s \"%s\"\n", name, convar.defValue);
}
// end with newline
file.WriteLine("");
delete file;
}
else
{
// writing failed, notify developer.
char pluginName[64];
GetPluginFilename(GetMyHandle(), pluginName, 64);
LogError("Failed to auto generate config for %s at '%s', make sure the directory has write permission.", pluginName, local);
if(clearWhenDone)
{
delete _ConvarList;
}
return false;
}
}
// file already exists, just update the description and defaults
else
{
// open the file for reading
File file = OpenFile(local, "r");
// create a stringmap to hold our current convars.
StringMap convars = new StringMap();
char line[512];
int currentLine = 0;
while(!file.EndOfFile() && file.ReadLine(line, 512))
{
TrimString(line);
++currentLine;
// check if the line contains a valid statement
if(line[0] != '/' && line[0] != '\n' && line[0] != 0)
{
char buffers[2][512];
// only convars should be in here. which should contain convar [space] value.
if(ExplodeString(line, " ", buffers, 2, 512, true) == 2)
{
// remove any trailing whitespace. should be none
TrimString(buffers[0]);
TrimString(buffers[1]);
// remove the quotes from the values
StripQuotes(buffers[0]);
StripQuotes(buffers[1]);
// since convars are only ever strings we store it as strings.
convars.SetString(buffers[0], buffers[1]);
}
else
{
// someone put something in there that shouldn't be. Yell at the dev for doing stupid stuff.
LogError("Error exploding convar string: '%s' on line: %i", line, currentLine);
}
}
}
// close our file
delete file;
// yay duplicate code
// rewrite the cfg with old convars removed and new convars added.
/* Attempt to recreate it */
DeleteFile(local);
file = OpenFile(local, "wt");
if (file != null)
{
fileExists = true;
char pluginName[64];
GetPluginFilename(GetMyHandle(), pluginName, 64);
file.WriteLine("// This file was auto-generated by KiD's Convar Class. Only plugin convars are allowed.");
file.WriteLine("// ConVars for plugin \"%s\"\n\n", pluginName);
float x;
for (int i = 0; i < _ConvarList.Length; ++i)
{
convar_t convar;
_ConvarList.GetArray(i, convar);
if (convar.cvar.Flags & FCVAR_DONTRECORD != 0)
{
continue;
}
char descr[512];
descr = convar.description;
ReplaceString(descr, 512, "\n", "\n// ");
file.WriteLine("// %s", descr);
char name[64];
convar.cvar.GetName(name, 64);
file.WriteLine("// -");
file.WriteLine("// Default: \"%s\"", convar.defValue);
if (convar.GetMin(x))
{
file.WriteLine("// Minimum: \"%02f\"", x);
}
if (convar.GetMax(x))
{
file.WriteLine("// Maximum: \"%02f\"", x);
}
// only difference is that now we check for a stored value.
char storedValue[512];
if(convars.GetString(name, storedValue, 512))
{
file.WriteLine("%s \"%s\"\n", name, storedValue);
}
else
{
file.WriteLine("%s \"%s\"\n", name, convar.defValue);
}
}
file.WriteLine("");
delete file;
}
else
{
char pluginName[64];
GetPluginFilename(GetMyHandle(), pluginName, 64);
LogError("Failed to auto generate config for %s, make sure the directory has write permission.", pluginName);
if(clearWhenDone)
{
delete _ConvarList;
}
delete convars;
return false;
}
delete convars;
}
if(fileExists)
{
ServerCommand("exec \"%s\"", local[4]);
}
if(clearWhenDone)
{
delete _ConvarList;
}
return true;
}
public static void AutoExecConfig(const char[] fileName = "", const char[] folder = "sourcemod", const bool clearWhenDone = true)
{
if(Convar.CreateConfig(fileName, folder, clearWhenDone))
{
AutoExecConfig(false, fileName, folder);
}
}
public void Close()
{
delete _ConvarList;
}
}