PageRenderTime 117ms CodeModel.GetById 61ms app.highlight 38ms RepoModel.GetById 12ms app.codeStats 0ms

/fCraft/Player/PlayerEnumerable.cs

https://github.com/EpicClowny/LegendCraft
C# | 688 lines | 424 code | 90 blank | 174 comment | 187 complexity | 312916d3118171343118f58a805c3e8d MD5 | raw file
  1// Copyright 2009-2012 Matvei Stefarov <me@matvei.org>
  2using System;
  3using System.Collections.Generic;
  4using System.Net;
  5using JetBrains.Annotations;
  6
  7// ReSharper disable LoopCanBeConvertedToQuery
  8namespace fCraft {
  9    /// <summary> Contains a set of utilities that simplify working with sets of players.
 10    /// All the utilities are implemented as extension methods,
 11    /// and it is recommended that you invoke them as extension methods. </summary>
 12    public static class PlayerEnumerable {
 13
 14        #region Rank Filters
 15
 16        /// <summary> Filters a collection of players, leaving only those of the given rank. </summary>
 17        /// <param name="source"> Original collection of players. Will not get modified. </param>
 18        /// <param name="rank"> Desired rank. </param>
 19        /// <returns> Filtered collection of players. </returns>
 20        [NotNull]
 21        public static IEnumerable<Player> Ranked( this IEnumerable<Player> source, Rank rank ) {
 22            if( source == null ) throw new ArgumentNullException( "source" );
 23            if( rank == null ) throw new ArgumentNullException( "rank" );
 24            foreach( Player player in source ) {
 25                if( player.Info.Rank == rank ) {
 26                    yield return player;
 27                }
 28            }
 29        }
 30
 31
 32        /// <summary> Filters a collection of players, leaving only those NOT of the given rank. </summary>
 33        /// <param name="source"> Original collection of players. Will not get modified. </param>
 34        /// <param name="rank"> Undesired rank. </param>
 35        /// <returns> Filtered collection of players. </returns>
 36        [NotNull]
 37        public static IEnumerable<Player> NotRanked( this IEnumerable<Player> source, Rank rank ) {
 38            if( source == null ) throw new ArgumentNullException( "source" );
 39            if( rank == null ) throw new ArgumentNullException( "rank" );
 40            foreach( Player player in source ) {
 41                if( player.Info.Rank != rank ) {
 42                    yield return player;
 43                }
 44            }
 45        }
 46
 47
 48        /// <summary> Filters a collection of players, leaving only those above the given rank. </summary>
 49        /// <param name="source"> Original collection of players. Will not get modified. </param>
 50        /// <param name="minRank"> All ranks above this one will be kept. This and lower ranks will be filtered out. </param>
 51        /// <returns> Filtered collection of players. </returns>
 52        [NotNull]
 53        public static IEnumerable<Player> RankedAbove( this IEnumerable<Player> source, Rank minRank ) {
 54            if( source == null ) throw new ArgumentNullException( "source" );
 55            if( minRank == null ) throw new ArgumentNullException( "minRank" );
 56            foreach( Player player in source ) {
 57                if( player.Info.Rank > minRank ) {
 58                    yield return player;
 59                }
 60            }
 61        }
 62
 63
 64        /// <summary> Filters a collection of players, leaving only those of or above the given rank. </summary>
 65        /// <param name="source"> Original collection of players. Will not get modified. </param>
 66        /// <param name="minRank"> Minimum desired rank. </param>
 67        /// <returns> Filtered collection of players. </returns>
 68        [NotNull]
 69        public static IEnumerable<Player> RankedAtLeast( this IEnumerable<Player> source, Rank minRank ) {
 70            if( source == null ) throw new ArgumentNullException( "source" );
 71            if( minRank == null ) throw new ArgumentNullException( "minRank" );
 72            foreach( Player player in source ) {
 73                if( player.Info.Rank >= minRank ) {
 74                    yield return player;
 75                }
 76            }
 77        }
 78
 79
 80        /// <summary> Filters a collection of players, leaving only those below the given rank. </summary>
 81        /// <param name="source"> Original collection of players. Will not get modified. </param>
 82        /// <param name="maxRank"> All ranks below this one will be kept. This and higher ranks will be filtered out. </param>
 83        /// <returns> Filtered collection of players. </returns>
 84        [NotNull]
 85        public static IEnumerable<Player> RankedBelow( this IEnumerable<Player> source, Rank maxRank ) {
 86            if( source == null ) throw new ArgumentNullException( "source" );
 87            if( maxRank == null ) throw new ArgumentNullException( "maxRank" );
 88            foreach( Player player in source ) {
 89                if( player.Info.Rank < maxRank ) {
 90                    yield return player;
 91                }
 92            }
 93        }
 94
 95
 96        /// <summary> Filters a collection of players, leaving only those of or below the given rank. </summary>
 97        /// <param name="source"> Original collection of players. Will not get modified. </param>
 98        /// <param name="maxRank"> Maximum desired rank. </param>
 99        /// <returns> Filtered collection of players. </returns>
100        [NotNull]
101        public static IEnumerable<Player> RankedAtMost( this IEnumerable<Player> source, Rank maxRank ) {
102            if( source == null ) throw new ArgumentNullException( "source" );
103            if( maxRank == null ) throw new ArgumentNullException( "maxRank" );
104            foreach( Player player in source ) {
105                if( player.Info.Rank <= maxRank ) {
106                    yield return player;
107                }
108            }
109        }
110
111        #endregion
112
113
114        #region Permissions
115
116        /// <summary> Filters a collection of players, leaving only those who have the given permission. </summary>
117        /// <param name="source"> Original collection of players. Will not get modified. </param>
118        /// <param name="permission"> Permission that players are required to have. </param>
119        /// <returns> Filtered collection of players. </returns>
120        [NotNull]
121        public static IEnumerable<Player> Can( [NotNull] this IEnumerable<Player> source, Permission permission ) {
122            if( source == null ) throw new ArgumentNullException( "source" );
123            foreach( Player player in source ) {
124                if( player.Can( permission ) ) {
125                    yield return player;
126                }
127            }
128        }
129
130
131        /// <summary> Filters a collection of players, leaving only those who have the given permission,
132        /// and with permission limits allowing operation on the given rank. </summary>
133        /// <param name="source"> Original collection of players. Will not get modified. </param>
134        /// <param name="permission"> Permission that players are required to have. </param>
135        /// <param name="affectedRank"> Permission limit will be checked against this rank. </param>
136        /// <returns> Filtered collection of players. </returns>
137        [NotNull]
138        public static IEnumerable<Player> Can( [NotNull] this IEnumerable<Player> source, Permission permission, [NotNull] Rank affectedRank ) {
139            if( source == null ) throw new ArgumentNullException( "source" );
140            if( affectedRank == null ) throw new ArgumentNullException( "affectedRank" );
141            foreach( Player player in source ) {
142                if( player.Can( permission, affectedRank ) ) {
143                    yield return player;
144                }
145            }
146        }
147
148
149        /// <summary> Filters a collection of players, leaving only those who do NOT have the given permission. </summary>
150        /// <param name="source"> Original collection of players. Will not get modified. </param>
151        /// <param name="permission"> Permission that players are required to NOT have. </param>
152        /// <returns> Filtered collection of players. </returns>
153        [NotNull]
154        public static IEnumerable<Player> Cant( [NotNull] this IEnumerable<Player> source, Permission permission ) {
155            foreach( Player player in source ) {
156                if( !player.Can( permission ) ) {
157                    yield return player;
158                }
159            }
160        }
161
162
163        /// <summary> Filters a collection of players, leaving only those who do NOT have the given permission,
164        /// or with permission limits NOT allowing operation on the given rank. </summary>
165        /// <param name="source"> Original collection of players. Will not get modified. </param>
166        /// <param name="permission"> Permission that players are required to NOT have. </param>
167        /// <param name="affectedRank"> Permission limit will be checked against this rank. </param>
168        /// <returns> Filtered collection of players. </returns>
169        [NotNull]
170        public static IEnumerable<Player> Cant( [NotNull] this IEnumerable<Player> source, Permission permission, [NotNull] Rank affectedRank ) {
171            if( source == null ) throw new ArgumentNullException( "source" );
172            if( affectedRank == null ) throw new ArgumentNullException( "affectedRank" );
173            foreach( Player player in source ) {
174                if( !player.Can( permission, affectedRank ) ) {
175                    yield return player;
176                }
177            }
178        }
179
180
181        /// <summary> Filters a collection of players, leaving only those who can see the target.
182        /// Does not include the target itself. </summary>
183        /// <param name="source"> Original collection of players. Will not get modified. </param>
184        /// <param name="targetPlayer"> Player whose visibility is being tested. </param>
185        /// <returns> Filtered collection of players. </returns>
186        [NotNull]
187        public static IEnumerable<Player> CanSee( [NotNull] this IEnumerable<Player> source, [NotNull] Player targetPlayer ) {
188            if( source == null ) throw new ArgumentNullException( "source" );
189            if( targetPlayer == null ) throw new ArgumentNullException( "targetPlayer" );
190            foreach( Player player in source ) {
191                if( player != targetPlayer && player.CanSee( targetPlayer ) ) {
192                    yield return player;
193                }
194            }
195        }
196
197
198        /// <summary> Filters a collection of players, leaving only those who can NOT see the target.
199        /// Does not include the target itself. </summary>
200        /// <param name="source"> Original collection of players. Will not get modified. </param>
201        /// <param name="targetPlayer"> Player whose visibility is being tested. </param>
202        /// <returns> Filtered collection of players. </returns>
203        [NotNull]
204        public static IEnumerable<Player> CantSee( [NotNull] this IEnumerable<Player> source, [NotNull] Player targetPlayer ) {
205            if( source == null ) throw new ArgumentNullException( "source" );
206            if( targetPlayer == null ) throw new ArgumentNullException( "targetPlayer" );
207            foreach( Player player in source ) {
208                if( player != targetPlayer && !player.CanSee( targetPlayer ) ) {
209                    yield return player;
210                }
211            }
212        }
213
214
215        /// <summary> Filters a collection of players, leaving only those who can be seen by the given player. </summary>
216        /// <param name="source"> Original collection of players. Will not get modified. </param>
217        /// <param name="observer"> Player whose vision is being tested. </param>
218        /// <returns> Filtered collection of players. </returns>
219        [NotNull]
220        public static IEnumerable<Player> CanBeSeen( [NotNull] this IEnumerable<Player> source, [NotNull] Player observer ) {
221            if( source == null ) throw new ArgumentNullException( "source" );
222            if( observer == null ) throw new ArgumentNullException( "observer" );
223            foreach( Player player in source ) {
224                if( player != observer && observer.CanSee( player ) ) {
225                    yield return player;
226                }
227            }
228        }
229
230
231        /// <summary> Filters a collection of players, leaving only those who can NOT be seen by the given player. </summary>
232        /// <param name="source"> Original collection of players. Will not get modified. </param>
233        /// <param name="observer"> Player whose vision is being tested. </param>
234        /// <returns> Filtered collection of players. </returns>
235        [NotNull]
236        public static IEnumerable<Player> CantBeSeen( [NotNull] this IEnumerable<Player> source, [NotNull] Player observer ) {
237            if( source == null ) throw new ArgumentNullException( "source" );
238            if( observer == null ) throw new ArgumentNullException( "observer" );
239            foreach( Player player in source ) {
240                if( player != observer && !observer.CanSee( player ) ) {
241                    yield return player;
242                }
243            }
244        }
245
246        #endregion
247
248
249        #region Ignore
250
251        /// <summary> Filters a collection of players, leaving only those who are ignoring the given player. </summary>
252        /// <param name="source"> Original collection of players. Will not get modified. </param>
253        /// <param name="player"> Player whose ignore standing is being checked. </param>
254        /// <returns> Filtered collection of players. </returns>
255        [NotNull]
256        public static IEnumerable<Player> Ignoring( [NotNull] this IEnumerable<Player> source, [NotNull] Player player ) {
257            if( source == null ) throw new ArgumentNullException( "source" );
258            if( player == null ) throw new ArgumentNullException( "player" );
259            foreach( Player otherPlayer in source ) {
260                if( otherPlayer.IsIgnoring( player.Info ) ) {
261                    yield return otherPlayer;
262                }
263            }
264        }
265
266
267        /// <summary> Filters a collection of players, leaving only those who are NOT ignoring the given player. </summary>
268        /// <param name="source"> Original collection of players. Will not get modified. </param>
269        /// <param name="player"> Player whose ignore standing is being checked. </param>
270        /// <returns> Filtered collection of players. </returns>
271        [NotNull]
272        public static IEnumerable<Player> NotIgnoring( [NotNull] this IEnumerable<Player> source, [NotNull] Player player ) {
273            if( source == null ) throw new ArgumentNullException( "source" );
274            if( player == null ) throw new ArgumentNullException( "player" );
275            foreach( Player otherPlayer in source ) {
276                if( !otherPlayer.IsIgnoring( player.Info ) ) {
277                    yield return otherPlayer;
278                }
279            }
280        }
281
282
283        /// <summary> Filters a collection of players, leaving only those who are ignoring the given player. </summary>
284        /// <param name="source"> Original collection of players. Will not get modified. </param>
285        /// <param name="playerInfo"> Player whose ignore standing is being checked. </param>
286        /// <returns> Filtered collection of players. </returns>
287        [NotNull]
288        public static IEnumerable<Player> Ignoring( [NotNull] this IEnumerable<Player> source, [NotNull] PlayerInfo playerInfo ) {
289            if( source == null ) throw new ArgumentNullException( "source" );
290            if( playerInfo == null ) throw new ArgumentNullException( "playerInfo" );
291            foreach( Player otherPlayer in source ) {
292                if( otherPlayer.IsIgnoring( playerInfo ) ) {
293                    yield return otherPlayer;
294                }
295            }
296        }
297
298
299        /// <summary> Filters a collection of players, leaving only those who are NOT ignoring the given player. </summary>
300        /// <param name="source"> Original collection of players. Will not get modified. </param>
301        /// <param name="playerInfo"> Player whose ignore standing is being checked. </param>
302        /// <returns> Filtered collection of players. </returns>
303        [NotNull]
304        public static IEnumerable<Player> NotIgnoring( [NotNull] this IEnumerable<Player> source, [NotNull] PlayerInfo playerInfo ) {
305            if( source == null ) throw new ArgumentNullException( "source" );
306            if( playerInfo == null ) throw new ArgumentNullException( "playerInfo" );
307            foreach( Player otherPlayer in source ) {
308                if( !otherPlayer.IsIgnoring( playerInfo ) ) {
309                    yield return otherPlayer;
310                }
311            }
312        }
313
314
315        /// <summary> Filters a collection of players, leaving only those who are ignored by the given player. </summary>
316        /// <param name="source"> Original collection of players. Will not get modified. </param>
317        /// <param name="ignorer"> Player whose disposition is being checked. </param>
318        /// <returns> Filtered collection of players. </returns>
319        [NotNull]
320        public static IEnumerable<Player> IgnoredBy( [NotNull] this IEnumerable<Player> source, [NotNull] Player ignorer ) {
321            if( source == null ) throw new ArgumentNullException( "source" );
322            if( ignorer == null ) throw new ArgumentNullException( "ignorer" );
323            foreach( Player otherPlayer in source ) {
324                if( ignorer.IsIgnoring( otherPlayer.Info ) ) {
325                    yield return otherPlayer;
326                }
327            }
328        }
329
330
331        /// <summary> Filters a collection of players, leaving only those who are NOT ignored by the given player. </summary>
332        /// <param name="source"> Original collection of players. Will not get modified. </param>
333        /// <param name="ignorer"> Player whose disposition is being checked. </param>
334        /// <returns> Filtered collection of players. </returns>
335        [NotNull]
336        public static IEnumerable<Player> NotIgnoredBy( [NotNull] this IEnumerable<Player> source, [NotNull] Player ignorer ) {
337            if( source == null ) throw new ArgumentNullException( "source" );
338            if( ignorer == null ) throw new ArgumentNullException( "ignorer" );
339            foreach( Player otherPlayer in source ) {
340                if( !ignorer.IsIgnoring( otherPlayer.Info ) ) {
341                    yield return otherPlayer;
342                }
343            }
344        }
345
346        #endregion
347
348
349        #region Worlds
350
351        /// <summary> Filters a collection of players, leaving only those who are currently located on the given world. </summary>
352        /// <param name="source"> Original collection of players. Will not get modified. </param>
353        /// <param name="world"> World that players are desired to be on. </param>
354        /// <returns> Filtered collection of players. </returns>
355        [NotNull]
356        public static IEnumerable<Player> InWorld( [NotNull] this IEnumerable<Player> source, [NotNull] World world ) {
357            if( source == null ) throw new ArgumentNullException( "source" );
358            if( world == null ) throw new ArgumentNullException( "world" );
359            foreach( Player player in source ) {
360                if( player.World == world ) {
361                    yield return player;
362                }
363            }
364        }
365
366
367        /// <summary> Filters a collection of players, leaving only those who are currently NOT located on the given world. </summary>
368        /// <param name="source"> Original collection of players. Will not get modified. </param>
369        /// <param name="world"> World that players are desired to NOT be on. </param>
370        /// <returns> Filtered collection of players. </returns>
371        [NotNull]
372        public static IEnumerable<Player> NotInWorld( [NotNull] this IEnumerable<Player> source, [NotNull] World world ) {
373            if( source == null ) throw new ArgumentNullException( "source" );
374            if( world == null ) throw new ArgumentNullException( "world" );
375            foreach( Player player in source ) {
376                if( player.World != world ) {
377                    yield return player;
378                }
379            }
380        }
381
382        #endregion
383
384
385        #region Personal Inclusion / Exclusion
386
387        /// <summary> Adds players to the given set.
388        /// ]If the given sequence of players already contains player, no duplicate is added.
389        /// Precisely speaking, produces the set union of a given collection of players and a given player. </summary>
390        /// <param name="source"> Original set of players. Will not get modified. </param>
391        /// <param name="includedPlayer"> Player to add to the set. </param>
392        /// <returns> A set that contains all players in the input sequence, plus the given player. </returns>
393        [NotNull]
394        public static IEnumerable<Player> Union( [NotNull] this IEnumerable<Player> source, [NotNull] Player includedPlayer ) {
395            bool found = false;
396            foreach( Player player in source ) {
397                yield return player;
398                if( player == includedPlayer ) {
399                    found = true;
400                }
401            }
402            if( !found ) {
403                yield return includedPlayer;
404            }
405        }
406
407
408        /// <summary> Removes player from the given set.
409        /// Precisely speaking, produces the set difference between the given collection of players and a given player. </summary>
410        /// <param name="source"> Original set of players. Will not get modified. </param>
411        /// <param name="excludedPlayer"> Player to remove from the set. </param>
412        /// <returns> A set that contains all players in the input sequence, minus the given player. </returns>
413        [NotNull]
414        public static IEnumerable<Player> Except( [NotNull] this IEnumerable<Player> source, [CanBeNull] Player excludedPlayer ) {
415            foreach( Player player in source ) {
416                if( player != excludedPlayer ) {
417                    yield return player;
418                }
419            }
420        }
421
422        #endregion
423
424
425        #region IPAddress
426
427        /// <summary> Filters a collection of players, leaving only those connected from a given IP. </summary>
428        /// <param name="source"> Original collection of players. Will not get modified. </param>
429        /// <param name="ip"> IP that we are including. </param>
430        /// <returns> Filtered collection of players. </returns>
431        [NotNull]
432        public static IEnumerable<Player> FromIP( [NotNull] this IEnumerable<Player> source, [NotNull] IPAddress ip ) {
433            if( source == null ) throw new ArgumentNullException( "source" );
434            if( ip == null ) throw new ArgumentNullException( "ip" );
435            foreach( Player player in source ) {
436                if( ip.Equals( player.IP ) ) {
437                    yield return player;
438                }
439            }
440        }
441
442
443        /// <summary> Filters a collection of players, leaving only those NOT connected from a given IP. </summary>
444        /// <param name="source"> Original collection of players. Will not get modified. </param>
445        /// <param name="ip"> IP that we are excluding. </param>
446        /// <returns> Filtered collection of players. </returns>
447        [NotNull]
448        public static IEnumerable<Player> NotFromIP( [NotNull] this IEnumerable<Player> source, [NotNull] IPAddress ip ) {
449            if( source == null ) throw new ArgumentNullException( "source" );
450            if( ip == null ) throw new ArgumentNullException( "ip" );
451            foreach( Player player in source ) {
452                if( !ip.Equals( player.IP ) ) {
453                    yield return player;
454                }
455            }
456        }
457
458        #endregion
459
460
461        #region Messaging
462
463        /// <summary> Broadcasts a message. </summary>
464        /// <param name="source"> List of players who will receive the message. </param>
465        /// <param name="message"> String/message to send. </param>
466        /// <returns> Number of players who received the message. </returns>
467        public static int Message( [NotNull] this IEnumerable<Player> source,
468                                   [NotNull] string message ) {
469            if( source == null ) throw new ArgumentNullException( "source" );
470            if( message == null ) throw new ArgumentNullException( "message" );
471            int i = 0;
472            foreach( Packet packet in LineWrapper.Wrap( message ) ) {
473                foreach( Player player in source ) {
474                    player.Send( packet );
475                    i++;
476                }
477            }
478            return i;
479        }
480
481        /// <summary> Broadcasts a message. </summary>
482        /// <param name="source"> List of players who will receive the message. </param>
483        /// <param name="except"> Player to exclude from the recepient list. </param>
484        /// <param name="message"> String/message to send. </param>
485        /// <returns> Number of players who received the message. </returns>
486        public static int Message( [NotNull] this IEnumerable<Player> source,
487                                   [CanBeNull] Player except,
488                                   [NotNull] string message ) {
489            if( source == null ) throw new ArgumentNullException( "source" );
490            if( message == null ) throw new ArgumentNullException( "message" );
491            int i = 0;
492            foreach( Packet packet in LineWrapper.Wrap( message ) ) {
493                foreach( Player player in source ) {
494                    if( player == except ) continue;
495                    player.Send( packet );
496                    i++;
497                }
498            }
499            return i;
500        }
501
502        /// <summary> Formats and broadcasts a message. </summary>
503        /// <param name="source"> List of players who will receive the message. </param>
504        /// <param name="except"> Player to exclude from the recepient list. </param>
505        /// <param name="message"> String/message to send. </param>
506        /// <param name="formatArgs"> Format parameters. Same semantics as String.Format </param>
507        /// <returns> Number of players who received the message. </returns>
508        [StringFormatMethod( "message" )]
509        public static int Message( [NotNull] this IEnumerable<Player> source,
510                                   [CanBeNull] Player except,
511                                   [NotNull] string message,
512                                   [NotNull] params object[] formatArgs ) {
513            if( source == null ) throw new ArgumentNullException( "source" );
514            if( message == null ) throw new ArgumentNullException( "message" );
515            if( formatArgs == null ) throw new ArgumentNullException( "formatArgs" );
516            int i = 0;
517            foreach( Packet packet in LineWrapper.Wrap( String.Format( message, formatArgs ) ) ) {
518                foreach( Player player in source ) {
519                    if( player == except ) continue;
520                    player.Send( packet );
521                    i++;
522                }
523            }
524            return i;
525        }
526
527
528        /// <summary> Formats and broadcasts a message. </summary>
529        /// <param name="source"> List of players who will receive the message. </param>
530        /// <param name="message"> String/message to send. </param>
531        /// <param name="formatArgs"> Format parameters. Same semantics as String.Format </param>
532        /// <returns> Number of players who received the message. </returns>
533        [StringFormatMethod( "message" )]
534        public static int Message( [NotNull] this IEnumerable<Player> source,
535                                   [NotNull] string message,
536                                   [NotNull] params object[] formatArgs ) {
537            if( source == null ) throw new ArgumentNullException( "source" );
538            if( message == null ) throw new ArgumentNullException( "message" );
539            if( formatArgs == null ) throw new ArgumentNullException( "formatArgs" );
540            int i = 0;
541            foreach( Packet packet in LineWrapper.Wrap( String.Format( message, formatArgs ) ) ) {
542                foreach( Player player in source ) {
543                    player.Send( packet );
544                    i++;
545                }
546            }
547            return i;
548        }
549
550
551        /// <summary> Broadcasts a message, prefixing wrapped lines. </summary>
552        /// <param name="source"> List of players who will receive the message. </param>
553        /// <param name="prefix"> Prefix to prepend to prepend to each line after the 1st,
554        /// if any line-wrapping occurs. Does NOT get prepended to first line. </param>
555        /// <param name="message"> String/message to send. </param>
556        /// <returns> Number of players who received the message. </returns>
557        public static int MessagePrefixed( [NotNull] this IEnumerable<Player> source, [NotNull] string prefix, [NotNull] string message ) {
558            if( source == null ) throw new ArgumentNullException( "source" );
559            if( prefix == null ) throw new ArgumentNullException( "prefix" );
560            if( message == null ) throw new ArgumentNullException( "message" );
561            int i = 0;
562            foreach( Packet packet in LineWrapper.WrapPrefixed( prefix, message ) ) {
563                foreach( Player player in source ) {
564                    player.Send( packet );
565                    i++;
566                }
567            }
568            return i;
569        }
570
571
572        /// <summary> Formats and broadcasts a message, prefixing wrapped lines. </summary>
573        /// <param name="source"> List of players who will receive the message. </param>
574        /// <param name="prefix"> Prefix to prepend to prepend to each line after the 1st,
575        /// if any line-wrapping occurs. Does NOT get prepended to first line. </param>
576        /// <param name="message"> String/message to send. </param>
577        /// <param name="formatArgs"> Format parameters. Same semantics as String.Format </param>
578        /// <returns> Number of players who received the message. </returns>
579        [StringFormatMethod( "message" )]
580        public static int MessagePrefixed( [NotNull] this IEnumerable<Player> source, [NotNull] string prefix, [NotNull] string message, params object[] formatArgs ) {
581            if( source == null ) throw new ArgumentNullException( "source" );
582            if( message == null ) throw new ArgumentNullException( "message" );
583            if( prefix == null ) throw new ArgumentNullException( "prefix" );
584            if( formatArgs == null ) throw new ArgumentNullException( "formatArgs" );
585            int i = 0;
586            foreach( Packet packet in LineWrapper.WrapPrefixed( prefix, String.Format( message, formatArgs ) ) ) {
587                foreach( Player player in source ) {
588                    player.Send( packet );
589                    i++;
590                }
591            }
592            return i;
593        }
594
595
596
597
598        /// <summary> Formats and broadcasts a message, showing on top-left for those who use WoM. </summary>
599        /// <param name="source"> List of players who will receive the message. </param>
600        /// <param name="message"> String/message to send. </param>
601        /// <param name="formatArgs"> Format parameters. Same semantics as String.Format </param>
602        /// <returns> Number of players who received the message. </returns>
603        [StringFormatMethod( "message" )]
604        public static int MessageAlt( [NotNull] this IEnumerable<Player> source,
605                                      [NotNull] string message,
606                                      [NotNull] params object[] formatArgs ) {
607            if( source == null ) throw new ArgumentNullException( "source" );
608            if( message == null ) throw new ArgumentNullException( "message" );
609            if( formatArgs == null ) throw new ArgumentNullException( "formatArgs" );
610            int i = 0;
611            foreach( Player player in source ) {
612                player.MessageAlt( message, formatArgs );
613                i++;
614            }
615            return i;
616        }
617
618        #endregion
619
620
621        #region Packet Sending
622
623        /// <summary> Broadcasts a packet with normal priority. </summary>
624        /// <param name="source"> List of players who will receive the packet. </param>
625        /// <param name="packet"> Packet to send. </param>
626        /// <returns> Number of players who received the packet. </returns>
627        public static int Send( [NotNull] this IEnumerable<Player> source, Packet packet ) {
628            if( source == null ) throw new ArgumentNullException( "source" );
629            int i = 0;
630            foreach( Player player in source ) {
631                player.Send( packet );
632                i++;
633            }
634            return i;
635        }
636
637
638        /// <summary> Broadcasts a packet with normal priority. </summary>
639        /// <param name="source"> List of players who will receive the packet. </param>
640        /// <param name="except"> Player to exclude from the recepient list. </param>
641        /// <param name="packet"> Packet to send. </param>
642        /// <returns> Number of players who received the packet. </returns>
643        public static int Send( [NotNull] this IEnumerable<Player> source, [CanBeNull] Player except, Packet packet ) {
644            if( source == null ) throw new ArgumentNullException( "source" );
645            int i = 0;
646            foreach( Player player in source ) {
647                if( player == except ) continue;
648                player.Send( packet );
649                i++;
650            }
651            return i;
652        }
653
654
655        /// <summary> Broadcasts a packet with low priority. </summary>
656        /// <param name="source"> List of players who will receive the packet. </param>
657        /// <param name="packet"> Packet to send. </param>
658        /// <returns> Number of players who received the packet. </returns>
659        public static int SendLowPriority( [NotNull] this IEnumerable<Player> source, Packet packet ) {
660            if( source == null ) throw new ArgumentNullException( "source" );
661            int i = 0;
662            foreach( Player player in source ) {
663                player.SendLowPriority( packet );
664                i++;
665            }
666            return i;
667        }
668
669
670        /// <summary> Broadcasts a packet with low priority. </summary>
671        /// <param name="source"> List of players who will receive the packet. </param>
672        /// <param name="except"> Player to exclude from the recepient list. </param>
673        /// <param name="packet"> Packet to send. </param>
674        /// <returns> Number of players who received the packet. </returns>
675        public static int SendLowPriority( [NotNull] this IEnumerable<Player> source, [CanBeNull] Player except, Packet packet ) {
676            if( source == null ) throw new ArgumentNullException( "source" );
677            int i = 0;
678            foreach( Player player in source ) {
679                if( player == except ) continue;
680                player.SendLowPriority( packet );
681                i++;
682            }
683            return i;
684        }
685
686        #endregion
687    }
688}