public void ClassifiedInfoRequest(UUID queryClassifiedID, IClientAPI remoteClient) { Hashtable ReqHash = new Hashtable(); ReqHash["classifiedID"] = queryClassifiedID.ToString(); Hashtable result = GenericXMLRPCRequest(ReqHash, "classifieds_info_query"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage( result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; if (dataArray.Count == 0) { // something bad happened here, if we could return an // event after the search, // we should be able to find it here // TODO do some (more) sensible error-handling here remoteClient.SendAgentAlertMessage("Couldn't find any classifieds.", false); return; } Hashtable d = (Hashtable)dataArray[0]; Vector3 globalPos = new Vector3(); Vector3.TryParse(d["posglobal"].ToString(), out globalPos); remoteClient.SendClassifiedInfoReply( new UUID(d["classifieduuid"].ToString()), new UUID(d["creatoruuid"].ToString()), Convert.ToUInt32(d["creationdate"]), Convert.ToUInt32(d["expirationdate"]), Convert.ToUInt32(d["category"]), d["name"].ToString(), d["description"].ToString(), new UUID(d["parceluuid"].ToString()), Convert.ToUInt32(d["parentestate"]), new UUID(d["snapshotuuid"].ToString()), d["simname"].ToString(), globalPos, d["parcelname"].ToString(), Convert.ToByte(d["classifiedflags"]), Convert.ToInt32(d["priceforlisting"])); }
public void DirClassifiedQuery(IClientAPI remoteClient, UUID queryID, string queryText, uint queryFlags, uint category, int queryStart) { Hashtable ReqHash = new Hashtable(); ReqHash["text"] = queryText; ReqHash["flags"] = queryFlags.ToString(); ReqHash["category"] = category.ToString(); ReqHash["query_start"] = queryStart.ToString(); Hashtable result = GenericXMLRPCRequest(ReqHash, "dir_classified_query"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage(result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; int count = dataArray.Count; if (count > 100) count = 101; DirClassifiedReplyData[] data = new DirClassifiedReplyData[count]; int i = 0; foreach (Object o in dataArray) { Hashtable d = (Hashtable)o; string name = d["name"].ToString(); if (Enc!=null) name = Enc.GetString(Convert.FromBase64String(name)); data[i] = new DirClassifiedReplyData(); data[i].classifiedID = new UUID(d["classifiedid"].ToString()); data[i].name = name; data[i].classifiedFlags = Convert.ToByte(d["classifiedflags"]); data[i].creationDate = Convert.ToUInt32(d["creation_date"]); data[i].expirationDate = Convert.ToUInt32(d["expiration_date"]); data[i].price = Convert.ToInt32(d["priceforlisting"]); i++; if (i >= count) break; } remoteClient.SendDirClassifiedReply(queryID, data); }
/////////////////////////////////////////////////////////////////////////////////////////////// // // Interests // // Update Interests public void AvatarInterestsUpdate(IClientAPI remoteClient, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages) { Hashtable ReqHash = new Hashtable(); ReqHash["avatar_id"] = remoteClient.AgentId.ToString(); ReqHash["WantToMask"] = wantmask.ToString(); ReqHash["WantToText"] = wanttext; ReqHash["SkillsMask"] = skillsmask.ToString(); ReqHash["SkillsText"] = skillstext; ReqHash["LanguagesText"] = languages; Hashtable result = GenericXMLRPCRequest(ReqHash, "avatar_interests_update"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage(result["errorMessage"].ToString(), false); return; } }
// Standard Profile bits public void AvatarInterestsUpdate(IClientAPI remoteClient, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages) { if (m_Debug) { m_log.DebugFormat("[{0}] AvatarInterestsUpdate for {1}", m_moduleName, remoteClient.AgentId.ToString()); } Hashtable ReqHash = new Hashtable(); ReqHash["avatar_id"] = remoteClient.AgentId.ToString(); ReqHash["wantmask"] = wantmask.ToString(); ReqHash["wanttext"] = wanttext; ReqHash["skillsmask"] = skillsmask.ToString(); ReqHash["skillstext"] = skillstext; ReqHash["languages"] = languages; Hashtable result = GenericXMLRPCRequest(ReqHash, "avatar_interests_update"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage(result["errorMessage"].ToString(), false); } }
// Picks Handler public void HandleAvatarPicksRequest(Object sender, string method, List <String> args) { if (!(sender is IClientAPI)) { return; } IClientAPI remoteClient = (IClientAPI)sender; Hashtable ReqHash = new Hashtable(); ReqHash["uuid"] = args[0]; Hashtable result = GenericXMLRPCRequest(ReqHash, method); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage( result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; Dictionary <UUID, string> picks = new Dictionary <UUID, string>(); if (dataArray != null) { foreach (Object o in dataArray) { Hashtable d = (Hashtable)o; picks[new UUID(d["pickid"].ToString())] = d["name"].ToString(); } } remoteClient.SendAvatarPicksReply(new UUID(args[0]), picks); }
/// <summary> /// Classifieds delete. /// </summary> /// <param name='queryClassifiedID'> /// Query classified I. /// </param> /// <param name='remoteClient'> /// Remote client. /// </param> public void ClassifiedDelete(UUID queryClassifiedID, IClientAPI remoteClient) { string serverURI = string.Empty; GetUserProfileServerURI(remoteClient.AgentId, out serverURI); UUID classifiedId; OSDMap parameters = new OSDMap(); UUID.TryParse(queryClassifiedID.ToString(), out classifiedId); parameters.Add("classifiedId", OSD.FromUUID(classifiedId)); OSD Params = (OSD)parameters; if (!rpc.JsonRpcRequest(ref Params, "classified_delete", serverURI, UUID.Random().ToString())) { remoteClient.SendAgentAlertMessage( "Error classified delete", false); return; } parameters = (OSDMap)Params; }
private void OnRemoveMuteListEntry(IClientAPI client, UUID MuteID, string Name) { m_log.DebugFormat("[OS MUTELIST] Got mute list removal request"); Hashtable ReqHash = new Hashtable(); ReqHash["avataruuid"] = client.AgentId.ToString(); ReqHash["muteuuid"] = MuteID.ToString(); string serverURI = String.Empty; GetUserMutelistServerURI(client.AgentId, out serverURI); Hashtable result = GenericXMLRPCRequest(ReqHash, "mutelist_remove", serverURI); if (!Convert.ToBoolean(result["success"])) { client.SendAgentAlertMessage( result["errorMessage"].ToString(), false); } }
/// <summary> /// Users the preferences request. /// </summary> /// <param name='remoteClient'> /// Remote client. /// </param> public void UserPreferencesRequest(IClientAPI remoteClient) { UserPreferences pref = new UserPreferences(); pref.UserId = remoteClient.AgentId; string serverURI = string.Empty; bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Pref = (object)pref; if (!rpc.JsonRpcRequest(ref Pref, "user_preferences_request", serverURI, UUID.Random().ToString())) { m_log.InfoFormat("[PROFILES]: UserPreferences request error"); remoteClient.SendAgentAlertMessage("Error requesting preferences", false); return; } pref = (UserPreferences)Pref; remoteClient.SendUserInfoReply(pref.IMViaEmail, pref.Visible, pref.EMail); }
private void TaskInventoryOfferAccept(IClientAPI client, Scene scene, GridInstantMessage im) { InventoryFolderBase folder = null; InventoryItemBase item = null; // The inventory item/folder, back from it's trip UUID inventoryEntityID = new UUID(im.imSessionID); // 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. CachedUserInfo userInfo = scene.CommsManager.UserService.GetUserDetails(client.AgentId); if (userInfo != null) { // Is it a folder or an item? if (userInfo.QueryItem(inventoryEntityID)) { // It's an item. item = userInfo.FindItem(inventoryEntityID); if (item == null) { client.SendAgentAlertMessage("Unable to accept received inventory: item/folder not found.", false); return; } client.SendInventoryItemCreateUpdate(item, 0); } else { // It's a folder. folder = userInfo.GetFolder(inventoryEntityID); if (folder != null) { client.SendBulkUpdateInventory(folder); // If we don't send the descendents, viewer shows "Loading..." on the trash item. userInfo.SendInventoryDecendents(client, folder.ID, false, true); } } } // RelayInventoryOfferIM(scene, im); // we don't need to notify a box that the user accepted this }
/////////////////////////////////////////////////////////////////////////////////////////////// // // Picks // // Request Picks Name public void HandleAvatarPicksRequest(Object sender, string method, List<String> args) { if (!(sender is IClientAPI)) return; IClientAPI remoteClient = (IClientAPI)sender; Hashtable ReqHash = new Hashtable(); ReqHash["uuid"] = args[0]; Hashtable result = GenericXMLRPCRequest(ReqHash, method); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage(result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; Dictionary<UUID, string> picks = new Dictionary<UUID, string>(); string uuid = ""; foreach (Object o in dataArray) { Hashtable d = (Hashtable)o; uuid = d["creatoruuid"].ToString(); string name = d["name"].ToString(); if (Enc!=null) name = Enc.GetString(Convert.FromBase64String(name)); picks[new UUID(d["pickid"].ToString())] = name; } UUID agentid; if (uuid!="") agentid = new UUID(uuid); else agentid = remoteClient.AgentId; remoteClient.SendAvatarPicksReply(agentid, picks); }
/// /// RezObject /// public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { m_log.DebugFormat("[HGScene] RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID); //if (fromTaskID.Equals(UUID.Zero)) //{ InventoryItemBase item = new InventoryItemBase(itemID); item.Owner = remoteClient.AgentId; item = m_Scene.InventoryService.GetItem(item); //if (item == null) //{ // Fetch the item // item = new InventoryItemBase(); // item.Owner = remoteClient.AgentId; // item.ID = itemID; // item = m_assMapper.Get(item, userInfo.RootFolder.ID, userInfo); //} string userAssetServer = string.Empty; if (item != null && IsForeignUser(remoteClient.AgentId, out userAssetServer)) { m_assMapper.Get(item.AssetID, remoteClient.AgentId, userAssetServer); } //} // OK, we're done fetching. Pass it up to the default RezObject SceneObjectGroup sog = base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, RezSelected, RemoveItem, fromTaskID, attachment); if (sog == null) { remoteClient.SendAgentAlertMessage("Unable to rez: problem accessing inventory or locating assets", false); } return(sog); }
public void UserPreferencesRequest(IClientAPI remoteClient) { Hashtable ReqHash = new Hashtable(); ReqHash["avatar_id"] = remoteClient.AgentId.ToString(); string serverURI = string.Empty; GetUserProfileServerURI(remoteClient.AgentId, out serverURI); Hashtable result = GenericXMLRPCRequest(ReqHash, "user_preferences_request", serverURI); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage( result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; if (dataArray != null && dataArray[0] != null) { Hashtable d = (Hashtable)dataArray[0]; string mail = ""; if (d["email"] != null) { mail = d["email"].ToString(); } remoteClient.SendUserInfoReply( Convert.ToBoolean(d["imviaemail"]), Convert.ToBoolean(d["visible"]), mail); } }
public void UpdateAvatarProperties(IClientAPI remoteClient, string AboutText, string FLAboutText, UUID FLImageID, UUID ImageID, string WebProfileURL, bool allowpublish, bool maturepublish) { // if it's the profile of the user requesting the update, then we change only a few things. Hashtable ReqHash = new Hashtable(); ReqHash["avatar_id"] = remoteClient.AgentId.ToString(); ReqHash["ProfileUrl"] = WebProfileURL; ReqHash["Image"] = ImageID.ToString(); ReqHash["AboutText"] = AboutText; ReqHash["FirstLifeImage"] = FLImageID.ToString(); ReqHash["FirstLifeAboutText"] = FLAboutText; Hashtable result = GenericXMLRPCRequest(ReqHash, "avatar_properties_update"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage( result["errorMessage"].ToString(), false); } RequestAvatarProperties(remoteClient, remoteClient.AgentId); }
/// <summary> /// Update the avatars interests . /// </summary> /// <param name='remoteClient'> /// Remote client. /// </param> /// <param name='wantmask'> /// Wantmask. /// </param> /// <param name='wanttext'> /// Wanttext. /// </param> /// <param name='skillsmask'> /// Skillsmask. /// </param> /// <param name='skillstext'> /// Skillstext. /// </param> /// <param name='languages'> /// Languages. /// </param> public void AvatarInterestsUpdate(IClientAPI remoteClient, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages) { UserProfileProperties prop = new UserProfileProperties(); prop.UserId = remoteClient.AgentId; prop.WantToMask = (int)wantmask; prop.WantToText = wanttext; prop.SkillsMask = (int)skillsmask; prop.SkillsText = skillstext; prop.Language = languages; string serverURI = string.Empty; GetUserProfileServerURI(remoteClient.AgentId, out serverURI); object Param = prop; if (!rpc.JsonRpcRequest(ref Param, "avatar_interests_update", serverURI, UUID.Random().ToString())) { remoteClient.SendAgentAlertMessage( "Error updating interests", false); } }
// Standard Profile bits public void AvatarInterestsUpdate(IClientAPI remoteClient, uint wantmask, string wanttext, uint skillsmask, string skillstext, string languages) { Hashtable ReqHash = new Hashtable(); ReqHash["avatar_id"] = remoteClient.AgentId.ToString(); ReqHash["wantmask"] = wantmask.ToString(); ReqHash["wanttext"] = wanttext; ReqHash["skillsmask"] = skillsmask.ToString(); ReqHash["skillstext"] = skillstext; ReqHash["languages"] = languages; string serverURI = string.Empty; bool foreign = GetUserProfileServerURI(remoteClient.AgentId, out serverURI); Hashtable result = GenericXMLRPCRequest(ReqHash, "avatar_interests_update", serverURI); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage( result["errorMessage"].ToString(), false); } }
/// <summary> /// Request that a client (agent) begin an asset transfer. /// </summary> /// <param name="remoteClient"></param> /// <param name="assetID"></param> /// <param name="transaction"></param> /// <param name="type"></param> /// <param name="data"></param></param> /// <param name="tempFile"></param> public void HandleUDPUploadRequest(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal, bool tempFile) { // m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile); if (((AssetType)type == AssetType.Texture || (AssetType)type == AssetType.Sound || (AssetType)type == AssetType.TextureTGA || (AssetType)type == AssetType.Animation) && tempFile == false) { Scene scene = (Scene)remoteClient.Scene; IMoneyModule mm = scene.RequestModuleInterface <IMoneyModule>(); if (mm != null) { if (!mm.UploadCovered(remoteClient, mm.UploadCharge)) { remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); return; } } } AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); AssetXferUploader uploader = transactions.RequestXferUploader(transaction); if (uploader != null) { uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); } }
// Update Picks public void PickInfoUpdate(IClientAPI remoteClient, UUID pickID, UUID creatorID, bool topPick, string name, string desc, UUID snapshotID, int sortOrder, bool enabled) { Hashtable ReqHash = new Hashtable(); ReqHash["agent_id"] = remoteClient.AgentId.ToString(); ReqHash["pick_id"] = pickID.ToString(); ReqHash["creator_id"] = creatorID.ToString(); ReqHash["top_pick"] = topPick.ToString(); ReqHash["name"] = name; ReqHash["desc"] = desc; ReqHash["snapshot_id"] = snapshotID.ToString(); ReqHash["sort_order"] = sortOrder.ToString(); ReqHash["enabled"] = enabled.ToString(); ReqHash["sim_name"] = remoteClient.Scene.RegionInfo.RegionName; ScenePresence p = FindPresence(remoteClient.AgentId); Vector3 avaPos = p.AbsolutePosition; // Getting the parceluuid for this parcel ReqHash["parcel_uuid"] = p.currentParcelUUID.ToString(); // Getting the global position for the Avatar Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.RegionLocX*Constants.RegionSize + avaPos.X, remoteClient.Scene.RegionInfo.RegionLocY*Constants.RegionSize + avaPos.Y, avaPos.Z); ReqHash["pos_global"] = posGlobal.ToString(); // Getting the owner of the parcel // Getting the description of the parcel // Do the request Hashtable result = GenericXMLRPCRequest(ReqHash, "picks_update"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage(result["errorMessage"].ToString(), false); return; } }
public void ObjectBuy(IClientAPI remoteClient, UUID agentID, UUID sessionID, UUID groupID, UUID categoryID, uint localID, byte saleType, int salePrice) { Scene s = SceneHandler.Instance.LocateSceneClientIn(remoteClient.AgentId); SceneObjectPart part = s.GetSceneObjectPart(localID); if (part == null) { remoteClient.SendAgentAlertMessage("Unable to buy now. The object can not be found.", false); return; } if (salePrice == 0) { IBuySellModule buyModule = s.RequestModuleInterface <IBuySellModule>(); if (buyModule != null) { buyModule.BuyObject(remoteClient, categoryID, localID, saleType, salePrice); } else { throw new Exception("Could not find IBuySellModule"); } } else { Dictionary <string, string> buyObject = new Dictionary <string, string>(); buyObject.Add("categoryID", categoryID.ToString()); buyObject.Add("localID", Convert.ToString(localID)); buyObject.Add("saleType", saleType.ToString()); buyObject.Add("objectUUID", part.UUID.ToString()); buyObject.Add("objectName", part.Name); buyObject.Add("objectDescription", part.Description); buyObject.Add("objectLocation", SceneHandler.Instance.GetObjectLocation(part)); DoMoneyTransfer(remoteClient.AgentId, part.OwnerID, salePrice, (int)TransactionType.BUY_OBJECT, buyObject); } }
public void UserPreferencesRequest(IClientAPI remoteClient) { if (m_Debug) { m_log.DebugFormat("[{0}] UserPreferencesRequest for {1}", m_moduleName, remoteClient.AgentId.ToString()); } Hashtable ReqHash = new Hashtable(); ReqHash["avatar_id"] = remoteClient.AgentId.ToString(); Hashtable result = GenericXMLRPCRequest(ReqHash, "user_preferences_request"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage(result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; if (dataArray != null && dataArray[0] != null) { Hashtable d = (Hashtable)dataArray[0]; string mail = ""; if (d["email"] != null) { mail = d["email"].ToString(); } remoteClient.SendUserInfoReply( Convert.ToBoolean(d["imviaemail"]), Convert.ToBoolean(d["visible"]), mail); } }
// Upfate Classifieds 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) { Hashtable ReqHash = new Hashtable(); ReqHash["creatorUUID"] = remoteClient.AgentId.ToString(); ReqHash["classifiedUUID"] = queryclassifiedID.ToString(); ReqHash["category"] = queryCategory.ToString(); ReqHash["name"] = queryName; ReqHash["description"] = queryDescription; ReqHash["parentestate"] = queryParentEstate.ToString(); ReqHash["snapshotUUID"] = querySnapshotID.ToString(); ReqHash["sim_name"] = remoteClient.Scene.RegionInfo.RegionName; ReqHash["pos_global"] = queryGlobalPos.ToString(); ReqHash["classifiedFlags"] = queryclassifiedFlags.ToString(); ReqHash["classifiedPrice"] = queryclassifiedPrice.ToString(); //ScenePresence p = FindPresence(remoteClient.AgentId); //ReqHash["parcel_uuid"] = p.currentParcelUUID.ToString(); ReqHash["parcel_uuid"] = queryParcelID.ToString(); // Getting the global position for the Avatar //Vector3 avaPos = p.AbsolutePosition; //Vector3 posGlobal = new Vector3(remoteClient.Scene.RegionInfo.RegionLocX * Constants.RegionSize + avaPos.X, // remoteClient.Scene.RegionInfo.RegionLocY * Constants.RegionSize + avaPos.Y, avaPos.Z); //ReqHash["pos_global"] = posGlobal.ToString(); Hashtable result = GenericXMLRPCRequest(ReqHash, "classified_update"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage(result["errorMessage"].ToString(), false); return; } }
private void OnInstantMessage(IClientAPI client, GridInstantMessage im) { //m_log.InfoFormat("[INVENTORY TRANSFER]: OnInstantMessage {0}", im.dialog); 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 = im.toAgentID; IScenePresence user = scene.GetScenePresence (receipientID); UUID copyID; // 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) { // 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, im.toAgentID); InventoryFolderBase folderCopy = null; ILLClientInventory inventoryModule = scene.RequestModuleInterface<ILLClientInventory> (); if (inventoryModule != null) folderCopy = inventoryModule.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); } im.imSessionID = folderID; } 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, im.toAgentID); InventoryItemBase itemCopy = null; ILLClientInventory inventoryModule = scene.RequestModuleInterface<ILLClientInventory> (); if (inventoryModule != null) itemCopy = inventoryModule.GiveInventoryItem ( im.toAgentID, im.fromAgentID, itemID, UUID.Zero); 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); } im.imSessionID = itemID; } user.ControllingClient.SendInstantMessage (im); return; } else { if (m_TransferModule != null) m_TransferModule.SendInstantMessage (im); } } else if (im.dialog == (byte) InstantMessageDialog.InventoryAccepted) { IScenePresence user = scene.GetScenePresence (im.toAgentID); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) m_TransferModule.SendInstantMessage(im); } } 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, InventoryType.Unknown, AssetType.TrashFolder); UUID inventoryID = 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); ILLClientInventory inventory = client.Scene.RequestModuleInterface<ILLClientInventory>(); if (inventory != null) inventory.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); } IScenePresence user = scene.GetScenePresence (im.toAgentID); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) m_TransferModule.SendInstantMessage(im); } } }
/// <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, primLocalID, item, copyID); m_log.InfoFormat( "[PRIM INVENTORY]: Update with item {0} requested of prim {1} for {2}", item.Name, primLocalID, remoteClient.Name); part.GetProperties(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 { IAgentAssetTransactions agentTransactions = this.RequestModuleInterface<IAgentAssetTransactions>(); if (agentTransactions != null) { agentTransactions.HandleTaskItemUpdateFromTransaction( remoteClient, part, transactionID, currentItem); if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) remoteClient.SendAgentAlertMessage("Notecard saved", false); else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) remoteClient.SendAgentAlertMessage("Script saved", false); else remoteClient.SendAgentAlertMessage("Item saved", false); } // Base ALWAYS has move currentItem.BasePermissions |= (uint)PermissionMask.Move; // 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; itemInfo.EveryonePermissions &= currentItem.BasePermissions; itemInfo.GroupPermissions &= currentItem.BasePermissions; itemInfo.CurrentPermissions &= currentItem.BasePermissions; itemInfo.NextPermissions &= currentItem.BasePermissions; } } // Next ALWAYS has move itemInfo.NextPermissions |= (uint)PermissionMask.Move; if (part.Inventory.UpdateInventoryItem(itemInfo)) { part.GetProperties(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); } }
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); }
public string NewAgentInventoryRequest(string request, UUID agentID) { OSDMap map = (OSDMap)OSDParser.DeserializeLLSDXml(request); //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit // You need to be aware of this and //if (llsdRequest.asset_type == "texture" || // llsdRequest.asset_type == "animation" || // llsdRequest.asset_type == "sound") // { IClientAPI client = null; IMoneyModule mm = m_scene.RequestModuleInterface <IMoneyModule>(); if (mm != null) { if (m_scene.TryGetClient(agentID, out client)) { if (!mm.Charge(agentID, mm.UploadCharge, "Asset upload")) { if (client != null) { client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); } map = new OSDMap(); map["rsvp"] = ""; map["state"] = "error"; return(OSDParser.SerializeLLSDXmlString(map)); } } } // } string asset_type = map["asset_type"].AsString(); string assetName = map["name"].AsString(); string assetDes = map["description"].AsString(); string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/"; string inventory_type = map["inventory_type"].AsString(); UUID newAsset = UUID.Random(); UUID newInvItem = UUID.Random(); UUID parentFolder = map["folder_id"].AsUUID(); string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/"; AssetUploader uploader = new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, inventory_type, asset_type, capsBase + uploaderPath, MainServer.Instance, agentID, this); MainServer.Instance.AddStreamHandler( new BinaryStreamHandler("POST", capsBase + uploaderPath, uploader.uploaderCaps)); string uploaderURL = m_scene.RegionInfo.ServerURI + capsBase + uploaderPath; map = new OSDMap(); map["rsvp"] = uploaderURL; map["state"] = "upload"; map["resource_cost"] = 0; map["upload_price"] = 0; return(OSDParser.SerializeLLSDXmlString(map)); }
/// /// RezObject /// public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) { m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID); //if (fromTaskID.Equals(UUID.Zero)) //{ InventoryItemBase item = new InventoryItemBase(itemID); item.Owner = remoteClient.AgentId; item = m_Scene.InventoryService.GetItem(item); //if (item == null) //{ // Fetch the item // item = new InventoryItemBase(); // item.Owner = remoteClient.AgentId; // item.ID = itemID; // item = m_assMapper.Get(item, userInfo.RootFolder.ID, userInfo); //} string userAssetServer = string.Empty; if (item != null && IsForeignUser(remoteClient.AgentId, out userAssetServer)) { m_assMapper.Get(item.AssetID, remoteClient.AgentId, userAssetServer); } //} // OK, we're done fetching. Pass it up to the default RezObject SceneObjectGroup sog = base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, RezSelected, RemoveItem, fromTaskID, attachment); if (sog == null) remoteClient.SendAgentAlertMessage("Unable to rez: problem accessing inventory or locating assets", false); return sog; }
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!! // 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)); 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!! // 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 LLSDNewFileAngentInventoryVariablePriceReplyResponse NewAgentInventoryRequest(LLSDAssetUploadRequest llsdRequest, UUID agentID) { m_log.DebugFormat("[NewFileAgentInventoryVariablePriceModule]: NewAgentInventroryRequest({0},{1})", llsdRequest.name, agentID.ToString()); //TODO: The Mesh uploader uploads many types of content. If you're going to implement a Money based limit // you need to be aware of this //if (llsdRequest.asset_type == "texture" || // llsdRequest.asset_type == "animation" || // llsdRequest.asset_type == "sound") // { // check user level ScenePresence avatar = null; IClientAPI client = null; m_scene.TryGetScenePresence(agentID, out avatar); if (avatar != null) { client = avatar.ControllingClient; if (avatar.UserLevel < m_levelUpload) { if (client != null) { client.SendAgentAlertMessage("Unable to upload asset. Insufficient permissions.", false); } LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); errorResponse.rsvp = ""; errorResponse.state = "error"; return(errorResponse); } } // check funds IMoneyModule mm = m_scene.RequestModuleInterface <IMoneyModule>(); if (mm != null) { if (!mm.UploadCovered(agentID, mm.UploadCharge)) { if (client != null) { client.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); } LLSDNewFileAngentInventoryVariablePriceReplyResponse errorResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); errorResponse.rsvp = ""; errorResponse.state = "error"; return(errorResponse); } } // } string assetName = llsdRequest.name; string assetDes = llsdRequest.description; string capsBase = "/CAPS/NewFileAgentInventoryVariablePrice/"; UUID newAsset = UUID.Random(); UUID newInvItem = UUID.Random(); UUID parentFolder = llsdRequest.folder_id; string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000") + "/"; AssetUploader uploader = new AssetUploader(assetName, assetDes, newAsset, newInvItem, parentFolder, llsdRequest.inventory_type, llsdRequest.asset_type, capsBase + uploaderPath, MainServer.Instance, m_dumpAssetsToFile); MainServer.Instance.AddStreamHandler( new BinaryStreamHandler( "POST", capsBase + uploaderPath, uploader.uploaderCaps, "NewFileAgentInventoryVariablePrice", agentID.ToString())); string protocol = "http://"; if (MainServer.Instance.UseSSL) { protocol = "https://"; } string uploaderURL = protocol + m_scene.RegionInfo.ExternalHostName + ":" + MainServer.Instance.Port.ToString() + capsBase + uploaderPath; LLSDNewFileAngentInventoryVariablePriceReplyResponse uploadResponse = new LLSDNewFileAngentInventoryVariablePriceReplyResponse(); uploadResponse.rsvp = uploaderURL; uploadResponse.state = "upload"; uploadResponse.resource_cost = 0; uploadResponse.upload_price = 0; uploader.OnUpLoad += //UploadCompleteHandler; delegate( string passetName, string passetDescription, UUID passetID, UUID pinventoryItem, UUID pparentFolder, byte[] pdata, string pinventoryType, string passetType) { UploadCompleteHandler(passetName, passetDescription, passetID, pinventoryItem, pparentFolder, pdata, pinventoryType, passetType, agentID); }; return(uploadResponse); }
/// <summary> /// Attach a scene object to an avatar. /// </summary> /// <param name="remoteClient"></param> /// <param name="objectLocalID"></param> /// <param name="AttachmentPt"></param> /// <param name="rot"></param> /// <param name="attachPos"></param> /// <param name="silent"></param> /// <returns>true if the attachment was successful, false otherwise</returns> protected internal bool AttachObject( IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) { SceneObjectGroup group = GetGroupByPrim(objectLocalID); if (group != null) { if (m_parentScene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) { // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) { attachPos = Vector3.Zero; } // AttachmentPt 0 means the client chose to 'wear' the attachment. if (AttachmentPt == 0) { // Check object for stored attachment point AttachmentPt = (uint)group.GetAttachmentPoint(); } // if we still didn't find a suitable attachment point....... if (AttachmentPt == 0) { // Stick it on left hand with Zero Offset from the attachment point. AttachmentPt = (uint)AttachmentPoint.LeftHand; attachPos = Vector3.Zero; } group.SetAttachmentPoint((byte)AttachmentPt); group.AbsolutePosition = attachPos; // Saves and gets itemID UUID itemId; if (group.GetFromItemID() == UUID.Zero) { m_parentScene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemId); } else { itemId = group.GetFromItemID(); } m_parentScene.AttachObject(remoteClient, AttachmentPt, itemId, group); group.AttachToAgent(remoteClient.AgentId, AttachmentPt, attachPos, silent); // In case it is later dropped again, don't let // it get cleaned up // group.RootPart.RemFlag(PrimFlags.TemporaryOnRez); group.HasGroupChanged = false; } else { remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false); return false; } } else { m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID); return false; } return true; }
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) {}); } } } 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) {}); } } } }
/* * // * // Already defined by osprofile * // * public void ClassifiedInfoRequest(UUID queryClassifiedID, IClientAPI remoteClient) * { * Hashtable ReqHash = new Hashtable(); * ReqHash["classifiedID"] = queryClassifiedID.ToString(); * * Hashtable result = GenericXMLRPCRequest(ReqHash, "classifieds_info_query"); * * if (!Convert.ToBoolean(result["success"])) * { * remoteClient.SendAgentAlertMessage(result["errorMessage"].ToString(), false); * return; * } * * ArrayList dataArray = (ArrayList)result["data"]; * if (dataArray.Count == 0) * { * // something bad happened here, if we could return an * // event after the search, * // we should be able to find it here * // TODO do some (more) sensible error-handling here * remoteClient.SendAgentAlertMessage("Couldn't find this classifieds.", false); * return; * } * * Hashtable d = (Hashtable)dataArray[0]; * * Vector3 globalPos = new Vector3(); * Vector3.TryParse(d["posglobal"].ToString(), out globalPos); * * if (d["name"]==null) d["name"] = String.Empty; * if (d["description"]==null) d["description"] = String.Empty; * if (d["parcelname"]==null) d["parcelname"] = String.Empty; * * string name = d["name"].ToString(); * string desc = d["description"].ToString(); * if (Enc!=null) { * name = Enc.GetString(Convert.FromBase64String(name)); * desc = Enc.GetString(Convert.FromBase64String(desc)); * } * * remoteClient.SendClassifiedInfoReply( * new UUID(d["classifieduuid"].ToString()), * new UUID(d["creatoruuid"].ToString()), * Convert.ToUInt32(d["creationdate"]), * Convert.ToUInt32(d["expirationdate"]), * Convert.ToUInt32(d["category"]), * name, * desc, * new UUID(d["parceluuid"].ToString()), * Convert.ToUInt32(d["parentestate"]), * new UUID(d["snapshotuuid"].ToString()), * d["simname"].ToString(), * globalPos, * d["parcelname"].ToString(), * Convert.ToByte(d["classifiedflags"]), * Convert.ToInt32(d["priceforlisting"])); * } */ public void HandleMapItemRequest(IClientAPI remoteClient, uint flags, uint EstateID, bool godlike, uint itemtype, ulong regionhandle) { //The following constant appears to be from GridLayerType enum //defined in OpenMetaverse/GridManager.cs of libopenmetaverse. if (itemtype == 7) //(land sales) { int tc = Environment.TickCount; Hashtable ReqHash = new Hashtable(); //m_log.Info("[OPEN SEARCH MODULE] HandleMapItemRequest Start"); //The flags are: SortAsc (1 << 15), PerMeterSort (1 << 17) ReqHash["flags"] = "163840"; ReqHash["type"] = "4294967295"; //This is -1 in 32 bits ReqHash["price"] = "0"; ReqHash["area"] = "0"; ReqHash["query_start"] = "0"; Hashtable result = GenericXMLRPCRequest(ReqHash, "dir_land_query"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage(result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; int count = dataArray.Count; if (count > 100) { count = 101; } DirLandReplyData[] Landdata = new DirLandReplyData[count]; int i = 0; string[] ParcelLandingPoint = new string[count]; string[] ParcelRegionUUID = new string[count]; foreach (Object o in dataArray) { Hashtable d = (Hashtable)o; if (d["name"] == null) { continue; } string name = d["name"].ToString(); if (Enc != null) { name = Enc.GetString(Convert.FromBase64String(name)); } Landdata[i] = new DirLandReplyData(); Landdata[i].parcelID = new UUID(d["parcel_id"].ToString()); Landdata[i].name = name; Landdata[i].auction = Convert.ToBoolean(d["auction"]); Landdata[i].forSale = Convert.ToBoolean(d["for_sale"]); Landdata[i].salePrice = Convert.ToInt32(d["sale_price"]); Landdata[i].actualArea = Convert.ToInt32(d["area"]); ParcelLandingPoint[i] = d["landing_point"].ToString(); ParcelRegionUUID[i] = d["region_UUID"].ToString(); i++; if (i >= count) { break; } } i = 0; uint locX = 0; uint locY = 0; List <mapItemReply> mapitems = new List <mapItemReply>(); foreach (DirLandReplyData landDir in Landdata) { foreach (Scene scene in m_Scenes) { if (scene.RegionInfo.RegionID.ToString() == ParcelRegionUUID[i]) { locX = scene.RegionInfo.RegionLocX; locY = scene.RegionInfo.RegionLocY; } } string[] landingpoint = ParcelLandingPoint[i].Split('/'); mapItemReply mapitem = new mapItemReply(); mapitem.x = (uint)(locX + Convert.ToDecimal(landingpoint[0])); mapitem.y = (uint)(locY + Convert.ToDecimal(landingpoint[1])); mapitem.id = landDir.parcelID; mapitem.name = landDir.name; mapitem.Extra = landDir.actualArea; mapitem.Extra2 = landDir.salePrice; mapitems.Add(mapitem); i++; } remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); mapitems.Clear(); } }
// Request Classifieds public void ClassifiedInfoRequest(UUID classifiedID, IClientAPI remoteClient) { if (m_Debug) { m_log.DebugFormat("[{0}] ClassifiedInfoRequest for AgentId {1} for {2}", m_moduleName, remoteClient.AgentId.ToString(), classifiedID.ToString()); } Hashtable ReqHash = new Hashtable(); ReqHash["avatar_id"] = remoteClient.AgentId.ToString(); ReqHash["classified_id"] = classifiedID.ToString(); Hashtable result = GenericXMLRPCRequest(ReqHash, "classifiedinforequest"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage(result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; if (dataArray.Count == 0) { if (m_Debug) { m_log.DebugFormat("[{0}] nothing returned at ClassifiedInfoRequest for AgentId {1} for {2}", m_moduleName, remoteClient.AgentId.ToString(), classifiedID.ToString()); } // something bad happened here, if we could return an // event after the search, // we should be able to find it here // TODO do some (more) sensible error-handling here return; } Hashtable d = (Hashtable)dataArray[0]; Vector3 globalPos = new Vector3(); Vector3.TryParse(d["posglobal"].ToString(), out globalPos); if (d["description"] == null) { d["description"] = String.Empty; } string name = d["name"].ToString(); string desc = d["description"].ToString(); remoteClient.SendClassifiedInfoReply(new UUID(d["classifieduuid"].ToString()), new UUID(d["creatoruuid"].ToString()), Convert.ToUInt32(d["creationdate"]), Convert.ToUInt32(d["expirationdate"]), Convert.ToUInt32(d["category"]), name, desc, new UUID(d["parceluuid"].ToString()), Convert.ToUInt32(d["parentestate"]), new UUID(d["snapshotuuid"].ToString()), d["simname"].ToString(), globalPos, d["parcelname"].ToString(), Convert.ToByte(d["classifiedflags"]), Convert.ToInt32(d["priceforlisting"])); }
public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) { Vector3 attachPos = group.AbsolutePosition; if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) { // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should // be removed when that functionality is implemented in opensim AttachmentPt &= 0x7f; // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. if (AttachmentPt != 0 && AttachmentPt != (uint)group.GetAttachmentPoint()) { attachPos = Vector3.Zero; } // AttachmentPt 0 means the client chose to 'wear' the attachment. if (AttachmentPt == 0) { // Check object for stored attachment point AttachmentPt = (uint)group.GetAttachmentPoint(); } // if we still didn't find a suitable attachment point....... if (AttachmentPt == 0) { // Stick it on left hand with Zero Offset from the attachment point. AttachmentPt = (uint)AttachmentPoint.LeftHand; attachPos = Vector3.Zero; } group.SetAttachmentPoint((byte)AttachmentPt); group.AbsolutePosition = attachPos; // Remove any previous attachments ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); UUID itemID = UUID.Zero; if (sp != null) { foreach (SceneObjectGroup grp in sp.GetAttachments(AttachmentPt)) { itemID = grp.GetFromItemID(); if (itemID != UUID.Zero) { DetachSingleAttachmentToInv(itemID, remoteClient); } } } if (group.GetFromItemID() == UUID.Zero) { m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID); } else { itemID = group.GetFromItemID(); } ShowAttachInUserInventory(remoteClient, AttachmentPt, itemID, group); AttachToAgent(sp, group, AttachmentPt, attachPos, silent); } else { remoteClient.SendAgentAlertMessage( "You don't have sufficient permissions to attach this object", false); return(false); } return(true); }
private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset) { // The viewer requires parent ID, position and rotation to be relative to the root prim. // Internally, we will continue to track parentID, offset and m_bodyRot relative to the child prim. // The following three variables with a 'v' prefix refer to the viewer-centric model. UUID vParentID; // parentID to send to viewer, always the root prim Vector3 vPos; // viewer position of avatar relative to root prim Quaternion vRot; // viewer rotation of avatar relative to root prim // We'll use the next two to update the internal avatar position and rotation. Vector3 avSitPos; Quaternion avSitRot; Vector3 cameraEyeOffset = Vector3.Zero; Vector3 cameraAtOffset = Vector3.Zero; bool forceMouselook = false; DumpDebug("SendSitResponse", "n/a"); SceneObjectPart part = null; lock (m_scene.SyncRoot) { part = FindNextAvailableSitTarget(targetID); if (part == null) { m_log.Error("[SCENE PRESENCE]: SendSitResponse could not find part " + targetID.ToString()); remoteClient.SendAgentAlertMessage("Could not sit - seat could not be found in region.", false); return; } SitTargetInfo sitInfo = part.ParentGroup.SitTargetForPart(part.UUID); // First, remove the PhysicsActor since we're going to be sitting, so that physics doesn't interfere while we're doing this update. if (PhysicsActor != null) { RemoveFromPhysicalScene(); } // Determine position to sit at based on scene geometry; don't trust offset from client // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it // The viewer requires parent ID, position and rotation to be relative to the root prim. // Internally, we will continue to track parentID, offset and m_bodyRot relative to the child prim. // The following three variables with a 'v' prefix refer to the viewer-centric model. SceneObjectPart rootPart = part.ParentGroup.RootPart; vParentID = rootPart.UUID; // parentID to send to viewer, always the root prim vPos = Vector3.Zero; // viewer position of avatar relative to root prim vRot = Quaternion.Identity; // viewer rotation of avatar relative to root prim avSitPos = Vector3.Zero; avSitRot = rootPart.RotationOffset; if (part != rootPart) { vRot *= part.RotationOffset; avSitRot *= part.RotationOffset; } // Viewer seems to draw the avatar based on the hip position. // If you don't include HipOffset (which is raising the avatar // since it's normally negative), then the viewer will draw // the avatar walking with toes underground/inside prim. // Full updates were missing this, so a rebake would reproduce it. // This adjustment gives the viewer the position it expects. vPos.Z -= m_appearance.HipOffset; if (sitInfo.IsSet) { avSitPos += sitInfo.Offset; if (ADJUST_SIT_TARGET) { // If we want to support previous IW sit target offsets, rather than SL-accurate sit targets, // we need to apply the OpenSim sit target correction adjustment. avSitPos += m_sitTargetCorrectionOffset; } avSitRot *= sitInfo.Rotation; vRot *= sitInfo.Rotation; } else { // Make up a desired facing, relative to the child prim seated on. // We'll use the prim rotation for now. // avSitPos += Vector3.Zero; // could put the avatar on top of the prim // avSitRot *= Quaternion.Identity; // could face the avatar to the side clicked on // vRot *= Quaternion.Identity; // could face the avatar to the side clicked on } #if false // I believe this is correct for root-relative storage but not for now, // while we want to maintain it relative to the parentID pointing at child prim. avSitPos += part.OffsetPosition; if (part == rootPart) avSitPos *= rootPart.RotationOffset; #endif // The only thing left to make avSitPos completely absolute would be to add rootPart.AbsolutePosition // but SetAgentPositionInfo takes that as a parameter. lock (m_posInfo) { // Update these together SetAgentPositionInfo(null, true, avSitPos, part, part.AbsolutePosition, Vector3.Zero); // now update the part to reflect the new avatar part.AddSeatedAvatar(this, true); // Now update the SP.Rotation with the sit rotation // m_bodyRot also needs the root rotation m_bodyRot = avSitRot; } cameraAtOffset = part.GetCameraAtOffset(); cameraEyeOffset = part.GetCameraEyeOffset(); forceMouselook = part.GetForceMouselook(); m_requestedSitTargetUUID = part.UUID; m_requestedSitTargetID = part.LocalId; // This calls HandleAgentSit twice, once from here, and the client calls // HandleAgentSit itself after it gets to the location // It doesn't get to the location until we've moved them there though // which happens in HandleAgentSit :P m_autopilotMoving = false; m_autoPilotTarget = offset; m_sitAtAutoTarget = false; } //we're sitting on a prim, so definitely not on the ground anymore //this should've been cleared by a previous sit request, but setting here is safe m_sittingGround = false; HandleAgentSit(remoteClient, UUID); ControllingClient.SendSitResponse(vParentID, vPos, vRot, false, cameraAtOffset, cameraEyeOffset, forceMouselook); SceneView.SendFullUpdateToAllClients(); part.ParentGroup.ScheduleGroupForFullUpdate(PrimUpdateFlags.ForcedFullUpdate);//Tell all avatars about this object, as otherwise avatars will show up at <0,0,0> on the radar if they have not seen this object before (culling) }
/// <summary> /// Attach the object to the avatar /// </summary> /// <param name="remoteClient">The client that is having the attachment done</param> /// <param name="localID">The localID (SceneObjectPart) that is being attached (for the attach script event)</param> /// <param name="group">The group (SceneObjectGroup) that is being attached</param> /// <param name="AttachmentPt">The point to where the attachment will go</param> /// <param name="item">If this is not null, it saves a query in this method to the InventoryService /// This is the Item that the object is in (if it is in one yet)</param> protected void FindAttachmentPoint (IClientAPI remoteClient, uint localID, ISceneEntity group, int AttachmentPt, InventoryItemBase item) { //Make sure that we arn't over the limit of attachments ISceneEntity[] attachments = GetAttachmentsForAvatar (remoteClient.AgentId); if (attachments.Length + 1 > m_maxNumberOfAttachments) { //Too many remoteClient.SendAgentAlertMessage( "You are wearing too many attachments. Take one off to attach this object", false); return; } Vector3 attachPos = group.GetAttachmentPos(); bool hasMultipleAttachmentsSet = (AttachmentPt & 0x7f) != 0 || AttachmentPt == 0; if(!m_allowMultipleAttachments) hasMultipleAttachmentsSet = false; AttachmentPt &= 0x7f; //Disable it! Its evil! //Did the attachment change position or attachment point? bool changedPositionPoint = false; // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. //Simplier terms: the attachment point changed, set it to the default 0,0,0 location if (AttachmentPt != 0 && AttachmentPt != (int)(group.GetAttachmentPoint() & 0x7f)) { attachPos = Vector3.Zero; changedPositionPoint = true; } else { // AttachmentPt 0 means the client chose to 'wear' the attachment. if (AttachmentPt == 0) { // Check object for stored attachment point AttachmentPt = (int)group.GetSavedAttachmentPoint() & 0x7f; attachPos = group.GetAttachmentPos(); } //Check state afterwards... use the newer GetSavedAttachmentPoint and Pos above first if (AttachmentPt == 0) { // Check object for older stored attachment point AttachmentPt = group.RootChild.Shape.State & 0x7f; //attachPos = group.AbsolutePosition; } // if we still didn't find a suitable attachment point, force it to the default //This happens on the first time an avatar 'wears' an object if (AttachmentPt == 0) { // Stick it on right hand with Zero Offset from the attachment point. AttachmentPt = (int)AttachmentPoint.RightHand; //Default location attachPos = Vector3.Zero; changedPositionPoint = true; } } group.HasGroupChanged = changedPositionPoint; //Update where we are put group.SetAttachmentPoint((byte)AttachmentPt); //Fix the position with the one we found group.AbsolutePosition = attachPos; // Remove any previous attachments IScenePresence presence = m_scene.GetScenePresence (remoteClient.AgentId); if (presence == null) return; UUID itemID = UUID.Zero; //Check for multiple attachment bits and whether we should remove the old if(!hasMultipleAttachmentsSet) { foreach (ISceneEntity grp in attachments) { if (grp.GetAttachmentPoint() == (byte)AttachmentPt) { itemID = grp.RootChild.FromUserInventoryItemID; break; } } if (itemID != UUID.Zero) DetachSingleAttachmentToInventory(itemID, remoteClient); } itemID = group.RootChild.FromUserInventoryItemID; group.RootChild.AttachedAvatar = presence.UUID; List<ISceneChildEntity> parts = group.ChildrenEntities(); for (int i = 0; i < parts.Count; i++) parts[i].AttachedAvatar = presence.UUID; if (group.RootChild.PhysActor != null) { m_scene.PhysicsScene.RemovePrim (group.RootChild.PhysActor); group.RootChild.PhysActor = null; } group.RootChild.AttachedPos = attachPos; group.RootChild.IsAttachment = true; group.AbsolutePosition = attachPos; group.RootChild.SetParentLocalId (presence.LocalId); group.SetAttachmentPoint(Convert.ToByte(AttachmentPt)); AvatarAttachments attPlugin = presence.RequestModuleInterface<AvatarAttachments>(); if (attPlugin != null) { attPlugin.AddAttachment (group); presence.AddAttachment (group); } // Killing it here will cause the client to deselect it // It then reappears on the avatar, deselected // through the full update below // if (group.IsSelected) { foreach (ISceneChildEntity part in group.ChildrenEntities()) { part.CreateSelected = true; } } //Kill the previous entity so that it will be selected SendKillEntity(group.RootChild); //NOTE: This MUST be here, otherwise we limit full updates during attachments when they are selected and it will block the first update. // So until that is changed, this MUST stay. The client will instantly reselect it, so this value doesn't stay borked for long. group.IsSelected = false; if (itemID == UUID.Zero) { //Delete the object inworld to inventory List<ISceneEntity> groups = new List<ISceneEntity> (1) { group }; IInventoryAccessModule inventoryAccess = m_scene.RequestModuleInterface<IInventoryAccessModule>(); if (inventoryAccess != null) inventoryAccess.DeleteToInventory(DeRezAction.AcquireToUserInventory, UUID.Zero, groups, remoteClient.AgentId, out itemID); } else { //it came from an item, we need to start the scripts // Fire after attach, so we don't get messy perms dialogs // 4 == AttachedRez group.CreateScriptInstances(0, true, StateSource.AttachedRez, UUID.Zero); group.ResumeScripts(); } if (UUID.Zero == itemID) { m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID."); remoteClient.SendAgentAlertMessage( "Unable to save attachment. Error inventory item ID.", false); return; } // XXYY!! if (item == null) { item = new InventoryItemBase(itemID, remoteClient.AgentId); item = m_scene.InventoryService.GetItem(item); } //Update the ItemID with the new item group.SetFromItemID (itemID); //If we updated the attachment, we need to save the change IAvatarAppearanceModule appearance = presence.RequestModuleInterface<IAvatarAppearanceModule> (); if (appearance.Appearance.SetAttachment ((int)AttachmentPt, itemID, item.AssetID)) AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); // In case it is later dropped again, don't let // it get cleaned up group.RootChild.RemFlag(PrimFlags.TemporaryOnRez); group.HasGroupChanged = false; //Now recreate it so that it is selected group.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); m_scene.EventManager.TriggerOnAttach(localID, group.RootChild.FromUserInventoryItemID, remoteClient.AgentId); }
public bool AttachObjectFromInworldObject(uint localID, IClientAPI remoteClient, ISceneEntity group, int AttachmentPt) { if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) FindAttachmentPoint(remoteClient, localID, group, AttachmentPt, null); else { remoteClient.SendAgentAlertMessage( "You don't have sufficient permissions to attach this object", false); return false; } return true; }
public void HandleAgentRequestSit(IClientAPI remoteClient, UUID agentID, UUID targetID, Vector3 offset) { if (IsChildAgent) { remoteClient.SendAgentAlertMessage("Cannot sit on an object in a different region.", false); return; } StandUp(false, true); //SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); SceneObjectPart part = FindNextAvailableSitTarget(targetID); if (part == null) { m_log.Warn("[SCENE PRESENCE]: Sit requested on unknown object: " + targetID.ToString()); return; } if (part.RegionHandle != remoteClient.Scene.RegionInfo.RegionHandle) { //m_log.InfoFormat("[SCENE PRESENCE]: Viewer requested a sit to the wrong region server: {0} {1}", remoteClient.Name, remoteClient.AgentId); remoteClient.SendAgentAlertMessage("Cannot sit on an object in a different region.", false); return; } m_nextSitAnimation = "SIT"; if (!String.IsNullOrEmpty(part.SitAnimation)) { m_nextSitAnimation = part.SitAnimation; } m_requestedSitTargetID = part.LocalId; m_requestedSitTargetUUID = part.UUID; //m_requestedSitOffset = offset; SendSitResponse(remoteClient, targetID, offset); }
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) { }); } } } }
private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", // objectLocalID, remoteClient.Name, AttachmentPt, silent); if (!Enabled) return; try { ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); if (sp == null) { m_log.ErrorFormat( "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId); return; } // If we can't take it, we can't attach it! SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID); if (part == null) return; if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) { remoteClient.SendAgentAlertMessage( "You don't have sufficient permissions to attach this object", false); return; } // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should // be removed when that functionality is implemented in opensim AttachmentPt &= 0x7f; // Calls attach with a Zero position AttachObject(sp, part.ParentGroup, AttachmentPt, false, false); } catch (Exception e) { m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace); } }
private void Lure(IClientAPI client, uint teleportflags, GridInstantMessage im) { Scene scene = (Scene)(client.Scene); GridRegion region = scene.GridService.GetRegionByUUID(scene.RegionInfo.ScopeID, new UUID(im.RegionID)); if (region != null) scene.RequestTeleportLocation(client, region.RegionHandle, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags); else // we don't have that region here. Check if it's HG { string[] parts = im.message.Split(new char[] { '@' }); if (parts.Length > 1) { string url = parts[parts.Length - 1]; // the last part if (url.Trim(new char[] {'/'}) != m_ThisGridURL.Trim(new char[] {'/'})) { m_log.DebugFormat("[HG LURE MODULE]: Luring agent to grid {0} region {1} position {2}", url, im.RegionID, im.Position); GatekeeperServiceConnector gConn = new GatekeeperServiceConnector(); GridRegion gatekeeper = new GridRegion(); gatekeeper.ServerURI = url; string homeURI = scene.GetAgentHomeURI(client.AgentId); string message; GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(im.RegionID), client.AgentId, homeURI, out message); if (finalDestination != null) { ScenePresence sp = scene.GetScenePresence(client.AgentId); IEntityTransferModule transferMod = scene.RequestModuleInterface<IEntityTransferModule>(); if (transferMod != null && sp != null) { if (message != null) sp.ControllingClient.SendAgentAlertMessage(message, true); transferMod.DoTeleport( sp, gatekeeper, finalDestination, im.Position + new Vector3(0.5f, 0.5f, 0f), Vector3.UnitX, teleportflags); } } else { m_log.InfoFormat("[HG LURE MODULE]: Lure failed: {0}", message); client.SendAgentAlertMessage(message, true); } } } } }
public void ObjectBuy(IClientAPI remoteClient, UUID agentID, UUID sessionID, UUID groupID, UUID categoryID, uint localID, byte saleType, int salePrice) { Scene s = SceneHandler.Instance.LocateSceneClientIn(remoteClient.AgentId); SceneObjectPart part = s.GetSceneObjectPart(localID); if (part == null) { remoteClient.SendAgentAlertMessage("Unable to buy now. The object can not be found.", false); return; } if (salePrice == 0) { IBuySellModule buyModule = s.RequestModuleInterface<IBuySellModule>(); if (buyModule != null) { buyModule.BuyObject(remoteClient, categoryID, localID, saleType, salePrice); } else { throw new Exception("Could not find IBuySellModule"); } } else { Dictionary<string, string> buyObject = new Dictionary<string, string>(); buyObject.Add("categoryID", categoryID.ToString()); buyObject.Add("localID", Convert.ToString(localID)); buyObject.Add("saleType", saleType.ToString()); buyObject.Add("objectUUID", part.UUID.ToString()); buyObject.Add("objectName", part.Name); buyObject.Add("objectDescription", part.Description); buyObject.Add("objectLocation", SceneHandler.Instance.GetObjectLocation(part)); DoMoneyTransfer(remoteClient.AgentId, part.OwnerID, salePrice, (int)TransactionType.BUY_OBJECT, buyObject); } }
public void ObjectBuy(IClientAPI remoteClient, UUID agentID, UUID sessionID, UUID groupID, UUID categoryID, uint localID, byte saleType, int salePrice) { if (!m_sellEnabled) { remoteClient.SendBlueBoxMessage(UUID.Zero, "", "Buying is not implemented in this version"); return; } if (salePrice != 0) { remoteClient.SendBlueBoxMessage(UUID.Zero, "", "Buying anything for a price other than zero is not implemented"); return; } Scene s = LocateSceneClientIn(remoteClient.AgentId); // Implmenting base sale data checking here so the default OpenSimulator implementation isn't useless // combined with other implementations. We're actually validating that the client is sending the data // that it should. In theory, the client should already know what to send here because it'll see it when it // gets the object data. If the data sent by the client doesn't match the object, the viewer probably has an // old idea of what the object properties are. Viewer developer Hazim informed us that the base module // didn't check the client sent data against the object do any. Since the base modules are the // 'crowning glory' examples of good practice.. // Validate that the object exists in the scene the user is in SceneObjectPart part = s.GetSceneObjectPart(localID); if (part == null) { remoteClient.SendAgentAlertMessage("Unable to buy now. The object was not found.", false); return; } // Validate that the client sent the price that the object is being sold for if (part.SalePrice != salePrice) { remoteClient.SendAgentAlertMessage("Cannot buy at this price. Buy Failed. If you continue to get this relog.", false); return; } // Validate that the client sent the proper sale type the object has set if (part.ObjectSaleType != saleType) { remoteClient.SendAgentAlertMessage("Cannot buy this way. Buy Failed. If you continue to get this relog.", false); return; } IBuySellModule module = s.RequestModuleInterface<IBuySellModule>(); if (module != null) module.BuyObject(remoteClient, categoryID, localID, saleType, salePrice); }
/// <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 UUID 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.SendAgentAlertMessage("Insufficient permissions to edit notecard", false); return UUID.Zero; } remoteClient.SendAgentAlertMessage("Notecard saved", false); } else if ((InventoryType)item.InvType == InventoryType.LSL) { if (!m_Scene.Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId)) { remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false); return UUID.Zero; } remoteClient.SendAgentAlertMessage("Script saved", false); } 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); // remoteClient.SendInventoryItemCreateUpdate(item); return (asset.FullID); } else { m_log.ErrorFormat( "[AGENT INVENTORY]: Could not find item {0} for caps inventory update", itemID); } return UUID.Zero; }
/// <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 OnInstantMessage(IClientAPI client, GridInstantMessage im) { //MainConsole.Instance.InfoFormat("[INVENTORY TRANSFER]: OnInstantMessage {0}", im.dialog); IScene clientScene = FindClientScene(client.AgentId); if (clientScene == null) // Something seriously wrong here. { MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Cannot find originating user scene"); return; } if (im.Dialog == (byte)InstantMessageDialog.InventoryOffered) { //MainConsole.Instance.DebugFormat("Asset type {0}", ((AssetType)im.binaryBucket[0])); if (im.BinaryBucket.Length < 17) // Invalid { MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Invalid length {0} for asset type {1}", im.BinaryBucket.Length, ((AssetType)im.BinaryBucket[0])); return; } UUID receipientID = im.ToAgentID; IScenePresence recipientUser = null; IScene recipientUserScene = FindClientScene(client.AgentId); if (recipientUserScene != null) { recipientUser = recipientUserScene.GetScenePresence(receipientID); } UUID copyID; // user is online now... if (recipientUser != null) { // First byte is the asset type AssetType assetType = (AssetType)im.BinaryBucket [0]; if (assetType == AssetType.Folder) { UUID folderID = new UUID(im.BinaryBucket, 1); MainConsole.Instance.DebugFormat( "[INVENTORY TRANSFER]: Inserting original folder {0} into agent {1}'s inventory", folderID, im.ToAgentID); clientScene.InventoryService.GiveInventoryFolderAsync( receipientID, client.AgentId, folderID, UUID.Zero, (folder) => { if (folder == 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 = folder.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); // m_currencyService.UserCurrencyTransfer(im.FromAgentID, im.ToAgentID, 0, // "Inworld inventory folder transfer", TransactionType.GiveInventory, UUID.Zero); if (moneyService != null) { moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0, "Inworld inventory folder transfer", TransactionType.GiveInventory); } if (recipientUser != null) { recipientUser.ControllingClient.SendBulkUpdateInventory(folder); im.SessionID = copyID; recipientUser.ControllingClient.SendInstantMessage(im); } }); } else { // First byte of the array is probably the item type // Next 16 bytes are the UUID UUID itemID = new UUID(im.BinaryBucket, 1); MainConsole.Instance.DebugFormat( "[INVENTORY TRANSFER]: (giving) Inserting item {0} into agent {1}'s inventory", itemID, im.ToAgentID); clientScene.InventoryService.GiveInventoryItemAsync( im.ToAgentID, im.FromAgentID, itemID, UUID.Zero, false, (itemCopy) => { if (itemCopy == null) { MainConsole.Instance.DebugFormat( "[INVENTORY TRANSFER]: (giving) Unable to find item {0} to give to agent {1}'s inventory", itemID, im.ToAgentID); 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 (moneyService != null) { moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0, "Inworld inventory item transfer", TransactionType.GiveInventory); } if (recipientUser != null) { recipientUser.ControllingClient.SendBulkUpdateInventory(itemCopy); im.SessionID = itemCopy.ID; recipientUser.ControllingClient.SendInstantMessage(im); } }); } } else { // recipient is offline. // Send the IM to the recipient. The item is already // in their inventory, so it will not be lost if // they are offline. // if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im); } } } else if (im.Dialog == (byte)InstantMessageDialog.InventoryAccepted) { IScenePresence user = clientScene.GetScenePresence(im.ToAgentID); MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Acceptance message received"); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im); } } } 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 = clientScene.InventoryService; MainConsole.Instance.DebugFormat("[INVENTORY TRANSFER]: Declined message received"); InventoryFolderBase trashFolder = invService.GetFolderForType(client.AgentId, InventoryType.Unknown, AssetType.TrashFolder); UUID inventoryID = im.SessionID; // The inventory item/folder, back from it's trip InventoryItemBase item = invService.GetItem(client.AgentId, inventoryID); 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> { item.ID }; invService.DeleteItems(item.Owner, uuids); ILLClientInventory inventory = client.Scene.RequestModuleInterface <ILLClientInventory>(); if (inventory != null) { inventory.AddInventoryItemAsync(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); 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); } //m_currencyService.UserCurrencyTransfer(im.FromAgentID, im.ToAgentID, 0, // "Inworld inventory transfer declined", TransactionType.GiveInventory, UUID.Zero); if (moneyService != null) { moneyService.Transfer(im.ToAgentID, im.FromAgentID, 0, "Inworld inventory transfer declined", TransactionType.GiveInventory); } IScenePresence user = clientScene.GetScenePresence(im.ToAgentID); if (user != null) // Local { user.ControllingClient.SendInstantMessage(im); } else { if (m_TransferModule != null) { m_TransferModule.SendInstantMessage(im); } } } }
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) { // getting information lined up for the query UUID avatarID = remoteClient.AgentId; UUID regionUUID = remoteClient.Scene.RegionInfo.RegionID; UUID ParcelID = UUID.Zero; uint regionX = remoteClient.Scene.RegionInfo.RegionLocX; uint regionY = remoteClient.Scene.RegionInfo.RegionLocY; // m_log.DebugFormat("[CLASSIFIED]: Got the RegionX Location as: {0}, and RegionY as: {1}", regionX.ToString(), regionY.ToString()); string regionName = remoteClient.Scene.RegionInfo.RegionName; int creationDate = Util.UnixTimeSinceEpoch(); int expirationDate = creationDate + 604800; if (queryclassifiedPrice < MIN_CLASSIFIED_PRICE) { m_log.ErrorFormat("[CLASSIFIED]: Got a request for invalid price I'z${0} on a classified from {1}.", queryclassifiedPrice.ToString(), remoteClient.AgentId.ToString()); remoteClient.SendAgentAlertMessage("Error: The minimum price for a classified advertisement is I'z$" + MIN_CLASSIFIED_PRICE.ToString() + ".", true); return; } // Check for hacked names that start with special characters if (!Char.IsLetterOrDigit(queryName, 0)) { m_log.ErrorFormat("[CLASSIFIED]: Got a hacked request from {0} for invalid name classified name: {1}", remoteClient.AgentId.ToString(), queryName); remoteClient.SendAgentAlertMessage("Error: The name of your classified must start with a letter or a number. No punctuation is allowed.", true); return; } // In case of insert, original values are the new values (by default) int origPrice = 0; using (ISimpleDB db = _connFactory.GetConnection()) { //if this is an existing classified make sure the client is the owner or don't touch it string existingCheck = "SELECT creatoruuid FROM classifieds WHERE classifieduuid = ?classifiedID"; Dictionary <string, object> checkParms = new Dictionary <string, object>(); checkParms.Add("?classifiedID", queryclassifiedID); List <Dictionary <string, string> > existingResults = db.QueryWithResults(existingCheck, checkParms); if (existingResults.Count > 0) { string existingAuthor = existingResults[0]["creatoruuid"]; if (existingAuthor != avatarID.ToString()) { m_log.ErrorFormat("[CLASSIFIED]: Got a request for from {0} to modify a classified from {1}: {2}", remoteClient.AgentId.ToString(), existingAuthor, queryclassifiedID.ToString()); remoteClient.SendAgentAlertMessage("Error: You do not have permission to modify that classified ad.", true); return; } } Dictionary <string, object> parms = new Dictionary <string, object>(); parms.Add("?avatarID", avatarID); parms.Add("?classifiedID", queryclassifiedID); parms.Add("?category", queryCategory); parms.Add("?name", queryName); parms.Add("?description", queryDescription); //parms.Add("?parcelID", queryParcelID); parms.Add("?parentEstate", queryParentEstate); parms.Add("?snapshotID", querySnapshotID); parms.Add("?globalPos", queryGlobalPos); parms.Add("?classifiedFlags", queryclassifiedFlags); parms.Add("?classifiedPrice", queryclassifiedPrice); parms.Add("?creationDate", creationDate); parms.Add("?expirationDate", expirationDate); parms.Add("?regionUUID", regionUUID); parms.Add("?regionName", regionName); // We need parcelUUID from land to place in the query properly // However, there can be multiple Parcel UUIDS per region, // so we need to do some math from the classified entry // to the positioning of the avatar // The point we have is a global position value, which means // we need to to get the location with: (GlobalX / 256) - RegionX and // (GlobalY / 256) - RegionY for the values of the avatar standign position // then compare that to the parcels for the closest match // explode the GlobalPos value off the bat string origGlobPos = queryGlobalPos.ToString(); string tempAGlobPos = origGlobPos.Replace("<", String.Empty); string tempBGlobPos = tempAGlobPos.Replace(">", String.Empty); char[] delimiterChars = { ',', ' ' }; string[] globalPosBits = tempBGlobPos.Split(delimiterChars); uint tempAvaXLoc = Convert.ToUInt32(Convert.ToDouble(globalPosBits[0])); uint tempAvaYLoc = Convert.ToUInt32(Convert.ToDouble(globalPosBits[2])); uint avaXLoc = tempAvaXLoc - (256 * regionX); uint avaYLoc = tempAvaYLoc - (256 * regionY); //uint avatarPosX = (posGlobalX / 256) - regionX; parms.Add("?avaXLoc", avaXLoc.ToString()); parms.Add("?avaYLoc", avaYLoc.ToString()); string parcelLocate = "select uuid, MIN(ABS(UserLocationX - ?avaXLoc)) as minXValue, MIN(ABS(UserLocationY - ?avaYLoc)) as minYValue from land where RegionUUID=?regionUUID GROUP BY UserLocationX ORDER BY minXValue, minYValue LIMIT 1;"; using (ISimpleDB landDb = _regionConnFactory.GetConnection()) { List <Dictionary <string, string> > parcelLocated = landDb.QueryWithResults(parcelLocate, parms); foreach (Dictionary <string, string> row in parcelLocated) { ParcelID = new UUID(row["uuid"].ToString()); } } parms.Add("?parcelID", ParcelID); string queryClassifieds = "select * from classifieds where classifieduuid=?classifiedID AND creatoruuid=?avatarID"; List <Dictionary <string, string> > results = db.QueryWithResults(queryClassifieds, parms); bool isUpdate = false; int costToApply; string transactionDesc; if (results.Count != 0) { if (results.Count != 1) { remoteClient.SendAgentAlertMessage("Classified record is not consistent. Contact Support for assistance.", false); m_log.ErrorFormat("[CLASSIFIED]: Error, query for user {0} classified ad {1} returned {2} results.", avatarID.ToString(), queryclassifiedID.ToString(), results.Count.ToString()); return; } // This is an upgrade of a classified ad. Dictionary <string, string> row = results[0]; isUpdate = true; transactionDesc = "Classified price change"; origPrice = Convert.ToInt32(row["priceforlisting"]); // Also preserve original creation date and expiry. creationDate = Convert.ToInt32(row["creationdate"]); expirationDate = Convert.ToInt32(row["expirationdate"]); costToApply = queryclassifiedPrice - origPrice; if (costToApply < 0) { costToApply = 0; } } else { // This is the initial placement of the classified. transactionDesc = "Classified charge"; creationDate = Util.UnixTimeSinceEpoch(); expirationDate = creationDate + 604800; costToApply = queryclassifiedPrice; } EventManager.ClassifiedPaymentArgs paymentArgs = new EventManager.ClassifiedPaymentArgs(remoteClient.AgentId, queryclassifiedID, origPrice, queryclassifiedPrice, transactionDesc, true); if (costToApply > 0) { // Now check whether the payment is authorized by the currency system. ((Scene)remoteClient.Scene).EventManager.TriggerClassifiedPayment(remoteClient, paymentArgs); if (!paymentArgs.mIsAuthorized) { return; // already reported to user by the check above. } } string query; if (isUpdate) { query = "UPDATE classifieds set creationdate=?creationDate, " + "category=?category, name=?name, description=?description, parceluuid=?parcelID, " + "parentestate=?parentEstate, snapshotuuid=?snapshotID, simname=?regionName, posglobal=?globalPos, parcelname=?name, " + " classifiedflags=?classifiedFlags, priceforlisting=?classifiedPrice where classifieduuid=?classifiedID"; } else { query = "INSERT into classifieds (classifieduuid, creatoruuid, creationdate, expirationdate, category, name, " + "description, parceluuid, parentestate, snapshotuuid, simname, posglobal, parcelname, classifiedflags, priceforlisting) " + "VALUES (?classifiedID, ?avatarID, ?creationDate, ?expirationDate, ?category, ?name, ?description, ?parcelID, " + "?parentEstate, ?snapshotID, ?regionName, ?globalPos, ?name, ?classifiedFlags, ?classifiedPrice)"; } db.QueryNoResults(query, parms); if (costToApply > 0) // no refunds for lower prices { // Handle the actual money transaction here. paymentArgs.mIsPreCheck = false; // now call it again but for real this time ((Scene)remoteClient.Scene).EventManager.TriggerClassifiedPayment(remoteClient, paymentArgs); // Errors reported by the payment request above. } } }
public void HandleMapItemRequest(IClientAPI remoteClient, uint flags, uint EstateID, bool godlike, uint itemtype, ulong regionhandle) { //The following constant appears to be from GridLayerType enum //defined in OpenMetaverse/GridManager.cs of libopenmetaverse. if (itemtype == (uint)OpenMetaverse.GridItemType.LandForSale) { Hashtable ReqHash = new Hashtable(); //The flags are: SortAsc (1 << 15), PerMeterSort (1 << 17) ReqHash["flags"] = "163840"; ReqHash["type"] = "4294967295"; //This is -1 in 32 bits ReqHash["price"] = "0"; ReqHash["area"] = "0"; ReqHash["query_start"] = "0"; Hashtable result = GenericXMLRPCRequest(ReqHash, "dir_land_query"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage( result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; int count = dataArray.Count; if (count > 100) { count = 101; } List <mapItemReply> mapitems = new List <mapItemReply>(); string ParcelRegionUUID; string[] landingpoint; foreach (Object o in dataArray) { Hashtable d = (Hashtable)o; if (d["name"] == null) { continue; } mapItemReply mapitem = new mapItemReply(); ParcelRegionUUID = d["region_UUID"].ToString(); foreach (Scene scene in m_Scenes) { if (scene.RegionInfo.RegionID.ToString() == ParcelRegionUUID) { landingpoint = d["landing_point"].ToString().Split('/'); mapitem.x = (uint)((scene.RegionInfo.RegionLocX * 256) + Convert.ToDecimal(landingpoint[0])); mapitem.y = (uint)((scene.RegionInfo.RegionLocY * 256) + Convert.ToDecimal(landingpoint[1])); break; } } mapitem.id = new UUID(d["parcel_id"].ToString()); mapitem.Extra = Convert.ToInt32(d["area"]); mapitem.Extra2 = Convert.ToInt32(d["sale_price"]); mapitem.name = d["name"].ToString(); mapitems.Add(mapitem); } remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); mapitems.Clear(); } if (itemtype == (uint)OpenMetaverse.GridItemType.PgEvent || itemtype == (uint)OpenMetaverse.GridItemType.MatureEvent || itemtype == (uint)OpenMetaverse.GridItemType.AdultEvent) { Hashtable ReqHash = new Hashtable(); //Find the maturity level int maturity = (1 << 24); //Find the maturity level if (itemtype == (uint)OpenMetaverse.GridItemType.MatureEvent) { maturity = (1 << 25); } else { if (itemtype == (uint)OpenMetaverse.GridItemType.AdultEvent) { maturity = (1 << 26); } } //The flags are: SortAsc (1 << 15), PerMeterSort (1 << 17) maturity |= 163840; //When character before | is a u get upcoming/in-progress events //Character before | is number of days before/after current date //Characters after | is the number for a category ReqHash["text"] = "u|0"; ReqHash["flags"] = maturity.ToString(); ReqHash["query_start"] = "0"; Hashtable result = GenericXMLRPCRequest(ReqHash, "dir_events_query"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage( result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; List <mapItemReply> mapitems = new List <mapItemReply>(); int event_id; string[] landingpoint; foreach (Object o in dataArray) { Hashtable d = (Hashtable)o; if (d["name"] == null) { continue; } mapItemReply mapitem = new mapItemReply(); //Events use a comma separator in the landing point landingpoint = d["landing_point"].ToString().Split(','); mapitem.x = Convert.ToUInt32(landingpoint[0]); mapitem.y = Convert.ToUInt32(landingpoint[1]); //This is a crazy way to pass the event ID back to the //viewer but that is the way it wants the information. event_id = Convert.ToInt32(d["event_id"]); mapitem.id = new UUID("00000000-0000-0000-0000-0000" + event_id.ToString("X8")); mapitem.Extra = Convert.ToInt32(d["unix_time"]); mapitem.Extra2 = 0; //FIXME: No idea what to do here mapitem.name = d["name"].ToString(); mapitems.Add(mapitem); } remoteClient.SendMapItemReply(mapitems.ToArray(), itemtype, flags); mapitems.Clear(); } }
/// <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 (null == part.ParentGroup) { m_log.ErrorFormat( "[PRIM INVENTORY]: " + "Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist", itemId, primId); return new ArrayList(); } // Retrieve item TaskInventoryItem item = part.Inventory.GetInventoryItem(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); // Update item with new asset item.AssetID = asset.FullID; if (part.ParentGroup.UpdateInventoryItem(item)) if(item.InvType == (int)InventoryType.LSL) remoteClient.SendAgentAlertMessage("Script saved", false); part.GetProperties(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.UpdateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0); errors = part.Inventory.GetScriptErrors(item.ItemID, DefaultScriptEngine); } else { remoteClient.SendAgentAlertMessage("Script saved", false); } part.ParentGroup.ResumeScripts(); return errors; }
private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { if (DebugLevel > 0) m_log.DebugFormat( "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", objectLocalID, remoteClient.Name, AttachmentPt, silent); if (!Enabled) return; try { ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); if (sp == null) { m_log.ErrorFormat( "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId); return; } // If we can't take it, we can't attach it! SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID); if (part == null) return; if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) { remoteClient.SendAgentAlertMessage( "You don't have sufficient permissions to attach this object", false); return; } bool append = (AttachmentPt & 0x80) != 0; AttachmentPt &= 0x7f; // Calls attach with a Zero position if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, true, append)) { if (DebugLevel > 0) m_log.Debug( "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", AttachmentPoint: " + AttachmentPt); // Save avatar attachment information m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId); } } catch (Exception e) { m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace); } }
public void DirLandQuery(IClientAPI remoteClient, UUID queryID, uint queryFlags, uint searchType, int price, int area, int queryStart) { Hashtable ReqHash = new Hashtable(); ReqHash["flags"] = queryFlags.ToString(); ReqHash["type"] = searchType.ToString(); ReqHash["price"] = price.ToString(); ReqHash["area"] = area.ToString(); ReqHash["query_start"] = queryStart.ToString(); Hashtable result = GenericXMLRPCRequest(ReqHash, "dir_land_query"); if (!Convert.ToBoolean(result["success"])) { remoteClient.SendAgentAlertMessage( result["errorMessage"].ToString(), false); return; } ArrayList dataArray = (ArrayList)result["data"]; int count = 0; /* Count entries in dataArray with valid region name to */ /* prevent allocating data array with too many entries. */ foreach (Object o in dataArray) { Hashtable d = (Hashtable)o; if (d["name"] != null) { ++count; } } if (count > 100) { count = 101; } DirLandReplyData[] data = new DirLandReplyData[count]; int i = 0; foreach (Object o in dataArray) { Hashtable d = (Hashtable)o; if (d["name"] == null) { continue; } data[i] = new DirLandReplyData(); data[i].parcelID = new UUID(d["parcel_id"].ToString()); data[i].name = d["name"].ToString(); data[i].auction = Convert.ToBoolean(d["auction"]); data[i].forSale = Convert.ToBoolean(d["for_sale"]); data[i].salePrice = Convert.ToInt32(d["sale_price"]); data[i].actualArea = Convert.ToInt32(d["area"]); if (++i >= count) { break; } } remoteClient.SendDirLandReply(queryID, data); }
public void UpdateGroupInfo(IClientAPI remoteClient, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Note: Permissions checking for modification rights is handled by the Groups Server/Service string reason = string.Empty; if (!m_groupData.UpdateGroup(GetRequestingAgentIDStr(remoteClient), groupID, charter, showInList, insigniaID, membershipFee, openEnrollment, allowPublish, maturePublish, out reason)) remoteClient.SendAgentAlertMessage(reason, false); }
public void ObjectBuy(IClientAPI remoteClient, UUID agentID, UUID sessionID, UUID groupID, UUID categoryID, uint localID, byte saleType, int salePrice) { if (salePrice < 0) return; if (salePrice > 0) { // allow users with negative balances to buy freebies int avatarFunds = getCurrentBalance(agentID); if (avatarFunds < salePrice) { // The viewer runs a check on monies balance, however, let's make sure another viewer // can't exploit this by removing and check their funds ourselves. remoteClient.SendAgentAlertMessage("Insufficient funds to purchase this item!", false); return; } } IClientAPI sourceAvatarClient = LocateClientObject(remoteClient.AgentId); if (sourceAvatarClient == null) { sourceAvatarClient.SendAgentAlertMessage("Purchase failed. No Controlling client found for sourceAvatar!", false); return; } Scene s = LocateSceneClientIn(remoteClient.AgentId); //Scene s = GetScenePresence(remoteClient.AgentId); SceneObjectPart objectPart = s.GetSceneObjectPart(localID); if (objectPart == null) { sourceAvatarClient.SendAgentAlertMessage("Purchase failed. The object was not found.", false); return; } ///// Prevent purchase spoofing, as well as viewer bugs. ///// // Verify that the object is actually for sale if (objectPart.ObjectSaleType == (byte)SaleType.Not) { remoteClient.SendAgentAlertMessage("Purchase failed. The item is not for sale.", false); return; } // Verify that the viewer sale type actually matches the correct sale type of the object if (saleType != objectPart.ObjectSaleType) { remoteClient.SendAgentAlertMessage("Purchase failed. The sale type does not match.", false); return; } // Verify that the buyer is paying the correct amount if (salePrice != objectPart.SalePrice) { remoteClient.SendAgentAlertMessage("Purchase failed. The payment price does not match the sale price.", false); return; } string objName = objectPart.ParentGroup.RootPart.Name; Vector3 pos = objectPart.AbsolutePosition; int posx = (int)(pos.X + 0.5); int posy = (int)(pos.Y + 0.5); int posz = (int)(pos.Z + 0.5); string transDesc = String.Format("{0} in {1} at <{2},{3},{4}>", objName, objectPart.ParentGroup.Scene.RegionInfo.RegionName, posx, posy, posz); string sourceAlertText = "Purchased " + objName + " for Iz$" + salePrice; string destAlertText = resolveAgentName(agentID) + " paid you Iz$" + salePrice + " via " + objName; int transType = (int)MoneyTransactionType.ObjectSale; UUID transID = UUID.Zero; TransactionInfoBlock transInfo = new TransactionInfoBlock(); transInfo.Amount = salePrice; transInfo.TransactionType = transType; transInfo.SourceID = remoteClient.AgentId; transInfo.DestID = objectPart.OwnerID; transInfo.IsSourceGroup = false; transInfo.IsDestGroup = false; transInfo.ItemDescription = Util.StringToBytes256(objName); if (agentID == objectPart.OwnerID) { // we'll let them test the buy, but nothing happens money wise. if (!s.PerformObjectBuy(remoteClient, categoryID, localID, saleType)) return; sourceAvatarClient.SendBlueBoxMessage(agentID, "", sourceAlertText); } else { if (salePrice == 0) { // We need to add a counter here for Freebies thus bypassing the DB for transactions cause // Freebies are a pain to have to track in the transaction history. if (!s.PerformObjectBuy(remoteClient, categoryID, localID, saleType)) return; } else { UUID originalOwnerID = objectPart.OwnerID; // capture the original seller's UUID for the money transfer if (!s.PerformObjectBuy(remoteClient, categoryID, localID, saleType)) // changes objectPart.OwnerID return; transID = doMoneyTransfer(remoteClient.AgentId, originalOwnerID, salePrice, transType, transDesc); } SendMoneyBalanceTransaction(sourceAvatarClient, transID, true, sourceAlertText, transInfo); } IClientAPI destAvatarClient = LocateClientObject(objectPart.OwnerID); if (destAvatarClient == null) { return; } else { SendMoneyBalanceTransaction(destAvatarClient, transID, true, destAlertText, transInfo); } }
/// <summary> /// Request that a client (agent) begin an asset transfer. /// </summary> /// <param name="remoteClient"></param> /// <param name="assetID"></param> /// <param name="transaction"></param> /// <param name="type"></param> /// <param name="data"></param></param> /// <param name="tempFile"></param> public void HandleUDPUploadRequest(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal, bool tempFile) { // m_log.Debug("HandleUDPUploadRequest - assetID: " + assetID.ToString() + " transaction: " + transaction.ToString() + " type: " + type.ToString() + " storelocal: " + storeLocal + " tempFile: " + tempFile); if (((AssetType)type == AssetType.Texture || (AssetType)type == AssetType.Sound || (AssetType)type == AssetType.TextureTGA || (AssetType)type == AssetType.Animation) && tempFile == false) { Scene scene = (Scene)remoteClient.Scene; IMoneyModule mm = scene.RequestModuleInterface<IMoneyModule>(); if (mm != null) { if (!mm.UploadCovered(remoteClient, mm.UploadCharge)) { remoteClient.SendAgentAlertMessage("Unable to upload asset. Insufficient funds.", false); return; } } } AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); AssetXferUploader uploader = transactions.RequestXferUploader(transaction); if (uploader != null) { uploader.Initialise(remoteClient, assetID, transaction, type, data, storeLocal, tempFile); } }
private void OnInstantMessage(IClientAPI remoteClient, GridInstantMessage im) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); //m_log.DebugFormat("[Groups]: IM From {0} to {1} msg {2} type {3}", im.fromAgentID, im.toAgentID, im.message, (InstantMessageDialog)im.dialog); // Group invitations if ((im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) || (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline)) { UUID inviteID = new UUID(im.imSessionID); GroupInviteInfo inviteInfo = m_groupData.GetAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID); if (inviteInfo == null) { if (m_debugEnabled) m_log.WarnFormat("[Groups]: Received an Invite IM for an invite that does not exist {0}.", inviteID); return; } //m_log.DebugFormat("[XXX]: Invite is for Agent {0} to Group {1}.", inviteInfo.AgentID, inviteInfo.GroupID); UUID fromAgentID = new UUID(im.fromAgentID); UUID invitee = UUID.Zero; string tmp = string.Empty; Util.ParseUniversalUserIdentifier(inviteInfo.AgentID, out invitee, out tmp, out tmp, out tmp, out tmp); if ((inviteInfo != null) && (fromAgentID == invitee)) { // Accept if (im.dialog == (byte)InstantMessageDialog.GroupInvitationAccept) { //m_log.DebugFormat("[XXX]: Received an accept invite notice."); // and the sessionid is the role string reason = string.Empty; if (!m_groupData.AddAgentToGroup(GetRequestingAgentIDStr(remoteClient), invitee.ToString(), inviteInfo.GroupID, inviteInfo.RoleID, string.Empty, out reason)) remoteClient.SendAgentAlertMessage("Unable to add you to the group: " + reason, false); else { GridInstantMessage msg = new GridInstantMessage(); msg.imSessionID = UUID.Zero.Guid; msg.fromAgentID = UUID.Zero.Guid; msg.toAgentID = invitee.Guid; msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); msg.fromAgentName = "Groups"; msg.message = string.Format("You have been added to the group."); msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.MessageBox; msg.fromGroup = false; msg.offline = (byte)0; msg.ParentEstateID = 0; msg.Position = Vector3.Zero; msg.RegionID = UUID.Zero.Guid; msg.binaryBucket = new byte[0]; OutgoingInstantMessage(msg, invitee); UpdateAllClientsWithGroupInfo(invitee); } m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID); } // Reject if (im.dialog == (byte)InstantMessageDialog.GroupInvitationDecline) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: Received a reject invite notice."); m_groupData.RemoveAgentToGroupInvite(GetRequestingAgentIDStr(remoteClient), inviteID); m_groupData.RemoveAgentFromGroup(GetRequestingAgentIDStr(remoteClient), inviteInfo.AgentID, inviteInfo.GroupID); } } } // Group notices if ((im.dialog == (byte)InstantMessageDialog.GroupNotice)) { if (!m_groupNoticesEnabled) { return; } UUID GroupID = new UUID(im.toAgentID); if (m_groupData.GetGroupRecord(GetRequestingAgentIDStr(remoteClient), GroupID, null) != null) { UUID NoticeID = UUID.Random(); string Subject = im.message.Substring(0, im.message.IndexOf('|')); string Message = im.message.Substring(Subject.Length + 1); InventoryItemBase item = null; bool hasAttachment = false; if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0) { hasAttachment = true; string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); binBucket = binBucket.Remove(0, 14).Trim(); OSD binBucketOSD = OSDParser.DeserializeLLSDXml(binBucket); if (binBucketOSD is OSDMap) { OSDMap binBucketMap = (OSDMap)binBucketOSD; UUID itemID = binBucketMap["item_id"].AsUUID(); UUID ownerID = binBucketMap["owner_id"].AsUUID(); item = new InventoryItemBase(itemID, ownerID); item = m_sceneList[0].InventoryService.GetItem(item); } else m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType()); } if (m_groupData.AddGroupNotice(GetRequestingAgentIDStr(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, hasAttachment, (byte)(item == null ? 0 : item.AssetType), item == null ? null : item.Name, item == null ? UUID.Zero : item.ID, item == null ? UUID.Zero.ToString() : item.Owner.ToString())) { if (OnNewGroupNotice != null) { OnNewGroupNotice(GroupID, NoticeID); } // Send notice out to everyone that wants notices foreach (GroupMembersData member in m_groupData.GetGroupMembers(GetRequestingAgentIDStr(remoteClient), GroupID)) { if (member.AcceptNotices) { // Build notice IIM, one of reach, because the sending may be async GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); msg.toAgentID = member.AgentID.Guid; OutgoingInstantMessage(msg, member.AgentID); } } } } } if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted) { if (im.binaryBucket.Length < 16) // Invalid return; //// 16 bytes are the UUID. Maybe. // UUID folderID = new UUID(im.binaryBucket, 0); UUID noticeID = new UUID(im.imSessionID); GroupNoticeInfo notice = m_groupData.GetGroupNotice(remoteClient.AgentId.ToString(), noticeID); if (notice != null) { UUID giver = new UUID(im.toAgentID); string tmp = string.Empty; Util.ParseUniversalUserIdentifier(notice.noticeData.AttachmentOwnerID, out giver, out tmp, out tmp, out tmp, out tmp); m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, giver, notice.noticeData.AttachmentItemID); if (itemCopy == null) { remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); return; } remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); } } // Interop, received special 210 code for ejecting a group member // this only works within the comms servers domain, and won't work hypergrid // TODO:FIXME: Use a presense server of some kind to find out where the // client actually is, and try contacting that region directly to notify them, // or provide the notification via xmlrpc update queue if ((im.dialog == 210)) { // This is sent from the region that the ejectee was ejected from // if it's being delivered here, then the ejectee is here // so we need to send local updates to the agent. UUID ejecteeID = new UUID(im.toAgentID); im.dialog = (byte)InstantMessageDialog.MessageFromAgent; OutgoingInstantMessage(im, ejecteeID); IClientAPI ejectee = GetActiveClient(ejecteeID); if (ejectee != null) { UUID groupID = new UUID(im.imSessionID); ejectee.SendAgentDropGroup(groupID); } } }
public void SendAlertToUser(IClientAPI client, string message, bool modal) { client.SendAgentAlertMessage(message, modal); }
public void GroupRoleUpdate(IClientAPI remoteClient, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, byte updateType) { if (m_debugEnabled) m_log.DebugFormat("[Groups]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); // Security Checks are handled in the Groups Service. switch ((OpenMetaverse.GroupRoleUpdate)updateType) { case OpenMetaverse.GroupRoleUpdate.Create: string reason = string.Empty; if (!m_groupData.AddGroupRole(GetRequestingAgentIDStr(remoteClient), groupID, UUID.Random(), name, description, title, powers, out reason)) remoteClient.SendAgentAlertMessage("Unable to create role: " + reason, false); break; case OpenMetaverse.GroupRoleUpdate.Delete: m_groupData.RemoveGroupRole(GetRequestingAgentIDStr(remoteClient), groupID, roleID); break; case OpenMetaverse.GroupRoleUpdate.UpdateAll: case OpenMetaverse.GroupRoleUpdate.UpdateData: case OpenMetaverse.GroupRoleUpdate.UpdatePowers: if (m_debugEnabled) { GroupPowers gp = (GroupPowers)powers; m_log.DebugFormat("[Groups]: Role ({0}) updated with Powers ({1}) ({2})", name, powers.ToString(), gp.ToString()); } m_groupData.UpdateGroupRole(GetRequestingAgentIDStr(remoteClient), groupID, roleID, name, description, title, powers); break; case OpenMetaverse.GroupRoleUpdate.NoUpdate: default: // No Op break; } // TODO: This update really should send out updates for everyone in the role that just got changed. SendAgentGroupDataUpdate(remoteClient, GetRequestingAgentID(remoteClient)); }
public virtual bool GetAgentInventoryItem(IClientAPI remoteClient, UUID itemID, UUID requestID) { //Attempt to just get the item with no owner, as it might be a library item InventoryItemBase assetRequestItem = GetItem(UUID.Zero, itemID); if (assetRequestItem == null) { return false; } // At this point, we need to apply perms // only to notecards and scripts. All // other asset types are always available // if (assetRequestItem.AssetType == (int) AssetType.LSLText) { if (!m_scene.Permissions.CanViewScript(itemID, UUID.Zero, remoteClient.AgentId)) { remoteClient.SendAgentAlertMessage("Insufficient permissions to view script", false); return false; } } else if (assetRequestItem.AssetType == (int) AssetType.Notecard) { if (!m_scene.Permissions.CanViewNotecard(itemID, UUID.Zero, remoteClient.AgentId)) { remoteClient.SendAgentAlertMessage("Insufficient permissions to view notecard", false); return false; } } if (assetRequestItem.AssetID != requestID) { MainConsole.Instance.WarnFormat( "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", Name, requestID, itemID, assetRequestItem.AssetID); return false; } return true; }
public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, int AttachmentPt, bool silent) { Vector3 attachPos = group.AbsolutePosition; if (m_scene.Permissions.CanTakeObject(group.UUID, remoteClient.AgentId)) { // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should // be removed when that functionality is implemented in opensim AttachmentPt &= 0x7f; // If the attachment point isn't the same as the one previously used // set it's offset position = 0 so that it appears on the attachment point // and not in a weird location somewhere unknown. if (AttachmentPt != 0 && AttachmentPt != (int)group.GetAttachmentPoint()) { attachPos = Vector3.Zero; } // AttachmentPt 0 means the client chose to 'wear' the attachment. /*if (AttachmentPt == 0) { // Check object for stored attachment point AttachmentPt = (int)group.GetAttachmentPoint(); attachPos = group.GetAttachmentPos(); }*/ if (AttachmentPt == 0) { // Check object for older stored attachment point AttachmentPt = group.RootPart.Shape.State; //attachPos = group.AbsolutePosition; } // if we still didn't find a suitable attachment point....... if (AttachmentPt == 0) { // Stick it on right hand with Zero Offset from the attachment point. AttachmentPt = (int)AttachmentPoint.RightHand; attachPos = Vector3.Zero; } group.SetAttachmentPoint((byte)AttachmentPt); group.AbsolutePosition = attachPos; // Remove any previous attachments ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); UUID itemID = UUID.Zero; if (sp != null) { foreach (SceneObjectGroup grp in sp.GetAttachments(AttachmentPt)) { itemID = grp.GetFromItemID(); if (itemID != UUID.Zero) DetachSingleAttachmentToInv(itemID, remoteClient); } } if (group.GetFromItemID() == UUID.Zero) { m_scene.attachObjectAssetStore(remoteClient, group, remoteClient.AgentId, out itemID); } else { itemID = group.GetFromItemID(); } ShowAttachInUserInventory(remoteClient, AttachmentPt, itemID, group); AttachToAgent(sp, group, AttachmentPt, attachPos, silent); } else { remoteClient.SendAgentAlertMessage( "You don't have sufficient permissions to attach this object", false); return false; } return true; }
protected void ObjectBuy(IClientAPI remoteClient, UUID sessionID, UUID groupID, UUID categoryID, uint localID, byte saleType, int salePrice) { // We're actually validating that the client is sending the data // that it should. In theory, the client should already know what to send here because it'll see it when it // gets the object data. If the data sent by the client doesn't match the object, the viewer probably has an // old idea of what the object properties are. Viewer developer Hazim informed us that the base module // didn't check the client sent data against the object do any. Since the base modules are the // 'crowning glory' examples of good practice.. ISceneChildEntity part = ((Scene)remoteClient.Scene).GetSceneObjectPart (localID); if (part == null) { remoteClient.SendAgentAlertMessage("Unable to buy now. The object was not found.", false); return; } // Validate that the client sent the price that the object is being sold for if (part.SalePrice != salePrice) { remoteClient.SendAgentAlertMessage("Cannot buy at this price. Buy Failed. If you continue to get this relog.", false); return; } // Validate that the client sent the proper sale type the object has set if (part.ObjectSaleType != saleType) { remoteClient.SendAgentAlertMessage("Cannot buy this way. Buy Failed. If you continue to get this relog.", false); return; } IMoneyModule moneyMod = remoteClient.Scene.RequestModuleInterface<IMoneyModule>(); if (moneyMod != null) { if (!moneyMod.Transfer(part.OwnerID, remoteClient.AgentId, part.ParentUUID, UUID.Zero, part.SalePrice, "Object Purchase", TransactionType.ObjectPay)) { remoteClient.SendAgentAlertMessage("You do not have enough money to buy this object.", false); return; } } BuyObject(remoteClient, categoryID, localID, saleType, salePrice); }
/// <summary> /// The god has requested that we update something in the region configs /// </summary> /// <param name="client"></param> /// <param name="BillableFactor"></param> /// <param name="PricePerMeter"></param> /// <param name="EstateID"></param> /// <param name="RegionFlags"></param> /// <param name="SimName"></param> /// <param name="RedirectX"></param> /// <param name="RedirectY"></param> public void GodUpdateRegionInfoUpdate(IClientAPI client, float BillableFactor, int PricePerMeter, ulong EstateID, ulong RegionFlags, byte[] SimName, int RedirectX, int RedirectY) { //Check god perms if (!((Scene)client.Scene).Permissions.IsGod(client.AgentId)) { return; } //Update their current region with new information string oldRegionName = client.Scene.RegionInfo.RegionName; client.Scene.RegionInfo.RegionName = Utils.BytesToString(SimName); //Set the region loc X and Y if (RedirectX != 0) { client.Scene.RegionInfo.RegionLocX = RedirectX * (int)Constants.RegionSize; } if (RedirectY != 0) { client.Scene.RegionInfo.RegionLocY = RedirectY * (int)Constants.RegionSize; } //Update the estate ID if (client.Scene.RegionInfo.EstateSettings.EstateID != EstateID) { //If they are changing estates, we have to ask them for the password to the estate, so send them an llTextBox string Password = ""; IWorldComm comm = client.Scene.RequestModuleInterface <IWorldComm>(); IDialogModule dialog = client.Scene.RequestModuleInterface <IDialogModule>(); //If the comms module is not null, we send the user a text box on a random channel so that they cannot be tapped into if (comm != null && dialog != null) { int Channel = new Random().Next(1000, 100000); //Block the channel so NOONE can access it until the question is answered comm.AddBlockedChannel(Channel); ChannelDirectory.Add(client.AgentId, new EstateChange() { Channel = Channel, EstateID = (uint)EstateID, OldEstateID = ((Scene)client.Scene).RegionInfo.EstateSettings.EstateID }); //Set the ID temperarily, if it doesn't work, we will revert it later ((Scene)client.Scene).RegionInfo.EstateSettings.EstateID = (uint)EstateID; client.OnChatFromClient += OnChatFromClient; dialog.SendTextBoxToUser(client.AgentId, "Please type the password for the estate you wish to join. (Note: this channel is secured and will not be able to be listened in on)", Channel, "Server", UUID.Zero, UUID.Zero); } else { bool changed = DataManager.DataManager.RequestPlugin <IEstateConnector>().LinkRegion(((Scene)client.Scene).RegionInfo.RegionID, (int)EstateID, Util.Md5Hash(Password)); if (!changed) { client.SendAgentAlertMessage("Unable to connect to the given estate.", false); } else { client.Scene.RegionInfo.EstateSettings.EstateID = (uint)EstateID; client.Scene.RegionInfo.EstateSettings.Save(); } } } //Set the other settings client.Scene.RegionInfo.EstateSettings.BillableFactor = BillableFactor; client.Scene.RegionInfo.EstateSettings.PricePerMeter = PricePerMeter; client.Scene.RegionInfo.EstateSettings.SetFromFlags(RegionFlags); client.Scene.RegionInfo.RegionSettings.AllowDamage = ((RegionFlags & (ulong)OpenMetaverse.RegionFlags.AllowDamage) == (ulong)OpenMetaverse.RegionFlags.AllowDamage); client.Scene.RegionInfo.RegionSettings.FixedSun = ((RegionFlags & (ulong)OpenMetaverse.RegionFlags.SunFixed) == (ulong)OpenMetaverse.RegionFlags.SunFixed); client.Scene.RegionInfo.RegionSettings.BlockTerraform = ((RegionFlags & (ulong)OpenMetaverse.RegionFlags.BlockTerraform) == (ulong)OpenMetaverse.RegionFlags.BlockTerraform); client.Scene.RegionInfo.RegionSettings.Sandbox = ((RegionFlags & (ulong)OpenMetaverse.RegionFlags.Sandbox) == (ulong)OpenMetaverse.RegionFlags.Sandbox); //Update skipping scripts/physics/collisions IEstateModule mod = client.Scene.RequestModuleInterface <IEstateModule>(); if (mod != null) { mod.SetSceneCoreDebug(((RegionFlags & (ulong)OpenMetaverse.RegionFlags.SkipScripts) == (ulong)OpenMetaverse.RegionFlags.SkipScripts), ((RegionFlags & (ulong)OpenMetaverse.RegionFlags.SkipCollisions) == (ulong)OpenMetaverse.RegionFlags.SkipCollisions), ((RegionFlags & (ulong)OpenMetaverse.RegionFlags.SkipPhysics) == (ulong)OpenMetaverse.RegionFlags.SkipPhysics)); } //Save the changes client.Scene.RegionInfo.EstateSettings.Save(); client.Scene.RegionInfo.RegionSettings.Save(); //Save the changes IConfig config = m_config.Configs["RegionStartup"]; if (config != null) { //TERRIBLE! Needs to be modular, but we can't access the module from a scene module! if (config.GetString("Default") == "RegionLoaderDataBaseSystem") { SaveChangesDatabase(client.Scene.RegionInfo); } else { SaveChangesFile(oldRegionName, client.Scene.RegionInfo); } } else { SaveChangesFile(oldRegionName, client.Scene.RegionInfo); } //Tell the clients to update all references to the new settings foreach (IScenePresence sp in client.Scene.GetScenePresences()) { HandleRegionInfoRequest(sp.ControllingClient, ((Scene)client.Scene)); } //Update the grid server as well IGridRegisterModule gridRegisterModule = client.Scene.RequestModuleInterface <IGridRegisterModule>(); if (gridRegisterModule != null) { gridRegisterModule.UpdateGridRegion(client.Scene); } }