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;
}
|