static void MarkHandler([NotNull] Player player, [NotNull] CommandReader cmd) { Map map = player.WorldMap; int x, y, z; Vector3I coords; if (cmd.NextInt(out x) && cmd.NextInt(out y) && cmd.NextInt(out z)) { if (cmd.HasNext) { CdMark.PrintUsage(player); return; } coords = new Vector3I(x, y, z); } else { coords = player.Position.ToBlockCoords(); } coords.X = Math.Min(map.Width - 1, Math.Max(0, coords.X)); coords.Y = Math.Min(map.Length - 1, Math.Max(0, coords.Y)); coords.Z = Math.Min(map.Height - 1, Math.Max(0, coords.Z)); if (player.SelectionMarksExpected > 0) { player.SelectionAddMark(coords, true, true); } else { player.MessageNow("Cannot mark - no selection in progress."); } }
static void RollHandler([NotNull] Player player, [NotNull] CommandReader cmd) { if (player.Info.IsMuted) { player.MessageMuted(); return; } if (player.DetectChatSpam()) { return; } Random rand = new Random(); int n1; int min, max; if (cmd.NextInt(out n1)) { int n2; if (!cmd.NextInt(out n2)) { n2 = 1; } min = Math.Min(n1, n2); max = Math.Max(n1, n2); } else { min = 1; max = 100; } if (max == Int32.MaxValue - 1) { player.Message("Roll: Given values must be between {0} and {1}", Int32.MinValue, Int32.MaxValue - 1); return; } int num = rand.Next(min, max + 1); Server.Message(player, "{0}{1} rolled {2} ({3}...{4})", player.ClassyName, ChatColor.Silver, num, min, max); player.Message("{0}You rolled {1} ({2}...{3})", ChatColor.Silver, num, min, max); }
static void RollHandler(Player player, CommandReader cmd) { if (player.Info.IsMuted) { player.MessageMuted(); return; } if (player.DetectChatSpam()) { return; } Random rand = new Random(); int n1; int min, max; if (cmd.NextInt(out n1)) { int n2; if (!cmd.NextInt(out n2)) { n2 = 1; } min = Math.Min(n1, n2); max = Math.Max(n1, n2); } else { min = 1; max = 100; } int num = rand.Next(min, max + 1); Server.Message(player, "{0}{1} rolled {2} ({3}...{4})", player.ClassyName, Color.Silver, num, min, max); player.Message("{0}You rolled {1} ({2}...{3})", Color.Silver, num, min, max); }
static void CopySlotHandler([NotNull] Player player, [NotNull] CommandReader cmd) { int slotNumber; if (cmd.NextInt(out slotNumber)) { if (cmd.HasNext) { CdCopySlot.PrintUsage(player); return; } if (slotNumber < 1 || slotNumber > player.Info.Rank.CopySlots) { player.Message("CopySlot: Select a number between 1 and {0}", player.Info.Rank.CopySlots); } else { player.CopySlot = slotNumber - 1; CopyState info = player.GetCopyState(); if (info == null) { player.Message("Selected copy slot {0} (unused).", slotNumber); } else { player.Message("Selected copy slot {0}: {1} blocks from {2}, {3} old.", slotNumber, info.Blocks.Length, info.OriginWorld, DateTime.UtcNow.Subtract(info.CopyTime).ToMiniString()); } } } else { CopyState[] slots = player.CopyStates; player.Message("Using {0} of {1} slots. Selected slot: {2}", slots.Count(info => info != null), player.Info.Rank.CopySlots, player.CopySlot + 1); for (int i = 0; i < slots.Length; i++) { if (slots[i] != null) { player.Message(" {0}: {1} blocks from {2}, {3} old", i + 1, slots[i].Blocks.Length, slots[i].OriginWorld, DateTime.UtcNow.Subtract(slots[i].CopyTime).ToMiniString()); } } } }
static void EmotesHandler( Player player, CommandReader cmd ) { int page = 1; if( cmd.HasNext ) { if( !cmd.NextInt( out page ) ) { CdEmotes.PrintUsage( player ); return; } } if( page < 1 || page > 3 ) { CdEmotes.PrintUsage( player ); return; } var emoteChars = Chat.EmoteKeywords .Values .Distinct() .Skip( ( page - 1 ) * 11 ) .Take( 11 ); player.Message( "List of emotes, page {0} of 3:", page ); foreach( char ch in emoteChars ) { char ch1 = ch; string keywords = Chat.EmoteKeywords .Where( pair => pair.Value == ch1 ) .Select( kvp => "{&F" + kvp.Key.UppercaseFirst() + "&7}" ) .JoinToString( " " ); player.Message( "&F {0} &7= {1}", ch, keywords ); } if( !player.Can( Permission.UseEmotes ) ) { Rank reqRank = RankManager.GetMinRankWithAllPermissions( Permission.UseEmotes ); if( reqRank == null ) { player.Message( "&SNote: None of the ranks have permission to use emotes." ); } else { player.Message( "&SNote: only {0}+&S can use emotes in chat.", reqRank.ClassyName ); } } }
static void TimerHandler([NotNull] Player player, [NotNull] CommandReader cmd) { string param = cmd.Next(); // List timers if (param == null) { ChatTimer[] list = ChatTimer.TimerList.OrderBy(timer => timer.TimeLeft).ToArray(); if (list.Length == 0) { player.Message("No timers running."); } else { player.Message("There are {0} timers running:", list.Length); foreach (ChatTimer timer in list) { player.Message(" #{0} \"{1}&S\" (started by {2}, {3} left)", timer.Id, timer.Message, timer.StartedBy, timer.TimeLeft.ToMiniString()); } } return; } // Abort a timer if (param.Equals("abort", StringComparison.OrdinalIgnoreCase)) { int timerId; if (cmd.NextInt(out timerId)) { ChatTimer timer = ChatTimer.FindTimerById(timerId); if (timer == null || !timer.IsRunning) { player.Message("Given timer (#{0}) does not exist.", timerId); } else { timer.Abort(); string abortMsg = String.Format("&Y(Timer) {0}&Y aborted a timer with {1} left: {2}", player.ClassyName, timer.TimeLeft.ToMiniString(), timer.Message); Chat.SendSay(player, abortMsg); } } else { CdTimer.PrintUsage(player); } return; } // Start a timer if (player.Info.IsMuted) { player.MessageMuted(); return; } if (player.DetectChatSpam()) { return; } TimeSpan duration; if (!param.TryParseMiniTimeSpan(out duration)) { CdTimer.PrintUsage(player); return; } if (duration > DateTimeUtil.MaxTimeSpan) { player.MessageMaxTimeSpan(); return; } if (duration < ChatTimer.MinDuration) { player.Message("Timer: Must be at least 1 second."); return; } string sayMessage; string message = cmd.NextAll(); if (String.IsNullOrWhiteSpace(message)) { sayMessage = String.Format("&Y(Timer) {0}&Y started a {1} timer", player.ClassyName, duration.ToMiniString()); } else { sayMessage = String.Format("&Y(Timer) {0}&Y started a {1} timer: {2}", player.ClassyName, duration.ToMiniString(), message); } Chat.SendSay(player, sayMessage); ChatTimer.Start(duration, message, player.Name); }
private static void TeleportHandler(Player player, CommandReader cmd) { string name = cmd.Next(); if (name == null) { CdTeleport.PrintUsage(player); return; } if (player.World.Name.ToLower() == "maze") { player.Message("Hey no cheating!"); return; } if (name == "zone") { string zoneName = cmd.Next(); if (zoneName == null) { player.Message("No zone name specified. See &H/Help tpzone"); return; } else { Zone zone = player.World.Map.Zones.Find(zoneName); if (zone == null) { player.MessageNoZone(zoneName); return; } int zoneX = (zone.Bounds.XMin + zone.Bounds.XMax)/2; int zoneY = (zone.Bounds.YMin + zone.Bounds.YMax)/2; int zoneZ = (zone.Bounds.ZMin + zone.Bounds.ZMax)/2; retry2: if (player.World.map.GetBlock(zoneX, zoneY, zoneZ - 1) == Block.Air) { zoneZ = zoneZ - 1; goto retry2; } retry: if (player.World.map.GetBlock(zoneX, zoneY, zoneZ) != Block.Air || player.World.map.GetBlock(zoneX, zoneY, zoneZ + 1) != Block.Air) { zoneZ = zoneZ + 1; goto retry; } Position zPos = new Position((zoneX) * 32 + 16, (zoneY) * 32 + 16, (zoneZ) * 32 + 64); if (player.World != null) { player.LastWorld = player.World; player.LastPosition = player.Position; } player.TeleportTo((zPos)); player.Message("&sTeleporting you to zone " + zone.ClassyName); return; } } if (name == "random" || name == "rand") { Random rand = new Random(); int x = rand.Next(0, player.WorldMap.Width); int y = rand.Next(0, player.WorldMap.Length); int z = player.Position.Z/32 + 1; retry2: if (player.World.map.GetBlock(x, y, z - 3) == Block.Air) { z = z - 1; goto retry2; } retry: if (player.World.map.GetBlock(x, y, z - 2) != Block.Air || player.World.map.GetBlock(x, y, z - 1) != Block.Air) { z = z + 1; goto retry; } if (player.World != null) { player.LastWorld = player.World; player.LastPosition = player.Position; } player.TeleportTo(new Position { X = (short) (x*32 + 16), Y = (short) (y*32 + 16), Z = (short) (z*32 + 16), R = player.Position.R, L = player.Position.L }); player.Message("Teleported to: ({0}, {1}, {2})", x, y, z); return; } if (cmd.Next() != null) { cmd.Rewind(); int x, y, z, rot, lot; rot = player.Position.R; lot = player.Position.L; if (cmd.NextInt(out x) && cmd.NextInt(out y) && cmd.NextInt(out z)) { if (cmd.HasNext) { if (cmd.HasNext) { if (cmd.NextInt(out rot) && cmd.NextInt(out lot)) { if (rot > 255 || rot < 0) { player.Message("R must be inbetween 0 and 255. Set to player R"); } if (lot > 255 || lot < 0) { player.Message("L must be inbetween 0 and 255. Set to player L"); } } } } if (x <= -1024 || x >= 1024 || y <= -1024 || y >= 1024 || z <= -1024 || z >= 1024) { player.Message("Coordinates are outside the valid range!"); } else { if (player.World != null) { player.LastWorld = player.World; player.LastPosition = player.Position; } player.TeleportTo(new Position { X = (short) (x*32 + 16), Y = (short) (y*32 + 16), Z = (short) (z*32 + 48), R = (byte) rot, L = (byte) lot }); } } else { CdTeleport.PrintUsage(player); } } else { if (name == "-") { if (player.LastUsedPlayerName != null) { name = player.LastUsedPlayerName; } else { player.Message("Cannot repeat player name: you haven't used any names yet."); return; } } Player[] matches = Server.FindPlayers(player, name, SearchOptions.Default); if (matches.Length == 1) { Player target = matches[0]; World targetWorld = target.World; if (targetWorld == null) PlayerOpException.ThrowNoWorld(target); if (target.Info.TPDeny && target.Info.Rank >= player.Info.Rank) { player.Message("&CThis player does not want people teleporting to them"); player.Message("Cannot teleport to {0}&S.", target.ClassyName, targetWorld.ClassyName, targetWorld.AccessSecurity.MinRank.ClassyName); return; } if (targetWorld == player.World) { if (player.World != null) { player.LastWorld = player.World; player.LastPosition = player.Position; } player.TeleportTo(target.Position); } else { if (targetWorld.Name.StartsWith("PW_") && !targetWorld.AccessSecurity.ExceptionList.Included.Contains(player.Info)) { player.Message( "You cannot join due to that player being in a personal world that you cannot access."); return; } switch (targetWorld.AccessSecurity.CheckDetailed(player.Info)) { case SecurityCheckResult.Allowed: case SecurityCheckResult.WhiteListed: if (player.Info.Rank.Name == "Banned") { player.Message("&CYou can not change worlds while banned."); player.Message("Cannot teleport to {0}&S.", target.ClassyName, targetWorld.ClassyName, targetWorld.AccessSecurity.MinRank.ClassyName); break; } if (targetWorld.IsFull) { player.Message("Cannot teleport to {0}&S because world {1}&S is full.", target.ClassyName, targetWorld.ClassyName); player.Message("Cannot teleport to {0}&S.", target.ClassyName, targetWorld.ClassyName, targetWorld.AccessSecurity.MinRank.ClassyName); break; } player.StopSpectating(); player.JoinWorld(targetWorld, WorldChangeReason.Tp, target.Position); break; case SecurityCheckResult.BlackListed: player.Message("Cannot teleport to {0}&S because you are blacklisted on world {1}", target.ClassyName, targetWorld.ClassyName); break; case SecurityCheckResult.RankTooLow: if (player.Info.Rank.Name == "Banned") { player.Message("&CYou can not change worlds while banned."); player.Message("Cannot teleport to {0}&S.", target.ClassyName, targetWorld.ClassyName, targetWorld.AccessSecurity.MinRank.ClassyName); break; } if (targetWorld.IsFull) { if (targetWorld.IsFull) { player.Message("Cannot teleport to {0}&S because world {1}&S is full.", target.ClassyName, targetWorld.ClassyName); player.Message("Cannot teleport to {0}&S.", target.ClassyName, targetWorld.ClassyName, targetWorld.AccessSecurity.MinRank.ClassyName); break; } player.StopSpectating(); player.JoinWorld(targetWorld, WorldChangeReason.Tp, target.Position); break; } player.Message("Cannot teleport to {0}&S because world {1}&S requires {2}+&S to join.", target.ClassyName, targetWorld.ClassyName, targetWorld.AccessSecurity.MinRank.ClassyName); break; } } } else if (matches.Length > 1) { player.MessageManyMatches("player", matches); } } }
static void BlockInfoHandler( Player player, CommandReader cmd ) { World playerWorld = player.World; if( playerWorld == null ) PlayerOpException.ThrowNoWorld( player ); // Make sure BlockDB is usable if( !BlockDB.IsEnabledGlobally ) { player.Message( "&WBlockDB is disabled on this server." ); return; } if( !playerWorld.BlockDB.IsEnabled ) { player.Message( "&WBlockDB is disabled in this world." ); return; } int x, y, z; if( cmd.NextInt( out x ) && cmd.NextInt( out y ) && cmd.NextInt( out z ) ) { // If block coordinates are given, run the BlockDB query right away if( cmd.HasNext ) { CdBlockInfo.PrintUsage( player ); return; } Vector3I coords = new Vector3I( x, y, z ); Map map = player.WorldMap; coords.X = Math.Min( map.Width - 1, Math.Max( 0, coords.X ) ); coords.Y = Math.Min( map.Length - 1, Math.Max( 0, coords.Y ) ); coords.Z = Math.Min( map.Height - 1, Math.Max( 0, coords.Z ) ); BlockInfoSelectionCallback( player, new[] { coords }, null ); } else { // Otherwise, start a selection player.Message( "BInfo: Click a block to look it up." ); player.SelectionStart( 1, BlockInfoSelectionCallback, null, CdBlockInfo.Permissions ); } }
static bool CheckBlockId(Player player, CommandReader cmd, out int blockId) { if (!cmd.HasNext) { blockId = 0; player.Message("You most provide a block ID argument."); return false; } if (!cmd.NextInt(out blockId)) { player.Message("Provided block id is not a number."); return false; } if (blockId <= 65 || blockId >= 255) { player.Message("Block id must be between 65-254"); return false; } return true; }
private static void SwearHandler(Player player, CommandReader cmd) { string param = cmd.Next(); if (param == null) { CdSwear.PrintUsage(player); return; } switch (param.ToLower()) { case "r": case "d": case "remove": case "delete": int fId; bool removed = false; Filter fRemove = null; if (cmd.NextInt(out fId)) { foreach (Filter f in Chat.Filters) { if (f.Id == fId) { Server.Message("&Y[Filters] {0}&Y removed the filter \"{1}\" -> \"{2}\"", player.ClassyName, f.Word, f.Replacement); fRemove = f; removed = true; } } if (fRemove != null) { fRemove.removeFilter(); } if (!removed) { player.Message("Given filter (#{0}) does not exist.", fId); } } else { CdSwear.PrintUsage(player); } break; case "a": case "add": case "create": Filter fCreate = new Filter(); if (player.Info.IsMuted) { player.MessageMuted(); return; } string word = cmd.Next(); string replacement = cmd.NextAll(); if ("".Equals(word) || "".Equals(replacement)) { CdSwear.PrintUsage(player); break; } bool exists = false; foreach (Filter f in Chat.Filters) { if (f.Word.ToLower().Equals(word.ToLower())) { exists = true; } } if (!exists) { Server.Message("&Y[Filters] \"{0}\" is now replaced by \"{1}\"", word, replacement); fCreate.addFilter(getNewFilterId(), word, replacement); } else { player.Message("A filter with that world already exists!"); } break; default: CdSwear.PrintUsage(player); break; } }
static void TimerHandler(Player player, CommandReader cmd) { string param = cmd.Next(); // List timers if (param == null) { ChatTimer[] list = ChatTimer.TimerList.OrderBy(timer => timer.TimeLeft).ToArray(); if (list.Length == 0) { player.Message("No timers running."); } else { player.Message("There are {0} timers running:", list.Length); foreach (ChatTimer timer in list) { if (timer.Message.Equals("")) { player.Message(" #{0} \"&7*CountDown*&s\" (started by {2}, {3} left)", timer.ID, timer.Message, timer.StartedBy, timer.TimeLeft.ToMiniString()); } else { player.Message(" #{0} \"{1}&s\" (started by {2}, {3} left)", timer.ID, timer.Message, timer.StartedBy, timer.TimeLeft.ToMiniString()); } } } return; } // Abort a timer if (param.Equals("abort", StringComparison.OrdinalIgnoreCase)) { int timerId; if (cmd.NextInt(out timerId)) { ChatTimer timer = ChatTimer.FindTimerById(timerId); if (timer == null || !timer.IsRunning) { player.Message("Given timer (#{0}) does not exist.", timerId); } else { timer.Abort(); string abortMsg = ""; string abortircMsg = ""; if (timer.Message.Equals("")) { abortMsg = String.Format("&S{0}&S aborted a &7CountDown&S with {1} left", player.ClassyName, timer.TimeLeft.ToMiniString()); abortircMsg = String.Format("\u212C&S{0}&S aborted a &7CountDown&S with {1} left", player.ClassyName, timer.TimeLeft.ToMiniString()); } else { abortMsg = String.Format("&S{0}&S aborted a &7Timer&S with {1} left: &7{2}", player.ClassyName, timer.TimeLeft.ToMiniString(), timer.Message); abortircMsg = String.Format( "\u212C&S{0}&S aborted a &7Timer&S with {1} left: \u211C{2}", player.ClassyName, timer.TimeLeft.ToMiniString(), timer.Message); } Server.Players.Message(abortMsg); IRC.SendChannelMessage(abortircMsg); } } else { CdTimer.PrintUsage(player); } return; } // Start a timer if (player.Info.IsMuted) { player.MessageMuted(); return; } if (player.DetectChatSpam()) return; TimeSpan duration; if (!param.TryParseMiniTimespan(out duration)) { CdTimer.PrintUsage(player); return; } if (duration > DateTimeUtil.MaxTimeSpan) { player.MessageMaxTimeSpan(); return; } if (duration < ChatTimer.MinDuration) { player.Message("Timer: Must be at least 1 second."); return; } string sayMessage; string ircMessage; string message = cmd.NextAll(); if (String.IsNullOrEmpty(message)) { sayMessage = String.Format("&2[&7CountDown Started&2][&7{1}&2] &2-&7{0}", player.Name, duration.ToMiniString()); ircMessage = String.Format( "\u212C&2[&7{1} CountDown Started&2] -\u211C{0}", player.Name, duration.ToMiniString()); } else { sayMessage = String.Format("&2[&7Timer Started&2][&7{1}&2] &7{2} &2-&7{0}", player.Name, duration.ToMiniString(), message); ircMessage = String.Format( "\u212C&2[&7{1} Timer Started&2][&7{0}&2] \u211C{2}", player.Name, duration.ToMiniString(), message); } Server.Players.Message(sayMessage); IRC.SendChannelMessage(ircMessage); ChatTimer.Start(duration, message, player.Name); }
private static void ReportsHandler(Player player, CommandReader cmd) { string param = cmd.Next() ?? "n/a"; int reportId; // List Reports switch (param.ToLower()) { case "abort": case "r": case "d": case "remove": case "delete": bool removed = false; Report rRemove = null; if (cmd.NextInt(out reportId)) { foreach (Report r in Chat.Reports) if (r.Id == reportId) { player.Message(" #{0} has been removed", r.Id); rRemove = r; removed = true; } if (rRemove != null) { rRemove.removeFilter(); } if (!removed) { player.Message("Given Report (#{0}) does not exist.", reportId); } } else { CdReports.PrintUsage(player); } break; case "read": case "open": case "view": bool read = false; if (cmd.NextInt(out reportId)) { foreach (Report r in Chat.Reports) { if (r.Id == reportId) { player.Message( "&s[&1Report&s] #&f{0}&n" + " &sFrom:&f {1}&n" + " &sDate: &7{2} at {3}&n" + " &sMessage:&f {4}", r.Id, r.Sender, r.Datesent.ToShortDateString(), r.Datesent.ToLongTimeString(), r.Message); read = true; } } if (!read) { player.Message("Given Report (#{0}) does not exist.", reportId); } } else { CdReports.PrintUsage(player); } break; default: if (Chat.Reports.Count == 0) { player.Message("There are no reports."); } else { player.Message("There are {0} reports:", Chat.Reports.Count); foreach (Report r in Chat.Reports.OrderBy(r => r.Datesent)) { player.Message("&s[&1Report&s] #&f" + r.Id + " &sFrom:&f " + r.Sender); } } break; } }
static void RollHandler(Player player, CommandReader cmd) { if (player.Info.IsMuted) { player.MessageMuted(); return; } if (player.Info.TimeSinceLastServerMessage.TotalSeconds < 5) { player.Info.getLeftOverTime(5, cmd); return; } if (player.DetectChatSpam()) return; Random rand = new Random(); int n1; int min, max; if (cmd.NextInt(out n1)) { int n2; if (!cmd.NextInt(out n2)) { n2 = 1; } min = Math.Min(n1, n2); max = Math.Max(n1, n2); } else { min = 1; max = 100; } int num = rand.Next(min, max + 1); Server.Message(player, "{0}{1} rolled {2} ({3}...{4})", player.ClassyName, Color.Silver, num, min, max); player.Message("{0}You rolled {1} ({2}...{3})", Color.Silver, num, min, max); player.Info.LastServerMessageDate = DateTime.Now; if (min == 1 && max == 100) { if (num == 69) { Server.BotMessage("Tehe....69"); } if (num == Server.CountPlayers(false)) { Server.BotMessage("That's how many players are online :D"); } } }
private static void IdeaHandler(Player player, CommandReader cmd) { string[] adjectiveStrings; string[] nounStrings; if (File.Exists("./Bot/Adjectives.txt") && File.Exists("./Bot/Nouns.txt")) { adjectiveStrings = File.ReadAllLines("./Bot/Adjectives.txt"); nounStrings = File.ReadAllLines("./Bot/Nouns.txt"); } else { player.Message( "&cError: No idea files! This should not happen! Yell at the host for deleting Adjectives.txt and Nouns.txt in the bot file."); return; } Random randAdjectiveString = new Random(); Random randNounString = new Random(); string adjective; string noun; int amount; string ana = "a"; if (player.Info.TimeSinceLastServerMessage.TotalSeconds < 5) { player.Info.getLeftOverTime(5, cmd); return; } if (cmd.NextInt(out amount)) { if (amount > 10) amount = 10; if (amount < 1) amount = 1; player.Message("{0} random building ideas", amount); for (int i = 1; i <= amount;) { adjective = adjectiveStrings[randAdjectiveString.Next(0, adjectiveStrings.Length)]; noun = nounStrings[randNounString.Next(0, nounStrings.Length)]; if (adjective.StartsWith("a") || adjective.StartsWith("e") || adjective.StartsWith("i") || adjective.StartsWith("o") || adjective.StartsWith("u")) { ana = "an"; } else if (noun.EndsWith("s")) { ana = "some"; } player.Message("&sIdea #{0}&f: Build " + ana + " " + adjective + " " + noun, i); i++; ana = "a"; } } else { adjective = adjectiveStrings[randAdjectiveString.Next(0, adjectiveStrings.Length)]; noun = nounStrings[randNounString.Next(0, nounStrings.Length)]; if (adjective.StartsWith("a") || adjective.StartsWith("e") || adjective.StartsWith("i") || adjective.StartsWith("o") || adjective.StartsWith("u")) { ana = "an"; } else if (noun.EndsWith("s")) { ana = "some"; } player.Message("&sIdea&f: Build " + ana + " " + adjective + " " + noun); } player.Info.LastServerMessageDate = DateTime.Now; }
static void PlayersHandler( Player player, CommandReader cmd ) { string param = cmd.Next(); Player[] players; string worldName = null; string qualifier; int offset = 0; if( param == null || Int32.TryParse( param, out offset ) ) { // No world name given; Start with a list of all players. players = Server.Players; qualifier = "online"; if( cmd.HasNext ) { CdPlayers.PrintUsage( player ); return; } } else { // Try to find the world World world = WorldManager.FindWorldOrPrintMatches( player, param ); if( world == null ) return; worldName = param; // If found, grab its player list players = world.Players; qualifier = String.Format( "in world {0}&S", world.ClassyName ); if( cmd.HasNext && !cmd.NextInt( out offset ) ) { CdPlayers.PrintUsage( player ); return; } } if( players.Length > 0 ) { // Filter out hidden players, and sort Player[] visiblePlayers = players.Where( player.CanSee ) .OrderBy( p => p, PlayerListSorter.Instance ) .ToArray(); if( visiblePlayers.Length == 0 ) { player.Message( "There are no players {0}", qualifier ); } else if( visiblePlayers.Length <= PlayersPerPage || player.IsSuper ) { player.MessagePrefixed( "&S ", "&SThere are {0} players {1}: {2}", visiblePlayers.Length, qualifier, visiblePlayers.JoinToClassyString() ); } else { if( offset >= visiblePlayers.Length ) { offset = Math.Max( 0, visiblePlayers.Length - PlayersPerPage ); } Player[] playersPart = visiblePlayers.Skip( offset ).Take( PlayersPerPage ).ToArray(); player.MessagePrefixed( "&S ", "&SPlayers {0}: {1}", qualifier, playersPart.JoinToClassyString() ); if( offset + playersPart.Length < visiblePlayers.Length ) { player.Message( "Showing {0}-{1} (out of {2}). Next: &H/Players {3}{1}", offset + 1, offset + playersPart.Length, visiblePlayers.Length, (worldName == null ? "" : worldName + " ") ); } else { player.Message( "Showing players {0}-{1} (out of {2}).", offset + 1, offset + playersPart.Length, visiblePlayers.Length ); } } } else { player.Message( "There are no players {0}", qualifier ); } }
static void MarkHandler( Player player, CommandReader cmd ) { Map map = player.WorldMap; int x, y, z; Vector3I coords; if( cmd.NextInt( out x ) && cmd.NextInt( out y ) && cmd.NextInt( out z ) ) { if( cmd.HasNext ) { CdMark.PrintUsage( player ); return; } coords = new Vector3I( x, y, z ); } else { coords = player.Position.ToBlockCoords(); } coords.X = Math.Min( map.Width - 1, Math.Max( 0, coords.X ) ); coords.Y = Math.Min( map.Length - 1, Math.Max( 0, coords.Y ) ); coords.Z = Math.Min( map.Height - 1, Math.Max( 0, coords.Z ) ); if( player.SelectionMarksExpected > 0 ) { player.SelectionAddMark( coords, true, true ); } else { player.MessageNow( "Cannot mark - no selection in progress." ); } }
static void GlobalBlockListHandler(Player player, CommandReader cmd) { int offset = 0, index = 0, count = 0; cmd.NextInt( out offset ); BlockDefinition[] defs = BlockDefinition.GlobalDefinitions; for( int i = 0; i < defs.Length; i++ ) { BlockDefinition def = defs[i]; if (def == null) continue; if (index >= offset) { count++; player.Message("&sCustom block &h{0} &shas name &h{1}", def.BlockID, def.Name); if(count >= 8) { player.Message("To see the next set of global definitions, " + "type /gb list {0}", offset + 8); return; } } index++; } }
static void WorldsHandler( Player player, CommandReader 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( 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 '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 ); } } }
private static void PortalH(Player player, CommandReader cmd) { try { string option = cmd.Next(); if (string.IsNullOrEmpty(option)) { CdPortal.PrintUsage(player); return; } switch (option.ToLower()) { case "create": case "add": if (player.Can(Permission.CreatePortals)) { string addWorld = cmd.Next(); if (!string.IsNullOrEmpty(addWorld) && WorldManager.FindWorldExact(addWorld) != null) { DrawOperation operation = new CuboidDrawOperation(player); NormalBrush brush = new NormalBrush(Block.Water, Block.Water); string blockTypeOrName = cmd.Next(); Block pblock; if (blockTypeOrName != null && Map.GetBlockByName(blockTypeOrName, false, out pblock)) { if ((!validPBlocks.Contains(pblock) && pblock <= Block.StoneBrick) || (pblock == Block.Air && player.Info.Rank != RankManager.HighestRank)) { player.Message("Invalid block, choose a non-solid block"); return; } else { brush = new NormalBrush(pblock, pblock); } } string addPortalName = cmd.Next(); if (string.IsNullOrEmpty(addPortalName)) { player.PortalName = null; } else { if (!Portal.DoesNameExist(player.World, addPortalName)) { player.PortalName = addPortalName; } else { player.Message("A portal with name {0} already exists in this world.", addPortalName); return; } } World tpWorld = WorldManager.FindWorldExact(addWorld); if (cmd.HasNext) { int x, y, z, rot = player.Position.R, lot = player.Position.L; if (cmd.NextInt(out x) && cmd.NextInt(out y) && cmd.NextInt(out z)) { if (cmd.HasNext && cmd.HasNext) { if (cmd.NextInt(out rot) && cmd.NextInt(out lot)) { if (rot > 255 || rot < 0) { player.Message("R must be inbetween 0 and 255. Set to player R"); rot = player.Position.R; } if (lot > 255 || lot < 0) { player.Message("L must be inbetween 0 and 255. Set to player L"); lot = player.Position.L; } } } if (x < 1 || x >= 1024 || y < 1 || y >= 1024 || z < 1 || z >= 1024) { player.Message("Coordinates are outside the valid range!"); return; } else { player.PortalTPPos = new Position((short)(x * 32), (short)(y * 32), (short)(z * 32), (byte)rot, (byte)lot); } } else { player.PortalTPPos = tpWorld.map == null ? new Position(0, 0, 0) : tpWorld.map.Spawn; } } else { player.PortalTPPos = tpWorld.map == null ? new Position(0, 0, 0) : tpWorld.map.Spawn; } operation.Brush = brush; player.PortalWorld = addWorld; player.SelectionStart(operation.ExpectedMarks, PortalCreateCallback, operation, Permission.CreatePortals); player.Message("Click {0} blocks or use &H/Mark&S to mark the area of the portal.", operation.ExpectedMarks); } else { if (string.IsNullOrEmpty(addWorld)) { player.Message("No world specified."); } else { player.MessageNoWorld(addWorld); } } } else { player.MessageNoAccess(Permission.CreatePortals); } break; case "remove": case "delete": if (player.Can(Permission.CreatePortals)) { string remPortalName = cmd.Next(); string remWString = cmd.Next(); World remWorld = player.World; if (!string.IsNullOrEmpty(remWString)) { remWorld = WorldManager.FindWorldOrPrintMatches(player, remWString); } if (remWorld == null) { return; } if (string.IsNullOrEmpty(remPortalName)) { player.Message("No portal name specified."); } else { if (remWorld.Portals != null && remWorld.Portals.Count > 0) { bool found = false; Portal portalFound = null; lock (remWorld.Portals.SyncRoot) { foreach (Portal portal in remWorld.Portals) { if (portal.Name.ToLower().Equals(remPortalName.ToLower())) { portalFound = portal; found = true; break; } } if (!found) { player.Message("Could not find portal by name {0}.", remPortalName); } else { portalFound.Remove(player, remWorld); player.Message("Portal was removed."); } } } else { player.Message("Could not find portal as this world doesn't contain a portal."); } } } else { player.MessageNoAccess(Permission.CreatePortals); } break; case "info": case "i": string iPortalName = cmd.Next(); string iWString = cmd.Next(); World iWorld = player.World; if (!string.IsNullOrEmpty(iWString)) { iWorld = WorldManager.FindWorldOrPrintMatches(player, iWString); } if (iWorld == null) { return; } if (string.IsNullOrEmpty(iPortalName)) { player.Message("No portal name specified."); } else { if (iWorld.Portals != null && iWorld.Portals.Count > 0) { bool found = false; lock (iWorld.Portals.SyncRoot) { foreach (Portal portal in iWorld.Portals) { if (portal.Name.ToLower().Equals(iPortalName.ToLower())) { World portalWorld = WorldManager.FindWorldExact(portal.World); player.Message("Portal {0}&S was created by {1}&S at {2} and teleports to world {3} at {4}&S.", portal.Name, PlayerDB.FindPlayerInfoExact(portal.Creator).ClassyName, portal.Created, portalWorld.ClassyName, portal.position().ToString()); found = true; } } } if (!found) { player.Message("Could not find portal by name {0}.", iPortalName); } } else { player.Message("Could not find portal as this world doesn't contain a portal."); } } break; case "list": case "l": string lWString = cmd.Next(); World lWorld = player.World; if (!string.IsNullOrEmpty(lWString)) { lWorld = WorldManager.FindWorldOrPrintMatches(player, lWString); } if (lWorld == null) { return; } if (lWorld.Portals == null || lWorld.Portals.Count == 0) { player.Message("There are no portals in {0}&S.", lWorld.ClassyName); } else { string[] portalNames = new string[lWorld.Portals.Count]; StringBuilder output = new StringBuilder("There are " + lWorld.Portals.Count + " portals in " + lWorld.ClassyName + "&S: "); for (int i = 0; i < lWorld.Portals.Count; i++) { portalNames[i] = ((Portal)lWorld.Portals[i]).Name; } output.Append(portalNames.JoinToString(", ")); player.Message(output.ToString()); } break; case "enable": case "on": player.PortalsEnabled = true; player.Message("You enabled the use of portals."); break; case "disable": case "off": player.PortalsEnabled = false; player.Message("You disabled the use of portals, type /portal enable to re-enable portals."); break; default: CdPortal.PrintUsage(player); break; } } catch (PortalException ex) { player.Message(ex.Message); Logger.Log(LogType.Error, "WorldCommands.PortalH: " + ex); } catch (Exception ex) { player.Message("Unexpected error: " + ex); Logger.Log(LogType.Error, "WorldCommands.PortalH: " + ex); } }
static void GenHandler( Player player, CommandReader cmd ) { World playerWorld = player.World; World world = null; string fileName = null; int mapWidth, mapLength, mapHeight; // make sure the player has generator parameters set MapGeneratorParameters genParams = player.GenParams; if( genParams == null ) { player.Message( "No gen parameters set. Use &H/SetGen&S to configure map generation." ); return; } if( cmd.HasNext ) { // Something's given, assume that it's map dimensions. if( !(cmd.NextInt( out mapWidth ) && cmd.NextInt( out mapLength ) && cmd.NextInt( out mapHeight )) ) { CdGen.PrintUsage( player ); return; } } else if( playerWorld != null ) { // Nothing is given. Assume that we're replacing the current world. // Use dimensions of the currently-loaded map. Map oldMap = playerWorld.LoadMap(); mapWidth = oldMap.Width; mapLength = oldMap.Length; mapHeight = oldMap.Height; world = playerWorld; } else { player.Message( "When used from console, /Gen requires map dimensions." ); CdGen.PrintUsage( player ); return; } // Check map dimensions and volume const string dimensionRecommendation = "Dimensions must be between 16 and 2047. " + "Recommended values: 16, 32, 64, 128, 256, 512, and 1024."; if( !Map.IsValidDimension( mapWidth ) ) { player.Message( "Cannot make map with width {0}. {1}", mapWidth, dimensionRecommendation ); return; } else if( !Map.IsValidDimension( mapLength ) ) { player.Message( "Cannot make map with length {0}. {1}", mapLength, dimensionRecommendation ); return; } else if( !Map.IsValidDimension( mapHeight ) ) { player.Message( "Cannot make map with height {0}. {1}", mapHeight, dimensionRecommendation ); return; } long volume = (long)mapWidth*mapLength*mapHeight; if( volume > Int32.MaxValue ) { player.Message( "Map volume may not exceed {0}", Int32.MaxValue ); return; } // Print dimension warning, if applicable. if( !cmd.IsConfirmed && // Only print once -- before confirmation is given. (!Map.IsRecommendedDimension( mapWidth ) || !Map.IsRecommendedDimension( mapLength ) || mapHeight%16 != 0) ) { player.Message( "&WThe map will have non-standard dimensions. " + "You may see glitched blocks or visual artifacts. " + "The only recommended map dimensions are: 16, 32, 64, 128, 256, 512, and 1024." ); } // See what else the player has given us... string givenName = cmd.Next(); if( givenName == null ) { // No name given. Assume that we're replacing the current world. if( playerWorld != null ) { world = playerWorld; if( !cmd.IsConfirmed ) { Logger.Log( LogType.UserActivity, "Gen: Asked {0} to confirm replacing the map of world {1} (\"this map\")", player.Name, playerWorld.Name ); player.Confirm( cmd, "Gen: Replace THIS MAP with a generated one ({0})?", genParams ); return; } } else { player.Message( "When used from console, /Gen requires a world name or map file name." ); CdGen.PrintUsage( player ); return; } } else { // Either a world name or a filename was given. Check worlds first. World existingWorld = WorldManager.FindWorldExact( givenName ); if( existingWorld != null ) { // A matching world name found. Assume that we're replacing it. if( !cmd.IsConfirmed ) { Logger.Log( LogType.UserActivity, "Gen: Asked {0} to confirm replacing the map of world {1}", player.Name, existingWorld.Name ); player.Confirm( cmd, "Gen: Replace the map of world {0}&S with a generated one ({1})?", existingWorld.ClassyName, genParams ); return; } world = existingWorld; } else { // No world with this name found. Assume that we were given a filename. givenName = givenName.Replace( Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar ); if( !givenName.EndsWith( ".fcm", StringComparison.OrdinalIgnoreCase ) ) { givenName += ".fcm"; } if( !Paths.IsValidPath( givenName ) ) { player.Message( "Gen: Invalid file name given." ); return; } fileName = Path.Combine( Paths.MapPath, givenName ); if( !Paths.Contains( Paths.MapPath, fileName ) ) { player.MessageUnsafePath(); return; } if( File.Exists( fileName ) ) { if( !cmd.IsConfirmed ) { Logger.Log( LogType.UserActivity, "Gen: Asked {0} to confirm overwriting map file \"{1}\"", player.Name, givenName ); player.Confirm( cmd, "Gen: The map file \"{0}\" already exists. Overwrite?", givenName ); return; } } } } // Warn players on the affected world, if applicable if( world != null ) { world.Players .Except( player ) .Message( "&SIncoming map change!" ); } // Prepare to generate genParams.MapWidth = mapWidth; genParams.MapLength = mapLength; genParams.MapHeight = mapHeight; GenTaskParams genTaskParams = new GenTaskParams { Player = player, World = world, FileName = givenName, FullFileName = fileName, GenState = genParams.CreateGenerator() }; player.MessageNow( "Generating (please wait): {0}", genParams ); // Do the rest in a background thread Scheduler.NewBackgroundTask( GenTaskCallback, genTaskParams ) .RunOnce(); }
private static void GenHandler(Player player, CommandReader cmd) { World playerWorld = player.World; string themeName = cmd.Next(); bool genOcean = false; bool genEmpty = false; bool noTrees = false; if (string.IsNullOrEmpty(themeName)) { CdGenerate.PrintUsage(player); return; } else { themeName = themeName.ToLower(); } MapGenTheme theme = MapGenTheme.Forest; MapGenTemplate template = MapGenTemplate.Flat; // parse special template names (which do not need a theme) if (themeName.Equals("ocean")) { genOcean = true; } else if (themeName.Equals("empty")) { genEmpty = true; } else { string templateName = cmd.Next(); if (templateName == null) { CdGenerate.PrintUsage(player); return; } // parse theme bool swapThemeAndTemplate = false; if (themeName.Equals("grass", StringComparison.OrdinalIgnoreCase)) { theme = MapGenTheme.Forest; noTrees = true; } else if (templateName.Equals("grass", StringComparison.OrdinalIgnoreCase)) { theme = MapGenTheme.Forest; noTrees = true; swapThemeAndTemplate = true; } else if (EnumUtil.TryParse(themeName, out theme, true)) { noTrees = (theme != MapGenTheme.Forest); } else if (EnumUtil.TryParse(templateName, out theme, true)) { noTrees = (theme != MapGenTheme.Forest); swapThemeAndTemplate = true; } else { player.Message("Gen: Unrecognized theme \"{0}\". Available themes are: Grass, {1}", themeName, Enum.GetNames(typeof (MapGenTheme)).JoinToString()); return; } // parse template if (swapThemeAndTemplate) { if (!EnumUtil.TryParse(themeName, out template, true)) { player.Message("Unrecognized template \"{0}\". Available terrain types: Empty, Ocean, {1}", themeName, Enum.GetNames(typeof (MapGenTemplate)).JoinToString()); return; } } else { if (!EnumUtil.TryParse(templateName, out template, true)) { player.Message("Unrecognized template \"{0}\". Available terrain types: Empty, Ocean, {1}", templateName, Enum.GetNames(typeof (MapGenTemplate)).JoinToString()); return; } } } // parse map dimensions int mapWidth, mapLength, mapHeight; if (cmd.HasNext) { int offset = cmd.Offset; if (!(cmd.NextInt(out mapWidth) && cmd.NextInt(out mapLength) && cmd.NextInt(out mapHeight))) { if (playerWorld != null) { Map oldMap = player.WorldMap; // If map dimensions were not given, use current map's dimensions mapWidth = oldMap.Width; mapLength = oldMap.Length; mapHeight = oldMap.Height; } else { player.Message("When used from console, /Gen requires map dimensions."); CdGenerate.PrintUsage(player); return; } cmd.Offset = offset; } } else if (playerWorld != null) { Map oldMap = player.WorldMap; // If map dimensions were not given, use current map's dimensions mapWidth = oldMap.Width; mapLength = oldMap.Length; mapHeight = oldMap.Height; } else { player.Message("When used from console, /Gen requires map dimensions."); CdGenerate.PrintUsage(player); return; } // Check map dimensions const string dimensionRecommendation = "Dimensions must be between 16 and 2047. " + "Recommended values: 16, 32, 64, 128, 256, 512, and 1024."; if (!Map.IsValidDimension(mapWidth)) { player.Message("Cannot make map with width {0}. {1}", mapWidth, dimensionRecommendation); return; } else if (!Map.IsValidDimension(mapLength)) { player.Message("Cannot make map with length {0}. {1}", mapLength, dimensionRecommendation); return; } else if (!Map.IsValidDimension(mapHeight)) { player.Message("Cannot make map with height {0}. {1}", mapHeight, dimensionRecommendation); return; } long volume = (long) mapWidth*mapLength*mapHeight; if (volume > Int32.MaxValue) { player.Message("Map volume may not exceed {0}", Int32.MaxValue); return; } if (!cmd.IsConfirmed && (!Map.IsRecommendedDimension(mapWidth) || !Map.IsRecommendedDimension(mapLength) || mapHeight%16 != 0)) { player.Message("&WThe map will have non-standard dimensions. " + "You may see glitched blocks or visual artifacts. " + "The only recommended map dimensions are: 16, 32, 64, 128, 256, 512, and 1024."); } // figure out full template name bool genFlatgrass = (theme == MapGenTheme.Forest && noTrees && template == MapGenTemplate.Flat); string templateFullName; if (genEmpty) { templateFullName = "Empty"; } else if (genOcean) { templateFullName = "Ocean"; } else if (genFlatgrass) { templateFullName = "Flatgrass"; } else { if (theme == MapGenTheme.Forest && noTrees) { templateFullName = "Grass " + template; } else { templateFullName = theme + " " + template; } } // check file/world name string fileName = cmd.Next(); string fullFileName = null; if (fileName == null) { // replacing current world if (playerWorld == null) { player.Message("When used from console, /Gen requires FileName."); CdGenerate.PrintUsage(player); return; } if (!cmd.IsConfirmed) { Logger.Log(LogType.UserActivity, "Gen: Asked {0} to confirm replacing the map of world {1} (\"this map\"). Request Denied because of Security Precautions In Place.", player.Name, playerWorld.Name); player.Confirm(cmd, "Replace THIS MAP with a generated one ({0})?", templateFullName); return; } } else if (fileName.ToLower().StartsWith("pw_")) { player.Message("You cannot make fake personal worlds"); return; } else { if (cmd.HasNext) { CdGenerate.PrintUsage(player); return; } // saving to file fileName = fileName.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); if (!fileName.EndsWith(".fcm", StringComparison.OrdinalIgnoreCase)) { fileName += ".fcm"; } if (!Paths.IsValidPath(fileName)) { player.Message("Invalid file name."); return; } fullFileName = Path.Combine(Paths.MapPath, fileName); if (!Paths.Contains(Paths.MapPath, fullFileName)) { player.MessageUnsafePath(); return; } string dirName = fullFileName.Substring(0, fullFileName.LastIndexOf(Path.DirectorySeparatorChar)); if (!Directory.Exists(dirName)) { Directory.CreateDirectory(dirName); } if (!cmd.IsConfirmed && File.Exists(fullFileName)) { Logger.Log(LogType.UserActivity, "Gen: Asked {0} to confirm overwriting map file \"{1}\"", player.Name, fileName); player.Confirm(cmd, "The mapfile \"{0}\" already exists. Overwrite?", fileName); return; } } // generate the map Map map; player.Message("Generating {0}...", templateFullName); if (genEmpty) { map = MapGenerator.GenerateEmpty(mapWidth, mapLength, mapHeight); } else if (genOcean) { map = MapGenerator.GenerateOcean(mapWidth, mapLength, mapHeight); } else if (genFlatgrass) { map = MapGenerator.GenerateFlatgrass(mapWidth, mapLength, mapHeight); } else { MapGeneratorArgs args = MapGenerator.MakeTemplate(template); if (theme == MapGenTheme.Desert) { args.AddWater = false; } float ratio = mapHeight/(float) args.MapHeight; args.MapWidth = mapWidth; args.MapLength = mapLength; args.MapHeight = mapHeight; args.MaxHeight = (int) Math.Round(args.MaxHeight*ratio); args.MaxDepth = (int) Math.Round(args.MaxDepth*ratio); args.SnowAltitude = (int) Math.Round(args.SnowAltitude*ratio); args.Theme = theme; args.AddTrees = !noTrees; MapGenerator generator = new MapGenerator(args); map = generator.Generate(); } Server.RequestGC(); // save map to file, or load it into a world if (fileName != null) { if (map.Save(fullFileName)) { player.Message("Generation done. Saved to {0}", fileName); } else { player.Message("&WAn error occurred while saving generated map to {0}", fileName); } } else { player.Message("Generation done. Changing map..."); playerWorld.MapChangedBy = player.Name; playerWorld.ChangeMap(map); } }
static void TeleportPHandler(Player player, CommandReader cmd) { int x, y, z; int rot = player.Position.R; int lot = player.Position.L; if (cmd.NextInt(out x) && cmd.NextInt(out y) && cmd.NextInt(out z)) { if (cmd.NextInt(out rot) && cmd.NextInt(out lot)) { if (rot < 0 || rot > 255) { player.Message("R must be inbetween 0 and 255, using player R"); rot = player.Position.R; } if (lot < 0 || lot > 255) { player.Message("L must be inbetween 0 and 255, using player L"); lot = player.Position.L; } } if (x < short.MinValue || x > short.MaxValue || y < short.MinValue || y > short.MaxValue || z < short.MinValue || z > short.MaxValue) { player.Message("Coordinates are outside the valid range!"); } else { if (player.World != null) { player.LastWorld = player.World; player.LastPosition = player.Position; } player.TeleportTo(new Position((short)x, (short)y, (short)z, (byte)rot, (byte)lot)); } } else { CdTeleportP.PrintUsage(player); } }
static void LPRHandler(Player player, CommandReader cmd) { string name = cmd.Next(); PlayerInfo[] infos; Rank rank = RankManager.FindRank(player.Info.Rank.Name); if (name != null) { rank = RankManager.FindRank(name); if (rank == null) { player.MessageNoRank(name); return; } } infos = PlayerDB.PlayerInfoList.Where(info => info.PreviousRank == rank).OrderBy(c => c.TimeSinceRankChange).ToArray(); int offset; if (!cmd.NextInt(out offset)) offset = 0; if (offset >= infos.Count()) { offset = Math.Max(0, infos.Count() - PlayersPerPage); } var playersPart = infos.Skip(offset).Take(10).ToArray(); player.MessagePrefixed("&S ", "&SPlayers who previously had rank ({1}&s): {0}", playersPart.JoinToString((r => String.Format("&n{0}&S (Had current rank ({2}&s) for: {1})", r.ClassyName, r.TimeSinceRankChange.ToMiniString(), r.Rank.ClassyName))), rank.ClassyName); player.Message("Showing players {0}-{1} (out of {2}).", offset + 1, offset + playersPart.Length, infos.Count()); }
static void RotateHandler([NotNull] Player player, [NotNull] CommandReader cmd) { CopyState originalInfo = player.GetCopyState(); if (originalInfo == null) { player.MessageNow("Nothing to rotate! Copy something first."); return; } int degrees; if (!cmd.NextInt(out degrees) || (degrees != 90 && degrees != -90 && degrees != 180 && degrees != 270)) { CdRotate.PrintUsage(player); return; } string axisName = cmd.Next(); Axis axis = Axis.Z; if (axisName != null) { switch (axisName.ToLower()) { case "x": axis = Axis.X; break; case "y": axis = Axis.Y; break; case "z": case "h": axis = Axis.Z; break; default: CdRotate.PrintUsage(player); return; } } // allocate the new buffer Block[,,] oldBuffer = originalInfo.Blocks; Block[,,] newBuffer; if (degrees == 180) { newBuffer = new Block[oldBuffer.GetLength(0), oldBuffer.GetLength(1), oldBuffer.GetLength(2)]; } else if (axis == Axis.X) { newBuffer = new Block[oldBuffer.GetLength(0), oldBuffer.GetLength(2), oldBuffer.GetLength(1)]; } else if (axis == Axis.Y) { newBuffer = new Block[oldBuffer.GetLength(2), oldBuffer.GetLength(1), oldBuffer.GetLength(0)]; } else { // axis == Axis.Z newBuffer = new Block[oldBuffer.GetLength(1), oldBuffer.GetLength(0), oldBuffer.GetLength(2)]; } // clone to avoid messing up any paste-in-progress CopyState info = new CopyState(originalInfo, newBuffer); // construct the rotation matrix int[,] matrix = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; int a, b; switch (axis) { case Axis.X: a = 1; b = 2; break; case Axis.Y: a = 0; b = 2; break; default: a = 0; b = 1; break; } switch (degrees) { case 90: matrix[a, a] = 0; matrix[b, b] = 0; matrix[a, b] = -1; matrix[b, a] = 1; break; case 180: matrix[a, a] = -1; matrix[b, b] = -1; break; case -90: case 270: matrix[a, a] = 0; matrix[b, b] = 0; matrix[a, b] = 1; matrix[b, a] = -1; break; } // apply the rotation matrix for (int x = oldBuffer.GetLength(0) - 1; x >= 0; x--) { for (int y = oldBuffer.GetLength(1) - 1; y >= 0; y--) { for (int z = oldBuffer.GetLength(2) - 1; z >= 0; z--) { int nx = (matrix[0, 0] < 0 ? oldBuffer.GetLength(0) - 1 - x : (matrix[0, 0] > 0 ? x : 0)) + (matrix[0, 1] < 0 ? oldBuffer.GetLength(1) - 1 - y : (matrix[0, 1] > 0 ? y : 0)) + (matrix[0, 2] < 0 ? oldBuffer.GetLength(2) - 1 - z : (matrix[0, 2] > 0 ? z : 0)); int ny = (matrix[1, 0] < 0 ? oldBuffer.GetLength(0) - 1 - x : (matrix[1, 0] > 0 ? x : 0)) + (matrix[1, 1] < 0 ? oldBuffer.GetLength(1) - 1 - y : (matrix[1, 1] > 0 ? y : 0)) + (matrix[1, 2] < 0 ? oldBuffer.GetLength(2) - 1 - z : (matrix[1, 2] > 0 ? z : 0)); int nz = (matrix[2, 0] < 0 ? oldBuffer.GetLength(0) - 1 - x : (matrix[2, 0] > 0 ? x : 0)) + (matrix[2, 1] < 0 ? oldBuffer.GetLength(1) - 1 - y : (matrix[2, 1] > 0 ? y : 0)) + (matrix[2, 2] < 0 ? oldBuffer.GetLength(2) - 1 - z : (matrix[2, 2] > 0 ? z : 0)); newBuffer[nx, ny, nz] = oldBuffer[x, y, z]; } } } player.Message("Rotated copy (slot {0}) by {1} degrees around {2} axis.", info.Slot + 1, degrees, axis); player.SetCopyState(info); }
static void SetFontHandler(Player player, CommandReader cmd) { string Param = cmd.Next(); if (Param == null) { CdSetFont.PrintUsage(player); return; } if (Param.ToLower() == "reset") { player.font = new Font("Times New Roman", 20, FontStyle.Regular); player.Message("SetFont: Font reverted back to default ({0} size {1})", player.font.FontFamily.Name, player.font.Size); return; } if (Param.ToLower() == "font") { string sectionName = cmd.NextAll(); if (!Directory.Exists(Paths.FontsPath)) { Directory.CreateDirectory(Paths.FontsPath); player.Message("There are no fonts available for this server. Font is set to default: {0}", player.font.FontFamily.Name); return; } string fontFileName = null; string[] sectionFiles = Directory.GetFiles(Paths.FontsPath, "*.ttf", SearchOption.TopDirectoryOnly); if (sectionName.Length < 1) { var sectionList = GetFontSectionList(); player.Message("{0} fonts Available: {1}", sectionList.Length, sectionList.JoinToString()); //print the folder contents return; } for (int i = 0; i < sectionFiles.Length; i++) { string sectionFullName = System.IO.Path.GetFileNameWithoutExtension(sectionFiles[i]); if (sectionFullName == null) continue; if (sectionFullName.StartsWith(sectionName, StringComparison.OrdinalIgnoreCase)) { if (sectionFullName.Equals(sectionName, StringComparison.OrdinalIgnoreCase)) { fontFileName = sectionFiles[i]; break; } else if (fontFileName == null) { fontFileName = sectionFiles[i]; } else { var matches = sectionFiles.Select(f => System.IO.Path.GetFileNameWithoutExtension(f)) .Where(sn => sn != null && sn.StartsWith(sectionName, StringComparison.OrdinalIgnoreCase)); player.Message("Multiple font files matched \"{0}\": {1}", sectionName, matches.JoinToString()); return; } } } if (fontFileName != null) { string sectionFullName = System.IO.Path.GetFileNameWithoutExtension(fontFileName); player.Message("Your font has changed to \"{0}\":", sectionFullName); //change font here player.font = new System.Drawing.Font(player.LoadFontFamily(fontFileName), player.font.Size); return; } else { var sectionList = GetFontSectionList(); if (sectionList == null) { player.Message("No fonts have been found."); } else { player.Message("No fonts found for \"{0}\". Available fonts: {1}", sectionName, sectionList.JoinToString()); } } } if (Param.ToLower() == "size") { int Size = -1; if (cmd.NextInt(out Size)) { if (Size < 5) { player.Message("&WIncorrect font size ({0}): Size needs to be at least 5(which is ideal for minecraft font, not the others)", Size); return; } player.Message("SetFont: Size changed from {0} to {1} ({2})", player.font.Size, Size, player.font.FontFamily.Name); player.font = new System.Drawing.Font(player.font.FontFamily, Size); } else { player.Message("&WInvalid size, use /SetFont Size FontSize. Example: /SetFont Size 14"); return; } return; } else { CdSetFont.PrintUsage(player); return; } }
static void Draw2DHandler(Player player, CommandReader cmd) { string Shape = cmd.Next(); if (Shape == null) { CdDraw2D.PrintUsage(player); return; } switch (Shape.ToLower()) { case "polygon": case "star": case "spiral": break; default: CdDraw2D.PrintUsage(player); return; } int radius = 0; int Points = 0; if (!cmd.NextInt(out radius)) { radius = 20; } if (!cmd.NextInt(out Points)) { Points = 5; } bool fill = true; if (cmd.HasNext) { if (!bool.TryParse(cmd.Next(), out fill)) { fill = true; } } Draw2DData tag = new Draw2DData() { Shape = Shape, Points = Points, Radius = radius, Fill = fill }; player.Message("Draw2D({0}): Click 2 blocks or use &H/Mark&S to set direction.", Shape); player.SelectionStart(2, Draw2DCallback, tag, Permission.DrawAdvanced); }
static void TreeHandler(Player player, CommandReader cmd) { string shapeName = cmd.Next(); int height; Forester.TreeShape shape; // that's one ugly if statement... does the job though. if (shapeName == null || !cmd.NextInt(out height) || !EnumUtil.TryParse(shapeName, out shape, true) || shape == Forester.TreeShape.Stickly || shape == Forester.TreeShape.Procedural) { CdTree.PrintUsage(player); player.Message("Available shapes: Normal, Bamboo, Palm, Cone, Round, Rainforest, Mangrove."); return; } if (height < 6 || height > 1024) { player.Message("Tree height must be 6 blocks or above"); return; } int volume = (int)Math.Pow(height, 3); if (!player.CanDraw(volume)) { player.Message(String.Format("You are only allowed to run commands that affect up to {0} blocks. This one would affect {1} blocks.", player.Info.Rank.DrawLimit, volume)); return; } Map map = player.World.Map; ForesterArgs args = new ForesterArgs { Height = height - 1, Operation = Forester.ForesterOperation.Add, Map = map, Shape = shape, TreeCount = 1, RootButtresses = false, Roots = Forester.RootMode.None, Rand = new Random() }; player.SelectionStart(1, TreeCallback, args, CdTree.Permissions); player.Message("Tree: Place a block or type /Mark to use your location."); }
static void TeleportHandler( Player player, CommandReader cmd ) { string name = cmd.Next(); if( name == null ) { CdTeleport.PrintUsage( player ); return; } if( cmd.Next() != null ) { cmd.Rewind(); int x, y, z; if( cmd.NextInt( out x ) && cmd.NextInt( out y ) && cmd.NextInt( out z ) ) { if( x <= -1024 || x >= 1024 || y <= -1024 || y >= 1024 || z <= -1024 || z >= 1024 ) { player.Message( "Coordinates are outside the valid range!" ); } else { player.TeleportTo( new Position { X = (short)(x * 32 + 16), Y = (short)(y * 32 + 16), Z = (short)(z * 32 + 16), R = player.Position.R, L = player.Position.L } ); } } else { CdTeleport.PrintUsage( player ); } } else { if( name == "-" ) { if( player.LastUsedPlayerName != null ) { name = player.LastUsedPlayerName; } else { player.Message( "Cannot repeat player name: you haven't used any names yet." ); return; } } Player[] matches = Server.FindPlayers( player, name, false, true, true ); if( matches.Length == 1 ) { Player target = matches[0]; World targetWorld = target.World; if( targetWorld == null ) PlayerOpException.ThrowNoWorld( target ); if( targetWorld == player.World ) { player.TeleportTo( target.Position ); } else { switch( targetWorld.AccessSecurity.CheckDetailed( player.Info ) ) { case SecurityCheckResult.Allowed: case SecurityCheckResult.WhiteListed: if( targetWorld.IsFull ) { player.Message( "Cannot teleport to {0}&S because world {1}&S is full.", target.ClassyName, targetWorld.ClassyName ); return; } player.StopSpectating(); player.JoinWorld( targetWorld, WorldChangeReason.Tp, target.Position ); break; case SecurityCheckResult.BlackListed: player.Message( "Cannot teleport to {0}&S because you are blacklisted on world {1}", target.ClassyName, targetWorld.ClassyName ); break; case SecurityCheckResult.RankTooLow: player.Message( "Cannot teleport to {0}&S because world {1}&S requires {2}+&S to join.", target.ClassyName, targetWorld.ClassyName, targetWorld.AccessSecurity.MinRank.ClassyName ); break; } } } else if( matches.Length > 1 ) { player.MessageManyMatches( "player", matches ); } else { player.MessageNoPlayer( name ); } } }
private static void PlaceHandler(Player player, CommandReader cmd) { bool isConsole = (player == Player.Console); if (isConsole && cmd.Count < 6) { player.Message("When used by console /Place requires a world name."); player.Message("/Place [x] [y] [z] [block] [world]"); return; } Block block = Block.Stone; if (!isConsole && player.LastUsedBlockType != Block.None) block = player.LastUsedBlockType; Vector3I coords; int x, y, z; if (cmd.NextInt(out x) && cmd.NextInt(out y) && cmd.NextInt(out z)) { if (cmd.HasNext) { string last = cmd.Next(); if (!Map.GetBlockByName(last, false, out block)) { player.Message("\"{0}\" is not a valid block type", last); return; } } coords = new Vector3I(x, y, z); } else if (isConsole) { player.Message("Invalid coordinates!"); return; } else { cmd.Rewind(); if (cmd.HasNext) { string last = cmd.Next(); if (!Map.GetBlockByName(last, false, out block)) { player.Message("\"{0}\" is not a valid block type", last); return; } } coords = new Vector3I(player.Position.X / 32, player.Position.Y / 32, (player.Position.Z - 64) / 32); } World world; if (player == Player.Console) { string worldName = cmd.Next(); if (string.IsNullOrEmpty(worldName)) { player.Message("Console must specify a world!"); } world = WorldManager.FindWorldOrPrintMatches(player, worldName); if (world == null) return; } else { world = player.World; } bool unLoad = false; if (!world.IsLoaded) { world.LoadMap(); unLoad = true; } coords.X = Math.Min(world.map.Width - 1, Math.Max(0, coords.X)); coords.Y = Math.Min(world.map.Length - 1, Math.Max(0, coords.Y)); coords.Z = Math.Min(world.map.Height - 1, Math.Max(0, coords.Z)); if (player == Player.Console) { BlockUpdate blockUpdate = new BlockUpdate(player, coords, block); player.Info.ProcessBlockPlaced((byte)block); world.map.QueueUpdate(blockUpdate); player.RaisePlayerPlacedBlockEvent(player, world.map, coords, block, world.map.GetBlock(coords), BlockChangeContext.Manual, true); } else { player.SendNow(Packet.MakeSetBlock(coords, block, player)); player.PlaceBlockWithEvents(coords, ClickAction.Build, block); } if (!isConsole) player.Message("{0} placed at {1}", block.ToString(), coords.ToString()); if (unLoad) { world.UnloadMap(true); } }
static void InfoHandler( Player player, CommandReader cmd ) { string name = cmd.Next(); if( name == null ) { // no name given, print own info PrintPlayerInfo( player, player.Info ); return; } else if( name.Equals( player.Name, StringComparison.OrdinalIgnoreCase ) ) { // own name given player.LastUsedPlayerName = player.Name; PrintPlayerInfo( player, player.Info ); return; } else if( !player.Can( Permission.ViewOthersInfo ) ) { // someone else's name or IP given, permission required. player.MessageNoAccess( Permission.ViewOthersInfo ); return; } // repeat last-typed name if( name == "-" ) { if( player.LastUsedPlayerName != null ) { name = player.LastUsedPlayerName; } else { player.Message( "Cannot repeat player name: you haven't used any names yet." ); return; } } PlayerInfo[] infos; IPAddress ip; if( name.Contains( "/" ) ) { // IP range matching (CIDR notation) string ipString = name.Substring( 0, name.IndexOf( '/' ) ); string rangeString = name.Substring( name.IndexOf( '/' ) + 1 ); byte range; if( IPAddressUtil.IsIP( ipString ) && IPAddress.TryParse( ipString, out ip ) && Byte.TryParse( rangeString, out range ) && range <= 32 ) { player.Message( "Searching {0}-{1}", ip.RangeMin( range ), ip.RangeMax( range ) ); infos = PlayerDB.FindPlayersCidr( ip, range ); } else { player.Message( "Info: Invalid IP range format. Use CIDR notation." ); return; } } else if( IPAddressUtil.IsIP( name ) && IPAddress.TryParse( name, out ip ) ) { // find players by IP infos = PlayerDB.FindPlayers( ip ); } else if( name.Equals( "*" ) ) { infos = (PlayerInfo[])PlayerDB.PlayerInfoList.Clone(); } else if( name.Contains( "*" ) || name.Contains( "?" ) ) { // find players by regex/wildcard string regexString = "^" + RegexNonNameChars.Replace( name, "" ).Replace( "*", ".*" ).Replace( "?", "." ) + "$"; Regex regex = new Regex( regexString, RegexOptions.IgnoreCase | RegexOptions.Compiled ); infos = PlayerDB.FindPlayers( regex ); } else if( name.StartsWith( "@" ) ) { string rankName = name.Substring( 1 ); Rank rank = RankManager.FindRank( rankName ); if( rank == null ) { player.MessageNoRank( rankName ); return; } else { infos = PlayerDB.PlayerInfoList .Where( info => info.Rank == rank ) .ToArray(); } } else if( name.StartsWith( "!" ) ) { // find online players by partial matches name = name.Substring( 1 ); infos = Server.FindPlayers( name, true ) .Select( p => p.Info ) .ToArray(); } else { // find players by partial matching PlayerInfo tempInfo; if( !PlayerDB.FindPlayerInfo( name, out tempInfo ) ) { infos = PlayerDB.FindPlayers( name ); } else if( tempInfo == null ) { player.MessageNoPlayer( name ); return; } else { infos = new[] { tempInfo }; } } Array.Sort( infos, new PlayerInfoComparer( player ) ); if( infos.Length == 1 ) { // only one match found; print it right away player.LastUsedPlayerName = infos[0].Name; PrintPlayerInfo( player, infos[0] ); } else if( infos.Length > 1 ) { // multiple matches found if( infos.Length <= PlayersPerPage ) { // all fit to one page player.MessageManyMatches( "player", infos ); } else { // pagination int offset; if( !cmd.NextInt( out offset ) ) offset = 0; if( offset >= infos.Length ) { offset = Math.Max( 0, infos.Length - PlayersPerPage ); } PlayerInfo[] infosPart = infos.Skip( offset ).Take( PlayersPerPage ).ToArray(); player.MessageManyMatches( "player", infosPart ); if( offset + infosPart.Length < infos.Length ) { // normal page player.Message( "Showing {0}-{1} (out of {2}). Next: &H/Info {3} {4}", offset + 1, offset + infosPart.Length, infos.Length, name, offset + infosPart.Length ); } else { // last page player.Message( "Showing matches {0}-{1} (out of {2}).", offset + 1, offset + infosPart.Length, infos.Length ); } } } else { // no matches found player.MessageNoPlayer( name ); } }
static void RollHandler( Player player, CommandReader cmd ) { if( player.Info.IsMuted ) { player.MessageMuted(); return; } if( player.DetectChatSpam() ) return; Random rand = new Random(); int n1; int min, max; if( cmd.NextInt( out n1 ) ) { int n2; if( !cmd.NextInt( out n2 ) ) { n2 = 1; } min = Math.Min( n1, n2 ); max = Math.Max( n1, n2 ); } else { min = 1; max = 100; } if( max == Int32.MaxValue - 1 ) { player.Message( "Roll: Given values must be between {0} and {1}", Int32.MinValue, Int32.MaxValue - 1 ); return; } int num = rand.Next( min, max + 1 ); Server.Message( player, "{0}{1} rolled {2} ({3}...{4})", player.ClassyName, Color.Silver, num, min, max ); player.Message( "{0}You rolled {1} ({2}...{3})", Color.Silver, num, min, max ); }
static void RotateHandler( Player player, CommandReader cmd ) { CopyState originalInfo = player.GetCopyState(); if( originalInfo == null ) { player.MessageNow( "Nothing to rotate! Copy something first." ); return; } int degrees; if( !cmd.NextInt( out degrees ) || (degrees != 90 && degrees != -90 && degrees != 180 && degrees != 270) ) { CdRotate.PrintUsage( player ); return; } string axisName = cmd.Next(); Axis axis = Axis.Z; if( axisName != null ) { switch( axisName.ToLower() ) { case "x": axis = Axis.X; break; case "y": axis = Axis.Y; break; case "z": case "h": axis = Axis.Z; break; default: CdRotate.PrintUsage( player ); return; } } // allocate the new buffer Block[, ,] oldBuffer = originalInfo.Blocks; Block[, ,] newBuffer; if( degrees == 180 ) { newBuffer = new Block[oldBuffer.GetLength( 0 ), oldBuffer.GetLength( 1 ), oldBuffer.GetLength( 2 )]; } else if( axis == Axis.X ) { newBuffer = new Block[oldBuffer.GetLength( 0 ), oldBuffer.GetLength( 2 ), oldBuffer.GetLength( 1 )]; } else if( axis == Axis.Y ) { newBuffer = new Block[oldBuffer.GetLength( 2 ), oldBuffer.GetLength( 1 ), oldBuffer.GetLength( 0 )]; } else { // axis == Axis.Z newBuffer = new Block[oldBuffer.GetLength( 1 ), oldBuffer.GetLength( 0 ), oldBuffer.GetLength( 2 )]; } // clone to avoid messing up any paste-in-progress CopyState info = new CopyState( originalInfo, newBuffer ); // construct the rotation matrix int[,] matrix = { {1,0,0}, {0,1,0}, {0,0,1} }; int a, b; switch( axis ) { case Axis.X: a = 1; b = 2; break; case Axis.Y: a = 0; b = 2; break; default: a = 0; b = 1; break; } switch( degrees ) { case 90: matrix[a, a] = 0; matrix[b, b] = 0; matrix[a, b] = -1; matrix[b, a] = 1; break; case 180: matrix[a, a] = -1; matrix[b, b] = -1; break; case -90: case 270: matrix[a, a] = 0; matrix[b, b] = 0; matrix[a, b] = 1; matrix[b, a] = -1; break; } // apply the rotation matrix for( int x = oldBuffer.GetLength( 0 ) - 1; x >= 0; x-- ) { for( int y = oldBuffer.GetLength( 1 ) - 1; y >= 0; y-- ) { for( int z = oldBuffer.GetLength( 2 ) - 1; z >= 0; z-- ) { int nx = (matrix[0, 0] < 0 ? oldBuffer.GetLength( 0 ) - 1 - x : (matrix[0, 0] > 0 ? x : 0)) + (matrix[0, 1] < 0 ? oldBuffer.GetLength( 1 ) - 1 - y : (matrix[0, 1] > 0 ? y : 0)) + (matrix[0, 2] < 0 ? oldBuffer.GetLength( 2 ) - 1 - z : (matrix[0, 2] > 0 ? z : 0)); int ny = (matrix[1, 0] < 0 ? oldBuffer.GetLength( 0 ) - 1 - x : (matrix[1, 0] > 0 ? x : 0)) + (matrix[1, 1] < 0 ? oldBuffer.GetLength( 1 ) - 1 - y : (matrix[1, 1] > 0 ? y : 0)) + (matrix[1, 2] < 0 ? oldBuffer.GetLength( 2 ) - 1 - z : (matrix[1, 2] > 0 ? z : 0)); int nz = (matrix[2, 0] < 0 ? oldBuffer.GetLength( 0 ) - 1 - x : (matrix[2, 0] > 0 ? x : 0)) + (matrix[2, 1] < 0 ? oldBuffer.GetLength( 1 ) - 1 - y : (matrix[2, 1] > 0 ? y : 0)) + (matrix[2, 2] < 0 ? oldBuffer.GetLength( 2 ) - 1 - z : (matrix[2, 2] > 0 ? z : 0)); newBuffer[nx, ny, nz] = oldBuffer[x, y, z]; } } } player.Message( "Rotated copy (slot {0}) by {1} degrees around {2} axis.", info.Slot + 1, degrees, axis ); player.SetCopyState( info ); }
static void TimerHandler( Player player, CommandReader cmd ) { string param = cmd.Next(); // List timers if( param == null ) { ChatTimer[] list = ChatTimer.TimerList.OrderBy( timer => timer.TimeLeft ).ToArray(); if( list.Length == 0 ) { player.Message( "No timers running." ); } else { player.Message( "There are {0} timers running:", list.Length ); foreach( ChatTimer timer in list ) { player.Message( " #{0} \"{1}&S\" (started by {2}, {3} left)", timer.ID, timer.Message, timer.StartedBy, timer.TimeLeft.ToMiniString() ); } } return; } // Abort a timer if( param.Equals( "abort", StringComparison.OrdinalIgnoreCase ) ) { int timerId; if( cmd.NextInt( out timerId ) ) { ChatTimer timer = ChatTimer.FindTimerById( timerId ); if( timer == null || !timer.IsRunning ) { player.Message( "Given timer (#{0}) does not exist.", timerId ); } else { timer.Abort(); string abortMsg = String.Format( "&Y(Timer) {0}&Y aborted a timer with {1} left: {2}", player.ClassyName, timer.TimeLeft.ToMiniString(), timer.Message ); Chat.SendSay( player, abortMsg ); } } else { CdTimer.PrintUsage( player ); } return; } // Start a timer if( player.Info.IsMuted ) { player.MessageMuted(); return; } if( player.DetectChatSpam() ) return; TimeSpan duration; if( !param.TryParseMiniTimespan( out duration ) ) { CdTimer.PrintUsage( player ); return; } if( duration > DateTimeUtil.MaxTimeSpan ) { player.MessageMaxTimeSpan(); return; } if( duration < ChatTimer.MinDuration ) { player.Message( "Timer: Must be at least 1 second." ); return; } string sayMessage; string message = cmd.NextAll(); if( String.IsNullOrEmpty( message ) ) { sayMessage = String.Format( "&Y(Timer) {0}&Y started a {1} timer", player.ClassyName, duration.ToMiniString() ); } else { sayMessage = String.Format( "&Y(Timer) {0}&Y started a {1} timer: {2}", player.ClassyName, duration.ToMiniString(), message ); } Chat.SendSay( player, sayMessage ); ChatTimer.Start( duration, message, player.Name ); }
static void CopySlotHandler( Player player, CommandReader cmd ) { int slotNumber; if( cmd.NextInt( out slotNumber ) ) { if( cmd.HasNext ) { CdCopySlot.PrintUsage( player ); return; } if( slotNumber < 1 || slotNumber > player.Info.Rank.CopySlots ) { player.Message( "CopySlot: Select a number between 1 and {0}", player.Info.Rank.CopySlots ); } else { player.CopySlot = slotNumber - 1; CopyState info = player.GetCopyState(); if( info == null ) { player.Message( "Selected copy slot {0} (unused).", slotNumber ); } else { player.Message( "Selected copy slot {0}: {1} blocks from {2}, {3} old.", slotNumber, info.Blocks.Length, info.OriginWorld, DateTime.UtcNow.Subtract( info.CopyTime ).ToMiniString() ); } } } else { CopyState[] slots = player.CopyStates; player.Message( "Using {0} of {1} slots. Selected slot: {2}", slots.Count( info => info != null ), player.Info.Rank.CopySlots, player.CopySlot + 1 ); for( int i = 0; i < slots.Length; i++ ) { if( slots[i] != null ) { player.Message( " {0}: {1} blocks from {2}, {3} old", i + 1, slots[i].Blocks.Length, slots[i].OriginWorld, DateTime.UtcNow.Subtract( slots[i].CopyTime ).ToMiniString() ); } } } }
static void InfoHandler( Player player, CommandReader cmd ) { string name = cmd.Next(); if( name == null ) { // no name given, print own info PrintPlayerInfo( player, player.Info ); return; } else if( name.Equals( player.Name, StringComparison.OrdinalIgnoreCase ) ) { // own name given player.LastUsedPlayerName = player.Name; PrintPlayerInfo( player, player.Info ); return; } else if( !player.Can( Permission.ViewOthersInfo ) ) { // someone else's name or IP given, permission required. player.MessageNoAccess( Permission.ViewOthersInfo ); return; } // repeat last-typed name if( name == "-" ) { if( player.LastUsedPlayerName != null ) { name = player.LastUsedPlayerName; } else { player.Message( "Cannot repeat player name: you haven't used any names yet." ); return; } } PlayerInfo[] infos; IPAddress ip; if( IPAddressUtil.IsIP( name ) && IPAddress.TryParse( name, out ip ) ) { // find players by IP infos = PlayerDB.FindByIP( ip ).ToArray(); } else if( name.Contains( "*" ) || name.Contains( "?" ) ) { // find players by regex/wildcard infos = PlayerDB.FindByPattern( name ).ToArray(); } else if( name.StartsWith( "@" ) ) { string rankName = name.Substring( 1 ); Rank rank = RankManager.FindRank( rankName ); if( rank == null ) { player.Message( "Unknown rank: {0}", rankName ); return; } else { using( PlayerDB.GetReadLock() ) { infos = PlayerDB.List .Where( info => info.Rank == rank ) .ToArray(); } } } else { // find players by partial matching PlayerInfo tempInfo; if( !PlayerDB.FindOneByPartialName( name, out tempInfo ) ) { infos = PlayerDB.FindByPartialName( name ).ToArray(); } else if( tempInfo == null ) { player.MessageNoPlayer( name ); return; } else { infos = new[] { tempInfo }; } } Array.Sort( infos, new PlayerInfoComparer( player ) ); if( infos.Length == 1 ) { // only one match found; print it right away player.LastUsedPlayerName = infos[0].Name; PrintPlayerInfo( player, infos[0] ); } else if( infos.Length > 1 ) { // multiple matches found if( infos.Length <= PlayersPerPage ) { // all fit to one page player.MessageManyMatches( "player", infos ); } else { // pagination int offset; if( !cmd.NextInt( out offset ) ) offset = 0; if( offset >= infos.Length ) { offset = Math.Max( 0, infos.Length - PlayersPerPage ); } PlayerInfo[] infosPart = infos.Skip( offset ).Take( PlayersPerPage ).ToArray(); player.MessageManyMatches( "player", infosPart ); if( offset + infosPart.Length < infos.Length ) { // normal page player.Message( "Showing {0}-{1} (out of {2}). Next: &H/Info {3} {4}", offset + 1, offset + infosPart.Length, infos.Length, name, offset + infosPart.Length ); } else { // last page player.Message( "Showing matches {0}-{1} (out of {2}).", offset + 1, offset + infosPart.Length, infos.Length ); } } } else { // no matches found player.MessageNoPlayer( name ); } }