diff options
author | Adam Frisby | 2008-04-30 21:16:36 +0000 |
---|---|---|
committer | Adam Frisby | 2008-04-30 21:16:36 +0000 |
commit | f5c312bc3c2567449c7268a54a08a54119f58d53 (patch) | |
tree | 424668a4bbec6873ebc5b8256f3671db102f5e9c /OpenSim/Region/Environment/Modules/Avatar | |
parent | * Adds the AuthbuyerID field to sqlite and makes use of it. (diff) | |
download | opensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.zip opensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.gz opensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.bz2 opensim-SC_OLD-f5c312bc3c2567449c7268a54a08a54119f58d53.tar.xz |
* Refactored Environment/Modules directory - modules now reside in their own directory with any associated module-specific classes.
* Each module directory is currently inside one of the following category folders: Agent (Anything relating to do with Client<->Server communications.), Avatar (Anything to do with the avatar or presence inworld), Framework (Classes modules can use), Grid (Grid traffic, new OGS2 grid comms), Scripting (Scripting functions, etc), World (The enrivonment/scene, IE Sun/Tree modules.)
* This should be moved into a seperate project file.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs (renamed from OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs) | 676 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs (renamed from OpenSim/Region/Environment/Modules/ChatModule.cs) | 1662 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs (renamed from OpenSim/Region/Environment/Modules/BetaGridLikeMoneyModule.cs) | 2981 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs (renamed from OpenSim/Region/Environment/Modules/FriendsModule.cs) | 1008 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/Groups/GroupsModule.cs (renamed from OpenSim/Region/Environment/Modules/GroupsModule.cs) | 556 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs (renamed from OpenSim/Region/Environment/Modules/InstantMessageModule.cs) | 316 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryModule.cs (renamed from OpenSim/Region/Environment/Modules/InventoryModule.cs) | 432 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/Profiles/AvatarProfilesModule.cs (renamed from OpenSim/Region/Environment/Modules/AvatarProfilesModule.cs) | 258 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs (renamed from OpenSim/Region/Environment/Modules/AsteriskVoiceModule.cs) | 570 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Modules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs (renamed from OpenSim/Region/Environment/Modules/VoiceModule.cs) | 394 |
10 files changed, 4426 insertions, 4427 deletions
diff --git a/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs b/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs index cb94021..3614686 100644 --- a/OpenSim/Region/Environment/Modules/AvatarFactoryModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -1,338 +1,338 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | /* | 28 | /* |
29 | using System; | 29 | using System; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Threading; | 31 | using System.Threading; |
32 | using libsecondlife; | 32 | using libsecondlife; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications.Cache; | 35 | using OpenSim.Framework.Communications.Cache; |
36 | using OpenSim.Data.MySQLMapper; | 36 | using OpenSim.Data.MySQLMapper; |
37 | using OpenSim.Region.Environment.Interfaces; | 37 | using OpenSim.Region.Environment.Interfaces; |
38 | using OpenSim.Region.Environment.Scenes; | 38 | using OpenSim.Region.Environment.Scenes; |
39 | using OpenSim.Data.Base; | 39 | using OpenSim.Data.Base; |
40 | 40 | ||
41 | namespace OpenSim.Region.Environment.Modules | 41 | namespace OpenSim.Region.Environment.Modules |
42 | { | 42 | { |
43 | public class AvatarFactoryModule : IAvatarFactory | 43 | public class AvatarFactoryModule : IAvatarFactory |
44 | { | 44 | { |
45 | private Scene m_scene = null; | 45 | private Scene m_scene = null; |
46 | private readonly Dictionary<LLUUID, AvatarAppearance> m_avatarsAppearance = new Dictionary<LLUUID, AvatarAppearance>(); | 46 | private readonly Dictionary<LLUUID, AvatarAppearance> m_avatarsAppearance = new Dictionary<LLUUID, AvatarAppearance>(); |
47 | 47 | ||
48 | private bool m_enablePersist = false; | 48 | private bool m_enablePersist = false; |
49 | private string m_connectionString; | 49 | private string m_connectionString; |
50 | private bool m_configured = false; | 50 | private bool m_configured = false; |
51 | private BaseDatabaseConnector m_databaseMapper; | 51 | private BaseDatabaseConnector m_databaseMapper; |
52 | private AppearanceTableMapper m_appearanceMapper; | 52 | private AppearanceTableMapper m_appearanceMapper; |
53 | 53 | ||
54 | private Dictionary<LLUUID, EventWaitHandle> m_fetchesInProgress = new Dictionary<LLUUID, EventWaitHandle>(); | 54 | private Dictionary<LLUUID, EventWaitHandle> m_fetchesInProgress = new Dictionary<LLUUID, EventWaitHandle>(); |
55 | private object m_syncLock = new object(); | 55 | private object m_syncLock = new object(); |
56 | 56 | ||
57 | public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance) | 57 | public bool TryGetAvatarAppearance(LLUUID avatarId, out AvatarAppearance appearance) |
58 | { | 58 | { |
59 | 59 | ||
60 | //should only let one thread at a time do this part | 60 | //should only let one thread at a time do this part |
61 | EventWaitHandle waitHandle = null; | 61 | EventWaitHandle waitHandle = null; |
62 | bool fetchInProgress = false; | 62 | bool fetchInProgress = false; |
63 | lock (m_syncLock) | 63 | lock (m_syncLock) |
64 | { | 64 | { |
65 | appearance = CheckCache(avatarId); | 65 | appearance = CheckCache(avatarId); |
66 | if (appearance != null) | 66 | if (appearance != null) |
67 | { | 67 | { |
68 | return true; | 68 | return true; |
69 | } | 69 | } |
70 | 70 | ||
71 | //not in cache so check to see if another thread is already fetching it | 71 | //not in cache so check to see if another thread is already fetching it |
72 | if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle)) | 72 | if (m_fetchesInProgress.TryGetValue(avatarId, out waitHandle)) |
73 | { | 73 | { |
74 | fetchInProgress = true; | 74 | fetchInProgress = true; |
75 | } | 75 | } |
76 | else | 76 | else |
77 | { | 77 | { |
78 | fetchInProgress = false; | 78 | fetchInProgress = false; |
79 | 79 | ||
80 | //no thread already fetching this appearance, so add a wait handle to list | 80 | //no thread already fetching this appearance, so add a wait handle to list |
81 | //for any following threads that want the same appearance | 81 | //for any following threads that want the same appearance |
82 | waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); | 82 | waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); |
83 | m_fetchesInProgress.Add(avatarId, waitHandle); | 83 | m_fetchesInProgress.Add(avatarId, waitHandle); |
84 | } | 84 | } |
85 | } | 85 | } |
86 | 86 | ||
87 | if (fetchInProgress) | 87 | if (fetchInProgress) |
88 | { | 88 | { |
89 | waitHandle.WaitOne(); | 89 | waitHandle.WaitOne(); |
90 | appearance = CheckCache(avatarId); | 90 | appearance = CheckCache(avatarId); |
91 | if (appearance != null) | 91 | if (appearance != null) |
92 | { | 92 | { |
93 | waitHandle = null; | 93 | waitHandle = null; |
94 | return true; | 94 | return true; |
95 | } | 95 | } |
96 | else | 96 | else |
97 | { | 97 | { |
98 | waitHandle = null; | 98 | waitHandle = null; |
99 | return false; | 99 | return false; |
100 | } | 100 | } |
101 | } | 101 | } |
102 | else | 102 | else |
103 | { | 103 | { |
104 | Thread.Sleep(5000); | 104 | Thread.Sleep(5000); |
105 | 105 | ||
106 | //this is the first thread to request this appearance | 106 | //this is the first thread to request this appearance |
107 | //so let it check the db and if not found then create a default appearance | 107 | //so let it check the db and if not found then create a default appearance |
108 | //and add that to the cache | 108 | //and add that to the cache |
109 | appearance = CheckDatabase(avatarId); | 109 | appearance = CheckDatabase(avatarId); |
110 | if (appearance != null) | 110 | if (appearance != null) |
111 | { | 111 | { |
112 | //appearance has now been added to cache so lets pulse any waiting threads | 112 | //appearance has now been added to cache so lets pulse any waiting threads |
113 | lock (m_syncLock) | 113 | lock (m_syncLock) |
114 | { | 114 | { |
115 | m_fetchesInProgress.Remove(avatarId); | 115 | m_fetchesInProgress.Remove(avatarId); |
116 | waitHandle.Set(); | 116 | waitHandle.Set(); |
117 | } | 117 | } |
118 | // waitHandle.Close(); | 118 | // waitHandle.Close(); |
119 | waitHandle = null; | 119 | waitHandle = null; |
120 | return true; | 120 | return true; |
121 | } | 121 | } |
122 | 122 | ||
123 | //not found a appearance for the user, so create a new default one | 123 | //not found a appearance for the user, so create a new default one |
124 | appearance = CreateDefault(avatarId); | 124 | appearance = CreateDefault(avatarId); |
125 | if (appearance != null) | 125 | if (appearance != null) |
126 | { | 126 | { |
127 | //update database | 127 | //update database |
128 | if (m_enablePersist) | 128 | if (m_enablePersist) |
129 | { | 129 | { |
130 | m_appearanceMapper.Add(avatarId.UUID, appearance); | 130 | m_appearanceMapper.Add(avatarId.UUID, appearance); |
131 | } | 131 | } |
132 | 132 | ||
133 | //add appearance to dictionary cache | 133 | //add appearance to dictionary cache |
134 | lock (m_avatarsAppearance) | 134 | lock (m_avatarsAppearance) |
135 | { | 135 | { |
136 | m_avatarsAppearance[avatarId] = appearance; | 136 | m_avatarsAppearance[avatarId] = appearance; |
137 | } | 137 | } |
138 | 138 | ||
139 | //appearance has now been added to cache so lets pulse any waiting threads | 139 | //appearance has now been added to cache so lets pulse any waiting threads |
140 | lock (m_syncLock) | 140 | lock (m_syncLock) |
141 | { | 141 | { |
142 | m_fetchesInProgress.Remove(avatarId); | 142 | m_fetchesInProgress.Remove(avatarId); |
143 | waitHandle.Set(); | 143 | waitHandle.Set(); |
144 | } | 144 | } |
145 | // waitHandle.Close(); | 145 | // waitHandle.Close(); |
146 | waitHandle = null; | 146 | waitHandle = null; |
147 | return true; | 147 | return true; |
148 | } | 148 | } |
149 | else | 149 | else |
150 | { | 150 | { |
151 | //something went wrong, so release the wait handle and remove it | 151 | //something went wrong, so release the wait handle and remove it |
152 | //all waiting threads will fail to find cached appearance | 152 | //all waiting threads will fail to find cached appearance |
153 | //but its better for them to fail than wait for ever | 153 | //but its better for them to fail than wait for ever |
154 | lock (m_syncLock) | 154 | lock (m_syncLock) |
155 | { | 155 | { |
156 | m_fetchesInProgress.Remove(avatarId); | 156 | m_fetchesInProgress.Remove(avatarId); |
157 | waitHandle.Set(); | 157 | waitHandle.Set(); |
158 | } | 158 | } |
159 | //waitHandle.Close(); | 159 | //waitHandle.Close(); |
160 | waitHandle = null; | 160 | waitHandle = null; |
161 | return false; | 161 | return false; |
162 | } | 162 | } |
163 | } | 163 | } |
164 | } | 164 | } |
165 | 165 | ||
166 | private AvatarAppearance CreateDefault(LLUUID avatarId) | 166 | private AvatarAppearance CreateDefault(LLUUID avatarId) |
167 | { | 167 | { |
168 | AvatarAppearance appearance = null; | 168 | AvatarAppearance appearance = null; |
169 | AvatarWearable[] wearables; | 169 | AvatarWearable[] wearables; |
170 | byte[] visualParams; | 170 | byte[] visualParams; |
171 | GetDefaultAvatarAppearance(out wearables, out visualParams); | 171 | GetDefaultAvatarAppearance(out wearables, out visualParams); |
172 | appearance = new AvatarAppearance(avatarId, wearables, visualParams); | 172 | appearance = new AvatarAppearance(avatarId, wearables, visualParams); |
173 | 173 | ||
174 | return appearance; | 174 | return appearance; |
175 | } | 175 | } |
176 | 176 | ||
177 | private AvatarAppearance CheckDatabase(LLUUID avatarId) | 177 | private AvatarAppearance CheckDatabase(LLUUID avatarId) |
178 | { | 178 | { |
179 | AvatarAppearance appearance = null; | 179 | AvatarAppearance appearance = null; |
180 | if (m_enablePersist) | 180 | if (m_enablePersist) |
181 | { | 181 | { |
182 | if (m_appearanceMapper.TryGetValue(avatarId.UUID, out appearance)) | 182 | if (m_appearanceMapper.TryGetValue(avatarId.UUID, out appearance)) |
183 | { | 183 | { |
184 | appearance.VisualParams = GetDefaultVisualParams(); | 184 | appearance.VisualParams = GetDefaultVisualParams(); |
185 | appearance.TextureEntry = AvatarAppearance.GetDefaultTextureEntry(); | 185 | appearance.TextureEntry = AvatarAppearance.GetDefaultTextureEntry(); |
186 | lock (m_avatarsAppearance) | 186 | lock (m_avatarsAppearance) |
187 | { | 187 | { |
188 | m_avatarsAppearance[avatarId] = appearance; | 188 | m_avatarsAppearance[avatarId] = appearance; |
189 | } | 189 | } |
190 | } | 190 | } |
191 | } | 191 | } |
192 | return appearance; | 192 | return appearance; |
193 | } | 193 | } |
194 | 194 | ||
195 | private AvatarAppearance CheckCache(LLUUID avatarId) | 195 | private AvatarAppearance CheckCache(LLUUID avatarId) |
196 | { | 196 | { |
197 | AvatarAppearance appearance = null; | 197 | AvatarAppearance appearance = null; |
198 | lock (m_avatarsAppearance) | 198 | lock (m_avatarsAppearance) |
199 | { | 199 | { |
200 | if (m_avatarsAppearance.ContainsKey(avatarId)) | 200 | if (m_avatarsAppearance.ContainsKey(avatarId)) |
201 | { | 201 | { |
202 | appearance = m_avatarsAppearance[avatarId]; | 202 | appearance = m_avatarsAppearance[avatarId]; |
203 | } | 203 | } |
204 | } | 204 | } |
205 | return appearance; | 205 | return appearance; |
206 | } | 206 | } |
207 | 207 | ||
208 | public void Initialise(Scene scene, IConfigSource source) | 208 | public void Initialise(Scene scene, IConfigSource source) |
209 | { | 209 | { |
210 | scene.RegisterModuleInterface<IAvatarFactory>(this); | 210 | scene.RegisterModuleInterface<IAvatarFactory>(this); |
211 | scene.EventManager.OnNewClient += NewClient; | 211 | scene.EventManager.OnNewClient += NewClient; |
212 | 212 | ||
213 | if (m_scene == null) | 213 | if (m_scene == null) |
214 | { | 214 | { |
215 | m_scene = scene; | 215 | m_scene = scene; |
216 | } | 216 | } |
217 | 217 | ||
218 | if (!m_configured) | 218 | if (!m_configured) |
219 | { | 219 | { |
220 | m_configured = true; | 220 | m_configured = true; |
221 | try | 221 | try |
222 | { | 222 | { |
223 | m_enablePersist = source.Configs["Startup"].GetBoolean("appearance_persist", false); | 223 | m_enablePersist = source.Configs["Startup"].GetBoolean("appearance_persist", false); |
224 | m_connectionString = source.Configs["Startup"].GetString("appearance_connection_string", ""); | 224 | m_connectionString = source.Configs["Startup"].GetString("appearance_connection_string", ""); |
225 | } | 225 | } |
226 | catch (Exception) | 226 | catch (Exception) |
227 | { | 227 | { |
228 | } | 228 | } |
229 | if (m_enablePersist) | 229 | if (m_enablePersist) |
230 | { | 230 | { |
231 | m_databaseMapper = new MySQLDatabaseMapper(m_connectionString); | 231 | m_databaseMapper = new MySQLDatabaseMapper(m_connectionString); |
232 | m_appearanceMapper = new AppearanceTableMapper(m_databaseMapper, "AvatarAppearance"); | 232 | m_appearanceMapper = new AppearanceTableMapper(m_databaseMapper, "AvatarAppearance"); |
233 | } | 233 | } |
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
237 | public void PostInitialise() | 237 | public void PostInitialise() |
238 | { | 238 | { |
239 | } | 239 | } |
240 | 240 | ||
241 | public void Close() | 241 | public void Close() |
242 | { | 242 | { |
243 | } | 243 | } |
244 | 244 | ||
245 | public string Name | 245 | public string Name |
246 | { | 246 | { |
247 | get { return "Default Avatar Factory"; } | 247 | get { return "Default Avatar Factory"; } |
248 | } | 248 | } |
249 | 249 | ||
250 | public bool IsSharedModule | 250 | public bool IsSharedModule |
251 | { | 251 | { |
252 | get { return true; } | 252 | get { return true; } |
253 | } | 253 | } |
254 | 254 | ||
255 | public void NewClient(IClientAPI client) | 255 | public void NewClient(IClientAPI client) |
256 | { | 256 | { |
257 | client.OnAvatarNowWearing += AvatarIsWearing; | 257 | client.OnAvatarNowWearing += AvatarIsWearing; |
258 | } | 258 | } |
259 | 259 | ||
260 | public void RemoveClient(IClientAPI client) | 260 | public void RemoveClient(IClientAPI client) |
261 | { | 261 | { |
262 | // client.OnAvatarNowWearing -= AvatarIsWearing; | 262 | // client.OnAvatarNowWearing -= AvatarIsWearing; |
263 | } | 263 | } |
264 | 264 | ||
265 | public void AvatarIsWearing(Object sender, AvatarWearingArgs e) | 265 | public void AvatarIsWearing(Object sender, AvatarWearingArgs e) |
266 | { | 266 | { |
267 | IClientAPI clientView = (IClientAPI)sender; | 267 | IClientAPI clientView = (IClientAPI)sender; |
268 | CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(clientView.AgentId); | 268 | CachedUserInfo profile = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(clientView.AgentId); |
269 | if (profile != null) | 269 | if (profile != null) |
270 | { | 270 | { |
271 | if (profile.RootFolder != null) | 271 | if (profile.RootFolder != null) |
272 | { | 272 | { |
273 | if (m_avatarsAppearance.ContainsKey(clientView.AgentId)) | 273 | if (m_avatarsAppearance.ContainsKey(clientView.AgentId)) |
274 | { | 274 | { |
275 | AvatarAppearance avatAppearance = null; | 275 | AvatarAppearance avatAppearance = null; |
276 | lock (m_avatarsAppearance) | 276 | lock (m_avatarsAppearance) |
277 | { | 277 | { |
278 | avatAppearance = m_avatarsAppearance[clientView.AgentId]; | 278 | avatAppearance = m_avatarsAppearance[clientView.AgentId]; |
279 | } | 279 | } |
280 | 280 | ||
281 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) | 281 | foreach (AvatarWearingArgs.Wearable wear in e.NowWearing) |
282 | { | 282 | { |
283 | if (wear.Type < 13) | 283 | if (wear.Type < 13) |
284 | { | 284 | { |
285 | if (wear.ItemID == LLUUID.Zero) | 285 | if (wear.ItemID == LLUUID.Zero) |
286 | { | 286 | { |
287 | avatAppearance.Wearables[wear.Type].ItemID = LLUUID.Zero; | 287 | avatAppearance.Wearables[wear.Type].ItemID = LLUUID.Zero; |
288 | avatAppearance.Wearables[wear.Type].AssetID = LLUUID.Zero; | 288 | avatAppearance.Wearables[wear.Type].AssetID = LLUUID.Zero; |
289 | 289 | ||
290 | UpdateDatabase(clientView.AgentId, avatAppearance); | 290 | UpdateDatabase(clientView.AgentId, avatAppearance); |
291 | } | 291 | } |
292 | else | 292 | else |
293 | { | 293 | { |
294 | LLUUID assetId; | 294 | LLUUID assetId; |
295 | 295 | ||
296 | InventoryItemBase baseItem = profile.RootFolder.HasItem(wear.ItemID); | 296 | InventoryItemBase baseItem = profile.RootFolder.HasItem(wear.ItemID); |
297 | if (baseItem != null) | 297 | if (baseItem != null) |
298 | { | 298 | { |
299 | assetId = baseItem.assetID; | 299 | assetId = baseItem.assetID; |
300 | avatAppearance.Wearables[wear.Type].AssetID = assetId; | 300 | avatAppearance.Wearables[wear.Type].AssetID = assetId; |
301 | avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID; | 301 | avatAppearance.Wearables[wear.Type].ItemID = wear.ItemID; |
302 | 302 | ||
303 | UpdateDatabase(clientView.AgentId, avatAppearance); | 303 | UpdateDatabase(clientView.AgentId, avatAppearance); |
304 | } | 304 | } |
305 | } | 305 | } |
306 | } | 306 | } |
307 | } | 307 | } |
308 | } | 308 | } |
309 | } | 309 | } |
310 | } | 310 | } |
311 | } | 311 | } |
312 | 312 | ||
313 | public void UpdateDatabase(LLUUID userID, AvatarAppearance avatAppearance) | 313 | public void UpdateDatabase(LLUUID userID, AvatarAppearance avatAppearance) |
314 | { | 314 | { |
315 | if (m_enablePersist) | 315 | if (m_enablePersist) |
316 | { | 316 | { |
317 | m_appearanceMapper.Update(userID.UUID, avatAppearance); | 317 | m_appearanceMapper.Update(userID.UUID, avatAppearance); |
318 | } | 318 | } |
319 | } | 319 | } |
320 | 320 | ||
321 | public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams) | 321 | public static void GetDefaultAvatarAppearance(out AvatarWearable[] wearables, out byte[] visualParams) |
322 | { | 322 | { |
323 | visualParams = GetDefaultVisualParams(); | 323 | visualParams = GetDefaultVisualParams(); |
324 | wearables = AvatarWearable.DefaultWearables; | 324 | wearables = AvatarWearable.DefaultWearables; |
325 | } | 325 | } |
326 | 326 | ||
327 | private static byte[] GetDefaultVisualParams() | 327 | private static byte[] GetDefaultVisualParams() |
328 | { | 328 | { |
329 | byte[] visualParams; | 329 | byte[] visualParams; |
330 | visualParams = new byte[218]; | 330 | visualParams = new byte[218]; |
331 | for (int i = 0; i < 218; i++) | 331 | for (int i = 0; i < 218; i++) |
332 | { | 332 | { |
333 | visualParams[i] = 100; | 333 | visualParams[i] = 100; |
334 | } | 334 | } |
335 | return visualParams; | 335 | return visualParams; |
336 | } | 336 | } |
337 | } | 337 | } |
338 | }*/ | 338 | }*/ |
diff --git a/OpenSim/Region/Environment/Modules/ChatModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs index 30c1397..1281873 100644 --- a/OpenSim/Region/Environment/Modules/ChatModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Chat/ChatModule.cs | |||
@@ -1,831 +1,831 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.IO; | 30 | using System.IO; |
31 | using System.Net.Sockets; | 31 | using System.Net.Sockets; |
32 | using System.Reflection; | 32 | using System.Reflection; |
33 | using System.Text.RegularExpressions; | 33 | using System.Text.RegularExpressions; |
34 | using System.Threading; | 34 | using System.Threading; |
35 | using libsecondlife; | 35 | using libsecondlife; |
36 | using log4net; | 36 | using log4net; |
37 | using Nini.Config; | 37 | using Nini.Config; |
38 | using OpenSim.Framework; | 38 | using OpenSim.Framework; |
39 | using OpenSim.Region.Environment.Interfaces; | 39 | using OpenSim.Region.Environment.Interfaces; |
40 | using OpenSim.Region.Environment.Scenes; | 40 | using OpenSim.Region.Environment.Scenes; |
41 | 41 | ||
42 | namespace OpenSim.Region.Environment.Modules | 42 | namespace OpenSim.Region.Environment.Modules.Avatar.Chat |
43 | { | 43 | { |
44 | public class ChatModule : IRegionModule, ISimChat | 44 | public class ChatModule : IRegionModule, ISimChat |
45 | { | 45 | { |
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
47 | 47 | ||
48 | private List<Scene> m_scenes = new List<Scene>(); | 48 | private List<Scene> m_scenes = new List<Scene>(); |
49 | 49 | ||
50 | private int m_whisperdistance = 10; | 50 | private int m_whisperdistance = 10; |
51 | private int m_saydistance = 30; | 51 | private int m_saydistance = 30; |
52 | private int m_shoutdistance = 100; | 52 | private int m_shoutdistance = 100; |
53 | 53 | ||
54 | private IRCChatModule m_irc = null; | 54 | private IRCChatModule m_irc = null; |
55 | 55 | ||
56 | private string m_last_new_user = null; | 56 | private string m_last_new_user = null; |
57 | private string m_last_leaving_user = null; | 57 | private string m_last_leaving_user = null; |
58 | private string m_defaultzone = null; | 58 | private string m_defaultzone = null; |
59 | internal object m_syncInit = new object(); | 59 | internal object m_syncInit = new object(); |
60 | internal object m_syncLogout = new object(); | 60 | internal object m_syncLogout = new object(); |
61 | private Thread m_irc_connector=null; | 61 | private Thread m_irc_connector=null; |
62 | 62 | ||
63 | public void Initialise(Scene scene, IConfigSource config) | 63 | public void Initialise(Scene scene, IConfigSource config) |
64 | { | 64 | { |
65 | lock (m_syncInit) | 65 | lock (m_syncInit) |
66 | { | 66 | { |
67 | if (!m_scenes.Contains(scene)) | 67 | if (!m_scenes.Contains(scene)) |
68 | { | 68 | { |
69 | m_scenes.Add(scene); | 69 | m_scenes.Add(scene); |
70 | scene.EventManager.OnNewClient += NewClient; | 70 | scene.EventManager.OnNewClient += NewClient; |
71 | scene.RegisterModuleInterface<ISimChat>(this); | 71 | scene.RegisterModuleInterface<ISimChat>(this); |
72 | } | 72 | } |
73 | 73 | ||
74 | // wrap this in a try block so that defaults will work if | 74 | // wrap this in a try block so that defaults will work if |
75 | // the config file doesn't specify otherwise. | 75 | // the config file doesn't specify otherwise. |
76 | try | 76 | try |
77 | { | 77 | { |
78 | m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); | 78 | m_whisperdistance = config.Configs["Chat"].GetInt("whisper_distance", m_whisperdistance); |
79 | m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); | 79 | m_saydistance = config.Configs["Chat"].GetInt("say_distance", m_saydistance); |
80 | m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); | 80 | m_shoutdistance = config.Configs["Chat"].GetInt("shout_distance", m_shoutdistance); |
81 | } | 81 | } |
82 | catch (Exception) | 82 | catch (Exception) |
83 | { | 83 | { |
84 | } | 84 | } |
85 | 85 | ||
86 | try | 86 | try |
87 | { | 87 | { |
88 | m_defaultzone = config.Configs["IRC"].GetString("nick","Sim"); | 88 | m_defaultzone = config.Configs["IRC"].GetString("nick","Sim"); |
89 | } | 89 | } |
90 | catch (Exception) | 90 | catch (Exception) |
91 | { | 91 | { |
92 | } | 92 | } |
93 | 93 | ||
94 | // setup IRC Relay | 94 | // setup IRC Relay |
95 | if (m_irc == null) { m_irc = new IRCChatModule(config); } | 95 | if (m_irc == null) { m_irc = new IRCChatModule(config); } |
96 | if (m_irc_connector == null) | 96 | if (m_irc_connector == null) |
97 | { | 97 | { |
98 | m_irc_connector = new Thread(IRCConnectRun); | 98 | m_irc_connector = new Thread(IRCConnectRun); |
99 | m_irc_connector.Name = "IRCConnectorThread"; | 99 | m_irc_connector.Name = "IRCConnectorThread"; |
100 | m_irc_connector.IsBackground = true; | 100 | m_irc_connector.IsBackground = true; |
101 | } | 101 | } |
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | public void PostInitialise() | 105 | public void PostInitialise() |
106 | { | 106 | { |
107 | if (m_irc.Enabled) | 107 | if (m_irc.Enabled) |
108 | { | 108 | { |
109 | try | 109 | try |
110 | { | 110 | { |
111 | //m_irc.Connect(m_scenes); | 111 | //m_irc.Connect(m_scenes); |
112 | if (m_irc_connector == null) | 112 | if (m_irc_connector == null) |
113 | { | 113 | { |
114 | m_irc_connector = new Thread(IRCConnectRun); | 114 | m_irc_connector = new Thread(IRCConnectRun); |
115 | m_irc_connector.Name = "IRCConnectorThread"; | 115 | m_irc_connector.Name = "IRCConnectorThread"; |
116 | m_irc_connector.IsBackground = true; | 116 | m_irc_connector.IsBackground = true; |
117 | } | 117 | } |
118 | if (!m_irc_connector.IsAlive) | 118 | if (!m_irc_connector.IsAlive) |
119 | { | 119 | { |
120 | m_irc_connector.Start(); | 120 | m_irc_connector.Start(); |
121 | ThreadTracker.Add(m_irc_connector); | 121 | ThreadTracker.Add(m_irc_connector); |
122 | } | 122 | } |
123 | } | 123 | } |
124 | catch (Exception) | 124 | catch (Exception) |
125 | { | 125 | { |
126 | } | 126 | } |
127 | } | 127 | } |
128 | } | 128 | } |
129 | 129 | ||
130 | public void Close() | 130 | public void Close() |
131 | { | 131 | { |
132 | m_irc.Close(); | 132 | m_irc.Close(); |
133 | } | 133 | } |
134 | 134 | ||
135 | public string Name | 135 | public string Name |
136 | { | 136 | { |
137 | get { return "ChatModule"; } | 137 | get { return "ChatModule"; } |
138 | } | 138 | } |
139 | 139 | ||
140 | public bool IsSharedModule | 140 | public bool IsSharedModule |
141 | { | 141 | { |
142 | get { return true; } | 142 | get { return true; } |
143 | } | 143 | } |
144 | 144 | ||
145 | public void NewClient(IClientAPI client) | 145 | public void NewClient(IClientAPI client) |
146 | { | 146 | { |
147 | try | 147 | try |
148 | { | 148 | { |
149 | client.OnChatFromViewer += SimChat; | 149 | client.OnChatFromViewer += SimChat; |
150 | 150 | ||
151 | if ((m_irc.Enabled) && (m_irc.Connected)) | 151 | if ((m_irc.Enabled) && (m_irc.Connected)) |
152 | { | 152 | { |
153 | string clientName = client.FirstName + " " + client.LastName; | 153 | string clientName = client.FirstName + " " + client.LastName; |
154 | // handles simple case. May not work for hundred connecting in per second. | 154 | // handles simple case. May not work for hundred connecting in per second. |
155 | // and the NewClients calles getting interleved | 155 | // and the NewClients calles getting interleved |
156 | // but filters out multiple reports | 156 | // but filters out multiple reports |
157 | if (clientName != m_last_new_user) | 157 | if (clientName != m_last_new_user) |
158 | { | 158 | { |
159 | m_last_new_user = clientName; | 159 | m_last_new_user = clientName; |
160 | string clientRegion = FindClientRegion(client.FirstName, client.LastName); | 160 | string clientRegion = FindClientRegion(client.FirstName, client.LastName); |
161 | m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in "+clientRegion); | 161 | m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " in "+clientRegion); |
162 | } | 162 | } |
163 | } | 163 | } |
164 | client.OnLogout += ClientLoggedOut; | 164 | client.OnLogout += ClientLoggedOut; |
165 | client.OnConnectionClosed += ClientLoggedOut; | 165 | client.OnConnectionClosed += ClientLoggedOut; |
166 | client.OnLogout += ClientLoggedOut; | 166 | client.OnLogout += ClientLoggedOut; |
167 | } | 167 | } |
168 | catch (Exception ex) | 168 | catch (Exception ex) |
169 | { | 169 | { |
170 | m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString()); | 170 | m_log.Error("[IRC]: NewClient exception trap:" + ex.ToString()); |
171 | } | 171 | } |
172 | } | 172 | } |
173 | 173 | ||
174 | public void ClientLoggedOut(IClientAPI client) | 174 | public void ClientLoggedOut(IClientAPI client) |
175 | { | 175 | { |
176 | lock (m_syncLogout) | 176 | lock (m_syncLogout) |
177 | { | 177 | { |
178 | try | 178 | try |
179 | { | 179 | { |
180 | if ((m_irc.Enabled) && (m_irc.Connected)) | 180 | if ((m_irc.Enabled) && (m_irc.Connected)) |
181 | { | 181 | { |
182 | string clientName = client.FirstName + " " + client.LastName; | 182 | string clientName = client.FirstName + " " + client.LastName; |
183 | string clientRegion = FindClientRegion(client.FirstName, client.LastName); | 183 | string clientRegion = FindClientRegion(client.FirstName, client.LastName); |
184 | // handles simple case. May not work for hundred connecting in per second. | 184 | // handles simple case. May not work for hundred connecting in per second. |
185 | // and the NewClients calles getting interleved | 185 | // and the NewClients calles getting interleved |
186 | // but filters out multiple reports | 186 | // but filters out multiple reports |
187 | if (clientName != m_last_leaving_user) | 187 | if (clientName != m_last_leaving_user) |
188 | { | 188 | { |
189 | m_last_leaving_user = clientName; | 189 | m_last_leaving_user = clientName; |
190 | m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion); | 190 | m_irc.PrivMsg(m_irc.Nick, "Sim", "notices " + clientName + " left " + clientRegion); |
191 | m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion); | 191 | m_log.Info("[IRC]: IRC watcher notices " + clientName + " left " + clientRegion); |
192 | } | 192 | } |
193 | } | 193 | } |
194 | } | 194 | } |
195 | catch (Exception ex) | 195 | catch (Exception ex) |
196 | { | 196 | { |
197 | m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString()); | 197 | m_log.Error("[IRC]: ClientLoggedOut exception trap:" + ex.ToString()); |
198 | } | 198 | } |
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos, | 202 | private void TrySendChatMessage(ScenePresence presence, LLVector3 fromPos, LLVector3 regionPos, |
203 | LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message) | 203 | LLUUID fromAgentID, string fromName, ChatTypeEnum type, string message) |
204 | { | 204 | { |
205 | if (!presence.IsChildAgent) | 205 | if (!presence.IsChildAgent) |
206 | { | 206 | { |
207 | LLVector3 fromRegionPos = fromPos + regionPos; | 207 | LLVector3 fromRegionPos = fromPos + regionPos; |
208 | LLVector3 toRegionPos = presence.AbsolutePosition + regionPos; | 208 | LLVector3 toRegionPos = presence.AbsolutePosition + regionPos; |
209 | int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos)); | 209 | int dis = Math.Abs((int) Util.GetDistanceTo(toRegionPos, fromRegionPos)); |
210 | 210 | ||
211 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || | 211 | if (type == ChatTypeEnum.Whisper && dis > m_whisperdistance || |
212 | type == ChatTypeEnum.Say && dis > m_saydistance || | 212 | type == ChatTypeEnum.Say && dis > m_saydistance || |
213 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) | 213 | type == ChatTypeEnum.Shout && dis > m_shoutdistance) |
214 | { | 214 | { |
215 | return; | 215 | return; |
216 | } | 216 | } |
217 | 217 | ||
218 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView | 218 | // TODO: should change so the message is sent through the avatar rather than direct to the ClientView |
219 | presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID); | 219 | presence.ControllingClient.SendChatMessage(message, (byte) type, fromPos, fromName, fromAgentID); |
220 | } | 220 | } |
221 | } | 221 | } |
222 | 222 | ||
223 | public void SimChat(Object sender, ChatFromViewerArgs e) | 223 | public void SimChat(Object sender, ChatFromViewerArgs e) |
224 | { | 224 | { |
225 | // FROM: Sim TO: IRC | 225 | // FROM: Sim TO: IRC |
226 | 226 | ||
227 | ScenePresence avatar = null; | 227 | ScenePresence avatar = null; |
228 | 228 | ||
229 | //TODO: Move ForEachScenePresence and others into IScene. | 229 | //TODO: Move ForEachScenePresence and others into IScene. |
230 | Scene scene = (Scene) e.Scene; | 230 | Scene scene = (Scene) e.Scene; |
231 | 231 | ||
232 | //TODO: Remove the need for this check | 232 | //TODO: Remove the need for this check |
233 | if (scene == null) | 233 | if (scene == null) |
234 | scene = m_scenes[0]; | 234 | scene = m_scenes[0]; |
235 | 235 | ||
236 | // Filled in since it's easier than rewriting right now. | 236 | // Filled in since it's easier than rewriting right now. |
237 | LLVector3 fromPos = e.Position; | 237 | LLVector3 fromPos = e.Position; |
238 | LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | 238 | LLVector3 regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); |
239 | 239 | ||
240 | string fromName = e.From; | 240 | string fromName = e.From; |
241 | string message = e.Message; | 241 | string message = e.Message; |
242 | LLUUID fromAgentID = LLUUID.Zero; | 242 | LLUUID fromAgentID = LLUUID.Zero; |
243 | 243 | ||
244 | if (e.Sender != null) | 244 | if (e.Sender != null) |
245 | { | 245 | { |
246 | avatar = scene.GetScenePresence(e.Sender.AgentId); | 246 | avatar = scene.GetScenePresence(e.Sender.AgentId); |
247 | } | 247 | } |
248 | 248 | ||
249 | if (avatar != null) | 249 | if (avatar != null) |
250 | { | 250 | { |
251 | fromPos = avatar.AbsolutePosition; | 251 | fromPos = avatar.AbsolutePosition; |
252 | regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); | 252 | regionPos = new LLVector3(scene.RegionInfo.RegionLocX * Constants.RegionSize, scene.RegionInfo.RegionLocY * Constants.RegionSize, 0); |
253 | fromName = avatar.Firstname + " " + avatar.Lastname; | 253 | fromName = avatar.Firstname + " " + avatar.Lastname; |
254 | fromAgentID = e.Sender.AgentId; | 254 | fromAgentID = e.Sender.AgentId; |
255 | } | 255 | } |
256 | 256 | ||
257 | // Try to reconnect to server if not connected | 257 | // Try to reconnect to server if not connected |
258 | if (m_irc.Enabled && !m_irc.Connected) | 258 | if (m_irc.Enabled && !m_irc.Connected) |
259 | { | 259 | { |
260 | // In a non-blocking way. Eventually the connector will get it started | 260 | // In a non-blocking way. Eventually the connector will get it started |
261 | try | 261 | try |
262 | { | 262 | { |
263 | if (m_irc_connector == null) | 263 | if (m_irc_connector == null) |
264 | { | 264 | { |
265 | m_irc_connector = new Thread(IRCConnectRun); | 265 | m_irc_connector = new Thread(IRCConnectRun); |
266 | m_irc_connector.Name = "IRCConnectorThread"; | 266 | m_irc_connector.Name = "IRCConnectorThread"; |
267 | m_irc_connector.IsBackground = true; | 267 | m_irc_connector.IsBackground = true; |
268 | } | 268 | } |
269 | if (!m_irc_connector.IsAlive) | 269 | if (!m_irc_connector.IsAlive) |
270 | { | 270 | { |
271 | m_irc_connector.Start(); | 271 | m_irc_connector.Start(); |
272 | ThreadTracker.Add(m_irc_connector); | 272 | ThreadTracker.Add(m_irc_connector); |
273 | } | 273 | } |
274 | } | 274 | } |
275 | catch (Exception) | 275 | catch (Exception) |
276 | { | 276 | { |
277 | } | 277 | } |
278 | } | 278 | } |
279 | 279 | ||
280 | 280 | ||
281 | // We only want to relay stuff on channel 0 | 281 | // We only want to relay stuff on channel 0 |
282 | if (e.Channel == 0) | 282 | if (e.Channel == 0) |
283 | { | 283 | { |
284 | // IRC stuff | 284 | // IRC stuff |
285 | if (e.Message.Length > 0) | 285 | if (e.Message.Length > 0) |
286 | { | 286 | { |
287 | if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC | 287 | if (m_irc.Connected && (avatar != null)) // this is to keep objects from talking to IRC |
288 | { | 288 | { |
289 | m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message); | 289 | m_irc.PrivMsg(fromName, scene.RegionInfo.RegionName, e.Message); |
290 | } | 290 | } |
291 | } | 291 | } |
292 | 292 | ||
293 | foreach (Scene s in m_scenes) | 293 | foreach (Scene s in m_scenes) |
294 | { | 294 | { |
295 | s.ForEachScenePresence(delegate(ScenePresence presence) | 295 | s.ForEachScenePresence(delegate(ScenePresence presence) |
296 | { | 296 | { |
297 | TrySendChatMessage(presence, fromPos, regionPos, | 297 | TrySendChatMessage(presence, fromPos, regionPos, |
298 | fromAgentID, fromName, e.Type, message); | 298 | fromAgentID, fromName, e.Type, message); |
299 | }); | 299 | }); |
300 | } | 300 | } |
301 | } | 301 | } |
302 | } | 302 | } |
303 | 303 | ||
304 | // if IRC is enabled then just keep trying using a monitor thread | 304 | // if IRC is enabled then just keep trying using a monitor thread |
305 | public void IRCConnectRun() | 305 | public void IRCConnectRun() |
306 | { | 306 | { |
307 | while(true) | 307 | while(true) |
308 | { | 308 | { |
309 | if ((m_irc.Enabled)&&(!m_irc.Connected)) | 309 | if ((m_irc.Enabled)&&(!m_irc.Connected)) |
310 | { | 310 | { |
311 | m_irc.Connect(m_scenes); | 311 | m_irc.Connect(m_scenes); |
312 | } | 312 | } |
313 | Thread.Sleep(15000); | 313 | Thread.Sleep(15000); |
314 | } | 314 | } |
315 | } | 315 | } |
316 | 316 | ||
317 | public string FindClientRegion(string client_FirstName,string client_LastName) | 317 | public string FindClientRegion(string client_FirstName,string client_LastName) |
318 | { | 318 | { |
319 | string sourceRegion = null; | 319 | string sourceRegion = null; |
320 | foreach (Scene s in m_scenes) | 320 | foreach (Scene s in m_scenes) |
321 | { | 321 | { |
322 | s.ForEachScenePresence(delegate(ScenePresence presence) | 322 | s.ForEachScenePresence(delegate(ScenePresence presence) |
323 | { | 323 | { |
324 | if ((presence.IsChildAgent==false) | 324 | if ((presence.IsChildAgent==false) |
325 | &&(presence.Firstname==client_FirstName) | 325 | &&(presence.Firstname==client_FirstName) |
326 | &&(presence.Lastname==client_LastName)) | 326 | &&(presence.Lastname==client_LastName)) |
327 | { | 327 | { |
328 | sourceRegion = presence.Scene.RegionInfo.RegionName; | 328 | sourceRegion = presence.Scene.RegionInfo.RegionName; |
329 | //sourceRegion= s.RegionInfo.RegionName; | 329 | //sourceRegion= s.RegionInfo.RegionName; |
330 | } | 330 | } |
331 | }); | 331 | }); |
332 | if (sourceRegion != null) return sourceRegion; | 332 | if (sourceRegion != null) return sourceRegion; |
333 | } | 333 | } |
334 | if (m_defaultzone == null) { m_defaultzone = "Sim"; } | 334 | if (m_defaultzone == null) { m_defaultzone = "Sim"; } |
335 | return m_defaultzone; | 335 | return m_defaultzone; |
336 | } | 336 | } |
337 | } | 337 | } |
338 | 338 | ||
339 | internal class IRCChatModule | 339 | internal class IRCChatModule |
340 | { | 340 | { |
341 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 341 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
342 | 342 | ||
343 | private string m_server = null; | 343 | private string m_server = null; |
344 | private uint m_port = 6668; | 344 | private uint m_port = 6668; |
345 | private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot"; | 345 | private string m_user = "USER OpenSimBot 8 * :I'm a OpenSim to irc bot"; |
346 | private string m_nick = null; | 346 | private string m_nick = null; |
347 | private string m_basenick = null; | 347 | private string m_basenick = null; |
348 | private string m_channel = null; | 348 | private string m_channel = null; |
349 | private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"; | 349 | private string m_privmsgformat = "PRIVMSG {0} :<{1} in {2}>: {3}"; |
350 | 350 | ||
351 | private NetworkStream m_stream; | 351 | private NetworkStream m_stream; |
352 | private TcpClient m_tcp; | 352 | private TcpClient m_tcp; |
353 | private StreamWriter m_writer; | 353 | private StreamWriter m_writer; |
354 | private StreamReader m_reader; | 354 | private StreamReader m_reader; |
355 | 355 | ||
356 | private Thread pingSender; | 356 | private Thread pingSender; |
357 | private Thread listener; | 357 | private Thread listener; |
358 | internal object m_syncConnect = new object(); | 358 | internal object m_syncConnect = new object(); |
359 | 359 | ||
360 | private bool m_enabled = false; | 360 | private bool m_enabled = false; |
361 | private bool m_connected = false; | 361 | private bool m_connected = false; |
362 | 362 | ||
363 | private List<Scene> m_scenes = null; | 363 | private List<Scene> m_scenes = null; |
364 | private List<Scene> m_last_scenes = null; | 364 | private List<Scene> m_last_scenes = null; |
365 | 365 | ||
366 | public IRCChatModule(IConfigSource config) | 366 | public IRCChatModule(IConfigSource config) |
367 | { | 367 | { |
368 | m_nick = "OSimBot" + Util.RandomClass.Next(1, 99); | 368 | m_nick = "OSimBot" + Util.RandomClass.Next(1, 99); |
369 | m_tcp = null; | 369 | m_tcp = null; |
370 | m_writer = null; | 370 | m_writer = null; |
371 | m_reader = null; | 371 | m_reader = null; |
372 | 372 | ||
373 | // configuration in OpenSim.ini | 373 | // configuration in OpenSim.ini |
374 | // [IRC] | 374 | // [IRC] |
375 | // server = chat.freenode.net | 375 | // server = chat.freenode.net |
376 | // nick = OSimBot_mysim | 376 | // nick = OSimBot_mysim |
377 | // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot | 377 | // ;username = USER OpenSimBot 8 * :I'm a OpenSim to irc bot |
378 | // ; username is the IRC command line sent | 378 | // ; username is the IRC command line sent |
379 | // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname> | 379 | // ; USER <irc_user> <visible=8,invisible=0> * : <IRC_realname> |
380 | // channel = #opensim-regions | 380 | // channel = #opensim-regions |
381 | // port = 6667 | 381 | // port = 6667 |
382 | // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message | 382 | // ;MSGformat fields : 0=botnick, 1=user, 2=region, 3=message |
383 | // ;for <bot>:<user in region> :<message> | 383 | // ;for <bot>:<user in region> :<message> |
384 | // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}" | 384 | // ;msgformat = "PRIVMSG {0} :<{1} in {2}>: {3}" |
385 | // ;for <bot>:<message> - <user of region> : | 385 | // ;for <bot>:<message> - <user of region> : |
386 | // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}" | 386 | // ;msgformat = "PRIVMSG {0} : {3} - {1} of {2}" |
387 | // ;for <bot>:<message> - from <user> : | 387 | // ;for <bot>:<message> - from <user> : |
388 | // ;msgformat = "PRIVMSG {0} : {3} - from {1}" | 388 | // ;msgformat = "PRIVMSG {0} : {3} - from {1}" |
389 | // Traps I/O disconnects so it does not crash the sim | 389 | // Traps I/O disconnects so it does not crash the sim |
390 | // Trys to reconnect if disconnected and someone says something | 390 | // Trys to reconnect if disconnected and someone says something |
391 | // Tells IRC server "QUIT" when doing a close (just to be nice) | 391 | // Tells IRC server "QUIT" when doing a close (just to be nice) |
392 | // Default port back to 6667 | 392 | // Default port back to 6667 |
393 | 393 | ||
394 | try | 394 | try |
395 | { | 395 | { |
396 | m_server = config.Configs["IRC"].GetString("server"); | 396 | m_server = config.Configs["IRC"].GetString("server"); |
397 | m_nick = config.Configs["IRC"].GetString("nick"); | 397 | m_nick = config.Configs["IRC"].GetString("nick"); |
398 | m_basenick = m_nick; | 398 | m_basenick = m_nick; |
399 | m_channel = config.Configs["IRC"].GetString("channel"); | 399 | m_channel = config.Configs["IRC"].GetString("channel"); |
400 | m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port); | 400 | m_port = (uint) config.Configs["IRC"].GetInt("port", (int) m_port); |
401 | m_user = config.Configs["IRC"].GetString("username", m_user); | 401 | m_user = config.Configs["IRC"].GetString("username", m_user); |
402 | m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat); | 402 | m_privmsgformat = config.Configs["IRC"].GetString("msgformat", m_privmsgformat); |
403 | if (m_server != null && m_nick != null && m_channel != null) | 403 | if (m_server != null && m_nick != null && m_channel != null) |
404 | { | 404 | { |
405 | m_nick = m_nick + Util.RandomClass.Next(1, 99); | 405 | m_nick = m_nick + Util.RandomClass.Next(1, 99); |
406 | m_enabled = true; | 406 | m_enabled = true; |
407 | } | 407 | } |
408 | } | 408 | } |
409 | catch (Exception) | 409 | catch (Exception) |
410 | { | 410 | { |
411 | m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration"); | 411 | m_log.Info("[CHAT]: No IRC config information, skipping IRC bridge configuration"); |
412 | } | 412 | } |
413 | } | 413 | } |
414 | 414 | ||
415 | public bool Connect(List<Scene> scenes) | 415 | public bool Connect(List<Scene> scenes) |
416 | { | 416 | { |
417 | lock (m_syncConnect) | 417 | lock (m_syncConnect) |
418 | { | 418 | { |
419 | try | 419 | try |
420 | { | 420 | { |
421 | if (m_connected) return true; | 421 | if (m_connected) return true; |
422 | m_scenes = scenes; | 422 | m_scenes = scenes; |
423 | if (m_last_scenes == null) { m_last_scenes = scenes; } | 423 | if (m_last_scenes == null) { m_last_scenes = scenes; } |
424 | 424 | ||
425 | m_tcp = new TcpClient(m_server, (int)m_port); | 425 | m_tcp = new TcpClient(m_server, (int)m_port); |
426 | m_log.Info("[IRC]: Connecting..."); | 426 | m_log.Info("[IRC]: Connecting..."); |
427 | m_stream = m_tcp.GetStream(); | 427 | m_stream = m_tcp.GetStream(); |
428 | m_log.Info("[IRC]: Connected to " + m_server); | 428 | m_log.Info("[IRC]: Connected to " + m_server); |
429 | m_reader = new StreamReader(m_stream); | 429 | m_reader = new StreamReader(m_stream); |
430 | m_writer = new StreamWriter(m_stream); | 430 | m_writer = new StreamWriter(m_stream); |
431 | 431 | ||
432 | pingSender = new Thread(new ThreadStart(PingRun)); | 432 | pingSender = new Thread(new ThreadStart(PingRun)); |
433 | pingSender.Name = "PingSenderThread"; | 433 | pingSender.Name = "PingSenderThread"; |
434 | pingSender.IsBackground = true; | 434 | pingSender.IsBackground = true; |
435 | pingSender.Start(); | 435 | pingSender.Start(); |
436 | ThreadTracker.Add(pingSender); | 436 | ThreadTracker.Add(pingSender); |
437 | 437 | ||
438 | listener = new Thread(new ThreadStart(ListenerRun)); | 438 | listener = new Thread(new ThreadStart(ListenerRun)); |
439 | listener.Name = "IRCChatModuleListenerThread"; | 439 | listener.Name = "IRCChatModuleListenerThread"; |
440 | listener.IsBackground = true; | 440 | listener.IsBackground = true; |
441 | listener.Start(); | 441 | listener.Start(); |
442 | ThreadTracker.Add(listener); | 442 | ThreadTracker.Add(listener); |
443 | 443 | ||
444 | m_writer.WriteLine(m_user); | 444 | m_writer.WriteLine(m_user); |
445 | m_writer.Flush(); | 445 | m_writer.Flush(); |
446 | m_writer.WriteLine("NICK " + m_nick); | 446 | m_writer.WriteLine("NICK " + m_nick); |
447 | m_writer.Flush(); | 447 | m_writer.Flush(); |
448 | m_writer.WriteLine("JOIN " + m_channel); | 448 | m_writer.WriteLine("JOIN " + m_channel); |
449 | m_writer.Flush(); | 449 | m_writer.Flush(); |
450 | m_log.Info("[IRC]: Connection fully established"); | 450 | m_log.Info("[IRC]: Connection fully established"); |
451 | m_connected = true; | 451 | m_connected = true; |
452 | } | 452 | } |
453 | catch (Exception e) | 453 | catch (Exception e) |
454 | { | 454 | { |
455 | Console.WriteLine(e.ToString()); | 455 | Console.WriteLine(e.ToString()); |
456 | } | 456 | } |
457 | return m_connected; | 457 | return m_connected; |
458 | } | 458 | } |
459 | } | 459 | } |
460 | 460 | ||
461 | public bool Enabled | 461 | public bool Enabled |
462 | { | 462 | { |
463 | get { return m_enabled; } | 463 | get { return m_enabled; } |
464 | } | 464 | } |
465 | 465 | ||
466 | public bool Connected | 466 | public bool Connected |
467 | { | 467 | { |
468 | get { return m_connected; } | 468 | get { return m_connected; } |
469 | } | 469 | } |
470 | 470 | ||
471 | public string Nick | 471 | public string Nick |
472 | { | 472 | { |
473 | get { return m_nick; } | 473 | get { return m_nick; } |
474 | } | 474 | } |
475 | 475 | ||
476 | public void Reconnect() | 476 | public void Reconnect() |
477 | { | 477 | { |
478 | m_connected = false; | 478 | m_connected = false; |
479 | listener.Abort(); | 479 | listener.Abort(); |
480 | pingSender.Abort(); | 480 | pingSender.Abort(); |
481 | m_writer.Close(); | 481 | m_writer.Close(); |
482 | m_reader.Close(); | 482 | m_reader.Close(); |
483 | m_tcp.Close(); | 483 | m_tcp.Close(); |
484 | if (m_enabled) { Connect(m_last_scenes); } | 484 | if (m_enabled) { Connect(m_last_scenes); } |
485 | } | 485 | } |
486 | 486 | ||
487 | public void PrivMsg(string from, string region, string msg) | 487 | public void PrivMsg(string from, string region, string msg) |
488 | { | 488 | { |
489 | // One message to the IRC server | 489 | // One message to the IRC server |
490 | 490 | ||
491 | try | 491 | try |
492 | { | 492 | { |
493 | if (m_privmsgformat == null) | 493 | if (m_privmsgformat == null) |
494 | { | 494 | { |
495 | m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg); | 495 | m_writer.WriteLine("PRIVMSG {0} :<{1} in {2}>: {3}", m_channel, from, region, msg); |
496 | } | 496 | } |
497 | else | 497 | else |
498 | { | 498 | { |
499 | m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg); | 499 | m_writer.WriteLine(m_privmsgformat, m_channel, from, region, msg); |
500 | } | 500 | } |
501 | m_writer.Flush(); | 501 | m_writer.Flush(); |
502 | m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg); | 502 | m_log.Info("[IRC]: PrivMsg " + from + " in " + region + " :" + msg); |
503 | } | 503 | } |
504 | catch (IOException) | 504 | catch (IOException) |
505 | { | 505 | { |
506 | m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)"); | 506 | m_log.Error("[IRC]: Disconnected from IRC server.(PrivMsg)"); |
507 | Reconnect(); | 507 | Reconnect(); |
508 | } | 508 | } |
509 | catch (Exception ex) | 509 | catch (Exception ex) |
510 | { | 510 | { |
511 | m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString()); | 511 | m_log.Error("[IRC]: PrivMsg exception trap:" + ex.ToString()); |
512 | } | 512 | } |
513 | } | 513 | } |
514 | 514 | ||
515 | private Dictionary<string, string> ExtractMsg(string input) | 515 | private Dictionary<string, string> ExtractMsg(string input) |
516 | { | 516 | { |
517 | //examines IRC commands and extracts any private messages | 517 | //examines IRC commands and extracts any private messages |
518 | // which will then be reboadcast in the Sim | 518 | // which will then be reboadcast in the Sim |
519 | 519 | ||
520 | m_log.Info("[IRC]: ExtractMsg: " + input); | 520 | m_log.Info("[IRC]: ExtractMsg: " + input); |
521 | Dictionary<string, string> result = null; | 521 | Dictionary<string, string> result = null; |
522 | //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; | 522 | //string regex = @":(?<nick>\w*)!~(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; |
523 | string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; | 523 | string regex = @":(?<nick>\w*)!(?<user>\S*) PRIVMSG (?<channel>\S+) :(?<msg>.*)"; |
524 | Regex RE = new Regex(regex, RegexOptions.Multiline); | 524 | Regex RE = new Regex(regex, RegexOptions.Multiline); |
525 | MatchCollection matches = RE.Matches(input); | 525 | MatchCollection matches = RE.Matches(input); |
526 | // Get some direct matches $1 $4 is a | 526 | // Get some direct matches $1 $4 is a |
527 | if ((matches.Count == 1) && (matches[0].Groups.Count == 5)) | 527 | if ((matches.Count == 1) && (matches[0].Groups.Count == 5)) |
528 | { | 528 | { |
529 | result = new Dictionary<string, string>(); | 529 | result = new Dictionary<string, string>(); |
530 | result.Add("nick", matches[0].Groups[1].Value); | 530 | result.Add("nick", matches[0].Groups[1].Value); |
531 | result.Add("user", matches[0].Groups[2].Value); | 531 | result.Add("user", matches[0].Groups[2].Value); |
532 | result.Add("channel", matches[0].Groups[3].Value); | 532 | result.Add("channel", matches[0].Groups[3].Value); |
533 | result.Add("msg", matches[0].Groups[4].Value); | 533 | result.Add("msg", matches[0].Groups[4].Value); |
534 | } | 534 | } |
535 | else | 535 | else |
536 | { | 536 | { |
537 | m_log.Info("[IRC]: Number of matches: " + matches.Count); | 537 | m_log.Info("[IRC]: Number of matches: " + matches.Count); |
538 | if (matches.Count > 0) | 538 | if (matches.Count > 0) |
539 | { | 539 | { |
540 | m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count); | 540 | m_log.Info("[IRC]: Number of groups: " + matches[0].Groups.Count); |
541 | } | 541 | } |
542 | } | 542 | } |
543 | return result; | 543 | return result; |
544 | } | 544 | } |
545 | 545 | ||
546 | public void PingRun() | 546 | public void PingRun() |
547 | { | 547 | { |
548 | // IRC keep alive thread | 548 | // IRC keep alive thread |
549 | // send PING ever 15 seconds | 549 | // send PING ever 15 seconds |
550 | while (true) | 550 | while (true) |
551 | { | 551 | { |
552 | try | 552 | try |
553 | { | 553 | { |
554 | if (m_connected == true) | 554 | if (m_connected == true) |
555 | { | 555 | { |
556 | m_writer.WriteLine("PING :" + m_server); | 556 | m_writer.WriteLine("PING :" + m_server); |
557 | m_writer.Flush(); | 557 | m_writer.Flush(); |
558 | Thread.Sleep(15000); | 558 | Thread.Sleep(15000); |
559 | } | 559 | } |
560 | } | 560 | } |
561 | catch (IOException) | 561 | catch (IOException) |
562 | { | 562 | { |
563 | m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)"); | 563 | m_log.Error("[IRC]: Disconnected from IRC server.(PingRun)"); |
564 | Reconnect(); | 564 | Reconnect(); |
565 | } | 565 | } |
566 | catch (Exception ex) | 566 | catch (Exception ex) |
567 | { | 567 | { |
568 | m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); | 568 | m_log.Error("[IRC]: PingRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); |
569 | } | 569 | } |
570 | } | 570 | } |
571 | } | 571 | } |
572 | 572 | ||
573 | public void ListenerRun() | 573 | public void ListenerRun() |
574 | { | 574 | { |
575 | string inputLine; | 575 | string inputLine; |
576 | LLVector3 pos = new LLVector3(128, 128, 20); | 576 | LLVector3 pos = new LLVector3(128, 128, 20); |
577 | while (true) | 577 | while (true) |
578 | { | 578 | { |
579 | try | 579 | try |
580 | { | 580 | { |
581 | while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null)) | 581 | while ((m_connected == true) && ((inputLine = m_reader.ReadLine()) != null)) |
582 | { | 582 | { |
583 | // Console.WriteLine(inputLine); | 583 | // Console.WriteLine(inputLine); |
584 | if (inputLine.Contains(m_channel)) | 584 | if (inputLine.Contains(m_channel)) |
585 | { | 585 | { |
586 | Dictionary<string, string> data = ExtractMsg(inputLine); | 586 | Dictionary<string, string> data = ExtractMsg(inputLine); |
587 | // Any chat ??? | 587 | // Any chat ??? |
588 | if (data != null) | 588 | if (data != null) |
589 | { | 589 | { |
590 | foreach (Scene m_scene in m_scenes) | 590 | foreach (Scene m_scene in m_scenes) |
591 | { | 591 | { |
592 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) | 592 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) |
593 | { | 593 | { |
594 | if (!avatar.IsChildAgent) | 594 | if (!avatar.IsChildAgent) |
595 | { | 595 | { |
596 | avatar.ControllingClient.SendChatMessage( | 596 | avatar.ControllingClient.SendChatMessage( |
597 | Helpers.StringToField(data["msg"]), 255, | 597 | Helpers.StringToField(data["msg"]), 255, |
598 | pos, data["nick"], | 598 | pos, data["nick"], |
599 | LLUUID.Zero); | 599 | LLUUID.Zero); |
600 | } | 600 | } |
601 | }); | 601 | }); |
602 | } | 602 | } |
603 | } | 603 | } |
604 | else | 604 | else |
605 | { | 605 | { |
606 | // Was an command from the IRC server | 606 | // Was an command from the IRC server |
607 | ProcessIRCCommand(inputLine); | 607 | ProcessIRCCommand(inputLine); |
608 | } | 608 | } |
609 | } | 609 | } |
610 | else | 610 | else |
611 | { | 611 | { |
612 | // Was an command from the IRC server | 612 | // Was an command from the IRC server |
613 | ProcessIRCCommand(inputLine); | 613 | ProcessIRCCommand(inputLine); |
614 | } | 614 | } |
615 | Thread.Sleep(150); | 615 | Thread.Sleep(150); |
616 | } | 616 | } |
617 | } | 617 | } |
618 | catch (IOException) | 618 | catch (IOException) |
619 | { | 619 | { |
620 | m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)"); | 620 | m_log.Error("[IRC]: ListenerRun IOException. Disconnected from IRC server ??? (ListenerRun)"); |
621 | Reconnect(); | 621 | Reconnect(); |
622 | } | 622 | } |
623 | catch (Exception ex) | 623 | catch (Exception ex) |
624 | { | 624 | { |
625 | m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); | 625 | m_log.Error("[IRC]: ListenerRun exception trap:" + ex.ToString() + "\n" + ex.StackTrace); |
626 | } | 626 | } |
627 | } | 627 | } |
628 | } | 628 | } |
629 | 629 | ||
630 | public void BroadcastSim(string message,string sender) | 630 | public void BroadcastSim(string message,string sender) |
631 | { | 631 | { |
632 | LLVector3 pos = new LLVector3(128, 128, 20); | 632 | LLVector3 pos = new LLVector3(128, 128, 20); |
633 | try | 633 | try |
634 | { | 634 | { |
635 | foreach (Scene m_scene in m_scenes) | 635 | foreach (Scene m_scene in m_scenes) |
636 | { | 636 | { |
637 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) | 637 | m_scene.ForEachScenePresence(delegate(ScenePresence avatar) |
638 | { | 638 | { |
639 | if (!avatar.IsChildAgent) | 639 | if (!avatar.IsChildAgent) |
640 | { | 640 | { |
641 | avatar.ControllingClient.SendChatMessage( | 641 | avatar.ControllingClient.SendChatMessage( |
642 | Helpers.StringToField(message), 255, | 642 | Helpers.StringToField(message), 255, |
643 | pos, sender, | 643 | pos, sender, |
644 | LLUUID.Zero); | 644 | LLUUID.Zero); |
645 | } | 645 | } |
646 | }); | 646 | }); |
647 | } | 647 | } |
648 | } | 648 | } |
649 | catch (Exception ex) // IRC gate should not crash Sim | 649 | catch (Exception ex) // IRC gate should not crash Sim |
650 | { | 650 | { |
651 | m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace); | 651 | m_log.Error("[IRC]: BroadcastSim Exception Trap:" + ex.ToString() + "\n" + ex.StackTrace); |
652 | } | 652 | } |
653 | } | 653 | } |
654 | 654 | ||
655 | public enum ErrorReplies | 655 | public enum ErrorReplies |
656 | { | 656 | { |
657 | NotRegistered = 451, // ":You have not registered" | 657 | NotRegistered = 451, // ":You have not registered" |
658 | NicknameInUse = 433 // "<nick> :Nickname is already in use" | 658 | NicknameInUse = 433 // "<nick> :Nickname is already in use" |
659 | } | 659 | } |
660 | 660 | ||
661 | public enum Replies | 661 | public enum Replies |
662 | { | 662 | { |
663 | MotdStart = 375, // ":- <server> Message of the day - " | 663 | MotdStart = 375, // ":- <server> Message of the day - " |
664 | Motd = 372, // ":- <text>" | 664 | Motd = 372, // ":- <text>" |
665 | EndOfMotd = 376 // ":End of /MOTD command" | 665 | EndOfMotd = 376 // ":End of /MOTD command" |
666 | } | 666 | } |
667 | 667 | ||
668 | public void ProcessIRCCommand(string command) | 668 | public void ProcessIRCCommand(string command) |
669 | { | 669 | { |
670 | //m_log.Info("[IRC]: ProcessIRCCommand:" + command); | 670 | //m_log.Info("[IRC]: ProcessIRCCommand:" + command); |
671 | 671 | ||
672 | string[] commArgs = new string[command.Split(' ').Length]; | 672 | string[] commArgs = new string[command.Split(' ').Length]; |
673 | string c_server = m_server; | 673 | string c_server = m_server; |
674 | 674 | ||
675 | commArgs = command.Split(' '); | 675 | commArgs = command.Split(' '); |
676 | if (commArgs[0].Substring(0, 1) == ":") | 676 | if (commArgs[0].Substring(0, 1) == ":") |
677 | { | 677 | { |
678 | commArgs[0] = commArgs[0].Remove(0, 1); | 678 | commArgs[0] = commArgs[0].Remove(0, 1); |
679 | } | 679 | } |
680 | 680 | ||
681 | if (commArgs[1] == "002") | 681 | if (commArgs[1] == "002") |
682 | { | 682 | { |
683 | // fetch the correct servername | 683 | // fetch the correct servername |
684 | // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/... | 684 | // ex: irc.freenode.net -> brown.freenode.net/kornbluth.freenode.net/... |
685 | // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch | 685 | // irc.bluewin.ch -> irc1.bluewin.ch/irc2.bluewin.ch |
686 | 686 | ||
687 | c_server = (commArgs[6].Split('['))[0]; | 687 | c_server = (commArgs[6].Split('['))[0]; |
688 | m_server = c_server; | 688 | m_server = c_server; |
689 | } | 689 | } |
690 | 690 | ||
691 | if (commArgs[0] == "ERROR") | 691 | if (commArgs[0] == "ERROR") |
692 | { | 692 | { |
693 | m_log.Error("[IRC]: IRC SERVER ERROR:" + command); | 693 | m_log.Error("[IRC]: IRC SERVER ERROR:" + command); |
694 | } | 694 | } |
695 | 695 | ||
696 | if (commArgs[0] == "PING") | 696 | if (commArgs[0] == "PING") |
697 | { | 697 | { |
698 | string p_reply = ""; | 698 | string p_reply = ""; |
699 | 699 | ||
700 | for (int i = 1; i < commArgs.Length; i++) | 700 | for (int i = 1; i < commArgs.Length; i++) |
701 | { | 701 | { |
702 | p_reply += commArgs[i] + " "; | 702 | p_reply += commArgs[i] + " "; |
703 | } | 703 | } |
704 | 704 | ||
705 | m_writer.WriteLine("PONG " + p_reply); | 705 | m_writer.WriteLine("PONG " + p_reply); |
706 | m_writer.Flush(); | 706 | m_writer.Flush(); |
707 | } | 707 | } |
708 | else if (commArgs[0] == c_server) | 708 | else if (commArgs[0] == c_server) |
709 | { | 709 | { |
710 | // server message | 710 | // server message |
711 | try | 711 | try |
712 | { | 712 | { |
713 | Int32 commandCode = Int32.Parse(commArgs[1]); | 713 | Int32 commandCode = Int32.Parse(commArgs[1]); |
714 | switch (commandCode) | 714 | switch (commandCode) |
715 | { | 715 | { |
716 | case (int)ErrorReplies.NicknameInUse: | 716 | case (int)ErrorReplies.NicknameInUse: |
717 | // Gen a new name | 717 | // Gen a new name |
718 | m_nick = m_basenick + Util.RandomClass.Next(1, 99); | 718 | m_nick = m_basenick + Util.RandomClass.Next(1, 99); |
719 | m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick); | 719 | m_log.Error("[IRC]: IRC SERVER reports NicknameInUse, trying " + m_nick); |
720 | // Retry | 720 | // Retry |
721 | m_writer.WriteLine("NICK " + m_nick); | 721 | m_writer.WriteLine("NICK " + m_nick); |
722 | m_writer.Flush(); | 722 | m_writer.Flush(); |
723 | m_writer.WriteLine("JOIN " + m_channel); | 723 | m_writer.WriteLine("JOIN " + m_channel); |
724 | m_writer.Flush(); | 724 | m_writer.Flush(); |
725 | break; | 725 | break; |
726 | case (int)ErrorReplies.NotRegistered: | 726 | case (int)ErrorReplies.NotRegistered: |
727 | break; | 727 | break; |
728 | case (int)Replies.EndOfMotd: | 728 | case (int)Replies.EndOfMotd: |
729 | break; | 729 | break; |
730 | } | 730 | } |
731 | } | 731 | } |
732 | catch (Exception) | 732 | catch (Exception) |
733 | { | 733 | { |
734 | } | 734 | } |
735 | } | 735 | } |
736 | else | 736 | else |
737 | { | 737 | { |
738 | // Normal message | 738 | // Normal message |
739 | string commAct = commArgs[1]; | 739 | string commAct = commArgs[1]; |
740 | switch (commAct) | 740 | switch (commAct) |
741 | { | 741 | { |
742 | case "JOIN": eventIrcJoin(commArgs); break; | 742 | case "JOIN": eventIrcJoin(commArgs); break; |
743 | case "PART": eventIrcPart(commArgs); break; | 743 | case "PART": eventIrcPart(commArgs); break; |
744 | case "MODE": eventIrcMode(commArgs); break; | 744 | case "MODE": eventIrcMode(commArgs); break; |
745 | case "NICK": eventIrcNickChange(commArgs); break; | 745 | case "NICK": eventIrcNickChange(commArgs); break; |
746 | case "KICK": eventIrcKick(commArgs); break; | 746 | case "KICK": eventIrcKick(commArgs); break; |
747 | case "QUIT": eventIrcQuit(commArgs); break; | 747 | case "QUIT": eventIrcQuit(commArgs); break; |
748 | case "PONG": break; // that's nice | 748 | case "PONG": break; // that's nice |
749 | } | 749 | } |
750 | } | 750 | } |
751 | } | 751 | } |
752 | 752 | ||
753 | public void eventIrcJoin(string[] commArgs) | 753 | public void eventIrcJoin(string[] commArgs) |
754 | { | 754 | { |
755 | string IrcChannel = commArgs[2]; | 755 | string IrcChannel = commArgs[2]; |
756 | string IrcUser = commArgs[0].Split('!')[0]; | 756 | string IrcUser = commArgs[0].Split('!')[0]; |
757 | BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick); | 757 | BroadcastSim(IrcUser + " is joining " + IrcChannel, m_nick); |
758 | } | 758 | } |
759 | 759 | ||
760 | public void eventIrcPart(string[] commArgs) | 760 | public void eventIrcPart(string[] commArgs) |
761 | { | 761 | { |
762 | string IrcChannel = commArgs[2]; | 762 | string IrcChannel = commArgs[2]; |
763 | string IrcUser = commArgs[0].Split('!')[0]; | 763 | string IrcUser = commArgs[0].Split('!')[0]; |
764 | BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick); | 764 | BroadcastSim(IrcUser + " is parting " + IrcChannel, m_nick); |
765 | } | 765 | } |
766 | 766 | ||
767 | public void eventIrcMode(string[] commArgs) | 767 | public void eventIrcMode(string[] commArgs) |
768 | { | 768 | { |
769 | string IrcChannel = commArgs[2]; | 769 | string IrcChannel = commArgs[2]; |
770 | string IrcUser = commArgs[0].Split('!')[0]; | 770 | string IrcUser = commArgs[0].Split('!')[0]; |
771 | string UserMode = ""; | 771 | string UserMode = ""; |
772 | for (int i = 3; i < commArgs.Length; i++) | 772 | for (int i = 3; i < commArgs.Length; i++) |
773 | { | 773 | { |
774 | UserMode += commArgs[i] + " "; | 774 | UserMode += commArgs[i] + " "; |
775 | } | 775 | } |
776 | 776 | ||
777 | if (UserMode.Substring(0, 1) == ":") | 777 | if (UserMode.Substring(0, 1) == ":") |
778 | { | 778 | { |
779 | UserMode = UserMode.Remove(0, 1); | 779 | UserMode = UserMode.Remove(0, 1); |
780 | } | 780 | } |
781 | } | 781 | } |
782 | 782 | ||
783 | public void eventIrcNickChange(string[] commArgs) | 783 | public void eventIrcNickChange(string[] commArgs) |
784 | { | 784 | { |
785 | string UserOldNick = commArgs[0].Split('!')[0]; | 785 | string UserOldNick = commArgs[0].Split('!')[0]; |
786 | string UserNewNick = commArgs[2].Remove(0, 1); | 786 | string UserNewNick = commArgs[2].Remove(0, 1); |
787 | BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick); | 787 | BroadcastSim(UserOldNick + " changed their nick to " + UserNewNick, m_nick); |
788 | } | 788 | } |
789 | 789 | ||
790 | public void eventIrcKick(string[] commArgs) | 790 | public void eventIrcKick(string[] commArgs) |
791 | { | 791 | { |
792 | string UserKicker = commArgs[0].Split('!')[0]; | 792 | string UserKicker = commArgs[0].Split('!')[0]; |
793 | string UserKicked = commArgs[3]; | 793 | string UserKicked = commArgs[3]; |
794 | string IrcChannel = commArgs[2]; | 794 | string IrcChannel = commArgs[2]; |
795 | string KickMessage = ""; | 795 | string KickMessage = ""; |
796 | for (int i = 4; i < commArgs.Length; i++) | 796 | for (int i = 4; i < commArgs.Length; i++) |
797 | { | 797 | { |
798 | KickMessage += commArgs[i] + " "; | 798 | KickMessage += commArgs[i] + " "; |
799 | } | 799 | } |
800 | BroadcastSim(UserKicker + " kicked " + UserKicked +" on "+IrcChannel+" saying "+KickMessage, m_nick); | 800 | BroadcastSim(UserKicker + " kicked " + UserKicked +" on "+IrcChannel+" saying "+KickMessage, m_nick); |
801 | if (UserKicked == m_nick) | 801 | if (UserKicked == m_nick) |
802 | { | 802 | { |
803 | BroadcastSim("Hey, that was me!!!", m_nick); | 803 | BroadcastSim("Hey, that was me!!!", m_nick); |
804 | } | 804 | } |
805 | } | 805 | } |
806 | 806 | ||
807 | public void eventIrcQuit(string[] commArgs) | 807 | public void eventIrcQuit(string[] commArgs) |
808 | { | 808 | { |
809 | string IrcUser = commArgs[0].Split('!')[0]; | 809 | string IrcUser = commArgs[0].Split('!')[0]; |
810 | string QuitMessage = ""; | 810 | string QuitMessage = ""; |
811 | 811 | ||
812 | for (int i = 2; i < commArgs.Length; i++) | 812 | for (int i = 2; i < commArgs.Length; i++) |
813 | { | 813 | { |
814 | QuitMessage += commArgs[i] + " "; | 814 | QuitMessage += commArgs[i] + " "; |
815 | } | 815 | } |
816 | BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick); | 816 | BroadcastSim(IrcUser + " quits saying " + QuitMessage, m_nick); |
817 | } | 817 | } |
818 | 818 | ||
819 | public void Close() | 819 | public void Close() |
820 | { | 820 | { |
821 | m_connected = false; | 821 | m_connected = false; |
822 | m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing"); | 822 | m_writer.WriteLine("QUIT :" + m_nick + " to " + m_channel + " wormhole with " + m_server + " closing"); |
823 | m_writer.Flush(); | 823 | m_writer.Flush(); |
824 | listener.Abort(); | 824 | listener.Abort(); |
825 | pingSender.Abort(); | 825 | pingSender.Abort(); |
826 | m_writer.Close(); | 826 | m_writer.Close(); |
827 | m_reader.Close(); | 827 | m_reader.Close(); |
828 | m_tcp.Close(); | 828 | m_tcp.Close(); |
829 | } | 829 | } |
830 | } | 830 | } |
831 | } | 831 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/BetaGridLikeMoneyModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs index 3a8906e..0e058ec 100644 --- a/OpenSim/Region/Environment/Modules/BetaGridLikeMoneyModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Currency/SampleMoney/SampleMoneyModule.cs | |||
@@ -1,1490 +1,1491 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
31 | using System.Net; | 31 | using System.Net; |
32 | using System.Net.Sockets; | 32 | using System.Net.Sockets; |
33 | using System.Reflection; | 33 | using System.Reflection; |
34 | using System.Xml; | 34 | using System.Xml; |
35 | using libsecondlife; | 35 | using libsecondlife; |
36 | using log4net; | 36 | using log4net; |
37 | using Nini.Config; | 37 | using Nini.Config; |
38 | using Nwc.XmlRpc; | 38 | using Nwc.XmlRpc; |
39 | using OpenSim.Framework; | 39 | using OpenSim.Framework; |
40 | using OpenSim.Region.Environment.Interfaces; | 40 | using OpenSim.Region.Environment.Interfaces; |
41 | using OpenSim.Region.Environment.Scenes; | 41 | using OpenSim.Region.Environment.Scenes; |
42 | 42 | ||
43 | namespace OpenSim.Region.Environment.Modules | 43 | namespace OpenSim.Region.Environment.Modules.Avatar.Currency.SampleMoney |
44 | { | 44 | { |
45 | /// <summary> | 45 | /// <summary> |
46 | /// Demo Economy/Money Module. This is not a production quality money/economy module! | 46 | /// Demo Economy/Money Module. This is not a production quality money/economy module! |
47 | /// This is a demo for you to use when making one that works for you. | 47 | /// This is a demo for you to use when making one that works for you. |
48 | /// // To use the following you need to add: | 48 | /// // To use the following you need to add: |
49 | /// -helperuri <ADDRESS TO HERE OR grid MONEY SERVER> | 49 | /// -helperuri <ADDRESS TO HERE OR grid MONEY SERVER> |
50 | /// to the command line parameters you use to start up your client | 50 | /// to the command line parameters you use to start up your client |
51 | /// This commonly looks like -helperuri http://127.0.0.1:9000/ | 51 | /// This commonly looks like -helperuri http://127.0.0.1:9000/ |
52 | /// | 52 | /// |
53 | /// Centralized grid structure example using OpenSimWi Redux revision 9+ | 53 | /// Centralized grid structure example using OpenSimWi Redux revision 9+ |
54 | /// svn co https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux | 54 | /// svn co https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux |
55 | /// </summary> | 55 | /// </summary> |
56 | 56 | ||
57 | public delegate void ObjectPaid(LLUUID objectID, LLUUID agentID, int amount); | 57 | public delegate void ObjectPaid(LLUUID objectID, LLUUID agentID, int amount); |
58 | 58 | ||
59 | public interface IMoneyModule : IRegionModule | 59 | public interface IMoneyModule : IRegionModule |
60 | { | 60 | { |
61 | bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount); | 61 | bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount); |
62 | 62 | ||
63 | event ObjectPaid OnObjectPaid; | 63 | event ObjectPaid OnObjectPaid; |
64 | } | 64 | } |
65 | 65 | ||
66 | public class BetaGridLikeMoneyModule: IMoneyModule | 66 | public class SampleMoneyModule : IMoneyModule |
67 | { | 67 | { |
68 | public event ObjectPaid OnObjectPaid; | 68 | public event ObjectPaid OnObjectPaid; |
69 | 69 | ||
70 | private ObjectPaid handerOnObjectPaid; | 70 | private ObjectPaid handerOnObjectPaid; |
71 | 71 | ||
72 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 72 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
73 | 73 | ||
74 | /// <summary> | 74 | /// <summary> |
75 | /// Region UUIDS indexed by AgentID | 75 | /// Region UUIDS indexed by AgentID |
76 | /// </summary> | 76 | /// </summary> |
77 | Dictionary<LLUUID, LLUUID> m_rootAgents = new Dictionary<LLUUID, LLUUID>(); | 77 | Dictionary<LLUUID, LLUUID> m_rootAgents = new Dictionary<LLUUID, LLUUID>(); |
78 | 78 | ||
79 | /// <summary> | 79 | /// <summary> |
80 | /// Scenes by Region Handle | 80 | /// Scenes by Region Handle |
81 | /// </summary> | 81 | /// </summary> |
82 | private Dictionary<ulong,Scene> m_scenel = new Dictionary<ulong,Scene>(); | 82 | private Dictionary<ulong,Scene> m_scenel = new Dictionary<ulong,Scene>(); |
83 | 83 | ||
84 | private IConfigSource m_gConfig; | 84 | private IConfigSource m_gConfig; |
85 | 85 | ||
86 | private bool m_keepMoneyAcrossLogins = true; | 86 | private bool m_keepMoneyAcrossLogins = true; |
87 | 87 | ||
88 | private int m_minFundsBeforeRefresh = 100; | 88 | private int m_minFundsBeforeRefresh = 100; |
89 | 89 | ||
90 | private int m_stipend = 1000; | 90 | private int m_stipend = 1000; |
91 | 91 | ||
92 | private bool m_enabled = true; | 92 | private bool m_enabled = true; |
93 | 93 | ||
94 | private Dictionary<LLUUID, int> m_KnownClientFunds = new Dictionary<LLUUID, int>(); | 94 | private Dictionary<LLUUID, int> m_KnownClientFunds = new Dictionary<LLUUID, int>(); |
95 | 95 | ||
96 | private bool gridmode = false; | 96 | private bool gridmode = false; |
97 | private Scene XMLRPCHandler; | 97 | private Scene XMLRPCHandler; |
98 | private float EnergyEfficiency = 0f; | 98 | private float EnergyEfficiency = 0f; |
99 | private int ObjectCapacity = 45000; | 99 | private int ObjectCapacity = 45000; |
100 | private int ObjectCount = 0; | 100 | private int ObjectCount = 0; |
101 | private int PriceEnergyUnit = 0; | 101 | private int PriceEnergyUnit = 0; |
102 | private int PriceGroupCreate = 0; | 102 | private int PriceGroupCreate = 0; |
103 | private int PriceObjectClaim = 0; | 103 | private int PriceObjectClaim = 0; |
104 | private float PriceObjectRent = 0f; | 104 | private float PriceObjectRent = 0f; |
105 | private float PriceObjectScaleFactor = 0f; | 105 | private float PriceObjectScaleFactor = 0f; |
106 | private int PriceParcelClaim = 0; | 106 | private int PriceParcelClaim = 0; |
107 | private float PriceParcelClaimFactor = 0f; | 107 | private float PriceParcelClaimFactor = 0f; |
108 | private int PriceParcelRent = 0; | 108 | private int PriceParcelRent = 0; |
109 | private int PricePublicObjectDecay = 0; | 109 | private int PricePublicObjectDecay = 0; |
110 | private int PricePublicObjectDelete = 0; | 110 | private int PricePublicObjectDelete = 0; |
111 | private int PriceRentLight = 0; | 111 | private int PriceRentLight = 0; |
112 | private int PriceUpload = 0; | 112 | private int PriceUpload = 0; |
113 | private int TeleportMinPrice = 0; | 113 | private int TeleportMinPrice = 0; |
114 | private int UserLevelPaysFees = 2; | 114 | private int UserLevelPaysFees = 2; |
115 | private string m_MoneyAddress = String.Empty; | 115 | private string m_MoneyAddress = String.Empty; |
116 | private string m_LandAddress = String.Empty; | 116 | private string m_LandAddress = String.Empty; |
117 | 117 | ||
118 | float TeleportPriceExponent = 0f; | 118 | float TeleportPriceExponent = 0f; |
119 | 119 | ||
120 | /// <summary> | 120 | /// <summary> |
121 | /// Where Stipends come from and Fees go to. | 121 | /// Where Stipends come from and Fees go to. |
122 | /// </summary> | 122 | /// </summary> |
123 | LLUUID EconomyBaseAccount = LLUUID.Zero; | 123 | LLUUID EconomyBaseAccount = LLUUID.Zero; |
124 | 124 | ||
125 | /// <summary> | 125 | /// <summary> |
126 | /// Startup | 126 | /// Startup |
127 | /// </summary> | 127 | /// </summary> |
128 | /// <param name="scene"></param> | 128 | /// <param name="scene"></param> |
129 | /// <param name="config"></param> | 129 | /// <param name="config"></param> |
130 | public void Initialise(Scene scene, IConfigSource config) | 130 | public void Initialise(Scene scene, IConfigSource config) |
131 | { | 131 | { |
132 | m_gConfig = config; | 132 | m_gConfig = config; |
133 | 133 | ||
134 | IConfig startupConfig = m_gConfig.Configs["Startup"]; | 134 | IConfig startupConfig = m_gConfig.Configs["Startup"]; |
135 | IConfig economyConfig = m_gConfig.Configs["Economy"]; | 135 | IConfig economyConfig = m_gConfig.Configs["Economy"]; |
136 | 136 | ||
137 | scene.RegisterModuleInterface<IMoneyModule>(this); | 137 | scene.RegisterModuleInterface<IMoneyModule>(this); |
138 | 138 | ||
139 | ReadConfigAndPopulate(scene, startupConfig, "Startup"); | 139 | ReadConfigAndPopulate(scene, startupConfig, "Startup"); |
140 | ReadConfigAndPopulate(scene, economyConfig, "Economy"); | 140 | ReadConfigAndPopulate(scene, economyConfig, "Economy"); |
141 | 141 | ||
142 | if (m_enabled) | 142 | if (m_enabled) |
143 | { | 143 | { |
144 | lock (m_scenel) | 144 | lock (m_scenel) |
145 | { | 145 | { |
146 | if (m_scenel.Count == 0) | 146 | if (m_scenel.Count == 0) |
147 | { | 147 | { |
148 | XMLRPCHandler = scene; | 148 | XMLRPCHandler = scene; |
149 | 149 | ||
150 | // To use the following you need to add: | 150 | // To use the following you need to add: |
151 | // -helperuri <ADDRESS TO HERE OR grid MONEY SERVER> | 151 | // -helperuri <ADDRESS TO HERE OR grid MONEY SERVER> |
152 | // to the command line parameters you use to start up your client | 152 | // to the command line parameters you use to start up your client |
153 | // This commonly looks like -helperuri http://127.0.0.1:9000/ | 153 | // This commonly looks like -helperuri http://127.0.0.1:9000/ |
154 | 154 | ||
155 | if (m_MoneyAddress.Length > 0) | 155 | if (m_MoneyAddress.Length > 0) |
156 | { | 156 | { |
157 | // Centralized grid structure using OpenSimWi Redux revision 9+ | 157 | // Centralized grid structure using OpenSimWi Redux revision 9+ |
158 | // https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux | 158 | // https://opensimwiredux.svn.sourceforge.net/svnroot/opensimwiredux |
159 | scene.AddXmlRPCHandler("balanceUpdateRequest", GridMoneyUpdate); | 159 | scene.AddXmlRPCHandler("balanceUpdateRequest", GridMoneyUpdate); |
160 | scene.AddXmlRPCHandler("userAlert", UserAlert); | 160 | scene.AddXmlRPCHandler("userAlert", UserAlert); |
161 | } | 161 | } |
162 | else | 162 | else |
163 | { | 163 | { |
164 | // Local Server.. enables functionality only. | 164 | // Local Server.. enables functionality only. |
165 | scene.AddXmlRPCHandler("getCurrencyQuote", quote_func); | 165 | scene.AddXmlRPCHandler("getCurrencyQuote", quote_func); |
166 | scene.AddXmlRPCHandler("buyCurrency", buy_func); | 166 | scene.AddXmlRPCHandler("buyCurrency", buy_func); |
167 | scene.AddXmlRPCHandler("preflightBuyLandPrep", preflightBuyLandPrep_func); | 167 | scene.AddXmlRPCHandler("preflightBuyLandPrep", preflightBuyLandPrep_func); |
168 | scene.AddXmlRPCHandler("buyLandPrep", landBuy_func); | 168 | scene.AddXmlRPCHandler("buyLandPrep", landBuy_func); |
169 | } | 169 | } |
170 | 170 | ||
171 | 171 | ||
172 | } | 172 | } |
173 | 173 | ||
174 | if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle)) | 174 | if (m_scenel.ContainsKey(scene.RegionInfo.RegionHandle)) |
175 | { | 175 | { |
176 | m_scenel[scene.RegionInfo.RegionHandle] = scene; | 176 | m_scenel[scene.RegionInfo.RegionHandle] = scene; |
177 | } | 177 | } |
178 | else | 178 | else |
179 | { | 179 | { |
180 | m_scenel.Add(scene.RegionInfo.RegionHandle, scene); | 180 | m_scenel.Add(scene.RegionInfo.RegionHandle, scene); |
181 | } | 181 | } |
182 | } | 182 | } |
183 | 183 | ||
184 | scene.EventManager.OnNewClient += OnNewClient; | 184 | scene.EventManager.OnNewClient += OnNewClient; |
185 | scene.EventManager.OnMoneyTransfer += MoneyTransferAction; | 185 | scene.EventManager.OnMoneyTransfer += MoneyTransferAction; |
186 | scene.EventManager.OnClientClosed += ClientClosed; | 186 | scene.EventManager.OnClientClosed += ClientClosed; |
187 | scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; | 187 | scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; |
188 | scene.EventManager.OnMakeChildAgent += MakeChildAgent; | 188 | scene.EventManager.OnMakeChildAgent += MakeChildAgent; |
189 | scene.EventManager.OnClientClosed += ClientLoggedOut; | 189 | scene.EventManager.OnClientClosed += ClientLoggedOut; |
190 | scene.EventManager.OnValidateLandBuy += ValidateLandBuy; | 190 | scene.EventManager.OnValidateLandBuy += ValidateLandBuy; |
191 | scene.EventManager.OnLandBuy += processLandBuy; | 191 | scene.EventManager.OnLandBuy += processLandBuy; |
192 | 192 | ||
193 | } | 193 | } |
194 | } | 194 | } |
195 | /// <summary> | 195 | /// <summary> |
196 | /// Parse Configuration | 196 | /// Parse Configuration |
197 | /// </summary> | 197 | /// </summary> |
198 | /// <param name="scene"></param> | 198 | /// <param name="scene"></param> |
199 | /// <param name="startupConfig"></param> | 199 | /// <param name="startupConfig"></param> |
200 | /// <param name="config"></param> | 200 | /// <param name="config"></param> |
201 | private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string config) | 201 | private void ReadConfigAndPopulate(Scene scene, IConfig startupConfig, string config) |
202 | { | 202 | { |
203 | if (config == "Startup" && startupConfig != null) | 203 | if (config == "Startup" && startupConfig != null) |
204 | { | 204 | { |
205 | gridmode = startupConfig.GetBoolean("gridmode", false); | 205 | gridmode = startupConfig.GetBoolean("gridmode", false); |
206 | m_enabled = (startupConfig.GetString("economymodule", "BetaGridLikeMoneyModule") == "BetaGridLikeMoneyModule"); | 206 | m_enabled = (startupConfig.GetString("economymodule", "BetaGridLikeMoneyModule") == "BetaGridLikeMoneyModule"); |
207 | } | 207 | } |
208 | 208 | ||
209 | if (config == "Economy" && startupConfig != null) | 209 | if (config == "Economy" && startupConfig != null) |
210 | { | 210 | { |
211 | ObjectCapacity = startupConfig.GetInt("ObjectCapacity", 45000); | 211 | ObjectCapacity = startupConfig.GetInt("ObjectCapacity", 45000); |
212 | PriceEnergyUnit = startupConfig.GetInt("PriceEnergyUnit", 100); | 212 | PriceEnergyUnit = startupConfig.GetInt("PriceEnergyUnit", 100); |
213 | PriceObjectClaim = startupConfig.GetInt("PriceObjectClaim", 10); | 213 | PriceObjectClaim = startupConfig.GetInt("PriceObjectClaim", 10); |
214 | PricePublicObjectDecay = startupConfig.GetInt("PricePublicObjectDecay", 4); | 214 | PricePublicObjectDecay = startupConfig.GetInt("PricePublicObjectDecay", 4); |
215 | PricePublicObjectDelete = startupConfig.GetInt("PricePublicObjectDelete", 4); | 215 | PricePublicObjectDelete = startupConfig.GetInt("PricePublicObjectDelete", 4); |
216 | PriceParcelClaim = startupConfig.GetInt("PriceParcelClaim", 1); | 216 | PriceParcelClaim = startupConfig.GetInt("PriceParcelClaim", 1); |
217 | PriceParcelClaimFactor = startupConfig.GetFloat("PriceParcelClaimFactor", 1f); | 217 | PriceParcelClaimFactor = startupConfig.GetFloat("PriceParcelClaimFactor", 1f); |
218 | PriceUpload = startupConfig.GetInt("PriceUpload", 0); | 218 | PriceUpload = startupConfig.GetInt("PriceUpload", 0); |
219 | PriceRentLight = startupConfig.GetInt("PriceRentLight", 5); | 219 | PriceRentLight = startupConfig.GetInt("PriceRentLight", 5); |
220 | TeleportMinPrice = startupConfig.GetInt("TeleportMinPrice", 2); | 220 | TeleportMinPrice = startupConfig.GetInt("TeleportMinPrice", 2); |
221 | TeleportPriceExponent = startupConfig.GetFloat("TeleportPriceExponent", 2f); | 221 | TeleportPriceExponent = startupConfig.GetFloat("TeleportPriceExponent", 2f); |
222 | EnergyEfficiency = startupConfig.GetFloat("EnergyEfficiency", 1); | 222 | EnergyEfficiency = startupConfig.GetFloat("EnergyEfficiency", 1); |
223 | PriceObjectRent = startupConfig.GetFloat("PriceObjectRent", 1); | 223 | PriceObjectRent = startupConfig.GetFloat("PriceObjectRent", 1); |
224 | PriceObjectScaleFactor = startupConfig.GetFloat("PriceObjectScaleFactor", 10); | 224 | PriceObjectScaleFactor = startupConfig.GetFloat("PriceObjectScaleFactor", 10); |
225 | PriceParcelRent = startupConfig.GetInt("PriceParcelRent", 1); | 225 | PriceParcelRent = startupConfig.GetInt("PriceParcelRent", 1); |
226 | PriceGroupCreate = startupConfig.GetInt("PriceGroupCreate", -1); | 226 | PriceGroupCreate = startupConfig.GetInt("PriceGroupCreate", -1); |
227 | string EBA = startupConfig.GetString("EconomyBaseAccount", LLUUID.Zero.ToString()); | 227 | string EBA = startupConfig.GetString("EconomyBaseAccount", LLUUID.Zero.ToString()); |
228 | Helpers.TryParse(EBA,out EconomyBaseAccount); | 228 | Helpers.TryParse(EBA,out EconomyBaseAccount); |
229 | 229 | ||
230 | UserLevelPaysFees = startupConfig.GetInt("UserLevelPaysFees", -1); | 230 | UserLevelPaysFees = startupConfig.GetInt("UserLevelPaysFees", -1); |
231 | m_stipend = startupConfig.GetInt("UserStipend", 500); | 231 | m_stipend = startupConfig.GetInt("UserStipend", 500); |
232 | m_minFundsBeforeRefresh = startupConfig.GetInt("IssueStipendWhenClientIsBelowAmount", 10); | 232 | m_minFundsBeforeRefresh = startupConfig.GetInt("IssueStipendWhenClientIsBelowAmount", 10); |
233 | m_keepMoneyAcrossLogins = startupConfig.GetBoolean("KeepMoneyAcrossLogins", true); | 233 | m_keepMoneyAcrossLogins = startupConfig.GetBoolean("KeepMoneyAcrossLogins", true); |
234 | m_MoneyAddress = startupConfig.GetString("CurrencyServer", String.Empty); | 234 | m_MoneyAddress = startupConfig.GetString("CurrencyServer", String.Empty); |
235 | m_LandAddress = startupConfig.GetString("LandServer", String.Empty); | 235 | m_LandAddress = startupConfig.GetString("LandServer", String.Empty); |
236 | } | 236 | } |
237 | 237 | ||
238 | // Send ObjectCapacity to Scene.. Which sends it to the SimStatsReporter. | 238 | // Send ObjectCapacity to Scene.. Which sends it to the SimStatsReporter. |
239 | scene.SetObjectCapacity(ObjectCapacity); | 239 | scene.SetObjectCapacity(ObjectCapacity); |
240 | } | 240 | } |
241 | 241 | ||
242 | /// <summary> | 242 | /// <summary> |
243 | /// New Client Event Handler | 243 | /// New Client Event Handler |
244 | /// </summary> | 244 | /// </summary> |
245 | /// <param name="client"></param> | 245 | /// <param name="client"></param> |
246 | private void OnNewClient(IClientAPI client) | 246 | private void OnNewClient(IClientAPI client) |
247 | { | 247 | { |
248 | // Here we check if we're in grid mode | 248 | // Here we check if we're in grid mode |
249 | // I imagine that the 'check balance' | 249 | // I imagine that the 'check balance' |
250 | // function for the client should be here or shortly after | 250 | // function for the client should be here or shortly after |
251 | 251 | ||
252 | if (gridmode) | 252 | if (gridmode) |
253 | { | 253 | { |
254 | if (m_MoneyAddress.Length == 0) | 254 | if (m_MoneyAddress.Length == 0) |
255 | { | 255 | { |
256 | 256 | ||
257 | CheckExistAndRefreshFunds(client.AgentId); | 257 | CheckExistAndRefreshFunds(client.AgentId); |
258 | } | 258 | } |
259 | else | 259 | else |
260 | { | 260 | { |
261 | bool childYN = true; | 261 | bool childYN = true; |
262 | ScenePresence agent = null; | 262 | ScenePresence agent = null; |
263 | //client.SecureSessionId; | 263 | //client.SecureSessionId; |
264 | Scene s = LocateSceneClientIn(client.AgentId); | 264 | Scene s = LocateSceneClientIn(client.AgentId); |
265 | if (s != null) | 265 | if (s != null) |
266 | { | 266 | { |
267 | agent = s.GetScenePresence(client.AgentId); | 267 | agent = s.GetScenePresence(client.AgentId); |
268 | if (agent != null) | 268 | if (agent != null) |
269 | childYN = agent.IsChildAgent; | 269 | childYN = agent.IsChildAgent; |
270 | } | 270 | } |
271 | if (s != null && agent != null && childYN == false) | 271 | if (s != null && agent != null && childYN == false) |
272 | { | 272 | { |
273 | //s.RegionInfo.RegionHandle; | 273 | //s.RegionInfo.RegionHandle; |
274 | LLUUID agentID = LLUUID.Zero; | 274 | LLUUID agentID = LLUUID.Zero; |
275 | int funds = 0; | 275 | int funds = 0; |
276 | 276 | ||
277 | Hashtable hbinfo = GetBalanceForUserFromMoneyServer(client.AgentId, client.SecureSessionId, s.RegionInfo.originRegionID.ToString(), s.RegionInfo.regionSecret); | 277 | Hashtable hbinfo = GetBalanceForUserFromMoneyServer(client.AgentId, client.SecureSessionId, s.RegionInfo.originRegionID.ToString(), s.RegionInfo.regionSecret); |
278 | if ((bool)hbinfo["success"] == true) | 278 | if ((bool)hbinfo["success"] == true) |
279 | { | 279 | { |
280 | 280 | ||
281 | Helpers.TryParse((string)hbinfo["agentId"], out agentID); | 281 | Helpers.TryParse((string)hbinfo["agentId"], out agentID); |
282 | try | 282 | try |
283 | { | 283 | { |
284 | funds = (Int32)hbinfo["funds"]; | 284 | funds = (Int32)hbinfo["funds"]; |
285 | } | 285 | } |
286 | catch (ArgumentException) | 286 | catch (ArgumentException) |
287 | { | 287 | { |
288 | } | 288 | } |
289 | catch (FormatException) | 289 | catch (FormatException) |
290 | { | 290 | { |
291 | } | 291 | } |
292 | catch (OverflowException) | 292 | catch (OverflowException) |
293 | { | 293 | { |
294 | m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentID); | 294 | m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentID); |
295 | client.SendAlertMessage("Unable to get your money balance, money operations will be unavailable"); | 295 | client.SendAlertMessage("Unable to get your money balance, money operations will be unavailable"); |
296 | } | 296 | } |
297 | catch (InvalidCastException) | 297 | catch (InvalidCastException) |
298 | { | 298 | { |
299 | funds = 0; | 299 | funds = 0; |
300 | } | 300 | } |
301 | 301 | ||
302 | m_KnownClientFunds[agentID] = funds; | 302 | m_KnownClientFunds[agentID] = funds; |
303 | } | 303 | } |
304 | else | 304 | else |
305 | { | 305 | { |
306 | m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentID, (string)hbinfo["errorMessage"]); | 306 | m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentID, (string)hbinfo["errorMessage"]); |
307 | client.SendAlertMessage((string)hbinfo["errorMessage"]); | 307 | client.SendAlertMessage((string)hbinfo["errorMessage"]); |
308 | } | 308 | } |
309 | SendMoneyBalance(client, agentID, client.SessionId, LLUUID.Zero); | 309 | SendMoneyBalance(client, agentID, client.SessionId, LLUUID.Zero); |
310 | 310 | ||
311 | } | 311 | } |
312 | } | 312 | } |
313 | 313 | ||
314 | } | 314 | } |
315 | else | 315 | else |
316 | { | 316 | { |
317 | CheckExistAndRefreshFunds(client.AgentId); | 317 | CheckExistAndRefreshFunds(client.AgentId); |
318 | } | 318 | } |
319 | 319 | ||
320 | // Subscribe to Money messages | 320 | // Subscribe to Money messages |
321 | client.OnEconomyDataRequest += EconomyDataRequestHandler; | 321 | client.OnEconomyDataRequest += EconomyDataRequestHandler; |
322 | client.OnMoneyBalanceRequest += SendMoneyBalance; | 322 | client.OnMoneyBalanceRequest += SendMoneyBalance; |
323 | client.OnRequestPayPrice += requestPayPrice; | 323 | client.OnRequestPayPrice += requestPayPrice; |
324 | client.OnLogout += ClientClosed; | 324 | client.OnLogout += ClientClosed; |
325 | 325 | ||
326 | 326 | ||
327 | } | 327 | } |
328 | 328 | ||
329 | #region event Handlers | 329 | #region event Handlers |
330 | 330 | ||
331 | public void requestPayPrice(IClientAPI client, LLUUID objectID) | 331 | public void requestPayPrice(IClientAPI client, LLUUID objectID) |
332 | { | 332 | { |
333 | Scene scene=LocateSceneClientIn(client.AgentId); | 333 | Scene scene=LocateSceneClientIn(client.AgentId); |
334 | if(scene == null) | 334 | if(scene == null) |
335 | return; | 335 | return; |
336 | 336 | ||
337 | SceneObjectPart task=scene.GetSceneObjectPart(objectID); | 337 | SceneObjectPart task=scene.GetSceneObjectPart(objectID); |
338 | if(task == null) | 338 | if(task == null) |
339 | return; | 339 | return; |
340 | SceneObjectGroup group=task.ParentGroup; | 340 | SceneObjectGroup group=task.ParentGroup; |
341 | SceneObjectPart root=group.RootPart; | 341 | SceneObjectPart root=group.RootPart; |
342 | 342 | ||
343 | client.SendPayPrice(objectID, root.PayPrice); | 343 | client.SendPayPrice(objectID, root.PayPrice); |
344 | } | 344 | } |
345 | 345 | ||
346 | /// <summary> | 346 | /// <summary> |
347 | /// When the client closes the connection we remove their accounting info from memory to free up resources. | 347 | /// When the client closes the connection we remove their accounting info from memory to free up resources. |
348 | /// </summary> | 348 | /// </summary> |
349 | /// <param name="AgentID"></param> | 349 | /// <param name="AgentID"></param> |
350 | public void ClientClosed(LLUUID AgentID) | 350 | public void ClientClosed(LLUUID AgentID) |
351 | { | 351 | { |
352 | lock (m_KnownClientFunds) | 352 | lock (m_KnownClientFunds) |
353 | { | 353 | { |
354 | if (m_keepMoneyAcrossLogins && m_MoneyAddress.Length == 0) | 354 | if (m_keepMoneyAcrossLogins && m_MoneyAddress.Length == 0) |
355 | { | 355 | { |
356 | } | 356 | } |
357 | else | 357 | else |
358 | { | 358 | { |
359 | m_KnownClientFunds.Remove(AgentID); | 359 | m_KnownClientFunds.Remove(AgentID); |
360 | } | 360 | } |
361 | } | 361 | } |
362 | } | 362 | } |
363 | 363 | ||
364 | /// <summary> | 364 | /// <summary> |
365 | /// Event called Economy Data Request handler. | 365 | /// Event called Economy Data Request handler. |
366 | /// </summary> | 366 | /// </summary> |
367 | /// <param name="agentId"></param> | 367 | /// <param name="agentId"></param> |
368 | public void EconomyDataRequestHandler(LLUUID agentId) | 368 | public void EconomyDataRequestHandler(LLUUID agentId) |
369 | { | 369 | { |
370 | IClientAPI user = LocateClientObject(agentId); | 370 | IClientAPI user = LocateClientObject(agentId); |
371 | 371 | ||
372 | if (user != null) | 372 | if (user != null) |
373 | { | 373 | { |
374 | user.SendEconomyData(EnergyEfficiency, ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, | 374 | user.SendEconomyData(EnergyEfficiency, ObjectCapacity, ObjectCount, PriceEnergyUnit, PriceGroupCreate, |
375 | PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, | 375 | PriceObjectClaim, PriceObjectRent, PriceObjectScaleFactor, PriceParcelClaim, PriceParcelClaimFactor, |
376 | PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload, | 376 | PriceParcelRent, PricePublicObjectDecay, PricePublicObjectDelete, PriceRentLight, PriceUpload, |
377 | TeleportMinPrice, TeleportPriceExponent); | 377 | TeleportMinPrice, TeleportPriceExponent); |
378 | } | 378 | } |
379 | } | 379 | } |
380 | 380 | ||
381 | private void ValidateLandBuy (Object osender, EventManager.LandBuyArgs e) | 381 | private void ValidateLandBuy (Object osender, EventManager.LandBuyArgs e) |
382 | { | 382 | { |
383 | if (m_MoneyAddress.Length == 0) | 383 | if (m_MoneyAddress.Length == 0) |
384 | { | 384 | { |
385 | lock (m_KnownClientFunds) | 385 | lock (m_KnownClientFunds) |
386 | { | 386 | { |
387 | if (m_KnownClientFunds.ContainsKey(e.agentId)) | 387 | if (m_KnownClientFunds.ContainsKey(e.agentId)) |
388 | { | 388 | { |
389 | // Does the sender have enough funds to give? | 389 | // Does the sender have enough funds to give? |
390 | if (m_KnownClientFunds[e.agentId] >= e.parcelPrice) | 390 | if (m_KnownClientFunds[e.agentId] >= e.parcelPrice) |
391 | { | 391 | { |
392 | lock(e) | 392 | lock(e) |
393 | { | 393 | { |
394 | e.economyValidated=true; | 394 | e.economyValidated=true; |
395 | } | 395 | } |
396 | } | 396 | } |
397 | } | 397 | } |
398 | } | 398 | } |
399 | } | 399 | } |
400 | else | 400 | else |
401 | { | 401 | { |
402 | if(GetRemoteBalance(e.agentId) >= e.parcelPrice) | 402 | if(GetRemoteBalance(e.agentId) >= e.parcelPrice) |
403 | { | 403 | { |
404 | lock(e) | 404 | lock(e) |
405 | { | 405 | { |
406 | e.economyValidated=true; | 406 | e.economyValidated=true; |
407 | } | 407 | } |
408 | } | 408 | } |
409 | } | 409 | } |
410 | } | 410 | } |
411 | 411 | ||
412 | private void processLandBuy(Object osender, EventManager.LandBuyArgs e) | 412 | private void processLandBuy(Object osender, EventManager.LandBuyArgs e) |
413 | { | 413 | { |
414 | lock(e) | 414 | lock(e) |
415 | { | 415 | { |
416 | if(e.economyValidated == true && e.transactionID == 0) | 416 | if(e.economyValidated == true && e.transactionID == 0) |
417 | { | 417 | { |
418 | e.transactionID=Util.UnixTimeSinceEpoch(); | 418 | e.transactionID=Util.UnixTimeSinceEpoch(); |
419 | 419 | ||
420 | if(doMoneyTransfer(e.agentId, e.parcelOwnerID, e.parcelPrice, 0, "Land purchase")) | 420 | if(doMoneyTransfer(e.agentId, e.parcelOwnerID, e.parcelPrice, 0, "Land purchase")) |
421 | { | 421 | { |
422 | lock (e) | 422 | lock (e) |
423 | { | 423 | { |
424 | e.amountDebited = e.parcelPrice; | 424 | e.amountDebited = e.parcelPrice; |
425 | } | 425 | } |
426 | } | 426 | } |
427 | } | 427 | } |
428 | } | 428 | } |
429 | } | 429 | } |
430 | 430 | ||
431 | /// <summary> | 431 | /// <summary> |
432 | /// THis method gets called when someone pays someone else as a gift. | 432 | /// THis method gets called when someone pays someone else as a gift. |
433 | /// </summary> | 433 | /// </summary> |
434 | /// <param name="osender"></param> | 434 | /// <param name="osender"></param> |
435 | /// <param name="e"></param> | 435 | /// <param name="e"></param> |
436 | private void MoneyTransferAction (Object osender, EventManager.MoneyTransferArgs e) | 436 | private void MoneyTransferAction (Object osender, EventManager.MoneyTransferArgs e) |
437 | { | 437 | { |
438 | IClientAPI sender = null; | 438 | IClientAPI sender = null; |
439 | IClientAPI receiver = null; | 439 | IClientAPI receiver = null; |
440 | 440 | ||
441 | if(m_MoneyAddress.Length > 0) // Handled on server | 441 | if(m_MoneyAddress.Length > 0) // Handled on server |
442 | e.description=String.Empty; | 442 | e.description=String.Empty; |
443 | 443 | ||
444 | if(e.transactiontype == 5008) // Object gets paid | 444 | if(e.transactiontype == 5008) // Object gets paid |
445 | { | 445 | { |
446 | sender = LocateClientObject(e.sender); | 446 | sender = LocateClientObject(e.sender); |
447 | if (sender != null) | 447 | if (sender != null) |
448 | { | 448 | { |
449 | SceneObjectPart part=findPrim(e.receiver); | 449 | SceneObjectPart part=findPrim(e.receiver); |
450 | if(part == null) | 450 | if(part == null) |
451 | return; | 451 | return; |
452 | 452 | ||
453 | string name=resolveAgentName(part.OwnerID); | 453 | string name=resolveAgentName(part.OwnerID); |
454 | if(name == String.Empty) | 454 | if(name == String.Empty) |
455 | name="(hippos)"; | 455 | name="(hippos)"; |
456 | 456 | ||
457 | receiver = LocateClientObject(part.OwnerID); | 457 | receiver = LocateClientObject(part.OwnerID); |
458 | 458 | ||
459 | string description=String.Format("Paid {0} via object {1}", name, e.description); | 459 | string description=String.Format("Paid {0} via object {1}", name, e.description); |
460 | bool transactionresult = doMoneyTransfer(e.sender, part.OwnerID, e.amount, e.transactiontype, description); | 460 | bool transactionresult = doMoneyTransfer(e.sender, part.OwnerID, e.amount, e.transactiontype, description); |
461 | 461 | ||
462 | if(transactionresult) | 462 | if(transactionresult) |
463 | { | 463 | { |
464 | ObjectPaid handlerOnObjectPaid = OnObjectPaid; | 464 | ObjectPaid handlerOnObjectPaid = OnObjectPaid; |
465 | if(handlerOnObjectPaid != null) | 465 | if(handlerOnObjectPaid != null) |
466 | { | 466 | { |
467 | handlerOnObjectPaid(e.receiver, e.sender, e.amount); | 467 | handlerOnObjectPaid(e.receiver, e.sender, e.amount); |
468 | } | 468 | } |
469 | } | 469 | } |
470 | 470 | ||
471 | if (e.sender != e.receiver) | 471 | if (e.sender != e.receiver) |
472 | { | 472 | { |
473 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender)); | 473 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender)); |
474 | } | 474 | } |
475 | if(receiver != null) | 475 | if(receiver != null) |
476 | { | 476 | { |
477 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(part.OwnerID)); | 477 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(part.OwnerID)); |
478 | } | 478 | } |
479 | } | 479 | } |
480 | return; | 480 | return; |
481 | } | 481 | } |
482 | 482 | ||
483 | sender = LocateClientObject(e.sender); | 483 | sender = LocateClientObject(e.sender); |
484 | if (sender != null) | 484 | if (sender != null) |
485 | { | 485 | { |
486 | receiver = LocateClientObject(e.receiver); | 486 | receiver = LocateClientObject(e.receiver); |
487 | 487 | ||
488 | bool transactionresult = doMoneyTransfer(e.sender, e.receiver, e.amount, e.transactiontype, e.description); | 488 | bool transactionresult = doMoneyTransfer(e.sender, e.receiver, e.amount, e.transactiontype, e.description); |
489 | 489 | ||
490 | if (e.sender != e.receiver) | 490 | if (e.sender != e.receiver) |
491 | { | 491 | { |
492 | if (sender != null) | 492 | if (sender != null) |
493 | { | 493 | { |
494 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender)); | 494 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.sender)); |
495 | } | 495 | } |
496 | } | 496 | } |
497 | 497 | ||
498 | if (receiver != null) | 498 | if (receiver != null) |
499 | { | 499 | { |
500 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.receiver)); | 500 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(e.description), GetFundsForAgentID(e.receiver)); |
501 | } | 501 | } |
502 | } | 502 | } |
503 | else | 503 | else |
504 | { | 504 | { |
505 | m_log.Warn("[MONEY]: Potential Fraud Warning, got money transfer request for avatar that isn't in this simulator - Details; Sender:" + e.sender.ToString() + " Receiver: " + e.receiver.ToString() + " Amount: " + e.amount.ToString()); | 505 | m_log.Warn("[MONEY]: Potential Fraud Warning, got money transfer request for avatar that isn't in this simulator - Details; Sender:" + e.sender.ToString() + " Receiver: " + e.receiver.ToString() + " Amount: " + e.amount.ToString()); |
506 | } | 506 | } |
507 | } | 507 | } |
508 | 508 | ||
509 | /// <summary> | 509 | /// <summary> |
510 | /// Event Handler for when a root agent becomes a child agent | 510 | /// Event Handler for when a root agent becomes a child agent |
511 | /// </summary> | 511 | /// </summary> |
512 | /// <param name="avatar"></param> | 512 | /// <param name="avatar"></param> |
513 | private void MakeChildAgent(ScenePresence avatar) | 513 | private void MakeChildAgent(ScenePresence avatar) |
514 | { | 514 | { |
515 | lock (m_rootAgents) | 515 | lock (m_rootAgents) |
516 | { | 516 | { |
517 | if (m_rootAgents.ContainsKey(avatar.UUID)) | 517 | if (m_rootAgents.ContainsKey(avatar.UUID)) |
518 | { | 518 | { |
519 | if (m_rootAgents[avatar.UUID] == avatar.Scene.RegionInfo.originRegionID) | 519 | if (m_rootAgents[avatar.UUID] == avatar.Scene.RegionInfo.originRegionID) |
520 | { | 520 | { |
521 | m_rootAgents.Remove(avatar.UUID); | 521 | m_rootAgents.Remove(avatar.UUID); |
522 | m_log.Info("[MONEY]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); | 522 | m_log.Info("[MONEY]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); |
523 | } | 523 | } |
524 | 524 | ||
525 | } | 525 | } |
526 | } | 526 | } |
527 | 527 | ||
528 | } | 528 | } |
529 | 529 | ||
530 | /// <summary> | 530 | /// <summary> |
531 | /// Event Handler for when the client logs out. | 531 | /// Event Handler for when the client logs out. |
532 | /// </summary> | 532 | /// </summary> |
533 | /// <param name="AgentId"></param> | 533 | /// <param name="AgentId"></param> |
534 | private void ClientLoggedOut(LLUUID AgentId) | 534 | private void ClientLoggedOut(LLUUID AgentId) |
535 | { | 535 | { |
536 | lock (m_rootAgents) | 536 | lock (m_rootAgents) |
537 | { | 537 | { |
538 | if (m_rootAgents.ContainsKey(AgentId)) | 538 | if (m_rootAgents.ContainsKey(AgentId)) |
539 | { | 539 | { |
540 | m_rootAgents.Remove(AgentId); | 540 | m_rootAgents.Remove(AgentId); |
541 | //m_log.Info("[MONEY]: Removing " + AgentId + ". Agent logged out."); | 541 | //m_log.Info("[MONEY]: Removing " + AgentId + ". Agent logged out."); |
542 | } | 542 | } |
543 | } | 543 | } |
544 | } | 544 | } |
545 | 545 | ||
546 | /// <summary> | 546 | /// <summary> |
547 | /// Call this when the client disconnects. | 547 | /// Call this when the client disconnects. |
548 | /// </summary> | 548 | /// </summary> |
549 | /// <param name="client"></param> | 549 | /// <param name="client"></param> |
550 | public void ClientClosed(IClientAPI client) | 550 | public void ClientClosed(IClientAPI client) |
551 | { | 551 | { |
552 | ClientClosed(client.AgentId); | 552 | ClientClosed(client.AgentId); |
553 | } | 553 | } |
554 | 554 | ||
555 | /// <summary> | 555 | /// <summary> |
556 | /// Event Handler for when an Avatar enters one of the parcels in the simulator. | 556 | /// Event Handler for when an Avatar enters one of the parcels in the simulator. |
557 | /// </summary> | 557 | /// </summary> |
558 | /// <param name="avatar"></param> | 558 | /// <param name="avatar"></param> |
559 | /// <param name="localLandID"></param> | 559 | /// <param name="localLandID"></param> |
560 | /// <param name="regionID"></param> | 560 | /// <param name="regionID"></param> |
561 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) | 561 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) |
562 | { | 562 | { |
563 | lock (m_rootAgents) | 563 | lock (m_rootAgents) |
564 | { | 564 | { |
565 | if (m_rootAgents.ContainsKey(avatar.UUID)) | 565 | if (m_rootAgents.ContainsKey(avatar.UUID)) |
566 | { | 566 | { |
567 | if (avatar.Scene.RegionInfo.originRegionID != m_rootAgents[avatar.UUID]) | 567 | if (avatar.Scene.RegionInfo.originRegionID != m_rootAgents[avatar.UUID]) |
568 | { | 568 | { |
569 | m_rootAgents[avatar.UUID] = avatar.Scene.RegionInfo.originRegionID; | 569 | m_rootAgents[avatar.UUID] = avatar.Scene.RegionInfo.originRegionID; |
570 | //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); | 570 | //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); |
571 | // Claim User! my user! Mine mine mine! | 571 | // Claim User! my user! Mine mine mine! |
572 | if (m_MoneyAddress.Length > 0) | 572 | if (m_MoneyAddress.Length > 0) |
573 | { | 573 | { |
574 | Scene RegionItem = GetSceneByUUID(regionID); | 574 | Scene RegionItem = GetSceneByUUID(regionID); |
575 | if (RegionItem != null) | 575 | if (RegionItem != null) |
576 | { | 576 | { |
577 | Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret); | 577 | Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret); |
578 | if ((bool)hresult["success"] == true) | 578 | if ((bool)hresult["success"] == true) |
579 | { | 579 | { |
580 | int funds = 0; | 580 | int funds = 0; |
581 | try | 581 | try |
582 | { | 582 | { |
583 | funds = (Int32)hresult["funds"]; | 583 | funds = (Int32)hresult["funds"]; |
584 | } | 584 | } |
585 | catch (InvalidCastException) | 585 | catch (InvalidCastException) |
586 | { | 586 | { |
587 | 587 | ||
588 | } | 588 | } |
589 | SetLocalFundsForAgentID(avatar.UUID, funds); | 589 | SetLocalFundsForAgentID(avatar.UUID, funds); |
590 | } | 590 | } |
591 | else | 591 | else |
592 | { | 592 | { |
593 | avatar.ControllingClient.SendAgentAlertMessage((string)hresult["errorMessage"], true); | 593 | avatar.ControllingClient.SendAgentAlertMessage((string)hresult["errorMessage"], true); |
594 | } | 594 | } |
595 | } | 595 | } |
596 | } | 596 | } |
597 | } | 597 | } |
598 | } | 598 | } |
599 | else | 599 | else |
600 | { | 600 | { |
601 | lock (m_rootAgents) | 601 | lock (m_rootAgents) |
602 | { | 602 | { |
603 | m_rootAgents.Add(avatar.UUID, avatar.Scene.RegionInfo.originRegionID); | 603 | m_rootAgents.Add(avatar.UUID, avatar.Scene.RegionInfo.originRegionID); |
604 | } | 604 | } |
605 | if (m_MoneyAddress.Length > 0) | 605 | if (m_MoneyAddress.Length > 0) |
606 | { | 606 | { |
607 | Scene RegionItem = GetSceneByUUID(regionID); | 607 | Scene RegionItem = GetSceneByUUID(regionID); |
608 | if (RegionItem != null) | 608 | if (RegionItem != null) |
609 | { | 609 | { |
610 | Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret); | 610 | Hashtable hresult = claim_user(avatar.UUID, avatar.ControllingClient.SecureSessionId, regionID, RegionItem.RegionInfo.regionSecret); |
611 | if ((bool)hresult["success"] == true) | 611 | if ((bool)hresult["success"] == true) |
612 | { | 612 | { |
613 | int funds = 0; | 613 | int funds = 0; |
614 | try | 614 | try |
615 | { | 615 | { |
616 | funds = (Int32)hresult["funds"]; | 616 | funds = (Int32)hresult["funds"]; |
617 | } | 617 | } |
618 | catch (InvalidCastException) | 618 | catch (InvalidCastException) |
619 | { | 619 | { |
620 | 620 | ||
621 | } | 621 | } |
622 | SetLocalFundsForAgentID(avatar.UUID, funds); | 622 | SetLocalFundsForAgentID(avatar.UUID, funds); |
623 | } | 623 | } |
624 | else | 624 | else |
625 | { | 625 | { |
626 | avatar.ControllingClient.SendAgentAlertMessage((string)hresult["errorMessage"], true); | 626 | avatar.ControllingClient.SendAgentAlertMessage((string)hresult["errorMessage"], true); |
627 | } | 627 | } |
628 | } | 628 | } |
629 | } | 629 | } |
630 | 630 | ||
631 | //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); | 631 | //m_log.Info("[MONEY]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); |
632 | } | 632 | } |
633 | } | 633 | } |
634 | //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); | 634 | //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); |
635 | } | 635 | } |
636 | 636 | ||
637 | #endregion | 637 | #endregion |
638 | 638 | ||
639 | /// <summary> | 639 | /// <summary> |
640 | /// Transfer money | 640 | /// Transfer money |
641 | /// </summary> | 641 | /// </summary> |
642 | /// <param name="Sender"></param> | 642 | /// <param name="Sender"></param> |
643 | /// <param name="Receiver"></param> | 643 | /// <param name="Receiver"></param> |
644 | /// <param name="amount"></param> | 644 | /// <param name="amount"></param> |
645 | /// <returns></returns> | 645 | /// <returns></returns> |
646 | private bool doMoneyTransfer(LLUUID Sender, LLUUID Receiver, int amount, int transactiontype, string description) | 646 | private bool doMoneyTransfer(LLUUID Sender, LLUUID Receiver, int amount, int transactiontype, string description) |
647 | { | 647 | { |
648 | bool result = false; | 648 | bool result = false; |
649 | if (amount >= 0) | 649 | if (amount >= 0) |
650 | { | 650 | { |
651 | lock (m_KnownClientFunds) | 651 | lock (m_KnownClientFunds) |
652 | { | 652 | { |
653 | // If we don't know about the sender, then the sender can't | 653 | // If we don't know about the sender, then the sender can't |
654 | // actually be here and therefore this is likely fraud or outdated. | 654 | // actually be here and therefore this is likely fraud or outdated. |
655 | if (m_MoneyAddress.Length == 0) | 655 | if (m_MoneyAddress.Length == 0) |
656 | { | 656 | { |
657 | if (m_KnownClientFunds.ContainsKey(Sender)) | 657 | if (m_KnownClientFunds.ContainsKey(Sender)) |
658 | { | 658 | { |
659 | // Does the sender have enough funds to give? | 659 | // Does the sender have enough funds to give? |
660 | if (m_KnownClientFunds[Sender] >= amount) | 660 | if (m_KnownClientFunds[Sender] >= amount) |
661 | { | 661 | { |
662 | // Subtract the funds from the senders account | 662 | // Subtract the funds from the senders account |
663 | m_KnownClientFunds[Sender] -= amount; | 663 | m_KnownClientFunds[Sender] -= amount; |
664 | 664 | ||
665 | // do we know about the receiver? | 665 | // do we know about the receiver? |
666 | if (!m_KnownClientFunds.ContainsKey(Receiver)) | 666 | if (!m_KnownClientFunds.ContainsKey(Receiver)) |
667 | { | 667 | { |
668 | // Make a record for them so they get the updated balance when they login | 668 | // Make a record for them so they get the updated balance when they login |
669 | CheckExistAndRefreshFunds(Receiver); | 669 | CheckExistAndRefreshFunds(Receiver); |
670 | } | 670 | } |
671 | if (m_enabled) | 671 | if (m_enabled) |
672 | { | 672 | { |
673 | //Add the amount to the Receiver's funds | 673 | //Add the amount to the Receiver's funds |
674 | m_KnownClientFunds[Receiver] += amount; | 674 | m_KnownClientFunds[Receiver] += amount; |
675 | result = true; | 675 | result = true; |
676 | } | 676 | } |
677 | } | 677 | } |
678 | else | 678 | else |
679 | { | 679 | { |
680 | // These below are redundant to make this clearer to read | 680 | // These below are redundant to make this clearer to read |
681 | result = false; | 681 | result = false; |
682 | } | 682 | } |
683 | } | 683 | } |
684 | else | 684 | else |
685 | { | 685 | { |
686 | result = false; | 686 | result = false; |
687 | } | 687 | } |
688 | } | 688 | } |
689 | else | 689 | else |
690 | { | 690 | { |
691 | result = TransferMoneyonMoneyServer(Sender, Receiver, amount, transactiontype, description); | 691 | result = TransferMoneyonMoneyServer(Sender, Receiver, amount, transactiontype, description); |
692 | } | 692 | } |
693 | } | 693 | } |
694 | } | 694 | } |
695 | return result; | 695 | return result; |
696 | } | 696 | } |
697 | 697 | ||
698 | #region Utility Helpers | 698 | #region Utility Helpers |
699 | /// <summary> | 699 | /// <summary> |
700 | /// Locates a IClientAPI for the client specified | 700 | /// Locates a IClientAPI for the client specified |
701 | /// </summary> | 701 | /// </summary> |
702 | /// <param name="AgentID"></param> | 702 | /// <param name="AgentID"></param> |
703 | /// <returns></returns> | 703 | /// <returns></returns> |
704 | private IClientAPI LocateClientObject(LLUUID AgentID) | 704 | private IClientAPI LocateClientObject(LLUUID AgentID) |
705 | { | 705 | { |
706 | ScenePresence tPresence = null; | 706 | ScenePresence tPresence = null; |
707 | IClientAPI rclient = null; | 707 | IClientAPI rclient = null; |
708 | 708 | ||
709 | lock (m_scenel) | 709 | lock (m_scenel) |
710 | { | 710 | { |
711 | foreach (Scene _scene in m_scenel.Values) | 711 | foreach (Scene _scene in m_scenel.Values) |
712 | { | 712 | { |
713 | tPresence = _scene.GetScenePresence(AgentID); | 713 | tPresence = _scene.GetScenePresence(AgentID); |
714 | if (tPresence != null) | 714 | if (tPresence != null) |
715 | { | 715 | { |
716 | if (!tPresence.IsChildAgent) | 716 | if (!tPresence.IsChildAgent) |
717 | { | 717 | { |
718 | rclient = tPresence.ControllingClient; | 718 | rclient = tPresence.ControllingClient; |
719 | } | 719 | } |
720 | } | 720 | } |
721 | if (rclient != null) | 721 | if (rclient != null) |
722 | { | 722 | { |
723 | return rclient; | 723 | return rclient; |
724 | } | 724 | } |
725 | } | 725 | } |
726 | 726 | ||
727 | } | 727 | } |
728 | return null; | 728 | return null; |
729 | } | 729 | } |
730 | 730 | ||
731 | private Scene LocateSceneClientIn(LLUUID AgentId) | 731 | private Scene LocateSceneClientIn(LLUUID AgentId) |
732 | { | 732 | { |
733 | lock (m_scenel) | 733 | lock (m_scenel) |
734 | { | 734 | { |
735 | foreach (Scene _scene in m_scenel.Values) | 735 | foreach (Scene _scene in m_scenel.Values) |
736 | { | 736 | { |
737 | ScenePresence tPresence = _scene.GetScenePresence(AgentId); | 737 | ScenePresence tPresence = _scene.GetScenePresence(AgentId); |
738 | if (tPresence != null) | 738 | if (tPresence != null) |
739 | { | 739 | { |
740 | if (!tPresence.IsChildAgent) | 740 | if (!tPresence.IsChildAgent) |
741 | { | 741 | { |
742 | return _scene; | 742 | return _scene; |
743 | } | 743 | } |
744 | } | 744 | } |
745 | 745 | ||
746 | } | 746 | } |
747 | 747 | ||
748 | } | 748 | } |
749 | return null; | 749 | return null; |
750 | } | 750 | } |
751 | 751 | ||
752 | /// <summary> | 752 | /// <summary> |
753 | /// Utility function Gets a Random scene in the instance. For when which scene exactly you're doing something with doesn't matter | 753 | /// Utility function Gets a Random scene in the instance. For when which scene exactly you're doing something with doesn't matter |
754 | /// </summary> | 754 | /// </summary> |
755 | /// <returns></returns> | 755 | /// <returns></returns> |
756 | public Scene GetRandomScene() | 756 | public Scene GetRandomScene() |
757 | { | 757 | { |
758 | lock (m_scenel) | 758 | lock (m_scenel) |
759 | { | 759 | { |
760 | foreach (Scene rs in m_scenel.Values) | 760 | foreach (Scene rs in m_scenel.Values) |
761 | return rs; | 761 | return rs; |
762 | } | 762 | } |
763 | return null; | 763 | return null; |
764 | 764 | ||
765 | } | 765 | } |
766 | /// <summary> | 766 | /// <summary> |
767 | /// Utility function to get a Scene by RegionID in a module | 767 | /// Utility function to get a Scene by RegionID in a module |
768 | /// </summary> | 768 | /// </summary> |
769 | /// <param name="RegionID"></param> | 769 | /// <param name="RegionID"></param> |
770 | /// <returns></returns> | 770 | /// <returns></returns> |
771 | public Scene GetSceneByUUID(LLUUID RegionID) | 771 | public Scene GetSceneByUUID(LLUUID RegionID) |
772 | { | 772 | { |
773 | lock (m_scenel) | 773 | lock (m_scenel) |
774 | { | 774 | { |
775 | foreach (Scene rs in m_scenel.Values) | 775 | foreach (Scene rs in m_scenel.Values) |
776 | { | 776 | { |
777 | if (rs.RegionInfo.originRegionID == RegionID) | 777 | if (rs.RegionInfo.originRegionID == RegionID) |
778 | { | 778 | { |
779 | return rs; | 779 | return rs; |
780 | } | 780 | } |
781 | } | 781 | } |
782 | } | 782 | } |
783 | return null; | 783 | return null; |
784 | } | 784 | } |
785 | #endregion | 785 | #endregion |
786 | 786 | ||
787 | 787 | ||
788 | 788 | ||
789 | /// <summary> | 789 | /// <summary> |
790 | /// Sends the the stored money balance to the client | 790 | /// Sends the the stored money balance to the client |
791 | /// </summary> | 791 | /// </summary> |
792 | /// <param name="client"></param> | 792 | /// <param name="client"></param> |
793 | /// <param name="agentID"></param> | 793 | /// <param name="agentID"></param> |
794 | /// <param name="SessionID"></param> | 794 | /// <param name="SessionID"></param> |
795 | /// <param name="TransactionID"></param> | 795 | /// <param name="TransactionID"></param> |
796 | public void SendMoneyBalance(IClientAPI client, LLUUID agentID, LLUUID SessionID, LLUUID TransactionID) | 796 | public void SendMoneyBalance(IClientAPI client, LLUUID agentID, LLUUID SessionID, LLUUID TransactionID) |
797 | { | 797 | { |
798 | if (client.AgentId == agentID && client.SessionId == SessionID) | 798 | if (client.AgentId == agentID && client.SessionId == SessionID) |
799 | { | 799 | { |
800 | int returnfunds = 0; | 800 | int returnfunds = 0; |
801 | 801 | ||
802 | try | 802 | try |
803 | { | 803 | { |
804 | returnfunds = GetFundsForAgentID(agentID); | 804 | returnfunds = GetFundsForAgentID(agentID); |
805 | } | 805 | } |
806 | catch (Exception e) | 806 | catch (Exception e) |
807 | { | 807 | { |
808 | client.SendAlertMessage(e.Message + " "); | 808 | client.SendAlertMessage(e.Message + " "); |
809 | } | 809 | } |
810 | 810 | ||
811 | client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds); | 811 | client.SendMoneyBalance(TransactionID, true, new byte[0], returnfunds); |
812 | } | 812 | } |
813 | else | 813 | else |
814 | { | 814 | { |
815 | client.SendAlertMessage("Unable to send your money balance to you!"); | 815 | client.SendAlertMessage("Unable to send your money balance to you!"); |
816 | } | 816 | } |
817 | } | 817 | } |
818 | 818 | ||
819 | #region local Fund Management | 819 | #region local Fund Management |
820 | /// <summary> | 820 | /// <summary> |
821 | /// Ensures that the agent accounting data is set up in this instance. | 821 | /// Ensures that the agent accounting data is set up in this instance. |
822 | /// </summary> | 822 | /// </summary> |
823 | /// <param name="agentID"></param> | 823 | /// <param name="agentID"></param> |
824 | private void CheckExistAndRefreshFunds(LLUUID agentID) | 824 | private void CheckExistAndRefreshFunds(LLUUID agentID) |
825 | { | 825 | { |
826 | lock (m_KnownClientFunds) | 826 | lock (m_KnownClientFunds) |
827 | { | 827 | { |
828 | if (!m_KnownClientFunds.ContainsKey(agentID)) | 828 | if (!m_KnownClientFunds.ContainsKey(agentID)) |
829 | { | 829 | { |
830 | m_KnownClientFunds.Add(agentID, m_stipend); | 830 | m_KnownClientFunds.Add(agentID, m_stipend); |
831 | } | 831 | } |
832 | else | 832 | else |
833 | { | 833 | { |
834 | if (m_KnownClientFunds[agentID] <= m_minFundsBeforeRefresh) | 834 | if (m_KnownClientFunds[agentID] <= m_minFundsBeforeRefresh) |
835 | { | 835 | { |
836 | m_KnownClientFunds[agentID] = m_stipend; | 836 | m_KnownClientFunds[agentID] = m_stipend; |
837 | } | 837 | } |
838 | } | 838 | } |
839 | } | 839 | } |
840 | } | 840 | } |
841 | /// <summary> | 841 | /// <summary> |
842 | /// Gets the amount of Funds for an agent | 842 | /// Gets the amount of Funds for an agent |
843 | /// </summary> | 843 | /// </summary> |
844 | /// <param name="AgentID"></param> | 844 | /// <param name="AgentID"></param> |
845 | /// <returns></returns> | 845 | /// <returns></returns> |
846 | private int GetFundsForAgentID(LLUUID AgentID) | 846 | private int GetFundsForAgentID(LLUUID AgentID) |
847 | { | 847 | { |
848 | int returnfunds = 0; | 848 | int returnfunds = 0; |
849 | lock (m_KnownClientFunds) | 849 | lock (m_KnownClientFunds) |
850 | { | 850 | { |
851 | if (m_KnownClientFunds.ContainsKey(AgentID)) | 851 | if (m_KnownClientFunds.ContainsKey(AgentID)) |
852 | { | 852 | { |
853 | returnfunds = m_KnownClientFunds[AgentID]; | 853 | returnfunds = m_KnownClientFunds[AgentID]; |
854 | } | 854 | } |
855 | else | 855 | else |
856 | { | 856 | { |
857 | //throw new Exception("Unable to get funds."); | 857 | //throw new Exception("Unable to get funds."); |
858 | } | 858 | } |
859 | } | 859 | } |
860 | return returnfunds; | 860 | return returnfunds; |
861 | } | 861 | } |
862 | private void SetLocalFundsForAgentID(LLUUID AgentID, int amount) | 862 | private void SetLocalFundsForAgentID(LLUUID AgentID, int amount) |
863 | { | 863 | { |
864 | lock (m_KnownClientFunds) | 864 | lock (m_KnownClientFunds) |
865 | { | 865 | { |
866 | if (m_KnownClientFunds.ContainsKey(AgentID)) | 866 | if (m_KnownClientFunds.ContainsKey(AgentID)) |
867 | { | 867 | { |
868 | m_KnownClientFunds[AgentID] = amount; | 868 | m_KnownClientFunds[AgentID] = amount; |
869 | } | 869 | } |
870 | else | 870 | else |
871 | { | 871 | { |
872 | m_KnownClientFunds.Add(AgentID, amount); | 872 | m_KnownClientFunds.Add(AgentID, amount); |
873 | } | 873 | } |
874 | } | 874 | } |
875 | 875 | ||
876 | } | 876 | } |
877 | 877 | ||
878 | #endregion | 878 | #endregion |
879 | 879 | ||
880 | /// <summary> | 880 | /// <summary> |
881 | /// Gets the current balance for the user from the Grid Money Server | 881 | /// Gets the current balance for the user from the Grid Money Server |
882 | /// </summary> | 882 | /// </summary> |
883 | /// <param name="agentId"></param> | 883 | /// <param name="agentId"></param> |
884 | /// <param name="secureSessionID"></param> | 884 | /// <param name="secureSessionID"></param> |
885 | /// <param name="regionId"></param> | 885 | /// <param name="regionId"></param> |
886 | /// <param name="regionSecret"></param> | 886 | /// <param name="regionSecret"></param> |
887 | /// <returns></returns> | 887 | /// <returns></returns> |
888 | public Hashtable GetBalanceForUserFromMoneyServer(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret) | 888 | public Hashtable GetBalanceForUserFromMoneyServer(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret) |
889 | { | 889 | { |
890 | 890 | ||
891 | Hashtable MoneyBalanceRequestParams = new Hashtable(); | 891 | Hashtable MoneyBalanceRequestParams = new Hashtable(); |
892 | MoneyBalanceRequestParams["agentId"] = agentId.ToString(); | 892 | MoneyBalanceRequestParams["agentId"] = agentId.ToString(); |
893 | MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString(); | 893 | MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString(); |
894 | MoneyBalanceRequestParams["regionId"] = regionId.ToString(); | 894 | MoneyBalanceRequestParams["regionId"] = regionId.ToString(); |
895 | MoneyBalanceRequestParams["secret"] = regionSecret; | 895 | MoneyBalanceRequestParams["secret"] = regionSecret; |
896 | MoneyBalanceRequestParams["currencySecret"] = ""; // per - region/user currency secret gotten from the money system | 896 | MoneyBalanceRequestParams["currencySecret"] = ""; // per - region/user currency secret gotten from the money system |
897 | 897 | ||
898 | Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorUserBalanceRequest"); | 898 | Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorUserBalanceRequest"); |
899 | 899 | ||
900 | return MoneyRespData; | 900 | return MoneyRespData; |
901 | } | 901 | } |
902 | 902 | ||
903 | 903 | ||
904 | 904 | ||
905 | /// <summary> | 905 | /// <summary> |
906 | /// Generic XMLRPC client abstraction | 906 | /// Generic XMLRPC client abstraction |
907 | /// </summary> | 907 | /// </summary> |
908 | /// <param name="ReqParams">Hashtable containing parameters to the method</param> | 908 | /// <param name="ReqParams">Hashtable containing parameters to the method</param> |
909 | /// <param name="method">Method to invoke</param> | 909 | /// <param name="method">Method to invoke</param> |
910 | /// <returns>Hashtable with success=>bool and other values</returns> | 910 | /// <returns>Hashtable with success=>bool and other values</returns> |
911 | public Hashtable genericCurrencyXMLRPCRequest(Hashtable ReqParams, string method) | 911 | public Hashtable genericCurrencyXMLRPCRequest(Hashtable ReqParams, string method) |
912 | { | 912 | { |
913 | ArrayList SendParams = new ArrayList(); | 913 | ArrayList SendParams = new ArrayList(); |
914 | SendParams.Add(ReqParams); | 914 | SendParams.Add(ReqParams); |
915 | // Send Request | 915 | // Send Request |
916 | XmlRpcResponse MoneyResp; | 916 | XmlRpcResponse MoneyResp; |
917 | try | 917 | try |
918 | { | 918 | { |
919 | XmlRpcRequest BalanceRequestReq = new XmlRpcRequest(method, SendParams); | 919 | XmlRpcRequest BalanceRequestReq = new XmlRpcRequest(method, SendParams); |
920 | MoneyResp = BalanceRequestReq.Send(m_MoneyAddress, 30000); | 920 | MoneyResp = BalanceRequestReq.Send(m_MoneyAddress, 30000); |
921 | } | 921 | } |
922 | catch (WebException ex) | 922 | catch (WebException ex) |
923 | { | 923 | { |
924 | 924 | ||
925 | m_log.ErrorFormat( | 925 | m_log.ErrorFormat( |
926 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", | 926 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", |
927 | m_MoneyAddress, ex); | 927 | m_MoneyAddress, ex); |
928 | 928 | ||
929 | Hashtable ErrorHash = new Hashtable(); | 929 | Hashtable ErrorHash = new Hashtable(); |
930 | ErrorHash["success"] = false; | 930 | ErrorHash["success"] = false; |
931 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; | 931 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; |
932 | ErrorHash["errorURI"] = ""; | 932 | ErrorHash["errorURI"] = ""; |
933 | 933 | ||
934 | return ErrorHash; | 934 | return ErrorHash; |
935 | //throw (ex); | 935 | //throw (ex); |
936 | } | 936 | } |
937 | catch (SocketException ex) | 937 | catch (SocketException ex) |
938 | { | 938 | { |
939 | 939 | ||
940 | m_log.ErrorFormat( | 940 | m_log.ErrorFormat( |
941 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", | 941 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", |
942 | m_MoneyAddress, ex); | 942 | m_MoneyAddress, ex); |
943 | 943 | ||
944 | Hashtable ErrorHash = new Hashtable(); | 944 | Hashtable ErrorHash = new Hashtable(); |
945 | ErrorHash["success"] = false; | 945 | ErrorHash["success"] = false; |
946 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; | 946 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; |
947 | ErrorHash["errorURI"] = ""; | 947 | ErrorHash["errorURI"] = ""; |
948 | 948 | ||
949 | return ErrorHash; | 949 | return ErrorHash; |
950 | //throw (ex); | 950 | //throw (ex); |
951 | } | 951 | } |
952 | catch (XmlException ex) | 952 | catch (XmlException ex) |
953 | { | 953 | { |
954 | m_log.ErrorFormat( | 954 | m_log.ErrorFormat( |
955 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", | 955 | "[MONEY]: Unable to connect to Money Server {0}. Exception {1}", |
956 | m_MoneyAddress, ex); | 956 | m_MoneyAddress, ex); |
957 | 957 | ||
958 | Hashtable ErrorHash = new Hashtable(); | 958 | Hashtable ErrorHash = new Hashtable(); |
959 | ErrorHash["success"] = false; | 959 | ErrorHash["success"] = false; |
960 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; | 960 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; |
961 | ErrorHash["errorURI"] = ""; | 961 | ErrorHash["errorURI"] = ""; |
962 | 962 | ||
963 | return ErrorHash; | 963 | return ErrorHash; |
964 | 964 | ||
965 | } | 965 | } |
966 | if (MoneyResp.IsFault) | 966 | if (MoneyResp.IsFault) |
967 | { | 967 | { |
968 | Hashtable ErrorHash = new Hashtable(); | 968 | Hashtable ErrorHash = new Hashtable(); |
969 | ErrorHash["success"] = false; | 969 | ErrorHash["success"] = false; |
970 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; | 970 | ErrorHash["errorMessage"] = "Unable to manage your money at this time. Purchases may be unavailable"; |
971 | ErrorHash["errorURI"] = ""; | 971 | ErrorHash["errorURI"] = ""; |
972 | 972 | ||
973 | return ErrorHash; | 973 | return ErrorHash; |
974 | 974 | ||
975 | } | 975 | } |
976 | Hashtable MoneyRespData = (Hashtable)MoneyResp.Value; | 976 | Hashtable MoneyRespData = (Hashtable)MoneyResp.Value; |
977 | 977 | ||
978 | return MoneyRespData; | 978 | return MoneyRespData; |
979 | } | 979 | } |
980 | /// <summary> | 980 | /// <summary> |
981 | /// This informs the Money Grid Server that the avatar is in this simulator | 981 | /// This informs the Money Grid Server that the avatar is in this simulator |
982 | /// </summary> | 982 | /// </summary> |
983 | /// <param name="agentId"></param> | 983 | /// <param name="agentId"></param> |
984 | /// <param name="secureSessionID"></param> | 984 | /// <param name="secureSessionID"></param> |
985 | /// <param name="regionId"></param> | 985 | /// <param name="regionId"></param> |
986 | /// <param name="regionSecret"></param> | 986 | /// <param name="regionSecret"></param> |
987 | /// <returns></returns> | 987 | /// <returns></returns> |
988 | public Hashtable claim_user(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret) | 988 | public Hashtable claim_user(LLUUID agentId, LLUUID secureSessionID, LLUUID regionId, string regionSecret) |
989 | { | 989 | { |
990 | 990 | ||
991 | Hashtable MoneyBalanceRequestParams = new Hashtable(); | 991 | Hashtable MoneyBalanceRequestParams = new Hashtable(); |
992 | MoneyBalanceRequestParams["agentId"] = agentId.ToString(); | 992 | MoneyBalanceRequestParams["agentId"] = agentId.ToString(); |
993 | MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString(); | 993 | MoneyBalanceRequestParams["secureSessionId"] = secureSessionID.ToString(); |
994 | MoneyBalanceRequestParams["regionId"] = regionId.ToString(); | 994 | MoneyBalanceRequestParams["regionId"] = regionId.ToString(); |
995 | MoneyBalanceRequestParams["secret"] = regionSecret; | 995 | MoneyBalanceRequestParams["secret"] = regionSecret; |
996 | 996 | ||
997 | Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorClaimUserRequest"); | 997 | Hashtable MoneyRespData = genericCurrencyXMLRPCRequest(MoneyBalanceRequestParams, "simulatorClaimUserRequest"); |
998 | IClientAPI sendMoneyBal = LocateClientObject(agentId); | 998 | IClientAPI sendMoneyBal = LocateClientObject(agentId); |
999 | if (sendMoneyBal != null) | 999 | if (sendMoneyBal != null) |
1000 | { | 1000 | { |
1001 | SendMoneyBalance(sendMoneyBal, agentId, sendMoneyBal.SessionId, LLUUID.Zero); | 1001 | SendMoneyBalance(sendMoneyBal, agentId, sendMoneyBal.SessionId, LLUUID.Zero); |
1002 | } | 1002 | } |
1003 | return MoneyRespData; | 1003 | return MoneyRespData; |
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | private SceneObjectPart findPrim(LLUUID objectID) | 1006 | private SceneObjectPart findPrim(LLUUID objectID) |
1007 | { | 1007 | { |
1008 | lock (m_scenel) | 1008 | lock (m_scenel) |
1009 | { | 1009 | { |
1010 | foreach (Scene s in m_scenel.Values) | 1010 | foreach (Scene s in m_scenel.Values) |
1011 | { | 1011 | { |
1012 | SceneObjectPart part=s.GetSceneObjectPart(objectID); | 1012 | SceneObjectPart part=s.GetSceneObjectPart(objectID); |
1013 | if(part != null) | 1013 | if(part != null) |
1014 | { | 1014 | { |
1015 | return part; | 1015 | return part; |
1016 | } | 1016 | } |
1017 | } | 1017 | } |
1018 | } | 1018 | } |
1019 | return null; | 1019 | return null; |
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | private string resolveObjectName(LLUUID objectID) | 1022 | private string resolveObjectName(LLUUID objectID) |
1023 | { | 1023 | { |
1024 | SceneObjectPart part=findPrim(objectID); | 1024 | SceneObjectPart part=findPrim(objectID); |
1025 | if(part != null) | 1025 | if(part != null) |
1026 | { | 1026 | { |
1027 | return part.Name; | 1027 | return part.Name; |
1028 | } | 1028 | } |
1029 | return String.Empty; | 1029 | return String.Empty; |
1030 | } | 1030 | } |
1031 | 1031 | ||
1032 | private string resolveAgentName(LLUUID agentID) | 1032 | private string resolveAgentName(LLUUID agentID) |
1033 | { | 1033 | { |
1034 | // try avatar username surname | 1034 | // try avatar username surname |
1035 | Scene scene=GetRandomScene(); | 1035 | Scene scene=GetRandomScene(); |
1036 | UserProfileData profile = scene.CommsManager.UserService.GetUserProfile(agentID); | 1036 | UserProfileData profile = scene.CommsManager.UserService.GetUserProfile(agentID); |
1037 | if (profile != null) | 1037 | if (profile != null) |
1038 | { | 1038 | { |
1039 | string avatarname = profile.FirstName + " " + profile.SurName; | 1039 | string avatarname = profile.FirstName + " " + profile.SurName; |
1040 | return avatarname; | 1040 | return avatarname; |
1041 | } | 1041 | } |
1042 | return String.Empty; | 1042 | return String.Empty; |
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | public bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount) | 1045 | public bool ObjectGiveMoney(LLUUID objectID, LLUUID fromID, LLUUID toID, int amount) |
1046 | { | 1046 | { |
1047 | string description=String.Format("Object {0} pays {1}", resolveObjectName(objectID), resolveAgentName(toID)); | 1047 | string description=String.Format("Object {0} pays {1}", resolveObjectName(objectID), resolveAgentName(toID)); |
1048 | 1048 | ||
1049 | bool give_result = doMoneyTransfer(fromID, toID, amount, 2, description); | 1049 | bool give_result = doMoneyTransfer(fromID, toID, amount, 2, description); |
1050 | 1050 | ||
1051 | if (m_MoneyAddress.Length == 0) | 1051 | if (m_MoneyAddress.Length == 0) |
1052 | BalanceUpdate(fromID, toID, give_result, description); | 1052 | BalanceUpdate(fromID, toID, give_result, description); |
1053 | 1053 | ||
1054 | return give_result; | 1054 | return give_result; |
1055 | 1055 | ||
1056 | 1056 | ||
1057 | } | 1057 | } |
1058 | private void BalanceUpdate(LLUUID senderID, LLUUID receiverID, bool transactionresult, string description) | 1058 | private void BalanceUpdate(LLUUID senderID, LLUUID receiverID, bool transactionresult, string description) |
1059 | { | 1059 | { |
1060 | IClientAPI sender = LocateClientObject(senderID); | 1060 | IClientAPI sender = LocateClientObject(senderID); |
1061 | IClientAPI receiver = LocateClientObject(receiverID); | 1061 | IClientAPI receiver = LocateClientObject(receiverID); |
1062 | 1062 | ||
1063 | if (senderID != receiverID) | 1063 | if (senderID != receiverID) |
1064 | { | 1064 | { |
1065 | if (sender != null) | 1065 | if (sender != null) |
1066 | { | 1066 | { |
1067 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(senderID)); | 1067 | sender.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(senderID)); |
1068 | } | 1068 | } |
1069 | 1069 | ||
1070 | if (receiver != null) | 1070 | if (receiver != null) |
1071 | { | 1071 | { |
1072 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(receiverID)); | 1072 | receiver.SendMoneyBalance(LLUUID.Random(), transactionresult, Helpers.StringToField(description), GetFundsForAgentID(receiverID)); |
1073 | } | 1073 | } |
1074 | } | 1074 | } |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | /// <summary> | 1077 | /// <summary> |
1078 | /// Informs the Money Grid Server of a transfer. | 1078 | /// Informs the Money Grid Server of a transfer. |
1079 | /// </summary> | 1079 | /// </summary> |
1080 | /// <param name="sourceId"></param> | 1080 | /// <param name="sourceId"></param> |
1081 | /// <param name="destId"></param> | 1081 | /// <param name="destId"></param> |
1082 | /// <param name="amount"></param> | 1082 | /// <param name="amount"></param> |
1083 | /// <returns></returns> | 1083 | /// <returns></returns> |
1084 | public bool TransferMoneyonMoneyServer(LLUUID sourceId, LLUUID destId, int amount, int transactiontype, string description) | 1084 | public bool TransferMoneyonMoneyServer(LLUUID sourceId, LLUUID destId, int amount, int transactiontype, string description) |
1085 | { | 1085 | { |
1086 | int aggregatePermInventory = 0; | 1086 | int aggregatePermInventory = 0; |
1087 | int aggregatePermNextOwner = 0; | 1087 | int aggregatePermNextOwner = 0; |
1088 | int flags = 0; | 1088 | int flags = 0; |
1089 | bool rvalue = false; | 1089 | bool rvalue = false; |
1090 | 1090 | ||
1091 | IClientAPI cli = LocateClientObject(sourceId); | 1091 | IClientAPI cli = LocateClientObject(sourceId); |
1092 | if (cli != null) | 1092 | if (cli != null) |
1093 | { | 1093 | { |
1094 | 1094 | ||
1095 | Scene userScene = null; | 1095 | Scene userScene = null; |
1096 | lock (m_rootAgents) | 1096 | lock (m_rootAgents) |
1097 | { | 1097 | { |
1098 | userScene = GetSceneByUUID(m_rootAgents[sourceId]); | 1098 | userScene = GetSceneByUUID(m_rootAgents[sourceId]); |
1099 | } | 1099 | } |
1100 | if (userScene != null) | 1100 | if (userScene != null) |
1101 | { | 1101 | { |
1102 | Hashtable ht = new Hashtable(); | 1102 | Hashtable ht = new Hashtable(); |
1103 | ht["agentId"] = sourceId.ToString(); | 1103 | ht["agentId"] = sourceId.ToString(); |
1104 | ht["secureSessionId"] = cli.SecureSessionId.ToString(); | 1104 | ht["secureSessionId"] = cli.SecureSessionId.ToString(); |
1105 | ht["regionId"] = userScene.RegionInfo.originRegionID.ToString(); | 1105 | ht["regionId"] = userScene.RegionInfo.originRegionID.ToString(); |
1106 | ht["secret"] = userScene.RegionInfo.regionSecret; | 1106 | ht["secret"] = userScene.RegionInfo.regionSecret; |
1107 | ht["currencySecret"] = " "; | 1107 | ht["currencySecret"] = " "; |
1108 | ht["destId"] = destId.ToString(); | 1108 | ht["destId"] = destId.ToString(); |
1109 | ht["cash"] = amount; | 1109 | ht["cash"] = amount; |
1110 | ht["aggregatePermInventory"] = aggregatePermInventory; | 1110 | ht["aggregatePermInventory"] = aggregatePermInventory; |
1111 | ht["aggregatePermNextOwner"] = aggregatePermNextOwner; | 1111 | ht["aggregatePermNextOwner"] = aggregatePermNextOwner; |
1112 | ht["flags"] = flags; | 1112 | ht["flags"] = flags; |
1113 | ht["transactionType"] = transactiontype; | 1113 | ht["transactionType"] = transactiontype; |
1114 | ht["description"] = description; | 1114 | ht["description"] = description; |
1115 | 1115 | ||
1116 | Hashtable hresult = genericCurrencyXMLRPCRequest(ht, "regionMoveMoney"); | 1116 | Hashtable hresult = genericCurrencyXMLRPCRequest(ht, "regionMoveMoney"); |
1117 | 1117 | ||
1118 | if ((bool)hresult["success"] == true) | 1118 | if ((bool)hresult["success"] == true) |
1119 | { | 1119 | { |
1120 | int funds1 = 0; | 1120 | int funds1 = 0; |
1121 | int funds2 = 0; | 1121 | int funds2 = 0; |
1122 | try | 1122 | try |
1123 | { | 1123 | { |
1124 | funds1 = (Int32)hresult["funds"]; | 1124 | funds1 = (Int32)hresult["funds"]; |
1125 | } | 1125 | } |
1126 | catch(InvalidCastException) | 1126 | catch(InvalidCastException) |
1127 | { | 1127 | { |
1128 | funds1 = 0; | 1128 | funds1 = 0; |
1129 | } | 1129 | } |
1130 | SetLocalFundsForAgentID(sourceId, funds1); | 1130 | SetLocalFundsForAgentID(sourceId, funds1); |
1131 | if (m_KnownClientFunds.ContainsKey(destId)) | 1131 | if (m_KnownClientFunds.ContainsKey(destId)) |
1132 | { | 1132 | { |
1133 | try | 1133 | try |
1134 | { | 1134 | { |
1135 | funds2 = (Int32)hresult["funds2"]; | 1135 | funds2 = (Int32)hresult["funds2"]; |
1136 | } | 1136 | } |
1137 | catch (InvalidCastException) | 1137 | catch (InvalidCastException) |
1138 | { | 1138 | { |
1139 | funds2 = 0; | 1139 | funds2 = 0; |
1140 | } | 1140 | } |
1141 | SetLocalFundsForAgentID(destId, funds2); | 1141 | SetLocalFundsForAgentID(destId, funds2); |
1142 | } | 1142 | } |
1143 | 1143 | ||
1144 | 1144 | ||
1145 | rvalue = true; | 1145 | rvalue = true; |
1146 | } | 1146 | } |
1147 | else | 1147 | else |
1148 | { | 1148 | { |
1149 | cli.SendAgentAlertMessage((string)hresult["errorMessage"], true); | 1149 | cli.SendAgentAlertMessage((string)hresult["errorMessage"], true); |
1150 | } | 1150 | } |
1151 | 1151 | ||
1152 | } | 1152 | } |
1153 | } | 1153 | } |
1154 | else | 1154 | else |
1155 | { | 1155 | { |
1156 | m_log.ErrorFormat("[MONEY]: Client {0} not found", sourceId.ToString()); | 1156 | m_log.ErrorFormat("[MONEY]: Client {0} not found", sourceId.ToString()); |
1157 | } | 1157 | } |
1158 | 1158 | ||
1159 | return rvalue; | 1159 | return rvalue; |
1160 | 1160 | ||
1161 | } | 1161 | } |
1162 | 1162 | ||
1163 | public int GetRemoteBalance(LLUUID agentId) | 1163 | public int GetRemoteBalance(LLUUID agentId) |
1164 | { | 1164 | { |
1165 | int funds = 0; | 1165 | int funds = 0; |
1166 | 1166 | ||
1167 | IClientAPI aClient = LocateClientObject(agentId); | 1167 | IClientAPI aClient = LocateClientObject(agentId); |
1168 | if (aClient != null) | 1168 | if (aClient != null) |
1169 | { | 1169 | { |
1170 | Scene s = LocateSceneClientIn(agentId); | 1170 | Scene s = LocateSceneClientIn(agentId); |
1171 | if (s != null) | 1171 | if (s != null) |
1172 | { | 1172 | { |
1173 | if (m_MoneyAddress.Length > 0) | 1173 | if (m_MoneyAddress.Length > 0) |
1174 | { | 1174 | { |
1175 | Hashtable hbinfo = GetBalanceForUserFromMoneyServer(aClient.AgentId, aClient.SecureSessionId, s.RegionInfo.originRegionID.ToString(), s.RegionInfo.regionSecret); | 1175 | Hashtable hbinfo = GetBalanceForUserFromMoneyServer(aClient.AgentId, aClient.SecureSessionId, s.RegionInfo.originRegionID.ToString(), s.RegionInfo.regionSecret); |
1176 | if ((bool)hbinfo["success"] == true) | 1176 | if ((bool)hbinfo["success"] == true) |
1177 | { | 1177 | { |
1178 | try | 1178 | try |
1179 | { | 1179 | { |
1180 | funds = (Int32)hbinfo["funds"]; | 1180 | funds = (Int32)hbinfo["funds"]; |
1181 | } | 1181 | } |
1182 | catch (ArgumentException) | 1182 | catch (ArgumentException) |
1183 | { | 1183 | { |
1184 | } | 1184 | } |
1185 | catch (FormatException) | 1185 | catch (FormatException) |
1186 | { | 1186 | { |
1187 | } | 1187 | } |
1188 | catch (OverflowException) | 1188 | catch (OverflowException) |
1189 | { | 1189 | { |
1190 | m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentId); | 1190 | m_log.ErrorFormat("[MONEY]: While getting the Currency for user {0}, the return funds overflowed.", agentId); |
1191 | aClient.SendAlertMessage("Unable to get your money balance, money operations will be unavailable"); | 1191 | aClient.SendAlertMessage("Unable to get your money balance, money operations will be unavailable"); |
1192 | } | 1192 | } |
1193 | catch (InvalidCastException) | 1193 | catch (InvalidCastException) |
1194 | { | 1194 | { |
1195 | funds = 0; | 1195 | funds = 0; |
1196 | } | 1196 | } |
1197 | 1197 | ||
1198 | } | 1198 | } |
1199 | else | 1199 | else |
1200 | { | 1200 | { |
1201 | m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentId, (string)hbinfo["errorMessage"]); | 1201 | m_log.WarnFormat("[MONEY]: Getting Money for user {0} failed with the following message:{1}", agentId, (string)hbinfo["errorMessage"]); |
1202 | aClient.SendAlertMessage((string)hbinfo["errorMessage"]); | 1202 | aClient.SendAlertMessage((string)hbinfo["errorMessage"]); |
1203 | } | 1203 | } |
1204 | } | 1204 | } |
1205 | 1205 | ||
1206 | SetLocalFundsForAgentID(agentId, funds); | 1206 | SetLocalFundsForAgentID(agentId, funds); |
1207 | SendMoneyBalance(aClient, agentId, aClient.SessionId, LLUUID.Zero); | 1207 | SendMoneyBalance(aClient, agentId, aClient.SessionId, LLUUID.Zero); |
1208 | } | 1208 | } |
1209 | else | 1209 | else |
1210 | { | 1210 | { |
1211 | m_log.Debug("[MONEY]: Got balance request update for agent that is here, but couldn't find which scene."); | 1211 | m_log.Debug("[MONEY]: Got balance request update for agent that is here, but couldn't find which scene."); |
1212 | } | 1212 | } |
1213 | } | 1213 | } |
1214 | else | 1214 | else |
1215 | { | 1215 | { |
1216 | m_log.Debug("[MONEY]: Got balance request update for agent that isn't here."); | 1216 | m_log.Debug("[MONEY]: Got balance request update for agent that isn't here."); |
1217 | } | 1217 | } |
1218 | return funds; | 1218 | return funds; |
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | public XmlRpcResponse GridMoneyUpdate(XmlRpcRequest request) | 1221 | public XmlRpcResponse GridMoneyUpdate(XmlRpcRequest request) |
1222 | { | 1222 | { |
1223 | m_log.Debug("[MONEY]: Dynamic balance update called."); | 1223 | m_log.Debug("[MONEY]: Dynamic balance update called."); |
1224 | Hashtable requestData = (Hashtable)request.Params[0]; | 1224 | Hashtable requestData = (Hashtable)request.Params[0]; |
1225 | 1225 | ||
1226 | if (requestData.ContainsKey("agentId")) | 1226 | if (requestData.ContainsKey("agentId")) |
1227 | { | 1227 | { |
1228 | LLUUID agentId = LLUUID.Zero; | 1228 | LLUUID agentId = LLUUID.Zero; |
1229 | 1229 | ||
1230 | Helpers.TryParse((string)requestData["agentId"], out agentId); | 1230 | Helpers.TryParse((string)requestData["agentId"], out agentId); |
1231 | if (agentId != LLUUID.Zero) | 1231 | if (agentId != LLUUID.Zero) |
1232 | { | 1232 | { |
1233 | GetRemoteBalance(agentId); | 1233 | GetRemoteBalance(agentId); |
1234 | 1234 | ||
1235 | } | 1235 | } |
1236 | else | 1236 | else |
1237 | { | 1237 | { |
1238 | m_log.Debug("[MONEY]: invalid agentId specified, dropping."); | 1238 | m_log.Debug("[MONEY]: invalid agentId specified, dropping."); |
1239 | } | 1239 | } |
1240 | } | 1240 | } |
1241 | else | 1241 | else |
1242 | { | 1242 | { |
1243 | m_log.Debug("[MONEY]: no agentId specified, dropping."); | 1243 | m_log.Debug("[MONEY]: no agentId specified, dropping."); |
1244 | } | 1244 | } |
1245 | XmlRpcResponse r = new XmlRpcResponse(); | 1245 | XmlRpcResponse r = new XmlRpcResponse(); |
1246 | Hashtable rparms = new Hashtable(); | 1246 | Hashtable rparms = new Hashtable(); |
1247 | rparms["success"] = true; | 1247 | rparms["success"] = true; |
1248 | 1248 | ||
1249 | r.Value = rparms; | 1249 | r.Value = rparms; |
1250 | return r; | 1250 | return r; |
1251 | } | 1251 | } |
1252 | 1252 | ||
1253 | /// <summary> | 1253 | /// <summary> |
1254 | /// XMLRPC handler to send alert message and sound to client | 1254 | /// XMLRPC handler to send alert message and sound to client |
1255 | /// </summary> | 1255 | /// </summary> |
1256 | public XmlRpcResponse UserAlert(XmlRpcRequest request) | 1256 | public XmlRpcResponse UserAlert(XmlRpcRequest request) |
1257 | { | 1257 | { |
1258 | XmlRpcResponse ret = new XmlRpcResponse(); | 1258 | XmlRpcResponse ret = new XmlRpcResponse(); |
1259 | Hashtable retparam = new Hashtable(); | 1259 | Hashtable retparam = new Hashtable(); |
1260 | Hashtable requestData = (Hashtable)request.Params[0]; | 1260 | Hashtable requestData = (Hashtable)request.Params[0]; |
1261 | 1261 | ||
1262 | LLUUID agentId = LLUUID.Zero; | 1262 | LLUUID agentId = LLUUID.Zero; |
1263 | LLUUID soundId = LLUUID.Zero; | 1263 | LLUUID soundId = LLUUID.Zero; |
1264 | 1264 | ||
1265 | Helpers.TryParse((string)requestData["agentId"], out agentId); | 1265 | Helpers.TryParse((string)requestData["agentId"], out agentId); |
1266 | Helpers.TryParse((string)requestData["soundId"], out soundId); | 1266 | Helpers.TryParse((string)requestData["soundId"], out soundId); |
1267 | string text=(string)requestData["text"]; | 1267 | string text=(string)requestData["text"]; |
1268 | string secret=(string)requestData["secret"]; | 1268 | string secret=(string)requestData["secret"]; |
1269 | 1269 | ||
1270 | Scene userScene = GetRandomScene(); | 1270 | Scene userScene = GetRandomScene(); |
1271 | if(userScene.RegionInfo.regionSecret.ToString() == secret) | 1271 | if(userScene.RegionInfo.regionSecret.ToString() == secret) |
1272 | { | 1272 | { |
1273 | IClientAPI client = LocateClientObject(agentId); | 1273 | IClientAPI client = LocateClientObject(agentId); |
1274 | 1274 | ||
1275 | if (client != null) | 1275 | if (client != null) |
1276 | { | 1276 | { |
1277 | if(soundId != LLUUID.Zero) | 1277 | if(soundId != LLUUID.Zero) |
1278 | client.SendPlayAttachedSound(soundId, LLUUID.Zero, LLUUID.Zero, 1.0f, 0); | 1278 | client.SendPlayAttachedSound(soundId, LLUUID.Zero, LLUUID.Zero, 1.0f, 0); |
1279 | client.SendBlueBoxMessage(LLUUID.Zero, LLUUID.Zero, "", text); | 1279 | client.SendBlueBoxMessage(LLUUID.Zero, LLUUID.Zero, "", text); |
1280 | retparam.Add("success", true); | 1280 | retparam.Add("success", true); |
1281 | } | 1281 | } |
1282 | else | 1282 | else |
1283 | { | 1283 | { |
1284 | retparam.Add("success", false); | 1284 | retparam.Add("success", false); |
1285 | } | 1285 | } |
1286 | } | 1286 | } |
1287 | else | 1287 | else |
1288 | { | 1288 | { |
1289 | retparam.Add("success", false); | 1289 | retparam.Add("success", false); |
1290 | } | 1290 | } |
1291 | ret.Value = retparam; | 1291 | ret.Value = retparam; |
1292 | 1292 | ||
1293 | return ret; | 1293 | return ret; |
1294 | } | 1294 | } |
1295 | 1295 | ||
1296 | 1296 | ||
1297 | # region Standalone box enablers only | 1297 | # region Standalone box enablers only |
1298 | 1298 | ||
1299 | public XmlRpcResponse quote_func(XmlRpcRequest request) | 1299 | public XmlRpcResponse quote_func(XmlRpcRequest request) |
1300 | { | 1300 | { |
1301 | Hashtable requestData = (Hashtable)request.Params[0]; | 1301 | Hashtable requestData = (Hashtable)request.Params[0]; |
1302 | LLUUID agentId = LLUUID.Zero; | 1302 | LLUUID agentId = LLUUID.Zero; |
1303 | int amount = 0; | 1303 | int amount = 0; |
1304 | Hashtable quoteResponse = new Hashtable(); | 1304 | Hashtable quoteResponse = new Hashtable(); |
1305 | XmlRpcResponse returnval = new XmlRpcResponse(); | 1305 | XmlRpcResponse returnval = new XmlRpcResponse(); |
1306 | 1306 | ||
1307 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) | 1307 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) |
1308 | { | 1308 | { |
1309 | Helpers.TryParse((string)requestData["agentId"], out agentId); | 1309 | Helpers.TryParse((string)requestData["agentId"], out agentId); |
1310 | try | 1310 | try |
1311 | { | 1311 | { |
1312 | amount = (Int32)requestData["currencyBuy"]; | 1312 | amount = (Int32)requestData["currencyBuy"]; |
1313 | } | 1313 | } |
1314 | catch (InvalidCastException) | 1314 | catch (InvalidCastException) |
1315 | { | 1315 | { |
1316 | 1316 | ||
1317 | } | 1317 | } |
1318 | Hashtable currencyResponse = new Hashtable(); | 1318 | Hashtable currencyResponse = new Hashtable(); |
1319 | currencyResponse.Add("estimatedCost", 0); | 1319 | currencyResponse.Add("estimatedCost", 0); |
1320 | currencyResponse.Add("currencyBuy", amount); | 1320 | currencyResponse.Add("currencyBuy", amount); |
1321 | 1321 | ||
1322 | quoteResponse.Add("success", true); | 1322 | quoteResponse.Add("success", true); |
1323 | quoteResponse.Add("currency", currencyResponse); | 1323 | quoteResponse.Add("currency", currencyResponse); |
1324 | quoteResponse.Add("confirm", "asdfad9fj39ma9fj"); | 1324 | quoteResponse.Add("confirm", "asdfad9fj39ma9fj"); |
1325 | 1325 | ||
1326 | returnval.Value = quoteResponse; | 1326 | returnval.Value = quoteResponse; |
1327 | return returnval; | 1327 | return returnval; |
1328 | } | 1328 | } |
1329 | 1329 | ||
1330 | 1330 | ||
1331 | 1331 | ||
1332 | quoteResponse.Add("success", false); | 1332 | quoteResponse.Add("success", false); |
1333 | quoteResponse.Add("errorMessage", "Invalid parameters passed to the quote box"); | 1333 | quoteResponse.Add("errorMessage", "Invalid parameters passed to the quote box"); |
1334 | quoteResponse.Add("errorURI", "http://www.opensimulator.org/wiki"); | 1334 | quoteResponse.Add("errorURI", "http://www.opensimulator.org/wiki"); |
1335 | returnval.Value = quoteResponse; | 1335 | returnval.Value = quoteResponse; |
1336 | return returnval; | 1336 | return returnval; |
1337 | } | 1337 | } |
1338 | public XmlRpcResponse buy_func(XmlRpcRequest request) | 1338 | public XmlRpcResponse buy_func(XmlRpcRequest request) |
1339 | { | 1339 | { |
1340 | 1340 | ||
1341 | Hashtable requestData = (Hashtable)request.Params[0]; | 1341 | Hashtable requestData = (Hashtable)request.Params[0]; |
1342 | LLUUID agentId = LLUUID.Zero; | 1342 | LLUUID agentId = LLUUID.Zero; |
1343 | int amount = 0; | 1343 | int amount = 0; |
1344 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) | 1344 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) |
1345 | { | 1345 | { |
1346 | Helpers.TryParse((string)requestData["agentId"], out agentId); | 1346 | Helpers.TryParse((string)requestData["agentId"], out agentId); |
1347 | try | 1347 | try |
1348 | { | 1348 | { |
1349 | amount = (Int32)requestData["currencyBuy"]; | 1349 | amount = (Int32)requestData["currencyBuy"]; |
1350 | } | 1350 | } |
1351 | catch (InvalidCastException) | 1351 | catch (InvalidCastException) |
1352 | { | 1352 | { |
1353 | 1353 | ||
1354 | } | 1354 | } |
1355 | if (agentId != LLUUID.Zero) | 1355 | if (agentId != LLUUID.Zero) |
1356 | { | 1356 | { |
1357 | lock (m_KnownClientFunds) | 1357 | lock (m_KnownClientFunds) |
1358 | { | 1358 | { |
1359 | if (m_KnownClientFunds.ContainsKey(agentId)) | 1359 | if (m_KnownClientFunds.ContainsKey(agentId)) |
1360 | { | 1360 | { |
1361 | m_KnownClientFunds[agentId] += amount; | 1361 | m_KnownClientFunds[agentId] += amount; |
1362 | } | 1362 | } |
1363 | else | 1363 | else |
1364 | { | 1364 | { |
1365 | m_KnownClientFunds.Add(agentId, amount); | 1365 | m_KnownClientFunds.Add(agentId, amount); |
1366 | } | 1366 | } |
1367 | } | 1367 | } |
1368 | IClientAPI client = LocateClientObject(agentId); | 1368 | IClientAPI client = LocateClientObject(agentId); |
1369 | if (client != null) | 1369 | if (client != null) |
1370 | { | 1370 | { |
1371 | SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero); | 1371 | SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero); |
1372 | } | 1372 | } |
1373 | } | 1373 | } |
1374 | } | 1374 | } |
1375 | XmlRpcResponse returnval = new XmlRpcResponse(); | 1375 | XmlRpcResponse returnval = new XmlRpcResponse(); |
1376 | Hashtable returnresp = new Hashtable(); | 1376 | Hashtable returnresp = new Hashtable(); |
1377 | returnresp.Add("success", true); | 1377 | returnresp.Add("success", true); |
1378 | returnval.Value = returnresp; | 1378 | returnval.Value = returnresp; |
1379 | return returnval; | 1379 | return returnval; |
1380 | } | 1380 | } |
1381 | 1381 | ||
1382 | public XmlRpcResponse preflightBuyLandPrep_func(XmlRpcRequest request) | 1382 | public XmlRpcResponse preflightBuyLandPrep_func(XmlRpcRequest request) |
1383 | { | 1383 | { |
1384 | XmlRpcResponse ret = new XmlRpcResponse(); | 1384 | XmlRpcResponse ret = new XmlRpcResponse(); |
1385 | Hashtable retparam = new Hashtable(); | 1385 | Hashtable retparam = new Hashtable(); |
1386 | Hashtable membershiplevels = new Hashtable(); | 1386 | Hashtable membershiplevels = new Hashtable(); |
1387 | ArrayList levels = new ArrayList(); | 1387 | ArrayList levels = new ArrayList(); |
1388 | Hashtable level = new Hashtable(); | 1388 | Hashtable level = new Hashtable(); |
1389 | level.Add("id", "00000000-0000-0000-0000-000000000000"); | 1389 | level.Add("id", "00000000-0000-0000-0000-000000000000"); |
1390 | level.Add("description", "some level"); | 1390 | level.Add("description", "some level"); |
1391 | levels.Add(level); | 1391 | levels.Add(level); |
1392 | //membershiplevels.Add("levels",levels); | 1392 | //membershiplevels.Add("levels",levels); |
1393 | 1393 | ||
1394 | Hashtable landuse = new Hashtable(); | 1394 | Hashtable landuse = new Hashtable(); |
1395 | landuse.Add("upgrade", false); | 1395 | landuse.Add("upgrade", false); |
1396 | landuse.Add("action", "http://invaliddomaininvalid.com/"); | 1396 | landuse.Add("action", "http://invaliddomaininvalid.com/"); |
1397 | 1397 | ||
1398 | Hashtable currency = new Hashtable(); | 1398 | Hashtable currency = new Hashtable(); |
1399 | currency.Add("estimatedCost", 0); | 1399 | currency.Add("estimatedCost", 0); |
1400 | 1400 | ||
1401 | Hashtable membership = new Hashtable(); | 1401 | Hashtable membership = new Hashtable(); |
1402 | membershiplevels.Add("upgrade", false); | 1402 | membershiplevels.Add("upgrade", false); |
1403 | membershiplevels.Add("action", "http://invaliddomaininvalid.com/"); | 1403 | membershiplevels.Add("action", "http://invaliddomaininvalid.com/"); |
1404 | membershiplevels.Add("levels", membershiplevels); | 1404 | membershiplevels.Add("levels", membershiplevels); |
1405 | 1405 | ||
1406 | retparam.Add("success", true); | 1406 | retparam.Add("success", true); |
1407 | retparam.Add("currency", currency); | 1407 | retparam.Add("currency", currency); |
1408 | retparam.Add("membership", membership); | 1408 | retparam.Add("membership", membership); |
1409 | retparam.Add("landuse", landuse); | 1409 | retparam.Add("landuse", landuse); |
1410 | retparam.Add("confirm", "asdfajsdkfjasdkfjalsdfjasdf"); | 1410 | retparam.Add("confirm", "asdfajsdkfjasdkfjalsdfjasdf"); |
1411 | 1411 | ||
1412 | ret.Value = retparam; | 1412 | ret.Value = retparam; |
1413 | 1413 | ||
1414 | return ret; | 1414 | return ret; |
1415 | 1415 | ||
1416 | } | 1416 | } |
1417 | public XmlRpcResponse landBuy_func(XmlRpcRequest request) | 1417 | public XmlRpcResponse landBuy_func(XmlRpcRequest request) |
1418 | { | 1418 | { |
1419 | XmlRpcResponse ret = new XmlRpcResponse(); | 1419 | XmlRpcResponse ret = new XmlRpcResponse(); |
1420 | Hashtable retparam = new Hashtable(); | 1420 | Hashtable retparam = new Hashtable(); |
1421 | Hashtable requestData = (Hashtable)request.Params[0]; | 1421 | Hashtable requestData = (Hashtable)request.Params[0]; |
1422 | 1422 | ||
1423 | LLUUID agentId = LLUUID.Zero; | 1423 | LLUUID agentId = LLUUID.Zero; |
1424 | int amount = 0; | 1424 | int amount = 0; |
1425 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) | 1425 | if (requestData.ContainsKey("agentId") && requestData.ContainsKey("currencyBuy")) |
1426 | { | 1426 | { |
1427 | Helpers.TryParse((string)requestData["agentId"], out agentId); | 1427 | Helpers.TryParse((string)requestData["agentId"], out agentId); |
1428 | try | 1428 | try |
1429 | { | 1429 | { |
1430 | amount = (Int32)requestData["currencyBuy"]; | 1430 | amount = (Int32)requestData["currencyBuy"]; |
1431 | } | 1431 | } |
1432 | catch (InvalidCastException) | 1432 | catch (InvalidCastException) |
1433 | { | 1433 | { |
1434 | 1434 | ||
1435 | } | 1435 | } |
1436 | if (agentId != LLUUID.Zero) | 1436 | if (agentId != LLUUID.Zero) |
1437 | { | 1437 | { |
1438 | lock (m_KnownClientFunds) | 1438 | lock (m_KnownClientFunds) |
1439 | { | 1439 | { |
1440 | if (m_KnownClientFunds.ContainsKey(agentId)) | 1440 | if (m_KnownClientFunds.ContainsKey(agentId)) |
1441 | { | 1441 | { |
1442 | m_KnownClientFunds[agentId] += amount; | 1442 | m_KnownClientFunds[agentId] += amount; |
1443 | } | 1443 | } |
1444 | else | 1444 | else |
1445 | { | 1445 | { |
1446 | m_KnownClientFunds.Add(agentId, amount); | 1446 | m_KnownClientFunds.Add(agentId, amount); |
1447 | } | 1447 | } |
1448 | } | 1448 | } |
1449 | IClientAPI client = LocateClientObject(agentId); | 1449 | IClientAPI client = LocateClientObject(agentId); |
1450 | if (client != null) | 1450 | if (client != null) |
1451 | { | 1451 | { |
1452 | SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero); | 1452 | SendMoneyBalance(client, agentId, client.SessionId, LLUUID.Zero); |
1453 | } | 1453 | } |
1454 | } | 1454 | } |
1455 | } | 1455 | } |
1456 | retparam.Add("success", true); | 1456 | retparam.Add("success", true); |
1457 | ret.Value = retparam; | 1457 | ret.Value = retparam; |
1458 | 1458 | ||
1459 | return ret; | 1459 | return ret; |
1460 | 1460 | ||
1461 | } | 1461 | } |
1462 | #endregion | 1462 | #endregion |
1463 | 1463 | ||
1464 | public void PostInitialise() | 1464 | public void PostInitialise() |
1465 | { | 1465 | { |
1466 | } | 1466 | } |
1467 | 1467 | ||
1468 | public void Close() | 1468 | public void Close() |
1469 | { | 1469 | { |
1470 | } | 1470 | } |
1471 | 1471 | ||
1472 | public string Name | 1472 | public string Name |
1473 | { | 1473 | { |
1474 | get { return "BetaGridLikeMoneyModule"; } | 1474 | get { return "BetaGridLikeMoneyModule"; } |
1475 | } | 1475 | } |
1476 | 1476 | ||
1477 | public bool IsSharedModule | 1477 | public bool IsSharedModule |
1478 | { | 1478 | { |
1479 | get { return true; } | 1479 | get { return true; } |
1480 | } | 1480 | } |
1481 | } | 1481 | } |
1482 | public enum TransactionType : int | 1482 | |
1483 | { | 1483 | public enum TransactionType : int |
1484 | SystemGenerated=0, | 1484 | { |
1485 | RegionMoneyRequest=1, | 1485 | SystemGenerated=0, |
1486 | Gift=2, | 1486 | RegionMoneyRequest=1, |
1487 | Purchase=3 | 1487 | Gift=2, |
1488 | 1488 | Purchase=3 | |
1489 | } | 1489 | |
1490 | } | 1490 | } |
1491 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/Environment/Modules/FriendsModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs index 7078906..3b0cc4c 100644 --- a/OpenSim/Region/Environment/Modules/FriendsModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs | |||
@@ -1,504 +1,504 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | 27 | using System; |
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using libsecondlife.Packets; | 31 | using libsecondlife.Packets; |
32 | using log4net; | 32 | using log4net; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using Nwc.XmlRpc; | 34 | using Nwc.XmlRpc; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Region.Environment.Interfaces; | 36 | using OpenSim.Region.Environment.Interfaces; |
37 | using OpenSim.Region.Environment.Scenes; | 37 | using OpenSim.Region.Environment.Scenes; |
38 | 38 | ||
39 | namespace OpenSim.Region.Environment.Modules | 39 | namespace OpenSim.Region.Environment.Modules.Avatar.Friends |
40 | { | 40 | { |
41 | public class FriendsModule : IRegionModule | 41 | public class FriendsModule : IRegionModule |
42 | { | 42 | { |
43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 43 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
44 | 44 | ||
45 | private List<Scene> m_scene = new List<Scene>(); | 45 | private List<Scene> m_scene = new List<Scene>(); |
46 | 46 | ||
47 | Dictionary<LLUUID, ulong> m_rootAgents = new Dictionary<LLUUID, ulong>(); | 47 | Dictionary<LLUUID, ulong> m_rootAgents = new Dictionary<LLUUID, ulong>(); |
48 | 48 | ||
49 | Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>(); | 49 | Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>(); |
50 | 50 | ||
51 | Dictionary<LLUUID, List<FriendListItem>> FriendLists = new Dictionary<LLUUID, List<FriendListItem>>(); | 51 | Dictionary<LLUUID, List<FriendListItem>> FriendLists = new Dictionary<LLUUID, List<FriendListItem>>(); |
52 | 52 | ||
53 | public void Initialise(Scene scene, IConfigSource config) | 53 | public void Initialise(Scene scene, IConfigSource config) |
54 | { | 54 | { |
55 | lock (m_scene) | 55 | lock (m_scene) |
56 | { | 56 | { |
57 | if (m_scene.Count == 0) | 57 | if (m_scene.Count == 0) |
58 | { | 58 | { |
59 | scene.AddXmlRPCHandler("presence_update", processPresenceUpdate); | 59 | scene.AddXmlRPCHandler("presence_update", processPresenceUpdate); |
60 | } | 60 | } |
61 | 61 | ||
62 | if (!m_scene.Contains(scene)) | 62 | if (!m_scene.Contains(scene)) |
63 | m_scene.Add(scene); | 63 | m_scene.Add(scene); |
64 | } | 64 | } |
65 | scene.EventManager.OnNewClient += OnNewClient; | 65 | scene.EventManager.OnNewClient += OnNewClient; |
66 | scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage; | 66 | scene.EventManager.OnGridInstantMessageToFriendsModule += OnGridInstantMessage; |
67 | scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; | 67 | scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; |
68 | scene.EventManager.OnMakeChildAgent += MakeChildAgent; | 68 | scene.EventManager.OnMakeChildAgent += MakeChildAgent; |
69 | scene.EventManager.OnClientClosed += ClientLoggedOut; | 69 | scene.EventManager.OnClientClosed += ClientLoggedOut; |
70 | } | 70 | } |
71 | public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req) | 71 | public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req) |
72 | { | 72 | { |
73 | m_log.Info("[FRIENDS]: Got Notification about a user! OMG"); | 73 | m_log.Info("[FRIENDS]: Got Notification about a user! OMG"); |
74 | return new XmlRpcResponse(); | 74 | return new XmlRpcResponse(); |
75 | } | 75 | } |
76 | private void OnNewClient(IClientAPI client) | 76 | private void OnNewClient(IClientAPI client) |
77 | { | 77 | { |
78 | // All friends establishment protocol goes over instant message | 78 | // All friends establishment protocol goes over instant message |
79 | // There's no way to send a message from the sim | 79 | // There's no way to send a message from the sim |
80 | // to a user to 'add a friend' without causing dialog box spam | 80 | // to a user to 'add a friend' without causing dialog box spam |
81 | // | 81 | // |
82 | // The base set of friends are added when the user signs on in their XMLRPC response | 82 | // The base set of friends are added when the user signs on in their XMLRPC response |
83 | // Generated by LoginService. The friends are retreived from the database by the UserManager | 83 | // Generated by LoginService. The friends are retreived from the database by the UserManager |
84 | 84 | ||
85 | // Subscribe to instant messages | 85 | // Subscribe to instant messages |
86 | 86 | ||
87 | client.OnInstantMessage += OnInstantMessage; | 87 | client.OnInstantMessage += OnInstantMessage; |
88 | client.OnApproveFriendRequest += OnApprovedFriendRequest; | 88 | client.OnApproveFriendRequest += OnApprovedFriendRequest; |
89 | client.OnDenyFriendRequest += OnDenyFriendRequest; | 89 | client.OnDenyFriendRequest += OnDenyFriendRequest; |
90 | client.OnTerminateFriendship += OnTerminateFriendship; | 90 | client.OnTerminateFriendship += OnTerminateFriendship; |
91 | 91 | ||
92 | List<FriendListItem> fl = new List<FriendListItem>(); | 92 | List<FriendListItem> fl = new List<FriendListItem>(); |
93 | 93 | ||
94 | //bool addFLback = false; | 94 | //bool addFLback = false; |
95 | 95 | ||
96 | lock (FriendLists) | 96 | lock (FriendLists) |
97 | { | 97 | { |
98 | if (FriendLists.ContainsKey(client.AgentId)) | 98 | if (FriendLists.ContainsKey(client.AgentId)) |
99 | { | 99 | { |
100 | fl = FriendLists[client.AgentId]; | 100 | fl = FriendLists[client.AgentId]; |
101 | } | 101 | } |
102 | else | 102 | else |
103 | { | 103 | { |
104 | fl = m_scene[0].GetFriendList(client.AgentId); | 104 | fl = m_scene[0].GetFriendList(client.AgentId); |
105 | 105 | ||
106 | //lock (FriendLists) | 106 | //lock (FriendLists) |
107 | //{ | 107 | //{ |
108 | if (!FriendLists.ContainsKey(client.AgentId)) | 108 | if (!FriendLists.ContainsKey(client.AgentId)) |
109 | FriendLists.Add(client.AgentId, fl); | 109 | FriendLists.Add(client.AgentId, fl); |
110 | //} | 110 | //} |
111 | } | 111 | } |
112 | } | 112 | } |
113 | 113 | ||
114 | List<LLUUID> UpdateUsers = new List<LLUUID>(); | 114 | List<LLUUID> UpdateUsers = new List<LLUUID>(); |
115 | 115 | ||
116 | foreach (FriendListItem f in fl) | 116 | foreach (FriendListItem f in fl) |
117 | { | 117 | { |
118 | if (m_rootAgents.ContainsKey(f.Friend)) | 118 | if (m_rootAgents.ContainsKey(f.Friend)) |
119 | { | 119 | { |
120 | if (f.onlinestatus == false) | 120 | if (f.onlinestatus == false) |
121 | { | 121 | { |
122 | UpdateUsers.Add(f.Friend); | 122 | UpdateUsers.Add(f.Friend); |
123 | f.onlinestatus = true; | 123 | f.onlinestatus = true; |
124 | } | 124 | } |
125 | } | 125 | } |
126 | } | 126 | } |
127 | foreach (LLUUID user in UpdateUsers) | 127 | foreach (LLUUID user in UpdateUsers) |
128 | { | 128 | { |
129 | ScenePresence av = GetPresenceFromAgentID(user); | 129 | ScenePresence av = GetPresenceFromAgentID(user); |
130 | if (av != null) | 130 | if (av != null) |
131 | { | 131 | { |
132 | List<FriendListItem> usrfl = new List<FriendListItem>(); | 132 | List<FriendListItem> usrfl = new List<FriendListItem>(); |
133 | 133 | ||
134 | lock (FriendLists) | 134 | lock (FriendLists) |
135 | { | 135 | { |
136 | usrfl = FriendLists[user]; | 136 | usrfl = FriendLists[user]; |
137 | } | 137 | } |
138 | 138 | ||
139 | lock (usrfl) | 139 | lock (usrfl) |
140 | { | 140 | { |
141 | foreach (FriendListItem fli in usrfl) | 141 | foreach (FriendListItem fli in usrfl) |
142 | { | 142 | { |
143 | if (fli.Friend == client.AgentId) | 143 | if (fli.Friend == client.AgentId) |
144 | { | 144 | { |
145 | fli.onlinestatus = true; | 145 | fli.onlinestatus = true; |
146 | OnlineNotificationPacket onp = new OnlineNotificationPacket(); | 146 | OnlineNotificationPacket onp = new OnlineNotificationPacket(); |
147 | OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[1]; | 147 | OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[1]; |
148 | OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); | 148 | OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); |
149 | onpbl.AgentID = client.AgentId; | 149 | onpbl.AgentID = client.AgentId; |
150 | onpb[0] = onpbl; | 150 | onpb[0] = onpbl; |
151 | onp.AgentBlock = onpb; | 151 | onp.AgentBlock = onpb; |
152 | av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); | 152 | av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); |
153 | } | 153 | } |
154 | } | 154 | } |
155 | } | 155 | } |
156 | } | 156 | } |
157 | } | 157 | } |
158 | 158 | ||
159 | if (UpdateUsers.Count > 0) | 159 | if (UpdateUsers.Count > 0) |
160 | { | 160 | { |
161 | OnlineNotificationPacket onp = new OnlineNotificationPacket(); | 161 | OnlineNotificationPacket onp = new OnlineNotificationPacket(); |
162 | OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[UpdateUsers.Count]; | 162 | OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[UpdateUsers.Count]; |
163 | for (int i = 0; i < UpdateUsers.Count; i++) | 163 | for (int i = 0; i < UpdateUsers.Count; i++) |
164 | { | 164 | { |
165 | OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); | 165 | OnlineNotificationPacket.AgentBlockBlock onpbl = new OnlineNotificationPacket.AgentBlockBlock(); |
166 | onpbl.AgentID = UpdateUsers[i]; | 166 | onpbl.AgentID = UpdateUsers[i]; |
167 | onpb[i] = onpbl; | 167 | onpb[i] = onpbl; |
168 | } | 168 | } |
169 | onp.AgentBlock = onpb; | 169 | onp.AgentBlock = onpb; |
170 | client.OutPacket(onp, ThrottleOutPacketType.Task); | 170 | client.OutPacket(onp, ThrottleOutPacketType.Task); |
171 | } | 171 | } |
172 | 172 | ||
173 | 173 | ||
174 | 174 | ||
175 | 175 | ||
176 | } | 176 | } |
177 | 177 | ||
178 | private void ClientLoggedOut(LLUUID AgentId) | 178 | private void ClientLoggedOut(LLUUID AgentId) |
179 | { | 179 | { |
180 | lock (m_rootAgents) | 180 | lock (m_rootAgents) |
181 | { | 181 | { |
182 | if (m_rootAgents.ContainsKey(AgentId)) | 182 | if (m_rootAgents.ContainsKey(AgentId)) |
183 | { | 183 | { |
184 | m_rootAgents.Remove(AgentId); | 184 | m_rootAgents.Remove(AgentId); |
185 | m_log.Info("[FRIEND]: Removing " + AgentId + ". Agent logged out."); | 185 | m_log.Info("[FRIEND]: Removing " + AgentId + ". Agent logged out."); |
186 | } | 186 | } |
187 | } | 187 | } |
188 | List<FriendListItem> lfli = new List<FriendListItem>(); | 188 | List<FriendListItem> lfli = new List<FriendListItem>(); |
189 | lock (FriendLists) | 189 | lock (FriendLists) |
190 | { | 190 | { |
191 | if (FriendLists.ContainsKey(AgentId)) | 191 | if (FriendLists.ContainsKey(AgentId)) |
192 | { | 192 | { |
193 | lfli = FriendLists[AgentId]; | 193 | lfli = FriendLists[AgentId]; |
194 | } | 194 | } |
195 | } | 195 | } |
196 | List<LLUUID> updateUsers = new List<LLUUID>(); | 196 | List<LLUUID> updateUsers = new List<LLUUID>(); |
197 | foreach (FriendListItem fli in lfli) | 197 | foreach (FriendListItem fli in lfli) |
198 | { | 198 | { |
199 | if (fli.onlinestatus == true) | 199 | if (fli.onlinestatus == true) |
200 | { | 200 | { |
201 | updateUsers.Add(fli.Friend); | 201 | updateUsers.Add(fli.Friend); |
202 | } | 202 | } |
203 | } | 203 | } |
204 | lock (updateUsers) | 204 | lock (updateUsers) |
205 | { | 205 | { |
206 | for (int i = 0; i < updateUsers.Count; i++) | 206 | for (int i = 0; i < updateUsers.Count; i++) |
207 | { | 207 | { |
208 | List<FriendListItem> flfli = new List<FriendListItem>(); | 208 | List<FriendListItem> flfli = new List<FriendListItem>(); |
209 | try | 209 | try |
210 | { | 210 | { |
211 | 211 | ||
212 | lock (FriendLists) | 212 | lock (FriendLists) |
213 | { | 213 | { |
214 | if (FriendLists.ContainsKey(updateUsers[i])) | 214 | if (FriendLists.ContainsKey(updateUsers[i])) |
215 | flfli = FriendLists[updateUsers[i]]; | 215 | flfli = FriendLists[updateUsers[i]]; |
216 | } | 216 | } |
217 | } | 217 | } |
218 | catch (IndexOutOfRangeException) | 218 | catch (IndexOutOfRangeException) |
219 | { | 219 | { |
220 | // Ignore the index out of range exception. | 220 | // Ignore the index out of range exception. |
221 | // This causes friend lists to get out of sync slightly.. however | 221 | // This causes friend lists to get out of sync slightly.. however |
222 | // prevents a sim crash. | 222 | // prevents a sim crash. |
223 | m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); | 223 | m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); |
224 | } | 224 | } |
225 | 225 | ||
226 | for (int j = 0; j < flfli.Count; j++) | 226 | for (int j = 0; j < flfli.Count; j++) |
227 | { | 227 | { |
228 | try | 228 | try |
229 | { | 229 | { |
230 | if (flfli[i].Friend == AgentId) | 230 | if (flfli[i].Friend == AgentId) |
231 | { | 231 | { |
232 | flfli[i].onlinestatus = false; | 232 | flfli[i].onlinestatus = false; |
233 | } | 233 | } |
234 | 234 | ||
235 | } | 235 | } |
236 | 236 | ||
237 | catch (IndexOutOfRangeException) | 237 | catch (IndexOutOfRangeException) |
238 | { | 238 | { |
239 | // Ignore the index out of range exception. | 239 | // Ignore the index out of range exception. |
240 | // This causes friend lists to get out of sync slightly.. however | 240 | // This causes friend lists to get out of sync slightly.. however |
241 | // prevents a sim crash. | 241 | // prevents a sim crash. |
242 | m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); | 242 | m_log.Info("[FRIEND]: Unable to enumerate last friendlist user. User logged off"); |
243 | } | 243 | } |
244 | } | 244 | } |
245 | 245 | ||
246 | } | 246 | } |
247 | 247 | ||
248 | for (int i = 0; i < updateUsers.Count; i++) | 248 | for (int i = 0; i < updateUsers.Count; i++) |
249 | { | 249 | { |
250 | ScenePresence av = GetPresenceFromAgentID(updateUsers[i]); | 250 | ScenePresence av = GetPresenceFromAgentID(updateUsers[i]); |
251 | if (av != null) | 251 | if (av != null) |
252 | { | 252 | { |
253 | 253 | ||
254 | OfflineNotificationPacket onp = new OfflineNotificationPacket(); | 254 | OfflineNotificationPacket onp = new OfflineNotificationPacket(); |
255 | OfflineNotificationPacket.AgentBlockBlock[] onpb = new OfflineNotificationPacket.AgentBlockBlock[1]; | 255 | OfflineNotificationPacket.AgentBlockBlock[] onpb = new OfflineNotificationPacket.AgentBlockBlock[1]; |
256 | OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); | 256 | OfflineNotificationPacket.AgentBlockBlock onpbl = new OfflineNotificationPacket.AgentBlockBlock(); |
257 | onpbl.AgentID = AgentId; | 257 | onpbl.AgentID = AgentId; |
258 | onpb[0] = onpbl; | 258 | onpb[0] = onpbl; |
259 | onp.AgentBlock = onpb; | 259 | onp.AgentBlock = onpb; |
260 | av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); | 260 | av.ControllingClient.OutPacket(onp, ThrottleOutPacketType.Task); |
261 | } | 261 | } |
262 | } | 262 | } |
263 | } | 263 | } |
264 | lock (FriendLists) | 264 | lock (FriendLists) |
265 | { | 265 | { |
266 | FriendLists.Remove(AgentId); | 266 | FriendLists.Remove(AgentId); |
267 | } | 267 | } |
268 | 268 | ||
269 | } | 269 | } |
270 | 270 | ||
271 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) | 271 | private void AvatarEnteringParcel(ScenePresence avatar, int localLandID, LLUUID regionID) |
272 | { | 272 | { |
273 | lock (m_rootAgents) | 273 | lock (m_rootAgents) |
274 | { | 274 | { |
275 | if (m_rootAgents.ContainsKey(avatar.UUID)) | 275 | if (m_rootAgents.ContainsKey(avatar.UUID)) |
276 | { | 276 | { |
277 | if (avatar.RegionHandle != m_rootAgents[avatar.UUID]) | 277 | if (avatar.RegionHandle != m_rootAgents[avatar.UUID]) |
278 | { | 278 | { |
279 | m_rootAgents[avatar.UUID] = avatar.RegionHandle; | 279 | m_rootAgents[avatar.UUID] = avatar.RegionHandle; |
280 | m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); | 280 | m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); |
281 | if (avatar.JID.Length > 0) | 281 | if (avatar.JID.Length > 0) |
282 | { | 282 | { |
283 | JId avatarID = new JId(avatar.JID); | 283 | JId avatarID = new JId(avatar.JID); |
284 | // REST Post XMPP Stanzas! | 284 | // REST Post XMPP Stanzas! |
285 | 285 | ||
286 | } | 286 | } |
287 | // Claim User! my user! Mine mine mine! | 287 | // Claim User! my user! Mine mine mine! |
288 | } | 288 | } |
289 | } | 289 | } |
290 | else | 290 | else |
291 | { | 291 | { |
292 | m_rootAgents.Add(avatar.UUID, avatar.RegionHandle); | 292 | m_rootAgents.Add(avatar.UUID, avatar.RegionHandle); |
293 | m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); | 293 | m_log.Info("[FRIEND]: Claiming " + avatar.Firstname + " " + avatar.Lastname + " in region:" + avatar.RegionHandle + "."); |
294 | } | 294 | } |
295 | } | 295 | } |
296 | //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); | 296 | //m_log.Info("[FRIEND]: " + avatar.Name + " status:" + (!avatar.IsChildAgent).ToString()); |
297 | } | 297 | } |
298 | private void MakeChildAgent(ScenePresence avatar) | 298 | private void MakeChildAgent(ScenePresence avatar) |
299 | { | 299 | { |
300 | 300 | ||
301 | lock (m_rootAgents) | 301 | lock (m_rootAgents) |
302 | { | 302 | { |
303 | if (m_rootAgents.ContainsKey(avatar.UUID)) | 303 | if (m_rootAgents.ContainsKey(avatar.UUID)) |
304 | { | 304 | { |
305 | if (m_rootAgents[avatar.UUID] == avatar.RegionHandle) | 305 | if (m_rootAgents[avatar.UUID] == avatar.RegionHandle) |
306 | { | 306 | { |
307 | m_rootAgents.Remove(avatar.UUID); | 307 | m_rootAgents.Remove(avatar.UUID); |
308 | m_log.Info("[FRIEND]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); | 308 | m_log.Info("[FRIEND]: Removing " + avatar.Firstname + " " + avatar.Lastname + " as a root agent"); |
309 | } | 309 | } |
310 | 310 | ||
311 | } | 311 | } |
312 | } | 312 | } |
313 | 313 | ||
314 | } | 314 | } |
315 | #region FriendRequestHandling | 315 | #region FriendRequestHandling |
316 | private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID, | 316 | private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID, |
317 | LLUUID fromAgentSession, LLUUID toAgentID, | 317 | LLUUID fromAgentSession, LLUUID toAgentID, |
318 | LLUUID imSessionID, uint timestamp, string fromAgentName, | 318 | LLUUID imSessionID, uint timestamp, string fromAgentName, |
319 | string message, byte dialog, bool fromGroup, byte offline, | 319 | string message, byte dialog, bool fromGroup, byte offline, |
320 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, | 320 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, |
321 | byte[] binaryBucket) | 321 | byte[] binaryBucket) |
322 | { | 322 | { |
323 | // Friend Requests go by Instant Message.. using the dialog param | 323 | // Friend Requests go by Instant Message.. using the dialog param |
324 | // https://wiki.secondlife.com/wiki/ImprovedInstantMessage | 324 | // https://wiki.secondlife.com/wiki/ImprovedInstantMessage |
325 | 325 | ||
326 | // 38 == Offer friendship | 326 | // 38 == Offer friendship |
327 | if (dialog == (byte)38) | 327 | if (dialog == (byte)38) |
328 | { | 328 | { |
329 | LLUUID friendTransactionID = LLUUID.Random(); | 329 | LLUUID friendTransactionID = LLUUID.Random(); |
330 | 330 | ||
331 | m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); | 331 | m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); |
332 | 332 | ||
333 | m_log.Info("[FRIEND]: 38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message); | 333 | m_log.Info("[FRIEND]: 38 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message); |
334 | GridInstantMessage msg = new GridInstantMessage(); | 334 | GridInstantMessage msg = new GridInstantMessage(); |
335 | msg.fromAgentID = fromAgentID.UUID; | 335 | msg.fromAgentID = fromAgentID.UUID; |
336 | msg.fromAgentSession = fromAgentSession.UUID; | 336 | msg.fromAgentSession = fromAgentSession.UUID; |
337 | msg.toAgentID = toAgentID.UUID; | 337 | msg.toAgentID = toAgentID.UUID; |
338 | msg.imSessionID = friendTransactionID.UUID; // This is the item we're mucking with here | 338 | msg.imSessionID = friendTransactionID.UUID; // This is the item we're mucking with here |
339 | m_log.Info("[FRIEND]: Filling Session: " + msg.imSessionID.ToString()); | 339 | m_log.Info("[FRIEND]: Filling Session: " + msg.imSessionID.ToString()); |
340 | msg.timestamp = timestamp; | 340 | msg.timestamp = timestamp; |
341 | if (client != null) | 341 | if (client != null) |
342 | { | 342 | { |
343 | msg.fromAgentName = client.FirstName + " " + client.LastName;// fromAgentName; | 343 | msg.fromAgentName = client.FirstName + " " + client.LastName;// fromAgentName; |
344 | } | 344 | } |
345 | else | 345 | else |
346 | { | 346 | { |
347 | msg.fromAgentName = "(hippos)";// Added for posterity. This means that we can't figure out who sent it | 347 | msg.fromAgentName = "(hippos)";// Added for posterity. This means that we can't figure out who sent it |
348 | } | 348 | } |
349 | msg.message = message; | 349 | msg.message = message; |
350 | msg.dialog = dialog; | 350 | msg.dialog = dialog; |
351 | msg.fromGroup = fromGroup; | 351 | msg.fromGroup = fromGroup; |
352 | msg.offline = offline; | 352 | msg.offline = offline; |
353 | msg.ParentEstateID = ParentEstateID; | 353 | msg.ParentEstateID = ParentEstateID; |
354 | msg.Position = new sLLVector3(Position); | 354 | msg.Position = new sLLVector3(Position); |
355 | msg.RegionID = RegionID.UUID; | 355 | msg.RegionID = RegionID.UUID; |
356 | msg.binaryBucket = binaryBucket; | 356 | msg.binaryBucket = binaryBucket; |
357 | // We don't really care which scene we pipe it through. | 357 | // We don't really care which scene we pipe it through. |
358 | m_scene[0].TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); | 358 | m_scene[0].TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); |
359 | } | 359 | } |
360 | 360 | ||
361 | // 39 == Accept Friendship | 361 | // 39 == Accept Friendship |
362 | if (dialog == (byte)39) | 362 | if (dialog == (byte)39) |
363 | { | 363 | { |
364 | m_log.Info("[FRIEND]: 39 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message); | 364 | m_log.Info("[FRIEND]: 39 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message); |
365 | } | 365 | } |
366 | 366 | ||
367 | // 40 == Decline Friendship | 367 | // 40 == Decline Friendship |
368 | if (dialog == (byte)40) | 368 | if (dialog == (byte)40) |
369 | { | 369 | { |
370 | m_log.Info("[FRIEND]: 40 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message); | 370 | m_log.Info("[FRIEND]: 40 - From:" + fromAgentID.ToString() + " To: " + toAgentID.ToString() + " Session:" + imSessionID.ToString() + " Message:" + message); |
371 | } | 371 | } |
372 | } | 372 | } |
373 | 373 | ||
374 | private void OnApprovedFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) | 374 | private void OnApprovedFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) |
375 | { | 375 | { |
376 | if (m_pendingFriendRequests.ContainsKey(transactionID)) | 376 | if (m_pendingFriendRequests.ContainsKey(transactionID)) |
377 | { | 377 | { |
378 | // Found Pending Friend Request with that Transaction.. | 378 | // Found Pending Friend Request with that Transaction.. |
379 | Scene SceneAgentIn = m_scene[0]; | 379 | Scene SceneAgentIn = m_scene[0]; |
380 | 380 | ||
381 | // Found Pending Friend Request with that Transaction.. | 381 | // Found Pending Friend Request with that Transaction.. |
382 | ScenePresence agentpresence = GetPresenceFromAgentID(agentID); | 382 | ScenePresence agentpresence = GetPresenceFromAgentID(agentID); |
383 | if (agentpresence != null) | 383 | if (agentpresence != null) |
384 | { | 384 | { |
385 | SceneAgentIn = agentpresence.Scene; | 385 | SceneAgentIn = agentpresence.Scene; |
386 | } | 386 | } |
387 | 387 | ||
388 | // Compose response to other agent. | 388 | // Compose response to other agent. |
389 | GridInstantMessage msg = new GridInstantMessage(); | 389 | GridInstantMessage msg = new GridInstantMessage(); |
390 | msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; | 390 | msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; |
391 | msg.fromAgentID = agentID.UUID; | 391 | msg.fromAgentID = agentID.UUID; |
392 | msg.fromAgentName = client.FirstName + " " + client.LastName; | 392 | msg.fromAgentName = client.FirstName + " " + client.LastName; |
393 | msg.fromAgentSession = client.SessionId.UUID; | 393 | msg.fromAgentSession = client.SessionId.UUID; |
394 | msg.fromGroup = false; | 394 | msg.fromGroup = false; |
395 | msg.imSessionID = transactionID.UUID; | 395 | msg.imSessionID = transactionID.UUID; |
396 | msg.message = agentID.UUID.ToString(); | 396 | msg.message = agentID.UUID.ToString(); |
397 | msg.ParentEstateID = 0; | 397 | msg.ParentEstateID = 0; |
398 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | 398 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); |
399 | msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; | 399 | msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; |
400 | msg.dialog = (byte)39;// Approved friend request | 400 | msg.dialog = (byte)39;// Approved friend request |
401 | msg.Position = new sLLVector3(); | 401 | msg.Position = new sLLVector3(); |
402 | msg.offline = (byte)0; | 402 | msg.offline = (byte)0; |
403 | msg.binaryBucket = new byte[0]; | 403 | msg.binaryBucket = new byte[0]; |
404 | // We don't really care which scene we pipe it through, it goes to the shared IM Module and/or the database | 404 | // We don't really care which scene we pipe it through, it goes to the shared IM Module and/or the database |
405 | 405 | ||
406 | SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); | 406 | SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); |
407 | SceneAgentIn.StoreAddFriendship(m_pendingFriendRequests[transactionID], agentID, (uint)1); | 407 | SceneAgentIn.StoreAddFriendship(m_pendingFriendRequests[transactionID], agentID, (uint)1); |
408 | m_pendingFriendRequests.Remove(transactionID); | 408 | m_pendingFriendRequests.Remove(transactionID); |
409 | 409 | ||
410 | // TODO: Inform agent that the friend is online | 410 | // TODO: Inform agent that the friend is online |
411 | } | 411 | } |
412 | } | 412 | } |
413 | 413 | ||
414 | private void OnDenyFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) | 414 | private void OnDenyFriendRequest(IClientAPI client, LLUUID agentID, LLUUID transactionID, List<LLUUID> callingCardFolders) |
415 | { | 415 | { |
416 | if (m_pendingFriendRequests.ContainsKey(transactionID)) | 416 | if (m_pendingFriendRequests.ContainsKey(transactionID)) |
417 | { | 417 | { |
418 | Scene SceneAgentIn = m_scene[0]; | 418 | Scene SceneAgentIn = m_scene[0]; |
419 | 419 | ||
420 | // Found Pending Friend Request with that Transaction.. | 420 | // Found Pending Friend Request with that Transaction.. |
421 | ScenePresence agentpresence = GetPresenceFromAgentID(agentID); | 421 | ScenePresence agentpresence = GetPresenceFromAgentID(agentID); |
422 | if (agentpresence != null) | 422 | if (agentpresence != null) |
423 | { | 423 | { |
424 | SceneAgentIn = agentpresence.Scene; | 424 | SceneAgentIn = agentpresence.Scene; |
425 | } | 425 | } |
426 | // Compose response to other agent. | 426 | // Compose response to other agent. |
427 | GridInstantMessage msg = new GridInstantMessage(); | 427 | GridInstantMessage msg = new GridInstantMessage(); |
428 | msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; | 428 | msg.toAgentID = m_pendingFriendRequests[transactionID].UUID; |
429 | msg.fromAgentID = agentID.UUID; | 429 | msg.fromAgentID = agentID.UUID; |
430 | msg.fromAgentName = client.FirstName + " " + client.LastName; | 430 | msg.fromAgentName = client.FirstName + " " + client.LastName; |
431 | msg.fromAgentSession = client.SessionId.UUID; | 431 | msg.fromAgentSession = client.SessionId.UUID; |
432 | msg.fromGroup = false; | 432 | msg.fromGroup = false; |
433 | msg.imSessionID = transactionID.UUID; | 433 | msg.imSessionID = transactionID.UUID; |
434 | msg.message = agentID.UUID.ToString(); | 434 | msg.message = agentID.UUID.ToString(); |
435 | msg.ParentEstateID = 0; | 435 | msg.ParentEstateID = 0; |
436 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | 436 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); |
437 | msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; | 437 | msg.RegionID = SceneAgentIn.RegionInfo.RegionID.UUID; |
438 | msg.dialog = (byte)40;// Deny friend request | 438 | msg.dialog = (byte)40;// Deny friend request |
439 | msg.Position = new sLLVector3(); | 439 | msg.Position = new sLLVector3(); |
440 | msg.offline = (byte)0; | 440 | msg.offline = (byte)0; |
441 | msg.binaryBucket = new byte[0]; | 441 | msg.binaryBucket = new byte[0]; |
442 | SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); | 442 | SceneAgentIn.TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule); |
443 | m_pendingFriendRequests.Remove(transactionID); | 443 | m_pendingFriendRequests.Remove(transactionID); |
444 | } | 444 | } |
445 | } | 445 | } |
446 | 446 | ||
447 | private void OnTerminateFriendship(IClientAPI client, LLUUID agent, LLUUID exfriendID) | 447 | private void OnTerminateFriendship(IClientAPI client, LLUUID agent, LLUUID exfriendID) |
448 | { | 448 | { |
449 | m_scene[0].StoreRemoveFriendship(agent, exfriendID); | 449 | m_scene[0].StoreRemoveFriendship(agent, exfriendID); |
450 | // TODO: Inform the client that the ExFriend is offline | 450 | // TODO: Inform the client that the ExFriend is offline |
451 | } | 451 | } |
452 | 452 | ||
453 | private void OnGridInstantMessage(GridInstantMessage msg) | 453 | private void OnGridInstantMessage(GridInstantMessage msg) |
454 | { | 454 | { |
455 | // Trigger the above event handler | 455 | // Trigger the above event handler |
456 | OnInstantMessage(null,new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), | 456 | OnInstantMessage(null,new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), |
457 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, | 457 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, |
458 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, | 458 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, |
459 | new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), | 459 | new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), |
460 | msg.binaryBucket); | 460 | msg.binaryBucket); |
461 | } | 461 | } |
462 | #endregion | 462 | #endregion |
463 | private ScenePresence GetPresenceFromAgentID(LLUUID AgentID) | 463 | private ScenePresence GetPresenceFromAgentID(LLUUID AgentID) |
464 | { | 464 | { |
465 | ScenePresence returnAgent = null; | 465 | ScenePresence returnAgent = null; |
466 | lock (m_scene) | 466 | lock (m_scene) |
467 | { | 467 | { |
468 | ScenePresence queryagent = null; | 468 | ScenePresence queryagent = null; |
469 | for (int i = 0; i < m_scene.Count; i++) | 469 | for (int i = 0; i < m_scene.Count; i++) |
470 | { | 470 | { |
471 | queryagent = m_scene[i].GetScenePresence(AgentID); | 471 | queryagent = m_scene[i].GetScenePresence(AgentID); |
472 | if (queryagent != null) | 472 | if (queryagent != null) |
473 | { | 473 | { |
474 | if (!queryagent.IsChildAgent) | 474 | if (!queryagent.IsChildAgent) |
475 | { | 475 | { |
476 | returnAgent = queryagent; | 476 | returnAgent = queryagent; |
477 | break; | 477 | break; |
478 | } | 478 | } |
479 | } | 479 | } |
480 | } | 480 | } |
481 | } | 481 | } |
482 | return returnAgent; | 482 | return returnAgent; |
483 | 483 | ||
484 | } | 484 | } |
485 | 485 | ||
486 | public void PostInitialise() | 486 | public void PostInitialise() |
487 | { | 487 | { |
488 | } | 488 | } |
489 | 489 | ||
490 | public void Close() | 490 | public void Close() |
491 | { | 491 | { |
492 | } | 492 | } |
493 | 493 | ||
494 | public string Name | 494 | public string Name |
495 | { | 495 | { |
496 | get { return "FriendsModule"; } | 496 | get { return "FriendsModule"; } |
497 | } | 497 | } |
498 | 498 | ||
499 | public bool IsSharedModule | 499 | public bool IsSharedModule |
500 | { | 500 | { |
501 | get { return true; } | 501 | get { return true; } |
502 | } | 502 | } |
503 | } | 503 | } |
504 | } | 504 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/GroupsModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Groups/GroupsModule.cs index b23bb91..4b28ad7 100644 --- a/OpenSim/Region/Environment/Modules/GroupsModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Groups/GroupsModule.cs | |||
@@ -1,278 +1,278 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using log4net; | 32 | using log4net; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Region.Environment.Interfaces; | 35 | using OpenSim.Region.Environment.Interfaces; |
36 | using OpenSim.Region.Environment.Scenes; | 36 | using OpenSim.Region.Environment.Scenes; |
37 | 37 | ||
38 | namespace OpenSim.Region.Environment.Modules | 38 | namespace OpenSim.Region.Environment.Modules.Avatar.Groups |
39 | { | 39 | { |
40 | public class GroupsModule : IRegionModule | 40 | public class GroupsModule : IRegionModule |
41 | { | 41 | { |
42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 42 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
43 | 43 | ||
44 | private List<Scene> m_scene = new List<Scene>(); | 44 | private List<Scene> m_scene = new List<Scene>(); |
45 | private Dictionary<LLUUID, IClientAPI> m_iclientmap = new Dictionary<LLUUID, IClientAPI>(); | 45 | private Dictionary<LLUUID, IClientAPI> m_iclientmap = new Dictionary<LLUUID, IClientAPI>(); |
46 | private Dictionary<LLUUID, GroupData> m_groupmap = new Dictionary<LLUUID, GroupData>(); | 46 | private Dictionary<LLUUID, GroupData> m_groupmap = new Dictionary<LLUUID, GroupData>(); |
47 | private Dictionary<LLUUID, GroupList> m_grouplistmap = new Dictionary<LLUUID, GroupList>(); | 47 | private Dictionary<LLUUID, GroupList> m_grouplistmap = new Dictionary<LLUUID, GroupList>(); |
48 | 48 | ||
49 | public void Initialise(Scene scene, IConfigSource config) | 49 | public void Initialise(Scene scene, IConfigSource config) |
50 | { | 50 | { |
51 | lock (m_scene) | 51 | lock (m_scene) |
52 | { | 52 | { |
53 | m_scene.Add(scene); | 53 | m_scene.Add(scene); |
54 | } | 54 | } |
55 | scene.EventManager.OnNewClient += OnNewClient; | 55 | scene.EventManager.OnNewClient += OnNewClient; |
56 | scene.EventManager.OnClientClosed += OnClientClosed; | 56 | scene.EventManager.OnClientClosed += OnClientClosed; |
57 | scene.EventManager.OnGridInstantMessageToGroupsModule += OnGridInstantMessage; | 57 | scene.EventManager.OnGridInstantMessageToGroupsModule += OnGridInstantMessage; |
58 | //scene.EventManager. | 58 | //scene.EventManager. |
59 | } | 59 | } |
60 | 60 | ||
61 | private void OnNewClient(IClientAPI client) | 61 | private void OnNewClient(IClientAPI client) |
62 | { | 62 | { |
63 | // All friends establishment protocol goes over instant message | 63 | // All friends establishment protocol goes over instant message |
64 | // There's no way to send a message from the sim | 64 | // There's no way to send a message from the sim |
65 | // to a user to 'add a friend' without causing dialog box spam | 65 | // to a user to 'add a friend' without causing dialog box spam |
66 | // | 66 | // |
67 | // The base set of friends are added when the user signs on in their XMLRPC response | 67 | // The base set of friends are added when the user signs on in their XMLRPC response |
68 | // Generated by LoginService. The friends are retreived from the database by the UserManager | 68 | // Generated by LoginService. The friends are retreived from the database by the UserManager |
69 | 69 | ||
70 | // Subscribe to instant messages | 70 | // Subscribe to instant messages |
71 | client.OnInstantMessage += OnInstantMessage; | 71 | client.OnInstantMessage += OnInstantMessage; |
72 | client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; | 72 | client.OnAgentDataUpdateRequest += OnAgentDataUpdateRequest; |
73 | lock (m_iclientmap) | 73 | lock (m_iclientmap) |
74 | { | 74 | { |
75 | if (!m_iclientmap.ContainsKey(client.AgentId)) | 75 | if (!m_iclientmap.ContainsKey(client.AgentId)) |
76 | { | 76 | { |
77 | m_iclientmap.Add(client.AgentId, client); | 77 | m_iclientmap.Add(client.AgentId, client); |
78 | } | 78 | } |
79 | } | 79 | } |
80 | GroupData OpenSimulatorGroup = new GroupData(); | 80 | GroupData OpenSimulatorGroup = new GroupData(); |
81 | OpenSimulatorGroup.ActiveGroupTitle = "OpenSimulator Tester"; | 81 | OpenSimulatorGroup.ActiveGroupTitle = "OpenSimulator Tester"; |
82 | OpenSimulatorGroup.GroupID = new LLUUID("00000000-68f9-1111-024e-222222111120"); | 82 | OpenSimulatorGroup.GroupID = new LLUUID("00000000-68f9-1111-024e-222222111120"); |
83 | OpenSimulatorGroup.GroupMembers.Add(client.AgentId); | 83 | OpenSimulatorGroup.GroupMembers.Add(client.AgentId); |
84 | OpenSimulatorGroup.groupName = "OpenSimulator Testing"; | 84 | OpenSimulatorGroup.groupName = "OpenSimulator Testing"; |
85 | OpenSimulatorGroup.ActiveGroupPowers = GroupPowers.LandAllowSetHome; | 85 | OpenSimulatorGroup.ActiveGroupPowers = GroupPowers.LandAllowSetHome; |
86 | OpenSimulatorGroup.GroupTitles.Add("OpenSimulator Tester"); | 86 | OpenSimulatorGroup.GroupTitles.Add("OpenSimulator Tester"); |
87 | lock (m_groupmap) | 87 | lock (m_groupmap) |
88 | { | 88 | { |
89 | if (!m_groupmap.ContainsKey(client.AgentId)) | 89 | if (!m_groupmap.ContainsKey(client.AgentId)) |
90 | { | 90 | { |
91 | m_groupmap.Add(client.AgentId, OpenSimulatorGroup); | 91 | m_groupmap.Add(client.AgentId, OpenSimulatorGroup); |
92 | } | 92 | } |
93 | } | 93 | } |
94 | GroupList testGroupList = new GroupList(); | 94 | GroupList testGroupList = new GroupList(); |
95 | testGroupList.m_GroupList.Add(new LLUUID("00000000-68f9-1111-024e-222222111120")); | 95 | testGroupList.m_GroupList.Add(new LLUUID("00000000-68f9-1111-024e-222222111120")); |
96 | 96 | ||
97 | lock (m_grouplistmap) | 97 | lock (m_grouplistmap) |
98 | { | 98 | { |
99 | if (!m_grouplistmap.ContainsKey(client.AgentId)) | 99 | if (!m_grouplistmap.ContainsKey(client.AgentId)) |
100 | { | 100 | { |
101 | m_grouplistmap.Add(client.AgentId, testGroupList); | 101 | m_grouplistmap.Add(client.AgentId, testGroupList); |
102 | } | 102 | } |
103 | } | 103 | } |
104 | m_log.Info("[GROUP]: Adding " + client.FirstName + " " + client.LastName + " to OpenSimulator Tester group"); | 104 | m_log.Info("[GROUP]: Adding " + client.FirstName + " " + client.LastName + " to OpenSimulator Tester group"); |
105 | } | 105 | } |
106 | 106 | ||
107 | private void OnAgentDataUpdateRequest(IClientAPI remoteClient, LLUUID AgentID, LLUUID SessionID) | 107 | private void OnAgentDataUpdateRequest(IClientAPI remoteClient, LLUUID AgentID, LLUUID SessionID) |
108 | { | 108 | { |
109 | string firstname = remoteClient.FirstName; | 109 | string firstname = remoteClient.FirstName; |
110 | string lastname = remoteClient.LastName; | 110 | string lastname = remoteClient.LastName; |
111 | 111 | ||
112 | LLUUID ActiveGroupID = LLUUID.Zero; | 112 | LLUUID ActiveGroupID = LLUUID.Zero; |
113 | uint ActiveGroupPowers = 0; | 113 | uint ActiveGroupPowers = 0; |
114 | string ActiveGroupName = ""; | 114 | string ActiveGroupName = ""; |
115 | string ActiveGroupTitle = ""; | 115 | string ActiveGroupTitle = ""; |
116 | 116 | ||
117 | bool foundUser = false; | 117 | bool foundUser = false; |
118 | 118 | ||
119 | lock (m_iclientmap) | 119 | lock (m_iclientmap) |
120 | { | 120 | { |
121 | if (m_iclientmap.ContainsKey(remoteClient.AgentId)) | 121 | if (m_iclientmap.ContainsKey(remoteClient.AgentId)) |
122 | { | 122 | { |
123 | foundUser = true; | 123 | foundUser = true; |
124 | } | 124 | } |
125 | } | 125 | } |
126 | if (foundUser) | 126 | if (foundUser) |
127 | { | 127 | { |
128 | lock (m_groupmap) | 128 | lock (m_groupmap) |
129 | { | 129 | { |
130 | if (m_groupmap.ContainsKey(remoteClient.AgentId)) | 130 | if (m_groupmap.ContainsKey(remoteClient.AgentId)) |
131 | { | 131 | { |
132 | GroupData grp = m_groupmap[remoteClient.AgentId]; | 132 | GroupData grp = m_groupmap[remoteClient.AgentId]; |
133 | if (grp != null) | 133 | if (grp != null) |
134 | { | 134 | { |
135 | ActiveGroupID = grp.GroupID; | 135 | ActiveGroupID = grp.GroupID; |
136 | ActiveGroupName = grp.groupName; | 136 | ActiveGroupName = grp.groupName; |
137 | ActiveGroupPowers = grp.groupPowers; | 137 | ActiveGroupPowers = grp.groupPowers; |
138 | ActiveGroupTitle = grp.ActiveGroupTitle; | 138 | ActiveGroupTitle = grp.ActiveGroupTitle; |
139 | } | 139 | } |
140 | 140 | ||
141 | //remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, lastname, ActiveGroupPowers, ActiveGroupName, ActiveGroupTitle); | 141 | //remoteClient.SendAgentDataUpdate(AgentID, ActiveGroupID, firstname, lastname, ActiveGroupPowers, ActiveGroupName, ActiveGroupTitle); |
142 | 142 | ||
143 | } | 143 | } |
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
147 | } | 147 | } |
148 | 148 | ||
149 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, | 149 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, |
150 | LLUUID fromAgentSession, LLUUID toAgentID, | 150 | LLUUID fromAgentSession, LLUUID toAgentID, |
151 | LLUUID imSessionID, uint timestamp, string fromAgentName, | 151 | LLUUID imSessionID, uint timestamp, string fromAgentName, |
152 | string message, byte dialog, bool fromGroup, byte offline, | 152 | string message, byte dialog, bool fromGroup, byte offline, |
153 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, | 153 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, |
154 | byte[] binaryBucket) | 154 | byte[] binaryBucket) |
155 | { | 155 | { |
156 | } | 156 | } |
157 | 157 | ||
158 | private void OnGridInstantMessage(GridInstantMessage msg) | 158 | private void OnGridInstantMessage(GridInstantMessage msg) |
159 | { | 159 | { |
160 | // Trigger the above event handler | 160 | // Trigger the above event handler |
161 | OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), | 161 | OnInstantMessage(null, new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), |
162 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, | 162 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, |
163 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, | 163 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, |
164 | new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), | 164 | new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), |
165 | msg.binaryBucket); | 165 | msg.binaryBucket); |
166 | } | 166 | } |
167 | 167 | ||
168 | private void OnClientClosed(LLUUID agentID) | 168 | private void OnClientClosed(LLUUID agentID) |
169 | { | 169 | { |
170 | lock (m_iclientmap) | 170 | lock (m_iclientmap) |
171 | { | 171 | { |
172 | if (m_iclientmap.ContainsKey(agentID)) | 172 | if (m_iclientmap.ContainsKey(agentID)) |
173 | { | 173 | { |
174 | IClientAPI cli = m_iclientmap[agentID]; | 174 | IClientAPI cli = m_iclientmap[agentID]; |
175 | if (cli != null) | 175 | if (cli != null) |
176 | { | 176 | { |
177 | m_log.Info("[GROUP]: Removing all reference to groups for " + cli.FirstName + " " + cli.LastName); | 177 | m_log.Info("[GROUP]: Removing all reference to groups for " + cli.FirstName + " " + cli.LastName); |
178 | } | 178 | } |
179 | else | 179 | else |
180 | { | 180 | { |
181 | m_log.Info("[GROUP]: Removing all reference to groups for " + agentID.ToString()); | 181 | m_log.Info("[GROUP]: Removing all reference to groups for " + agentID.ToString()); |
182 | } | 182 | } |
183 | m_iclientmap.Remove(agentID); | 183 | m_iclientmap.Remove(agentID); |
184 | } | 184 | } |
185 | } | 185 | } |
186 | 186 | ||
187 | lock (m_groupmap) | 187 | lock (m_groupmap) |
188 | { | 188 | { |
189 | if (m_groupmap.ContainsKey(agentID)) | 189 | if (m_groupmap.ContainsKey(agentID)) |
190 | { | 190 | { |
191 | m_groupmap.Remove(agentID); | 191 | m_groupmap.Remove(agentID); |
192 | } | 192 | } |
193 | } | 193 | } |
194 | 194 | ||
195 | lock (m_grouplistmap) | 195 | lock (m_grouplistmap) |
196 | { | 196 | { |
197 | if (m_grouplistmap.ContainsKey(agentID)) | 197 | if (m_grouplistmap.ContainsKey(agentID)) |
198 | { | 198 | { |
199 | m_grouplistmap.Remove(agentID); | 199 | m_grouplistmap.Remove(agentID); |
200 | } | 200 | } |
201 | } | 201 | } |
202 | GC.Collect(); | 202 | GC.Collect(); |
203 | } | 203 | } |
204 | 204 | ||
205 | public void PostInitialise() | 205 | public void PostInitialise() |
206 | { | 206 | { |
207 | } | 207 | } |
208 | 208 | ||
209 | public void Close() | 209 | public void Close() |
210 | { | 210 | { |
211 | m_log.Info("[GROUP]: Shutting down group module."); | 211 | m_log.Info("[GROUP]: Shutting down group module."); |
212 | lock (m_iclientmap) | 212 | lock (m_iclientmap) |
213 | { | 213 | { |
214 | m_iclientmap.Clear(); | 214 | m_iclientmap.Clear(); |
215 | } | 215 | } |
216 | 216 | ||
217 | lock (m_groupmap) | 217 | lock (m_groupmap) |
218 | { | 218 | { |
219 | m_groupmap.Clear(); | 219 | m_groupmap.Clear(); |
220 | } | 220 | } |
221 | 221 | ||
222 | lock (m_grouplistmap) | 222 | lock (m_grouplistmap) |
223 | { | 223 | { |
224 | m_grouplistmap.Clear(); | 224 | m_grouplistmap.Clear(); |
225 | } | 225 | } |
226 | GC.Collect(); | 226 | GC.Collect(); |
227 | } | 227 | } |
228 | 228 | ||
229 | public string Name | 229 | public string Name |
230 | { | 230 | { |
231 | get { return "GroupsModule"; } | 231 | get { return "GroupsModule"; } |
232 | } | 232 | } |
233 | 233 | ||
234 | public bool IsSharedModule | 234 | public bool IsSharedModule |
235 | { | 235 | { |
236 | get { return true; } | 236 | get { return true; } |
237 | } | 237 | } |
238 | 238 | ||
239 | } | 239 | } |
240 | 240 | ||
241 | public class GroupData | 241 | public class GroupData |
242 | { | 242 | { |
243 | public LLUUID GroupID; | 243 | public LLUUID GroupID; |
244 | public string groupName; | 244 | public string groupName; |
245 | public string ActiveGroupTitle; | 245 | public string ActiveGroupTitle; |
246 | public List<string> GroupTitles; | 246 | public List<string> GroupTitles; |
247 | public List<LLUUID> GroupMembers; | 247 | public List<LLUUID> GroupMembers; |
248 | public uint groupPowers = (uint)(GroupPowers.LandAllowLandmark | GroupPowers.LandAllowSetHome); | 248 | public uint groupPowers = (uint)(GroupPowers.LandAllowLandmark | GroupPowers.LandAllowSetHome); |
249 | 249 | ||
250 | public GroupPowers ActiveGroupPowers | 250 | public GroupPowers ActiveGroupPowers |
251 | { | 251 | { |
252 | set | 252 | set |
253 | { | 253 | { |
254 | groupPowers = (uint) value; | 254 | groupPowers = (uint) value; |
255 | } | 255 | } |
256 | get | 256 | get |
257 | { | 257 | { |
258 | return (GroupPowers)groupPowers; | 258 | return (GroupPowers)groupPowers; |
259 | } | 259 | } |
260 | } | 260 | } |
261 | 261 | ||
262 | public GroupData() | 262 | public GroupData() |
263 | { | 263 | { |
264 | GroupTitles = new List<string>(); | 264 | GroupTitles = new List<string>(); |
265 | GroupMembers = new List<LLUUID>(); | 265 | GroupMembers = new List<LLUUID>(); |
266 | } | 266 | } |
267 | 267 | ||
268 | } | 268 | } |
269 | 269 | ||
270 | public class GroupList | 270 | public class GroupList |
271 | { | 271 | { |
272 | public List<LLUUID> m_GroupList; | 272 | public List<LLUUID> m_GroupList; |
273 | public GroupList() | 273 | public GroupList() |
274 | { | 274 | { |
275 | m_GroupList = new List<LLUUID>(); | 275 | m_GroupList = new List<LLUUID>(); |
276 | } | 276 | } |
277 | } | 277 | } |
278 | } | 278 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/InstantMessageModule.cs b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs index 6e13b73..1b82837 100644 --- a/OpenSim/Region/Environment/Modules/InstantMessageModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs | |||
@@ -1,159 +1,157 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections; | 28 | using System.Collections.Generic; |
29 | using System.Collections.Generic; | 29 | using libsecondlife; |
30 | using libsecondlife; | 30 | using Nini.Config; |
31 | using Nini.Config; | 31 | using OpenSim.Framework; |
32 | using OpenSim.Framework; | 32 | using OpenSim.Region.Environment.Interfaces; |
33 | using OpenSim.Region.Environment.Interfaces; | 33 | using OpenSim.Region.Environment.Scenes; |
34 | using OpenSim.Region.Environment.Scenes; | 34 | |
35 | 35 | namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage | |
36 | namespace OpenSim.Region.Environment.Modules | 36 | { |
37 | { | 37 | public class InstantMessageModule : IRegionModule |
38 | public class InstantMessageModule : IRegionModule | 38 | { |
39 | { | 39 | private readonly List<Scene> m_scenes = new List<Scene>(); |
40 | private List<Scene> m_scenes = new List<Scene>(); | 40 | |
41 | private Hashtable m_RegionInfoCache = new Hashtable(); | 41 | public void Initialise(Scene scene, IConfigSource config) |
42 | 42 | { | |
43 | public void Initialise(Scene scene, IConfigSource config) | 43 | lock (m_scenes) |
44 | { | 44 | { |
45 | lock (m_scenes) | 45 | if (m_scenes.Count == 0) |
46 | { | 46 | { |
47 | if (m_scenes.Count == 0) | 47 | //scene.AddXmlRPCHandler("avatar_location_update", processPresenceUpdate); |
48 | { | 48 | } |
49 | //scene.AddXmlRPCHandler("avatar_location_update", processPresenceUpdate); | 49 | |
50 | } | 50 | if (!m_scenes.Contains(scene)) |
51 | 51 | { | |
52 | if (!m_scenes.Contains(scene)) | 52 | m_scenes.Add(scene); |
53 | { | 53 | scene.EventManager.OnNewClient += OnNewClient; |
54 | m_scenes.Add(scene); | 54 | scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage; |
55 | scene.EventManager.OnNewClient += OnNewClient; | 55 | } |
56 | scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage; | 56 | } |
57 | } | 57 | } |
58 | } | 58 | |
59 | } | 59 | private void OnNewClient(IClientAPI client) |
60 | 60 | { | |
61 | private void OnNewClient(IClientAPI client) | 61 | client.OnInstantMessage += OnInstantMessage; |
62 | { | 62 | } |
63 | client.OnInstantMessage += OnInstantMessage; | 63 | |
64 | } | 64 | private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID, |
65 | 65 | LLUUID fromAgentSession, LLUUID toAgentID, | |
66 | private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID, | 66 | LLUUID imSessionID, uint timestamp, string fromAgentName, |
67 | LLUUID fromAgentSession, LLUUID toAgentID, | 67 | string message, byte dialog, bool fromGroup, byte offline, |
68 | LLUUID imSessionID, uint timestamp, string fromAgentName, | 68 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, |
69 | string message, byte dialog, bool fromGroup, byte offline, | 69 | byte[] binaryBucket) |
70 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, | 70 | { |
71 | byte[] binaryBucket) | 71 | bool dialogHandledElsewhere |
72 | { | 72 | = ((dialog == 38) || (dialog == 39) || (dialog == 40) |
73 | bool dialogHandledElsewhere | 73 | || dialog == (byte)InstantMessageDialog.InventoryOffered |
74 | = ((dialog == (byte)38) || (dialog == (byte)39) || (dialog == (byte)40) | 74 | || dialog == (byte)InstantMessageDialog.InventoryAccepted |
75 | || dialog == (byte)InstantMessageDialog.InventoryOffered | 75 | || dialog == (byte)InstantMessageDialog.InventoryDeclined); |
76 | || dialog == (byte)InstantMessageDialog.InventoryAccepted | 76 | |
77 | || dialog == (byte)InstantMessageDialog.InventoryDeclined); | 77 | // IM dialogs need to be pre-processed and have their sessionID filled by the server |
78 | 78 | // so the sim can match the transaction on the return packet. | |
79 | // IM dialogs need to be pre-processed and have their sessionID filled by the server | 79 | |
80 | // so the sim can match the transaction on the return packet. | 80 | // Don't send a Friend Dialog IM with a LLUUID.Zero session. |
81 | 81 | if (!(dialogHandledElsewhere && imSessionID == LLUUID.Zero)) | |
82 | // Don't send a Friend Dialog IM with a LLUUID.Zero session. | 82 | { |
83 | if (!(dialogHandledElsewhere && imSessionID == LLUUID.Zero)) | 83 | // Try root avatar only first |
84 | { | 84 | foreach (Scene scene in m_scenes) |
85 | // Try root avatar only first | 85 | { |
86 | foreach (Scene scene in m_scenes) | 86 | if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) |
87 | { | 87 | { |
88 | if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) | 88 | // Local message |
89 | { | 89 | ScenePresence user = (ScenePresence)scene.Entities[toAgentID]; |
90 | // Local message | 90 | if (!user.IsChildAgent) |
91 | ScenePresence user = (ScenePresence)scene.Entities[toAgentID]; | 91 | { |
92 | if (!user.IsChildAgent) | 92 | user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, |
93 | { | 93 | toAgentID, imSessionID, fromAgentName, dialog, |
94 | user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, | 94 | timestamp); |
95 | toAgentID, imSessionID, fromAgentName, dialog, | 95 | // Message sent |
96 | timestamp); | 96 | return; |
97 | // Message sent | 97 | } |
98 | return; | 98 | } |
99 | } | 99 | } |
100 | } | 100 | |
101 | } | 101 | // try child avatar second |
102 | 102 | foreach (Scene scene in m_scenes) | |
103 | // try child avatar second | 103 | { |
104 | foreach (Scene scene in m_scenes) | 104 | if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) |
105 | { | 105 | { |
106 | if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) | 106 | // Local message |
107 | { | 107 | ScenePresence user = (ScenePresence)scene.Entities[toAgentID]; |
108 | // Local message | 108 | |
109 | ScenePresence user = (ScenePresence)scene.Entities[toAgentID]; | 109 | user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, |
110 | 110 | toAgentID, imSessionID, fromAgentName, dialog, | |
111 | user.ControllingClient.SendInstantMessage(fromAgentID, fromAgentSession, message, | 111 | timestamp); |
112 | toAgentID, imSessionID, fromAgentName, dialog, | 112 | // Message sent |
113 | timestamp); | 113 | return; |
114 | // Message sent | 114 | |
115 | return; | 115 | } |
116 | 116 | } | |
117 | } | 117 | |
118 | } | 118 | } |
119 | 119 | ||
120 | } | 120 | |
121 | 121 | // Still here, try send via Grid | |
122 | 122 | // TODO | |
123 | // Still here, try send via Grid | 123 | } |
124 | // TODO | 124 | |
125 | } | 125 | // Trusty OSG1 called method. This method also gets called from the FriendsModule |
126 | 126 | // Turns out the sim has to send an instant message to the user to get it to show an accepted friend. | |
127 | // Trusty OSG1 called method. This method also gets called from the FriendsModule | 127 | |
128 | // Turns out the sim has to send an instant message to the user to get it to show an accepted friend. | 128 | private void OnGridInstantMessage(GridInstantMessage msg) |
129 | 129 | { | |
130 | private void OnGridInstantMessage(GridInstantMessage msg) | 130 | // Trigger the above event handler |
131 | { | 131 | OnInstantMessage(null,new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), |
132 | // Trigger the above event handler | 132 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, |
133 | OnInstantMessage(null,new LLUUID(msg.fromAgentID), new LLUUID(msg.fromAgentSession), | 133 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, |
134 | new LLUUID(msg.toAgentID), new LLUUID(msg.imSessionID), msg.timestamp, msg.fromAgentName, | 134 | new LLVector3(msg.Position.x,msg.Position.y,msg.Position.z), new LLUUID(msg.RegionID), |
135 | msg.message, msg.dialog, msg.fromGroup, msg.offline, msg.ParentEstateID, | 135 | msg.binaryBucket); |
136 | new LLVector3(msg.Position.x,msg.Position.y,msg.Position.z), new LLUUID(msg.RegionID), | 136 | |
137 | msg.binaryBucket); | 137 | } |
138 | 138 | ||
139 | } | 139 | public void PostInitialise() |
140 | 140 | { | |
141 | public void PostInitialise() | 141 | } |
142 | { | 142 | |
143 | } | 143 | public void Close() |
144 | 144 | { | |
145 | public void Close() | 145 | } |
146 | { | 146 | |
147 | } | 147 | public string Name |
148 | 148 | { | |
149 | public string Name | 149 | get { return "InstantMessageModule"; } |
150 | { | 150 | } |
151 | get { return "InstantMessageModule"; } | 151 | |
152 | } | 152 | public bool IsSharedModule |
153 | 153 | { | |
154 | public bool IsSharedModule | 154 | get { return true; } |
155 | { | 155 | } |
156 | get { return true; } | 156 | } |
157 | } | 157 | } \ No newline at end of file |
158 | } | ||
159 | } | ||
diff --git a/OpenSim/Region/Environment/Modules/InventoryModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryModule.cs index ff5a02c..42c6238 100644 --- a/OpenSim/Region/Environment/Modules/InventoryModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Inventory/InventoryModule.cs | |||
@@ -1,216 +1,216 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Environment.Interfaces; | 34 | using OpenSim.Region.Environment.Interfaces; |
35 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | 36 | ||
37 | namespace OpenSim.Region.Environment.Modules | 37 | namespace OpenSim.Region.Environment.Modules.Avatar.Inventory |
38 | { | 38 | { |
39 | public class InventoryModule : IRegionModule | 39 | public class InventoryModule : IRegionModule |
40 | { | 40 | { |
41 | private static readonly ILog m_log | 41 | private static readonly ILog m_log |
42 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 42 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
43 | 43 | ||
44 | private Scene m_scene; | 44 | private Scene m_scene; |
45 | 45 | ||
46 | /// <summary> | 46 | /// <summary> |
47 | /// We need to keep track of the pending item offers between clients since the itemId offered only | 47 | /// We need to keep track of the pending item offers between clients since the itemId offered only |
48 | /// occurs in the initial offer message, not the accept message. So this dictionary links | 48 | /// occurs in the initial offer message, not the accept message. So this dictionary links |
49 | /// IM Session Ids to ItemIds | 49 | /// IM Session Ids to ItemIds |
50 | /// </summary> | 50 | /// </summary> |
51 | private IDictionary<LLUUID, LLUUID> m_pendingOffers = new Dictionary<LLUUID, LLUUID>(); | 51 | private IDictionary<LLUUID, LLUUID> m_pendingOffers = new Dictionary<LLUUID, LLUUID>(); |
52 | 52 | ||
53 | public void Initialise(Scene scene, IConfigSource config) | 53 | public void Initialise(Scene scene, IConfigSource config) |
54 | { | 54 | { |
55 | m_scene = scene; | 55 | m_scene = scene; |
56 | scene.EventManager.OnNewClient += OnNewClient; | 56 | scene.EventManager.OnNewClient += OnNewClient; |
57 | } | 57 | } |
58 | 58 | ||
59 | public void PostInitialise() | 59 | public void PostInitialise() |
60 | { | 60 | { |
61 | } | 61 | } |
62 | 62 | ||
63 | public void Close() | 63 | public void Close() |
64 | { | 64 | { |
65 | } | 65 | } |
66 | 66 | ||
67 | public string Name | 67 | public string Name |
68 | { | 68 | { |
69 | get { return "InventoryModule"; } | 69 | get { return "InventoryModule"; } |
70 | } | 70 | } |
71 | 71 | ||
72 | public bool IsSharedModule | 72 | public bool IsSharedModule |
73 | { | 73 | { |
74 | get { return false; } | 74 | get { return false; } |
75 | } | 75 | } |
76 | 76 | ||
77 | private void OnNewClient(IClientAPI client) | 77 | private void OnNewClient(IClientAPI client) |
78 | { | 78 | { |
79 | // Inventory giving is conducted via instant message | 79 | // Inventory giving is conducted via instant message |
80 | client.OnInstantMessage += OnInstantMessage; | 80 | client.OnInstantMessage += OnInstantMessage; |
81 | } | 81 | } |
82 | 82 | ||
83 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, | 83 | private void OnInstantMessage(IClientAPI client, LLUUID fromAgentID, |
84 | LLUUID fromAgentSession, LLUUID toAgentID, | 84 | LLUUID fromAgentSession, LLUUID toAgentID, |
85 | LLUUID imSessionID, uint timestamp, string fromAgentName, | 85 | LLUUID imSessionID, uint timestamp, string fromAgentName, |
86 | string message, byte dialog, bool fromGroup, byte offline, | 86 | string message, byte dialog, bool fromGroup, byte offline, |
87 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, | 87 | uint ParentEstateID, LLVector3 Position, LLUUID RegionID, |
88 | byte[] binaryBucket) | 88 | byte[] binaryBucket) |
89 | { | 89 | { |
90 | if (dialog == (byte)InstantMessageDialog.InventoryOffered) | 90 | if (dialog == (byte)InstantMessageDialog.InventoryOffered) |
91 | { | 91 | { |
92 | m_log.DebugFormat( | 92 | m_log.DebugFormat( |
93 | "[AGENT INVENTORY]: Routing inventory offering message from {0}, {1} to {2}", | 93 | "[AGENT INVENTORY]: Routing inventory offering message from {0}, {1} to {2}", |
94 | client.AgentId, client.Name, toAgentID); | 94 | client.AgentId, client.Name, toAgentID); |
95 | 95 | ||
96 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) | 96 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) |
97 | { | 97 | { |
98 | ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; | 98 | ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; |
99 | 99 | ||
100 | if (!user.IsChildAgent) | 100 | if (!user.IsChildAgent) |
101 | { | 101 | { |
102 | //byte[] rawId = new byte[16]; | 102 | //byte[] rawId = new byte[16]; |
103 | 103 | ||
104 | // First byte of the array is probably the item type | 104 | // First byte of the array is probably the item type |
105 | // Next 16 bytes are the UUID | 105 | // Next 16 bytes are the UUID |
106 | //Array.Copy(binaryBucket, 1, rawId, 0, 16); | 106 | //Array.Copy(binaryBucket, 1, rawId, 0, 16); |
107 | 107 | ||
108 | //LLUUID itemId = new LLUUID(new Guid(rawId)); | 108 | //LLUUID itemId = new LLUUID(new Guid(rawId)); |
109 | LLUUID itemId = new LLUUID(binaryBucket, 1); | 109 | LLUUID itemId = new LLUUID(binaryBucket, 1); |
110 | 110 | ||
111 | m_log.DebugFormat( | 111 | m_log.DebugFormat( |
112 | "[AGENT INVENTORY]: ItemId for giving is {0}", itemId); | 112 | "[AGENT INVENTORY]: ItemId for giving is {0}", itemId); |
113 | 113 | ||
114 | m_pendingOffers[imSessionID] = itemId; | 114 | m_pendingOffers[imSessionID] = itemId; |
115 | 115 | ||
116 | user.ControllingClient.SendInstantMessage( | 116 | user.ControllingClient.SendInstantMessage( |
117 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, | 117 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, |
118 | dialog, timestamp, binaryBucket); | 118 | dialog, timestamp, binaryBucket); |
119 | 119 | ||
120 | return; | 120 | return; |
121 | } | 121 | } |
122 | else | 122 | else |
123 | { | 123 | { |
124 | m_log.WarnFormat( | 124 | m_log.WarnFormat( |
125 | "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", | 125 | "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", |
126 | toAgentID, client.AgentId, client.Name, message); | 126 | toAgentID, client.AgentId, client.Name, message); |
127 | } | 127 | } |
128 | } | 128 | } |
129 | else | 129 | else |
130 | { | 130 | { |
131 | m_log.WarnFormat( | 131 | m_log.WarnFormat( |
132 | "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", | 132 | "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", |
133 | toAgentID, client.AgentId, client.Name, message); | 133 | toAgentID, client.AgentId, client.Name, message); |
134 | } | 134 | } |
135 | } | 135 | } |
136 | else if (dialog == (byte)InstantMessageDialog.InventoryAccepted) | 136 | else if (dialog == (byte)InstantMessageDialog.InventoryAccepted) |
137 | { | 137 | { |
138 | m_log.DebugFormat( | 138 | m_log.DebugFormat( |
139 | "[AGENT INVENTORY]: Routing inventory accepted message from {0}, {1} to {2}", | 139 | "[AGENT INVENTORY]: Routing inventory accepted message from {0}, {1} to {2}", |
140 | client.AgentId, client.Name, toAgentID); | 140 | client.AgentId, client.Name, toAgentID); |
141 | 141 | ||
142 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) | 142 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) |
143 | { | 143 | { |
144 | ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; | 144 | ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; |
145 | 145 | ||
146 | if (!user.IsChildAgent) | 146 | if (!user.IsChildAgent) |
147 | { | 147 | { |
148 | user.ControllingClient.SendInstantMessage( | 148 | user.ControllingClient.SendInstantMessage( |
149 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, | 149 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, |
150 | dialog, timestamp, binaryBucket); | 150 | dialog, timestamp, binaryBucket); |
151 | 151 | ||
152 | if (m_pendingOffers.ContainsKey(imSessionID)) | 152 | if (m_pendingOffers.ContainsKey(imSessionID)) |
153 | { | 153 | { |
154 | m_log.DebugFormat( | 154 | m_log.DebugFormat( |
155 | "[AGENT INVENTORY]: Accepted item id {0}", m_pendingOffers[imSessionID]); | 155 | "[AGENT INVENTORY]: Accepted item id {0}", m_pendingOffers[imSessionID]); |
156 | 156 | ||
157 | // Since the message originates from the accepting client, the toAgentID is | 157 | // Since the message originates from the accepting client, the toAgentID is |
158 | // the agent giving the item. | 158 | // the agent giving the item. |
159 | m_scene.GiveInventoryItem(client, toAgentID, m_pendingOffers[imSessionID]); | 159 | m_scene.GiveInventoryItem(client, toAgentID, m_pendingOffers[imSessionID]); |
160 | 160 | ||
161 | m_pendingOffers.Remove(imSessionID); | 161 | m_pendingOffers.Remove(imSessionID); |
162 | } | 162 | } |
163 | else | 163 | else |
164 | { | 164 | { |
165 | m_log.ErrorFormat( | 165 | m_log.ErrorFormat( |
166 | "[AGENT INVENTORY]: Could not find an item associated with session id {0} to accept", | 166 | "[AGENT INVENTORY]: Could not find an item associated with session id {0} to accept", |
167 | imSessionID); | 167 | imSessionID); |
168 | } | 168 | } |
169 | 169 | ||
170 | return; | 170 | return; |
171 | } | 171 | } |
172 | else | 172 | else |
173 | { | 173 | { |
174 | m_log.WarnFormat( | 174 | m_log.WarnFormat( |
175 | "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", | 175 | "[AGENT INVENTORY]: Agent {0} targeted for inventory give by {1}, {2} of {3} was a child agent!", |
176 | toAgentID, client.AgentId, client.Name, message); | 176 | toAgentID, client.AgentId, client.Name, message); |
177 | } | 177 | } |
178 | } | 178 | } |
179 | else | 179 | else |
180 | { | 180 | { |
181 | m_log.WarnFormat( | 181 | m_log.WarnFormat( |
182 | "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", | 182 | "[AGENT INVENTORY]: Could not find agent {0} for user {1}, {2} to give {3}", |
183 | toAgentID, client.AgentId, client.Name, message); | 183 | toAgentID, client.AgentId, client.Name, message); |
184 | } | 184 | } |
185 | } | 185 | } |
186 | else if (dialog == (byte)InstantMessageDialog.InventoryDeclined) | 186 | else if (dialog == (byte)InstantMessageDialog.InventoryDeclined) |
187 | { | 187 | { |
188 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) | 188 | if (m_scene.Entities.ContainsKey(toAgentID) && m_scene.Entities[toAgentID] is ScenePresence) |
189 | { | 189 | { |
190 | ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; | 190 | ScenePresence user = (ScenePresence)m_scene.Entities[toAgentID]; |
191 | 191 | ||
192 | if (!user.IsChildAgent) | 192 | if (!user.IsChildAgent) |
193 | { | 193 | { |
194 | user.ControllingClient.SendInstantMessage( | 194 | user.ControllingClient.SendInstantMessage( |
195 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, | 195 | fromAgentID, fromAgentSession, message, toAgentID, imSessionID, fromAgentName, |
196 | dialog, timestamp, binaryBucket); | 196 | dialog, timestamp, binaryBucket); |
197 | 197 | ||
198 | if (m_pendingOffers.ContainsKey(imSessionID)) | 198 | if (m_pendingOffers.ContainsKey(imSessionID)) |
199 | { | 199 | { |
200 | m_log.DebugFormat( | 200 | m_log.DebugFormat( |
201 | "[AGENT INVENTORY]: Declined item id {0}", m_pendingOffers[imSessionID]); | 201 | "[AGENT INVENTORY]: Declined item id {0}", m_pendingOffers[imSessionID]); |
202 | 202 | ||
203 | m_pendingOffers.Remove(imSessionID); | 203 | m_pendingOffers.Remove(imSessionID); |
204 | } | 204 | } |
205 | else | 205 | else |
206 | { | 206 | { |
207 | m_log.ErrorFormat( | 207 | m_log.ErrorFormat( |
208 | "[AGENT INVENTORY]: Could not find an item associated with session id {0} to decline", | 208 | "[AGENT INVENTORY]: Could not find an item associated with session id {0} to decline", |
209 | imSessionID); | 209 | imSessionID); |
210 | } | 210 | } |
211 | } | 211 | } |
212 | } | 212 | } |
213 | } | 213 | } |
214 | } | 214 | } |
215 | } | 215 | } |
216 | } | 216 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/AvatarProfilesModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Profiles/AvatarProfilesModule.cs index 44b3f8b..f8b14d3 100644 --- a/OpenSim/Region/Environment/Modules/AvatarProfilesModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Profiles/AvatarProfilesModule.cs | |||
@@ -1,129 +1,129 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Reflection; | 29 | using System.Reflection; |
30 | using libsecondlife; | 30 | using libsecondlife; |
31 | using log4net; | 31 | using log4net; |
32 | using Nini.Config; | 32 | using Nini.Config; |
33 | using OpenSim.Framework; | 33 | using OpenSim.Framework; |
34 | using OpenSim.Region.Environment.Interfaces; | 34 | using OpenSim.Region.Environment.Interfaces; |
35 | using OpenSim.Region.Environment.Scenes; | 35 | using OpenSim.Region.Environment.Scenes; |
36 | 36 | ||
37 | namespace OpenSim.Region.Environment.Modules | 37 | namespace OpenSim.Region.Environment.Modules.Avatar.Profiles |
38 | { | 38 | { |
39 | public class AvatarProfilesModule : IRegionModule | 39 | public class AvatarProfilesModule : IRegionModule |
40 | { | 40 | { |
41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 41 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
42 | private Scene m_scene; | 42 | private Scene m_scene; |
43 | 43 | ||
44 | public AvatarProfilesModule() | 44 | public AvatarProfilesModule() |
45 | { | 45 | { |
46 | } | 46 | } |
47 | 47 | ||
48 | public void Initialise(Scene scene, IConfigSource config) | 48 | public void Initialise(Scene scene, IConfigSource config) |
49 | { | 49 | { |
50 | m_scene = scene; | 50 | m_scene = scene; |
51 | m_scene.EventManager.OnNewClient += NewClient; | 51 | m_scene.EventManager.OnNewClient += NewClient; |
52 | } | 52 | } |
53 | 53 | ||
54 | public void PostInitialise() | 54 | public void PostInitialise() |
55 | { | 55 | { |
56 | } | 56 | } |
57 | 57 | ||
58 | public void Close() | 58 | public void Close() |
59 | { | 59 | { |
60 | } | 60 | } |
61 | 61 | ||
62 | public string Name | 62 | public string Name |
63 | { | 63 | { |
64 | get { return "AvatarProfilesModule"; } | 64 | get { return "AvatarProfilesModule"; } |
65 | } | 65 | } |
66 | 66 | ||
67 | public bool IsSharedModule | 67 | public bool IsSharedModule |
68 | { | 68 | { |
69 | get { return false; } | 69 | get { return false; } |
70 | } | 70 | } |
71 | 71 | ||
72 | public void NewClient(IClientAPI client) | 72 | public void NewClient(IClientAPI client) |
73 | { | 73 | { |
74 | client.OnRequestAvatarProperties += RequestAvatarProperty; | 74 | client.OnRequestAvatarProperties += RequestAvatarProperty; |
75 | client.OnUpdateAvatarProperties += UpdateAvatarProperties; | 75 | client.OnUpdateAvatarProperties += UpdateAvatarProperties; |
76 | } | 76 | } |
77 | 77 | ||
78 | public void RemoveClient(IClientAPI client) | 78 | public void RemoveClient(IClientAPI client) |
79 | { | 79 | { |
80 | client.OnRequestAvatarProperties -= RequestAvatarProperty; | 80 | client.OnRequestAvatarProperties -= RequestAvatarProperty; |
81 | client.OnUpdateAvatarProperties -= UpdateAvatarProperties; | 81 | client.OnUpdateAvatarProperties -= UpdateAvatarProperties; |
82 | } | 82 | } |
83 | 83 | ||
84 | /// <summary> | 84 | /// <summary> |
85 | /// | 85 | /// |
86 | /// </summary> | 86 | /// </summary> |
87 | /// <param name="remoteClient"></param> | 87 | /// <param name="remoteClient"></param> |
88 | /// <param name="avatarID"></param> | 88 | /// <param name="avatarID"></param> |
89 | public void RequestAvatarProperty(IClientAPI remoteClient, LLUUID avatarID) | 89 | public void RequestAvatarProperty(IClientAPI remoteClient, LLUUID avatarID) |
90 | { | 90 | { |
91 | // FIXME: finish adding fields such as url, masking, etc. | 91 | // FIXME: finish adding fields such as url, masking, etc. |
92 | LLUUID partner = new LLUUID("11111111-1111-0000-0000-000100bba000"); | 92 | LLUUID partner = new LLUUID("11111111-1111-0000-0000-000100bba000"); |
93 | UserProfileData profile = m_scene.CommsManager.UserService.GetUserProfile(avatarID); | 93 | UserProfileData profile = m_scene.CommsManager.UserService.GetUserProfile(avatarID); |
94 | if (null != profile) | 94 | if (null != profile) |
95 | { | 95 | { |
96 | remoteClient.SendAvatarProperties(profile.ID, profile.AboutText, | 96 | remoteClient.SendAvatarProperties(profile.ID, profile.AboutText, |
97 | Util.ToDateTime(profile.Created).ToString(), | 97 | Util.ToDateTime(profile.Created).ToString(), |
98 | String.Empty, profile.FirstLifeAboutText, profile.CanDoMask, | 98 | String.Empty, profile.FirstLifeAboutText, profile.CanDoMask, |
99 | profile.FirstLifeImage, profile.Image, String.Empty, partner); | 99 | profile.FirstLifeImage, profile.Image, String.Empty, partner); |
100 | } | 100 | } |
101 | else | 101 | else |
102 | { | 102 | { |
103 | m_log.Debug("[AvatarProfilesModule]: Got null for profile for " + avatarID.ToString()); | 103 | m_log.Debug("[AvatarProfilesModule]: Got null for profile for " + avatarID.ToString()); |
104 | } | 104 | } |
105 | } | 105 | } |
106 | 106 | ||
107 | public void UpdateAvatarProperties(IClientAPI remoteClient, UserProfileData newProfile) | 107 | public void UpdateAvatarProperties(IClientAPI remoteClient, UserProfileData newProfile) |
108 | { | 108 | { |
109 | UserProfileData Profile = m_scene.CommsManager.UserService.GetUserProfile(newProfile.ID); | 109 | UserProfileData Profile = m_scene.CommsManager.UserService.GetUserProfile(newProfile.ID); |
110 | 110 | ||
111 | // if it's the profile of the user requesting the update, then we change only a few things. | 111 | // if it's the profile of the user requesting the update, then we change only a few things. |
112 | if (remoteClient.AgentId.CompareTo(Profile.ID) == 0) | 112 | if (remoteClient.AgentId.CompareTo(Profile.ID) == 0) |
113 | { | 113 | { |
114 | Profile.Image = newProfile.Image; | 114 | Profile.Image = newProfile.Image; |
115 | Profile.FirstLifeImage = newProfile.FirstLifeImage; | 115 | Profile.FirstLifeImage = newProfile.FirstLifeImage; |
116 | Profile.AboutText = newProfile.AboutText; | 116 | Profile.AboutText = newProfile.AboutText; |
117 | Profile.FirstLifeAboutText = newProfile.FirstLifeAboutText; | 117 | Profile.FirstLifeAboutText = newProfile.FirstLifeAboutText; |
118 | } | 118 | } |
119 | else | 119 | else |
120 | { | 120 | { |
121 | return; | 121 | return; |
122 | } | 122 | } |
123 | if (m_scene.CommsManager.UserService.UpdateUserProfileProperties(Profile)) | 123 | if (m_scene.CommsManager.UserService.UpdateUserProfileProperties(Profile)) |
124 | { | 124 | { |
125 | RequestAvatarProperty(remoteClient, newProfile.ID); | 125 | RequestAvatarProperty(remoteClient, newProfile.ID); |
126 | } | 126 | } |
127 | } | 127 | } |
128 | } | 128 | } |
129 | } | 129 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/AsteriskVoiceModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs index 38c0c1d..0d7de78 100644 --- a/OpenSim/Region/Environment/Modules/AsteriskVoiceModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Voice/AsterixVoice/AsteriskVoiceModule.cs | |||
@@ -1,285 +1,285 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using log4net; | 32 | using log4net; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using Nwc.XmlRpc; | 34 | using Nwc.XmlRpc; |
35 | using OpenSim.Framework; | 35 | using OpenSim.Framework; |
36 | using OpenSim.Framework.Communications.Cache; | 36 | using OpenSim.Framework.Communications.Cache; |
37 | using OpenSim.Framework.Servers; | 37 | using OpenSim.Framework.Servers; |
38 | using OpenSim.Region.Capabilities; | 38 | using OpenSim.Region.Capabilities; |
39 | using OpenSim.Region.Environment.Interfaces; | 39 | using OpenSim.Region.Environment.Interfaces; |
40 | using OpenSim.Region.Environment.Scenes; | 40 | using OpenSim.Region.Environment.Scenes; |
41 | using Caps=OpenSim.Region.Capabilities.Caps; | 41 | using Caps=OpenSim.Region.Capabilities.Caps; |
42 | 42 | ||
43 | namespace OpenSim.Region.Environment.Modules | 43 | namespace OpenSim.Region.Environment.Modules.Avatar.Voice.AsterixVoice |
44 | { | 44 | { |
45 | public class AsteriskVoiceModule : IRegionModule | 45 | public class AsteriskVoiceModule : IRegionModule |
46 | { | 46 | { |
47 | private static readonly ILog m_log = | 47 | private static readonly ILog m_log = |
48 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 48 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
49 | 49 | ||
50 | private Scene m_scene; | 50 | private Scene m_scene; |
51 | private IConfig m_config; | 51 | private IConfig m_config; |
52 | private string m_asterisk; | 52 | private string m_asterisk; |
53 | private string m_asterisk_password; | 53 | private string m_asterisk_password; |
54 | private string m_asterisk_salt; | 54 | private string m_asterisk_salt; |
55 | private int m_asterisk_timeout; | 55 | private int m_asterisk_timeout; |
56 | private string m_sipDomain; | 56 | private string m_sipDomain; |
57 | private string m_confDomain; | 57 | private string m_confDomain; |
58 | 58 | ||
59 | private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; | 59 | private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; |
60 | private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; | 60 | private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; |
61 | 61 | ||
62 | public void Initialise(Scene scene, IConfigSource config) | 62 | public void Initialise(Scene scene, IConfigSource config) |
63 | { | 63 | { |
64 | m_scene = scene; | 64 | m_scene = scene; |
65 | m_config = config.Configs["AsteriskVoice"]; | 65 | m_config = config.Configs["AsteriskVoice"]; |
66 | 66 | ||
67 | if (null == m_config) | 67 | if (null == m_config) |
68 | { | 68 | { |
69 | m_log.Info("[ASTERISKVOICE] no config found, plugin disabled"); | 69 | m_log.Info("[ASTERISKVOICE] no config found, plugin disabled"); |
70 | return; | 70 | return; |
71 | } | 71 | } |
72 | 72 | ||
73 | if (!m_config.GetBoolean("enabled", false)) | 73 | if (!m_config.GetBoolean("enabled", false)) |
74 | { | 74 | { |
75 | m_log.Info("[ASTERISKVOICE] plugin disabled by configuration"); | 75 | m_log.Info("[ASTERISKVOICE] plugin disabled by configuration"); |
76 | return; | 76 | return; |
77 | } | 77 | } |
78 | m_log.Info("[ASTERISKVOICE] plugin enabled"); | 78 | m_log.Info("[ASTERISKVOICE] plugin enabled"); |
79 | 79 | ||
80 | try { | 80 | try { |
81 | m_sipDomain = m_config.GetString("sip_domain", String.Empty); | 81 | m_sipDomain = m_config.GetString("sip_domain", String.Empty); |
82 | m_log.InfoFormat("[ASTERISKVOICE] using SIP domain {0}", m_sipDomain); | 82 | m_log.InfoFormat("[ASTERISKVOICE] using SIP domain {0}", m_sipDomain); |
83 | 83 | ||
84 | m_confDomain = m_config.GetString("conf_domain", String.Empty); | 84 | m_confDomain = m_config.GetString("conf_domain", String.Empty); |
85 | m_log.InfoFormat("[ASTERISKVOICE] using conf domain {0}", m_confDomain); | 85 | m_log.InfoFormat("[ASTERISKVOICE] using conf domain {0}", m_confDomain); |
86 | 86 | ||
87 | m_asterisk = m_config.GetString("asterisk_frontend", String.Empty); | 87 | m_asterisk = m_config.GetString("asterisk_frontend", String.Empty); |
88 | m_asterisk_password = m_config.GetString("asterisk_password", String.Empty); | 88 | m_asterisk_password = m_config.GetString("asterisk_password", String.Empty); |
89 | m_asterisk_timeout = m_config.GetInt("asterisk_timeout", 3000); | 89 | m_asterisk_timeout = m_config.GetInt("asterisk_timeout", 3000); |
90 | m_asterisk_salt = m_config.GetString("asterisk_salt", "Wuffwuff"); | 90 | m_asterisk_salt = m_config.GetString("asterisk_salt", "Wuffwuff"); |
91 | if (String.IsNullOrEmpty(m_asterisk)) throw new Exception("missing asterisk_frontend config parameter"); | 91 | if (String.IsNullOrEmpty(m_asterisk)) throw new Exception("missing asterisk_frontend config parameter"); |
92 | if (String.IsNullOrEmpty(m_asterisk_password)) throw new Exception("missing asterisk_password config parameter"); | 92 | if (String.IsNullOrEmpty(m_asterisk_password)) throw new Exception("missing asterisk_password config parameter"); |
93 | m_log.InfoFormat("[ASTERISKVOICE] using asterisk front end {0}", m_asterisk); | 93 | m_log.InfoFormat("[ASTERISKVOICE] using asterisk front end {0}", m_asterisk); |
94 | 94 | ||
95 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; | 95 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; |
96 | } | 96 | } |
97 | catch (Exception e) | 97 | catch (Exception e) |
98 | { | 98 | { |
99 | m_log.ErrorFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.Message); | 99 | m_log.ErrorFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.Message); |
100 | m_log.DebugFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.ToString()); | 100 | m_log.DebugFormat("[ASTERISKVOICE] plugin initialization failed: {0}", e.ToString()); |
101 | return; | 101 | return; |
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | public void PostInitialise() | 105 | public void PostInitialise() |
106 | { | 106 | { |
107 | } | 107 | } |
108 | 108 | ||
109 | public void Close() | 109 | public void Close() |
110 | { | 110 | { |
111 | } | 111 | } |
112 | 112 | ||
113 | public string Name | 113 | public string Name |
114 | { | 114 | { |
115 | get { return "AsteriskVoiceModule"; } | 115 | get { return "AsteriskVoiceModule"; } |
116 | } | 116 | } |
117 | 117 | ||
118 | public bool IsSharedModule | 118 | public bool IsSharedModule |
119 | { | 119 | { |
120 | get { return false; } | 120 | get { return false; } |
121 | } | 121 | } |
122 | 122 | ||
123 | public void OnRegisterCaps(LLUUID agentID, Caps caps) | 123 | public void OnRegisterCaps(LLUUID agentID, Caps caps) |
124 | { | 124 | { |
125 | m_log.DebugFormat("[ASTERISKVOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); | 125 | m_log.DebugFormat("[ASTERISKVOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); |
126 | string capsBase = "/CAPS/" + caps.CapsObjectPath; | 126 | string capsBase = "/CAPS/" + caps.CapsObjectPath; |
127 | caps.RegisterHandler("ParcelVoiceInfoRequest", | 127 | caps.RegisterHandler("ParcelVoiceInfoRequest", |
128 | new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, | 128 | new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, |
129 | delegate(string request, string path, string param) | 129 | delegate(string request, string path, string param) |
130 | { | 130 | { |
131 | return ParcelVoiceInfoRequest(request, path, param, | 131 | return ParcelVoiceInfoRequest(request, path, param, |
132 | agentID, caps); | 132 | agentID, caps); |
133 | })); | 133 | })); |
134 | caps.RegisterHandler("ProvisionVoiceAccountRequest", | 134 | caps.RegisterHandler("ProvisionVoiceAccountRequest", |
135 | new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, | 135 | new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, |
136 | delegate(string request, string path, string param) | 136 | delegate(string request, string path, string param) |
137 | { | 137 | { |
138 | return ProvisionVoiceAccountRequest(request, path, param, | 138 | return ProvisionVoiceAccountRequest(request, path, param, |
139 | agentID, caps); | 139 | agentID, caps); |
140 | })); | 140 | })); |
141 | } | 141 | } |
142 | 142 | ||
143 | /// <summary> | 143 | /// <summary> |
144 | /// Callback for a client request for ParcelVoiceInfo | 144 | /// Callback for a client request for ParcelVoiceInfo |
145 | /// </summary> | 145 | /// </summary> |
146 | /// <param name="request"></param> | 146 | /// <param name="request"></param> |
147 | /// <param name="path"></param> | 147 | /// <param name="path"></param> |
148 | /// <param name="param"></param> | 148 | /// <param name="param"></param> |
149 | /// <param name="agentID"></param> | 149 | /// <param name="agentID"></param> |
150 | /// <param name="caps"></param> | 150 | /// <param name="caps"></param> |
151 | /// <returns></returns> | 151 | /// <returns></returns> |
152 | public string ParcelVoiceInfoRequest(string request, string path, string param, | 152 | public string ParcelVoiceInfoRequest(string request, string path, string param, |
153 | LLUUID agentID, Caps caps) | 153 | LLUUID agentID, Caps caps) |
154 | { | 154 | { |
155 | // we need to do: | 155 | // we need to do: |
156 | // - send channel_uri: as "sip:regionID@m_sipDomain" | 156 | // - send channel_uri: as "sip:regionID@m_sipDomain" |
157 | try | 157 | try |
158 | { | 158 | { |
159 | m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", | 159 | m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", |
160 | request, path, param); | 160 | request, path, param); |
161 | 161 | ||
162 | 162 | ||
163 | // setup response to client | 163 | // setup response to client |
164 | Hashtable creds = new Hashtable(); | 164 | Hashtable creds = new Hashtable(); |
165 | creds["channel_uri"] = String.Format("sip:{0}@{1}", | 165 | creds["channel_uri"] = String.Format("sip:{0}@{1}", |
166 | m_scene.RegionInfo.RegionID, m_sipDomain); | 166 | m_scene.RegionInfo.RegionID, m_sipDomain); |
167 | 167 | ||
168 | string regionName = m_scene.RegionInfo.RegionName; | 168 | string regionName = m_scene.RegionInfo.RegionName; |
169 | ScenePresence avatar = m_scene.GetScenePresence(agentID); | 169 | ScenePresence avatar = m_scene.GetScenePresence(agentID); |
170 | if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); | 170 | if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); |
171 | LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | 171 | LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); |
172 | 172 | ||
173 | LLSDParcelVoiceInfoResponse parcelVoiceInfo = | 173 | LLSDParcelVoiceInfoResponse parcelVoiceInfo = |
174 | new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds); | 174 | new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds); |
175 | 175 | ||
176 | string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); | 176 | string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); |
177 | 177 | ||
178 | 178 | ||
179 | // update region on asterisk-opensim frontend | 179 | // update region on asterisk-opensim frontend |
180 | Hashtable requestData = new Hashtable(); | 180 | Hashtable requestData = new Hashtable(); |
181 | requestData["admin_password"] = m_asterisk_password; | 181 | requestData["admin_password"] = m_asterisk_password; |
182 | requestData["region"] = m_scene.RegionInfo.RegionID.ToString(); | 182 | requestData["region"] = m_scene.RegionInfo.RegionID.ToString(); |
183 | if (!String.IsNullOrEmpty(m_confDomain)) | 183 | if (!String.IsNullOrEmpty(m_confDomain)) |
184 | { | 184 | { |
185 | requestData["region"] += String.Format("@{0}", m_confDomain); | 185 | requestData["region"] += String.Format("@{0}", m_confDomain); |
186 | } | 186 | } |
187 | 187 | ||
188 | ArrayList SendParams = new ArrayList(); | 188 | ArrayList SendParams = new ArrayList(); |
189 | SendParams.Add(requestData); | 189 | SendParams.Add(requestData); |
190 | XmlRpcRequest updateAccountRequest = new XmlRpcRequest("region_update", SendParams); | 190 | XmlRpcRequest updateAccountRequest = new XmlRpcRequest("region_update", SendParams); |
191 | XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); | 191 | XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); |
192 | Hashtable responseData = (Hashtable)updateAccountResponse.Value; | 192 | Hashtable responseData = (Hashtable)updateAccountResponse.Value; |
193 | 193 | ||
194 | if (!responseData.ContainsKey("success")) throw new Exception("region_update call failed"); | 194 | if (!responseData.ContainsKey("success")) throw new Exception("region_update call failed"); |
195 | 195 | ||
196 | bool success = Convert.ToBoolean((string)responseData["success"]); | 196 | bool success = Convert.ToBoolean((string)responseData["success"]); |
197 | if (!success) throw new Exception("region_update failed"); | 197 | if (!success) throw new Exception("region_update failed"); |
198 | 198 | ||
199 | 199 | ||
200 | m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: {0}", r); | 200 | m_log.DebugFormat("[ASTERISKVOICE][PARCELVOICE]: {0}", r); |
201 | return r; | 201 | return r; |
202 | } | 202 | } |
203 | catch (Exception e) | 203 | catch (Exception e) |
204 | { | 204 | { |
205 | m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0}, retry later", e.Message); | 205 | m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0}, retry later", e.Message); |
206 | m_log.DebugFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0} failed", e.ToString()); | 206 | m_log.DebugFormat("[ASTERISKVOICE][CAPS][PARCELVOICE]: {0} failed", e.ToString()); |
207 | 207 | ||
208 | return "<llsd>undef</llsd>"; | 208 | return "<llsd>undef</llsd>"; |
209 | } | 209 | } |
210 | } | 210 | } |
211 | 211 | ||
212 | /// <summary> | 212 | /// <summary> |
213 | /// Callback for a client request for Voice Account Details | 213 | /// Callback for a client request for Voice Account Details |
214 | /// </summary> | 214 | /// </summary> |
215 | /// <param name="request"></param> | 215 | /// <param name="request"></param> |
216 | /// <param name="path"></param> | 216 | /// <param name="path"></param> |
217 | /// <param name="param"></param> | 217 | /// <param name="param"></param> |
218 | /// <param name="agentID"></param> | 218 | /// <param name="agentID"></param> |
219 | /// <param name="caps"></param> | 219 | /// <param name="caps"></param> |
220 | /// <returns></returns> | 220 | /// <returns></returns> |
221 | public string ProvisionVoiceAccountRequest(string request, string path, string param, | 221 | public string ProvisionVoiceAccountRequest(string request, string path, string param, |
222 | LLUUID agentID, Caps caps) | 222 | LLUUID agentID, Caps caps) |
223 | { | 223 | { |
224 | // we need to | 224 | // we need to |
225 | // - get user data from UserProfileCacheService | 225 | // - get user data from UserProfileCacheService |
226 | // - generate nonce for user voice account password | 226 | // - generate nonce for user voice account password |
227 | // - issue XmlRpc request to asterisk opensim front end: | 227 | // - issue XmlRpc request to asterisk opensim front end: |
228 | // + user: base 64 encoded user name (otherwise SL | 228 | // + user: base 64 encoded user name (otherwise SL |
229 | // client is unhappy) | 229 | // client is unhappy) |
230 | // + password: nonce | 230 | // + password: nonce |
231 | // - the XmlRpc call to asteris-opensim was successful: | 231 | // - the XmlRpc call to asteris-opensim was successful: |
232 | // send account details back to client | 232 | // send account details back to client |
233 | try | 233 | try |
234 | { | 234 | { |
235 | m_log.DebugFormat("[ASTERISKVOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", | 235 | m_log.DebugFormat("[ASTERISKVOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", |
236 | request, path, param); | 236 | request, path, param); |
237 | 237 | ||
238 | // get user data & prepare voice account response | 238 | // get user data & prepare voice account response |
239 | string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); | 239 | string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); |
240 | voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); | 240 | voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); |
241 | 241 | ||
242 | CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); | 242 | CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); |
243 | if (null == userInfo) throw new Exception("cannot get user details"); | 243 | if (null == userInfo) throw new Exception("cannot get user details"); |
244 | 244 | ||
245 | // we generate a nonce everytime | 245 | // we generate a nonce everytime |
246 | string voicePassword = "$1$" + Util.Md5Hash(DateTime.UtcNow.ToLongTimeString() + m_asterisk_salt); | 246 | string voicePassword = "$1$" + Util.Md5Hash(DateTime.UtcNow.ToLongTimeString() + m_asterisk_salt); |
247 | LLSDVoiceAccountResponse voiceAccountResponse = | 247 | LLSDVoiceAccountResponse voiceAccountResponse = |
248 | new LLSDVoiceAccountResponse(voiceUser, voicePassword); | 248 | new LLSDVoiceAccountResponse(voiceUser, voicePassword); |
249 | string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); | 249 | string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); |
250 | m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); | 250 | m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); |
251 | 251 | ||
252 | 252 | ||
253 | // update user account on asterisk frontend | 253 | // update user account on asterisk frontend |
254 | Hashtable requestData = new Hashtable(); | 254 | Hashtable requestData = new Hashtable(); |
255 | requestData["admin_password"] = m_asterisk_password; | 255 | requestData["admin_password"] = m_asterisk_password; |
256 | requestData["username"] = voiceUser; | 256 | requestData["username"] = voiceUser; |
257 | if (!String.IsNullOrEmpty(m_sipDomain)) | 257 | if (!String.IsNullOrEmpty(m_sipDomain)) |
258 | { | 258 | { |
259 | requestData["username"] += String.Format("@{0}", m_sipDomain); | 259 | requestData["username"] += String.Format("@{0}", m_sipDomain); |
260 | } | 260 | } |
261 | requestData["password"] = voicePassword; | 261 | requestData["password"] = voicePassword; |
262 | 262 | ||
263 | ArrayList SendParams = new ArrayList(); | 263 | ArrayList SendParams = new ArrayList(); |
264 | SendParams.Add(requestData); | 264 | SendParams.Add(requestData); |
265 | XmlRpcRequest updateAccountRequest = new XmlRpcRequest("account_update", SendParams); | 265 | XmlRpcRequest updateAccountRequest = new XmlRpcRequest("account_update", SendParams); |
266 | XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); | 266 | XmlRpcResponse updateAccountResponse = updateAccountRequest.Send(m_asterisk, m_asterisk_timeout); |
267 | Hashtable responseData = (Hashtable)updateAccountResponse.Value; | 267 | Hashtable responseData = (Hashtable)updateAccountResponse.Value; |
268 | 268 | ||
269 | if (!responseData.ContainsKey("success")) throw new Exception("account_update call failed"); | 269 | if (!responseData.ContainsKey("success")) throw new Exception("account_update call failed"); |
270 | 270 | ||
271 | bool success = Convert.ToBoolean((string)responseData["success"]); | 271 | bool success = Convert.ToBoolean((string)responseData["success"]); |
272 | if (!success) throw new Exception("account_update failed"); | 272 | if (!success) throw new Exception("account_update failed"); |
273 | 273 | ||
274 | return r; | 274 | return r; |
275 | } | 275 | } |
276 | catch (Exception e) | 276 | catch (Exception e) |
277 | { | 277 | { |
278 | m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); | 278 | m_log.ErrorFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); |
279 | m_log.DebugFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0} failed", e.ToString()); | 279 | m_log.DebugFormat("[ASTERISKVOICE][CAPS][PROVISIONVOICE]: {0} failed", e.ToString()); |
280 | 280 | ||
281 | return "<llsd>undef</llsd>"; | 281 | return "<llsd>undef</llsd>"; |
282 | } | 282 | } |
283 | } | 283 | } |
284 | } | 284 | } |
285 | } | 285 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Environment/Modules/VoiceModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs index 106becd..8b7c3d0 100644 --- a/OpenSim/Region/Environment/Modules/VoiceModule.cs +++ b/OpenSim/Region/Environment/Modules/Avatar/Voice/SIPVoice/SIPVoiceModule.cs | |||
@@ -1,197 +1,197 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyright | 9 | * * Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSim Project nor the | 12 | * * Neither the name of the OpenSim Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections; | 29 | using System.Collections; |
30 | using System.Reflection; | 30 | using System.Reflection; |
31 | using libsecondlife; | 31 | using libsecondlife; |
32 | using log4net; | 32 | using log4net; |
33 | using Nini.Config; | 33 | using Nini.Config; |
34 | using OpenSim.Framework; | 34 | using OpenSim.Framework; |
35 | using OpenSim.Framework.Communications.Cache; | 35 | using OpenSim.Framework.Communications.Cache; |
36 | using OpenSim.Framework.Servers; | 36 | using OpenSim.Framework.Servers; |
37 | using OpenSim.Region.Capabilities; | 37 | using OpenSim.Region.Capabilities; |
38 | using OpenSim.Region.Environment.Interfaces; | 38 | using OpenSim.Region.Environment.Interfaces; |
39 | using OpenSim.Region.Environment.Scenes; | 39 | using OpenSim.Region.Environment.Scenes; |
40 | using Caps=OpenSim.Region.Capabilities.Caps; | 40 | using Caps=OpenSim.Region.Capabilities.Caps; |
41 | 41 | ||
42 | namespace OpenSim.Region.Environment.Modules | 42 | namespace OpenSim.Region.Environment.Modules.Avatar.Voice.SIPVoice |
43 | { | 43 | { |
44 | public class VoiceModule : IRegionModule | 44 | public class SIPVoiceModule : IRegionModule |
45 | { | 45 | { |
46 | private static readonly ILog m_log = | 46 | private static readonly ILog m_log = |
47 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 48 | ||
49 | private Scene m_scene; | 49 | private Scene m_scene; |
50 | private IConfig m_config; | 50 | private IConfig m_config; |
51 | private string m_sipDomain; | 51 | private string m_sipDomain; |
52 | 52 | ||
53 | private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; | 53 | private static readonly string m_parcelVoiceInfoRequestPath = "0007/"; |
54 | private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; | 54 | private static readonly string m_provisionVoiceAccountRequestPath = "0008/"; |
55 | 55 | ||
56 | public void Initialise(Scene scene, IConfigSource config) | 56 | public void Initialise(Scene scene, IConfigSource config) |
57 | { | 57 | { |
58 | m_scene = scene; | 58 | m_scene = scene; |
59 | m_config = config.Configs["Voice"]; | 59 | m_config = config.Configs["Voice"]; |
60 | 60 | ||
61 | if (null == m_config || !m_config.GetBoolean("enabled", false)) | 61 | if (null == m_config || !m_config.GetBoolean("enabled", false)) |
62 | { | 62 | { |
63 | m_log.Info("[VOICE] plugin disabled"); | 63 | m_log.Info("[VOICE] plugin disabled"); |
64 | return; | 64 | return; |
65 | } | 65 | } |
66 | m_log.Info("[VOICE] plugin enabled"); | 66 | m_log.Info("[VOICE] plugin enabled"); |
67 | 67 | ||
68 | m_sipDomain = m_config.GetString("sip_domain", String.Empty); | 68 | m_sipDomain = m_config.GetString("sip_domain", String.Empty); |
69 | if (String.IsNullOrEmpty(m_sipDomain)) | 69 | if (String.IsNullOrEmpty(m_sipDomain)) |
70 | { | 70 | { |
71 | m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration"); | 71 | m_log.Error("[VOICE] plugin mis-configured: missing sip_domain configuration"); |
72 | m_log.Info("[VOICE] plugin disabled"); | 72 | m_log.Info("[VOICE] plugin disabled"); |
73 | return; | 73 | return; |
74 | } | 74 | } |
75 | m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain); | 75 | m_log.InfoFormat("[VOICE] using SIP domain {0}", m_sipDomain); |
76 | 76 | ||
77 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; | 77 | scene.EventManager.OnRegisterCaps += OnRegisterCaps; |
78 | } | 78 | } |
79 | 79 | ||
80 | public void PostInitialise() | 80 | public void PostInitialise() |
81 | { | 81 | { |
82 | } | 82 | } |
83 | 83 | ||
84 | public void Close() | 84 | public void Close() |
85 | { | 85 | { |
86 | } | 86 | } |
87 | 87 | ||
88 | public string Name | 88 | public string Name |
89 | { | 89 | { |
90 | get { return "VoiceModule"; } | 90 | get { return "VoiceModule"; } |
91 | } | 91 | } |
92 | 92 | ||
93 | public bool IsSharedModule | 93 | public bool IsSharedModule |
94 | { | 94 | { |
95 | get { return false; } | 95 | get { return false; } |
96 | } | 96 | } |
97 | 97 | ||
98 | public void OnRegisterCaps(LLUUID agentID, Caps caps) | 98 | public void OnRegisterCaps(LLUUID agentID, Caps caps) |
99 | { | 99 | { |
100 | m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); | 100 | m_log.DebugFormat("[VOICE] OnRegisterCaps: agentID {0} caps {1}", agentID, caps); |
101 | string capsBase = "/CAPS/" + caps.CapsObjectPath; | 101 | string capsBase = "/CAPS/" + caps.CapsObjectPath; |
102 | caps.RegisterHandler("ParcelVoiceInfoRequest", | 102 | caps.RegisterHandler("ParcelVoiceInfoRequest", |
103 | new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, | 103 | new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath, |
104 | delegate(string request, string path, string param) | 104 | delegate(string request, string path, string param) |
105 | { | 105 | { |
106 | return ParcelVoiceInfoRequest(request, path, param, | 106 | return ParcelVoiceInfoRequest(request, path, param, |
107 | agentID, caps); | 107 | agentID, caps); |
108 | })); | 108 | })); |
109 | caps.RegisterHandler("ProvisionVoiceAccountRequest", | 109 | caps.RegisterHandler("ProvisionVoiceAccountRequest", |
110 | new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, | 110 | new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath, |
111 | delegate(string request, string path, string param) | 111 | delegate(string request, string path, string param) |
112 | { | 112 | { |
113 | return ProvisionVoiceAccountRequest(request, path, param, | 113 | return ProvisionVoiceAccountRequest(request, path, param, |
114 | agentID, caps); | 114 | agentID, caps); |
115 | })); | 115 | })); |
116 | } | 116 | } |
117 | 117 | ||
118 | /// <summary> | 118 | /// <summary> |
119 | /// Callback for a client request for ParcelVoiceInfo | 119 | /// Callback for a client request for ParcelVoiceInfo |
120 | /// </summary> | 120 | /// </summary> |
121 | /// <param name="request"></param> | 121 | /// <param name="request"></param> |
122 | /// <param name="path"></param> | 122 | /// <param name="path"></param> |
123 | /// <param name="param"></param> | 123 | /// <param name="param"></param> |
124 | /// <param name="agentID"></param> | 124 | /// <param name="agentID"></param> |
125 | /// <param name="caps"></param> | 125 | /// <param name="caps"></param> |
126 | /// <returns></returns> | 126 | /// <returns></returns> |
127 | public string ParcelVoiceInfoRequest(string request, string path, string param, | 127 | public string ParcelVoiceInfoRequest(string request, string path, string param, |
128 | LLUUID agentID, Caps caps) | 128 | LLUUID agentID, Caps caps) |
129 | { | 129 | { |
130 | try | 130 | try |
131 | { | 131 | { |
132 | m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param); | 132 | m_log.DebugFormat("[VOICE][PARCELVOICE]: request: {0}, path: {1}, param: {2}", request, path, param); |
133 | 133 | ||
134 | // FIXME: get the creds from region file or from config | 134 | // FIXME: get the creds from region file or from config |
135 | Hashtable creds = new Hashtable(); | 135 | Hashtable creds = new Hashtable(); |
136 | 136 | ||
137 | creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID.ToString(), m_sipDomain); | 137 | creds["channel_uri"] = String.Format("sip:{0}@{1}", agentID, m_sipDomain); |
138 | 138 | ||
139 | string regionName = m_scene.RegionInfo.RegionName; | 139 | string regionName = m_scene.RegionInfo.RegionName; |
140 | ScenePresence avatar = m_scene.GetScenePresence(agentID); | 140 | ScenePresence avatar = m_scene.GetScenePresence(agentID); |
141 | if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); | 141 | if (null == m_scene.LandChannel) throw new Exception("land data not yet available"); |
142 | LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); | 142 | LandData land = m_scene.GetLandData(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y); |
143 | 143 | ||
144 | LLSDParcelVoiceInfoResponse parcelVoiceInfo = | 144 | LLSDParcelVoiceInfoResponse parcelVoiceInfo = |
145 | new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds); | 145 | new LLSDParcelVoiceInfoResponse(regionName, land.localID, creds); |
146 | 146 | ||
147 | string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); | 147 | string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo); |
148 | m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r); | 148 | m_log.DebugFormat("[VOICE][PARCELVOICE]: {0}", r); |
149 | 149 | ||
150 | return r; | 150 | return r; |
151 | } | 151 | } |
152 | catch (Exception e) | 152 | catch (Exception e) |
153 | { | 153 | { |
154 | m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString()); | 154 | m_log.ErrorFormat("[CAPS]: {0}, try again later", e.ToString()); |
155 | } | 155 | } |
156 | 156 | ||
157 | return null; | 157 | return null; |
158 | } | 158 | } |
159 | 159 | ||
160 | /// <summary> | 160 | /// <summary> |
161 | /// Callback for a client request for Voice Account Details | 161 | /// Callback for a client request for Voice Account Details |
162 | /// </summary> | 162 | /// </summary> |
163 | /// <param name="request"></param> | 163 | /// <param name="request"></param> |
164 | /// <param name="path"></param> | 164 | /// <param name="path"></param> |
165 | /// <param name="param"></param> | 165 | /// <param name="param"></param> |
166 | /// <param name="agentID"></param> | 166 | /// <param name="agentID"></param> |
167 | /// <param name="caps"></param> | 167 | /// <param name="caps"></param> |
168 | /// <returns></returns> | 168 | /// <returns></returns> |
169 | public string ProvisionVoiceAccountRequest(string request, string path, string param, | 169 | public string ProvisionVoiceAccountRequest(string request, string path, string param, |
170 | LLUUID agentID, Caps caps) | 170 | LLUUID agentID, Caps caps) |
171 | { | 171 | { |
172 | try | 172 | try |
173 | { | 173 | { |
174 | m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", | 174 | m_log.DebugFormat("[VOICE][PROVISIONVOICE]: request: {0}, path: {1}, param: {2}", |
175 | request, path, param); | 175 | request, path, param); |
176 | 176 | ||
177 | string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); | 177 | string voiceUser = "x" + Convert.ToBase64String(agentID.GetBytes()); |
178 | voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); | 178 | voiceUser = voiceUser.Replace('+', '-').Replace('/', '_'); |
179 | 179 | ||
180 | CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); | 180 | CachedUserInfo userInfo = m_scene.CommsManager.UserProfileCacheService.GetUserDetails(agentID); |
181 | if (null == userInfo) throw new Exception("cannot get user details"); | 181 | if (null == userInfo) throw new Exception("cannot get user details"); |
182 | 182 | ||
183 | LLSDVoiceAccountResponse voiceAccountResponse = | 183 | LLSDVoiceAccountResponse voiceAccountResponse = |
184 | new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.PasswordHash); | 184 | new LLSDVoiceAccountResponse(voiceUser, "$1$" + userInfo.UserProfile.PasswordHash); |
185 | string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); | 185 | string r = LLSDHelpers.SerialiseLLSDReply(voiceAccountResponse); |
186 | m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); | 186 | m_log.DebugFormat("[CAPS][PROVISIONVOICE]: {0}", r); |
187 | return r; | 187 | return r; |
188 | } | 188 | } |
189 | catch (Exception e) | 189 | catch (Exception e) |
190 | { | 190 | { |
191 | m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); | 191 | m_log.ErrorFormat("[CAPS][PROVISIONVOICE]: {0}, retry later", e.Message); |
192 | } | 192 | } |
193 | 193 | ||
194 | return null; | 194 | return null; |
195 | } | 195 | } |
196 | } | 196 | } |
197 | } | 197 | } \ No newline at end of file |