Witam posiadam taki plugin do triggerów (do tworzenia własnych)
Spoiler
#pragma semicolon 1
#include <sourcemod>
#define PLUGIN_VERSION "2.3.0"
public Plugin:myinfo =
{
name = "Triggers",
author = "theY4Kman",
description = "Advanced commandlist.txt functionality",
version = PLUGIN_VERSION,
url = "http://y4kstudios.com/sourcemod/"
};
enum TriggersFlag
{
trg_None = 0,
trg_Rcon = 1,
trg_Client = 1<<1,
trg_Fake = 1<<2,
trg_Say = 1<<3,
trg_NoDisplayPlayerMessage = 1<<4,
trg_NoVariables = 1<<5,
};
new Handle:g_hTriggers;
new g_iRconFlags;
new Handle:g_hHostname;
new Handle:g_hIp;
public OnPluginStart()
{
// Create our trie
g_hTriggers = CreateTrie();
// Try opening commandlist.txt first, otherwise use commandlist.cfg
ReloadTriggers(0, 0);
RegConsoleCmd("say", Trigger);
RegConsoleCmd("say_team", Trigger);
RegAdminCmd("triggers_reload", ReloadTriggers, ADMFLAG_CONFIG, "Reloads the commandlist", "", FCVAR_PLUGIN);
CreateConVar("triggers_version", PLUGIN_VERSION, "The version of Triggers installed", FCVAR_REPLICATED | FCVAR_PLUGIN | FCVAR_NOTIFY | FCVAR_SPONLY);
new Handle:hRconFlags = CreateConVar("triggers_rcon", "rz");
if(hRconFlags == INVALID_HANDLE)
hRconFlags = FindConVar("triggers_rcon");
g_hHostname = FindConVar("hostname");
g_hIp = FindConVar("ip");
HookConVarChange(hRconFlags, RconFlagsChange);
decl String:sRconFlags[32];
GetConVarString(hRconFlags, sRconFlags, sizeof(sRconFlags));
g_iRconFlags = ReadFlagString(sRconFlags);
}
public OnPluginEnd()
{
CloseHandle(g_hHostname);
CloseHandle(g_hIp);
CloseHandle(g_hTriggers);
}
public RconFlagsChange(Handle:convar, const String:oldValue[], const String:newValue[])
{
g_iRconFlags = ReadFlagString(newValue);
}
// Parses a commandlist file
bool:ParseCommandlist(const String:file[] = "commandlist.txt")
{
decl String:sBuffer[256];
BuildPath( Path_SM, sBuffer, sizeof(sBuffer), "/configs/%s", file );
new Handle:hConf = OpenFile( sBuffer, "r" );
if( hConf == INVALID_HANDLE )
return false;
ClearTrie( g_hTriggers );
decl String:sCmd[128]; // Buffer for command
decl iTemp, iTemp2, iSize; // Integer to store locations of spaces and size of buffer
new TriggersFlag:iFlags, iRconFlags; // Variables to store flags
new bool:iRconFlagsSet;
decl Handle:hDp; // Handle to datapack
while(ReadFileLine(hConf, sBuffer, sizeof(sBuffer))) {
if( (sBuffer[0] == '/' && sBuffer[1] == '/') || (iTemp = StrContains(sBuffer, " ")) == -1 )
continue;
// Gotta add the '+ 1' in to account for the NULL
strcopy(sCmd, iTemp + 1, sBuffer);
strcopy(sBuffer, sizeof(sBuffer), sBuffer[iTemp+1]);
iTemp2 = StrContains( sBuffer, " " );
// Reset RCON flags
iRconFlags = 0;
iRconFlagsSet = false;
iFlags = StringToFlags( sBuffer, iTemp2, iRconFlags, iRconFlagsSet );
// Remove the newline
iSize = strlen(sBuffer);
if(sBuffer[iSize-1] == '\n')
sBuffer[iSize-1] = '\0';
hDp = CreateDataPack();
WritePackCell( hDp, _:iFlags ); // Flags, duh
/* Cell indicating that RCON flags have been set */
WritePackCell( hDp, iRconFlagsSet);
if(iRconFlagsSet)
{
WritePackCell( hDp, _:iRconFlags );
}
WritePackString( hDp, sBuffer[iTemp2+1] ); // Replaced string
SetTrieValue( g_hTriggers, sCmd, hDp );
}
CloseHandle(hConf);
return true;
}
// Command Trigger
public Action:Trigger(client, args)
{
decl String:sCmd[256], String:sReplace[256], Handle:hDp;
new iSindex;
new TriggersFlag:iFlags; // Flags for the trigger
new iRconFlags; // RCON flags for the trigger
// Get the command
if( args >= 2 )
GetCmdArg(1, sCmd, sizeof(sCmd));
else {
GetCmdArgString(sCmd, sizeof(sCmd));
if(StrContains(sCmd, " ") != -1)
sCmd[StrContains(sCmd, " ")] = '\0';
if(sCmd[0] == '"' && sCmd[strlen(sCmd)-1] == '"')
{
iSindex = 1;
sCmd[strlen(sCmd)-1] = '\0';
}
}
StrToLower(sCmd[iSindex]);
if( !(GetTrieValue(g_hTriggers, sCmd[iSindex], hDp) ) || ( hDp == INVALID_HANDLE ) )
return Plugin_Continue;
iSindex = strlen(sCmd[iSindex]);
// Reuse sCmd to hold the arguments
GetCmdArgString(sCmd, sizeof(sCmd));
if( sCmd[0] == '"' && sCmd[strlen(sCmd)-1] == '"' )
{
sCmd[strlen(sCmd)-1] = '\0';
strcopy(sCmd, sizeof(sCmd), sCmd[iSindex+1]);
}
SetPackPosition( hDp, 0 );
iFlags = TriggersFlag:ReadPackCell( hDp );
new iRconFlagsSet = ReadPackCell( hDp );
if(iRconFlagsSet)
{
iRconFlags = ReadPackCell( hDp );
}
else
{
iRconFlags = g_iRconFlags;
}
ReadPackString( hDp, sReplace, sizeof(sReplace) );
// Preprocessing
if( !(iFlags & trg_NoVariables) )
{
decl String:sBuffer[128];
new iTemp = 0, iSize = strlen(sReplace), iSize2 = 0;
/* Variables:
* %i - IP of server
* %s - Steam ID of player
* %h - Hostname of server
* %n - Player's name
*
* They are parsed in that order
*/
// When setting iTemp, we leap ahead to whatever iTemp holds (the last format variable found),
// and the length of the string that replaced the format variable.
for(; iTemp < iSize; iTemp++)
{
if(sReplace[iTemp] != '%')
continue;
if(iTemp && sReplace[iTemp-1] == '\\')
{
strcopy(sReplace[iTemp-1], sizeof(sReplace), sReplace[iTemp]);
continue;
}
switch( sReplace[iTemp+1] )
{
/* Server IP */
case 'i':{
GetConVarString(g_hIp, sBuffer, sizeof(sBuffer));
ReplaceStringEx(sReplace[iTemp], sizeof(sReplace) - iTemp, "%i", sBuffer);
}
/* Player Steam ID */
case 's':{
GetClientAuthString(client, sBuffer, sizeof(sBuffer));
ReplaceStringEx(sReplace[iTemp], sizeof(sReplace) - iTemp, "%s", sBuffer);
}
/* Server hostname */
case 'h':{
GetConVarString(g_hHostname, sBuffer, sizeof(sBuffer));
ReplaceStringEx(sReplace[iTemp], sizeof(sReplace) - iTemp, "%h", sBuffer);
}
/* Player name */
case 'n':{
GetClientName(client, sBuffer, sizeof(sBuffer));
ReplaceStringEx(sReplace[iTemp], sizeof(sReplace) - iTemp, "%n", sBuffer);
}
/* User ID */
case 'u':{
IntToString(GetClientUserId(client), sBuffer, sizeof(sBuffer));
ReplaceStringEx(sReplace[iTemp], sizeof(sReplace) - iTemp, "%u", sBuffer);
}
/* Custom ConVar */
case 'c':{
/* We add 2 to iTemp because this switch is for iTemp+1 */
if(sReplace[iTemp+2] != '{')
{
break;
}
decl iFoundEnd;
if((iFoundEnd = FindCharInString(sReplace[iTemp+2], '}')) == -1
|| iFoundEnd <= 1)
{
break;
}
/* Length of ConVar name + %c{ + } + NULL
* Will be used when replacing stuff in trigger string
*/
new iSizeOfConvar = iFoundEnd+3+1+1;
decl String:sConvar[iSizeOfConvar];
/* If we copy the string to the fourth position, we can insert
* the chars needed to replace without any calls to Format.
*/
strcopy(sConvar[3], iSizeOfConvar-5, sReplace[iTemp+3]);
PrintToChatAll("Convar tag: %s", sConvar[3]);
new Handle:hConvar = FindConVar(sConvar[3]);
if(hConvar == INVALID_HANDLE)
{
break;
}
GetConVarString(hConvar, sBuffer, sizeof(sBuffer));
/* Replacement format! */
sConvar[0] = '%';
sConvar[1] = 'c';
sConvar[2] = '{';
sConvar[iSizeOfConvar-3] = '}';
sConvar[iSizeOfConvar-2] = '\0';
/* The intricacies of replacing strings are far too detailed
* to write my own implementation for this one purpose. It's
* better to use more memory (remember, it's only a few damn bytes)
* than to write it slower and less bug-tested in Pawn.
*/
ReplaceStringEx(sReplace[iTemp], sizeof(sReplace) - iTemp, sConvar, sBuffer);
}
default:
continue;
}
iSize2 = strlen(sBuffer);
iTemp += iSize2-1;
iSize += iSize2;
}
}
// Output
if( (iFlags & trg_Rcon) && ( iRconFlags == 0 || GetUserFlagBits(client) & iRconFlags ) )
{
ServerCommand("%s %s", sReplace, sCmd);
}
if( (iFlags & trg_Client) )
{
ClientCommand(client, "%s %s", sReplace, sCmd);
}
if( (iFlags & trg_Fake) )
{
if( (iFlags & trg_NoDisplayPlayerMessage) )
{
FakeClientCommand(client, "%s %s", sReplace, sCmd);
return Plugin_Handled;
}
FakeClientCommandEx(client, "%s %s", sReplace, sCmd);
}
if( (iFlags & trg_Say) )
{
if( (iFlags & trg_NoDisplayPlayerMessage) )
{
FakeClientCommand(client, "say %s %s", sReplace, sCmd);
return Plugin_Handled;
}
FakeClientCommandEx(client, "say %s %s", sReplace, sCmd);
}
return (iFlags & trg_NoDisplayPlayerMessage) ? Plugin_Handled : Plugin_Continue;
}
public Action:ReloadTriggers(client, args)
{
new bool:success = false;
if(args >= 1)
{
decl String:file[PLATFORM_MAX_PATH];
GetCmdArgString(file, sizeof(file));
success = ParseCommandlist(file);
if(!success)
{
ReplyToCommand(client, "Configuration from '%s' failed", file);
return Plugin_Handled;
}
}
else if( !ParseCommandlist() )
{
success = ParseCommandlist("commandlist.cfg");
}
if(success)
ReplyToCommand(client, "Configuration loading failed");
else
ReplyToCommand(client, "Successfully loaded configuration!");
return Plugin_Handled;
}
TriggersFlag:StringToFlags( const String:sFlags[]="", maxlength=-1, &iRconFlags=0, &iRconFlagsSet=false )
{
new TriggersFlag:iFlags = trg_None;
new iStrSize = (maxlength > -1) ? maxlength : strlen(sFlags);
new i;
for(i = 0; i < iStrSize; ++i)
{
switch(sFlags[i])
{
/* A command to be processed as an Rcon command */
case 'R': iFlags |= trg_Rcon;
/* A command to be processed as a client command */
case 'C': iFlags |= trg_Client;
/* A command to be processed as a fake client command */
case 'F': iFlags |= trg_Fake;
/* A command to be processed as a fake client command, prepended by "say" */
case 'S': iFlags |= trg_Say;
/* No variables will be processed in the command */
case 'v': iFlags |= trg_NoVariables;
/* The message that was said by the player will not be broadcasted */
case 'd': iFlags |= trg_NoDisplayPlayerMessage;
/* Flags necessary to run this trigger */
case 'f':
{
iRconFlagsSet = true;
if(sFlags[i+1] != '{')
{
break;
}
i++;
decl iFoundEnd;
if((iFoundEnd = FindCharInString(sFlags[i], '}')) == -1
|| iFoundEnd <= 1)
{
break;
}
decl String:sRconFlags[iFoundEnd+1];
strcopy(sRconFlags, iFoundEnd, sFlags[i+1]);
iRconFlags |= ReadFlagString(sRconFlags);
i += iFoundEnd;
}
}
}
return iFlags;
}
StrToLower( String:string[] )
{
new size = strlen(string);
for(new i=0; i < size; i++)
string[i] = CharToLower(string[i]);
}
Oraz to jest w folderze config z tego pluginu.
Spoiler
// Triggers configuration file
// by theY4Kman
//
// So, here's the rundown!
// Commands are entered using the format "<command> <flags> <replacement>"
//
// For example:
// die C kill
//
// When the player types "die" into chat, it will run "kill" on them,
// forcing them to suicide.
//
// Here are the core flags (One needs at least one of these flags to do anything):
// R - Rcon command
// To run this, the user must have Rcon or Root access
// C - Client command
// Run on the player
// Note: only commands with FCVAR_SERVER_CAN_EXECUTE will run
// F - Fake client command
// Runs a networked command as if a player had done it
// S - Fake client say command
// Convenience flag that runs a fake client command with "say" in front of it
// So "hi S Hi!" is the same as "hi F say Hi!"
//
// These next flags are optional:
// v - No variables (Disables the parsing of variables)
// "hi S Hi, I'm %n!" will actually display "Hi, I'm %n!"
// d - Do not display the player's message
// f - Begins a block denoting the flags necessary to run the trigger.
// After the letter, a block beginning with '{' and ending with '}' will contain
// admin flags required for this trigger. For example:
// "kick Rf{c} sm_kick"
// This will let any admin with the kick admin flag execute this trigger.
// If this flag is left out, Triggers will use the admin flags in the cvar "triggers_rcon"
// If one wishes to simply have a command without permissions, use a lone 'f' character.
// e.g., "killme Rf sm_slay %n" is the same as "killme Rf{} sm_slay %n"
//
// Yes, there are variables in this, if only a few.
// The variables are in C-type format, meaning they are a percent sign followed by a single character:
// %i - The IP of the server
// %s - The Steam ID of the player whom triggered the command
// %n - The name of the player whom triggered the command
// %u - The user ID of the player whom triggered the command
// %h - The hostname of the server
// %c - Begins a custom ConVar block.
// This allows one to access ConVars besides "ip" and "hostname"
// To utilize it, use the same syntax as for the `f` flag:
// %c{convar_name}
// To display a literal '%', prepend it with a backslash ('\')
//
// The only comment type available is the single line comment.
// To use it, place "//" IN FRONT OF THE LINE. It will not work anywhere else
//
// Note: For chat messages, the longest a message can be is 127 characters long.
// This includes players' names, hostname, etc!
//theY4Kman Rf sm_say He's so cool!
!trig1 C "sm_knife"
!trig2 C "sm_knife"
!trig3 C "sm_knife"
Stworzyłem tam 3 przykładowe trigery do komendy sm_knife. działa dobrze jednak chce zrobić tak aby np tylko gracz bez żadnej flagi miał do nich dostęp a gracz z flagą (przykładowo) "ADMFLAG_CUSTOM1" czyli O nie miał do niej dostępu dało by rade jakoś wyedytować ten kod? kontakt z twórą plugina jest w tej chwili niedostępny.


Dodatki SourceMod



Temat jest zamknięty









