aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/OpenSim.RegionServer/ClientView
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/OpenSim.RegionServer/ClientView/ClientView.API.cs682
-rw-r--r--OpenSim/OpenSim.RegionServer/ClientView/ClientView.AgentAssetUpload.cs262
-rw-r--r--OpenSim/OpenSim.RegionServer/ClientView/ClientView.Grid.cs59
-rw-r--r--OpenSim/OpenSim.RegionServer/ClientView/ClientView.PacketHandlers.cs193
-rw-r--r--OpenSim/OpenSim.RegionServer/ClientView/ClientView.ProcessPackets.cs537
-rw-r--r--OpenSim/OpenSim.RegionServer/ClientView/ClientView.cs292
-rw-r--r--OpenSim/OpenSim.RegionServer/ClientView/ClientViewBase.cs327
7 files changed, 2352 insertions, 0 deletions
diff --git a/OpenSim/OpenSim.RegionServer/ClientView/ClientView.API.cs b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.API.cs
new file mode 100644
index 0000000..b9773c6
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.API.cs
@@ -0,0 +1,682 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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*/
28using System;
29using System.Collections.Generic;
30using System.Text;
31using OpenSim.Framework.Interfaces;
32using OpenSim.Framework.Inventory;
33using OpenSim.Framework.Types;
34
35using libsecondlife;
36using libsecondlife.Packets;
37
38namespace OpenSim
39{
40 partial class ClientView
41 {
42 public event ChatFromViewer OnChatFromViewer;
43 public event RezObject OnRezObject;
44 public event GenericCall4 OnDeRezObject;
45 public event ModifyTerrain OnModifyTerrain;
46 public event GenericCall OnRegionHandShakeReply;
47 public event GenericCall OnRequestWearables;
48 public event SetAppearance OnSetAppearance;
49 public event GenericCall2 OnCompleteMovementToRegion;
50 public event GenericCall3 OnAgentUpdate;
51 public event StartAnim OnStartAnim;
52 public event GenericCall OnRequestAvatarsData;
53 public event LinkObjects OnLinkObjects;
54 public event GenericCall4 OnAddPrim;
55 public event UpdateShape OnUpdatePrimShape;
56 public event ObjectSelect OnObjectSelect;
57 public event UpdatePrimFlags OnUpdatePrimFlags;
58 public event UpdatePrimTexture OnUpdatePrimTexture;
59 public event UpdatePrimVector OnUpdatePrimPosition;
60 public event UpdatePrimRotation OnUpdatePrimRotation;
61 public event UpdatePrimVector OnUpdatePrimScale;
62 public event StatusChange OnChildAgentStatus;
63 public event GenericCall2 OnStopMovement;
64 public event NewAvatar OnNewAvatar;
65 public event GenericCall6 OnRemoveAvatar;
66
67 public event ParcelPropertiesRequest OnParcelPropertiesRequest;
68 public event ParcelDivideRequest OnParcelDivideRequest;
69 public event ParcelJoinRequest OnParcelJoinRequest;
70 public event ParcelPropertiesUpdateRequest OnParcelPropertiesUpdateRequest;
71
72 public event EstateOwnerMessageRequest OnEstateOwnerMessage;
73
74 /// <summary>
75 ///
76 /// </summary>
77 public LLVector3 StartPos
78 {
79 get
80 {
81 return startpos;
82 }
83 set
84 {
85 startpos = value;
86 }
87 }
88
89 /// <summary>
90 ///
91 /// </summary>
92 public LLUUID AgentId
93 {
94 get
95 {
96 return this.AgentID;
97 }
98 }
99
100 /// <summary>
101 ///
102 /// </summary>
103 public string FirstName
104 {
105 get
106 {
107 return this.firstName;
108 }
109
110 }
111
112 /// <summary>
113 ///
114 /// </summary>
115 public string LastName
116 {
117 get
118 {
119 return this.lastName;
120 }
121 }
122
123 #region World/Avatar to Client
124
125 /// <summary>
126 ///
127 /// </summary>
128 /// <param name="regionInfo"></param>
129 public void SendRegionHandshake(RegionInfo regionInfo)
130 {
131 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
132 RegionHandshakePacket handshake = new RegionHandshakePacket();
133
134 handshake.RegionInfo.BillableFactor = regionInfo.estateSettings.billableFactor;
135 handshake.RegionInfo.IsEstateManager = false;
136 handshake.RegionInfo.TerrainHeightRange00 = regionInfo.estateSettings.terrainHeightRange0;
137 handshake.RegionInfo.TerrainHeightRange01 = regionInfo.estateSettings.terrainHeightRange1;
138 handshake.RegionInfo.TerrainHeightRange10 = regionInfo.estateSettings.terrainHeightRange2;
139 handshake.RegionInfo.TerrainHeightRange11 = regionInfo.estateSettings.terrainHeightRange3;
140 handshake.RegionInfo.TerrainStartHeight00 = regionInfo.estateSettings.terrainStartHeight0;
141 handshake.RegionInfo.TerrainStartHeight01 = regionInfo.estateSettings.terrainStartHeight1;
142 handshake.RegionInfo.TerrainStartHeight10 = regionInfo.estateSettings.terrainStartHeight2;
143 handshake.RegionInfo.TerrainStartHeight11 = regionInfo.estateSettings.terrainStartHeight3;
144 handshake.RegionInfo.SimAccess = (byte)regionInfo.estateSettings.simAccess;
145 handshake.RegionInfo.WaterHeight = regionInfo.estateSettings.waterHeight;
146
147
148 handshake.RegionInfo.RegionFlags = (uint)regionInfo.estateSettings.regionFlags;
149
150 handshake.RegionInfo.SimName = _enc.GetBytes(regionInfo.estateSettings.waterHeight + "\0");
151 handshake.RegionInfo.SimOwner = regionInfo.MasterAvatarAssignedUUID;
152 handshake.RegionInfo.TerrainBase0 = regionInfo.estateSettings.terrainBase0;
153 handshake.RegionInfo.TerrainBase1 = regionInfo.estateSettings.terrainBase1;
154 handshake.RegionInfo.TerrainBase2 = regionInfo.estateSettings.terrainBase2;
155 handshake.RegionInfo.TerrainBase3 = regionInfo.estateSettings.terrainBase3;
156 handshake.RegionInfo.TerrainDetail0 = regionInfo.estateSettings.terrainDetail0;
157 handshake.RegionInfo.TerrainDetail1 = regionInfo.estateSettings.terrainDetail1;
158 handshake.RegionInfo.TerrainDetail2 =regionInfo.estateSettings.terrainDetail2;
159 handshake.RegionInfo.TerrainDetail3 = regionInfo.estateSettings.terrainDetail3;
160 handshake.RegionInfo.CacheID = LLUUID.Random(); //I guess this is for the client to remember an old setting?
161
162 this.OutPacket(handshake);
163 }
164
165 /// <summary>
166 ///
167 /// </summary>
168 /// <param name="regInfo"></param>
169 public void MoveAgentIntoRegion(RegionInfo regInfo)
170 {
171 AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
172 mov.AgentData.SessionID = this.SessionID;
173 mov.AgentData.AgentID = this.AgentID;
174 mov.Data.RegionHandle = regInfo.RegionHandle;
175 // TODO - dynamicalise this stuff
176 mov.Data.Timestamp = 1172750370;
177 mov.Data.Position = this.startpos;
178 mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0);
179
180 OutPacket(mov);
181 }
182
183 public void SendChatMessage(string message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
184 {
185 SendChatMessage( Helpers.StringToField( message ), type, fromPos, fromName, fromAgentID);
186 }
187
188 /// <summary>
189 ///
190 /// </summary>
191 /// <param name="message"></param>
192 /// <param name="type"></param>
193 /// <param name="fromPos"></param>
194 /// <param name="fromName"></param>
195 /// <param name="fromAgentID"></param>
196 public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID)
197 {
198 System.Text.Encoding enc = System.Text.Encoding.ASCII;
199 libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
200 reply.ChatData.Audible = 1;
201 reply.ChatData.Message = message;
202 reply.ChatData.ChatType = type;
203 reply.ChatData.SourceType = 1;
204 reply.ChatData.Position = fromPos;
205 reply.ChatData.FromName = enc.GetBytes(fromName + "\0");
206 reply.ChatData.OwnerID = fromAgentID;
207 reply.ChatData.SourceID = fromAgentID;
208
209 this.OutPacket(reply);
210 }
211
212
213 /// <summary>
214 /// Send the region heightmap to the client
215 /// </summary>
216 /// <param name="map">heightmap</param>
217 public virtual void SendLayerData(float[] map)
218 {
219 try
220 {
221 int[] patches = new int[4];
222
223 for (int y = 0; y < 16; y++)
224 {
225 for (int x = 0; x < 16; x = x + 4)
226 {
227 patches[0] = x + 0 + y * 16;
228 patches[1] = x + 1 + y * 16;
229 patches[2] = x + 2 + y * 16;
230 patches[3] = x + 3 + y * 16;
231
232 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
233 OutPacket(layerpack);
234 }
235 }
236 }
237 catch (Exception e)
238 {
239 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "ClientView API.cs: SendLayerData() - Failed with exception " + e.ToString());
240 }
241 }
242
243 /// <summary>
244 /// Sends a specified patch to a client
245 /// </summary>
246 /// <param name="px">Patch coordinate (x) 0..16</param>
247 /// <param name="py">Patch coordinate (y) 0..16</param>
248 /// <param name="map">heightmap</param>
249 public void SendLayerData(int px, int py, float[] map)
250 {
251 try
252 {
253 int[] patches = new int[1];
254 int patchx, patchy;
255 patchx = px / 16;
256 patchy = py / 16;
257
258 patches[0] = patchx + 0 + patchy * 16;
259
260 Packet layerpack = TerrainManager.CreateLandPacket(map, patches);
261 OutPacket(layerpack);
262 }
263 catch (Exception e)
264 {
265 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "ClientView API .cs: SendLayerData() - Failed with exception " + e.ToString());
266 }
267 }
268
269 public void InformClientOfNeighbour(ulong neighbourHandle, System.Net.IPAddress neighbourIP, ushort neighbourPort)
270 {
271 EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket();
272 enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock();
273 enablesimpacket.SimulatorInfo.Handle = neighbourHandle;
274
275 byte[] byteIP = neighbourIP.GetAddressBytes();
276 enablesimpacket.SimulatorInfo.IP = (uint)byteIP[3] << 24;
277 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[2] << 16;
278 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[1] << 8;
279 enablesimpacket.SimulatorInfo.IP += (uint)byteIP[0];
280 enablesimpacket.SimulatorInfo.Port = neighbourPort;
281 OutPacket(enablesimpacket);
282 }
283
284 public AgentCircuitData RequestClientInfo()
285 {
286 AgentCircuitData agentData = new AgentCircuitData();
287 agentData.AgentID = this.AgentId;
288 agentData.SessionID = this.SessionID;
289 agentData.SecureSessionID = this.SecureSessionID;
290 agentData.circuitcode = this.CircuitCode;
291 agentData.child = false;
292 agentData.firstname = this.firstName;
293 agentData.lastname = this.lastName;
294
295 return agentData;
296 }
297
298 #region Appearance/ Wearables Methods
299
300 /// <summary>
301 ///
302 /// </summary>
303 /// <param name="wearables"></param>
304 public void SendWearables(AvatarWearable[] wearables)
305 {
306 AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
307 aw.AgentData.AgentID = this.AgentID;
308 aw.AgentData.SerialNum = 0;
309 aw.AgentData.SessionID = this.SessionID;
310
311 aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
312 AgentWearablesUpdatePacket.WearableDataBlock awb;
313 for (int i = 0; i < wearables.Length; i++)
314 {
315 awb = new AgentWearablesUpdatePacket.WearableDataBlock();
316 awb.WearableType = (byte)i;
317 awb.AssetID = wearables[i].AssetID;
318 awb.ItemID = wearables[i].ItemID;
319 aw.WearableData[i] = awb;
320 }
321
322 this.OutPacket(aw);
323 }
324
325 /// <summary>
326 ///
327 /// </summary>
328 /// <param name="agentID"></param>
329 /// <param name="visualParams"></param>
330 /// <param name="textureEntry"></param>
331 public void SendAppearance(LLUUID agentID, byte[] visualParams, byte[] textureEntry)
332 {
333 AvatarAppearancePacket avp = new AvatarAppearancePacket();
334 avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
335 avp.ObjectData.TextureEntry = textureEntry;
336
337 AvatarAppearancePacket.VisualParamBlock avblock = null;
338 for (int i = 0; i < visualParams.Length; i++)
339 {
340 avblock = new AvatarAppearancePacket.VisualParamBlock();
341 avblock.ParamValue = visualParams[i];
342 avp.VisualParam[i] = avblock;
343 }
344
345 avp.Sender.IsTrial = false;
346 avp.Sender.ID = agentID;
347 OutPacket(avp);
348 }
349
350 #endregion
351
352 #region Avatar Packet/data sending Methods
353
354 /// <summary>
355 ///
356 /// </summary>
357 /// <param name="regionInfo"></param>
358 /// <param name="firstName"></param>
359 /// <param name="lastName"></param>
360 /// <param name="avatarID"></param>
361 /// <param name="avatarLocalID"></param>
362 /// <param name="Pos"></param>
363 public void SendAvatarData(RegionInfo regionInfo, string firstName, string lastName, LLUUID avatarID, uint avatarLocalID, LLVector3 Pos)
364 {
365 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
366 //send a objectupdate packet with information about the clients avatar
367
368 ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
369 objupdate.RegionData.RegionHandle = regionInfo.RegionHandle;
370 objupdate.RegionData.TimeDilation = 64096;
371 objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
372 objupdate.ObjectData[0] = this.CreateDefaultAvatarPacket();
373 //give this avatar object a local id and assign the user a name
374
375 objupdate.ObjectData[0].ID = avatarLocalID;
376 objupdate.ObjectData[0].FullID = avatarID;
377 objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + " \0");
378 libsecondlife.LLVector3 pos2 = new LLVector3((float)Pos.X, (float)Pos.Y, (float)Pos.Z);
379 byte[] pb = pos2.GetBytes();
380 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
381
382 OutPacket(objupdate);
383
384 }
385
386
387 /// <summary>
388 ///
389 /// </summary>
390 /// <param name="objdata"></param>
391 protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata)
392 {
393 objdata.PSBlock = new byte[0];
394 objdata.ExtraParams = new byte[1];
395 objdata.MediaURL = new byte[0];
396 objdata.NameValue = new byte[0];
397 objdata.Text = new byte[0];
398 objdata.TextColor = new byte[4];
399 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
400 objdata.JointPivot = new LLVector3(0, 0, 0);
401 objdata.Material = 4;
402 objdata.TextureAnim = new byte[0];
403 objdata.Sound = LLUUID.Zero;
404 LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
405 objdata.TextureEntry = ntex.ToBytes();
406 objdata.State = 0;
407 objdata.Data = new byte[0];
408
409 objdata.ObjectData = new byte[76];
410 objdata.ObjectData[15] = 128;
411 objdata.ObjectData[16] = 63;
412 objdata.ObjectData[56] = 128;
413 objdata.ObjectData[61] = 102;
414 objdata.ObjectData[62] = 40;
415 objdata.ObjectData[63] = 61;
416 objdata.ObjectData[64] = 189;
417 }
418
419 /// <summary>
420 ///
421 /// </summary>
422 /// <returns></returns>
423 protected ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket()
424 {
425 libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new ObjectUpdatePacket.ObjectDataBlock(); // new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
426
427 SetDefaultAvatarPacketValues(ref objdata);
428 objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24);
429 objdata.PathCurve = 16;
430 objdata.ProfileCurve = 1;
431 objdata.PathScaleX = 100;
432 objdata.PathScaleY = 100;
433 objdata.ParentID = 0;
434 objdata.OwnerID = LLUUID.Zero;
435 objdata.Scale = new LLVector3(1, 1, 1);
436 objdata.PCode = 47;
437 System.Text.Encoding enc = System.Text.Encoding.ASCII;
438 libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
439 pos.X = 100f;
440 objdata.ID = 8880000;
441 objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
442 libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100f, 23f);
443 //objdata.FullID=user.AgentID;
444 byte[] pb = pos.GetBytes();
445 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
446
447 return objdata;
448 }
449
450 #endregion
451
452 #region Primitive Packet/data Sending Methods
453
454 /// <summary>
455 ///
456 /// </summary>
457 /// <param name="localID"></param>
458 /// <param name="rotation"></param>
459 /// <param name="attachPoint"></param>
460 public void AttachObject(uint localID, LLQuaternion rotation, byte attachPoint)
461 {
462 ObjectAttachPacket attach = new ObjectAttachPacket();
463 attach.AgentData.AgentID = this.AgentID;
464 attach.AgentData.SessionID = this.SessionID;
465 attach.AgentData.AttachmentPoint = attachPoint;
466 attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
467 attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
468 attach.ObjectData[0].ObjectLocalID = localID;
469 attach.ObjectData[0].Rotation = rotation;
470
471 this.OutPacket(attach);
472 }
473
474 /// <summary>
475 /// Sends a full ObjectUpdatePacket to a client to inform it of a new primitive
476 /// or big changes to a existing primitive.
477 /// </summary>
478 /// <param name="regionHandle"></param>
479 /// <param name="timeDilation"></param>
480 /// <param name="localID"></param>
481 /// <param name="primData"></param>
482 /// <param name="pos"></param>
483 /// <param name="rotation"></param>
484 /// <param name="textureID"></param>
485 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimData primData, LLVector3 pos, LLQuaternion rotation, LLUUID textureID)
486 {
487 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
488 outPacket.RegionData.RegionHandle = regionHandle;
489 outPacket.RegionData.TimeDilation = timeDilation;
490 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
491 outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primData, textureID);
492 outPacket.ObjectData[0].ID = localID;
493 outPacket.ObjectData[0].FullID = primData.FullID;
494 byte[] pb = pos.GetBytes();
495 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
496 byte[] rot = rotation.GetBytes();
497 Array.Copy(rot, 0, outPacket.ObjectData[0].ObjectData, 48, rot.Length);
498 OutPacket(outPacket);
499 }
500
501 /// <summary>
502 /// Sends a full ObjectUpdatePacket to a client to inform it of a new primitive
503 /// or big changes to a existing primitive.
504 /// uses default rotation
505 /// </summary>
506 /// <param name="primData"></param>
507 /// <param name="pos"></param>
508 public void SendPrimitiveToClient(ulong regionHandle, ushort timeDilation, uint localID, PrimData primData, LLVector3 pos, LLUUID textureID)
509 {
510 ObjectUpdatePacket outPacket = new ObjectUpdatePacket();
511 outPacket.RegionData.RegionHandle = regionHandle;
512 outPacket.RegionData.TimeDilation = timeDilation;
513 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
514 outPacket.ObjectData[0] = this.CreatePrimUpdateBlock(primData, textureID);
515 outPacket.ObjectData[0].ID = localID;
516 outPacket.ObjectData[0].FullID = primData.FullID;
517 byte[] pb = pos.GetBytes();
518 Array.Copy(pb, 0, outPacket.ObjectData[0].ObjectData, 0, pb.Length);
519
520 OutPacket(outPacket);
521 }
522
523 /// <summary>
524 /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive)
525 /// </summary>
526 /// <param name="primData"></param>
527 /// <returns></returns>
528 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimData primData, LLUUID textureID)
529 {
530 ObjectUpdatePacket.ObjectDataBlock objupdate = new ObjectUpdatePacket.ObjectDataBlock();
531 this.SetDefaultPrimPacketValues(objupdate);
532 objupdate.UpdateFlags = 32 + 65536 + 131072 + 256 + 4 + 8 + 2048 + 524288 + 268435456;
533 this.SetPrimPacketShapeData(objupdate, primData, textureID);
534
535 return objupdate;
536 }
537
538 /// <summary>
539 /// Set some default values in a ObjectUpdatePacket
540 /// </summary>
541 /// <param name="objdata"></param>
542 protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata)
543 {
544 objdata.PSBlock = new byte[0];
545 objdata.ExtraParams = new byte[1];
546 objdata.MediaURL = new byte[0];
547 objdata.NameValue = new byte[0];
548 objdata.Text = new byte[0];
549 objdata.TextColor = new byte[4];
550 objdata.JointAxisOrAnchor = new LLVector3(0, 0, 0);
551 objdata.JointPivot = new LLVector3(0, 0, 0);
552 objdata.Material = 3;
553 objdata.TextureAnim = new byte[0];
554 objdata.Sound = LLUUID.Zero;
555 objdata.State = 0;
556 objdata.Data = new byte[0];
557
558 objdata.ObjectData = new byte[60];
559 objdata.ObjectData[46] = 128;
560 objdata.ObjectData[47] = 63;
561 }
562
563 /// <summary>
564 /// Copy the data from a PrimData object to a ObjectUpdatePacket
565 /// </summary>
566 /// <param name="objectData"></param>
567 /// <param name="primData"></param>
568 protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimData primData, LLUUID textureID)
569 {
570 LLObject.TextureEntry ntex = new LLObject.TextureEntry(textureID);
571 objectData.TextureEntry = ntex.ToBytes();
572 objectData.OwnerID = primData.OwnerID;
573 objectData.PCode = primData.PCode;
574 objectData.PathBegin =primData.PathBegin;
575 objectData.PathEnd = primData.PathEnd;
576 objectData.PathScaleX = primData.PathScaleX;
577 objectData.PathScaleY = primData.PathScaleY;
578 objectData.PathShearX = primData.PathShearX;
579 objectData.PathShearY = primData.PathShearY;
580 objectData.PathSkew = primData.PathSkew;
581 objectData.ProfileBegin = primData.ProfileBegin;
582 objectData.ProfileEnd = primData.ProfileEnd;
583 objectData.Scale = primData.Scale;
584 objectData.PathCurve = primData.PathCurve;
585 objectData.ProfileCurve = primData.ProfileCurve;
586 objectData.ParentID = primData.ParentID;
587 objectData.ProfileHollow = primData.ProfileHollow;
588 objectData.PathRadiusOffset = primData.PathRadiusOffset;
589 objectData.PathRevolutions = primData.PathRevolutions;
590 objectData.PathTaperX = primData.PathTaperX;
591 objectData.PathTaperY = primData.PathTaperY;
592 objectData.PathTwist = primData.PathTwist;
593 objectData.PathTwistBegin = primData.PathTwistBegin;
594 }
595
596 public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, LLVector3 position, LLQuaternion rotation)
597 {
598 ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
599 terse.RegionData.RegionHandle = regionHandle;
600 terse.RegionData.TimeDilation = timeDilation;
601 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
602 terse.ObjectData[0] = this.CreatePrimImprovedBlock(localID, position, rotation);
603
604 this.OutPacket(terse);
605 }
606
607 /// <summary>
608 ///
609 /// </summary>
610 /// <param name="localID"></param>
611 /// <param name="position"></param>
612 /// <param name="rotation"></param>
613 /// <returns></returns>
614 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID, LLVector3 position, LLQuaternion rotation)
615 {
616 uint ID = localID;
617 byte[] bytes = new byte[60];
618
619 int i = 0;
620 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
621 dat.TextureEntry = new byte[0];
622 bytes[i++] = (byte)(ID % 256);
623 bytes[i++] = (byte)((ID >> 8) % 256);
624 bytes[i++] = (byte)((ID >> 16) % 256);
625 bytes[i++] = (byte)((ID >> 24) % 256);
626 bytes[i++] = 0;
627 bytes[i++] = 0;
628
629 byte[] pb = position.GetBytes();
630 Array.Copy(pb, 0, bytes, i, pb.Length);
631 i += 12;
632 ushort ac = 32767;
633
634 //vel
635 bytes[i++] = (byte)(ac % 256);
636 bytes[i++] = (byte)((ac >> 8) % 256);
637 bytes[i++] = (byte)(ac % 256);
638 bytes[i++] = (byte)((ac >> 8) % 256);
639 bytes[i++] = (byte)(ac % 256);
640 bytes[i++] = (byte)((ac >> 8) % 256);
641
642 //accel
643 bytes[i++] = (byte)(ac % 256);
644 bytes[i++] = (byte)((ac >> 8) % 256);
645 bytes[i++] = (byte)(ac % 256);
646 bytes[i++] = (byte)((ac >> 8) % 256);
647 bytes[i++] = (byte)(ac % 256);
648 bytes[i++] = (byte)((ac >> 8) % 256);
649
650 ushort rw, rx, ry, rz;
651 rw = (ushort)(32768 * (rotation.W + 1));
652 rx = (ushort)(32768 * (rotation.X + 1));
653 ry = (ushort)(32768 * (rotation.Y + 1));
654 rz = (ushort)(32768 * (rotation.Z + 1));
655
656 //rot
657 bytes[i++] = (byte)(rx % 256);
658 bytes[i++] = (byte)((rx >> 8) % 256);
659 bytes[i++] = (byte)(ry % 256);
660 bytes[i++] = (byte)((ry >> 8) % 256);
661 bytes[i++] = (byte)(rz % 256);
662 bytes[i++] = (byte)((rz >> 8) % 256);
663 bytes[i++] = (byte)(rw % 256);
664 bytes[i++] = (byte)((rw >> 8) % 256);
665
666 //rotation vel
667 bytes[i++] = (byte)(ac % 256);
668 bytes[i++] = (byte)((ac >> 8) % 256);
669 bytes[i++] = (byte)(ac % 256);
670 bytes[i++] = (byte)((ac >> 8) % 256);
671 bytes[i++] = (byte)(ac % 256);
672 bytes[i++] = (byte)((ac >> 8) % 256);
673
674 dat.Data = bytes;
675 return dat;
676 }
677 #endregion
678
679 #endregion
680
681 }
682}
diff --git a/OpenSim/OpenSim.RegionServer/ClientView/ClientView.AgentAssetUpload.cs b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.AgentAssetUpload.cs
new file mode 100644
index 0000000..e57bb42
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.AgentAssetUpload.cs
@@ -0,0 +1,262 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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*/
28using System;
29using System.Collections.Generic;
30using System.Text;
31using OpenSim.Assets;
32using OpenSim.Framework.Types;
33using OpenSim.Framework.Utilities;
34using libsecondlife;
35using libsecondlife.Packets;
36
37namespace OpenSim
38{
39 partial class ClientView
40 {
41 public class AgentAssetUpload
42 {
43 private Dictionary<LLUUID, AssetTransaction> transactions = new Dictionary<LLUUID, AssetTransaction>();
44 private ClientView ourClient;
45 private AssetCache m_assetCache;
46 private InventoryCache m_inventoryCache;
47
48 public AgentAssetUpload(ClientView client, AssetCache assetCache, InventoryCache inventoryCache)
49 {
50 this.ourClient = client;
51 m_assetCache = assetCache;
52 m_inventoryCache = inventoryCache;
53 }
54
55 public void AddUpload(LLUUID transactionID, AssetBase asset)
56 {
57 AssetTransaction upload = new AssetTransaction();
58 lock (this.transactions)
59 {
60 upload.Asset = asset;
61 upload.TransactionID = transactionID;
62 this.transactions.Add(transactionID, upload);
63 }
64 if (upload.Asset.Data.Length > 2)
65 {
66 //is complete
67 upload.UploadComplete = true;
68 AssetUploadCompletePacket response = new AssetUploadCompletePacket();
69 response.AssetBlock.Type = asset.Type;
70 response.AssetBlock.Success = true;
71 response.AssetBlock.UUID = transactionID.Combine(this.ourClient.SecureSessionID);
72 this.ourClient.OutPacket(response);
73 m_assetCache.AddAsset(asset);
74 }
75 else
76 {
77 upload.UploadComplete = false;
78 upload.XferID = Util.GetNextXferID();
79 RequestXferPacket xfer = new RequestXferPacket();
80 xfer.XferID.ID = upload.XferID;
81 xfer.XferID.VFileType = upload.Asset.Type;
82 xfer.XferID.VFileID = transactionID.Combine(this.ourClient.SecureSessionID);
83 xfer.XferID.FilePath = 0;
84 xfer.XferID.Filename = new byte[0];
85 this.ourClient.OutPacket(xfer);
86 }
87
88 }
89
90 public AssetBase GetUpload(LLUUID transactionID)
91 {
92 if (this.transactions.ContainsKey(transactionID))
93 {
94 return this.transactions[transactionID].Asset;
95 }
96
97 return null;
98 }
99
100 public void HandleUploadPacket(AssetUploadRequestPacket pack, LLUUID assetID)
101 {
102 // Console.Write("asset upload request , type = " + pack.AssetBlock.Type.ToString());
103 AssetBase asset = null;
104 if (pack.AssetBlock.Type == 0)
105 {
106
107 //first packet for transaction
108 asset = new AssetBase();
109 asset.FullID = assetID;
110 asset.Type = pack.AssetBlock.Type;
111 asset.InvType = asset.Type;
112 asset.Name = "UploadedTexture" + Util.RandomClass.Next(1, 1000).ToString("000");
113 asset.Data = pack.AssetBlock.AssetData;
114
115
116 }
117 else if (pack.AssetBlock.Type == 13 | pack.AssetBlock.Type == 5 | pack.AssetBlock.Type == 7)
118 {
119
120 asset = new AssetBase();
121 asset.FullID = assetID;
122 // Console.WriteLine("skin asset id is " + assetID.ToStringHyphenated());
123 asset.Type = pack.AssetBlock.Type;
124 asset.InvType = asset.Type;
125 asset.Name = "NewClothing" + Util.RandomClass.Next(1, 1000).ToString("000");
126 asset.Data = pack.AssetBlock.AssetData;
127
128
129 }
130
131 if (asset != null)
132 {
133 this.AddUpload(pack.AssetBlock.TransactionID, asset);
134 }
135 else
136 {
137
138 //currently we don't support this asset type
139 //so lets just tell the client that the upload is complete
140 AssetUploadCompletePacket response = new AssetUploadCompletePacket();
141 response.AssetBlock.Type = pack.AssetBlock.Type;
142 response.AssetBlock.Success = true;
143 response.AssetBlock.UUID = pack.AssetBlock.TransactionID.Combine(this.ourClient.SecureSessionID);
144 this.ourClient.OutPacket(response);
145 }
146
147 }
148
149 #region Xfer packet system for larger uploads
150
151 public void HandleXferPacket(SendXferPacketPacket xferPacket)
152 {
153 lock (this.transactions)
154 {
155 foreach (AssetTransaction trans in this.transactions.Values)
156 {
157 if (trans.XferID == xferPacket.XferID.ID)
158 {
159 if (trans.Asset.Data.Length > 1)
160 {
161 byte[] newArray = new byte[trans.Asset.Data.Length + xferPacket.DataPacket.Data.Length];
162 Array.Copy(trans.Asset.Data, 0, newArray, 0, trans.Asset.Data.Length);
163 Array.Copy(xferPacket.DataPacket.Data, 0, newArray, trans.Asset.Data.Length, xferPacket.DataPacket.Data.Length);
164 trans.Asset.Data = newArray;
165 }
166 else
167 {
168 byte[] newArray = new byte[xferPacket.DataPacket.Data.Length - 4];
169 Array.Copy(xferPacket.DataPacket.Data, 4, newArray, 0, xferPacket.DataPacket.Data.Length - 4);
170 trans.Asset.Data = newArray;
171 }
172
173 if ((xferPacket.XferID.Packet & 2147483648) != 0)
174 {
175 //end of transfer
176 trans.UploadComplete = true;
177 AssetUploadCompletePacket response = new AssetUploadCompletePacket();
178 response.AssetBlock.Type = trans.Asset.Type;
179 response.AssetBlock.Success = true;
180 response.AssetBlock.UUID = trans.TransactionID.Combine(this.ourClient.SecureSessionID);
181 this.ourClient.OutPacket(response);
182
183 m_assetCache.AddAsset(trans.Asset);
184 //check if we should add it to inventory
185 if (trans.AddToInventory)
186 {
187 // m_assetCache.AddAsset(trans.Asset);
188 m_inventoryCache.AddNewInventoryItem(this.ourClient, trans.InventFolder, trans.Asset);
189 }
190
191
192 }
193 break;
194 }
195
196 }
197 }
198
199 ConfirmXferPacketPacket confirmXfer = new ConfirmXferPacketPacket();
200 confirmXfer.XferID.ID = xferPacket.XferID.ID;
201 confirmXfer.XferID.Packet = xferPacket.XferID.Packet;
202 this.ourClient.OutPacket(confirmXfer);
203 }
204
205 #endregion
206
207 public AssetBase AddUploadToAssetCache(LLUUID transactionID)
208 {
209 AssetBase asset = null;
210 if (this.transactions.ContainsKey(transactionID))
211 {
212 AssetTransaction trans = this.transactions[transactionID];
213 if (trans.UploadComplete)
214 {
215 m_assetCache.AddAsset(trans.Asset);
216 asset = trans.Asset;
217 }
218 }
219
220 return asset;
221 }
222
223 public void CreateInventoryItem(CreateInventoryItemPacket packet)
224 {
225 if (this.transactions.ContainsKey(packet.InventoryBlock.TransactionID))
226 {
227 AssetTransaction trans = this.transactions[packet.InventoryBlock.TransactionID];
228 trans.Asset.Description = Util.FieldToString(packet.InventoryBlock.Description);
229 trans.Asset.Name = Util.FieldToString(packet.InventoryBlock.Name);
230 trans.Asset.Type = packet.InventoryBlock.Type;
231 trans.Asset.InvType = packet.InventoryBlock.InvType;
232 if (trans.UploadComplete)
233 {
234 //already complete so we can add it to the inventory
235 //m_assetCache.AddAsset(trans.Asset);
236 m_inventoryCache.AddNewInventoryItem(this.ourClient, packet.InventoryBlock.FolderID, trans.Asset);
237 }
238 else
239 {
240 trans.AddToInventory = true;
241 trans.InventFolder = packet.InventoryBlock.FolderID;
242 }
243 }
244 }
245
246 private class AssetTransaction
247 {
248 public uint XferID;
249 public AssetBase Asset;
250 public bool AddToInventory;
251 public LLUUID InventFolder = LLUUID.Zero;
252 public bool UploadComplete = false;
253 public LLUUID TransactionID = LLUUID.Zero;
254
255 public AssetTransaction()
256 {
257
258 }
259 }
260 }
261 }
262}
diff --git a/OpenSim/OpenSim.RegionServer/ClientView/ClientView.Grid.cs b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.Grid.cs
new file mode 100644
index 0000000..ae4c066
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.Grid.cs
@@ -0,0 +1,59 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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*/
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using libsecondlife;
32using libsecondlife.Packets;
33using Nwc.XmlRpc;
34using System.Net;
35using System.Net.Sockets;
36using System.IO;
37using System.Threading;
38using System.Timers;
39using OpenSim.Framework.Interfaces;
40using OpenSim.Framework.Types;
41using OpenSim.Framework.Inventory;
42using OpenSim.Framework.Utilities;
43using OpenSim.Assets;
44
45namespace OpenSim
46{
47 public partial class ClientView
48 {
49
50 public void EnableNeighbours()
51 {
52
53 }
54
55 public void CrossSimBorder(LLVector3 avatarpos)
56 {
57 }
58 }
59}
diff --git a/OpenSim/OpenSim.RegionServer/ClientView/ClientView.PacketHandlers.cs b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.PacketHandlers.cs
new file mode 100644
index 0000000..d35868e
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.PacketHandlers.cs
@@ -0,0 +1,193 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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*/
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using libsecondlife;
32using libsecondlife.Packets;
33using Nwc.XmlRpc;
34using System.Net;
35using System.Net.Sockets;
36using System.IO;
37using System.Threading;
38using System.Timers;
39using OpenSim.Framework.Interfaces;
40using OpenSim.Framework.Types;
41using OpenSim.Framework.Inventory;
42using OpenSim.Framework.Utilities;
43using OpenSim.Assets;
44
45namespace OpenSim
46{
47 public partial class ClientView
48 {
49 protected virtual void RegisterLocalPacketHandlers()
50 {
51 this.AddLocalPacketHandler(PacketType.LogoutRequest, this.Logout);
52 this.AddLocalPacketHandler(PacketType.AgentCachedTexture, this.AgentTextureCached);
53 this.AddLocalPacketHandler(PacketType.MultipleObjectUpdate, this.MultipleObjUpdate);
54 }
55
56 protected virtual bool Logout(ClientView simClient, Packet packet)
57 {
58 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:ProcessInPacket() - Got a logout request");
59 //send reply to let the client logout
60 LogoutReplyPacket logReply = new LogoutReplyPacket();
61 logReply.AgentData.AgentID = this.AgentID;
62 logReply.AgentData.SessionID = this.SessionID;
63 logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1];
64 logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock();
65 logReply.InventoryData[0].ItemID = LLUUID.Zero;
66 OutPacket(logReply);
67 //tell all clients to kill our object
68 KillObjectPacket kill = new KillObjectPacket();
69 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
70 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
71 // kill.ObjectData[0].ID = this.ClientAvatar.localid;
72 foreach (ClientView client in m_clientThreads.Values)
73 {
74 client.OutPacket(kill);
75 }
76
77 this.m_inventoryCache.ClientLeaving(this.AgentID, null);
78
79
80 // m_gridServer.LogoutSession(this.SessionID, this.AgentID, this.CircuitCode);
81 /*lock (m_world.Entities)
82 {
83 m_world.Entities.Remove(this.AgentID);
84 }*/
85 // m_world.RemoveViewerAgent(this);
86 //need to do other cleaning up here too
87 m_clientThreads.Remove(this.CircuitCode);
88 m_networkServer.RemoveClientCircuit(this.CircuitCode);
89 this.ClientThread.Abort();
90 return true;
91 }
92
93 protected bool AgentTextureCached(ClientView simclient, Packet packet)
94 {
95 // Console.WriteLine(packet.ToString());
96 AgentCachedTexturePacket chechedtex = (AgentCachedTexturePacket)packet;
97 AgentCachedTextureResponsePacket cachedresp = new AgentCachedTextureResponsePacket();
98 cachedresp.AgentData.AgentID = this.AgentID;
99 cachedresp.AgentData.SessionID = this.SessionID;
100 cachedresp.AgentData.SerialNum = this.cachedtextureserial;
101 this.cachedtextureserial++;
102 cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[chechedtex.WearableData.Length];
103 for (int i = 0; i < chechedtex.WearableData.Length; i++)
104 {
105 cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
106 cachedresp.WearableData[i].TextureIndex = chechedtex.WearableData[i].TextureIndex;
107 cachedresp.WearableData[i].TextureID = LLUUID.Zero;
108 cachedresp.WearableData[i].HostName = new byte[0];
109 }
110 this.OutPacket(cachedresp);
111 return true;
112 }
113
114 protected bool MultipleObjUpdate(ClientView simClient, Packet packet)
115 {
116 MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet;
117 for (int i = 0; i < multipleupdate.ObjectData.Length; i++)
118 {
119 if (multipleupdate.ObjectData[i].Type == 9) //change position
120 {
121 if (OnUpdatePrimPosition != null)
122 {
123 libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0);
124 OnUpdatePrimPosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this);
125 }
126 //should update stored position of the prim
127 }
128 else if (multipleupdate.ObjectData[i].Type == 10)//rotation
129 {
130 if (OnUpdatePrimRotation != null)
131 {
132 libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true);
133 OnUpdatePrimRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this);
134 }
135 }
136 else if (multipleupdate.ObjectData[i].Type == 13)//scale
137 {
138 if (OnUpdatePrimScale != null)
139 {
140 libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12);
141 OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this);
142 }
143 }
144 }
145 return true;
146 }
147
148 public void RequestMapLayer() //should be getting the map layer from the grid server
149 {
150 //send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area)
151 MapLayerReplyPacket mapReply = new MapLayerReplyPacket();
152 mapReply.AgentData.AgentID = this.AgentID;
153 mapReply.AgentData.Flags = 0;
154 mapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1];
155 mapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock();
156 mapReply.LayerData[0].Bottom = 800;
157 mapReply.LayerData[0].Left = 800;
158 mapReply.LayerData[0].Top = 1200;
159 mapReply.LayerData[0].Right = 1200;
160 mapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-9999-000000000006");
161 this.OutPacket(mapReply);
162 }
163
164 public void RequestMapBlocks(int minX, int minY, int maxX, int maxY)
165 {
166 IList simMapProfiles = m_gridServer.RequestMapBlocks(minX, minY, maxX, maxY);
167 MapBlockReplyPacket mbReply = new MapBlockReplyPacket();
168 mbReply.AgentData.AgentID = this.AgentID;
169 int len;
170 if (simMapProfiles == null)
171 len = 0;
172 else
173 len = simMapProfiles.Count;
174
175 mbReply.Data = new MapBlockReplyPacket.DataBlock[len];
176 int iii;
177 for (iii = 0; iii < len; iii++)
178 {
179 Hashtable mp = (Hashtable)simMapProfiles[iii];
180 mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock();
181 mbReply.Data[iii].Name = System.Text.Encoding.UTF8.GetBytes((string)mp["name"]);
182 mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]);
183 mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]);
184 mbReply.Data[iii].MapImageID = new LLUUID((string)mp["map-image-id"]);
185 mbReply.Data[iii].RegionFlags = System.Convert.ToUInt32(mp["region-flags"]);
186 mbReply.Data[iii].WaterHeight = System.Convert.ToByte(mp["water-height"]);
187 mbReply.Data[iii].X = System.Convert.ToUInt16(mp["x"]);
188 mbReply.Data[iii].Y = System.Convert.ToUInt16(mp["y"]);
189 }
190 this.OutPacket(mbReply);
191 }
192 }
193}
diff --git a/OpenSim/OpenSim.RegionServer/ClientView/ClientView.ProcessPackets.cs b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.ProcessPackets.cs
new file mode 100644
index 0000000..b86d9e8
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.ProcessPackets.cs
@@ -0,0 +1,537 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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*/
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using libsecondlife;
32using libsecondlife.Packets;
33using Nwc.XmlRpc;
34using System.Net;
35using System.Net.Sockets;
36using System.IO;
37using System.Threading;
38using System.Timers;
39using OpenSim.Framework.Interfaces;
40using OpenSim.Framework.Types;
41using OpenSim.Framework.Inventory;
42using OpenSim.Framework.Utilities;
43using OpenSim.Assets;
44
45namespace OpenSim
46{
47 public partial class ClientView
48 {
49 protected override void ProcessInPacket(Packet Pack)
50 {
51 ack_pack(Pack);
52 if (debug)
53 {
54 if (Pack.Type != PacketType.AgentUpdate)
55 {
56 Console.WriteLine(Pack.Type.ToString());
57 }
58 }
59
60 if (this.ProcessPacketMethod(Pack))
61 {
62 //there is a handler registered that handled this packet type
63 return;
64 }
65 else
66 {
67 System.Text.Encoding _enc = System.Text.Encoding.ASCII;
68
69 switch (Pack.Type)
70 {
71 case PacketType.ViewerEffect:
72 ViewerEffectPacket viewer = (ViewerEffectPacket)Pack;
73 foreach (ClientView client in m_clientThreads.Values)
74 {
75 if (client.AgentID != this.AgentID)
76 {
77 viewer.AgentData.AgentID = client.AgentID;
78 viewer.AgentData.SessionID = client.SessionID;
79 client.OutPacket(viewer);
80 }
81 }
82 break;
83
84 #region New Event System - World/Avatar
85 case PacketType.ChatFromViewer:
86 ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack;
87 if (Util.FieldToString(inchatpack.ChatData.Message) == "")
88 {
89 //empty message so don't bother with it
90 break;
91 }
92 string fromName = ""; //ClientAvatar.firstname + " " + ClientAvatar.lastname;
93 byte[] message = inchatpack.ChatData.Message;
94 byte type = inchatpack.ChatData.Type;
95 LLVector3 fromPos = new LLVector3(); // ClientAvatar.Pos;
96 LLUUID fromAgentID = AgentID;
97 if (OnChatFromViewer != null)
98 {
99 this.OnChatFromViewer(message, type, fromPos, fromName, fromAgentID);
100 }
101 break;
102 case PacketType.RezObject:
103 RezObjectPacket rezPacket = (RezObjectPacket)Pack;
104 AgentInventory inven = this.m_inventoryCache.GetAgentsInventory(this.AgentID);
105 if (inven != null)
106 {
107 if (inven.InventoryItems.ContainsKey(rezPacket.InventoryData.ItemID))
108 {
109 AssetBase asset = this.m_assetCache.GetAsset(inven.InventoryItems[rezPacket.InventoryData.ItemID].AssetID);
110 if (asset != null)
111 {
112 if (OnRezObject != null)
113 {
114 this.OnRezObject(asset, rezPacket.RezData.RayEnd);
115 this.m_inventoryCache.DeleteInventoryItem(this, rezPacket.InventoryData.ItemID);
116 }
117 }
118 }
119 }
120 break;
121 case PacketType.DeRezObject:
122 if (OnDeRezObject != null)
123 {
124 OnDeRezObject(Pack, this);
125 }
126 break;
127 case PacketType.ModifyLand:
128 ModifyLandPacket modify = (ModifyLandPacket)Pack;
129 if (modify.ParcelData.Length > 0)
130 {
131 if (OnModifyTerrain != null)
132 {
133 OnModifyTerrain(modify.ModifyBlock.Action, modify.ParcelData[0].North, modify.ParcelData[0].West);
134 }
135 }
136 break;
137 case PacketType.RegionHandshakeReply:
138 if (OnRegionHandShakeReply != null)
139 {
140 OnRegionHandShakeReply(this);
141 }
142 break;
143 case PacketType.AgentWearablesRequest:
144 if (OnRequestWearables != null)
145 {
146 OnRequestWearables(this);
147 }
148 if (OnRequestAvatarsData != null)
149 {
150 OnRequestAvatarsData(this);
151 }
152 break;
153 case PacketType.AgentSetAppearance:
154 AgentSetAppearancePacket appear = (AgentSetAppearancePacket)Pack;
155 if (OnSetAppearance != null)
156 {
157 OnSetAppearance(appear.ObjectData.TextureEntry, appear.VisualParam);
158 }
159 break;
160 case PacketType.CompleteAgentMovement:
161 if (this.m_child) this.UpgradeClient();
162 if (OnCompleteMovementToRegion != null)
163 {
164 OnCompleteMovementToRegion();
165 }
166 this.EnableNeighbours();
167 break;
168 case PacketType.AgentUpdate:
169 if (OnAgentUpdate != null)
170 {
171 OnAgentUpdate(Pack);
172 }
173 break;
174 case PacketType.AgentAnimation:
175 if (!m_child)
176 {
177 AgentAnimationPacket AgentAni = (AgentAnimationPacket)Pack;
178 for (int i = 0; i < AgentAni.AnimationList.Length; i++)
179 {
180 if (AgentAni.AnimationList[i].StartAnim)
181 {
182 if (OnStartAnim != null)
183 {
184 OnStartAnim(AgentAni.AnimationList[i].AnimID, 1);
185 }
186 }
187 }
188 }
189 break;
190
191 #endregion
192
193 #region New Event System - Objects/Prims
194 case PacketType.ObjectLink:
195 // OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, Pack.ToString());
196 ObjectLinkPacket link = (ObjectLinkPacket)Pack;
197 uint parentprimid = 0;
198 List<uint> childrenprims = new List<uint>();
199 if (link.ObjectData.Length > 1)
200 {
201 parentprimid = link.ObjectData[0].ObjectLocalID;
202
203 for (int i = 1; i < link.ObjectData.Length; i++)
204 {
205 childrenprims.Add(link.ObjectData[i].ObjectLocalID);
206 }
207 }
208 if (OnLinkObjects != null)
209 {
210 OnLinkObjects(parentprimid, childrenprims);
211 }
212 break;
213 case PacketType.ObjectAdd:
214 // m_world.AddNewPrim((ObjectAddPacket)Pack, this);
215 if (OnAddPrim != null)
216 {
217 OnAddPrim(Pack, this);
218 }
219 break;
220 case PacketType.ObjectShape:
221 ObjectShapePacket shape = (ObjectShapePacket)Pack;
222 for (int i = 0; i < shape.ObjectData.Length; i++)
223 {
224 if (OnUpdatePrimShape != null)
225 {
226 OnUpdatePrimShape(shape.ObjectData[i].ObjectLocalID, shape.ObjectData[i]);
227 }
228 }
229 break;
230 case PacketType.ObjectSelect:
231 ObjectSelectPacket incomingselect = (ObjectSelectPacket)Pack;
232 for (int i = 0; i < incomingselect.ObjectData.Length; i++)
233 {
234 if (OnObjectSelect != null)
235 {
236 OnObjectSelect(incomingselect.ObjectData[i].ObjectLocalID, this);
237 }
238 }
239 break;
240 case PacketType.ObjectFlagUpdate:
241 ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket)Pack;
242 if (OnUpdatePrimFlags != null)
243 {
244 OnUpdatePrimFlags(flags.AgentData.ObjectLocalID, Pack, this);
245 }
246 break;
247 case PacketType.ObjectImage:
248 ObjectImagePacket imagePack = (ObjectImagePacket)Pack;
249 for (int i = 0; i < imagePack.ObjectData.Length; i++)
250 {
251 if (OnUpdatePrimTexture != null)
252 {
253 OnUpdatePrimTexture(imagePack.ObjectData[i].ObjectLocalID, imagePack.ObjectData[i].TextureEntry, this);
254 }
255 }
256 break;
257 #endregion
258
259 #region Inventory/Asset/Other related packets
260 case PacketType.RequestImage:
261 RequestImagePacket imageRequest = (RequestImagePacket)Pack;
262 for (int i = 0; i < imageRequest.RequestImage.Length; i++)
263 {
264 m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image);
265 }
266 break;
267 case PacketType.TransferRequest:
268 //Console.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request");
269 TransferRequestPacket transfer = (TransferRequestPacket)Pack;
270 m_assetCache.AddAssetRequest(this, transfer);
271 break;
272 case PacketType.AssetUploadRequest:
273 AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack;
274 this.UploadAssets.HandleUploadPacket(request, request.AssetBlock.TransactionID.Combine(this.SecureSessionID));
275 break;
276 case PacketType.RequestXfer:
277 //Console.WriteLine(Pack.ToString());
278 break;
279 case PacketType.SendXferPacket:
280 this.UploadAssets.HandleXferPacket((SendXferPacketPacket)Pack);
281 break;
282 case PacketType.CreateInventoryFolder:
283 CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket)Pack;
284 m_inventoryCache.CreateNewInventoryFolder(this, invFolder.FolderData.FolderID, (ushort)invFolder.FolderData.Type, Util.FieldToString(invFolder.FolderData.Name), invFolder.FolderData.ParentID);
285 //Console.WriteLine(Pack.ToString());
286 break;
287 case PacketType.CreateInventoryItem:
288 //Console.WriteLine(Pack.ToString());
289 CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack;
290 if (createItem.InventoryBlock.TransactionID != LLUUID.Zero)
291 {
292 this.UploadAssets.CreateInventoryItem(createItem);
293 }
294 else
295 {
296 // Console.Write(Pack.ToString());
297 this.CreateInventoryItem(createItem);
298 }
299 break;
300 case PacketType.FetchInventory:
301 //Console.WriteLine("fetch item packet");
302 FetchInventoryPacket FetchInventory = (FetchInventoryPacket)Pack;
303 m_inventoryCache.FetchInventory(this, FetchInventory);
304 break;
305 case PacketType.FetchInventoryDescendents:
306 FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket)Pack;
307 m_inventoryCache.FetchInventoryDescendents(this, Fetch);
308 break;
309 case PacketType.UpdateInventoryItem:
310 UpdateInventoryItemPacket update = (UpdateInventoryItemPacket)Pack;
311 //Console.WriteLine(Pack.ToString());
312 for (int i = 0; i < update.InventoryData.Length; i++)
313 {
314 if (update.InventoryData[i].TransactionID != LLUUID.Zero)
315 {
316 AssetBase asset = m_assetCache.GetAsset(update.InventoryData[i].TransactionID.Combine(this.SecureSessionID));
317 if (asset != null)
318 {
319 // Console.WriteLine("updating inventory item, found asset" + asset.FullID.ToStringHyphenated() + " already in cache");
320 m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset);
321 }
322 else
323 {
324 asset = this.UploadAssets.AddUploadToAssetCache(update.InventoryData[i].TransactionID);
325 if (asset != null)
326 {
327 //Console.WriteLine("updating inventory item, adding asset" + asset.FullID.ToStringHyphenated() + " to cache");
328 m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset);
329 }
330 else
331 {
332 //Console.WriteLine("trying to update inventory item, but asset is null");
333 }
334 }
335 }
336 else
337 {
338 m_inventoryCache.UpdateInventoryItemDetails(this, update.InventoryData[i].ItemID, update.InventoryData[i]); ;
339 }
340 }
341 break;
342 case PacketType.RequestTaskInventory:
343 // Console.WriteLine(Pack.ToString());
344 RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket)Pack;
345 ReplyTaskInventoryPacket replytask = new ReplyTaskInventoryPacket();
346 bool foundent = false;
347 /* foreach (Entity ent in m_world.Entities.Values)
348 {
349 if (ent.localid == requesttask.InventoryData.LocalID)
350 {
351 replytask.InventoryData.TaskID = ent.uuid;
352 replytask.InventoryData.Serial = 0;
353 replytask.InventoryData.Filename = new byte[0];
354 foundent = true;
355 }
356 }
357 if (foundent)
358 {
359 this.OutPacket(replytask);
360 }*/
361 break;
362 case PacketType.UpdateTaskInventory:
363 // Console.WriteLine(Pack.ToString());
364 UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket)Pack;
365 AgentInventory myinventory = this.m_inventoryCache.GetAgentsInventory(this.AgentID);
366 /*if (myinventory != null)
367 {
368 if (updatetask.UpdateData.Key == 0)
369 {
370 if (myinventory.InventoryItems[updatetask.InventoryData.ItemID] != null)
371 {
372 if (myinventory.InventoryItems[updatetask.InventoryData.ItemID].Type == 7)
373 {
374 LLUUID noteaid = myinventory.InventoryItems[updatetask.InventoryData.ItemID].AssetID;
375 AssetBase assBase = this.m_assetCache.GetAsset(noteaid);
376 if (assBase != null)
377 {
378 foreach (Entity ent in m_world.Entities.Values)
379 {
380 if (ent.localid == updatetask.UpdateData.LocalID)
381 {
382 if (ent is OpenSim.world.Primitive)
383 {
384 this.m_world.AddScript(ent, Util.FieldToString(assBase.Data));
385 }
386 }
387 }
388 }
389 }
390 }
391 }
392 }*/
393 break;
394 case PacketType.MapLayerRequest:
395 this.RequestMapLayer();
396 break;
397 case PacketType.MapBlockRequest:
398 MapBlockRequestPacket MapRequest = (MapBlockRequestPacket)Pack;
399
400 this.RequestMapBlocks(MapRequest.PositionData.MinX, MapRequest.PositionData.MinY, MapRequest.PositionData.MaxX, MapRequest.PositionData.MaxY);
401 break;
402 case PacketType.TeleportLandmarkRequest:
403 TeleportLandmarkRequestPacket tpReq = (TeleportLandmarkRequestPacket)Pack;
404
405 TeleportStartPacket tpStart = new TeleportStartPacket();
406 tpStart.Info.TeleportFlags = 8; // tp via lm
407 this.OutPacket(tpStart);
408
409 TeleportProgressPacket tpProgress = new TeleportProgressPacket();
410 tpProgress.Info.Message = (new System.Text.ASCIIEncoding()).GetBytes("sending_landmark");
411 tpProgress.Info.TeleportFlags = 8;
412 tpProgress.AgentData.AgentID = tpReq.Info.AgentID;
413 this.OutPacket(tpProgress);
414
415 // Fetch landmark
416 LLUUID lmid = tpReq.Info.LandmarkID;
417 AssetBase lma = this.m_assetCache.GetAsset(lmid);
418 if (lma != null)
419 {
420 AssetLandmark lm = new AssetLandmark(lma);
421
422 if (lm.RegionID == m_regionData.SimUUID)
423 {
424 TeleportLocalPacket tpLocal = new TeleportLocalPacket();
425
426 tpLocal.Info.AgentID = tpReq.Info.AgentID;
427 tpLocal.Info.TeleportFlags = 8; // Teleport via landmark
428 tpLocal.Info.LocationID = 2;
429 tpLocal.Info.Position = lm.Position;
430 OutPacket(tpLocal);
431 }
432 else
433 {
434 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
435 tpCancel.Info.AgentID = tpReq.Info.AgentID;
436 tpCancel.Info.SessionID = tpReq.Info.SessionID;
437 OutPacket(tpCancel);
438 }
439 }
440 else
441 {
442 Console.WriteLine("Cancelling Teleport - fetch asset not yet implemented");
443
444 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
445 tpCancel.Info.AgentID = tpReq.Info.AgentID;
446 tpCancel.Info.SessionID = tpReq.Info.SessionID;
447 OutPacket(tpCancel);
448 }
449 break;
450 case PacketType.TeleportLocationRequest:
451 TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack;
452 Console.WriteLine(tpLocReq.ToString());
453
454 tpStart = new TeleportStartPacket();
455 tpStart.Info.TeleportFlags = 16; // Teleport via location
456 Console.WriteLine(tpStart.ToString());
457 OutPacket(tpStart);
458
459 if (m_regionData.RegionHandle != tpLocReq.Info.RegionHandle)
460 {
461 /* m_gridServer.getRegion(tpLocReq.Info.RegionHandle); */
462 Console.WriteLine("Inter-sim teleport not yet implemented");
463 TeleportCancelPacket tpCancel = new TeleportCancelPacket();
464 tpCancel.Info.SessionID = tpLocReq.AgentData.SessionID;
465 tpCancel.Info.AgentID = tpLocReq.AgentData.AgentID;
466
467 OutPacket(tpCancel);
468 }
469 else
470 {
471 Console.WriteLine("Local teleport");
472 TeleportLocalPacket tpLocal = new TeleportLocalPacket();
473 tpLocal.Info.AgentID = tpLocReq.AgentData.AgentID;
474 tpLocal.Info.TeleportFlags = tpStart.Info.TeleportFlags;
475 tpLocal.Info.LocationID = 2;
476 tpLocal.Info.LookAt = tpLocReq.Info.LookAt;
477 tpLocal.Info.Position = tpLocReq.Info.Position;
478 OutPacket(tpLocal);
479
480 }
481 break;
482 #endregion
483
484 #region Parcel related packets
485 case PacketType.ParcelPropertiesRequest:
486 ParcelPropertiesRequestPacket propertiesRequest = (ParcelPropertiesRequestPacket)Pack;
487 if(OnParcelPropertiesRequest != null)
488 {
489 OnParcelPropertiesRequest((int)Math.Round(propertiesRequest.ParcelData.West), (int)Math.Round(propertiesRequest.ParcelData.South), (int)Math.Round(propertiesRequest.ParcelData.East), (int)Math.Round(propertiesRequest.ParcelData.North), propertiesRequest.ParcelData.SequenceID, propertiesRequest.ParcelData.SnapSelection, this);
490 }
491 break;
492 case PacketType.ParcelDivide:
493 ParcelDividePacket parcelDivide = (ParcelDividePacket)Pack;
494 if (OnParcelDivideRequest != null)
495 {
496 OnParcelDivideRequest((int)Math.Round(parcelDivide.ParcelData.West), (int)Math.Round(parcelDivide.ParcelData.South), (int)Math.Round(parcelDivide.ParcelData.East), (int)Math.Round(parcelDivide.ParcelData.North), this);
497 }
498 break;
499 case PacketType.ParcelJoin:
500 ParcelJoinPacket parcelJoin = (ParcelJoinPacket)Pack;
501 if (OnParcelJoinRequest != null)
502 {
503 OnParcelJoinRequest((int)Math.Round(parcelJoin.ParcelData.West), (int)Math.Round(parcelJoin.ParcelData.South), (int)Math.Round(parcelJoin.ParcelData.East), (int)Math.Round(parcelJoin.ParcelData.North), this);
504 }
505 break;
506 case PacketType.ParcelPropertiesUpdate:
507 ParcelPropertiesUpdatePacket updatePacket = (ParcelPropertiesUpdatePacket)Pack;
508 if (OnParcelPropertiesUpdateRequest != null)
509 {
510 OnParcelPropertiesUpdateRequest(updatePacket, this);
511 }
512 break;
513 #endregion
514
515 #region Estate Packets
516 case PacketType.EstateOwnerMessage:
517 EstateOwnerMessagePacket messagePacket = (EstateOwnerMessagePacket)Pack;
518 if (OnEstateOwnerMessage != null)
519 {
520 OnEstateOwnerMessage(messagePacket, this);
521 }
522 break;
523 #endregion
524 #region unimplemented handlers
525 case PacketType.AgentIsNowWearing:
526 // AgentIsNowWearingPacket wear = (AgentIsNowWearingPacket)Pack;
527 //Console.WriteLine(Pack.ToString());
528 break;
529 case PacketType.ObjectScale:
530 //OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, Pack.ToString());
531 break;
532 #endregion
533 }
534 }
535 }
536 }
537}
diff --git a/OpenSim/OpenSim.RegionServer/ClientView/ClientView.cs b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.cs
new file mode 100644
index 0000000..0693f70
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/ClientView/ClientView.cs
@@ -0,0 +1,292 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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*/
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using libsecondlife;
32using libsecondlife.Packets;
33using Nwc.XmlRpc;
34using System.Net;
35using System.Net.Sockets;
36using System.IO;
37using System.Threading;
38using System.Timers;
39using OpenSim.Framework;
40using OpenSim.Framework.Interfaces;
41using OpenSim.Framework.Types;
42using OpenSim.Framework.Inventory;
43using OpenSim.Framework.Utilities;
44using OpenSim.Assets;
45
46namespace OpenSim
47{
48 public delegate bool PacketMethod(ClientView simClient, Packet packet);
49
50 /// <summary>
51 /// Handles new client connections
52 /// Constructor takes a single Packet and authenticates everything
53 /// </summary>
54 public partial class ClientView : ClientViewBase, IClientAPI
55 {
56 public static TerrainManager TerrainManager;
57
58 protected static Dictionary<PacketType, PacketMethod> PacketHandlers = new Dictionary<PacketType, PacketMethod>(); //Global/static handlers for all clients
59 protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>(); //local handlers for this instance
60
61 public LLUUID AgentID;
62 public LLUUID SessionID;
63 public LLUUID SecureSessionID = LLUUID.Zero;
64 public string firstName;
65 public string lastName;
66 public bool m_child = false;
67 private UseCircuitCodePacket cirpack;
68 public Thread ClientThread;
69 public LLVector3 startpos;
70
71 private AgentAssetUpload UploadAssets;
72 private LLUUID newAssetFolder = LLUUID.Zero;
73 private bool debug = false;
74 protected IWorld m_world;
75 private Dictionary<uint, ClientView> m_clientThreads;
76 private AssetCache m_assetCache;
77 private IGridServer m_gridServer;
78 private InventoryCache m_inventoryCache;
79 private int cachedtextureserial = 0;
80 private RegionInfo m_regionData;
81 protected AuthenticateSessionsBase m_authenticateSessionsHandler;
82
83 public ClientView(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, Dictionary<uint, ClientView> clientThreads, IWorld world, AssetCache assetCache, PacketServer packServer, InventoryCache inventoryCache, AuthenticateSessionsBase authenSessions )
84 {
85 m_world = world;
86 m_clientThreads = clientThreads;
87 m_assetCache = assetCache;
88
89 m_networkServer = packServer;
90 m_inventoryCache = inventoryCache;
91 m_authenticateSessionsHandler = authenSessions;
92
93 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs - Started up new client thread to handle incoming request");
94 cirpack = initialcirpack;
95 userEP = remoteEP;
96
97 this.m_child = m_authenticateSessionsHandler.GetAgentChildStatus(initialcirpack.CircuitCode.Code);
98 this.startpos = m_authenticateSessionsHandler.GetPosition(initialcirpack.CircuitCode.Code);
99
100 PacketQueue = new BlockingQueue<QueItem>();
101
102 this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache);
103 AckTimer = new System.Timers.Timer(500);
104 AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
105 AckTimer.Start();
106
107 this.RegisterLocalPacketHandlers();
108
109 ClientThread = new Thread(new ThreadStart(AuthUser));
110 ClientThread.IsBackground = true;
111 ClientThread.Start();
112 }
113
114 # region Client Methods
115 public void UpgradeClient()
116 {
117 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "SimClient.cs:UpgradeClient() - upgrading child to full agent");
118 this.m_child = false;
119 this.startpos = m_authenticateSessionsHandler.GetPosition(CircuitCode);
120 m_authenticateSessionsHandler.UpdateAgentChildStatus(CircuitCode, false);
121 OnChildAgentStatus(this.m_child);
122 }
123
124 public void DowngradeClient()
125 {
126 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "SimClient.cs:UpgradeClient() - changing full agent to child");
127 this.m_child = true;
128 OnChildAgentStatus(this.m_child);
129
130 }
131
132 public void KillClient()
133 {
134 KillObjectPacket kill = new KillObjectPacket();
135 kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1];
136 kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock();
137 //kill.ObjectData[0].ID = this.ClientAvatar.localid;
138 foreach (ClientView client in m_clientThreads.Values)
139 {
140 client.OutPacket(kill);
141 }
142
143 this.m_inventoryCache.ClientLeaving(this.AgentID, null);
144
145
146 // m_world.RemoveViewerAgent(this);
147
148 m_clientThreads.Remove(this.CircuitCode);
149 m_networkServer.RemoveClientCircuit(this.CircuitCode);
150 this.ClientThread.Abort();
151 }
152 #endregion
153
154 # region Packet Handling
155 public static bool AddPacketHandler(PacketType packetType, PacketMethod handler)
156 {
157 bool result = false;
158 lock (PacketHandlers)
159 {
160 if (!PacketHandlers.ContainsKey(packetType))
161 {
162 PacketHandlers.Add(packetType, handler);
163 result = true;
164 }
165 }
166 return result;
167 }
168
169 public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler)
170 {
171 bool result = false;
172 lock (m_packetHandlers)
173 {
174 if (!m_packetHandlers.ContainsKey(packetType))
175 {
176 m_packetHandlers.Add(packetType, handler);
177 result = true;
178 }
179 }
180 return result;
181 }
182
183 protected virtual bool ProcessPacketMethod(Packet packet)
184 {
185 bool result = false;
186 bool found = false;
187 PacketMethod method;
188 if (m_packetHandlers.TryGetValue(packet.Type, out method))
189 {
190 //there is a local handler for this packet type
191 result = method(this, packet);
192 }
193 else
194 {
195 //there is not a local handler so see if there is a Global handler
196 lock (PacketHandlers)
197 {
198 found = PacketHandlers.TryGetValue(packet.Type, out method);
199 }
200 if (found)
201 {
202 result = method(this, packet);
203 }
204 }
205 return result;
206 }
207
208 protected virtual void ClientLoop()
209 {
210 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:ClientLoop() - Entered loop");
211 while (true)
212 {
213 QueItem nextPacket = PacketQueue.Dequeue();
214 if (nextPacket.Incoming)
215 {
216 //is a incoming packet
217 ProcessInPacket(nextPacket.Packet);
218 }
219 else
220 {
221 //is a out going packet
222 ProcessOutPacket(nextPacket.Packet);
223 }
224 }
225 }
226 # endregion
227
228 # region Setup
229
230 protected virtual void InitNewClient()
231 {
232 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:InitNewClient() - Adding viewer agent to world");
233 this.m_world.AddNewAvatar(this, this.AgentID, false);
234 }
235
236 protected virtual void AuthUser()
237 {
238 // AuthenticateResponse sessionInfo = m_gridServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code);
239 AuthenticateResponse sessionInfo = this.m_authenticateSessionsHandler.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code);
240 if (!sessionInfo.Authorised)
241 {
242 //session/circuit not authorised
243 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.NORMAL, "OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString());
244 ClientThread.Abort();
245 }
246 else
247 {
248 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.NORMAL, "OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString());
249 //session is authorised
250 this.AgentID = cirpack.CircuitCode.ID;
251 this.SessionID = cirpack.CircuitCode.SessionID;
252 this.CircuitCode = cirpack.CircuitCode.Code;
253 this.firstName = sessionInfo.LoginInfo.First;
254 this.lastName = sessionInfo.LoginInfo.Last;
255
256 if (sessionInfo.LoginInfo.SecureSession != LLUUID.Zero)
257 {
258 this.SecureSessionID = sessionInfo.LoginInfo.SecureSession;
259 }
260 InitNewClient();
261
262 ClientLoop();
263 }
264 }
265 # endregion
266
267
268 protected override void KillThread()
269 {
270 this.ClientThread.Abort();
271 }
272
273 #region Inventory Creation
274 private void SetupInventory(AuthenticateResponse sessionInfo)
275 {
276
277 }
278 private AgentInventory CreateInventory(LLUUID baseFolder)
279 {
280 AgentInventory inventory = null;
281
282 return inventory;
283 }
284
285 private void CreateInventoryItem(CreateInventoryItemPacket packet)
286 {
287
288 }
289 #endregion
290
291 }
292}
diff --git a/OpenSim/OpenSim.RegionServer/ClientView/ClientViewBase.cs b/OpenSim/OpenSim.RegionServer/ClientView/ClientViewBase.cs
new file mode 100644
index 0000000..facb3fa
--- /dev/null
+++ b/OpenSim/OpenSim.RegionServer/ClientView/ClientViewBase.cs
@@ -0,0 +1,327 @@
1
2/*
3* Copyright (c) Contributors, http://www.openmetaverse.org/
4* See CONTRIBUTORS.TXT for a full list of copyright holders.
5*
6* Redistribution and use in source and binary forms, with or without
7* modification, are permitted provided that the following conditions are met:
8* * Redistributions of source code must retain the above copyright
9* notice, this list of conditions and the following disclaimer.
10* * Redistributions in binary form must reproduce the above copyright
11* notice, this list of conditions and the following disclaimer in the
12* documentation and/or other materials provided with the distribution.
13* * Neither the name of the OpenSim Project nor the
14* names of its contributors may be used to endorse or promote products
15* derived from this software without specific prior written permission.
16*
17* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
18* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
21* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*
28*/
29using System;
30using System.Collections;
31using System.Collections.Generic;
32using libsecondlife;
33using libsecondlife.Packets;
34using System.Net;
35using System.Net.Sockets;
36using System.IO;
37using System.Threading;
38using System.Timers;
39using OpenSim.Framework.Utilities;
40using OpenSim.Framework.Interfaces;
41
42namespace OpenSim
43{
44 public class ClientViewBase
45 {
46 protected BlockingQueue<QueItem> PacketQueue;
47 protected Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
48 protected Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
49
50 protected System.Timers.Timer AckTimer;
51 protected uint Sequence = 0;
52 protected object SequenceLock = new object();
53 protected const int MAX_APPENDED_ACKS = 10;
54 protected const int RESEND_TIMEOUT = 4000;
55 protected const int MAX_SEQUENCE = 0xFFFFFF;
56
57 public uint CircuitCode;
58 public EndPoint userEP;
59
60 protected PacketServer m_networkServer;
61
62 public ClientViewBase()
63 {
64
65 }
66
67 protected virtual void ProcessInPacket(Packet Pack)
68 {
69
70 }
71
72 protected virtual void ProcessOutPacket(Packet Pack)
73 {
74 // Keep track of when this packet was sent out
75 Pack.TickCount = Environment.TickCount;
76
77 if (!Pack.Header.Resent)
78 {
79 // Set the sequence number
80 lock (SequenceLock)
81 {
82 if (Sequence >= MAX_SEQUENCE)
83 Sequence = 1;
84 else
85 Sequence++;
86 Pack.Header.Sequence = Sequence;
87 }
88
89 if (Pack.Header.Reliable) //DIRTY HACK
90 {
91 lock (NeedAck)
92 {
93 if (!NeedAck.ContainsKey(Pack.Header.Sequence))
94 {
95 try
96 {
97 NeedAck.Add(Pack.Header.Sequence, Pack);
98 }
99 catch (Exception e) // HACKY
100 {
101 e.ToString();
102 // Ignore
103 // Seems to throw a exception here occasionally
104 // of 'duplicate key' despite being locked.
105 // !?!?!?
106 }
107 }
108 else
109 {
110 // Client.Log("Attempted to add a duplicate sequence number (" +
111 // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
112 // packet.Type.ToString(), Helpers.LogLevel.Warning);
113 }
114 }
115
116 // Don't append ACKs to resent packets, in case that's what was causing the
117 // delivery to fail
118 if (!Pack.Header.Resent)
119 {
120 // Append any ACKs that need to be sent out to this packet
121 lock (PendingAcks)
122 {
123 if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS &&
124 Pack.Type != PacketType.PacketAck &&
125 Pack.Type != PacketType.LogoutRequest)
126 {
127 Pack.Header.AckList = new uint[PendingAcks.Count];
128 int i = 0;
129
130 foreach (uint ack in PendingAcks.Values)
131 {
132 Pack.Header.AckList[i] = ack;
133 i++;
134 }
135
136 PendingAcks.Clear();
137 Pack.Header.AppendedAcks = true;
138 }
139 }
140 }
141 }
142 }
143
144 byte[] ZeroOutBuffer = new byte[4096];
145 byte[] sendbuffer;
146 sendbuffer = Pack.ToBytes();
147
148 try
149 {
150 if (Pack.Header.Zerocoded)
151 {
152 int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
153 m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP);
154 }
155 else
156 {
157 m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP);
158 }
159 }
160 catch (Exception)
161 {
162 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread");
163 this.KillThread();
164 }
165
166 }
167
168 public virtual void InPacket(Packet NewPack)
169 {
170 // Handle appended ACKs
171 if (NewPack.Header.AppendedAcks)
172 {
173 lock (NeedAck)
174 {
175 foreach (uint ack in NewPack.Header.AckList)
176 {
177 NeedAck.Remove(ack);
178 }
179 }
180 }
181
182 // Handle PacketAck packets
183 if (NewPack.Type == PacketType.PacketAck)
184 {
185 PacketAckPacket ackPacket = (PacketAckPacket)NewPack;
186
187 lock (NeedAck)
188 {
189 foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
190 {
191 NeedAck.Remove(block.ID);
192 }
193 }
194 }
195 else if ((NewPack.Type == PacketType.StartPingCheck))
196 {
197 //reply to pingcheck
198 libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack;
199 libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket();
200 endPing.PingID.PingID = startPing.PingID.PingID;
201 OutPacket(endPing);
202 }
203 else
204 {
205 QueItem item = new QueItem();
206 item.Packet = NewPack;
207 item.Incoming = true;
208 this.PacketQueue.Enqueue(item);
209 }
210
211 }
212
213 public virtual void OutPacket(Packet NewPack)
214 {
215 QueItem item = new QueItem();
216 item.Packet = NewPack;
217 item.Incoming = false;
218 this.PacketQueue.Enqueue(item);
219 }
220
221 # region Low Level Packet Methods
222
223 protected void ack_pack(Packet Pack)
224 {
225 if (Pack.Header.Reliable)
226 {
227 libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket();
228 ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
229 ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
230 ack_it.Packets[0].ID = Pack.Header.Sequence;
231 ack_it.Header.Reliable = false;
232
233 OutPacket(ack_it);
234
235 }
236 /*
237 if (Pack.Header.Reliable)
238 {
239 lock (PendingAcks)
240 {
241 uint sequence = (uint)Pack.Header.Sequence;
242 if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
243 }
244 }*/
245 }
246
247 protected void ResendUnacked()
248 {
249 int now = Environment.TickCount;
250
251 lock (NeedAck)
252 {
253 foreach (Packet packet in NeedAck.Values)
254 {
255 if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent))
256 {
257 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.VERBOSE, "Resending " + packet.Type.ToString() + " packet, " +
258 (now - packet.TickCount) + "ms have passed");
259
260 packet.Header.Resent = true;
261 OutPacket(packet);
262 }
263 }
264 }
265 }
266
267 protected void SendAcks()
268 {
269 lock (PendingAcks)
270 {
271 if (PendingAcks.Count > 0)
272 {
273 if (PendingAcks.Count > 250)
274 {
275 // FIXME: Handle the odd case where we have too many pending ACKs queued up
276 OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.VERBOSE, "Too many ACKs queued up!");
277 return;
278 }
279
280 //OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Sending PacketAck");
281
282
283 int i = 0;
284 PacketAckPacket acks = new PacketAckPacket();
285 acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];
286
287 foreach (uint ack in PendingAcks.Values)
288 {
289 acks.Packets[i] = new PacketAckPacket.PacketsBlock();
290 acks.Packets[i].ID = ack;
291 i++;
292 }
293
294 acks.Header.Reliable = false;
295 OutPacket(acks);
296
297 PendingAcks.Clear();
298 }
299 }
300 }
301
302 protected void AckTimer_Elapsed(object sender, ElapsedEventArgs ea)
303 {
304 SendAcks();
305 ResendUnacked();
306 }
307 #endregion
308
309 protected virtual void KillThread()
310 {
311
312 }
313
314 #region Nested Classes
315
316 public class QueItem
317 {
318 public QueItem()
319 {
320 }
321
322 public Packet Packet;
323 public bool Incoming;
324 }
325 #endregion
326 }
327}