started using BerkeleyDB as local database
parent
b8822e4340
commit
4be3f7c49b
220
AgentManager.cs
220
AgentManager.cs
|
@ -26,24 +26,173 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using libsecondlife;
|
||||
using libsecondlife.Packets;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages Agent details.
|
||||
/// </summary>
|
||||
public class AgentManager
|
||||
{
|
||||
public AgentManager()
|
||||
public Dictionary<libsecondlife.LLUUID,AgentProfile> AgentList;
|
||||
private uint _localNumber=0;
|
||||
private Server _server;
|
||||
|
||||
public AgentManager(Server server)
|
||||
{
|
||||
_server=server;
|
||||
this.AgentList = new Dictionary<LLUUID, AgentProfile>();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="agent"></param>
|
||||
public void AddAgent(AgentProfile agent)
|
||||
{
|
||||
this.AgentList.Add(agent.Avatar.FullID, agent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userInfo"></param>
|
||||
/// <param name="first"></param>
|
||||
/// <param name="last"></param>
|
||||
/// <param name="baseFolder"></param>
|
||||
/// <param name="inventoryFolder"></param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="UserInfo"></param>
|
||||
public void RemoveAgent(NetworkInfo userInfo)
|
||||
{
|
||||
this.AgentList.Remove(userInfo.User.AgentID);
|
||||
|
||||
//tell other clients to delete this avatar
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="userInfo"></param>
|
||||
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<libsecondlife.LLUUID, AgentProfile> 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<libsecondlife.LLUUID, AgentProfile> 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<libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock> ObjectUpdateList;
|
||||
public List<libsecondlife.Packets.ImprovedTerseObjectUpdatePacket.ObjectDataBlock> 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<libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock>();
|
||||
this.TerseUpdateList = new List<libsecondlife.Packets.ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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("")]
|
||||
|
|
220
AssetManager.cs
220
AssetManager.cs
|
@ -30,23 +30,33 @@ using System.Collections.Generic;
|
|||
using libsecondlife;
|
||||
using libsecondlife.Packets;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages local cache of assets and their sending to viewers.
|
||||
/// </summary>
|
||||
public class AssetManager
|
||||
public class AssetManager : IAssetReceived
|
||||
{
|
||||
public Dictionary<libsecondlife.LLUUID, AssetInfo> Assets;
|
||||
public Dictionary<libsecondlife.LLUUID, TextureImage> Textures;
|
||||
|
||||
public List<AssetRequest> AssetRequests = new List<AssetRequest>(); //assets ready to be sent to viewers
|
||||
public List<TextureRequest> TextureRequests = new List<TextureRequest>(); //textures ready to be sent
|
||||
|
||||
public List<AssetRequest> RequestedAssets = new List<AssetRequest>(); //Assets requested from the asset server
|
||||
public List<TextureRequest> RequestedTextures = new List<TextureRequest>(); //Textures requested from the asset server
|
||||
|
||||
private AssetServer _assetServer;
|
||||
private Server _server;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public AssetManager(AssetServer assetServer)
|
||||
public AssetManager(Server server, AssetServer assetServer)
|
||||
{
|
||||
_assetServer=assetServer;
|
||||
_server = server;
|
||||
_assetServer = assetServer;
|
||||
_assetServer.SetReceiver(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -54,15 +64,8 @@ namespace OpenSimLite
|
|||
/// </summary>
|
||||
private void RunAssetManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
private void ProcessAssetQueue()
|
||||
{
|
||||
|
||||
this.ProcessAssetQueue();
|
||||
this.ProcessTextureQueue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -70,9 +73,97 @@ namespace OpenSimLite
|
|||
/// </summary>
|
||||
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
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -81,8 +172,32 @@ namespace OpenSimLite
|
|||
/// <param name="transferRequest"></param>
|
||||
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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
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()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -26,14 +26,20 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using libsecondlife;
|
||||
using BerkeleyDb;
|
||||
using Kds.Serialization;
|
||||
using Kds.Serialization.Buffer;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles connection to Asset Server.
|
||||
/// </summary>
|
||||
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<string>(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<AssetBase>(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<string>(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<AssetBase>(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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 <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 libsecondlife;
|
||||
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of Assets.
|
||||
/// </summary>
|
||||
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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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 <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 libsecondlife;
|
||||
using BerkeleyDb;
|
||||
using System.IO;
|
||||
using Kds.Serialization;
|
||||
using Kds.Serialization.Buffer;
|
||||
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of BerkeleyDatabase.
|
||||
/// </summary>
|
||||
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<PrimAsset>(new PrimAssetField(formatter));
|
||||
formatter.RegisterField<AssetBase>(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<PrimAsset>
|
||||
{
|
||||
public PrimAssetField(Formatter formatter) : base(formatter) { }
|
||||
|
||||
protected override void SerializeValue(PrimAsset value) {
|
||||
Formatter.Serialize<string>(value.Name);
|
||||
Formatter.Serialize<string>(value.Description);
|
||||
|
||||
}
|
||||
|
||||
protected override void DeserializeInstance(ref PrimAsset instance) {
|
||||
if (instance == null)
|
||||
instance = new PrimAsset();
|
||||
}
|
||||
|
||||
protected override void DeserializeMembers(PrimAsset instance) {
|
||||
Formatter.Deserialize<string>(ref instance.Name);
|
||||
Formatter.Deserialize<string>(ref instance.Description);
|
||||
|
||||
}
|
||||
|
||||
protected override void SkipValue() {
|
||||
if (Formatter.Skip<string>())
|
||||
Formatter.Skip<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public class AssetBaseField: ReferenceField<AssetBase>
|
||||
{
|
||||
public AssetBaseField(Formatter formatter) : base(formatter) { }
|
||||
|
||||
protected override void SerializeValue(AssetBase value) {
|
||||
Formatter.Serialize<string>(value.Name);
|
||||
Formatter.Serialize<string>(value.Description);
|
||||
|
||||
}
|
||||
|
||||
protected override void DeserializeInstance(ref AssetBase instance) {
|
||||
if (instance == null)
|
||||
instance = new AssetBase();
|
||||
}
|
||||
|
||||
protected override void DeserializeMembers(AssetBase instance) {
|
||||
Formatter.Deserialize<string>(ref instance.Name);
|
||||
Formatter.Deserialize<string>(ref instance.Description);
|
||||
|
||||
}
|
||||
|
||||
protected override void SkipValue() {
|
||||
if (Formatter.Skip<string>())
|
||||
Formatter.Skip<string>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ using System.Threading;
|
|||
using libsecondlife;
|
||||
using libsecondlife.Packets;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using libsecondlife;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of Globals.
|
||||
|
|
|
@ -32,7 +32,7 @@ using libsecondlife;
|
|||
using libsecondlife.Packets;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
|
@ -213,7 +213,7 @@ namespace OpenSimLite
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// most of this should be moved into the grid server class
|
||||
/// </summary>
|
||||
private void LoadGrid()
|
||||
{
|
||||
|
|
|
@ -26,17 +26,33 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using libsecondlife;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles connection to Grid Servers.
|
||||
/// also Sim to Sim connections?
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
using System;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of InstantMessaging.
|
||||
|
|
|
@ -29,7 +29,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using libsecondlife;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Local cache of Inventories
|
||||
|
|
|
@ -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 <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>
|
||||
/// Description of LocalAssetCache.
|
||||
/// </summary>
|
||||
public class LocalAssetCache
|
||||
{
|
||||
public LocalAssetCache()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public interface ILocalCacheStorage
|
||||
{
|
||||
void SaveAsset(AssetBase asset);
|
||||
}
|
||||
}
|
|
@ -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 <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 BerkeleyDb;
|
||||
using Kds.Serialization;
|
||||
using Kds.Serialization.Buffer;
|
||||
using libsecondlife;
|
||||
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of LocalPrimDB.
|
||||
/// </summary>
|
||||
///
|
||||
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<string>(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<PrimAsset>(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<string>(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<PrimAsset>(ref prim, dataEntry.Buffer, ref index);
|
||||
return prim;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// test function
|
||||
/// </summary>
|
||||
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<PrimAsset>(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);
|
||||
}
|
||||
}
|
|
@ -37,18 +37,19 @@ using System.Collections;
|
|||
using System.Xml;
|
||||
using libsecondlife;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// When running in local (default) mode , handles client logins.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>OpenSimLite</RootNamespace>
|
||||
<AssemblyName>OpenSimLite</AssemblyName>
|
||||
<RootNamespace>OpenSim</RootNamespace>
|
||||
<AssemblyName>OpenSim</AssemblyName>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{782CCAFD-7313-4638-ADAC-53703DF24DF0}</ProjectGuid>
|
||||
|
@ -31,6 +31,14 @@
|
|||
<HintPath>bin\Debug\libsecondlife.dll</HintPath>
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="libdb_dotNET43">
|
||||
<HintPath>bin\Debug\libdb_dotNET43.dll</HintPath>
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
</Reference>
|
||||
<Reference Include="Kds.Serialization">
|
||||
<HintPath>bin\Debug\Kds.Serialization.dll</HintPath>
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Controller.cs" />
|
||||
|
@ -52,6 +60,10 @@
|
|||
<Compile Include="InstantMessaging.cs" />
|
||||
<Compile Include="Globals.cs" />
|
||||
<Compile Include="Utility.cs" />
|
||||
<Compile Include="LocalStorageBase.cs" />
|
||||
<Compile Include="Assets.cs" />
|
||||
<Compile Include="LocalAssetCache.cs" />
|
||||
<Compile Include="BerkeleyDatabase.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
|
||||
</Project>
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
using System;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of PhysicsManager.
|
||||
|
|
|
@ -26,16 +26,34 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using libsecondlife;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages and provides local cache of Prims.
|
||||
/// </summary>
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
244
SceneGraph.cs
244
SceneGraph.cs
|
@ -32,7 +32,7 @@ using System.Threading;
|
|||
using libsecondlife;
|
||||
using libsecondlife.Packets;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// 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<UpdateCommand> 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<UpdateCommand>();
|
||||
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<Node> _children;
|
||||
private List<SceneObject> _attached;
|
||||
//private List<SceneObject> _attached;
|
||||
public byte SceneType;
|
||||
public string SceneName;
|
||||
public LLVector3 Position;
|
||||
public LLVector3 Velocity = new LLVector3(0,0,0);
|
||||
public byte UpdateFlag;
|
||||
|
||||
public List<Node> ChildNodes
|
||||
{
|
||||
|
@ -186,6 +350,14 @@ namespace OpenSimLite
|
|||
}
|
||||
}
|
||||
|
||||
public int ChildrenCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return(_children.Count);
|
||||
}
|
||||
}
|
||||
/*
|
||||
public List<SceneObject> AttachedObjexts
|
||||
{
|
||||
get
|
||||
|
@ -193,13 +365,13 @@ namespace OpenSimLite
|
|||
return(_attached);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
public Node()
|
||||
{
|
||||
_children = new List<Node>();
|
||||
_attached = new List<SceneObject>();
|
||||
//_attached = new List<SceneObject>();
|
||||
}
|
||||
|
||||
/*
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
@ -252,6 +424,7 @@ namespace OpenSimLite
|
|||
}
|
||||
return(rValue);
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
|
@ -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<SendInfo> SendList;
|
||||
private Thread mthread;
|
||||
private Server _server;
|
||||
private AgentManager _agentManager;
|
||||
|
||||
public UpdateSender()
|
||||
public UpdateSender(Server server, AgentManager agentManager)
|
||||
{
|
||||
SendList = new BlockingQueue<SendInfo>();
|
||||
_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()
|
||||
{
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
using System;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
|
|
|
@ -26,17 +26,21 @@
|
|||
*/
|
||||
|
||||
using System;
|
||||
using libsecondlife;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Handles connection to User Servers
|
||||
///
|
||||
/// </summary>
|
||||
public class UserServer
|
||||
public class UserServer :IUserServer
|
||||
{
|
||||
public List<Logon> Sessions = new List<Logon>(); //should change to something other than logon classes?
|
||||
public UserServer()
|
||||
{
|
||||
Sessions = new List<Logon>();
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
65
Utility.cs
65
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
|
||||
{
|
||||
/// <summary>
|
||||
/// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
186
ViewerServer.cs
186
ViewerServer.cs
|
@ -35,7 +35,7 @@ using System.Net;
|
|||
using System.Net.Sockets;
|
||||
using System.Timers;
|
||||
|
||||
namespace OpenSimLite
|
||||
namespace OpenSim
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
|||
/// <summary>The Region class that this Simulator wraps</summary>
|
||||
// public Region Region;
|
||||
|
||||
private object _sendPacketSync = new object();
|
||||
/// <summary>
|
||||
/// 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;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public Server()
|
||||
public Server(IUserServer userServer)
|
||||
{
|
||||
|
||||
this._userServer = userServer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -207,110 +209,113 @@ namespace OpenSimLite
|
|||
/// <param name="incrementSequence">Increment sequence number?</param>
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue