diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 1151 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | 55 |
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)) |