Пример #1
0
        /// <summary>
        /// Return best matching parent region for our new region or return an interferring region if found
        /// Check for Cover to make sure the returning region is not crossing edges
        /// </summary>
        public static WorldRegion GetBaseRegion(List <WorldRegion> list, Region reg, Dimensions dimension)
        {
            foreach (WorldRegion r in list)
            {
                if ((int)dimension != r.Dimension)
                {
                    continue;
                }
                if (reg.Overlap(r) == false)
                {
                    continue;
                }

                if (r.Cover(reg) == false)
                {
                    return(r); // we will catch this later
                }
                if (r.SubRegions == null)
                {
                    return(r);
                }

                WorldRegion w = GetBaseRegion(r.SubRegions, reg, dimension);

                if (w == null)
                {
                    return(r);
                }
                else
                {
                    return(w);
                }
            }
            return(null);
        }
Пример #2
0
        public static WorldRegion GetRegion(List <WorldRegion> list, CoordDouble pos, Dimensions dimension)
        {
            if (list == null)
            {
                return(null);
            }

            foreach (WorldRegion r in list)
            {
                if (r.Dimension != (int)dimension)
                {
                    continue;
                }
                if (r.Contains(pos))
                {
                    if (r.SubRegions == null)
                    {
                        return(r);
                    }

                    WorldRegion w = GetRegion(r.SubRegions, pos, dimension);
                    if (w == null)
                    {
                        return(r);
                    }
                    else
                    {
                        return(w);
                    }
                }
            }
            return(null);
        }
Пример #3
0
        public static bool IsBlockProtected(WorldSession session, WorldRegion r)
        {
            if (r == null)
            {
                return(false);
            }

            if (session.Mode == GameMode.Creative && session.Player.Admin(Permissions.AnyAdmin))
            {
                return(false);
            }
            if (r.IsResident(session.Player))
            {
                return(false);
            }

            switch (r.Type)
            {
            case Protected.Type:
            case Preserved.Type:
            case Adventure.Type:
            case Honeypot.Type:
            case SpawnRegion.Type:
            case WarpZone.Type:
                return(true);
            }

            return(false);
        }
Пример #4
0
        static List <WorldRegion> GetParentList(List <WorldRegion> list, WorldRegion region)
        {
            if (list == null)
            {
                return(null);
            }

            foreach (WorldRegion r in list)
            {
                if (r.Dimension != region.Dimension)
                {
                    continue;
                }

                if (r.Overlap(region) == false)
                {
                    continue;
                }

                if (r == region)
                {
                    return(list);
                }

                //Search subregions
                return(GetParentList(r.SubRegions, region));
            }
            return(null);
        }
Пример #5
0
        /// <summary>
        /// Prevent block modification, aplies to all, residents should never get called here
        /// </summary>
        public static bool ProtectBlockBreak(VanillaSession session, WorldRegion region, PlayerDigging d)
        {
            if (IsBlockProtected(session, region) == false)
            {
                return(false);
            }

            //Block single click from outside the adventure mode
            if (d.Status == PlayerDigging.StatusEnum.StartedDigging)
            {
                return(true);
            }

            if (d.Status != PlayerDigging.StatusEnum.FinishedDigging)
            {
                return(false);
            }

            //Old method - not needed
            BlockChange bc = new BlockChange(d.Position, BlockID.Bedrock);

            session.Player.SendToClient(bc);

            //New method - Works

            /*
             * PlayerDigging pd = new PlayerDigging();
             * pd.Position = d.Position;
             * pd.Face = Face.Down;
             * pd.Status = PlayerDigging.StatusEnum.CheckBlock;
             * session.FromClient(pd);
             */

            return(true);
        }
Пример #6
0
        /// <summary>
        /// Leaving the specified player and forAnotherRegion.
        /// </summary>
        /// <param name='player'>
        /// Player.
        /// </param>
        /// <param name='forAnotherRegion'>
        /// If going into another region dont tell the player, leaving
        /// </param>
        internal virtual void Leaving(Client player, WorldRegion nextRegion)
        {
            if (Type == SpawnRegion.Type)
            {
                SpawnRegion.Leaving(player);
            }

            if (Type == SpawnTimeRegion.Type)
            {
                SpawnTimeRegion.Leaving(player);
                return;
            }

            Log.WriteRegion(player, this, false);
            if (nextRegion == null || nextRegion.SubRegions != null && nextRegion.SubRegions.Contains(this))
            {
                player.TellAbove(Chat.Gray, "Leaving " + Name);
            }

            if (player.Settings.Cloaked != null)
            {
                return;
            }
            if (ReportVisits == false)
            {
                return;
            }

            TellResidentsSystem(player, Chat.Gray, player.Name + " left " + Name + " " + FromDirection(player.Session.Position));
        }
