diff options
author | Cinder | 2015-05-27 08:55:49 -0600 |
---|---|---|
committer | Diva Canto | 2015-05-27 11:15:09 -0700 |
commit | 0af17c94848724c0d56d4be12c01983b4793b8bf (patch) | |
tree | c28c9f82c7d3d801bcc6d4d6dc41d619733ecf9f /OpenSim | |
parent | Merge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff) | |
download | opensim-SC-0af17c94848724c0d56d4be12c01983b4793b8bf.zip opensim-SC-0af17c94848724c0d56d4be12c01983b4793b8bf.tar.gz opensim-SC-0af17c94848724c0d56d4be12c01983b4793b8bf.tar.bz2 opensim-SC-0af17c94848724c0d56d4be12c01983b4793b8bf.tar.xz |
llListRandomize() wasn't very random
Signed-off-by: Diva Canto <diva@metaverseink.com>
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/Util.cs | 51 | ||||
-rw-r--r-- | OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 13 |
2 files changed, 58 insertions, 6 deletions
diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 56a90b1..2d0b280 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs | |||
@@ -3036,4 +3036,55 @@ namespace OpenSim.Framework | |||
3036 | } | 3036 | } |
3037 | } | 3037 | } |
3038 | } | 3038 | } |
3039 | |||
3040 | public class BetterRandom | ||
3041 | { | ||
3042 | private const int BufferSize = 1024; // must be a multiple of 4 | ||
3043 | private byte[] RandomBuffer; | ||
3044 | private int BufferOffset; | ||
3045 | private RNGCryptoServiceProvider rng; | ||
3046 | public BetterRandom() | ||
3047 | { | ||
3048 | RandomBuffer = new byte[BufferSize]; | ||
3049 | rng = new RNGCryptoServiceProvider(); | ||
3050 | BufferOffset = RandomBuffer.Length; | ||
3051 | } | ||
3052 | private void FillBuffer() | ||
3053 | { | ||
3054 | rng.GetBytes(RandomBuffer); | ||
3055 | BufferOffset = 0; | ||
3056 | } | ||
3057 | public int Next() | ||
3058 | { | ||
3059 | if (BufferOffset >= RandomBuffer.Length) | ||
3060 | { | ||
3061 | FillBuffer(); | ||
3062 | } | ||
3063 | int val = BitConverter.ToInt32(RandomBuffer, BufferOffset) & 0x7fffffff; | ||
3064 | BufferOffset += sizeof(int); | ||
3065 | return val; | ||
3066 | } | ||
3067 | public int Next(int maxValue) | ||
3068 | { | ||
3069 | return Next() % maxValue; | ||
3070 | } | ||
3071 | public int Next(int minValue, int maxValue) | ||
3072 | { | ||
3073 | if (maxValue < minValue) | ||
3074 | { | ||
3075 | throw new ArgumentOutOfRangeException("maxValue must be greater than or equal to minValue"); | ||
3076 | } | ||
3077 | int range = maxValue - minValue; | ||
3078 | return minValue + Next(range); | ||
3079 | } | ||
3080 | public double NextDouble() | ||
3081 | { | ||
3082 | int val = Next(); | ||
3083 | return (double)val / int.MaxValue; | ||
3084 | } | ||
3085 | public void GetBytes(byte[] buff) | ||
3086 | { | ||
3087 | rng.GetBytes(buff); | ||
3088 | } | ||
3089 | } | ||
3039 | } | 3090 | } |
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index c5e02a6..53c198e 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -5631,7 +5631,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5631 | public LSL_List llListRandomize(LSL_List src, int stride) | 5631 | public LSL_List llListRandomize(LSL_List src, int stride) |
5632 | { | 5632 | { |
5633 | LSL_List result; | 5633 | LSL_List result; |
5634 | Random rand = new Random(); | 5634 | BetterRandom rand = new BetterRandom(); |
5635 | 5635 | ||
5636 | int chunkk; | 5636 | int chunkk; |
5637 | int[] chunks; | 5637 | int[] chunks; |
@@ -5647,24 +5647,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5647 | // If not, then return the src list. This also | 5647 | // If not, then return the src list. This also |
5648 | // traps those cases where stride > length. | 5648 | // traps those cases where stride > length. |
5649 | 5649 | ||
5650 | if (src.Length != stride && src.Length%stride == 0) | 5650 | if (src.Length != stride && src.Length % stride == 0) |
5651 | { | 5651 | { |
5652 | chunkk = src.Length/stride; | 5652 | chunkk = src.Length/stride; |
5653 | 5653 | ||
5654 | chunks = new int[chunkk]; | 5654 | chunks = new int[chunkk]; |
5655 | 5655 | ||
5656 | for (int i = 0; i < chunkk; i++) | 5656 | for (int i = 0; i < chunkk; i++) |
5657 | { | ||
5657 | chunks[i] = i; | 5658 | chunks[i] = i; |
5659 | } | ||
5658 | 5660 | ||
5659 | // Knuth shuffle the chunkk index | 5661 | // Knuth shuffle the chunkk index |
5660 | for (int i = chunkk - 1; i >= 1; i--) | 5662 | for (int i = chunkk - 1; i > 0; i--) |
5661 | { | 5663 | { |
5662 | // Elect an unrandomized chunk to swap | 5664 | // Elect an unrandomized chunk to swap |
5663 | int index = rand.Next(i + 1); | 5665 | int index = rand.Next(i + 1); |
5664 | int tmp; | ||
5665 | 5666 | ||
5666 | // and swap position with first unrandomized chunk | 5667 | // and swap position with first unrandomized chunk |
5667 | tmp = chunks[i]; | 5668 | int tmp = chunks[i]; |
5668 | chunks[i] = chunks[index]; | 5669 | chunks[i] = chunks[index]; |
5669 | chunks[index] = tmp; | 5670 | chunks[index] = tmp; |
5670 | } | 5671 | } |
@@ -5677,7 +5678,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5677 | { | 5678 | { |
5678 | for (int j = 0; j < stride; j++) | 5679 | for (int j = 0; j < stride; j++) |
5679 | { | 5680 | { |
5680 | result.Add(src.Data[chunks[i]*stride+j]); | 5681 | result.Add(src.Data[chunks[i] * stride + j]); |
5681 | } | 5682 | } |
5682 | } | 5683 | } |
5683 | } | 5684 | } |