예제 #1
0
        public void Blockchange(Player p, ushort x, ushort y, ushort z, byte type, byte extType = 0) {
            string errorLocation = "start";
        retry:
            try
            {
                if (x < 0 || y < 0 || z < 0) return;
                if (x >= Width || y >= Height || z >= Length) return;
                byte b = GetTile(x, y, z), extB = 0;
                if (b == Block.custom_block)
                	extB = GetExtTile(x, y, z);

                errorLocation = "Permission checking";
                if (!CheckAffectPermissions(p, x, y, z, b, type, extType)) {
                    p.RevertBlock(x, y, z); return;
                }

                if (b == Block.sponge && physics > 0 && type != Block.sponge)
                    PhysSpongeRemoved(PosToInt(x, y, z));
                if (b == Block.lava_sponge && physics > 0 && type != Block.lava_sponge)
                    PhysSpongeRemoved(PosToInt(x, y, z), true);

                errorLocation = "Undo buffer filling";
                Player.UndoPos Pos;
                Pos.x = x; Pos.y = y; Pos.z = z;
                Pos.mapName = name;
                Pos.type = b; Pos.extType = extB;
                Pos.newtype = type; Pos.newExtType = extType;
                Pos.timePlaced = DateTime.Now;
                p.UndoBuffer.Add(Pos);

                errorLocation = "Setting tile";
                p.loginBlocks++;
                p.overallBlocks++;
                SetTile(x, y, z, type);
                if (b == Block.custom_block && type != Block.custom_block)
                	RevertExtTileNoCheck(x, y, z);
                if (type == Block.custom_block)
                    SetExtTileNoCheck(x, y, z, extType);
                
                errorLocation = "Block sending";
                bool diffBlock = Block.Convert(b) != Block.Convert(type);
                if (!diffBlock && b == Block.custom_block)
                	diffBlock = extType != extB;
                if (diffBlock && !Instant)
                    Player.GlobalBlockchange(this, x, y, z, type, extType);

                errorLocation = "Growing grass";
                if (GetTile(x, (ushort)(y - 1), z) == Block.grass && GrassDestroy && !Block.LightPass(type)) {
                    Blockchange(p, x, (ushort)(y - 1), z, Block.dirt);
                }

                errorLocation = "Adding physics";
                if (p.PlayingTntWars && type == Block.smalltnt) AddCheck(PosToInt(x, y, z), "", false, p);
                if (physics > 0) if (Block.Physics(type)) AddCheck(PosToInt(x, y, z), "", false, p);

                changed = true;
                backedup = false;
            } catch (OutOfMemoryException) {
                Player.SendMessage(p, "Undo buffer too big! Cleared!");
                p.UndoBuffer.Clear();
                goto retry;
            } catch (Exception e) {
                Server.ErrorLog(e);
                Chat.GlobalMessageOps(p.name + " triggered a non-fatal error on " + name);
                Chat.GlobalMessageOps("Error location: " + errorLocation);
                Server.s.Log(p.name + " triggered a non-fatal error on " + name);
                Server.s.Log("Error location: " + errorLocation);
            }
        }
예제 #2
0
 /// <summary> Clears the block change handler, and reverts the block back
 /// to the existing one in the world. </summary>
 protected static void RevertAndClearState(Player p, ushort x, ushort y, ushort z)
 {
     p.ClearBlockchange();
     p.RevertBlock(x, y, z);
 }
