OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
BuySellModule.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31 using log4net;
32 using Mono.Addins;
33 using Nini.Config;
34 using OpenMetaverse;
35 using OpenMetaverse.Packets;
36 using OpenSim.Framework;
37 using OpenSim.Region.Framework;
38 using OpenSim.Region.Framework.Interfaces;
39 using OpenSim.Region.Framework.Scenes;
40 using OpenSim.Region.Framework.Scenes.Serialization;
42 
43 namespace OpenSim.Region.CoreModules.World.Objects.BuySell
44 {
45  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "BuySellModule")]
47  {
48 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 
50  protected Scene m_scene = null;
52 
53  public string Name { get { return "Object BuySell Module"; } }
54  public Type ReplaceableInterface { get { return null; } }
55 
56  public void Initialise(IConfigSource source) {}
57 
58  public void AddRegion(Scene scene)
59  {
60  m_scene = scene;
61  m_scene.RegisterModuleInterface<IBuySellModule>(this);
62  m_scene.EventManager.OnNewClient += SubscribeToClientEvents;
63  }
64 
65  public void RemoveRegion(Scene scene)
66  {
67  m_scene.EventManager.OnNewClient -= SubscribeToClientEvents;
68  }
69 
70  public void RegionLoaded(Scene scene)
71  {
72  m_dialogModule = scene.RequestModuleInterface<IDialogModule>();
73  }
74 
75  public void Close()
76  {
77  RemoveRegion(m_scene);
78  }
79 
80  public void SubscribeToClientEvents(IClientAPI client)
81  {
82  client.OnObjectSaleInfo += ObjectSaleInfo;
83  }
84 
85  protected void ObjectSaleInfo(
86  IClientAPI client, UUID agentID, UUID sessionID, uint localID, byte saleType, int salePrice)
87  {
88  SceneObjectPart part = m_scene.GetSceneObjectPart(localID);
89  if (part == null)
90  return;
91 
92  if (part.ParentGroup.IsDeleted)
93  return;
94 
95  if (part.OwnerID != client.AgentId && (!m_scene.Permissions.IsGod(client.AgentId)))
96  return;
97 
98  part = part.ParentGroup.RootPart;
99 
100  part.ObjectSaleType = saleType;
101  part.SalePrice = salePrice;
102 
103  part.ParentGroup.HasGroupChanged = true;
104 
105  part.SendPropertiesToClient(client);
106  }
107 
108  public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice)
109  {
110  SceneObjectPart part = m_scene.GetSceneObjectPart(localID);
111 
112  if (part == null)
113  return false;
114 
115  SceneObjectGroup group = part.ParentGroup;
116 
117  switch (saleType)
118  {
119  case 1: // Sell as original (in-place sale)
120  uint effectivePerms = group.GetEffectivePermissions();
121 
122  if ((effectivePerms & (uint)PermissionMask.Transfer) == 0)
123  {
124  if (m_dialogModule != null)
125  m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale");
126  return false;
127  }
128 
129  group.SetOwnerId(remoteClient.AgentId);
130  group.SetRootPartOwner(part, remoteClient.AgentId, remoteClient.ActiveGroupId);
131 
132  if (m_scene.Permissions.PropagatePermissions())
133  {
134  foreach (SceneObjectPart child in group.Parts)
135  {
136  child.Inventory.ChangeInventoryOwner(remoteClient.AgentId);
137  child.TriggerScriptChangedEvent(Changed.OWNER);
138  child.ApplyNextOwnerPermissions();
139  }
140  }
141 
142  part.ObjectSaleType = 0;
143  part.SalePrice = 10;
144  part.ClickAction = Convert.ToByte(0);
145 
146  group.HasGroupChanged = true;
147  part.SendPropertiesToClient(remoteClient);
148  part.TriggerScriptChangedEvent(Changed.OWNER);
149  group.ResumeScripts();
150  part.ScheduleFullUpdate();
151 
152  break;
153 
154  case 2: // Sell a copy
155  Vector3 inventoryStoredPosition = new Vector3(
156  Math.Min(group.AbsolutePosition.X, m_scene.RegionInfo.RegionSizeX - 6),
157  Math.Min(group.AbsolutePosition.Y, m_scene.RegionInfo.RegionSizeY - 6),
158  group.AbsolutePosition.Z);
159 
160  Vector3 originalPosition = group.AbsolutePosition;
161 
162  group.AbsolutePosition = inventoryStoredPosition;
163 
164  string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(group);
165  group.AbsolutePosition = originalPosition;
166 
167  uint perms = group.GetEffectivePermissions();
168 
169  if ((perms & (uint)PermissionMask.Transfer) == 0)
170  {
171  if (m_dialogModule != null)
172  m_dialogModule.SendAlertToUser(remoteClient, "This item doesn't appear to be for sale");
173  return false;
174  }
175 
176  if ((perms & (uint)PermissionMask.Copy) == 0)
177  {
178  if (m_dialogModule != null)
179  m_dialogModule.SendAlertToUser(remoteClient, "This sale has been blocked by the permissions system");
180  return false;
181  }
182 
183  AssetBase asset = m_scene.CreateAsset(
184  group.GetPartName(localID),
185  group.GetPartDescription(localID),
186  (sbyte)AssetType.Object,
187  Utils.StringToBytes(sceneObjectXml),
188  group.OwnerID);
189  m_scene.AssetService.Store(asset);
190 
192  item.CreatorId = part.CreatorID.ToString();
193  item.CreatorData = part.CreatorData;
194 
195  item.ID = UUID.Random();
196  item.Owner = remoteClient.AgentId;
197  item.AssetID = asset.FullID;
198  item.Description = asset.Description;
199  item.Name = asset.Name;
200  item.AssetType = asset.Type;
201  item.InvType = (int)InventoryType.Object;
202  item.Folder = categoryID;
203 
204  PermissionsUtil.ApplyFoldedPermissions(perms, ref perms);
205 
206  item.BasePermissions = perms & part.NextOwnerMask;
207  item.CurrentPermissions = perms & part.NextOwnerMask;
208  item.NextPermissions = part.NextOwnerMask;
209  item.EveryOnePermissions = part.EveryoneMask &
210  part.NextOwnerMask;
211  item.GroupPermissions = part.GroupMask &
212  part.NextOwnerMask;
213  item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm;
214  item.CreationDate = Util.UnixTimeSinceEpoch();
215 
216  if (m_scene.AddInventoryItem(item))
217  {
218  remoteClient.SendInventoryItemCreateUpdate(item, 0);
219  }
220  else
221  {
222  if (m_dialogModule != null)
223  m_dialogModule.SendAlertToUser(remoteClient, "Cannot buy now. Your inventory is unavailable");
224  return false;
225  }
226  break;
227 
228  case 3: // Sell contents
229  List<UUID> invList = part.Inventory.GetInventoryList();
230 
231  bool okToSell = true;
232 
233  foreach (UUID invID in invList)
234  {
235  TaskInventoryItem item1 = part.Inventory.GetInventoryItem(invID);
236  if ((item1.CurrentPermissions &
237  (uint)PermissionMask.Transfer) == 0)
238  {
239  okToSell = false;
240  break;
241  }
242  }
243 
244  if (!okToSell)
245  {
246  if (m_dialogModule != null)
247  m_dialogModule.SendAlertToUser(
248  remoteClient, "This item's inventory doesn't appear to be for sale");
249  return false;
250  }
251 
252  if (invList.Count > 0)
253  m_scene.MoveTaskInventoryItems(remoteClient.AgentId, part.Name, part, invList);
254  break;
255  }
256 
257  return true;
258  }
259  }
260 }
delegate void ObjectSaleInfo(IClientAPI remoteClient, UUID agentID, UUID sessionID, uint localID, byte saleType, int salePrice)
OpenSim.Server.Handlers.Simulation.Utils Utils
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
Represents an item in a task inventory
bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice)
Try to buy an object
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
bool IsDeleted
Signals whether this entity was in a scene but has since been removed from it.
Definition: EntityBase.cs:73
Asset class. All Assets are reference by this class or a class derived from this class ...
Definition: AssetBase.cs:49
OpenSim.Framework.PermissionMask PermissionMask
Inventory Item - contains all the properties associated with an individual inventory piece...
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
Interactive OpenSim region server
Definition: OpenSim.cs:55
void ObjectSaleInfo(IClientAPI client, UUID agentID, UUID sessionID, uint localID, byte saleType, int salePrice)
override Vector3 AbsolutePosition
The absolute position of this scene object in the scene
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...