opensim-development – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | eva | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ |
||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
||
4 | * |
||
5 | * Redistribution and use in source and binary forms, with or without |
||
6 | * modification, are permitted provided that the following conditions are met: |
||
7 | * * Redistributions of source code must retain the above copyright |
||
8 | * notice, this list of conditions and the following disclaimer. |
||
9 | * * Redistributions in binary form must reproduce the above copyright |
||
10 | * notice, this list of conditions and the following disclaimer in the |
||
11 | * documentation and/or other materials provided with the distribution. |
||
12 | * * Neither the name of the OpenSimulator Project nor the |
||
13 | * names of its contributors may be used to endorse or promote products |
||
14 | * derived from this software without specific prior written permission. |
||
15 | * |
||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||
26 | */ |
||
27 | |||
28 | using System; |
||
29 | using System.Collections.Generic; |
||
30 | using System.Collections.Specialized; |
||
31 | // DEBUG ON |
||
32 | using System.Diagnostics; |
||
33 | // DEBUG OFF |
||
34 | using System.Reflection; |
||
35 | using log4net; |
||
36 | using Mono.Addins; |
||
37 | using Nini.Config; |
||
38 | using OpenSim.Framework; |
||
39 | using OpenSim.Region.Framework.Interfaces; |
||
40 | using OpenSim.Region.Framework.Scenes; |
||
41 | using OpenSim.Services.Interfaces; |
||
42 | using OpenMetaverse; |
||
43 | using OpenMetaverse.StructuredData; |
||
44 | |||
45 | namespace OpenSim.Services.Connectors.SimianGrid |
||
46 | { |
||
47 | /// <summary> |
||
48 | /// Connects avatar appearance data to the SimianGrid backend |
||
49 | /// </summary> |
||
50 | [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "SimianAvatarServiceConnector")] |
||
51 | public class SimianAvatarServiceConnector : IAvatarService, ISharedRegionModule |
||
52 | { |
||
53 | private static readonly ILog m_log = |
||
54 | LogManager.GetLogger( |
||
55 | MethodBase.GetCurrentMethod().DeclaringType); |
||
56 | // private static string ZeroID = UUID.Zero.ToString(); |
||
57 | |||
58 | private string m_serverUrl = String.Empty; |
||
59 | private bool m_Enabled = false; |
||
60 | |||
61 | #region ISharedRegionModule |
||
62 | |||
63 | public Type ReplaceableInterface { get { return null; } } |
||
64 | public void RegionLoaded(Scene scene) { } |
||
65 | public void PostInitialise() { } |
||
66 | public void Close() { } |
||
67 | |||
68 | public SimianAvatarServiceConnector() { } |
||
69 | public string Name { get { return "SimianAvatarServiceConnector"; } } |
||
70 | public void AddRegion(Scene scene) { if (m_Enabled) { scene.RegisterModuleInterface<IAvatarService>(this); } } |
||
71 | public void RemoveRegion(Scene scene) { if (m_Enabled) { scene.UnregisterModuleInterface<IAvatarService>(this); } } |
||
72 | |||
73 | #endregion ISharedRegionModule |
||
74 | |||
75 | public SimianAvatarServiceConnector(IConfigSource source) |
||
76 | { |
||
77 | CommonInit(source); |
||
78 | } |
||
79 | |||
80 | public void Initialise(IConfigSource source) |
||
81 | { |
||
82 | IConfig moduleConfig = source.Configs["Modules"]; |
||
83 | if (moduleConfig != null) |
||
84 | { |
||
85 | string name = moduleConfig.GetString("AvatarServices", ""); |
||
86 | if (name == Name) |
||
87 | CommonInit(source); |
||
88 | } |
||
89 | } |
||
90 | |||
91 | private void CommonInit(IConfigSource source) |
||
92 | { |
||
93 | IConfig gridConfig = source.Configs["AvatarService"]; |
||
94 | if (gridConfig != null) |
||
95 | { |
||
96 | string serviceUrl = gridConfig.GetString("AvatarServerURI"); |
||
97 | if (!String.IsNullOrEmpty(serviceUrl)) |
||
98 | { |
||
99 | if (!serviceUrl.EndsWith("/") && !serviceUrl.EndsWith("=")) |
||
100 | serviceUrl = serviceUrl + '/'; |
||
101 | m_serverUrl = serviceUrl; |
||
102 | m_Enabled = true; |
||
103 | } |
||
104 | } |
||
105 | |||
106 | if (String.IsNullOrEmpty(m_serverUrl)) |
||
107 | m_log.Info("[SIMIAN AVATAR CONNECTOR]: No AvatarServerURI specified, disabling connector"); |
||
108 | } |
||
109 | |||
110 | #region IAvatarService |
||
111 | |||
112 | // <summary> |
||
113 | // Retrieves the LLPackedAppearance field from user data and unpacks |
||
114 | // it into an AvatarAppearance structure |
||
115 | // </summary> |
||
116 | // <param name="userID"></param> |
||
117 | public AvatarAppearance GetAppearance(UUID userID) |
||
118 | { |
||
119 | NameValueCollection requestArgs = new NameValueCollection |
||
120 | { |
||
121 | { "RequestMethod", "GetUser" }, |
||
122 | { "UserID", userID.ToString() } |
||
123 | }; |
||
124 | |||
125 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
126 | if (response["Success"].AsBoolean()) |
||
127 | { |
||
128 | OSDMap map = null; |
||
129 | try { map = OSDParser.DeserializeJson(response["LLPackedAppearance"].AsString()) as OSDMap; } |
||
130 | catch { } |
||
131 | |||
132 | if (map != null) |
||
133 | { |
||
134 | AvatarAppearance appearance = new AvatarAppearance(map); |
||
135 | // DEBUG ON |
||
136 | m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR] retrieved appearance for {0}:\n{1}",userID,appearance.ToString()); |
||
137 | // DEBUG OFF |
||
138 | return appearance; |
||
139 | } |
||
140 | |||
141 | m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to decode appearance for {0}",userID); |
||
142 | return null; |
||
143 | } |
||
144 | |||
145 | m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to get appearance for {0}: {1}", |
||
146 | userID,response["Message"].AsString()); |
||
147 | return null; |
||
148 | } |
||
149 | |||
150 | // <summary> |
||
151 | // </summary> |
||
152 | // <param name=""></param> |
||
153 | public bool SetAppearance(UUID userID, AvatarAppearance appearance) |
||
154 | { |
||
155 | OSDMap map = appearance.Pack(); |
||
156 | if (map == null) |
||
157 | { |
||
158 | m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to encode appearance for {0}",userID); |
||
159 | return false; |
||
160 | } |
||
161 | |||
162 | // m_log.DebugFormat("[SIMIAN AVATAR CONNECTOR] save appearance for {0}",userID); |
||
163 | |||
164 | NameValueCollection requestArgs = new NameValueCollection |
||
165 | { |
||
166 | { "RequestMethod", "AddUserData" }, |
||
167 | { "UserID", userID.ToString() }, |
||
168 | { "LLPackedAppearance", OSDParser.SerializeJsonString(map) } |
||
169 | }; |
||
170 | |||
171 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
172 | bool success = response["Success"].AsBoolean(); |
||
173 | |||
174 | if (! success) |
||
175 | m_log.WarnFormat("[SIMIAN AVATAR CONNECTOR]: Failed to save appearance for {0}: {1}", |
||
176 | userID,response["Message"].AsString()); |
||
177 | |||
178 | return success; |
||
179 | } |
||
180 | |||
181 | // <summary> |
||
182 | // </summary> |
||
183 | // <param name=""></param> |
||
184 | public AvatarData GetAvatar(UUID userID) |
||
185 | { |
||
186 | NameValueCollection requestArgs = new NameValueCollection |
||
187 | { |
||
188 | { "RequestMethod", "GetUser" }, |
||
189 | { "UserID", userID.ToString() } |
||
190 | }; |
||
191 | |||
192 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
193 | if (response["Success"].AsBoolean()) |
||
194 | { |
||
195 | OSDMap map = null; |
||
196 | try { map = OSDParser.DeserializeJson(response["LLAppearance"].AsString()) as OSDMap; } |
||
197 | catch { } |
||
198 | |||
199 | if (map != null) |
||
200 | { |
||
201 | AvatarWearable[] wearables = new AvatarWearable[13]; |
||
202 | wearables[0] = new AvatarWearable(map["ShapeItem"].AsUUID(), map["ShapeAsset"].AsUUID()); |
||
203 | wearables[1] = new AvatarWearable(map["SkinItem"].AsUUID(), map["SkinAsset"].AsUUID()); |
||
204 | wearables[2] = new AvatarWearable(map["HairItem"].AsUUID(), map["HairAsset"].AsUUID()); |
||
205 | wearables[3] = new AvatarWearable(map["EyesItem"].AsUUID(), map["EyesAsset"].AsUUID()); |
||
206 | wearables[4] = new AvatarWearable(map["ShirtItem"].AsUUID(), map["ShirtAsset"].AsUUID()); |
||
207 | wearables[5] = new AvatarWearable(map["PantsItem"].AsUUID(), map["PantsAsset"].AsUUID()); |
||
208 | wearables[6] = new AvatarWearable(map["ShoesItem"].AsUUID(), map["ShoesAsset"].AsUUID()); |
||
209 | wearables[7] = new AvatarWearable(map["SocksItem"].AsUUID(), map["SocksAsset"].AsUUID()); |
||
210 | wearables[8] = new AvatarWearable(map["JacketItem"].AsUUID(), map["JacketAsset"].AsUUID()); |
||
211 | wearables[9] = new AvatarWearable(map["GlovesItem"].AsUUID(), map["GlovesAsset"].AsUUID()); |
||
212 | wearables[10] = new AvatarWearable(map["UndershirtItem"].AsUUID(), map["UndershirtAsset"].AsUUID()); |
||
213 | wearables[11] = new AvatarWearable(map["UnderpantsItem"].AsUUID(), map["UnderpantsAsset"].AsUUID()); |
||
214 | wearables[12] = new AvatarWearable(map["SkirtItem"].AsUUID(), map["SkirtAsset"].AsUUID()); |
||
215 | |||
216 | AvatarAppearance appearance = new AvatarAppearance(); |
||
217 | appearance.Wearables = wearables; |
||
218 | appearance.AvatarHeight = (float)map["Height"].AsReal(); |
||
219 | |||
220 | AvatarData avatar = new AvatarData(appearance); |
||
221 | |||
222 | // Get attachments |
||
223 | map = null; |
||
224 | try { map = OSDParser.DeserializeJson(response["LLAttachments"].AsString()) as OSDMap; } |
||
225 | catch { } |
||
226 | |||
227 | if (map != null) |
||
228 | { |
||
229 | foreach (KeyValuePair<string, OSD> kvp in map) |
||
230 | avatar.Data[kvp.Key] = kvp.Value.AsString(); |
||
231 | } |
||
232 | |||
233 | return avatar; |
||
234 | } |
||
235 | else |
||
236 | { |
||
237 | m_log.Warn("[SIMIAN AVATAR CONNECTOR]: Failed to get user appearance for " + userID + |
||
238 | ", LLAppearance is missing or invalid"); |
||
239 | return null; |
||
240 | } |
||
241 | } |
||
242 | else |
||
243 | { |
||
244 | m_log.Warn("[SIMIAN AVATAR CONNECTOR]: Failed to get user appearance for " + userID + ": " + |
||
245 | response["Message"].AsString()); |
||
246 | } |
||
247 | |||
248 | return null; |
||
249 | } |
||
250 | |||
251 | // <summary> |
||
252 | // </summary> |
||
253 | // <param name=""></param> |
||
254 | public bool SetAvatar(UUID userID, AvatarData avatar) |
||
255 | { |
||
256 | m_log.Debug("[SIMIAN AVATAR CONNECTOR]: SetAvatar called for " + userID); |
||
257 | |||
258 | if (avatar.AvatarType == 1) // LLAvatar |
||
259 | { |
||
260 | AvatarAppearance appearance = avatar.ToAvatarAppearance(); |
||
261 | |||
262 | OSDMap map = new OSDMap(); |
||
263 | |||
264 | map["Height"] = OSD.FromReal(appearance.AvatarHeight); |
||
265 | |||
266 | map["BodyItem"] = appearance.Wearables[AvatarWearable.BODY][0].ItemID.ToString(); |
||
267 | map["EyesItem"] = appearance.Wearables[AvatarWearable.EYES][0].ItemID.ToString(); |
||
268 | map["GlovesItem"] = appearance.Wearables[AvatarWearable.GLOVES][0].ItemID.ToString(); |
||
269 | map["HairItem"] = appearance.Wearables[AvatarWearable.HAIR][0].ItemID.ToString(); |
||
270 | map["JacketItem"] = appearance.Wearables[AvatarWearable.JACKET][0].ItemID.ToString(); |
||
271 | map["PantsItem"] = appearance.Wearables[AvatarWearable.PANTS][0].ItemID.ToString(); |
||
272 | map["ShirtItem"] = appearance.Wearables[AvatarWearable.SHIRT][0].ItemID.ToString(); |
||
273 | map["ShoesItem"] = appearance.Wearables[AvatarWearable.SHOES][0].ItemID.ToString(); |
||
274 | map["SkinItem"] = appearance.Wearables[AvatarWearable.SKIN][0].ItemID.ToString(); |
||
275 | map["SkirtItem"] = appearance.Wearables[AvatarWearable.SKIRT][0].ItemID.ToString(); |
||
276 | map["SocksItem"] = appearance.Wearables[AvatarWearable.SOCKS][0].ItemID.ToString(); |
||
277 | map["UnderPantsItem"] = appearance.Wearables[AvatarWearable.UNDERPANTS][0].ItemID.ToString(); |
||
278 | map["UnderShirtItem"] = appearance.Wearables[AvatarWearable.UNDERSHIRT][0].ItemID.ToString(); |
||
279 | map["BodyAsset"] = appearance.Wearables[AvatarWearable.BODY][0].AssetID.ToString(); |
||
280 | map["EyesAsset"] = appearance.Wearables[AvatarWearable.EYES][0].AssetID.ToString(); |
||
281 | map["GlovesAsset"] = appearance.Wearables[AvatarWearable.GLOVES][0].AssetID.ToString(); |
||
282 | map["HairAsset"] = appearance.Wearables[AvatarWearable.HAIR][0].AssetID.ToString(); |
||
283 | map["JacketAsset"] = appearance.Wearables[AvatarWearable.JACKET][0].AssetID.ToString(); |
||
284 | map["PantsAsset"] = appearance.Wearables[AvatarWearable.PANTS][0].AssetID.ToString(); |
||
285 | map["ShirtAsset"] = appearance.Wearables[AvatarWearable.SHIRT][0].AssetID.ToString(); |
||
286 | map["ShoesAsset"] = appearance.Wearables[AvatarWearable.SHOES][0].AssetID.ToString(); |
||
287 | map["SkinAsset"] = appearance.Wearables[AvatarWearable.SKIN][0].AssetID.ToString(); |
||
288 | map["SkirtAsset"] = appearance.Wearables[AvatarWearable.SKIRT][0].AssetID.ToString(); |
||
289 | map["SocksAsset"] = appearance.Wearables[AvatarWearable.SOCKS][0].AssetID.ToString(); |
||
290 | map["UnderPantsAsset"] = appearance.Wearables[AvatarWearable.UNDERPANTS][0].AssetID.ToString(); |
||
291 | map["UnderShirtAsset"] = appearance.Wearables[AvatarWearable.UNDERSHIRT][0].AssetID.ToString(); |
||
292 | |||
293 | |||
294 | OSDMap items = new OSDMap(); |
||
295 | foreach (KeyValuePair<string, string> kvp in avatar.Data) |
||
296 | { |
||
297 | if (kvp.Key.StartsWith("_ap_")) |
||
298 | items.Add(kvp.Key, OSD.FromString(kvp.Value)); |
||
299 | } |
||
300 | |||
301 | NameValueCollection requestArgs = new NameValueCollection |
||
302 | { |
||
303 | { "RequestMethod", "AddUserData" }, |
||
304 | { "UserID", userID.ToString() }, |
||
305 | { "LLAppearance", OSDParser.SerializeJsonString(map) }, |
||
306 | { "LLAttachments", OSDParser.SerializeJsonString(items) } |
||
307 | }; |
||
308 | |||
309 | OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs); |
||
310 | bool success = response["Success"].AsBoolean(); |
||
311 | |||
312 | if (!success) |
||
313 | m_log.Warn("[SIMIAN AVATAR CONNECTOR]: Failed saving appearance for " + userID + ": " + response["Message"].AsString()); |
||
314 | |||
315 | return success; |
||
316 | } |
||
317 | else |
||
318 | { |
||
319 | m_log.Error("[SIMIAN AVATAR CONNECTOR]: Can't save appearance for " + userID + ". Unhandled avatar type " + avatar.AvatarType); |
||
320 | return false; |
||
321 | } |
||
322 | } |
||
323 | |||
324 | public bool ResetAvatar(UUID userID) |
||
325 | { |
||
326 | m_log.Error("[SIMIAN AVATAR CONNECTOR]: ResetAvatar called for " + userID + ", implement this"); |
||
327 | return false; |
||
328 | } |
||
329 | |||
330 | public bool SetItems(UUID userID, string[] names, string[] values) |
||
331 | { |
||
332 | m_log.Error("[SIMIAN AVATAR CONNECTOR]: SetItems called for " + userID + " with " + names.Length + " names and " + values.Length + " values, implement this"); |
||
333 | return false; |
||
334 | } |
||
335 | |||
336 | public bool RemoveItems(UUID userID, string[] names) |
||
337 | { |
||
338 | m_log.Error("[SIMIAN AVATAR CONNECTOR]: RemoveItems called for " + userID + " with " + names.Length + " names, implement this"); |
||
339 | return false; |
||
340 | } |
||
341 | |||
342 | #endregion IAvatarService |
||
343 | } |
||
344 | } |