public Player[] FindPlayers([NotNull] Player player, [NotNull] string playerName) { if (player == null) { throw new ArgumentNullException("player"); } if (playerName == null) { throw new ArgumentNullException("playerName"); } Player[] tempList = Players; List <Player> results = new List <Player>(); for (int i = 0; i < tempList.Length; i++) { if (tempList[i] != null && player.CanSee(tempList[i])) { if (tempList[i].Name.Equals(playerName, StringComparison.OrdinalIgnoreCase)) { results.Clear(); results.Add(tempList[i]); break; } else if (tempList[i].Name.StartsWith(playerName, StringComparison.OrdinalIgnoreCase)) { results.Add(tempList[i]); } } } return(results.ToArray()); }
static void ReplyHandler([NotNull] Player player, [NotNull] CommandReader cmd) { string messageText = cmd.NextAll(); if (messageText.Length == 0) { player.Message("Reply: No message to send!"); return; } string targetName = player.LastPrivateMessageSender; if (targetName != null) { Player targetPlayer = Server.FindPlayerExact(player, targetName, SearchOptions.IncludeHidden); if (targetPlayer != null) { if (player.CanSee(targetPlayer)) { if (targetPlayer.IsDeaf) { player.Message("Cannot PM {0}&S: they are currently deaf.", targetPlayer.ClassyName); } else if (targetPlayer.IsIgnoring(player.Info)) { player.Message("&WCannot PM {0}&W: you are ignored.", targetPlayer.ClassyName); } else { Chat.SendPM(player, targetPlayer, messageText); player.MessageNow("&Pto {0}: {1}", targetPlayer.Name, messageText); } } else { player.Message("Reply: Cannot send message; player {0}&S is offline.", PlayerDB.FindExactClassyName(targetName)); if (targetPlayer.CanHear(player)) { Chat.SendPM(player, targetPlayer, messageText); player.Info.DecrementMessageWritten(); } } } else { player.Message("Reply: Cannot send message; player {0}&S is offline.", PlayerDB.FindExactClassyName(targetName)); } } else { player.Message("Reply: You have not sent any messages yet."); } }
public static IEnumerable <Player> CantBeSeen([NotNull] this IEnumerable <Player> source, [NotNull] Player observer) { if (source == null) { throw new ArgumentNullException("source"); } if (observer == null) { throw new ArgumentNullException("observer"); } foreach (Player player in source) { if (player != observer && !observer.CanSee(player)) { yield return(player); } } }
static void ReplyHandler( Player player, CommandReader cmd ) { string messageText = cmd.NextAll(); if( messageText.Length == 0 ) { player.Message( "Reply: No message to send!" ); return; } string targetName = player.lastPrivateMessageSender; if( targetName != null ) { Player targetPlayer = Server.FindPlayerExact( player, targetName, SearchOptions.IncludeHidden ); if( targetPlayer != null ) { if( player.CanSee( targetPlayer ) ) { if( targetPlayer.IsDeaf ) { player.Message( "Cannot PM {0}&S: they are currently deaf.", targetPlayer.ClassyName ); } else if( targetPlayer.IsIgnoring( player.Info ) ) { player.Message( "&WCannot PM {0}&W: you are ignored.", targetPlayer.ClassyName ); } else { Chat.SendPM( player, targetPlayer, messageText ); player.MessageNow( "&Pto {0}: {1}", targetPlayer.Name, messageText ); } } else { player.Message( "Reply: Cannot send message; player {0}&S is offline.", PlayerDB.FindExactClassyName( targetName ) ); if( targetPlayer.CanHear( player ) ) { Chat.SendPM( player, targetPlayer, messageText ); player.Info.DecrementMessageWritten(); } } } else { player.Message( "Reply: Cannot send message; player {0}&S is offline.", PlayerDB.FindExactClassyName( targetName ) ); } } else { player.Message( "Reply: You have not sent any messages yet." ); } }
static void WorldsHandler(Player player, Command cmd) { string param = cmd.Next(); World[] worlds; string listName; string extraParam; int offset = 0; if (param == null || Int32.TryParse(param, out offset)) { listName = "available worlds"; extraParam = ""; worlds = WorldManager.Worlds.Where(w => !w.IsRealm).Where(player.CanSee).ToArray(); } else { switch (Char.ToLower(param[0])) { case 'a': listName = "worlds"; extraParam = "all "; worlds = WorldManager.Worlds; break; case 'h': listName = "hidden worlds"; extraParam = "hidden "; worlds = WorldManager.Worlds.Where(w => !player.CanSee(w)).ToArray(); break; case 'r': listName = "Available Realms"; extraParam = "realms"; worlds = WorldManager.Worlds.Where(w => w.IsRealm).ToArray(); break; case 'p': listName = "populated worlds"; extraParam = "populated "; worlds = WorldManager.Worlds.Where(w => w.Players.Any(player.CanSee)).ToArray(); break; case '@': if (param.Length == 1) { CdWorlds.PrintUsage(player); return; } string rankName = param.Substring(1); Rank rank = RankManager.FindRank(rankName); if (rank == null) { player.MessageNoRank(rankName); return; } listName = String.Format("worlds where {0}&S+ can build", rank.ClassyName); extraParam = "@" + rank.Name + " "; worlds = WorldManager.Worlds.Where(w => (w.BuildSecurity.MinRank <= rank) && player.CanSee(w)) .ToArray(); break; default: CdWorlds.PrintUsage(player); return; } if (cmd.HasNext && !cmd.NextInt(out offset)) { CdWorlds.PrintUsage(player); return; } } if (worlds.Length == 0) { player.Message("There are no {0}.", listName); } else if (worlds.Length <= WorldNamesPerPage || player.IsSuper) { player.MessagePrefixed("&S ", "&SThere are {0} {1}: {2}", worlds.Length, listName, worlds.JoinToClassyString()); } else { if (offset >= worlds.Length) { offset = Math.Max(0, worlds.Length - WorldNamesPerPage); } World[] worldsPart = worlds.Skip(offset).Take(WorldNamesPerPage).ToArray(); player.MessagePrefixed("&S ", "&S{0}: {1}", listName.UppercaseFirst(), worldsPart.JoinToClassyString()); if (offset + worldsPart.Length < worlds.Length) { player.Message("Showing {0}-{1} (out of {2}). Next: &H/Worlds {3}{1}", offset + 1, offset + worldsPart.Length, worlds.Length, extraParam); } else { player.Message("Showing worlds {0}-{1} (out of {2}).", offset + 1, offset + worldsPart.Length, worlds.Length); } } }
static void OnlineStaffHandler(Player player, CommandReader cmd) { Player[] onlineStaff = Server.Players.Where(p => p.IsStaff && player.CanSee(p)).ToArray(); if (!onlineStaff.Any()) { player.Message("There are no online staff at the moment"); return; } player.Message("Below is a list of online staff members:"); foreach (Rank rank in RankManager.Ranks.Where(r => r.IsStaff)) { string StaffListTemporary = ""; foreach (Player stafflistplayer in onlineStaff.Where(r => r.Info.Rank == rank)) { StaffListTemporary += stafflistplayer.ClassyName + ", "; } if (StaffListTemporary.Length > 2) { StaffListTemporary = StaffListTemporary.Remove((StaffListTemporary.Length - 2), 2); StaffListTemporary += "."; StaffListTemporary = rank.ClassyName + ": " + StaffListTemporary; player.Message(StaffListTemporary); } } }
static void InfoHandler( Player player, CommandReader cmd ) { if( player == null ) throw new ArgumentNullException( "player" ); PlayerInfo info = FindPlayerInfo(player, cmd, ""); if (info == null) return; Player target = info.PlayerObject; // hide online status when hidden if( target != null && !player.CanSee( target ) ) { target = null; } if( info.LastIP.Equals( IPAddress.None ) ) { player.Message( "About {0}&S: Never seen before.", info.ClassyName); } else { StringBuilder firstLine = new StringBuilder(); if( info.DisplayedName != null ) { firstLine.AppendFormat( "About {0}&S ({1}): ", info.ClassyName, info.Name ); } else { firstLine.AppendFormat( "About {0}&S: ", info.ClassyName ); } if( target != null ) { if( info.IsHidden ) { firstLine.AppendFormat( "HIDDEN" ); } else { firstLine.AppendFormat( "Online now" ); } if( target.IsDeaf ) { firstLine.Append( " (deaf)" ); } if( player.Can( Permission.ViewPlayerIPs ) ) { firstLine.AppendFormat( " from {0}", info.LastIP ); } if( target.IdBotTime > InfoIdleThreshold ) { firstLine.AppendFormat( " (idle {0})", target.IdBotTime.ToMiniString() ); } } else { firstLine.AppendFormat( "Last seen {0} ago", info.TimeSinceLastSeen.ToMiniString()); if( player.Can( Permission.ViewPlayerIPs ) ) { firstLine.AppendFormat( " from {0}", info.LastIP ); } if( info.LeaveReason != LeaveReason.Unknown ) { firstLine.AppendFormat( " ({0})", info.LeaveReason ); } } player.Message( firstLine.ToString() ); if (info.Email != null && (player == Player.Console || player.Info == info)) { // Show login information player.Message(" <{0}> {1} logins since {2:d MMM yyyy}.", Color.StripColors(info.Email), info.TimesVisited, info.FirstLoginDate); } else { // Show login information player.Message(" {0} logins since {1:d MMM yyyy}.", info.TimesVisited, info.FirstLoginDate); } } if( info.IsFrozen ) { player.Message( " Frozen {0} ago by {1}", info.TimeSinceFrozen.ToMiniString(), info.FrozenByClassy ); } if (info.IsMuted) { player.Message( " Muted for {0} by {1}", info.TimeMutedLeft.ToMiniString(), info.MutedByClassy ); } // Show ban information IPBanInfo ipBan = IPBanList.Get( info.LastIP ); switch( info.BanStatus ) { case BanStatus.Banned: if( ipBan != null ) { player.Message( " Account and IP are &CBANNED" ); } else if( String.IsNullOrEmpty( info.BanReason ) ) { player.Message( " Account is &CBANNED" ); } else { player.Message( " Account is &CBANNED&S ({0}&S)", info.BanReason ); } break; case BanStatus.IPBanExempt: if( ipBan != null ) { player.Message( " IP is &CBANNED&S, but account is exempt." ); } else { player.Message( " IP is not banned, and account is exempt." ); } break; case BanStatus.NotBanned: if( ipBan != null ) { if( String.IsNullOrEmpty( ipBan.BanReason ) ) { player.Message( " IP is &CBANNED" ); } else { player.Message( " IP is &CBANNED&S ({0}&S)", ipBan.BanReason ); } } break; } if( !info.LastIP.Equals( IPAddress.None ) ) { // Show alts List<PlayerInfo> altNames = new List<PlayerInfo>(); int bannedAltCount = 0; foreach( PlayerInfo playerFromSameIP in PlayerDB.FindPlayers( info.LastIP ) ) { if( playerFromSameIP == info ) continue; altNames.Add( playerFromSameIP ); if( playerFromSameIP.IsBanned ) { bannedAltCount++; } } if( altNames.Count > 0 ) { altNames.Sort( new PlayerInfoComparer( player ) ); if( altNames.Count > MaxAltsToPrint ) { if( bannedAltCount > 0 ) { player.MessagePrefixed( "&S ", "&S Over {0} accounts ({1} banned) on IP: {2} &Setc", MaxAltsToPrint, bannedAltCount, altNames.Take( 15 ).ToArray().JoinToClassyString() ); } else { player.MessagePrefixed( "&S ", "&S Over {0} accounts on IP: {1} &Setc", MaxAltsToPrint, altNames.Take( 15 ).ToArray().JoinToClassyString() ); } } else { if( bannedAltCount > 0 ) { player.MessagePrefixed( "&S ", "&S {0} accounts ({1} banned) on IP: {2}", altNames.Count, bannedAltCount, altNames.ToArray().JoinToClassyString() ); } else { player.MessagePrefixed( "&S ", "&S {0} accounts on IP: {1}", altNames.Count, altNames.ToArray().JoinToClassyString() ); } } } } // Stats if (info.BlocksDrawn > 0) { player.Message(" Built &f{0:N0} &sDeleted &f{1:N0}&s Drew &f{2:N1}&sk", info.BlocksBuilt, info.BlocksDeleted, info.BlocksDrawn / 1000d); } else { player.Message(" Built &f{0:N0} &sDeleted &f{1:N0}", info.BlocksBuilt, info.BlocksDeleted); } float blocks = ((info.BlocksBuilt) - info.BlocksDeleted); player.Message(" Wrote {0:N0} messages.", info.MessagesWritten); // More stats if (info.TimesBannedOthers > 0 || info.TimesKickedOthers > 0) { player.Message( " Kicked {0}, banned {1}", info.TimesKickedOthers, info.TimesBannedOthers); } if( info.TimesKicked > 0 ) { if( info.LastKickDate != DateTime.MinValue ) { player.Message( " Got kicked {0} times. Last kick {1} ago by {2}", info.TimesKicked, info.TimeSinceLastKick.ToMiniString(), info.LastKickByClassy ); } else { player.Message( " Got kicked {0} times.", info.TimesKicked ); } if( info.LastKickReason != null ) { player.Message( " Kick reason: {0}", info.LastKickReason ); } } // Promotion/demotion if( info.PreviousRank == null ) { if( info.RankChangedBy == null ) { player.Message( " Rank is {0}&S (default).", info.Rank.ClassyName ); } else { player.Message( " Promoted to {0}&S by {1}&S {2} ago.", info.Rank.ClassyName, info.RankChangedByClassy, info.TimeSinceRankChange.ToMiniString() ); if( info.RankChangeReason != null ) { player.Message( " Promotion reason: {0}", info.RankChangeReason ); } } } else if( info.PreviousRank <= info.Rank ) { player.Message( " Promoted from {0}&S to {1}&S by {2}&S {3} ago.", info.PreviousRank.ClassyName, info.Rank.ClassyName, info.RankChangedByClassy, info.TimeSinceRankChange.ToMiniString() ); if( info.RankChangeReason != null ) { player.Message( " Promotion reason: {0}", info.RankChangeReason ); } } else { player.Message( " Demoted from {0}&S to {1}&S by {2}&S {3} ago.", info.PreviousRank.ClassyName, info.Rank.ClassyName, info.RankChangedByClassy, info.TimeSinceRankChange.ToMiniString() ); if( info.RankChangeReason != null ) { player.Message( " Demotion reason: {0}", info.RankChangeReason ); } } if (!info.LastIP.Equals(IPAddress.None)) { // Time on the server TimeSpan totalTime = info.TotalTime; if (target != null) { totalTime = totalTime.Add(info.TimeSinceLastLogin); } if (info.IsOnline && target != null) { player.Message(" Total time: {0:F1} hours. This session: {1:F1} hours.", totalTime.TotalHours, target.Info.TimeSinceLastLogin.TotalHours); } else { player.Message(" Total time: {0:F1} hours", totalTime.TotalHours); } } }
static void WeatherHandler(Player player, CommandReader cmd) { if (cmd.Count == 1) { player.Message(Cdweather.Usage); return; } string name = cmd.Next(); PlayerInfo p = PlayerDB.FindPlayerInfoOrPrintMatches(player, name, SearchOptions.IncludeSelf); if (p == null) { return; } string valueText = cmd.Next(); byte weather; if (!byte.TryParse(valueText, out weather)) { if (valueText.Equals("sun", StringComparison.OrdinalIgnoreCase)) { weather = 0; } else if (valueText.Equals("rain", StringComparison.OrdinalIgnoreCase)) { weather = 1; } else if (valueText.Equals("snow", StringComparison.OrdinalIgnoreCase)) { weather = 2; } } if (weather < 0 || weather > 2) { player.Message("Please use a valid integer(0,1,2) or string(sun,rain,snow)"); return; } if (p != player.Info) { if (p.IsOnline) { if (p.PlayerObject.Supports(CpeExtension.EnvWeatherType)) { p.PlayerObject.Message("&a{0} set your weather to {1} ({2}&a)", player.Name, weather, weather == 0 ? "&sSun" : (weather == 1 ? "&1Rain" : "&fSnow")); player.Message("&aSet weather for {0} to {1} ({2}&a)", p.Name, weather, weather == 0 ? "&sSun" : (weather == 1 ? "&1Rain" : "&fSnow")); p.PlayerObject.Send(Packet.SetWeather((byte)weather)); } else { player.Message("That player does not support WeatherType packet"); } } else if (p.IsOnline == false || !player.CanSee(p.PlayerObject)) { player.Message("That player is not online!"); } } else { if (player.Supports(CpeExtension.EnvWeatherType)) { player.Message("&aSet weather to {0} ({1}&a)", weather, weather == 0 ? "&sSun" : (weather == 1 ? "&1Rain" : "&fSnow")); player.Send(Packet.SetWeather((byte)weather)); } else { player.Message("You don't support WeatherType packet"); } } }
/// <summary>Finds a player by name, using autocompletion. /// Does not count hidden players.</summary> /// <param name="player">Player who initiated the search. /// Used to determine whether others are hidden or not.</param> /// <param name="name">Full or partial name of the search target.</param> /// <returns>An array of matches. List length of 0 means "no matches"; /// 1 is an exact match; over 1 for multiple matches.</returns> public static Player[] FindPlayers( Player player, string name ) { if( player == null ) throw new ArgumentNullException( "player" ); if( name == null ) throw new ArgumentNullException( "name" ); List<Player> results = new List<Player>(); Player[] tempList = PlayerList; for( int i = 0; i < tempList.Length; i++ ) { if( tempList[i] != null && player.CanSee( tempList[i] ) ) { if( tempList[i].Name.Equals( name, StringComparison.OrdinalIgnoreCase ) ) { results.Clear(); results.Add( tempList[i] ); break; } else if( tempList[i].Name.StartsWith( name, StringComparison.OrdinalIgnoreCase ) ) { results.Add( tempList[i] ); } } } return results.ToArray(); }
public static void PrintPlayerInfo( Player player, PlayerInfo info ) { Player target = Server.FindPlayerExact( info.Name ); // hide online status when hidden if( target != null && !player.CanSee( target ) ) { target = null; } if( info.LastIP.Equals( IPAddress.None ) ) { player.Message( "About {0}&S: Never seen before.", info.GetClassyName() ); } else { if( target != null ) { if( target.IsHidden ) { if( player.Can( Permission.ViewPlayerIPs ) ) { player.Message( "About {0}&S: HIDDEN. Online from {1}", info.GetClassyName(), info.LastIP ); } else { player.Message( "About {0}&S: HIDDEN.", info.GetClassyName() ); } } else { if( player.Can( Permission.ViewPlayerIPs ) ) { player.Message( "About {0}&S: Online now from {1}", info.GetClassyName(), info.LastIP ); } else { player.Message( "About {0}&S: Online now.", info.GetClassyName() ); } } } else { if( player.Can( Permission.ViewPlayerIPs ) ) { player.Message( "About {0}&S: Last seen {1} ago from {2}", info.GetClassyName(), info.TimeSinceLastSeen.ToMiniString(), info.LastIP ); } else { player.Message( "About {0}&S: Last seen {1} ago.", info.GetClassyName(), info.TimeSinceLastSeen.ToMiniString() ); } } // Show login information player.Message( " Logged in {0} time(s) since {1:d MMM yyyy}.", info.TimesVisited, info.FirstLoginDate ); } // Show ban information IPBanInfo ipBan = IPBanList.Get( info.LastIP ); if( ipBan != null && info.Banned ) { player.Message( " Both name and IP are {0}BANNED&S. See &H/baninfo", Color.Red ); } else if( ipBan != null ) { player.Message( " IP is {0}BANNED&S (but nick isn't). See &H/baninfo", Color.Red ); } else if( info.Banned ) { player.Message( " Nick is {0}BANNED&S (but IP isn't). See &H/baninfo", Color.Red ); } if( info.LastIP.ToString() != IPAddress.None.ToString() ) { // Show alts List<PlayerInfo> altNames = new List<PlayerInfo>(); int bannedAltCount = 0; foreach( PlayerInfo playerFromSameIP in PlayerDB.FindPlayers( info.LastIP, 25 ) ) { if( playerFromSameIP != info ) { altNames.Add( playerFromSameIP ); if( playerFromSameIP.Banned ) { bannedAltCount++; } } } if( altNames.Count > 0 ) { if( bannedAltCount > 0 ) { player.Message( " {0} accounts ({1} banned) share this IP: {2}", altNames.Count, bannedAltCount, altNames.ToArray().JoinToClassyString() ); } else { player.Message( " {0} accounts share this IP: {1}", altNames.Count, altNames.ToArray().JoinToClassyString() ); } } } // Stats if( info.BlocksDrawn > 500000000 ) { player.Message( " Built {0} and deleted {1} blocks, drew {2}M blocks, wrote {3} messages.", info.BlocksBuilt, info.BlocksDeleted, info.BlocksDrawn / 1000000, info.LinesWritten ); } else if( info.BlocksDrawn > 500000 ) { player.Message( " Built {0} and deleted {1} blocks, drew {2}K blocks, wrote {3} messages.", info.BlocksBuilt, info.BlocksDeleted, info.BlocksDrawn / 1000, info.LinesWritten ); } else if( info.BlocksDrawn > 0 ) { player.Message( " Built {0} and deleted {1} blocks, drew {2} blocks, wrote {3} messages.", info.BlocksBuilt, info.BlocksDeleted, info.BlocksDrawn, info.LinesWritten ); } else { player.Message( " Built {0} and deleted {1} blocks, wrote {2} messages.", info.BlocksBuilt, info.BlocksDeleted, info.LinesWritten ); } // More stats if( info.TimesBannedOthers > 0 || info.TimesKickedOthers > 0 ) { player.Message( " Kicked {0} and banned {1} players.", info.TimesKickedOthers, info.TimesBannedOthers ); } if( info.TimesKicked > 0 ) { if( info.LastKickDate != DateTime.MinValue ) { player.Message( " Got kicked {0} times. Last kick {1} ago by {2}", info.TimesKicked, info.TimeSinceLastKick.ToMiniString(), info.LastKickBy ); if( info.LastKickReason.Length > 0 ) { player.Message( " Last kick reason: {0}", info.LastKickReason ); } } else { player.Message( " Got kicked {0} times", info.TimesKicked ); } } // Promotion/demotion if( !String.IsNullOrEmpty( info.RankChangedBy ) ) { if( info.PreviousRank == null ) { player.Message( " Promoted to {0}&S by {1} {2} ago.", info.Rank.GetClassyName(), info.RankChangedBy, info.TimeSinceRankChange.ToMiniString() ); } else if( info.PreviousRank < info.Rank ) { player.Message( " Promoted from {0}&S to {1}&S by {2} {3} ago.", info.PreviousRank.GetClassyName(), info.Rank.GetClassyName(), info.RankChangedBy, info.TimeSinceRankChange.ToMiniString() ); if( !string.IsNullOrEmpty( info.RankChangeReason ) ) { player.Message( " Promotion reason: {0}", info.RankChangeReason ); } } else { player.Message( " Demoted from {0}&S to {1}&S by {2} {3} ago.", info.PreviousRank.GetClassyName(), info.Rank.GetClassyName(), info.RankChangedBy, info.TimeSinceRankChange.ToMiniString() ); if( info.RankChangeReason.Length > 0 ) { player.Message( " Demotion reason: {0}", info.RankChangeReason ); } } } else { player.Message( " Rank is {0}&S (default).", info.Rank.GetClassyName() ); } if( info.LastIP.ToString() != IPAddress.None.ToString() ) { // Time on the server TimeSpan totalTime = info.TotalTime; if( target != null ) { totalTime = totalTime.Add( info.TimeSinceLastLogin ); } player.Message( " Spent a total of {0:F1} hours ({1:F1} minutes) here.", totalTime.TotalHours, totalTime.TotalMinutes ); } }
public static void PrintPlayerInfo(Player player, PlayerInfo info) { Player target = Server.FindPlayerExact(info.Name); // hide online status when hidden if (target != null && !player.CanSee(target)) { target = null; } if (info.LastIP.Equals(IPAddress.None)) { player.Message("About {0}&S: Never seen before.", info.GetClassyName()); } else { if (target != null) { if (target.IsHidden) { if (player.Can(Permission.ViewPlayerIPs)) { player.Message("About {0}&S: HIDDEN. Online from {1}", info.GetClassyName(), info.LastIP); } else { player.Message("About {0}&S: HIDDEN.", info.GetClassyName()); } } else { if (player.Can(Permission.ViewPlayerIPs)) { player.Message("About {0}&S: Online now from {1}", info.GetClassyName(), info.LastIP); } else { player.Message("About {0}&S: Online now.", info.GetClassyName()); } } } else { if (player.Can(Permission.ViewPlayerIPs)) { player.Message("About {0}&S: Last seen {1} ago from {2}", info.GetClassyName(), info.TimeSinceLastSeen.ToMiniString(), info.LastIP); } else { player.Message("About {0}&S: Last seen {1} ago.", info.GetClassyName(), info.TimeSinceLastSeen.ToMiniString()); } } // Show login information player.Message(" Logged in {0} time(s) since {1:d MMM yyyy}.", info.TimesVisited, info.FirstLoginDate); } // Show ban information IPBanInfo ipBan = IPBanList.Get(info.LastIP); if (ipBan != null && info.Banned) { player.Message(" Both name and IP are {0}BANNED&S. See &H/baninfo", Color.Red); } else if (ipBan != null) { player.Message(" IP is {0}BANNED&S (but nick isn't). See &H/baninfo", Color.Red); } else if (info.Banned) { player.Message(" Nick is {0}BANNED&S (but IP isn't). See &H/baninfo", Color.Red); } if (info.LastIP.ToString() != IPAddress.None.ToString()) { // Show alts List <PlayerInfo> altNames = new List <PlayerInfo>(); int bannedAltCount = 0; foreach (PlayerInfo playerFromSameIP in PlayerDB.FindPlayers(info.LastIP, 25)) { if (playerFromSameIP != info) { altNames.Add(playerFromSameIP); if (playerFromSameIP.Banned) { bannedAltCount++; } } } if (altNames.Count > 0) { if (bannedAltCount > 0) { player.Message(" {0} accounts ({1} banned) share this IP: {2}", altNames.Count, bannedAltCount, altNames.ToArray().JoinToClassyString()); } else { player.Message(" {0} accounts share this IP: {1}", altNames.Count, altNames.ToArray().JoinToClassyString()); } } } // Stats if (info.BlocksDrawn > 500000000) { player.Message(" Built {0} and deleted {1} blocks, drew {2}M blocks, wrote {3} messages.", info.BlocksBuilt, info.BlocksDeleted, info.BlocksDrawn / 1000000, info.LinesWritten); } else if (info.BlocksDrawn > 500000) { player.Message(" Built {0} and deleted {1} blocks, drew {2}K blocks, wrote {3} messages.", info.BlocksBuilt, info.BlocksDeleted, info.BlocksDrawn / 1000, info.LinesWritten); } else if (info.BlocksDrawn > 0) { player.Message(" Built {0} and deleted {1} blocks, drew {2} blocks, wrote {3} messages.", info.BlocksBuilt, info.BlocksDeleted, info.BlocksDrawn, info.LinesWritten); } else { player.Message(" Built {0} and deleted {1} blocks, wrote {2} messages.", info.BlocksBuilt, info.BlocksDeleted, info.LinesWritten); } // More stats if (info.TimesBannedOthers > 0 || info.TimesKickedOthers > 0) { player.Message(" Kicked {0} and banned {1} players.", info.TimesKickedOthers, info.TimesBannedOthers); } if (info.TimesKicked > 0) { if (info.LastKickDate != DateTime.MinValue) { player.Message(" Got kicked {0} times. Last kick {1} ago by {2}", info.TimesKicked, info.TimeSinceLastKick.ToMiniString(), info.LastKickBy); if (info.LastKickReason.Length > 0) { player.Message(" Last kick reason: {0}", info.LastKickReason); } } else { player.Message(" Got kicked {0} times", info.TimesKicked); } } // Promotion/demotion if (!String.IsNullOrEmpty(info.RankChangedBy)) { if (info.PreviousRank == null) { player.Message(" Promoted to {0}&S by {1} {2} ago.", info.Rank.GetClassyName(), info.RankChangedBy, info.TimeSinceRankChange.ToMiniString()); } else if (info.PreviousRank < info.Rank) { player.Message(" Promoted from {0}&S to {1}&S by {2} {3} ago.", info.PreviousRank.GetClassyName(), info.Rank.GetClassyName(), info.RankChangedBy, info.TimeSinceRankChange.ToMiniString()); if (!string.IsNullOrEmpty(info.RankChangeReason)) { player.Message(" Promotion reason: {0}", info.RankChangeReason); } } else { player.Message(" Demoted from {0}&S to {1}&S by {2} {3} ago.", info.PreviousRank.GetClassyName(), info.Rank.GetClassyName(), info.RankChangedBy, info.TimeSinceRankChange.ToMiniString()); if (info.RankChangeReason.Length > 0) { player.Message(" Demotion reason: {0}", info.RankChangeReason); } } } else { player.Message(" Rank is {0}&S (default).", info.Rank.GetClassyName()); } if (info.LastIP.ToString() != IPAddress.None.ToString()) { // Time on the server TimeSpan totalTime = info.TotalTime; if (target != null) { totalTime = totalTime.Add(info.TimeSinceLastLogin); } player.Message(" Spent a total of {0:F1} hours ({1:F1} minutes) here.", totalTime.TotalHours, totalTime.TotalMinutes); } }