Пример #1
0
        public void ManualChange(ushort x, ushort y, ushort z, bool placing,
                                 ExtBlock block, bool checkPlaceDist)
        {
            ExtBlock old = level.GetBlock(x, y, z);

            if (old.IsInvalid)
            {
                return;
            }

            if (jailed || !canBuild)
            {
                RevertBlock(x, y, z); return;
            }
            if (!agreed)
            {
                SendMessage(mustAgreeMsg);
                RevertBlock(x, y, z); return;
            }

            if (level.IsMuseum && Blockchange == null)
            {
                return;
            }
            bool deletingBlock = !painting && !placing;

            if (ServerConfig.verifyadmins && adminpen)
            {
                SendMessage("&cYou must first verify with %T/Pass [Password]");
                RevertBlock(x, y, z); return;
            }

            if (Server.lava.active && Server.lava.HasPlayer(this) && Server.lava.IsPlayerDead(this))
            {
                SendMessage("You are out of the round, and cannot build.");
                RevertBlock(x, y, z); return;
            }

            if (ClickToMark && DoBlockchangeCallback(x, y, z, block))
            {
                return;
            }

            OnBlockChangeEvent.Call(this, x, y, z, block, placing);
            if (cancelBlock)
            {
                cancelBlock = false; return;
            }

            if (old.BlockID >= Block.Air_Flood && old.BlockID <= Block.Door_Air_air)
            {
                SendMessage("Block is active, you cannot disturb it.");
                RevertBlock(x, y, z); return;
            }

            if (!deletingBlock)
            {
                PhysicsArgs args = level.foundInfo(x, y, z);
                if (args.HasWait)
                {
                    return;
                }
            }

            if (group.Permission == LevelPermission.Banned)
            {
                return;
            }
            if (checkPlaceDist)
            {
                int dx = Pos.BlockX - x, dy = Pos.BlockY - y, dz = Pos.BlockZ - z;
                int diff = (int)Math.Sqrt(dx * dx + dy * dy + dz * dz);

                if (diff > ReachDistance + 4)
                {
                    Logger.Log(LogType.Warning, "{0} attempted to build with a {1} distance offset", name, diff);
                    SendMessage("You can't build that far away.");
                    RevertBlock(x, y, z); return;
                }
            }

            ExtBlock held = block;

            block = BlockBindings[block.RawID];
            if (!CheckManualChange(old, block, deletingBlock))
            {
                RevertBlock(x, y, z); return;
            }
            if (!ModeBlock.IsAir)
            {
                block = ModeBlock;
            }

            //Ignores updating blocks that are the same and revert block back only to the player
            ExtBlock newB = deletingBlock ? ExtBlock.Air : block;

            if (old == newB)
            {
                if (painting || !old.VisuallyEquals(held))
                {
                    RevertBlock(x, y, z);
                }
                return;
            }

            if (deletingBlock)
            {
                bool deleted = DeleteBlock(old, x, y, z, block);
            }
            else
            {
                bool placed = PlaceBlock(old, x, y, z, block);
                // Client always assumes delete succeeds, so we need to echo back the painted over block
                // if the block was not changed visually (e.g. they paint white with door_white)
                if (!placed && painting)
                {
                    RevertBlock(x, y, z);
                }
            }
        }
Пример #2
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);
            }
        }