コード例 #1
0
ファイル: Map.cs プロジェクト: jamierocks/femtocraft
        public bool SetBlockNoNeighborChange([CanBeNull] Player except, int x, int y, int z, Block newBlock)
        {
            Block oldBlock = GetBlock(x, y, z);

            if (oldBlock == newBlock || oldBlock == Block.Undefined)
            {
                return(false);
            }

            // water at map edges
            if ((x == 0 || y == 0 || x == Width - 1 || y == Length - 1) && (z >= WaterLevel - 2 && z < WaterLevel) &&
                (newBlock == Block.Air))
            {
                newBlock = Block.Water;

                // stair stacking
            }
            else if (newBlock == Block.Slab && GetBlock(x, y, z - 1) == Block.Slab)
            {
                SetBlock(null, x, y, z, Block.Air);
                SetBlock(null, x, y, z - 1, Block.DoubleSlab);
                return(true);
            }
            else if (newBlock == Block.CobbleSlab && GetBlock(x, y, z - 1) == Block.CobbleSlab)
            {
                SetBlock(null, x, y, z, Block.Air);
                SetBlock(null, x, y, z - 1, Block.Cobble);
                return(true);
            }

            Blocks[Index(x, y, z)] = (byte)newBlock;
            ChangedSinceSave       = true;

            PhysicsOnRemoved(x, y, z, oldBlock);
            PhysicsOnPlaced(x, y, z, newBlock);

            if (IsActive)
            {
                Server.Players.Send(except, Packet.MakeSetBlock(x, y, z, GetBlock(x, y, z)));
            }
            return(true);
        }
コード例 #2
0
        bool ProcessSetBlockPacket()
        {
            ResetIdleTimer();
            short x          = reader.ReadInt16();
            short z          = reader.ReadInt16();
            short y          = reader.ReadInt16();
            bool  isDeleting = (reader.ReadByte() == 0);
            byte  rawType    = reader.ReadByte();

            // check if block type is valid
            if (!UsesCustomBlocks && rawType > (byte)Map.MaxLegalBlockType ||
                UsesCustomBlocks && rawType > (byte)Map.MaxCustomBlockType)
            {
                KickNow("Hacking detected.");
                Logger.LogWarning("Player {0} tried to place an invalid block type.", Name);
                return(false);
            }
            if (IsPainting)
            {
                isDeleting = false;
            }
            Block block = (Block)rawType;

            if (isDeleting)
            {
                block = Block.Air;
            }

            // check if coordinates are within map boundaries (don't kick)
            if (!Map.InBounds(x, y, z))
            {
                return(true);
            }

            // check if player is close enough to place
            if (!IsOp && Config.LimitClickDistance || IsOp && Config.OpLimitClickDistance)
            {
                if (Math.Abs(x * 32 - Position.X) > MaxBlockPlacementRange ||
                    Math.Abs(y * 32 - Position.Y) > MaxBlockPlacementRange ||
                    Math.Abs(z * 32 - Position.Z) > MaxBlockPlacementRange)
                {
                    KickNow("Hacking detected.");
                    Logger.LogWarning("Player {0} tried to place a block too far away.", Name);
                    return(false);
                }
            }

            // check click rate
            if (!IsOp && Config.LimitClickRate || IsOp && Config.OpLimitClickRate)
            {
                if (DetectBlockSpam())
                {
                    KickNow("Hacking detected.");
                    Logger.LogWarning("Player {0} tried to place blocks too quickly.", Name);
                    return(false);
                }
            }

            // apply blocktype mapping
            if (block == Block.Blue && PlaceWater)
            {
                block = Block.Water;
            }
            else if (block == Block.Red && PlaceLava)
            {
                block = Block.Lava;
            }
            else if (block == Block.Stone && PlaceSolid)
            {
                block = Block.Admincrete;
            }
            else if (block == Block.Dirt && PlaceGrass)
            {
                block = Block.Grass;
            }

            // check if blocktype is permitted
            if ((block == Block.Water || block == Block.StillWater) && !CanUseWater ||
                (block == Block.Lava || block == Block.StillLava) && !CanUseLava ||
                (block == Block.Grass) && !CanUseGrass ||
                (block == Block.Admincrete || block == Block.Admincrete) && !CanUseSolid)
            {
                KickNow("Hacking detected.");
                Logger.LogWarning("Player {0} tried to place a restricted block type.", Name);
                return(false);
            }

            // check if deleting admincrete
            Block oldBlock = Map.GetBlock(x, y, z);

            if ((oldBlock == Block.Admincrete) && !CanUseSolid)
            {
                KickNow("Hacking detected.");
                Logger.LogWarning("Player {0} tried to delete a restricted block type.", Name);
                return(false);
            }

            // update map
            Map.SetBlock(this, x, y, z, block);

            // check if sending back an update is necessary
            Block placedBlock = Map.GetBlock(x, y, z);

            if (IsPainting || (!isDeleting && placedBlock != (Block)rawType))
            {
                writer.Write(Packet.MakeSetBlock(x, y, z, placedBlock).Bytes);
            }
            return(true);
        }