OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
CallingCardModule.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 Nini.Config;
33 using OpenMetaverse;
34 using OpenSim.Framework;
35 using OpenSim.Region.Framework.Interfaces;
36 using OpenSim.Region.Framework.Scenes;
37 using OpenSim.Services.Interfaces;
38 using Mono.Addins;
40 
41 namespace OpenSim.Region.CoreModules.Avatar.Friends
42 {
43  [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "XCallingCard")]
45  {
46  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
47  protected List<Scene> m_Scenes = new List<Scene>();
48  protected bool m_Enabled = true;
49 
50  public void Initialise(IConfigSource source)
51  {
52  IConfig ccConfig = source.Configs["XCallingCard"];
53  if (ccConfig != null)
54  m_Enabled = ccConfig.GetBoolean("Enabled", true);
55  }
56 
57  public void AddRegion(Scene scene)
58  {
59  if (!m_Enabled)
60  return;
61 
62  m_Scenes.Add(scene);
63 
64  scene.RegisterModuleInterface<ICallingCardModule>(this);
65  }
66 
67  public void RemoveRegion(Scene scene)
68  {
69  if (!m_Enabled)
70  return;
71 
72  m_Scenes.Remove(scene);
73 
74  scene.EventManager.OnNewClient -= OnNewClient;
75  scene.EventManager.OnIncomingInstantMessage +=
76  OnIncomingInstantMessage;
77 
78  scene.UnregisterModuleInterface<ICallingCardModule>(this);
79  }
80 
81  public void RegionLoaded(Scene scene)
82  {
83  if (!m_Enabled)
84  return;
85  scene.EventManager.OnNewClient += OnNewClient;
86  }
87 
88  public void PostInitialise()
89  {
90  }
91 
92  public void Close()
93  {
94  }
95 
96  public Type ReplaceableInterface
97  {
98  get { return null; }
99  }
100 
101  public string Name
102  {
103  get { return "XCallingCardModule"; }
104  }
105 
106  private void OnNewClient(IClientAPI client)
107  {
108  client.OnOfferCallingCard += OnOfferCallingCard;
109  client.OnAcceptCallingCard += OnAcceptCallingCard;
110  client.OnDeclineCallingCard += OnDeclineCallingCard;
111  }
112 
113  private void OnOfferCallingCard(IClientAPI client, UUID destID, UUID transactionID)
114  {
115  ScenePresence sp = GetClientPresence(client.AgentId);
116  if (sp != null)
117  {
118  // If we're in god mode, we reverse the meaning. Offer
119  // calling card becomes "Take a calling card" for that
120  // person, no matter if they agree or not.
121  if (sp.GodLevel >= 200)
122  {
123  CreateCallingCard(client.AgentId, destID, UUID.Zero, true);
124  return;
125  }
126  }
127 
128  IClientAPI dest = FindClientObject(destID);
129  if (dest != null)
130  {
131  DoCallingCardOffer(dest, client.AgentId);
132  return;
133  }
134 
135  IMessageTransferModule transferModule =
136  m_Scenes[0].RequestModuleInterface<IMessageTransferModule>();
137 
138  if (transferModule != null)
139  {
140  transferModule.SendInstantMessage(new GridInstantMessage(
141  client.Scene, client.AgentId,
142  client.FirstName+" "+client.LastName,
143  destID, (byte)211, false,
144  String.Empty,
145  transactionID, false, new Vector3(), new byte[0], true),
146  delegate(bool success) {} );
147  }
148  }
149 
150  private void DoCallingCardOffer(IClientAPI dest, UUID from)
151  {
152  UUID itemID = CreateCallingCard(dest.AgentId, from, UUID.Zero, false);
153 
154  dest.SendOfferCallingCard(from, itemID);
155  }
156 
157  // Create a calling card in the user's inventory. This is called
158  // from direct calling card creation, when the offer is forwarded,
159  // and from the friends module when the friend is confirmed.
160  // Because of the latter, it will send a bulk inventory update
161  // if the receiving user is in the same simulator.
162  public UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID)
163  {
164  return CreateCallingCard(userID, creatorID, folderID, false);
165  }
166 
167  private UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID, bool isGod)
168  {
169  IUserAccountService userv = m_Scenes[0].UserAccountService;
170  if (userv == null)
171  return UUID.Zero;
172 
173  UserAccount info = userv.GetUserAccount(UUID.Zero, creatorID);
174  if (info == null)
175  return UUID.Zero;
176 
177  IInventoryService inv = m_Scenes[0].InventoryService;
178  if (inv == null)
179  return UUID.Zero;
180 
181  if (folderID == UUID.Zero)
182  {
183  InventoryFolderBase folder = inv.GetFolderForType(userID,
184  FolderType.CallingCard);
185 
186  if (folder == null) // Nowhere to put it
187  return UUID.Zero;
188 
189  folderID = folder.ID;
190  }
191 
192  m_log.DebugFormat("[XCALLINGCARD]: Creating calling card for {0} in inventory of {1}", info.Name, userID);
193 
195  item.AssetID = UUID.Zero;
196  item.AssetType = (int)AssetType.CallingCard;
197  item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
198  if (isGod)
199  item.BasePermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify | PermissionMask.Transfer | PermissionMask.Move);
200 
201  item.EveryOnePermissions = (uint)PermissionMask.None;
202  item.CurrentPermissions = item.BasePermissions;
203  item.NextPermissions = (uint)(PermissionMask.Copy | PermissionMask.Modify);
204 
205  item.ID = UUID.Random();
206  item.CreatorId = creatorID.ToString();
207  item.Owner = userID;
208  item.GroupID = UUID.Zero;
209  item.GroupOwned = false;
210  item.Folder = folderID;
211 
212  item.CreationDate = Util.UnixTimeSinceEpoch();
213  item.InvType = (int)InventoryType.CallingCard;
214  item.Flags = 0;
215 
216  item.Name = info.Name;
217  item.Description = "";
218 
219  item.SalePrice = 10;
220  item.SaleType = (byte)SaleType.Not;
221 
222  inv.AddItem(item);
223 
224  IClientAPI client = FindClientObject(userID);
225  if (client != null)
226  client.SendBulkUpdateInventory(item);
227 
228  return item.ID;
229  }
230 
231  private void OnAcceptCallingCard(IClientAPI client, UUID transactionID, UUID folderID)
232  {
233  }
234 
235  private void OnDeclineCallingCard(IClientAPI client, UUID transactionID)
236  {
237  IInventoryService invService = m_Scenes[0].InventoryService;
238 
239  InventoryFolderBase trashFolder =
240  invService.GetFolderForType(client.AgentId, FolderType.Trash);
241 
242  InventoryItemBase item = new InventoryItemBase(transactionID, client.AgentId);
243  item = invService.GetItem(item);
244 
245  if (item != null && trashFolder != null)
246  {
247  item.Folder = trashFolder.ID;
248  List<UUID> uuids = new List<UUID>();
249  uuids.Add(item.ID);
250  invService.DeleteItems(item.Owner, uuids);
251  m_Scenes[0].AddInventoryItem(client, item);
252  }
253  }
254 
255  public IClientAPI FindClientObject(UUID agentID)
256  {
257  Scene scene = GetClientScene(agentID);
258  if (scene == null)
259  return null;
260 
261  ScenePresence presence = scene.GetScenePresence(agentID);
262  if (presence == null)
263  return null;
264 
265  return presence.ControllingClient;
266  }
267 
268  private Scene GetClientScene(UUID agentId)
269  {
270  lock (m_Scenes)
271  {
272  foreach (Scene scene in m_Scenes)
273  {
274  ScenePresence presence = scene.GetScenePresence(agentId);
275  if (presence != null)
276  {
277  if (!presence.IsChildAgent)
278  return scene;
279  }
280  }
281  }
282  return null;
283  }
284 
285  private ScenePresence GetClientPresence(UUID agentId)
286  {
287  lock (m_Scenes)
288  {
289  foreach (Scene scene in m_Scenes)
290  {
291  ScenePresence presence = scene.GetScenePresence(agentId);
292  if (presence != null)
293  {
294  if (!presence.IsChildAgent)
295  return presence;
296  }
297  }
298  }
299  return null;
300  }
301 
302  private void OnIncomingInstantMessage(GridInstantMessage msg)
303  {
304  if (msg.dialog == (uint)211)
305  {
306  IClientAPI client = FindClientObject(new UUID(msg.toAgentID));
307  if (client == null)
308  return;
309 
310  DoCallingCardOffer(client, new UUID(msg.fromAgentID));
311  }
312  }
313  }
314 }
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
UUID CreateCallingCard(UUID userID, UUID creatorID, UUID folderID)
OpenSim.Framework.PermissionMask PermissionMask
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
Inventory Item - contains all the properties associated with an individual inventory piece...
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
Interactive OpenSim region server
Definition: OpenSim.cs:55
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void PostInitialise()
This is called exactly once after all the shared region-modules have been instanciated and IRegionMod...
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...