diff --git a/AgentManager.cs b/AgentManager.cs
index 56d51a8509..84248139c7 100644
--- a/AgentManager.cs
+++ b/AgentManager.cs
@@ -26,24 +26,173 @@
*/
using System;
+using System.Collections.Generic;
using libsecondlife;
+using libsecondlife.Packets;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Manages Agent details.
///
public class AgentManager
{
- public AgentManager()
+ public Dictionary AgentList;
+ private uint _localNumber=0;
+ private Server _server;
+
+ public AgentManager(Server server)
{
+ _server=server;
+ this.AgentList = new Dictionary();
}
public AgentName GetAgentName(LLUUID AgentID)
{
- AgentName name = new AgentName();
+
+ AgentName name;
+ if(AgentList.ContainsKey(AgentID))
+ {
+ name=AgentList[AgentID].Name;
+ }
+ else
+ {
+ name = new AgentName();
+ }
return(name);
}
+
+ public AgentProfile GetAgent(LLUUID id)
+ {
+ if(!this.AgentList.ContainsKey(id))
+ {
+ return null;
+ }
+ else
+ {
+ AgentProfile avatar = this.AgentList[id];
+ return avatar;
+ }
+ }
+ ///
+ ///
+ ///
+ ///
+ public void AddAgent(AgentProfile agent)
+ {
+ this.AgentList.Add(agent.Avatar.FullID, agent);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool NewAgent(NetworkInfo userInfo, string first, string last, LLUUID baseFolder, LLUUID inventoryFolder)
+ {
+ Console.WriteLine("new agent called");
+ AgentProfile agent = new AgentProfile();
+ agent.Avatar.FullID = userInfo.User.AgentID;
+ agent.Avatar.NetInfo = userInfo;
+ agent.Avatar.NetInfo.User.FirstName =first;
+ agent.Avatar.NetInfo.User.LastName = last;
+ agent.Avatar.Position = new LLVector3(100, 100, 22);
+ agent.Avatar.BaseFolder = baseFolder;
+ agent.Avatar.InventoryFolder = inventoryFolder;
+ agent.Avatar.LocalID = 8880000 + this._localNumber;
+ this._localNumber++;
+ this.AgentList.Add(agent.Avatar.FullID, agent);
+
+ //Create new Wearable Assets and place in Inventory
+ //this.assetManager.CreateNewInventorySet(ref agent, userInfo);
+
+ return(true);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void RemoveAgent(NetworkInfo userInfo)
+ {
+ this.AgentList.Remove(userInfo.User.AgentID);
+
+ //tell other clients to delete this avatar
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void AgentJoin(NetworkInfo userInfo)
+ {
+ //inform client of join comlete
+ libsecondlife.Packets.AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
+ mov.AgentData.SessionID = userInfo.User.SessionID;
+ mov.AgentData.AgentID = userInfo.User.AgentID;
+ mov.Data.RegionHandle = Globals.Instance.RegionHandle;
+ mov.Data.Timestamp = 1169838966;
+ mov.Data.Position = new LLVector3(100f, 100f, 22f);
+ mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0);
+ _server.SendPacket(mov, true, userInfo);
+ }
+
+ public void RequestWearables(NetworkInfo userInfo)
+ {
+ AgentProfile Agent = this.AgentList[userInfo.User.AgentID];
+ AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
+ aw.AgentData.AgentID = userInfo.User.AgentID;
+ aw.AgentData.SerialNum = 0;
+ aw.AgentData.SessionID = userInfo.User.SessionID;
+
+ aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
+ AgentWearablesUpdatePacket.WearableDataBlock awb = null;
+ awb = new AgentWearablesUpdatePacket.WearableDataBlock();
+ awb.WearableType = (byte)0;
+ awb.AssetID = Agent.Avatar.Wearables[0].AssetID;
+ awb.ItemID = Agent.Avatar.Wearables[0].ItemID;
+ aw.WearableData[0] = awb;
+
+ awb = new AgentWearablesUpdatePacket.WearableDataBlock();
+ awb.WearableType =(byte)1;
+ awb.AssetID = Agent.Avatar.Wearables[1].AssetID;
+ awb.ItemID = Agent.Avatar.Wearables[1].ItemID;
+ aw.WearableData[1] = awb;
+
+ for(int i=2; i<13; i++)
+ {
+ awb = new AgentWearablesUpdatePacket.WearableDataBlock();
+ awb.WearableType = (byte)i;
+ awb.AssetID = new LLUUID("00000000-0000-0000-0000-000000000000");
+ awb.ItemID = new LLUUID("00000000-0000-0000-0000-000000000000");
+ aw.WearableData[i] = awb;
+ }
+
+ _server.SendPacket(aw, true, userInfo);
+ }
+
+ public void SendPacketToAllExcept(Packet packet, LLUUID exceptAgent)
+ {
+ foreach (KeyValuePair kp in this.AgentList)
+ {
+ if(kp.Value.Avatar.NetInfo.User.AgentID != exceptAgent)
+ {
+ _server.SendPacket(packet, true, kp.Value.Avatar.NetInfo);
+ }
+ }
+ }
+
+ public void SendPacketToALL(Packet packet)
+ {
+ foreach (KeyValuePair kp in this.AgentList)
+ {
+ _server.SendPacket(packet, true, kp.Value.Avatar.NetInfo);
+ }
+ }
}
public struct AgentName
@@ -54,9 +203,74 @@ namespace OpenSimLite
public class AgentProfile
{
+ public AgentName Name;
+ public AvatarData Avatar;
+ //public AgentInventory Inventory;
+
public AgentProfile()
+ {
+ Name = new AgentName();
+ Avatar = new AvatarData();
+ }
+ }
+
+ public class AvatarData : Node
+ {
+ public NetworkInfo NetInfo;
+ public LLUUID FullID;
+ public uint LocalID;
+ //public LLQuaternion Rotation;
+ public bool Walk = false;
+ public bool Started = false;
+ //public TextureEntry TextureEntry;
+ public AvatarWearable[] Wearables;
+ public LLUUID InventoryFolder;
+ public LLUUID BaseFolder;
+ public AvatarParams VisParams;
+
+ public List ObjectUpdateList;
+ public List TerseUpdateList;
+
+ public AvatarData()
+ {
+ Wearables=new AvatarWearable[2]; //should be 13
+ for(int i = 0; i < 2; i++)
+ {
+ Wearables[i] = new AvatarWearable();
+ }
+ this.SceneType = 1; //Avatar type
+
+ this.ObjectUpdateList = new List();
+ this.TerseUpdateList = new List();
+ VisParams = new AvatarParams();
+ }
+ }
+
+ public class AvatarWearable
+ {
+ public LLUUID AssetID;
+ public LLUUID ItemID;
+
+ public AvatarWearable()
{
}
}
+
+
+ public class AvatarParams
+ {
+ public byte[] Params;
+
+ public AvatarParams()
+ {
+ Params = new byte [ 218];
+ for(int i = 0; i < 218; i++)
+ {
+ Params[i] = 100;
+ }
+ }
+
+ }
+
}
diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs
index 88d8e1022e..d465bc69ed 100644
--- a/AssemblyInfo.cs
+++ b/AssemblyInfo.cs
@@ -8,11 +8,11 @@ using System.Runtime.InteropServices;
// change them to the information which is associated with the assembly
// you compile.
-[assembly: AssemblyTitle("OpenSimLite")]
+[assembly: AssemblyTitle("OpenSim")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("OpenSim project")]
-[assembly: AssemblyProduct("OpenSimLite")]
+[assembly: AssemblyProduct("OpenSim")]
[assembly: AssemblyCopyright("(c) OpenSim project")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
diff --git a/AssetManager.cs b/AssetManager.cs
index 81071901b8..e053eb8350 100644
--- a/AssetManager.cs
+++ b/AssetManager.cs
@@ -30,23 +30,33 @@ using System.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Manages local cache of assets and their sending to viewers.
///
- public class AssetManager
+ public class AssetManager : IAssetReceived
{
public Dictionary Assets;
public Dictionary Textures;
+
+ public List AssetRequests = new List(); //assets ready to be sent to viewers
+ public List TextureRequests = new List(); //textures ready to be sent
+
+ public List RequestedAssets = new List(); //Assets requested from the asset server
+ public List RequestedTextures = new List(); //Textures requested from the asset server
+
private AssetServer _assetServer;
+ private Server _server;
///
///
///
- public AssetManager(AssetServer assetServer)
+ public AssetManager(Server server, AssetServer assetServer)
{
- _assetServer=assetServer;
+ _server = server;
+ _assetServer = assetServer;
+ _assetServer.SetReceiver(this);
}
///
@@ -54,15 +64,8 @@ namespace OpenSimLite
///
private void RunAssetManager()
{
-
- }
-
- ///
- ///
- ///
- private void ProcessAssetQueue()
- {
-
+ this.ProcessAssetQueue();
+ this.ProcessTextureQueue();
}
///
@@ -70,9 +73,97 @@ namespace OpenSimLite
///
private void ProcessTextureQueue()
{
+ if(this.TextureRequests.Count == 0)
+ {
+ //no requests waiting
+ return;
+ }
+ int num;
+ //should be running in its own thread but for now is called by timer
+
+ if(this.TextureRequests.Count < 5)
+ {
+ //lower than 5 so do all of them
+ num = this.TextureRequests.Count;
+ }
+ else
+ {
+ num=5;
+ }
+ TextureRequest req;
+ for(int i = 0; i < num; i++)
+ {
+ req=(TextureRequest)this.TextureRequests[i];
+
+ if(req.PacketCounter == 0)
+ {
+ //first time for this request so send imagedata packet
+ if(req.NumPackets == 1)
+ {
+ //only one packet so send whole file
+ ImageDataPacket im = new ImageDataPacket();
+ im.ImageID.Packets = 1;
+ im.ImageID.ID = req.ImageInfo.FullID;
+ im.ImageID.Size = (uint)req.ImageInfo.Data.Length;
+ im.ImageData.Data = req.ImageInfo.Data;
+ im.ImageID.Codec = 2;
+ _server.SendPacket(im, true, req.RequestUser);
+ req.PacketCounter++;
+ //req.ImageInfo.l= time;
+ //System.Console.WriteLine("sent texture: "+req.image_info.FullID);
+ }
+ else
+ {
+ //more than one packet so split file up
+ ImageDataPacket im = new ImageDataPacket();
+ im.ImageID.Packets = (ushort)req.NumPackets;
+ im.ImageID.ID = req.ImageInfo.FullID;
+ im.ImageID.Size = (uint)req.ImageInfo.Data.Length;
+ im.ImageData.Data = new byte[600];
+ Array.Copy(req.ImageInfo.Data, 0, im.ImageData.Data, 0, 600);
+ im.ImageID.Codec = 2;
+ _server.SendPacket(im, true, req.RequestUser);
+ req.PacketCounter++;
+ //req.ImageInfo.last_used = time;
+ //System.Console.WriteLine("sent first packet of texture:
+ }
+ }
+ else
+ {
+ //send imagepacket
+ //more than one packet so split file up
+ ImagePacketPacket im = new ImagePacketPacket();
+ im.ImageID.Packet = (ushort)req.PacketCounter;
+ im.ImageID.ID = req.ImageInfo.FullID;
+ int size = req.ImageInfo.Data.Length - 600 - 1000*(req.PacketCounter - 1);
+ if(size > 1000) size = 1000;
+ im.ImageData.Data = new byte[size];
+ Array.Copy(req.ImageInfo.Data, 600 + 1000*(req.PacketCounter - 1), im.ImageData.Data, 0, size);
+ _server.SendPacket(im, true, req.RequestUser);
+ req.PacketCounter++;
+ //req.ImageInfo.last_used = time;
+ //System.Console.WriteLine("sent a packet of texture: "+req.image_info.FullID);
+ }
+ }
+
+ //remove requests that have been completed
+ for(int i = 0; i < num; i++)
+ {
+ req=(TextureRequest)this.TextureRequests[i];
+ if(req.PacketCounter == req.NumPackets)
+ {
+ this.TextureRequests.Remove(req);
+ }
+ }
}
-
+ public void AssetReceived(AssetBase asset)
+ {
+ //check if it is a texture or not
+ //then add to the correct cache list
+ //then check for waiting requests for this asset/texture (in the Requested lists)
+ //and move those requests into the Requests list.
+ }
#region Assets
///
///
@@ -81,8 +172,32 @@ namespace OpenSimLite
///
public void AddAssetRequest(NetworkInfo userInfo, TransferRequestPacket transferRequest)
{
- LLUUID RequestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
+ LLUUID requestID = new LLUUID(transferRequest.TransferInfo.Params, 0);
//check to see if asset is in local cache, if not we need to request it from asset server.
+ if(!this.Assets.ContainsKey(requestID))
+ {
+ //not found asset
+ // so request from asset server
+ AssetRequest request = new AssetRequest();
+ request.RequestUser = userInfo;
+ request.RequestImage = requestID;
+ this.AssetRequests.Add(request);
+ this._assetServer.RequestAsset(requestID);
+ return;
+ }
+ //it is in our cache
+ AssetInfo info = this.Assets[requestID];
+
+ //work out how many packets it should be sent in
+ // and add to the AssetRequests list
+ }
+
+ ///
+ ///
+ ///
+ private void ProcessAssetQueue()
+ {
+
}
#endregion
@@ -96,39 +211,72 @@ namespace OpenSimLite
public void AddTextureRequest(NetworkInfo userInfo, LLUUID imageID)
{
//check to see if texture is in local cache, if not request from asset server
+ if(!this.Textures.ContainsKey(imageID))
+ {
+ /*not found image so send back image not in data base message
+ ImageNotInDatabasePacket im_not = new ImageNotInDatabasePacket();
+ im_not.ImageID.ID=imageID;
+ _server.SendPacket(im_not, true, userInfo);*/
+
+ //not is cache so request from asset server
+ TextureRequest request = new TextureRequest();
+ request.RequestUser = userInfo;
+ request.RequestImage = imageID;
+ this.TextureRequests.Add(request);
+ this._assetServer.RequestAsset(imageID);
+ return;
+ }
+ TextureImage imag = this.Textures[imageID];
+ TextureRequest req = new TextureRequest();
+ req.RequestUser = userInfo;
+ req.RequestImage = imageID;
+ req.ImageInfo = imag;
+
+ if(imag.Data.LongLength>600)
+ {
+ //over 600 bytes so split up file
+ req.NumPackets = 1 + (int)(imag.Data.Length-600+999)/1000;
+ }
+ else
+ {
+ req.NumPackets = 1;
+ }
+
+ this.TextureRequests.Add(req);
}
#endregion
}
-
- public class AssetBase
+
+ public class AssetRequest
{
- public byte[] Data;
- public LLUUID FullID;
- public sbyte Type;
- public sbyte InvType;
- public string Name;
- public string Description;
- public string Filename;
+ public NetworkInfo RequestUser;
+ public LLUUID RequestImage;
+ public AssetInfo asset_inf;
+ public long data_pointer = 0;
+ public int num_packets = 0;
+ public int packet_counter = 0;
+ //public bool AssetInCache;
+ //public int TimeRequested;
- public AssetBase()
+ public AssetRequest()
{
}
}
- //needed?
- public class TextureImage
+ public class TextureRequest
{
- public TextureImage()
- {
-
- }
- }
-
- public class AssetInfo
- {
- public AssetInfo()
+ public NetworkInfo RequestUser;
+ public LLUUID RequestImage;
+ public TextureImage ImageInfo;
+ public long DataPointer = 0;
+ public int NumPackets = 0;
+ public int PacketCounter = 0;
+ //public bool TextureInCache;
+ //public int TimeRequested;
+
+ public TextureRequest()
{
}
diff --git a/AssetServer.cs b/AssetServer.cs
index 89b55f12bc..db6967ab47 100644
--- a/AssetServer.cs
+++ b/AssetServer.cs
@@ -26,14 +26,20 @@
*/
using System;
+using libsecondlife;
+using BerkeleyDb;
+using Kds.Serialization;
+using Kds.Serialization.Buffer;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Handles connection to Asset Server.
///
- public class AssetServer
+ public class AssetServer : IAssetServer
{
+ private IAssetReceived _receiver;
+
public AssetServer()
{
}
@@ -46,5 +52,71 @@ namespace OpenSimLite
}
}
+ public void SetReceiver(IAssetReceived receiver)
+ {
+ this._receiver = receiver;
+ }
+ public void RequestAsset(LLUUID assetID)
+ {
+ AssetBase asset = null;
+ byte[] dataBuffer = new byte[4096];
+ byte[] keyBuffer = new byte[256];
+ int index;
+ DbEntry keyEntry;
+ DbEntry dataEntry;
+ dataEntry = DbEntry.InOut(dataBuffer, 0, 4096);
+ index = 0;
+ BerkeleyDatabases.Instance.dbs.Formatter.Serialize(assetID.ToStringHyphenated(), keyBuffer, ref index);
+ byte[] co= new byte[44];
+ Array.Copy(keyBuffer,co,44);
+ keyEntry = DbEntry.InOut(co, 0, 44);
+ ReadStatus status = BerkeleyDatabases.Instance.dbs.AssetDb.Get(null, ref keyEntry, ref dataEntry, DbFile.ReadFlags.None);
+ if (status != ReadStatus.Success)
+ {
+ throw new ApplicationException("Read failed");
+ }
+ index = 0;
+ BerkeleyDatabases.Instance.dbs.Formatter.Deserialize(ref asset, dataEntry.Buffer, ref index);
+ this._receiver.AssetReceived( asset);
+ }
+ public void UpdateAsset(AssetBase asset)
+ {
+ //can we use UploadNewAsset to update as well?
+ this.UploadNewAsset(asset);
+ }
+ public void UploadNewAsset(AssetBase asset)
+ {
+ byte[] dataBuffer = new byte[4096];
+ byte[] keyBuffer = new byte[256];
+ int index;
+ DbEntry keyEntry;
+ DbEntry dataEntry;
+ index = 0;
+ BerkeleyDatabases.Instance.dbs.Formatter.Serialize(asset.FullID.ToStringHyphenated(), keyBuffer, ref index);
+ byte[] co= new byte[44];
+ Array.Copy(keyBuffer,co,44);
+ keyEntry = DbEntry.InOut(co, 0, 44);
+ index = 0;
+ BerkeleyDatabases.Instance.dbs.Formatter.Serialize(asset, dataBuffer, ref index);
+ dataEntry = DbEntry.InOut(dataBuffer, 0, index);
+ WriteStatus status = BerkeleyDatabases.Instance.dbs.AssetDb.Put(null, ref keyEntry, ref dataEntry, DbFile.WriteFlags.None);
+ if (status != WriteStatus.Success)
+ throw new ApplicationException("Put failed");
+ }
+
+ }
+
+ public interface IAssetServer
+ {
+ void SetReceiver(IAssetReceived receiver);
+ void RequestAsset(LLUUID assetID);
+ void UpdateAsset(AssetBase asset);
+ void UploadNewAsset(AssetBase asset);
+ }
+
+ // could change to delegate
+ public interface IAssetReceived
+ {
+ void AssetReceived(AssetBase asset);
}
}
diff --git a/Assets.cs b/Assets.cs
new file mode 100644
index 0000000000..a15c0e9fed
--- /dev/null
+++ b/Assets.cs
@@ -0,0 +1,105 @@
+/*
+* 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 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 ``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 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 libsecondlife;
+
+namespace OpenSim
+{
+ ///
+ /// Description of Assets.
+ ///
+ public class AssetBase
+ {
+ public byte[] Data;
+ public LLUUID FullID;
+ public sbyte Type;
+ public sbyte InvType;
+ public string Name;
+ public string Description;
+ public string Filename;
+
+ public AssetBase()
+ {
+
+ }
+ }
+
+ public class PrimAsset: AssetBase
+ {
+ public PrimData PrimData;
+
+ public PrimAsset()
+ {
+ this.PrimData = new PrimData();
+ }
+ }
+ public class PrimData
+ {
+ public LLUUID OwnerID;
+ public byte PCode;
+ public byte PathBegin;
+ public byte PathEnd;
+ public byte PathScaleX;
+ public byte PathScaleY;
+ public byte PathShearX;
+ public byte PathShearY;
+ public sbyte PathSkew;
+ public byte ProfileBegin;
+ public byte ProfileEnd;
+ public LLVector3 Scale;
+ public byte PathCurve;
+ public byte ProfileCurve;
+ public uint ParentID=0;
+ public byte ProfileHollow;
+ //public bool DataBaseStorage=false;
+
+ public PrimData()
+ {
+
+ }
+ }
+
+ //a hangover from the old code, so is it needed for future use?
+ public class TextureImage: AssetBase
+ {
+ public TextureImage()
+ {
+
+ }
+ }
+
+ //a hangover from the old code, so is it needed for future use?
+ public class AssetInfo :AssetBase
+ {
+ public AssetInfo()
+ {
+
+ }
+ }
+
+}
diff --git a/BerkeleyDatabase.cs b/BerkeleyDatabase.cs
new file mode 100644
index 0000000000..3456039097
--- /dev/null
+++ b/BerkeleyDatabase.cs
@@ -0,0 +1,205 @@
+/*
+* 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 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 ``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 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 libsecondlife;
+using BerkeleyDb;
+using System.IO;
+using Kds.Serialization;
+using Kds.Serialization.Buffer;
+
+namespace OpenSim
+{
+ ///
+ /// Description of BerkeleyDatabase.
+ ///
+ public class BerkeleyDatabases
+ {
+
+ public const string primDbName = "prim.db";
+ public const string assetDbName = "asset.db";
+
+
+ // will be initialized on first access to static field in a thread-safe way
+ private static readonly BerkeleyDatabases instance = new BerkeleyDatabases();
+ private FileStream errStream;
+ private string dbDir;
+ private DbBTree primDb;
+ private DbBTree assetDb;
+
+ // used for key gnerator call-backs, not thread-safe
+ private BEFormatter formatter;
+ private byte[] keyBuffer = new byte[2048];
+
+ private BerkeleyDatabases() {
+ formatter = new BEFormatter();
+ formatter.RegisterField(new PrimAssetField(formatter));
+ formatter.RegisterField(new AssetBaseField(formatter));
+
+ }
+ ~BerkeleyDatabases()
+ {
+ this.Close();
+ }
+
+ public BerkeleyDatabases dbs;
+
+ // singleton
+ public static BerkeleyDatabases Instance {
+ get { return instance; }
+ }
+
+ public void Open(string dbDir, string appName, Stream errStream) {
+ this.dbDir = dbDir;
+ //Remove();
+
+ // open local prim database
+ Db db = new Db(DbCreateFlags.None);
+ db.ErrorPrefix = appName;
+ db.ErrorStream = errStream;
+ primDb = (DbBTree)db.Open(null, PrimDbName, null, DbType.BTree, Db.OpenFlags.Create, 0);
+
+ //open asset server database
+ db = new Db(DbCreateFlags.None);
+ db.ErrorPrefix = appName;
+ db.ErrorStream = errStream;
+ assetDb = (DbBTree)db.Open(null, AssetDbName, null, DbType.BTree, Db.OpenFlags.Create, 0);
+
+ }
+
+ public void Remove() {
+ try {
+ Db db = new Db(DbCreateFlags.None);
+ db.Remove(PrimDbName, null);
+ }
+ catch { }
+
+ try {
+ Db db = new Db(DbCreateFlags.None);
+ db.Remove(AssetDbName, null);
+ }
+ catch { }
+
+ }
+
+ public void Close() {
+ if (primDb != null) {
+ primDb.GetDb().Close();
+ primDb = null;
+ }
+
+ if (assetDb != null) {
+ assetDb.GetDb().Close();
+ assetDb = null;
+ }
+
+ }
+
+ public BEFormatter Formatter {
+ get { return formatter; }
+ }
+
+ public string PrimDbName {
+ get { return Path.Combine(dbDir, primDbName); }
+ }
+
+ public DbBTree PrimDb {
+ get { return primDb; }
+ }
+
+ public string AssetDbName {
+ get { return Path.Combine(dbDir, assetDbName); }
+ }
+
+ public DbBTree AssetDb {
+ get { return assetDb; }
+ }
+
+ public void Startup()
+ {
+ dbs = BerkeleyDatabases.Instance;
+ string dbPath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Db");
+ string appName = Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
+ errStream = File.Open(Path.Combine(dbPath, "errors.txt"), FileMode.OpenOrCreate, FileAccess.Write);
+ dbs.Open(dbPath, appName, errStream);
+ }
+ }
+
+ public class PrimAssetField: ReferenceField
+ {
+ public PrimAssetField(Formatter formatter) : base(formatter) { }
+
+ protected override void SerializeValue(PrimAsset value) {
+ Formatter.Serialize(value.Name);
+ Formatter.Serialize(value.Description);
+
+ }
+
+ protected override void DeserializeInstance(ref PrimAsset instance) {
+ if (instance == null)
+ instance = new PrimAsset();
+ }
+
+ protected override void DeserializeMembers(PrimAsset instance) {
+ Formatter.Deserialize(ref instance.Name);
+ Formatter.Deserialize(ref instance.Description);
+
+ }
+
+ protected override void SkipValue() {
+ if (Formatter.Skip())
+ Formatter.Skip();
+ }
+ }
+
+ public class AssetBaseField: ReferenceField
+ {
+ public AssetBaseField(Formatter formatter) : base(formatter) { }
+
+ protected override void SerializeValue(AssetBase value) {
+ Formatter.Serialize(value.Name);
+ Formatter.Serialize(value.Description);
+
+ }
+
+ protected override void DeserializeInstance(ref AssetBase instance) {
+ if (instance == null)
+ instance = new AssetBase();
+ }
+
+ protected override void DeserializeMembers(AssetBase instance) {
+ Formatter.Deserialize(ref instance.Name);
+ Formatter.Deserialize(ref instance.Description);
+
+ }
+
+ protected override void SkipValue() {
+ if (Formatter.Skip())
+ Formatter.Skip();
+ }
+ }
+}
diff --git a/ClientConnection.cs b/ClientConnection.cs
index 89dcc425c1..bcda5991f9 100644
--- a/ClientConnection.cs
+++ b/ClientConnection.cs
@@ -31,7 +31,7 @@ using System.Threading;
using libsecondlife;
using libsecondlife.Packets;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Hanldes a single clients connection. Runs in own thread.
@@ -40,6 +40,9 @@ namespace OpenSimLite
{
public static GridManager Grid;
public static SceneGraph Scene;
+ public static AgentManager AgentManager;
+ public static PrimManager PrimManager;
+ public byte ConnectionType=1;
private Thread _mthread;
@@ -50,6 +53,7 @@ namespace OpenSimLite
public override void Start()
{
_mthread = new Thread(new ThreadStart(RunClientRead));
+ _mthread.IsBackground = true;
_mthread.Start();
}
@@ -64,16 +68,45 @@ namespace OpenSimLite
switch(packet.Type)
{
case PacketType.UseCircuitCode:
- //should be a new user joining
- Console.WriteLine("new agent");
+ Console.WriteLine("new circuit");
+ //should be a new user/circuit joining
+ // add agents profile to agentmanager
+ string first = "",last ="";
+ LLUUID baseFolder = null, inventoryFolder =null;
+
+ //rather than use IncomingLogins list, the logon object could be passed to this connection on creation
+ lock(Globals.Instance.IncomingLogins)
+ {
+ for(int i = 0; i < Globals.Instance.IncomingLogins.Count; i++)
+ {
+ if(Globals.Instance.IncomingLogins[i].Agent == this.NetInfo.User.AgentID)
+ {
+ first = Globals.Instance.IncomingLogins[i].First;
+ last = Globals.Instance.IncomingLogins[i].Last;
+ baseFolder = Globals.Instance.IncomingLogins[i].BaseFolder;
+ inventoryFolder = Globals.Instance.IncomingLogins[i].InventoryFolder;
+ Globals.Instance.IncomingLogins.RemoveAt(i);
+ break;
+ }
+ }
+ }
+ if(first != "")
+ {
+ AgentManager.NewAgent(this.NetInfo, first, last, baseFolder, inventoryFolder);
+ }
break;
case PacketType.CompleteAgentMovement:
//Agent completing movement to region
+ // so send region handshake
Grid.SendRegionData(this.NetInfo);
+ // send movmentcomplete reply
+ Scene.AgentCompletingMove(this.NetInfo);
break;
case PacketType.RegionHandshakeReply:
Console.WriteLine("RegionHandshake reply");
Scene.SendTerrainData(this.NetInfo);
+ Scene.AddNewAvatar(AgentManager.GetAgent(this.NetInfo.User.AgentID).Avatar);
+ // send current avatars and prims data
break;
default:
break;
@@ -82,7 +115,7 @@ namespace OpenSimLite
}
catch (Exception e)
{
- Console.WriteLine(e.Message);
+ Console.WriteLine(e.Message + ", So die!");
}
}
}
@@ -101,67 +134,5 @@ namespace OpenSimLite
{
}
- }
-
- public class BlockingQueue< T >
- {
- private Queue< T > _queue = new Queue< T >();
- private object _queueSync = new object();
-
- public void Enqueue(T value)
- {
- lock(_queueSync)
- {
- _queue.Enqueue(value);
- Monitor.Pulse(_queueSync);
- }
- }
-
- public T Dequeue()
- {
- lock(_queueSync)
- {
- if( _queue.Count < 1)
- Monitor.Wait(_queueSync);
-
- return _queue.Dequeue();
- }
- }
- }
-
- public class NonBlockingQueue< T >
- {
- private Queue< T > _queue = new Queue< T >();
- private object _queueSync = new object();
-
- public void Enqueue(T value)
- {
- lock(_queueSync)
- {
- _queue.Enqueue(value);
- }
- }
-
- public T Dequeue()
- {
- T rValue = default(T);
- lock(_queueSync)
- {
- if( _queue.Count > 0)
- {
- rValue = _queue.Dequeue();
- }
- }
- return rValue;
- }
-
- public int Count
- {
- get
- {
- return(_queue.Count);
- }
- }
- }
-
+ }
}
diff --git a/Controller.cs b/Controller.cs
index 608e2dd5e7..6dd5d72b69 100644
--- a/Controller.cs
+++ b/Controller.cs
@@ -31,7 +31,7 @@ using System.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
-namespace OpenSimLite
+namespace OpenSim
{
class Controller
{
@@ -40,29 +40,47 @@ namespace OpenSimLite
private LoginServer _loginServer;
private GridManager _gridManager;
private AgentManager _agentManager;
+ private AssetManager _assetManager;
private SceneGraph _scene;
+ private PrimManager _primManager;
public static void Main(string[] args)
{
Controller c = new Controller();
- while( true )
- System.Threading.Thread.Sleep( 1000 );
+ bool Run=true;
+ while( Run )
+ {
+
+ string input = Console.ReadLine();
+
+ if(input == "Exit")
+ {
+ Run = false;
+ }
+
+ }
+
+ BerkeleyDatabases.Instance.Close();
}
public Controller()
{
- _viewerServer = new Server();
_backboneServers = new BackboneServers();
- _agentManager = new AgentManager();
+ _viewerServer = new Server(_backboneServers.UserServer);
+ _agentManager = new AgentManager(_viewerServer);
_gridManager = new GridManager(_viewerServer, _agentManager);
- _scene = new SceneGraph(_viewerServer);
+ _scene = new SceneGraph(_viewerServer, _agentManager);
+ _assetManager = new AssetManager(_viewerServer, _backboneServers.AssetServer);
ClientConnection.Grid = _gridManager;
ClientConnection.Scene = _scene;
+ ClientConnection.AgentManager = _agentManager;
_viewerServer.Startup();
+ BerkeleyDatabases.Instance.Startup();
+ _primManager = new PrimManager();
if(Globals.Instance.StartLoginServer)
{
- _loginServer = new LoginServer();
+ _loginServer = new LoginServer(_backboneServers.UserServer);
_loginServer.Startup();
}
diff --git a/Globals.cs b/Globals.cs
index b79bb9017d..0f90e60001 100644
--- a/Globals.cs
+++ b/Globals.cs
@@ -29,7 +29,7 @@ using System;
using System.Collections.Generic;
using libsecondlife;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Description of Globals.
diff --git a/GridManager.cs b/GridManager.cs
index 31c10473cd..b45c1ff4d4 100644
--- a/GridManager.cs
+++ b/GridManager.cs
@@ -32,7 +32,7 @@ using libsecondlife;
using libsecondlife.Packets;
using System.Collections.Generic;
-namespace OpenSimLite
+namespace OpenSim
{
///
@@ -213,7 +213,7 @@ namespace OpenSimLite
}
///
- ///
+ /// most of this should be moved into the grid server class
///
private void LoadGrid()
{
diff --git a/GridServer.cs b/GridServer.cs
index 87a3b25ec3..3cfeba6bcc 100644
--- a/GridServer.cs
+++ b/GridServer.cs
@@ -26,17 +26,33 @@
*/
using System;
+using libsecondlife;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Handles connection to Grid Servers.
/// also Sim to Sim connections?
///
- public class GridServer
+ public class GridServer //:IGridServer
{
public GridServer()
{
}
}
+
+ public interface IGridServer
+ {
+ bool RequestConnection(RegionInfo myRegion);
+ UUIDBlock RequestUUIDBlock();
+ RegionInfo[] RequestNeighbours();
+ }
+
+ public struct UUIDBlock
+ {
+ public LLUUID BlockStart;
+ public LLUUID BlockEnd;
+ }
+
}
+
diff --git a/InstantMessaging.cs b/InstantMessaging.cs
index da40d86625..2ae51c7c7f 100644
--- a/InstantMessaging.cs
+++ b/InstantMessaging.cs
@@ -27,7 +27,7 @@
using System;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Description of InstantMessaging.
diff --git a/InventoryManager.cs b/InventoryManager.cs
index c6aedb605a..56f2759135 100644
--- a/InventoryManager.cs
+++ b/InventoryManager.cs
@@ -29,7 +29,7 @@ using System;
using System.Collections.Generic;
using libsecondlife;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Local cache of Inventories
diff --git a/LocalAssetCache.cs b/LocalAssetCache.cs
new file mode 100644
index 0000000000..35a40b0788
--- /dev/null
+++ b/LocalAssetCache.cs
@@ -0,0 +1,46 @@
+/*
+* 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 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 ``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 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
+{
+ ///
+ /// Description of LocalAssetCache.
+ ///
+ public class LocalAssetCache
+ {
+ public LocalAssetCache()
+ {
+ }
+ }
+
+ public interface ILocalCacheStorage
+ {
+ void SaveAsset(AssetBase asset);
+ }
+}
diff --git a/LocalStorageBase.cs b/LocalStorageBase.cs
new file mode 100644
index 0000000000..c062335e04
--- /dev/null
+++ b/LocalStorageBase.cs
@@ -0,0 +1,132 @@
+/*
+* 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 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 ``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 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 BerkeleyDb;
+using Kds.Serialization;
+using Kds.Serialization.Buffer;
+using libsecondlife;
+
+namespace OpenSim
+{
+ ///
+ /// Description of LocalPrimDB.
+ ///
+ ///
+ public class LocalPrimDb :ILocalPrimStorage
+ {
+ public LocalPrimDb()
+ {
+
+ }
+
+ public void LoadScene(IPrimReceiver receiver)
+ {
+
+ }
+ public void CreateNewPrimStorage(PrimAsset prim)
+ {
+ byte[] dataBuffer = new byte[4096];
+ byte[] keyBuffer = new byte[256];
+ int index;
+ DbEntry keyEntry;
+ DbEntry dataEntry;
+ index = 0;
+ BerkeleyDatabases.Instance.dbs.Formatter.Serialize(prim.FullID.ToStringHyphenated(), keyBuffer, ref index);
+ byte[] co= new byte[44];
+ Array.Copy(keyBuffer,co,44);
+ keyEntry = DbEntry.InOut(co, 0, 44);
+ index = 0;
+ BerkeleyDatabases.Instance.dbs.Formatter.Serialize(prim, dataBuffer, ref index);
+ dataEntry = DbEntry.InOut(dataBuffer, 0, index);
+ WriteStatus status = BerkeleyDatabases.Instance.dbs.PrimDb.Put(null, ref keyEntry, ref dataEntry, DbFile.WriteFlags.None);
+ if (status != WriteStatus.Success)
+ throw new ApplicationException("Put failed");
+
+ }
+ public void UpdatePrimStorage(PrimAsset prim)
+ {
+ //can we just use CreateNewPrimStorage to update a prim?
+ this.CreateNewPrimStorage(prim);
+ }
+ public void RemovePrimStorage()
+ {
+
+ }
+ public PrimAsset GetPrimFromStroage(LLUUID primID)
+ {
+ PrimAsset prim = null;
+ byte[] dataBuffer = new byte[4096];
+ byte[] keyBuffer = new byte[256];
+ int index;
+ DbEntry keyEntry;
+ DbEntry dataEntry;
+ dataEntry = DbEntry.InOut(dataBuffer, 0, 4096);
+ index = 0;
+ BerkeleyDatabases.Instance.dbs.Formatter.Serialize(primID.ToStringHyphenated(), keyBuffer, ref index);
+ byte[] co= new byte[44];
+ Array.Copy(keyBuffer,co,44);
+ keyEntry = DbEntry.InOut(co, 0, 44);
+ ReadStatus status = BerkeleyDatabases.Instance.dbs.PrimDb.Get(null, ref keyEntry, ref dataEntry, DbFile.ReadFlags.None);
+ if (status != ReadStatus.Success)
+ {
+ throw new ApplicationException("Read failed");
+ }
+ index = 0;
+ BerkeleyDatabases.Instance.dbs.Formatter.Deserialize(ref prim, dataEntry.Buffer, ref index);
+ return prim;
+ }
+
+ ///
+ /// test function
+ ///
+ public void ReadWholedatabase()
+ {
+ foreach (KeyDataPair entry in BerkeleyDatabases.Instance.dbs.PrimDb.OpenCursor(null, DbFileCursor.CreateFlags.None)) {
+ PrimAsset vendor = null;
+ int index = entry.Data.Start;
+ BerkeleyDatabases.Instance.dbs.Formatter.Deserialize(ref vendor, entry.Data.Buffer, ref index);
+ Console.WriteLine("prim found: "+vendor.Name + " "+ vendor.Description);
+ }
+ }
+ }
+
+ public interface ILocalPrimStorage
+ {
+ void LoadScene(IPrimReceiver receiver);
+ void CreateNewPrimStorage(PrimAsset prim);
+ void UpdatePrimStorage(PrimAsset prim);
+ void RemovePrimStorage();
+ PrimAsset GetPrimFromStroage(LLUUID primID);
+ }
+
+ //change to delegate?
+ public interface IPrimReceiver
+ {
+ void ReceivePrim(PrimAsset prim);
+ }
+}
diff --git a/LoginServer.cs b/LoginServer.cs
index c5ac284afd..8b2c0a3967 100644
--- a/LoginServer.cs
+++ b/LoginServer.cs
@@ -37,18 +37,19 @@ using System.Collections;
using System.Xml;
using libsecondlife;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// When running in local (default) mode , handles client logins.
///
public class LoginServer
{
- public LoginServer()
+ public LoginServer(UserServer userServer)
{
-
+ _userServer = userServer;
}
private Logon _login;
+ private UserServer _userServer;
private ushort _loginPort = Globals.Instance.LoginServerPort;
public IPAddress clientAddress = IPAddress.Loopback;
public IPAddress remoteAddress = IPAddress.Any;
@@ -58,7 +59,7 @@ namespace OpenSimLite
private string _defaultResponse;
private string _mpasswd;
- private bool _needPassswd=false;
+ private bool _needPasswd=false;
// InitializeLoginProxy: initialize the login proxy
private void InitializeLoginProxy() {
@@ -66,7 +67,7 @@ namespace OpenSimLite
loginServer.Bind(new IPEndPoint(remoteAddress, _loginPort));
loginServer.Listen(1);
- this._needPassswd=Globals.Instance.NeedPasswd;
+ this._needPasswd=Globals.Instance.NeedPasswd;
//read in default response string
StreamReader SR;
string lines;
@@ -94,7 +95,7 @@ namespace OpenSimLite
private void RunLoginProxy()
{
- Console.WriteLine("Starting Login Sever");
+ Console.WriteLine("Starting Login Server");
try
{
for (;;)
@@ -145,7 +146,7 @@ namespace OpenSimLite
{
// read one line of the header
line = reader.ReadLine();
-
+
// check for premature EOF
if (line == null)
throw new Exception("EOF in client HTTP header");
@@ -157,7 +158,6 @@ namespace OpenSimLite
} while (line != "");
// read the HTTP body into a buffer
- this._login = new Logon();
char[] content = new char[contentLength];
reader.Read(content, 0, contentLength);
@@ -180,6 +180,7 @@ namespace OpenSimLite
{
first = "test";
}
+
if(requestData.Contains("last"))
{
last = (string)requestData["last"];
@@ -188,6 +189,7 @@ namespace OpenSimLite
{
last = "User"+NumClients.ToString();
}
+
if(requestData.Contains("passwd"))
{
passwd = (string)requestData["passwd"];
@@ -235,6 +237,7 @@ namespace OpenSimLite
CustomiseLoginResponse( responseData, first, last );
+ this._login = new Logon();
//copy data to login object
_login.First = first;
_login.Last = last;
@@ -243,9 +246,10 @@ namespace OpenSimLite
_login.BaseFolder = BaseFolderID;
_login.InventoryFolder = InventoryFolderID;
- lock(Globals.Instance.IncomingLogins)
+ //working on local computer so lets add to the userserver's list of sessions
+ lock(this._userServer.Sessions)
{
- Globals.Instance.IncomingLogins.Add(_login);
+ this._userServer.Sessions.Add(_login);
}
// forward the XML-RPC response to the client
@@ -279,11 +283,11 @@ namespace OpenSimLite
protected virtual bool Authenticate(string first, string last, string passwd)
{
- if(this._needPassswd)
+ if(this._needPasswd)
{
//every user needs the password to login
- string encodedpass = passwd.Remove(0,3); //remove $1$
- if(encodedpass == this._mpasswd)
+ string encodedPass = passwd.Remove(0,3); //remove $1$
+ if(encodedPass == this._mpasswd)
{
return true;
}
@@ -294,7 +298,7 @@ namespace OpenSimLite
}
else
{
- //not need password to login
+ //do not need password to login
return true;
}
}
diff --git a/OpenSimLite.csproj b/OpenSimLite.csproj
index 3833a9f06d..50081a135c 100644
--- a/OpenSimLite.csproj
+++ b/OpenSimLite.csproj
@@ -1,8 +1,8 @@
Exe
- OpenSimLite
- OpenSimLite
+ OpenSim
+ OpenSim
Debug
AnyCPU
{782CCAFD-7313-4638-ADAC-53703DF24DF0}
@@ -31,6 +31,14 @@
bin\Debug\libsecondlife.dll
False
+
+ bin\Debug\libdb_dotNET43.dll
+ False
+
+
+ bin\Debug\Kds.Serialization.dll
+ False
+
@@ -52,6 +60,10 @@
+
+
+
+
\ No newline at end of file
diff --git a/PhysicsManager.cs b/PhysicsManager.cs
index 62e2016bd0..991be5a787 100644
--- a/PhysicsManager.cs
+++ b/PhysicsManager.cs
@@ -27,7 +27,7 @@
using System;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Description of PhysicsManager.
diff --git a/PrimManager.cs b/PrimManager.cs
index 27a77de8ef..b861d22aff 100644
--- a/PrimManager.cs
+++ b/PrimManager.cs
@@ -26,16 +26,34 @@
*/
using System;
+using libsecondlife;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Manages and provides local cache of Prims.
///
public class PrimManager
{
+ private LocalPrimDb _localPrimDB;
+
public PrimManager()
{
+ this._localPrimDB = new LocalPrimDb();
+
+
+ //database test
+ /*PrimAsset prim = new PrimAsset();
+ prim.Name="happy now";
+ prim.Description= "test";
+ prim.FullID = new LLUUID("00000000-0000-0000-0000-000000000008");
+ this._localPrimDB.CreateNewPrimStorage(prim);
+
+ PrimAsset prim1 = this._localPrimDB.GetPrimFromStroage( new LLUUID("00000000-0000-0000-0000-000000000008"));
+ Console.WriteLine("prim recieved : "+prim1.Name + " "+ prim1.Description);
+ */
+ //this._localPrimDB.ReadWholedatabase();
}
+
}
}
diff --git a/SceneGraph.cs b/SceneGraph.cs
index 1ff47176c5..547388422e 100644
--- a/SceneGraph.cs
+++ b/SceneGraph.cs
@@ -32,7 +32,7 @@ using System.Threading;
using libsecondlife;
using libsecondlife.Packets;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Manages prim and avatar sim positions and movements and updating clients
@@ -45,7 +45,10 @@ namespace OpenSimLite
private Server _server;
private System.Text.Encoding _enc = System.Text.Encoding.ASCII;
private libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock _avatarTemplate;
-
+ private int _objectCount=0;
+ private UpdateSender _updateSender;
+ private AgentManager _agentManager;
+
public NonBlockingQueue Commands;
@@ -54,21 +57,112 @@ namespace OpenSimLite
private object _sendTerrainSync = new object();
#endregion
- public SceneGraph(Server server)
+ public SceneGraph(Server server, AgentManager agentManager)
{
_server = server;
RootNode = new Node();
_physics = new PhysicsManager(this);
Commands = new NonBlockingQueue();
Terrain = new Terrain();
-
+ _updateSender = new UpdateSender(_server, agentManager);
+ _agentManager = agentManager;
//testing
this.SetupTemplate("objectupate168.dat");
+ _updateSender.Startup();
}
public void Update()
{
+ // run physics engine to update positions etc since last frame
+ // process command list
+ lock(this.Commands) //do we want to stop new commands being added while we process?
+ {
+ while(this.Commands.Count > 0)
+ {
+ UpdateCommand command = this.Commands.Dequeue();
+ switch(command.CommandType)
+ {
+ case 1:
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ // check to see if any new avatars have joined since last frame
+ //if so send data to clients.
+ lock(this.RootNode)
+ {
+ for (int i = 0; i < this.RootNode.ChildrenCount; i++)
+ {
+ //for now we will limit avatars to being a child of the rootnode
+ if(this.RootNode.GetChild(i).SceneType == 1) //check it is a avatar node
+ {
+ AvatarData avatar =(AvatarData) this.RootNode.GetChild(i);
+ int updatemask = avatar.UpdateFlag & (128);
+ if(updatemask == 128) //is a new avatar?
+ {
+ this.SendAvatarDataToAll(avatar);
+
+ //should send a avatar appearance to other clients except the avatar's owner
+
+ //and send complete scene update to the new avatar's owner
+ this.SendCompleteSceneTo(avatar);
+
+ //reset new avatar flag
+ //avatar.UpdateFlag -= 128;
+ }
+ }
+ }
+ }
+
+ //send updates to clients
+ //might be better to do these updates reverse to how is done here
+ // ie.. loop through the avatars and find objects /other avatars in their range/vision
+ //instead of looping through all objects/avatars and then finding avatars in range
+ //but that would mean looping through all objects/avatar for each avatar,
+ //rather than looping through just the avatars for each object/avatar
+ lock(this.RootNode)
+ {
+ for (int i = 0; i < this.RootNode.ChildrenCount; i++)
+ {
+ if(this.RootNode.GetChild(i).SceneType == 1) //check it is a avatar node
+ {
+ AvatarData avatar =(AvatarData) this.RootNode.GetChild(i);
+ int updatemask = avatar.UpdateFlag & (1);
+ if(updatemask == 1)
+ {
+ //avatar has changed velocity
+ //check what avatars are in range and add to their update lists
+ //but for now we will say all avatars are in range
+ for (int n = 0; n < this.RootNode.ChildrenCount; n++)
+ {
+ if(this.RootNode.GetChild(n).SceneType == 1) //check it is a avatar node
+ {
+ AvatarData avatar2 =(AvatarData) this.RootNode.GetChild(i);
+ int newmask = avatar2.UpdateFlag & (128);
+ if(newmask != 128) //is a new avatar?
+ {
+ //no its not so let add to its updatelist
+ avatar2.TerseUpdateList.Add(this.CreateTerseBlock(avatar));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //now reset all update flags
+ lock(this.RootNode)
+ {
+ for (int i = 0; i < this.RootNode.ChildrenCount; i++)
+ {
+ this.RootNode.GetChild(i).UpdateFlag = 0;
+ }
+ }
}
#region send terrain data
@@ -80,13 +174,15 @@ namespace OpenSimLite
{
lock(this._sendTerrainSync)
{
- string data_path = System.AppDomain.CurrentDomain.BaseDirectory + @"\layer_data\";
+ string data_path = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory ,"layer_data" );
//send layerdata
LayerDataPacket layerpack = new LayerDataPacket();
layerpack.LayerID.Type = 76;
- this.SendLayerData(userInfo, layerpack, data_path+@"layerdata0.dat");
+ this.SendLayerData(userInfo, layerpack, Path.Combine(data_path,"layerdata0.dat"));
Console.WriteLine("Sent terrain data");
+
+ //test
this.SendAvatarData(userInfo);
}
}
@@ -112,6 +208,32 @@ namespace OpenSimLite
}
#endregion
+ public void AgentCompletingMove(NetworkInfo userInfo)
+ {
+ libsecondlife.Packets.AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
+ mov.AgentData.SessionID = userInfo.User.SessionID;
+ mov.AgentData.AgentID = userInfo.User.AgentID;
+ mov.Data.RegionHandle = Globals.Instance.RegionHandle;
+ mov.Data.Timestamp = 1169838966;
+ mov.Data.Position = new LLVector3(100f, 100f, 22f);
+ mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0);
+ _server.SendPacket(mov, true, userInfo);
+ }
+
+ public void AddNewAvatar(AvatarData avatar)
+ {
+ lock(this.RootNode)
+ {
+ avatar.SceneName = "Avatar" + this._objectCount.ToString("00000");
+ this._objectCount++;
+ this.RootNode.AddChild(avatar);
+ }
+ avatar.UpdateFlag = 128;
+
+ //add to new clients list?
+
+ }
+
#region testing
//test only
private void SendAvatarData(NetworkInfo userInfo)
@@ -132,7 +254,7 @@ namespace OpenSimLite
//userInfo.User.FullName = "FirstName STRING RW SV " + userInfo.first_name + "\nLastName STRING RW SV " + userInfo.last_name + " \0";
libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100.0f, 22.0f);
- byte[] pb = pos2.GetBytes();
+ byte[] pb = pos2.GetBytes();
Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
//this._localNumber++;
@@ -142,7 +264,7 @@ namespace OpenSimLite
//test only
private void SetupTemplate(string name)
{
-
+ //should be replaced with completely code generated packets
int i = 0;
FileInfo fInfo = new FileInfo(name);
long numBytes = fInfo.Length;
@@ -168,7 +290,44 @@ namespace OpenSimLite
}
#endregion
+ private void SendAvatarDataToAll(AvatarData avatar)
+ {
+ ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
+ objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle;
+ objupdate.RegionData.TimeDilation = 0;
+ objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
+
+ objupdate.ObjectData[0] = _avatarTemplate;
+ objupdate.ObjectData[0].ID = avatar.LocalID;
+ objupdate.ObjectData[0].FullID = avatar.NetInfo.User.AgentID;
+ objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + avatar.NetInfo.User.FirstName + "\nLastName STRING RW SV " + avatar.NetInfo.User.LastName + " \0");
+
+ libsecondlife.LLVector3 pos2 = new LLVector3(100f, 100.0f, 22.0f);
+ byte[] pb = pos2.GetBytes();
+ Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
+
+ SendInfo send = new SendInfo();
+ send.Incr = true;
+ send.NetInfo = avatar.NetInfo;
+ send.Packet = objupdate;
+ send.SentTo = 1; //to all clients
+ this._updateSender.SendList.Enqueue(send);
+ }
+ public void SendCompleteSceneTo(AvatarData avatar)
+ {
+
+ }
+
+ public ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateTerseBlock(AvatarData avatar)
+ {
+ return(null);
+ }
+
+ public void SendAvatarAppearanceToAllExcept(AvatarData avatar)
+ {
+
+ }
}
//any need for separate nodes and sceneobjects?
@@ -176,7 +335,12 @@ namespace OpenSimLite
public class Node
{
private List _children;
- private List _attached;
+ //private List _attached;
+ public byte SceneType;
+ public string SceneName;
+ public LLVector3 Position;
+ public LLVector3 Velocity = new LLVector3(0,0,0);
+ public byte UpdateFlag;
public List ChildNodes
{
@@ -186,6 +350,14 @@ namespace OpenSimLite
}
}
+ public int ChildrenCount
+ {
+ get
+ {
+ return(_children.Count);
+ }
+ }
+ /*
public List AttachedObjexts
{
get
@@ -193,13 +365,13 @@ namespace OpenSimLite
return(_attached);
}
}
-
+ */
public Node()
{
_children = new List();
- _attached = new List();
+ //_attached = new List();
}
-
+ /*
///
///
///
@@ -252,6 +424,7 @@ namespace OpenSimLite
}
return(rValue);
}
+ */
///
///
@@ -289,15 +462,18 @@ namespace OpenSimLite
}
}
+ /*
public class SceneObject
{
public byte SceneType;
+ public string SceneName;
public SceneObject()
{
}
- }
+ }*/
+
public class Terrain
{
@@ -326,7 +502,7 @@ namespace OpenSimLite
public class UpdateCommand
{
public byte CommandType;
- public SceneObject SObject;
+ public Node SObject;
public LLVector3 Position;
public LLVector3 Velocity;
public LLQuaternion Rotation;
@@ -341,29 +517,63 @@ namespace OpenSimLite
{
public BlockingQueue SendList;
private Thread mthread;
+ private Server _server;
+ private AgentManager _agentManager;
- public UpdateSender()
+ public UpdateSender(Server server, AgentManager agentManager)
{
SendList = new BlockingQueue();
+ _server = server;
+ _agentManager = agentManager;
}
public void Startup()
{
mthread = new Thread(new System.Threading.ThreadStart(RunSender));
+ mthread.IsBackground = true;
mthread.Start();
}
private void RunSender()
{
-
+ //process SendList and send packets to clients
+ try
+ {
+ for(;;)
+ {
+ SendInfo sendInfo;
+ sendInfo = this.SendList.Dequeue();
+
+ switch(sendInfo.SentTo)
+ {
+ case 0:
+ this._server.SendPacket(sendInfo.Packet, sendInfo.Incr, sendInfo.NetInfo);
+ break;
+ case 1:
+ this._agentManager.SendPacketToALL(sendInfo.Packet);
+ break;
+ case 2:
+ this._agentManager.SendPacketToAllExcept(sendInfo.Packet, sendInfo.NetInfo.User.AgentID);
+ break;
+ default:
+ break;
+ }
+
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
}
}
public class SendInfo
{
public Packet Packet;
- public bool Incr;
+ public bool Incr = true;
public NetworkInfo NetInfo;
+ public byte SentTo = 0; // 0 just this client, 1 to all clients, 2 to all except this client.
public SendInfo()
{
diff --git a/ScriptManager.cs b/ScriptManager.cs
index 656fdd2de7..654249bb7c 100644
--- a/ScriptManager.cs
+++ b/ScriptManager.cs
@@ -27,7 +27,7 @@
using System;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Description of ScriptManager.
@@ -39,10 +39,10 @@ namespace OpenSimLite
}
}
- public interface ScriptPlugin
+ public interface IScriptPlugin
{
- ScriptObject ICompileScript(string script);
- bool IStart();
+ ScriptObject CompileScript(string script);
+ bool Start();
}
public interface ScriptObject
diff --git a/UserServer.cs b/UserServer.cs
index f272ed2991..f6671438e9 100644
--- a/UserServer.cs
+++ b/UserServer.cs
@@ -26,17 +26,21 @@
*/
using System;
+using libsecondlife;
+using System.Collections.Generic;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Handles connection to User Servers
///
///
- public class UserServer
+ public class UserServer :IUserServer
{
+ public List Sessions = new List(); //should change to something other than logon classes?
public UserServer()
{
+ Sessions = new List();
}
private void Initialise()
@@ -47,5 +51,46 @@ namespace OpenSimLite
}
}
+
+ public AuthenticateResponse AuthenticateSession(LLUUID sessionID, LLUUID agentID, uint circuitCode)
+ {
+ //For Grid use:
+ //should check to see if it is a teleportation, if so then we should be expecting this session, agent. (?)
+ //if not check with User server/ login server that it is authorised.
+
+ //but for now we are running local
+ AuthenticateResponse user = new AuthenticateResponse();
+
+ lock(this.Sessions)
+ {
+
+ for(int i = 0; i < Sessions.Count; i++)
+ {
+ if((Sessions[i].Agent == agentID) && (Sessions[i].Session == sessionID))
+ {
+ user.Authorised = true;
+ user.LogonInfo = Sessions[i];
+ }
+ }
+ }
+ return(user);
+ }
+ }
+
+ public interface IUserServer
+ {
+ AuthenticateResponse AuthenticateSession(LLUUID sessionID, LLUUID agentID, uint circuitCode);
+ }
+
+ public class AuthenticateResponse
+ {
+ public bool Authorised;
+ public Logon LogonInfo;
+
+ public AuthenticateResponse()
+ {
+
+ }
+
}
}
diff --git a/Utility.cs b/Utility.cs
index d657764e4f..1549f11006 100644
--- a/Utility.cs
+++ b/Utility.cs
@@ -27,10 +27,12 @@
using System;
using System.Text;
+using System.Collections.Generic;
+using System.Threading;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Description of Utility.
@@ -54,4 +56,65 @@ namespace OpenSimLite
return Regex.Replace(BitConverter.ToString(encodedBytes), "-", "").ToLower();
}
}
+
+ public class BlockingQueue< T >
+ {
+ private Queue< T > _queue = new Queue< T >();
+ private object _queueSync = new object();
+
+ public void Enqueue(T value)
+ {
+ lock(_queueSync)
+ {
+ _queue.Enqueue(value);
+ Monitor.Pulse(_queueSync);
+ }
+ }
+
+ public T Dequeue()
+ {
+ lock(_queueSync)
+ {
+ if( _queue.Count < 1)
+ Monitor.Wait(_queueSync);
+
+ return _queue.Dequeue();
+ }
+ }
+ }
+
+ public class NonBlockingQueue< T >
+ {
+ private Queue< T > _queue = new Queue< T >();
+ private object _queueSync = new object();
+
+ public void Enqueue(T value)
+ {
+ lock(_queueSync)
+ {
+ _queue.Enqueue(value);
+ }
+ }
+
+ public T Dequeue()
+ {
+ T rValue = default(T);
+ lock(_queueSync)
+ {
+ if( _queue.Count > 0)
+ {
+ rValue = _queue.Dequeue();
+ }
+ }
+ return rValue;
+ }
+
+ public int Count
+ {
+ get
+ {
+ return(_queue.Count);
+ }
+ }
+ }
}
diff --git a/ViewerServer.cs b/ViewerServer.cs
index d39f459b84..9a689906d1 100644
--- a/ViewerServer.cs
+++ b/ViewerServer.cs
@@ -35,7 +35,7 @@ using System.Net;
using System.Net.Sockets;
using System.Timers;
-namespace OpenSimLite
+namespace OpenSim
{
///
/// Manages Viewer connections
@@ -55,7 +55,7 @@ namespace OpenSimLite
}
}*/
- //for now though, we will use a slightly adapted version of the server
+ //for now though, we will use a adapted version of the server
// class from version 0.1
public class Server
{
@@ -66,6 +66,7 @@ namespace OpenSimLite
/// The Region class that this Simulator wraps
// public Region Region;
+ private object _sendPacketSync = new object();
///
/// Used internally to track sim disconnections, do not modify this
/// variable
@@ -116,13 +117,14 @@ namespace OpenSimLite
private System.Timers.Timer AckTimer;
private Server_Settings Settings=new Server_Settings();
public ArrayList User_agents=new ArrayList();
+ private IUserServer _userServer;
///
///
///
- public Server()
+ public Server(IUserServer userServer)
{
-
+ this._userServer = userServer;
}
///
@@ -207,110 +209,113 @@ namespace OpenSimLite
/// Increment sequence number?
public void SendPacket(Packet packet, bool incrementSequence, NetworkInfo User_info)
{
- byte[] buffer;
- int bytes;
-
- if (!connected && packet.Type != PacketType.UseCircuitCode)
+ lock(this._sendPacketSync)
{
- // Client.Log("Trying to send a " + packet.Type.ToString() + " packet when the socket is closed",
- // Helpers.LogLevel.Info);
+ byte[] buffer;
+ int bytes;
- return;
- }
-
- if (packet.Header.AckList.Length > 0)
- {
- // Scrub any appended ACKs since all of the ACK handling is done here
- packet.Header.AckList = new uint[0];
- }
- packet.Header.AppendedAcks = false;
-
- // Keep track of when this packet was sent out
- packet.TickCount = Environment.TickCount;
-
- if (incrementSequence)
- {
- // Set the sequence number
- lock (SequenceLock)
+ if (!connected && packet.Type != PacketType.UseCircuitCode)
{
- if (Sequence > Settings.MAX_SEQUENCE)
- Sequence = 1;
- else
- Sequence++;
- packet.Header.Sequence = Sequence;
+ // Client.Log("Trying to send a " + packet.Type.ToString() + " packet when the socket is closed",
+ // Helpers.LogLevel.Info);
+
+ return;
}
- if (packet.Header.Reliable)
+ if (packet.Header.AckList.Length > 0)
{
- lock (User_info.NeedAck)
+ // Scrub any appended ACKs since all of the ACK handling is done here
+ packet.Header.AckList = new uint[0];
+ }
+ packet.Header.AppendedAcks = false;
+
+ // Keep track of when this packet was sent out
+ packet.TickCount = Environment.TickCount;
+
+ if (incrementSequence)
+ {
+ // Set the sequence number
+ lock (SequenceLock)
{
- if (!User_info.NeedAck.ContainsKey(packet.Header.Sequence))
- {
- User_info.NeedAck.Add(packet.Header.Sequence, packet);
- }
+ if (Sequence > Settings.MAX_SEQUENCE)
+ Sequence = 1;
else
- {
- // Client.Log("Attempted to add a duplicate sequence number (" +
- // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
- // packet.Type.ToString(), Helpers.LogLevel.Warning);
- }
+ Sequence++;
+ packet.Header.Sequence = Sequence;
}
- // Don't append ACKs to resent packets, in case that's what was causing the
- // delivery to fail
- if (!packet.Header.Resent)
+ if (packet.Header.Reliable)
{
- // Append any ACKs that need to be sent out to this packet
- lock (User_info.PendingAcks)
+ lock (User_info.NeedAck)
{
- if (User_info.PendingAcks.Count > 0 && User_info.PendingAcks.Count < Settings.MAX_APPENDED_ACKS &&
- packet.Type != PacketType.PacketAck &&
- packet.Type != PacketType.LogoutRequest)
+ if (!User_info.NeedAck.ContainsKey(packet.Header.Sequence))
{
- packet.Header.AckList = new uint[User_info.PendingAcks.Count];
- int i = 0;
-
- foreach (uint ack in User_info.PendingAcks.Values)
- {
- packet.Header.AckList[i] = ack;
- i++;
- }
+ User_info.NeedAck.Add(packet.Header.Sequence, packet);
+ }
+ else
+ {
+ // Client.Log("Attempted to add a duplicate sequence number (" +
+ // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
+ // packet.Type.ToString(), Helpers.LogLevel.Warning);
+ }
+ }
- User_info.PendingAcks.Clear();
- packet.Header.AppendedAcks = true;
+ // Don't append ACKs to resent packets, in case that's what was causing the
+ // delivery to fail
+ if (!packet.Header.Resent)
+ {
+ // Append any ACKs that need to be sent out to this packet
+ lock (User_info.PendingAcks)
+ {
+ if (User_info.PendingAcks.Count > 0 && User_info.PendingAcks.Count < Settings.MAX_APPENDED_ACKS &&
+ packet.Type != PacketType.PacketAck &&
+ packet.Type != PacketType.LogoutRequest)
+ {
+ packet.Header.AckList = new uint[User_info.PendingAcks.Count];
+ int i = 0;
+
+ foreach (uint ack in User_info.PendingAcks.Values)
+ {
+ packet.Header.AckList[i] = ack;
+ i++;
+ }
+
+ User_info.PendingAcks.Clear();
+ packet.Header.AppendedAcks = true;
+ }
}
}
}
}
- }
- // Serialize the packet
- buffer = packet.ToBytes();
- bytes = buffer.Length;
+ // Serialize the packet
+ buffer = packet.ToBytes();
+ bytes = buffer.Length;
- try
- {
- // Zerocode if needed
- if (packet.Header.Zerocoded)
+ try
{
- lock (ZeroOutBuffer)
+ // Zerocode if needed
+ if (packet.Header.Zerocoded)
{
- bytes = Helpers.ZeroEncode(buffer, bytes, ZeroOutBuffer);
- Connection.SendTo(ZeroOutBuffer, bytes, SocketFlags.None,User_info.endpoint);
+ lock (ZeroOutBuffer)
+ {
+ bytes = Helpers.ZeroEncode(buffer, bytes, ZeroOutBuffer);
+ Connection.SendTo(ZeroOutBuffer, bytes, SocketFlags.None,User_info.endpoint);
+ }
+ }
+ else
+ {
+
+ Connection.SendTo(buffer, bytes, SocketFlags.None,User_info.endpoint);
}
}
- else
+ catch (SocketException)
{
-
- Connection.SendTo(buffer, bytes, SocketFlags.None,User_info.endpoint);
- }
- }
- catch (SocketException)
- {
- //Client.Log("Tried to send a " + packet.Type.ToString() + " on a closed socket",
- // Helpers.LogLevel.Warning);
+ //Client.Log("Tried to send a " + packet.Type.ToString() + " on a closed socket",
+ // Helpers.LogLevel.Warning);
- Disconnect();
+ Disconnect();
+ }
}
}
@@ -425,6 +430,23 @@ namespace OpenSimLite
{
//new connection
UseCircuitCodePacket cir_pack=(UseCircuitCodePacket)packet;
+ //should check that this session/circuit is authorised
+ AuthenticateResponse sessionInfo = this._userServer.AuthenticateSession(cir_pack.CircuitCode.SessionID, cir_pack.CircuitCode.ID, cir_pack.CircuitCode.Code);
+ if(!sessionInfo.Authorised)
+ {
+ //session/circuit not authorised
+ //so do something about it
+ }
+ else
+ {
+ //is authorised so add the logon object to the incominglogin list
+ //should be a better way of doing this now the login server connects to the user server
+ // like passing the logon object straight to the ClientConnection
+ lock(Globals.Instance.IncomingLogins)
+ {
+ Globals.Instance.IncomingLogins.Add(sessionInfo.LogonInfo);
+ }
+ }
NetworkInfo new_user=new NetworkInfo();
new_user.CircuitCode=cir_pack.CircuitCode.Code;
new_user.User.AgentID=cir_pack.CircuitCode.ID;