示例#1
0
        public bool CheckAffectPermissions(Player p, ushort x, ushort y, ushort z, ExtBlock old, ExtBlock block)
        {
            if (!p.group.Blocks[old.BlockID] && !Block.AllowBreak(old.BlockID) && !Block.BuildIn(old.BlockID))
            {
                return(false);
            }
            if (p.PlayingTntWars && !CheckTNTWarsChange(p, x, y, z, ref block.BlockID))
            {
                return(false);
            }
            Zone[] zones = Zones.Items;
            if (zones.Length == 0)
            {
                return(CheckRank(p));
            }

            // Check zones specifically allowed in
            for (int i = 0; i < zones.Length; i++)
            {
                Zone zn = zones[i];
                if (x < zn.MinX || x > zn.MaxX || y < zn.MinY || y > zn.MaxY || z < zn.MinZ || z > zn.MaxZ)
                {
                    continue;
                }

                ZoneConfig cfg = zn.Config;
                if (p.group.Permission >= cfg.BuildMin)
                {
                    return(true);
                }
                if (cfg.BuildWhitelist.Count > 0 && cfg.BuildWhitelist.CaselessContains(p.name))
                {
                    return(true);
                }
            }

            // Check zones denied from
            for (int i = 0; i < zones.Length; i++)
            {
                Zone zn = zones[i];
                if (x < zn.MinX || x > zn.MaxX || y < zn.MinY || y > zn.MaxY || z < zn.MinZ || z > zn.MaxZ)
                {
                    continue;
                }
                AccessResult access = zn.Access.Check(p);
                if (access == AccessResult.Allowed || access == AccessResult.Whitelisted)
                {
                    continue;
                }

                if (p.ZoneSpam > DateTime.UtcNow)
                {
                    return(false);
                }
                zn.Access.CheckDetailed(p);
                p.ZoneSpam = DateTime.UtcNow.AddSeconds(2);
                return(false);
            }
            return(CheckRank(p));
        }
示例#2
0
 public void Blockchange(Player p, ushort x, ushort y, ushort z, ExtBlock block)
 {
     if (DoBlockchange(p, x, y, z, block) == 2)
     {
         Player.GlobalBlockchange(this, x, y, z, block);
     }
 }
示例#3
0
        void RevertPhysics(Check C)
        {
            //attemps on shutdown to change blocks back into normal selves that are active, hopefully without needing to send into to clients.
            switch (blocks[C.b])
            {
            case Block.Air_Flood:
            case Block.Air_FloodLayer:
            case Block.Air_FloodDown:
            case Block.Air_FloodUp:
                blocks[C.b] = 0; break;
            }

            try {
                PhysicsArgs args = C.data;
                // Copy paste here because it's worthwhile inlining
                if (args.Type1 == PhysicsArgs.Revert)
                {
                    ushort x, y, z;
                    IntToPos(C.b, out x, out y, out z);

                    ExtBlock block = ExtBlock.FromRaw(args.Value1, args.ExtBlock);
                    Blockchange(C.b, block, true, default(PhysicsArgs));
                }
                else if (args.Type2 == PhysicsArgs.Revert)
                {
                    ushort x, y, z;
                    IntToPos(C.b, out x, out y, out z);

                    ExtBlock block = ExtBlock.FromRaw(args.Value2, args.ExtBlock);
                    Blockchange(C.b, block, true, default(PhysicsArgs));
                }
            } catch (Exception e) {
                Logger.LogError(e);
            }
        }
示例#4
0
        public void UpdateBlock(Player p, ushort x, ushort y, ushort z, ExtBlock block,
                                ushort flags = BlockDBFlags.ManualPlace, bool buffered = false)
        {
            ExtBlock old   = GetBlock(x, y, z);
            bool     drawn = (flags & BlockDBFlags.ManualPlace) != 0;
            int      type  = DoBlockchange(p, x, y, z, block, drawn);

            if (type == 0)
            {
                return;            // no block change performed
            }
            BlockDB.Cache.Add(p, x, y, z, flags, old, block);
            if (type == 1)
            {
                return;            // not different visually
            }
            int index = PosToInt(x, y, z);

            if (buffered)
            {
                BlockQueue.Addblock(p, index, block);
            }
            else
            {
                Player.GlobalBlockchange(this, x, y, z, block);
            }
        }
