aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorCinder2015-05-27 08:55:49 -0600
committerDiva Canto2015-05-27 11:15:09 -0700
commit0af17c94848724c0d56d4be12c01983b4793b8bf (patch)
treec28c9f82c7d3d801bcc6d4d6dc41d619733ecf9f
parentMerge branch 'master' of ssh://opensimulator.org/var/git/opensim (diff)
downloadopensim-SC_OLD-0af17c94848724c0d56d4be12c01983b4793b8bf.zip
opensim-SC_OLD-0af17c94848724c0d56d4be12c01983b4793b8bf.tar.gz
opensim-SC_OLD-0af17c94848724c0d56d4be12c01983b4793b8bf.tar.bz2
opensim-SC_OLD-0af17c94848724c0d56d4be12c01983b4793b8bf.tar.xz
llListRandomize() wasn't very random
Signed-off-by: Diva Canto <diva@metaverseink.com>
-rw-r--r--OpenSim/Framework/Util.cs51
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs13
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 }