aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Client/MXP/ClientStack/MXPClientView.cs1158
-rw-r--r--OpenSim/Client/MXP/MXPModule.cs87
-rw-r--r--OpenSim/Client/MXP/MXPUtil.cs15
-rw-r--r--OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs367
4 files changed, 1627 insertions, 0 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
new file mode 100644
index 0000000..4a102e9
--- /dev/null
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -0,0 +1,1158 @@
1using System;
2using System.Collections.Generic;
3using System.Net;
4using System.Reflection;
5using System.Text;
6using log4net;
7using MXP;
8using MXP.Messages;
9using OpenMetaverse;
10using OpenMetaverse.Packets;
11using OpenSim.Framework;
12using OpenSim.Framework.Client;
13using Packet=OpenMetaverse.Packets.Packet;
14
15namespace OpenSim.Client.MXP.ClientStack
16{
17 class MXPClientView : IClientAPI, IClientCore
18 {
19 internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
20
21 private readonly Session mxpSession;
22 private readonly UUID mxpSessionID;
23 private readonly IScene mxpHostBubble;
24 private readonly string mxpUsername;
25
26 private int debugLevel;
27
28 public MXPClientView(Session mxpSession, UUID mxpSessionID, IScene mxpHostBubble, string mxpUsername)
29 {
30 this.mxpSession = mxpSession;
31 this.mxpUsername = mxpUsername;
32 this.mxpHostBubble = mxpHostBubble;
33 this.mxpSessionID = mxpSessionID;
34 }
35
36 public Session Session
37 {
38 get { return mxpSession; }
39 }
40
41 public bool ProcessMXPPacket(Message msg)
42 {
43 if (debugLevel > 0)
44 m_log.Warn("[MXP] Got Action/Command Packet: " + msg);
45
46 return false;
47 }
48
49 #region IClientAPI
50
51 public Vector3 StartPos
52 {
53 get { return new Vector3(128f, 128f, 128f); }
54 set { } // TODO: Implement Me
55 }
56
57 public UUID AgentId
58 {
59 get { return mxpSessionID; }
60 }
61
62 public UUID SessionId
63 {
64 get { return mxpSessionID; }
65 }
66
67 public UUID SecureSessionId
68 {
69 get { return mxpSessionID; }
70 }
71
72 public UUID ActiveGroupId
73 {
74 get { return UUID.Zero; }
75 }
76
77 public string ActiveGroupName
78 {
79 get { return ""; }
80 }
81
82 public ulong ActiveGroupPowers
83 {
84 get { return 0; }
85 }
86
87 public ulong GetGroupPowers(UUID groupID)
88 {
89 return 0;
90 }
91
92 public bool IsGroupMember(UUID GroupID)
93 {
94 return false;
95 }
96
97 public string FirstName
98 {
99 get { return mxpUsername; }
100 }
101
102 public string LastName
103 {
104 get { return "@mxp://" + Session.RemoteEndPoint.Address; }
105 }
106
107 public IScene Scene
108 {
109 get { return mxpHostBubble; }
110 }
111
112 public int NextAnimationSequenceNumber
113 {
114 get { return 0; }
115 }
116
117 public string Name
118 {
119 get { return FirstName; }
120 }
121
122 public bool IsActive
123 {
124 get { return Session.SessionState == SessionState.Connected; }
125 set
126 {
127 if (!value)
128 Stop();
129 }
130 }
131
132 // Do we need this?
133 public bool SendLogoutPacketWhenClosing
134 {
135 set { }
136 }
137
138 public uint CircuitCode
139 {
140 get { return mxpSessionID.CRC(); }
141 }
142
143 public event GenericMessage OnGenericMessage;
144 public event ImprovedInstantMessage OnInstantMessage;
145 public event ChatMessage OnChatFromClient;
146 public event TextureRequest OnRequestTexture;
147 public event RezObject OnRezObject;
148 public event ModifyTerrain OnModifyTerrain;
149 public event BakeTerrain OnBakeTerrain;
150 public event EstateChangeInfo OnEstateChangeInfo;
151 public event SetAppearance OnSetAppearance;
152 public event AvatarNowWearing OnAvatarNowWearing;
153 public event RezSingleAttachmentFromInv OnRezSingleAttachmentFromInv;
154 public event UUIDNameRequest OnDetachAttachmentIntoInv;
155 public event ObjectAttach OnObjectAttach;
156 public event ObjectDeselect OnObjectDetach;
157 public event ObjectDrop OnObjectDrop;
158 public event StartAnim OnStartAnim;
159 public event StopAnim OnStopAnim;
160 public event LinkObjects OnLinkObjects;
161 public event DelinkObjects OnDelinkObjects;
162 public event RequestMapBlocks OnRequestMapBlocks;
163 public event RequestMapName OnMapNameRequest;
164 public event TeleportLocationRequest OnTeleportLocationRequest;
165 public event DisconnectUser OnDisconnectUser;
166 public event RequestAvatarProperties OnRequestAvatarProperties;
167 public event SetAlwaysRun OnSetAlwaysRun;
168 public event TeleportLandmarkRequest OnTeleportLandmarkRequest;
169 public event DeRezObject OnDeRezObject;
170 public event Action<IClientAPI> OnRegionHandShakeReply;
171 public event GenericCall2 OnRequestWearables;
172 public event GenericCall2 OnCompleteMovementToRegion;
173 public event UpdateAgent OnAgentUpdate;
174 public event AgentRequestSit OnAgentRequestSit;
175 public event AgentSit OnAgentSit;
176 public event AvatarPickerRequest OnAvatarPickerRequest;
177 public event Action<IClientAPI> OnRequestAvatarsData;
178 public event AddNewPrim OnAddPrim;
179 public event FetchInventory OnAgentDataUpdateRequest;
180 public event TeleportLocationRequest OnSetStartLocationRequest;
181 public event RequestGodlikePowers OnRequestGodlikePowers;
182 public event GodKickUser OnGodKickUser;
183 public event ObjectDuplicate OnObjectDuplicate;
184 public event ObjectDuplicateOnRay OnObjectDuplicateOnRay;
185 public event GrabObject OnGrabObject;
186 public event ObjectSelect OnDeGrabObject;
187 public event MoveObject OnGrabUpdate;
188 public event UpdateShape OnUpdatePrimShape;
189 public event ObjectExtraParams OnUpdateExtraParams;
190 public event ObjectSelect OnObjectSelect;
191 public event ObjectDeselect OnObjectDeselect;
192 public event GenericCall7 OnObjectDescription;
193 public event GenericCall7 OnObjectName;
194 public event GenericCall7 OnObjectClickAction;
195 public event GenericCall7 OnObjectMaterial;
196 public event RequestObjectPropertiesFamily OnRequestObjectPropertiesFamily;
197 public event UpdatePrimFlags OnUpdatePrimFlags;
198 public event UpdatePrimTexture OnUpdatePrimTexture;
199 public event UpdateVector OnUpdatePrimGroupPosition;
200 public event UpdateVector OnUpdatePrimSinglePosition;
201 public event UpdatePrimRotation OnUpdatePrimGroupRotation;
202 public event UpdatePrimSingleRotation OnUpdatePrimSingleRotation;
203 public event UpdatePrimGroupRotation OnUpdatePrimGroupMouseRotation;
204 public event UpdateVector OnUpdatePrimScale;
205 public event UpdateVector OnUpdatePrimGroupScale;
206 public event StatusChange OnChildAgentStatus;
207 public event GenericCall2 OnStopMovement;
208 public event Action<UUID> OnRemoveAvatar;
209 public event ObjectPermissions OnObjectPermissions;
210 public event CreateNewInventoryItem OnCreateNewInventoryItem;
211 public event CreateInventoryFolder OnCreateNewInventoryFolder;
212 public event UpdateInventoryFolder OnUpdateInventoryFolder;
213 public event MoveInventoryFolder OnMoveInventoryFolder;
214 public event FetchInventoryDescendents OnFetchInventoryDescendents;
215 public event PurgeInventoryDescendents OnPurgeInventoryDescendents;
216 public event FetchInventory OnFetchInventory;
217 public event RequestTaskInventory OnRequestTaskInventory;
218 public event UpdateInventoryItem OnUpdateInventoryItem;
219 public event CopyInventoryItem OnCopyInventoryItem;
220 public event MoveInventoryItem OnMoveInventoryItem;
221 public event RemoveInventoryFolder OnRemoveInventoryFolder;
222 public event RemoveInventoryItem OnRemoveInventoryItem;
223 public event UDPAssetUploadRequest OnAssetUploadRequest;
224 public event XferReceive OnXferReceive;
225 public event RequestXfer OnRequestXfer;
226 public event ConfirmXfer OnConfirmXfer;
227 public event AbortXfer OnAbortXfer;
228 public event RezScript OnRezScript;
229 public event UpdateTaskInventory OnUpdateTaskInventory;
230 public event MoveTaskInventory OnMoveTaskItem;
231 public event RemoveTaskInventory OnRemoveTaskItem;
232 public event RequestAsset OnRequestAsset;
233 public event UUIDNameRequest OnNameFromUUIDRequest;
234 public event ParcelAccessListRequest OnParcelAccessListRequest;
235 public event ParcelAccessListUpdateRequest OnParcelAccessListUpdateRequest;
236 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
237 public event ParcelDivideRequest OnParcelDivideRequest;
238 public event ParcelJoinRequest OnParcelJoinRequest;
239 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
240 public event ParcelSelectObjects OnParcelSelectObjects;
241 public event ParcelObjectOwnerRequest OnParcelObjectOwnerRequest;
242 public event ParcelAbandonRequest OnParcelAbandonRequest;
243 public event ParcelGodForceOwner OnParcelGodForceOwner;
244 public event ParcelReclaim OnParcelReclaim;
245 public event ParcelReturnObjectsRequest OnParcelReturnObjectsRequest;
246 public event RegionInfoRequest OnRegionInfoRequest;
247 public event EstateCovenantRequest OnEstateCovenantRequest;
248 public event FriendActionDelegate OnApproveFriendRequest;
249 public event FriendActionDelegate OnDenyFriendRequest;
250 public event FriendshipTermination OnTerminateFriendship;
251 public event MoneyTransferRequest OnMoneyTransferRequest;
252 public event EconomyDataRequest OnEconomyDataRequest;
253 public event MoneyBalanceRequest OnMoneyBalanceRequest;
254 public event UpdateAvatarProperties OnUpdateAvatarProperties;
255 public event ParcelBuy OnParcelBuy;
256 public event RequestPayPrice OnRequestPayPrice;
257 public event ObjectSaleInfo OnObjectSaleInfo;
258 public event ObjectBuy OnObjectBuy;
259 public event BuyObjectInventory OnBuyObjectInventory;
260 public event RequestTerrain OnRequestTerrain;
261 public event RequestTerrain OnUploadTerrain;
262 public event ObjectIncludeInSearch OnObjectIncludeInSearch;
263 public event UUIDNameRequest OnTeleportHomeRequest;
264 public event ScriptAnswer OnScriptAnswer;
265 public event AgentSit OnUndo;
266 public event ForceReleaseControls OnForceReleaseControls;
267 public event GodLandStatRequest OnLandStatRequest;
268 public event DetailedEstateDataRequest OnDetailedEstateDataRequest;
269 public event SetEstateFlagsRequest OnSetEstateFlagsRequest;
270 public event SetEstateTerrainBaseTexture OnSetEstateTerrainBaseTexture;
271 public event SetEstateTerrainDetailTexture OnSetEstateTerrainDetailTexture;
272 public event SetEstateTerrainTextureHeights OnSetEstateTerrainTextureHeights;
273 public event CommitEstateTerrainTextureRequest OnCommitEstateTerrainTextureRequest;
274 public event SetRegionTerrainSettings OnSetRegionTerrainSettings;
275 public event EstateRestartSimRequest OnEstateRestartSimRequest;
276 public event EstateChangeCovenantRequest OnEstateChangeCovenantRequest;
277 public event UpdateEstateAccessDeltaRequest OnUpdateEstateAccessDeltaRequest;
278 public event SimulatorBlueBoxMessageRequest OnSimulatorBlueBoxMessageRequest;
279 public event EstateBlueBoxMessageRequest OnEstateBlueBoxMessageRequest;
280 public event EstateDebugRegionRequest OnEstateDebugRegionRequest;
281 public event EstateTeleportOneUserHomeRequest OnEstateTeleportOneUserHomeRequest;
282 public event EstateTeleportAllUsersHomeRequest OnEstateTeleportAllUsersHomeRequest;
283 public event UUIDNameRequest OnUUIDGroupNameRequest;
284 public event RegionHandleRequest OnRegionHandleRequest;
285 public event ParcelInfoRequest OnParcelInfoRequest;
286 public event RequestObjectPropertiesFamily OnObjectGroupRequest;
287 public event ScriptReset OnScriptReset;
288 public event GetScriptRunning OnGetScriptRunning;
289 public event SetScriptRunning OnSetScriptRunning;
290 public event UpdateVector OnAutoPilotGo;
291 public event TerrainUnacked OnUnackedTerrain;
292 public event ActivateGesture OnActivateGesture;
293 public event DeactivateGesture OnDeactivateGesture;
294 public event ObjectOwner OnObjectOwner;
295 public event DirPlacesQuery OnDirPlacesQuery;
296 public event DirFindQuery OnDirFindQuery;
297 public event DirLandQuery OnDirLandQuery;
298 public event DirPopularQuery OnDirPopularQuery;
299 public event DirClassifiedQuery OnDirClassifiedQuery;
300 public event EventInfoRequest OnEventInfoRequest;
301 public event ParcelSetOtherCleanTime OnParcelSetOtherCleanTime;
302 public event MapItemRequest OnMapItemRequest;
303 public event OfferCallingCard OnOfferCallingCard;
304 public event AcceptCallingCard OnAcceptCallingCard;
305 public event DeclineCallingCard OnDeclineCallingCard;
306 public event SoundTrigger OnSoundTrigger;
307 public event StartLure OnStartLure;
308 public event TeleportLureRequest OnTeleportLureRequest;
309 public event NetworkStats OnNetworkStatsUpdate;
310 public event ClassifiedInfoRequest OnClassifiedInfoRequest;
311 public event ClassifiedInfoUpdate OnClassifiedInfoUpdate;
312 public event ClassifiedDelete OnClassifiedDelete;
313 public event ClassifiedDelete OnClassifiedGodDelete;
314 public event EventNotificationAddRequest OnEventNotificationAddRequest;
315 public event EventNotificationRemoveRequest OnEventNotificationRemoveRequest;
316 public event EventGodDelete OnEventGodDelete;
317 public event ParcelDwellRequest OnParcelDwellRequest;
318 public event UserInfoRequest OnUserInfoRequest;
319 public event UpdateUserInfo OnUpdateUserInfo;
320
321 public void SetDebugPacketLevel(int newDebug)
322 {
323 debugLevel = newDebug;
324 }
325
326 public void InPacket(object NewPack)
327 {
328 //throw new System.NotImplementedException();
329 }
330
331 public void ProcessInPacket(Packet NewPack)
332 {
333 //throw new System.NotImplementedException();
334 }
335
336 public void Close(bool ShutdownCircuit)
337 {
338 m_log.Info("[MXP ClientStack] Close Called with SC=" + ShutdownCircuit);
339
340 // Tell the client to go
341 SendLogoutPacket();
342
343 // Let MXPPacketServer clean it up
344 if (Session.SessionState != SessionState.Disconnected)
345 {
346 Session.SetStateDisconnected();
347 }
348
349 // Handle OpenSim cleanup
350 if (ShutdownCircuit)
351 {
352 if (OnConnectionClosed != null)
353 OnConnectionClosed(this);
354 }
355 else
356 {
357 Scene.RemoveClient(AgentId);
358 }
359 }
360
361 public void Kick(string message)
362 {
363 Close(false);
364 }
365
366 public void Start()
367 {
368 // We dont do this
369 }
370
371 public void Stop()
372 {
373 // Nor this
374 }
375
376 public void SendWearables(AvatarWearable[] wearables, int serial)
377 {
378 // Need to translate to MXP somehow
379 }
380
381 public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
382 {
383 // Need to translate to MXP somehow
384 }
385
386 public void SendStartPingCheck(byte seq)
387 {
388 // Need to translate to MXP somehow
389 }
390
391 public void SendKillObject(ulong regionHandle, uint localID)
392 {
393 DisappearanceEventMessage de = new DisappearanceEventMessage();
394 de.ObjectIndex = localID;
395
396 Session.Send(de);
397 }
398
399 public void SendAnimations(UUID[] animID, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
400 {
401 // Need to translate to MXP somehow
402 }
403
404 public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
405 {
406 // Need to translate to MXP somehow
407 }
408
409 public void SendChatMessage(string message, byte type, Vector3 fromPos, string fromName, UUID fromAgentID, byte source, byte audible)
410 {
411 ActionEventMessage chatActionEvent = new ActionEventMessage();
412 chatActionEvent.ActionFragment.ActionName = "Chat";
413 chatActionEvent.ActionFragment.SourceObjectId = fromAgentID.Guid;
414 chatActionEvent.ActionFragment.ObservationRadius = 180.0f;
415 chatActionEvent.ActionFragment.ActionPayloadDialect = "TEXT";
416 chatActionEvent.SetPayloadData(Encoding.UTF8.GetBytes(message));
417 chatActionEvent.ActionFragment.ActionPayloadLength = (uint)chatActionEvent.GetPayloadData().Length;
418
419 Session.Send(chatActionEvent);
420 }
421
422 public void SendInstantMessage(UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, uint timeStamp)
423 {
424 // Need to translate to MXP somehow
425 }
426
427 public void SendInstantMessage(UUID fromAgent, string message, UUID toAgent, string fromName, byte dialog, uint timeStamp, UUID transactionID, bool fromGroup, byte[] binaryBucket)
428 {
429 // Need to translate to MXP somehow
430 }
431
432 public void SendGenericMessage(string method, List<string> message)
433 {
434 // Need to translate to MXP somehow
435 }
436
437 public void SendLayerData(float[] map)
438 {
439 // Need to translate to MXP somehow
440 }
441
442 public void SendLayerData(int px, int py, float[] map)
443 {
444 // Need to translate to MXP somehow
445 }
446
447 public void SendWindData(Vector2[] windSpeeds)
448 {
449 // Need to translate to MXP somehow
450 }
451
452 public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
453 {
454 //throw new System.NotImplementedException();
455 }
456
457 public void InformClientOfNeighbour(ulong neighbourHandle, IPEndPoint neighbourExternalEndPoint)
458 {
459 //throw new System.NotImplementedException();
460 }
461
462 public AgentCircuitData RequestClientInfo()
463 {
464 AgentCircuitData clientinfo = new AgentCircuitData();
465 clientinfo.AgentID = AgentId;
466 clientinfo.Appearance = new AvatarAppearance();
467 clientinfo.BaseFolder = UUID.Zero;
468 clientinfo.CapsPath = "";
469 clientinfo.child = false;
470 clientinfo.ChildrenCapSeeds = new Dictionary<ulong, string>();
471 clientinfo.circuitcode = CircuitCode;
472 clientinfo.firstname = FirstName;
473 clientinfo.InventoryFolder = UUID.Zero;
474 clientinfo.lastname = LastName;
475 clientinfo.SecureSessionID = SecureSessionId;
476 clientinfo.SessionID = SessionId;
477 clientinfo.startpos = StartPos;
478
479 return clientinfo;
480 }
481
482 public void CrossRegion(ulong newRegionHandle, Vector3 pos, Vector3 lookAt, IPEndPoint newRegionExternalEndPoint, string capsURL)
483 {
484 // TODO: We'll want to get this one working.
485 // Need to translate to MXP somehow
486 }
487
488 public void SendMapBlock(List<MapBlockData> mapBlocks, uint flag)
489 {
490 // Need to translate to MXP somehow
491 }
492
493 public void SendLocalTeleport(Vector3 position, Vector3 lookAt, uint flags)
494 {
495 //throw new System.NotImplementedException();
496 }
497
498 public void SendRegionTeleport(ulong regionHandle, byte simAccess, IPEndPoint regionExternalEndPoint, uint locationID, uint flags, string capsURL)
499 {
500 // Need to translate to MXP somehow
501 }
502
503 public void SendTeleportFailed(string reason)
504 {
505 // Need to translate to MXP somehow
506 }
507
508 public void SendTeleportLocationStart()
509 {
510 // Need to translate to MXP somehow
511 }
512
513 public void SendMoneyBalance(UUID transaction, bool success, byte[] description, int balance)
514 {
515 // Need to translate to MXP somehow
516 }
517
518 public void SendPayPrice(UUID objectID, int[] payPrice)
519 {
520 // Need to translate to MXP somehow
521 }
522
523 public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation)
524 {
525 // TODO: This needs handling - to display other avatars
526 }
527
528 public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation)
529 {
530 // TODO: This probably needs handling - update other avatar positions
531 }
532
533 public void SendCoarseLocationUpdate(List<Vector3> CoarseLocations)
534 {
535 // Minimap function, not used.
536 }
537
538 public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID)
539 {
540 // Need to translate to MXP somehow
541 }
542
543 public void SetChildAgentThrottle(byte[] throttle)
544 {
545 // Need to translate to MXP somehow
546 }
547
548 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material, byte[] textureanim, bool attachment, uint AttachPoint, UUID AssetId, UUID SoundId, double SoundVolume, byte SoundFlags, double SoundRadius)
549 {
550 MXPSendPrimitive(localID, ownerID, acc, rvel, primShape, pos, objectID, vel, rotation);
551 }
552
553 private void MXPSendPrimitive(uint localID, UUID ownerID, Vector3 acc, Vector3 rvel, PrimitiveBaseShape primShape, Vector3 pos, UUID objectID, Vector3 vel, Quaternion rotation)
554 {
555 PerceptionEventMessage pe = new PerceptionEventMessage();
556
557 pe.ObjectFragment.ObjectIndex = localID;
558 pe.ObjectFragment.ObjectName = "Object";
559 pe.ObjectFragment.OwnerId = ownerID.Guid;
560 pe.ObjectFragment.TypeId = Guid.Empty;
561
562 pe.ObjectFragment.Acceleration = new[] { acc.X, acc.Y, acc.Z };
563 pe.ObjectFragment.AngularAcceleration = new float[4];
564 pe.ObjectFragment.AngularVelocity = new[] { rvel.X, rvel.Y, rvel.Z, 0.0f };
565 pe.ObjectFragment.BoundingSphereRadius = primShape.Scale.Length()/2.0f;
566 pe.ObjectFragment.Location = new[] { pos.X, pos.Y, pos.Z };
567 pe.ObjectFragment.Mass = 1.0f;
568 pe.ObjectFragment.ObjectId = objectID.Guid;
569 pe.ObjectFragment.Orientation = new[] {rotation.X, rotation.Y, rotation.Z, rotation.W};
570 pe.ObjectFragment.ParentObjectId = Guid.Empty;
571 pe.ObjectFragment.Velocity = new[] { vel.X, vel.Y, vel.Z };
572
573 pe.ObjectFragment.StatePayloadDialect = "";
574 pe.ObjectFragment.StatePayloadLength = 0;
575 pe.ObjectFragment.SetStatePayloadData(new byte[0]);
576
577 Session.Send(pe);
578 }
579
580 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, Vector3 pos, Vector3 vel, Vector3 acc, Quaternion rotation, Vector3 rvel, uint flags, UUID objectID, UUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, byte clickAction, byte material)
581 {
582 MXPSendPrimitive(localID, ownerID, acc, rvel, primShape, pos, objectID, vel, rotation);
583 }
584
585 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID owner, int attachPoint)
586 {
587 MovementEventMessage me = new MovementEventMessage();
588 me.ObjectIndex = localID;
589 me.Location = new[] {position.X, position.Y, position.Z};
590 me.Orientation = new[] {rotation.X, rotation.Y, rotation.Z, rotation.W};
591
592 Session.Send(me);
593 }
594
595 public void SendInventoryFolderDetails(UUID ownerID, UUID folderID, List<InventoryItemBase> items, List<InventoryFolderBase> folders, bool fetchFolders, bool fetchItems)
596 {
597 // Need to translate to MXP somehow
598 }
599
600 public void SendInventoryItemDetails(UUID ownerID, InventoryItemBase item)
601 {
602 // Need to translate to MXP somehow
603 }
604
605 public void SendInventoryItemCreateUpdate(InventoryItemBase Item, uint callbackId)
606 {
607 // Need to translate to MXP somehow
608 }
609
610 public void SendRemoveInventoryItem(UUID itemID)
611 {
612 // Need to translate to MXP somehow
613 }
614
615 public void SendTakeControls(int controls, bool passToAgent, bool TakeControls)
616 {
617 // Need to translate to MXP somehow
618 }
619
620 public void SendTaskInventory(UUID taskID, short serial, byte[] fileName)
621 {
622 // Need to translate to MXP somehow
623 }
624
625 public void SendBulkUpdateInventory(InventoryNodeBase node)
626 {
627 // Need to translate to MXP somehow
628 }
629
630 public void SendXferPacket(ulong xferID, uint packet, byte[] data)
631 {
632 // SL Specific, Ignore. (Remove from IClient)
633 }
634
635 public void SendEconomyData(float EnergyEfficiency, int ObjectCapacity, int ObjectCount, int PriceEnergyUnit, int PriceGroupCreate, int PriceObjectClaim, float PriceObjectRent, float PriceObjectScaleFactor, int PriceParcelClaim, float PriceParcelClaimFactor, int PriceParcelRent, int PricePublicObjectDecay, int PricePublicObjectDelete, int PriceRentLight, int PriceUpload, int TeleportMinPrice, float TeleportPriceExponent)
636 {
637 // SL Specific, Ignore. (Remove from IClient)
638 }
639
640 public void SendAvatarPickerReply(AvatarPickerReplyAgentDataArgs AgentData, List<AvatarPickerReplyDataArgs> Data)
641 {
642 // Need to translate to MXP somehow
643 }
644
645 public void SendAgentDataUpdate(UUID agentid, UUID activegroupid, string firstname, string lastname, ulong grouppowers, string groupname, string grouptitle)
646 {
647 // Need to translate to MXP somehow
648 // TODO: This may need doing - involves displaying the users avatar name
649 }
650
651 public void SendPreLoadSound(UUID objectID, UUID ownerID, UUID soundID)
652 {
653 // Need to translate to MXP somehow
654 }
655
656 public void SendPlayAttachedSound(UUID soundID, UUID objectID, UUID ownerID, float gain, byte flags)
657 {
658 // Need to translate to MXP somehow
659 }
660
661 public void SendTriggeredSound(UUID soundID, UUID ownerID, UUID objectID, UUID parentID, ulong handle, Vector3 position, float gain)
662 {
663 // Need to translate to MXP somehow
664 }
665
666 public void SendAttachedSoundGainChange(UUID objectID, float gain)
667 {
668 // Need to translate to MXP somehow
669 }
670
671 public void SendNameReply(UUID profileId, string firstname, string lastname)
672 {
673 // SL Specific
674 }
675
676 public void SendAlertMessage(string message)
677 {
678 SendChatMessage(message, 0, Vector3.Zero, "System", UUID.Zero, 0, 0);
679 }
680
681 public void SendAgentAlertMessage(string message, bool modal)
682 {
683 SendChatMessage(message, 0, Vector3.Zero, "System" + (modal ? " Notice" : ""), UUID.Zero, 0, 0);
684 }
685
686 public void SendLoadURL(string objectname, UUID objectID, UUID ownerID, bool groupOwned, string message, string url)
687 {
688 // TODO: Probably can do this better
689 SendChatMessage("Please visit: " + url, 0, Vector3.Zero, objectname, UUID.Zero, 0, 0);
690 }
691
692 public void SendDialog(string objectname, UUID objectID, UUID ownerID, string msg, UUID textureID, int ch, string[] buttonlabels)
693 {
694 // TODO: Probably can do this better
695 SendChatMessage("Dialog: " + msg, 0, Vector3.Zero, objectname, UUID.Zero, 0, 0);
696 }
697
698 public bool AddMoney(int debit)
699 {
700 SendChatMessage("You were paid: " + debit, 0, Vector3.Zero, "System", UUID.Zero, 0, 0);
701 return true;
702 }
703
704 public void SendSunPos(Vector3 sunPos, Vector3 sunVel, ulong CurrentTime, uint SecondsPerSunCycle, uint SecondsPerYear, float OrbitalPosition)
705 {
706 // Need to translate to MXP somehow
707 // Send a light object?
708 }
709
710 public void SendViewerEffect(ViewerEffectPacket.EffectBlock[] effectBlocks)
711 {
712 // Need to translate to MXP somehow
713 }
714
715 public void SendViewerTime(int phase)
716 {
717 // Need to translate to MXP somehow
718 }
719
720 public UUID GetDefaultAnimation(string name)
721 {
722 return UUID.Zero;
723 }
724
725 public void SendAvatarProperties(UUID avatarID, string aboutText, string bornOn, byte[] charterMember, string flAbout, uint flags, UUID flImageID, UUID imageID, string profileURL, UUID partnerID)
726 {
727 // Need to translate to MXP somehow
728 }
729
730 public void SendScriptQuestion(UUID taskID, string taskName, string ownerName, UUID itemID, int question)
731 {
732 // Need to translate to MXP somehow
733 }
734
735 public void SendHealth(float health)
736 {
737 // Need to translate to MXP somehow
738 }
739
740 public void SendEstateManagersList(UUID invoice, UUID[] EstateManagers, uint estateID)
741 {
742 // Need to translate to MXP somehow
743 }
744
745 public void SendBannedUserList(UUID invoice, EstateBan[] banlist, uint estateID)
746 {
747 // Need to translate to MXP somehow
748 }
749
750 public void SendRegionInfoToEstateMenu(RegionInfoForEstateMenuArgs args)
751 {
752 // Need to translate to MXP somehow
753 }
754
755 public void SendEstateCovenantInformation(UUID covenant)
756 {
757 // Need to translate to MXP somehow
758 }
759
760 public void SendDetailedEstateData(UUID invoice, string estateName, uint estateID, uint parentEstate, uint estateFlags, uint sunPosition, UUID covenant, string abuseEmail, UUID estateOwner)
761 {
762 // Need to translate to MXP somehow
763 }
764
765 public void SendLandProperties(int sequence_id, bool snap_selection, int request_result, LandData landData, float simObjectBonusFactor, int parcelObjectCapacity, int simObjectCapacity, uint regionFlags)
766 {
767 // Need to translate to MXP somehow
768 }
769
770 public void SendLandAccessListData(List<UUID> avatars, uint accessFlag, int localLandID)
771 {
772 // Need to translate to MXP somehow
773 }
774
775 public void SendForceClientSelectObjects(List<uint> objectIDs)
776 {
777 // Need to translate to MXP somehow
778 }
779
780 public void SendLandObjectOwners(Dictionary<UUID, int> ownersAndCount)
781 {
782 // Need to translate to MXP somehow
783 }
784
785 public void SendLandParcelOverlay(byte[] data, int sequence_id)
786 {
787 // Need to translate to MXP somehow
788 }
789
790 public void SendParcelMediaCommand(uint flags, ParcelMediaCommandEnum command, float time)
791 {
792 // Need to translate to MXP somehow
793 }
794
795 public void SendParcelMediaUpdate(string mediaUrl, UUID mediaTextureID, byte autoScale, string mediaType, string mediaDesc, int mediaWidth, int mediaHeight, byte mediaLoop)
796 {
797 // Need to translate to MXP somehow
798 }
799
800 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
801 {
802 // Need to translate to MXP somehow
803 }
804
805 public void SendConfirmXfer(ulong xferID, uint PacketID)
806 {
807 // Need to translate to MXP somehow
808 }
809
810 public void SendXferRequest(ulong XferID, short AssetType, UUID vFileID, byte FilePath, byte[] FileName)
811 {
812 // Need to translate to MXP somehow
813 }
814
815 public void SendInitiateDownload(string simFileName, string clientFileName)
816 {
817 // Need to translate to MXP somehow
818 }
819
820 public void SendImageFirstPart(ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec)
821 {
822 // Need to translate to MXP somehow
823 }
824
825 public void SendImageNextPart(ushort partNumber, UUID imageUuid, byte[] imageData)
826 {
827 // Need to translate to MXP somehow
828 }
829
830 public void SendImageNotFound(UUID imageid)
831 {
832 // Need to translate to MXP somehow
833 }
834
835 public void SendShutdownConnectionNotice()
836 {
837 // Need to translate to MXP somehow
838 }
839
840 public void SendSimStats(SimStats stats)
841 {
842 // Need to translate to MXP somehow
843 }
844
845 public void SendObjectPropertiesFamilyData(uint RequestFlags, UUID ObjectUUID, UUID OwnerID, UUID GroupID, uint BaseMask, uint OwnerMask, uint GroupMask, uint EveryoneMask, uint NextOwnerMask, int OwnershipCost, byte SaleType, int SalePrice, uint Category, UUID LastOwnerID, string ObjectName, string Description)
846 {
847 //throw new System.NotImplementedException();
848 }
849
850 public void SendObjectPropertiesReply(UUID ItemID, ulong CreationDate, UUID CreatorUUID, UUID FolderUUID, UUID FromTaskUUID, UUID GroupUUID, short InventorySerial, UUID LastOwnerUUID, UUID ObjectUUID, UUID OwnerUUID, string TouchTitle, byte[] TextureID, string SitTitle, string ItemName, string ItemDescription, uint OwnerMask, uint NextOwnerMask, uint GroupMask, uint EveryoneMask, uint BaseMask, byte saleType, int salePrice)
851 {
852 //throw new System.NotImplementedException();
853 }
854
855 public void SendAgentOffline(UUID[] agentIDs)
856 {
857 // Need to translate to MXP somehow (Friends List)
858 }
859
860 public void SendAgentOnline(UUID[] agentIDs)
861 {
862 // Need to translate to MXP somehow (Friends List)
863 }
864
865 public void SendSitResponse(UUID TargetID, Vector3 OffsetPos, Quaternion SitOrientation, bool autopilot, Vector3 CameraAtOffset, Vector3 CameraEyeOffset, bool ForceMouseLook)
866 {
867 // Need to translate to MXP somehow
868 }
869
870 public void SendAdminResponse(UUID Token, uint AdminLevel)
871 {
872 // Need to translate to MXP somehow
873 }
874
875 public void SendGroupMembership(GroupMembershipData[] GroupMembership)
876 {
877 // Need to translate to MXP somehow
878 }
879
880 public void SendGroupNameReply(UUID groupLLUID, string GroupName)
881 {
882 // Need to translate to MXP somehow
883 }
884
885 public void SendJoinGroupReply(UUID groupID, bool success)
886 {
887 // Need to translate to MXP somehow
888 }
889
890 public void SendEjectGroupMemberReply(UUID agentID, UUID groupID, bool success)
891 {
892 // Need to translate to MXP somehow
893 }
894
895 public void SendLeaveGroupReply(UUID groupID, bool success)
896 {
897 // Need to translate to MXP somehow
898 }
899
900 public void SendLandStatReply(uint reportType, uint requestFlags, uint resultCount, LandStatReportItem[] lsrpia)
901 {
902 // Need to translate to MXP somehow
903 }
904
905 public void SendScriptRunningReply(UUID objectID, UUID itemID, bool running)
906 {
907 // Need to translate to MXP somehow
908 }
909
910 public void SendAsset(AssetRequestToClient req)
911 {
912 // Need to translate to MXP somehow
913 }
914
915 public void SendTexture(AssetBase TextureAsset)
916 {
917 // Need to translate to MXP somehow
918 }
919
920 public byte[] GetThrottlesPacked(float multiplier)
921 {
922 // LL Specific, get out of IClientAPI
923
924 const int singlefloat = 4;
925 float tResend = multiplier;
926 float tLand = multiplier;
927 float tWind = multiplier;
928 float tCloud = multiplier;
929 float tTask = multiplier;
930 float tTexture = multiplier;
931 float tAsset = multiplier;
932
933 byte[] throttles = new byte[singlefloat * 7];
934 int i = 0;
935 Buffer.BlockCopy(BitConverter.GetBytes(tResend), 0, throttles, singlefloat * i, singlefloat);
936 i++;
937 Buffer.BlockCopy(BitConverter.GetBytes(tLand), 0, throttles, singlefloat * i, singlefloat);
938 i++;
939 Buffer.BlockCopy(BitConverter.GetBytes(tWind), 0, throttles, singlefloat * i, singlefloat);
940 i++;
941 Buffer.BlockCopy(BitConverter.GetBytes(tCloud), 0, throttles, singlefloat * i, singlefloat);
942 i++;
943 Buffer.BlockCopy(BitConverter.GetBytes(tTask), 0, throttles, singlefloat * i, singlefloat);
944 i++;
945 Buffer.BlockCopy(BitConverter.GetBytes(tTexture), 0, throttles, singlefloat * i, singlefloat);
946 i++;
947 Buffer.BlockCopy(BitConverter.GetBytes(tAsset), 0, throttles, singlefloat * i, singlefloat);
948
949 return throttles;
950 }
951
952 public event ViewerEffectEventHandler OnViewerEffect;
953 public event Action<IClientAPI> OnLogout;
954 public event Action<IClientAPI> OnConnectionClosed;
955
956
957 public void SendBlueBoxMessage(UUID FromAvatarID, string FromAvatarName, string Message)
958 {
959 SendChatMessage(Message, 0, Vector3.Zero, FromAvatarName, UUID.Zero, 0, 0);
960 }
961
962 public void SendLogoutPacket()
963 {
964 LeaveRequestMessage lrm = new LeaveRequestMessage();
965 Session.Send(lrm);
966 }
967
968 public ClientInfo GetClientInfo()
969 {
970 return null;
971 //throw new System.NotImplementedException();
972 }
973
974 public void SetClientInfo(ClientInfo info)
975 {
976 //throw new System.NotImplementedException();
977 }
978
979 public void SetClientOption(string option, string value)
980 {
981 // Need to translate to MXP somehow
982 }
983
984 public string GetClientOption(string option)
985 {
986 // Need to translate to MXP somehow
987 return "";
988 }
989
990 public void Terminate()
991 {
992 Close(false);
993 }
994
995 public void SendSetFollowCamProperties(UUID objectID, SortedDictionary<int, float> parameters)
996 {
997 // Need to translate to MXP somehow
998 }
999
1000 public void SendClearFollowCamProperties(UUID objectID)
1001 {
1002 // Need to translate to MXP somehow
1003 }
1004
1005 public void SendRegionHandle(UUID regoinID, ulong handle)
1006 {
1007 // Need to translate to MXP somehow
1008 }
1009
1010 public void SendParcelInfo(RegionInfo info, LandData land, UUID parcelID, uint x, uint y)
1011 {
1012 // Need to translate to MXP somehow
1013 }
1014
1015 public void SendScriptTeleportRequest(string objName, string simName, Vector3 pos, Vector3 lookAt)
1016 {
1017 // Need to translate to MXP somehow
1018 }
1019
1020 public void SendDirPlacesReply(UUID queryID, DirPlacesReplyData[] data)
1021 {
1022 // Need to translate to MXP somehow
1023 }
1024
1025 public void SendDirPeopleReply(UUID queryID, DirPeopleReplyData[] data)
1026 {
1027 // Need to translate to MXP somehow
1028 }
1029
1030 public void SendDirEventsReply(UUID queryID, DirEventsReplyData[] data)
1031 {
1032 // Need to translate to MXP somehow
1033 }
1034
1035 public void SendDirGroupsReply(UUID queryID, DirGroupsReplyData[] data)
1036 {
1037 // Need to translate to MXP somehow
1038 }
1039
1040 public void SendDirClassifiedReply(UUID queryID, DirClassifiedReplyData[] data)
1041 {
1042 // Need to translate to MXP somehow
1043 }
1044
1045 public void SendDirLandReply(UUID queryID, DirLandReplyData[] data)
1046 {
1047 // Need to translate to MXP somehow
1048 }
1049
1050 public void SendDirPopularReply(UUID queryID, DirPopularReplyData[] data)
1051 {
1052 // Need to translate to MXP somehow
1053 }
1054
1055 public void SendEventInfoReply(EventData info)
1056 {
1057 // Need to translate to MXP somehow
1058 }
1059
1060 public void SendMapItemReply(mapItemReply[] replies, uint mapitemtype, uint flags)
1061 {
1062 // Need to translate to MXP somehow
1063 }
1064
1065 public void SendAvatarGroupsReply(UUID avatarID, GroupMembershipData[] data)
1066 {
1067 // Need to translate to MXP somehow
1068 }
1069
1070 public void SendOfferCallingCard(UUID srcID, UUID transactionID)
1071 {
1072 // Need to translate to MXP somehow
1073 }
1074
1075 public void SendAcceptCallingCard(UUID transactionID)
1076 {
1077 // Need to translate to MXP somehow
1078 }
1079
1080 public void SendDeclineCallingCard(UUID transactionID)
1081 {
1082 // Need to translate to MXP somehow
1083 }
1084
1085 public void SendTerminateFriend(UUID exFriendID)
1086 {
1087 // Need to translate to MXP somehow
1088 }
1089
1090 public void SendAvatarClassifiedReply(UUID targetID, UUID[] classifiedID, string[] name)
1091 {
1092 // Need to translate to MXP somehow
1093 }
1094
1095 public void SendClassifiedInfoReply(UUID classifiedID, UUID creatorID, uint creationDate, uint expirationDate, uint category, string name, string description, UUID parcelID, uint parentEstate, UUID snapshotID, string simName, Vector3 globalPos, string parcelName, byte classifiedFlags, int price)
1096 {
1097 // Need to translate to MXP somehow
1098 }
1099
1100 public void SendAgentDropGroup(UUID groupID)
1101 {
1102 // Need to translate to MXP somehow
1103 }
1104
1105 public void SendAvatarNotesReply(UUID targetID, string text)
1106 {
1107 // Need to translate to MXP somehow
1108 }
1109
1110 public void SendAvatarPicksReply(UUID targetID, Dictionary<UUID, string> picks)
1111 {
1112 // Need to translate to MXP somehow
1113 }
1114
1115 public void SendAvatarClassifiedReply(UUID targetID, Dictionary<UUID, string> classifieds)
1116 {
1117 // Need to translate to MXP somehow
1118 }
1119
1120 public void SendParcelDwellReply(int localID, UUID parcelID, float dwell)
1121 {
1122 // Need to translate to MXP somehow
1123 }
1124
1125 public void SendUserInfoReply(bool imViaEmail, bool visible, string email)
1126 {
1127 // Need to translate to MXP somehow
1128 }
1129
1130 public void KillEndDone()
1131 {
1132 Stop();
1133 }
1134
1135 public bool AddGenericPacketHandler(string MethodName, GenericMessage handler)
1136 {
1137 // Need to translate to MXP somehow
1138 return true;
1139 }
1140
1141 #endregion
1142
1143 #region IClientCore
1144
1145 public bool TryGet<T>(out T iface)
1146 {
1147 iface = default(T);
1148 return false;
1149 }
1150
1151 public T Get<T>()
1152 {
1153 return default(T);
1154 }
1155
1156 #endregion
1157 }
1158}
diff --git a/OpenSim/Client/MXP/MXPModule.cs b/OpenSim/Client/MXP/MXPModule.cs
new file mode 100644
index 0000000..345e4fb
--- /dev/null
+++ b/OpenSim/Client/MXP/MXPModule.cs
@@ -0,0 +1,87 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Timers;
5using MXP;
6using Nini.Config;
7using OpenMetaverse;
8using OpenSim.Client.MXP.PacketHandler;
9using OpenSim.Region.Framework.Interfaces;
10using OpenSim.Region.Framework.Scenes;
11
12namespace OpenSim.Client.MXP
13{
14 public class MXPModule : IRegionModule
15 {
16 private int mxp_Port = 1253;
17 private double mxp_BubbleRadius = 181.01933598375616624661615669884; // Radius of a sphere big enough to encapsulate a 256x256 square
18
19 private readonly Timer ticker = new Timer(100);
20
21 private int ticks;
22 private bool shutdown = false;
23
24 private IConfigSource config;
25
26 private readonly Dictionary<UUID,Scene> m_scenes = new Dictionary<UUID, Scene>();
27
28 private MXPPacketServer server;
29
30
31 public void Initialise(Scene scene, IConfigSource source)
32 {
33 m_scenes.Add(scene.RegionInfo.RegionID, scene);
34 config = source;
35 }
36
37 public void PostInitialise()
38 {
39 if (config.Configs["MXP"] != null)
40 {
41 IConfig con = config.Configs["MXP"];
42
43 if(!con.GetBoolean("Enabled",false))
44 return;
45
46 mxp_Port = con.GetInt("Port", mxp_Port);
47
48
49 server = new MXPPacketServer("http://null", mxp_Port, m_scenes);
50
51 ticker.AutoReset = false;
52 ticker.Elapsed += ticker_Elapsed;
53
54 ticker.Start();
55 }
56 }
57
58 void ticker_Elapsed(object sender, ElapsedEventArgs e)
59 {
60 server.Process();
61
62 if (!shutdown)
63 ticker.Start();
64
65 if(++ticks % 100 == 0)
66 {
67 server.PrintDebugInformation();
68 }
69 }
70
71 public void Close()
72 {
73 shutdown = true;
74 ticker.Stop();
75 }
76
77 public string Name
78 {
79 get { return "MXP ClientStack Module"; }
80 }
81
82 public bool IsSharedModule
83 {
84 get { return true; }
85 }
86 }
87}
diff --git a/OpenSim/Client/MXP/MXPUtil.cs b/OpenSim/Client/MXP/MXPUtil.cs
new file mode 100644
index 0000000..7ca4533
--- /dev/null
+++ b/OpenSim/Client/MXP/MXPUtil.cs
@@ -0,0 +1,15 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using OpenMetaverse;
5
6namespace OpenSim.Client.MXP
7{
8 static class MXPUtil
9 {
10 public static string GenerateMXPURL(string server, int port, UUID bubbleID, Vector3 location)
11 {
12 return string.Format("mxp://{0}:{1}/{2}/{3}", server, port, bubbleID.Guid, location);
13 }
14 }
15}
diff --git a/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs b/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs
new file mode 100644
index 0000000..b35ab9c
--- /dev/null
+++ b/OpenSim/Client/MXP/PacketHandler/MXPPacketServer.cs
@@ -0,0 +1,367 @@
1/* This file borrows heavily from MXPServer.cs - the reference MXPServer
2 * See http://www.bubblecloud.org for a copy of the original file and
3 * implementation details. */
4using System;
5using System.Collections.Generic;
6using System.Reflection;
7using log4net;
8using MXP;
9using MXP.Messages;
10using OpenMetaverse;
11using OpenSim.Client.MXP.ClientStack;
12using OpenSim.Region.Framework.Scenes;
13
14namespace OpenSim.Client.MXP.PacketHandler
15{
16 class MXPPacketServer
17 {
18 internal static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
19
20 private readonly List<MXPClientView> Clients = new List<MXPClientView>();
21 private readonly Dictionary<UUID, Scene> Scenes;
22
23 #region Fields
24
25 private readonly Transmitter transmitter;
26
27 private readonly IList<Session> sessions = new List<Session>();
28 private readonly IList<MXPClientView> sessionsToRemove = new List<MXPClientView>();
29
30 private readonly String cloudUrl;
31 private readonly String programName;
32 private readonly byte programMajorVersion;
33 private readonly byte programMinorVersion;
34
35 #endregion
36
37 #region Constructors
38
39 public MXPPacketServer(string cloudUrl, int port, Dictionary<UUID, Scene> scenes)
40 {
41 this.cloudUrl = cloudUrl;
42
43 Scenes = scenes;
44
45 programMinorVersion = 63;
46 programMajorVersion = 0;
47 programName = "OpenSimulator";
48
49 transmitter = new Transmitter(port);
50 }
51
52 #endregion
53
54 #region Properties
55
56 /// <summary>
57 /// Number of sessions pending. (Process() accepts pending sessions).
58 /// </summary>
59 public int PendingSessionCount
60 {
61 get
62 {
63 return transmitter.PendingSessionCount;
64 }
65 }
66 /// <summary>
67 /// Number of connected sessions.
68 /// </summary>
69 public int SessionCount
70 {
71 get
72 {
73 return sessions.Count;
74 }
75 }
76 /// <summary>
77 /// Property reflecting whether client transmitter threads are alive.
78 /// </summary>
79 public bool IsTransmitterAlive
80 {
81 get
82 {
83 return transmitter != null && transmitter.IsAlive;
84 }
85 }
86 /// <summary>
87 /// Number of packets sent.
88 /// </summary>
89 public ulong PacketsSent
90 {
91 get
92 {
93 return transmitter != null ? transmitter.PacketsSent : 0;
94 }
95 }
96 /// <summary>
97 /// Number of packets received.
98 /// </summary>
99 public ulong PacketsReceived
100 {
101 get
102 {
103 return transmitter != null ? transmitter.PacketsReceived : 0;
104 }
105 }
106 /// <summary>
107 /// Bytes client has received so far.
108 /// </summary>
109 public ulong BytesReceived
110 {
111 get
112 {
113 return transmitter != null ? transmitter.BytesReceived : 0;
114 }
115 }
116 /// <summary>
117 /// Bytes client has sent so far.
118 /// </summary>
119 public ulong BytesSent
120 {
121 get
122 {
123 return transmitter != null ? transmitter.BytesSent : 0;
124 }
125 }
126 /// <summary>
127 /// Number of bytes received (bytes per second) during past second.
128 /// </summary>
129 public double ReceiveRate
130 {
131 get
132 {
133 return transmitter != null ? transmitter.ReceiveRate : 0;
134 }
135 }
136 /// <summary>
137 /// Number of bytes sent (bytes per second) during past second.
138 /// </summary>
139 public double SendRate
140 {
141 get
142 {
143 return transmitter != null ? transmitter.SendRate : 0;
144 }
145 }
146
147 #endregion
148
149 #region Session Management
150
151 public void Disconnect(Session session)
152 {
153 if (session.IsConnected)
154 {
155 Message message = MessageFactory.Current.ReserveMessage(typeof(LeaveRequestMessage));
156 session.Send(message);
157 MessageFactory.Current.ReleaseMessage(message);
158 }
159 else
160 {
161 throw new Exception("Not connected.");
162 }
163 }
164
165 #endregion
166
167
168 #region Processing
169
170 public void PrintDebugInformation()
171 {
172 m_log.Info("[MXP ClientStack] Statistics report");
173 m_log.Info("Pending Sessions: " + PendingSessionCount);
174 m_log.Info("Sessions: " + SessionCount + " (Clients: " + Clients.Count + " )");
175 m_log.Info("Transmitter Alive?: " + IsTransmitterAlive);
176 m_log.Info("Packets Sent/Recieved: " + PacketsSent + " / " + PacketsReceived);
177 m_log.Info("Bytes Sent/Recieved: " + BytesSent + " / " + BytesReceived);
178 m_log.Info("Send/Recieve Rate (bps): " + SendRate + " / " + ReceiveRate);
179 }
180
181 public void Process()
182 {
183 ProcessMessages();
184 Clean();
185 }
186
187 public void Clean()
188 {
189 foreach (MXPClientView clientView in Clients)
190 {
191 if (clientView.Session.SessionState == SessionState.Disconnected)
192 {
193 sessionsToRemove.Add(clientView);
194 }
195 }
196
197 foreach (MXPClientView clientView in sessionsToRemove)
198 {
199 clientView.Scene.RemoveClient(clientView.AgentId);
200 Clients.Remove(clientView);
201 sessions.Remove(clientView.Session);
202 }
203
204 sessionsToRemove.Clear();
205 }
206
207 public bool AuthoriseUser(string participantName, string pass, UUID scene)
208 {
209 if (Scenes.ContainsKey(scene))
210 return true;
211
212 return false;
213 }
214
215 public void ProcessMessages()
216 {
217 if (transmitter.PendingSessionCount > 0)
218 {
219 sessions.Add(transmitter.AcceptPendingSession());
220 }
221
222 foreach (MXPClientView clientView in Clients)
223 {
224
225 int messagesProcessedCount = 0;
226 Session session = clientView.Session;
227
228 while (session.AvailableMessages > 0)
229 {
230
231 Message message = session.Receive();
232
233 if (message.GetType() == typeof(JoinRequestMessage))
234 {
235
236 JoinRequestMessage joinRequestMessage = (JoinRequestMessage)message;
237
238 bool authorized = AuthoriseUser(joinRequestMessage.ParticipantName,
239 joinRequestMessage.ParticipantPassphrase,
240 new UUID(joinRequestMessage.BubbleId));
241
242 if (authorized)
243 {
244 Scene target = Scenes[new UUID(joinRequestMessage.BubbleId)];
245
246 UUID mxpSessionID = UUID.Random();
247
248 m_log.Info("[MXP ClientStack] Session join request success: " + session.SessionId + " (" + (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" + session.RemoteEndPoint.Port + ")");
249
250 AcceptConnection(session, joinRequestMessage, mxpSessionID);
251
252 MXPClientView client = new MXPClientView(session, mxpSessionID, target,
253 joinRequestMessage.ParticipantName);
254 Clients.Add(client);
255
256 target.AddNewClient(client);
257 }
258 else
259 {
260 m_log.Info("[MXP ClientStack] Session join request failure: " + session.SessionId + " (" + (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" + session.RemoteEndPoint.Port + ")");
261
262 DeclineConnection(session, joinRequestMessage);
263 }
264
265 }
266 if (message.GetType() == typeof(LeaveRequestMessage))
267 {
268
269 LeaveResponseMessage leaveResponseMessage = (LeaveResponseMessage)MessageFactory.Current.ReserveMessage(
270 typeof(LeaveResponseMessage));
271
272 m_log.Info("[MXP ClientStack] Session leave request: " + session.SessionId + " (" + (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" + session.RemoteEndPoint.Port + ")");
273
274 leaveResponseMessage.RequestMessageId = message.MessageId;
275 leaveResponseMessage.FailureCode = 0;
276 session.Send(leaveResponseMessage);
277
278 if (session.SessionState != SessionState.Disconnected)
279 {
280 session.SetStateDisconnected();
281 }
282
283 m_log.Info("[MXP ClientStack] Removing Client from Scene");
284 clientView.Scene.RemoveClient(clientView.AgentId);
285 }
286 if (message.GetType() == typeof(LeaveResponseMessage))
287 {
288
289 LeaveResponseMessage leaveResponseMessage = (LeaveResponseMessage)message;
290
291 m_log.Info("[MXP ClientStack] Session leave response: " + session.SessionId + " (" + (session.IsIncoming ? "from" : "to") + " " + session.RemoteEndPoint.Address + ":" + session.RemoteEndPoint.Port + ")");
292
293 if (leaveResponseMessage.FailureCode == 0)
294 {
295 session.SetStateDisconnected();
296 }
297
298 m_log.Info("[MXP ClientStack] Removing Client from Scene");
299 clientView.Scene.RemoveClient(clientView.AgentId);
300 }
301 else
302 {
303 clientView.ProcessMXPPacket(message);
304 }
305
306 MessageFactory.Current.ReleaseMessage(message);
307 messagesProcessedCount++;
308 if (messagesProcessedCount > 1000)
309 {
310 break;
311 }
312 }
313 }
314 }
315
316 private void AcceptConnection(Session session, JoinRequestMessage joinRequestMessage, UUID mxpSessionID)
317 {
318 JoinResponseMessage joinResponseMessage = (JoinResponseMessage)MessageFactory.Current.ReserveMessage(
319 typeof(JoinResponseMessage));
320
321 joinResponseMessage.RequestMessageId = joinRequestMessage.MessageId;
322 joinResponseMessage.FailureCode = 0;
323
324 joinResponseMessage.ParticipantId = mxpSessionID.Guid;
325 joinResponseMessage.CloudUrl = cloudUrl;
326
327 joinResponseMessage.BubbleName = Scenes[new UUID(joinRequestMessage.BubbleId)].RegionInfo.RegionName;
328
329 joinResponseMessage.BubbleRealTime = 0;
330 joinResponseMessage.ProgramName = programName;
331 joinResponseMessage.ProgramMajorVersion = programMajorVersion;
332 joinResponseMessage.ProgramMinorVersion = programMinorVersion;
333 joinResponseMessage.ProtocolMajorVersion = MxpConstants.ProtocolMajorVersion;
334 joinResponseMessage.ProtocolMinorVersion = MxpConstants.ProtocolMinorVersion;
335
336 session.Send(joinResponseMessage);
337
338 session.SetStateConnected();
339 }
340
341 private void DeclineConnection(Session session, Message joinRequestMessage)
342 {
343 JoinResponseMessage joinResponseMessage = (JoinResponseMessage)MessageFactory.Current.ReserveMessage(typeof(JoinResponseMessage));
344
345 joinResponseMessage.RequestMessageId = joinRequestMessage.MessageId;
346 joinResponseMessage.FailureCode = 1;
347
348 joinResponseMessage.CloudUrl = cloudUrl;
349
350 joinResponseMessage.BubbleName = "Declined OpenSim Region"; // Dont reveal anything about the sim in the disconnect notice
351
352 joinResponseMessage.BubbleRealTime = 0;
353 joinResponseMessage.ProgramName = programName;
354 joinResponseMessage.ProgramMajorVersion = programMajorVersion;
355 joinResponseMessage.ProgramMinorVersion = programMinorVersion;
356 joinResponseMessage.ProtocolMajorVersion = MxpConstants.ProtocolMajorVersion;
357 joinResponseMessage.ProtocolMinorVersion = MxpConstants.ProtocolMinorVersion;
358
359 session.Send(joinResponseMessage);
360
361 session.SetStateDisconnected();
362 }
363
364 #endregion
365
366 }
367}