private void HandleParcelBuy(AgentCircuit circuit, SceneInterface scene, Message m)
        {
            var req = (ParcelBuy)m;

            if (req.CircuitAgentID != req.AgentID ||
                req.CircuitSessionID != req.SessionID)
            {
                return;
            }

            ViewerAgent agent = circuit.Agent;

            ParcelInfo pinfo;

            if (scene.Parcels.TryGetValue(req.LocalID, out pinfo) && (pinfo.Flags & ParcelFlags.ForSale) != 0)
            {
                if (pinfo.AuthBuyer.EqualsGrid(agent.Owner) || pinfo.AuthBuyer == UGUI.Unknown)
                {
                    if (pinfo.SalePrice != 0)
                    {
                        /* we have to process it on economy */
                        EconomyServiceInterface economyService = agent.EconomyService;
                        if (economyService != null)
                        {
                            if (pinfo.GroupOwned)
                            {
                                economyService.TransferMoney(agent.Owner, pinfo.Group, new LandSaleTransaction(scene.GetRegionInfo().Location, scene.ID, scene.Name)
                                {
                                    ParcelID   = pinfo.ID,
                                    ParcelName = pinfo.Name
                                }, pinfo.SalePrice, () => ChangeParcelOwnership(scene, pinfo, agent.Owner, pinfo.SalePrice, req));
                            }
                            else
                            {
                                economyService.TransferMoney(agent.Owner, pinfo.Owner, new LandSaleTransaction(scene.GetRegionInfo().Location, scene.ID, scene.Name)
                                {
                                    ParcelID   = pinfo.ID,
                                    ParcelName = pinfo.Name
                                }, pinfo.SalePrice, () => ChangeParcelOwnership(scene, pinfo, agent.Owner, pinfo.SalePrice, req));
                            }
                        }
                    }
                    else
                    {
                        ChangeParcelOwnership(scene, pinfo, agent.Owner, pinfo.SalePrice, req);
                    }
                }
            }
        }
        private void HandleParcelClaim(AgentCircuit circuit, SceneInterface scene, Message m)
        {
            var req = (ParcelClaim)m;

            if (req.CircuitAgentID != req.AgentID ||
                req.CircuitSessionID != req.SessionID)
            {
                return;
            }

            ViewerAgent agent = circuit.Agent;

            int totalPrice = 0;

            foreach (ParcelClaim.ParcelDataEntry d in req.ParcelData)
            {
                if (!scene.IsParcelClaimable((int)Math.Round(d.West), (int)Math.Round(d.South), (int)Math.Round(d.East), (int)Math.Round(d.North)))
                {
                    return;
                }
                totalPrice += CalculateClaimPrice(d);
            }

            int    parcelClaimPrice  = scene.EconomyData.PriceParcelClaim;
            double parcelClaimFactor = scene.EconomyData.PriceParcelClaimFactor;

            totalPrice = (int)Math.Ceiling(totalPrice * parcelClaimPrice * parcelClaimFactor);
            EconomyServiceInterface economyService = agent.EconomyService;

            if (totalPrice == 0)
            {
                foreach (ParcelClaim.ParcelDataEntry d in req.ParcelData)
                {
                    scene.ClaimParcel(agent.Owner, (int)Math.Round(d.West), (int)Math.Round(d.South), (int)Math.Round(d.East), (int)Math.Round(d.North),
                                      CalculateClaimPrice(d));
                }
            }
            else if (economyService != null)
            {
                economyService.ChargeAmount(agent.Owner, new LandClaimTransaction(scene.GridPosition, scene.ID, scene.Name), totalPrice, () =>
                {
                    foreach (ParcelClaim.ParcelDataEntry d in req.ParcelData)
                    {
                        scene.ClaimParcel(agent.Owner, (int)Math.Round(d.West), (int)Math.Round(d.South), (int)Math.Round(d.East), (int)Math.Round(d.North),
                                          CalculateClaimPrice(d));
                    }
                });
            }
        }
        public void Startup(ConfigurationLoader loader)
        {
            m_CommandRegistry           = loader.CommandRegistry;
            m_TeleportProtocols         = loader.GetServicesByValue <ITeleportHandlerFactoryServiceInterface>();
            m_UserSessionStatusServices = loader.GetServicesByValue <IUserSessionStatusHandler>();
            m_Scenes                = loader.Scenes;
            m_CapsRedirector        = loader.CapsRedirector;
            m_AuthorizationServices = loader.GetServicesByValue <AuthorizationServiceInterface>();
            m_HttpServer            = loader.HttpServer;
            m_GridService           = loader.GetService <GridServiceInterface>(m_GridServiceName);
            Commands                = loader.CommandRegistry;
            m_PacketHandlerPlugins  = loader.GetServicesByValue <IProtocolExtender>();
            m_GatekeeperURI         = loader.GatekeeperURI;

            loader.GetService(m_LocalUserAccountServiceName, out m_LocalUserAccountService);
            loader.GetService(m_LocalAssetServiceName, out m_LocalAssetService);
            loader.GetService(m_LocalInventoryServiceName, out m_LocalInventoryService);
            if (!string.IsNullOrEmpty(m_LocalProfileServiceName))
            {
                loader.GetService(m_LocalProfileServiceName, out m_LocalProfileService);
            }
            loader.GetService(m_LocalFriendsServiceName, out m_LocalFriendsService);
            loader.GetService(m_LocalUserSessionServiceName, out m_LocalUserSessionService);
            loader.GetService(m_LocalOfflineIMServiceName, out m_LocalOfflineIMService);
            if (!string.IsNullOrEmpty(m_LocalGroupsServiceName))
            {
                loader.GetService(m_LocalGroupsServiceName, out m_LocalGroupsService);
            }
            if (!string.IsNullOrEmpty(m_LocalExperienceServiceName))
            {
                loader.GetService(m_LocalExperienceServiceName, out m_LocalExperienceService);
            }
            if (!loader.TryGetService(m_LocalEconomyServiceName, out m_LocalEconomyService))
            {
                m_LocalEconomyService = null;
            }
        }
        public SimulatorFeatures(ViewerAgent agent, SceneInterface scene, string remoteip)
        {
            m_Agent    = agent;
            m_Scene    = scene;
            m_RemoteIP = remoteip;

            Features.Add("MeshRezEnabled", true);
            Features.Add("MeshUploadEnabled", true);
            Features.Add("MeshXferEnabled", true);
            Features.Add("PhysicsMaterialsEnabled", true);
            Features.Add("RenderMaterialsCapability", 1.0);
            Features.Add("MaxMaterialsPerTransaction", 50);
            Features.Add("DynamicPathfindingEnabled", scene.PathfindingService?.IsDynamicEnabled ?? false);
            Features.Add("AvatarHoverHeightEnabled", true);
            Features.Add("PhysicsShapeTypes", new Map
            {
                { "convex", true },
                { "none", true },
                { "prim", true }
            });
            Features.Add("AnimatedObjects", new Map
            {
                { "AnimatedObjectMaxTris", 20000 },
                { "MaxAgentAnimatedObjectAttachments", 2 }
            });
            var extrasMap = new Map();

            if (!string.IsNullOrEmpty(scene.GatekeeperURI))
            {
                extrasMap.Add("GridURL", scene.GatekeeperURI);
            }

            extrasMap.Add("SimulatorFPS", 30.0);
            extrasMap.Add("SimulatorFPSWarnPercent", 66.6);
            extrasMap.Add("SimulatorFPSCritPercent", 33.3);
            extrasMap.Add("SimulatorFPSFactor", 1.0);
            extrasMap.Add("ExportSupported", true);
            EconomyServiceInterface economyService = agent.EconomyService;

            foreach (KeyValuePair <string, IValue> kvp in scene.SimulatorFeaturesExtrasMap)
            {
                extrasMap[kvp.Key] = kvp.Value;
            }
            if (economyService != null)
            {
                extrasMap["currency"] = new AString(economyService.CurrencySymbol);
            }
            if (extrasMap.Count > 0)
            {
                Features.Add("OpenSimExtras", extrasMap);
            }

            /* known OpenSimExtras
             * GridName:string
             * GridURL:string
             * ExportSupported:bool
             * map-server-url:string
             * say-range:integer
             * shout-range:integer
             * whisper-range:integer
             * SimulatorFPS:double
             * SimulatorFPSFactor:double
             * SimulatorFPSWarnPercent:double
             * SimulatorFPSCritPercent:double
             * search-server-url:string
             * destination-guide-url:string
             * avatar-picker-url:string
             * camera-only-mode:bool
             * special-ui:map(toolbar:string,floaters:map)
             * currency
             * currency-base-uri
             *
             * known root features:
             * god_names:map(last_names:array(string),full_names:array(string))
             * MeshRezEnabled:bool
             * MeshUploadEnabled:bool
             * MeshXferEnabled:true
             * PhysicsMaterialsEnabled:true
             * RenderMaterialsCapability:double
             * MaxMaterialsPerTransaction:integer
             * DynamicPathfindingEnabled:bool
             * AvatarHoverHeightEnabled:bool
             * PhysicsShapeTypes:map(convex:bool,none:bool,prim:bool)
             */
        }
        private XmlRpc.XmlRpcResponse HandleGetCurrencyQuote(XmlRpc.XmlRpcRequest req)
        {
            Map     structParam;
            UUID    agentId;
            UUID    secureSessionId;
            Integer currencyBuy;
            IValue  language;

            if (!req.Params.TryGetValue(0, out structParam) ||
                !structParam.TryGetValue("agentId", out agentId) ||
                !structParam.TryGetValue("secureSessionId", out secureSessionId) ||
                !structParam.TryGetValue("currencyBuy", out currencyBuy) ||
                !structParam.TryGetValue("language", out language))
            {
                throw new XmlRpc.XmlRpcFaultException(4, "Missing parameters");
            }

            bool   validated = false;
            IAgent agent     = null;

            foreach (SceneInterface scene in m_Scenes.ValuesByKey1)
            {
                if (scene.Agents.TryGetValue(agentId, out agent) && agent.Session.SecureSessionID == secureSessionId)
                {
                    validated = true;
                    break;
                }
            }

            var resdata = new Map();

            if (!validated)
            {
                resdata.Add("success", false);
                resdata.Add("errorMessage", this.GetLanguageString(GetLanguageCulture(language.ToString()), "UnableToAuthenticate", "Unable to authenticate."));
                resdata.Add("errorURI", string.Empty);
                return(new XmlRpc.XmlRpcResponse {
                    ReturnValue = resdata
                });
            }

            EconomyServiceInterface economyService = agent.EconomyService;

            if (economyService == null)
            {
                resdata.Add("success", false);
                resdata.Add("errorMessage", this.GetLanguageString(agent.CurrentCulture, "NoEconomyConfigured", "No economy configured."));
                resdata.Add("errorURI", string.Empty);
                return(new XmlRpc.XmlRpcResponse {
                    ReturnValue = resdata
                });
            }

            EconomyServiceInterface.CurrencyQuote quote;

            try
            {
                quote = economyService.GetCurrencyQuote(agent.Owner, language.ToString(), currencyBuy.AsInt);
            }
            catch (EconomyServiceInterface.UrlAttachedErrorException e)
            {
                resdata.Add("success", false);
                resdata.Add("errorMessage", e.Message);
                resdata.Add("errorURI", e.Uri);
                return(new XmlRpc.XmlRpcResponse {
                    ReturnValue = resdata
                });
            }
            catch (Exception e)
            {
                resdata.Add("success", false);
                resdata.Add("errorMessage", "\n\n" + e.Message);
                resdata.Add("errorURI", string.Empty);
                return(new XmlRpc.XmlRpcResponse {
                    ReturnValue = resdata
                });
            }

            resdata.Add("currency", quote.LocalCurrency);
            resdata.Add("estimatedCost", quote.EstimatedUsCents);
            resdata.Add("estimatedLocalCost", quote.EstimatedLocalCost);
            resdata.Add("currencyBuy", quote.CurrencyToBuy);
            switch (quote.ConfirmType)
            {
            case EconomyServiceInterface.ConfirmTypeEnum.None:
                resdata.Add("confirm", "none");
                break;

            default:
                resdata.Add("confirm", "click");
                break;

            case EconomyServiceInterface.ConfirmTypeEnum.Password:
                resdata.Add("confirm", "password");
                break;
            }

            return(new XmlRpc.XmlRpcResponse {
                ReturnValue = resdata
            });
        }
        public void HandleBuyPass(Message m)
        {
            var p = (ParcelBuyPass)m;

            if (p.CircuitAgentID != p.AgentID ||
                p.CircuitSessionID != p.SessionID)
            {
                return;
            }

            IAgent agent;

            if (!Agents.TryGetValue(p.AgentID, out agent))
            {
                return;
            }

            ParcelInfo parcelInfo;

            if (!Parcels.TryGetValue(p.LocalID, out parcelInfo))
            {
                return;
            }

            double passHours = parcelInfo.PassHours;
            int    passPrice = parcelInfo.PassPrice;

            if ((parcelInfo.Flags & ParcelFlags.UsePassList) == 0 || passPrice < 0 || passHours <= 0)
            {
                return;
            }

            EconomyServiceInterface economyService = agent.EconomyService;

            if (economyService == null)
            {
                agent.SendAlertMessage(this.GetLanguageString(agent.CurrentCulture, "UnableToBuyNoEconomyConfigured", "Unable to buy. No economy configured."), ID);
                return;
            }

            var extendSeconds = (ulong)TimeSpan.FromHours(passHours).Seconds;

            if (parcelInfo.GroupOwned)
            {
                economyService.TransferMoney(agent.Owner, parcelInfo.Group, new LandpassSaleTransaction(
                                                 GridPosition,
                                                 ID,
                                                 Name)
                {
                    ParcelID   = parcelInfo.ID,
                    ParcelName = parcelInfo.Name,
                    PassHours  = passHours
                }, passPrice, () => Parcels.LandpassList.ExtendExpiry(ID, parcelInfo.ID, agent.Owner, extendSeconds));
            }
            else
            {
                economyService.TransferMoney(agent.Owner, parcelInfo.Owner, new LandpassSaleTransaction(
                                                 GridPosition,
                                                 ID,
                                                 Name)
                {
                    ParcelID   = parcelInfo.ID,
                    ParcelName = parcelInfo.Name,
                    PassHours  = passHours
                }, passPrice, () => Parcels.LandpassList.ExtendExpiry(ID, parcelInfo.ID, agent.Owner, extendSeconds));
            }
        }