/// <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); }
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); }
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); }
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); }
/// <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); }
/// <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)); }
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); }
public override bool Overlap(Region r) { WorldRegion w = r as WorldRegion; if (w != null && w.Dimension != Dimension) { return(false); } return(base.Overlap(r)); }
/// <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); }
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); }
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; } }
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 (); }
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); }
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); }
//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); }
/// <summary> /// return the list "region" is located in /// </summary> public static List <WorldRegion> GetParentList(RegionList regions, WorldRegion region) { return(GetParentList(regions.List, region)); }
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); }
/// <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 { } }