예제 #3
0
        /// <summary> Returns: <br/>
        /// 0 - block change was not performed <br/>
        /// 1 - old block was same as new block visually (e.g. white to door_white)<br/>
        /// 2 - old block was different to new block visually </summary>
        /// <remarks> The return code can be used to avoid sending redundant block changes. </remarks>
        public int DoBlockchange(Player p, ushort x, ushort y, ushort z, BlockID block, bool drawn = false)
        {
            string errorLocation = "start";

            try
            {
                if (x >= Width || y >= Height || z >= Length)
                {
                    return(0);
                }
                BlockID old = GetBlock(x, y, z);

                errorLocation = "Permission checking";
                if (!CheckAffect(p, x, y, z, old, block))
                {
                    p.RevertBlock(x, y, z); return(0);
                }
                if (old == block)
                {
                    return(0);
                }

                if (old == Block.Sponge && physics > 0 && block != Block.Sponge)
                {
                    OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), false);
                }
                if (old == Block.LavaSponge && physics > 0 && block != Block.LavaSponge)
                {
                    OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), true);
                }

                p.SessionModified++;
                p.TotalModified++;

                if (drawn)
                {
                    p.TotalDrawn++;
                }
                else if (block == Block.Air)
                {
                    p.TotalDeleted++;
                }
                else
                {
                    p.TotalPlaced++;
                }

                errorLocation = "Setting tile";
                if (block >= Block.Extended)
                {
                    #if TEN_BIT_BLOCKS
                    SetTile(x, y, z, Block.ExtendedClass[block >> Block.ExtendedShift]);
                    #else
                    SetTile(x, y, z, Block.custom_block);
                    #endif
                    FastSetExtTile(x, y, z, (BlockRaw)block);
                }
                else
                {
                    SetTile(x, y, z, (BlockRaw)block);
                    if (old >= Block.Extended)
                    {
                        FastRevertExtTile(x, y, z);
                    }
                }

                errorLocation = "Adding physics";
                if (physics > 0 && ActivatesPhysics(block))
                {
                    AddCheck(PosToInt(x, y, z));
                }

                Changed  = true;
                backedup = false;

                return(Block.VisuallyEquals(old, block) ? 1 : 2);
            } catch (Exception e) {
                Logger.LogError(e);
                Chat.MessageOps(p.name + " triggered a non-fatal error on " + ColoredName + ", %Sat location: " + errorLocation);
                Logger.Log(LogType.Warning, "{0} triggered a non-fatal error on {1}, %Sat location: {2}",
                           p.name, ColoredName, errorLocation);
                return(0);
            }
        }
예제 #4
0
        /// <summary> Returns: <br/>
        /// 0 - block change was not performed <br/>
        /// 1 - old block was same as new block visually (e.g. white to door_white)<br/>
        /// 2 - old block was different to new block visually </summary>
        /// <remarks> The return code can be used to avoid sending redundant block changes. </remarks>
        public int DoBlockchange(Player p, ushort x, ushort y, ushort z, ExtBlock block, bool drawn = false)
        {
            string errorLocation = "start";

            try
            {
                if (x >= Width || y >= Height || z >= Length)
                {
                    return(0);
                }
                ExtBlock old = GetBlock(x, y, z);

                errorLocation = "Permission checking";
                if (!CheckAffectPermissions(p, x, y, z, old, block))
                {
                    p.RevertBlock(x, y, z); return(0);
                }
                if (old == block)
                {
                    return(0);
                }

                if (old.BlockID == Block.Sponge && physics > 0 && block.BlockID != Block.Sponge)
                {
                    OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), false);
                }
                if (old.BlockID == Block.LavaSponge && physics > 0 && block.BlockID != Block.LavaSponge)
                {
                    OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), true);
                }

                p.SessionModified++;
                p.TotalModified++;

                if (drawn)
                {
                    p.TotalDrawn++;
                }
                else if (block.BlockID == Block.Air)
                {
                    p.TotalDeleted++;
                }
                else
                {
                    p.TotalPlaced++;
                }

                errorLocation = "Setting tile";
                SetTile(x, y, z, block.BlockID);
                if (old.BlockID == Block.custom_block && block.BlockID != Block.custom_block)
                {
                    RevertExtTileNoCheck(x, y, z);
                }
                if (block.BlockID == Block.custom_block)
                {
                    SetExtTileNoCheck(x, y, z, block.ExtID);
                }

                errorLocation = "Adding physics";
                if (p.PlayingTntWars && block.BlockID == Block.TNT_Small)
                {
                    AddTntCheck(PosToInt(x, y, z), p);
                }
                if (physics > 0 && ActivatesPhysics(block))
                {
                    AddCheck(PosToInt(x, y, z));
                }

                Changed  = true;
                backedup = false;

                return(old.VisuallyEquals(block) ? 1 : 2);
            } catch (Exception e) {
                Logger.LogError(e);
                Chat.MessageOps(p.name + " triggered a non-fatal error on " + ColoredName + ", %Sat location: " + errorLocation);
                Logger.Log(LogType.Warning, "{0} triggered a non-fatal error on {1}, %Sat location: {2}",
                           p.name, ColoredName, errorLocation);
                return(0);
            }
        }
예제 #5
0
		protected static void RevertAndClearState(Player p, ushort x, ushort y, ushort z) {
			p.ClearBlockchange();
			p.RevertBlock(x, y, z);
		}
