llListRandomize() wasn't very random
Signed-off-by: Diva Canto <diva@metaverseink.com>fsassets
parent
f0533132eb
commit
0af17c9484
|
@ -3036,4 +3036,55 @@ namespace OpenSim.Framework
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BetterRandom
|
||||
{
|
||||
private const int BufferSize = 1024; // must be a multiple of 4
|
||||
private byte[] RandomBuffer;
|
||||
private int BufferOffset;
|
||||
private RNGCryptoServiceProvider rng;
|
||||
public BetterRandom()
|
||||
{
|
||||
RandomBuffer = new byte[BufferSize];
|
||||
rng = new RNGCryptoServiceProvider();
|
||||
BufferOffset = RandomBuffer.Length;
|
||||
}
|
||||
private void FillBuffer()
|
||||
{
|
||||
rng.GetBytes(RandomBuffer);
|
||||
BufferOffset = 0;
|
||||
}
|
||||
public int Next()
|
||||
{
|
||||
if (BufferOffset >= RandomBuffer.Length)
|
||||
{
|
||||
FillBuffer();
|
||||
}
|
||||
int val = BitConverter.ToInt32(RandomBuffer, BufferOffset) & 0x7fffffff;
|
||||
BufferOffset += sizeof(int);
|
||||
return val;
|
||||
}
|
||||
public int Next(int maxValue)
|
||||
{
|
||||
return Next() % maxValue;
|
||||
}
|
||||
public int Next(int minValue, int maxValue)
|
||||
{
|
||||
if (maxValue < minValue)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("maxValue must be greater than or equal to minValue");
|
||||
}
|
||||
int range = maxValue - minValue;
|
||||
return minValue + Next(range);
|
||||
}
|
||||
public double NextDouble()
|
||||
{
|
||||
int val = Next();
|
||||
return (double)val / int.MaxValue;
|
||||
}
|
||||
public void GetBytes(byte[] buff)
|
||||
{
|
||||
rng.GetBytes(buff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5631,7 +5631,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
public LSL_List llListRandomize(LSL_List src, int stride)
|
||||
{
|
||||
LSL_List result;
|
||||
Random rand = new Random();
|
||||
BetterRandom rand = new BetterRandom();
|
||||
|
||||
int chunkk;
|
||||
int[] chunks;
|
||||
|
@ -5647,24 +5647,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
// If not, then return the src list. This also
|
||||
// traps those cases where stride > length.
|
||||
|
||||
if (src.Length != stride && src.Length%stride == 0)
|
||||
if (src.Length != stride && src.Length % stride == 0)
|
||||
{
|
||||
chunkk = src.Length/stride;
|
||||
|
||||
chunks = new int[chunkk];
|
||||
|
||||
for (int i = 0; i < chunkk; i++)
|
||||
{
|
||||
chunks[i] = i;
|
||||
}
|
||||
|
||||
// Knuth shuffle the chunkk index
|
||||
for (int i = chunkk - 1; i >= 1; i--)
|
||||
for (int i = chunkk - 1; i > 0; i--)
|
||||
{
|
||||
// Elect an unrandomized chunk to swap
|
||||
int index = rand.Next(i + 1);
|
||||
int tmp;
|
||||
|
||||
// and swap position with first unrandomized chunk
|
||||
tmp = chunks[i];
|
||||
int tmp = chunks[i];
|
||||
chunks[i] = chunks[index];
|
||||
chunks[index] = tmp;
|
||||
}
|
||||
|
@ -5677,7 +5678,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
|||
{
|
||||
for (int j = 0; j < stride; j++)
|
||||
{
|
||||
result.Add(src.Data[chunks[i]*stride+j]);
|
||||
result.Add(src.Data[chunks[i] * stride + j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue