private void UndeliveredMessage(GridInstantMessage im) { if ((im.offline != 0) && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) { if (im.dialog == 32) //Group notice { IGroupsModule module = m_SceneList[0].RequestModuleInterface <IGroupsModule>(); if (module != null) { im = module.BuildOfflineGroupNotice(im); } } OfflineMessagesConnector.AddOfflineMessage(im); if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) { IClientAPI client = FindClient(new UUID(im.fromAgentID)); if (client == null) { return; } client.SendInstantMessage(new GridInstantMessage( null, new UUID(im.toAgentID), "System", new UUID(im.fromAgentID), (byte)InstantMessageDialog.MessageFromAgent, "User is not logged in. Message saved.", false, new Vector3())); } if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) { OfflineMessagesConnector.AddOfflineMessage(im); IClientAPI client = FindClient(new UUID(im.fromAgentID)); if (client == null) { return; } client.SendAlertMessage("User is not online. Inventory has been saved"); } } else if (im.offline == 0) { OfflineMessagesConnector.AddOfflineMessage(im); if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) { IClientAPI client = FindClient(new UUID(im.fromAgentID)); if (client == null) { return; } client.SendInstantMessage(new GridInstantMessage( null, new UUID(im.toAgentID), "System", new UUID(im.fromAgentID), (byte)InstantMessageDialog.MessageFromAgent, "User is not able to be found. Message saved.", false, new Vector3())); } if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) { OfflineMessagesConnector.AddOfflineMessage(im); IClientAPI client = FindClient(new UUID(im.fromAgentID)); if (client == null) { return; } client.SendAlertMessage("User not able to be found. Inventory has been saved"); } } }
public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) { if (m_scene.RegionInfo.EstateSettings.AllowParcelChanges) { try { bool snap_selection = false; if (args.AuthBuyerID != LandData.AuthBuyerID || args.SalePrice != LandData.SalePrice) { if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this) && m_scene.RegionInfo.RegionSettings.AllowLandResell) { LandData.AuthBuyerID = args.AuthBuyerID; LandData.SalePrice = args.SalePrice; snap_selection = true; } else { remote_client.SendAlertMessage("Permissions: You cannot set this parcel for sale"); args.ParcelFlags &= ~(uint) ParcelFlags.ForSale; args.ParcelFlags &= ~(uint) ParcelFlags.ForSaleObjects; args.ParcelFlags &= ~(uint) ParcelFlags.SellParcelObjects; } } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale)) { if (!LandData.IsGroupOwned) { LandData.GroupID = args.GroupID; } } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.FindPlaces)) LandData.Category = args.Category; if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.ChangeMedia)) { LandData.MediaAutoScale = args.MediaAutoScale; LandData.MediaID = args.MediaID; LandData.MediaURL = args.MediaURL; LandData.MusicURL = args.MusicURL; LandData.MediaType = args.MediaType; LandData.MediaDescription = args.MediaDescription; LandData.MediaWidth = args.MediaWidth; LandData.MediaHeight = args.MediaHeight; LandData.MediaLoop = args.MediaLoop; LandData.ObscureMusic = args.ObscureMusic; LandData.ObscureMedia = args.ObscureMedia; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) { if (m_scene.RegionInfo.RegionSettings.BlockFly && ((args.ParcelFlags & (uint)ParcelFlags.AllowFly) == (uint)ParcelFlags.AllowFly)) //Vanquish flying as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.AllowFly; if (m_scene.RegionInfo.RegionSettings.RestrictPushing && ((args.ParcelFlags & (uint)ParcelFlags.RestrictPushObject) == (uint)ParcelFlags.RestrictPushObject)) //Vanquish pushing as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.RestrictPushObject; if (!m_scene.RegionInfo.EstateSettings.AllowLandmark && ((args.ParcelFlags & (uint)ParcelFlags.AllowLandmark) == (uint)ParcelFlags.AllowLandmark)) //Vanquish landmarks as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.AllowLandmark; if (m_scene.RegionInfo.RegionSettings.BlockShowInSearch && ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory)) //Vanquish show in search as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.ShowDirectory; if ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory && (LandData.Flags & (uint)ParcelFlags.ShowDirectory) != (uint)ParcelFlags.ShowDirectory) { //If the flags have changed, we need to charge them.. maybe // We really need to check per month or whatever IScheduledMoneyModule scheduledMoneyModule = m_scene.RequestModuleInterface<IScheduledMoneyModule>(); IMoneyModule moneyModule = m_scene.RequestModuleInterface<IMoneyModule>(); if (scheduledMoneyModule != null) { if ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory) { //Flag is set if (!scheduledMoneyModule.Charge(remote_client.AgentId, moneyModule.DirectoryFeeCharge, "Parcel Show in Search Fee - " + LandData.GlobalID, 7, TransactionType.ParcelDirFee, "ShowInDirectory" + LandData.GlobalID.ToString(), false))// was true { remote_client.SendAlertMessage( "You don't have enough money to set this parcel in search."); args.ParcelFlags &= (uint)ParcelFlags.ShowDirectory; } } else { scheduledMoneyModule.RemoveFromScheduledCharge("ShowInDirectory" + LandData.GlobalID.ToString()); } } } LandData.Flags = args.ParcelFlags; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.SetLandingPoint)) { LandData.LandingType = args.LandingType; LandData.UserLocation = args.UserLocation; LandData.UserLookAt = args.UserLookAt; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandChangeIdentity)) { LandData.Description = args.Desc; LandData.Name = args.Name; LandData.SnapshotID = args.SnapshotID; LandData.Private = args.Privacy; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManagePasses)) { LandData.PassHours = args.PassHours; LandData.PassPrice = args.PassPrice; } LandData.Status = LandData.OwnerID == m_parcelManagementModule.GodParcelOwner ? ParcelStatus.Abandoned : LandData.AuthBuyerID != UUID.Zero ? ParcelStatus.LeasePending : ParcelStatus.Leased; m_parcelManagementModule.UpdateLandObject(this); SendLandUpdateToAvatarsOverMe(snap_selection); } catch (Exception ex) { MainConsole.Instance.Warn("[LAND]: Error updating land object " + this.LandData.Name + " in region " + this.m_scene.RegionInfo.RegionName + " : " + ex); } } }
public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) { if (m_scene.Permissions.CanEditParcel(remote_client.AgentId, this) && m_scene.RegionInfo.EstateSettings.AllowParcelChanges) { try { bool snap_selection = false; LandData newData = LandData.Copy(); if (args.AuthBuyerID != newData.AuthBuyerID || args.SalePrice != newData.SalePrice) { if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this) && m_scene.RegionInfo.RegionSettings.AllowLandResell) { newData.AuthBuyerID = args.AuthBuyerID; newData.SalePrice = args.SalePrice; snap_selection = true; } else remote_client.SendAlertMessage("Permissions: You cannot set this parcel for sale"); } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale)) { if (!LandData.IsGroupOwned) { newData.GroupID = args.GroupID; } } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.FindPlaces)) { newData.Category = args.Category; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.ChangeMedia)) { newData.MediaAutoScale = args.MediaAutoScale; newData.MediaID = args.MediaID; newData.MediaURL = args.MediaURL; newData.MusicURL = args.MusicURL; newData.MediaType = args.MediaType; newData.MediaDescription = args.MediaDescription; newData.MediaWidth = args.MediaWidth; newData.MediaHeight = args.MediaHeight; newData.MediaLoop = args.MediaLoop; newData.ObscureMusic = args.ObscureMusic; newData.ObscureMedia = args.ObscureMedia; } if (m_scene.RegionInfo.RegionSettings.BlockFly && ((args.ParcelFlags & (uint)ParcelFlags.AllowFly) == (uint)ParcelFlags.AllowFly)) //Vanquish flying as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.AllowFly; if (m_scene.RegionInfo.RegionSettings.RestrictPushing && ((args.ParcelFlags & (uint)ParcelFlags.RestrictPushObject) == (uint)ParcelFlags.RestrictPushObject)) //Vanquish pushing as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.RestrictPushObject; if (!m_scene.RegionInfo.EstateSettings.AllowLandmark && ((args.ParcelFlags & (uint)ParcelFlags.AllowLandmark) == (uint)ParcelFlags.AllowLandmark)) //Vanquish landmarks as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.AllowLandmark; if (m_scene.RegionInfo.RegionSettings.BlockShowInSearch && ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory)) //Vanquish show in search as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.ShowDirectory; if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.SetLandingPoint)) { newData.LandingType = args.LandingType; newData.UserLocation = args.UserLocation; newData.UserLookAt = args.UserLookAt; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandChangeIdentity)) { newData.Description = args.Desc; newData.Name = args.Name; newData.SnapshotID = args.SnapshotID; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManagePasses)) { newData.PassHours = args.PassHours; newData.PassPrice = args.PassPrice; } newData.Flags = args.ParcelFlags; m_parcelManagementModule.UpdateLandObject(LandData.LocalID, newData); SendLandUpdateToAvatarsOverMe(snap_selection); } catch(Exception ex) { m_log.Warn("[LAND]: Error updating land object " + this.LandData.Name + " in region " + this.m_scene.RegionInfo.RegionName + " : " + ex.ToString()); } } }
private void handleUploadTerrain(IClientAPI remote_client, string clientFileName) { lock (this) { if (TerrainUploader == null) { m_log.DebugFormat("Starting to receive uploaded terrain"); TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName); remote_client.OnXferReceive += TerrainUploader.XferReceive; remote_client.OnAbortXfer += AbortTerrainXferHandler; TerrainUploader.TerrainUploadDone += HandleTerrainApplication; TerrainUploader.RequestStartXfer(remote_client); } else { remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!"); } } }
/// <summary> /// Update an item in a prim (task) inventory. /// This method does not handle scripts, <see>RezScript(IClientAPI, UUID, unit)</see> /// </summary> /// <param name="remoteClient"></param> /// <param name="transactionID"></param> /// <param name="itemInfo"></param> /// <param name="primLocalID"></param> public void UpdateTaskInventory(IClientAPI remoteClient, UUID transactionID, TaskInventoryItem itemInfo, uint primLocalID) { UUID itemID = itemInfo.ItemID; // Find the prim we're dealing with SceneObjectPart part = GetSceneObjectPart(primLocalID); if (part != null) { TaskInventoryItem currentItem = part.Inventory.GetInventoryItem(itemID); bool allowInventoryDrop = (part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) != 0; // Explicity allow anyone to add to the inventory if the // AllowInventoryDrop flag has been set. Don't however let // them update an item unless they pass the external checks // if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId) && (currentItem != null || !allowInventoryDrop)) return; if (currentItem == null) { UUID copyID = UUID.Random(); if (itemID != UUID.Zero) { InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = InventoryService.GetItem(item); // Try library if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null) { item = LibraryService.LibraryRootFolder.FindItem(itemID); } // If we've found the item in the user's inventory or in the library if (item != null) { part.ParentGroup.AddInventoryItem(remoteClient.AgentId, primLocalID, item, copyID); m_log.InfoFormat( "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", item.Name, primLocalID, remoteClient.Name); part.SendPropertiesToClient(remoteClient); if (!Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) { List<UUID> uuids = new List<UUID>(); uuids.Add(itemID); RemoveInventoryItem(remoteClient, uuids); } } } else { m_log.ErrorFormat( "[PRIM INVENTORY]: Could not find inventory item {0} to update for {1}!", itemID, remoteClient.Name); } } } else // Updating existing item with new perms etc { // m_log.DebugFormat( // "[PRIM INVENTORY]: Updating item {0} in {1} for UpdateTaskInventory()", // currentItem.Name, part.Name); // Only look for an uploaded updated asset if we are passed a transaction ID. This is only the // case for updates uploded through UDP. Updates uploaded via a capability (e.g. a script update) // will not pass in a transaction ID in the update message. if (transactionID != UUID.Zero && AgentTransactionsModule != null) { AgentTransactionsModule.HandleTaskItemUpdateFromTransaction( remoteClient, part, transactionID, currentItem); if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) remoteClient.SendAlertMessage("Notecard saved"); else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) remoteClient.SendAlertMessage("Script saved"); else remoteClient.SendAlertMessage("Item saved"); } // Base ALWAYS has move currentItem.BasePermissions |= (uint)PermissionMask.Move; itemInfo.Flags = currentItem.Flags; // Check if we're allowed to mess with permissions if (!Permissions.IsGod(remoteClient.AgentId)) // Not a god { if (remoteClient.AgentId != part.OwnerID) // Not owner { // Friends and group members can't change any perms itemInfo.BasePermissions = currentItem.BasePermissions; itemInfo.EveryonePermissions = currentItem.EveryonePermissions; itemInfo.GroupPermissions = currentItem.GroupPermissions; itemInfo.NextPermissions = currentItem.NextPermissions; itemInfo.CurrentPermissions = currentItem.CurrentPermissions; } else { // Owner can't change base, and can change other // only up to base itemInfo.BasePermissions = currentItem.BasePermissions; if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone; if (itemInfo.GroupPermissions != currentItem.GroupPermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup; if (itemInfo.CurrentPermissions != currentItem.CurrentPermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner; if (itemInfo.NextPermissions != currentItem.NextPermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; itemInfo.EveryonePermissions &= currentItem.BasePermissions; itemInfo.GroupPermissions &= currentItem.BasePermissions; itemInfo.CurrentPermissions &= currentItem.BasePermissions; itemInfo.NextPermissions &= currentItem.BasePermissions; } } else { if (itemInfo.BasePermissions != currentItem.BasePermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteBase; if (itemInfo.EveryonePermissions != currentItem.EveryonePermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteEveryone; if (itemInfo.GroupPermissions != currentItem.GroupPermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteGroup; if (itemInfo.CurrentPermissions != currentItem.CurrentPermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteOwner; if (itemInfo.NextPermissions != currentItem.NextPermissions) itemInfo.Flags |= (uint)InventoryItemFlags.ObjectOverwriteNextOwner; } // Next ALWAYS has move itemInfo.NextPermissions |= (uint)PermissionMask.Move; if (part.Inventory.UpdateInventoryItem(itemInfo)) { part.SendPropertiesToClient(remoteClient); } } } else { m_log.WarnFormat( "[PRIM INVENTORY]: " + "Update with item {0} requested of prim {1} for {2} but this prim does not exist", itemID, primLocalID, remoteClient.Name); } }
private void OnMapNameRequest (IClientAPI remoteClient, string mapName, uint flags) { if (mapName.Length < 1) { remoteClient.SendAlertMessage("Use a search string with at least 1 character"); return; } bool TryCoordsSearch = false; int XCoord = 0; int YCoord = 0; string[] splitSearch = mapName.Split(','); if (splitSearch.Length != 1) { if (splitSearch[1].StartsWith (" ")) splitSearch[1] = splitSearch[1].Remove (0, 1); if (int.TryParse(splitSearch[0], out XCoord) && int.TryParse(splitSearch[1], out YCoord)) TryCoordsSearch = true; } List<MapBlockData> blocks = new List<MapBlockData>(); List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(UUID.Zero, mapName, 20); if (TryCoordsSearch) { GridRegion region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, XCoord * Constants.RegionSize, YCoord * Constants.RegionSize); if (region != null) { region.RegionName = mapName + " - " + region.RegionName; regionInfos.Add (region); } } List<GridRegion> allRegions = new List<GridRegion> (); foreach (GridRegion region in regionInfos) { //Add the found in search region first if (!allRegions.Contains (region)) { allRegions.Add (region); blocks.Add (SearchMapBlockFromGridRegion (region)); } //Then send surrounding regions List<GridRegion> regions = m_scene.GridService.GetRegionRange (m_scene.RegionInfo.ScopeID, (region.RegionLocX - (4 * Constants.RegionSize)), (region.RegionLocX + (4 * Constants.RegionSize)), (region.RegionLocY - (4 * Constants.RegionSize)), (region.RegionLocY + (4 * Constants.RegionSize))); if (regions != null) { foreach (GridRegion r in regions) { if (!allRegions.Contains (region)) { allRegions.Add (region); blocks.Add (SearchMapBlockFromGridRegion (r)); } } } } // final block, closing the search result MapBlockData data = new MapBlockData { Agents = 0, Access = 255, MapImageID = UUID.Zero, Name = mapName, RegionFlags = 0, WaterHeight = 0, X = 0, Y = 0, SizeX = 256, SizeY = 256 }; // not used blocks.Add(data); remoteClient.SendMapBlock (blocks, flags); }
private void handleEstateRestartSimRequest(IClientAPI remoteClient, int timeInSeconds) { if (!AllowRegionRestartFromClient) { if(!SilentRegionRestart) { remoteClient.SendAlertMessage("Region restart has been disabled on this simulator."); } return; } IRestartModule restartModule = Scene.RequestModuleInterface<IRestartModule>(); if (restartModule != null) { List<int> times = new List<int>(); while (timeInSeconds > 0) { times.Add(timeInSeconds); if (timeInSeconds > 300) timeInSeconds -= 120; else if (timeInSeconds > 30) timeInSeconds -= 30; else timeInSeconds -= 15; } restartModule.ScheduleRestart(UUID.Zero, "Region will restart in {0}", times.ToArray(), false); m_log.InfoFormat( "User {0} requested restart of region {1} in {2} seconds", remoteClient.Name, Scene.Name, times.Count != 0 ? times[0] : 0); } }
/// <summary> /// Capability originating call to update the asset of an item in an agent's inventory /// </summary> /// <param name="remoteClient"></param> /// <param name="itemID"></param> /// <param name="data"></param> /// <returns></returns> public virtual string CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data) { InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); if (item != null) { if ((InventoryType)item.InvType == InventoryType.Notecard) { if (!m_scene.Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId)) { remoteClient.SendAlertMessage("Insufficient permissions to edit notecard"); return(FailedPermissionsNotecardCAPSUpdate(UUID.Zero, itemID)); } UUID newID; if ((newID = m_scene.AssetService.UpdateContent(item.AssetID, data)) != UUID.Zero) { item.AssetID = newID; } else { remoteClient.SendAlertMessage("Failed to update notecard asset"); } m_scene.InventoryService.UpdateItem(item); return(SuccessNotecardCAPSUpdate(item.AssetID, itemID)); } if ((InventoryType)item.InvType == InventoryType.LSL) { if (!m_scene.Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId)) { return(FailedPermissionsScriptCAPSUpdate(UUID.Zero, itemID)); } UUID newID; if ((newID = m_scene.AssetService.UpdateContent(item.AssetID, data)) != UUID.Zero) { item.AssetID = newID; } else { remoteClient.SendAlertMessage("Failed to update script asset"); } m_scene.InventoryService.UpdateItem(item); IScriptModule ScriptEngine = m_scene.RequestModuleInterface <IScriptModule>(); if (ScriptEngine != null) { string Errors = ScriptEngine.TestCompileScript(item.AssetID, itemID); if (Errors != "") { return(FailedCompileScriptCAPSUpdate(item.AssetID, itemID, Errors)); } } return(SuccessScriptCAPSUpdate(item.AssetID, itemID)); } return(""); } MainConsole.Instance.ErrorFormat( "[AGENT INVENTORY]: Could not find item {0} for caps inventory update", itemID); return(""); }
/// <summary> /// Rez an object into the scene from the user's inventory /// </summary> /// FIXME: It would be really nice if inventory access modules didn't also actually do the work of rezzing /// things to the scene. The caller should be doing that, I think. /// <param name="remoteClient"></param> /// <param name="itemID"></param> /// <param name="RayEnd"></param> /// <param name="RayStart"></param> /// <param name="RayTargetID"></param> /// <param name="BypassRayCast"></param> /// <param name="RayEndIsIntersection"></param> /// <param name="RezSelected"></param> /// <param name="RemoveItem"></param> /// <param name="fromTaskID"></param> /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns> public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID) { // Work out position details byte bRayEndIsIntersection = (byte)0; bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); XmlDocument doc; InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); SceneObjectGroup group = CreateObjectFromInventory(item, remoteClient, itemID, out doc); Vector3 pos = m_scene.SceneGraph.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, new Vector3(0.5f, 0.5f, 0.5f), false); if (doc == null) { //No asset, check task inventory IEntity e; m_scene.SceneGraph.TryGetEntity(fromTaskID, out e); if (e != null && e is SceneObjectGroup) { SceneObjectGroup grp = (SceneObjectGroup)e; TaskInventoryItem taskItem = grp.RootPart.Inventory.GetInventoryItem(itemID); item = new InventoryItemBase { ID = UUID.Random(), CreatorId = taskItem.CreatorID.ToString(), Owner = remoteClient.AgentId, AssetID = taskItem.AssetID, Description = taskItem.Description, Name = taskItem.Name, AssetType = taskItem.Type, InvType = taskItem.InvType, Flags = taskItem.Flags, SalePrice = taskItem.SalePrice, SaleType = taskItem.SaleType }; if (m_scene.Permissions.PropagatePermissions()) { item.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); if (taskItem.InvType == (int)InventoryType.Object) { item.CurrentPermissions = item.BasePermissions & (((taskItem.CurrentPermissions & 7) << 13) | (taskItem.CurrentPermissions & (uint)PermissionMask.Move)); } else { item.CurrentPermissions = item.BasePermissions & taskItem.CurrentPermissions; } item.CurrentPermissions |= 16; // Slam item.NextPermissions = taskItem.NextPermissions; item.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move); item.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions; } else { item.BasePermissions = taskItem.BasePermissions; item.CurrentPermissions = taskItem.CurrentPermissions; item.NextPermissions = taskItem.NextPermissions; item.EveryOnePermissions = taskItem.EveryonePermissions; item.GroupPermissions = taskItem.GroupPermissions; } group = CreateObjectFromInventory(item, remoteClient, itemID, out doc); } } if (group == null && doc != null && (doc.FirstChild.OuterXml.StartsWith("<groups>") || (doc.FirstChild.NextSibling != null && doc.FirstChild.NextSibling.OuterXml.StartsWith("<groups>")))) { XmlNodeList nodes; if (doc.FirstChild.OuterXml.StartsWith("<groups>")) { nodes = doc.FirstChild.ChildNodes; } else if (doc.FirstChild.NextSibling != null) { nodes = doc.FirstChild.NextSibling.ChildNodes; } else { remoteClient.SendAlertMessage("Failed to find the item you requested."); return(null); } List <SceneObjectGroup> Groups = RezMultipleObjectsFromInventory(nodes, itemID, remoteClient, pos, RezSelected, item, RayTargetID, BypassRayCast, RayEndIsIntersection, RayEnd, RayStart, bRayEndIsIntersection); if (Groups.Count != 0) { return(Groups[0]); } remoteClient.SendAlertMessage("Failed to rez the item you requested."); return(null); } if (group == null) { remoteClient.SendAlertMessage("Failed to find the item you requested."); return(null); } string reason; if (!m_scene.Permissions.CanRezObject( group.ChildrenList.Count, remoteClient.AgentId, pos, out reason)) { // The client operates in no fail mode. It will // have already removed the item from the folder // if it's no copy. // Put it back if it's not an attachment // if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) { remoteClient.SendBulkUpdateInventory(item); } remoteClient.SendAlertMessage("You do not have permission to rez objects here."); return(null); } if (RezSelected) { group.RootPart.AddFlag(PrimFlags.CreateSelected); } // If we're rezzing an attachment then don't ask AddNewSceneObject() to update the client since // we'll be doing that later on. Scheduling more than one full update during the attachment // process causes some clients to fail to display the attachment properly. m_scene.SceneGraph.AddPrimToScene(group); // MainConsole.Instance.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); // Set it's position in world. const float offsetHeight = 0; //The OOBsize is only half the size, x2 Vector3 newSize = (group.OOBsize * 2) * Quaternion.Inverse(group.GroupRotation); pos = m_scene.SceneGraph.GetNewRezLocation( RayStart, RayEnd, RayTargetID, Quaternion.Identity, BypassRayCast, bRayEndIsIntersection, true, newSize, false); pos.Z += offsetHeight; group.AbsolutePosition = pos; // MainConsole.Instance.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight); ISceneChildEntity rootPart = group.GetChildPart(group.UUID); if (rootPart == null) { MainConsole.Instance.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart."); return(null); } // Since renaming the item in the inventory does not affect the name stored // in the serialization, transfer the correct name from the inventory to the // object itself before we rez. rootPart.Name = item.Name; rootPart.Description = item.Description; List <SceneObjectPart> partList = new List <SceneObjectPart> (group.ChildrenList); group.SetGroup(remoteClient.ActiveGroupId, remoteClient.AgentId, false); item.Owner = remoteClient.AgentId; if (rootPart.OwnerID != item.Owner) { //Need to kill the for sale here rootPart.ObjectSaleType = 0; rootPart.SalePrice = 10; if (m_scene.Permissions.PropagatePermissions()) { if ((item.CurrentPermissions & 8) != 0) { foreach (SceneObjectPart part in partList) { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; part.GroupMask = 0; // DO NOT propagate here } } group.ApplyNextOwnerPermissions(); } } foreach (SceneObjectPart part in partList) { if (part.OwnerID != item.Owner) { part.LastOwnerID = part.OwnerID; part.OwnerID = item.Owner; part.Inventory.ChangeInventoryOwner(item.Owner); } else if ((item.CurrentPermissions & 8) != 0) // Slam! { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; part.GroupMask = 0; // DO NOT propagate here } } rootPart.TrimPermissions(); if (group.RootPart.Shape.PCode == (byte)PCode.Prim) { group.ClearPartAttachmentData(); } // Fire on_rez group.CreateScriptInstances(0, true, StateSource.NewRez, UUID.Zero); group.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); if (!m_scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) { List <UUID> uuids = new List <UUID> { item.ID }; m_scene.InventoryService.DeleteItems(item.Owner, uuids); } } return(group); }
void OnDirFindQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) { if (!string.IsNullOrEmpty(queryText)) { queryText = queryText.Trim(); queryText = queryText.ToLowerInvariant(); } if (((DirFindFlags)queryFlags & DirFindFlags.People) == DirFindFlags.People) { if (string.IsNullOrEmpty(queryText)) { remoteClient.SendDirPeopleReply(queryID, new DirPeopleReplyData[0]); } List <UserAccount> accounts; if (!queryPeopleCache.TryGetValue(queryText, out accounts)) { accounts = m_Scenes[0].UserAccountService.GetUserAccounts(m_Scenes[0].RegionInfo.ScopeID, queryText); } queryPeopleCache.AddOrUpdate(queryText, accounts, 30.0); if (accounts.Count == 0) { remoteClient.SendDirPeopleReply(queryID, new DirPeopleReplyData[0]); return; } DirPeopleReplyData[] hits = new DirPeopleReplyData[accounts.Count]; int count = 0; foreach (UserAccount acc in accounts) { DirPeopleReplyData d = new DirPeopleReplyData(); d.agentID = acc.PrincipalID; d.firstName = acc.FirstName; d.lastName = acc.LastName; d.online = false; hits[count++] = d; } // viewers don't sent sorting, so results they show are a nice mess if ((queryStart > 0) && (queryStart < count)) { int len = count - queryStart; if (len > 101) // a viewer page is 100 { len = 101; } DirPeopleReplyData[] tmp = new DirPeopleReplyData[len]; Array.Copy(hits, queryStart, tmp, 0, len); hits = tmp; } else if (count > 101) { DirPeopleReplyData[] tmp = new DirPeopleReplyData[101]; Array.Copy(hits, 0, tmp, 0, 101); hits = tmp; } // TODO: This currently ignores pretty much all the query flags including Mature and sort order remoteClient.SendDirPeopleReply(queryID, hits); } else if (((DirFindFlags)queryFlags & DirFindFlags.Groups) == DirFindFlags.Groups) { if (m_GroupsService == null) { m_log.Warn("[BASIC SEARCH MODULE]: Groups service is not available. Unable to search groups."); remoteClient.SendAlertMessage("Groups search is not enabled"); return; } if (string.IsNullOrEmpty(queryText)) { remoteClient.SendDirGroupsReply(queryID, new DirGroupsReplyData[0]); } List <DirGroupsReplyData> answer; if (!queryGroupCache.TryGetValue(queryText, out answer)) { answer = m_GroupsService.FindGroups(remoteClient, queryText); } queryGroupCache.AddOrUpdate(queryText, answer, 30.0); if (answer.Count == 0) { remoteClient.SendDirGroupsReply(queryID, new DirGroupsReplyData[0]); return; } // filter out groups DirGroupsReplyData[] result = new DirGroupsReplyData[answer.Count]; int count = 0; foreach (DirGroupsReplyData dgrd in answer) { if (dgrd.members > 0) { result[count++] = dgrd; } } answer = null; // viewers don't sent sorting, so results they show are a nice mess if ((queryStart > 0) && (queryStart < count)) { int len = count - queryStart; if (len > 101) // a viewer page is 100 { len = 101; } DirGroupsReplyData[] tmp = new DirGroupsReplyData[len]; Array.Copy(result, queryStart, tmp, 0, len); result = tmp; } else if (count > 101) { DirGroupsReplyData[] tmp = new DirGroupsReplyData[101]; Array.Copy(result, 0, tmp, 0, 101); result = tmp; } // TODO: This currently ignores pretty much all the query flags including Mature and sort order remoteClient.SendDirGroupsReply(queryID, result); } }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { if (mapName.Length < 3) { remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } //m_log.DebugFormat("MAP NAME=({0})", mapName); // try to fetch from GridServer List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); if (regionInfos.Count == 0) { remoteClient.SendAlertMessage("Hyperlink could not be established."); } m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); List <MapBlockData> blocks = new List <MapBlockData>(); MapBlockData data; if (regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; if (flags == 2) // V2 sends this { data.MapImageId = UUID.Zero; } else { data.MapImageId = info.TerrainImage; } data.Name = info.RegionName; data.RegionFlags = 0; // TODO not used? data.WaterHeight = 0; // not used data.X = (ushort)(info.RegionLocX / Constants.RegionSize); data.Y = (ushort)(info.RegionLocY / Constants.RegionSize); blocks.Add(data); } } // final block, closing the search result data = new MapBlockData(); data.Agents = 0; data.Access = 255; data.MapImageId = UUID.Zero; data.Name = ""; // mapName; data.RegionFlags = 0; data.WaterHeight = 0; // not used data.X = 0; data.Y = 0; blocks.Add(data); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); }
/// <summary> /// Capability originating call to update the asset of an item in an agent's inventory /// </summary> /// <param name="remoteClient"></param> /// <param name="itemID"></param> /// <param name="data"></param> /// <returns></returns> public virtual string CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data) { InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); if (item != null) { if ((InventoryType)item.InvType == InventoryType.Notecard) { if (!m_scene.Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId)) { remoteClient.SendAlertMessage("Insufficient permissions to edit notecard"); return(FailedPermissionsNotecardCAPSUpdate(UUID.Zero, itemID)); } AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data, remoteClient.AgentId.ToString()); item.AssetID = asset.FullID; m_scene.AssetService.Store(asset); m_scene.InventoryService.UpdateItem(item); return(SuccessNotecardCAPSUpdate(item.AssetID, itemID)); } else if ((InventoryType)item.InvType == InventoryType.LSL) { if (!m_scene.Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId)) { return(FailedPermissionsScriptCAPSUpdate(UUID.Zero, itemID)); } IScriptModule ScriptEngine = m_scene.RequestModuleInterface <IScriptModule>(); AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data, remoteClient.AgentId.ToString()); item.AssetID = asset.FullID; m_scene.AssetService.Store(asset); m_scene.InventoryService.UpdateItem(item); if (ScriptEngine != null) { string Errors = ScriptEngine.TestCompileScript(asset.FullID, itemID); if (Errors != "") { return(FailedCompileScriptCAPSUpdate(item.AssetID, itemID, Errors)); } } return(SuccessScriptCAPSUpdate(item.AssetID, itemID)); } return(""); } else { m_log.ErrorFormat( "[AGENT INVENTORY]: Could not find item {0} for caps inventory update", itemID); } return(""); }
private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { // m_log.DebugFormat( // "[INVENTORY TRANSFER]: {0} IM type received from client {1}. From={2} ({3}), To={4}", // (InstantMessageDialog)im.dialog, client.Name, // im.fromAgentID, im.fromAgentName, im.toAgentID); Scene scene = FindClientScene(client.AgentId); if (scene == null) // Something seriously wrong here. { return; } UUID agentID = client.AgentId; switch ((InstantMessageDialog)im.dialog) { case InstantMessageDialog.InventoryOffered: { if (im.binaryBucket.Length < 17) // Invalid { return; } UUID recipientID = new UUID(im.toAgentID); ScenePresence recipientAgent = scene.GetScenePresence(recipientID); UUID copyID; // First byte is the asset type AssetType assetType = (AssetType)im.binaryBucket[0]; if (assetType == AssetType.LinkFolder || assetType == AssetType.Link) { client.SendAgentAlertMessage("Can't give a link. Nothing given.", false); return; } if (assetType == AssetType.Folder) { UUID folderID = new UUID(im.binaryBucket, 1); if (folderID == UUID.Zero) { client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false); return; } m_log.DebugFormat( "[INVENTORY TRANSFER]: offering folder {0} to agent {1}'s inventory", folderID, recipientID); InventoryFolderBase folderCopy = scene.GiveInventoryFolder(client, recipientID, agentID, folderID, UUID.Zero); if (folderCopy == null) { client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false); return; } copyID = folderCopy.ID; copyID.ToBytes(im.binaryBucket, 1); im.imSessionID = copyID.Guid; if (recipientAgent != null) { recipientAgent.ControllingClient.SendBulkUpdateInventory(folderCopy); } } else { UUID itemID = new UUID(im.binaryBucket, 1); if (itemID == UUID.Zero) { client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); return; } m_log.DebugFormat("[INVENTORY TRANSFER]: (giving) Inserting item {0} " + "into agent {1}'s inventory", itemID, recipientID); string message; InventoryItemBase itemCopy = scene.GiveInventoryItem(recipientID, agentID, itemID, out message); if (itemCopy == null) { client.SendAgentAlertMessage(message, false); return; } copyID = itemCopy.ID; copyID.ToBytes(im.binaryBucket, 1); if (recipientAgent != null) { recipientAgent.ControllingClient.SendBulkUpdateInventory(itemCopy); } im.imSessionID = copyID.Guid; } // Send the IM to the recipient. The item is already // in their inventory, so it will not be lost if // they are offline. if (recipientAgent != null) { im.offline = 0; recipientAgent.ControllingClient.SendInstantMessage(im); return; } else { im.offline = 0; if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { if (!success) { client.SendAlertMessage("User not online. Inventory has been saved"); } }); } } break; } case InstantMessageDialog.InventoryAccepted: { UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip if (inventoryID == UUID.Zero) { return; } IInventoryService invService = scene.InventoryService; ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); } } break; } case InstantMessageDialog.TaskInventoryAccepted: { if (im.binaryBucket == null || im.binaryBucket.Length < 16) { return; } UUID destinationFolderID = new UUID(im.binaryBucket, 0); if (destinationFolderID == UUID.Zero) // uuid-zero is a valid folder ID(?) keeping old code assuming not { return; } IInventoryService invService = scene.InventoryService; InventoryFolderBase destinationFolder = null; destinationFolder = invService.GetFolder(agentID, destinationFolderID); if (destinationFolder == null) { return; // no where to put it } UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip if (inventoryID == UUID.Zero) { return; } InventoryItemBase item = invService.GetItem(agentID, inventoryID); InventoryFolderBase folder = null; //UUID? previousParentFolderID = null; if (item != null) // It's an item { if (item.Folder != destinationFolderID) { //previousParentFolderID = item.Folder; item.Folder = destinationFolderID; invService.MoveItems(item.Owner, new List <InventoryItemBase>() { item }); client.SendInventoryItemCreateUpdate(item, 0); } } else { folder = invService.GetFolder(agentID, inventoryID); if (folder != null) // It's a folder { if (folder.ParentID != destinationFolderID) { //previousParentFolderID = folder.ParentID; folder.ParentID = destinationFolderID; invService.MoveFolder(folder); client.SendBulkUpdateInventory(folder); } } } // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). //if (previousParentFolderID != null) { //InventoryFolderBase previousParentFolder = invService.GetFolder(agentID, previousParentFolderID.Value); //if(previousParentFolder != null) //scene.SendInventoryUpdate(client, previousParentFolder, true, true); //scene.SendInventoryUpdate(client, destinationFolder, true, true); } break; } case InstantMessageDialog.InventoryDeclined: case InstantMessageDialog.TaskInventoryDeclined: { IInventoryService invService = scene.InventoryService; InventoryFolderBase trashFolder = invService.GetFolderForType(agentID, FolderType.Trash); if (trashFolder == null) //?? { client.SendAgentAlertMessage("Trash folder not found", false); return; } UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip if (inventoryID == UUID.Zero) { client.SendAgentAlertMessage("Item or folder not found", false); return; } InventoryItemBase item = invService.GetItem(agentID, inventoryID); InventoryFolderBase folder = null; //UUID? previousParentFolderID = null; if (item != null) { if (trashFolder.ID != item.Folder) { //previousParentFolderID = item.Folder; item.Folder = trashFolder.ID; invService.MoveItems(item.Owner, new List <InventoryItemBase>() { item }); client.SendInventoryItemCreateUpdate(item, 0); } } else { folder = invService.GetFolder(agentID, inventoryID); if (folder != null) { if (trashFolder.ID != folder.ParentID) { //previousParentFolderID = folder.ParentID; folder.ParentID = trashFolder.ID; invService.MoveFolder(folder); client.SendBulkUpdateInventory(folder); } } } // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). //if (previousParentFolderID != null) { //InventoryFolderBase previousParentFolder = invService.GetFolder(agentID, (UUID)previousParentFolderID); //if(previousParentFolder != null) //scene.SendInventoryUpdate(client, previousParentFolder, true, true); //scene.SendInventoryUpdate(client, trashFolder, true, true); } if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined) { ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { }); } } } break; } default: break; } }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName) { if (mapName.Length < 1) { remoteClient.SendAlertMessage("Use a search string with at least 1 character"); return; } bool TryCoordsSearch = false; int XCoord = 0; int YCoord = 0; string[] splitSearch = mapName.Split(','); if (splitSearch.Length != 1) { if (int.TryParse(splitSearch[0], out XCoord) && int.TryParse(splitSearch[1], out YCoord)) { TryCoordsSearch = true; } } List <MapBlockData> blocks = new List <MapBlockData>(); List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(UUID.Zero, mapName, 20); if (TryCoordsSearch) { GridRegion region = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)(XCoord * Constants.RegionSize), (int)(YCoord * Constants.RegionSize)); if (region != null) { regionInfos.Add(region); } } foreach (GridRegion region in regionInfos) { //Add the found in search region first blocks.Add(SearchMapBlockFromGridRegion(region)); //Then send surrounding regions List <GridRegion> regions = m_scene.GridService.GetRegionRange(m_scene.RegionInfo.ScopeID, (region.RegionLocX - (4 * (int)Constants.RegionSize)), (region.RegionLocX + (4 * (int)Constants.RegionSize)), (region.RegionLocY - (4 * (int)Constants.RegionSize)), (region.RegionLocY + (4 * (int)Constants.RegionSize))); foreach (GridRegion r in regions) { blocks.Add(SearchMapBlockFromGridRegion(r)); } } // final block, closing the search result MapBlockData data = new MapBlockData(); data.Agents = 0; data.Access = 255; data.MapImageID = UUID.Zero; data.Name = mapName; data.RegionFlags = 0; data.WaterHeight = 0; // not used data.X = 0; data.Y = 0; blocks.Add(data); remoteClient.SendMapBlock(blocks, 0); }
public void SimWideDeletes(IClientAPI client, int flags, UUID targetID) { if (m_scene.Permissions.CanIssueEstateCommand(client.AgentId, false)) { List<ISceneEntity> prims = new List<ISceneEntity>(); IParcelManagementModule parcelManagement = m_scene.RequestModuleInterface<IParcelManagementModule>(); if (parcelManagement != null) { int containsScript = (flags & (int) SimWideDeletesFlags.ScriptedPrimsOnly); foreach (ILandObject selectedParcel in parcelManagement.AllParcels()) { if ((flags & (int) SimWideDeletesFlags.OthersLandNotUserOnly) == (int) SimWideDeletesFlags.OthersLandNotUserOnly) { if (selectedParcel.LandData.OwnerID != targetID) //Check to make sure it isn't their land prims.AddRange(selectedParcel.GetPrimsOverByOwner(targetID, containsScript)); } //Other estates flag doesn't seem to get sent by the viewer, so don't touch it //else if ((flags & (int)SimWideDeletesFlags.ReturnObjectsOtherEstate) == (int)SimWideDeletesFlags.ReturnObjectsOtherEstate) // prims.AddRange (selectedParcel.GetPrimsOverByOwner (targetID, containsScript)); else // if ((flags & (int)SimWideDeletesFlags.ReturnObjects) == (int)SimWideDeletesFlags.ReturnObjects)//Return them all prims.AddRange(selectedParcel.GetPrimsOverByOwner(targetID, containsScript)); } } ILLClientInventory inventoryModule = m_scene.RequestModuleInterface<ILLClientInventory>(); if (inventoryModule != null) inventoryModule.ReturnObjects(prims.ToArray(), UUID.Zero); } else { client.SendAlertMessage("You do not have permissions to return objects in this sim."); } }
private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { // m_log.DebugFormat( // "[INVENTORY TRANSFER]: {0} IM type received from {1}", // (InstantMessageDialog)im.dialog, client.Name); Scene scene = FindClientScene(client.AgentId); if (scene == null) // Something seriously wrong here. { return; } if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) { //m_log.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0])); if (im.binaryBucket.Length < 17) // Invalid { return; } UUID receipientID = new UUID(im.toAgentID); ScenePresence user = scene.GetScenePresence(receipientID); UUID copyID; // First byte is the asset type AssetType assetType = (AssetType)im.binaryBucket[0]; if (AssetType.Folder == assetType) { UUID folderID = new UUID(im.binaryBucket, 1); m_log.DebugFormat("[INVENTORY TRANSFER]: Inserting original folder {0} " + "into agent {1}'s inventory", folderID, new UUID(im.toAgentID)); InventoryFolderBase folderCopy = scene.GiveInventoryFolder(receipientID, client.AgentId, folderID, UUID.Zero); if (folderCopy == null) { client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false); return; } // The outgoing binary bucket should contain only the byte which signals an asset folder is // being copied and the following bytes for the copied folder's UUID copyID = folderCopy.ID; byte[] copyIDBytes = copyID.GetBytes(); im.binaryBucket = new byte[1 + copyIDBytes.Length]; im.binaryBucket[0] = (byte)AssetType.Folder; Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length); if (user != null) { user.ControllingClient.SendBulkUpdateInventory(folderCopy); } // HACK!! im.imSessionID = folderID.Guid; } else { // First byte of the array is probably the item type // Next 16 bytes are the UUID UUID itemID = new UUID(im.binaryBucket, 1); m_log.DebugFormat("[INVENTORY TRANSFER]: (giving) Inserting item {0} " + "into agent {1}'s inventory", itemID, new UUID(im.toAgentID)); InventoryItemBase itemCopy = scene.GiveInventoryItem( new UUID(im.toAgentID), client.AgentId, itemID); if (itemCopy == null) { client.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); return; } copyID = itemCopy.ID; Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); if (user != null) { user.ControllingClient.SendBulkUpdateInventory(itemCopy); } // HACK!! im.imSessionID = itemID.Guid; } // Send the IM to the recipient. The item is already // in their inventory, so it will not be lost if // they are offline. // if (user != null) { user.ControllingClient.SendInstantMessage(im); return; } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { if (!success) { client.SendAlertMessage("User not online. Inventory has been saved"); } }); } } } else if (im.dialog == (byte)InstantMessageDialog.InventoryAccepted) { ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { // justincc - FIXME: Comment out for now. This code was added in commit db91044 Mon Aug 22 2011 // and is apparently supposed to fix bulk inventory updates after accepting items. But // instead it appears to cause two copies of an accepted folder for the receiving user in // at least some cases. Folder/item update is already done when the offer is made (see code above) // // Send BulkUpdateInventory // IInventoryService invService = scene.InventoryService; // UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip // // InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId); // folder = invService.GetFolder(folder); // // ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID)); // // // If the user has left the scene by the time the message comes back then we can't send // // them the update. // if (fromUser != null) // fromUser.ControllingClient.SendBulkUpdateInventory(folder); }); } } } else if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined) { // Here, the recipient is local and we can assume that the // inventory is loaded. Courtesy of the above bulk update, // It will have been pushed to the client, too // IInventoryService invService = scene.InventoryService; InventoryFolderBase trashFolder = invService.GetFolderForType(client.AgentId, AssetType.TrashFolder); UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); item = invService.GetItem(item); InventoryFolderBase folder = null; if (item != null && trashFolder != null) { item.Folder = trashFolder.ID; // Diva comment: can't we just update this item??? List <UUID> uuids = new List <UUID>(); uuids.Add(item.ID); invService.DeleteItems(item.Owner, uuids); scene.AddInventoryItem(client, item); } else { folder = new InventoryFolderBase(inventoryID, client.AgentId); folder = invService.GetFolder(folder); if (folder != null & trashFolder != null) { folder.ParentID = trashFolder.ID; invService.MoveFolder(folder); } } if ((null == item && null == folder) | null == trashFolder) { string reason = String.Empty; if (trashFolder == null) { reason += " Trash folder not found."; } if (item == null) { reason += " Item not found."; } if (folder == null) { reason += " Folder not found."; } client.SendAgentAlertMessage("Unable to delete " + "received inventory" + reason, false); } ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); } } } }
private void handleEstateAccessDeltaRequest(IClientAPI remote_client, UUID invoice, int estateAccessType, UUID user) { // EstateAccessDelta handles Estate Managers, Sim Access, Sim Banlist, allowed Groups.. etc. // OMV documents AllEstates variants as either bit 0 or bit 1 set. // Testing finds it's always bit 0, however to be safe, let's treat either as on. bool noReply = ((int)estateAccessType & (int)Constants.EstateAccessDeltaCommands.NoReply) != 0; bool allEstates = ((int)estateAccessType & 3) != 0; // mask off lower 2 bits int operation = (int)estateAccessType & ~((int)Constants.EstateAccessDeltaCommands.NoReply|3); // mask off lower 2 bits + NoReply if ((operation & (int)Constants.EstateAccessDeltaCommands.BanUser) != 0) { if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { EstateResult result = EstateBanUser(user, true); if (result == EstateResult.Success) { if (!noReply) SendEstateUserAccessChanged(remote_client, invoice, true); } else if (result == EstateResult.AlreadySet) { remote_client.SendAlertMessage("User is already on the region ban list"); } } else { remote_client.SendAlertMessage("You are not permitted to change the estate ban list."); } } if ((operation & (int)Constants.EstateAccessDeltaCommands.UnbanUser) != 0) { if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { EstateResult result = EstateBanUser(user, false); if (result == EstateResult.Success) { if (!noReply) SendEstateUserAccessChanged(remote_client, invoice, true); } else if (result == EstateResult.AlreadySet) { remote_client.SendAlertMessage("User is not on the region ban list"); } } else { remote_client.SendAlertMessage("You are not permitted to change the estate ban list."); } } if ((operation & (int)Constants.EstateAccessDeltaCommands.AddUserAsAllowed) != 0) { if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { EstateResult result = EstateAllowUser(user, true); if (result == EstateResult.Success) { if (!noReply) SendEstateUserAccessChanged(remote_client, invoice, false); } else if (result == EstateResult.AlreadySet) { remote_client.SendAlertMessage("User is already on the region access list."); } } else { remote_client.SendAlertMessage("You are not permitted to change the estate access list."); } } if ((operation & (int)Constants.EstateAccessDeltaCommands.RemoveUserAsAllowed) != 0) { if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { EstateResult result = EstateAllowUser(user, false); if (result == EstateResult.Success) { if (!noReply) SendEstateUserAccessChanged(remote_client, invoice, false); } else if (result == EstateResult.AlreadySet) { remote_client.SendAlertMessage("User is not on the region access list"); } } else { remote_client.SendAlertMessage("You are not permitted to change the estate access list."); } } if ((operation & (int)Constants.EstateAccessDeltaCommands.AddGroupAsAllowed) != 0) { if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { EstateResult result = EstateAllowGroup(user, true); if (result == EstateResult.Success) { if (!noReply) remote_client.SendEstateUUIDList(invoice, (int)Constants.EstateAccessDeltaResponse.AllowedGroups, m_scene.RegionInfo.EstateSettings.EstateGroups, m_scene.RegionInfo.EstateSettings.EstateID); } else if (result == EstateResult.AlreadySet) { remote_client.SendAlertMessage("Group is already in the region group access list."); } } else { remote_client.SendAlertMessage("You are not permitted to change the estate group access list."); } } if ((operation & (int)Constants.EstateAccessDeltaCommands.RemoveGroupAsAllowed) != 0) { if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { EstateResult result = EstateAllowGroup(user, false); if (result == EstateResult.Success) { if (!noReply) remote_client.SendEstateUUIDList(invoice, (int)Constants.EstateAccessDeltaResponse.AllowedGroups, m_scene.RegionInfo.EstateSettings.EstateGroups, m_scene.RegionInfo.EstateSettings.EstateID); } else if (result == EstateResult.AlreadySet) { remote_client.SendAlertMessage("Group is not on the estate group access list"); } } else { remote_client.SendAlertMessage("You are not permitted to change the estate group access list."); } } if ((operation & (int)Constants.EstateAccessDeltaCommands.AddManager) != 0) { if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || m_scene.Permissions.BypassPermissions()) { m_scene.RegionInfo.EstateSettings.AddEstateManager(user); SaveEstateDataAndUpdateRegions((uint)EstateSettings.EstateSaveOptions.EstateSaveManagers); if (!noReply) remote_client.SendEstateUUIDList(invoice, (int)Constants.EstateAccessDeltaResponse.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("You are not permitted to change the estate manager list."); } } if ((operation & (int)Constants.EstateAccessDeltaCommands.RemoveManager) != 0) { if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || m_scene.Permissions.BypassPermissions()) { m_scene.RegionInfo.EstateSettings.RemoveEstateManager(user); SaveEstateDataAndUpdateRegions((uint)EstateSettings.EstateSaveOptions.EstateSaveManagers); if (!noReply) remote_client.SendEstateUUIDList(invoice, (int)Constants.EstateAccessDeltaResponse.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("You are not permitted to change the estate manager list."); } } if (allEstates) remote_client.SendAlertMessage("The 'All Estates' option is not implemented yet. Change applied to This Estate only."); }
private void OnMapNameRequestHandler(IClientAPI remoteClient, string mapName, uint flags) { if (m_gridservice == null) { return; } try { List <MapBlockData> blocks = new List <MapBlockData>(); if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) { // final block, closing the search result AddFinalBlock(blocks, mapName); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } //m_log.DebugFormat("MAP NAME=({0})", mapName); string mapNameOrig = mapName; int indx = mapName.IndexOfAny(new char[] { '.', '!', '+', '|', ':', '%' }); bool needOriginalName = indx >= 0; // try to fetch from GridServer List <GridRegion> regionInfos = m_gridservice.GetRegionsByName(m_stupidScope, mapName, 20); if (!remoteClient.IsActive) { return; } //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); MapBlockData data; if (regionInfos != null && regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; MapBlockData block = new MapBlockData(); MapBlockFromGridRegion(block, info, flags); if (needOriginalName && flags == 2 && regionInfos.Count == 1) { block.Name = mapNameOrig; } blocks.Add(block); } } // final block, closing the search result AddFinalBlock(blocks, mapNameOrig); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); // send extra user messages for V3 // because the UI is very confusing // while we don't fix the hard-coded urls if (flags == 2) { if (regionInfos == null || regionInfos.Count == 0) { remoteClient.SendAgentAlertMessage("No regions found with that name.", true); } } } catch { } }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { List<MapBlockData> blocks = new List<MapBlockData>(); if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) { // final block, closing the search result AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); string mapNameOrig = mapName; if (regionInfos.Count == 0) { // Hack to get around the fact that ll V3 now drops the port from the // map name. See https://jira.secondlife.com/browse/VWR-28570 // // Caller, use this magic form instead: // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 // or url encode if possible. // the hacks we do with this viewer... // if (mapName.Contains("|")) mapName = mapName.Replace('|', ':'); if (mapName.Contains("+")) mapName = mapName.Replace('+', ' '); if (mapName.Contains("!")) mapName = mapName.Replace('!', '/'); if (mapName != mapNameOrig) regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); } m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); if (regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { if ((flags & 2) == 2) // V2 sends this { List<MapBlockData> datas = WorldMap.Map2BlockFromGridRegion(info, flags); // ugh! V2-3 is very sensitive about the result being // exactly the same as the requested name if (regionInfos.Count == 1 && (mapName != mapNameOrig)) datas.ForEach(d => d.Name = mapNameOrig); blocks.AddRange(datas); } else { MapBlockData data = WorldMap.MapBlockFromGridRegion(info, flags); blocks.Add(data); } } } // final block, closing the search result AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); // send extra user messages for V3 // because the UI is very confusing // while we don't fix the hard-coded urls if (flags == 2) { if (regionInfos.Count == 0) remoteClient.SendAlertMessage("No regions found with that name."); else if (regionInfos.Count == 1) remoteClient.SendAlertMessage("Region found!"); } }
public static bool TryCreateLink(Scene m_scene, IClientAPI client, uint xloc, uint yloc, string externalRegionName, uint externalPort, string externalHostName, out RegionInfo regInfo) { m_log.DebugFormat("[HGrid]: Link to {0}:{1}, in {2}-{3}", externalHostName, externalPort, xloc, yloc); regInfo = new RegionInfo(); regInfo.RegionName = externalRegionName; regInfo.HttpPort = externalPort; regInfo.ExternalHostName = externalHostName; regInfo.RegionLocX = xloc; regInfo.RegionLocY = yloc; try { regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0); } catch (Exception e) { m_log.Warn("[HGrid]: Wrong format for link-region: " + e.Message); return(false); } regInfo.RemotingAddress = regInfo.ExternalEndPoint.Address.ToString(); // Finally, link it try { m_scene.CommsManager.GridService.RegisterRegion(regInfo); } catch (Exception e) { m_log.Warn("[HGrid]: Unable to link region: " + e.Message); return(false); } uint x, y; if (!Check4096(m_scene, regInfo, out x, out y)) { m_scene.CommsManager.GridService.DeregisterRegion(regInfo); if (client != null) { client.SendAlertMessage("Region is too far (" + x + ", " + y + ")"); } m_log.Info("[HGrid]: Unable to link, region is too far (" + x + ", " + y + ")"); return(false); } if (!CheckCoords(m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, x, y)) { m_scene.CommsManager.GridService.DeregisterRegion(regInfo); if (client != null) { client.SendAlertMessage("Region has incompatible coordinates (" + x + ", " + y + ")"); } m_log.Info("[HGrid]: Unable to link, region has incompatible coordinates (" + x + ", " + y + ")"); return(false); } m_log.Debug("[HGrid]: link region succeeded"); return(true); }
private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID) { lock (this) { if ((TerrainUploader != null) && (XferID == TerrainUploader.XferID)) { remoteClient.OnXferReceive -= TerrainUploader.XferReceive; remoteClient.OnAbortXfer -= AbortTerrainXferHandler; TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; TerrainUploader = null; remoteClient.SendAlertMessage("Terrain Upload aborted by the client"); } } }
public void ClassifiedInfoUpdate(UUID queryClassifiedID, uint queryCategory, string queryName, string queryDescription, UUID queryParcelID, uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos, byte queryclassifiedFlags, int queryclassifiedPrice, IClientAPI remoteClient) { IScenePresence p = remoteClient.Scene.GetScenePresence(remoteClient.AgentId); if (p == null) { return; //Just fail } IScheduledMoneyModule scheduledMoneyModule = p.Scene.RequestModuleInterface <IScheduledMoneyModule>(); IMoneyModule moneyModule = p.Scene.RequestModuleInterface <IMoneyModule>(); Classified classcheck = ProfileFrontend.GetClassified(queryClassifiedID); if (((queryclassifiedFlags & 32) != 32) && moneyModule != null) { //Single week if (!moneyModule.Charge(remoteClient.AgentId, queryclassifiedPrice, "Add Classified", TransactionType.ClassifiedCharge)) { remoteClient.SendAlertMessage("You do not have enough money to create this classified."); return; } } else if (scheduledMoneyModule != null) { //Auto-renew if (classcheck != null) { scheduledMoneyModule.RemoveFromScheduledCharge("[Classified: " + queryClassifiedID + "]"); } if (!scheduledMoneyModule.Charge(remoteClient.AgentId, queryclassifiedPrice, "Add Reoccurring Classified (" + queryClassifiedID + ")", 7, TransactionType.ClassifiedCharge, "[Classified: " + queryClassifiedID + "]", true)) { remoteClient.SendAlertMessage("You do not have enough money to create this classified."); return; } } UUID creatorUUID = remoteClient.AgentId; UUID classifiedUUID = queryClassifiedID; uint category = queryCategory; string name = queryName; string description = queryDescription; uint parentestate = queryParentEstate; UUID snapshotUUID = querySnapshotID; string simname = remoteClient.Scene.RegionInfo.RegionName; Vector3 globalpos = queryGlobalPos; byte classifiedFlags = queryclassifiedFlags; int classifiedPrice = queryclassifiedPrice; UUID parceluuid = p.CurrentParcelUUID; string parcelname = "Unknown"; IParcelManagementModule parcelManagement = remoteClient.Scene.RequestModuleInterface <IParcelManagementModule>(); if (parcelManagement != null) { ILandObject parcel = parcelManagement.GetLandObject(p.AbsolutePosition.X, p.AbsolutePosition.Y); if (parcel != null) { parcelname = parcel.LandData.Name; parceluuid = parcel.LandData.GlobalID; } } uint creationdate = (uint)Util.UnixTimeSinceEpoch(); uint expirationdate = (uint)Util.UnixTimeSinceEpoch() + (365 * 24 * 60 * 60); Classified classified = new Classified { ClassifiedUUID = classifiedUUID, CreatorUUID = creatorUUID, CreationDate = creationdate, ExpirationDate = expirationdate, Category = category, Name = name, Description = description, ParcelUUID = parceluuid, ParentEstate = parentestate, SnapshotUUID = snapshotUUID, SimName = simname, GlobalPos = globalpos, ParcelName = parcelname, ClassifiedFlags = classifiedFlags, PriceForListing = classifiedPrice, ScopeID = remoteClient.ScopeID }; ProfileFrontend.AddClassified(classified); }
private void DoCreateItem(uint callbackID, IClientAPI remoteClient) { m_userTransactions.Manager.MyScene.AssetService.Store(m_asset); IMonitorModule monitorModule = m_userTransactions.Manager.MyScene.RequestModuleInterface<IMonitorModule>(); if (monitorModule != null) { INetworkMonitor networkMonitor = (INetworkMonitor)monitorModule.GetMonitor(m_userTransactions.Manager.MyScene.RegionInfo.RegionID.ToString(), "Network Monitor"); networkMonitor.AddPendingUploads(-1); } InventoryItemBase item = new InventoryItemBase(); item.Owner = remoteClient.AgentId; item.CreatorId = remoteClient.AgentId.ToString(); item.ID = UUID.Random(); item.AssetID = m_asset.FullID; item.Description = m_description; item.Name = m_name; item.AssetType = type; item.InvType = invType; item.Folder = InventFolder; item.BasePermissions = 0x7fffffff; item.CurrentPermissions = 0x7fffffff; item.GroupPermissions=0; item.EveryOnePermissions=0; item.NextPermissions = nextPerm; item.Flags = (uint) wearableType; item.CreationDate = Util.UnixTimeSinceEpoch(); ILLClientInventory inventoryModule = m_userTransactions.Manager.MyScene.RequestModuleInterface<ILLClientInventory>(); if(inventoryModule != null && inventoryModule.AddInventoryItem(item)) remoteClient.SendInventoryItemCreateUpdate(item, callbackID); else remoteClient.SendAlertMessage("Unable to create inventory item"); }
private void handleEstateAccessDeltaRequest(IClientAPI remote_client, UUID invoice, int estateAccessType, UUID user) { // EstateAccessDelta handles Estate Managers, Sim Access, Sim Banlist, allowed Groups.. etc. if (user == m_scene.RegionInfo.EstateSettings.EstateOwner) { return; // never process EO } if (user == m_scene.RegionInfo.MasterAvatarAssignedUUID) { return; // never process owner } switch (estateAccessType) { case 64: if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { EstateBan[] banlistcheck = m_scene.RegionInfo.EstateSettings.EstateBans; bool alreadyInList = false; for (int i = 0; i < banlistcheck.Length; i++) { if (user == banlistcheck[i].BannedUserID) { alreadyInList = true; break; } } if (!alreadyInList) { EstateBan item = new EstateBan(); item.BannedUserID = user; item.EstateID = m_scene.RegionInfo.EstateSettings.EstateID; item.BannedHostAddress = "0.0.0.0"; item.BannedHostIPMask = "0.0.0.0"; m_scene.RegionInfo.EstateSettings.AddBan(item); m_scene.RegionInfo.EstateSettings.Save(); ScenePresence s = m_scene.GetScenePresence(user); if (s != null) { if (!s.IsChildAgent) { s.ControllingClient.SendTeleportLocationStart(); m_scene.TeleportClientHome(user, s.ControllingClient); } } } else { remote_client.SendAlertMessage("User is already on the region ban list"); } //m_scene.RegionInfo.regionBanlist.Add(Manager(user); remote_client.SendBannedUserList(invoice, m_scene.RegionInfo.EstateSettings.EstateBans, m_scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } break; case 128: if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false) || m_scene.Permissions.BypassPermissions()) { EstateBan[] banlistcheck = m_scene.RegionInfo.EstateSettings.EstateBans; bool alreadyInList = false; EstateBan listitem = null; for (int i = 0; i < banlistcheck.Length; i++) { if (user == banlistcheck[i].BannedUserID) { alreadyInList = true; listitem = banlistcheck[i]; break; } } if (alreadyInList && listitem != null) { m_scene.RegionInfo.EstateSettings.RemoveBan(listitem.BannedUserID); m_scene.RegionInfo.EstateSettings.Save(); } else { remote_client.SendAlertMessage("User is not on the region ban list"); } //m_scene.RegionInfo.regionBanlist.Add(Manager(user); remote_client.SendBannedUserList(invoice, m_scene.RegionInfo.EstateSettings.EstateBans, m_scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } break; case 256: if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || m_scene.Permissions.BypassPermissions()) { m_scene.RegionInfo.EstateSettings.AddEstateManager(user); m_scene.RegionInfo.EstateSettings.Save(); remote_client.SendEstateManagersList(invoice, m_scene.RegionInfo.EstateSettings.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } break; case 512: if (m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || m_scene.Permissions.BypassPermissions()) { m_scene.RegionInfo.EstateSettings.RemoveEstateManager(user); m_scene.RegionInfo.EstateSettings.Save(); remote_client.SendEstateManagersList(invoice, m_scene.RegionInfo.EstateSettings.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } break; default: m_log.ErrorFormat("EstateOwnerMessage: Unknown EstateAccessType requested in estateAccessDelta: {0}", estateAccessType.ToString()); break; } }
/// <summary> /// Capability originating call to update the asset of a script in a prim's (task's) inventory /// </summary> /// <param name="remoteClient"></param> /// <param name="itemID"></param> /// <param name="primID">The prim which contains the item to update</param> /// <param name="isScriptRunning">Indicates whether the script to update is currently running</param> /// <param name="data"></param> public ArrayList CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, UUID itemId, UUID primId, bool isScriptRunning, byte[] data) { if (!Permissions.CanEditScript(itemId, primId, remoteClient.AgentId)) { remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false); return new ArrayList(); } // Retrieve group SceneObjectPart part = GetSceneObjectPart(primId); if (part == null) return new ArrayList(); SceneObjectGroup group = part.ParentGroup; // Retrieve item TaskInventoryItem item = group.GetInventoryItem(part.LocalId, itemId); if (null == item) { m_log.ErrorFormat( "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for caps script update " + " but the item does not exist in this inventory", itemId, part.Name, part.UUID); return new ArrayList(); } AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data, remoteClient.AgentId); AssetService.Store(asset); // m_log.DebugFormat( // "[PRIM INVENTORY]: Stored asset {0} when updating item {1} in prim {2} for {3}", // asset.ID, item.Name, part.Name, remoteClient.Name); if (isScriptRunning) { part.Inventory.RemoveScriptInstance(item.ItemID, false); } // Update item with new asset item.AssetID = asset.FullID; if (group.UpdateInventoryItem(item)) remoteClient.SendAlertMessage("Script saved"); part.SendPropertiesToClient(remoteClient); // Trigger rerunning of script (use TriggerRezScript event, see RezScript) ArrayList errors = new ArrayList(); if (isScriptRunning) { // Needs to determine which engine was running it and use that // part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0); errors = part.Inventory.GetScriptErrors(item.ItemID); } else { remoteClient.SendAlertMessage("Script saved"); } // Tell anyone managing scripts that a script has been reloaded/changed EventManager.TriggerUpdateScript(remoteClient.AgentId, itemId, primId, isScriptRunning, item.AssetID); part.ParentGroup.ResumeScripts(); return errors; }
private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient) { lock (TerrainUploader) { remoteClient.OnXferReceive -= TerrainUploader.XferReceive; remoteClient.OnAbortXfer -= AbortTerrainXferHandler; TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; TerrainUploader = null; } remoteClient.SendAlertMessage("Terrain Upload Complete. Loading...."); ITerrainModule terr = m_scene.RequestModuleInterface <ITerrainModule>(); if (terr != null) { m_log.Warn("[CLIENT]: Got Request to Send Terrain in region " + m_scene.RegionInfo.RegionName); if (File.Exists(Util.dataDir() + "/terrain.raw")) { File.Delete(Util.dataDir() + "/terrain.raw"); } try { FileStream input = new FileStream(Util.dataDir() + "/terrain.raw", FileMode.CreateNew); input.Write(terrainData, 0, terrainData.Length); input.Close(); } catch (IOException e) { m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was an IO Exception loading your terrain. Please check free space"); return; } catch (SecurityException e) { m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was a security Exception loading your terrain. Please check the security on the simulator drive"); return; } catch (UnauthorizedAccessException e) { m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was a security Exception loading your terrain. Please check the security on the simulator drive"); return; } try { terr.LoadFromFile(Util.dataDir() + "/terrain.raw"); remoteClient.SendAlertMessage("Your terrain was loaded. Give it a minute or two to apply"); } catch (Exception e) { m_log.ErrorFormat("[TERRAIN]: Error loading a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was a general error loading your terrain. Please fix the terrain file and try again"); } } else { remoteClient.SendAlertMessage("Unable to apply terrain. Cannot get an instance of the terrain module"); } }
public void ClassifiedInfoUpdate(UUID queryClassifiedID, uint queryCategory, string queryName, string queryDescription, UUID queryParcelID, uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos, byte queryclassifiedFlags, int queryclassifiedPrice, IClientAPI remoteClient) { IScenePresence p = remoteClient.Scene.GetScenePresence (remoteClient.AgentId); if (p == null) return; //Just fail IScheduledMoneyModule scheduledMoneyModule = p.Scene.RequestModuleInterface<IScheduledMoneyModule> (); IMoneyModule moneyModule = p.Scene.RequestModuleInterface<IMoneyModule> (); Classified classcheck = ProfileFrontend.GetClassified (queryClassifiedID); if (((queryclassifiedFlags & 32) != 32) && moneyModule != null) { //Single week if (!moneyModule.Charge (remoteClient.AgentId, queryclassifiedPrice, "Add Classified", TransactionType.ClassifiedCharge)) { remoteClient.SendAlertMessage ("You do not have enough money to create this classified."); return; } } else if (scheduledMoneyModule != null) { //Auto-renew if (classcheck != null) scheduledMoneyModule.RemoveFromScheduledCharge ("[Classified: " + queryClassifiedID + "]"); var payOK = scheduledMoneyModule.Charge ( remoteClient.AgentId, // who to charge queryclassifiedPrice, // how much "Add Reoccurring Classified (" + queryClassifiedID + ")", // description TransactionType.ClassifiedCharge, // transaction type "[Classified: " + queryClassifiedID + "]", // scheduler identifier true, // charger immediately false); // run once if (!payOK) { remoteClient.SendAlertMessage ("You do not have enough money to create this classified."); return; } } UUID creatorUUID = remoteClient.AgentId; UUID classifiedUUID = queryClassifiedID; uint category = queryCategory; string name = queryName; string description = queryDescription; uint parentestate = queryParentEstate; UUID snapshotUUID = querySnapshotID; string simname = remoteClient.Scene.RegionInfo.RegionName; Vector3 globalpos = queryGlobalPos; byte classifiedFlags = queryclassifiedFlags; int classifiedPrice = queryclassifiedPrice; UUID parceluuid = p.CurrentParcelUUID; string parcelname = "Unknown"; IParcelManagementModule parcelManagement = remoteClient.Scene.RequestModuleInterface<IParcelManagementModule> (); if (parcelManagement != null) { ILandObject parcel = parcelManagement.GetLandObject (p.AbsolutePosition.X, p.AbsolutePosition.Y); if (parcel != null) { parcelname = parcel.LandData.Name; parceluuid = parcel.LandData.GlobalID; } } uint creationdate = (uint)Util.UnixTimeSinceEpoch (); uint expirationdate = (uint)Util.UnixTimeSinceEpoch () + (365 * 24 * 60 * 60); Classified classified = new Classified { ClassifiedUUID = classifiedUUID, CreatorUUID = creatorUUID, CreationDate = creationdate, ExpirationDate = expirationdate, Category = category, Name = name, Description = description, ParcelUUID = parceluuid, ParentEstate = parentestate, SnapshotUUID = snapshotUUID, SimName = simname, GlobalPos = globalpos, ParcelName = parcelname, ClassifiedFlags = classifiedFlags, PriceForListing = classifiedPrice, ScopeID = remoteClient.ScopeID }; ProfileFrontend.AddClassified (classified); }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { if (mapName.Length < 1) { remoteClient.SendAlertMessage("Use a search string with at least 1 character"); return; } bool TryCoordsSearch = false; int XCoord = 0; int YCoord = 0; string[] splitSearch = mapName.Split(','); if (splitSearch.Length != 1) { if (splitSearch[1].StartsWith(" ")) { splitSearch[1] = splitSearch[1].Remove(0, 1); } if (int.TryParse(splitSearch[0], out XCoord) && int.TryParse(splitSearch[1], out YCoord)) { TryCoordsSearch = true; } } List <MapBlockData> blocks = new List <MapBlockData>(); List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(remoteClient.AllScopeIDs, mapName, 0, 20); if (TryCoordsSearch) { GridRegion region = m_scene.GridService.GetRegionByPosition(remoteClient.AllScopeIDs, XCoord * Constants.RegionSize, YCoord * Constants.RegionSize); if (region != null) { region.RegionName = mapName + " - " + region.RegionName; regionInfos.Add(region); } } List <GridRegion> allRegions = new List <GridRegion>(); if (regionInfos != null) { foreach (GridRegion region in regionInfos) { //Add the found in search region first if (!allRegions.Contains(region)) { allRegions.Add(region); blocks.Add(SearchMapBlockFromGridRegion(region)); } //Then send surrounding regions List <GridRegion> regions = m_scene.GridService.GetRegionRange(remoteClient.AllScopeIDs, (region.RegionLocX - (4 * Constants.RegionSize)), (region.RegionLocX + (4 * Constants.RegionSize)), (region.RegionLocY - (4 * Constants.RegionSize)), (region.RegionLocY + (4 * Constants.RegionSize))); if (regions != null) { foreach (GridRegion r in regions) { if (!allRegions.Contains(region)) { allRegions.Add(region); blocks.Add(SearchMapBlockFromGridRegion(r)); } } } } } // final block, closing the search result MapBlockData data = new MapBlockData { Agents = 0, Access = 255, MapImageID = UUID.Zero, Name = mapName, RegionFlags = 0, WaterHeight = 0, X = 0, Y = 0, SizeX = 256, SizeY = 256 }; // not used blocks.Add(data); remoteClient.SendMapBlock(blocks, flags); }
public void JoinGroupRequest(IClientAPI remoteClient, UUID groupID) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); string reason = string.Empty; // Should check to see if OpenEnrollment, or if there's an outstanding invitation if (m_groupData.AddAgentToGroup(GetRequestingAgentIDStr(remoteClient), GetRequestingAgentIDStr(remoteClient), groupID, UUID.Zero, string.Empty, out reason)) { remoteClient.SendJoinGroupReply(groupID, true); // Should this send updates to everyone in the group? SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); if (reason != string.Empty) // A warning remoteClient.SendAlertMessage("Warning: " + reason); } else remoteClient.SendJoinGroupReply(groupID, false); }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName) { if (mapName.Length < 3) { remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } // try to fetch from GridServer List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); if (regionInfos == null) { m_log.Warn("[MAPSEARCHMODULE]: RequestNamedRegions returned null. Old gridserver?"); // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region regionInfos = new List <GridRegion>(); GridRegion info = m_scene.GridService.GetRegionByName(m_scene.RegionInfo.ScopeID, mapName); if (info != null) { regionInfos.Add(info); } } else if (regionInfos.Count == 0 && mapName.StartsWith("http://")) { remoteClient.SendAlertMessage("Hyperlink could not be established."); } m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); List <MapBlockData> blocks = new List <MapBlockData>(); MapBlockData data; if (regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; data.MapImageId = UUID.Zero; // could use info.TerrainImage but it seems to break viewer2 data.Name = info.RegionName; data.RegionFlags = 0; // TODO not used? data.WaterHeight = 0; // not used data.X = (ushort)(info.RegionLocX / Constants.RegionSize); data.Y = (ushort)(info.RegionLocY / Constants.RegionSize); blocks.Add(data); } } // final block, closing the search result data = new MapBlockData(); data.Agents = 0; data.Access = 255; data.MapImageId = UUID.Zero; data.Name = ""; // mapName; data.RegionFlags = 0; data.WaterHeight = 0; // not used data.X = 0; data.Y = 0; blocks.Add(data); // not sure what the flags do here, but seems to be necessary // to set to "2" for viewer 2 remoteClient.SendMapBlock(blocks, 2); }
private void handleUploadTerrain(IClientAPI remote_client, string clientFileName) { if (TerrainUploader == null) { remote_client.SendAlertMessage("Uploading terrain file..."); TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName); lock (TerrainUploader) { remote_client.OnXferReceive += TerrainUploader.XferReceive; remote_client.OnAbortXfer += AbortTerrainXferHandler; TerrainUploader.TerrainUploadDone += HandleTerrainApplication; } TerrainUploader.RequestStartXfer(remote_client); } else { remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!"); } }
public void DirEventsQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) { Hashtable ReqHash = new Hashtable(); ReqHash["avatar_id"] = remoteClient.AgentId.ToString(); ReqHash["text"] = queryText; ReqHash["flags"] = queryFlags.ToString(); ReqHash["query_start"] = queryStart.ToString(); Hashtable result = GenericXMLRPCRequest(ReqHash, "dir_events_query"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage( result["errorMessage"].ToString(), false); return; } else { if (result["timezone"].ToString() != customTimeZone) { customTimeZone = result["timezone"].ToString(); remoteClient.SendAlertMessage("All event times are displayed in the timezone " + customTimeZone); } } ArrayList dataArray = (ArrayList)result["data"]; int count = dataArray.Count; if (count > 100) { count = 101; } DirEventsReplyData[] data = new DirEventsReplyData[count]; int i = 0; foreach (Object o in dataArray) { Hashtable d = (Hashtable)o; data[i] = new DirEventsReplyData(); data[i].ownerID = new UUID(d["owner_id"].ToString()); data[i].name = d["name"].ToString(); data[i].eventID = Convert.ToUInt32(d["event_id"]); data[i].date = d["date"].ToString(); data[i].unixTime = Convert.ToUInt32(d["unix_time"]); data[i].eventFlags = Convert.ToUInt32(d["event_flags"]); i++; if (i >= count) { break; } } remoteClient.SendDirEventsReply(queryID, data); }
private void handleEstateAccessDeltaRequest(IClientAPI remote_client, UUID invoice, int estateAccessType, UUID user) { // EstateAccessDelta handles Estate Managers, Sim Access, Sim Banlist, allowed Groups.. etc. if (user == m_scene.RegionInfo.EstateSettings.EstateOwner) return; // never process EO IEstateConnector connector = Framework.Utilities.DataManager.RequestPlugin<IEstateConnector>(); List<EstateSettings> estates = new List<EstateSettings>(); if ((estateAccessType & (int)AccessDeltaRequest.ApplyToAllEstates) != 0 && connector != null) estates = connector.GetEstates(m_scene.RegionInfo.EstateSettings.EstateOwner); else estates = new List<EstateSettings>() { m_scene.RegionInfo.EstateSettings }; bool moreToCome = (estateAccessType & (int)AccessDeltaRequest.MoreToCome) != 0; List<Action<UUID>> actions = new List<Action<UUID>>(); bool isOwner = m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true) || m_scene.Permissions.BypassPermissions(); bool isManager = m_scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false); foreach (EstateSettings es in estates) { if (isOwner) { if ((estateAccessType & (int)AccessDeltaRequest.AddEstateManager) != 0) actions.Add(es.AddEstateManager); else if ((estateAccessType & (int)AccessDeltaRequest.RemoveEstateManager) != 0) actions.Add(es.RemoveEstateManager); } if (isManager) { if ((estateAccessType & (int)AccessDeltaRequest.AddAllowedUser) != 0) actions.Add(es.AddEstateUser); else if ((estateAccessType & (int)AccessDeltaRequest.RemoveAllowedUser) != 0) actions.Add(es.RemoveEstateUser); else if ((estateAccessType & (int)AccessDeltaRequest.AddAllowedGroup) != 0) actions.Add(es.AddEstateGroup); else if ((estateAccessType & (int)AccessDeltaRequest.RemoveAllowedGroup) != 0) actions.Add(es.RemoveEstateGroup); else if ((estateAccessType & (int)AccessDeltaRequest.AddBannedUser) != 0) actions.Add((userID) => { IScenePresence SP = m_scene.GetScenePresence(user); EstateBan item = new EstateBan { BannedUserID = userID, EstateID = es.EstateID, BannedHostAddress = "0.0.0.0", BannedHostIPMask = (SP != null) ? ((System.Net.IPEndPoint)SP.ControllingClient.GetClientEP()) .Address.ToString() : "0.0.0.0" }; es.AddBan(item); IEntityTransferModule transferModule = m_scene.RequestModuleInterface<IEntityTransferModule>(); if (SP != null && transferModule != null) { if (!SP.IsChildAgent) transferModule.TeleportHome(user, SP.ControllingClient); else transferModule.IncomingCloseAgent(SP.Scene, SP.UUID); } }); else if ((estateAccessType & (int)AccessDeltaRequest.RemoveBannedUser) != 0) actions.Add(es.RemoveBan); } } foreach (Action<UUID> es in actions) { es(user); if (!moreToCome) connector.SaveEstateSettings(m_scene.RegionInfo.EstateSettings); } if(actions.Count > 0) TriggerEstateInfoChange(); if (!isManager && !isOwner) remote_client.SendAlertMessage("You don't have the correct permissions to accomplish this action."); if ((estateAccessType & (int) AccessDeltaRequest.MoreToCome) == 0) //1024 means more than one is being sent { remote_client.SendEstateList(invoice, (int) EstateTools.EstateAccessReplyDelta.AllowedUsers, m_scene.RegionInfo.EstateSettings.EstateAccess, m_scene.RegionInfo.EstateSettings.EstateID); remote_client.SendEstateList(invoice, (int) EstateTools.EstateAccessReplyDelta.AllowedGroups, m_scene.RegionInfo.EstateSettings.EstateGroups, m_scene.RegionInfo.EstateSettings.EstateID); remote_client.SendBannedUserList(invoice, m_scene.RegionInfo.EstateSettings.EstateBans, m_scene.RegionInfo.EstateSettings.EstateID); remote_client.SendEstateList(invoice, (int) EstateTools.EstateAccessReplyDelta.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateManagers, m_scene.RegionInfo.EstateSettings.EstateID); } }
public void DirEventsQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, int queryStart) { // Flags are going to be 0 or 32 for Mature // We also know text comes in 3 segments X|Y|Text where X is the day difference from // the current day, Y is the category to search, Text is the user input for search string // so let's 'split up the queryText to get our values we need first off string eventTime = ""; string eventCategory = ""; string userText = ""; queryText = queryText.Trim(); // newer viewers sometimes append a space string[] querySplode = queryText.Split(new Char[] { '|' }); if (querySplode.Length > 0) { eventTime = querySplode[0]; } if (querySplode.Length > 1) { eventCategory = querySplode[1]; } if (querySplode.Length > 0) { userText = querySplode[2]; userText = userText.Trim(); // newer viewers sometimes append a space } // Ok we have values, now we need to do something with all this lovely information string query = ""; string searchStart = Convert.ToString(queryStart); int count = 100; DirEventsReplyData[] data = new DirEventsReplyData[count]; string searchEnd = Convert.ToString(queryStart + count); int i = 0; int unixEventUpcomingEndDateToCheck = 0; int eventTimeAmt = 0; int unixEventDateToCheckMidnight = 0; int unixEventEndDateToCheckMidnight = 0; string sqlAddTerms = ""; DateTime saveNow = DateTime.Now; int startDateCheck; // Quick catch to see if the eventTime is set to "u" for In Progress & Upcoming Radio button if (eventTime == "u") { DateTime eventUpcomingEndDateToCheck = saveNow.AddDays(+7); DateTime eventUpcomingEndDateToCheckMidnight = new DateTime(eventUpcomingEndDateToCheck.Year, eventUpcomingEndDateToCheck.Month, eventUpcomingEndDateToCheck.Day); unixEventUpcomingEndDateToCheck = Util.ToUnixTime(eventUpcomingEndDateToCheckMidnight); // for "in progress" events, show everything that has started within the last three hours (arbitrary) startDateCheck = Util.ToUnixTime(saveNow.AddHours(-3.0)); sqlAddTerms = " where (dateUTC>=?startDateCheck AND dateUTC<=?unixEventUpcomingEndDateToCheck)"; } else { // we need the current date, in order to subtract/add the days to view, or see the week upcoming. // this will probably be some really ugly code :) startDateCheck = Util.ToUnixTime(saveNow); eventTimeAmt = Convert.ToInt16(eventTime); DateTime eventDateToCheck = saveNow.AddDays(Convert.ToInt16(eventTime)); DateTime eventEndDateToCheck = new DateTime(); if (eventTime == "0") { eventEndDateToCheck = saveNow.AddDays(+2); } else { eventEndDateToCheck = saveNow.AddDays(eventTimeAmt + 1); } // now truncate the information so we get the midnight value (and yes David, I'm sure there's an // easier way to do this, but this will work for now :) ) DateTime eventDateToCheckMidnight = new DateTime(eventDateToCheck.Year, eventDateToCheck.Month, eventDateToCheck.Day); DateTime eventEndDateToCheckMidnight = new DateTime(eventEndDateToCheck.Year, eventEndDateToCheck.Month, eventEndDateToCheck.Day); // this is the start unix timestamp to look for, we still need the end which is the next day, plus // we need the week end unix timestamp for the In Progress & upcoming radio button unixEventDateToCheckMidnight = Util.ToUnixTime(eventDateToCheckMidnight); unixEventEndDateToCheckMidnight = Util.ToUnixTime(eventEndDateToCheckMidnight); sqlAddTerms = " where (dateUTC>=?unixEventDateToCheck AND dateUTC<=?unixEventEndDateToCheckMidnight)"; } if ((queryFlags & ((uint)DirFindFlags.IncludeAdult | (uint)DirFindFlags.IncludeAdult | (uint)DirFindFlags.IncludeAdult)) == 0) { // don't just give them an empty list... remoteClient.SendAlertMessage("You must included at least one maturity rating."); remoteClient.SendDirEventsReply(queryID, data); return; } // Event DB storage does not currently support adult events, so if someone asks for adult, search mature for now. if ((queryFlags & (uint)DirFindFlags.IncludeAdult) != 0) { queryFlags |= (uint)DirFindFlags.IncludeMature; } if ((queryFlags & (uint)DirFindFlags.IncludeMature) != 0) { // they included mature and possibly others if ((queryFlags & (uint)DirFindFlags.IncludePG) == 0) { sqlAddTerms += " AND mature='true'"; // exclude PG } } if ((queryFlags & (uint)DirFindFlags.IncludePG) != 0) { // they included PG and possibly others if ((queryFlags & (uint)DirFindFlags.IncludeMature) == 0) { sqlAddTerms += " AND mature='false'"; // exclude mature } } if (eventCategory != "0") { sqlAddTerms += " AND category=?category"; } if (userText != "") { sqlAddTerms += " AND (description LIKE ?userText OR name LIKE ?userText)"; } // Events results should come back sorted by date sqlAddTerms += " order by dateUTC ASC"; query = "select owneruuid, name, eventid, dateUTC, eventflags from events" + sqlAddTerms + " limit " + searchStart + ", " + searchEnd + ""; Dictionary <string, object> parms = new Dictionary <string, object>(); parms.Add("?startDateCheck", Convert.ToString(startDateCheck)); parms.Add("?unixEventUpcomingEndDateToCheck", Convert.ToString(unixEventUpcomingEndDateToCheck)); parms.Add("?unixEventDateToCheck", Convert.ToString(unixEventDateToCheckMidnight)); parms.Add("?unixEventEndDateToCheckMidnight", Convert.ToString(unixEventEndDateToCheckMidnight)); parms.Add("?category", eventCategory); parms.Add("?userText", "%" + Convert.ToString(userText) + "%"); using (ISimpleDB db = _connFactory.GetConnection()) { List <Dictionary <string, string> > results = db.QueryWithResults(query, parms); foreach (Dictionary <string, string> row in results) { data[i] = new DirEventsReplyData(); data[i].ownerID = new UUID(row["owneruuid"].ToString()); data[i].name = row["name"].ToString(); data[i].eventID = Convert.ToUInt32(row["eventid"]); // need to convert the unix timestamp we get into legible date for viewer DateTime localViewerEventTime = Util.UnixToLocalDateTime(Convert.ToInt32(row["dateUTC"])); string newSendingDate = String.Format("{0:MM/dd hh:mm tt}", localViewerEventTime); data[i].date = newSendingDate; data[i].unixTime = Convert.ToUInt32(row["dateUTC"]); data[i].eventFlags = Convert.ToUInt32(row["eventflags"]); i++; if (i >= count) { break; } } } remoteClient.SendDirEventsReply(queryID, data); }
private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient) { lock (TerrainUploader) { remoteClient.OnXferReceive -= TerrainUploader.XferReceive; remoteClient.OnAbortXfer -= AbortTerrainXferHandler; TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; TerrainUploader = null; } remoteClient.SendAlertMessage("Terrain Upload Complete. Loading...."); ITerrainModule terr = m_scene.RequestModuleInterface<ITerrainModule>(); if (terr != null) { m_log.Warn("[CLIENT]: Got Request to Send Terrain in region " + m_scene.RegionInfo.RegionName); if (File.Exists(Util.dataDir() + "/terrain.raw")) { File.Delete(Util.dataDir() + "/terrain.raw"); } try { FileStream input = new FileStream(Util.dataDir() + "/terrain.raw", FileMode.CreateNew); input.Write(terrainData, 0, terrainData.Length); input.Close(); } catch (IOException e) { m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was an IO Exception loading your terrain. Please check free space"); return; } catch (SecurityException e) { m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was a security Exception loading your terrain. Please check the security on the simulator drive"); return; } catch (UnauthorizedAccessException e) { m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was a security Exception loading your terrain. Please check the security on the simulator drive"); return; } try { terr.LoadFromFile(Util.dataDir() + "/terrain.raw"); remoteClient.SendAlertMessage("Your terrain was loaded. Give it a minute or two to apply"); } catch (Exception e) { m_log.ErrorFormat("[TERRAIN]: Error loading a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was a general error loading your terrain. Please fix the terrain file and try again"); } } else { remoteClient.SendAlertMessage("Unable to apply terrain. Cannot get an instance of the terrain module"); } }
public void GrantRights(IClientAPI remoteClient, UUID friendID, int rights) { UUID requester = remoteClient.AgentId; m_log.DebugFormat( "[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, friendID); FriendInfo[] friends = GetFriendsFromCache(requester); if (friends.Length == 0) { return; } // Let's find the friend in this user's friend list FriendInfo friend = GetFriend(friends, friendID); if (friend != null) // Found it { // Store it on service if (!StoreRights(requester, friendID, rights)) { remoteClient.SendAlertMessage("Unable to grant rights."); return; } // Store it in the local cache int myFlags = friend.MyFlags; friend.MyFlags = rights; // Always send this back to the original client remoteClient.SendChangeUserRights(requester, friendID, rights); // // Notify the friend // // Try local if (LocalGrantRights(requester, friendID, myFlags, rights)) { return; } PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() }); if (friendSessions != null && friendSessions.Length > 0) { PresenceInfo friendSession = friendSessions[0]; if (friendSession != null) { GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID); // TODO: You might want to send the delta to save the lookup // on the other end!! m_FriendsSimConnector.GrantRights(region, requester, friendID, myFlags, rights); } } } else { m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", friendID, requester); } }
public bool TryCreateLink(Scene m_scene, IClientAPI client, int xloc, int yloc, string externalRegionName, uint externalPort, string externalHostName, out GridRegion regInfo) { m_log.DebugFormat("[HGrid]: Link to {0}:{1}, in {2}-{3}", externalHostName, externalPort, xloc, yloc); regInfo = new GridRegion(); regInfo.RegionName = externalRegionName; regInfo.HttpPort = externalPort; regInfo.ExternalHostName = externalHostName; regInfo.RegionLocX = xloc; regInfo.RegionLocY = yloc; try { regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0); } catch (Exception e) { m_log.Warn("[HGrid]: Wrong format for link-region: " + e.Message); return false; } // Finally, link it if (!RegisterRegion(UUID.Zero, regInfo)) { m_log.Warn("[HGrid]: Unable to link region"); return false; } int x, y; if (!Check4096(m_scene, regInfo, out x, out y)) { DeregisterRegion(regInfo.RegionID); if (client != null) client.SendAlertMessage("Region is too far (" + x + ", " + y + ")"); m_log.Info("[HGrid]: Unable to link, region is too far (" + x + ", " + y + ")"); return false; } if (!CheckCoords(m_scene.RegionInfo.RegionLocX, m_scene.RegionInfo.RegionLocY, x, y)) { DeregisterRegion(regInfo.RegionID); if (client != null) client.SendAlertMessage("Region has incompatible coordinates (" + x + ", " + y + ")"); m_log.Info("[HGrid]: Unable to link, region has incompatible coordinates (" + x + ", " + y + ")"); return false; } m_log.Debug("[HGrid]: link region succeeded"); return true; }
private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { // m_log.DebugFormat( // "[INVENTORY TRANSFER]: {0} IM type received from client {1}. From={2} ({3}), To={4}", // (InstantMessageDialog)im.dialog, client.Name, // im.fromAgentID, im.fromAgentName, im.toAgentID); Scene scene = FindClientScene(client.AgentId); if (scene == null) // Something seriously wrong here. { return; } if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) { //m_log.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0])); if (im.binaryBucket.Length < 17) // Invalid { return; } UUID recipientID = new UUID(im.toAgentID); ScenePresence user = scene.GetScenePresence(recipientID); UUID copyID; // First byte is the asset type AssetType assetType = (AssetType)im.binaryBucket[0]; if (AssetType.Folder == assetType) { UUID folderID = new UUID(im.binaryBucket, 1); m_log.DebugFormat( "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory", folderID, new UUID(im.toAgentID)); InventoryFolderBase folderCopy = scene.GiveInventoryFolder(client, recipientID, client.AgentId, folderID, UUID.Zero); if (folderCopy == null) { client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false); return; } // The outgoing binary bucket should contain only the byte which signals an asset folder is // being copied and the following bytes for the copied folder's UUID copyID = folderCopy.ID; byte[] copyIDBytes = copyID.GetBytes(); im.binaryBucket = new byte[1 + copyIDBytes.Length]; im.binaryBucket[0] = (byte)AssetType.Folder; Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length); if (user != null) { user.ControllingClient.SendBulkUpdateInventory(folderCopy); } // HACK!! // Insert the ID of the copied folder into the IM so that we know which item to move to trash if it // is rejected. // XXX: This is probably a misuse of the session ID slot. im.imSessionID = copyID.Guid; } else { // First byte of the array is probably the item type // Next 16 bytes are the UUID UUID itemID = new UUID(im.binaryBucket, 1); m_log.DebugFormat("[INVENTORY TRANSFER]: (giving) Inserting item {0} " + "into agent {1}'s inventory", itemID, new UUID(im.toAgentID)); string message; InventoryItemBase itemCopy = scene.GiveInventoryItem(new UUID(im.toAgentID), client.AgentId, itemID, out message); if (itemCopy == null) { client.SendAgentAlertMessage(message, false); return; } copyID = itemCopy.ID; Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); if (user != null) { user.ControllingClient.SendBulkUpdateInventory(itemCopy); } // HACK!! // Insert the ID of the copied item into the IM so that we know which item to move to trash if it // is rejected. // XXX: This is probably a misuse of the session ID slot. im.imSessionID = copyID.Guid; } im.offline = 0; // Send the IM to the recipient. The item is already // in their inventory, so it will not be lost if // they are offline. // if (user != null) { user.ControllingClient.SendInstantMessage(im); return; } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { if (!success) { client.SendAlertMessage("User not online. Inventory has been saved"); } }); } } } else if (im.dialog == (byte)InstantMessageDialog.InventoryAccepted || im.dialog == (byte)InstantMessageDialog.TaskInventoryAccepted) { UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip IInventoryService invService = scene.InventoryService; // Special case: folder redirect. // RLV uses this if (im.dialog == (byte)InstantMessageDialog.TaskInventoryAccepted) { InventoryFolderBase folder = invService.GetFolder(client.AgentId, inventoryID); if (folder != null) { if (im.binaryBucket.Length >= 16) { UUID destFolderID = new UUID(im.binaryBucket, 0); if (destFolderID != UUID.Zero) { InventoryFolderBase destFolder = invService.GetFolder(client.AgentId, destFolderID); if (destFolder != null) { if (folder.ParentID != destFolder.ID) { folder.ParentID = destFolder.ID; invService.MoveFolder(folder); client.SendBulkUpdateInventory(folder); } } } } } } ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) {}); } } } // XXX: This code was placed here to try and accomodate RLV which moves given folders named #RLV/~<name> // to the requested folder, which in this case is #RLV. However, it is the viewer that appears to be // response from renaming the #RLV/~example folder to ~example. For some reason this is not yet // happening, possibly because we are not sending the correct inventory update messages with the correct // transaction IDs else if (im.dialog == (byte)InstantMessageDialog.TaskInventoryAccepted) { UUID destinationFolderID = UUID.Zero; if (im.binaryBucket != null && im.binaryBucket.Length >= 16) { destinationFolderID = new UUID(im.binaryBucket, 0); } if (destinationFolderID != UUID.Zero) { InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); IInventoryService invService = scene.InventoryService; UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip InventoryItemBase item = invService.GetItem(client.AgentId, inventoryID); InventoryFolderBase folder = null; UUID?previousParentFolderID = null; if (item != null) // It's an item { previousParentFolderID = item.Folder; item.Folder = destinationFolderID; invService.DeleteItems(item.Owner, new List <UUID>() { item.ID }); scene.AddInventoryItem(client, item); } else { folder = invService.GetFolder(client.AgentId, inventoryID); if (folder != null) // It's a folder { previousParentFolderID = folder.ParentID; folder.ParentID = destinationFolderID; invService.MoveFolder(folder); } } // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). if (previousParentFolderID != null) { InventoryFolderBase previousParentFolder = invService.GetFolder(client.AgentId, (UUID)previousParentFolderID); scene.SendInventoryUpdate(client, previousParentFolder, true, true); scene.SendInventoryUpdate(client, destinationFolder, true, true); } } } else if ( im.dialog == (byte)InstantMessageDialog.InventoryDeclined || im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined) { // Here, the recipient is local and we can assume that the // inventory is loaded. Courtesy of the above bulk update, // It will have been pushed to the client, too // IInventoryService invService = scene.InventoryService; InventoryFolderBase trashFolder = invService.GetFolderForType(client.AgentId, FolderType.Trash); UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip InventoryItemBase item = invService.GetItem(client.AgentId, inventoryID); InventoryFolderBase folder = null; UUID?previousParentFolderID = null; if (item != null && trashFolder != null) { previousParentFolderID = item.Folder; item.Folder = trashFolder.ID; // Diva comment: can't we just update this item??? List <UUID> uuids = new List <UUID>(); uuids.Add(item.ID); invService.DeleteItems(item.Owner, uuids); scene.AddInventoryItem(client, item); } else { folder = invService.GetFolder(client.AgentId, inventoryID); if (folder != null && trashFolder != null) { previousParentFolderID = folder.ParentID; folder.ParentID = trashFolder.ID; invService.MoveFolder(folder); client.SendBulkUpdateInventory(folder); } } if ((null == item && null == folder) || null == trashFolder) { string reason = String.Empty; if (trashFolder == null) { reason += " Trash folder not found."; } if (item == null) { reason += " Item not found."; } if (folder == null) { reason += " Folder not found."; } client.SendAgentAlertMessage("Unable to delete " + "received inventory" + reason, false); } // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). else if (previousParentFolderID != null) { InventoryFolderBase previousParentFolder = invService.GetFolder(client.AgentId, (UUID)previousParentFolderID); scene.SendInventoryUpdate(client, previousParentFolder, true, true); scene.SendInventoryUpdate(client, trashFolder, true, true); } if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined) { ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im, delegate(bool success) { }); } } } } }
private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { // m_log.DebugFormat( // "[INVENTORY TRANSFER]: {0} IM type received from client {1}. From={2} ({3}), To={4}", // (InstantMessageDialog)im.dialog, client.Name, // im.fromAgentID, im.fromAgentName, im.toAgentID); Scene scene = FindClientScene(client.AgentId); if (scene == null) // Something seriously wrong here. return; if (im.dialog == (byte) InstantMessageDialog.InventoryOffered) { //m_log.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0])); if (im.binaryBucket.Length < 17) // Invalid return; UUID receipientID = new UUID(im.toAgentID); ScenePresence user = scene.GetScenePresence(receipientID); UUID copyID; // First byte is the asset type AssetType assetType = (AssetType)im.binaryBucket[0]; if (AssetType.Folder == assetType) { UUID folderID = new UUID(im.binaryBucket, 1); m_log.DebugFormat( "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory", folderID, new UUID(im.toAgentID)); InventoryFolderBase folderCopy = scene.GiveInventoryFolder(client, receipientID, client.AgentId, folderID, UUID.Zero); if (folderCopy == null) { client.SendAgentAlertMessage("Can't find folder to give. Nothing given.", false); return; } // The outgoing binary bucket should contain only the byte which signals an asset folder is // being copied and the following bytes for the copied folder's UUID copyID = folderCopy.ID; byte[] copyIDBytes = copyID.GetBytes(); im.binaryBucket = new byte[1 + copyIDBytes.Length]; im.binaryBucket[0] = (byte)AssetType.Folder; Array.Copy(copyIDBytes, 0, im.binaryBucket, 1, copyIDBytes.Length); if (user != null) user.ControllingClient.SendBulkUpdateInventory(folderCopy); // HACK!! // Insert the ID of the copied folder into the IM so that we know which item to move to trash if it // is rejected. // XXX: This is probably a misuse of the session ID slot. im.imSessionID = copyID.Guid; } else { // First byte of the array is probably the item type // Next 16 bytes are the UUID UUID itemID = new UUID(im.binaryBucket, 1); m_log.DebugFormat("[INVENTORY TRANSFER]: (giving) Inserting item {0} "+ "into agent {1}'s inventory", itemID, new UUID(im.toAgentID)); string message; InventoryItemBase itemCopy = scene.GiveInventoryItem(new UUID(im.toAgentID), client.AgentId, itemID, out message); if (itemCopy == null) { client.SendAgentAlertMessage(message, false); return; } copyID = itemCopy.ID; Array.Copy(copyID.GetBytes(), 0, im.binaryBucket, 1, 16); if (user != null) user.ControllingClient.SendBulkUpdateInventory(itemCopy); // HACK!! // Insert the ID of the copied item into the IM so that we know which item to move to trash if it // is rejected. // XXX: This is probably a misuse of the session ID slot. im.imSessionID = copyID.Guid; } // Send the IM to the recipient. The item is already // in their inventory, so it will not be lost if // they are offline. // if (user != null) { user.ControllingClient.SendInstantMessage(im); return; } else { if (m_TransferModule != null) m_TransferModule.SendInstantMessage(im, delegate(bool success) { if (!success) client.SendAlertMessage("User not online. Inventory has been saved"); }); } } else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted) { ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) m_TransferModule.SendInstantMessage(im, delegate(bool success) { // justincc - FIXME: Comment out for now. This code was added in commit db91044 Mon Aug 22 2011 // and is apparently supposed to fix bulk inventory updates after accepting items. But // instead it appears to cause two copies of an accepted folder for the receiving user in // at least some cases. Folder/item update is already done when the offer is made (see code above) // // Send BulkUpdateInventory // IInventoryService invService = scene.InventoryService; // UUID inventoryEntityID = new UUID(im.imSessionID); // The inventory item /folder, back from it's trip // // InventoryFolderBase folder = new InventoryFolderBase(inventoryEntityID, client.AgentId); // folder = invService.GetFolder(folder); // // ScenePresence fromUser = scene.GetScenePresence(new UUID(im.fromAgentID)); // // // If the user has left the scene by the time the message comes back then we can't send // // them the update. // if (fromUser != null) // fromUser.ControllingClient.SendBulkUpdateInventory(folder); }); } } // XXX: This code was placed here to try and accomodate RLV which moves given folders named #RLV/~<name> // to the requested folder, which in this case is #RLV. However, it is the viewer that appears to be // response from renaming the #RLV/~example folder to ~example. For some reason this is not yet // happening, possibly because we are not sending the correct inventory update messages with the correct // transaction IDs else if (im.dialog == (byte) InstantMessageDialog.TaskInventoryAccepted) { UUID destinationFolderID = UUID.Zero; if (im.binaryBucket != null && im.binaryBucket.Length >= 16) { destinationFolderID = new UUID(im.binaryBucket, 0); } if (destinationFolderID != UUID.Zero) { InventoryFolderBase destinationFolder = new InventoryFolderBase(destinationFolderID, client.AgentId); if (destinationFolder == null) { m_log.WarnFormat( "[INVENTORY TRANSFER]: TaskInventoryAccepted message from {0} in {1} specified folder {2} which does not exist", client.Name, scene.Name, destinationFolderID); return; } IInventoryService invService = scene.InventoryService; UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); item = invService.GetItem(item); InventoryFolderBase folder = null; UUID? previousParentFolderID = null; if (item != null) // It's an item { previousParentFolderID = item.Folder; item.Folder = destinationFolderID; invService.DeleteItems(item.Owner, new List<UUID>() { item.ID }); scene.AddInventoryItem(client, item); } else { folder = new InventoryFolderBase(inventoryID, client.AgentId); folder = invService.GetFolder(folder); if (folder != null) // It's a folder { previousParentFolderID = folder.ParentID; folder.ParentID = destinationFolderID; invService.MoveFolder(folder); } } // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). if (previousParentFolderID != null) { InventoryFolderBase previousParentFolder = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); previousParentFolder = invService.GetFolder(previousParentFolder); scene.SendInventoryUpdate(client, previousParentFolder, true, true); scene.SendInventoryUpdate(client, destinationFolder, true, true); } } } else if ( im.dialog == (byte)InstantMessageDialog.InventoryDeclined || im.dialog == (byte)InstantMessageDialog.TaskInventoryDeclined) { // Here, the recipient is local and we can assume that the // inventory is loaded. Courtesy of the above bulk update, // It will have been pushed to the client, too // IInventoryService invService = scene.InventoryService; InventoryFolderBase trashFolder = invService.GetFolderForType(client.AgentId, AssetType.TrashFolder); UUID inventoryID = new UUID(im.imSessionID); // The inventory item/folder, back from it's trip InventoryItemBase item = new InventoryItemBase(inventoryID, client.AgentId); item = invService.GetItem(item); InventoryFolderBase folder = null; UUID? previousParentFolderID = null; if (item != null && trashFolder != null) { previousParentFolderID = item.Folder; item.Folder = trashFolder.ID; // Diva comment: can't we just update this item??? List<UUID> uuids = new List<UUID>(); uuids.Add(item.ID); invService.DeleteItems(item.Owner, uuids); scene.AddInventoryItem(client, item); } else { folder = new InventoryFolderBase(inventoryID, client.AgentId); folder = invService.GetFolder(folder); if (folder != null & trashFolder != null) { previousParentFolderID = folder.ParentID; folder.ParentID = trashFolder.ID; invService.MoveFolder(folder); } } if ((null == item && null == folder) | null == trashFolder) { string reason = String.Empty; if (trashFolder == null) reason += " Trash folder not found."; if (item == null) reason += " Item not found."; if (folder == null) reason += " Folder not found."; client.SendAgentAlertMessage("Unable to delete "+ "received inventory" + reason, false); } // Tell client about updates to original parent and new parent (this should probably be factored with existing move item/folder code). else if (previousParentFolderID != null) { InventoryFolderBase previousParentFolder = new InventoryFolderBase((UUID)previousParentFolderID, client.AgentId); previousParentFolder = invService.GetFolder(previousParentFolder); scene.SendInventoryUpdate(client, previousParentFolder, true, true); scene.SendInventoryUpdate(client, trashFolder, true, true); } if (im.dialog == (byte)InstantMessageDialog.InventoryDeclined) { ScenePresence user = scene.GetScenePresence(new UUID(im.toAgentID)); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) m_TransferModule.SendInstantMessage(im, delegate(bool success) { }); } } } }
public void ClassifiedInfoUpdate(UUID queryclassifiedID, uint queryCategory, string queryName, string queryDescription, UUID queryParcelID, uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos, byte queryclassifiedFlags, int queryclassifiedPrice, IClientAPI remoteClient) { IScenePresence p = GetRegionUserIsIn(remoteClient.AgentId).GetScenePresence(remoteClient.AgentId); if (p == null) { return; //Just fail } IMoneyModule money = p.Scene.RequestModuleInterface <IMoneyModule>(); if (money != null) { if (!money.Charge(remoteClient.AgentId, queryclassifiedPrice, "Add Classified")) { remoteClient.SendAlertMessage("You do not have enough money to complete this upload."); return; } } UUID creatorUUID = remoteClient.AgentId; UUID classifiedUUID = queryclassifiedID; uint category = queryCategory; string name = queryName; string description = queryDescription; uint parentestate = queryParentEstate; UUID snapshotUUID = querySnapshotID; string simname = remoteClient.Scene.RegionInfo.RegionName; Vector3 globalpos = queryGlobalPos; byte classifiedFlags = queryclassifiedFlags; int classifiedPrice = queryclassifiedPrice; UUID parceluuid = p.CurrentParcelUUID; string parcelname = "Unknown"; IParcelManagementModule parcelManagement = GetRegionUserIsIn(remoteClient.AgentId).RequestModuleInterface <IParcelManagementModule>(); if (parcelManagement != null) { ILandObject parcel = parcelManagement.GetLandObject(p.AbsolutePosition.X, p.AbsolutePosition.Y); if (parcel != null) { parcelname = parcel.LandData.Name; parceluuid = parcel.LandData.InfoUUID; } } uint creationdate = (uint)Util.UnixTimeSinceEpoch(); uint expirationdate = (uint)Util.UnixTimeSinceEpoch() + (365 * 24 * 60 * 60); Classified classified = new Classified { ClassifiedUUID = classifiedUUID, CreatorUUID = creatorUUID, CreationDate = creationdate, ExpirationDate = expirationdate, Category = category, Name = name, Description = description, ParcelUUID = parceluuid, ParentEstate = parentestate, SnapshotUUID = snapshotUUID, SimName = simname, GlobalPos = globalpos, ParcelName = parcelname, ClassifiedFlags = classifiedFlags, PriceForListing = classifiedPrice }; ProfileFrontend.AddClassified(classified); }
private void handleEstateAccessDeltaRequest(IClientAPI remote_client, UUID invoice, int estateAccessType, UUID user) { // EstateAccessDelta handles Estate Managers, Sim Access, Sim Banlist, allowed Groups.. etc. if (user == Scene.RegionInfo.EstateSettings.EstateOwner) return; // never process EO if ((estateAccessType & 4) != 0) // User add { if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { List<int> estateIDs = Scene.EstateDataService.GetEstatesByOwner(Scene.RegionInfo.EstateSettings.EstateOwner); EstateSettings estateSettings; foreach (int estateID in estateIDs) { if (estateID != Scene.RegionInfo.EstateSettings.EstateID) { estateSettings = Scene.EstateDataService.LoadEstateSettings(estateID); estateSettings.AddEstateUser(user); estateSettings.Save(); } } } Scene.RegionInfo.EstateSettings.AddEstateUser(user); Scene.RegionInfo.EstateSettings.Save(); TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.AccessOptions, Scene.RegionInfo.EstateSettings.EstateAccess, Scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } if ((estateAccessType & 8) != 0) // User remove { if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { List<int> estateIDs = Scene.EstateDataService.GetEstatesByOwner(Scene.RegionInfo.EstateSettings.EstateOwner); EstateSettings estateSettings; foreach (int estateID in estateIDs) { if (estateID != Scene.RegionInfo.EstateSettings.EstateID) { estateSettings = Scene.EstateDataService.LoadEstateSettings(estateID); estateSettings.RemoveEstateUser(user); estateSettings.Save(); } } } Scene.RegionInfo.EstateSettings.RemoveEstateUser(user); Scene.RegionInfo.EstateSettings.Save(); TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.AccessOptions, Scene.RegionInfo.EstateSettings.EstateAccess, Scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } if ((estateAccessType & 16) != 0) // Group add { if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { List<int> estateIDs = Scene.EstateDataService.GetEstatesByOwner(Scene.RegionInfo.EstateSettings.EstateOwner); EstateSettings estateSettings; foreach (int estateID in estateIDs) { if (estateID != Scene.RegionInfo.EstateSettings.EstateID) { estateSettings = Scene.EstateDataService.LoadEstateSettings(estateID); estateSettings.AddEstateGroup(user); estateSettings.Save(); } } } Scene.RegionInfo.EstateSettings.AddEstateGroup(user); Scene.RegionInfo.EstateSettings.Save(); TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.AllowedGroups, Scene.RegionInfo.EstateSettings.EstateGroups, Scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } if ((estateAccessType & 32) != 0) // Group remove { if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { List<int> estateIDs = Scene.EstateDataService.GetEstatesByOwner(Scene.RegionInfo.EstateSettings.EstateOwner); EstateSettings estateSettings; foreach (int estateID in estateIDs) { if (estateID != Scene.RegionInfo.EstateSettings.EstateID) { estateSettings = Scene.EstateDataService.LoadEstateSettings(estateID); estateSettings.RemoveEstateGroup(user); estateSettings.Save(); } } } Scene.RegionInfo.EstateSettings.RemoveEstateGroup(user); Scene.RegionInfo.EstateSettings.Save(); TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.AllowedGroups, Scene.RegionInfo.EstateSettings.EstateGroups, Scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } if ((estateAccessType & 64) != 0) // Ban add { if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false)) { EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans; bool alreadyInList = false; for (int i = 0; i < banlistcheck.Length; i++) { if (user == banlistcheck[i].BannedUserID) { alreadyInList = true; break; } } if (!alreadyInList) { if ((estateAccessType & 1) != 0) // All estates { List<int> estateIDs = Scene.EstateDataService.GetEstatesByOwner(Scene.RegionInfo.EstateSettings.EstateOwner); EstateSettings estateSettings; foreach (int estateID in estateIDs) { if (estateID != Scene.RegionInfo.EstateSettings.EstateID) { EstateBan bitem = new EstateBan(); bitem.BannedUserID = user; bitem.EstateID = (uint)estateID; bitem.BannedHostAddress = "0.0.0.0"; bitem.BannedHostIPMask = "0.0.0.0"; estateSettings = Scene.EstateDataService.LoadEstateSettings(estateID); estateSettings.AddBan(bitem); estateSettings.Save(); } } } EstateBan item = new EstateBan(); item.BannedUserID = user; item.EstateID = Scene.RegionInfo.EstateSettings.EstateID; item.BannedHostAddress = "0.0.0.0"; item.BannedHostIPMask = "0.0.0.0"; Scene.RegionInfo.EstateSettings.AddBan(item); Scene.RegionInfo.EstateSettings.Save(); TriggerEstateInfoChange(); ScenePresence s = Scene.GetScenePresence(user); if (s != null) { if (!s.IsChildAgent) { if (!Scene.TeleportClientHome(user, s.ControllingClient)) { s.ControllingClient.Kick("Your access to the region was revoked and TP home failed - you have been logged out."); Scene.CloseAgent(s.UUID, false); } } } } else { remote_client.SendAlertMessage("User is already on the region ban list"); } //Scene.RegionInfo.regionBanlist.Add(Manager(user); remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } if ((estateAccessType & 128) != 0) // Ban remove { if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, false)) { EstateBan[] banlistcheck = Scene.RegionInfo.EstateSettings.EstateBans; bool alreadyInList = false; EstateBan listitem = null; for (int i = 0; i < banlistcheck.Length; i++) { if (user == banlistcheck[i].BannedUserID) { alreadyInList = true; listitem = banlistcheck[i]; break; } } if (alreadyInList && listitem != null) { if ((estateAccessType & 1) != 0) // All estates { List<int> estateIDs = Scene.EstateDataService.GetEstatesByOwner(Scene.RegionInfo.EstateSettings.EstateOwner); EstateSettings estateSettings; foreach (int estateID in estateIDs) { if (estateID != Scene.RegionInfo.EstateSettings.EstateID) { estateSettings = Scene.EstateDataService.LoadEstateSettings(estateID); estateSettings.RemoveBan(user); estateSettings.Save(); } } } Scene.RegionInfo.EstateSettings.RemoveBan(listitem.BannedUserID); Scene.RegionInfo.EstateSettings.Save(); TriggerEstateInfoChange(); } else { remote_client.SendAlertMessage("User is not on the region ban list"); } //Scene.RegionInfo.regionBanlist.Add(Manager(user); remote_client.SendBannedUserList(invoice, Scene.RegionInfo.EstateSettings.EstateBans, Scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } if ((estateAccessType & 256) != 0) // Manager add { if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { List<int> estateIDs = Scene.EstateDataService.GetEstatesByOwner(Scene.RegionInfo.EstateSettings.EstateOwner); EstateSettings estateSettings; foreach (int estateID in estateIDs) { if (estateID != Scene.RegionInfo.EstateSettings.EstateID) { estateSettings = Scene.EstateDataService.LoadEstateSettings(estateID); estateSettings.AddEstateManager(user); estateSettings.Save(); } } } Scene.RegionInfo.EstateSettings.AddEstateManager(user); Scene.RegionInfo.EstateSettings.Save(); TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.EstateManagers, Scene.RegionInfo.EstateSettings.EstateManagers, Scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } if ((estateAccessType & 512) != 0) // Manager remove { if (Scene.Permissions.CanIssueEstateCommand(remote_client.AgentId, true)) { if ((estateAccessType & 1) != 0) // All estates { List<int> estateIDs = Scene.EstateDataService.GetEstatesByOwner(Scene.RegionInfo.EstateSettings.EstateOwner); EstateSettings estateSettings; foreach (int estateID in estateIDs) { if (estateID != Scene.RegionInfo.EstateSettings.EstateID) { estateSettings = Scene.EstateDataService.LoadEstateSettings(estateID); estateSettings.RemoveEstateManager(user); estateSettings.Save(); } } } Scene.RegionInfo.EstateSettings.RemoveEstateManager(user); Scene.RegionInfo.EstateSettings.Save(); TriggerEstateInfoChange(); remote_client.SendEstateList(invoice, (int)Constants.EstateAccessCodex.EstateManagers, Scene.RegionInfo.EstateSettings.EstateManagers, Scene.RegionInfo.EstateSettings.EstateID); } else { remote_client.SendAlertMessage("Method EstateAccessDelta Failed, you don't have permissions"); } } }
void UndeliveredMessage(GridInstantMessage im, string reason) { if (OfflineMessagesConnector == null || im == null) { return; } IClientAPI client = FindClient(im.FromAgentID); if ((client == null) && (im.Dialog != 32)) { return; } if (!OfflineMessagesConnector.AddOfflineMessage(im)) { if ((!im.FromGroup) && (reason != "User does not exist.") && (client != null)) { client.SendInstantMessage(new GridInstantMessage { FromAgentID = im.ToAgentID, FromAgentName = "System", ToAgentID = im.FromAgentID, Dialog = (byte)InstantMessageDialog.MessageFromAgent, Message = "User has too many IMs already, please try again later.", Offline = 0, RegionID = im.RegionID }); } else if (client == null) { return; } } else if ((im.Offline != 0) && (!im.FromGroup || im.FromGroup)) { if (im.Dialog == 32) //Group notice { IGroupsModule module = m_Scene.RequestModuleInterface <IGroupsModule> (); if (module != null) { im = module.BuildOfflineGroupNotice(im); } // TODO: This drops (supposedly) group messages and the logic above is interesting!! return; } if (client == null) { return; } IEmailModule emailModule = m_Scene.RequestModuleInterface <IEmailModule> (); if (emailModule != null && m_SendOfflineMessagesToEmail) { IUserProfileInfo profile = Framework.Utilities.DataManager.RequestPlugin <IProfileConnector> ().GetUserProfile(im.ToAgentID); if (profile != null && profile.IMViaEmail) { UserAccount account = m_Scene.UserAccountService.GetUserAccount(null, im.ToAgentID); if (account != null && !string.IsNullOrEmpty(account.Email)) { emailModule.SendEmail(UUID.Zero, account.Email, string.Format("Offline Message from {0}", im.FromAgentName), string.Format("Time: {0}\n", Util.ToDateTime(im.Timestamp).ToShortDateString()) + string.Format("From: {0}\n", im.FromAgentName) + string.Format("Message: {0}\n", im.Message), m_Scene); } } } if (im.Dialog == (byte)InstantMessageDialog.MessageFromAgent && !im.FromGroup) { client.SendInstantMessage(new GridInstantMessage { FromAgentID = im.ToAgentID, FromAgentName = "System", ToAgentID = im.FromAgentID, Dialog = (byte)InstantMessageDialog.MessageFromAgent, Message = "Message saved, reason: " + reason, Offline = 0, RegionID = im.RegionID }); } if (im.Dialog == (byte)InstantMessageDialog.InventoryOffered) { client.SendAlertMessage("User is not currently online. (Inventory has been saved)"); } } else if (im.Offline == 0) { if (client == null) { return; } if (im.Dialog == (byte)InstantMessageDialog.MessageFromAgent && !im.FromGroup) { client.SendInstantMessage(new GridInstantMessage { FromAgentID = im.ToAgentID, FromAgentName = "System", ToAgentID = im.FromAgentID, Dialog = (byte)InstantMessageDialog.MessageFromAgent, Message = "Message saved, reason: " + reason, Offline = 0, RegionID = im.RegionID }); } if (im.Dialog == (byte)InstantMessageDialog.InventoryOffered) { client.SendAlertMessage("User is not currently online. (Inventory has been saved)"); } } }
private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient) { lock (this) { remoteClient.OnXferReceive -= TerrainUploader.XferReceive; remoteClient.OnAbortXfer -= AbortTerrainXferHandler; TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; TerrainUploader = null; } remoteClient.SendAlertMessage("Terrain Upload Complete. Loading...."); ITerrainModule terr = Scene.RequestModuleInterface<ITerrainModule>(); if (terr != null) { m_log.Warn("[CLIENT]: Got Request to Send Terrain in region " + Scene.RegionInfo.RegionName); try { MemoryStream terrainStream = new MemoryStream(terrainData); terr.LoadFromStream(filename, terrainStream); terrainStream.Close(); FileInfo x = new FileInfo(filename); remoteClient.SendAlertMessage("Your terrain was loaded as a " + x.Extension + " file. It may take a few moments to appear."); } catch (IOException e) { m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was an IO Exception loading your terrain. Please check free space."); return; } catch (SecurityException e) { m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was a security Exception loading your terrain. Please check the security on the simulator drive"); return; } catch (UnauthorizedAccessException e) { m_log.ErrorFormat("[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was a security Exception loading your terrain. Please check the security on the simulator drive"); return; } catch (Exception e) { m_log.ErrorFormat("[TERRAIN]: Error loading a terrain file uploaded via the estate tools. It gave us the following error: {0}", e.ToString()); remoteClient.SendAlertMessage("There was a general error loading your terrain. Please fix the terrain file and try again"); } } else { remoteClient.SendAlertMessage("Unable to apply terrain. Cannot get an instance of the terrain module"); } }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { Util.FireAndForget(x => { try { List <MapBlockData> blocks = new List <MapBlockData>(); if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) { // final block, closing the search result AddFinalBlock(blocks, mapName); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } //m_log.DebugFormat("MAP NAME=({0})", mapName); // Hack to get around the fact that ll V3 now drops the port from the // map name. See https://jira.secondlife.com/browse/VWR-28570 // // Caller, use this magic form instead: // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 // or url encode if possible. // the hacks we do with this viewer... // bool needOriginalName = false; string mapNameOrig = mapName; if (mapName.Contains("|")) { mapName = mapName.Replace('|', ':'); needOriginalName = true; } if (mapName.Contains("+")) { mapName = mapName.Replace('+', ' '); needOriginalName = true; } if (mapName.Contains("!")) { mapName = mapName.Replace('!', '/'); needOriginalName = true; } if (mapName.Contains(".")) { needOriginalName = true; } // try to fetch from GridServer List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); // if (regionInfos.Count == 0) // remoteClient.SendAlertMessage("Hyperlink could not be established."); //m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions", mapName, regionInfos.Count); MapBlockData data; if (regionInfos != null && regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; MapBlockData block = new MapBlockData(); WorldMap.MapBlockFromGridRegion(block, info, flags); if (flags == 2 && regionInfos.Count == 1 && needOriginalName) { block.Name = mapNameOrig; } blocks.Add(block); } } // final block, closing the search result AddFinalBlock(blocks, mapNameOrig); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); // send extra user messages for V3 // because the UI is very confusing // while we don't fix the hard-coded urls if (flags == 2) { if (regionInfos == null || regionInfos.Count == 0) { remoteClient.SendAgentAlertMessage("No regions found with that name.", true); } // else if (regionInfos.Count == 1) // remoteClient.SendAgentAlertMessage("Region found!", false); } } finally { lock (m_Clients) m_Clients.Remove(remoteClient.AgentId); } }); }
private void handleTerrainRequest(IClientAPI remote_client, string clientFileName) { // Save terrain here ITerrainModule terr = Scene.RequestModuleInterface<ITerrainModule>(); if (terr != null) { m_log.Warn("[CLIENT]: Got Request to Send Terrain in region " + Scene.RegionInfo.RegionName); if (File.Exists(Util.dataDir() + "/terrain.raw")) { File.Delete(Util.dataDir() + "/terrain.raw"); } terr.SaveToFile(Util.dataDir() + "/terrain.raw"); FileStream input = new FileStream(Util.dataDir() + "/terrain.raw", FileMode.Open); byte[] bdata = new byte[input.Length]; input.Read(bdata, 0, (int)input.Length); remote_client.SendAlertMessage("Terrain file written, starting download..."); Scene.XferManager.AddNewFile("terrain.raw", bdata); // Tell client about it m_log.Warn("[CLIENT]: Sending Terrain to " + remote_client.Name); remote_client.SendInitiateDownload("terrain.raw", clientFileName); } }
private void UndeliveredMessage(GridInstantMessage im, string reason) { if (OfflineMessagesConnector == null || im == null) { return; } IClientAPI client = FindClient(im.fromAgentID); if ((client == null) && (im.dialog != 32)) { return; } if (!OfflineMessagesConnector.AddOfflineMessage(im)) { if ((!im.fromGroup) && (reason != "User does not exist.") && (client != null)) { client.SendInstantMessage(new GridInstantMessage( null, im.toAgentID, "System", im.fromAgentID, (byte)InstantMessageDialog.MessageFromAgent, "User has too many IMs already, please try again later.", false, Vector3.Zero)); } else if (client == null) { return; } } else if ((im.offline != 0) && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) { if (im.dialog == 32) //Group notice { IGroupsModule module = m_SceneList[0].RequestModuleInterface <IGroupsModule>(); if (module != null) { im = module.BuildOfflineGroupNotice(im); } return; } if (client == null) { return; } IEmailModule emailModule = m_SceneList[0].RequestModuleInterface <IEmailModule> (); if (emailModule != null && m_SendOfflineMessagesToEmail) { IUserProfileInfo profile = DataManager.DataManager.RequestPlugin <IProfileConnector> ().GetUserProfile(im.toAgentID); if (profile != null && profile.IMViaEmail) { UserAccount account = m_SceneList[0].UserAccountService.GetUserAccount(UUID.Zero, im.toAgentID.ToString()); if (account != null && !string.IsNullOrEmpty(account.Email)) { emailModule.SendEmail(UUID.Zero, account.Email, string.Format("Offline Message from {0}", im.fromAgentName), string.Format("Time: {0}\n", Util.ToDateTime(im.timestamp).ToShortDateString()) + string.Format("From: {0}\n", im.fromAgentName) + string.Format("Message: {0}\n", im.message)); } } } if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent && !im.fromGroup) { client.SendInstantMessage(new GridInstantMessage( null, im.toAgentID, "System", im.fromAgentID, (byte)InstantMessageDialog.MessageFromAgent, "Message saved, reason: " + reason, false, new Vector3())); } if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) { client.SendAlertMessage("User is not online. Inventory has been saved"); } } else if (im.offline == 0) { if (client == null) { return; } if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent && !im.fromGroup) { client.SendInstantMessage(new GridInstantMessage( null, im.toAgentID, "System", im.fromAgentID, (byte)InstantMessageDialog.MessageFromAgent, "Message saved, reason: " + reason, false, new Vector3())); } if (im.dialog == (byte)InstantMessageDialog.InventoryOffered) { client.SendAlertMessage("User not able to be found. Inventory has been saved"); } } }
/// <summary> /// Sends the the stored money balance to the client /// </summary> /// <param name="client"></param> /// <param name="agentID"></param> /// <param name="SessionID"></param> /// <param name="TransactionID"></param> public void SendMoneyBalance(IClientAPI client, UUID agentID, UUID SessionID, UUID TransactionID) { if (client.AgentId == agentID && client.SessionId == SessionID) { int returnfunds = 0; try { returnfunds = GetFundsForAgentID(agentID); } catch (Exception e) { client.SendAlertMessage(e.Message + " "); } client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds); } else { client.SendAlertMessage("Unable to send your money balance to you!"); } }
public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) { if (m_scene.RegionInfo.EstateSettings.AllowParcelChanges) { try { bool snap_selection = false; if (args.AuthBuyerID != LandData.AuthBuyerID || args.SalePrice != LandData.SalePrice) { if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this) && m_scene.RegionInfo.RegionSettings.AllowLandResell) { LandData.AuthBuyerID = args.AuthBuyerID; LandData.SalePrice = args.SalePrice; snap_selection = true; } else { remote_client.SendAlertMessage("Permissions: You cannot set this parcel for sale"); args.ParcelFlags &= ~(uint)ParcelFlags.ForSale; args.ParcelFlags &= ~(uint)ParcelFlags.ForSaleObjects; args.ParcelFlags &= ~(uint)ParcelFlags.SellParcelObjects; } } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale)) { if (!LandData.IsGroupOwned) { LandData.GroupID = args.GroupID; } } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.FindPlaces)) { LandData.Category = args.Category; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.ChangeMedia)) { LandData.MediaAutoScale = args.MediaAutoScale; LandData.MediaID = args.MediaID; LandData.MediaURL = args.MediaURL; LandData.MusicURL = args.MusicURL; LandData.MediaType = args.MediaType; LandData.MediaDescription = args.MediaDescription; LandData.MediaWidth = args.MediaWidth; LandData.MediaHeight = args.MediaHeight; LandData.MediaLoop = args.MediaLoop; LandData.ObscureMusic = args.ObscureMusic; LandData.ObscureMedia = args.ObscureMedia; // 25062016 Added for LibOMV update 0.9.4.5 LandData.AnyAVSounds = args.AnyAVSounds; LandData.GroupAVSounds = args.GroupAVSounds; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) { // check for allowed settings and clear if necessary if (m_scene.RegionInfo.RegionSettings.BlockFly && ((args.ParcelFlags & (uint)ParcelFlags.AllowFly) == (uint)ParcelFlags.AllowFly)) { //Vanquish flying as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.AllowFly; } if (m_scene.RegionInfo.RegionSettings.RestrictPushing && ((args.ParcelFlags & (uint)ParcelFlags.RestrictPushObject) == (uint)ParcelFlags.RestrictPushObject)) { //Vanquish pushing as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.RestrictPushObject; } if (!m_scene.RegionInfo.EstateSettings.AllowLandmark && ((args.ParcelFlags & (uint)ParcelFlags.AllowLandmark) == (uint)ParcelFlags.AllowLandmark)) { //Vanquish landmarks as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.AllowLandmark; } if (m_scene.RegionInfo.RegionSettings.BlockShowInSearch && ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory)) { //Vanquish show in search as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.ShowDirectory; } // Check if ShowDirectory has changed var updShowInDir = (args.ParcelFlags & (uint)ParcelFlags.ShowDirectory); if ((LandData.Flags & (uint)ParcelFlags.ShowDirectory) != updShowInDir) { IScheduledMoneyModule scheduledMoneyModule = m_scene.RequestModuleInterface <IScheduledMoneyModule> (); if (scheduledMoneyModule != null) { if ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory) { //Flag is set var payOk = scheduledMoneyModule.Charge(remote_client.AgentId, // who to charge scheduledMoneyModule.DirectoryFeeCharge, // how much "Parcel Show in Search Fee - " + LandData.GlobalID, // description (needs UUID) TransactionType.ParcelDirFee, // transaction type "[ShowInDirectory: " + LandData.GlobalID + "]", // scheduler identifier false, // charge immediately false); // run once if (!payOk) { // Payment was not processed remote_client.SendAlertMessage("You don't have enough money to set this parcel in search."); args.ParcelFlags &= (uint)ParcelFlags.ShowDirectory; } } else { scheduledMoneyModule.RemoveDirFeeScheduledCharge("[ShowInDirectory: " + LandData.GlobalID + "]"); } } } LandData.Flags = args.ParcelFlags; // 25062016 Added for LibOMV update 0.9.4.5 LandData.SeeAVS = args.SeeAVs; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.SetLandingPoint)) { LandData.LandingType = args.LandingType; LandData.UserLocation = args.UserLocation; LandData.UserLookAt = args.UserLookAt; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandChangeIdentity)) { LandData.Description = args.Desc; LandData.Name = args.Name; LandData.SnapshotID = args.SnapshotID; LandData.Private = args.Privacy; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManagePasses)) { LandData.PassHours = args.PassHours; LandData.PassPrice = args.PassPrice; } // 20160203 -greythane- the only time we should play with the ParcelStatus is // if it is being sold to a specified buyer if (LandData.AuthBuyerID != UUID.Zero) { LandData.Status = ParcelStatus.LeasePending; } // 141031 Greythane, this is an example of where the check needs to go /* LandData.Status = LandData.OwnerID == m_parcelManagementModule.GodParcelOwner * ? ParcelStatus.Abandoned * : LandData.AuthBuyerID != UUID.Zero * ? ParcelStatus.LeasePending * : ParcelStatus.Leased; */ m_parcelManagementModule.UpdateLandObject(this); SendLandUpdateToAvatarsOverMe(snap_selection); } catch (Exception ex) { MainConsole.Instance.Warn("[LAND]: Error updating land object " + LandData.Name + " in region " + m_scene.RegionInfo.RegionName + " : " + ex); } } }
/// <summary> /// Derez one or more objects from the scene. /// </summary> /// <remarks> /// Won't actually remove the scene object in the case where the object is being copied to a user inventory. /// </remarks> /// <param name='remoteClient'>Client requesting derez</param> /// <param name='localIDs'>Local ids of root parts of objects to delete.</param> /// <param name='groupID'>Not currently used. Here because the client passes this to us.</param> /// <param name='action'>DeRezAction</param> /// <param name='destinationID'>User folder ID to place derezzed object</param> public virtual void DeRezObjects( IClientAPI remoteClient, List<uint> localIDs, UUID groupID, DeRezAction action, UUID destinationID) { // First, see of we can perform the requested action and // build a list of eligible objects List<uint> deleteIDs = new List<uint>(); List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>(); // Start with true for both, then remove the flags if objects // that we can't derez are part of the selection bool permissionToTake = true; bool permissionToTakeCopy = true; bool permissionToDelete = true; foreach (uint localID in localIDs) { // Invalid id SceneObjectPart part = GetSceneObjectPart(localID); if (part == null) continue; // Already deleted by someone else if (part.ParentGroup.IsDeleted) continue; // Can't delete child prims if (part != part.ParentGroup.RootPart) continue; SceneObjectGroup grp = part.ParentGroup; deleteIDs.Add(localID); deleteGroups.Add(grp); // If child prims have invalid perms, fix them grp.AdjustChildPrimPermissions(false); if (remoteClient == null) { // Autoreturn has a null client. Nothing else does. So // allow only returns if (action != DeRezAction.Return) { m_log.WarnFormat( "[AGENT INVENTORY]: Ignoring attempt to {0} {1} {2} without a client", action, grp.Name, grp.UUID); return; } permissionToTakeCopy = false; } else { if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) permissionToTakeCopy = false; if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) permissionToTake = false; if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) permissionToDelete = false; } } // Handle god perms if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) { permissionToTake = true; permissionToTakeCopy = true; permissionToDelete = true; } // If we're re-saving, we don't even want to delete if (action == DeRezAction.SaveToExistingUserInventoryItem) permissionToDelete = false; // if we want to take a copy, we also don't want to delete // Note: after this point, the permissionToTakeCopy flag // becomes irrelevant. It already includes the permissionToTake // permission and after excluding no copy items here, we can // just use that. if (action == DeRezAction.TakeCopy) { // If we don't have permission, stop right here if (!permissionToTakeCopy) { remoteClient.SendAlertMessage("You don't have permission to take the object"); return; } permissionToTake = true; // Don't delete permissionToDelete = false; } if (action == DeRezAction.Return) { if (remoteClient != null) { if (Permissions.CanReturnObjects( null, remoteClient.AgentId, deleteGroups)) { permissionToTake = true; permissionToDelete = true; foreach (SceneObjectGroup g in deleteGroups) { AddReturn(g.OwnerID == g.GroupID ? g.LastOwnerID : g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); } } } else // Auto return passes through here with null agent { permissionToTake = true; permissionToDelete = true; } } if (permissionToTake && (action != DeRezAction.Delete || this.m_useTrashOnDelete)) { m_asyncSceneObjectDeleter.DeleteToInventory( action, destinationID, deleteGroups, remoteClient, permissionToDelete); } else if (permissionToDelete) { foreach (SceneObjectGroup g in deleteGroups) DeleteSceneObject(g, false); } }
public void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client) { if (m_scene.RegionInfo.EstateSettings.AllowParcelChanges) { try { bool snap_selection = false; if (args.AuthBuyerID != LandData.AuthBuyerID || args.SalePrice != LandData.SalePrice) { if (m_scene.Permissions.CanSellParcel(remote_client.AgentId, this) && m_scene.RegionInfo.RegionSettings.AllowLandResell) { LandData.AuthBuyerID = args.AuthBuyerID; LandData.SalePrice = args.SalePrice; snap_selection = true; } else { remote_client.SendAlertMessage("Permissions: You cannot set this parcel for sale"); args.ParcelFlags &= ~(uint)ParcelFlags.ForSale; args.ParcelFlags &= ~(uint)ParcelFlags.ForSaleObjects; args.ParcelFlags &= ~(uint)ParcelFlags.SellParcelObjects; } } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandSetSale)) { if (!LandData.IsGroupOwned) { LandData.GroupID = args.GroupID; } } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.FindPlaces)) { LandData.Category = args.Category; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.ChangeMedia)) { LandData.MediaAutoScale = args.MediaAutoScale; LandData.MediaID = args.MediaID; LandData.MediaURL = args.MediaURL; LandData.MusicURL = args.MusicURL; LandData.MediaType = args.MediaType; LandData.MediaDescription = args.MediaDescription; LandData.MediaWidth = args.MediaWidth; LandData.MediaHeight = args.MediaHeight; LandData.MediaLoop = args.MediaLoop; LandData.ObscureMusic = args.ObscureMusic; LandData.ObscureMedia = args.ObscureMedia; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandOptions)) { if (m_scene.RegionInfo.RegionSettings.BlockFly && ((args.ParcelFlags & (uint)ParcelFlags.AllowFly) == (uint)ParcelFlags.AllowFly)) { //Vanquish flying as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.AllowFly; } if (m_scene.RegionInfo.RegionSettings.RestrictPushing && ((args.ParcelFlags & (uint)ParcelFlags.RestrictPushObject) == (uint)ParcelFlags.RestrictPushObject)) { //Vanquish pushing as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.RestrictPushObject; } if (!m_scene.RegionInfo.EstateSettings.AllowLandmark && ((args.ParcelFlags & (uint)ParcelFlags.AllowLandmark) == (uint)ParcelFlags.AllowLandmark)) { //Vanquish landmarks as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.AllowLandmark; } if (m_scene.RegionInfo.RegionSettings.BlockShowInSearch && ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory)) { //Vanquish show in search as per estate settings! args.ParcelFlags &= ~(uint)ParcelFlags.ShowDirectory; } if ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory && (LandData.Flags & (uint)ParcelFlags.ShowDirectory) != (uint)ParcelFlags.ShowDirectory) { //If the flags have changed, we need to charge them.. maybe // We really need to check per month or whatever IScheduledMoneyModule scheduledMoneyModule = m_scene.RequestModuleInterface <IScheduledMoneyModule>(); IMoneyModule moneyModule = m_scene.RequestModuleInterface <IMoneyModule>(); if (scheduledMoneyModule != null) { if ((args.ParcelFlags & (uint)ParcelFlags.ShowDirectory) == (uint)ParcelFlags.ShowDirectory) { //Flag is set if (!scheduledMoneyModule.Charge(remote_client.AgentId, moneyModule.DirectoryFeeCharge, "Parcel Show in Search Fee - " + LandData.GlobalID, 7, TransactionType.ParcelDirFee, "ShowInDirectory" + LandData.GlobalID.ToString(), true)) { remote_client.SendAlertMessage( "You don't have enough money to set this parcel in search."); args.ParcelFlags &= (uint)ParcelFlags.ShowDirectory; } } else { scheduledMoneyModule.RemoveFromScheduledCharge("ShowInDirectory" + LandData.GlobalID.ToString()); } } } LandData.Flags = args.ParcelFlags; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.SetLandingPoint)) { LandData.LandingType = args.LandingType; LandData.UserLocation = args.UserLocation; LandData.UserLookAt = args.UserLookAt; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandChangeIdentity)) { LandData.Description = args.Desc; LandData.Name = args.Name; LandData.SnapshotID = args.SnapshotID; LandData.Private = args.Privacy; } if (m_scene.Permissions.CanEditParcelProperties(remote_client.AgentId, this, GroupPowers.LandManagePasses)) { LandData.PassHours = args.PassHours; LandData.PassPrice = args.PassPrice; } LandData.Status = LandData.OwnerID == m_parcelManagementModule.GodParcelOwner ? ParcelStatus.Abandoned : LandData.AuthBuyerID != UUID.Zero ? ParcelStatus.LeasePending : ParcelStatus.Leased; m_parcelManagementModule.UpdateLandObject(this); SendLandUpdateToAvatarsOverMe(snap_selection); } catch (Exception ex) { MainConsole.Instance.Warn("[LAND]: Error updating land object " + this.LandData.Name + " in region " + this.m_scene.RegionInfo.RegionName + " : " + ex); } } }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName) { if (mapName.Length < 3) { remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } // try to fetch from GridServer List<GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(UUID.Zero, mapName, 20); if (regionInfos == null) { m_log.Warn("[MAPSEARCHMODULE]: RequestNamedRegions returned null. Old gridserver?"); // service wasn't available; maybe still an old GridServer. Try the old API, though it will return only one region regionInfos = new List<GridRegion>(); GridRegion info = m_scene.GridService.GetRegionByName(UUID.Zero, mapName); if (info != null) regionInfos.Add(info); } List<MapBlockData> blocks = new List<MapBlockData>(); MapBlockData data; if (regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; data.MapImageID = info.TerrainImage; data.Name = info.RegionName; data.RegionFlags = 0; data.WaterHeight = 0; // not used data.X = (ushort)(info.RegionLocX / Constants.RegionSize); data.Y = (ushort)(info.RegionLocY / Constants.RegionSize); blocks.Add(data); } } // final block, closing the search result data = new MapBlockData(); data.Agents = 0; data.Access = 255; data.MapImageID = UUID.Zero; data.Name = mapName; data.RegionFlags = 0; data.WaterHeight = 0; // not used data.X = 0; data.Y = 0; blocks.Add(data); remoteClient.SendMapBlock(blocks, 2); }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { List <MapBlockData> blocks = new List <MapBlockData>(); MapBlockData data; if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) { // final block, closing the search result AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } //m_log.DebugFormat("MAP NAME=({0})", mapName); // Hack to get around the fact that ll V3 now drops the port from the // map name. See https://jira.secondlife.com/browse/VWR-28570 // // Caller, use this magic form instead: // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 // or url encode if possible. // the hacks we do with this viewer... // string mapNameOrig = mapName; if (mapName.Contains("|")) { mapName = mapName.Replace('|', ':'); } if (mapName.Contains("+")) { mapName = mapName.Replace('+', ' '); } if (mapName.Contains("!")) { mapName = mapName.Replace('!', '/'); } // try to fetch from GridServer List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); if (regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { data = new MapBlockData(); data.Agents = 0; data.Access = info.Access; if (flags == 2) // V2 sends this { data.MapImageId = UUID.Zero; } else { data.MapImageId = info.TerrainImage; } // ugh! V2-3 is very sensitive about the result being // exactly the same as the requested name if (regionInfos.Count == 1 && mapNameOrig.Contains("|") || mapNameOrig.Contains("+")) { data.Name = mapNameOrig; } else { data.Name = info.RegionName; } data.RegionFlags = 0; // TODO not used? data.WaterHeight = 0; // not used data.X = (ushort)(info.RegionLocX / Constants.RegionSize); data.Y = (ushort)(info.RegionLocY / Constants.RegionSize); blocks.Add(data); } } // final block, closing the search result AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); // send extra user messages for V3 // because the UI is very confusing // while we don't fix the hard-coded urls if (flags == 2) { if (regionInfos.Count == 0) { remoteClient.SendAlertMessage("No regions found with that name."); } else if (regionInfos.Count == 1) { remoteClient.SendAlertMessage("Region found!"); } } }
public void ParcelBuyPass(IClientAPI client, UUID agentID, int ParcelLocalID) { ILandObject landObject = GetLandObject(ParcelLocalID); if (landObject == null) { client.SendAlertMessage("Could not find the parcel you are currently on."); return; } if (landObject.IsBannedFromLand(agentID)) { client.SendAlertMessage("You cannot buy a pass as you are banned from this parcel."); return; } IMoneyModule module = m_scene.RequestModuleInterface<IMoneyModule>(); if (module != null) if ( !module.Transfer(landObject.LandData.OwnerID, client.AgentId, landObject.LandData.PassPrice, "Parcel Pass")) { client.SendAlertMessage("You do not have enough funds to complete this transaction."); return; } ParcelManager.ParcelAccessEntry entry = new ParcelManager.ParcelAccessEntry { AgentID = agentID, Flags = AccessList.Access, Time = DateTime.Now.AddHours(landObject.LandData.PassHours) }; landObject.LandData.ParcelAccessList.Add(entry); client.SendAgentAlertMessage("You have been added to the parcel access list.", false); }
//protected override bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agentData, ScenePresence sp) //{ // int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); // if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) // { // // this user is going to another grid // if (m_RestrictAppearanceAbroad && Scene.UserManagementModule.IsLocalGridUser(agentData.AgentID)) // { // // We need to strip the agent off its appearance // m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Sending generic appearance"); // // Delete existing npc attachments // Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false); // // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet since it doesn't transfer attachments // AvatarAppearance newAppearance = new AvatarAppearance(ExportedAppearance, true); // sp.Appearance = newAppearance; // // Rez needed npc attachments // Scene.AttachmentsModule.RezAttachments(sp); // IAvatarFactoryModule module = Scene.RequestModuleInterface<IAvatarFactoryModule>(); // //module.SendAppearance(sp.UUID); // module.RequestRebake(sp, false); // Scene.AttachmentsModule.CopyAttachments(sp, agentData); // agentData.Appearance = sp.Appearance; // } // } // foreach (AvatarAttachment a in agentData.Appearance.GetAttachments()) // m_log.DebugFormat("[XXX]: {0}-{1}", a.ItemID, a.AssetID); // return base.UpdateAgent(reg, finalDestination, agentData, sp); //} public override bool TeleportHome(UUID id, IClientAPI client) { // Let's find out if this is a foreign user or a local user IUserManagement uMan = Scene.RequestModuleInterface <IUserManagement>(); if (uMan != null && uMan.IsLocalGridUser(id)) { // local grid user return(base.TeleportHome(id, client)); } bool notsame = false; if (client == null) { m_log.DebugFormat( "[HG ENTITY TRANSFER MODULE]: Request to teleport {0} home", id); } else { if (id == client.AgentId) { m_log.DebugFormat( "[HG ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, id); } else { notsame = true; m_log.DebugFormat( "[HG ENTITY TRANSFER MODULE]: Request to teleport {0} home by {1} {2}", id, client.Name, client.AgentId); } } ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(id); if (sp == null || sp.IsDeleted || sp.IsChildAgent || sp.ControllingClient == null || !sp.ControllingClient.IsActive) { if (notsame) { client.SendAlertMessage("TeleportHome: Agent not found in the scene"); } m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene"); return(false); } IClientAPI targetClient = sp.ControllingClient; if (sp.IsInTransit) { if (notsame) { client.SendAlertMessage("TeleportHome: Agent already processing a teleport"); } targetClient.SendTeleportFailed("Already processing a teleport"); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent still in teleport"); return(false); } // Foreign user wants to go home // AgentCircuitData aCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(targetClient.CircuitCode); if (aCircuit == null) { if (notsame) { client.SendAlertMessage("TeleportHome: Agent information not found"); } targetClient.SendTeleportFailed("Home information not found"); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); return(false); } if (!aCircuit.ServiceURLs.ContainsKey("HomeURI")) { if (notsame) { client.SendAlertMessage("TeleportHome: Agent home not set"); } targetClient.SendTeleportFailed("Home not set"); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent home not set"); return(false); } string homeURI = aCircuit.ServiceURLs["HomeURI"].ToString(); IUserAgentService userAgentService = new UserAgentServiceConnector(homeURI); Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; GridRegion finalDestination = null; try { finalDestination = userAgentService.GetHomeRegion(id, out position, out lookAt); } catch (Exception e) { m_log.Debug("[HG ENTITY TRANSFER MODULE]: GetHomeRegion call failed ", e); } if (finalDestination == null) { if (notsame) { client.SendAlertMessage("TeleportHome: Agent Home region not found"); } targetClient.SendTeleportFailed("Home region not found"); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found"); return(false); } GridRegion homeGatekeeper = MakeGateKeeperRegion(homeURI); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome)); return(true); }
public void LinkObjects(IClientAPI client, uint parentPrimId, List<uint> childPrimIds) { List<UUID> owners = new List<UUID>(); List<ISceneChildEntity> children = new List<ISceneChildEntity>(); ISceneChildEntity root = m_parentScene.GetSceneObjectPart(parentPrimId); if (root == null) { MainConsole.Instance.DebugFormat("[LINK]: Can't find linkset root prim {0}", parentPrimId); return; } if (!m_parentScene.Permissions.CanLinkObject(client.AgentId, root.ParentEntity.UUID)) { MainConsole.Instance.DebugFormat("[LINK]: Refusing link. No permissions on root prim"); return; } foreach (uint localID in childPrimIds) { ISceneChildEntity part = m_parentScene.GetSceneObjectPart(localID); if (part == null) continue; if (!owners.Contains(part.OwnerID)) owners.Add(part.OwnerID); if (m_parentScene.Permissions.CanLinkObject(client.AgentId, part.ParentEntity.UUID)) children.Add(part); } // Must be all one owner // if (owners.Count > 1) { MainConsole.Instance.DebugFormat("[LINK]: Refusing link. Too many owners"); client.SendAlertMessage("Permissions: Cannot link, too many owners."); return; } if (children.Count == 0) { MainConsole.Instance.DebugFormat("[LINK]: Refusing link. No permissions to link any of the children"); client.SendAlertMessage("Permissions: Cannot link, not enough permissions."); return; } int LinkCount = children.Cast<SceneObjectPart>().Sum(part => part.ParentGroup.ChildrenList.Count); IOpenRegionSettingsModule module = m_parentScene.RequestModuleInterface<IOpenRegionSettingsModule>(); if (module != null) { if (LinkCount > module.MaximumLinkCount && module.MaximumLinkCount != -1) { client.SendAlertMessage("You cannot link more than " + module.MaximumLinkCount + " prims. Please try again with fewer prims."); return; } if ((root.Flags & PrimFlags.Physics) == PrimFlags.Physics) { //We only check the root here because if the root is physical, it will be applied to all during the link if (LinkCount > module.MaximumLinkCountPhys && module.MaximumLinkCountPhys != -1) { client.SendAlertMessage("You cannot link more than " + module.MaximumLinkCountPhys + " physical prims. Please try again with fewer prims."); return; } } } LinkObjects(root, children); }
/// <summary> /// Do pre-rez processing when the object comes from an item. /// </summary> /// <param name="remoteClient"></param> /// <param name="item"></param> /// <param name="objlist"></param> /// <param name="pos"></param> /// <param name="veclist"> /// List of vector position adjustments for a coalesced objects. For ordinary objects /// this list will contain just Vector3.Zero. The order of adjustments must match the order of objlist /// </param> /// <param name="isAttachment"></param> /// <returns>true if we can processed with rezzing, false if we need to abort</returns> private bool DoPreRezWhenFromItem( IClientAPI remoteClient, InventoryItemBase item, List <SceneObjectGroup> objlist, Vector3 pos, List <Vector3> veclist, bool isAttachment) { UUID fromUserInventoryItemId = UUID.Zero; // If we have permission to copy then link the rezzed object back to the user inventory // item that it came from. This allows us to enable 'save object to inventory' if (!m_Scene.Permissions.BypassPermissions()) { if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy && (item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { fromUserInventoryItemId = item.ID; } } else { if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { // Brave new fullperm world fromUserInventoryItemId = item.ID; } } for (int i = 0; i < objlist.Count; i++) { SceneObjectGroup g = objlist[i]; if (!m_Scene.Permissions.CanRezObject( g.PrimCount, remoteClient.AgentId, pos + veclist[i]) && !isAttachment) { // The client operates in no fail mode. It will // have already removed the item from the folder // if it's no copy. // Put it back if it's not an attachment // if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment)) { remoteClient.SendBulkUpdateInventory(item); } ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y); remoteClient.SendAlertMessage(string.Format( "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.", item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.Name)); return(false); } } for (int i = 0; i < objlist.Count; i++) { SceneObjectGroup so = objlist[i]; SceneObjectPart rootPart = so.RootPart; // Since renaming the item in the inventory does not // affect the name stored in the serialization, transfer // the correct name from the inventory to the // object itself before we rez. // // Only do these for the first object if we are rezzing a coalescence. if (i == 0) { rootPart.Name = item.Name; rootPart.Description = item.Description; rootPart.ObjectSaleType = item.SaleType; rootPart.SalePrice = item.SalePrice; } so.FromFolderID = item.Folder; // m_log.DebugFormat( // "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", // rootPart.OwnerID, item.Owner, item.CurrentPermissions); if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) { //Need to kill the for sale here rootPart.ObjectSaleType = 0; rootPart.SalePrice = 10; if (m_Scene.Permissions.PropagatePermissions()) { foreach (SceneObjectPart part in so.Parts) { if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; } part.GroupMask = 0; // DO NOT propagate here } so.ApplyNextOwnerPermissions(); } } foreach (SceneObjectPart part in so.Parts) { part.FromUserInventoryItemID = fromUserInventoryItemId; if ((part.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) { part.Inventory.ChangeInventoryOwner(item.Owner); part.GroupMask = 0; // DO NOT propagate here } part.EveryoneMask = item.EveryOnePermissions; part.NextOwnerMask = item.NextPermissions; } rootPart.TrimPermissions(); if (isAttachment) { so.FromItemID = item.ID; } } return(true); }
/// <summary> /// Create a new inventory item. Called when the client creates a new item directly within their /// inventory (e.g. by selecting a context inventory menu option). /// </summary> /// <param name="remoteClient"></param> /// <param name="transactionID"></param> /// <param name="folderID"></param> /// <param name="callbackID"></param> /// <param name="description"></param> /// <param name="name"></param> /// <param name="invType"></param> /// <param name="assetType"></param> /// <param name="wearableType"></param> /// <param name="nextOwnerMask"></param> /// <param name="creationDate"></param> protected void CreateNewInventoryItem(IClientAPI remoteClient, UUID transactionID, UUID folderID, uint callbackID, string description, string name, sbyte invType, sbyte assetType, byte wearableType, uint nextOwnerMask, int creationDate) { //MainConsole.Instance.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID); if (!m_scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) return; if (transactionID == UUID.Zero) { IScenePresence presence; if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) { byte[] data = null; if (invType == (sbyte)InventoryType.Landmark && presence != null) { if (m_scene.Permissions.CanTakeLandmark(remoteClient.AgentId)) { data = BuildLandmark (presence); } else { remoteClient.SendAlertMessage("You cannot create a landmark here."); } } if(invType == (sbyte)InventoryType.LSL) { data = Encoding.ASCII.GetBytes(DefaultLSLScript); } if(invType == (sbyte)InventoryType.CallingCard) { return; } if (invType == (sbyte)InventoryType.Notecard) { data = Encoding.ASCII.GetBytes(" "); } if (invType == (sbyte)InventoryType.Gesture) { data = /*Default empty gesture*/ new byte[13] { 50, 10, 50, 53, 53, 10, 48, 10, 10, 10, 48, 10, 0 }; } AssetBase asset = new AssetBase(UUID.Random(), name, (AssetType)assetType, remoteClient.AgentId) {Data = data, Description = description}; asset.ID = m_scene.AssetService.Store(asset); CreateNewInventoryItem( remoteClient, remoteClient.AgentId.ToString(), "", folderID, name, 0, callbackID, asset, invType, (uint)PermissionMask.All, (uint)PermissionMask.All, 0, nextOwnerMask, 0, creationDate); } else { MainConsole.Instance.ErrorFormat( "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", remoteClient.AgentId); } } else { IAgentAssetTransactions agentTransactions = m_scene.RequestModuleInterface<IAgentAssetTransactions>(); if (agentTransactions != null) { agentTransactions.HandleItemCreationFromTransaction( remoteClient, transactionID, folderID, callbackID, description, name, invType, assetType, wearableType, nextOwnerMask); } } }
private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient) { lock (TerrainUploader) { remoteClient.OnXferReceive -= TerrainUploader.XferReceive; remoteClient.OnAbortXfer -= AbortTerrainXferHandler; TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; TerrainUploader = null; } remoteClient.SendAlertMessage("Terrain Upload Complete. Loading...."); ITerrainModule terr = m_scene.RequestModuleInterface<ITerrainModule>(); if (terr != null) { MainConsole.Instance.Warn("[CLIENT]: Got Request to Send Terrain in region " + m_scene.RegionInfo.RegionName); try { FileInfo x = new FileInfo(filename); if (x.Extension == ".oar") // It's an oar file { bool check = false; while (!check) { if (File.Exists(filename)) { filename = "duplicate" + filename; } else check = true; } FileStream input = new FileStream(filename, FileMode.CreateNew); input.Write(terrainData, 0, terrainData.Length); input.Close(); MainConsole.Instance.RunCommand("load oar " + filename); remoteClient.SendAlertMessage("Your oar file was loaded. It may take a few moments to appear."); } else { MemoryStream terrainStream = new MemoryStream(terrainData); terr.LoadFromStream(filename, terrainStream); terrainStream.Close(); remoteClient.SendAlertMessage("Your terrain was loaded as a ." + x.Extension + " file. It may take a few moments to appear."); } } catch (IOException e) { MainConsole.Instance.ErrorFormat( "[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e); remoteClient.SendAlertMessage( "There was an IO Exception loading your terrain. Please check free space."); return; } catch (SecurityException e) { MainConsole.Instance.ErrorFormat( "[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e); remoteClient.SendAlertMessage( "There was a security Exception loading your terrain. Please check the security on the simulator drive"); return; } catch (UnauthorizedAccessException e) { MainConsole.Instance.ErrorFormat( "[TERRAIN]: Error Saving a terrain file uploaded via the estate tools. It gave us the following error: {0}", e); remoteClient.SendAlertMessage( "There was a security Exception loading your terrain. Please check the security on the simulator drive"); return; } catch (Exception e) { MainConsole.Instance.ErrorFormat( "[TERRAIN]: Error loading a terrain file uploaded via the estate tools. It gave us the following error: {0}", e); remoteClient.SendAlertMessage( "There was a general error loading your terrain. Please fix the terrain file and try again"); } } else { remoteClient.SendAlertMessage("Unable to apply terrain. Cannot get an instance of the terrain module"); } }
public void ClassifiedInfoUpdate(UUID queryclassifiedID, uint queryCategory, string queryName, string queryDescription, UUID queryParcelID, uint queryParentEstate, UUID querySnapshotID, Vector3 queryGlobalPos, byte queryclassifiedFlags, int queryclassifiedPrice, IClientAPI remoteClient) { IScenePresence p = remoteClient.Scene.GetScenePresence(remoteClient.AgentId); if (p == null) return; //Just fail IMoneyModule money = p.Scene.RequestModuleInterface<IMoneyModule>(); if (money != null) { if (!money.Charge(remoteClient.AgentId, queryclassifiedPrice, "Add Classified")) { remoteClient.SendAlertMessage("You do not have enough money to complete this upload."); return; } } UUID creatorUUID = remoteClient.AgentId; UUID classifiedUUID = queryclassifiedID; uint category = queryCategory; string name = queryName; string description = queryDescription; uint parentestate = queryParentEstate; UUID snapshotUUID = querySnapshotID; string simname = remoteClient.Scene.RegionInfo.RegionName; Vector3 globalpos = queryGlobalPos; byte classifiedFlags = queryclassifiedFlags; int classifiedPrice = queryclassifiedPrice; UUID parceluuid = p.CurrentParcelUUID; string parcelname = "Unknown"; IParcelManagementModule parcelManagement = remoteClient.Scene.RequestModuleInterface<IParcelManagementModule>(); if (parcelManagement != null) { ILandObject parcel = parcelManagement.GetLandObject(p.AbsolutePosition.X, p.AbsolutePosition.Y); if (parcel != null) { parcelname = parcel.LandData.Name; parceluuid = parcel.LandData.InfoUUID; } } uint creationdate = (uint) Util.UnixTimeSinceEpoch(); uint expirationdate = (uint) Util.UnixTimeSinceEpoch() + (365*24*60*60); Classified classified = new Classified { ClassifiedUUID = classifiedUUID, CreatorUUID = creatorUUID, CreationDate = creationdate, ExpirationDate = expirationdate, Category = category, Name = name, Description = description, ParcelUUID = parceluuid, ParentEstate = parentestate, SnapshotUUID = snapshotUUID, SimName = simname, GlobalPos = globalpos, ParcelName = parcelname, ClassifiedFlags = classifiedFlags, PriceForListing = classifiedPrice, ScopeID = remoteClient.ScopeID }; ProfileFrontend.AddClassified(classified); }
private void OnMapNameRequest(IClientAPI remoteClient, string mapName, uint flags) { List <MapBlockData> blocks = new List <MapBlockData>(); if (mapName.Length < 3 || (mapName.EndsWith("#") && mapName.Length < 4)) { // final block, closing the search result AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); remoteClient.SendAlertMessage("Use a search string with at least 3 characters"); return; } List <GridRegion> regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); string mapNameOrig = mapName; if (regionInfos.Count == 0) { // Hack to get around the fact that ll V3 now drops the port from the // map name. See https://jira.secondlife.com/browse/VWR-28570 // // Caller, use this magic form instead: // secondlife://http|!!mygrid.com|8002|Region+Name/128/128 // or url encode if possible. // the hacks we do with this viewer... // if (mapName.Contains("|")) { mapName = mapName.Replace('|', ':'); } if (mapName.Contains("+")) { mapName = mapName.Replace('+', ' '); } if (mapName.Contains("!")) { mapName = mapName.Replace('!', '/'); } if (mapName != mapNameOrig) { regionInfos = m_scene.GridService.GetRegionsByName(m_scene.RegionInfo.ScopeID, mapName, 20); } } m_log.DebugFormat("[MAPSEARCHMODULE]: search {0} returned {1} regions. Flags={2}", mapName, regionInfos.Count, flags); if (regionInfos.Count > 0) { foreach (GridRegion info in regionInfos) { if ((flags & 2) == 2) // V2 sends this { List <MapBlockData> datas = WorldMap.Map2BlockFromGridRegion(info, flags); // ugh! V2-3 is very sensitive about the result being // exactly the same as the requested name if (regionInfos.Count == 1 && (mapName != mapNameOrig)) { datas.ForEach(d => d.Name = mapNameOrig); } blocks.AddRange(datas); } else { MapBlockData data = WorldMap.MapBlockFromGridRegion(info, flags); blocks.Add(data); } } } // final block, closing the search result AddFinalBlock(blocks); // flags are agent flags sent from the viewer. // they have different values depending on different viewers, apparently remoteClient.SendMapBlock(blocks, flags); // send extra user messages for V3 // because the UI is very confusing // while we don't fix the hard-coded urls if (flags == 2) { if (regionInfos.Count == 0) { remoteClient.SendAlertMessage("No regions found with that name."); } else if (regionInfos.Count == 1) { remoteClient.SendAlertMessage("Region found!"); } } }