예제 #6
0
        public bool DoBlockchange(Player p, ushort x, ushort y, ushort z,
                                  byte block, byte extBlock = 0, bool drawn = false)
        {
            string errorLocation = "start";

retry:
            try
            {
                //if (x < 0 || y < 0 || z < 0) return;
                if (x >= Width || y >= Height || z >= Length)
                {
                    return(false);
                }
                byte old = GetTile(x, y, z), extOld = 0;
                if (old == Block.custom_block)
                {
                    extOld = GetExtTile(x, y, z);
                }

                errorLocation = "Permission checking";
                if (!CheckAffectPermissions(p, x, y, z, old, block, extBlock))
                {
                    p.RevertBlock(x, y, z); return(false);
                }

                if (old == Block.sponge && physics > 0 && block != Block.sponge)
                {
                    OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z));
                }
                if (old == Block.lava_sponge && physics > 0 && block != Block.lava_sponge)
                {
                    OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), true);
                }

                errorLocation = "Undo buffer filling";
                Player.UndoPos Pos;
                Pos.x         = x; Pos.y = y; Pos.z = z;
                Pos.mapName   = name;
                Pos.type      = old; Pos.extType = extOld;
                Pos.newtype   = block; Pos.newExtType = extBlock;
                Pos.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
                p.UndoBuffer.Add(this, Pos);

                errorLocation = "Setting tile";
                p.IncrementBlockStats(block, drawn);

                SetTile(x, y, z, block);
                if (old == Block.custom_block && block != Block.custom_block)
                {
                    RevertExtTileNoCheck(x, y, z);
                }
                if (block == Block.custom_block)
                {
                    SetExtTileNoCheck(x, y, z, extBlock);
                }

                errorLocation = "Adding physics";
                if (p.PlayingTntWars && block == Block.smalltnt)
                {
                    AddTntCheck(PosToInt(x, y, z), p);
                }
                if (physics > 0 && ActivatesPhysics(block, extBlock))
                {
                    AddCheck(PosToInt(x, y, z));
                }

                changed  = true;
                backedup = false;
                bool diffBlock = old == Block.custom_block ? extOld != extBlock :
                                 Block.Convert(old) != Block.Convert(block);
                return(diffBlock);
            } catch (OutOfMemoryException) {
                Player.Message(p, "Undo buffer too big! Cleared!");
                p.UndoBuffer.Clear();
                p.RemoveInvalidUndos();
                goto retry;
            } catch (Exception e) {
                Server.ErrorLog(e);
                Chat.MessageOps(p.name + " triggered a non-fatal error on " + ColoredName);
                Chat.MessageOps("Error location: " + errorLocation);
                Server.s.Log(p.name + " triggered a non-fatal error on " + ColoredName);
                Server.s.Log("Error location: " + errorLocation);
                return(false);
            }
        }
