-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Monera
committed
Aug 27, 2023
0 parents
commit 7417136
Showing
3 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# EZ Load UnLoad Plugins | ||
|
||
Easy load unload plugins by using PluginSys Wrapper | ||
|
||
```sm_ezload (string): Load plugins whose path starts with given substring | ||
sm_ezunload (string): Unload plugins whose path starts with given substring``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
#include <sourcemod> | ||
#include <adt> | ||
#include <regex> | ||
#include "pluginsyswrapper" | ||
|
||
#pragma newdecls required | ||
#pragma semicolon 1 | ||
|
||
public Plugin myinfo = | ||
{ | ||
name = "EZ Load Unload", | ||
author = "Monera", | ||
description = "Plugin that allows easy load/unload plugins by utilizing pluginsys wrapper", | ||
version = "0.0.1", | ||
url = "" | ||
}; | ||
|
||
Regex pluginExtensionRegex; | ||
|
||
public void OnPluginStart() | ||
{ | ||
pluginExtensionRegex = new Regex("\\.smx$"); | ||
|
||
RegServerCmd("sm_ezload", SvrCmd_EZLoad, "Load plugins whose path starts with given substring"); | ||
RegServerCmd("sm_ezunload", SvrCmd_EZUnload, "Unload plugins whose path starts with given substring"); | ||
} | ||
|
||
public Action SvrCmd_EZLoad(int args) | ||
{ | ||
if(args != 1) | ||
{ | ||
PrintToServer("Usage: sm_ezload (string)"); | ||
return Plugin_Handled; | ||
} | ||
|
||
char substring[PLATFORM_MAX_PATH]; | ||
GetCmdArg(1, substring, sizeof(substring)); | ||
|
||
ArrayList list = ListPlugins(substring); | ||
int length = list.Length; | ||
int failure = 0; | ||
for(int i = 0; i < length; i++) | ||
{ | ||
char path[PLATFORM_MAX_PATH]; | ||
char err[256]; | ||
bool wasloaded; | ||
|
||
list.GetString(i, path, sizeof(path)); | ||
Handle plugin = LoadPluginEx(path, err, sizeof(err), wasloaded); | ||
|
||
if(plugin == null) | ||
{ | ||
PrintToServer("[EZ] Plugin %s failed to load: %s", path, err); | ||
failure += 1; | ||
} | ||
else if(wasloaded) | ||
{ | ||
failure += 1; | ||
} | ||
} | ||
|
||
PrintToServer("[EZ] %d plugins are loaded", length - failure); | ||
|
||
return Plugin_Handled; | ||
} | ||
|
||
public Action SvrCmd_EZUnload(int args) | ||
{ | ||
if(args != 1) | ||
{ | ||
PrintToServer("Usage: sm_ezunload (string)"); | ||
return Plugin_Handled; | ||
} | ||
|
||
char substring[PLATFORM_MAX_PATH]; | ||
GetCmdArg(1, substring, sizeof(substring)); | ||
|
||
ArrayList list = ListLoadedPlugins(substring); | ||
int length = list.Length; | ||
int failure = 0; | ||
Handle myself = GetMyHandle(); | ||
for(int i = 0; i < length; i++) | ||
{ | ||
Handle plugin = list.Get(i); | ||
if(plugin == myself) | ||
{ | ||
char path[PLATFORM_MAX_PATH]; | ||
GetPluginFilename(null, path, sizeof(path)); | ||
PrintToServer("[EZ] Plugin %s failed to unload: Unloading itself is not allowed", path); | ||
failure += 1; | ||
continue; | ||
} | ||
UnloadPlugin(list.Get(i)); | ||
} | ||
|
||
PrintToServer("[EZ] %d plugins are unloaded", length - failure); | ||
|
||
return Plugin_Handled; | ||
} | ||
|
||
// BFS | ||
stock ArrayList ListPlugins(const char[] startsWith) | ||
{ | ||
int startsWithLength = strlen(startsWith); | ||
|
||
ArrayList list = new ArrayList(PLATFORM_MAX_PATH / 4); | ||
|
||
char rootPath[PLATFORM_MAX_PATH]; | ||
int rootPos; | ||
rootPos = BuildPath(Path_SM, rootPath, sizeof(rootPath), "plugins"); | ||
|
||
ArrayStack stack = new ArrayStack(PLATFORM_MAX_PATH / 4); | ||
stack.PushString(rootPath); | ||
while(!stack.Empty) | ||
{ | ||
char path[PLATFORM_MAX_PATH]; | ||
int pos; | ||
stack.PopString(path, sizeof(path), pos); | ||
|
||
if(pos + 1 == PLATFORM_MAX_PATH) | ||
{ | ||
continue; | ||
} | ||
path[pos++] = '/'; | ||
|
||
DirectoryListing directoryListing = OpenDirectory(path); | ||
FileType type; | ||
while(directoryListing.GetNext(path[pos], sizeof(path) - pos, type)) | ||
{ | ||
switch(type) | ||
{ | ||
case FileType_File: | ||
{ | ||
pluginExtensionRegex.Match(path[pos]); | ||
if(!pluginExtensionRegex.MatchCount()) | ||
{ | ||
continue; | ||
} | ||
if(strncmp(path[rootPos + 1], startsWith, startsWithLength) != 0) | ||
{ | ||
continue; | ||
} | ||
list.PushString(path[rootPos + 1]); | ||
} | ||
case FileType_Directory: | ||
{ | ||
if(strcmp(path[pos], ".") != 0 && strcmp(path[pos], "..") != 0) | ||
{ | ||
stack.PushString(path); | ||
} | ||
} | ||
} | ||
} | ||
delete directoryListing; | ||
} | ||
delete stack; | ||
|
||
return list; | ||
} | ||
|
||
stock ArrayList ListLoadedPlugins(const char[] startsWith) | ||
{ | ||
int startsWithLength = strlen(startsWith); | ||
|
||
ArrayList list = new ArrayList(); | ||
|
||
Handle it = GetPluginIterator(); | ||
while(MorePlugins(it)) | ||
{ | ||
Handle plugin = ReadPlugin(it); | ||
|
||
char path[PLATFORM_MAX_PATH]; | ||
GetPluginFilename(plugin, path, sizeof(path)); | ||
|
||
if(strncmp(path, startsWith, startsWithLength) != 0) | ||
{ | ||
continue; | ||
} | ||
list.Push(plugin); | ||
} | ||
delete it; | ||
|
||
return list; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#if defined _pluginsyswrapper_included_ | ||
#endinput | ||
#endif | ||
#define _pluginsyswrapper_included_ | ||
|
||
public Extension __ext_pluginsyswrapper = | ||
{ | ||
name = "PluginSys Wrapper", | ||
file = "pluginsyswrapper.ext", | ||
autoload = 1, | ||
required = 1, | ||
}; | ||
|
||
enum HandleError | ||
{ | ||
HandleError_None = 0, /**< No error */ | ||
HandleError_Changed, /**< The handle has been freed and reassigned */ | ||
HandleError_Type, /**< The handle has a different type registered */ | ||
HandleError_Freed, /**< The handle has been freed */ | ||
HandleError_Index, /**< generic internal indexing error */ | ||
HandleError_Access, /**< No access permitted to free this handle */ | ||
HandleError_Limit, /**< The limited number of handles has been reached */ | ||
HandleError_Identity, /**< The identity token was not usable */ | ||
HandleError_Owner, /**< Owners do not match for this operation */ | ||
HandleError_Version, /**< Unrecognized security structure version */ | ||
HandleError_Parameter, /**< An invalid parameter was passed */ | ||
HandleError_NoInherit, /**< This type cannot be inherited */ | ||
}; | ||
|
||
/** | ||
* @brief Attempts to load a plugin. | ||
* | ||
* @param path Path and filename of plugin, relative to plugins folder. | ||
* @param error Buffer to hold any error message. | ||
* @param maxlength Maximum length of error message buffer. | ||
* @param wasloaded Stores if the plugin is already loaded. | ||
* @return A new plugin handle on success, null otherwise. | ||
*/ | ||
native Handle LoadPluginEx(const char[] path, char[] error, int maxlength, bool &wasloaded); | ||
|
||
/** | ||
* @brief Attempts to load a plugin. | ||
* | ||
* @param path Path and filename of plugin, relative to plugins folder. | ||
* @return A new plugin handle on success, null otherwise. | ||
*/ | ||
stock Handle LoadPlugin(const char[] path) | ||
{ | ||
char error[4]; | ||
bool wasloaded; | ||
return LoadPluginEx(path, error, sizeof(error), wasloaded); | ||
} | ||
|
||
/** | ||
* @brief Attempts to unload a plugin. | ||
* | ||
* @param plugin Handle. | ||
* @param err Error, set on handle failure. | ||
* @return True on success, false otherwise. | ||
*/ | ||
native bool UnloadPluginEx(Handle handle, HandleError &err); | ||
|
||
/** | ||
* @brief Attempts to unload a plugin. | ||
* | ||
* @param plugin Handle. | ||
* @return True on success, false otherwise. | ||
*/ | ||
stock bool UnloadPlugin(Handle handle) | ||
{ | ||
HandleError err; | ||
return UnloadPluginEx(handle, err); | ||
} |