aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Avatar/InstantMessage
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs190
1 files changed, 167 insertions, 23 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs
index fdded90..36184d2 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/InstantMessageModule.cs
@@ -161,11 +161,24 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
161 if (gridmode) 161 if (gridmode)
162 { 162 {
163 // Still here, try send via Grid 163 // Still here, try send via Grid
164 // TODO 164
165 // don't send session drop yet, as it's not reliable somehow.
166 if (dialog != (byte)InstantMessageDialog.SessionDrop)
167 {
168 SendGridInstantMessageViaXMLRPC(client, fromAgentID,
169 fromAgentSession, toAgentID,
170 imSessionID, timestamp, fromAgentName,
171 message, dialog, fromGroup, offline,
172 ParentEstateID, Position, RegionID,
173 binaryBucket, getLocalRegionHandleFromUUID(RegionID), 0);
174 }
175 }
176 else
177 {
165 if (client != null) 178 if (client != null)
166 { 179 {
167 if (dialog != (byte)InstantMessageDialog.StartTyping && dialog != (byte)InstantMessageDialog.StopTyping && dialog != (byte)InstantMessageDialog.SessionDrop) 180 if (dialog != (byte)InstantMessageDialog.StartTyping && dialog != (byte)InstantMessageDialog.StopTyping && dialog != (byte)InstantMessageDialog.SessionDrop)
168 client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.BusyAutoResponse, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message"); 181 client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message. User is not logged in.", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.BusyAutoResponse, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message");
169 } 182 }
170 } 183 }
171 } 184 }
@@ -175,7 +188,10 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
175 188
176 // Trusty OSG1 called method. This method also gets called from the FriendsModule 189 // Trusty OSG1 called method. This method also gets called from the FriendsModule
177 // Turns out the sim has to send an instant message to the user to get it to show an accepted friend. 190 // Turns out the sim has to send an instant message to the user to get it to show an accepted friend.
178 191 /// <summary>
192 ///
193 /// </summary>
194 /// <param name="msg"></param>
179 private void OnGridInstantMessage(GridInstantMessage msg) 195 private void OnGridInstantMessage(GridInstantMessage msg)
180 { 196 {
181 // Trigger the above event handler 197 // Trigger the above event handler
@@ -185,6 +201,15 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
185 new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), 201 new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID),
186 msg.binaryBucket); 202 msg.binaryBucket);
187 } 203 }
204
205
206 /// <summary>
207 /// Process a XMLRPC Grid Instant Message
208 /// </summary>
209 /// <param name="request">XMLRPC parameters from_agent_id from_agent_session to_agent_id im_session_id timestamp
210 /// from_agent_name message dialog from_group offline parent_estate_id position_x position_y position_z region_id
211 /// binary_bucket region_handle</param>
212 /// <returns>Nothing much</returns>
188 protected virtual XmlRpcResponse processXMLRPCGridInstantMessage(XmlRpcRequest request) 213 protected virtual XmlRpcResponse processXMLRPCGridInstantMessage(XmlRpcRequest request)
189 { 214 {
190 bool successful = false; 215 bool successful = false;
@@ -207,11 +232,11 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
207 float pos_x = 0; 232 float pos_x = 0;
208 float pos_y = 0; 233 float pos_y = 0;
209 float pos_z = 0; 234 float pos_z = 0;
210 235 //m_log.Info("Processing IM");
211 236
212 237
213 Hashtable requestData = (Hashtable)request.Params[0]; 238 Hashtable requestData = (Hashtable)request.Params[0];
214 239 // Check if it's got all the data
215 if (requestData.ContainsKey("from_agent_id") && requestData.ContainsKey("from_agent_session") 240 if (requestData.ContainsKey("from_agent_id") && requestData.ContainsKey("from_agent_session")
216 && requestData.ContainsKey("to_agent_id") && requestData.ContainsKey("im_session_id") 241 && requestData.ContainsKey("to_agent_id") && requestData.ContainsKey("im_session_id")
217 && requestData.ContainsKey("timestamp") && requestData.ContainsKey("from_agent_name") 242 && requestData.ContainsKey("timestamp") && requestData.ContainsKey("from_agent_name")
@@ -222,6 +247,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
222 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id") 247 && requestData.ContainsKey("position_z") && requestData.ContainsKey("region_id")
223 && requestData.ContainsKey("binary_bucket") && requestData.ContainsKey("region_handle")) 248 && requestData.ContainsKey("binary_bucket") && requestData.ContainsKey("region_handle"))
224 { 249 {
250 // Do the easy way of validating the UUIDs
225 Helpers.TryParse((string)requestData["from_agent_id"], out fromAgentID); 251 Helpers.TryParse((string)requestData["from_agent_id"], out fromAgentID);
226 Helpers.TryParse((string)requestData["from_agent_session"], out fromAgentSession); 252 Helpers.TryParse((string)requestData["from_agent_session"], out fromAgentSession);
227 Helpers.TryParse((string)requestData["to_agent_id"], out toAgentID); 253 Helpers.TryParse((string)requestData["to_agent_id"], out toAgentID);
@@ -246,12 +272,16 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
246 272
247 fromAgentName = (string)requestData["from_agent_name"]; 273 fromAgentName = (string)requestData["from_agent_name"];
248 message = (string)requestData["message"]; 274 message = (string)requestData["message"];
249 dialog = (byte)requestData["dialog"]; 275
276 // Bytes don't transfer well over XMLRPC, so, we Base64 Encode them.
277 byte[] dialogdata = Convert.FromBase64String((string)requestData["dialog"]);
278 dialog = dialogdata[0];
250 279
251 if ((string)requestData["from_group"] == "TRUE") 280 if ((string)requestData["from_group"] == "TRUE")
252 fromGroup = true; 281 fromGroup = true;
253 282
254 offline = (byte)requestData["offline"]; 283 byte[] offlinedata = Convert.FromBase64String((string)requestData["offline"]);
284 offline = offlinedata[0];
255 285
256 # region ParentEstateID 286 # region ParentEstateID
257 try 287 try
@@ -316,7 +346,9 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
316 # endregion 346 # endregion
317 347
318 Position = new LLVector3(pos_x, pos_y, pos_z); 348 Position = new LLVector3(pos_x, pos_y, pos_z);
319 binaryBucket = (byte[])requestData["binary_bucket"]; 349 binaryBucket = Convert.FromBase64String((string)requestData["binary_bucket"]);
350
351 // Create a New GridInstantMessageObject the the data
320 GridInstantMessage gim = new GridInstantMessage(); 352 GridInstantMessage gim = new GridInstantMessage();
321 gim.fromAgentID = fromAgentID.UUID; 353 gim.fromAgentID = fromAgentID.UUID;
322 gim.fromAgentName = fromAgentName; 354 gim.fromAgentName = fromAgentName;
@@ -334,6 +366,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
334 gim.binaryBucket = binaryBucket; 366 gim.binaryBucket = binaryBucket;
335 367
336 368
369 // Trigger the Instant message in the scene.
337 foreach (Scene scene in m_scenes) 370 foreach (Scene scene in m_scenes)
338 { 371 {
339 if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) 372 if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence)
@@ -343,13 +376,16 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
343 if (!user.IsChildAgent) 376 if (!user.IsChildAgent)
344 { 377 {
345 scene.EventManager.TriggerGridInstantMessage(gim, InstantMessageReceiver.FriendsModule | InstantMessageReceiver.GroupsModule | InstantMessageReceiver.IMModule); 378 scene.EventManager.TriggerGridInstantMessage(gim, InstantMessageReceiver.FriendsModule | InstantMessageReceiver.GroupsModule | InstantMessageReceiver.IMModule);
379 successful = true;
346 } 380 }
347 } 381 }
348 } 382 }
349 OnGridInstantMessage(gim); 383 //OnGridInstantMessage(gim);
350 successful = true; 384
351 } 385 }
352 386
387 //Send response back to region calling if it was successful
388 // calling region uses this to know when to look up a user's location again.
353 XmlRpcResponse resp = new XmlRpcResponse(); 389 XmlRpcResponse resp = new XmlRpcResponse();
354 Hashtable respdata = new Hashtable(); 390 Hashtable respdata = new Hashtable();
355 if (successful) 391 if (successful)
@@ -361,6 +397,41 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
361 return resp; 397 return resp;
362 } 398 }
363 399
400 #region Asynchronous setup
401 /// <summary>
402 /// delegate for sending a grid instant message asynchronously
403 /// </summary>
404 /// <param name="client"></param>
405 /// <param name="fromAgentID"></param>
406 /// <param name="fromAgentSession"></param>
407 /// <param name="toAgentID"></param>
408 /// <param name="imSessionID"></param>
409 /// <param name="timestamp"></param>
410 /// <param name="fromAgentName"></param>
411 /// <param name="message"></param>
412 /// <param name="dialog"></param>
413 /// <param name="fromGroup"></param>
414 /// <param name="offline"></param>
415 /// <param name="ParentEstateID"></param>
416 /// <param name="Position"></param>
417 /// <param name="RegionID"></param>
418 /// <param name="binaryBucket"></param>
419 /// <param name="regionhandle"></param>
420 /// <param name="prevRegionHandle"></param>
421 public delegate void GridInstantMessageDelegate(IClientAPI client, LLUUID fromAgentID,
422 LLUUID fromAgentSession, LLUUID toAgentID,
423 LLUUID imSessionID, uint timestamp, string fromAgentName,
424 string message, byte dialog, bool fromGroup, byte offline,
425 uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
426 byte[] binaryBucket, ulong regionhandle, ulong prevRegionHandle);
427
428 private void GridInstantMessageCompleted(IAsyncResult iar)
429 {
430 GridInstantMessageDelegate icon = (GridInstantMessageDelegate)iar.AsyncState;
431 icon.EndInvoke(iar);
432 }
433
434
364 protected virtual void SendGridInstantMessageViaXMLRPC(IClientAPI client, LLUUID fromAgentID, 435 protected virtual void SendGridInstantMessageViaXMLRPC(IClientAPI client, LLUUID fromAgentID,
365 LLUUID fromAgentSession, LLUUID toAgentID, 436 LLUUID fromAgentSession, LLUUID toAgentID,
366 LLUUID imSessionID, uint timestamp, string fromAgentName, 437 LLUUID imSessionID, uint timestamp, string fromAgentName,
@@ -368,6 +439,33 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
368 uint ParentEstateID, LLVector3 Position, LLUUID RegionID, 439 uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
369 byte[] binaryBucket, ulong regionhandle, ulong prevRegionHandle) 440 byte[] binaryBucket, ulong regionhandle, ulong prevRegionHandle)
370 { 441 {
442 GridInstantMessageDelegate d = SendGridInstantMessageViaXMLRPCAsync;
443
444 d.BeginInvoke(client,fromAgentID,
445 fromAgentSession,toAgentID,
446 imSessionID,timestamp, fromAgentName,
447 message, dialog, fromGroup, offline,
448 ParentEstateID, Position, RegionID,
449 binaryBucket, regionhandle, prevRegionHandle,
450 GridInstantMessageCompleted,
451 d);
452 }
453
454 #endregion
455
456
457 /// <summary>
458 /// Recursive SendGridInstantMessage over XMLRPC method. The prevRegionHandle contains the last regionhandle tried
459 /// if it's the same as the user's looked up region handle, then we end the recursive loop
460 /// </summary>
461 /// <param name="prevRegionHandle"></param>
462 protected virtual void SendGridInstantMessageViaXMLRPCAsync(IClientAPI client, LLUUID fromAgentID,
463 LLUUID fromAgentSession, LLUUID toAgentID,
464 LLUUID imSessionID, uint timestamp, string fromAgentName,
465 string message, byte dialog, bool fromGroup, byte offline,
466 uint ParentEstateID, LLVector3 Position, LLUUID RegionID,
467 byte[] binaryBucket, ulong regionhandle, ulong prevRegionHandle)
468 {
371 UserAgentData upd = null; 469 UserAgentData upd = null;
372 470
373 bool lookupAgent = false; 471 bool lookupAgent = false;
@@ -389,16 +487,34 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
389 } 487 }
390 } 488 }
391 489
490 // Are we needing to look-up an agent?
392 if (lookupAgent) 491 if (lookupAgent)
393 { 492 {
493 // Non-cached user agent lookup.
394 upd = m_scenes[0].CommsManager.UserService.GetAgentByUUID(toAgentID); 494 upd = m_scenes[0].CommsManager.UserService.GetAgentByUUID(toAgentID);
395 495
396 // check if we've tried this before.. 496 if (upd != null)
397 if (upd.Handle == prevRegionHandle) 497 {
498 // check if we've tried this before.. This is one way to end the recursive loop
499 if (upd.Handle == prevRegionHandle)
500 {
501 m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
502 if (client != null)
503 {
504 if (dialog != (byte)InstantMessageDialog.StartTyping && dialog != (byte)InstantMessageDialog.StopTyping && dialog != (byte)InstantMessageDialog.SessionDrop)
505 client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.BusyAutoResponse, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message");
506 }
507 return;
508 }
509 }
510 else
398 { 511 {
399 m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message"); 512 m_log.Error("[GRID INSTANT MESSAGE]: Unable to deliver an instant message");
400 if (client != null) 513 if (client != null)
401 client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.MessageFromObject,(uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message"); 514 {
515 if (dialog != (byte)InstantMessageDialog.StartTyping && dialog != (byte)InstantMessageDialog.StopTyping && dialog != (byte)InstantMessageDialog.SessionDrop)
516 client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.BusyAutoResponse, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message");
517 }
402 return; 518 return;
403 } 519 }
404 } 520 }
@@ -431,6 +547,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
431 bool imresult = doIMSending(reginfo, msgdata); 547 bool imresult = doIMSending(reginfo, msgdata);
432 if (imresult) 548 if (imresult)
433 { 549 {
550 // IM delivery successful, so store the Agent's location in our local cache.
434 lock (m_userRegionMap) 551 lock (m_userRegionMap)
435 { 552 {
436 if (m_userRegionMap.ContainsKey(toAgentID)) 553 if (m_userRegionMap.ContainsKey(toAgentID))
@@ -442,12 +559,18 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
442 m_userRegionMap.Add(toAgentID, upd.Handle); 559 m_userRegionMap.Add(toAgentID, upd.Handle);
443 } 560 }
444 } 561 }
445 m_log.Info("[GRID INSTANT MESSAGE]: Successfully sent a message"); 562 //m_log.Info("[GRID INSTANT MESSAGE]: Successfully sent a message");
446 } 563 }
447 else 564 else
448 { 565 {
449 // try again, but lookup user this time. 566 // try again, but lookup user this time.
450 SendGridInstantMessageViaXMLRPC(client, fromAgentID, 567 // Warning, this must call the Async version
568 // of this method or we'll be making thousands of threads
569 // The version within the spawned thread is SendGridInstantMessageViaXMLRPCAsync
570 // The version that spawns the thread is SendGridInstantMessageViaXMLRPC
571
572 // This is recursive!!!!!
573 SendGridInstantMessageViaXMLRPCAsync(client, fromAgentID,
451 fromAgentSession, toAgentID, 574 fromAgentSession, toAgentID,
452 imSessionID, timestamp, fromAgentName, 575 imSessionID, timestamp, fromAgentName,
453 message, dialog, fromGroup, offline, 576 message, dialog, fromGroup, offline,
@@ -461,18 +584,27 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
461 { 584 {
462 // send Agent Offline message 585 // send Agent Offline message
463 if (client != null) 586 if (client != null)
464 client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.MessageFromObject, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message"); 587 {
588 if (dialog != (byte)InstantMessageDialog.StartTyping && dialog != (byte)InstantMessageDialog.StopTyping && dialog != (byte)InstantMessageDialog.SessionDrop)
589 client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message: Agent Offline", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.BusyAutoResponse, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message");
590 }
465 } 591 }
466 } 592 }
467 else 593 else
468 { 594 {
469 // send Agent Offline message 595 // send Agent doesn't exist message
470 if (client != null) 596 if (client != null)
471 client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.MessageFromObject, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message"); 597 client.SendInstantMessage(toAgentID, fromAgentSession, "Unable to send instant message: Are you sure this agent exists anymore?", fromAgentID, imSessionID, "System", (byte)InstantMessageDialog.MessageFromObject, (uint)Util.UnixTimeSinceEpoch());// SendAlertMessage("Unable to send instant message");
472 } 598 }
473 599
474 } 600 }
475 601
602 /// <summary>
603 /// This actually does the XMLRPC Request
604 /// </summary>
605 /// <param name="reginfo">RegionInfo we pull the data out of to send the request to</param>
606 /// <param name="xmlrpcdata">The Instant Message data Hashtable</param>
607 /// <returns>Bool if the message was successfully delivered at the other side.</returns>
476 private bool doIMSending(RegionInfo reginfo, Hashtable xmlrpcdata) 608 private bool doIMSending(RegionInfo reginfo, Hashtable xmlrpcdata)
477 { 609 {
478 610
@@ -502,7 +634,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
502 return false; 634 return false;
503 } 635 }
504 } 636 }
505 catch (WebException) 637 catch (WebException e)
506 { 638 {
507 m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0} the host didn't respond", "http://" + reginfo.ExternalHostName + ":" + reginfo.HttpPort); 639 m_log.ErrorFormat("[GRID INSTANT MESSAGE]: Error sending message to {0} the host didn't respond", "http://" + reginfo.ExternalHostName + ":" + reginfo.HttpPort);
508 } 640 }
@@ -510,6 +642,12 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
510 return false; 642 return false;
511 } 643 }
512 644
645 /// <summary>
646 /// Get ulong region handle for region by it's Region UUID.
647 /// We use region handles over grid comms because there's all sorts of free and cool caching.
648 /// </summary>
649 /// <param name="regionID">UUID of region to get the region handle for</param>
650 /// <returns></returns>
513 private ulong getLocalRegionHandleFromUUID(LLUUID regionID) 651 private ulong getLocalRegionHandleFromUUID(LLUUID regionID)
514 { 652 {
515 ulong returnhandle = 0; 653 ulong returnhandle = 0;
@@ -528,6 +666,11 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
528 return returnhandle; 666 return returnhandle;
529 } 667 }
530 668
669 /// <summary>
670 /// Takes a GridInstantMessage and converts it into a Hashtable for XMLRPC
671 /// </summary>
672 /// <param name="msg">The GridInstantMessage object</param>
673 /// <returns>Hashtable containing the XMLRPC request</returns>
531 private Hashtable ConvertGridInstantMessageToXMLRPC(GridInstantMessage msg) 674 private Hashtable ConvertGridInstantMessageToXMLRPC(GridInstantMessage msg)
532 { 675 {
533 Hashtable gim = new Hashtable(); 676 Hashtable gim = new Hashtable();
@@ -538,20 +681,21 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
538 gim["timestamp"] = msg.timestamp.ToString(); 681 gim["timestamp"] = msg.timestamp.ToString();
539 gim["from_agent_name"] = msg.fromAgentName; 682 gim["from_agent_name"] = msg.fromAgentName;
540 gim["message"] = msg.message; 683 gim["message"] = msg.message;
541 gim["dialog"] = msg.dialog; 684 byte[] dialogdata = new byte[1];dialogdata[0] = msg.dialog;
685 gim["dialog"] = Convert.ToBase64String(dialogdata,Base64FormattingOptions.None);
542 686
543 if (msg.fromGroup) 687 if (msg.fromGroup)
544 gim["from_group"] = "TRUE"; 688 gim["from_group"] = "TRUE";
545 else 689 else
546 gim["from_group"] = "FALSE"; 690 gim["from_group"] = "FALSE";
547 691 byte[] offlinedata = new byte[1]; offlinedata[0] = msg.offline;
548 gim["offline"] = msg.offline; 692 gim["offline"] = Convert.ToBase64String(offlinedata, Base64FormattingOptions.None);
549 gim["parent_estate_id"] = msg.ParentEstateID.ToString(); 693 gim["parent_estate_id"] = msg.ParentEstateID.ToString();
550 gim["position_x"] = msg.Position.x.ToString(); 694 gim["position_x"] = msg.Position.x.ToString();
551 gim["position_y"] = msg.Position.y.ToString(); 695 gim["position_y"] = msg.Position.y.ToString();
552 gim["position_z"] = msg.Position.z.ToString(); 696 gim["position_z"] = msg.Position.z.ToString();
553 gim["region_id"] = msg.RegionID.ToString(); 697 gim["region_id"] = msg.RegionID.ToString();
554 gim["binary_bucket"] = msg.binaryBucket; 698 gim["binary_bucket"] = Convert.ToBase64String(msg.binaryBucket,Base64FormattingOptions.None);
555 return gim; 699 return gim;
556 } 700 }
557 701