summaryrefslogtreecommitdiff
path: root/nameblocker.sp
blob: 8254cd0935e7b40446053b3f0a019d8cf2ec2fbc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#pragma newdecls required

#include <sourcemod>
#include <regex>

public Plugin myinfo = {
    name            = "SM Name Blocker",
    description     = "A simple plugin to stop people with blacklisted names from joining a server",
    author          = "NW/RL",
    version         = "alpha-0.1",
    url             = "git.dabikers.online/smnameblocker"
};

#define HANDLE_SIZE 32
// This exists because you can't sizeof() a Handle, but it IS specified to be a 32bit integer. This should also equal the size of
// any other methodmap or descendant of Handle (like Regex)

enum OperatingMode {
    OP_DISABLED,
    OP_KICK,
    OP_BAN,
    OP_TOOBIG
}
OperatingMode gOperMode = OP_DISABLED;

ArrayList filterlist;
// Note: Contents of ArrayLists are lost on map change / reload. I should store everything in a database,
// then use the database to populate the list whenever it is cleared

public void OnAllPluginsLoaded() {
    filterlist = new ArrayList(ByteCountToCells(HANDLE_SIZE));
}

public void OnClientPostAdminCheck(int client) {
    checkName(client);
}

public void OnClientSettingsChanged(int client) {
    checkName(client);
}



void checkName(int client) {
    if(client <= 0) return;

    char name[64 + 1];
    if(getName(client, name, sizeof(name)) <= 0)
        return; // TODO: better error checking

    RegexError reerr;
    for(int i = 0, m = 0; i < filterlist.Length; i++) {
        m = MatchRegex(filterlist.Get(i), name, reerr);

        if(m == 0) continue;
        if(m < 0) {
            handleFailedRegex(client, reerr, name, sizeof(name));
            return;
        }

        handleNameHit(client);
    }

    return;
}

int getName(int client, char[] buf, int buflen) {
    if(client <= 0 || buflen <= 0) return -1;
    if(IsNullString(buf)) return -1;

    return Format(buf, buflen, "%N", client);
}

int handleNameHit(int client) {
    if(client <= 0) return -1;

    switch(gOperMode) {
        case OP_DISABLED: {return 0;}
        case OP_KICK: {
            KickClient(client, "Failed Name Check");
            // Log kick
            return 0;
        }
        case OP_BAN: {
            // BanClient()
            // TODO: Interop with other ban systems
            // Log ban
        }
        default: {
            LogError("Operating mode in an invalid state");
            return -1;
        }
    }

    LogError("Broke out of switch statement that shouldn't have happened");
    return -1; // Shouldn't get to this point
}

int handleFailedRegex(int client, RegexError reerr, char[] name, int namelen) {
    return 0;
}