44using System . Linq ;
55
66namespace 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