예제 #7
0
 void Player_PlayerBlockChange(Player p, ushort x, ushort y, ushort z, byte type, byte extType)
 {
     if (started)
     {
         if (p.level == mainlevel && !blueteam.members.Contains(p) && !redteam.members.Contains(p))
         {
             p.RevertBlock(x, y, z);
             Player.SendMessage(p, "You are not on a team!");
             Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p);
         }
         if (p.level == mainlevel && blueteam.members.Contains(p) && x == redbase.x && y == redbase.y && z == redbase.z && mainlevel.GetTile(redbase.x, redbase.y, redbase.z) != Block.air)
         {
             Chat.GlobalMessageLevel(mainlevel, blueteam.color + p.name + " took the " + redteam.color + " red team's FLAG!");
             GetPlayer(p).hasflag = true;
         }
         if (p.level == mainlevel && redteam.members.Contains(p) && x == bluebase.x && y == bluebase.y && z == bluebase.z && mainlevel.GetTile(bluebase.x, bluebase.y, bluebase.z) != Block.air)
         {
             Chat.GlobalMessageLevel(mainlevel, redteam.color + p.name + " took the " + blueteam.color + " blue team's FLAG");
             GetPlayer(p).hasflag = true;
         }
         if (p.level == mainlevel && blueteam.members.Contains(p) && x == bluebase.x && y == bluebase.y && z == bluebase.z && mainlevel.GetTile(bluebase.x, bluebase.y, bluebase.z) != Block.air)
         {
             if (GetPlayer(p).hasflag)
             {
                 Chat.GlobalMessageLevel(mainlevel, blueteam.color + p.name + " RETURNED THE FLAG!");
                 GetPlayer(p).hasflag = false;
                 GetPlayer(p).cap++;
                 GetPlayer(p).points += cappoint;
                 blueteam.points++;
                 mainlevel.Blockchange(redbase.x, redbase.y, redbase.z, Block.red);
                 p.RevertBlock(x, y, z);
                 Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p);
                 if (blueteam.points >= maxpoints)
                 {
                     End();
                     return;
                 }
             }
             else
             {
                 Player.SendMessage(p, "You cant take your own flag!");
                 p.RevertBlock(x, y, z);
                 Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p);
             }
         }
         if (p.level == mainlevel && redteam.members.Contains(p) && x == redbase.x && y == redbase.y && z == redbase.z && mainlevel.GetTile(redbase.x, redbase.y, redbase.z) != Block.air)
         {
             if (GetPlayer(p).hasflag)
             {
                 Chat.GlobalMessageLevel(mainlevel, redteam.color + p.name + " RETURNED THE FLAG!");
                 GetPlayer(p).hasflag = false;
                 GetPlayer(p).points += cappoint;
                 GetPlayer(p).cap++;
                 redteam.points++;
                 mainlevel.Blockchange(bluebase.x, bluebase.y, bluebase.z, Block.blue);
                 p.RevertBlock(x, y, z);
                 Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p);
                 if (redteam.points >= maxpoints)
                 {
                     End();
                     return;
                 }
             }
             else
             {
                 Player.SendMessage(p, "You cant take your own flag!");
                 p.RevertBlock(x, y, z);
                 Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p);
             }
         }
     }
 }
예제 #8
0
        internal bool DoBlockchange(Player p, ushort x, ushort y, ushort z, byte type, byte extType = 0)
        {
            string errorLocation = "start";

retry:
            try
            {
                //if (x < 0 || y < 0 || z < 0) return;
                if (x >= Width || y >= Height || z >= Length)
                {
                    return(false);
                }
                byte b = GetTile(x, y, z), extB = 0;
                if (b == Block.custom_block)
                {
                    extB = GetExtTile(x, y, z);
                }

                errorLocation = "Permission checking";
                if (!CheckAffectPermissions(p, x, y, z, b, type, extType))
                {
                    p.RevertBlock(x, y, z); return(false);
                }

                if (b == Block.sponge && physics > 0 && type != Block.sponge)
                {
                    OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z));
                }
                if (b == Block.lava_sponge && physics > 0 && type != Block.lava_sponge)
                {
                    OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), true);
                }

                errorLocation = "Undo buffer filling";
                Player.UndoPos Pos;
                Pos.x         = x; Pos.y = y; Pos.z = z;
                Pos.mapName   = name;
                Pos.type      = b; Pos.extType = extB;
                Pos.newtype   = type; Pos.newExtType = extType;
                Pos.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
                p.UndoBuffer.Add(this, Pos);

                errorLocation = "Setting tile";
                p.loginBlocks++;
                p.overallBlocks++;
                SetTile(x, y, z, type);
                if (b == Block.custom_block && type != Block.custom_block)
                {
                    RevertExtTileNoCheck(x, y, z);
                }
                if (type == Block.custom_block)
                {
                    SetExtTileNoCheck(x, y, z, extType);
                }

                errorLocation = "Adding physics";
                if (p.PlayingTntWars && type == Block.smalltnt)
                {
                    AddTntCheck(PosToInt(x, y, z), p);
                }
                if (physics > 0 && Block.Physics(type))
                {
                    AddCheck(PosToInt(x, y, z));
                }

                changed  = true;
                backedup = false;
                bool diffBlock = b == Block.custom_block ? extB != extType :
                                 Block.Convert(b) != Block.Convert(type);
                return(diffBlock);
            } catch (OutOfMemoryException) {
                Player.SendMessage(p, "Undo buffer too big! Cleared!");
                p.UndoBuffer.Clear();
                p.RemoveInvalidUndos();
                goto retry;
            } catch (Exception e) {
                Server.ErrorLog(e);
                Chat.GlobalMessageOps(p.name + " triggered a non-fatal error on " + name);
                Chat.GlobalMessageOps("Error location: " + errorLocation);
                Server.s.Log(p.name + " triggered a non-fatal error on " + name);
                Server.s.Log("Error location: " + errorLocation);
                return(false);
            }
        }