Пример #7
0
        public static bool Trigger(Client player, WorldRegion r)
        {
#if DEBUG
            player.TellAbove("DEBUG: ", "You triggered the ban");
#else
            player.BanByServer(DateTime.Now.AddMinutes(30), r.Name);
#endif
            return(true);
        }
Пример #8
0
        public override bool Overlap(Region r)
        {
            WorldRegion w = r as WorldRegion;

            if (w != null && w.Dimension != Dimension)
            {
                return(false);
            }
            return(base.Overlap(r));
        }
Пример #9
0
 /// <summary>
 /// True if w is added to current region anywhere recursively
 /// </summary>
 /// <returns>
 /// <c>true</c> if this instance has child the specified w; otherwise, <c>false</c>.
 /// </returns>
 /// <param name='w'>
 /// The width.
 /// </param>
 public bool HasChild(WorldRegion w)
 {
     foreach (WorldRegion r in SubRegions)
     {
         if (r == w)
         {
             return(true);
         }
         if (r.HasChild(w))
         {
             return(true);
         }
     }
     return(false);
 }
Пример #10
0
        public static bool ProtectBlockPlace(VanillaSession session, WorldRegion region, PlayerBlockPlacement bp)
        {
            if (IsBlockProtected(session, region) == false)
            {
                return(false);
            }

            if (FilterFire(session, bp))
            {
                string i = "";
                if (session.ActiveItem != null)
                {
                    i += "(server)" + session.ActiveItem.ItemID;
                }
                if (bp.Item != null)
                {
                    i += "(client)" + bp.Item.ItemID;
                }

                Chatting.Parser.TellAdmin(Permissions.Ban, session.Player.Name + " tried to use " + i + " in " + region.Name + " at " + session.Position);
                //session.Player.Kick("Arson");
                return(true);
            }

            //If adventure protection is active, allow all actions
            if (session.Mode == GameMode.Adventure) //buggy but best bet so far
            {
                return(false);                      //ok, only activate levers and chests
            }
            //Block all placements, non resident must be inside the region
            session.TellSystem(Chat.Aqua, "move inside the region before you open a door or chest");

            //New method, works - no longer works

            /*
             * PlayerDigging pd = new PlayerDigging();
             * pd.Position = bp.BlockPosition.Offset(bp.FaceDirection);
             * pd.Face = Face.Down;
             * pd.Status = PlayerDigging.StatusEnum.CheckBlock;
             * session.FromClient(pd);
             */

            //Old method - not perfect, disabling:

            /*BlockChange bc = new BlockChange(bp.BlockPosition.Offset(bp.FaceDirection), BlockID.Air);
             * session.Player.SendToClient(bc);*/
            return(true);
        }
Пример #11
0
 static void SetStats(WorldRegion r, Client player)
 {
     if (r == null)
     {
         return;
     }
     if (r.Stats == null)
     {
         r.Stats = new RegionStats();
     }
     r.Stats.LastVisit = DateTime.UtcNow;
     if (r.IsResident(player))
     {
         r.Stats.LastVisitResident = DateTime.UtcNow;
     }
 }
Пример #12
0
        public static void WriteRegion(Client player, WorldRegion region, bool inside)
        {
            if (LogDate != DateTime.Now.Date)
            {
                OpenLog();
            }

            if (inside)
            {
                regionLog.WriteLine(Timestamp + "\t" +
                                    player.MinecraftUsername + "\tEntered\t" + region + "\tat" + player.Session.Position);
            }
            else
            {
                regionLog.WriteLine(Timestamp + "\t" +
                                    player.MinecraftUsername + "\tLeft\t" + region + "\tat" + player.Session.Position);
            }

            //regionLog.Flush ();
        }
