Raised This Month: $32 Target: $400
 8% 

Infractions - The Early Stages


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
QuantumToast
Member
Join Date: May 2017
Location: US
Old 06-13-2017 , 19:06   Infractions - The Early Stages
Reply With Quote #1

Hello to you all. I just started learning how to write a plugin for my server, since I could not seem to find anything that met my needs. It's in its very early stages, and I don't have that much experience with the SourcePawn language, but seeing as it's very similar in structure to C++/Java, I have been not having too much issue. I'm going to post a link to what I have so far, since it's a little lengthy: https://pastebin.com/VkuKxuGW
Here's my mental map for what Infractions is supposed to accomplish:
  • Allow admins to stack "infractions" on players who break rules (and print a warning message to them in chat)
  • Also allow admins to possibly add a "reason" with an infraction, so others know why the player has infractions
  • Upon reaching certain amounts of infractions, a defined action is taken against the player, such as kicking or banning
  • Possibly, allow infractions to slowly decrease over time
  • Hook into certain commands like sm_kick, sm_ban, etc, to increment infractions
  • A sm_infractions.cfg file (name subject to change) that is created and populated with players and their SteamIDs or other sources of identification as they have infractions stacked against them
I have some basic functionality in place, namely that the plugin does hook into the commands I specified in the code, as all it does now is print a message in console that something was "done". I also successfully registered all the cvars I've deemed necessary so far.
However, at this point I seem to be suffering from a combination of writer's block and confusion, and have a few questions that may help guide me:
  1. How do I process arguments for a command like sm_kick or sm_ban?
  2. Branching off the previous question, can I process the target of one command and use them as the target for another?
  3. How do I create a structured file like I described above?
  4. Are there any features you'd like to see implemented other than the aforementioned?
Thanks all for your wonderful help!

(PS, Mods/Admins who noticed that I posted this in the AMX scripting section first by mistake, I apologise )
QuantumToast is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 06-14-2017 , 00:26   Re: Infractions - The Early Stages
Reply With Quote #2

Nice idea!

You can use GetCmdArg in the listener callback just like you would in a regular command, and get the target/process whatever you'd like in there. If you wanna know exactly how target is found from the name, you can check how the stock sourcemod functions do it as an example.

More info: https://sm.alliedmods.net/new-api/co...ommandListener

As for creating the file you can use the file class: https://sm.alliedmods.net/new-api/files/File
Lets you read and write whatever you'd like, for examples I'd take a look at how other plugins do it.
hmmmmm is offline
headline
SourceMod Moderator
Join Date: Mar 2015
Old 06-14-2017 , 01:28   Re: Infractions - The Early Stages
Reply With Quote #3

Quote:
Originally Posted by QuantumToast View Post
How do I process arguments for a command like sm_kick or sm_ban?
Use GetCmdArg, but you can review specifically how sm_kick handles targeting here, but keep in mind it uses a different method from what I show below.

If you don't care to support multiple client targeting like @ct or @t then I'd just use FindTarget like I do here.

Quote:
Originally Posted by QuantumToast View Post
Branching off the previous question, can I process the target of one command and use them as the target for another?
I don't think I understand your question well enough to answer it 100%, but if you're saying what I think you are saying then you'd just pass the client index to the function that does stuff.

Quote:
Originally Posted by QuantumToast View Post
How do I create a structured file like I described above?
Writing everyone's information to a file can be resource expensive. Using an SQL database would be more practical.

Last edited by headline; 06-14-2017 at 01:30.
headline is offline
QuantumToast
Member
Join Date: May 2017
Location: US
Old 06-14-2017 , 03:01   Re: Infractions - The Early Stages
Reply With Quote #4

Quote:
Originally Posted by Headline View Post
I don't think I understand your question well enough to answer it 100%, but if you're saying what I think you are saying then you'd just pass the client index to the function that does stuff.
I think you answered my question, but I'll reword it - just to be safe.
If an admin runs, for example, sm_mute MicSpammer, I'd like to be able to use the "MicSpammer" part of the command as an argument for stacking infractions on them. Whether or not it's by using their username, user ID, SteamID, whatever, just...something unique to them. When I write the file, though, using SteamID would definitely make the most sense, as to prevent punishment dodging via name-changing.
Quote:
Originally Posted by Headline View Post
Writing everyone's information to a file can be resource expensive. Using an SQL database would be more practical.
While I do understand the advantages of SQL, I have several reasons why I would prefer not to use it if I can help it, in this case:
  1. (Of course, this is only if possible), The file will only ever be populated with clients that have infractions stacked against them. In a perfect world, when a client loses all stacks, their entry will be removed. The file will not contain a list of every connected client.
  2. I don't really see my server growing to the point that there could be so many users with infractions that the filesize grows to ridiculous amounts. On top of that, the "cooldown" period I'm considering making a feature will help aid this, preventing players who have effectively left the server from clogging up the file.
  3. I'd like to not have to pay to get the means to have an SQL database host set up on my server - at the moment, I just have the server and a FastDL server set up, nothing more. My knowledge of SQL as a whole is minimal and I've really not had much success with it, either.
However, I do appreciate you both responding, and I'll be sure to post an update or a problem, if I come across one.
QuantumToast is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 06-14-2017 , 03:06   Re: Infractions - The Early Stages
Reply With Quote #5

To get the targetting to work same as sourcemod stock functions I'd just copy paste their targetting code since it all applies to yours. I'd use this as reference instead of kick since it takes multiple arguments, which most of the commands you're hooking will be: https://github.com/alliedmodders/sou...n.sp#L266-L305

Last edited by hmmmmm; 06-14-2017 at 03:10.
hmmmmm is offline
QuantumToast
Member
Join Date: May 2017
Location: US
Old 06-14-2017 , 03:28   Re: Infractions - The Early Stages
Reply With Quote #6

