diff options
author | Teravus Ovares | 2007-11-22 19:01:53 +0000 |
---|---|---|
committer | Teravus Ovares | 2007-11-22 19:01:53 +0000 |
commit | 999eec603ea62056f599761b90c7a0510336cdd9 (patch) | |
tree | 436e7a97ec06ab22b2378d24c5feb5296cfd7a6a /OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs | |
parent | * removed erroneous comments (diff) | |
download | opensim-SC-999eec603ea62056f599761b90c7a0510336cdd9.zip opensim-SC-999eec603ea62056f599761b90c7a0510336cdd9.tar.gz opensim-SC-999eec603ea62056f599761b90c7a0510336cdd9.tar.bz2 opensim-SC-999eec603ea62056f599761b90c7a0510336cdd9.tar.xz |
Created a client driven packet throttler. The sim now respects the client's network throttle settings but does sanity checks to avoid too little(nothing gets sent) or too much(the sim crashes) data.
* Consider this experimental.. however, it looks very promising.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs | 247 |
1 files changed, 234 insertions, 13 deletions
diff --git a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs index 7f762b6..93c12a6 100644 --- a/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs +++ b/OpenSim/Region/ClientStack/ClientView.ProcessPackets.cs | |||
@@ -781,12 +781,9 @@ namespace OpenSim.Region.ClientStack | |||
781 | } | 781 | } |
782 | break; | 782 | break; |
783 | 783 | ||
784 | #endregion | ||
785 | |||
786 | #region unimplemented handlers | ||
787 | case PacketType.AgentThrottle: | 784 | case PacketType.AgentThrottle: |
788 | 785 | ||
789 | //OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString()); | 786 | OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet " + Pack.ToString()); |
790 | 787 | ||
791 | AgentThrottlePacket atpack = (AgentThrottlePacket)Pack; | 788 | AgentThrottlePacket atpack = (AgentThrottlePacket)Pack; |
792 | 789 | ||
@@ -803,7 +800,7 @@ namespace OpenSim.Region.ClientStack | |||
803 | 800 | ||
804 | //Agent Throttle Block contains 7 single floatingpoint values. | 801 | //Agent Throttle Block contains 7 single floatingpoint values. |
805 | int j = 0; | 802 | int j = 0; |
806 | 803 | ||
807 | // Some Systems may be big endian... | 804 | // Some Systems may be big endian... |
808 | // it might be smart to do this check more often... | 805 | // it might be smart to do this check more often... |
809 | if (!BitConverter.IsLittleEndian) | 806 | if (!BitConverter.IsLittleEndian) |
@@ -813,22 +810,22 @@ namespace OpenSim.Region.ClientStack | |||
813 | // values gotten from libsecondlife.org/wiki/Throttle. Thanks MW_ | 810 | // values gotten from libsecondlife.org/wiki/Throttle. Thanks MW_ |
814 | // bytes | 811 | // bytes |
815 | // Convert to integer, since.. the full fp space isn't used. | 812 | // Convert to integer, since.. the full fp space isn't used. |
816 | tResend = (int)BitConverter.ToSingle(throttle, j); | 813 | tResend = (int)BitConverter.ToSingle(throttle, j); |
817 | j += singlefloat; | 814 | j += singlefloat; |
818 | tLand = (int)BitConverter.ToSingle(throttle, j); | 815 | tLand = (int)BitConverter.ToSingle(throttle, j); |
819 | j += singlefloat; | 816 | j += singlefloat; |
820 | tWind = (int)BitConverter.ToSingle(throttle, j); | 817 | tWind = (int)BitConverter.ToSingle(throttle, j); |
821 | j += singlefloat; | 818 | j += singlefloat; |
822 | tCloud = (int)BitConverter.ToSingle(throttle, j); | 819 | tCloud = (int)BitConverter.ToSingle(throttle, j); |
823 | j += singlefloat; | 820 | j += singlefloat; |
824 | tTask = (int)BitConverter.ToSingle(throttle, j); | 821 | tTask = (int)BitConverter.ToSingle(throttle, j); |
825 | j += singlefloat; | 822 | j += singlefloat; |
826 | tTexture = (int)BitConverter.ToSingle(throttle, j); | 823 | tTexture = (int)BitConverter.ToSingle(throttle, j); |
827 | j += singlefloat; | 824 | j += singlefloat; |
828 | tAsset = (int)BitConverter.ToSingle(throttle, j); | 825 | tAsset = (int)BitConverter.ToSingle(throttle, j); |
829 | 826 | ||
830 | tall = tResend + tLand + tWind + tCloud + tTask + tTexture + tAsset; | 827 | tall = tResend + tLand + tWind + tCloud + tTask + tTexture + tAsset; |
831 | OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "unhandled packet AgentThrottle - Got throttle:resendbytes=" + tResend + | 828 | OpenSim.Framework.Console.MainLog.Instance.Verbose("CLIENT", "Client AgentThrottle - Got throttle:resendbytes=" + tResend + |
832 | " landbytes=" + tLand + | 829 | " landbytes=" + tLand + |
833 | " windbytes=" + tWind + | 830 | " windbytes=" + tWind + |
834 | " cloudbytes=" + tCloud + | 831 | " cloudbytes=" + tCloud + |
@@ -836,9 +833,233 @@ namespace OpenSim.Region.ClientStack | |||
836 | " texturebytes=" + tTexture + | 833 | " texturebytes=" + tTexture + |
837 | " Assetbytes=" + tAsset + | 834 | " Assetbytes=" + tAsset + |
838 | " Allbytes=" + tall); | 835 | " Allbytes=" + tall); |
836 | // Total Sanity | ||
837 | // Make sure that the client sent sane total values. | ||
838 | |||
839 | // If the client didn't send acceptable values.... | ||
840 | // Scale the clients values down until they are acceptable. | ||
841 | |||
842 | if (tall <= throttleOutboundMax) | ||
843 | { | ||
844 | // Sanity | ||
845 | // Making sure the client sends sane values | ||
846 | // This gives us a measure of control of the comms | ||
847 | // Check Max of Type | ||
848 | // Then Check Min of type | ||
849 | |||
850 | // Resend throttle | ||
851 | if (tResend <= ResendthrottleMAX) | ||
852 | ResendthrottleOutbound = tResend; | ||
853 | |||
854 | if (tResend < ResendthrottleMin) | ||
855 | ResendthrottleOutbound = ResendthrottleMin; | ||
856 | |||
857 | // Land throttle | ||
858 | if (tLand <= LandthrottleMax) | ||
859 | LandthrottleOutbound = tLand; | ||
860 | |||
861 | if (tLand < LandthrottleMin) | ||
862 | LandthrottleOutbound = LandthrottleMin; | ||
863 | |||
864 | // Wind throttle | ||
865 | if (tWind <= WindthrottleMax) | ||
866 | WindthrottleOutbound = tWind; | ||
867 | |||
868 | if (tWind < WindthrottleMin) | ||
869 | WindthrottleOutbound = WindthrottleMin; | ||
870 | |||
871 | // Cloud throttle | ||
872 | if (tCloud <= CloudthrottleMax) | ||
873 | CloudthrottleOutbound = tCloud; | ||
874 | |||
875 | if (tCloud < CloudthrottleMin) | ||
876 | CloudthrottleOutbound = CloudthrottleMin; | ||
877 | |||
878 | // Task throttle | ||
879 | if (tTask <= TaskthrottleMax) | ||
880 | TaskthrottleOutbound = tTask; | ||
881 | |||
882 | if (tTask < TaskthrottleMin) | ||
883 | TaskthrottleOutbound = TaskthrottleMin; | ||
884 | |||
885 | // Texture throttle | ||
886 | if (tTexture <= TexturethrottleMax) | ||
887 | TexturethrottleOutbound = tTexture; | ||
888 | |||
889 | if (tTexture < TexturethrottleMin) | ||
890 | TexturethrottleOutbound = TexturethrottleMin; | ||
891 | |||
892 | //Asset throttle | ||
893 | if (tAsset <= AssetthrottleMax) | ||
894 | AssetthrottleOutbound = tAsset; | ||
895 | |||
896 | if (tAsset < AssetthrottleMin) | ||
897 | AssetthrottleOutbound = AssetthrottleMin; | ||
898 | |||
899 | OpenSim.Framework.Console.MainLog.Instance.Verbose("THROTTLE", "Using:resendbytes=" + ResendthrottleOutbound + | ||
900 | " landbytes=" + LandthrottleOutbound + | ||
901 | " windbytes=" + WindthrottleOutbound + | ||
902 | " cloudbytes=" + CloudthrottleOutbound + | ||
903 | " taskbytes=" + TaskthrottleOutbound + | ||
904 | " texturebytes=" + TexturethrottleOutbound + | ||
905 | " Assetbytes=" + AssetthrottleOutbound + | ||
906 | " Allbytes=" + tall); | ||
907 | } | ||
908 | else | ||
909 | { | ||
910 | // The client didn't send acceptable values.. | ||
911 | // so it's our job now to turn them into acceptable values | ||
912 | // We're going to first scale the values down | ||
913 | // After that we're going to check if the scaled values are sane | ||
914 | |||
915 | // We're going to be dividing by a user value.. so make sure | ||
916 | // we don't get a divide by zero error. | ||
917 | if (tall > 0) | ||
918 | { | ||
919 | // Find out the percentage of all communications | ||
920 | // the client requests for each type. We'll keep resend at | ||
921 | // it's client recommended level (won't scale it down) | ||
922 | // unless it's beyond sane values itself. | ||
923 | |||
924 | if (tResend <= ResendthrottleMAX) | ||
925 | { | ||
926 | // This is nexted because we only want to re-set the values | ||
927 | // the packet throttler uses once. | ||
928 | |||
929 | if (tResend >= ResendthrottleMin) | ||
930 | { | ||
931 | ResendthrottleOutbound = tResend; | ||
932 | } | ||
933 | else | ||
934 | { | ||
935 | ResendthrottleOutbound = ResendthrottleMin; | ||
936 | } | ||
937 | } | ||
938 | else | ||
939 | { | ||
940 | ResendthrottleOutbound = ResendthrottleMAX; | ||
941 | } | ||
942 | |||
943 | |||
944 | // Getting Percentages of communication for each type of data | ||
945 | float LandPercent = (float)(tLand / tall); | ||
946 | float WindPercent = (float)(tWind / tall); | ||
947 | float CloudPercent = (float)(tCloud / tall); | ||
948 | float TaskPercent = (float)(tTask / tall); | ||
949 | float TexturePercent = (float)(tTexture / tall); | ||
950 | float AssetPercent = (float)(tAsset / tall); | ||
951 | |||
952 | // Okay.. now we've got the percentages of total communication. | ||
953 | // Apply them to a new max total | ||
954 | |||
955 | int tLandResult = (int)(LandPercent * throttleOutboundMax); | ||
956 | int tWindResult = (int)(WindPercent * throttleOutboundMax); | ||
957 | int tCloudResult = (int)(CloudPercent * throttleOutboundMax); | ||
958 | int tTaskResult = (int)(TaskPercent * throttleOutboundMax); | ||
959 | int tTextureResult = (int)(TexturePercent * throttleOutboundMax); | ||
960 | int tAssetResult = (int)(AssetPercent * throttleOutboundMax); | ||
961 | |||
962 | // Now we have to check our scaled values for sanity | ||
963 | |||
964 | // Check Max of Type | ||
965 | // Then Check Min of type | ||
966 | |||
967 | // Land throttle | ||
968 | if (tLandResult <= LandthrottleMax) | ||
969 | LandthrottleOutbound = tLandResult; | ||
970 | |||
971 | if (tLandResult < LandthrottleMin) | ||
972 | LandthrottleOutbound = LandthrottleMin; | ||
973 | |||
974 | // Wind throttle | ||
975 | if (tWindResult <= WindthrottleMax) | ||
976 | WindthrottleOutbound = tWindResult; | ||
977 | |||
978 | if (tWindResult < WindthrottleMin) | ||
979 | WindthrottleOutbound = WindthrottleMin; | ||
980 | |||
981 | // Cloud throttle | ||
982 | if (tCloudResult <= CloudthrottleMax) | ||
983 | CloudthrottleOutbound = tCloudResult; | ||
984 | |||
985 | if (tCloudResult < CloudthrottleMin) | ||
986 | CloudthrottleOutbound = CloudthrottleMin; | ||
987 | |||
988 | // Task throttle | ||
989 | if (tTaskResult <= TaskthrottleMax) | ||
990 | TaskthrottleOutbound = tTaskResult; | ||
991 | |||
992 | if (tTaskResult < TaskthrottleMin) | ||
993 | TaskthrottleOutbound = TaskthrottleMin; | ||
994 | |||
995 | // Texture throttle | ||
996 | if (tTextureResult <= TexturethrottleMax) | ||
997 | TexturethrottleOutbound = tTextureResult; | ||
998 | |||
999 | if (tTextureResult < TexturethrottleMin) | ||
1000 | TexturethrottleOutbound = TexturethrottleMin; | ||
1001 | |||
1002 | //Asset throttle | ||
1003 | if (tAssetResult <= AssetthrottleMax) | ||
1004 | AssetthrottleOutbound = tAssetResult; | ||
1005 | |||
1006 | if (tAssetResult < AssetthrottleMin) | ||
1007 | AssetthrottleOutbound = AssetthrottleMin; | ||
1008 | |||
1009 | OpenSim.Framework.Console.MainLog.Instance.Verbose("THROTTLE", "Using:resendbytes=" + ResendthrottleOutbound + | ||
1010 | " landbytes=" + LandthrottleOutbound + | ||
1011 | " windbytes=" + WindthrottleOutbound + | ||
1012 | " cloudbytes=" + CloudthrottleOutbound + | ||
1013 | " taskbytes=" + TaskthrottleOutbound + | ||
1014 | " texturebytes=" + TexturethrottleOutbound + | ||
1015 | " Assetbytes=" + AssetthrottleOutbound + | ||
1016 | " Allbytes=" + tall); | ||
1017 | |||
1018 | } | ||
1019 | else | ||
1020 | { | ||
1021 | |||
1022 | // The client sent a stupid value.. | ||
1023 | // We're going to set the throttles to the minimum possible | ||
1024 | ResendthrottleOutbound = ResendthrottleMin; | ||
1025 | LandthrottleOutbound = LandthrottleMin; | ||
1026 | WindthrottleOutbound = WindthrottleMin; | ||
1027 | CloudthrottleOutbound = CloudthrottleMin; | ||
1028 | TaskthrottleOutbound = TaskthrottleMin; | ||
1029 | TexturethrottleOutbound = TexturethrottleMin; | ||
1030 | AssetthrottleOutbound = AssetthrottleMin; | ||
1031 | OpenSim.Framework.Console.MainLog.Instance.Verbose("THROTTLE", "ClientSentBadThrottle Using:resendbytes=" + ResendthrottleOutbound + | ||
1032 | " landbytes=" + LandthrottleOutbound + | ||
1033 | " windbytes=" + WindthrottleOutbound + | ||
1034 | " cloudbytes=" + CloudthrottleOutbound + | ||
1035 | " taskbytes=" + TaskthrottleOutbound + | ||
1036 | " texturebytes=" + TexturethrottleOutbound + | ||
1037 | " Assetbytes=" + AssetthrottleOutbound + | ||
1038 | " Allbytes=" + tall); | ||
1039 | } | ||
1040 | |||
1041 | } | ||
1042 | // Reset Client Throttles | ||
1043 | // This has the effect of 'wiggling the slider | ||
1044 | // causes prim and stuck textures that didn't download to download | ||
1045 | |||
1046 | ResendthrottleSentPeriod = 0; | ||
1047 | LandthrottleSentPeriod = 0; | ||
1048 | WindthrottleSentPeriod = 0; | ||
1049 | CloudthrottleSentPeriod = 0; | ||
1050 | TaskthrottleSentPeriod = 0; | ||
1051 | AssetthrottleSentPeriod = 0; | ||
1052 | TexturethrottleSentPeriod = 0; | ||
1053 | |||
1054 | //Yay, we've finally handled the agent Throttle packet! | ||
839 | 1055 | ||
840 | 1056 | ||
1057 | |||
841 | break; | 1058 | break; |
1059 | |||
1060 | #endregion | ||
1061 | |||
1062 | #region unimplemented handlers | ||
842 | case PacketType.StartPingCheck: | 1063 | case PacketType.StartPingCheck: |
843 | // Send the client the ping response back | 1064 | // Send the client the ping response back |
844 | // Pass the same PingID in the matching packet | 1065 | // Pass the same PingID in the matching packet |