29 using System.Collections.Generic;
30 using System.Collections.Specialized;
31 using System.Reflection;
36 using OpenMetaverse.StructuredData;
37 using OpenSim.Framework;
38 using OpenSim.Framework.Client;
39 using OpenSim.Region.Framework.Interfaces;
40 using OpenSim.Region.Framework.Scenes;
41 using OpenSim.Services.Interfaces;
43 namespace OpenSim.Services.Connectors.SimianGrid
62 [Extension(Path =
"/OpenSim/RegionModules", NodeName =
"RegionModule", Id =
"SimianProfiles")]
65 private static readonly ILog m_log =
67 MethodBase.GetCurrentMethod().DeclaringType);
69 private string m_serverUrl = String.Empty;
70 private bool m_Enabled =
false;
72 #region INonSharedRegionModule
74 public Type ReplaceableInterface {
get {
return null; } }
79 public string Name {
get {
return "SimianProfiles"; } }
85 CheckEstateManager(scene);
86 scene.EventManager.OnClientConnect += ClientConnectHandler;
94 scene.EventManager.OnClientConnect -= ClientConnectHandler;
98 #endregion INonSharedRegionModule
107 IConfig profileConfig = source.Configs[
"Profiles"];
108 if (profileConfig == null)
111 if (profileConfig.GetString(
"Module",
String.Empty) != Name)
114 m_log.DebugFormat(
"[SIMIAN PROFILES] module enabled");
117 IConfig gridConfig = source.Configs[
"UserAccountService"];
118 if (gridConfig != null)
120 string serviceUrl = gridConfig.GetString(
"UserAccountServerURI");
121 if (!
String.IsNullOrEmpty(serviceUrl))
123 if (!serviceUrl.EndsWith(
"/") && !serviceUrl.EndsWith(
"="))
124 serviceUrl = serviceUrl +
'/';
125 m_serverUrl = serviceUrl;
129 if (
String.IsNullOrEmpty(m_serverUrl))
130 m_log.Info(
"[SIMIAN PROFILES]: No UserAccountServerURI specified, disabling connector");
133 private void ClientConnectHandler(
IClientCore clientCore)
137 IClientAPI client = (IClientAPI)clientCore;
140 client.AddGenericPacketHandler(
"avatarclassifiedsrequest", AvatarClassifiedsRequestHandler);
141 client.OnClassifiedInfoRequest += ClassifiedInfoRequestHandler;
142 client.OnClassifiedInfoUpdate += ClassifiedInfoUpdateHandler;
143 client.OnClassifiedDelete += ClassifiedDeleteHandler;
146 client.AddGenericPacketHandler(
"avatarpicksrequest", HandleAvatarPicksRequest);
147 client.AddGenericPacketHandler(
"pickinforequest", HandlePickInfoRequest);
148 client.OnPickInfoUpdate += PickInfoUpdateHandler;
149 client.OnPickDelete += PickDeleteHandler;
152 client.AddGenericPacketHandler(
"avatarnotesrequest", HandleAvatarNotesRequest);
153 client.OnAvatarNotesUpdate += AvatarNotesUpdateHandler;
156 client.OnRequestAvatarProperties += RequestAvatarPropertiesHandler;
158 client.OnUpdateAvatarProperties += UpdateAvatarPropertiesHandler;
159 client.OnAvatarInterestUpdate += AvatarInterestUpdateHandler;
160 client.OnUserInfoRequest += UserInfoRequestHandler;
161 client.OnUpdateUserInfo += UpdateUserInfoHandler;
167 private void AvatarClassifiedsRequestHandler(Object sender,
string method, List<String> args)
171 IClientAPI client = (IClientAPI)sender;
174 if (args.Count < 1 || !
UUID.TryParse(args[0], out targetAvatarID))
176 m_log.Error(
"[SIMIAN PROFILES]: Unrecognized arguments for " + method);
181 client.SendAvatarClassifiedReply(targetAvatarID,
new Dictionary<UUID, string>(0));
184 private void ClassifiedInfoRequestHandler(UUID classifiedID,
IClientAPI client)
187 client.SendClassifiedInfoReply(classifiedID, UUID.Zero, 0, Utils.DateTimeToUnixTime(DateTime.UtcNow + TimeSpan.FromDays(1)),
188 0, String.Empty, String.Empty, UUID.Zero, 0, UUID.Zero, String.Empty, Vector3.Zero, String.Empty, 0, 0);
191 private void ClassifiedInfoUpdateHandler(UUID classifiedID, uint category,
string name,
string description,
192 UUID parcelID, uint parentEstate, UUID snapshotID, Vector3 globalPos, byte classifiedFlags,
int price,
198 private void ClassifiedDeleteHandler(UUID classifiedID,
IClientAPI client)
203 #endregion Classifieds
207 private void HandleAvatarPicksRequest(Object sender,
string method, List<String> args)
211 IClientAPI client = (IClientAPI)sender;
214 if (args.Count < 1 || !
UUID.TryParse(args[0], out targetAvatarID))
216 m_log.Error(
"[SIMIAN PROFILES]: Unrecognized arguments for " + method);
221 client.SendAvatarPicksReply(targetAvatarID,
new Dictionary<UUID, string>(0));
224 private void HandlePickInfoRequest(Object sender,
string method, List<String> args)
228 IClientAPI client = (IClientAPI)sender;
232 if (args.Count < 2 || !
UUID.TryParse(args[0], out avatarID) || !UUID.TryParse(args[1], out pickID))
234 m_log.Error(
"[SIMIAN PROFILES]: Unrecognized arguments for " + method);
239 client.SendPickInfoReply(pickID, avatarID,
false, UUID.Zero, String.Empty, String.Empty, UUID.Zero, String.Empty,
240 String.Empty, String.Empty, Vector3.Zero, 0,
false);
243 private void PickInfoUpdateHandler(IClientAPI client, UUID pickID, UUID creatorID,
bool topPick,
string name,
244 string desc, UUID snapshotID,
int sortOrder,
bool enabled)
249 private void PickDeleteHandler(IClientAPI client, UUID pickID)
258 private void HandleAvatarNotesRequest(Object sender,
string method, List<String> args)
260 if (!(sender is IClientAPI))
262 IClientAPI client = (IClientAPI)sender;
265 if (args.Count < 1 || !
UUID.TryParse(args[0], out targetAvatarID))
267 m_log.Error(
"[SIMIAN PROFILES]: Unrecognized arguments for " + method);
272 client.SendAvatarNotesReply(targetAvatarID, String.Empty);
275 private void AvatarNotesUpdateHandler(IClientAPI client, UUID targetID,
string notes)
284 private void RequestAvatarPropertiesHandler(IClientAPI client, UUID avatarID)
286 m_log.DebugFormat(
"[SIMIAN PROFILES]: Request avatar properties for {0}",avatarID);
288 OSDMap user = FetchUserData(avatarID);
290 ProfileFlags flags = ProfileFlags.AllowPublish | ProfileFlags.MaturePublish;
295 if (user.ContainsKey(
"LLAbout"))
299 about = OSDParser.DeserializeJson(user[
"LLAbout"].AsString()) as
OSDMap;
303 m_log.WarnFormat(
"[SIMIAN PROFILES]: Unable to decode LLAbout");
311 byte[] charterMember;
312 if (user[
"AccessLevel"].AsInteger() >= 200)
313 charterMember = Utils.StringToBytes(
"Operator");
315 charterMember = Utils.EmptyBytes;
321 if (presences != null && presences.Length > 0)
322 flags |= ProfileFlags.Online;
326 if (user[
"Identified"].AsBoolean())
327 flags |= ProfileFlags.Identified;
329 client.SendAvatarProperties(avatarID, about[
"About"].AsString(), user[
"CreationDate"].AsDate().ToString(
"M/d/yyyy",
330 System.Globalization.CultureInfo.InvariantCulture), charterMember, about[
"FLAbout"].AsString(), (uint)flags,
331 about[
"FLImage"].AsUUID(), about[
"Image"].AsUUID(), about[
"URL"].AsString(), user[
"Partner"].AsUUID());
334 if (user.ContainsKey(
"LLInterests"))
338 interests = OSDParser.DeserializeJson(user[
"LLInterests"].AsString()) as
OSDMap;
339 client.SendAvatarInterestsReply(avatarID, interests["WantMask"].AsUInteger(), interests["WantText"].AsString(), interests["SkillsMask"].AsUInteger(), interests["SkillsText"].AsString(), interests["Languages"].AsString());
349 m_log.Warn(
"[SIMIAN PROFILES]: Failed to fetch profile information for " + client.Name +
", returning default values");
350 client.SendAvatarProperties(avatarID, String.Empty,
"1/1/1970", Utils.EmptyBytes,
355 private void UpdateAvatarPropertiesHandler(IClientAPI client,
UserProfileData profileData)
359 {
"About", OSD.FromString(profileData.AboutText) },
360 {
"Image", OSD.FromUUID(profileData.Image) },
361 {
"FLAbout", OSD.FromString(profileData.FirstLifeAboutText) },
362 {
"FLImage", OSD.FromUUID(profileData.FirstLifeImage) },
363 {
"URL", OSD.FromString(profileData.ProfileUrl) }
366 AddUserData(client.
AgentId,
"LLAbout", map);
369 private void AvatarInterestUpdateHandler(IClientAPI client, uint wantmask,
string wanttext, uint skillsmask,
370 string skillstext,
string languages)
374 {
"WantMask", OSD.FromInteger(wantmask) },
375 {
"WantText", OSD.FromString(wanttext) },
376 {
"SkillsMask", OSD.FromInteger(skillsmask) },
377 {
"SkillsText", OSD.FromString(skillstext) },
378 {
"Languages", OSD.FromString(languages) }
381 AddUserData(client.
AgentId,
"LLInterests", map);
384 private void UserInfoRequestHandler(IClientAPI client)
386 m_log.Error(
"[SIMIAN PROFILES]: UserInfoRequestHandler");
389 NameValueCollection requestArgs =
new NameValueCollection
391 {
"RequestMethod",
"GetUser" },
392 {
"UserID", client.AgentId.ToString() }
395 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
396 string email = response[
"Email"].AsString();
398 if (!response[
"Success"].AsBoolean())
399 m_log.Warn(
"[SIMIAN PROFILES]: GetUser failed during a user info request for " + client.
Name);
401 client.SendUserInfoReply(
false,
true, email);
404 private void UpdateUserInfoHandler(
bool imViaEmail,
bool visible, IClientAPI client)
406 m_log.Info(
"[SIMIAN PROFILES]: Ignoring user info update from " + client.Name);
414 private void CheckEstateManager(Scene scene)
421 UserAccount admin = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, UUID.Zero);
424 m_log.InfoFormat(
"[SIMIAN PROFILES]: Setting estate {0} (ID: {1}) owner to {2}", estate.EstateName,
425 estate.EstateID, admin.Name);
427 estate.EstateOwner = admin.PrincipalID;
428 scene.EstateDataService.StoreEstateSettings(estate);
432 m_log.WarnFormat(
"[SIMIAN PROFILES]: Estate {0} (ID: {1}) does not have an owner", estate.EstateName, estate.EstateID);
437 private bool AddUserData(UUID userID,
string key,
OSDMap value)
439 NameValueCollection requestArgs =
new NameValueCollection
441 {
"RequestMethod",
"AddUserData" },
442 {
"UserID", userID.ToString() },
443 {
key, OSDParser.SerializeJsonString(value) }
446 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
447 bool success = response[
"Success"].AsBoolean();
450 m_log.WarnFormat(
"[SIMIAN PROFILES]: Failed to add user data with key {0} for {1}: {2}",
key, userID, response[
"Message"].AsString());
455 private OSDMap FetchUserData(UUID userID)
457 m_log.DebugFormat(
"[SIMIAN PROFILES]: Fetch information about {0}",userID);
459 NameValueCollection requestArgs =
new NameValueCollection
461 {
"RequestMethod",
"GetUser" },
462 {
"UserID", userID.ToString() }
465 OSDMap response = SimianGrid.PostToService(m_serverUrl, requestArgs);
466 if (response[
"Success"].AsBoolean() && response[
"User"] is
OSDMap)
468 return (
OSDMap)response[
"User"];
472 m_log.Error(
"[SIMIAN PROFILES]: Failed to fetch user data for " + userID +
": " + response[
"Message"].AsString());
void AddRegion(Scene scene)
This is called whenever a Scene is added. For shared modules, this can happen several times...
string Name
Returns the full name of the agent/avatar represented by this client
OpenMetaverse.StructuredData.OSDMap OSDMap
OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString key
Information about a particular user known to the userserver
void Close()
This is the inverse to Initialise. After a Close(), this instance won't be usable anymore...
void Initialise(IConfigSource source)
This is called to initialize the region module. For shared modules, this is called exactly once...
ProfileFlags
Avatar profile flags
SimianProfiles(IConfigSource source)
void RegionLoaded(Scene scene)
This will be called once for every scene loaded. In a shared module this will be multiple times in on...
Connects avatar profile and classified queries to the SimianGrid backend
void RemoveRegion(Scene scene)
This is called whenever a Scene is removed. For shared modules, this can happen several times...