Quote:
Originally Posted by hmmmmm View Post
To get the targetting to work same as sourcemod stock functions I'd just copy paste their targetting code since it all applies to yours.
Currently working on that. Another question, not sure if you know the answer:
If I have my own command, say, sm_infractions_increment, which will force an increment of a set amount to a player, and also a hook to sm_kick, sm_ban, etc. - should I just have both the command hook callback AND the actual "custom" command call the same function, say, Command_IncrementInfraction? To me, it would seem silly to have to have two different functions that do the same thing, just with different inputs(?), but that may be an oversight on my part.
QuantumToast is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 06-14-2017 , 03:44   Re: Infractions - The Early Stages
Reply With Quote #7

Yea you can hook them all to the same listener since they all take target as first argument I think but you'd have to figure out which command it came from and how many infractions to give them accordingly.
hmmmmm is offline
headline
SourceMod Moderator
Join Date: Mar 2015
Old 06-14-2017 , 04:15   Re: Infractions - The Early Stages
Reply With Quote #8

Quote:
Originally Posted by QuantumToast View Post
I think you answered my question, but I'll reword it - just to be safe.
If an admin runs, for example, sm_mute MicSpammer, I'd like to be able to use the "MicSpammer" part of the command as an argument for stacking infractions on them. Whether or not it's by using their username, user ID, SteamID, whatever, just...something unique to them. When I write the file, though, using SteamID would definitely make the most sense, as to prevent punishment dodging via name-changing.
Definitely write SteamIDs as the unique identifer for each client, but when you use FindTarget it'll give you the client index which will allow you to do whatever to them.

Quote:
Originally Posted by QuantumToast View Post
While I do understand the advantages of SQL, I have several reasons why I would prefer not to use it if I can help it, in this case:
  1. (Of course, this is only if possible), The file will only ever be populated with clients that have infractions stacked against them. In a perfect world, when a client loses all stacks, their entry will be removed. The file will not contain a list of every connected client.
  2. I don't really see my server growing to the point that there could be so many users with infractions that the filesize grows to ridiculous amounts. On top of that, the "cooldown" period I'm considering making a feature will help aid this, preventing players who have effectively left the server from clogging up the file.
  3. I'd like to not have to pay to get the means to have an SQL database host set up on my server - at the moment, I just have the server and a FastDL server set up, nothing more. My knowledge of SQL as a whole is minimal and I've really not had much success with it, either.
Well, if you're set on using a file to write these client's information, I'd suggest reading information on OnMapStart and then write to it on OnMapEnd. Maybe something like this will start you off.
  • Create a KeyValues file structured like below
  • OnMapStart use FileToKeyValues to load KeyValues in
  • Cache KeyValues handle globally to allow us to lookup client info
  • OnClientPostAdminCheck search the tree for their steamid, if it exists set some boolean somewhere to true so we know they have some infraction count.

Spoiler


EDIT: Give me a few minutes I'll give you some code

Here's some inspiration
PHP Code:
KeyValues kvDatabase;

void LoadKvFile()
{
    
char path[PLATFORM_MAX_PATH];
    
BuildPath(Path_SMpathsizeof(path), "configs/infractions.txt");
    
    if (!
FileExists(path))
    {
        
SetFailState("Configuration file not found! (%s)"path);
        return;
    }
    
    if(!
FileToKeyValues(kvDatabasepath))
    {
        
SetFailState("Improper structure for configuration file %s!"path);
        return;
    }
}

void SaveKvFile()
{
    
char path[PLATFORM_MAX_PATH];
    
BuildPath(Path_SMpathsizeof(path), "configs/infractions.txt");

    
KeyValuesToFile(kvDatabasepath);
}

// Description: Returns infraction count (-1 if invalid client or not found in kv file)
int GetClientInfractionCount(int client)
{
    if (!
IsClientInGame(client))
    {
        return -
1;
    }
    
    
int count;
    
bool found false;
    
char needle[64];

    
GetClientAuthId(clientAuthId_Steam2needlesizeof(needle));
    
    if(
KvGotoFirstSubKey(kvDatabase)) // If there even is one to start on
    
{
        do
        {
            
char haystack[32];
            
char num[32];
            
            
KvGetSectionName(kvDatabasehaystacksizeof(haystack));    // get name of section (aka steamid)
            
            
if (StrEqual(needlehaystack)) // if steamid = current client's steamid
            
{
                
found true// stop while loop
            
}
    
            
KvGetString(kvDatabase"count"sBuffersizeof(sBuffer));
            
count StringToInt(num);
        }
        while(!
found && KvGotoNextKey(kvDatabasefalse));
        
        
KvGoBack(kvDatabase); // go back
    
}
    else
    {
        return -
1// no first subkey
    
}
    
    return (
found)?count:-1// return count if found, else -1


Last edited by headline; 06-14-2017 at 04:30.
headline is offline
hmmmmm
Great Tester of Whatever
Join Date: Mar 2017
Location: ...
Old 06-14-2017 , 05:01   Re: Infractions - The Early Stages
Reply With Quote #9

EDIT: im big dumbo, nevermind

Last edited by hmmmmm; 06-14-2017 at 05:06.
hmmmmm is offline
Peace-Maker
SourceMod Plugin Approver
Join Date: Aug 2008
Location: Germany
Old 06-14-2017 , 07:11   Re: Infractions - The Early Stages
Reply With Quote #10

You could have a look at this plugin which does most of what you want. I know you do this for learning purposes, but maybe you want to extend that plugin and add the other features you had in mind.
https://forums.alliedmods.net/showthread.php?t=197853
__________________
Peace-Maker is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 21:31.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode