Skip to content

Commit 8df09d1

Browse files
Modularise IRC command handling
1 parent 2d3fd26 commit 8df09d1

File tree

1 file changed

+167
-146
lines changed

1 file changed

+167
-146
lines changed

fCraft/Network/IRCHandlers.cs

Lines changed: 167 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -4,162 +4,44 @@
44
using System.Linq;
55

66
namespace fCraft {
7+
8+
internal delegate void IRCCommandHandler(string userNick, string cmdArgs);
9+
710
/// <summary> Handlers for commands and PM from IRC. </summary>
811
internal static class IRCHandlers {
912

1013
internal static DateTime lastIrcCommand, lastUrlExpand;
1114
const string Reset = "\u211C", Bold = "\u212C";
1215

13-
static string Formatter(Player p) {
14-
string value = p.Info.Rank.Color + p.Info.Name;
15-
if (p.World != null)
16-
value += " &S[" + p.World.ClassyName + "&S]" + Reset;
17-
return value;
18-
}
19-
2016
public static bool HandleCommand(string nick, string userNick, string rawMessage) {
2117
nick = nick.ToLower();
2218
if (!(rawMessage[0] == '!' || rawMessage[0] == '.' || rawMessage.CaselessStarts(nick)))
2319
return false;
2420

2521
string cmd = rawMessage.ToLower();
2622
bool elapsed = DateTime.UtcNow.Subtract(lastIrcCommand).TotalSeconds > 5;
27-
28-
if (cmd.StartsWith("!players") || cmd.StartsWith(".who") ||
29-
cmd.StartsWith(".players") || cmd.StartsWith(nick + " players")) {
30-
if (!elapsed) return true;
31-
var visiblePlayers = Server.Players.Where(p => !p.Info.IsHidden)
32-
.OrderBy(p => p, PlayerListSorter.Instance).ToArray();
33-
34-
if (visiblePlayers.Any()) {
35-
IRC.SendChannelMessage(Bold + "Players online: " + Reset +
36-
visiblePlayers.JoinToString(Formatter));
37-
lastIrcCommand = DateTime.UtcNow;
38-
} else {
39-
IRC.SendChannelMessage(Bold + "There are no players online.");
40-
lastIrcCommand = DateTime.UtcNow;
41-
}
42-
return true;
43-
} else if (cmd.StartsWith("!st") || cmd.StartsWith(nick + " st")) {
44-
if (!elapsed) return true;
45-
int start = cmd[0] == '!' ? 4 : nick.Length + 4;
46-
if (cmd.Length > start) {
47-
Chat.IRCSendStaff(userNick, rawMessage.Remove(0, start));
48-
lastIrcCommand = DateTime.UtcNow;
49-
}
50-
return true;
51-
} else if (cmd.StartsWith("!seen") || cmd.StartsWith(nick + " seen")) {
52-
if (!elapsed) return true;
53-
int start = cmd[0] == '!' ? 6 : nick.Length + 6;
54-
if (cmd.Length > start) {
55-
string findPlayer = rawMessage.Remove(0, start);
56-
PlayerInfo info = PlayerDB.FindPlayerInfoExact(findPlayer);
57-
if (info != null) {
58-
Player target = info.PlayerObject;
59-
if (target != null) {
60-
IRC.SendChannelMessage("Player " + Bold + "{0}" + Reset + " has been " +
61-
Bold + "&aOnline" + Reset + " for " + Bold + "{1}",
62-
target.Info.Rank.Color + target.Name, target.Info.TimeSinceLastLogin.ToMiniString());
63-
if (target.World != null) {
64-
IRC.SendChannelMessage("They are currently on world " + Bold + "{0}",
65-
target.World.ClassyName);
66-
}
67-
} else {
68-
IRC.SendChannelMessage("Player " + Bold + "{0}" + Reset + " is " + Bold + "&cOffline",
69-
info.ClassyName);
70-
IRC.SendChannelMessage(
71-
"They were last seen " + Bold + "{0}" + Reset + " ago on world " + Bold + "{1}",
72-
info.TimeSinceLastSeen.ToMiniString(),
73-
info.LastWorld);
74-
}
75-
} else {
76-
IRC.SendChannelMessage("No player found with name \"" + Bold + findPlayer + Reset + "\"");
77-
}
78-
} else {
79-
IRC.SendChannelMessage("Please specify a player name");
80-
}
81-
lastIrcCommand = DateTime.UtcNow;
82-
return true;
83-
} else if (cmd.StartsWith("!bd") || cmd.StartsWith(nick + " bd")) {
84-
if (!elapsed) return true;
85-
int start = cmd[0] == '!' ? 4 : nick.Length + 4;
86-
if (cmd.Length > start) {
87-
string findPlayer = rawMessage.Remove(0, start);
88-
PlayerInfo info = PlayerDB.FindPlayerInfoExact(findPlayer);
89-
if (info != null) {
90-
IRC.SendChannelMessage("Player " + Bold + "{0}" + Reset +
91-
" has Built: " + Bold + "{1}" + Reset +
92-
" blocks Deleted: " + Bold + "{2}" + Reset + " blocks{3}",
93-
info.ClassyName, info.BlocksBuilt, info.BlocksDeleted,
94-
(info.Can(Permission.Draw) ? " Drawn: " + Bold + info.BlocksDrawnString + Reset + " blocks." : ""));
95-
} else {
96-
IRC.SendChannelMessage("No player found with name \"" + Bold + findPlayer + Reset + "\"");
97-
}
98-
} else {
99-
IRC.SendChannelMessage("Please specify a player name.");
100-
}
101-
lastIrcCommand = DateTime.UtcNow;
102-
return true;
103-
} else if (cmd.StartsWith("!time") || cmd.StartsWith(nick + " time")) {
104-
if (!elapsed) return true;
105-
int start = cmd[0] == '!' ? 6 : nick.Length + 6;
106-
if (cmd.Length > start) {
107-
string findPlayer = rawMessage.Remove(0, start);
108-
PlayerInfo info = PlayerDB.FindPlayerInfoExact(findPlayer);
109-
if (info != null && info.IsOnline) {
110-
TimeSpan idle = info.PlayerObject.IdleTime;
111-
IRC.SendChannelMessage("Player " + Bold + "{0}" + Reset + " has spent a total of: " + Bold + "{1:F1}" + Reset +
112-
" hours (" + Bold + "{2:F1}" + Reset + " hours this session{3}",
113-
info.ClassyName,
114-
(info.TotalTime + info.TimeSinceLastLogin).TotalHours,
115-
info.TimeSinceLastLogin.TotalHours,
116-
idle > TimeSpan.FromMinutes(1) ? ", been idle for " + Bold +
117-
string.Format("{0:F2}", idle.TotalMinutes) + Reset + " minutes)" : ")");
118-
} else if (info != null) {
119-
IRC.SendChannelMessage("Player " + Bold + "{0}" + Reset + " has spent a total of: "
120-
+ Bold + "{1:F1}" + Reset + " hours",
121-
info.ClassyName,
122-
info.TotalTime.TotalHours);
123-
} else {
124-
IRC.SendChannelMessage("No player found with name \"" + Bold + findPlayer + Reset + "\"");
125-
}
126-
} else {
127-
IRC.SendChannelMessage("Server has been up for: " + Bold + DateTime.UtcNow.Subtract(Server.StartTime).ToMiniString());
128-
}
129-
lastIrcCommand = DateTime.UtcNow;
130-
return true;
131-
} else if (cmd.StartsWith("!clients") || cmd.StartsWith(nick + " clients")) {
132-
if (!elapsed) return true;
133-
134-
var visiblePlayers = Server.Players.Where(p => !p.Info.IsHidden)
135-
.OrderBy(p => p, PlayerListSorter.Instance).ToArray();
13623

137-
Dictionary<string, List<Player>> clients = new Dictionary<string, List<Player>>();
138-
foreach (var p in visiblePlayers) {
139-
string appName = p.ClientName;
140-
if (string.IsNullOrEmpty(appName))
141-
appName = "(unknown)";
142-
143-
List<Player> usingClient;
144-
if (!clients.TryGetValue(appName, out usingClient)) {
145-
usingClient = new List<Player>();
146-
clients[appName] = usingClient;
147-
}
148-
usingClient.Add(p);
149-
}
150-
IRC.SendChannelMessage(Bold + "Players using:");
151-
foreach (var kvp in clients) {
152-
IRC.SendChannelMessage(" " + Bold + "{0}" + Reset + ": {1}",
153-
kvp.Key, kvp.Value.JoinToClassyString());
154-
}
155-
lastIrcCommand = DateTime.UtcNow;
156-
return true;
157-
} else if (cmd == "!commands" || cmd == nick + " commands") {
24+
if (cmd.StartsWith(".players") || cmd.StartsWith(".who")) {
15825
if (!elapsed) return true;
159-
IRC.SendChannelMessage(Bold + "List of commands: " + Reset + "BD, Commands, Clients, Players, Seen, St, Time");
26+
HandlePlayers(userNick, null);
16027
lastIrcCommand = DateTime.UtcNow;
16128
return true;
16229
}
30+
31+
foreach (var kvp in commands) {
32+
string cmdName = kvp.Key;
33+
if (cmd.StartsWith("!" + cmdName) || cmd.StartsWith(nick + " " + kvp.Key)) {
34+
if (!elapsed) return true;
35+
36+
int start = cmd[0] == '!' ? 0 : nick.Length;
37+
start += cmdName.Length + 2; // account for ! or space, then space after command name for args
38+
string args = cmd.Length > start ? cmd.Substring(start) : null;
39+
40+
kvp.Value(userNick, args);
41+
lastIrcCommand = DateTime.UtcNow;
42+
return true;
43+
}
44+
}
16345
return false; //IRC Fantasy commands
16446
}
16547

@@ -175,7 +57,7 @@ public static bool HandlePM(string nick, string userNick, string rawMessage) {
17557
string[] parts = rawMessage.Split(trimChars, 2);
17658
if (parts.Length == 1) {
17759
IRC.SendChannelMessage("Please specify a message to send."); return true;
178-
}
60+
}
17961
string name = parts[0], contents = parts[1];
18062

18163
// first, find ALL players (visible and hidden)
@@ -195,23 +77,23 @@ public static bool HandlePM(string nick, string userNick, string rawMessage) {
19577
if (target.Info.IsHidden) {
19678
// message was sent to a hidden player
19779
IRC.SendChannelMessage("No players found matching \"" +
198-
Bold + name + Reset + "\"");
80+
Bold + name + Reset + "\"");
19981
lastIrcCommand = DateTime.UtcNow;
20082
} else {
20183
// message was sent normally
20284
if (!target.Info.ReadIRC) {
20385
if (!target.Info.IsHidden) {
20486
IRC.SendChannelMessage("&WCannot PM " + Bold +
205-
target.ClassyName + Reset +
206-
"&W: they have IRC ignored.");
87+
target.ClassyName + Reset +
88+
"&W: they have IRC ignored.");
20789
}
20890
} else if (target.IsDeaf) {
20991
IRC.SendChannelMessage("&WCannot PM " + Bold +
210-
target.ClassyName +
211-
Reset + "&W: they are currently deaf.");
92+
target.ClassyName +
93+
Reset + "&W: they are currently deaf.");
21294
} else {
21395
IRC.SendChannelMessage("to " + Bold + target.Name + Reset + ": " +
214-
contents);
96+
contents);
21597
}
21698
lastIrcCommand = DateTime.UtcNow;
21799
}
@@ -222,13 +104,152 @@ public static bool HandlePM(string nick, string userNick, string rawMessage) {
222104
string list = matches.Take(15).JoinToString(", ", p => p.ClassyName);
223105
if (matches.Length > 15) {
224106
IRC.SendChannelMessage("More than " + Bold + matches.Length + Reset +
225-
" players matched: " + list);
107+
" players matched: " + list);
226108
} else {
227109
IRC.SendChannelMessage("More than one player matched: " + list);
228110
}
229111
lastIrcCommand = DateTime.UtcNow;
230112
}
231113
return true;
232114
}
115+
116+
117+
static Dictionary<string, IRCCommandHandler> commands
118+
= new Dictionary<string, IRCCommandHandler>() {
119+
{ "bd", HandleBlockDelete }, { "commands", HandleCommands },
120+
{ "clients", HandleClients }, { "players", HandlePlayers },
121+
{ "seen", HandleSeen }, { "st", HandleStaff },
122+
{ "time", HandleTime },
123+
};
124+
125+
static void HandleBlockDelete(string userNick, string name) {
126+
if (name == null) {
127+
IRC.SendChannelMessage("Please specify a player name");
128+
return;
129+
}
130+
PlayerInfo info = PlayerDB.FindPlayerInfoExact(name);
131+
if (info == null) {
132+
IRC.SendChannelMessage("No player found with name \"" + Bold + name + Reset + "\"");
133+
return;
134+
}
135+
136+
IRC.SendChannelMessage("Player " + Bold + "{0}" + Reset +
137+
" has Built: " + Bold + "{1}" + Reset +
138+
" blocks Deleted: " + Bold + "{2}" + Reset + " blocks{3}",
139+
info.ClassyName, info.BlocksBuilt, info.BlocksDeleted,
140+
(info.Can(Permission.Draw) ? " Drawn: " + Bold + info.BlocksDrawnString + Reset + " blocks." : ""));
141+
}
142+
143+
static void HandleCommands(string userNick, string cmdArgs) {
144+
string cmds = commands.Keys.JoinToString(cmd => cmd.UppercaseFirst());
145+
IRC.SendChannelMessage(Bold + "List of commands: " + Reset + cmds);
146+
}
147+
148+
static void HandleClients(string userNick, string cmdArgs) {
149+
var visiblePlayers = Server.Players.Where(p => !p.Info.IsHidden)
150+
.OrderBy(p => p, PlayerListSorter.Instance).ToArray();
151+
152+
Dictionary<string, List<Player>> clients = new Dictionary<string, List<Player>>();
153+
foreach (var p in visiblePlayers) {
154+
string appName = p.ClientName;
155+
if (string.IsNullOrEmpty(appName))
156+
appName = "(unknown)";
157+
158+
List<Player> usingClient;
159+
if (!clients.TryGetValue(appName, out usingClient)) {
160+
usingClient = new List<Player>();
161+
clients[appName] = usingClient;
162+
}
163+
usingClient.Add(p);
164+
}
165+
166+
IRC.SendChannelMessage(Bold + "Players using:");
167+
foreach (var kvp in clients) {
168+
IRC.SendChannelMessage(" " + Bold + "{0}" + Reset + ": {1}",
169+
kvp.Key, kvp.Value.JoinToClassyString());
170+
}
171+
}
172+
173+
static void HandlePlayers(string userNick, string cmdArgs) {
174+
var visible = Server.Players.Where(p => !p.Info.IsHidden)
175+
.OrderBy(p => p, PlayerListSorter.Instance).ToArray();
176+
177+
if (visible.Any()) {
178+
IRC.SendChannelMessage(Bold + "Players online: " + Reset +
179+
visible.JoinToString(Formatter));
180+
} else {
181+
IRC.SendChannelMessage(Bold + "There are no players online.");
182+
183+
}
184+
}
185+
186+
static string Formatter(Player p) {
187+
string value = p.Info.Rank.Color + p.Info.Name;
188+
if (p.World != null)
189+
value += " &S[" + p.World.ClassyName + "&S]" + Reset;
190+
return value;
191+
}
192+
193+
static void HandleSeen(string userNick, string name) {
194+
if (name == null) {
195+
IRC.SendChannelMessage("Please specify a player name");
196+
return;
197+
}
198+
PlayerInfo info = PlayerDB.FindPlayerInfoExact(name);
199+
if (info == null) {
200+
IRC.SendChannelMessage("No player found with name \"" + Bold + name + Reset + "\"");
201+
return;
202+
}
203+
204+
Player target = info.PlayerObject;
205+
if (target != null) {
206+
IRC.SendChannelMessage("Player " + Bold + "{0}" + Reset + " has been " +
207+
Bold + "&aOnline" + Reset + " for " + Bold + "{1}",
208+
target.Info.Rank.Color + target.Name, target.Info.TimeSinceLastLogin.ToMiniString());
209+
210+
if (target.World != null) {
211+
IRC.SendChannelMessage("They are currently on world " + Bold + "{0}",
212+
target.World.ClassyName);
213+
}
214+
} else {
215+
IRC.SendChannelMessage("Player " + Bold + "{0}" + Reset + " is " + Bold + "&cOffline", info.ClassyName);
216+
IRC.SendChannelMessage("They were last seen " + Bold + "{0}" + Reset + " ago on world " + Bold + "{1}",
217+
info.TimeSinceLastSeen.ToMiniString(), info.LastWorld);
218+
}
219+
}
220+
221+
static void HandleStaff(string userNick, string msg) {
222+
if (msg == null) {
223+
IRC.SendChannelMessage("No message to send to staff.");
224+
} else {
225+
Chat.IRCSendStaff(userNick, msg);
226+
}
227+
}
228+
229+
static void HandleTime(string userNick, string name) {
230+
if (name == null) {
231+
IRC.SendChannelMessage("Server has been up for: " + Bold + DateTime.UtcNow.Subtract(Server.StartTime).ToMiniString());
232+
return;
233+
}
234+
PlayerInfo info = PlayerDB.FindPlayerInfoExact(name);
235+
if (info == null) {
236+
IRC.SendChannelMessage("No player found with name \"" + Bold + name + Reset + "\"");
237+
return;
238+
}
239+
240+
if (info.IsOnline) {
241+
TimeSpan idle = info.PlayerObject.IdleTime;
242+
IRC.SendChannelMessage("Player " + Bold + "{0}" + Reset + " has spent a total of: " + Bold + "{1:F1}" + Reset +
243+
" hours (" + Bold + "{2:F1}" + Reset + " hours this session{3}",
244+
info.ClassyName, (info.TotalTime + info.TimeSinceLastLogin).TotalHours,
245+
info.TimeSinceLastLogin.TotalHours,
246+
idle > TimeSpan.FromMinutes(1) ? ", been idle for " + Bold +
247+
string.Format("{0:F2}", idle.TotalMinutes) + Reset + " minutes)" : ")");
248+
} else {
249+
IRC.SendChannelMessage("Player " + Bold + "{0}" + Reset + " has spent a total of: "
250+
+ Bold + "{1:F1}" + Reset + " hours",
251+
info.ClassyName, info.TotalTime.TotalHours);
252+
}
253+
}
233254
}
234255
}

0 commit comments

Comments
 (0)