From e3d51f963c5316ef5a29f44963e7a276547d27e5 Mon Sep 17 00:00:00 2001 From: tilgep <66904238+tilgep@users.noreply.github.com> Date: Fri, 16 Sep 2022 13:57:09 +0100 Subject: [PATCH] v1.2 - Code optimisations - Added stripper_dump command --- stripper.sp | 300 +++++++++++++++++++++++++--------------------------- 1 file changed, 147 insertions(+), 153 deletions(-) diff --git a/stripper.sp b/stripper.sp index 2e460ca..8fbf551 100644 --- a/stripper.sp +++ b/stripper.sp @@ -1,19 +1,17 @@ -#pragma newdecls required #pragma semicolon 1 +#pragma newdecls required #include #include -#define PLUGIN_VERSION "1.1.0" - public Plugin myinfo = { - name = "Stripper:Source (SP edition)", - author = "tilgep, Stripper:Source by BAILOPAN", - description = "Stripper:Source functionality in a Sourcemod plugin", - version = PLUGIN_VERSION, - url = "" -}; + name = "Stripper:Source (SP edition)", + version = "1.2.0", + description = "Stripper:Source functionality in a Sourcemod plugin", + author = "tilgep, Stripper:Source by BAILOPAN", + url = "https://forums.alliedmods.net/showthread.php?t=339448" +} enum Mode { @@ -34,8 +32,8 @@ enum SubMode enum struct Property { - char key[255]; - char val[255]; + char key[PLATFORM_MAX_PATH]; + char val[PLATFORM_MAX_PATH]; bool regex; } @@ -44,11 +42,11 @@ enum struct Block { Mode mode; SubMode submode; - ArrayList match; // Filter/Modify - ArrayList replace; // Modify - ArrayList del; // Modify - ArrayList insert; // Add/Modify - bool hasClassname; // Ensures that an add block has a classname set + ArrayList match; // Filter/Modify + ArrayList replace; // Modify + ArrayList del; // Modify + ArrayList insert; // Add/Modify + bool hasClassname; // Ensures that an add block has a classname set void Init() { @@ -79,13 +77,66 @@ int section; public void OnPluginStart() { prop.Init(); + + RegAdminCmd("stripper_dump", Command_Dump, ADMFLAG_ROOT, "Writes all of the map entity properties to a file in configs/stripper/dumps/"); +} + +public Action Command_Dump(int client, int args) +{ + char buf1[PLATFORM_MAX_PATH], buf2[PLATFORM_MAX_PATH], path[PLATFORM_MAX_PATH]; + int num = -1; + + GetCurrentMap(buf1, PLATFORM_MAX_PATH); + + BuildPath(Path_SM, buf2, PLATFORM_MAX_PATH, "configs/stripper/dumps"); + + if(!DirExists(buf1)) CreateDirectory(buf1); + + do + { + num++; + // Use same format as original stripper + Format(path, PLATFORM_MAX_PATH, "%s/%s.%04d.cfg", buf2, buf1, num); + } + while(FileExists(path)); + + File fi = OpenFile(path, "w"); + if(fi == null) + { + LogError("Failed to create dump file \"%s\"", path); + return Plugin_Handled; + } + + EntityLumpEntry ent; + + for(int i = 0; i < EntityLump.Length(); i++) + { + ent = EntityLump.Get(i); + + fi.WriteLine("{"); + + for(int j = 0; j < ent.Length; j++) + { + ent.Get(j, buf1, PLATFORM_MAX_PATH, buf2, PLATFORM_MAX_PATH); + fi.WriteLine("\"%s\" \"%s\"", buf1, buf2); + } + + fi.WriteLine("}"); + + delete ent; + } + + delete fi; + + ReplyToCommand(client, "[SM] Dumped entities to '%s'", path); + return Plugin_Handled; } public void OnMapInit(const char[] mapName) { // Parse global filters BuildPath(Path_SM, file, sizeof(file), "configs/stripper/global_filters.cfg"); - + ParseFile(); // Now parse map config @@ -97,14 +148,13 @@ public void OnMapInit(const char[] mapName) /** * Parses a stripper config file - * - * @param path Path to parse from + * + * @param path Path to parse from */ public void ParseFile() { char error[128]; - int line = 0; - int col = 0; + int line, col; section = 0; prop.Clear(); @@ -115,17 +165,17 @@ public void ParseFile() SMCError result = SMC_ParseFile(parser, file, line, col); delete parser; - if (result != SMCError_Okay) + if(result != SMCError_Okay) { SMC_GetErrorString(result, error, sizeof(error)); LogError("%s on line %d, col %d of %s", error, line, col, file); } } -public SMCResult Config_NewSection(SMCParser smc, const char[] name, bool opt_quotes) +public SMCResult Config_NewSection(SMCParser smc, const char[] name, bool opt_quotes) { section++; - if (StrEqual(name, "filter:", false) || StrEqual(name, "remove:", false)) + if(!strcmp(name, "filter:", false) || !strcmp(name, "remove:", false)) { if(prop.mode != Mode_None) { @@ -135,7 +185,7 @@ public SMCResult Config_NewSection(SMCParser smc, const char[] name, bool opt_qu prop.Clear(); prop.mode = Mode_Filter; } - else if (StrEqual(name, "add:", false)) + else if(!strcmp(name, "add:", false)) { if(prop.mode != Mode_None) { @@ -145,7 +195,7 @@ public SMCResult Config_NewSection(SMCParser smc, const char[] name, bool opt_qu prop.Clear(); prop.mode = Mode_Add; } - else if (StrEqual(name, "modify:", false)) + else if(!strcmp(name, "modify:", false)) { if(prop.mode != Mode_None) { @@ -155,24 +205,12 @@ public SMCResult Config_NewSection(SMCParser smc, const char[] name, bool opt_qu prop.Clear(); prop.mode = Mode_Modify; } - else if (prop.mode == Mode_Modify) + else if(prop.mode == Mode_Modify) { - if (StrEqual(name, "match:", false)) - { - prop.submode = SubMode_Match; - } - else if (StrEqual(name, "replace:", false)) - { - prop.submode = SubMode_Replace; - } - if (StrEqual(name, "delete:", false)) - { - prop.submode = SubMode_Delete; - } - if (StrEqual(name, "insert:", false)) - { - prop.submode = SubMode_Insert; - } + if(!strcmp(name, "match:", false)) prop.submode = SubMode_Match; + else if(!strcmp(name, "replace:", false)) prop.submode = SubMode_Replace; + else if(!strcmp(name, "delete:", false)) prop.submode = SubMode_Delete; + else if(!strcmp(name, "insert:", false)) prop.submode = SubMode_Insert; } return SMCParse_Continue; @@ -181,51 +219,29 @@ public SMCResult Config_NewSection(SMCParser smc, const char[] name, bool opt_qu public SMCResult Config_KeyValue(SMCParser smc, const char[] key, const char[] value, bool key_quotes, bool value_quotes) { Property kv; - strcopy(kv.key, 255, key); - strcopy(kv.val, 255, value); + strcopy(kv.key, PLATFORM_MAX_PATH, key); + strcopy(kv.val, PLATFORM_MAX_PATH, value); kv.regex = FormatRegex(kv.val, strlen(value)); - switch (prop.mode) + switch(prop.mode) { - case Mode_None: - { - /* - * we shouldn't be getting key values if we aren't in a section - * ignore them and keep going - */ - return SMCParse_Continue; - } - case Mode_Filter: - { - prop.match.PushArray(kv); - } + case Mode_None: return SMCParse_Continue; + case Mode_Filter: prop.match.PushArray(kv); case Mode_Add: { - // Adding an entity without a classname will crash the server - if(StrEqual(key, "classname", false)) prop.hasClassname = true; + // Adding an entity without a classname will crash the server (shortest classname is "gib") + if(StrEqual(key, "classname", false) && strlen(value) > 2) prop.hasClassname = true; prop.insert.PushArray(kv); } case Mode_Modify: { - switch (prop.submode) + switch(prop.submode) { - case SubMode_Match: - { - prop.match.PushArray(kv); - } - case SubMode_Replace: - { - prop.replace.PushArray(kv); - } - case SubMode_Delete: - { - prop.del.PushArray(kv); - } - case SubMode_Insert: - { - prop.insert.PushArray(kv); - } + case SubMode_Match: prop.match.PushArray(kv); + case SubMode_Replace: prop.replace.PushArray(kv); + case SubMode_Delete: prop.del.PushArray(kv); + case SubMode_Insert: prop.insert.PushArray(kv); } } } @@ -235,29 +251,20 @@ public SMCResult Config_KeyValue(SMCParser smc, const char[] key, const char[] v public SMCResult Config_EndSection(SMCParser smc) { - switch (prop.mode) + switch(prop.mode) { case Mode_Filter: { - if (prop.match.Length > 0) - { - RunRemoveFilter(); - } + if(prop.match.Length > 0) RunRemoveFilter(); prop.mode = Mode_None; } case Mode_Add: { - if (prop.insert.Length > 0) + if(prop.insert.Length > 0) { - if(prop.hasClassname) - { - RunAddFilter(); - } - else - { - LogError("Add block with no classname found at section %d in file '%s'", section, file); - } + if(prop.hasClassname) RunAddFilter(); + else LogError("Add block with no classname found at section %d in file '%s'", section, file); } prop.mode = Mode_None; @@ -265,17 +272,14 @@ public SMCResult Config_EndSection(SMCParser smc) case Mode_Modify: { // Exiting a modify sub-block - if (prop.submode != SubMode_None) + if(prop.submode != SubMode_None) { prop.submode = SubMode_None; return SMCParse_Continue; } - // Must have some match for modify blocks - if (prop.match.Length > 0) - { - RunModifyFilter(); - } + // Must have something to match for modify blocks + if(prop.match.Length > 0) RunModifyFilter(); prop.mode = Mode_None; } @@ -289,33 +293,32 @@ public void RunRemoveFilter() * we know it has at least 1 entry here */ - char val2[255]; - - for (int i = 0; i < EntityLump.Length(); i++) + char val2[PLATFORM_MAX_PATH]; + Property kv; + EntityLumpEntry entry; + for(int i, matches, j, index; i < EntityLump.Length(); i++) { - int matches = 0; - EntityLumpEntry entry = EntityLump.Get(i); + matches = 0; + entry = EntityLump.Get(i); - for(int j = 0; j < prop.match.Length; j++) + for(j = 0; j < prop.match.Length; j++) { - Property kv; prop.match.GetArray(j, kv, sizeof(kv)); - int index = entry.GetNextKey(kv.key, val2, sizeof(val2)); - - while (index != -1) + index = entry.GetNextKey(kv.key, val2, sizeof(val2)); + while(index != -1) { - if (EntPropsMatch(kv.val, val2, kv.regex)) + if(EntPropsMatch(kv.val, val2, kv.regex)) { matches++; break; } - + index = entry.GetNextKey(kv.key, val2, sizeof(val2), index); } } - if (matches == prop.match.Length) + if(matches == prop.match.Length) { EntityLump.Erase(i); i--; @@ -333,11 +336,10 @@ public void RunAddFilter() int index = EntityLump.Append(); EntityLumpEntry entry = EntityLump.Get(index); - for(int i = 0; i < prop.insert.Length; i++) + Property kv; + for(int i; i < prop.insert.Length; i++) { - Property kv; prop.insert.GetArray(i, kv, sizeof(kv)); - entry.Append(kv.key, kv.val); } @@ -351,39 +353,39 @@ public void RunModifyFilter() */ // Nothing to do if these are all empty - if (prop.replace.Length == 0 && prop.del.Length == 0 && prop.insert.Length == 0) + if(prop.replace.Length == 0 && prop.del.Length == 0 && prop.insert.Length == 0) { return; } - char val2[255]; + char val2[PLATFORM_MAX_PATH]; - for (int i = 0; i < EntityLump.Length(); i++) + Property kv; + EntityLumpEntry entry; + for(int i, matches, j, index; i < EntityLump.Length(); i++) { - int matches = 0; - EntityLumpEntry entry = EntityLump.Get(i); + matches = 0; + entry = EntityLump.Get(i); /* Check matches */ - for(int j = 0; j < prop.match.Length; j++) + for(j = 0; j < prop.match.Length; j++) { - Property kv; prop.match.GetArray(j, kv, sizeof(kv)); - int index = entry.GetNextKey(kv.key, val2, sizeof(val2)); - - while (index != -1) + index = entry.GetNextKey(kv.key, val2, sizeof(val2)); + while(index != -1) { - if (EntPropsMatch(kv.val, val2, kv.regex)) + if(EntPropsMatch(kv.val, val2, kv.regex)) { matches++; break; } - + index = entry.GetNextKey(kv.key, val2, sizeof(val2), index); } } - if (matches < prop.match.Length) + if(matches < prop.match.Length) { delete entry; continue; @@ -392,17 +394,16 @@ public void RunModifyFilter() /* This entry matches, perform any changes */ /* First do deletions */ - if (prop.del.Length > 0) + if(prop.del.Length > 0) { - for(int j = 0; j < prop.del.Length; j++) + for(j = 0; j < prop.del.Length; j++) { - Property kv; prop.del.GetArray(j, kv, sizeof(kv)); - int index = entry.GetNextKey(kv.key, val2, sizeof(val2)); - while (index != -1) + index = entry.GetNextKey(kv.key, val2, sizeof(val2)); + while(index != -1) { - if (EntPropsMatch(kv.val, val2, kv.regex)) + if(EntPropsMatch(kv.val, val2, kv.regex)) { entry.Erase(index); index--; @@ -413,15 +414,14 @@ public void RunModifyFilter() } /* do replacements */ - if (prop.replace.Length > 0) + if(prop.replace.Length > 0) { - for(int j = 0; j < prop.replace.Length; j++) + for(j = 0; j < prop.replace.Length; j++) { - Property kv; prop.replace.GetArray(j, kv, sizeof(kv)); - int index = entry.GetNextKey(kv.key, val2, sizeof(val2)); - while (index != -1) + index = entry.GetNextKey(kv.key, val2, sizeof(val2)); + while(index != -1) { entry.Update(index, NULL_STRING, kv.val); index = entry.GetNextKey(kv.key, val2, sizeof(val2), index); @@ -430,13 +430,11 @@ public void RunModifyFilter() } /* do insertions */ - if (prop.insert.Length > 0) + if(prop.insert.Length > 0) { - for(int j = 0; j < prop.insert.Length; j++) + for(j = 0; j < prop.insert.Length; j++) { - Property kv; prop.insert.GetArray(j, kv, sizeof(kv)); - entry.Append(kv.key, kv.val); } } @@ -447,29 +445,25 @@ public void RunModifyFilter() /** * Checks if 2 values match - * - * @param val1 First value - * @param val2 Second value - * @param isRegex True if val1 should be treated as a regex pattern, false if not - * @return True if match, false otherwise + * + * @param val1 First value + * @param val2 Second value + * @param isRegex True if val1 should be treated as a regex pattern, false if not + * @return True if match, false otherwise * */ stock bool EntPropsMatch(const char[] val1, const char[] val2, bool isRegex) { - if (isRegex) - { - return SimpleRegexMatch(val2, val1) > 0; - } - - return StrEqual(val1, val2); + return isRegex ? SimpleRegexMatch(val2, val1) > 0 : !strcmp(val1, val2); } stock bool FormatRegex(char[] pattern, int len) { - if (pattern[0] == '/' && pattern[len-1] == '/') + if(pattern[0] == '/' && pattern[len-1] == '/') { strcopy(pattern, len-1, pattern[1]); return true; } + return false; } \ No newline at end of file