* Updating libsecondlife.dll to the latest version with a working LayerData function

* Reformatting some source files
* Adding a try/catch sanity check around a phoning home check to osgrid.org
* Updating the MSVC project file
* Converted LayerData generation to use the functions built in to libsecondlife
* Removing unused BitPack.cs and TerrainDecoder.cs files
* Added a basic terrain generator (hills algorithm)
adam
jhurliman 2007-03-07 05:09:18 +00:00
parent 5ebd471544
commit 0b6f8a02a7
10 changed files with 823 additions and 1404 deletions

Binary file not shown.

View File

@ -53,16 +53,17 @@ namespace OpenSim
public int IPListenPort;
public string IPListenAddr;
public bool sandbox;
public string AssetURL="";
public string AssetSendKey="";
public bool sandbox = true;
public string AssetURL = String.Empty;
public string AssetSendKey = String.Empty;
public string GridURL="";
public string GridSendKey="";
public string GridURL = String.Empty;
public string GridSendKey = String.Empty;
private IObjectContainer db;
public void LoadDefaults() {
public void LoadDefaults()
{
string tempstring;
OpenSim_Main.localcons.WriteLine("Config.cs:LoadDefaults() - Please press enter to retain default or enter new settings");
@ -72,15 +73,11 @@ namespace OpenSim
this.IPListenPort = Convert.ToInt32(OpenSim_Main.localcons.CmdPrompt("UDP port for client connections [9000]: ", "9000"));
this.IPListenAddr = OpenSim_Main.localcons.CmdPrompt("IP Address to listen on for client connections [127.0.0.1]: ", "127.0.0.1");
tempstring = OpenSim_Main.localcons.CmdPrompt("Run in sandbox or grid mode? [sandbox]: ", "sandbox", "sandbox", "grid");
if(tempstring=="grid"){
this.sandbox = false;
} else if(tempstring=="sandbox"){
this.sandbox=true;
}
this.sandbox = tempstring.Equals("sandbox");
if(!this.sandbox) {
if (!this.sandbox)
{
this.AssetURL = OpenSim_Main.localcons.CmdPrompt("Asset server URL: ");
this.AssetSendKey = OpenSim_Main.localcons.CmdPrompt("Asset server key: ");
this.GridURL = OpenSim_Main.localcons.CmdPrompt("Grid server URL: ");
@ -89,13 +86,17 @@ namespace OpenSim
this.RegionHandle = Helpers.UIntsToLong((RegionLocX * 256), (RegionLocY * 256));
}
public void InitConfig() {
try {
public void InitConfig()
{
try
{
db = Db4oFactory.OpenFile("opensim.yap");
IObjectSet result = db.Get(typeof(SimConfig));
if(result.Count==1) {
if (result.Count == 1)
{
OpenSim_Main.localcons.WriteLine("Config.cs:InitConfig() - Found a SimConfig object in the local database, loading");
foreach (SimConfig cfg in result) {
foreach (SimConfig cfg in result)
{
this.sandbox = cfg.sandbox;
this.RegionName = cfg.RegionName;
this.RegionLocX = cfg.RegionLocX;
@ -108,13 +109,17 @@ namespace OpenSim
this.GridURL = cfg.GridURL;
this.GridSendKey = cfg.GridSendKey;
}
} else {
}
else
{
OpenSim_Main.localcons.WriteLine("Config.cs:InitConfig() - Could not find object in database, loading precompiled defaults");
LoadDefaults();
OpenSim_Main.localcons.WriteLine("Writing out default settings to local database");
db.Set(this);
}
} catch(Exception e) {
}
catch (Exception e)
{
db.Close();
OpenSim_Main.localcons.WriteLine("Config.cs:InitConfig() - Exception occured");
OpenSim_Main.localcons.WriteLine(e.ToString());
@ -131,19 +136,23 @@ namespace OpenSim
OpenSim_Main.localcons.WriteLine("Grid key: " + this.GridSendKey);
}
public World LoadWorld() {
public World LoadWorld()
{
OpenSim_Main.localcons.WriteLine("Config.cs:LoadWorld() - Loading world....");
World blank = new World();
OpenSim_Main.localcons.WriteLine("Config.cs:LoadWorld() - Looking for a heightmap in local DB");
IObjectSet world_result = db.Get(new float[65536]);
if(world_result.Count>0) {
if (world_result.Count > 0)
{
OpenSim_Main.localcons.WriteLine("Config.cs:LoadWorld() - Found a heightmap in local database, loading");
blank.LandMap = (float[])world_result.Next();
} else {
OpenSim_Main.localcons.WriteLine("Config.cs:LoadWorld() - No heightmap found, generating new one");
for(int i =0; i < 65536; i++) {
blank.LandMap[i] = 21.4989f;
}
else
{
OpenSim_Main.localcons.WriteLine("Config.cs:LoadWorld() - No heightmap found, generating new one");
HeightmapGenHills hills = new HeightmapGenHills();
blank.LandMap = hills.GenerateHeightmap(200, 4.0f, 80.0f, false);
OpenSim_Main.localcons.WriteLine("Config.cs:LoadWorld() - Saving heightmap to local database");
db.Set(blank.LandMap);
db.Commit();
@ -151,12 +160,14 @@ namespace OpenSim
return blank;
}
public void LoadFromGrid() {
public void LoadFromGrid()
{
OpenSim_Main.localcons.WriteLine("Config.cs:LoadFromGrid() - dummy function, DOING ABSOLUTELY NOTHING AT ALL!!!");
// TODO: Make this crap work
}
public void Shutdown() {
public void Shutdown()
{
db.Close();
}
}

View File

@ -41,7 +41,8 @@ namespace OpenSim
/// Handles new client connections
/// Constructor takes a single Packet and authenticates everything
/// </summary>
public class OpenSimClient {
public class OpenSimClient
{
public LLUUID AgentID;
public LLUUID SessionID;
@ -60,9 +61,10 @@ namespace OpenSim
private const int MAX_APPENDED_ACKS = 10;
private const int RESEND_TIMEOUT = 4000;
private const int MAX_SEQUENCE = 0xFFFFFF;
private Queue<uint> Inbox;
//private Queue<uint> Inbox;
public void ack_pack(Packet Pack) {
public void ack_pack(Packet Pack)
{
//libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket();
//ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
//ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
@ -71,26 +73,42 @@ namespace OpenSim
//OutPacket(ack_it);
if (Pack.Header.Reliable) {
lock (PendingAcks) {
if (Pack.Header.Reliable)
{
lock (PendingAcks)
{
uint sequence = (uint)Pack.Header.Sequence;
if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
}
}
}
public void AssetLoader() {
if(OpenSim_Main.cfg.sandbox==false) {
public void AssetLoader()
{
if (OpenSim_Main.cfg.sandbox == false)
{
WebResponse AssetResponse;
byte[] idata;
OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AssetLoader() - Starting new thread");
TransferRequestPacket reqPacket = AssetRequests.Dequeue();
OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AssetLoader() - Got a request, processing it");
LLUUID AssetID = new LLUUID(reqPacket.TransferInfo.Params, 0);
try
{
WebRequest AssetLoad = WebRequest.Create(OpenSim_Main.cfg.AssetURL + "getasset/" + OpenSim_Main.cfg.AssetSendKey + "/" + AssetID + "/data");
WebResponse AssetResponse = AssetLoad.GetResponse();
byte[] idata = new byte[(int)AssetResponse.ContentLength];
AssetResponse = AssetLoad.GetResponse();
idata = new byte[(int)AssetResponse.ContentLength];
BinaryReader br = new BinaryReader(AssetResponse.GetResponseStream());
idata = br.ReadBytes((int)AssetResponse.ContentLength);
br.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
return;
}
TransferInfoPacket Transfer = new TransferInfoPacket();
Transfer.TransferInfo.ChannelType = 2;
@ -107,7 +125,8 @@ namespace OpenSim
TransferPacket.TransferData.ChannelType = 2;
TransferPacket.TransferData.TransferID = reqPacket.TransferInfo.TransferID;
if(AssetResponse.ContentLength>1000) {
if (AssetResponse.ContentLength > 1000)
{
byte[] chunk = new byte[1000];
Array.Copy(idata, chunk, 1000);
TransferPacket.TransferData.Data = chunk;
@ -123,7 +142,9 @@ namespace OpenSim
TransferPacket.TransferData.Data = chunk1;
TransferPacket.TransferData.Status = 1;
OutPacket(TransferPacket);
} else {
}
else
{
TransferPacket.TransferData.Status = 1;
TransferPacket.TransferData.Data = idata;
OutPacket(TransferPacket);
@ -132,14 +153,17 @@ namespace OpenSim
}
}
public void Logout() {
public void Logout()
{
// TODO - kill any AssetLoaders
ClientThread.Abort();
}
public void ProcessInPacket(Packet Pack) {
public void ProcessInPacket(Packet Pack)
{
ack_pack(Pack);
switch(Pack.Type) {
switch (Pack.Type)
{
case PacketType.CompleteAgentMovement:
ClientAvatar.CompleteMovement(OpenSim_Main.local_world);
ClientAvatar.SendInitialPosition();
@ -160,11 +184,13 @@ namespace OpenSim
break;
case PacketType.LogoutRequest:
OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got a logout request");
lock(OpenSim_Main.local_world.Entities) {
lock (OpenSim_Main.local_world.Entities)
{
OpenSim_Main.local_world.Entities.Remove(this.AgentID);
}
if(OpenSim_Main.cfg.sandbox==false) {
if (OpenSim_Main.cfg.sandbox == false)
{
WebRequest DeleteSession = WebRequest.Create(OpenSim_Main.cfg.GridURL + "/usersessions/" + OpenSim_Main.cfg.GridSendKey + "/" + this.AgentID.ToString() + this.CircuitCode.ToString() + "/delete");
WebResponse GridResponse = DeleteSession.GetResponse();
StreamReader sr = new StreamReader(GridResponse.GetResponseStream());
@ -195,7 +221,8 @@ namespace OpenSim
foreach(OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values) {
foreach (OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values)
{
client.OutPacket(reply);
}
break;
@ -258,7 +285,8 @@ namespace OpenSim
ResendUnacked();
}
public void ProcessOutPacket(Packet Pack) {
public void ProcessOutPacket(Packet Pack)
{
// Keep track of when this packet was sent out
Pack.TickCount = Environment.TickCount;
@ -324,21 +352,28 @@ namespace OpenSim
byte[] sendbuffer;
sendbuffer = Pack.ToBytes();
try {
if (Pack.Header.Zerocoded) {
try
{
if (Pack.Header.Zerocoded)
{
int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
OpenSim_Main.Server.SendTo(ZeroOutBuffer, packetsize, SocketFlags.None, userEP);
} else {
}
else
{
OpenSim_Main.Server.SendTo(sendbuffer, sendbuffer.Length, SocketFlags.None, userEP);
}
} catch (Exception) {
}
catch (Exception)
{
OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread");
ClientThread.Abort();
}
}
public void InPacket(Packet NewPack) {
public void InPacket(Packet NewPack)
{
// Handle appended ACKs
if (NewPack.Header.AppendedAcks)
{
@ -364,7 +399,9 @@ namespace OpenSim
NeedAck.Remove(block.ID);
}
}
} else if( ( NewPack.Type == PacketType.StartPingCheck ) ) {
}
else if ((NewPack.Type == PacketType.StartPingCheck))
{
//reply to pingcheck
libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack;
libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket();
@ -381,14 +418,16 @@ namespace OpenSim
}
public void OutPacket(Packet NewPack) {
public void OutPacket(Packet NewPack)
{
QueItem item = new QueItem();
item.Packet = NewPack;
item.Incoming = false;
this.PacketQueue.Enqueue(item);
}
public OpenSimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack) {
public OpenSimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack)
{
OpenSim_Main.localcons.WriteLine("OpenSimClient.cs - Started up new client thread to handle incoming request");
cirpack = initialcirpack;
userEP = remoteEP;
@ -403,9 +442,11 @@ namespace OpenSim
ClientThread.Start();
}
private void ClientLoop() {
private void ClientLoop()
{
OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ClientLoop() - Entered loop");
while(true) {
while (true)
{
QueItem nextPacket = PacketQueue.Dequeue();
if (nextPacket.Incoming)
{
@ -420,15 +461,18 @@ namespace OpenSim
}
}
private void InitNewClient() {
private void InitNewClient()
{
OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:InitNewClient() - Adding viewer agent to world");
OpenSim_Main.local_world.AddViewerAgent(this);
world.Entity tempent = OpenSim_Main.local_world.Entities[this.AgentID];
this.ClientAvatar = (world.Avatar)tempent;
}
private void AuthUser() {
if(OpenSim_Main.cfg.sandbox==false) {
private void AuthUser()
{
if (OpenSim_Main.cfg.sandbox == false)
{
OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - Authenticating new user request with grid");
WebRequest CheckSession = WebRequest.Create(OpenSim_Main.cfg.GridURL + "/usersessions/" + OpenSim_Main.cfg.GridSendKey + "/" + cirpack.CircuitCode.ID.ToString() + "/" + cirpack.CircuitCode.Code.ToString() + "/exists");
OpenSim_Main.localcons.WriteLine(OpenSim_Main.cfg.GridURL);
@ -437,18 +481,23 @@ namespace OpenSim
String grTest = sr.ReadLine();
sr.Close();
GridResponse.Close();
if(String.IsNullOrEmpty(grTest) || grTest.Equals("1")) { // YAY! Valid login
if (String.IsNullOrEmpty(grTest) || grTest.Equals("1"))
{ // YAY! Valid login
OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString());
this.AgentID = cirpack.CircuitCode.ID;
this.SessionID = cirpack.CircuitCode.SessionID;
this.CircuitCode = cirpack.CircuitCode.Code;
InitNewClient();
ClientLoop();
} else { // Invalid
}
else
{ // Invalid
OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString());
ClientThread.Abort();
}
} else {
}
else
{
this.AgentID = cirpack.CircuitCode.ID;
this.SessionID = cirpack.CircuitCode.SessionID;
this.CircuitCode = cirpack.CircuitCode.Code;

View File

@ -46,19 +46,19 @@
<Compile Include="Config.cs" />
<Compile Include="Main.cs" />
<Compile Include="OpenSimClient.cs" />
<Compile Include="types\BitPack.cs" />
<Compile Include="ServerConsole.cs" />
<Compile Include="types\Mesh.cs" />
<Compile Include="types\Triangle.cs" />
<Compile Include="Util.cs" />
<Compile Include="VersionInfo.cs" />
<Compile Include="world\Avatar.cs" />
<Compile Include="world\Entity.cs" />
<Compile Include="world\HeightmapGenHills.cs" />
<Compile Include="world\PhysicsEngine.cs" />
<Compile Include="world\Primitive.cs" />
<Compile Include="world\ScriptEngine.cs" />
<Compile Include="world\scripting\IScript.cs" />
<Compile Include="world\SurfacePatch.cs" />
<Compile Include="world\TerrainDecoder.cs" />
<Compile Include="world\World.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />

37
src/VersionInfo.cs Normal file
View File

@ -0,0 +1,37 @@
/*
Copyright (c) OpenSim project, http://osgrid.org/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
namespace OpenSim
{
/// <summary>
/// </summary>
public class VersionInfo
{
public static string Version = "0.0.1-unofficial";
}
}

View File

@ -1,138 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.types
{
/* New Method
*
* 1. Get all the individual bytes and their bitlength, put them in a dictionary
* 2. Mash together when wanted.
*
* */
public class Bits {
public byte[] data;
public int len;
}
public class InverseBitPack
{
private List<Bits> bits;
public InverseBitPack()
{
bits = new List<Bits>();
}
}
public class BitPack
{
private const int MAX_BITS = 8;
private byte[] Data;
private int bytePos;
private int bitPos;
public BitPack(byte[] data, int pos) // For libsl compatibility
{
Data = data;
bytePos = pos;
}
public BitPack() // Encoding version
{
}
public void LoadData(byte[] data, int pos) {
Data = data;
bytePos = pos;
bitPos = 0;
}
private void PackBitsArray(byte[] bits, int bitLen)
{
int offset = bitPos % MAX_BITS;
int i;
byte temp1;
byte temp2;
for (i = 0; i < bits.Length; i++)
{
int Byte = bits[i];
Byte <<= offset;
temp1 = (byte)(Byte & 0xFF);
temp2 = (byte)((Byte >> 8) & 0xFF);
Data[Data.Length - 1] |= temp1;
// Data
bitPos += bitLen;
}
}
public float UnpackFloat()
{
byte[] output = UnpackBitsArray(32);
if (!BitConverter.IsLittleEndian) Array.Reverse(output);
return BitConverter.ToSingle(output, 0);
}
public int UnpackBits(int totalCount)
{
byte[] output = UnpackBitsArray(totalCount);
if (!BitConverter.IsLittleEndian) Array.Reverse(output);
return BitConverter.ToInt32(output, 0);
}
private byte[] UnpackBitsArray(int totalCount)
{
int count = 0;
byte[] output = new byte[4];
int curBytePos = 0;
int curBitPos = 0;
while (totalCount > 0)
{
if (totalCount > MAX_BITS)
{
count = MAX_BITS;
totalCount -= MAX_BITS;
}
else
{
count = totalCount;
totalCount = 0;
}
while (count > 0)
{
// Shift the previous bits
output[curBytePos] <<= 1;
// Grab one bit
if ((Data[bytePos] & (0x80 >> bitPos++)) != 0)
++output[curBytePos];
--count;
++curBitPos;
if (bitPos >= MAX_BITS)
{
bitPos = 0;
++bytePos;
}
if (curBitPos >= MAX_BITS)
{
curBitPos = 0;
++curBytePos;
}
}
}
return output;
}
}
}

View File

@ -226,8 +226,8 @@ namespace OpenSim.world
handshake.RegionInfo.TerrainStartHeight10 = 10;
handshake.RegionInfo.TerrainStartHeight11 = 10;
handshake.RegionInfo.SimAccess = 13;
handshake.RegionInfo.WaterHeight = 5;
handshake.RegionInfo.RegionFlags = 72458694;
handshake.RegionInfo.WaterHeight = 20.0f;
handshake.RegionInfo.RegionFlags = 72458694; // TODO: WTF sirs? Use an enum!
handshake.RegionInfo.SimName = _enc.GetBytes(OpenSim_Main.cfg.RegionName + "\0");
handshake.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000");
handshake.RegionInfo.TerrainBase0 = new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975");

View File

@ -0,0 +1,122 @@
using System;
namespace libsecondlife
{
public class HeightmapGenHills
{
private Random Rand = new Random();
private int NumHills;
private float HillMin;
private float HillMax;
private bool Island;
private float[] heightmap;
public float[] GenerateHeightmap(int numHills, float hillMin, float hillMax, bool island)
{
NumHills = numHills;
HillMin = hillMin;
HillMax = hillMax;
Island = island;
heightmap = new float[256 * 256];
for (int i = 0; i < numHills; i++)
{
AddHill();
}
Normalize();
return heightmap;
}
private void AddHill()
{
float x, y;
float radius = RandomRange(HillMin, HillMax);
if (Island)
{
// Which direction from the center of the map the hill is placed
float theta = RandomRange(0, 6.28f);
// How far from the center of the map to place the hill. The radius
// is subtracted from the range to prevent any part of the hill from
// reaching the edge of the map
float distance = RandomRange(radius / 2.0f, 128.0f - radius);
x = 128.0f + (float)Math.Cos(theta) * distance;
y = 128.0f + (float)Math.Sin(theta) * distance;
}
else
{
x = RandomRange(-radius, 256.0f + radius);
y = RandomRange(-radius, 256.0f + radius);
}
float radiusSq = radius * radius;
float distSq;
float height;
int xMin = (int)(x - radius) - 1;
int xMax = (int)(x + radius) + 1;
if (xMin < 0) xMin = 0;
if (xMax > 255) xMax = 255;
int yMin = (int)(y - radius) - 1;
int yMax = (int)(y + radius) + 1;
if (yMin < 0) yMin = 0;
if (yMax > 255) yMax = 255;
// Loop through each affected cell and determine the height at that point
for (int v = yMin; v <= yMax; ++v)
{
float fv = (float)v;
for (int h = xMin; h <= xMax; ++h)
{
float fh = (float)h;
// Determine how far from the center of this hill this point is
distSq = (x - fh) * (x - fh) + (y - fv) * (y - fv);
height = radiusSq - distSq;
// Don't add negative hill values
if (height > 0.0f) heightmap[h + v * 256] += height;
}
}
}
private void Normalize()
{
float min = heightmap[0];
float max = heightmap[0];
for (int x = 0; x < 256; x++)
{
for (int y = 0; y < 256; y++)
{
if (heightmap[x + y * 256] < min) min = heightmap[x + y * 256];
if (heightmap[x + y * 256] > max) max = heightmap[x + y * 256];
}
}
// Avoid a rare divide by zero
if (min != max)
{
for (int x = 0; x < 256; x++)
{
for (int y = 0; y < 256; y++)
{
heightmap[x + y * 256] = ((heightmap[x + y * 256] - min) / (max - min)) * (HillMax - HillMin);
}
}
}
}
private float RandomRange(float min, float max)
{
return (float)Rand.NextDouble() * (max - min) + min;
}
}
}

View File

@ -1,683 +0,0 @@
/*
* Copyright (c) OpenSim project, http://sim.opensecondlife.org/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
using System;
using System.Collections.Generic;
//using libsecondlife;
using libsecondlife.Packets;
namespace OpenSim
{
/// <summary>
/// Description of TerrainDecoder.
/// </summary>
public class TerrainDecode
{
public enum LayerType : byte
{
Land = 0x4C,
Water = 0x57,
Wind = 0x37,
Cloud = 0x38
}
public struct GroupHeader
{
public int Stride;
public int PatchSize;
public LayerType Type;
}
public struct PatchHeader
{
public float DCOffset;
public int Range;
public int QuantWBits;
public int PatchIDs;
public uint WordBits;
}
public class Patch
{
public float[] Heightmap;
}
/// <summary>
///
/// </summary>
/// <param name="simulator"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="width"></param>
/// <param name="data"></param>
// public delegate void LandPatchCallback(Simulator simulator, int x, int y, int width, float[] data);
/// <summary>
///
/// </summary>
//public event LandPatchCallback OnLandPatch;
private Random RandomClass = new Random();
private const byte END_OF_PATCHES = 97;
private const int PATCHES_PER_EDGE = 16;
private const float OO_SQRT2 = 0.7071067811865475244008443621049f;
//private SecondLife Client;
private Dictionary<ulong, Patch[]> SimPatches = new Dictionary<ulong, Patch[]>();
private float[] DequantizeTable16 = new float[16 * 16];
private float[] DequantizeTable32 = new float[32 * 32];
private float[] ICosineTable16 = new float[16 * 16];
private float[] ICosineTable32 = new float[32 * 32];
private int[] DeCopyMatrix16 = new int[16 * 16];
private int[] DeCopyMatrix32 = new int[32 * 32];
/// <summary>
///
/// </summary>
/// <param name="client"></param>
public TerrainDecode()
{
// Initialize the decompression tables
BuildDequantizeTable16();
BuildDequantizeTable32();
SetupICosines16();
SetupICosines32();
BuildDecopyMatrix16();
BuildDecopyMatrix32();
}
private void BuildDequantizeTable16()
{
for (int j = 0; j < 16; j++)
{
for (int i = 0; i < 16; i++)
{
DequantizeTable16[j * 16 + i] = 1.0f + 2.0f * (float)(i + j);
}
}
}
private void BuildDequantizeTable32()
{
for (int j = 0; j < 32; j++)
{
for (int i = 0; i < 32; i++)
{
DequantizeTable32[j * 32 + i] = 1.0f + 2.0f * (float)(i + j);
}
}
}
private void SetupICosines16()
{
const float hposz = (float)Math.PI * 0.5f / 16.0f;
for (int u = 0; u < 16; u++)
{
for (int n = 0; n < 16; n++)
{
ICosineTable16[u * 16 + n] = (float)Math.Cos((2.0f * (float)n + 1.0f) * (float)u * hposz);
}
}
}
private void SetupICosines32()
{
const float hposz = (float)Math.PI * 0.5f / 32.0f;
for (int u = 0; u < 32; u++)
{
for (int n = 0; n < 32; n++)
{
ICosineTable32[u * 32 + n] = (float)Math.Cos((2.0f * (float)n + 1.0f) * (float)u * hposz);
}
}
}
private void BuildDecopyMatrix16()
{
bool diag = false;
bool right = true;
int i = 0;
int j = 0;
int count = 0;
while (i < 16 && j < 16)
{
DeCopyMatrix16[j * 16 + i] = count++;
if (!diag)
{
if (right)
{
if (i < 16 - 1) i++;
else j++;
right = false;
diag = true;
}
else
{
if (j < 16 - 1) j++;
else i++;
right = true;
diag = true;
}
}
else
{
if (right)
{
i++;
j--;
if (i == 16 - 1 || j == 0) diag = false;
}
else
{
i--;
j++;
if (j == 16 - 1 || i == 0) diag = false;
}
}
}
}
private void BuildDecopyMatrix32()
{
bool diag = false;
bool right = true;
int i = 0;
int j = 0;
int count = 0;
while (i < 32 && j < 32)
{
DeCopyMatrix32[j * 32 + i] = count++;
if (!diag)
{
if (right)
{
if (i < 32 - 1) i++;
else j++;
right = false;
diag = true;
}
else
{
if (j < 32 - 1) j++;
else i++;
right = true;
diag = true;
}
}
else
{
if (right)
{
i++;
j--;
if (i == 32 - 1 || j == 0) diag = false;
}
else
{
i--;
j++;
if (j == 32 - 1 || i == 0) diag = false;
}
}
}
}
private void EncodePatchHeader(BitPacker bitpack, PatchHeader header)
{
bitpack.PackBits(header.QuantWBits,8);
if (header.QuantWBits == END_OF_PATCHES)
return;
bitpack.PackFloat(header.DCOffset);
bitpack.PackBits(header.Range,16);
bitpack.PackBits(header.PatchIDs,10);
}
public void DCTLine16(float[] In, float[] Out, int line)
{
int N =16;
int lineSize = line * 16;
for(int k = 0; k < N;k++)
{
float sum = 0.0f;
for(int n = 0; n < N; n++)
{
float num = (float)(Math.PI*k*(2.0f*n+1)/(2*N));
float cosine = (float)Math.Cos(num);
float product = In[lineSize +n] * cosine;
sum += product;
}
float alpha;
if(k == 0)
{
alpha = (float)(1.0f/Math.Sqrt(2));
}
else
{
alpha = 1;
}
Out[lineSize + k] =(float)( sum * alpha );
}
}
public void DCTColumn16(float[] In, float[] Out, int Column)
{
int N =16;
int uSize;
for(int k = 0; k < N; k++){
float sum = 0.0f;
for(int n = 0; n < N; n++)
{
uSize = n * 16;
float num = (float)(Math.PI*k*(2.0f*n+1)/(2*N));
float cosine = (float)Math.Cos(num);
float product = In[uSize + Column] * cosine;
sum += product;
}
float alpha;
if(k == 0)
{
alpha = (float)(1.0f/Math.Sqrt(2));
}
else
{
alpha = 1;
}
Out[16 * k + Column] = (float)( sum * alpha * (2.0f /N));
}
}
private void EncodePatch(int[] patches, BitPacker bitpack, int size)
{
int lastnum =0;
for(int n = 0; n < size * size; n++)
{
if(patches[n]!=0)
lastnum=n;
}
for (int n = 0; n < lastnum+1; n++)
{
if(patches[n] != 0)
{
bitpack.PackBits(1,1); //value or EOB
bitpack.PackBits(1,1); //value
if(patches[n] > 0)
{
bitpack.PackBits(0,1); // positive
bitpack.PackBits(patches[n],13);
}
else
{
bitpack.PackBits(1,1); // negative
int temp = patches[n] * -1;
bitpack.PackBits(temp,13);
}
}
else
{
bitpack.PackBits(0,1); // no value
}
}
bitpack.PackBits(1,1); //value or EOB
bitpack.PackBits(0,1); // EOB
}
public int[] CompressPatch(float[] patches)
{
int size = 16;
float[] block = new float[size * size];
int[] output = new int[size * size];
int prequant = (139 >> 4) + 2;
int quantize = 1 << prequant;
float ooq = 1.0f / (float)quantize;
float mult = ooq * (float)1;
float addval = mult * (float)(1 << (prequant - 1)) + 20.4989f;
if (size == 16)
{
for (int n = 0; n < 16 * 16; n++)
{
block[n] = (float)((patches[n] - addval)/ mult);
}
float[] ftemp = new float[32 * 32];
for (int o = 0; o < 16; o++)
this.DCTColumn16(block, ftemp, o);
for (int o = 0; o < 16; o++)
this.DCTLine16(ftemp, block, o);
}
for (int j = 0; j < block.Length; j++)
{
output[DeCopyMatrix16[j]] = (int)(block[j] / DequantizeTable16[j]);
}
return output;
}
public Packet CreateLayerPacket(float[] heightmap, int minX, int minY, int maxX, int maxY)
{
//int minX = 0, maxX = 2, minY = 0, maxY = 1; //these should be passed to this function
LayerDataPacket layer = new LayerDataPacket();
byte[] Encoded = new byte[2048];
layer.LayerID.Type = 76;
GroupHeader header = new GroupHeader();
header.Stride = 264;
header.PatchSize = 16;
header.Type = LayerType.Land;
BitPacker newpack = new BitPacker(Encoded,0);
newpack.PackBits(header.Stride,16);
newpack.PackBits(header.PatchSize,8);
newpack.PackBits((int)header.Type,8);
float[] height;
for(int y = minY; y< maxY; y++)
{
for(int x = minX ; x < maxX ; x++)
{
height = new float[256];
Array.Copy(heightmap, (4096 *y) +(x *256), height, 0, 256);
this.CreatePatch(height, newpack, x, y);
}
}
PatchHeader headers = new PatchHeader();
headers.QuantWBits = END_OF_PATCHES;
this.EncodePatchHeader(newpack, headers);
int lastused=0;
for(int i = 0; i < 2048 ; i++)
{
if(Encoded[i] !=0)
lastused = i;
}
byte[] data = new byte[lastused+1];
Array.Copy(Encoded, data, lastused+1);
layer.LayerData.Data =data;
return(layer);
}
public void CreatePatch(float[] heightmap, BitPacker newpack, int x, int y)
{
PatchHeader header = new PatchHeader();
header.DCOffset = 20.4989f;
header.QuantWBits = 139;
header.Range = 1;
header.PatchIDs = (y & 0x1F);
header.PatchIDs += x <<5 ;
this.EncodePatchHeader(newpack, header);
int[] newpatch = this.CompressPatch(heightmap);
this.EncodePatch(newpatch, newpack, 16);
}
}
//***************************************************
public class BitPacker
{
private const int MAX_BITS = 8;
private byte[] Data;
public int bytePos;
public int bitPos;
/// <summary>
/// Default constructor, initialize the bit packer / bit unpacker
/// with a byte array and starting position
/// </summary>
/// <param name="data">Byte array to pack bits in to or unpack from</param>
/// <param name="pos">Starting position in the byte array</param>
public BitPacker(byte[] data, int pos)
{
Data = data;
bytePos = pos;
}
/// <summary>
/// Pack a floating point value in to the data
/// </summary>
/// <param name="data">Floating point value to pack</param>
public void PackFloat(float data)
{
byte[] input = BitConverter.GetBytes(data);
PackBitArray(input, 32);
}
/// <summary>
/// Pack part or all of an integer in to the data
/// </summary>
/// <param name="data">Integer containing the data to pack</param>
/// <param name="totalCount">Number of bits of the integer to pack</param>
public void PackBits(int data, int totalCount)
{
byte[] input = BitConverter.GetBytes(data);
PackBitArray(input, totalCount);
}
/// <summary>
/// Unpacking a floating point value from the data
/// </summary>
/// <returns>Unpacked floating point value</returns>
public float UnpackFloat()
{
byte[] output = UnpackBitsArray(32);
if (!BitConverter.IsLittleEndian) Array.Reverse(output);
return BitConverter.ToSingle(output, 0);
}
/// <summary>
/// Unpack a variable number of bits from the data in to integer format
/// </summary>
/// <param name="totalCount">Number of bits to unpack</param>
/// <returns>An integer containing the unpacked bits</returns>
/// <remarks>This function is only useful up to 32 bits</remarks>
public int UnpackBits(int totalCount)
{
byte[] output = UnpackBitsArray(totalCount);
if (!BitConverter.IsLittleEndian) Array.Reverse(output);
return BitConverter.ToInt32(output, 0);
}
private void PackBitArray(byte[] data, int totalCount)
{
int count = 0;
int curBytePos = 0;
int curBitPos = 0;
while (totalCount > 0)
{
if (totalCount > (MAX_BITS ))
{
count = MAX_BITS ;
totalCount -= MAX_BITS ;
}
else
{
count = totalCount;
totalCount = 0;
}
while (count > 0)
{
switch(count)
{
case 1:
if ((data[curBytePos] & (0x01)) != 0)
{
Data[bytePos] |= (byte)(0x80 >> bitPos);
}
break;
case 2:
if ((data[curBytePos] & (0x02)) != 0)
{
Data[bytePos] |= (byte)(0x80 >> bitPos);
}
break;
case 3:
if ((data[curBytePos] & (0x04)) != 0)
{
Data[bytePos] |= (byte)(0x80 >> bitPos);
}
break;
case 4:
if ((data[curBytePos] & (0x08)) != 0)
{
Data[bytePos] |= (byte)(0x80 >> bitPos);
}
break;
case 5:
if ((data[curBytePos] & (0x10)) != 0)
{
Data[bytePos] |= (byte)(0x80 >> bitPos);
}
break;
case 6:
if ((data[curBytePos] & (0x20)) != 0)
{
Data[bytePos] |= (byte)(0x80 >> bitPos);
}
break;
case 7:
if ((data[curBytePos] & (0x40)) != 0)
{
Data[bytePos] |= (byte)(0x80 >> bitPos);
}
break;
case 8:
if ((data[curBytePos] & (0x80)) != 0)
{
Data[bytePos] |= (byte)(0x80 >> bitPos);
}
break;
}
bitPos++;
--count;
++curBitPos;
if (bitPos >= MAX_BITS)
{
bitPos = 0;
++bytePos;
}
if (curBitPos >= MAX_BITS)
{
curBitPos = 0;
++curBytePos;
}
}
}
}
private byte[] UnpackBitsArray(int totalCount)
{
int count = 0;
byte[] output = new byte[4];
int curBytePos = 0;
int curBitPos = 0;
while (totalCount > 0)
{
if (totalCount > MAX_BITS)
{
count = MAX_BITS;
totalCount -= MAX_BITS;
}
else
{
count = totalCount;
totalCount = 0;
}
while (count > 0)
{
// Shift the previous bits
output[curBytePos] <<= 1;
// Grab one bit
if ((Data[bytePos] & (0x80 >> bitPos++)) != 0)
++output[curBytePos];
--count;
++curBitPos;
if (bitPos >= MAX_BITS)
{
bitPos = 0;
++bytePos;
}
if (curBitPos >= MAX_BITS)
{
curBitPos = 0;
++curBytePos;
}
}
}
return output;
}
}
}

View File

@ -1,9 +1,9 @@
using System;
using System.Threading;
using libsecondlife;
using libsecondlife.Packets;
using System.Collections.Generic;
using System.Text;
using libsecondlife;
using libsecondlife.Packets;
namespace OpenSim.world
{
@ -12,10 +12,10 @@ namespace OpenSim.world
public Dictionary<libsecondlife.LLUUID, Entity> Entities;
public float[] LandMap;
public ScriptEngine Scripts;
public TerrainDecode terrainengine = new TerrainDecode();
public uint _localNumber = 0;
public PhysicsEngine physics;
private libsecondlife.TerrainManager TerrainManager;
private Random Rand = new Random();
public World()
@ -24,35 +24,41 @@ namespace OpenSim.world
Entities = new Dictionary<libsecondlife.LLUUID, Entity>();
OpenSim_Main.localcons.WriteLine("World.cs - creating LandMap");
terrainengine = new TerrainDecode();
LandMap = new float[65536];
TerrainManager = new TerrainManager(new SecondLife());
}
public void InitLoop() {
public void InitLoop()
{
OpenSim_Main.localcons.WriteLine("World.cs:StartLoop() - Initialising physics");
this.physics = new PhysicsEngine();
physics.Startup();
}
public void DoStuff() {
lock(this) {
public void DoStuff()
{
lock (this)
{
physics.DoStuff(this);
this.Update();
}
}
public void Update() {
public void Update()
{
foreach (libsecondlife.LLUUID UUID in Entities.Keys)
{
if(Entities[UUID].needupdate) {
if (Entities[UUID].needupdate)
{
Entities[UUID].update();
if(Entities[UUID] is Avatar) {
if (Entities[UUID] is Avatar)
{
Avatar avatar = (Avatar)Entities[UUID];
if((avatar.oldpos!=avatar.position) || (avatar.oldvel!=avatar.velocity) || avatar.walking) {
if ((avatar.oldpos != avatar.position) || (avatar.oldvel != avatar.velocity) || avatar.walking)
{
ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = Entities[UUID].CreateTerseBlock();
foreach(OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values) {
foreach (OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values)
{
ImprovedTerseObjectUpdatePacket terse = new ImprovedTerseObjectUpdatePacket();
terse.RegionData.RegionHandle = OpenSim_Main.cfg.RegionHandle; // FIXME
terse.RegionData.TimeDilation = 0;
@ -60,19 +66,33 @@ namespace OpenSim.world
terse.ObjectData[0] = terseBlock;
client.OutPacket(terse);
}
}}
}
}
}
}
}
public void SendLayerData(OpenSimClient RemoteClient) {
for(int x=0; x<16; x=x+4) for(int y=0; y<16; y++){
Packet layerpack=this.terrainengine.CreateLayerPacket(LandMap, x,y,x+4,y+1);
public void SendLayerData(OpenSimClient RemoteClient)
{
int[] patches = new int[4];
for (int y = 0; y < 16; y++)
{
for (int x = 0; x < 16; x = x + 4)
{
patches[0] = x + 0 + y * 16;
patches[1] = x + 1 + y * 16;
patches[2] = x + 2 + y * 16;
patches[3] = x + 3 + y * 16;
Packet layerpack = TerrainManager.CreateLandPacket(LandMap, patches);
RemoteClient.OutPacket(layerpack);
}
}
}
public void AddViewerAgent(OpenSimClient AgentClient) {
public void AddViewerAgent(OpenSimClient AgentClient)
{
OpenSim_Main.localcons.WriteLine("World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent");
Avatar NewAvatar = new Avatar(AgentClient);
OpenSim_Main.localcons.WriteLine("World.cs:AddViewerAgent() - Adding new avatar to world");
@ -82,7 +102,8 @@ namespace OpenSim.world
this.Update(); // will work for now, but needs to be optimised so we don't update everything in the sim for each new user
}
public bool Backup() {
public bool Backup()
{
/* TODO: Save the current world entities state. */
return false;