示例#5
0
        public static void GlobalBlockchange(Level level, int b, ExtBlock block)
        {
            ushort x, y, z;

            level.IntToPos(b, out x, out y, out z);
            GlobalBlockchange(level, x, y, z, block);
        }
示例#6
0
        internal static void LoadMessages(Level level, string name)
        {
            level.hasMessageBlocks = Database.TableExists("Messages" + name);
            if (!level.hasMessageBlocks)
            {
                return;
            }

            using (DataTable table = Database.Backend.GetRows("Messages" + name, "*")) {
                foreach (DataRow row in table.Rows)
                {
                    ushort x = ushort.Parse(row["X"].ToString());
                    ushort y = ushort.Parse(row["Y"].ToString());
                    ushort z = ushort.Parse(row["Z"].ToString());

                    ExtBlock block = level.GetBlock(x, y, z);
                    if (level.Props[block.Index].IsMessageBlock)
                    {
                        continue;
                    }

                    Database.Backend.DeleteRows("Messages" + name, "WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z);
                }
            }
        }
示例#7
0
 public void UpdateBlockHandlers()
 {
     for (int i = 0; i < Props.Length; i++)
     {
         UpdateBlockHandler(ExtBlock.FromIndex(i));
     }
 }
示例#8
0
        internal bool AddUpdate(int b, ExtBlock block, bool overRide = false)
        {
            PhysicsArgs args = default(PhysicsArgs);

            args.ExtBlock = block.BlockID == Block.custom_block;
            return(AddUpdate(b, block.RawID, overRide, args));
        }
示例#9
0
 public void Blockchange(int b, ExtBlock block, bool overRide = false,
                         PhysicsArgs data = default(PhysicsArgs), bool addUndo = true)   //Block change made by physics
 {
     if (DoPhysicsBlockchange(b, block, overRide, data, addUndo))
     {
         Player.GlobalBlockchange(this, b, block);
     }
 }
示例#10
0
 internal bool HasCustomProps(ExtBlock block)
 {
     if (block.IsPhysicsType)
     {
         return(false);
     }
     return(CustomBlockDefs[block.RawID] != BlockDefinition.GlobalDefs[block.RawID]);
 }
示例#11
0
        public void UpdateCustomBlock(byte raw, BlockDefinition def)
        {
            CustomBlockDefs[raw] = def;
            ExtBlock block = ExtBlock.FromRaw(raw);

            UpdateBlockHandler(block);
            blockAABBs[block.Index] = Block.BlockAABB(block, this);
        }
示例#12
0
        void HandleBlockchange(byte[] buffer, int offset)
        {
            try {
                if (!loggedIn || spamChecker.CheckBlockSpam())
                {
                    return;
                }
                ushort x = NetUtils.ReadU16(buffer, offset + 1);
                ushort y = NetUtils.ReadU16(buffer, offset + 3);
                ushort z = NetUtils.ReadU16(buffer, offset + 5);
                if (frozen)
                {
                    RevertBlock(x, y, z); return;
                }

                byte action = buffer[offset + 7];
                if (action > 1)
                {
                    const string msg = "Unknown block action!";
                    Leave(msg, msg, true); return;
                }

                LastAction = DateTime.UtcNow;
                if (IsAfk)
                {
                    CmdAfk.ToggleAfk(this, "");
                }

                ExtBlock held = ExtBlock.FromRaw(buffer[offset + 8]);
                RawHeldBlock = held;

                if ((action == 0 || held.BlockID == Block.Air) && !level.Config.Deletable)
                {
                    SendMessage("Deleting blocks is disabled in this level.");
                    RevertBlock(x, y, z); return;
                }
                else if (action == 1 && !level.Config.Buildable)
                {
                    SendMessage("Placing blocks is disabled in this level.");
                    RevertBlock(x, y, z); return;
                }

                if (held.BlockID == Block.custom_block)
                {
                    if (!hasBlockDefs || level.CustomBlockDefs[held.ExtID] == null)
                    {
                        SendMessage("Invalid block type: " + held.ExtID);
                        RevertBlock(x, y, z); return;
                    }
                }
                ManualChange(x, y, z, action != 0, held, true);
            } catch (Exception e) {
                // Don't ya just love it when the server tattles?
                Chat.MessageOps(DisplayName + " has triggered a block change error");
                Chat.MessageOps(e.GetType().ToString() + ": " + e.Message);
                Logger.LogError(e);
            }
        }
示例#13
0
 internal Player()
 {
     spamChecker = new SpamChecker(this);
     SessionID   = Interlocked.Increment(ref sessionCounter) & SessionIDMask;
     for (int i = 0; i < BlockBindings.Length; i++)
     {
         BlockBindings[i] = ExtBlock.FromRaw((byte)i);
     }
 }
示例#14
0
 internal bool CheckManualChange(ExtBlock old, ExtBlock block, bool deleteMode)
 {
     if (!BlockPerms.UsableBy(this, old.BlockID) && !Block.BuildIn(old.BlockID) && !Block.AllowBreak(old.BlockID))
     {
         string action = deleteMode ? "delete" : "replace";
         BlockPerms.List[old.BlockID].MessageCannotUse(this, action);
         return(false);
     }
     return(CommandParser.IsBlockAllowed(this, "place", block));
 }
示例#15
0
        public bool LightPasses(ExtBlock block)
        {
            BlockDefinition def = GetBlockDef(block);

            if (def != null)
            {
                return(!def.BlocksLight || def.BlockDraw == DrawType.TransparentThick || def.MinZ > 0);
            }
            return(Block.LightPass(block.BlockID));
        }
示例#16
0
 public static void UpdateGlobalBlockProps()
 {
     for (int i = 0; i < GlobalProps.Length; i++)
     {
         ExtBlock block = ExtBlock.FromRaw((byte)i);
         GlobalProps[i] = BlockProps.MakeDefault();
         GlobalProps[i] = DefaultProps(block);
     }
     BlockProps.Load("global", GlobalProps, GlobalPropsLock, false);
 }
示例#17
0
        void HandleMovement(byte[] buffer, int offset)
        {
            if (!loggedIn || trainGrab || following.Length > 0)
            {
                CheckBlocks(Pos); return;
            }
            if (Supports(CpeExt.HeldBlock))
            {
                RawHeldBlock = ExtBlock.FromRaw(buffer[offset + 1]);
            }

            int x, y, z;

            if (hasExtPositions)
            {
                x       = NetUtils.ReadI32(buffer, offset + 2);
                y       = NetUtils.ReadI32(buffer, offset + 6);
                z       = NetUtils.ReadI32(buffer, offset + 10);
                offset += 6; // for yaw/pitch offset below
            }
            else
            {
                x = NetUtils.ReadI16(buffer, offset + 2);
                y = NetUtils.ReadI16(buffer, offset + 4);
                z = NetUtils.ReadI16(buffer, offset + 6);
            }

            byte     yaw = buffer[offset + 8], pitch = buffer[offset + 9];
            Position next = new Position(x, y, z);

            CheckBlocks(next);

            OnPlayerMoveEvent.Call(this, next, yaw, pitch);
            if (cancelmove)
            {
                cancelmove = false; return;
            }

            Pos = next;
            SetYawPitch(yaw, pitch);
            if (!Moved() || Loading)
            {
                return;
            }
            if (DateTime.UtcNow < AFKCooldown)
            {
                return;
            }

            LastAction = DateTime.UtcNow;
            if (IsAfk)
            {
                CmdAfk.ToggleAfk(this, "");
            }
        }
示例#18
0
        public void UpdateBlockHandler(ExtBlock block)
        {
            bool nonSolid = !MCGalaxy.Blocks.CollideType.IsSolid(CollideType(block));
            int  i        = block.Index;

            deleteHandlers[i]       = BlockBehaviour.GetDeleteHandler(block, Props);
            placeHandlers[i]        = BlockBehaviour.GetPlaceHandler(block, Props);
            walkthroughHandlers[i]  = BlockBehaviour.GetWalkthroughHandler(block, Props, nonSolid);
            physicsHandlers[i]      = BlockBehaviour.GetPhysicsHandler(block, Props);
            physicsDoorsHandlers[i] = BlockBehaviour.GetPhysicsDoorsHandler(block, Props);
        }
示例#19
0
        public byte CollideType(ExtBlock block)
        {
            BlockDefinition def     = GetBlockDef(block);
            byte            collide = def != null ? def.CollideType : MCGalaxy.Blocks.CollideType.Solid;

            if (def == null && !block.IsCustomType)
            {
                return(DefaultSet.Collide(Block.Convert(block.BlockID)));
            }
            return(collide);
        }
示例#20
0
        internal bool DoBlockchangeCallback(ushort x, ushort y, ushort z, ExtBlock block)
        {
            lastClick.X = x; lastClick.Y = y; lastClick.Z = z;
            if (Blockchange == null)
            {
                return(false);
            }

            Blockchange(this, x, y, z, block);
            return(true);
        }
示例#21
0
        bool PlaceBlock(ExtBlock old, ushort x, ushort y, ushort z, ExtBlock block)
        {
            HandlePlace handler = level.placeHandlers[block.Index];

            if (handler != null)
            {
                handler(this, block, x, y, z);
                return(true);
            }
            return(ChangeBlock(x, y, z, block) == 2);
        }
示例#22
0
        public Level(string name, ushort width, ushort height, ushort length)
        {
            if (width < 1)
            {
                width = 1;
            }
            if (height < 1)
            {
                height = 1;
            }
            if (length < 1)
            {
                length = 1;
            }

            Width = width; Height = height; Length = length;
            for (int i = 0; i < CustomBlockDefs.Length; i++)
            {
                CustomBlockDefs[i] = BlockDefinition.GlobalDefs[i];
            }

            LoadCoreProps();
            for (int i = 0; i < blockAABBs.Length; i++)
            {
                ExtBlock block = ExtBlock.FromIndex(i);
                blockAABBs[i] = Block.BlockAABB(block, this);
            }
            UpdateBlockHandlers();

            this.name           = name; MapName = name.ToLower();
            BlockDB             = new BlockDB(this);
            Config.EdgeLevel    = (short)(height / 2);
            Config.CloudsHeight = (short)(height + 2);

            blocks       = new byte[Width * Height * Length];
            ChunksX      = Utils.CeilDiv16(Width);
            ChunksY      = Utils.CeilDiv16(Height);
            ChunksZ      = Utils.CeilDiv16(Length);
            CustomBlocks = new byte[ChunksX * ChunksY * ChunksZ][];

            spawnx = (ushort)(Width / 2);
            spawny = (ushort)(Height * 0.75f);
            spawnz = (ushort)(Length / 2);
            rotx   = 0; roty = 0;

            VisitAccess      = new LevelAccessController(this, true);
            BuildAccess      = new LevelAccessController(this, false);
            listCheckExists  = new SparseBitSet(Width, Height, Length);
            listUpdateExists = new SparseBitSet(Width, Height, Length);
        }
示例#23
0
        void SelectionBlockChange(Player p, ushort x, ushort y, ushort z, ExtBlock block)
        {
            lock (selLock) {
                Blockchange = SelectionBlockChange;
                RevertBlock(x, y, z);

                selMarks[selIndex] = new Vec3S32(x, y, z);
                if (selMarkCallback != null)
                {
                    selMarkCallback(p, selMarks, selIndex, selState, block);
                }
                // Mark callback cancelled selection
                if (selCallback == null)
                {
                    return;
                }

                selIndex++;
                if (selIndex == 1 && selTitle != null)
                {
                    SendCpeMessage(CpeMessageType.BottomRight2, "Mark #1" + FormatSelectionMark(selMarks[0]));
                }
                else if (selIndex == 2 && selTitle != null)
                {
                    SendCpeMessage(CpeMessageType.BottomRight1, "Mark #2" + FormatSelectionMark(selMarks[0]));
                }
                if (selIndex != selMarks.Length)
                {
                    return;
                }

                string title = selTitle;
                object state = selState;
                SelectionMarkHandler markCallback = selMarkCallback;
                SelectionHandler     callback     = selCallback;
                ClearSelection();

                if (!block.IsPhysicsType)
                {
                    block = p.BlockBindings[block.RawID];
                }
                bool canRepeat = callback(this, selMarks, state, block);

                if (canRepeat && staticCommands)
                {
                    MakeSelection(selIndex, title, state, callback, markCallback);
                }
            }
        }
示例#24
0
 void LoadCoreProps()
 {
     for (int i = 0; i < Props.Length; i++)
     {
         ExtBlock block = ExtBlock.FromIndex(i);
         if (!HasCustomProps(block))
         {
             Props[i] = BlockDefinition.DefaultProps(block);
         }
         else
         {
             Props[i] = BlockProps.MakeDefault();
         }
     }
 }
示例#25
0
 internal static BlockProps DefaultProps(ExtBlock block)
 {
     if (block.IsPhysicsType)
     {
         return(Block.Props[block.Index]);
     }
     else if (!block.IsCustomType && GlobalDefs[block.RawID] == null)
     {
         return(Block.Props[block.RawID]);
     }
     else
     {
         return(GlobalProps[block.RawID]);
     }
 }
示例#26
0
        public string BlockName(ExtBlock block)
        {
            if (block.IsPhysicsType)
            {
                return(Block.Name(block.BlockID));
            }
            BlockDefinition def = GetBlockDef(block);

            if (def != null)
            {
                return(def.Name.Replace(" ", ""));
            }

            return(block.BlockID != Block.custom_block ? Block.Name(block.BlockID) : block.ExtID.ToString());
        }
示例#27
0
        bool DeleteBlock(ExtBlock old, ushort x, ushort y, ushort z, ExtBlock block)
        {
            if (deleteMode)
            {
                return(ChangeBlock(x, y, z, ExtBlock.Air) == 2);
            }

            HandleDelete handler = level.deleteHandlers[old.Index];

            if (handler != null)
            {
                handler(this, old, x, y, z);
                return(true);
            }
            return(ChangeBlock(x, y, z, ExtBlock.Air) == 2);
        }
示例#28
0
        internal bool ActivatesPhysics(ExtBlock block)
        {
            int i = block.Index;

            if (Props[i].IsMessageBlock || Props[i].IsPortal)
            {
                return(false);
            }
            if (Props[i].IsDoor || Props[i].IsTDoor)
            {
                return(false);
            }
            if (Props[i].OPBlock)
            {
                return(false);
            }
            return(physicsHandlers[i] != null);
        }
示例#29
0
        static void UpdateLoadedLevels(BlockDefinition[] oldGlobalDefs)
        {
            Level[] loaded = LevelInfo.Loaded.Items;
            foreach (Level lvl in loaded)
            {
                for (int i = 0; i < lvl.CustomBlockDefs.Length; i++)
                {
                    if (lvl.CustomBlockDefs[i] != oldGlobalDefs[i])
                    {
                        continue;
                    }

                    ExtBlock block = ExtBlock.FromRaw((byte)i);
                    lvl.Props[block.Index] = DefaultProps(block);
                    lvl.UpdateCustomBlock(block.RawID, GlobalDefs[i]);
                }
            }
        }
示例#30
0
        /// <summary> Updates the block at the given position, mainly intended for manual changes by the player. </summary>
        /// <remarks> Adds to the BlockDB. Also turns block below to grass/dirt depending on light. </remarks>
        /// <returns> Return code from DoBlockchange </returns>
        public int ChangeBlock(ushort x, ushort y, ushort z, ExtBlock block)
        {
            ExtBlock old  = level.GetBlock(x, y, z);
            int      type = level.DoBlockchange(this, x, y, z, block);

            if (type == 0)
            {
                return(type);                                               // no change performed
            }
            if (type == 2)
            {
                Player.GlobalBlockchange(level, x, y, z, block);            // different visually
            }
            ushort flags = BlockDBFlags.ManualPlace;

            if (painting && CollideType.IsSolid(level.CollideType(old)))
            {
                flags = BlockDBFlags.Painted;
            }
            level.BlockDB.Cache.Add(this, x, y, z, flags, old, block);

            bool autoGrass = level.Config.GrassGrow && (level.physics == 0 || level.physics == 5);

            if (!autoGrass)
            {
                return(type);
            }
            ExtBlock below = level.GetBlock(x, (ushort)(y - 1), z);

            ushort grassIdx = level.Props[below.Index].GrassIndex;

            if (grassIdx != Block.Invalid && block.BlockID == Block.Air)
            {
                level.Blockchange(this, x, (ushort)(y - 1), z, ExtBlock.FromIndex(grassIdx));
            }

            ushort dirtIdx = level.Props[below.Index].DirtIndex;

            if (dirtIdx != Block.Invalid && !level.LightPasses(block))
            {
                level.Blockchange(this, x, (ushort)(y - 1), z, ExtBlock.FromIndex(dirtIdx));
            }
            return(type);
        }