diff options
| -rw-r--r-- | nameblocker.sp | 56 | ||||
| -rw-r--r-- | orderchecker.sp | 29 |
2 files changed, 23 insertions, 62 deletions
diff --git a/nameblocker.sp b/nameblocker.sp index 3d5498c..b9f1e7a 100644 --- a/nameblocker.sp +++ b/nameblocker.sp | |||
| @@ -1,10 +1,14 @@ | |||
| 1 | // Notes: | 1 | // Notes: |
| 2 | // Memory allocated via the "new" keyword IS garbage collected. Handles are not. Close handles when you're done with them | 2 | // Memory allocated via the "new" keyword IS garbage collected. Handles are not. Close handles when you're done with them |
| 3 | // Handles are closed when the plugin is unloaded, so if the lifetime of a handle is the plugin's lifetime, don't worry about closing it | 3 | |
| 4 | // The contents of ArrayList objects are lost on map transition / server restart. Any persistent data should be stored in a | 4 | // Handles are closed when the plugin is unloaded, so if the lifetime of a handle is the plugin's lifetime, don't worry about |
| 5 | // key-value file OR in a database | 5 | // closing it |
| 6 | |||
| 7 | // The contents of ArrayList objects are lost on SERVER RESTART ONLY. Any persistent data should be stored in a key-value file | ||
| 8 | // OR in a database | ||
| 6 | 9 | ||
| 7 | // Basically every string function will add a null terminator, so add `+ 1` to the end of any defined size string definition | 10 | // Basically every string function will add a null terminator, so add `+ 1` to the end of any defined size string definition |
| 11 | |||
| 8 | // It is possible to throw an error with the ThrowError function, but anything that would bother should probably disable the | 12 | // It is possible to throw an error with the ThrowError function, but anything that would bother should probably disable the |
| 9 | // plugin entirely, so SetFailState is better | 13 | // plugin entirely, so SetFailState is better |
| 10 | 14 | ||
| @@ -16,13 +20,18 @@ | |||
| 16 | // The database should contain: | 20 | // The database should contain: |
| 17 | // The string used to compile a regex pattern, sanitized to avoid sql injection attacks | 21 | // The string used to compile a regex pattern, sanitized to avoid sql injection attacks |
| 18 | // The steamid of the admin who added a regex pattern | 22 | // The steamid of the admin who added a regex pattern |
| 19 | // The time a regex pattern was added | 23 | // The date (YYYY-MM-DD) a regex pattern was added |
| 24 | // The time (HH:MM:SS.SSS) a regex pattern was added | ||
| 20 | 25 | ||
| 21 | // In the future, this may change to include regex compilation flags, kick/ban modes, etc. . Depends on how many features | 26 | // In the future, this may change to include regex compilation flags, kick/ban modes, etc. . Depends on how many features |
| 22 | // I want to cram into this given how fundamentally shitty SourcePawn as a language is. I'm not trying to keep track of 17 | 27 | // I want to cram into this given how fundamentally shitty SourcePawn as a language is. I'm not trying to keep track of 17 |
| 23 | // different arrays and make sure that the indicies between them never get out of date. Maybe enum structs will solve my | 28 | // different arrays and make sure that the indicies between them never get out of date. Maybe enum structs will solve my |
| 24 | // concerns, maybe not | 29 | // concerns, maybe not |
| 25 | 30 | ||
| 31 | // Plugins are loaded/unloaded on server start/end, and on map changes IF the plugin has been modified. This means, because I'm | ||
| 32 | // first writing to the database and then updating the lists, there realistically shouldn't be any weird memory problems. | ||
| 33 | // That makes this a whole lot easier | ||
| 34 | |||
| 26 | #pragma newdecls required | 35 | #pragma newdecls required |
| 27 | #pragma semicolon 1 | 36 | #pragma semicolon 1 |
| 28 | 37 | ||
| @@ -54,7 +63,9 @@ enum OperatingMode { | |||
| 54 | 63 | ||
| 55 | ArrayList regexlist; | 64 | ArrayList regexlist; |
| 56 | ArrayList patternlist; | 65 | ArrayList patternlist; |
| 66 | |||
| 57 | Database db; | 67 | Database db; |
| 68 | static const char TABLENAME[] = "163687013_SMNameBlocker"; | ||
| 58 | 69 | ||
| 59 | ConVar gcvarOperMode; static const char OPERMODENAME[] = "nameblock_OperatingMode"; const OperatingMode DEFAULTOPERMODE = OP_KICK; | 70 | ConVar gcvarOperMode; static const char OPERMODENAME[] = "nameblock_OperatingMode"; const OperatingMode DEFAULTOPERMODE = OP_KICK; |
| 60 | ConVar gcvarAdmCmdFlag; static const char ADMCMDFLAGNAME[] = "nameblock_AdminCommandFlag"; const int DEFAULTADMCMDFLAG = ADMFLAG_BAN; | 71 | ConVar gcvarAdmCmdFlag; static const char ADMCMDFLAGNAME[] = "nameblock_AdminCommandFlag"; const int DEFAULTADMCMDFLAG = ADMFLAG_BAN; |
| @@ -125,34 +136,6 @@ public void OnAllPluginsLoaded() { | |||
| 125 | RegAdminCmd("nb_listpatterns", cmdListPatterns, gcvarAdmCmdFlag.IntValue, "List current regex patterns and their indicies"); | 136 | RegAdminCmd("nb_listpatterns", cmdListPatterns, gcvarAdmCmdFlag.IntValue, "List current regex patterns and their indicies"); |
| 126 | } | 137 | } |
| 127 | 138 | ||
| 128 | public void OnConfigsExecuted() { | ||
| 129 | // I'm not sure when this is executed in relation to when OnClientPostAdminCheck is. Sourcemod's API reference says it's ran | ||
| 130 | // once after OnMapStart, but idk if "Map Start" is a sufficient enough game state for players to join | ||
| 131 | |||
| 132 | // Let me illustrate my concern: | ||
| 133 | // Server starts normally, plugin is working | ||
| 134 | // Players join. Nothing weird happens because the plugin loaded everything before a player could have joined | ||
| 135 | // Players/Server initiates a map change WHILE players are still connected. If OnMapStart is when players can start | ||
| 136 | // connecting, and is before OnConfigsExecuted, the following scenarios could happen: | ||
| 137 | |||
| 138 | // 1: OnMapStart fires, players may join | ||
| 139 | // 2: Player joins. This fires OnClientPostAdminCheck | ||
| 140 | // 3: OnClientPostAdminCheck fires checkName, which tries to querry the array lists | ||
| 141 | // 4: ArrayLists are empty or null, causing unexpected behavior | ||
| 142 | // 4.1: ArrayLists are empty, nothing major happens, but a player with an invalid name gets through. Not ideal, but | ||
| 143 | // also not the end of the world | ||
| 144 | // 4.2: ArrayLists are null, trying to use them causes a null pointer dereference, either crashing the plugin &/or | ||
| 145 | // server, or resulting in some other undefined behavior for sourcemod to deal with | ||
| 146 | |||
| 147 | // If OnMapStart doesn't let players join, or rather OnConfigsExecuted fires before players can join, then there's no | ||
| 148 | // problem. Alternatively, I can write something to kick/retry players until OnConfigsExecuted fires | ||
| 149 | |||
| 150 | // As of now, I will simply leave this as a note. No need to go making weird systems if they may not be necessary | ||
| 151 | |||
| 152 | if(loadFromDatabase()) logAndFail(DATABASE_FAIL_MSG); | ||
| 153 | |||
| 154 | } | ||
| 155 | |||
| 156 | public void OnClientPostAdminCheck(int client) { | 139 | public void OnClientPostAdminCheck(int client) { |
| 157 | checkName(client); | 140 | checkName(client); |
| 158 | 141 | ||
| @@ -305,7 +288,12 @@ int loadFromDatabase() { | |||
| 305 | if(db == null) logAndFail("Could not connect to sql database: %s", sqlerr); | 288 | if(db == null) logAndFail("Could not connect to sql database: %s", sqlerr); |
| 306 | 289 | ||
| 307 | // Initialize table if it doesn't exist | 290 | // Initialize table if it doesn't exist |
| 308 | 291 | char sqlcbuf[256 + 1]; | |
| 292 | Format(sqlcbuf, sizeof(sqlcbuf), "CREATE TABLE IF NOT EXISTS \"%s\" (id INTEGER NOT NULL, regexstr TEXT NOT NULL ON CONFLICT IGNORE, steamid64 TEXT NOT NULL ON CONFLICT IGNORE, dateof TEXT DEFAULT CURRENT_DATE, timeof TEXT DEFAULT CURRENT_TIME, PRIMARY KEY (id), UNIQUE (regexstr));", TABLENAME); | ||
| 293 | if(!SQL_FastQuery(db, sqlcbuf)) { | ||
| 294 | SQL_GetError(db, sqlerr, sizeof(sqlerr)); | ||
| 295 | logAndFail("Could not initialize nameblocker table: %s", sqlerr); | ||
| 296 | } | ||
| 309 | 297 | ||
| 310 | // Initialize and populate datatypes | 298 | // Initialize and populate datatypes |
| 311 | regexlist = new ArrayList(ByteCountToCells(HANDLE_SIZE)); | 299 | regexlist = new ArrayList(ByteCountToCells(HANDLE_SIZE)); |
| @@ -315,6 +303,8 @@ int loadFromDatabase() { | |||
| 315 | if(patternlist == null) logAndFail("Could not initialize patternlist ArrayList"); | 303 | if(patternlist == null) logAndFail("Could not initialize patternlist ArrayList"); |
| 316 | 304 | ||
| 317 | // select patterns from nameblock table/database | 305 | // select patterns from nameblock table/database |
| 306 | |||
| 307 | |||
| 318 | // compile each pattern | 308 | // compile each pattern |
| 319 | // insert pattern & regex into respective lists | 309 | // insert pattern & regex into respective lists |
| 320 | 310 | ||
diff --git a/orderchecker.sp b/orderchecker.sp deleted file mode 100644 index a80ac4d..0000000 --- a/orderchecker.sp +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | #pragma newdecls required | ||
| 2 | #pragma semicolon 1 | ||
| 3 | |||
| 4 | #include <sourcemod> | ||
| 5 | |||
| 6 | public Plugin myinfo = { | ||
| 7 | name = "orderchecker", | ||
| 8 | description = "logs a message in chat when a callback is fired", | ||
| 9 | author = "NW/RL", | ||
| 10 | version = "alpha-0.1", | ||
| 11 | url = "" | ||
| 12 | }; | ||
| 13 | |||
| 14 | public void OnAllPluginsLoaded() { | ||
| 15 | PrintToChatAll("OnAllPluginsLoaded"); | ||
| 16 | } | ||
| 17 | |||
| 18 | public void OnConfigsExecuted() { | ||
| 19 | PrintToChatAll("OnConfigsExecuted"); | ||
| 20 | } | ||
| 21 | |||
| 22 | public void OnClientPostAdminCheck(int client) { | ||
| 23 | PrintToChatAll("OnClientPostAdminCheck on %N", client); | ||
| 24 | } | ||
| 25 | |||
| 26 | public void OnClientSettingsChanged(int client) { | ||
| 27 | PrintToChatAll("OnClientSettingsChanged on %N", client); | ||
| 28 | } | ||
| 29 | |||
