aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs1151
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs55
2 files changed, 513 insertions, 693 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 43c3c7c..1c463ea 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -295,6 +295,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
295 public event MuteListRequest OnMuteListRequest; 295 public event MuteListRequest OnMuteListRequest;
296 public event AvatarInterestUpdate OnAvatarInterestUpdate; 296 public event AvatarInterestUpdate OnAvatarInterestUpdate;
297 public event PlacesQuery OnPlacesQuery; 297 public event PlacesQuery OnPlacesQuery;
298 public event AgentFOV OnAgentFOV;
298 299
299 #endregion Events 300 #endregion Events
300 301
@@ -341,11 +342,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
341 protected Thread m_clientThread; 342 protected Thread m_clientThread;
342 protected Vector3 m_startpos; 343 protected Vector3 m_startpos;
343 protected EndPoint m_userEndPoint; 344 protected EndPoint m_userEndPoint;
344 protected UUID m_activeGroupID = UUID.Zero; 345 protected UUID m_activeGroupID;
345 protected string m_activeGroupName = String.Empty; 346 protected string m_activeGroupName = String.Empty;
346 protected ulong m_activeGroupPowers; 347 protected ulong m_activeGroupPowers;
347 protected Dictionary<UUID,ulong> m_groupPowers = new Dictionary<UUID, ulong>(); 348 protected Dictionary<UUID,ulong> m_groupPowers = new Dictionary<UUID, ulong>();
348 protected int m_terrainCheckerCount; 349 protected int m_terrainCheckerCount;
350 protected uint m_agentFOVCounter;
349 351
350 // These numbers are guesses at a decent tradeoff between responsiveness 352 // These numbers are guesses at a decent tradeoff between responsiveness
351 // of the interest list and throughput. Lower is more responsive, higher 353 // of the interest list and throughput. Lower is more responsive, higher
@@ -420,7 +422,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
420 m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>(); 422 m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>();
421 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); 423 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
422 m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>()); 424 m_imageManager = new LLImageManager(this, m_assetService, Scene.RequestModuleInterface<IJ2KDecoder>());
423 m_channelVersion = Utils.StringToBytes(scene.GetSimulatorVersion()); 425 m_channelVersion = Util.StringToBytes256(scene.GetSimulatorVersion());
424 m_agentId = agentId; 426 m_agentId = agentId;
425 m_sessionId = sessionId; 427 m_sessionId = sessionId;
426 m_secureSessionId = sessionInfo.LoginInfo.SecureSession; 428 m_secureSessionId = sessionInfo.LoginInfo.SecureSession;
@@ -496,7 +498,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
496 kupack.UserInfo.SessionID = SessionId; 498 kupack.UserInfo.SessionID = SessionId;
497 kupack.TargetBlock.TargetIP = 0; 499 kupack.TargetBlock.TargetIP = 0;
498 kupack.TargetBlock.TargetPort = 0; 500 kupack.TargetBlock.TargetPort = 0;
499 kupack.UserInfo.Reason = Utils.StringToBytes(message); 501 kupack.UserInfo.Reason = Util.StringToBytes256(message);
500 OutPacket(kupack, ThrottleOutPacketType.Task); 502 OutPacket(kupack, ThrottleOutPacketType.Task);
501 // You must sleep here or users get no message! 503 // You must sleep here or users get no message!
502 Thread.Sleep(500); 504 Thread.Sleep(500);
@@ -641,7 +643,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
641 handshake.RegionInfo.WaterHeight = args.waterHeight; 643 handshake.RegionInfo.WaterHeight = args.waterHeight;
642 644
643 handshake.RegionInfo.RegionFlags = args.regionFlags; 645 handshake.RegionInfo.RegionFlags = args.regionFlags;
644 handshake.RegionInfo.SimName = Utils.StringToBytes(args.regionName); 646 handshake.RegionInfo.SimName = Util.StringToBytes256(args.regionName);
645 handshake.RegionInfo.SimOwner = args.SimOwner; 647 handshake.RegionInfo.SimOwner = args.SimOwner;
646 handshake.RegionInfo.TerrainBase0 = args.terrainBase0; 648 handshake.RegionInfo.TerrainBase0 = args.terrainBase0;
647 handshake.RegionInfo.TerrainBase1 = args.terrainBase1; 649 handshake.RegionInfo.TerrainBase1 = args.terrainBase1;
@@ -697,11 +699,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
697 { 699 {
698 ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator); 700 ChatFromSimulatorPacket reply = (ChatFromSimulatorPacket)PacketPool.Instance.GetPacket(PacketType.ChatFromSimulator);
699 reply.ChatData.Audible = audible; 701 reply.ChatData.Audible = audible;
700 reply.ChatData.Message = Utils.StringToBytes(message); 702 reply.ChatData.Message = Util.StringToBytes1024(message);
701 reply.ChatData.ChatType = type; 703 reply.ChatData.ChatType = type;
702 reply.ChatData.SourceType = source; 704 reply.ChatData.SourceType = source;
703 reply.ChatData.Position = fromPos; 705 reply.ChatData.Position = fromPos;
704 reply.ChatData.FromName = Utils.StringToBytes(fromName); 706 reply.ChatData.FromName = Util.StringToBytes256(fromName);
705 reply.ChatData.OwnerID = fromAgentID; 707 reply.ChatData.OwnerID = fromAgentID;
706 reply.ChatData.SourceID = fromAgentID; 708 reply.ChatData.SourceID = fromAgentID;
707 709
@@ -722,7 +724,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
722 724
723 msg.AgentData.AgentID = new UUID(im.fromAgentID); 725 msg.AgentData.AgentID = new UUID(im.fromAgentID);
724 msg.AgentData.SessionID = UUID.Zero; 726 msg.AgentData.SessionID = UUID.Zero;
725 msg.MessageBlock.FromAgentName = Utils.StringToBytes(im.fromAgentName); 727 msg.MessageBlock.FromAgentName = Util.StringToBytes256(im.fromAgentName);
726 msg.MessageBlock.Dialog = im.dialog; 728 msg.MessageBlock.Dialog = im.dialog;
727 msg.MessageBlock.FromGroup = im.fromGroup; 729 msg.MessageBlock.FromGroup = im.fromGroup;
728 if (im.imSessionID == UUID.Zero.Guid) 730 if (im.imSessionID == UUID.Zero.Guid)
@@ -735,12 +737,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
735 msg.MessageBlock.RegionID = new UUID(im.RegionID); 737 msg.MessageBlock.RegionID = new UUID(im.RegionID);
736 msg.MessageBlock.Timestamp = im.timestamp; 738 msg.MessageBlock.Timestamp = im.timestamp;
737 msg.MessageBlock.ToAgentID = new UUID(im.toAgentID); 739 msg.MessageBlock.ToAgentID = new UUID(im.toAgentID);
738 // Cap the message length at 1099. There is a limit in ImprovedInstantMessagePacket 740 msg.MessageBlock.Message = Util.StringToBytes1024(im.message);
739 // the limit is 1100 but a 0 byte gets added to mark the end of the string
740 if (im.message != null && im.message.Length > 1099)
741 msg.MessageBlock.Message = Utils.StringToBytes(im.message.Substring(0, 1099));
742 else
743 msg.MessageBlock.Message = Utils.StringToBytes(im.message);
744 msg.MessageBlock.BinaryBucket = im.binaryBucket; 741 msg.MessageBlock.BinaryBucket = im.binaryBucket;
745 742
746 if (im.message.StartsWith("[grouptest]")) 743 if (im.message.StartsWith("[grouptest]"))
@@ -758,7 +755,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
758 eq.ChatterboxInvitation( 755 eq.ChatterboxInvitation(
759 new UUID("00000000-68f9-1111-024e-222222111123"), 756 new UUID("00000000-68f9-1111-024e-222222111123"),
760 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0, 757 "OpenSimulator Testing", new UUID(im.fromAgentID), im.message, new UUID(im.toAgentID), im.fromAgentName, im.dialog, 0,
761 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Utils.StringToBytes("OpenSimulator Testing")); 758 false, 0, new Vector3(), 1, new UUID(im.imSessionID), im.fromGroup, Util.StringToBytes256("OpenSimulator Testing"));
762 759
763 eq.ChatterBoxSessionAgentListUpdates( 760 eq.ChatterBoxSessionAgentListUpdates(
764 new UUID("00000000-68f9-1111-024e-222222111123"), 761 new UUID("00000000-68f9-1111-024e-222222111123"),
@@ -775,13 +772,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
775 public void SendGenericMessage(string method, List<string> message) 772 public void SendGenericMessage(string method, List<string> message)
776 { 773 {
777 GenericMessagePacket gmp = new GenericMessagePacket(); 774 GenericMessagePacket gmp = new GenericMessagePacket();
778 gmp.MethodData.Method = Utils.StringToBytes(method); 775 gmp.MethodData.Method = Util.StringToBytes256(method);
779 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count]; 776 gmp.ParamList = new GenericMessagePacket.ParamListBlock[message.Count];
780 int i = 0; 777 int i = 0;
781 foreach (string val in message) 778 foreach (string val in message)
782 { 779 {
783 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock(); 780 gmp.ParamList[i] = new GenericMessagePacket.ParamListBlock();
784 gmp.ParamList[i++].Parameter = Utils.StringToBytes(val); 781 gmp.ParamList[i++].Parameter = Util.StringToBytes256(val);
785 } 782 }
786 OutPacket(gmp, ThrottleOutPacketType.Task); 783 OutPacket(gmp, ThrottleOutPacketType.Task);
787 } 784 }
@@ -1045,7 +1042,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1045 newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8; 1042 newSimPack.RegionData.SimIP += (uint)byteIP[1] << 8;
1046 newSimPack.RegionData.SimIP += (uint)byteIP[0]; 1043 newSimPack.RegionData.SimIP += (uint)byteIP[0];
1047 newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port; 1044 newSimPack.RegionData.SimPort = (ushort)externalIPEndPoint.Port;
1048 newSimPack.RegionData.SeedCapability = Utils.StringToBytes(capsURL); 1045 newSimPack.RegionData.SeedCapability = Util.StringToBytes256(capsURL);
1049 1046
1050 // Hack to get this out immediately and skip throttles 1047 // Hack to get this out immediately and skip throttles
1051 OutPacket(newSimPack, ThrottleOutPacketType.Unknown); 1048 OutPacket(newSimPack, ThrottleOutPacketType.Unknown);
@@ -1123,7 +1120,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1123 teleport.Info.RegionHandle = regionHandle; 1120 teleport.Info.RegionHandle = regionHandle;
1124 teleport.Info.SimAccess = simAccess; 1121 teleport.Info.SimAccess = simAccess;
1125 1122
1126 teleport.Info.SeedCapability = Utils.StringToBytes(capsURL); 1123 teleport.Info.SeedCapability = Util.StringToBytes256(capsURL);
1127 1124
1128 IPAddress oIP = newRegionEndPoint.Address; 1125 IPAddress oIP = newRegionEndPoint.Address;
1129 byte[] byteIP = oIP.GetAddressBytes(); 1126 byte[] byteIP = oIP.GetAddressBytes();
@@ -1148,7 +1145,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1148 { 1145 {
1149 TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed); 1146 TeleportFailedPacket tpFailed = (TeleportFailedPacket)PacketPool.Instance.GetPacket(PacketType.TeleportFailed);
1150 tpFailed.Info.AgentID = AgentId; 1147 tpFailed.Info.AgentID = AgentId;
1151 tpFailed.Info.Reason = Utils.StringToBytes(reason); 1148 tpFailed.Info.Reason = Util.StringToBytes256(reason);
1152 tpFailed.AlertInfo = new TeleportFailedPacket.AlertInfoBlock[0]; 1149 tpFailed.AlertInfo = new TeleportFailedPacket.AlertInfoBlock[0];
1153 1150
1154 // Hack to get this out immediately and skip throttles 1151 // Hack to get this out immediately and skip throttles
@@ -1880,11 +1877,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1880 AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate); 1877 AgentDataUpdatePacket sendAgentDataUpdate = (AgentDataUpdatePacket)PacketPool.Instance.GetPacket(PacketType.AgentDataUpdate);
1881 sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid; 1878 sendAgentDataUpdate.AgentData.ActiveGroupID = activegroupid;
1882 sendAgentDataUpdate.AgentData.AgentID = agentid; 1879 sendAgentDataUpdate.AgentData.AgentID = agentid;
1883 sendAgentDataUpdate.AgentData.FirstName = Utils.StringToBytes(firstname); 1880 sendAgentDataUpdate.AgentData.FirstName = Util.StringToBytes256(firstname);
1884 sendAgentDataUpdate.AgentData.GroupName = Utils.StringToBytes(groupname); 1881 sendAgentDataUpdate.AgentData.GroupName = Util.StringToBytes256(groupname);
1885 sendAgentDataUpdate.AgentData.GroupPowers = grouppowers; 1882 sendAgentDataUpdate.AgentData.GroupPowers = grouppowers;
1886 sendAgentDataUpdate.AgentData.GroupTitle = Utils.StringToBytes(grouptitle); 1883 sendAgentDataUpdate.AgentData.GroupTitle = Util.StringToBytes256(grouptitle);
1887 sendAgentDataUpdate.AgentData.LastName = Utils.StringToBytes(lastname); 1884 sendAgentDataUpdate.AgentData.LastName = Util.StringToBytes256(lastname);
1888 OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task); 1885 OutPacket(sendAgentDataUpdate, ThrottleOutPacketType.Task);
1889 } 1886 }
1890 1887
@@ -1897,7 +1894,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1897 { 1894 {
1898 AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage); 1895 AlertMessagePacket alertPack = (AlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AlertMessage);
1899 alertPack.AlertData = new AlertMessagePacket.AlertDataBlock(); 1896 alertPack.AlertData = new AlertMessagePacket.AlertDataBlock();
1900 alertPack.AlertData.Message = Utils.StringToBytes(message); 1897 alertPack.AlertData.Message = Util.StringToBytes256(message);
1901 alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[0]; 1898 alertPack.AlertInfo = new AlertMessagePacket.AlertInfoBlock[0];
1902 OutPacket(alertPack, ThrottleOutPacketType.Task); 1899 OutPacket(alertPack, ThrottleOutPacketType.Task);
1903 } 1900 }
@@ -1924,7 +1921,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1924 { 1921 {
1925 AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage); 1922 AgentAlertMessagePacket alertPack = (AgentAlertMessagePacket)PacketPool.Instance.GetPacket(PacketType.AgentAlertMessage);
1926 alertPack.AgentData.AgentID = AgentId; 1923 alertPack.AgentData.AgentID = AgentId;
1927 alertPack.AlertData.Message = Utils.StringToBytes(message); 1924 alertPack.AlertData.Message = Util.StringToBytes256(message);
1928 alertPack.AlertData.Modal = modal; 1925 alertPack.AlertData.Modal = modal;
1929 1926
1930 return alertPack; 1927 return alertPack;
@@ -1934,12 +1931,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1934 string url) 1931 string url)
1935 { 1932 {
1936 LoadURLPacket loadURL = (LoadURLPacket)PacketPool.Instance.GetPacket(PacketType.LoadURL); 1933 LoadURLPacket loadURL = (LoadURLPacket)PacketPool.Instance.GetPacket(PacketType.LoadURL);
1937 loadURL.Data.ObjectName = Utils.StringToBytes(objectname); 1934 loadURL.Data.ObjectName = Util.StringToBytes256(objectname);
1938 loadURL.Data.ObjectID = objectID; 1935 loadURL.Data.ObjectID = objectID;
1939 loadURL.Data.OwnerID = ownerID; 1936 loadURL.Data.OwnerID = ownerID;
1940 loadURL.Data.OwnerIsGroup = groupOwned; 1937 loadURL.Data.OwnerIsGroup = groupOwned;
1941 loadURL.Data.Message = Utils.StringToBytes(message); 1938 loadURL.Data.Message = Util.StringToBytes256(message);
1942 loadURL.Data.URL = Utils.StringToBytes(url); 1939 loadURL.Data.URL = Util.StringToBytes256(url);
1943 OutPacket(loadURL, ThrottleOutPacketType.Task); 1940 OutPacket(loadURL, ThrottleOutPacketType.Task);
1944 } 1941 }
1945 1942
@@ -1947,18 +1944,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1947 { 1944 {
1948 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog); 1945 ScriptDialogPacket dialog = (ScriptDialogPacket)PacketPool.Instance.GetPacket(PacketType.ScriptDialog);
1949 dialog.Data.ObjectID = objectID; 1946 dialog.Data.ObjectID = objectID;
1950 dialog.Data.ObjectName = Utils.StringToBytes(objectname); 1947 dialog.Data.ObjectName = Util.StringToBytes256(objectname);
1951 // this is the username of the *owner* 1948 // this is the username of the *owner*
1952 dialog.Data.FirstName = Utils.StringToBytes(ownerFirstName); 1949 dialog.Data.FirstName = Util.StringToBytes256(ownerFirstName);
1953 dialog.Data.LastName = Utils.StringToBytes(ownerLastName); 1950 dialog.Data.LastName = Util.StringToBytes256(ownerLastName);
1954 dialog.Data.Message = Utils.StringToBytes(msg); 1951 dialog.Data.Message = Util.StringToBytes1024(msg);
1955 dialog.Data.ImageID = textureID; 1952 dialog.Data.ImageID = textureID;
1956 dialog.Data.ChatChannel = ch; 1953 dialog.Data.ChatChannel = ch;
1957 ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length]; 1954 ScriptDialogPacket.ButtonsBlock[] buttons = new ScriptDialogPacket.ButtonsBlock[buttonlabels.Length];
1958 for (int i = 0; i < buttonlabels.Length; i++) 1955 for (int i = 0; i < buttonlabels.Length; i++)
1959 { 1956 {
1960 buttons[i] = new ScriptDialogPacket.ButtonsBlock(); 1957 buttons[i] = new ScriptDialogPacket.ButtonsBlock();
1961 buttons[i].ButtonLabel = Utils.StringToBytes(buttonlabels[i]); 1958 buttons[i].ButtonLabel = Util.StringToBytes256(buttonlabels[i]);
1962 } 1959 }
1963 dialog.Buttons = buttons; 1960 dialog.Buttons = buttons;
1964 OutPacket(dialog, ThrottleOutPacketType.Task); 1961 OutPacket(dialog, ThrottleOutPacketType.Task);
@@ -2114,19 +2111,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2114 avatarReply.AgentData.AgentID = AgentId; 2111 avatarReply.AgentData.AgentID = AgentId;
2115 avatarReply.AgentData.AvatarID = avatarID; 2112 avatarReply.AgentData.AvatarID = avatarID;
2116 if (aboutText != null) 2113 if (aboutText != null)
2117 avatarReply.PropertiesData.AboutText = Utils.StringToBytes(aboutText); 2114 avatarReply.PropertiesData.AboutText = Util.StringToBytes1024(aboutText);
2118 else 2115 else
2119 avatarReply.PropertiesData.AboutText = Utils.StringToBytes(""); 2116 avatarReply.PropertiesData.AboutText = Utils.EmptyBytes;
2120 avatarReply.PropertiesData.BornOn = Utils.StringToBytes(bornOn); 2117 avatarReply.PropertiesData.BornOn = Util.StringToBytes256(bornOn);
2121 avatarReply.PropertiesData.CharterMember = charterMember; 2118 avatarReply.PropertiesData.CharterMember = charterMember;
2122 if (flAbout != null) 2119 if (flAbout != null)
2123 avatarReply.PropertiesData.FLAboutText = Utils.StringToBytes(flAbout); 2120 avatarReply.PropertiesData.FLAboutText = Util.StringToBytes256(flAbout);
2124 else 2121 else
2125 avatarReply.PropertiesData.FLAboutText = Utils.StringToBytes(""); 2122 avatarReply.PropertiesData.FLAboutText = Utils.EmptyBytes;
2126 avatarReply.PropertiesData.Flags = flags; 2123 avatarReply.PropertiesData.Flags = flags;
2127 avatarReply.PropertiesData.FLImageID = flImageID; 2124 avatarReply.PropertiesData.FLImageID = flImageID;
2128 avatarReply.PropertiesData.ImageID = imageID; 2125 avatarReply.PropertiesData.ImageID = imageID;
2129 avatarReply.PropertiesData.ProfileURL = Utils.StringToBytes(profileURL); 2126 avatarReply.PropertiesData.ProfileURL = Util.StringToBytes256(profileURL);
2130 avatarReply.PropertiesData.PartnerID = partnerID; 2127 avatarReply.PropertiesData.PartnerID = partnerID;
2131 OutPacket(avatarReply, ThrottleOutPacketType.Task); 2128 OutPacket(avatarReply, ThrottleOutPacketType.Task);
2132 } 2129 }
@@ -2253,7 +2250,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2253 Group.Contribution = GroupMembership[i].Contribution; 2250 Group.Contribution = GroupMembership[i].Contribution;
2254 Group.GroupID = GroupMembership[i].GroupID; 2251 Group.GroupID = GroupMembership[i].GroupID;
2255 Group.GroupInsigniaID = GroupMembership[i].GroupPicture; 2252 Group.GroupInsigniaID = GroupMembership[i].GroupPicture;
2256 Group.GroupName = Utils.StringToBytes(GroupMembership[i].GroupName); 2253 Group.GroupName = Util.StringToBytes256(GroupMembership[i].GroupName);
2257 Group.GroupPowers = GroupMembership[i].GroupPowers; 2254 Group.GroupPowers = GroupMembership[i].GroupPowers;
2258 Groups[i] = Group; 2255 Groups[i] = Group;
2259 2256
@@ -2287,7 +2284,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2287 UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1]; 2284 UUIDGroupNameReplyPacket.UUIDNameBlockBlock[] uidnameblock = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock[1];
2288 UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock(); 2285 UUIDGroupNameReplyPacket.UUIDNameBlockBlock uidnamebloc = new UUIDGroupNameReplyPacket.UUIDNameBlockBlock();
2289 uidnamebloc.ID = groupLLUID; 2286 uidnamebloc.ID = groupLLUID;
2290 uidnamebloc.GroupName = Utils.StringToBytes(GroupName); 2287 uidnamebloc.GroupName = Util.StringToBytes256(GroupName);
2291 uidnameblock[0] = uidnamebloc; 2288 uidnameblock[0] = uidnamebloc;
2292 pack.UUIDNameBlock = uidnameblock; 2289 pack.UUIDNameBlock = uidnameblock;
2293 OutPacket(pack, ThrottleOutPacketType.Task); 2290 OutPacket(pack, ThrottleOutPacketType.Task);
@@ -2312,8 +2309,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
2312 lsrepdb.Score = lsrpia[i].Score; 2309 lsrepdb.Score = lsrpia[i].Score;
2313 lsrepdb.TaskID = lsrpia[i].TaskID; 2310 lsrepdb.TaskID = lsrpia[i].TaskID;
2314 lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID; 2311 lsrepdb.TaskLocalID = lsrpia[i].TaskLocalID;
2315 lsrepdb.TaskName = Utils.StringToBytes(lsrpia[i].TaskName); 2312 lsrepdb.TaskName = Util.StringToBytes256(lsrpia[i].TaskName);
2316 lsrepdb.OwnerName = Utils.StringToBytes(lsrpia[i].OwnerName); 2313 lsrepdb.OwnerName = Util.StringToBytes256(lsrpia[i].OwnerName);
2317 lsrepdba[i] = lsrepdb; 2314 lsrepdba[i] = lsrepdb;
2318 } 2315 }
2319 lsrp.ReportData = lsrepdba; 2316 lsrp.ReportData = lsrepdba;
@@ -3255,127 +3252,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3255 canUseImproved = false; 3252 canUseImproved = false;
3256 } 3253 }
3257 } 3254 }
3258 }
3259
3260 static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlockFromPrim(SceneObjectPart prim, UUID assetID, PrimFlags flags, uint crc)
3261 {
3262 byte[] objectData = new byte[60];
3263 prim.OffsetPosition.ToBytes(objectData, 0);
3264 prim.Velocity.ToBytes(objectData, 12);
3265 prim.Acceleration.ToBytes(objectData, 24);
3266 prim.RotationOffset.ToBytes(objectData, 36);
3267 prim.AngularVelocity.ToBytes(objectData, 48);
3268
3269 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
3270 update.ClickAction = (byte)prim.ClickAction;
3271 update.CRC = crc;
3272 update.ExtraParams = prim.Shape.ExtraParams ?? Utils.EmptyBytes;
3273 update.Flags = (byte)flags;
3274 update.FullID = prim.UUID;
3275 update.ID = prim.LocalId;
3276 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
3277 //update.JointPivot = Vector3.Zero;
3278 //update.JointType = 0;
3279 update.Material = prim.Material;
3280 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
3281 if (prim.IsAttachment)
3282 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + assetID);
3283 else
3284 update.NameValue = Utils.EmptyBytes;
3285 update.ObjectData = objectData;
3286 update.ParentID = prim.ParentID;
3287 update.PathBegin = prim.Shape.PathBegin;
3288 update.PathCurve = prim.Shape.PathCurve;
3289 update.PathEnd = prim.Shape.PathEnd;
3290 update.PathRadiusOffset = prim.Shape.PathRadiusOffset;
3291 update.PathRevolutions = prim.Shape.PathRevolutions;
3292 update.PathScaleX = prim.Shape.PathScaleX;
3293 update.PathScaleY = prim.Shape.PathScaleY;
3294 update.PathShearX = prim.Shape.PathShearX;
3295 update.PathShearY = prim.Shape.PathShearY;
3296 update.PathSkew = prim.Shape.PathSkew;
3297 update.PathTaperX = prim.Shape.PathTaperX;
3298 update.PathTaperY = prim.Shape.PathTaperY;
3299 update.PathTwist = prim.Shape.PathTwist;
3300 update.PathTwistBegin = prim.Shape.PathTwistBegin;
3301 update.PCode = prim.Shape.PCode;
3302 update.ProfileBegin = prim.Shape.ProfileBegin;
3303 update.ProfileCurve = prim.Shape.ProfileCurve;
3304 update.ProfileEnd = prim.Shape.ProfileEnd;
3305 update.ProfileHollow = prim.Shape.ProfileHollow;
3306 update.PSBlock = prim.ParticleSystem ?? Utils.EmptyBytes;
3307 update.TextColor = new Color4(prim.Color).GetBytes(true);
3308 update.TextureAnim = prim.TextureAnimation ?? Utils.EmptyBytes;
3309 update.TextureEntry = prim.Shape.TextureEntry ?? Utils.EmptyBytes;
3310 update.Scale = prim.Scale;
3311 update.State = prim.Shape.State;
3312 update.Text = Util.StringToBytes256(prim.Text);
3313 update.UpdateFlags = (uint)flags;
3314
3315 if (prim.Sound != UUID.Zero)
3316 {
3317 update.Sound = prim.Sound;
3318 update.OwnerID = prim.OwnerID;
3319 update.Gain = (float)prim.SoundGain;
3320 update.Radius = (float)prim.SoundRadius;
3321 }
3322
3323 switch ((PCode)prim.Shape.PCode)
3324 {
3325 case PCode.Grass:
3326 case PCode.Tree:
3327 case PCode.NewTree:
3328 update.Data = new byte[] { prim.Shape.State };
3329 break;
3330 default:
3331 // TODO: Support ScratchPad
3332 //if (prim.ScratchPad != null)
3333 //{
3334 // update.Data = new byte[prim.ScratchPad.Length];
3335 // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length);
3336 //}
3337 //else
3338 //{
3339 // update.Data = Utils.EmptyBytes;
3340 //}
3341 update.Data = Utils.EmptyBytes;
3342 break;
3343 }
3344
3345 return update;
3346 }*/ 3255 }*/
3347 3256
3348 #endregion Prim/Avatar Updates 3257 #endregion Prim/Avatar Updates
3349 3258
3350 #region Avatar Packet/data sending Methods 3259 #region Avatar Packet/Data Sending Methods
3351 3260
3352 /// <summary> 3261 /// <summary>
3353 /// send a objectupdate packet with information about the clients avatar 3262 /// Send an ObjectUpdate packet with information about an avatar
3354 /// </summary> 3263 /// </summary>
3355 public void SendAvatarData(SendAvatarData data) 3264 public void SendAvatarData(SendAvatarData data)
3356 { 3265 {
3357 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3266 ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3358 // TODO: don't create new blocks if recycling an old packet 3267 objupdate.Header.Zerocoded = true;
3359 objupdate.RegionData.RegionHandle = data.regionHandle; 3268
3269 objupdate.RegionData.RegionHandle = data.RegionHandle;
3360 objupdate.RegionData.TimeDilation = ushort.MaxValue; 3270 objupdate.RegionData.TimeDilation = ushort.MaxValue;
3271
3361 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; 3272 objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1];
3362 objupdate.ObjectData[0] = CreateDefaultAvatarPacket(data.textureEntry); 3273 objupdate.ObjectData[0] = CreateAvatarUpdateBlock(data);
3363
3364 //give this avatar object a local id and assign the user a name
3365 objupdate.ObjectData[0].ID = data.avatarLocalID;
3366 objupdate.ObjectData[0].FullID = data.avatarID;
3367 objupdate.ObjectData[0].ParentID = data.parentID;
3368 objupdate.ObjectData[0].NameValue =
3369 Utils.StringToBytes("FirstName STRING RW SV " + data.firstName + "\nLastName STRING RW SV " + data.lastName + "\nTitle STRING RW SV " + data.grouptitle);
3370
3371 Vector3 pos2 = new Vector3(data.Pos.X, data.Pos.Y, data.Pos.Z);
3372 byte[] pb = pos2.GetBytes();
3373 Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
3374 3274
3375 byte[] rot = data.rotation.GetBytes();
3376 Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length);
3377
3378 objupdate.Header.Zerocoded = true;
3379 OutPacket(objupdate, ThrottleOutPacketType.Task); 3275 OutPacket(objupdate, ThrottleOutPacketType.Task);
3380 } 3276 }
3381 3277
@@ -3385,49 +3281,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3385 /// </summary> 3281 /// </summary>
3386 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) 3282 public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data)
3387 { 3283 {
3388 if (data.priority == double.NaN) 3284 if (data.Priority == double.NaN)
3389 { 3285 {
3390 m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update"); 3286 m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update");
3391 return; 3287 return;
3392 } 3288 }
3393 3289
3394 Quaternion rotation = data.rotation; 3290 Quaternion rotation = data.Rotation;
3395 3291
3396 if (rotation.X == rotation.Y && 3292 if (rotation.X == rotation.Y &&
3397 rotation.Y == rotation.Z && 3293 rotation.Y == rotation.Z &&
3398 rotation.Z == rotation.W && rotation.W == 0) 3294 rotation.Z == rotation.W && rotation.W == 0.0f)
3399 rotation = Quaternion.Identity; 3295 rotation = Quaternion.Identity;
3400 3296
3401 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = 3297 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data);
3402 CreateAvatarImprovedBlock(data.localID, data.position, data.velocity, rotation); 3298
3403
3404 lock (m_avatarTerseUpdates.SyncRoot) 3299 lock (m_avatarTerseUpdates.SyncRoot)
3405 m_avatarTerseUpdates.Enqueue(data.priority, terseBlock, data.localID); 3300 m_avatarTerseUpdates.Enqueue(data.Priority, terseBlock, data.LocalID);
3301
3302 // If we received an update about our own avatar, process the avatar update priority queue immediately
3303 if (data.AgentID == m_agentId)
3304 ProcessAvatarTerseUpdates();
3406 } 3305 }
3407 3306
3408 private void ProcessAvatarTerseUpdates() 3307 private void ProcessAvatarTerseUpdates()
3409 { 3308 {
3410 lock (m_avatarTerseUpdates.SyncRoot) 3309 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3411 { 3310 terse.Header.Reliable = false;
3412 ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 3311 terse.Header.Zerocoded = true;
3413
3414 terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
3415 3312
3416 terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; 3313 //terse.RegionData = new ImprovedTerseObjectUpdatePacket.RegionDataBlock();
3417 terse.RegionData.TimeDilation = 3314 terse.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
3418 (ushort)(Scene.TimeDilation * ushort.MaxValue); 3315 terse.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3419 3316
3317 lock (m_avatarTerseUpdates.SyncRoot)
3318 {
3420 int count = Math.Min(m_avatarTerseUpdates.Count, m_avatarTerseUpdatesPerPacket); 3319 int count = Math.Min(m_avatarTerseUpdates.Count, m_avatarTerseUpdatesPerPacket);
3320 if (count == 0)
3321 return;
3421 3322
3422 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; 3323 terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
3423 for (int i = 0; i < count; i++) 3324 for (int i = 0; i < count; i++)
3424 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue(); 3325 terse.ObjectData[i] = m_avatarTerseUpdates.Dequeue();
3425
3426 terse.Header.Reliable = false;
3427 terse.Header.Zerocoded = true;
3428
3429 OutPacket(terse, ThrottleOutPacketType.Task);
3430 } 3326 }
3327
3328 OutPacket(terse, ThrottleOutPacketType.Task);
3431 } 3329 }
3432 3330
3433 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations) 3331 public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
@@ -3466,33 +3364,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3466 OutPacket(loc, ThrottleOutPacketType.Task); 3364 OutPacket(loc, ThrottleOutPacketType.Task);
3467 } 3365 }
3468 3366
3469 #endregion 3367 #endregion Avatar Packet/Data Sending Methods
3470 3368
3471 #region Primitive Packet/data Sending Methods 3369 #region Primitive Packet/Data Sending Methods
3472
3473 /// <summary>
3474 ///
3475 /// </summary>
3476 /// <param name="localID"></param>
3477 /// <param name="rotation"></param>
3478 /// <param name="attachPoint"></param>
3479 public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID)
3480 {
3481 if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD
3482 return;
3483
3484 ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach);
3485 // TODO: don't create new blocks if recycling an old packet
3486 attach.AgentData.AgentID = AgentId;
3487 attach.AgentData.SessionID = m_sessionId;
3488 attach.AgentData.AttachmentPoint = attachPoint;
3489 attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
3490 attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
3491 attach.ObjectData[0].ObjectLocalID = localID;
3492 attach.ObjectData[0].Rotation = rotation;
3493 attach.Header.Zerocoded = true;
3494 OutPacket(attach, ThrottleOutPacketType.Task);
3495 }
3496 3370
3497 public void SendPrimitiveToClient(SendPrimitiveData data) 3371 public void SendPrimitiveToClient(SendPrimitiveData data)
3498 { 3372 {
@@ -3508,198 +3382,115 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3508 return; 3382 return;
3509 if (data.primShape.PCode == 9 && data.primShape.State != 0 && data.parentID == 0) 3383 if (data.primShape.PCode == 9 && data.primShape.State != 0 && data.parentID == 0)
3510 return; 3384 return;
3511 3385
3512 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0.0f) 3386 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0.0f)
3513 rotation = Quaternion.Identity; 3387 rotation = Quaternion.Identity;
3514 3388
3515 ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data.primShape, data.flags); 3389 ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data);
3516
3517 objectData.ID = data.localID;
3518 objectData.FullID = data.objectID;
3519 objectData.OwnerID = data.ownerID;
3520
3521 objectData.Text = Util.StringToBytes256(data.text);
3522 objectData.TextColor[0] = data.color[0];
3523 objectData.TextColor[1] = data.color[1];
3524 objectData.TextColor[2] = data.color[2];
3525 objectData.TextColor[3] = data.color[3];
3526 objectData.ParentID = data.parentID;
3527 objectData.PSBlock = data.particleSystem;
3528 objectData.ClickAction = data.clickAction;
3529 objectData.Material = data.material;
3530 objectData.Flags = 0;
3531
3532 if (data.attachment)
3533 {
3534 // Necessary???
3535 objectData.JointAxisOrAnchor = new Vector3(0, 0, 2);
3536 objectData.JointPivot = new Vector3(0, 0, 0);
3537
3538 // Item from inventory???
3539 objectData.NameValue =
3540 Utils.StringToBytes("AttachItemID STRING RW SV " + data.AssetId.Guid);
3541 objectData.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16));
3542 }
3543
3544 // Xantor 20080528: Send sound info as well
3545 // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again
3546 objectData.Sound = data.SoundId;
3547 if (data.SoundId == UUID.Zero)
3548 {
3549 objectData.OwnerID = UUID.Zero;
3550 objectData.Gain = 0.0f;
3551 objectData.Radius = 0.0f;
3552 objectData.Flags = 0;
3553 }
3554 else
3555 {
3556 objectData.OwnerID = data.ownerID;
3557 objectData.Gain = (float)data.SoundVolume;
3558 objectData.Radius = (float)data.SoundRadius;
3559 objectData.Flags = data.SoundFlags;
3560 }
3561
3562 byte[] pb = data.pos.GetBytes();
3563 Buffer.BlockCopy(pb, 0, objectData.ObjectData, 0, pb.Length);
3564
3565 byte[] vel = data.vel.GetBytes();
3566 Buffer.BlockCopy(vel, 0, objectData.ObjectData, pb.Length, vel.Length);
3567
3568 byte[] rot = rotation.GetBytes();
3569 Buffer.BlockCopy(rot, 0, objectData.ObjectData, 36, rot.Length);
3570
3571 byte[] rvel = data.rvel.GetBytes();
3572 Buffer.BlockCopy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length);
3573
3574 if (data.textureanim.Length > 0)
3575 {
3576 objectData.TextureAnim = data.textureanim;
3577 }
3578 3390
3579 lock (m_primFullUpdates.SyncRoot) 3391 lock (m_primFullUpdates.SyncRoot)
3580 m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); 3392 m_primFullUpdates.Enqueue(data.priority, objectData, data.localID);
3581 } 3393 }
3582 3394
3583 void HandleQueueEmpty(ThrottleOutPacketType queue) 3395 void ProcessPrimFullUpdates()
3584 { 3396 {
3585 int count = 0; 3397 ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3398 outPacket.Header.Zerocoded = true;
3586 3399
3587 switch (queue) 3400 //outPacket.RegionData = new ObjectUpdatePacket.RegionDataBlock();
3588 { 3401 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
3589 case ThrottleOutPacketType.Texture: 3402 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3590 ProcessTextureRequests();
3591 break;
3592 case ThrottleOutPacketType.Task:
3593 lock (m_avatarTerseUpdates.SyncRoot)
3594 count = m_avatarTerseUpdates.Count;
3595 if (count > 0)
3596 {
3597 ProcessAvatarTerseUpdates();
3598 return;
3599 }
3600 break;
3601 case ThrottleOutPacketType.State:
3602 lock (m_primFullUpdates.SyncRoot)
3603 count = m_primFullUpdates.Count;
3604 if (count > 0)
3605 {
3606 ProcessPrimFullUpdates();
3607 return;
3608 }
3609
3610 lock (m_primTerseUpdates.SyncRoot)
3611 count = m_primTerseUpdates.Count;
3612 if (count > 0)
3613 {
3614 ProcessPrimTerseUpdates();
3615 return;
3616 }
3617 break;
3618 }
3619 }
3620 3403
3621 void ProcessTextureRequests()
3622 {
3623 if (m_imageManager != null)
3624 m_imageManager.ProcessImageQueue(m_textureSendLimit);
3625 }
3626
3627 void ProcessPrimFullUpdates()
3628 {
3629 lock (m_primFullUpdates.SyncRoot) 3404 lock (m_primFullUpdates.SyncRoot)
3630 { 3405 {
3631 ObjectUpdatePacket outPacket =
3632 (ObjectUpdatePacket)PacketPool.Instance.GetPacket(
3633 PacketType.ObjectUpdate);
3634
3635 outPacket.RegionData.RegionHandle =
3636 Scene.RegionInfo.RegionHandle;
3637 outPacket.RegionData.TimeDilation =
3638 (ushort)(Scene.TimeDilation * ushort.MaxValue);
3639
3640 int count = Math.Min(m_primFullUpdates.Count, m_primFullUpdatesPerPacket); 3406 int count = Math.Min(m_primFullUpdates.Count, m_primFullUpdatesPerPacket);
3407 if (count == 0)
3408 return;
3641 3409
3642 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[count]; 3410 outPacket.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[count];
3643 for (int i = 0; i < count; i++) 3411 for (int i = 0; i < count; i++)
3644 outPacket.ObjectData[i] = m_primFullUpdates.Dequeue(); 3412 outPacket.ObjectData[i] = m_primFullUpdates.Dequeue();
3645
3646 outPacket.Header.Zerocoded = true;
3647 OutPacket(outPacket, ThrottleOutPacketType.State);
3648 } 3413 }
3414
3415 OutPacket(outPacket, ThrottleOutPacketType.State);
3649 } 3416 }
3650 3417
3651 /// <summary>
3652 ///
3653 /// </summary>
3654 //public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position,
3655 // Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint)
3656 public void SendPrimTerseUpdate(SendPrimitiveTerseData data) 3418 public void SendPrimTerseUpdate(SendPrimitiveTerseData data)
3657 { 3419 {
3658 if (data.priority == double.NaN) 3420 if (data.Priority == double.NaN)
3659 { 3421 {
3660 m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); 3422 m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update");
3661 return; 3423 return;
3662 } 3424 }
3663 3425
3664 Quaternion rotation = data.rotation; 3426 Quaternion rotation = data.Rotation;
3665 3427
3666 if (data.attachPoint > 30 && data.owner != AgentId) // Someone else's HUD 3428 if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD
3667 return; 3429 return;
3668 3430
3669 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) 3431 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0)
3670 rotation = Quaternion.Identity; 3432 rotation = Quaternion.Identity;
3671 3433
3672 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = 3434 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data);
3673 CreatePrimImprovedBlock(data.localID, data.position, rotation,
3674 data.velocity, data.rotationalvelocity, data.state);
3675 3435
3676 lock (m_primTerseUpdates.SyncRoot) 3436 lock (m_primTerseUpdates.SyncRoot)
3677 m_primTerseUpdates.Enqueue(data.priority, objectData, data.localID); 3437 m_primTerseUpdates.Enqueue(data.Priority, objectData, data.LocalID);
3678 } 3438 }
3679 3439
3680 void ProcessPrimTerseUpdates() 3440 void ProcessPrimTerseUpdates()
3681 { 3441 {
3682 lock (m_primTerseUpdates.SyncRoot) 3442 ImprovedTerseObjectUpdatePacket outPacket = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
3683 { 3443 outPacket.Header.Reliable = false;
3684 ImprovedTerseObjectUpdatePacket outPacket = 3444 outPacket.Header.Zerocoded = true;
3685 (ImprovedTerseObjectUpdatePacket)
3686 PacketPool.Instance.GetPacket(
3687 PacketType.ImprovedTerseObjectUpdate);
3688 3445
3689 outPacket.RegionData.RegionHandle = 3446 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
3690 Scene.RegionInfo.RegionHandle; 3447 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3691 outPacket.RegionData.TimeDilation =
3692 (ushort)(Scene.TimeDilation * ushort.MaxValue);
3693 3448
3449 lock (m_primTerseUpdates.SyncRoot)
3450 {
3694 int count = Math.Min(m_primTerseUpdates.Count, m_primTerseUpdatesPerPacket); 3451 int count = Math.Min(m_primTerseUpdates.Count, m_primTerseUpdatesPerPacket);
3452 if (count == 0)
3453 return;
3695 3454
3696 outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; 3455 outPacket.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count];
3697 for (int i = 0; i < count; i++) 3456 for (int i = 0; i < count; i++)
3698 outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue(); 3457 outPacket.ObjectData[i] = m_primTerseUpdates.Dequeue();
3458 }
3459
3460 OutPacket(outPacket, ThrottleOutPacketType.State);
3461 }
3462
3463 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
3464 {
3465 PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler =
3466 delegate(ref double priority, uint local_id)
3467 {
3468 priority = handler(new UpdatePriorityData(priority, local_id));
3469 return priority != double.NaN;
3470 };
3471 PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler =
3472 delegate(ref double priority, uint local_id)
3473 {
3474 priority = handler(new UpdatePriorityData(priority, local_id));
3475 return priority != double.NaN;
3476 };
3699 3477
3700 outPacket.Header.Reliable = false; 3478 if ((type & StateUpdateTypes.AvatarTerse) != 0)
3701 outPacket.Header.Zerocoded = true; 3479 {
3702 OutPacket(outPacket, ThrottleOutPacketType.State); 3480 lock (m_avatarTerseUpdates.SyncRoot)
3481 m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler);
3482 }
3483
3484 if ((type & StateUpdateTypes.PrimitiveFull) != 0)
3485 {
3486 lock (m_primFullUpdates.SyncRoot)
3487 m_primFullUpdates.Reprioritize(update_priority_handler);
3488 }
3489
3490 if ((type & StateUpdateTypes.PrimitiveTerse) != 0)
3491 {
3492 lock (m_primTerseUpdates.SyncRoot)
3493 m_primTerseUpdates.Reprioritize(terse_update_priority_handler);
3703 } 3494 }
3704 } 3495 }
3705 3496
@@ -3719,6 +3510,90 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3719 } 3510 }
3720 } 3511 }
3721 3512
3513 #endregion Primitive Packet/Data Sending Methods
3514
3515 /// <summary>
3516 ///
3517 /// </summary>
3518 /// <param name="localID"></param>
3519 /// <param name="rotation"></param>
3520 /// <param name="attachPoint"></param>
3521 public void AttachObject(uint localID, Quaternion rotation, byte attachPoint, UUID ownerID)
3522 {
3523 if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD
3524 return;
3525
3526 ObjectAttachPacket attach = (ObjectAttachPacket)PacketPool.Instance.GetPacket(PacketType.ObjectAttach);
3527 // TODO: don't create new blocks if recycling an old packet
3528 attach.AgentData.AgentID = AgentId;
3529 attach.AgentData.SessionID = m_sessionId;
3530 attach.AgentData.AttachmentPoint = attachPoint;
3531 attach.ObjectData = new ObjectAttachPacket.ObjectDataBlock[1];
3532 attach.ObjectData[0] = new ObjectAttachPacket.ObjectDataBlock();
3533 attach.ObjectData[0].ObjectLocalID = localID;
3534 attach.ObjectData[0].Rotation = rotation;
3535 attach.Header.Zerocoded = true;
3536 OutPacket(attach, ThrottleOutPacketType.Task);
3537 }
3538
3539 void HandleQueueEmpty(ThrottleOutPacketType queue)
3540 {
3541 switch (queue)
3542 {
3543 case ThrottleOutPacketType.Texture:
3544 ProcessTextureRequests();
3545 break;
3546 case ThrottleOutPacketType.Task:
3547 if (Monitor.TryEnter(m_avatarTerseUpdates.SyncRoot, 1))
3548 {
3549 try
3550 {
3551 if (m_avatarTerseUpdates.Count > 0)
3552 {
3553
3554 ProcessAvatarTerseUpdates();
3555 return;
3556 }
3557 }
3558 finally { Monitor.Exit(m_avatarTerseUpdates.SyncRoot); }
3559 }
3560 break;
3561 case ThrottleOutPacketType.State:
3562 if (Monitor.TryEnter(m_primFullUpdates.SyncRoot, 1))
3563 {
3564 try
3565 {
3566 if (m_primFullUpdates.Count > 0)
3567 {
3568 ProcessPrimFullUpdates();
3569 return;
3570 }
3571 }
3572 finally { Monitor.Exit(m_primFullUpdates.SyncRoot); }
3573 }
3574
3575 if (Monitor.TryEnter(m_primTerseUpdates.SyncRoot, 1))
3576 {
3577 try
3578 {
3579 if (m_primTerseUpdates.Count > 0)
3580 {
3581 ProcessPrimTerseUpdates();
3582 return;
3583 }
3584 }
3585 finally { Monitor.Exit(m_primTerseUpdates.SyncRoot); }
3586 }
3587 break;
3588 }
3589 }
3590
3591 void ProcessTextureRequests()
3592 {
3593 if (m_imageManager != null)
3594 m_imageManager.ProcessImageQueue(m_textureSendLimit);
3595 }
3596
3722 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID) 3597 public void SendAssetUploadCompleteMessage(sbyte AssetType, bool Success, UUID AssetFullID)
3723 { 3598 {
3724 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket(); 3599 AssetUploadCompletePacket newPack = new AssetUploadCompletePacket();
@@ -3900,8 +3775,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3900 OutPacket(proper, ThrottleOutPacketType.Task); 3775 OutPacket(proper, ThrottleOutPacketType.Task);
3901 } 3776 }
3902 3777
3903 #endregion
3904
3905 #region Estate Data Sending Methods 3778 #region Estate Data Sending Methods
3906 3779
3907 private static bool convertParamStringToBool(byte[] field) 3780 private static bool convertParamStringToBool(byte[] field)
@@ -4308,325 +4181,221 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4308 4181
4309 #region Helper Methods 4182 #region Helper Methods
4310 4183
4311 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateAvatarImprovedBlock(uint localID, Vector3 pos, 4184 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendAvatarTerseData data)
4312 Vector3 velocity,
4313 Quaternion rotation)
4314 { 4185 {
4315 byte[] bytes = new byte[60]; 4186 return CreateImprovedTerseBlock(true, data.LocalID, 0, data.CollisionPlane, data.Position, data.Velocity,
4316 int i = 0; 4187 data.Acceleration, data.Rotation, Vector3.Zero, data.TextureEntry);
4317 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = PacketPool.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
4318
4319 dat.TextureEntry = new byte[0]; // AvatarTemplate.TextureEntry;
4320
4321 uint ID = localID;
4322
4323 bytes[i++] = (byte)(ID % 256);
4324 bytes[i++] = (byte)((ID >> 8) % 256);
4325 bytes[i++] = (byte)((ID >> 16) % 256);
4326 bytes[i++] = (byte)((ID >> 24) % 256);
4327 bytes[i++] = 0;
4328 bytes[i++] = 1;
4329 i += 14;
4330 bytes[i++] = 128;
4331 bytes[i++] = 63;
4332
4333 byte[] pb = pos.GetBytes();
4334 Array.Copy(pb, 0, bytes, i, pb.Length);
4335 i += 12;
4336
4337 Vector3 internDirec = new Vector3(velocity.X, velocity.Y, velocity.Z);
4338
4339 internDirec = internDirec / 128.0f;
4340 internDirec.X += 1;
4341 internDirec.Y += 1;
4342 internDirec.Z += 1;
4343
4344 ushort InternVelocityX = (ushort)(32768 * internDirec.X);
4345 ushort InternVelocityY = (ushort)(32768 * internDirec.Y);
4346 ushort InternVelocityZ = (ushort)(32768 * internDirec.Z);
4347
4348 ushort ac = 32767;
4349 bytes[i++] = (byte)(InternVelocityX % 256);
4350 bytes[i++] = (byte)((InternVelocityX >> 8) % 256);
4351 bytes[i++] = (byte)(InternVelocityY % 256);
4352 bytes[i++] = (byte)((InternVelocityY >> 8) % 256);
4353 bytes[i++] = (byte)(InternVelocityZ % 256);
4354 bytes[i++] = (byte)((InternVelocityZ >> 8) % 256);
4355
4356 //accel
4357 bytes[i++] = (byte)(ac % 256);
4358 bytes[i++] = (byte)((ac >> 8) % 256);
4359 bytes[i++] = (byte)(ac % 256);
4360 bytes[i++] = (byte)((ac >> 8) % 256);
4361 bytes[i++] = (byte)(ac % 256);
4362 bytes[i++] = (byte)((ac >> 8) % 256);
4363
4364 //rotation
4365 ushort rw, rx, ry, rz;
4366 rw = (ushort)(32768 * (rotation.W + 1));
4367 rx = (ushort)(32768 * (rotation.X + 1));
4368 ry = (ushort)(32768 * (rotation.Y + 1));
4369 rz = (ushort)(32768 * (rotation.Z + 1));
4370
4371 //rot
4372 bytes[i++] = (byte)(rx % 256);
4373 bytes[i++] = (byte)((rx >> 8) % 256);
4374 bytes[i++] = (byte)(ry % 256);
4375 bytes[i++] = (byte)((ry >> 8) % 256);
4376 bytes[i++] = (byte)(rz % 256);
4377 bytes[i++] = (byte)((rz >> 8) % 256);
4378 bytes[i++] = (byte)(rw % 256);
4379 bytes[i++] = (byte)((rw >> 8) % 256);
4380
4381 //rotation vel
4382 bytes[i++] = (byte)(ac % 256);
4383 bytes[i++] = (byte)((ac >> 8) % 256);
4384 bytes[i++] = (byte)(ac % 256);
4385 bytes[i++] = (byte)((ac >> 8) % 256);
4386 bytes[i++] = (byte)(ac % 256);
4387 bytes[i++] = (byte)((ac >> 8) % 256);
4388
4389 dat.Data = bytes;
4390
4391 return (dat);
4392 } 4188 }
4393 4189
4394 /// <summary> 4190 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(SendPrimitiveTerseData data)
4395 ///
4396 /// </summary>
4397 /// <param name="localID"></param>
4398 /// <param name="position"></param>
4399 /// <param name="rotation"></param>
4400 /// <returns></returns>
4401 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreatePrimImprovedBlock(uint localID,
4402 Vector3 position,
4403 Quaternion rotation,
4404 Vector3 velocity,
4405 Vector3 rotationalvelocity,
4406 byte state)
4407 { 4191 {
4408 uint ID = localID; 4192 return CreateImprovedTerseBlock(false, data.LocalID, data.State, Vector4.Zero, data.Position, data.Velocity,
4409 byte[] bytes = new byte[60]; 4193 data.Acceleration, data.Rotation, data.AngularVelocity, data.TextureEntry);
4410
4411 int i = 0;
4412 ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = PacketPool.GetDataBlock<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
4413 dat.TextureEntry = new byte[0];
4414 bytes[i++] = (byte)(ID % 256);
4415 bytes[i++] = (byte)((ID >> 8) % 256);
4416 bytes[i++] = (byte)((ID >> 16) % 256);
4417 bytes[i++] = (byte)((ID >> 24) % 256);
4418 bytes[i++] = (byte)(((state & 0xf0) >> 4) | ((state & 0x0f) << 4));
4419 bytes[i++] = 0;
4420
4421 byte[] pb = position.GetBytes();
4422 Array.Copy(pb, 0, bytes, i, pb.Length);
4423 i += 12;
4424 ushort ac = 32767;
4425
4426 ushort velx, vely, velz;
4427 Vector3 vel = new Vector3(velocity.X, velocity.Y, velocity.Z);
4428
4429 vel = vel / 128.0f;
4430 vel.X += 1;
4431 vel.Y += 1;
4432 vel.Z += 1;
4433 //vel
4434 velx = (ushort)(32768 * (vel.X));
4435 vely = (ushort)(32768 * (vel.Y));
4436 velz = (ushort)(32768 * (vel.Z));
4437
4438 bytes[i++] = (byte)(velx % 256);
4439 bytes[i++] = (byte)((velx >> 8) % 256);
4440 bytes[i++] = (byte)(vely % 256);
4441 bytes[i++] = (byte)((vely >> 8) % 256);
4442 bytes[i++] = (byte)(velz % 256);
4443 bytes[i++] = (byte)((velz >> 8) % 256);
4444
4445 //accel
4446 bytes[i++] = (byte)(ac % 256);
4447 bytes[i++] = (byte)((ac >> 8) % 256);
4448 bytes[i++] = (byte)(ac % 256);
4449 bytes[i++] = (byte)((ac >> 8) % 256);
4450 bytes[i++] = (byte)(ac % 256);
4451 bytes[i++] = (byte)((ac >> 8) % 256);
4452
4453 ushort rw, rx, ry, rz;
4454 rw = (ushort)(32768 * (rotation.W + 1));
4455 rx = (ushort)(32768 * (rotation.X + 1));
4456 ry = (ushort)(32768 * (rotation.Y + 1));
4457 rz = (ushort)(32768 * (rotation.Z + 1));
4458
4459 //rot
4460 bytes[i++] = (byte)(rx % 256);
4461 bytes[i++] = (byte)((rx >> 8) % 256);
4462 bytes[i++] = (byte)(ry % 256);
4463 bytes[i++] = (byte)((ry >> 8) % 256);
4464 bytes[i++] = (byte)(rz % 256);
4465 bytes[i++] = (byte)((rz >> 8) % 256);
4466 bytes[i++] = (byte)(rw % 256);
4467 bytes[i++] = (byte)((rw >> 8) % 256);
4468
4469 //rotation vel
4470 Vector3 rvel = new Vector3(rotationalvelocity.X, rotationalvelocity.Y, rotationalvelocity.Z);
4471
4472 rvel = rvel / 128.0f;
4473 rvel.X += 1;
4474 rvel.Y += 1;
4475 rvel.Z += 1;
4476 //vel
4477 ushort rvelx = (ushort)(32768 * (rvel.X));
4478 ushort rvely = (ushort)(32768 * (rvel.Y));
4479 ushort rvelz = (ushort)(32768 * (rvel.Z));
4480
4481 bytes[i++] = (byte)(rvelx % 256);
4482 bytes[i++] = (byte)((rvelx >> 8) % 256);
4483 bytes[i++] = (byte)(rvely % 256);
4484 bytes[i++] = (byte)((rvely >> 8) % 256);
4485 bytes[i++] = (byte)(rvelz % 256);
4486 bytes[i++] = (byte)((rvelz >> 8) % 256);
4487 dat.Data = bytes;
4488
4489 return dat;
4490 } 4194 }
4491 4195
4492 /// <summary> 4196 protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, byte state,
4493 /// Create the ObjectDataBlock for a ObjectUpdatePacket (for a Primitive) 4197 Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation,
4494 /// </summary> 4198 Vector3 angularVelocity, byte[] textureEntry)
4495 /// <param name="primData"></param> 4199 {
4496 /// <returns></returns> 4200 int pos = 0;
4497 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(PrimitiveBaseShape primShape, uint flags) 4201 byte[] data = new byte[(avatar ? 60 : 44)];
4498 { 4202
4499 ObjectUpdatePacket.ObjectDataBlock objupdate = PacketPool.GetDataBlock<ObjectUpdatePacket.ObjectDataBlock>(); 4203 // LocalID
4500 SetDefaultPrimPacketValues(objupdate); 4204 Utils.UIntToBytes(localID, data, pos);
4501 objupdate.UpdateFlags = flags; 4205 pos += 4;
4502 SetPrimPacketShapeData(objupdate, primShape); 4206
4503 4207 // Avatar/CollisionPlane
4504 if ((primShape.PCode == (byte)PCode.NewTree) || (primShape.PCode == (byte)PCode.Tree) || (primShape.PCode == (byte)PCode.Grass)) 4208 data[pos++] = state;
4505 { 4209 if (avatar)
4506 objupdate.Data = new byte[1]; 4210 {
4507 objupdate.Data[0] = primShape.State; 4211 data[pos++] = 1;
4508 } 4212
4509 return objupdate; 4213 if (collisionPlane == Vector4.Zero)
4510 } 4214 collisionPlane = Vector4.UnitW;
4511 4215
4512 protected void SetPrimPacketShapeData(ObjectUpdatePacket.ObjectDataBlock objectData, PrimitiveBaseShape primData) 4216 collisionPlane.ToBytes(data, pos);
4513 { 4217 pos += 16;
4514 objectData.TextureEntry = primData.TextureEntry; 4218 }
4515 objectData.PCode = primData.PCode; 4219 else
4516 objectData.State = primData.State; 4220 {
4517 objectData.PathBegin = primData.PathBegin; 4221 ++pos;
4518 objectData.PathEnd = primData.PathEnd; 4222 }
4519 objectData.PathScaleX = primData.PathScaleX; 4223
4520 objectData.PathScaleY = primData.PathScaleY; 4224 // Position
4521 objectData.PathShearX = primData.PathShearX; 4225 position.ToBytes(data, pos);
4522 objectData.PathShearY = primData.PathShearY; 4226 pos += 12;
4523 objectData.PathSkew = primData.PathSkew; 4227
4524 objectData.ProfileBegin = primData.ProfileBegin; 4228 // Velocity
4525 objectData.ProfileEnd = primData.ProfileEnd; 4229 Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.X, -128.0f, 128.0f), data, pos); pos += 2;
4526 objectData.Scale = primData.Scale; 4230 Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Y, -128.0f, 128.0f), data, pos); pos += 2;
4527 objectData.PathCurve = primData.PathCurve; 4231 Utils.UInt16ToBytes(Utils.FloatToUInt16(velocity.Z, -128.0f, 128.0f), data, pos); pos += 2;
4528 objectData.ProfileCurve = primData.ProfileCurve; 4232
4529 objectData.ProfileHollow = primData.ProfileHollow; 4233 // Acceleration
4530 objectData.PathRadiusOffset = primData.PathRadiusOffset; 4234 Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.X, -64.0f, 64.0f), data, pos); pos += 2;
4531 objectData.PathRevolutions = primData.PathRevolutions; 4235 Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Y, -64.0f, 64.0f), data, pos); pos += 2;
4532 objectData.PathTaperX = primData.PathTaperX; 4236 Utils.UInt16ToBytes(Utils.FloatToUInt16(acceleration.Z, -64.0f, 64.0f), data, pos); pos += 2;
4533 objectData.PathTaperY = primData.PathTaperY; 4237
4534 objectData.PathTwist = primData.PathTwist; 4238 // Rotation
4535 objectData.PathTwistBegin = primData.PathTwistBegin; 4239 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.X, -1.0f, 1.0f), data, pos); pos += 2;
4536 objectData.ExtraParams = primData.ExtraParams; 4240 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Y, -1.0f, 1.0f), data, pos); pos += 2;
4241 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.Z, -1.0f, 1.0f), data, pos); pos += 2;
4242 Utils.UInt16ToBytes(Utils.FloatToUInt16(rotation.W, -1.0f, 1.0f), data, pos); pos += 2;
4243
4244 // Angular Velocity
4245 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.X, -64.0f, 64.0f), data, pos); pos += 2;
4246 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Y, -64.0f, 64.0f), data, pos); pos += 2;
4247 Utils.UInt16ToBytes(Utils.FloatToUInt16(angularVelocity.Z, -64.0f, 64.0f), data, pos); pos += 2;
4248
4249 ImprovedTerseObjectUpdatePacket.ObjectDataBlock block = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
4250 block.Data = data;
4251
4252 if (textureEntry != null && textureEntry.Length > 0)
4253 {
4254 byte[] teBytesFinal = new byte[textureEntry.Length + 4];
4255
4256 // Texture Length
4257 Utils.IntToBytes(textureEntry.Length, textureEntry, 0);
4258 // Texture
4259 Buffer.BlockCopy(textureEntry, 0, teBytesFinal, 4, textureEntry.Length);
4260
4261 block.TextureEntry = teBytesFinal;
4262 }
4263 else
4264 {
4265 block.TextureEntry = Utils.EmptyBytes;
4266 }
4267
4268 return block;
4537 } 4269 }
4538 4270
4539 /// <summary> 4271 protected ObjectUpdatePacket.ObjectDataBlock CreateAvatarUpdateBlock(SendAvatarData data)
4540 /// Set some default values in a ObjectUpdatePacket 4272 {
4541 /// </summary> 4273 byte[] objectData = new byte[60];
4542 /// <param name="objdata"></param> 4274 data.Position.ToBytes(objectData, 0);
4543 protected void SetDefaultPrimPacketValues(ObjectUpdatePacket.ObjectDataBlock objdata) 4275 //data.Velocity.ToBytes(objectData, 12);
4544 { 4276 //data.Acceleration.ToBytes(objectData, 24);
4545 objdata.PSBlock = new byte[0]; 4277 data.Rotation.ToBytes(objectData, 36);
4546 objdata.ExtraParams = new byte[1]; 4278 //data.AngularVelocity.ToBytes(objectData, 48);
4547 objdata.MediaURL = new byte[0]; 4279
4548 objdata.NameValue = new byte[0]; 4280 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
4549 objdata.Text = new byte[0]; 4281
4550 objdata.TextColor = new byte[4]; 4282 update.Data = Utils.EmptyBytes;
4551 objdata.JointAxisOrAnchor = new Vector3(0, 0, 0); 4283 update.ExtraParams = new byte[1];
4552 objdata.JointPivot = new Vector3(0, 0, 0); 4284 update.FullID = data.AvatarID;
4553 objdata.Material = 3; 4285 update.ID = data.AvatarLocalID;
4554 objdata.TextureAnim = new byte[0]; 4286 update.Material = (byte)Material.Flesh;
4555 objdata.Sound = UUID.Zero; 4287 update.MediaURL = Utils.EmptyBytes;
4556 objdata.State = 0; 4288 update.NameValue = Utils.StringToBytes("FirstName STRING RW SV " + data.FirstName + "\nLastName STRING RW SV " +
4557 objdata.Data = new byte[0]; 4289 data.LastName + "\nTitle STRING RW SV " + data.GroupTitle);
4558 4290 update.ObjectData = objectData;
4559 objdata.ObjectData = new byte[60]; 4291 update.ParentID = data.ParentID;
4560 objdata.ObjectData[46] = 128; 4292 update.PathCurve = 16;
4561 objdata.ObjectData[47] = 63; 4293 update.PathScaleX = 100;
4294 update.PathScaleY = 100;
4295 update.PCode = (byte)PCode.Avatar;
4296 update.ProfileCurve = 1;
4297 update.PSBlock = Utils.EmptyBytes;
4298 update.Scale = Vector3.One;
4299 update.Text = Utils.EmptyBytes;
4300 update.TextColor = new byte[4];
4301 update.TextureAnim = Utils.EmptyBytes;
4302 update.TextureEntry = data.TextureEntry ?? Utils.EmptyBytes;
4303 update.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); // TODO: Replace these numbers with PrimFlags
4304
4305 return update;
4562 } 4306 }
4563 4307
4564 /// <summary> 4308 protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SendPrimitiveData data)
4565 ///
4566 /// </summary>
4567 /// <returns></returns>
4568 public ObjectUpdatePacket.ObjectDataBlock CreateDefaultAvatarPacket(byte[] textureEntry)
4569 { 4309 {
4570 ObjectUpdatePacket.ObjectDataBlock objdata = PacketPool.GetDataBlock<ObjectUpdatePacket.ObjectDataBlock>(); 4310 byte[] objectData = new byte[60];
4571 // new OpenMetaverse.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i); 4311 data.pos.ToBytes(objectData, 0);
4312 data.vel.ToBytes(objectData, 12);
4313 data.acc.ToBytes(objectData, 24);
4314 data.rotation.ToBytes(objectData, 36);
4315 data.rvel.ToBytes(objectData, 48);
4572 4316
4573 SetDefaultAvatarPacketValues(ref objdata); 4317 ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock();
4574 objdata.UpdateFlags = 61 + (9 << 8) + (130 << 16) + (16 << 24); 4318 update.ClickAction = (byte)data.clickAction;
4575 objdata.PathCurve = 16; 4319 update.CRC = 0;
4576 objdata.ProfileCurve = 1; 4320 update.ExtraParams = data.primShape.ExtraParams ?? Utils.EmptyBytes;
4577 objdata.PathScaleX = 100; 4321 update.FullID = data.objectID;
4578 objdata.PathScaleY = 100; 4322 update.ID = data.localID;
4579 objdata.ParentID = 0; 4323 //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated
4580 objdata.OwnerID = UUID.Zero; 4324 //update.JointPivot = Vector3.Zero;
4581 objdata.Scale = new Vector3(1, 1, 1); 4325 //update.JointType = 0;
4582 objdata.PCode = (byte)PCode.Avatar; 4326 update.Material = data.material;
4583 if (textureEntry != null) 4327 update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim
4328 if (data.attachment)
4584 { 4329 {
4585 objdata.TextureEntry = textureEntry; 4330 update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + data.AssetId);
4331 update.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16));
4332 }
4333 else
4334 {
4335 update.NameValue = Utils.EmptyBytes;
4336 update.State = data.primShape.State;
4337 }
4338 update.ObjectData = objectData;
4339 update.ParentID = data.parentID;
4340 update.PathBegin = data.primShape.PathBegin;
4341 update.PathCurve = data.primShape.PathCurve;
4342 update.PathEnd = data.primShape.PathEnd;
4343 update.PathRadiusOffset = data.primShape.PathRadiusOffset;
4344 update.PathRevolutions = data.primShape.PathRevolutions;
4345 update.PathScaleX = data.primShape.PathScaleX;
4346 update.PathScaleY = data.primShape.PathScaleY;
4347 update.PathShearX = data.primShape.PathShearX;
4348 update.PathShearY = data.primShape.PathShearY;
4349 update.PathSkew = data.primShape.PathSkew;
4350 update.PathTaperX = data.primShape.PathTaperX;
4351 update.PathTaperY = data.primShape.PathTaperY;
4352 update.PathTwist = data.primShape.PathTwist;
4353 update.PathTwistBegin = data.primShape.PathTwistBegin;
4354 update.PCode = data.primShape.PCode;
4355 update.ProfileBegin = data.primShape.ProfileBegin;
4356 update.ProfileCurve = data.primShape.ProfileCurve;
4357 update.ProfileEnd = data.primShape.ProfileEnd;
4358 update.ProfileHollow = data.primShape.ProfileHollow;
4359 update.PSBlock = data.particleSystem ?? Utils.EmptyBytes;
4360 update.TextColor = data.color ?? Color4.Black.GetBytes(true);
4361 update.TextureAnim = data.textureanim ?? Utils.EmptyBytes;
4362 update.TextureEntry = data.primShape.TextureEntry ?? Utils.EmptyBytes;
4363 update.Scale = data.primShape.Scale;
4364 update.Text = Util.StringToBytes256(data.text);
4365 update.UpdateFlags = (uint)data.flags;
4366
4367 if (data.SoundId != UUID.Zero)
4368 {
4369 update.Sound = data.SoundId;
4370 update.OwnerID = data.ownerID;
4371 update.Gain = (float)data.SoundVolume;
4372 update.Radius = (float)data.SoundRadius;
4373 update.Flags = data.SoundFlags;
4374 }
4375
4376 switch ((PCode)data.primShape.PCode)
4377 {
4378 case PCode.Grass:
4379 case PCode.Tree:
4380 case PCode.NewTree:
4381 update.Data = new byte[] { data.primShape.State };
4382 break;
4383 default:
4384 // TODO: Support ScratchPad
4385 //if (prim.ScratchPad != null)
4386 //{
4387 // update.Data = new byte[prim.ScratchPad.Length];
4388 // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length);
4389 //}
4390 //else
4391 //{
4392 // update.Data = Utils.EmptyBytes;
4393 //}
4394 update.Data = Utils.EmptyBytes;
4395 break;
4586 } 4396 }
4587 Vector3 pos = new Vector3(objdata.ObjectData, 16);
4588 pos.X = 100f;
4589 objdata.ID = 8880000;
4590 objdata.NameValue = Utils.StringToBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User ");
4591 //Vector3 pos2 = new Vector3(100f, 100f, 23f);
4592 //objdata.FullID=user.AgentId;
4593 byte[] pb = pos.GetBytes();
4594 Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
4595
4596 return objdata;
4597 }
4598 4397
4599 /// <summary> 4398 return update;
4600 ///
4601 /// </summary>
4602 /// <param name="objdata"></param>
4603 protected void SetDefaultAvatarPacketValues(ref ObjectUpdatePacket.ObjectDataBlock objdata)
4604 {
4605 objdata.PSBlock = new byte[0];
4606 objdata.ExtraParams = new byte[1];
4607 objdata.MediaURL = new byte[0];
4608 objdata.NameValue = new byte[0];
4609 objdata.Text = new byte[0];
4610 objdata.TextColor = new byte[4];
4611 objdata.JointAxisOrAnchor = new Vector3(0, 0, 0);
4612 objdata.JointPivot = new Vector3(0, 0, 0);
4613 objdata.Material = 4;
4614 objdata.TextureAnim = new byte[0];
4615 objdata.Sound = UUID.Zero;
4616 Primitive.TextureEntry ntex = new Primitive.TextureEntry(new UUID("00000000-0000-0000-5005-000000000005"));
4617 objdata.TextureEntry = ntex.GetBytes();
4618
4619 objdata.State = 0;
4620 objdata.Data = new byte[0];
4621
4622 objdata.ObjectData = new byte[76];
4623 objdata.ObjectData[15] = 128;
4624 objdata.ObjectData[16] = 63;
4625 objdata.ObjectData[56] = 128;
4626 objdata.ObjectData[61] = 102;
4627 objdata.ObjectData[62] = 40;
4628 objdata.ObjectData[63] = 61;
4629 objdata.ObjectData[64] = 189;
4630 } 4399 }
4631 4400
4632 public void SendNameReply(UUID profileId, string firstname, string lastname) 4401 public void SendNameReply(UUID profileId, string firstname, string lastname)
@@ -4636,8 +4405,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4636 packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1]; 4405 packet.UUIDNameBlock = new UUIDNameReplyPacket.UUIDNameBlockBlock[1];
4637 packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock(); 4406 packet.UUIDNameBlock[0] = new UUIDNameReplyPacket.UUIDNameBlockBlock();
4638 packet.UUIDNameBlock[0].ID = profileId; 4407 packet.UUIDNameBlock[0].ID = profileId;
4639 packet.UUIDNameBlock[0].FirstName = Utils.StringToBytes(firstname); 4408 packet.UUIDNameBlock[0].FirstName = Util.StringToBytes256(firstname);
4640 packet.UUIDNameBlock[0].LastName = Utils.StringToBytes(lastname); 4409 packet.UUIDNameBlock[0].LastName = Util.StringToBytes256(lastname);
4641 4410
4642 OutPacket(packet, ThrottleOutPacketType.Task); 4411 OutPacket(packet, ThrottleOutPacketType.Task);
4643 } 4412 }
@@ -4833,8 +4602,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4833 scriptQuestion.Data.TaskID = taskID; 4602 scriptQuestion.Data.TaskID = taskID;
4834 scriptQuestion.Data.ItemID = itemID; 4603 scriptQuestion.Data.ItemID = itemID;
4835 scriptQuestion.Data.Questions = question; 4604 scriptQuestion.Data.Questions = question;
4836 scriptQuestion.Data.ObjectName = Utils.StringToBytes(taskName); 4605 scriptQuestion.Data.ObjectName = Util.StringToBytes256(taskName);
4837 scriptQuestion.Data.ObjectOwner = Utils.StringToBytes(ownerName); 4606 scriptQuestion.Data.ObjectOwner = Util.StringToBytes256(ownerName);
4838 4607
4839 OutPacket(scriptQuestion, ThrottleOutPacketType.Task); 4608 OutPacket(scriptQuestion, ThrottleOutPacketType.Task);
4840 } 4609 }
@@ -5228,7 +4997,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5228 if (m_moneyBalance + debit >= 0) 4997 if (m_moneyBalance + debit >= 0)
5229 { 4998 {
5230 m_moneyBalance += debit; 4999 m_moneyBalance += debit;
5231 SendMoneyBalance(UUID.Zero, true, Utils.StringToBytes("Poof Poof!"), m_moneyBalance); 5000 SendMoneyBalance(UUID.Zero, true, Util.StringToBytes256("Poof Poof!"), m_moneyBalance);
5232 return true; 5001 return true;
5233 } 5002 }
5234 return false; 5003 return false;
@@ -8826,19 +8595,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
8826 8595
8827 #endregion 8596 #endregion
8828 8597
8598 case PacketType.AgentFOV:
8599 AgentFOVPacket fovPacket = (AgentFOVPacket)Pack;
8829 8600
8830 #region unimplemented handlers 8601 if (fovPacket.FOVBlock.GenCounter > m_agentFOVCounter)
8831 8602 {
8832 case PacketType.StartPingCheck: 8603 m_agentFOVCounter = fovPacket.FOVBlock.GenCounter;
8833 StartPingCheckPacket pingStart = (StartPingCheckPacket)Pack; 8604 AgentFOV handlerAgentFOV = OnAgentFOV;
8834 CompletePingCheckPacket pingComplete = new CompletePingCheckPacket(); 8605 if (handlerAgentFOV != null)
8835 pingComplete.PingID.PingID = pingStart.PingID.PingID; 8606 {
8836 m_udpServer.SendPacket(m_udpClient, pingComplete, ThrottleOutPacketType.Unknown, false); 8607 handlerAgentFOV(this, fovPacket.FOVBlock.VerticalAngle);
8608 }
8609 }
8837 break; 8610 break;
8838 8611
8839 case PacketType.CompletePingCheck: 8612 #region unimplemented handlers
8840 // TODO: Do stats tracking or something with these?
8841 break;
8842 8613
8843 case PacketType.ViewerStats: 8614 case PacketType.ViewerStats:
8844 // TODO: handle this packet 8615 // TODO: handle this packet
@@ -9170,7 +8941,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9170 new GroupTitlesReplyPacket.GroupDataBlock(); 8941 new GroupTitlesReplyPacket.GroupDataBlock();
9171 8942
9172 groupTitlesReply.GroupData[i].Title = 8943 groupTitlesReply.GroupData[i].Title =
9173 Utils.StringToBytes(d.Name); 8944 Util.StringToBytes256(d.Name);
9174 groupTitlesReply.GroupData[i].RoleID = 8945 groupTitlesReply.GroupData[i].RoleID =
9175 d.UUID; 8946 d.UUID;
9176 groupTitlesReply.GroupData[i].Selected = 8947 groupTitlesReply.GroupData[i].Selected =
@@ -9207,10 +8978,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9207 groupProfileRequest.GroupData.GroupID); 8978 groupProfileRequest.GroupData.GroupID);
9208 8979
9209 groupProfileReply.GroupData.GroupID = d.GroupID; 8980 groupProfileReply.GroupData.GroupID = d.GroupID;
9210 groupProfileReply.GroupData.Name = Utils.StringToBytes(d.Name); 8981 groupProfileReply.GroupData.Name = Util.StringToBytes256(d.Name);
9211 groupProfileReply.GroupData.Charter = Utils.StringToBytes(d.Charter); 8982 groupProfileReply.GroupData.Charter = Util.StringToBytes1024(d.Charter);
9212 groupProfileReply.GroupData.ShowInList = d.ShowInList; 8983 groupProfileReply.GroupData.ShowInList = d.ShowInList;
9213 groupProfileReply.GroupData.MemberTitle = Utils.StringToBytes(d.MemberTitle); 8984 groupProfileReply.GroupData.MemberTitle = Util.StringToBytes256(d.MemberTitle);
9214 groupProfileReply.GroupData.PowersMask = d.PowersMask; 8985 groupProfileReply.GroupData.PowersMask = d.PowersMask;
9215 groupProfileReply.GroupData.InsigniaID = d.InsigniaID; 8986 groupProfileReply.GroupData.InsigniaID = d.InsigniaID;
9216 groupProfileReply.GroupData.FounderID = d.FounderID; 8987 groupProfileReply.GroupData.FounderID = d.FounderID;
@@ -9282,11 +9053,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9282 groupMembersReply.MemberData[i].Contribution = 9053 groupMembersReply.MemberData[i].Contribution =
9283 m.Contribution; 9054 m.Contribution;
9284 groupMembersReply.MemberData[i].OnlineStatus = 9055 groupMembersReply.MemberData[i].OnlineStatus =
9285 Utils.StringToBytes(m.OnlineStatus); 9056 Util.StringToBytes256(m.OnlineStatus);
9286 groupMembersReply.MemberData[i].AgentPowers = 9057 groupMembersReply.MemberData[i].AgentPowers =
9287 m.AgentPowers; 9058 m.AgentPowers;
9288 groupMembersReply.MemberData[i].Title = 9059 groupMembersReply.MemberData[i].Title =
9289 Utils.StringToBytes(m.Title); 9060 Util.StringToBytes256(m.Title);
9290 groupMembersReply.MemberData[i].IsOwner = 9061 groupMembersReply.MemberData[i].IsOwner =
9291 m.IsOwner; 9062 m.IsOwner;
9292 } 9063 }
@@ -9347,11 +9118,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9347 groupRolesReply.RoleData[i].RoleID = 9118 groupRolesReply.RoleData[i].RoleID =
9348 d.RoleID; 9119 d.RoleID;
9349 groupRolesReply.RoleData[i].Name = 9120 groupRolesReply.RoleData[i].Name =
9350 Utils.StringToBytes(d.Name); 9121 Util.StringToBytes256(d.Name);
9351 groupRolesReply.RoleData[i].Title = 9122 groupRolesReply.RoleData[i].Title =
9352 Utils.StringToBytes(d.Title); 9123 Util.StringToBytes256(d.Title);
9353 groupRolesReply.RoleData[i].Description = 9124 groupRolesReply.RoleData[i].Description =
9354 Utils.StringToBytes(d.Description); 9125 Util.StringToBytes1024(d.Description);
9355 groupRolesReply.RoleData[i].Powers = 9126 groupRolesReply.RoleData[i].Powers =
9356 d.Powers; 9127 d.Powers;
9357 groupRolesReply.RoleData[i].Members = 9128 groupRolesReply.RoleData[i].Members =
@@ -9578,9 +9349,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
9578 groupNoticesListReply.Data[i].Timestamp = 9349 groupNoticesListReply.Data[i].Timestamp =
9579 g.Timestamp; 9350 g.Timestamp;
9580 groupNoticesListReply.Data[i].FromName = 9351 groupNoticesListReply.Data[i].FromName =
9581 Utils.StringToBytes(g.FromName); 9352 Util.StringToBytes256(g.FromName);
9582 groupNoticesListReply.Data[i].Subject = 9353 groupNoticesListReply.Data[i].Subject =
9583 Utils.StringToBytes(g.Subject); 9354 Util.StringToBytes256(g.Subject);
9584 groupNoticesListReply.Data[i].HasAttachment = 9355 groupNoticesListReply.Data[i].HasAttachment =
9585 g.HasAttachment; 9356 g.HasAttachment;
9586 groupNoticesListReply.Data[i].AssetType = 9357 groupNoticesListReply.Data[i].AssetType =
@@ -10179,12 +9950,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10179 byte mediaLoop) 9950 byte mediaLoop)
10180 { 9951 {
10181 ParcelMediaUpdatePacket updatePacket = new ParcelMediaUpdatePacket(); 9952 ParcelMediaUpdatePacket updatePacket = new ParcelMediaUpdatePacket();
10182 updatePacket.DataBlock.MediaURL = Utils.StringToBytes(mediaUrl); 9953 updatePacket.DataBlock.MediaURL = Util.StringToBytes256(mediaUrl);
10183 updatePacket.DataBlock.MediaID = mediaTextureID; 9954 updatePacket.DataBlock.MediaID = mediaTextureID;
10184 updatePacket.DataBlock.MediaAutoScale = autoScale; 9955 updatePacket.DataBlock.MediaAutoScale = autoScale;
10185 9956
10186 updatePacket.DataBlockExtended.MediaType = Utils.StringToBytes(mediaType); 9957 updatePacket.DataBlockExtended.MediaType = Util.StringToBytes256(mediaType);
10187 updatePacket.DataBlockExtended.MediaDesc = Utils.StringToBytes(mediaDesc); 9958 updatePacket.DataBlockExtended.MediaDesc = Util.StringToBytes256(mediaDesc);
10188 updatePacket.DataBlockExtended.MediaWidth = mediaWidth; 9959 updatePacket.DataBlockExtended.MediaWidth = mediaWidth;
10189 updatePacket.DataBlockExtended.MediaHeight = mediaHeight; 9960 updatePacket.DataBlockExtended.MediaHeight = mediaHeight;
10190 updatePacket.DataBlockExtended.MediaLoop = mediaLoop; 9961 updatePacket.DataBlockExtended.MediaLoop = mediaLoop;
@@ -10465,6 +10236,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10465 #region PriorityQueue 10236 #region PriorityQueue
10466 private class PriorityQueue<TPriority, TValue> 10237 private class PriorityQueue<TPriority, TValue>
10467 { 10238 {
10239 internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id);
10240
10468 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1]; 10241 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1];
10469 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>(); 10242 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>();
10470 private Comparison<TPriority> comparison; 10243 private Comparison<TPriority> comparison;
@@ -10539,6 +10312,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10539 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 10312 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
10540 } 10313 }
10541 10314
10315 internal void Reprioritize(UpdatePriorityHandler handler)
10316 {
10317 MinHeapItem item;
10318 TPriority priority;
10319
10320 foreach (LookupItem lookup in new List<LookupItem>(this.lookup_table.Values))
10321 {
10322 if (lookup.Heap.TryGetValue(lookup.Handle, out item))
10323 {
10324 priority = item.Priority;
10325 if (handler(ref priority, item.LocalID))
10326 {
10327 if (lookup.Heap.ContainsHandle(lookup.Handle))
10328 lookup.Heap[lookup.Handle] =
10329 new MinHeapItem(priority, item.Value, item.LocalID);
10330 }
10331 else
10332 {
10333 m_log.Warn("[LLCLIENTVIEW]: UpdatePriorityHandler returned false, dropping update");
10334 lookup.Heap.Remove(lookup.Handle);
10335 this.lookup_table.Remove(item.LocalID);
10336 }
10337 }
10338 }
10339 }
10340
10542 #region MinHeapItem 10341 #region MinHeapItem
10543 private struct MinHeapItem : IComparable<MinHeapItem> 10342 private struct MinHeapItem : IComparable<MinHeapItem>
10544 { 10343 {
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 7a403aa..66e1468 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -572,6 +572,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
572 for (int i = 0; i < ackPacket.Packets.Length; i++) 572 for (int i = 0; i < ackPacket.Packets.Length; i++)
573 AcknowledgePacket(udpClient, ackPacket.Packets[i].ID, now, packet.Header.Resent); 573 AcknowledgePacket(udpClient, ackPacket.Packets[i].ID, now, packet.Header.Resent);
574 } 574 }
575
576 // We don't need to do anything else with PacketAck packets
577 return;
575 } 578 }
576 579
577 #endregion ACK Receiving 580 #endregion ACK Receiving
@@ -579,20 +582,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
579 #region ACK Sending 582 #region ACK Sending
580 583
581 if (packet.Header.Reliable) 584 if (packet.Header.Reliable)
585 {
582 udpClient.PendingAcks.Enqueue(packet.Header.Sequence); 586 udpClient.PendingAcks.Enqueue(packet.Header.Sequence);
583 587
584 // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out, 588 // This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out,
585 // add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove 589 // add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove
586 // 2*MTU bytes from the value and send ACKs, and finally add the local value back to 590 // 2*MTU bytes from the value and send ACKs, and finally add the local value back to
587 // client.BytesSinceLastACK. Lockless thread safety 591 // client.BytesSinceLastACK. Lockless thread safety
588 int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0); 592 int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0);
589 bytesSinceLastACK += buffer.DataLength; 593 bytesSinceLastACK += buffer.DataLength;
590 if (bytesSinceLastACK > LLUDPServer.MTU * 2) 594 if (bytesSinceLastACK > LLUDPServer.MTU * 2)
591 { 595 {
592 bytesSinceLastACK -= LLUDPServer.MTU * 2; 596 bytesSinceLastACK -= LLUDPServer.MTU * 2;
593 SendAcks(udpClient); 597 SendAcks(udpClient);
598 }
599 Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK);
594 } 600 }
595 Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK);
596 601
597 #endregion ACK Sending 602 #endregion ACK Sending
598 603
@@ -612,12 +617,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
612 617
613 #endregion Incoming Packet Accounting 618 #endregion Incoming Packet Accounting
614 619
615 // Don't bother clogging up the queue with PacketAck packets that are already handled here 620 #region Ping Check Handling
616 if (packet.Type != PacketType.PacketAck) 621
622 if (packet.Type == PacketType.StartPingCheck)
623 {
624 // We don't need to do anything else with ping checks
625 StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
626
627 CompletePingCheckPacket completePing = new CompletePingCheckPacket();
628 completePing.PingID.PingID = startPing.PingID.PingID;
629 SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false);
630 return;
631 }
632 else if (packet.Type == PacketType.CompletePingCheck)
617 { 633 {
618 // Inbox insertion 634 // We don't currently track client ping times
619 packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); 635 return;
620 } 636 }
637
638 #endregion Ping Check Handling
639
640 // Inbox insertion
641 packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
621 } 642 }
622 643
623 protected override void PacketSent(UDPPacketBuffer buffer, int bytesSent) 644 protected override void PacketSent(UDPPacketBuffer buffer, int bytesSent)
@@ -712,10 +733,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
712 // on to en-US to avoid number parsing issues 733 // on to en-US to avoid number parsing issues
713 Culture.SetCurrentCulture(); 734 Culture.SetCurrentCulture();
714 735
715 IncomingPacket incomingPacket = null;
716
717 while (base.IsRunning) 736 while (base.IsRunning)
718 { 737 {
738 IncomingPacket incomingPacket = null;
739
719 try 740 try
720 { 741 {
721 if (packetInbox.Dequeue(100, ref incomingPacket)) 742 if (packetInbox.Dequeue(100, ref incomingPacket))