Use better chat spam detection that works for multiple players spamming at once, instead of just one spammer in a row. Also fix issue with PlayerList/PlayerExtList opening the IOstream not being threadsafe.

This commit is contained in:
UnknownShadow200 2016-08-07 23:16:32 +10:00
parent e0c8f84981
commit 1092b1dc1c
5 changed files with 58 additions and 38 deletions

View File

@ -26,7 +26,7 @@ namespace MCGalaxy {
string path; string path;
List<string> players = new List<string>(); List<string> players = new List<string>();
List<string> lines = new List<string>(); List<string> lines = new List<string>();
readonly object locker = new object(); readonly object locker = new object(), saveLocker = new object();
public void Add(string p, string data) { public void Add(string p, string data) {
p = p.ToLower(); p = p.ToLower();
@ -68,16 +68,22 @@ namespace MCGalaxy {
public int Count { get { lock (locker) return players.Count; } } public int Count { get { lock (locker) return players.Count; } }
public void Save(bool console = false) { public void Save() { Save(true); }
using (StreamWriter w = new StreamWriter(path)) { public void Save(bool console) {
lock (locker) { lock (saveLocker) {
foreach (string line in lines) using (StreamWriter w = new StreamWriter(path))
w.WriteLine(line); SaveEntries(w);
}
} }
if (console) Server.s.Log("SAVED: " + path, true); if (console) Server.s.Log("SAVED: " + path, true);
} }
void SaveEntries(StreamWriter w) {
lock (locker) {
foreach (string p in players)
w.WriteLine(p);
}
}
public static PlayerExtList Load(string path) { public static PlayerExtList Load(string path) {
PlayerExtList list = new PlayerExtList(); PlayerExtList list = new PlayerExtList();
list.path = path; list.path = path;

View File

@ -24,7 +24,7 @@ namespace MCGalaxy {
public sealed class PlayerList { public sealed class PlayerList {
string path; string path;
List<string> players = new List<string>(); List<string> players = new List<string>();
readonly object locker = new object(); readonly object locker = new object(), saveLocker = new object();
public PlayerList() { } public PlayerList() { }
public PlayerList(string path) { this.path = path; } public PlayerList(string path) { this.path = path; }
@ -70,15 +70,20 @@ namespace MCGalaxy {
public void Save() { Save(true); } public void Save() { Save(true); }
public void Save(bool console) { public void Save(bool console) {
using (StreamWriter w = new StreamWriter(path)) { lock (saveLocker) {
lock (locker) { using (StreamWriter w = new StreamWriter(path))
foreach (string p in players) SaveEntries(w);
w.WriteLine(p);
}
} }
if (console) Server.s.Log("SAVED: " + path, true); if (console) Server.s.Log("SAVED: " + path, true);
} }
void SaveEntries(StreamWriter w) {
lock (locker) {
foreach (string p in players)
w.WriteLine(p);
}
}
public static PlayerList Load(string file) { public static PlayerList Load(string file) {
if (!Directory.Exists("ranks")) Directory.CreateDirectory("ranks"); if (!Directory.Exists("ranks")) Directory.CreateDirectory("ranks");
PlayerList list = new PlayerList(file); PlayerList list = new PlayerList(file);

View File

@ -260,6 +260,8 @@ namespace MCGalaxy {
Queue<DateTime> spamBlockLog = new Queue<DateTime>(spamBlockCount); Queue<DateTime> spamBlockLog = new Queue<DateTime>(spamBlockCount);
public int consecutivemessages; public int consecutivemessages;
internal readonly object lastMessageLock = new object();
public List<DateTime> LastMessageTimes;
//public static int spamChatCount = 3; //public static int spamChatCount = 3;
//public static int spamChatTimer = 4; //public static int spamChatTimer = 4;
//Queue<DateTime> spamChatLog = new Queue<DateTime>(spamChatCount); //Queue<DateTime> spamChatLog = new Queue<DateTime>(spamChatCount);

View File

@ -473,14 +473,9 @@ try { SendBlockchange(pos1.x, pos1.y, pos1.z, Block.waterstill); } catch { }
}); });
} }
} */ } */
DateTime lastSpamReset;
void HandleChat(byte[] packet) { void HandleChat(byte[] packet) {
try { try {
if (!loggedIn) return; if (!loggedIn) return;
if ((DateTime.UtcNow - lastSpamReset).TotalSeconds > Server.spamcountreset) {
lastSpamReset = DateTime.UtcNow;
consecutivemessages = 0;
}
byte continued = packet[1]; byte continued = packet[1];
string text = GetString(packet, 2); string text = GetString(packet, 2);
@ -660,26 +655,6 @@ return;
catch ( Exception e ) { Server.ErrorLog(e); Player.GlobalMessage("An error occurred: " + e.Message); } catch ( Exception e ) { Server.ErrorLog(e); Player.GlobalMessage("An error occurred: " + e.Message); }
} }
public void CheckForMessageSpam() {
if (!Server.checkspam || ircNick != null) { Player.lastMSG = name; return; }
if (Player.lastMSG == name) {
consecutivemessages++;
} else {
consecutivemessages--;
}
if (consecutivemessages >= Server.spamcounter) {
muteCooldown = Server.mutespamtime;
Command.all.Find("mute").Use(null, name);
Player.GlobalMessage(color + DisplayName + " %Shas been &0muted &efor spamming!");
muteTimer.Elapsed += MuteTimerElapsed;
muteTimer.Start();
return;
}
Player.lastMSG = name;
}
string HandleJoker(string text) { string HandleJoker(string text) {
if (!joker) return text; if (!joker) return text;
if (!File.Exists("text/joker.txt")) { if (!File.Exists("text/joker.txt")) {

View File

@ -624,5 +624,37 @@ namespace MCGalaxy {
MakeSelection(selIndex, selState, selCallback); MakeSelection(selIndex, selState, selCallback);
} }
} }
public void CheckForMessageSpam() {
Player.lastMSG = name;
if (!Server.checkspam || ircNick != null) return;
lock (lastMessageLock) {
if (LastMessageTimes == null)
LastMessageTimes = new List<DateTime>(Server.spamcounter);
DateTime now = DateTime.UtcNow;
int count = LastMessageTimes.Count, inThreshold = 0;
if (count > 0 && count >= Server.spamcounter)
LastMessageTimes.RemoveAt(0);
LastMessageTimes.Add(now);
// Count number of messages that are within the chat spam dection threshold
count = LastMessageTimes.Count;
for (int i = 0; i < count; i++) {
TimeSpan delta = now - LastMessageTimes[i];
if (delta.TotalSeconds <= Server.spamcountreset)
inThreshold++;
}
if (inThreshold < Server.spamcounter) return;
muteCooldown = Server.mutespamtime;
Command.all.Find("mute").Use(null, name);
Player.GlobalMessage(color + DisplayName + " %Shas been &0muted &efor spamming!");
muteTimer.Elapsed += MuteTimerElapsed;
muteTimer.Start();
}
}
} }
} }