public void AboutBlockchange(Player p, ushort x, ushort y, ushort z, ushort type)
        {
            if (!p.staticCommands)
            {
                p.ClearBlockchange();
            }
            ushort b = p.level.GetTile(x, y, z);

            if (b == Block.Zero)
            {
                Player.SendMessage(p, "Invalid Block(" + x + "," + y + "," + z + ")!"); return;
            }
            p.SendBlockchange(x, y, z, b);

            string message = "Block (" + x + "," + y + "," + z + "): ";

            message += "&f" + b + " = " + Block.Name(b);
            Player.SendMessage(p, message + Server.DefaultColor + ".");
            message = p.level.foundInfo(x, y, z);
            if (message != "")
            {
                Player.SendMessage(p, "Physics information: &a" + message);
            }

            string Username = "", TimePerformed = "", BlockUsed = "";
            bool   Deleted = false, foundOne = false;

            foreach (Blockchange bc in BlocksDB.blockchanges)
            {
                if (bc.level == p.level.name && bc.x == x && bc.y == y && bc.z == z)
                {
                    foundOne      = true;
                    Username      = bc.username;
                    TimePerformed = bc.timePerformed.ToString("HH:mm:ss (dd/MM/yy)");
                    BlockUsed     = Block.Name(bc.type);
                    Deleted       = bc.deleted;
                }
            }

            if (foundOne)
            {
                if (!Deleted)
                {
                    Player.SendMessage(p, "&3Created by " + Server.FindColor(Username.Trim()) + Username.Trim() + Server.DefaultColor + ", using &3" + BlockUsed);
                }
                else
                {
                    Player.SendMessage(p, "&4Destroyed by " + Server.FindColor(Username.Trim()) + Username.Trim() + Server.DefaultColor + ", using &3" + BlockUsed);
                }

                Player.SendMessage(p, "Date and time modified: &2" + TimePerformed);
            }
            else
            {
                List <Blockchange> inCache = p.level.blockCache.FindAll(bP => bP.x == x && bP.y == y && bP.z == z);

                for (int i = 0; i < inCache.Count; i++)
                {
                    foundOne      = true;
                    Deleted       = inCache[i].deleted;
                    Username      = inCache[i].username;
                    TimePerformed = inCache[i].timePerformed.ToString("HH:mm:ss (dd/MM/yy)");
                    BlockUsed     = Block.Name(inCache[i].type);
                }

                if (foundOne)
                {
                    if (!Deleted)
                    {
                        Player.SendMessage(p, "&3Created by " + Server.FindColor(Username.Trim()) + Username.Trim() + Server.DefaultColor + ", using &3" + BlockUsed);
                    }
                    else
                    {
                        Player.SendMessage(p, "&4Destroyed by " + Server.FindColor(Username.Trim()) + Username.Trim() + Server.DefaultColor + ", using &3" + BlockUsed);
                    }

                    Player.SendMessage(p, "Date and time modified: &2" + TimePerformed);
                }
            }

            if (!foundOne)
            {
                Player.SendMessage(p, "This block has not been modified since the map was cleared.");
            }

            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
예제 #2
0
        public override void Use(Player p, string message)
        {
            byte   b; Int64 seconds;
            Player who;

            Player.UndoPos Pos;
            int            CurrentPos = 0;
            bool           FoundUser  = false;

            if (message == "")
            {
                message = p.name + " 300";
            }

            if (message.Split(' ').Length == 2)
            {
                try
                {
                    seconds = Int64.Parse(message.Split(' ')[1]);
                }
                catch
                {
                    Player.SendMessage(p, "Invalid seconds.");
                    return;
                }
            }
            else
            {
                try
                {
                    seconds = int.Parse(message);
                    if (p != null)
                    {
                        message = p.name + " " + message;
                    }
                }
                catch
                {
                    seconds = 300;
                    message = message + " 300";
                }
            }

            if (seconds == 0)
            {
                seconds = 5400;
            }

            who = Player.Find(message.Split(' ')[0]);
            if (who != null)
            {
                message   = who.name + " " + seconds;
                FoundUser = true;
                for (CurrentPos = who.UndoBuffer.Count - 1; CurrentPos >= 0; --CurrentPos)
                {
                    try
                    {
                        Pos = who.UndoBuffer[CurrentPos];
                        Level foundLevel = Level.Find(Pos.mapName);
                        if (foundLevel == p.level)
                        {
                            b = foundLevel.GetTile(Pos.x, Pos.y, Pos.z);
                            if (Pos.timePlaced.AddSeconds(seconds) >= DateTime.Now)
                            {
                                if (b == Pos.newtype || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava)
                                {
                                    if (b == Block.air || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava)
                                    {
                                        p.SendBlockchange(Pos.x, Pos.y, Pos.z, Block.red);
                                    }
                                    else
                                    {
                                        p.SendBlockchange(Pos.x, Pos.y, Pos.z, Block.green);
                                    }
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                    catch { }
                }
            }

            try
            {
                DirectoryInfo di;
                string[]      fileContent;

                if (Directory.Exists("extra/undo/" + message.Split(' ')[0]))
                {
                    di = new DirectoryInfo("extra/undo/" + message.Split(' ')[0]);

                    for (int i = 0; i < di.GetFiles("*.undo").Length; i++)
                    {
                        fileContent = File.ReadAllText("extra/undo/" + message.Split(' ')[0] + "/" + i + ".undo").Split(' ');
                        highlightStuff(fileContent, seconds, p);
                    }
                    FoundUser = true;
                }

                if (Directory.Exists("extra/undoPrevious/" + message.Split(' ')[0]))
                {
                    di = new DirectoryInfo("extra/undoPrevious/" + message.Split(' ')[0]);

                    for (int i = 0; i < di.GetFiles("*.undo").Length; i++)
                    {
                        fileContent = File.ReadAllText("extra/undoPrevious/" + message.Split(' ')[0] + "/" + i + ".undo").Split(' ');
                        highlightStuff(fileContent, seconds, p);
                    }
                    FoundUser = true;
                }

                if (FoundUser)
                {
                    Player.SendMessage(p, "Now highlighting &b" + seconds + Server.DefaultColor + " seconds for " + Server.FindColor(message.Split(' ')[0]) + message.Split(' ')[0]);
                    Player.SendMessage(p, "&cUse /reveal to un-highlight");
                }
                else
                {
                    Player.SendMessage(p, "Could not find player specified.");
                }
            }
            catch (Exception e)
            {
                Server.ErrorLog(e);
            }
        }
예제 #3
0
        public override void Use(Player p, string message)
        {
            if (message.Split(' ').Length > 2) { Help(p); return; }
            // /awards
            // /awards 1
            // /awards bob
            // /awards bob 1

            int totalCount = 0;
            string foundPlayer = "";

            if (message != "")
            {
                if (message.Split(' ').Length == 2)
                {
                    foundPlayer = message.Split(' ')[0];
                    Player who = Player.Find(foundPlayer);
                    if (who != null) foundPlayer = who.name;
                    try
                    {
                        totalCount = int.Parse(message.Split(' ')[1]);
                    }
                    catch
                    {
                        Help(p);
                        return;
                    }
                }
                else
                {
                    if (message.Length <= 3)
                    {
                        try
                        {
                            totalCount = int.Parse(message);
                        }
                        catch
                        {
                            foundPlayer = message;
                            Player who = Player.Find(foundPlayer);
                            if (who != null) foundPlayer = who.name;
                        }
                    }
                    else
                    {
                        foundPlayer = message;
                        Player who = Player.Find(foundPlayer);
                        if (who != null) foundPlayer = who.name;
                    }
                }
            }

            if (totalCount < 0)
            {
                Player.SendMessage(p, "Cannot display pages less than 0");
                return;
            }

            List<Awards.awardData> awardList = new List<Awards.awardData>();
            if (foundPlayer == "")
            {
                awardList = Awards.allAwards;
            }
            else
            {
                foreach (string s in Awards.getPlayersAwards(foundPlayer))
                {
                    Awards.awardData aD = new Awards.awardData();
                    aD.awardName = s;
                    aD.description = Awards.getDescription(s);
                    awardList.Add(aD);
                }
            }

            if (awardList.Count == 0)
            {
                if (foundPlayer != "")
                    Player.SendMessage(p, "The player has no awards!");
                else
                    Player.SendMessage(p, "There are no awards in this server yet");

                return;
            }

            int max = totalCount * 5;
            int start = (totalCount - 1) * 5;
            if (start > awardList.Count)
            {
                Player.SendMessage(p, "There aren't that many awards. Enter a smaller number");
                return;
            }
            if (max > awardList.Count) 
                max = awardList.Count;

            if (foundPlayer != "")
                Player.SendMessage(p, Server.FindColor(foundPlayer) + foundPlayer + Server.DefaultColor + " has the following awards:");
            else
                Player.SendMessage(p, "Awards available: ");

            if (totalCount == 0)
            {
                foreach (Awards.awardData aD in awardList)
                    Player.SendMessage(p, "&6" + aD.awardName + ": &7" + aD.description);

                if (awardList.Count > 8) Player.SendMessage(p, "&5Use &b/awards " + message + " 1/2/3/... &5for a more ordered list");
            }
            else
            {
                for (int i = start; i < max; i++)
                {
                    Awards.awardData aD = awardList[i];
                    Player.SendMessage(p, "&6" + aD.awardName + ": &7" + aD.description);
                }
            }
        }
예제 #4
0
        int MAX = -1; // This is the value changed to MAX in the Undo list, and used to allow everything undone.

        public override void Use(Player p, string message)
        {
            byte b; long seconds = -2; Player who = null; Player.UndoPos Pos; int CurrentPos = 0; bool undoPhysics = false; string whoName = String.Empty;

            if (p != null)
            {
                p.RedoBuffer.Clear();
            }

            if (message == "")
            {
                if (p == null)
                {
                    Player.SendMessage(null, "Console doesn't have an undo buffer.");
                    return;
                }
                else
                {
                    message = p.name.ToLower() + " 30";
                }
            }

            try {
                if (message.Split(' ').Length > 1)
                {
                    whoName     = message.Split(' ')[0];
                    who         = message.Split(' ')[0].ToLower() == "physics" ? null : Player.Find(message.Split(' ')[0]);
                    undoPhysics = message.Split(' ')[0].ToLower() == "physics";
                    message     = message.Split(' ')[1].ToLower();
                }
                else
                {
                    who         = (p == null || message.ToLower() == "physics") ? null : p;
                    undoPhysics = message.ToLower() == "physics";
                }
                //If user is undoing him/herself, then all is go.
                //If user is undoing someone else, then restrictions are used.
                if (p == who)
                {
                    seconds = ((message.ToLower() != "all") ? long.Parse(message) : int.MaxValue);
                }
                else
                {
                    seconds = getAllowed(p, message.ToLower());
                }
            } catch {
                Player.SendMessage(p, "Invalid seconds, or you're unable to use /xundo. Using 30 seconds."); //only run if seconds is an invalid number
                seconds = 30;
            }

            //At this point, we know the number is valid, and allowed for the particular person's group.
            if (who != null)
            {
                if (p != null)
                {
                    if (who.group.Permission > p.group.Permission && who != p)
                    {
                        Player.SendMessage(p, "Cannot undo a user of higher or equal rank"); return;
                    }
                    if (who != p && (int)p.group.Permission < CommandOtherPerms.GetPerm(this, 1))
                    {
                        Player.SendMessage(p, "Only an " + Group.findPermInt(CommandOtherPerms.GetPerm(this, 1)).name + "+ may undo other people's actions"); return;
                    }
                }

                for (CurrentPos = who.UndoBuffer.Count - 1; CurrentPos >= 0; --CurrentPos)
                {
                    try {
                        Pos = who.UndoBuffer[CurrentPos];
                        Level foundLevel = Level.FindExact(Pos.mapName);
                        b = foundLevel.GetTile(Pos.x, Pos.y, Pos.z);
                        if (Pos.timePlaced.AddSeconds(seconds) >= DateTime.Now)
                        {
                            if (b == Pos.newtype || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava)
                            {
                                foundLevel.Blockchange(Pos.x, Pos.y, Pos.z, Pos.type, true);

                                Pos.newtype = Pos.type; Pos.type = b;
                                if (p != null)
                                {
                                    p.RedoBuffer.Add(Pos);
                                }
                                who.UndoBuffer.RemoveAt(CurrentPos);
                            }
                        }
                        else
                        {
                            break;
                        }
                    } catch { }
                }

                if (p == who)
                {
                    Player.SendMessage(p, "Undid your actions for the past &b" + seconds + Server.DefaultColor + " seconds.");
                }
                else
                {
                    Player.GlobalChat(who, who.color + who.name + Server.DefaultColor + "'s actions for the past &b" + seconds + " seconds were undone.", false);
                    // Also notify console
                    Server.s.Log(who.name + "'s actions for the past " + seconds + " seconds were undone.");
                }
                return;
            }
            else if (undoPhysics)
            {
                if ((int)p.group.Permission < CommandOtherPerms.GetPerm(this, 2))
                {
                    Player.SendMessage(p, "Reserved for " + Group.findPermInt(CommandOtherPerms.GetPerm(this, 2)).name + "+"); return;
                }
                if (!p.group.CanExecute(Command.all.Find("physics")))
                {
                    Player.SendMessage(p, "You can only undo physics if you can use them."); return;
                }

                Command.all.Find("physics").Use(p, "0");
                Level.UndoPos uP;
                ushort        x, y, z;

                if (p.level.UndoBuffer.Count != Server.physUndo)
                {
                    for (CurrentPos = p.level.currentUndo; CurrentPos >= 0; CurrentPos--)
                    {
                        try {
                            uP = p.level.UndoBuffer[CurrentPos];
                            b  = p.level.GetTile(uP.location);
                            if (uP.timePerformed.AddSeconds(seconds) >= DateTime.Now)
                            {
                                if (b == uP.newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava)
                                {
                                    p.level.IntToPos(uP.location, out x, out y, out z);
                                    p.level.Blockchange(p, x, y, z, uP.oldType, true);
                                }
                            }
                            else
                            {
                                break;
                            }
                        } catch { }
                    }
                }
                else
                {
                    for (CurrentPos = p.level.currentUndo; CurrentPos != p.level.currentUndo + 1; CurrentPos--)
                    {
                        try {
                            if (CurrentPos < 0)
                            {
                                CurrentPos = p.level.UndoBuffer.Count - 1;
                            }
                            uP = p.level.UndoBuffer[CurrentPos];
                            b  = p.level.GetTile(uP.location);
                            if (uP.timePerformed.AddSeconds(seconds) >= DateTime.Now)
                            {
                                if (b == uP.newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava)
                                {
                                    p.level.IntToPos(uP.location, out x, out y, out z);
                                    p.level.Blockchange(p, x, y, z, uP.oldType, true);
                                }
                            }
                            else
                            {
                                break;
                            }
                        } catch { }
                    }
                }

                Player.GlobalMessage("Physics were undone &b" + seconds + Server.DefaultColor + " seconds");
                // Also notify console
                Player.SendMessage(null, "Physics were undone &b" + seconds + Server.DefaultColor + " seconds");
            }
            else     // Here, who == null, meaning the user specified is offline
            {
                if (p != null)
                {
                    if ((int)p.group.Permission < CommandOtherPerms.GetPerm(this, 1))
                    {
                        Player.SendMessage(p, "Reserved for " + Group.findPermInt(CommandOtherPerms.GetPerm(this, 1)).name + "+"); return;
                    }
                    // ^^^ is using the same as the 1st other permission for the this command because the only difference is that this is for offline players so it might aswell be the same!!
                }

                bool FoundUser = false;

                try {
                    DirectoryInfo di;
                    string[]      fileContent;

                    if (p != null)
                    {
                        p.RedoBuffer.Clear();
                    }

                    if (Directory.Exists("extra/undo/" + whoName.ToLower()))
                    {
                        di = new DirectoryInfo("extra/undo/" + whoName.ToLower());

                        for (int i = di.GetFiles("*.undo").Length - 1; i >= 0; i--)
                        {
                            fileContent = File.ReadAllText("extra/undo/" + whoName.ToLower() + "/" + i + ".undo").Split(' ');
                            if (!undoBlah(fileContent, seconds, p))
                            {
                                break;
                            }
                        }
                        FoundUser = true;
                    }

                    if (Directory.Exists("extra/undoPrevious/" + whoName.ToLower()))
                    {
                        di = new DirectoryInfo("extra/undoPrevious/" + whoName.ToLower());

                        for (int i = di.GetFiles("*.undo").Length - 1; i >= 0; i--)
                        {
                            fileContent = File.ReadAllText("extra/undoPrevious/" + whoName.ToLower() + "/" + i + ".undo").Split(' ');
                            if (!undoBlah(fileContent, seconds, p))
                            {
                                break;
                            }
                        }
                        FoundUser = true;
                    }

                    if (FoundUser)
                    {
                        Player.GlobalMessage(Server.FindColor(whoName) + whoName + Server.DefaultColor + "'s actions for the past &b" + seconds + Server.DefaultColor + " seconds were undone.");
                        // Also notify console
                        Server.s.Log(whoName + "'s actions for the past " + seconds + " seconds were undone.");
                    }
                    else
                    {
                        Player.SendMessage(p, "Could not find player specified.");
                    }
                } catch (Exception e) {
                    Server.ErrorLog(e);
                }
            }
        }
예제 #5
0
        public override void Use(Player p, string message)
        {
            if (message == "" || message.IndexOf(' ') == -1)
            {
                Help(p); return;
            }

            bool give = true;

            if (message.Split(' ')[0].ToLower() == "give")
            {
                give    = true;
                message = message.Substring(message.IndexOf(' ') + 1);
            }
            else if (message.Split(' ')[0].ToLower() == "take")
            {
                give    = false;
                message = message.Substring(message.IndexOf(' ') + 1);
            }

            string foundPlayer = message.Split(' ')[0];
            Player who         = Player.Find(message);

            if (who != null)
            {
                foundPlayer = who.name;
            }
            string awardName = message.Substring(message.IndexOf(' ') + 1);

            if (!Awards.awardExists(awardName))
            {
                Player.SendMessage(p, "The award you entered doesn't exist");
                Player.SendMessage(p, "Use /awards for a list of awards");
                return;
            }

            if (give)
            {
                if (Awards.giveAward(foundPlayer, awardName))
                {
                    Player.GlobalMessage(Server.FindColor(foundPlayer) + foundPlayer + Server.DefaultColor + " was awarded: &b" + Awards.camelCase(awardName));
                }
                else
                {
                    Player.SendMessage(p, "The player already has that award!");
                }
            }
            else
            {
                if (Awards.takeAward(foundPlayer, awardName))
                {
                    Player.GlobalMessage(Server.FindColor(foundPlayer) + foundPlayer + Server.DefaultColor + " had their &b" + Awards.camelCase(awardName) + Server.DefaultColor + " award removed");
                }
                else
                {
                    Player.SendMessage(p, "The player didn't have the award you tried to take");
                }
            }

            Awards.Save();
        }
예제 #6
0
        public void AboutBlockchange(Player p, ushort x, ushort y, ushort z, byte type)
        {
            if (!p.staticCommands)
            {
                p.ClearBlockchange();
            }
            byte b = p.level.GetTile(x, y, z);

            if (b == Block.Zero)
            {
                Player.SendMessage(p, "Invalid Block(" + x + "," + y + "," + z + ")!"); return;
            }
            p.SendBlockchange(x, y, z, b);

            string message = "Block (" + x + "," + y + "," + z + "): ";

            message += "&f" + b + " = " + Block.Name(b);
            Player.SendMessage(p, message + Server.DefaultColor + ".");
            message = p.level.foundInfo(x, y, z);
            if (message != "")
            {
                Player.SendMessage(p, "Physics information: &a" + message);
            }

            DataTable Blocks = Server.useMySQL ? MySQL.fillData("SELECT * FROM `Block" + p.level.name + "` WHERE X=" + (int)x + " AND Y=" + (int)y + " AND Z=" + (int)z) : SQLite.fillData("SELECT * FROM Block" + p.level.name + " WHERE X=" + (int)x + " AND Y=" + (int)y + " AND Z=" + (int)z);

            string Username, TimePerformed, BlockUsed;
            bool   Deleted, foundOne = false;

            for (int i = 0; i < Blocks.Rows.Count; i++)
            {
                foundOne      = true;
                Username      = Blocks.Rows[i]["Username"].ToString();
                TimePerformed = DateTime.Parse(Blocks.Rows[i]["TimePerformed"].ToString()).ToString("yyyy-MM-dd HH:mm:ss");
                //Server.s.Log(Blocks.Rows[i]["Type"].ToString());
                BlockUsed = Block.Name(Convert.ToByte(Blocks.Rows[i]["Type"])).ToString();
                Deleted   = Convert.ToBoolean(Blocks.Rows[i]["Deleted"]);

                if (!Deleted)
                {
                    Player.SendMessage(p, "&3Created by " + Server.FindColor(Username.Trim()) + Username.Trim() + Server.DefaultColor + ", using &3" + BlockUsed);
                }
                else
                {
                    Player.SendMessage(p, "&4Destroyed by " + Server.FindColor(Username.Trim()) + Username.Trim() + Server.DefaultColor + ", using &3" + BlockUsed);
                }
                Player.SendMessage(p, "Date and time modified: &2" + TimePerformed);
            }

            List <Level.BlockPos> inCache = p.level.blockCache.FindAll(bP => bP.x == x && bP.y == y && bP.z == z);

            for (int i = 0; i < inCache.Count; i++)
            {
                foundOne      = true;
                Deleted       = inCache[i].deleted;
                Username      = inCache[i].name;
                TimePerformed = inCache[i].TimePerformed.ToString("yyyy-MM-dd HH:mm:ss");
                BlockUsed     = Block.Name(inCache[i].type);

                if (!Deleted)
                {
                    Player.SendMessage(p, "&3Created by " + Server.FindColor(Username.Trim()) + Username.Trim() + Server.DefaultColor + ", using &3" + BlockUsed);
                }
                else
                {
                    Player.SendMessage(p, "&4Destroyed by " + Server.FindColor(Username.Trim()) + Username.Trim() + Server.DefaultColor + ", using &3" + BlockUsed);
                }
                Player.SendMessage(p, "Date and time modified: &2" + TimePerformed);
            }

            if (!foundOne)
            {
                Player.SendMessage(p, "This block has not been modified since the map was cleared.");
            }

            Blocks.Dispose();

            GC.Collect();
            GC.WaitForPendingFinalizers();
        }
예제 #7
0
        public override void Use(Player p, string message)
        {
            byte b; Int64 seconds; Player who; Player.UndoPos Pos; int CurrentPos = 0;

            if (p != null)
            {
                p.RedoBuffer.Clear();
            }

            if (message == "")
            {
                if (p == null)
                {
                    Player.SendMessage(null, "Console doesn't have an undo buffer.");
                    return;
                }
                else
                {
                    message = p.name + " 30";
                }
            }

            if (message.Split(' ').Length == 2)
            {
                if (message.Split(' ')[1].ToLower() == "all" && p == null)
                {
                    seconds = 500000;
                }
                else if (message.Split(' ')[1].ToLower() == "all" && p.group.Permission > LevelPermission.Operator)
                {
                    seconds = 500000;
                }
                else
                {
                    try
                    {
                        seconds = Int64.Parse(message.Split(' ')[1]);
                    }
                    catch
                    {
                        Player.SendMessage(p, "Invalid seconds.");
                        return;
                    }
                }
            }
            else
            {
                try
                {
                    seconds = int.Parse(message);
                    if (p != null)
                    {
                        message = p.name + " " + message;
                    }
                }
                catch
                {
                    seconds = 30;
                    message = message + " 30";
                }
            }

            //if (message.Split(' ').Length == 1) if (char.IsDigit(message, 0)) { message = p.name + " " + message; } else { message = message + " 30"; }

            //try { seconds = Convert.ToInt16(message.Split(' ')[1]); } catch { seconds = 2; }
            if (seconds == 0)
            {
                seconds = 5400;
            }

            who = Player.Find(message.Split(' ')[0]);
            if (who != null)
            {
                if (p != null)
                {
                    if (who.group.Permission > p.group.Permission && who != p)
                    {
                        Player.SendMessage(p, "Cannot undo a user of higher or equal rank"); return;
                    }
                    if (who != p && p.group.Permission < LevelPermission.Operator)
                    {
                        Player.SendMessage(p, "Only an OP+ may undo other people's actions"); return;
                    }

                    if (p.group.Permission < LevelPermission.Builder && seconds > 120)
                    {
                        Player.SendMessage(p, "Guests may only undo 2 minutes."); return;
                    }
                    else if (p.group.Permission < LevelPermission.AdvBuilder && seconds > 300)
                    {
                        Player.SendMessage(p, "Builders may only undo 300 seconds."); return;
                    }
                    else if (p.group.Permission < LevelPermission.Operator && seconds > 1200)
                    {
                        Player.SendMessage(p, "AdvBuilders may only undo 600 seconds."); return;
                    }
                    else if (p.group.Permission == LevelPermission.Operator && seconds > 5400)
                    {
                        Player.SendMessage(p, "Operators may only undo 5400 seconds."); return;
                    }
                }

                for (CurrentPos = who.UndoBuffer.Count - 1; CurrentPos >= 0; --CurrentPos)
                {
                    try
                    {
                        Pos = who.UndoBuffer[CurrentPos];
                        Level foundLevel = Level.FindExact(Pos.mapName);
                        b = foundLevel.GetTile(Pos.x, Pos.y, Pos.z);
                        if (Pos.timePlaced.AddSeconds(seconds) >= DateTime.Now)
                        {
                            if (b == Pos.newtype || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava)
                            {
                                foundLevel.Blockchange(Pos.x, Pos.y, Pos.z, Pos.type, true);

                                Pos.newtype = Pos.type; Pos.type = b;
                                if (p != null)
                                {
                                    p.RedoBuffer.Add(Pos);
                                }
                                who.UndoBuffer.RemoveAt(CurrentPos);
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    catch { }
                }

                if (p == who)
                {
                    Player.SendMessage(p, "Undid your actions for the past &b" + seconds + Server.DefaultColor + " seconds.");
                }
                else
                {
                    Player.GlobalChat(p, who.color + who.name + Server.DefaultColor + "'s actions for the past &b" + seconds + " seconds were undone.", false);
                    // Also notify console
                    Player.SendMessage(null, who.color + who.name + Server.DefaultColor + "'s actions for the past &b" + seconds + " seconds were undone.");
                }
                return;
            }
            else if (message.Split(' ')[0].ToLower() == "physics")
            {
                if (p.group.Permission < LevelPermission.AdvBuilder)
                {
                    Player.SendMessage(p, "Reserved for Adv+"); return;
                }
                else if (p.group.Permission < LevelPermission.Operator && seconds > 1200)
                {
                    Player.SendMessage(p, "AdvBuilders may only undo 1200 seconds."); return;
                }
                else if (p.group.Permission == LevelPermission.Operator && seconds > 5400)
                {
                    Player.SendMessage(p, "Operators may only undo 5400 seconds."); return;
                }

                Command.all.Find("physics").Use(p, "0");
                Level.UndoPos uP;
                ushort        x, y, z;

                if (p.level.UndoBuffer.Count != Server.physUndo)
                {
                    for (CurrentPos = p.level.currentUndo; CurrentPos >= 0; CurrentPos--)
                    {
                        try
                        {
                            uP = p.level.UndoBuffer[CurrentPos];
                            b  = p.level.GetTile(uP.location);
                            if (uP.timePerformed.AddSeconds(seconds) >= DateTime.Now)
                            {
                                if (b == uP.newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava)
                                {
                                    p.level.IntToPos(uP.location, out x, out y, out z);
                                    p.level.Blockchange(p, x, y, z, uP.oldType, true);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        catch { }
                    }
                }
                else
                {
                    for (CurrentPos = p.level.currentUndo; CurrentPos != p.level.currentUndo + 1; CurrentPos--)
                    {
                        try
                        {
                            if (CurrentPos < 0)
                            {
                                CurrentPos = p.level.UndoBuffer.Count - 1;
                            }
                            uP = p.level.UndoBuffer[CurrentPos];
                            b  = p.level.GetTile(uP.location);
                            if (uP.timePerformed.AddSeconds(seconds) >= DateTime.Now)
                            {
                                if (b == uP.newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava)
                                {
                                    p.level.IntToPos(uP.location, out x, out y, out z);
                                    p.level.Blockchange(p, x, y, z, uP.oldType, true);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        catch { }
                    }
                }

                Player.GlobalMessage("Physics were undone &b" + seconds + Server.DefaultColor + " seconds");
                // Also notify console
                Player.SendMessage(null, "Physics were undone &b" + seconds + Server.DefaultColor + " seconds");
            }
            else
            {
                if (p != null)
                {
                    if (p.group.Permission < LevelPermission.Operator)
                    {
                        Player.SendMessage(p, "Reserved for OP+"); return;
                    }
                    if (seconds > 5400 && p.group.Permission == LevelPermission.Operator)
                    {
                        Player.SendMessage(p, "Only SuperOPs may undo more than 90 minutes."); return;
                    }
                }

                bool FoundUser = false;

                try
                {
                    DirectoryInfo di;
                    string[]      fileContent;

                    if (p != null)
                    {
                        p.RedoBuffer.Clear();
                    }

                    if (Directory.Exists("extra/undo/" + message.Split(' ')[0]))
                    {
                        di = new DirectoryInfo("extra/undo/" + message.Split(' ')[0]);

                        for (int i = di.GetFiles("*.undo").Length - 1; i >= 0; i--)
                        {
                            fileContent = File.ReadAllText("extra/undo/" + message.Split(' ')[0] + "/" + i + ".undo").Split(' ');
                            if (!undoBlah(fileContent, seconds, p))
                            {
                                break;
                            }
                        }
                        FoundUser = true;
                    }

                    if (Directory.Exists("extra/undoPrevious/" + message.Split(' ')[0]))
                    {
                        di = new DirectoryInfo("extra/undoPrevious/" + message.Split(' ')[0]);

                        for (int i = di.GetFiles("*.undo").Length - 1; i >= 0; i--)
                        {
                            fileContent = File.ReadAllText("extra/undoPrevious/" + message.Split(' ')[0] + "/" + i + ".undo").Split(' ');
                            if (!undoBlah(fileContent, seconds, p))
                            {
                                break;
                            }
                        }
                        FoundUser = true;
                    }

                    if (FoundUser)
                    {
                        Player.GlobalChat(p, Server.FindColor(message.Split(' ')[0]) + message.Split(' ')[0] + Server.DefaultColor + "'s actions for the past &b" + seconds + Server.DefaultColor + " seconds were undone.", false);
                        // Also notify console
                        Player.SendMessage(null, Server.FindColor(message.Split(' ')[0]) + message.Split(' ')[0] + Server.DefaultColor + "'s actions for the past &b" + seconds + Server.DefaultColor + " seconds were undone.");
                    }
                    else
                    {
                        Player.SendMessage(p, "Could not find player specified.");
                    }
                }
                catch (Exception e)
                {
                    Server.ErrorLog(e);
                }
            }
        }