Пример #13
0
        static bool Empty(WorldRegion r)
        {
            //To be removed
            List <WorldRegion> rem = new List <WorldRegion>();

            //Empty subregi ons
            foreach (WorldRegion wr in r.SubRegions)
            {
                if (Empty(wr))
                {
                    rem.Add(wr);
                }
            }
            foreach (WorldRegion tr in rem)
            {
                r.SubRegions.Remove(tr);
            }

            return(r.Residents.Count == 0 && r.SubRegions.Count == 0);
        }
Пример #14
0
        internal static bool FilterClient(WorldRegion region, Client player, Packet packet)
        {
            if (packet.PacketID != PlayerPositionLookClient.ID)
            {
                return(false);
            }

            CoordDouble pos = player.Session.Position;

            //Inner region
            if (region.SubRegions.Count == 0)
            {
                return(false);
            }
            WorldRegion inner = region.SubRegions[0];

            //Find proportions between region edges
            double dOuter = pos.X - region.MinX;

            dOuter = Math.Min(dOuter, region.MaxX - pos.X);
            dOuter = Math.Min(dOuter, pos.Z - region.MinZ);
            dOuter = Math.Min(dOuter, region.MaxZ - pos.Z);
            double dInner = inner.MinX - pos.X;

            dInner = Math.Max(dInner, pos.X - inner.MaxX);
            dInner = Math.Max(dInner, inner.MinZ - pos.Z);
            dInner = Math.Max(dInner, pos.Z - inner.MaxZ);

            double frac = dOuter / (dOuter + dInner);

#if DEBUG
            //player.Tell(frac.ToString("0.00") + ": " + dOuter + " " + dInner);
#endif

            player.SendToClient(NightTime(frac));

            return(false);
        }
Пример #15
0
        //Return null if no match is found
        //Return current if the list is the parent
        //Return the parent region if found
        public static WorldRegion GetParentRegion(List <WorldRegion> list, WorldRegion current)
        {
            foreach (WorldRegion r in list)
            {
                if (r.Dimension != current.Dimension)
                {
                    continue;
                }

                if (current.Overlap(r) == false)
                {
                    continue;
                }

                if (r == current)
                {
                    return(r);   //Signal that the parent is the list holder
                }
                if (r.SubRegions == null)
                {
                    throw new InvalidOperationException("Expected subregions");
                }

                WorldRegion w = GetParentRegion(r.SubRegions, current);

                if (w == current)
                {
                    return(r);   //return true parent
                }
                if (w != null)
                {
                    return(w); //return parent found in sub
                }
                //if null continue
            }
            return(null);
        }
Пример #16
0
 /// <summary>
 /// return the list "region" is located in
 /// </summary>
 public static List <WorldRegion> GetParentList(RegionList regions, WorldRegion region)
 {
     return(GetParentList(regions.List, region));
 }
