Example #1
0
        private bool OnAllowedIncomingTeleport(UUID userID, IScene scene, Vector3 Position, uint TeleportFlags,
                                               out Vector3 newPosition, out string reason)
        {
            newPosition = Position;
            UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.AllScopeIDs, userID);

            IScenePresence Sp = scene.GetScenePresence(userID);

            if (account == null)
            {
                reason = "Failed authentication.";
                return(false); //NO!
            }


            //Make sure that this user is inside the region as well
            if (Position.X < -2f || Position.Y < -2f ||
                Position.X > scene.RegionInfo.RegionSizeX + 2 || Position.Y > scene.RegionInfo.RegionSizeY + 2)
            {
                MainConsole.Instance.DebugFormat(
                    "[EstateService]: AllowedIncomingTeleport was given an illegal position of {0} for avatar {1}, {2}. Clamping",
                    Position, Name, userID);
                bool changedX = false;
                bool changedY = false;
                while (Position.X < 0)
                {
                    Position.X += scene.RegionInfo.RegionSizeX;
                    changedX    = true;
                }
                while (Position.X > scene.RegionInfo.RegionSizeX)
                {
                    Position.X -= scene.RegionInfo.RegionSizeX;
                    changedX    = true;
                }

                while (Position.Y < 0)
                {
                    Position.Y += scene.RegionInfo.RegionSizeY;
                    changedY    = true;
                }
                while (Position.Y > scene.RegionInfo.RegionSizeY)
                {
                    Position.Y -= scene.RegionInfo.RegionSizeY;
                    changedY    = true;
                }

                if (changedX)
                {
                    Position.X = scene.RegionInfo.RegionSizeX - Position.X;
                }
                if (changedY)
                {
                    Position.Y = scene.RegionInfo.RegionSizeY - Position.Y;
                }
            }

            IAgentConnector AgentConnector = Framework.Utilities.DataManager.RequestPlugin <IAgentConnector>();
            IAgentInfo      agentInfo      = null;

            if (AgentConnector != null)
            {
                agentInfo = AgentConnector.GetAgent(userID);
            }

            ILandObject             ILO = null;
            IParcelManagementModule parcelManagement = scene.RequestModuleInterface <IParcelManagementModule>();

            if (parcelManagement != null)
            {
                ILO = parcelManagement.GetLandObject(Position.X, Position.Y);
            }

            if (ILO == null)
            {
                if (Sp != null)
                {
                    Sp.ClearSavedVelocity(); //If we are moving the agent, clear their velocity
                }
                //Can't find land, give them the first parcel in the region and find a good position for them
                ILO      = parcelManagement.AllParcels()[0];
                Position = parcelManagement.GetParcelCenterAtGround(ILO);
            }

            //parcel permissions
            if (ILO.IsBannedFromLand(userID)) //Note: restricted is dealt with in the next block
            {
                if (Sp != null)
                {
                    Sp.ClearSavedVelocity(); //If we are moving the agent, clear their velocity
                }
                if (Sp == null)
                {
                    reason = "Banned from this parcel.";
                    return(false);
                }

                if (!FindUnBannedParcel(Position, Sp, userID, out ILO, out newPosition, out reason))
                {
                    //We found a place for them, but we don't need to check any further on positions here
                    //return true;
                }
            }
            //Move them out of banned parcels
            ParcelFlags parcelflags = (ParcelFlags)ILO.LandData.Flags;

            if ((parcelflags & ParcelFlags.UseAccessGroup) == ParcelFlags.UseAccessGroup &&
                (parcelflags & ParcelFlags.UseAccessList) == ParcelFlags.UseAccessList &&
                (parcelflags & ParcelFlags.UsePassList) == ParcelFlags.UsePassList)
            {
                if (Sp != null)
                {
                    Sp.ClearSavedVelocity(); //If we are moving the agent, clear their velocity
                }
                //One of these is in play then
                if ((parcelflags & ParcelFlags.UseAccessGroup) == ParcelFlags.UseAccessGroup)
                {
                    if (Sp == null)
                    {
                        reason = "Banned from this parcel.";
                        return(false);
                    }
                    if (Sp.ControllingClient.ActiveGroupId != ILO.LandData.GroupID)
                    {
                        if (!FindUnBannedParcel(Position, Sp, userID, out ILO, out newPosition, out reason))
                        {
                            //We found a place for them, but we don't need to check any further on positions here
                            //return true;
                        }
                    }
                }
                else if ((parcelflags & ParcelFlags.UseAccessList) == ParcelFlags.UseAccessList)
                {
                    if (Sp == null)
                    {
                        reason = "Banned from this parcel.";
                        return(false);
                    }
                    //All but the people on the access list are banned
                    if (ILO.IsRestrictedFromLand(userID))
                    {
                        if (!FindUnBannedParcel(Position, Sp, userID, out ILO, out newPosition, out reason))
                        {
                            //We found a place for them, but we don't need to check any further on positions here
                            //return true;
                        }
                    }
                }
                else if ((parcelflags & ParcelFlags.UsePassList) == ParcelFlags.UsePassList)
                {
                    if (Sp == null)
                    {
                        reason = "Banned from this parcel.";
                        return(false);
                    }
                    //All but the people on the pass/access list are banned
                    if (ILO.IsRestrictedFromLand(Sp.UUID))
                    {
                        if (!FindUnBannedParcel(Position, Sp, userID, out ILO, out newPosition, out reason))
                        {
                            //We found a place for them, but we don't need to check any further on positions here
                            //return true;
                        }
                    }
                }
            }

            EstateSettings      ES             = scene.RegionInfo.EstateSettings;
            TeleportFlags       tpflags        = (TeleportFlags)TeleportFlags;
            const TeleportFlags allowableFlags =
                OpenMetaverse.TeleportFlags.ViaLandmark | OpenMetaverse.TeleportFlags.ViaHome |
                OpenMetaverse.TeleportFlags.ViaLure |
                OpenMetaverse.TeleportFlags.ForceRedirect |
                OpenMetaverse.TeleportFlags.Godlike | OpenMetaverse.TeleportFlags.NineOneOne;

            //If the user wants to force landing points on crossing, we act like they are not crossing, otherwise, check the child property and that the ViaRegionID is set
            bool isCrossing = !ForceLandingPointsOnCrossing && (Sp != null && Sp.IsChildAgent &&
                                                                ((tpflags & OpenMetaverse.TeleportFlags.ViaRegionID) ==
                                                                 OpenMetaverse.TeleportFlags.ViaRegionID));

            //Move them to the nearest landing point
            if (!((tpflags & allowableFlags) != 0) && !isCrossing && !ES.AllowDirectTeleport)
            {
                if (Sp != null)
                {
                    Sp.ClearSavedVelocity(); //If we are moving the agent, clear their velocity
                }
                if (!scene.Permissions.IsGod(userID))
                {
                    Telehub telehub = RegionConnector.FindTelehub(scene.RegionInfo.RegionID,
                                                                  scene.RegionInfo.RegionHandle);
                    if (telehub != null)
                    {
                        if (telehub.SpawnPos.Count == 0)
                        {
                            Position = new Vector3(telehub.TelehubLocX, telehub.TelehubLocY, telehub.TelehubLocZ);
                        }
                        else
                        {
                            int LastTelehubNum = 0;
                            if (!LastTelehub.TryGetValue(scene.RegionInfo.RegionID, out LastTelehubNum))
                            {
                                LastTelehubNum = 0;
                            }
                            Position = telehub.SpawnPos[LastTelehubNum] +
                                       new Vector3(telehub.TelehubLocX, telehub.TelehubLocY, telehub.TelehubLocZ);
                            LastTelehubNum++;
                            if (LastTelehubNum == telehub.SpawnPos.Count)
                            {
                                LastTelehubNum = 0;
                            }
                            LastTelehub[scene.RegionInfo.RegionID] = LastTelehubNum;
                        }
                    }
                }
            }
            else if (!((tpflags & allowableFlags) != 0) && !isCrossing &&
                     !scene.Permissions.GenericParcelPermission(userID, ILO, (ulong)GroupPowers.None))
            //Telehubs override parcels
            {
                if (Sp != null)
                {
                    Sp.ClearSavedVelocity();                           //If we are moving the agent, clear their velocity
                }
                if (ILO.LandData.LandingType == (int)LandingType.None) //Blocked, force this person off this land
                {
                    //Find a new parcel for them
                    List <ILandObject> Parcels = parcelManagement.ParcelsNearPoint(Position);
                    if (Parcels.Count > 1)
                    {
                        newPosition = parcelManagement.GetNearestRegionEdgePosition(Sp);
                    }
                    else
                    {
                        bool found = false;
                        //We need to check here as well for bans, can't toss someone into a parcel they are banned from
                        foreach (ILandObject Parcel in Parcels.Where(Parcel => !Parcel.IsBannedFromLand(userID)))
                        {
                            //Now we have to check their userloc
                            if (ILO.LandData.LandingType == (int)LandingType.None)
                            {
                                continue; //Blocked, check next one
                            }
                            else if (ILO.LandData.LandingType == (int)LandingType.LandingPoint)
                            {
                                //Use their landing spot
                                newPosition = Parcel.LandData.UserLocation;
                            }
                            else //They allow for anywhere, so dump them in the center at the ground
                            {
                                newPosition = parcelManagement.GetParcelCenterAtGround(Parcel);
                            }
                            found = true;
                        }

                        if (!found) //Dump them at the edge
                        {
                            if (Sp != null)
                            {
                                newPosition = parcelManagement.GetNearestRegionEdgePosition(Sp);
                            }
                            else
                            {
                                reason = "Banned from this parcel.";
                                return(false);
                            }
                        }
                    }
                }
                else if (ILO.LandData.LandingType == (int)LandingType.LandingPoint)  //Move to tp spot
                {
                    newPosition = ILO.LandData.UserLocation != Vector3.Zero
                                      ? ILO.LandData.UserLocation
                                      : parcelManagement.GetNearestRegionEdgePosition(Sp);
                }
            }

            //We assume that our own region isn't null....
            if (agentInfo != null)
            {
                //Can only enter prelude regions once!
                if (scene.RegionInfo.RegionFlags != -1 &&
                    ((scene.RegionInfo.RegionFlags & (int)RegionFlags.Prelude) == (int)RegionFlags.Prelude) &&
                    agentInfo != null)
                {
                    if (agentInfo.OtherAgentInformation.ContainsKey("Prelude" + scene.RegionInfo.RegionID))
                    {
                        reason = "You may not enter this region as you have already been to this prelude region.";
                        return(false);
                    }
                    else
                    {
                        agentInfo.OtherAgentInformation.Add("Prelude" + scene.RegionInfo.RegionID,
                                                            OSD.FromInteger((int)IAgentFlags.PastPrelude));
                        AgentConnector.UpdateAgent(agentInfo);
                    }
                }
                if (agentInfo.OtherAgentInformation.ContainsKey("LimitedToEstate"))
                {
                    int LimitedToEstate = agentInfo.OtherAgentInformation["LimitedToEstate"];
                    if (scene.RegionInfo.EstateSettings.EstateID != LimitedToEstate)
                    {
                        reason = "You may not enter this reason, as it is outside of the estate you are limited to.";
                        return(false);
                    }
                }
            }


            if ((ILO.LandData.Flags & (int)ParcelFlags.DenyAnonymous) != 0)
            {
                if (account != null &&
                    (account.UserFlags & (int)IUserProfileInfo.ProfileFlags.NoPaymentInfoOnFile) ==
                    (int)IUserProfileInfo.ProfileFlags.NoPaymentInfoOnFile)
                {
                    reason = "You may not enter this region.";
                    return(false);
                }
            }

            if ((ILO.LandData.Flags & (uint)ParcelFlags.DenyAgeUnverified) != 0 && agentInfo != null)
            {
                if ((agentInfo.Flags & IAgentFlags.Minor) == IAgentFlags.Minor)
                {
                    reason = "You may not enter this region.";
                    return(false);
                }
            }

            //Check that we are not underground as well
            ITerrainChannel chan = scene.RequestModuleInterface <ITerrainChannel>();

            if (chan != null)
            {
                float posZLimit = chan[(int)newPosition.X, (int)newPosition.Y] + (float)1.25;

                if (posZLimit >= (newPosition.Z) && !(Single.IsInfinity(posZLimit) || Single.IsNaN(posZLimit)))
                {
                    newPosition.Z = posZLimit;
                }
            }

            //newPosition = Position;
            reason = "";
            return(true);
        }