Пример #17
0
        public void Resize(int minX, int maxX, int minY, int maxY, int minZ, int maxZ, Client player)
        {
            RegionList regions = player.Session.World.Regions;

            Region      test   = new Region(minX, maxX, minY, maxY, minZ, maxZ);
            WorldRegion parent = RegionCrossing.GetParentRegion(regions.List, this);

            if (parent == null)
            {
                player.TellSystem(Chat.Red, "parent not found");
                return;
            }

            if (player.Admin() == false)
            {
                if ((Donors.IsDonor(player) == false))
                {
                    player.TellSystem(Chat.Aqua, "Only for donors and admins may resize a region");
                    return;
                }
                //Useless since when only donors get this far:
                if (minY < 50 && (!player.Donor))
                {
                    player.TellSystem(Chat.Red, "Only admins and donors may make regions below Y=50");
                    return;
                }
                if (ResidentPermissions(player) == false)
                {
                    player.TellSystem(Chat.Yellow, "You are not a resident of this region");
                    return;
                }

                if (parent.ResidentPermissions(player) == false)
                {
                    player.TellSystem(Chat.Yellow, "You are not a resident of the parent region");
                    return;
                }
            }

            List <WorldRegion> list;

            if (parent == this)
            {
                list = player.Session.World.Regions.List;
            }
            else
            {
                list = parent.SubRegions;
            }

            //Make sure the new size overlaps the old one so we don't make huge mistakes
            if (test.Overlap(this) == false)
            {
                player.TellSystem(Chat.Red, "New size must overlap old one");
                player.TellSystem(Chat.Red, "New size " + test);
                player.TellSystem(Chat.Red, "Old size " + this.Coords());
                return;
            }

            //Check that the new size fits in the parent
            if (parent != this)
            {
                if (parent.Cover(test) == false)
                {
                    player.TellSystem(Chat.Red, "parent " + parent.Name + " is too small " + parent.Coords());
                    return;
                }
            }
            //else we are in the top level, no limit there

            //Make sure new size does not collide with siblings
            foreach (WorldRegion w in list)
            {
                if (w.Dimension != Dimension) //If toplevel "siblings" are all toplevel regions
                {
                    continue;
                }
                if (w == this)
                {
                    continue;
                }
                if (w.Overlap(test))
                {
                    player.TellSystem(Chat.Red, "new size overlap sibling " + w);
                    return;
                }
            }

            //Chech that subregions still fit into the new size
            if (SubRegions != null)
            {
                foreach (WorldRegion w in SubRegions)
                {
                    if (test.Cover(w) == false)
                    {
                        player.TellSystem(Chat.Red, "New size does not cover subregion:");
                        player.TellSystem(Chat.Red, w.ToString());
                        return;
                    }
                }
            }

            Log.WritePlayer(player, "Region Resized: from " + this + " to " + test);
            MinX = test.MinX;
            MaxX = test.MaxX;
            MinY = test.MinY;
            MaxY = test.MaxY;
            MinZ = test.MinZ;
            MaxZ = test.MaxZ;
            RegionLoader.Save(regions);
            player.TellSystem(Chat.Purple, "Region resized: " + this);
        }
Пример #18
0
        /// <summary>
        /// Find region and send message
        /// </summary>
        internal static void SetRegion(WorldSession session)
        {
            RegionList regions = session.World.Regions;

            if (regions == null)
            {
                return;
            }

            try
            {
                //This is called every single player movement, 20 times a second, some optimization might be needed.
                WorldRegion w = null;
                //First test if we are in the same as before
                WorldRegion current = session.CurrentRegion;
                if (current != null)
                {
                    if (current.Deleted == false && current.Contains(session.Position))
                    {
                        w = GetRegion(current.SubRegions, session.Position, session.Dimension);
                        if (w == null)
                        {
                            w = current;
                        }
                    }
                }
                if (w == null)
                {
                    w = GetRegion(regions.List, session.Position, session.Dimension);
                }

                //Debug.Write("Setregion: " + w);

                //If different
                if (session.CurrentRegion != w)
                {
                    //Leaving
                    if (session.CurrentRegion != null && (session.CurrentRegion.HasChild(w) == false))
                    {
                        session.CurrentRegion.Leaving(session.Player, w);
                    }

                    //Entering
                    if (w != null && w.HasChild(session.CurrentRegion) == false)
                    {
                        w.Entering(session.Player);
                    }

                    //Stats
                    SetStats(session.CurrentRegion, session.Player);
                    SetStats(w, session.Player);
                }
                //Adjust Survival/Adventure mode
                if (session.Mode != GameMode.Creative &&
                    session.Mode != GameMode.Spectator)
                {
                    bool protect = Protected.IsBlockProtected(session, w);
                    if (protect && w.IsResident(session.Player))
                    {
                        protect = false;
                    }

                    if (protect)
                    {
                        session.SetMode(GameMode.Adventure);
                    }
                    else
                    {
                        session.SetMode(GameMode.Survival);
                    }
                }

                if (w != null && w.Type == WarpZone.Type)
                {
                    if (session.Mode != GameMode.Creative)
                    {
                        WarpZone wz = new WarpZone(w.Name);
                        session.Player.Warp(wz.Destination, (Dimensions)wz.DestinationDimension, wz.DesinationWorld);
                    }
                }

                bool update = (w != session.CurrentRegion);
                session.CurrentRegion = w;
                if (update)
                {
                    ScoreboardRegionManager.UpdateRegion(session.Player);
                }
#if !DEBUG
            } catch (Exception e)
            {
                Log.WriteServer(e);
                return;
#endif
            } finally
            {
            }
        }