From 09dd4bd6834861791008e66652826a66724efa0e Mon Sep 17 00:00:00 2001
From: gareth
Date: Tue, 27 Feb 2007 23:00:49 +0000
Subject: Brought in code from branches/gareth
---
README | 22 ++
bin/Axiom.MathLib.dll | Bin 0 -> 69632 bytes
bin/Db4objects.Db4o.dll | Bin 0 -> 593408 bytes
bin/libsecondlife.dll | Bin 0 -> 1533440 bytes
bin/log4net.dll | Bin 0 -> 270336 bytes
genvers.sh | 9 +
opensim.build | 62 +++
src/Agent_Manager.cs | 879 +++++++++++++++++++++++++++++++++++++++++
src/AssetManagement.cs | 455 +++++++++++++++++++++
src/Asset_manager.cs | 231 +++++++++++
src/Config.cs | 140 +++++++
src/GridManager.cs | 372 +++++++++++++++++
src/InventoryManager.cs | 242 ++++++++++++
src/Login_manager.cs | 228 +++++++++++
src/Main.cs | 138 +++++++
src/OpenSimClient.cs | 339 ++++++++++++++++
src/Physics_manager.cs | 41 ++
src/Prim_manager.cs | 382 ++++++++++++++++++
src/SceneGraphManager.cs | 40 ++
src/Script_manager.cs | 103 +++++
src/Second-server.csproj | 60 +++
src/Second-server.sln | 34 ++
src/Second-server.suo | Bin 0 -> 27648 bytes
src/Server.cs | 707 +++++++++++++++++++++++++++++++++
src/StorageManager.cs | 53 +++
src/Texture_manager.cs | 238 +++++++++++
src/Util.cs | 75 ++++
src/VersionInfo.cs.template | 37 ++
src/types/BitPack.cs | 138 +++++++
src/types/Mesh.cs | 28 ++
src/types/Triangle.cs | 28 ++
src/world/Avatar.cs | 70 ++++
src/world/Entity.cs | 53 +++
src/world/Primitive.cs | 33 ++
src/world/ScriptEngine.cs | 18 +
src/world/SurfacePatch.cs | 22 ++
src/world/World.cs | 57 +++
src/world/scripting/IScript.cs | 16 +
38 files changed, 5350 insertions(+)
create mode 100644 README
create mode 100644 bin/Axiom.MathLib.dll
create mode 100755 bin/Db4objects.Db4o.dll
create mode 100755 bin/libsecondlife.dll
create mode 100644 bin/log4net.dll
create mode 100755 genvers.sh
create mode 100644 opensim.build
create mode 100644 src/Agent_Manager.cs
create mode 100644 src/AssetManagement.cs
create mode 100644 src/Asset_manager.cs
create mode 100644 src/Config.cs
create mode 100644 src/GridManager.cs
create mode 100644 src/InventoryManager.cs
create mode 100644 src/Login_manager.cs
create mode 100644 src/Main.cs
create mode 100644 src/OpenSimClient.cs
create mode 100644 src/Physics_manager.cs
create mode 100644 src/Prim_manager.cs
create mode 100644 src/SceneGraphManager.cs
create mode 100644 src/Script_manager.cs
create mode 100644 src/Second-server.csproj
create mode 100644 src/Second-server.sln
create mode 100644 src/Second-server.suo
create mode 100644 src/Server.cs
create mode 100644 src/StorageManager.cs
create mode 100644 src/Texture_manager.cs
create mode 100644 src/Util.cs
create mode 100644 src/VersionInfo.cs.template
create mode 100644 src/types/BitPack.cs
create mode 100644 src/types/Mesh.cs
create mode 100644 src/types/Triangle.cs
create mode 100644 src/world/Avatar.cs
create mode 100644 src/world/Entity.cs
create mode 100644 src/world/Primitive.cs
create mode 100644 src/world/ScriptEngine.cs
create mode 100644 src/world/SurfacePatch.cs
create mode 100644 src/world/World.cs
create mode 100644 src/world/scripting/IScript.cs
diff --git a/README b/README
new file mode 100644
index 0000000..f294295
--- /dev/null
+++ b/README
@@ -0,0 +1,22 @@
+Some basic instructions on how to use OpenSim/OGS for hackers and geeks
+-------------------------------------------------
+
+1.First, either get in touch with a grid owner or install the OGS server components on your own server.
+2.Ask the grid owner to send you keys over a secure channel (encrypted email, paper mail, phone, encrypted IM/IRC). If you and the grid owner are not concerned about security (YOU SHOULD BE!!!) then this exchange can be done over any communications channel.
+3.Edit src/Config.cs to reflect your changes or if the grid owner has provided you with a template/custom database, drop opensim.yap into bin/
+4.If you edited src/Config.cs then run "nant build" at the root directory
+5.With mono on Linux/BSD cd into bin/ and run "mono OpenSim.exe", On win32 just run OpenSim.exe
+5.Login to the grid with a standard viewer and find your sim (note that at certain times the SVN version does not allow logins)
+
+Some basic instructions on how to use OpenSim/OGS for the laymen
+-------------------------------------------------
+
+1.Ensure you either have mono or the .NET framework runtime installed
+2.Find a grid owner
+3.Ask the grid owner to send you connection instructions
+4.Either install the grid owner's opensim.yap by placing it into the same directory as OpenSim.exe or follow their instructions
+5.On Linux/BSD, go to a command prompt and type:
+cd /path/to/where/you/downloaded/
+cd bin/
+mono OpenSim.exe
+6.Login to the grid in the normal way
diff --git a/bin/Axiom.MathLib.dll b/bin/Axiom.MathLib.dll
new file mode 100644
index 0000000..21ce3a8
Binary files /dev/null and b/bin/Axiom.MathLib.dll differ
diff --git a/bin/Db4objects.Db4o.dll b/bin/Db4objects.Db4o.dll
new file mode 100755
index 0000000..be976a1
Binary files /dev/null and b/bin/Db4objects.Db4o.dll differ
diff --git a/bin/libsecondlife.dll b/bin/libsecondlife.dll
new file mode 100755
index 0000000..90189a2
Binary files /dev/null and b/bin/libsecondlife.dll differ
diff --git a/bin/log4net.dll b/bin/log4net.dll
new file mode 100644
index 0000000..ffc57e1
Binary files /dev/null and b/bin/log4net.dll differ
diff --git a/genvers.sh b/genvers.sh
new file mode 100755
index 0000000..3da91d7
--- /dev/null
+++ b/genvers.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+MAJOR=0
+MINOR=1
+BUILD=`date +%s`
+REVISION=`svnversion | sed s/:// | sed s/M//`
+REALREVISION=`svnversion`
+cat src/VersionInfo.cs.template | sed s/@@VERSION/"$MAJOR.$MINOR, Build $BUILD, Revision $REALREVISION"/g >src/VersionInfo.cs
+echo -n $MAJOR.$MINOR.*.$REVISION >VERSION
diff --git a/opensim.build b/opensim.build
new file mode 100644
index 0000000..d91e748
--- /dev/null
+++ b/opensim.build
@@ -0,0 +1,62 @@
+
+
+ First nant buildfile for OpenSim
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Agent_Manager.cs b/src/Agent_Manager.cs
new file mode 100644
index 0000000..195065e
--- /dev/null
+++ b/src/Agent_Manager.cs
@@ -0,0 +1,879 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the 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 System.Collections.Generic;
+using libsecondlife;
+using libsecondlife.Packets;
+using libsecondlife.AssetSystem;
+using System.IO;
+using Axiom.MathLib;
+
+namespace OpenSim
+{
+ ///
+ /// Description of Agent_Manager.
+ ///
+ public class AgentManager
+ {
+ public Dictionary AgentList;
+ public static Dictionary AnimsLLUUID = new Dictionary();
+ public static Dictionary AnimsNames = new Dictionary();
+
+ private uint _localNumber=0;
+ private Server _server;
+ public PrimManager Prim_Manager;
+ public AssetManagement assetManager;
+
+ private libsecondlife.Packets.RegionHandshakePacket RegionPacket;
+ private System.Text.Encoding _enc = System.Text.Encoding.ASCII;
+ private libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock AvatarTemplate;
+
+ ///
+ ///
+ ///
+ ///
+ public AgentManager(Server server)
+ {
+ AgentList = new Dictionary();
+ _server = server;
+ this.initialise();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public AvatarData GetAgent(LLUUID id)
+ {
+ if(!this.AgentList.ContainsKey(id))
+ {
+ return null;
+ }
+ else
+ {
+ AvatarData avatar = this.AgentList[id];
+ return avatar;
+ }
+ }
+ ///
+ ///
+ ///
+ ///
+ public void AddAgent(AvatarData agent)
+ {
+ this.AgentList.Add(agent.FullID, agent);
+ }
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool NewAgent(UserAgentInfo userInfo, string first, string last, LLUUID baseFolder, LLUUID inventoryFolder)
+ {
+ AvatarData agent = new AvatarData();
+ agent.FullID = userInfo.AgentID;
+ agent.NetInfo = userInfo;
+ agent.NetInfo.first_name =first;
+ agent.NetInfo.last_name = last;
+ agent.Position = new LLVector3(100, 100, 22);
+ agent.BaseFolder = baseFolder;
+ agent.InventoryFolder = inventoryFolder;
+ agent.AnimID = AnimsLLUUID["ANIM_AGENT_STAND"];
+ agent.AnimSequenceID = 1;
+
+ this.AgentList.Add(agent.FullID, agent);
+
+ //Create new Wearable Assets and place in Inventory
+ this.assetManager.CreateNewInventorySet(ref agent, userInfo);
+
+ return(true);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void RemoveAgent(UserAgentInfo userInfo)
+ {
+ this.AgentList.Remove(userInfo.AgentID);
+
+ //tell other clients to delete this avatar
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void AgentJoin(UserAgentInfo userInfo)
+ {
+ //send region data
+ _server.SendPacket(RegionPacket,true, userInfo);
+
+ //inform client of join comlete
+ libsecondlife.Packets.AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
+ mov.AgentData.SessionID = userInfo.SessionID;
+ mov.AgentData.AgentID = userInfo.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 UpdatePositions()
+ {
+ //update positions
+ foreach (KeyValuePair kp in this.AgentList)
+ {
+
+ kp.Value.Position.X += (kp.Value.Velocity.X * 0.2f);
+ kp.Value.Position.Y += (kp.Value.Velocity.Y * 0.2f);
+ kp.Value.Position.Z += (kp.Value.Velocity.Z * 0.2f);
+ }
+
+ }
+
+ public void UpdateAnim(UserAgentInfo userInfo, LLUUID AnimID, int AnimSeq)
+ {
+ AgentList[userInfo.AgentID].AnimID = AnimID;
+ AgentList[userInfo.AgentID].AnimSequenceID = AnimSeq;
+ UpdateAnim(userInfo);
+ }
+
+ public void UpdateAnim(UserAgentInfo userInfo)
+ {
+ Console.WriteLine("Agent_Manager.cs: UpdateAnim(UserAgentInfo userInfo): called for Agent " + userInfo.AgentID.ToString());
+ AvatarAnimationPacket ani = new AvatarAnimationPacket();
+ ani.AnimationSourceList = new AvatarAnimationPacket.AnimationSourceListBlock[1];
+ ani.AnimationSourceList[0] = new AvatarAnimationPacket.AnimationSourceListBlock();
+ ani.AnimationSourceList[0].ObjectID = new LLUUID("00000000000000000000000000000000");
+ ani.Sender = new AvatarAnimationPacket.SenderBlock();
+ ani.Sender.ID = userInfo.AgentID;
+ ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[1];
+ ani.AnimationList[0] = new AvatarAnimationPacket.AnimationListBlock();
+ ani.AnimationList[0].AnimID = AgentList[userInfo.AgentID].AnimID;
+ ani.AnimationList[0].AnimSequenceID = AgentList[userInfo.AgentID].AnimSequenceID;
+ Console.WriteLine("Agenct_Manager.cs: UpdateAnim(UserAgentInfo userInfo): Sent Animation to client - " + AgentManager.AnimsNames[ani.AnimationList[0].AnimID]);
+ _server.SendPacket(ani, true, userInfo);
+
+ // update other agents as appropiate
+ Axiom.MathLib.Sphere BoundingSphere;
+ foreach (KeyValuePair kp in this.AgentList)
+ {
+ if(kp.Key!=userInfo.AgentID) {
+ // Make a bounding sphere for the other avatar
+ BoundingSphere = new Sphere(new Vector3(kp.Value.Position.X,kp.Value.Position.Y,kp.Value.Position.Z), kp.Value.far);
+
+ // If it intersects with our position, send an update packet
+ if(BoundingSphere.Intersects(new Vector3(this.AgentList[userInfo.AgentID].Position.X,this.AgentList[userInfo.AgentID].Position.Y,this.AgentList[userInfo.AgentID].Position.Z))) {
+ ani.AnimationSourceList[0].ObjectID = userInfo.AgentID;
+ ani.Sender = new AvatarAnimationPacket.SenderBlock();
+ ani.Sender.ID = userInfo.AgentID;
+ ani.AnimationList = new AvatarAnimationPacket.AnimationListBlock[1];
+ ani.AnimationList[0] = new AvatarAnimationPacket.AnimationListBlock();
+ ani.AnimationList[0].AnimID = AgentList[userInfo.AgentID].AnimID;
+ ani.AnimationList[0].AnimSequenceID = AgentList[userInfo.AgentID].AnimSequenceID;
+ _server.SendPacket(ani, true, kp.Value.NetInfo);
+ }
+ }
+ }
+ }
+ ///
+ ///
+ ///
+ private void initialise()
+ {
+ //Region data
+ RegionPacket = new RegionHandshakePacket();
+ RegionPacket.RegionInfo.BillableFactor = 0;
+ RegionPacket.RegionInfo.IsEstateManager = false;
+ RegionPacket.RegionInfo.TerrainHeightRange00 = 60;
+ RegionPacket.RegionInfo.TerrainHeightRange01 = 60;
+ RegionPacket.RegionInfo.TerrainHeightRange10 = 60;
+ RegionPacket.RegionInfo.TerrainHeightRange11 = 60;
+ RegionPacket.RegionInfo.TerrainStartHeight00 = 20;
+ RegionPacket.RegionInfo.TerrainStartHeight01 = 20;
+ RegionPacket.RegionInfo.TerrainStartHeight10 = 20;
+ RegionPacket.RegionInfo.TerrainStartHeight11 = 20;
+ RegionPacket.RegionInfo.SimAccess = 13;
+ RegionPacket.RegionInfo.WaterHeight = 5;
+ RegionPacket.RegionInfo.RegionFlags = 72458694;
+ RegionPacket.RegionInfo.SimName = _enc.GetBytes( Globals.Instance.RegionName);
+ RegionPacket.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000");
+ RegionPacket.RegionInfo.TerrainBase0 = new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975");
+ RegionPacket.RegionInfo.TerrainBase1 = new LLUUID("abb783e6-3e93-26c0-248a-247666855da3");
+ RegionPacket.RegionInfo.TerrainBase2 = new LLUUID("179cdabd-398a-9b6b-1391-4dc333ba321f");
+ RegionPacket.RegionInfo.TerrainBase3 = new LLUUID("beb169c7-11ea-fff2-efe5-0f24dc881df2");
+ RegionPacket.RegionInfo.TerrainDetail0 = new LLUUID("00000000-0000-0000-0000-000000000000");
+ RegionPacket.RegionInfo.TerrainDetail1 = new LLUUID("00000000-0000-0000-0000-000000000000");
+ RegionPacket.RegionInfo.TerrainDetail2 = new LLUUID("00000000-0000-0000-0000-000000000000");
+ RegionPacket.RegionInfo.TerrainDetail3 = new LLUUID("00000000-0000-0000-0000-000000000000");
+ RegionPacket.RegionInfo.CacheID = new LLUUID("545ec0a5-5751-1026-8a0b-216e38a7ab37");
+
+ //this.SetupTemplate("objectupate168.dat");
+ this.LoadAnims();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ private void SetupTemplate(string name)
+ {
+
+ int i = 0;
+ FileInfo fInfo = new FileInfo(name);
+ long numBytes = fInfo.Length;
+ FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read);
+ BinaryReader br = new BinaryReader(fStream);
+ byte [] data1 = br.ReadBytes((int)numBytes);
+ br.Close();
+ fStream.Close();
+
+ libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
+
+ System.Text.Encoding enc = System.Text.Encoding.ASCII;
+ libsecondlife.LLVector3 pos = new LLVector3(objdata.ObjectData, 16);
+ pos.X = 100f;
+ objdata.ID = 8880000;
+ objdata.NameValue = enc.GetBytes("FirstName STRING RW SV Test \nLastName STRING RW SV User \0");
+ libsecondlife.LLVector3 pos2 = new LLVector3(13.981f,100.0f,20.0f);
+ //objdata.FullID=user.AgentID;
+ byte[] pb = pos.GetBytes();
+ Array.Copy(pb, 0, objdata.ObjectData, 16, pb.Length);
+
+ AvatarTemplate = objdata;
+
+ }
+
+ private void LoadAnims()
+ {
+ AnimsLLUUID.Add("ANIM_AGENT_AFRAID", new LLUUID("6b61c8e8-4747-0d75-12d7-e49ff207a4ca"));
+ AnimsLLUUID.Add("ANIM_AGENT_AIM_BAZOOKA_R", new LLUUID("b5b4a67d-0aee-30d2-72cd-77b333e932ef"));
+ AnimsLLUUID.Add("ANIM_AGENT_AIM_BOW_L", new LLUUID("46bb4359-de38-4ed8-6a22-f1f52fe8f506"));
+ AnimsLLUUID.Add("ANIM_AGENT_AIM_HANDGUN_R", new LLUUID("3147d815-6338-b932-f011-16b56d9ac18b"));
+ AnimsLLUUID.Add("ANIM_AGENT_AIM_RIFLE_R", new LLUUID("ea633413-8006-180a-c3ba-96dd1d756720"));
+ AnimsLLUUID.Add("ANIM_AGENT_ANGRY", new LLUUID("5747a48e-073e-c331-f6f3-7c2149613d3e"));
+ AnimsLLUUID.Add("ANIM_AGENT_AWAY", new LLUUID("fd037134-85d4-f241-72c6-4f42164fedee"));
+ AnimsLLUUID.Add("ANIM_AGENT_BACKFLIP", new LLUUID("c4ca6188-9127-4f31-0158-23c4e2f93304"));
+ AnimsLLUUID.Add("ANIM_AGENT_BELLY_LAUGH", new LLUUID("18b3a4b5-b463-bd48-e4b6-71eaac76c515"));
+ AnimsLLUUID.Add("ANIM_AGENT_BLOW_KISS", new LLUUID("db84829b-462c-ee83-1e27-9bbee66bd624"));
+ AnimsLLUUID.Add("ANIM_AGENT_BORED", new LLUUID("b906c4ba-703b-1940-32a3-0c7f7d791510"));
+ AnimsLLUUID.Add("ANIM_AGENT_BOW", new LLUUID("82e99230-c906-1403-4d9c-3889dd98daba"));
+ AnimsLLUUID.Add("ANIM_AGENT_BRUSH", new LLUUID("349a3801-54f9-bf2c-3bd0-1ac89772af01"));
+ AnimsLLUUID.Add("ANIM_AGENT_BUSY", new LLUUID("efcf670c-2d18-8128-973a-034ebc806b67"));
+ AnimsLLUUID.Add("ANIM_AGENT_CLAP", new LLUUID("9b0c1c4e-8ac7-7969-1494-28c874c4f668"));
+ AnimsLLUUID.Add("ANIM_AGENT_COURTBOW", new LLUUID("9ba1c942-08be-e43a-fb29-16ad440efc50"));
+ AnimsLLUUID.Add("ANIM_AGENT_CROUCH", new LLUUID("201f3fdf-cb1f-dbec-201f-7333e328ae7c"));
+ AnimsLLUUID.Add("ANIM_AGENT_CROUCHWALK", new LLUUID("47f5f6fb-22e5-ae44-f871-73aaaf4a6022"));
+ AnimsLLUUID.Add("ANIM_AGENT_CRY", new LLUUID("92624d3e-1068-f1aa-a5ec-8244585193ed"));
+ AnimsLLUUID.Add("ANIM_AGENT_CUSTOMIZE", new LLUUID("038fcec9-5ebd-8a8e-0e2e-6e71a0a1ac53"));
+ AnimsLLUUID.Add("ANIM_AGENT_CUSTOMIZE_DONE", new LLUUID("6883a61a-b27b-5914-a61e-dda118a9ee2c"));
+ AnimsLLUUID.Add("ANIM_AGENT_DANCE1", new LLUUID("b68a3d7c-de9e-fc87-eec8-543d787e5b0d"));
+ AnimsLLUUID.Add("ANIM_AGENT_DANCE2", new LLUUID("928cae18-e31d-76fd-9cc9-2f55160ff818"));
+ AnimsLLUUID.Add("ANIM_AGENT_DANCE3", new LLUUID("30047778-10ea-1af7-6881-4db7a3a5a114"));
+ AnimsLLUUID.Add("ANIM_AGENT_DANCE4", new LLUUID("951469f4-c7b2-c818-9dee-ad7eea8c30b7"));
+ AnimsLLUUID.Add("ANIM_AGENT_DANCE5", new LLUUID("4bd69a1d-1114-a0b4-625f-84e0a5237155"));
+ AnimsLLUUID.Add("ANIM_AGENT_DANCE6", new LLUUID("cd28b69b-9c95-bb78-3f94-8d605ff1bb12"));
+ AnimsLLUUID.Add("ANIM_AGENT_DANCE7", new LLUUID("a54d8ee2-28bb-80a9-7f0c-7afbbe24a5d6"));
+ AnimsLLUUID.Add("ANIM_AGENT_DANCE8", new LLUUID("b0dc417c-1f11-af36-2e80-7e7489fa7cdc"));
+ AnimsLLUUID.Add("ANIM_AGENT_DEAD", new LLUUID("57abaae6-1d17-7b1b-5f98-6d11a6411276"));
+ AnimsLLUUID.Add("ANIM_AGENT_DRINK", new LLUUID("0f86e355-dd31-a61c-fdb0-3a96b9aad05f"));
+ AnimsLLUUID.Add("ANIM_AGENT_EMBARRASSED", new LLUUID("514af488-9051-044a-b3fc-d4dbf76377c6"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_AFRAID", new LLUUID("aa2df84d-cf8f-7218-527b-424a52de766e"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_ANGER", new LLUUID("1a03b575-9634-b62a-5767-3a679e81f4de"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_BORED", new LLUUID("214aa6c1-ba6a-4578-f27c-ce7688f61d0d"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_CRY", new LLUUID("d535471b-85bf-3b4d-a542-93bea4f59d33"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_DISDAIN", new LLUUID("d4416ff1-09d3-300f-4183-1b68a19b9fc1"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_EMBARRASSED", new LLUUID("0b8c8211-d78c-33e8-fa28-c51a9594e424"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_FROWN", new LLUUID("fee3df48-fa3d-1015-1e26-a205810e3001"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_KISS", new LLUUID("1e8d90cc-a84e-e135-884c-7c82c8b03a14"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_LAUGH", new LLUUID("62570842-0950-96f8-341c-809e65110823"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_OPEN_MOUTH", new LLUUID("d63bc1f9-fc81-9625-a0c6-007176d82eb7"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_REPULSED", new LLUUID("f76cda94-41d4-a229-2872-e0296e58afe1"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_SAD", new LLUUID("eb6ebfb2-a4b3-a19c-d388-4dd5c03823f7"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_SHRUG", new LLUUID("a351b1bc-cc94-aac2-7bea-a7e6ebad15ef"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_SMILE", new LLUUID("b7c7c833-e3d3-c4e3-9fc0-131237446312"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_SURPRISE", new LLUUID("728646d9-cc79-08b2-32d6-937f0a835c24"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_TONGUE_OUT", new LLUUID("835965c6-7f2f-bda2-5deb-2478737f91bf"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_TOOTHSMILE", new LLUUID("b92ec1a5-e7ce-a76b-2b05-bcdb9311417e"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_WINK", new LLUUID("da020525-4d94-59d6-23d7-81fdebf33148"));
+ AnimsLLUUID.Add("ANIM_AGENT_EXPRESS_WORRY", new LLUUID("9c05e5c7-6f07-6ca4-ed5a-b230390c3950"));
+ AnimsLLUUID.Add("ANIM_AGENT_FALLDOWN", new LLUUID("666307d9-a860-572d-6fd4-c3ab8865c094"));
+ AnimsLLUUID.Add("ANIM_AGENT_FEMALE_WALK", new LLUUID("f5fc7433-043d-e819-8298-f519a119b688"));
+ AnimsLLUUID.Add("ANIM_AGENT_FINGER_WAG", new LLUUID("c1bc7f36-3ba0-d844-f93c-93be945d644f"));
+ AnimsLLUUID.Add("ANIM_AGENT_FIST_PUMP", new LLUUID("7db00ccd-f380-f3ee-439d-61968ec69c8a"));
+ AnimsLLUUID.Add("ANIM_AGENT_FLY", new LLUUID("aec4610c-757f-bc4e-c092-c6e9caf18daf"));
+ AnimsLLUUID.Add("ANIM_AGENT_FLYSLOW", new LLUUID("2b5a38b2-5e00-3a97-a495-4c826bc443e6"));
+ AnimsLLUUID.Add("ANIM_AGENT_HELLO", new LLUUID("9b29cd61-c45b-5689-ded2-91756b8d76a9"));
+ AnimsLLUUID.Add("ANIM_AGENT_HOLD_BAZOOKA_R", new LLUUID("ef62d355-c815-4816-2474-b1acc21094a6"));
+ AnimsLLUUID.Add("ANIM_AGENT_HOLD_BOW_L", new LLUUID("8b102617-bcba-037b-86c1-b76219f90c88"));
+ AnimsLLUUID.Add("ANIM_AGENT_HOLD_HANDGUN_R", new LLUUID("efdc1727-8b8a-c800-4077-975fc27ee2f2"));
+ AnimsLLUUID.Add("ANIM_AGENT_HOLD_RIFLE_R", new LLUUID("3d94bad0-c55b-7dcc-8763-033c59405d33"));
+ AnimsLLUUID.Add("ANIM_AGENT_HOLD_THROW_R", new LLUUID("7570c7b5-1f22-56dd-56ef-a9168241bbb6"));
+ AnimsLLUUID.Add("ANIM_AGENT_HOVER", new LLUUID("4ae8016b-31b9-03bb-c401-b1ea941db41d"));
+ AnimsLLUUID.Add("ANIM_AGENT_HOVER_DOWN", new LLUUID("20f063ea-8306-2562-0b07-5c853b37b31e"));
+ AnimsLLUUID.Add("ANIM_AGENT_HOVER_UP", new LLUUID("62c5de58-cb33-5743-3d07-9e4cd4352864"));
+ AnimsLLUUID.Add("ANIM_AGENT_IMPATIENT", new LLUUID("5ea3991f-c293-392e-6860-91dfa01278a3"));
+ AnimsLLUUID.Add("ANIM_AGENT_JUMP", new LLUUID("2305bd75-1ca9-b03b-1faa-b176b8a8c49e"));
+ AnimsLLUUID.Add("ANIM_AGENT_JUMP_FOR_JOY", new LLUUID("709ea28e-1573-c023-8bf8-520c8bc637fa"));
+ AnimsLLUUID.Add("ANIM_AGENT_KISS_MY_BUTT", new LLUUID("19999406-3a3a-d58c-a2ac-d72e555dcf51"));
+ AnimsLLUUID.Add("ANIM_AGENT_LAND", new LLUUID("7a17b059-12b2-41b1-570a-186368b6aa6f"));
+ AnimsLLUUID.Add("ANIM_AGENT_LAUGH_SHORT", new LLUUID("ca5b3f14-3194-7a2b-c894-aa699b718d1f"));
+ AnimsLLUUID.Add("ANIM_AGENT_MEDIUM_LAND", new LLUUID("f4f00d6e-b9fe-9292-f4cb-0ae06ea58d57"));
+ AnimsLLUUID.Add("ANIM_AGENT_MOTORCYCLE_SIT", new LLUUID("08464f78-3a8e-2944-cba5-0c94aff3af29"));
+ AnimsLLUUID.Add("ANIM_AGENT_MUSCLE_BEACH", new LLUUID("315c3a41-a5f3-0ba4-27da-f893f769e69b"));
+ AnimsLLUUID.Add("ANIM_AGENT_NO", new LLUUID("5a977ed9-7f72-44e9-4c4c-6e913df8ae74"));
+ AnimsLLUUID.Add("ANIM_AGENT_NO_UNHAPPY", new LLUUID("d83fa0e5-97ed-7eb2-e798-7bd006215cb4"));
+ AnimsLLUUID.Add("ANIM_AGENT_NYAH_NYAH", new LLUUID("f061723d-0a18-754f-66ee-29a44795a32f"));
+ AnimsLLUUID.Add("ANIM_AGENT_ONETWO_PUNCH", new LLUUID("eefc79be-daae-a239-8c04-890f5d23654a"));
+ AnimsLLUUID.Add("ANIM_AGENT_PEACE", new LLUUID("b312b10e-65ab-a0a4-8b3c-1326ea8e3ed9"));
+ AnimsLLUUID.Add("ANIM_AGENT_POINT_ME", new LLUUID("17c024cc-eef2-f6a0-3527-9869876d7752"));
+ AnimsLLUUID.Add("ANIM_AGENT_POINT_YOU", new LLUUID("ec952cca-61ef-aa3b-2789-4d1344f016de"));
+ AnimsLLUUID.Add("ANIM_AGENT_PRE_JUMP", new LLUUID("7a4e87fe-de39-6fcb-6223-024b00893244"));
+ AnimsLLUUID.Add("ANIM_AGENT_PUNCH_LEFT", new LLUUID("f3300ad9-3462-1d07-2044-0fef80062da0"));
+ AnimsLLUUID.Add("ANIM_AGENT_PUNCH_RIGHT", new LLUUID("c8e42d32-7310-6906-c903-cab5d4a34656"));
+ AnimsLLUUID.Add("ANIM_AGENT_REPULSED", new LLUUID("36f81a92-f076-5893-dc4b-7c3795e487cf"));
+ AnimsLLUUID.Add("ANIM_AGENT_ROUNDHOUSE_KICK", new LLUUID("49aea43b-5ac3-8a44-b595-96100af0beda"));
+ AnimsLLUUID.Add("ANIM_AGENT_RPS_COUNTDOWN", new LLUUID("35db4f7e-28c2-6679-cea9-3ee108f7fc7f"));
+ AnimsLLUUID.Add("ANIM_AGENT_RPS_PAPER", new LLUUID("0836b67f-7f7b-f37b-c00a-460dc1521f5a"));
+ AnimsLLUUID.Add("ANIM_AGENT_RPS_ROCK", new LLUUID("42dd95d5-0bc6-6392-f650-777304946c0f"));
+ AnimsLLUUID.Add("ANIM_AGENT_RPS_SCISSORS", new LLUUID("16803a9f-5140-e042-4d7b-d28ba247c325"));
+ AnimsLLUUID.Add("ANIM_AGENT_RUN", new LLUUID("05ddbff8-aaa9-92a1-2b74-8fe77a29b445"));
+ AnimsLLUUID.Add("ANIM_AGENT_SAD", new LLUUID("0eb702e2-cc5a-9a88-56a5-661a55c0676a"));
+ AnimsLLUUID.Add("ANIM_AGENT_SALUTE", new LLUUID("cd7668a6-7011-d7e2-ead8-fc69eff1a104"));
+ AnimsLLUUID.Add("ANIM_AGENT_SHOOT_BOW_L", new LLUUID("e04d450d-fdb5-0432-fd68-818aaf5935f8"));
+ AnimsLLUUID.Add("ANIM_AGENT_SHOUT", new LLUUID("6bd01860-4ebd-127a-bb3d-d1427e8e0c42"));
+ AnimsLLUUID.Add("ANIM_AGENT_SHRUG", new LLUUID("70ea714f-3a97-d742-1b01-590a8fcd1db5"));
+ AnimsLLUUID.Add("ANIM_AGENT_SIT", new LLUUID("1a5fe8ac-a804-8a5d-7cbd-56bd83184568"));
+ AnimsLLUUID.Add("ANIM_AGENT_SIT_FEMALE", new LLUUID("b1709c8d-ecd3-54a1-4f28-d55ac0840782"));
+ AnimsLLUUID.Add("ANIM_AGENT_SIT_GENERIC", new LLUUID("245f3c54-f1c0-bf2e-811f-46d8eeb386e7"));
+ AnimsLLUUID.Add("ANIM_AGENT_SIT_GROUND", new LLUUID("1c7600d6-661f-b87b-efe2-d7421eb93c86"));
+ AnimsLLUUID.Add("ANIM_AGENT_SIT_GROUND_CONSTRAINED", new LLUUID("1a2bd58e-87ff-0df8-0b4c-53e047b0bb6e"));
+ AnimsLLUUID.Add("ANIM_AGENT_SIT_TO_STAND", new LLUUID("a8dee56f-2eae-9e7a-05a2-6fb92b97e21e"));
+ AnimsLLUUID.Add("ANIM_AGENT_SLEEP", new LLUUID("f2bed5f9-9d44-39af-b0cd-257b2a17fe40"));
+ AnimsLLUUID.Add("ANIM_AGENT_SMOKE_IDLE", new LLUUID("d2f2ee58-8ad1-06c9-d8d3-3827ba31567a"));
+ AnimsLLUUID.Add("ANIM_AGENT_SMOKE_INHALE", new LLUUID("6802d553-49da-0778-9f85-1599a2266526"));
+ AnimsLLUUID.Add("ANIM_AGENT_SMOKE_THROW_DOWN", new LLUUID("0a9fb970-8b44-9114-d3a9-bf69cfe804d6"));
+ AnimsLLUUID.Add("ANIM_AGENT_SNAPSHOT", new LLUUID("eae8905b-271a-99e2-4c0e-31106afd100c"));
+ AnimsLLUUID.Add("ANIM_AGENT_STAND", new LLUUID("2408fe9e-df1d-1d7d-f4ff-1384fa7b350f"));
+ AnimsLLUUID.Add("ANIM_AGENT_STANDUP", new LLUUID("3da1d753-028a-5446-24f3-9c9b856d9422"));
+ AnimsLLUUID.Add("ANIM_AGENT_STAND_1", new LLUUID("15468e00-3400-bb66-cecc-646d7c14458e"));
+ AnimsLLUUID.Add("ANIM_AGENT_STAND_2", new LLUUID("370f3a20-6ca6-9971-848c-9a01bc42ae3c"));
+ AnimsLLUUID.Add("ANIM_AGENT_STAND_3", new LLUUID("42b46214-4b44-79ae-deb8-0df61424ff4b"));
+ AnimsLLUUID.Add("ANIM_AGENT_STAND_4", new LLUUID("f22fed8b-a5ed-2c93-64d5-bdd8b93c889f"));
+ AnimsLLUUID.Add("ANIM_AGENT_STRETCH", new LLUUID("80700431-74ec-a008-14f8-77575e73693f"));
+ AnimsLLUUID.Add("ANIM_AGENT_STRIDE", new LLUUID("1cb562b0-ba21-2202-efb3-30f82cdf9595"));
+ AnimsLLUUID.Add("ANIM_AGENT_SURF", new LLUUID("41426836-7437-7e89-025d-0aa4d10f1d69"));
+ AnimsLLUUID.Add("ANIM_AGENT_SURPRISE", new LLUUID("313b9881-4302-73c0-c7d0-0e7a36b6c224"));
+ AnimsLLUUID.Add("ANIM_AGENT_SWORD_STRIKE", new LLUUID("85428680-6bf9-3e64-b489-6f81087c24bd"));
+ AnimsLLUUID.Add("ANIM_AGENT_TALK", new LLUUID("5c682a95-6da4-a463-0bf6-0f5b7be129d1"));
+ AnimsLLUUID.Add("ANIM_AGENT_TANTRUM", new LLUUID("11000694-3f41-adc2-606b-eee1d66f3724"));
+ AnimsLLUUID.Add("ANIM_AGENT_THROW_R", new LLUUID("aa134404-7dac-7aca-2cba-435f9db875ca"));
+ AnimsLLUUID.Add("ANIM_AGENT_TRYON_SHIRT", new LLUUID("83ff59fe-2346-f236-9009-4e3608af64c1"));
+ AnimsLLUUID.Add("ANIM_AGENT_TURNLEFT", new LLUUID("56e0ba0d-4a9f-7f27-6117-32f2ebbf6135"));
+ AnimsLLUUID.Add("ANIM_AGENT_TURNRIGHT", new LLUUID("2d6daa51-3192-6794-8e2e-a15f8338ec30"));
+ AnimsLLUUID.Add("ANIM_AGENT_TYPE", new LLUUID("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9"));
+ AnimsLLUUID.Add("ANIM_AGENT_WALK", new LLUUID("6ed24bd8-91aa-4b12-ccc7-c97c857ab4e0"));
+ AnimsLLUUID.Add("ANIM_AGENT_WHISPER", new LLUUID("7693f268-06c7-ea71-fa21-2b30d6533f8f"));
+ AnimsLLUUID.Add("ANIM_AGENT_WHISTLE", new LLUUID("b1ed7982-c68e-a982-7561-52a88a5298c0"));
+ AnimsLLUUID.Add("ANIM_AGENT_WINK", new LLUUID("869ecdad-a44b-671e-3266-56aef2e3ac2e"));
+ AnimsLLUUID.Add("ANIM_AGENT_WINK_HOLLYWOOD", new LLUUID("c0c4030f-c02b-49de-24ba-2331f43fe41c"));
+ AnimsLLUUID.Add("ANIM_AGENT_WORRY", new LLUUID("9f496bd2-589a-709f-16cc-69bf7df1d36c"));
+ AnimsLLUUID.Add("ANIM_AGENT_YES", new LLUUID("15dd911d-be82-2856-26db-27659b142875"));
+ AnimsLLUUID.Add("ANIM_AGENT_YES_HAPPY", new LLUUID("b8c8b2a3-9008-1771-3bfc-90924955ab2d"));
+ AnimsLLUUID.Add("ANIM_AGENT_YOGA_FLOAT", new LLUUID("42ecd00b-9947-a97c-400a-bbc9174c7aeb"));
+
+
+ foreach (KeyValuePair kp in AgentManager.AnimsLLUUID)
+ {
+ AnimsNames.Add(kp.Value, kp.Key);
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void SendInitialData(UserAgentInfo userInfo)
+ {
+
+ //shouldn't have to read all this in from disk for every new client
+ string data_path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"layer_data");
+
+ //send layerdata
+ LayerDataPacket layerpack = new LayerDataPacket();
+ layerpack.LayerID.Type = 76;
+ this.SendLayerData(userInfo,ref layerpack, System.IO.Path.Combine(data_path, @"layerdata0.dat"));
+
+ LayerDataPacket layerpack1 = new LayerDataPacket();
+ layerpack1.LayerID.Type = 76;
+ this.SendLayerData(userInfo, ref layerpack, System.IO.Path.Combine(data_path, @"layerdata1.dat"));
+
+ LayerDataPacket layerpack2 = new LayerDataPacket();
+ layerpack2.LayerID.Type = 56;
+ this.SendLayerData(userInfo, ref layerpack, System.IO.Path.Combine(data_path, @"layerdata2.dat"));
+
+ LayerDataPacket layerpack3 = new LayerDataPacket();
+ layerpack3.LayerID.Type = 55;
+ this.SendLayerData(userInfo, ref layerpack, System.IO.Path.Combine(data_path, @"layerdata3.dat"));
+
+ LayerDataPacket layerpack4 = new LayerDataPacket();
+ layerpack4.LayerID.Type = 56;
+ this.SendLayerData(userInfo, ref layerpack, System.IO.Path.Combine(data_path, @"layerdata4.dat"));
+
+ LayerDataPacket layerpack5 = new LayerDataPacket();
+ layerpack5.LayerID.Type = 55;
+ this.SendLayerData(userInfo, ref layerpack, System.IO.Path.Combine(data_path, @"layerdata5.dat"));
+
+ //send intial set of captured prims data?
+ this.Prim_Manager.ReadPrimDatabase( "objectdatabase.ini", userInfo);
+
+ //send prims that have been created by users
+ //prim_man.send_existing_prims(User_info);
+
+ //send update about clients avatar
+ this.SendInitialAvatarPosition(userInfo);
+
+ //send updates about all other users
+ foreach (KeyValuePair kp in this.AgentList)
+ {
+ if(kp.Value.NetInfo.AgentID != userInfo.AgentID)
+ {
+ this.SendOtherAvatarPosition(userInfo, kp.Value);
+ }
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void SendInitialAvatarPosition(UserAgentInfo userInfo)
+ {
+ //send a objectupdate packet with information about the clients avatar
+ ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
+ objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle;
+ objupdate.RegionData.TimeDilation = 64096;
+ objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
+
+ objupdate.ObjectData[0] = AvatarTemplate;
+ //give this avatar object a local id and assign the user a name
+ objupdate.ObjectData[0].ID = 8880000 + this._localNumber;
+ userInfo.localID = objupdate.ObjectData[0].ID;
+ //User_info.name="Test"+this.local_numer+" User";
+ this.GetAgent(userInfo.AgentID).Started = true;
+ objupdate.ObjectData[0].FullID = userInfo.AgentID;
+ objupdate.ObjectData[0].NameValue = _enc.GetBytes("FirstName STRING RW SV " + userInfo.first_name + "\nLastName STRING RW SV " + userInfo.last_name + " \0");
+ userInfo.name = "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();
+
+ Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
+ this._localNumber++;
+
+ _server.SendPacket(objupdate, true, userInfo);
+
+ //send this info to other existing clients
+ foreach (KeyValuePair kp in this.AgentList)
+ {
+ if(kp.Value.NetInfo.AgentID != userInfo.AgentID)
+ {
+ _server.SendPacket(objupdate, true, kp.Value.NetInfo);
+ this.SendOtherAppearance(kp.Value.NetInfo, objupdate.ObjectData[0].FullID);
+ }
+ }
+
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void SendIntialAvatarAppearance(UserAgentInfo userInfo)
+ {
+ AvatarData Agent = this.AgentList[userInfo.AgentID];
+ AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket();
+ aw.AgentData.AgentID = userInfo.AgentID;
+ aw.AgentData.SerialNum = 0;
+ aw.AgentData.SessionID = userInfo.SessionID;
+
+ aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13];
+ AgentWearablesUpdatePacket.WearableDataBlock awb = null;
+ awb = new AgentWearablesUpdatePacket.WearableDataBlock();
+ awb.WearableType = (byte)0;
+ awb.AssetID = Agent.Wearables[0].AssetID;
+ awb.ItemID = Agent.Wearables[0].ItemID;
+ aw.WearableData[0] = awb;
+
+ awb = new AgentWearablesUpdatePacket.WearableDataBlock();
+ awb.WearableType =(byte)1;
+ awb.AssetID = Agent.Wearables[1].AssetID;
+ awb.ItemID = Agent.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 SendOtherAppearance(UserAgentInfo userInfo, LLUUID id)
+ {
+ AvatarAppearancePacket avp = new AvatarAppearancePacket();
+
+
+ avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218];
+ //avp.ObjectData.TextureEntry=this.avatar_template.TextureEntry;// br.ReadBytes((int)numBytes);
+
+ FileInfo fInfo = new FileInfo("Avatar_texture3.dat");
+ long numBytes = fInfo.Length;
+ FileStream fStream = new FileStream("Avatar_texture3.dat", FileMode.Open, FileAccess.Read);
+ BinaryReader br = new BinaryReader(fStream);
+ avp.ObjectData.TextureEntry = br.ReadBytes((int)numBytes);
+ br.Close();
+ fStream.Close();
+
+ AvatarAppearancePacket.VisualParamBlock avblock = null;
+ for(int i = 0; i < 218; i++)
+ {
+ avblock = new AvatarAppearancePacket.VisualParamBlock();
+ avblock.ParamValue = (byte)100;
+ avp.VisualParam[i] = avblock;
+ }
+
+ avp.Sender.IsTrial = false;
+ avp.Sender.ID = id;
+ _server.SendPacket(avp, true, userInfo);
+
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void SendOtherAvatarPosition(UserAgentInfo userInfo, AvatarData avatar)
+ {
+ //send a objectupdate packet with information about the clients avatar
+ ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
+ objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle;
+ objupdate.RegionData.TimeDilation = 64500;
+ objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
+
+ objupdate.ObjectData[0] = AvatarTemplate;
+ //give this avatar object a local id and assign the user a name
+ objupdate.ObjectData[0].ID = avatar.NetInfo.localID;
+ objupdate.ObjectData[0].FullID = avatar.NetInfo.AgentID;
+ objupdate.ObjectData[0].NameValue = _enc.GetBytes(avatar.NetInfo.name);
+ libsecondlife.LLVector3 pos2 = new LLVector3(avatar.Position.X, avatar.Position.Y, avatar.Position.Z);
+
+ byte[] pb = pos2.GetBytes();
+ Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length);
+ this._localNumber++;
+
+ _server.SendPacket(objupdate, true, userInfo);
+ this.SendOtherAppearance(userInfo, avatar.NetInfo.AgentID);
+
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void SendChatMessage(UserAgentInfo userInfo, string line)
+ {
+ libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
+ reply.ChatData.Audible = 1;
+ reply.ChatData.Message = _enc.GetBytes(line);
+ reply.ChatData.ChatType = 1;
+ reply.ChatData.SourceType = 1;
+ reply.ChatData.Position = new LLVector3(120, 100, 21); //should set to actual position
+ reply.ChatData.FromName = _enc.GetBytes(userInfo.first_name + " " + userInfo.last_name + "\0");
+ reply.ChatData.OwnerID = userInfo.AgentID;
+ reply.ChatData.SourceID = userInfo.AgentID;
+ //echo to sender
+ _server.SendPacket(reply, true, userInfo);
+
+ //send to all users
+ foreach (KeyValuePair kp in this.AgentList)
+ {
+ if(kp.Value.NetInfo.AgentID!=userInfo.AgentID)
+ {
+ _server.SendPacket(reply, true, kp.Value.NetInfo);
+ }
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void SendMoveCommand(UserAgentInfo userInfo, bool stop, float x, float y, float z, uint avatarID, libsecondlife.LLQuaternion body)
+ {
+ Console.WriteLine("sending move");
+ uint ID = userInfo.localID;
+ byte[] bytes = new byte[60];
+ int i=0;
+
+ ImprovedTerseObjectUpdatePacket im = new ImprovedTerseObjectUpdatePacket();
+ im.RegionData.RegionHandle = Globals.Instance.RegionHandle;;
+ im.RegionData.TimeDilation = 64096;
+
+ im.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
+ ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
+
+ im.ObjectData[0] = dat;
+
+ dat.TextureEntry = AvatarTemplate.TextureEntry;
+ libsecondlife.LLVector3 pos2 = new LLVector3(x, y, z);
+
+ bytes[i++] = (byte)(ID % 256);
+ bytes[i++] = (byte)((ID >> 8) % 256);
+ bytes[i++] = (byte)((ID >> 16) % 256);
+ bytes[i++] = (byte)((ID >> 24) % 256);
+
+ bytes[i++] = 0;
+ bytes[i++] = 1;
+
+ i += 14;
+ bytes[i++] = 128;
+ bytes[i++] = 63;
+ byte[] pb = pos2.GetBytes();
+
+ Array.Copy(pb, 0, bytes, i, pb.Length);
+ i += 12;
+ ushort ac = 32767;
+ Axiom.MathLib.Vector3 v3 = new Axiom.MathLib.Vector3(1, 0, 0);
+ Axiom.MathLib.Quaternion q = new Axiom.MathLib.Quaternion(body.W, body.X, body.Y, body.Z);
+ Axiom.MathLib.Vector3 direc = q * v3;
+ direc.Normalize();
+
+ direc = direc * (0.03f);
+ direc.x += 1;
+ direc.y += 1;
+ direc.z += 1;
+ ushort dx, dy, dz;
+ dx = (ushort)(32768 * direc.x);
+ dy = (ushort)(32768 * direc.y);
+ dz = (ushort)(32768 * direc.z);
+
+ //vel
+ if(!stop)
+ {
+ bytes[i++] = (byte)(dx % 256);
+ bytes[i++] = (byte)((dx >> 8) % 256);
+
+ bytes[i++] = (byte)(dy % 256);
+ bytes[i++] = (byte)((dy >> 8) % 256);
+
+ bytes[i++] = (byte)(dz % 256);
+ bytes[i++] = (byte)((dz >> 8) % 256);
+ }
+ else
+ {
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+ }
+ //accel
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ //rot
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ //rotation vel
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ dat.Data=bytes;
+
+ _server.SendPacket(im, true, userInfo);
+
+ //should send to all users.
+ foreach (KeyValuePair kp in this.AgentList)
+ {
+ if(kp.Value.NetInfo.AgentID != userInfo.AgentID)
+ {
+ _server.SendPacket(im, true, kp.Value.NetInfo);
+ }
+ }
+
+ //check if we should be standing or walking
+ if (this.AgentList[userInfo.AgentID].Walk)
+ {
+ this.AgentList[userInfo.AgentID].AnimID = AgentManager.AnimsLLUUID["ANIM_AGENT_WALK"];
+ this.AgentList[userInfo.AgentID].AnimSequenceID = 1;
+ this.UpdateAnim(userInfo);
+ }
+ else
+ {
+ this.AgentList[userInfo.AgentID].AnimID = AgentManager.AnimsLLUUID["ANIM_AGENT_STAND"];
+ this.AgentList[userInfo.AgentID].AnimSequenceID = 1;
+ this.UpdateAnim(userInfo);
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void SendLayerData(UserAgentInfo userInfo, ref LayerDataPacket layer, string name)
+ {
+ FileInfo fInfo = new FileInfo(name);
+ long numBytes = fInfo.Length;
+ FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read);
+ BinaryReader br = new BinaryReader(fStream);
+ byte [] data1 = br.ReadBytes((int)numBytes);
+ br.Close();
+ fStream.Close();
+ layer.LayerData.Data = data1;
+ _server.SendPacket(layer, true, userInfo);
+
+ }
+ }
+
+ public class AvatarData
+ {
+ public UserAgentInfo NetInfo;
+ public LLUUID FullID;
+ public LLVector3 Position;
+ public LLVector3 Velocity = new LLVector3(0,0,0);
+ //public LLQuaternion Rotation;
+ public bool Walk = false;
+ public bool Started = false;
+ //public TextureEntry TextureEntry;
+ public AvatarWearable[] Wearables;
+ public LLUUID InventoryFolder;
+ public LLUUID BaseFolder;
+ public LLUUID AnimID;
+ public int AnimSequenceID;
+ public float far;
+ public libsecondlife.LLVector3 CameraAtAxis;
+ public libsecondlife.LLVector3 CameraCenter;
+ public libsecondlife.LLVector3 CameraLeftAxis;
+ public libsecondlife.LLVector3 CameraUpAxis;
+
+ public AvatarData()
+ {
+ Wearables=new AvatarWearable[2]; //should be 13
+ for(int i = 0; i < 2; i++)
+ {
+ Wearables[i] = new AvatarWearable();
+ }
+ }
+ }
+
+ public class AvatarWearable
+ {
+ public LLUUID AssetID;
+ public LLUUID ItemID;
+
+ public AvatarWearable()
+ {
+
+ }
+ }
+ /*
+ public class AvatarParams
+ {
+ public byte[] Params;
+
+ public AvatarParams()
+ {
+
+ }
+
+ }
+ */
+}
diff --git a/src/AssetManagement.cs b/src/AssetManagement.cs
new file mode 100644
index 0000000..f919476
--- /dev/null
+++ b/src/AssetManagement.cs
@@ -0,0 +1,455 @@
+/*
+ *
+Copyright (c) OpenSim project, http://osgrid.org/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the 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 System.Net;
+using System.Collections.Generic;
+using libsecondlife;
+using System.Collections;
+using libsecondlife.Packets;
+using libsecondlife.AssetSystem;
+using System.IO;
+
+namespace OpenSim
+{
+ ///
+ /// Asset and Image management
+ ///
+ public class AssetManagement
+ {
+ public Dictionary Assets;
+ public Dictionary Textures;
+
+ public ArrayList AssetRequests = new ArrayList(); //should change to a generic
+ public ArrayList TextureRequests = new ArrayList();
+ //public ArrayList uploads=new ArrayList();
+ private Server _server;
+ private InventoryManager _inventoryManager;
+ private System.Text.Encoding _enc = System.Text.Encoding.ASCII;
+
+ ///
+ ///
+ ///
+ ///
+ public AssetManagement(Server server, InventoryManager inventoryManager)
+ {
+ this._server = server;
+ this._inventoryManager = inventoryManager;
+ Textures = new Dictionary ();
+ Assets = new Dictionary ();
+ this.initialise();
+ }
+
+ ///
+ ///
+ ///
+ private void initialise()
+ {
+ //Shape and skin base assets
+ AssetInfo Asset = new AssetInfo();
+ Asset.filename = "base_shape.dat";
+ Asset.FullID = new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73");
+ this.LoadAsset(Asset, false);
+ this.Assets.Add(Asset.FullID, Asset);
+
+ Asset = new AssetInfo();
+ Asset.filename = "base_skin.dat";
+ Asset.FullID = new LLUUID("e0ee49b5a4184df8d3c9a65361fe7f49");
+ this.LoadAsset(Asset, false);
+ this.Assets.Add(Asset.FullID, Asset);
+
+ //our test images
+ //Change these filenames to images you want to use.
+ TextureImage Image = new TextureImage();
+ Image.filename = "testpic2.jp2";
+ Image.FullID = new LLUUID("00000000-0000-0000-5005-000000000005");
+ Image.Name = "test Texture";
+ this.LoadAsset(Image, true);
+ this.Textures.Add(Image.FullID, Image);
+
+ Image = new TextureImage();
+ Image.filename = "map_base.jp2";
+ Image.FullID = new LLUUID("00000000-0000-0000-7007-000000000006");
+ this.LoadAsset(Image, true);
+ this.Textures.Add(Image.FullID, Image);
+
+ Image = new TextureImage();
+ Image.filename = "map1.jp2";
+ Image.FullID = new LLUUID("00000000-0000-0000-7009-000000000008");
+ this.LoadAsset(Image, true);
+ this.Textures.Add(Image.FullID, Image);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ #region AssetRegion
+
+ public void AddAssetRequest(UserAgentInfo userInfo, LLUUID assetID, TransferRequestPacket transferRequest)
+ {
+
+ if(!this.Assets.ContainsKey(assetID))
+ {
+ //not found asset
+ return;
+ }
+ AssetInfo info = this.Assets[assetID];
+ //for now as it will be only skin or shape request just send back the asset
+ TransferInfoPacket Transfer = new TransferInfoPacket();
+ Transfer.TransferInfo.ChannelType = 2;
+ Transfer.TransferInfo.Status = 0;
+ Transfer.TransferInfo.TargetType = 0;
+ Transfer.TransferInfo.Params = transferRequest.TransferInfo.Params;
+ Transfer.TransferInfo.Size = info.data.Length;
+ Transfer.TransferInfo.TransferID = transferRequest.TransferInfo.TransferID;
+
+ _server.SendPacket(Transfer, true, userInfo);
+
+ TransferPacketPacket TransferPacket = new TransferPacketPacket();
+ TransferPacket.TransferData.Packet = 0;
+ TransferPacket.TransferData.ChannelType = 2;
+ TransferPacket.TransferData.TransferID=transferRequest.TransferInfo.TransferID;
+ if(info.data.Length>1000) //but needs to be less than 2000 at the moment
+ {
+ byte[] chunk = new byte[1000];
+ Array.Copy(info.data,chunk,1000);
+ TransferPacket.TransferData.Data = chunk;
+ TransferPacket.TransferData.Status = 0;
+ _server.SendPacket(TransferPacket,true,userInfo);
+
+ TransferPacket = new TransferPacketPacket();
+ TransferPacket.TransferData.Packet = 1;
+ TransferPacket.TransferData.ChannelType = 2;
+ TransferPacket.TransferData.TransferID = transferRequest.TransferInfo.TransferID;
+ byte[] chunk1 = new byte[(info.data.Length-1000)];
+ Array.Copy(info.data, 1000, chunk1, 0, chunk1.Length);
+ TransferPacket.TransferData.Data = chunk1;
+ TransferPacket.TransferData.Status = 1;
+ _server.SendPacket(TransferPacket, true, userInfo);
+ }
+ else
+ {
+ TransferPacket.TransferData.Status = 1; //last packet? so set to 1
+ TransferPacket.TransferData.Data = info.data;
+ _server.SendPacket(TransferPacket, true, userInfo);
+ }
+
+ }
+
+ public void CreateNewInventorySet(ref AvatarData Avata,UserAgentInfo UserInfo)
+ {
+ //Create Folders
+ LLUUID BaseFolder = Avata.BaseFolder;
+ _inventoryManager.CreateNewFolder(UserInfo, Avata.InventoryFolder);
+ _inventoryManager.CreateNewFolder(UserInfo, BaseFolder);
+
+ //Give a copy of default shape
+ AssetInfo Base = this.Assets[new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73")];
+ AssetInfo Shape = this.CloneAsset(UserInfo.AgentID, Base);
+
+ Shape.filename = "";
+ Shape.Name = "Default Shape";
+ Shape.Description = "Default Shape";
+ Shape.InvType = 18;
+ Shape.Type=13;
+ //Shape.Type = libsecondlife.AssetSystem.Asset.ASSET_TYPE_WEARABLE_BODY;
+
+ byte[] Agentid = _enc.GetBytes(UserInfo.AgentID.ToStringHyphenated());
+ Array.Copy(Agentid, 0, Shape.data, 294, Agentid.Length);
+ this.Assets.Add(Shape.FullID, Shape);
+
+ Avata.Wearables[0].ItemID = _inventoryManager.AddToInventory(UserInfo, BaseFolder, Shape);
+ Avata.Wearables[0].AssetID = Shape.FullID;
+
+ //Give copy of default skin
+ Base = this.Assets[new LLUUID("e0ee49b5a4184df8d3c9a65361fe7f49")];
+ AssetInfo Skin=this.CloneAsset(UserInfo.AgentID, Base);
+
+ Skin.filename = "";
+ Skin.Name = "Default Skin";
+ Skin.Description = "Default Skin";
+ Skin.InvType = 18;
+ Skin.Type=13;
+ //Skin.Type = libsecondlife.AssetSystem.Asset.ASSET_TYPE_WEARABLE_BODY;
+
+ Array.Copy(Agentid,0,Skin.data,238,Agentid.Length);
+ this.Assets.Add(Skin.FullID, Skin);
+
+ Avata.Wearables[1].ItemID = _inventoryManager.AddToInventory(UserInfo, BaseFolder, Skin);
+ Avata.Wearables[1].AssetID = Skin.FullID;
+
+ //give a copy of test texture
+ TextureImage Texture = this.CloneImage(UserInfo.AgentID, Textures[new LLUUID("00000000-0000-0000-5005-000000000005")]);
+ this.Textures.Add(Texture.FullID, Texture);
+ _inventoryManager.AddToInventory(UserInfo, BaseFolder, Texture);
+
+ }
+
+
+ private void LoadAsset(AssetBase info, bool Image)
+ {
+ WebRequest AssetLoad = WebRequest.Create(Globals.Instance.AssetURL + "getasset/" + Globals.Instance.AssetSendKey + "/" + info.FullID + "/data");
+ WebResponse AssetResponse = AssetLoad.GetResponse();
+ byte[] idata = new byte[(int)AssetResponse.ContentLength];
+ BinaryReader br = new BinaryReader(AssetResponse.GetResponseStream());
+ idata = br.ReadBytes((int)AssetResponse.ContentLength);
+ br.Close();
+ AssetResponse.Close();
+ info.data = idata;
+ }
+
+ public AssetInfo CloneAsset(LLUUID NewOwner, AssetInfo SourceAsset)
+ {
+ AssetInfo NewAsset = new AssetInfo();
+ NewAsset.data = new byte[SourceAsset.data.Length];
+ Array.Copy(SourceAsset.data, NewAsset.data, SourceAsset.data.Length);
+ NewAsset.FullID = LLUUID.Random();
+ NewAsset.Type = SourceAsset.Type;
+ NewAsset.InvType = SourceAsset.InvType;
+ return(NewAsset);
+ }
+ #endregion
+
+ #region TextureRegion
+ public void AddTextureRequest(UserAgentInfo userInfo, LLUUID imageID)
+ {
+
+ 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);
+ return;
+ }
+ TextureImage imag = this.Textures[imageID];
+ TextureRequest req = new TextureRequest();
+ req.RequestUser = userInfo;
+ req.RequestImage = imageID;
+ req.ImageInfo = imag;
+
+ if(imag.data.LongLength>600) //should be bigger or smaller?
+ {
+ //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);
+
+ }
+
+ public void AddTexture(LLUUID imageID, string name, byte[] data)
+ {
+
+ }
+ public void DoWork(ulong time)
+ {
+ 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.last_used = 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 RecieveTexture(Packet pack)
+ {
+
+ }
+
+ public TextureImage CloneImage(LLUUID newOwner, TextureImage source)
+ {
+ TextureImage newImage = new TextureImage();
+ newImage.data = new byte[source.data.Length];
+ Array.Copy(source.data,newImage.data,source.data.Length);
+ newImage.filename = source.filename;
+ newImage.FullID = LLUUID.Random();
+ newImage.Name = source.Name;
+ return(newImage);
+ }
+
+ #endregion
+ }
+
+ public class AssetRequest
+ {
+ public UserAgentInfo RequestUser;
+ public LLUUID RequestImage;
+ public AssetInfo asset_inf;
+ public long data_pointer = 0;
+ public int num_packets = 0;
+ public int packet_counter = 0;
+
+ public AssetRequest()
+ {
+
+ }
+ }
+ public class AssetInfo:AssetBase
+ {
+ //public byte[] data;
+ //public LLUUID Full_ID;
+ public bool loaded;
+ public ulong last_used; //need to add a tick/time counter and keep record
+ // of how often images are requested to unload unused ones.
+
+ public AssetInfo()
+ {
+
+ }
+ }
+
+ 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 TextureRequest
+ {
+ public UserAgentInfo RequestUser;
+ public LLUUID RequestImage;
+ public TextureImage ImageInfo;
+ public long DataPointer = 0;
+ public int NumPackets = 0;
+ public int PacketCounter = 0;
+
+ public TextureRequest()
+ {
+
+ }
+ }
+ public class TextureImage: AssetBase
+ {
+ //any need for this class now most has been moved into AssetBase?
+ //public byte[] data;
+ //public LLUUID Full_ID;
+ //public string name;
+ public bool loaded;
+ public ulong last_used; //need to add a tick/time counter and keep record
+ // of how often images are requested to unload unused ones.
+
+ public TextureImage()
+ {
+
+ }
+ }
+
+
+}
diff --git a/src/Asset_manager.cs b/src/Asset_manager.cs
new file mode 100644
index 0000000..60f8945
--- /dev/null
+++ b/src/Asset_manager.cs
@@ -0,0 +1,231 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+
+* Copyright (c) ,
+* All rights reserved.
+*
+* 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 System.Collections.Generic;
+using libsecondlife;
+using System.Collections;
+using libsecondlife.Packets;
+using libsecondlife.AssetSystem;
+using System.IO;
+
+namespace OpenSim
+{
+ ///
+ /// Description of Asset_manager.
+ ///
+ public class AssetManager
+ {
+ public Dictionary Assets;
+ public ArrayList requests=new ArrayList(); //should change to a generic
+ // public ArrayList uploads=new ArrayList();
+ private Server server;
+ public TextureManager TextureMan;
+ public InventoryManager InventoryManager;
+ private System.Text.Encoding enc = System.Text.Encoding.ASCII;
+
+ public AssetManager(Server serve)
+ {
+ server=serve;
+ Assets=new Dictionary ();
+ this.initialise();
+ }
+
+ public void AddRequest(User_Agent_info user, LLUUID asset_id, TransferRequestPacket tran_req)
+ {
+ Console.WriteLine("Asset Request "+ asset_id);
+ if(!this.Assets.ContainsKey(asset_id))
+ {
+ //not found asset
+ return;
+ }
+ AssetInfo info=this.Assets[asset_id];
+ System.Console.WriteLine("send asset : "+asset_id);
+ //for now as it will be only skin or shape request just send back the asset
+ TransferInfoPacket Transfer=new TransferInfoPacket();
+ Transfer.TransferInfo.ChannelType=2;
+ Transfer.TransferInfo.Status=0;
+ Transfer.TransferInfo.TargetType=0;
+ Transfer.TransferInfo.Params=tran_req.TransferInfo.Params;
+ Transfer.TransferInfo.Size=info.data.Length;
+ Transfer.TransferInfo.TransferID=tran_req.TransferInfo.TransferID;
+
+ server.SendPacket(Transfer,true,user);
+
+ TransferPacketPacket tran_p=new TransferPacketPacket();
+ tran_p.TransferData.Packet=0;
+ tran_p.TransferData.ChannelType=2;
+ tran_p.TransferData.TransferID=tran_req.TransferInfo.TransferID;
+ if(info.data.Length>1000) //but needs to be less than 2000 at the moment
+ {
+ byte[] chunk=new byte[1000];
+ Array.Copy(info.data,chunk,1000);
+ tran_p.TransferData.Data=chunk;
+ tran_p.TransferData.Status=0;
+ server.SendPacket(tran_p,true,user);
+
+ tran_p=new TransferPacketPacket();
+ tran_p.TransferData.Packet=1;
+ tran_p.TransferData.ChannelType=2;
+ tran_p.TransferData.TransferID=tran_req.TransferInfo.TransferID;
+ byte[] chunk1=new byte[(info.data.Length-1000)];
+ Array.Copy(info.data,1000,chunk1,0,chunk1.Length);
+ tran_p.TransferData.Data=chunk1;
+ tran_p.TransferData.Status=1;
+ server.SendPacket(tran_p,true,user);
+ }
+ else
+ {
+ tran_p.TransferData.Status=1; //last packet? so set to 1
+ tran_p.TransferData.Data=info.data;
+ server.SendPacket(tran_p,true,user);
+ }
+
+ }
+ public void CreateNewBaseSet(ref AvatarData Avata,User_Agent_info UserInfo)
+ {
+ //LLUUID BaseFolder=new LLUUID("4f5f559e-77a0-a4b9-84f9-8c74c07f7cfc");//*/"4fb2dab6-a987-da66-05ee-96ca82bccbf1");
+ //LLUUID BaseFolder=new LLUUID("480e2d92-61f6-9f16-f4f5-0f77cfa4f8f9");
+ LLUUID BaseFolder=Avata.BaseFolder;
+ InventoryManager.CreateNewFolder(UserInfo,Avata.InventoryFolder);
+ InventoryManager.CreateNewFolder(UserInfo, BaseFolder);
+
+ AssetInfo Base=this.Assets[new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73")];
+ AssetInfo Shape=new AssetInfo();
+
+ Shape.filename="";
+ Shape.data=new byte[Base.data.Length];
+ Array.Copy(Base.data,Shape.data,Base.data.Length);
+ Shape.Full_ID=LLUUID.Random();
+ Shape.Name="Default Skin";
+ Shape.Description="Default";
+ Shape.InvType=18;
+
+ Shape.Type=libsecondlife.AssetSystem.ASSET_TYPE_WEARABLE_BODY;
+ byte[] Agentid=enc.GetBytes(UserInfo.AgentID.ToStringHyphenated());
+ Array.Copy(Agentid,0,Shape.data,294,Agentid.Length);
+ this.Assets.Add(Shape.Full_ID,Shape);
+ /*FileStream fStream = new FileStream("Assetshape.dat", FileMode.CreateNew);
+ BinaryWriter bw = new BinaryWriter(fStream);
+ bw.Write(Shape.data);
+ bw.Close();
+ fStream.Close();*/
+
+ Avata.Wearables[0].ItemID=InventoryManager.AddToInventory(UserInfo,BaseFolder,Shape);
+ Avata.Wearables[0].AssetID=Shape.Full_ID;
+ //Avata.RootFolder=BaseFolder;
+
+ //give test texture
+
+ TextureImage Texture=TextureMan.textures[new LLUUID("00000000-0000-0000-5005-000000000005")];
+ InventoryManager.AddToInventory(UserInfo,BaseFolder,Texture);
+
+ }
+
+ private void initialise()
+ {
+ //for now read in our test image
+ AssetInfo im=new AssetInfo();
+ im.filename="base_shape.dat";
+ im.Full_ID=new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73");
+ this.loadAsset(im);
+ this.Assets.Add(im.Full_ID,im);
+
+
+ im=new AssetInfo();
+ im.filename="base_skin.dat";
+ im.Full_ID=new LLUUID("e0ee49b5a4184df8d3c9a65361fe7f49");
+ this.loadAsset(im);
+ this.Assets.Add(im.Full_ID,im);
+ }
+ private void loadAsset(AssetInfo info)
+ {
+ //should request Asset from storage manager
+ //but for now read from file
+
+ string data_path = System.AppDomain.CurrentDomain.BaseDirectory + @"\assets\";
+ string filename=data_path+@info.filename;
+ FileInfo fInfo = new FileInfo(filename);
+
+ long numBytes = fInfo.Length;
+
+ FileStream fStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
+ byte[] idata=new byte[numBytes];
+ BinaryReader br = new BinaryReader(fStream);
+ idata= br.ReadBytes((int)numBytes);
+ br.Close();
+ fStream.Close();
+ info.data=idata;
+ info.loaded=true;
+ }
+ }
+
+ public class AssetRequest
+ {
+ public User_Agent_info RequestUser;
+ public LLUUID RequestImage;
+ public AssetInfo asset_inf;
+ public long data_pointer=0;
+ public int num_packets=0;
+ public int packet_counter=0;
+
+ public AssetRequest()
+ {
+
+ }
+ }
+ public class AssetInfo:AssetBase
+ {
+ //public byte[] data;
+ //public LLUUID Full_ID;
+ public string filename;
+ public bool loaded;
+ public ulong last_used; //need to add a tick/time counter and keep record
+ // of how often images are requested to unload unused ones.
+
+ public AssetInfo()
+ {
+
+ }
+ }
+
+ public class AssetBase
+ {
+ public byte[] data;
+ public LLUUID Full_ID;
+ public sbyte Type;
+ public sbyte InvType;
+ public string Name;
+ public string Description;
+
+ public AssetBase()
+ {
+
+ }
+ }
+}
diff --git a/src/Config.cs b/src/Config.cs
new file mode 100644
index 0000000..44e0689
--- /dev/null
+++ b/src/Config.cs
@@ -0,0 +1,140 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+
+* Copyright (c) ,
+* All rights reserved.
+*
+* 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 System.Collections.Generic;
+using System.IO;
+using Db4objects.Db4o;
+using libsecondlife;
+using OpenSim.world;
+
+namespace OpenSim
+{
+ ///
+ /// This class handles connection to the underlying database used for configuration of the region.
+ /// Region content is also stored by this class. The main entry point is InitConfig() which attempts to locate
+ /// opensim.yap in the current working directory. If opensim.yap can not be found, default settings are loaded from
+ /// what is hardcoded here and then saved into opensim.yap for future startups.
+ ///
+ public class SimConfig
+ {
+ public string RegionName;
+
+ public uint RegionLocX;
+ public uint RegionLocY;
+ public ulong RegionHandle;
+
+ public int IPListenPort;
+ public string IPListenAddr;
+
+ public string AssetURL;
+ public string AssetSendKey;
+
+ public string GridURL;
+ public string GridSendKey;
+
+ private IObjectContainer db;
+
+ public void LoadDefaults() {
+ this.RegionName = "OpenSim test\0";
+ this.RegionLocX = 997;
+ this.RegionLocY = 996;
+ this.RegionHandle = Helpers.UIntsToLong((RegionLocX*256), (RegionLocY*256));
+ this.IPListenPort = 9000;
+ this.IPListenAddr = "4.78.190.75";
+ this.AssetURL = "http://osgrid.org/ogs/assetserver/";
+ this.AssetSendKey = "1234";
+ this.GridURL = "http://osgrid.org/ogs/gridserver/";
+ this.GridSendKey = "1234";
+ }
+
+ public void InitConfig() {
+ try {
+ db = Db4oFactory.OpenFile("opensim.yap");
+ IObjectSet result = db.Get(typeof(SimConfig));
+ if(result.Count==1) {
+ Console.WriteLine("Config.cs:InitConfig() - Found a SimConfig object in the local database, loading");
+ foreach (SimConfig cfg in result) {
+ this.RegionName = cfg.RegionName;
+ this.RegionLocX = cfg.RegionLocX;
+ this.RegionLocY = cfg.RegionLocY;
+ this.RegionHandle = Helpers.UIntsToLong((RegionLocX*256), (RegionLocY*256));
+ this.IPListenPort = cfg.IPListenPort;
+ this.IPListenAddr = cfg.IPListenAddr;
+ this.AssetURL = cfg.AssetURL;
+ this.AssetSendKey = cfg.AssetSendKey;
+ this.GridURL = cfg.GridURL;
+ this.GridSendKey = cfg.GridSendKey;
+ }
+ } else {
+ Console.WriteLine("Config.cs:InitConfig() - Could not find object in database, loading precompiled defaults");
+ LoadDefaults();
+ Console.WriteLine("Writing out default settings to local database");
+ db.Set(this);
+ }
+ } catch(Exception e) {
+ db.Close();
+ Console.WriteLine("Config.cs:InitConfig() - Exception occured");
+ Console.WriteLine(e.ToString());
+ }
+ }
+
+ public World LoadWorld() {
+ IObjectSet world_result = db.Get(typeof(OpenSim.world.World));
+ if(world_result.Count==1) {
+ Console.WriteLine("Config.cs:LoadWorld() - Found an OpenSim.world.World object in local database, loading");
+ return (World)world_result.Next();
+ } else {
+ Console.WriteLine("Config.cs:LoadWorld() - Could not find the world or too many worlds! Constructing blank one");
+ World blank = new World();
+ Console.WriteLine("Config.cs:LoadWorld() - Saving initial world state to disk");
+ db.Set(blank);
+ db.Commit();
+ return blank;
+ }
+ }
+
+ public void LoadFromGrid() {
+ Console.WriteLine("Config.cs:LoadFromGrid() - dummy function, DOING ABSOLUTELY NOTHING AT ALL!!!");
+ // TODO: Make this crap work
+ /* WebRequest GridLogin = WebRequest.Create(this.GridURL + "regions/" + this.RegionHandle.ToString() + "/login");
+ WebResponse GridResponse = GridLogin.GetResponse();
+ byte[] idata = new byte[(int)GridResponse.ContentLength];
+ BinaryReader br = new BinaryReader(GridResponse.GetResponseStream());
+
+ br.Close();
+ GridResponse.Close();
+ */
+ }
+
+ public void Shutdown() {
+ db.Close();
+ }
+ }
+}
diff --git a/src/GridManager.cs b/src/GridManager.cs
new file mode 100644
index 0000000..3d3b35d
--- /dev/null
+++ b/src/GridManager.cs
@@ -0,0 +1,372 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+
+* Copyright (c) ,
+* All rights reserved.
+*
+* 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 System.Collections.Generic;
+using libsecondlife;
+using System.Collections;
+using libsecondlife.Packets;
+using libsecondlife.AssetSystem;
+using System.IO;
+using System.Xml;
+
+
+namespace OpenSim
+{
+ ///
+ /// Description of GridManager.
+ ///
+ public class GridManager
+ {
+ private Server _server;
+ private System.Text.Encoding _enc = System.Text.Encoding.ASCII;
+ private AgentManager _agentManager;
+ public Dictionary Grid;
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public GridManager(Server server, AgentManager agentManager)
+ {
+ Grid = new Dictionary();
+ _server = server;
+ _agentManager = agentManager;
+ LoadGrid();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void RequestMapLayer(UserAgentInfo userInfo)
+ {
+ //send a layer covering the 800,800 - 1200,1200 area
+ MapLayerReplyPacket MapReply = new MapLayerReplyPacket();
+ MapReply.AgentData.AgentID = userInfo.AgentID;
+ MapReply.AgentData.Flags = 0;
+ MapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1];
+ MapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock();
+ MapReply.LayerData[0].Bottom = 800;
+ MapReply.LayerData[0].Left = 800;
+ MapReply.LayerData[0].Top = 1200;
+ MapReply.LayerData[0].Right = 1200;
+ MapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-7007-000000000006");
+ _server.SendPacket(MapReply, true, userInfo);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void RequestMapBlock(UserAgentInfo userInfo, int minX, int minY,int maxX,int maxY)
+ {
+ foreach (KeyValuePair RegionPair in this.Grid)
+ {
+ //check Region is inside the requested area
+ RegionInfo Region = RegionPair.Value;
+ if(((Region.X > minX) && (Region.X < maxX)) && ((Region.Y > minY) && (Region.Y < maxY)))
+ {
+ MapBlockReplyPacket MapReply = new MapBlockReplyPacket();
+ MapReply.AgentData.AgentID = userInfo.AgentID;
+ MapReply.AgentData.Flags = 0;
+ MapReply.Data = new MapBlockReplyPacket.DataBlock[1];
+ MapReply.Data[0] = new MapBlockReplyPacket.DataBlock();
+ MapReply.Data[0].MapImageID = Region.ImageID;
+ MapReply.Data[0].X = Region.X;
+ MapReply.Data[0].Y = Region.Y;
+ MapReply.Data[0].WaterHeight = Region.WaterHeight;
+ MapReply.Data[0].Name = _enc.GetBytes( Region.Name);
+ MapReply.Data[0].RegionFlags = 72458694;
+ MapReply.Data[0].Access = 13;
+ MapReply.Data[0].Agents = 1;
+ _server.SendPacket(MapReply, true, userInfo);
+ }
+ }
+
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void RequestTeleport(UserAgentInfo userInfo, TeleportLocationRequestPacket request)
+ {
+ if(Grid.ContainsKey(request.Info.RegionHandle))
+ {
+ RegionInfo Region = Grid[request.Info.RegionHandle];
+ libsecondlife.Packets.TeleportStartPacket TeleportStart = new TeleportStartPacket();
+ TeleportStart.Info.TeleportFlags = 16;
+ _server.SendPacket(TeleportStart, true, userInfo);
+
+ libsecondlife.Packets.TeleportFinishPacket Teleport = new TeleportFinishPacket();
+ Teleport.Info.AgentID = userInfo.AgentID;
+ Teleport.Info.RegionHandle = request.Info.RegionHandle;
+ Teleport.Info.SimAccess = 13;
+ Teleport.Info.SeedCapability = new byte[0];
+
+ System.Net.IPAddress oIP = System.Net.IPAddress.Parse(Region.IPAddress.Address);
+ byte[] byteIP = oIP.GetAddressBytes();
+ uint ip=(uint)byteIP[3]<<24;
+ ip+=(uint)byteIP[2]<<16;
+ ip+=(uint)byteIP[1]<<8;
+ ip+=(uint)byteIP[0];
+
+ Teleport.Info.SimIP = ip;
+ Teleport.Info.SimPort = Region.IPAddress.Port;
+ Teleport.Info.LocationID = 4;
+ Teleport.Info.TeleportFlags = 1 << 4;;
+ _server.SendPacket(Teleport, true, userInfo);
+
+ this._agentManager.RemoveAgent(userInfo);
+ }
+
+ }
+
+ ///
+ ///
+ ///
+ private void LoadGrid()
+ {
+ //should connect to a space server to see what grids there are
+ //but for now we read static xml files
+ ulong CurrentHandle = 0;
+ bool Login = true;
+
+ XmlDocument doc = new XmlDocument();
+
+ try {
+ doc.Load(Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Grid.ini" ));
+ }
+ catch ( Exception e)
+ {
+ Console.WriteLine(e.Message);
+ return;
+ }
+
+ try
+ {
+ XmlNode root = doc.FirstChild;
+ if (root.Name != "Root")
+ throw new Exception("Error: Invalid File. Missing ");
+
+ XmlNode nodes = root.FirstChild;
+ if (nodes.Name != "Grid")
+ throw new Exception("Error: Invalid File. first child should be ");
+
+ if (nodes.HasChildNodes) {
+ foreach( XmlNode xmlnc in nodes.ChildNodes)
+ {
+ if(xmlnc.Name == "Region")
+ {
+ string xmlAttri;
+ RegionInfo Region = new RegionInfo();
+ if(xmlnc.Attributes["Name"] != null)
+ {
+ xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Name")).Value;
+ Region.Name = xmlAttri+" \0";
+ }
+ if(xmlnc.Attributes["ImageID"] != null)
+ {
+ xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("ImageID")).Value;
+ Region.ImageID = new LLUUID(xmlAttri);
+ }
+ if(xmlnc.Attributes["IP_Address"] != null)
+ {
+ xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("IP_Address")).Value;
+ Region.IPAddress.Address = xmlAttri;
+ }
+ if(xmlnc.Attributes["IP_Port"] != null)
+ {
+ xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("IP_Port")).Value;
+ Region.IPAddress.Port = Convert.ToUInt16(xmlAttri);
+ }
+ if(xmlnc.Attributes["Location_X"] != null)
+ {
+ xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Location_X")).Value;
+ Region.X = Convert.ToUInt16(xmlAttri);
+ }
+ if(xmlnc.Attributes["Location_Y"] != null)
+ {
+ xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Location_Y")).Value;
+ Region.Y = Convert.ToUInt16(xmlAttri);
+ }
+
+ this.Grid.Add(Region.Handle, Region);
+
+ }
+ if(xmlnc.Name == "CurrentRegion")
+ {
+
+ string xmlAttri;
+ uint Rx = 0, Ry = 0;
+ if(xmlnc.Attributes["RegionHandle"] != null)
+ {
+ xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("RegionHandle")).Value;
+ CurrentHandle = Convert.ToUInt64(xmlAttri);
+
+ }
+ else
+ {
+ if(xmlnc.Attributes["Region_X"] != null)
+ {
+ xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Region_X")).Value;
+ Rx = Convert.ToUInt32(xmlAttri);
+ }
+ if(xmlnc.Attributes["Region_Y"] != null)
+ {
+ xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("Region_Y")).Value;
+ Ry = Convert.ToUInt32(xmlAttri);
+ }
+ }
+ if(xmlnc.Attributes["LoginServer"] != null)
+ {
+ xmlAttri = ((XmlAttribute)xmlnc.Attributes.GetNamedItem("LoginServer")).Value;
+ Login = Convert.ToBoolean(xmlAttri);
+
+ }
+ if(CurrentHandle == 0)
+ {
+ //no RegionHandle set
+ //so check for Region X and Y
+ if((Rx > 0) && (Ry > 0))
+ {
+ CurrentHandle = Helpers.UIntsToLong((Rx*256), (Ry*256));
+ }
+ else
+ {
+ //seems to be no Region location set
+ // so set default
+ CurrentHandle = 1096213093147648;
+ }
+ }
+ }
+ }
+
+ //finished loading grid, now set Globals to current region
+ if(CurrentHandle != 0)
+ {
+ if(Grid.ContainsKey(CurrentHandle))
+ {
+ RegionInfo Region = Grid[CurrentHandle];
+ Globals.Instance.RegionHandle = Region.Handle;
+ Globals.Instance.RegionName = Region.Name;
+ Globals.Instance.IpPort = Region.IPAddress.Port;
+ Globals.Instance.LoginSever = Login;
+ }
+ }
+
+ }
+ }
+ catch ( Exception e)
+ {
+ Console.WriteLine(e.Message);
+ return;
+ }
+ }
+ }
+
+ public class RegionInfo
+ {
+ public RegionIP IPAddress;
+ public string Name;
+ public ushort x;
+ public ushort y;
+ public ulong handle;
+ public LLUUID ImageID;
+ public uint Flags;
+ public byte WaterHeight;
+
+ public ushort X
+ {
+ get
+ {
+ return(x);
+ }
+ set
+ {
+ x = value;
+ Handle = Helpers.UIntsToLong((((uint)x)*256), (((uint)y)*256));
+ }
+ }
+ public ushort Y
+ {
+ get
+ {
+ return(y);
+ }
+ set
+ {
+ y = value;
+ Handle = Helpers.UIntsToLong((((uint)x)*256), (((uint)y)*256));
+ }
+ }
+ public ulong Handle
+ {
+ get
+ {
+ if(handle > 0)
+ {
+ return(handle);
+ }
+ else
+ {
+ return(Helpers.UIntsToLong((((uint)x)*256), (((uint)y)*256)));
+ }
+ }
+ set
+ {
+ handle = value;
+ }
+
+ }
+
+ public RegionInfo()
+ {
+ this.IPAddress = new RegionIP();
+ }
+ }
+ public class RegionIP
+ {
+ public string Address;
+ public ushort Port;
+
+ public RegionIP()
+ {
+
+ }
+
+ }
+}
diff --git a/src/InventoryManager.cs b/src/InventoryManager.cs
new file mode 100644
index 0000000..1df55a3
--- /dev/null
+++ b/src/InventoryManager.cs
@@ -0,0 +1,242 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the 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 System.Collections.Generic;
+using libsecondlife;
+using libsecondlife.Packets;
+using libsecondlife.AssetSystem;
+using System.IO;
+
+namespace OpenSim
+{
+ ///
+ /// Description of InventoryManager.
+ ///
+ public class InventoryManager
+ {
+
+ public Dictionary Folders;
+ public Dictionary Items;
+ private Server _server;
+ private System.Text.Encoding _enc = System.Text.Encoding.ASCII;
+ private const uint FULL_MASK_PERMISSIONS = 2147483647;
+
+ ///
+ ///
+ ///
+ ///
+ public InventoryManager(Server server)
+ {
+ _server = server;
+ Folders=new Dictionary();
+ Items=new Dictionary();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public LLUUID AddToInventory(UserAgentInfo userInfo, LLUUID folderID, AssetBase asset)
+ {
+ if(this.Folders.ContainsKey(folderID))
+ {
+ LLUUID NewItemID = LLUUID.Random();
+
+ InventoryItem Item = new InventoryItem();
+ Item.FolderID = folderID;
+ Item.OwnerID = userInfo.AgentID;
+ Item.AssetID = asset.FullID;
+ Item.ItemID = NewItemID;
+ Item.Type = asset.Type;
+ Item.Name = asset.Name;
+ Item.Description = asset.Description;
+ Item.InvType = asset.InvType;
+ this.Items.Add(Item.ItemID, Item);
+ InventoryFolder Folder = Folders[Item.FolderID];
+ Folder.Items.Add(Item);
+ return(Item.ItemID);
+ }
+ else
+ {
+ return(null);
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public bool CreateNewFolder(UserAgentInfo userInfo, LLUUID newFolder)
+ {
+ InventoryFolder Folder = new InventoryFolder();
+ Folder.FolderID = newFolder;
+ Folder.OwnerID = userInfo.AgentID;
+ this.Folders.Add(Folder.FolderID, Folder);
+
+ return(true);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void FetchInventoryDescendents(UserAgentInfo userInfo, FetchInventoryDescendentsPacket FetchDescend)
+ {
+ if(FetchDescend.InventoryData.FetchItems)
+ {
+ if(this.Folders.ContainsKey(FetchDescend.InventoryData.FolderID))
+ {
+
+ InventoryFolder Folder = this.Folders[FetchDescend.InventoryData.FolderID];
+ InventoryDescendentsPacket Descend = new InventoryDescendentsPacket();
+ Descend.AgentData.AgentID = userInfo.AgentID;
+ Descend.AgentData.OwnerID = Folder.OwnerID;
+ Descend.AgentData.FolderID = FetchDescend.InventoryData.FolderID;
+ Descend.AgentData.Descendents = Folder.Items.Count;
+ Descend.AgentData.Version = Folder.Items.Count;
+
+ Descend.ItemData = new InventoryDescendentsPacket.ItemDataBlock[Folder.Items.Count];
+ for(int i = 0; i < Folder.Items.Count ; i++)
+ {
+
+ InventoryItem Item=Folder.Items[i];
+ Descend.ItemData[i] = new InventoryDescendentsPacket.ItemDataBlock();
+ Descend.ItemData[i].ItemID = Item.ItemID;
+ Descend.ItemData[i].AssetID = Item.AssetID;
+ Descend.ItemData[i].CreatorID = Item.CreatorID;
+ Descend.ItemData[i].BaseMask = FULL_MASK_PERMISSIONS;
+ Descend.ItemData[i].CreationDate = 1000;
+ Descend.ItemData[i].Description = _enc.GetBytes(Item.Description+"\0");
+ Descend.ItemData[i].EveryoneMask = FULL_MASK_PERMISSIONS;
+ Descend.ItemData[i].Flags = 1;
+ Descend.ItemData[i].FolderID = Item.FolderID;
+ Descend.ItemData[i].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000");
+ Descend.ItemData[i].GroupMask = FULL_MASK_PERMISSIONS;
+ Descend.ItemData[i].InvType = Item.InvType;
+ Descend.ItemData[i].Name = _enc.GetBytes(Item.Name+"\0");
+ Descend.ItemData[i].NextOwnerMask = FULL_MASK_PERMISSIONS;
+ Descend.ItemData[i].OwnerID = Item.OwnerID;
+ Descend.ItemData[i].OwnerMask = FULL_MASK_PERMISSIONS;
+ Descend.ItemData[i].SalePrice = 100;
+ Descend.ItemData[i].SaleType = 0;
+ Descend.ItemData[i].Type = Item.Type;
+ Descend.ItemData[i].CRC=libsecondlife.Helpers.InventoryCRC(1000, 0, Descend.ItemData[i].InvType, Descend.ItemData[i].Type, Descend.ItemData[i].AssetID, Descend.ItemData[i].GroupID, 100, Descend.ItemData[i].OwnerID, Descend.ItemData[i].CreatorID, Descend.ItemData[i].ItemID, Descend.ItemData[i].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS);
+ }
+ _server.SendPacket(Descend, true, userInfo);
+
+ }
+ }
+ else
+ {
+ Console.WriteLine("fetch subfolders");
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void FetchInventory(UserAgentInfo userInfo, FetchInventoryPacket FetchItems)
+ {
+
+ for(int i = 0; i < FetchItems.InventoryData.Length; i++)
+ {
+ if(this.Items.ContainsKey(FetchItems.InventoryData[i].ItemID))
+ {
+
+ InventoryItem Item = Items[FetchItems.InventoryData[i].ItemID];
+ FetchInventoryReplyPacket InventoryReply = new FetchInventoryReplyPacket();
+ InventoryReply.AgentData.AgentID = userInfo.AgentID;
+ InventoryReply.InventoryData = new FetchInventoryReplyPacket.InventoryDataBlock[1];
+ InventoryReply.InventoryData[0] = new FetchInventoryReplyPacket.InventoryDataBlock();
+ InventoryReply.InventoryData[0].ItemID = Item.ItemID;
+ InventoryReply.InventoryData[0].AssetID = Item.AssetID;
+ InventoryReply.InventoryData[0].CreatorID = Item.CreatorID;
+ InventoryReply.InventoryData[0].BaseMask = FULL_MASK_PERMISSIONS;
+ InventoryReply.InventoryData[0].CreationDate = 1000;
+ InventoryReply.InventoryData[0].Description = _enc.GetBytes( Item.Description+"\0");
+ InventoryReply.InventoryData[0].EveryoneMask = FULL_MASK_PERMISSIONS;
+ InventoryReply.InventoryData[0].Flags = 1;
+ InventoryReply.InventoryData[0].FolderID = Item.FolderID;
+ InventoryReply.InventoryData[0].GroupID = new LLUUID("00000000-0000-0000-0000-000000000000");
+ InventoryReply.InventoryData[0].GroupMask = FULL_MASK_PERMISSIONS;
+ InventoryReply.InventoryData[0].InvType = Item.InvType;
+ InventoryReply.InventoryData[0].Name = _enc.GetBytes(Item.Name+"\0");
+ InventoryReply.InventoryData[0].NextOwnerMask = FULL_MASK_PERMISSIONS;
+ InventoryReply.InventoryData[0].OwnerID = Item.OwnerID;
+ InventoryReply.InventoryData[0].OwnerMask = FULL_MASK_PERMISSIONS;
+ InventoryReply.InventoryData[0].SalePrice = 100;
+ InventoryReply.InventoryData[0].SaleType = 0;
+ InventoryReply.InventoryData[0].Type = Item.Type;
+ InventoryReply.InventoryData[0].CRC = libsecondlife.Helpers.InventoryCRC(1000, 0, InventoryReply.InventoryData[0].InvType, InventoryReply.InventoryData[0].Type, InventoryReply.InventoryData[0].AssetID, InventoryReply.InventoryData[0].GroupID, 100, InventoryReply.InventoryData[0].OwnerID, InventoryReply.InventoryData[0].CreatorID, InventoryReply.InventoryData[0].ItemID, InventoryReply.InventoryData[0].FolderID, FULL_MASK_PERMISSIONS, 1, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS, FULL_MASK_PERMISSIONS);
+ _server.SendPacket(InventoryReply, true, userInfo);
+ }
+ }
+ }
+ }
+
+ public class InventoryFolder
+ {
+ public List Items;
+ //public List Subfolders;
+
+ public LLUUID FolderID;
+ public LLUUID OwnerID;
+ public LLUUID ParentID;
+
+
+ public InventoryFolder()
+ {
+ Items = new List();
+ }
+
+ }
+
+ public class InventoryItem
+ {
+ public LLUUID FolderID;
+ public LLUUID OwnerID;
+ public LLUUID ItemID;
+ public LLUUID AssetID;
+ public LLUUID CreatorID = LLUUID.Zero;
+ public sbyte InvType;
+ public sbyte Type;
+ public string Name;
+ public string Description;
+
+ public InventoryItem()
+ {
+
+ }
+ }
+}
diff --git a/src/Login_manager.cs b/src/Login_manager.cs
new file mode 100644
index 0000000..dd741f5
--- /dev/null
+++ b/src/Login_manager.cs
@@ -0,0 +1,228 @@
+/*
+* Copyright (c) OpenSim project, http://osgrid.org/>
+* All rights reserved.
+*
+* 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 Nwc.XmlRpc;
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Collections;
+using System.Xml;
+using libsecondlife;
+
+namespace OpenSim
+{
+ ///
+ /// Description of Login_manager.
+ ///
+ public class LoginManager
+ {
+ public LoginManager(Logon login)
+ {
+ Login=login;
+ }
+ public Logon Login;
+ public ushort loginPort = Globals.Instance.LoginServerPort;
+ public IPAddress clientAddress = IPAddress.Loopback;
+ public IPAddress remoteAddress = IPAddress.Any;
+ private Socket loginServer;
+ private Random RandomClass = new Random();
+ private int NumClients;
+
+ // InitializeLoginProxy: initialize the login proxy
+ private void InitializeLoginProxy() {
+ loginServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+ loginServer.Bind(new IPEndPoint(remoteAddress, loginPort));
+ loginServer.Listen(1);
+ }
+
+ public void Startup()
+ {
+ this.InitializeLoginProxy();
+ Thread runLoginProxy = new Thread(new ThreadStart(RunLoginProxy));
+ runLoginProxy.IsBackground = true;
+ runLoginProxy.Start();
+ }
+
+ private void RunLoginProxy()
+ {
+ try
+ {
+ for (;;)
+ {
+ Socket client = loginServer.Accept();
+ IPEndPoint clientEndPoint = (IPEndPoint)client.RemoteEndPoint;
+
+
+ NetworkStream networkStream = new NetworkStream(client);
+ StreamReader networkReader = new StreamReader(networkStream);
+ StreamWriter networkWriter = new StreamWriter(networkStream);
+
+ try
+ {
+ ProxyLogin(networkReader, networkWriter);
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+
+ networkWriter.Close();
+ networkReader.Close();
+ networkStream.Close();
+
+ client.Close();
+
+ // send any packets queued for injection
+
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ Console.WriteLine(e.StackTrace);
+ }
+ }
+
+ // ProxyLogin: proxy a login request
+ private void ProxyLogin(StreamReader reader, StreamWriter writer) { lock(this) {
+ string line;
+ int contentLength = 0;
+
+ // read HTTP header
+ do
+ {
+ // read one line of the header
+ line = reader.ReadLine();
+
+ // check for premature EOF
+ if (line == null)
+ throw new Exception("EOF in client HTTP header");
+
+ // look for Content-Length
+ Match match = (new Regex(@"Content-Length: (\d+)$")).Match(line);
+ if (match.Success)
+ contentLength = Convert.ToInt32(match.Groups[1].Captures[0].ToString());
+ } while (line != "");
+
+ // read the HTTP body into a buffer
+ char[] content = new char[contentLength];
+ reader.Read(content, 0, contentLength);
+ //System.Text.Encoding enc = System.Text.Encoding.ASCII;
+ XmlRpcRequest request = (XmlRpcRequest)(new XmlRpcRequestDeserializer()).Deserialize(new String(content));
+ Hashtable requestData = (Hashtable)request.Params[0];
+
+ string first;
+ string last;
+ LLUUID Agent;
+ LLUUID Session;
+
+ //get login name
+ if(requestData.Contains("first"))
+ {
+ first = (string)requestData["first"];
+ }
+ else
+ {
+ first = "test";
+ }
+ if(requestData.Contains("last"))
+ {
+ last = (string)requestData["last"];
+ }
+ else
+ {
+ last = "User"+NumClients.ToString();
+ }
+ NumClients++;
+
+ //create a agent and session LLUUID
+ int AgentRand = this.RandomClass.Next(1,9999);
+ Agent = new LLUUID("99998888-"+AgentRand.ToString("0000")+"-4f52-8ec1-0b1d5cd6aead");
+ int SessionRand = this.RandomClass.Next(1,999);
+ Session = new LLUUID("aaaabbbb-8932-"+SessionRand.ToString("0000")+"-8664-58f53e442797");
+
+
+ StreamReader SR;
+ string ResponseString = "";
+ string lines;
+ SR=File.OpenText("new-login.dat");
+
+ lines=SR.ReadLine();
+
+ while(lines != "end-mfile")
+ {
+
+ ResponseString += lines;
+ lines = SR.ReadLine();
+ }
+ SR.Close();
+
+ XmlRpcResponse response =(XmlRpcResponse)(new XmlRpcResponseDeserializer()).Deserialize(ResponseString);
+ Hashtable responseData = (Hashtable)response.Value;
+
+ responseData["agent_id"] = Agent.ToStringHyphenated();
+ responseData["session_id"] = Session.ToStringHyphenated();
+ ArrayList InventoryList = (ArrayList) responseData["inventory-skeleton"];
+ Hashtable Inventory1 = (Hashtable)InventoryList[0];
+ Hashtable Inventory2 = (Hashtable)InventoryList[1];
+ LLUUID BaseFolderID = LLUUID.Random();
+ LLUUID InventoryFolderID = LLUUID.Random();
+ Inventory2["name"] = "Base";
+ Inventory2["folder_id"] = BaseFolderID.ToStringHyphenated();
+ Inventory1["folder_id"] = InventoryFolderID.ToStringHyphenated();
+
+ ArrayList InventoryRoot = (ArrayList) responseData["inventory-root"];
+ Hashtable Inventoryroot = (Hashtable)InventoryRoot[0];
+ Inventoryroot["folder_id"] = InventoryFolderID.ToStringHyphenated();
+
+
+ //copy data to login object
+ lock(Login)
+ {
+ Login.First = first;
+ Login.Last = last;
+ Login.Agent = Agent;
+ Login.Session = Session;
+ Login.BaseFolder = BaseFolderID;
+ Login.InventoryFolder = InventoryFolderID;
+ }
+
+ // forward the XML-RPC response to the client
+ writer.WriteLine("HTTP/1.0 200 OK");
+ writer.WriteLine("Content-type: text/xml");
+ writer.WriteLine();
+
+ XmlTextWriter responseWriter = new XmlTextWriter(writer);
+ XmlRpcResponseSerializer.Singleton.Serialize(responseWriter, response);
+ responseWriter.Close();
+ }
+ }
+ }
+}
diff --git a/src/Main.cs b/src/Main.cs
new file mode 100644
index 0000000..da926db
--- /dev/null
+++ b/src/Main.cs
@@ -0,0 +1,138 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+
+
+* All rights reserved.
+*
+* 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 System.Text;
+using System.IO;
+using System.Threading;
+using System.Net;
+using System.Net.Sockets;
+using System.Collections;
+using System.Collections.Generic;
+using libsecondlife;
+using libsecondlife.Packets;
+using OpenSim.world;
+
+namespace OpenSim
+{
+ ///
+ /// Description of MainForm.
+ ///
+ public class OpenSim_Main
+ {
+ private static OpenSim_Main sim;
+ public static SimConfig cfg;
+ public static World local_world;
+ private static Thread MainListener;
+ private static Thread PingRespponder;
+ public static Socket Server;
+ private static IPEndPoint ServerIncoming;
+ private static byte[] RecvBuffer = new byte[4096];
+ private byte[] ZeroBuffer = new byte[8192];
+ private static IPEndPoint ipeSender;
+ private static EndPoint epSender;
+ private static AsyncCallback ReceivedData;
+ public Dictionary ClientThreads = new Dictionary();
+
+ [STAThread]
+ public static void Main( string[] args )
+ {
+ Console.WriteLine("OpenSim " + VersionInfo.Version + "\n");
+ Console.WriteLine("Starting...\n");
+ sim = new OpenSim_Main();
+ sim.Startup();
+ while(true) {
+ Thread.Sleep(1000);
+ }
+ }
+
+ private OpenSim_Main() {
+ }
+
+ private void Startup() {
+ // We check our local database first, then the grid for config options
+ Console.WriteLine("Main.cs:Startup() - Loading configuration");
+ cfg = new SimConfig();
+ cfg.InitConfig();
+ Console.WriteLine("Main.cs:Startup() - Contacting gridserver");
+ cfg.LoadFromGrid();
+
+ Console.WriteLine("Main.cs:Startup() - We are " + cfg.RegionName + " at " + cfg.RegionLocX.ToString() + "," + cfg.RegionLocY.ToString());
+ Console.WriteLine("Initialising world");
+ local_world = cfg.LoadWorld();
+
+ Console.WriteLine("Main.cs:Startup() - Starting up messaging system");
+ MainListener = new Thread(new ThreadStart(MainServerListener));
+ MainListener.Start();
+
+ }
+
+ private void OnReceivedData(IAsyncResult result) {
+ ipeSender = new IPEndPoint(IPAddress.Any, 0);
+ epSender = (EndPoint)ipeSender;
+ Packet packet = null;
+ int numBytes = Server.EndReceiveFrom(result, ref epSender);
+ int packetEnd = numBytes - 1;
+ packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer);
+ Console.Error.WriteLine(packet.ToString());
+
+ // This is either a new client or a packet to send to an old one
+ if(ClientThreads.ContainsKey(epSender)) {
+ ClientThreads[epSender].InPacket(packet);
+ } else if( packet.Type == PacketType.UseCircuitCode ) { // new client
+ OpenSimClient newuser = new OpenSimClient(epSender,(UseCircuitCodePacket)packet);
+ ClientThreads.Add(epSender, newuser);
+ } else { // invalid client
+ Console.Error.WriteLine("Main.cs:OnReceivedData() - WARNING: Got a packet from an invalid client - " + epSender.ToString());
+ }
+ Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
+ }
+
+ private void MainServerListener() {
+ Console.WriteLine("Main.cs:MainServerListener() - New thread started");
+ Console.WriteLine("Main.cs:MainServerListener() - Opening UDP socket on " + cfg.IPListenAddr + ":" + cfg.IPListenPort);
+
+ ServerIncoming = new IPEndPoint(IPAddress.Parse(cfg.IPListenAddr),cfg.IPListenPort);
+ Server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+ Server.Bind(ServerIncoming);
+
+ Console.WriteLine("Main.cs:MainServerListener() - UDP socket bound, getting ready to listen");
+
+ ipeSender = new IPEndPoint(IPAddress.Any, 0);
+ epSender = (EndPoint) ipeSender;
+ ReceivedData = new AsyncCallback(this.OnReceivedData);
+ Server.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
+
+ Console.WriteLine("Main.cs:MainServerListener() - Listening...");
+ while(true) {
+ Thread.Sleep(1000);
+ }
+ }
+ }
+}
diff --git a/src/OpenSimClient.cs b/src/OpenSimClient.cs
new file mode 100644
index 0000000..d3f90b7
--- /dev/null
+++ b/src/OpenSimClient.cs
@@ -0,0 +1,339 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the 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 System.Collections;
+using System.Collections.Generic;
+using libsecondlife;
+using libsecondlife.Packets;
+using System.Net;
+using System.Net.Sockets;
+using System.IO;
+using System.Threading;
+using System.Timers;
+
+namespace OpenSim
+{
+ ///
+ /// Handles new client connections
+ /// Constructor takes a single Packet and authenticates everything
+ ///
+ public class OpenSimClient {
+
+ public LLUUID AgentID;
+ public LLUUID SessionID;
+ public uint CircuitCode;
+ public world.Avatar ClientAvatar;
+ private UseCircuitCodePacket cirpack;
+ private Thread ClientThread;
+ private EndPoint userEP;
+ private BlockingQueue PacketQueue;
+ private Dictionary PendingAcks = new Dictionary();
+ private Dictionary NeedAck = new Dictionary();
+ private System.Timers.Timer AckTimer;
+ private uint Sequence = 0;
+ private object SequenceLock = new object();
+ private const int MAX_APPENDED_ACKS = 10;
+ private const int RESEND_TIMEOUT = 4000;
+ private const int MAX_SEQUENCE = 0xFFFFFF;
+
+ public void ack_pack(Packet Pack) {
+ //libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket();
+ //ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
+ //ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
+ //ack_it.Packets[0].ID = Pack.Header.ID;
+ //ack_it.Header.Reliable = false;
+
+ //OutPacket(ack_it);
+
+ if (Pack.Header.Reliable) {
+ lock (PendingAcks) {
+ uint sequence = (uint)Pack.Header.Sequence;
+ if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
+ }
+ }
+ }
+
+ public void ProcessInPacket(Packet Pack) {
+ ack_pack(Pack);
+ switch(Pack.Type) {
+ case PacketType.CompleteAgentMovement:
+ ClientAvatar.CompleteMovement(OpenSim_Main.local_world);
+ break;
+ }
+ }
+
+ private void ResendUnacked()
+ {
+ int now = Environment.TickCount;
+
+ lock (NeedAck)
+ {
+ foreach (Packet packet in NeedAck.Values)
+ {
+ if (now - packet.TickCount > RESEND_TIMEOUT)
+ {
+ Console.WriteLine("Resending " + packet.Type.ToString() + " packet, " +
+ (now - packet.TickCount) + "ms have passed", Helpers.LogLevel.Info);
+
+ packet.Header.Resent = true;
+ OutPacket(packet);
+ }
+ }
+ }
+ }
+
+ private void SendAcks()
+ {
+ lock (PendingAcks)
+ {
+ if (PendingAcks.Count > 0)
+ {
+ if (PendingAcks.Count > 250)
+ {
+ // FIXME: Handle the odd case where we have too many pending ACKs queued up
+ Console.WriteLine("Too many ACKs queued up!", Helpers.LogLevel.Error);
+ return;
+ }
+
+ Console.WriteLine("Sending PacketAck");
+
+
+ int i = 0;
+ PacketAckPacket acks = new PacketAckPacket();
+ acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];
+
+ foreach (uint ack in PendingAcks.Values)
+ {
+ acks.Packets[i] = new PacketAckPacket.PacketsBlock();
+ acks.Packets[i].ID = ack;
+ i++;
+ }
+
+ acks.Header.Reliable = false;
+ OutPacket(acks);
+
+ PendingAcks.Clear();
+ }
+ }
+ }
+
+ private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea)
+ {
+ SendAcks(); ResendUnacked();
+ }
+
+ public void ProcessOutPacket(Packet Pack) {
+
+ // Keep track of when this packet was sent out
+ Pack.TickCount = Environment.TickCount;
+
+ if (!Pack.Header.Resent)
+ {
+ // Set the sequence number
+ lock (SequenceLock)
+ {
+ if (Sequence >= MAX_SEQUENCE)
+ Sequence = 1;
+ else
+ Sequence++;
+ Pack.Header.Sequence = Sequence;
+ }
+
+ if (Pack.Header.Reliable)
+ {
+ lock (NeedAck)
+ {
+ if (!NeedAck.ContainsKey(Pack.Header.Sequence))
+ {
+ NeedAck.Add(Pack.Header.Sequence, Pack);
+ }
+ 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);
+ }
+ }
+
+ // Don't append ACKs to resent packets, in case that's what was causing the
+ // delivery to fail
+ if (!Pack.Header.Resent)
+ {
+ // Append any ACKs that need to be sent out to this packet
+ lock (PendingAcks)
+ {
+ if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS &&
+ Pack.Type != PacketType.PacketAck &&
+ Pack.Type != PacketType.LogoutRequest)
+ {
+ Pack.Header.AckList = new uint[PendingAcks.Count];
+ int i = 0;
+
+ foreach (uint ack in PendingAcks.Values)
+ {
+ Pack.Header.AckList[i] = ack;
+ i++;
+ }
+
+ PendingAcks.Clear();
+ Pack.Header.AppendedAcks = true;
+ }
+ }
+ }
+ }
+ }
+
+ Console.WriteLine("OUT: \n" + Pack.ToString());
+
+ byte[] ZeroOutBuffer = new byte[4096];
+ byte[] sendbuffer;
+ sendbuffer = Pack.ToBytes();
+
+ try {
+ if (Pack.Header.Zerocoded) {
+ int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
+ OpenSim_Main.Server.SendTo(ZeroOutBuffer, packetsize, SocketFlags.None,userEP);
+ } else {
+ OpenSim_Main.Server.SendTo(sendbuffer, sendbuffer.Length, SocketFlags.None,userEP);
+ }
+ } catch (Exception) {
+ Console.WriteLine("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread");
+ ClientThread.Abort();
+ }
+
+ }
+
+ public void InPacket(Packet NewPack) {
+ // Handle appended ACKs
+ if (NewPack.Header.AppendedAcks)
+ {
+ lock (NeedAck)
+ {
+ foreach (uint ack in NewPack.Header.AckList)
+ {
+ NeedAck.Remove(ack);
+ }
+ }
+ }
+
+ // Handle PacketAck packets
+ if (NewPack.Type == PacketType.PacketAck)
+ {
+ PacketAckPacket ackPacket = (PacketAckPacket)NewPack;
+
+ lock (NeedAck)
+ {
+ foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
+ {
+ NeedAck.Remove(block.ID);
+ }
+ }
+ } else if( ( NewPack.Type == PacketType.StartPingCheck ) ) {
+ //reply to pingcheck
+ libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack;
+ libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket();
+ endPing.PingID.PingID = startPing.PingID.PingID;
+ OutPacket(endPing);
+ }
+ else
+ {
+ QueItem item = new QueItem();
+ item.Packet = NewPack;
+ item.Incoming = true;
+ this.PacketQueue.Enqueue(item);
+ }
+
+ }
+
+ public void OutPacket(Packet NewPack) {
+ QueItem item = new QueItem();
+ item.Packet = NewPack;
+ item.Incoming = false;
+ this.PacketQueue.Enqueue(item);
+ }
+
+ public OpenSimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack) {
+ Console.WriteLine("OpenSimClient.cs - Started up new client thread to handle incoming request");
+ cirpack = initialcirpack;
+ userEP = remoteEP;
+ PacketQueue = new BlockingQueue();
+ AckTimer = new System.Timers.Timer(500);
+ AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
+ AckTimer.Start();
+
+ Thread ClientThread = new Thread(new ThreadStart(AuthUser));
+ ClientThread.IsBackground = true;
+ ClientThread.Start();
+ }
+
+ private void ClientLoop() {
+ Console.WriteLine("OpenSimClient.cs:ClientLoop() - Entered loop");
+ while(true) {
+ QueItem nextPacket = PacketQueue.Dequeue();
+ if(nextPacket.Incoming)
+ {
+ //is a incoming packet
+ ProcessInPacket(nextPacket.Packet);
+ }
+ else
+ {
+ //is a out going packet
+ ProcessOutPacket(nextPacket.Packet);
+ }
+ }
+ }
+
+ private void InitNewClient() {
+ Console.WriteLine("OpenSimClient.cs:InitNewClient() - Adding viewer agent to world");
+ OpenSim_Main.local_world.AddViewerAgent(this);
+ world.Entity tempent=OpenSim_Main.local_world.Entities[this.AgentID];
+ this.ClientAvatar=(world.Avatar)tempent;
+ }
+
+ private void AuthUser() {
+ Console.WriteLine("OpenSimClient.cs:AuthUser() - Authenticating new user request with grid");
+ WebRequest CheckSession = WebRequest.Create(OpenSim_Main.cfg.GridURL + "/usersessions/" + OpenSim_Main.cfg.GridSendKey + "/" + cirpack.CircuitCode.ID.ToString() + "/" + cirpack.CircuitCode.Code.ToString() + "/exists");
+ WebResponse GridResponse = CheckSession.GetResponse();
+ StreamReader sr = new StreamReader(GridResponse.GetResponseStream());
+ String grTest = sr.ReadLine();
+ sr.Close();
+ GridResponse.Close();
+ if(grTest.Equals("1")) { // YAY! Valid login
+ Console.WriteLine("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString());
+ this.AgentID=cirpack.CircuitCode.ID;
+ this.SessionID=cirpack.CircuitCode.SessionID;
+ this.CircuitCode=cirpack.CircuitCode.Code;
+ InitNewClient();
+ ClientLoop();
+ } else { // Invalid
+ Console.WriteLine("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString());
+ ClientThread.Abort();
+ }
+ }
+ }
+
+}
diff --git a/src/Physics_manager.cs b/src/Physics_manager.cs
new file mode 100644
index 0000000..a813deb
--- /dev/null
+++ b/src/Physics_manager.cs
@@ -0,0 +1,41 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+* All rights reserved.
+*
+* 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 Physics_manager.
+ ///
+ public class PhysicsManager
+ {
+ public PhysicsManager()
+ {
+ }
+ }
+}
diff --git a/src/Prim_manager.cs b/src/Prim_manager.cs
new file mode 100644
index 0000000..72eae35
--- /dev/null
+++ b/src/Prim_manager.cs
@@ -0,0 +1,382 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+* All rights reserved.
+*
+* 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 System.Collections.Generic;
+using libsecondlife;
+using libsecondlife.Packets;
+using libsecondlife.AssetSystem;
+using System.IO;
+using Axiom.MathLib;
+
+namespace OpenSim
+{
+ ///
+ /// Description of Prim_manager.
+ ///
+ public class PrimManager
+ {
+ private Server _server;
+ private uint _primCount;
+
+ public AgentManager AgentManagement;
+ public libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock PrimTemplate;
+ public Dictionary PrimList;
+
+ ///
+ ///
+ ///
+ ///
+ public PrimManager(Server server)
+ {
+ _server = server;
+ PrimList = new Dictionary ();
+ //this.SetupTemplates("objectupate164.dat");
+
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void CreatePrim(UserAgentInfo userInfo, libsecondlife.LLVector3 pos1, ObjectAddPacket addPacket)
+ {
+ ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
+ objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle;
+ objupdate.RegionData.TimeDilation = 64096;
+
+ objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
+ PrimData PData = new PrimData();
+ objupdate.ObjectData[0] = this.PrimTemplate;
+ PData.OwnerID=objupdate.ObjectData[0].OwnerID = userInfo.AgentID;
+ PData.PCode=objupdate.ObjectData[0].PCode = addPacket.ObjectData.PCode;
+ PData.PathBegin=objupdate.ObjectData[0].PathBegin = addPacket.ObjectData.PathBegin;
+ PData.PathEnd=objupdate.ObjectData[0].PathEnd = addPacket.ObjectData.PathEnd;
+ PData.PathScaleX=objupdate.ObjectData[0].PathScaleX = addPacket.ObjectData.PathScaleX;
+ PData.PathScaleY=objupdate.ObjectData[0].PathScaleY = addPacket.ObjectData.PathScaleY;
+ PData.PathShearX=objupdate.ObjectData[0].PathShearX = addPacket.ObjectData.PathShearX;
+ PData.PathShearY=objupdate.ObjectData[0].PathShearY = addPacket.ObjectData.PathShearY;
+ PData.PathSkew=objupdate.ObjectData[0].PathSkew = addPacket.ObjectData.PathSkew;
+ PData.ProfileBegin=objupdate.ObjectData[0].ProfileBegin = addPacket.ObjectData.ProfileBegin;
+ PData.ProfileEnd=objupdate.ObjectData[0].ProfileEnd = addPacket.ObjectData.ProfileEnd;
+ PData.Scale=objupdate.ObjectData[0].Scale = addPacket.ObjectData.Scale;
+ PData.PathCurve=objupdate.ObjectData[0].PathCurve = addPacket.ObjectData.PathCurve;
+ PData.ProfileCurve=objupdate.ObjectData[0].ProfileCurve = addPacket.ObjectData.ProfileCurve;
+ PData.ParentID=objupdate.ObjectData[0].ParentID = 0;
+ PData.ProfileHollow=objupdate.ObjectData[0].ProfileHollow = addPacket.ObjectData.ProfileHollow;
+ //finish off copying rest of shape data
+
+ objupdate.ObjectData[0].ID = (uint)(702000 + _primCount);
+ objupdate.ObjectData[0].FullID = new LLUUID("edba7151-5857-acc5-b30b-f01efefda"+_primCount.ToString("000"));
+
+ //update position
+ byte[] pb = pos1.GetBytes();
+ Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 0, pb.Length);
+
+ _primCount++;
+ _server.SendPacket(objupdate, true, userInfo);
+
+ //should send to all users
+ foreach (KeyValuePair kp in AgentManagement.AgentList)
+ {
+ if(kp.Value.NetInfo.AgentID != userInfo.AgentID)
+ {
+ _server.SendPacket(objupdate, true, kp.Value.NetInfo);
+ }
+ }
+ //should store this infomation
+ PrimInfo NewPrim = new PrimInfo();
+ NewPrim.FullID = objupdate.ObjectData[0].FullID;
+ NewPrim.LocalID = objupdate.ObjectData[0].ID;
+ NewPrim.Position = pos1;
+ NewPrim.Data = PData;
+
+ this.PrimList.Add(NewPrim.FullID, NewPrim);
+
+ //store rest of data
+
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void UpdatePrimPosition(UserAgentInfo userInfo, LLVector3 position, uint localID, bool setRotation, LLQuaternion rotation)
+ {
+ PrimInfo pri = null;
+ foreach (KeyValuePair kp in this.PrimList)
+ {
+ if(kp.Value.LocalID == localID)
+ {
+ pri = kp.Value;
+ }
+ }
+ if(pri == null)
+ {
+ return;
+ }
+ uint ID = pri.LocalID;
+ libsecondlife.LLVector3 pos2 = new LLVector3(position.X, position.Y, position.Z);
+ libsecondlife.LLQuaternion rotation2;
+ if(!setRotation)
+ {
+ pri.Position = pos2;
+ rotation2 = new LLQuaternion(pri.Rotation.X, pri.Rotation.Y, pri.Rotation.Z, pri.Rotation.W);
+ }
+ else
+ {
+ rotation2=new LLQuaternion(rotation.X, rotation.Y, rotation.Z, rotation.W);
+ pos2 = pri.Position;
+ pri.Rotation = rotation;
+ }
+ rotation2.W += 1;
+ rotation2.X += 1;
+ rotation2.Y += 1;
+ rotation2.Z += 1;
+
+ byte[] bytes = new byte[60];
+
+ ImprovedTerseObjectUpdatePacket im = new ImprovedTerseObjectUpdatePacket();
+ im.RegionData.RegionHandle = Globals.Instance.RegionHandle;
+ im.RegionData.TimeDilation = 64096;
+ im.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1];
+ int i = 0;
+ ImprovedTerseObjectUpdatePacket.ObjectDataBlock dat = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock();
+ im.ObjectData[0] = dat;
+ dat.TextureEntry = PrimTemplate.TextureEntry;
+
+ bytes[i++] = (byte)(ID % 256);
+ bytes[i++] = (byte)((ID >> 8) % 256);
+ bytes[i++] = (byte)((ID >> 16) % 256);
+ bytes[i++] = (byte)((ID >> 24) % 256);
+ bytes[i++]= 0;
+ bytes[i++]= 0;
+
+ byte[] pb = pos2.GetBytes();
+ pri.Position = pos2;
+ Array.Copy(pb, 0, bytes, i, pb.Length);
+ i += 12;
+ ushort ac = 32767;
+
+ //vel
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ //accel
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ ushort rw, rx,ry,rz;
+ rw = (ushort)(32768 * rotation2.W);
+ rx = (ushort)(32768 * rotation2.X);
+ ry = (ushort)(32768 * rotation2.Y);
+ rz = (ushort)(32768 * rotation2.Z);
+
+ //rot
+ bytes[i++] = (byte)(rx % 256);
+ bytes[i++] = (byte)((rx >> 8) % 256);
+ bytes[i++] = (byte)(ry % 256);
+ bytes[i++] = (byte)((ry >> 8) % 256);
+ bytes[i++] = (byte)(rz % 256);
+ bytes[i++] = (byte)((rz >> 8) % 256);
+ bytes[i++] = (byte)(rw % 256);
+ bytes[i++] = (byte)((rw >> 8) % 256);
+
+ //rotation vel
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+ bytes[i++] = (byte)(ac % 256);
+ bytes[i++] = (byte)((ac >> 8) % 256);
+
+ dat.Data=bytes;
+
+ foreach (KeyValuePair kp in AgentManagement.AgentList)
+ {
+ if(kp.Value.NetInfo.AgentID!=userInfo.AgentID)
+ {
+ _server.SendPacket(im, true, kp.Value.NetInfo);
+ }
+ }
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void SendExistingPrims(UserAgentInfo userInfo)
+ {
+ //send data for already created prims to a new joining user
+ }
+
+ ///
+ ///
+ ///
+ ///
+ public void SetupTemplates(string name)
+ {
+ ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
+ objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle;
+ objupdate.RegionData.TimeDilation = 64096;
+ objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1];
+
+ int i = 0;
+ FileInfo fInfo = new FileInfo(name);
+ long numBytes = fInfo.Length;
+ FileStream fStream = new FileStream(name, FileMode.Open, FileAccess.Read);
+ BinaryReader br = new BinaryReader(fStream);
+ byte [] data1 = br.ReadBytes((int)numBytes);
+ br.Close();
+ fStream.Close();
+
+ libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1,ref i);
+ objupdate.ObjectData[0] = objdata;
+ this.PrimTemplate = objdata;
+ objdata.UpdateFlags = objdata.UpdateFlags + 12 - 16 + 32 + 256;
+ objdata.OwnerID = new LLUUID("00000000-0000-0000-0000-000000000000");
+ //test adding a new texture to object , to test image downloading
+ LLObject.TextureEntry te = new LLObject.TextureEntry(objdata.TextureEntry, 0, objdata.TextureEntry.Length);
+ te.DefaultTexture.TextureID = new LLUUID("00000000-0000-0000-5005-000000000005");
+
+ LLObject.TextureEntry ntex = new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005"));
+
+ objdata.TextureEntry = ntex.ToBytes();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void ReadPrimDatabase(string name, UserAgentInfo userInfo)
+ {
+ StreamReader SR;
+ string line;
+ SR=File.OpenText(name);
+ string [] comp = new string[10];
+ string delimStr = " , ";
+ char [] delimiter = delimStr.ToCharArray();
+
+ line=SR.ReadLine();
+ while(line != "end")
+ {
+ comp = line.Split(delimiter);
+ if(comp[0] == "ObjPack")
+ {
+ int num = Convert.ToInt32(comp[2]);
+ int start = Convert.ToInt32(comp[1]);
+ ObjectUpdatePacket objupdate = new ObjectUpdatePacket();
+ objupdate.RegionData.RegionHandle = Globals.Instance.RegionHandle;
+ objupdate.RegionData.TimeDilation = 64096;
+ objupdate.ObjectData = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[num];
+
+ // int count=0;
+ string data_path = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, @"data");
+ for(int cc = 0; cc < num; cc++)
+ {
+ string filenam = System.IO.Path.Combine(data_path, @"prim_updates"+start+".dat");
+ int i = 0;
+ //FileInfo fInfo = new FileInfo("objectupate"+start+".dat");
+ FileInfo fInfo = new FileInfo(filenam);
+ long numBytes = fInfo.Length;
+ //FileStream fStream = new FileStream("objectupate"+start+".dat", FileMode.Open, FileAccess.Read);
+ FileStream fStream = new FileStream(filenam, FileMode.Open, FileAccess.Read);
+ BinaryReader br = new BinaryReader(fStream);
+ byte [] data1 = br.ReadBytes((int)numBytes);
+ br.Close();
+ fStream.Close();
+
+ libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata = new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1, ref i);
+ objupdate.ObjectData[cc] = objdata;
+ start++;
+ }
+ _server.SendPacket(objupdate, true, userInfo);
+ line = SR.ReadLine();
+ }
+ }
+ SR.Close();
+ }
+ }
+
+ public class PrimInfo
+ {
+ public LLVector3 Position;
+ public LLVector3 Velocity;
+ public LLQuaternion Rotation=LLQuaternion.Identity;
+ public uint LocalID;
+ public LLUUID FullID;
+ public PrimData Data;
+
+ public PrimInfo()
+ {
+ Position=new LLVector3(0,0,0);
+ Velocity=new LLVector3(0,0,0);
+ //data=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()
+ {
+
+ }
+ }
+}
diff --git a/src/SceneGraphManager.cs b/src/SceneGraphManager.cs
new file mode 100644
index 0000000..c71ad54
--- /dev/null
+++ b/src/SceneGraphManager.cs
@@ -0,0 +1,40 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the 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 SceneGraphManager.
+ ///
+ public class SceneGraphManager
+ {
+ public SceneGraphManager()
+ {
+ }
+ }
+}
diff --git a/src/Script_manager.cs b/src/Script_manager.cs
new file mode 100644
index 0000000..1de1d22
--- /dev/null
+++ b/src/Script_manager.cs
@@ -0,0 +1,103 @@
+/*
+ Copyright (c) OpenSim project, http://osgrid.org/
+* All rights reserved.
+*
+* 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 System.Collections;
+//using LuaInterface;
+using libsecondlife;
+
+namespace OpenSim
+{
+ ///
+ /// Description of Script_manager.
+ ///
+ public class ScriptManager
+ {
+ //public LuaInterface.Lua Lu;
+ //private ArrayList scripts;
+ //private prim_info current_prim;
+
+ public ScriptManager()
+ {
+ }
+
+ /*public void start_up (Lua lua, App ap)
+ {
+ this.Lu=lua;
+ //register any lua routines , like check finish script one
+ Lu.OpenMathLib();
+ }*/
+
+ private void RegisterFunctions()
+ {
+ //lu.RegisterFunction( "RegisterScript",this,this.GetType().GetMethod("ScriptRegister"));
+ //lu.RegisterFunction( "MoveObject",this,this.GetType().GetMethod("MoveObject"));
+ //lu.RegisterFunction( "Say",this,this.GetType().GetMethod("Say"));
+
+ }
+
+ public void Call_tick(PrimInfo prim)
+ {
+ //set current prim and then call tick function in linked script
+ }
+ public void Call_touch(PrimInfo prim)
+ {
+ //set current prim and then call clicked function in linked script
+
+ }
+ public void Call_on_rex(PrimInfo prim)
+ {
+ //set current prim and then call clicked function in linked script
+
+ }
+
+ #region Lua Functions
+
+ public void ScriptRegister(script_object_interface script)
+ {
+ //called by scripts to register themselves
+ }
+ public void MoveObject(float x , float y, float z)
+ {
+
+ }
+ public void Say(string message)
+ {
+
+ }
+ #endregion
+
+ }
+
+ public interface script_object_interface
+ {
+ void frame_tick();
+ void touch(int num);
+ void on_rex(int num);
+ }
+}
diff --git a/src/Second-server.csproj b/src/Second-server.csproj
new file mode 100644
index 0000000..6d049ce
--- /dev/null
+++ b/src/Second-server.csproj
@@ -0,0 +1,60 @@
+
+
+ Exe
+ OpenSim
+ OpenSim
+ Debug
+ AnyCPU
+ {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}
+ OpenSim.Controller
+
+
+ bin\Debug\
+ False
+ DEBUG;TRACE
+ True
+ Full
+ True
+
+
+ bin\Release\
+ True
+ TRACE
+ False
+ None
+ False
+
+
+
+ False
+ ..\bin\Axiom.MathLib.dll
+
+
+ False
+ ..\bin\libsecondlife.dll
+
+
+ False
+ ..\bin\log4net.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Second-server.sln b/src/Second-server.sln
new file mode 100644
index 0000000..44be1db
--- /dev/null
+++ b/src/Second-server.sln
@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# SharpDevelop 2.1.0.2017
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Second-server", "Second-server.csproj", "{132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|.NET 1.1 = Debug|.NET 1.1
+ Debug|Any CPU = Debug|Any CPU
+ Release|.NET 1.1 = Release|.NET 1.1
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Debug|.NET 1.1.ActiveCfg = Debug|Any CPU
+ {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Release|.NET 1.1.ActiveCfg = Release|Any CPU
+ {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Debug|.NET 1.1.ActiveCfg = Debug|.NET 1.1
+ {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Debug|.NET 1.1.Build.0 = Debug|.NET 1.1
+ {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Release|.NET 1.1.ActiveCfg = Release|.NET 1.1
+ {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Release|.NET 1.1.Build.0 = Release|.NET 1.1
+ {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D9CDEDFB-8169-4B03-B57F-0DF638F044EC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Debug|.NET 1.1.Build.0 = Debug|.NET 1.1
+ {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Release|.NET 1.1.Build.0 = Release|.NET 1.1
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/Second-server.suo b/src/Second-server.suo
new file mode 100644
index 0000000..4ed1adc
Binary files /dev/null and b/src/Second-server.suo differ
diff --git a/src/Server.cs b/src/Server.cs
new file mode 100644
index 0000000..1f19bf9
--- /dev/null
+++ b/src/Server.cs
@@ -0,0 +1,707 @@
+/*
+ * Copyright (c) OpenSim project, http://osgrid.org/
+* All rights reserved.
+*
+* 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 System.Collections.Generic;
+using libsecondlife;
+using System.Collections;
+using libsecondlife.Packets;
+using libsecondlife.AssetSystem;
+using System.Net;
+using System.Net.Sockets;
+using System.Timers;
+
+//really hacked , messy code
+
+namespace OpenSim
+{
+ ///
+ /// Description of Server.
+ ///
+ public interface ServerCallback
+ {
+ //should replace with delegates
+ void MainCallback(Packet pack, UserAgentInfo User_info);
+ void NewUserCallback(UserAgentInfo User_info);
+ void ErrorCallback(string text);
+ }
+ public class Server
+ {
+ /// A public reference to the client that this Simulator object
+ /// is attached to
+ //public SecondLife Client;
+
+ /// The Region class that this Simulator wraps
+ // public Region Region;
+
+ ///
+ /// Used internally to track sim disconnections, do not modify this
+ /// variable
+ ///
+ public bool DisconnectCandidate = false;
+
+ ///
+ /// The ID number associated with this particular connection to the
+ /// simulator, used to emulate TCP connections. This is used
+ /// internally for packets that have a CircuitCode field
+ ///
+ public uint CircuitCode
+ {
+ get { return circuitCode; }
+ set { circuitCode = value; }
+ }
+
+ ///
+ /// The IP address and port of the server
+ ///
+ public IPEndPoint IPEndPoint
+ {
+ get { return ipEndPoint; }
+ }
+
+ ///
+ /// A boolean representing whether there is a working connection to the
+ /// simulator or not
+ ///
+ public bool Connected
+ {
+ get { return connected; }
+ }
+
+ private ServerCallback CallbackObject;
+ private uint Sequence = 0;
+ private object SequenceLock = new object();
+ private byte[] RecvBuffer = new byte[4096];
+ private byte[] ZeroBuffer = new byte[8192];
+ private byte[] ZeroOutBuffer = new byte[4096];
+ private Socket Connection = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
+ private AsyncCallback ReceivedData;
+ private bool connected = false;
+ private uint circuitCode;
+ private IPEndPoint ipEndPoint;
+ private EndPoint endPoint;
+ private IPEndPoint ipeSender;
+ private EndPoint epSender;
+ private System.Timers.Timer AckTimer;
+ private Server_Settings Settings=new Server_Settings();
+ public ArrayList User_agents=new ArrayList();
+
+ ///
+ /// Constructor for Simulator
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Server(ServerCallback s_callback)
+ {
+
+ this.CallbackObject=s_callback; //should be using delegate
+ AckTimer = new System.Timers.Timer(Settings.NETWORK_TICK_LENGTH);
+ AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
+
+ // Initialize the callback for receiving a new packet
+ ReceivedData = new AsyncCallback(this.OnReceivedData);
+
+ // Client.Log("Connecting to " + ip.ToString() + ":" + port, Helpers.LogLevel.Info);
+
+ try
+ {
+ // Create an endpoint that we will be communicating with (need it in two
+ // types due to .NET weirdness)
+ // ipEndPoint = new IPEndPoint(ip, port);
+ ipEndPoint = new IPEndPoint(IPAddress.Any, Globals.Instance.IpPort);
+ endPoint = (EndPoint)ipEndPoint;
+
+ // Associate this simulator's socket with the given ip/port and start listening
+ Connection.Bind(endPoint);
+ ipeSender = new IPEndPoint(IPAddress.Any, 0);
+ //The epSender identifies the incoming clients
+ epSender = (EndPoint) ipeSender;
+ Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
+
+ // Start the ACK timer
+ AckTimer.Start();
+ }
+ catch (Exception e)
+ {
+
+ System.Console.WriteLine(e.Message);
+ }
+ }
+
+ ///
+ /// Disconnect a Simulator
+ ///
+ public void Disconnect()
+ {
+ if (connected)
+ {
+ connected = false;
+ AckTimer.Stop();
+
+ // Send the CloseCircuit notice
+ CloseCircuitPacket close = new CloseCircuitPacket();
+
+ if (Connection.Connected)
+ {
+ try
+ {
+ // Connection.Send(close.ToBytes());
+ }
+ catch (SocketException)
+ {
+ // There's a high probability of this failing if the network is
+ // disconnecting, so don't even bother logging the error
+ }
+ }
+
+ try
+ {
+ // Shut the socket communication down
+ // Connection.Shutdown(SocketShutdown.Both);
+ }
+ catch (SocketException)
+ {
+ }
+ }
+ }
+
+ ///
+ /// Sends a packet
+ ///
+ /// Packet to be sent
+ /// Increment sequence number?
+ public void SendPacket(Packet packet, bool incrementSequence, UserAgentInfo User_info)
+ {
+ Console.WriteLine("OUTGOING");
+ Console.WriteLine(packet.ToString());
+ byte[] buffer;
+ int bytes;
+
+ if (!connected && packet.Type != PacketType.UseCircuitCode)
+ {
+ Console.WriteLine("Trying to send a " + packet.Type.ToString() + " packet when the socket is closed");
+
+
+ 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 (Sequence > Settings.MAX_SEQUENCE)
+ Sequence = 1;
+ else
+ Sequence++;
+ packet.Header.Sequence = Sequence;
+ }
+
+ if (packet.Header.Reliable)
+ {
+ lock (User_info.NeedAck)
+ {
+ if (!User_info.NeedAck.ContainsKey(packet.Header.Sequence))
+ {
+ 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);
+ }
+ }
+
+ // 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;
+
+ try
+ {
+ // Zerocode if needed
+ if (packet.Header.Zerocoded)
+ {
+ 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);
+ }
+ }
+ catch (SocketException)
+ {
+ //Client.Log("Tried to send a " + packet.Type.ToString() + " on a closed socket",
+ // Helpers.LogLevel.Warning);
+
+ Disconnect();
+ }
+ }
+
+ ///
+ /// Send a raw byte array payload as a packet
+ ///
+ /// The packet payload
+ /// Whether the second, third, and fourth bytes
+ /// should be modified to the current stream sequence number
+ ///
+ /// Returns Simulator Name as a String
+ ///
+ ///
+ public override string ToString()
+ {
+ return( " (" + ipEndPoint.ToString() + ")");
+ }
+
+ ///
+ /// Sends out pending acknowledgements
+ ///
+ private void SendAcks(UserAgentInfo User_info)
+ {
+ lock (User_info.PendingAcks)
+ {
+ if (connected && User_info.PendingAcks.Count > 0)
+ {
+ if (User_info.PendingAcks.Count > 250)
+ {
+ // FIXME: Handle the odd case where we have too many pending ACKs queued up
+ //Client.Log("Too many ACKs queued up!", Helpers.LogLevel.Error);
+ return;
+ }
+
+ int i = 0;
+ PacketAckPacket acks = new PacketAckPacket();
+ acks.Packets = new PacketAckPacket.PacketsBlock[User_info.PendingAcks.Count];
+
+ foreach (uint ack in User_info.PendingAcks.Values)
+ {
+ acks.Packets[i] = new PacketAckPacket.PacketsBlock();
+ acks.Packets[i].ID = ack;
+ i++;
+ }
+
+ acks.Header.Reliable = false;
+ //SendPacket(acks, true,User_info);
+
+ User_info.PendingAcks.Clear();
+ }
+ }
+ }
+ ///
+ /// Resend unacknowledged packets
+ ///
+ private void ResendUnacked(UserAgentInfo User_info)
+ {
+ if (connected)
+ {
+ int now = Environment.TickCount;
+
+ lock (User_info.NeedAck)
+ {
+ foreach (Packet packet in User_info.NeedAck.Values)
+ {
+ if (now - packet.TickCount > Settings.RESEND_TIMEOUT)
+ {
+ // Client.Log("Resending " + packet.Type.ToString() + " packet, " +
+ // (now - packet.TickCount) + "ms have passed", Helpers.LogLevel.Info);
+
+ //packet.Header.Resent = true;
+ // SendPacket(packet, false,User_info);
+ }
+ }
+ }
+ }
+ }
+ ///
+ /// Callback handler for incomming data
+ ///
+ ///
+ private void OnReceivedData(IAsyncResult result)
+ {
+ ipeSender = new IPEndPoint(IPAddress.Any, 0);
+ epSender = (EndPoint)ipeSender;
+ Packet packet = null;
+ int numBytes;
+ UserAgentInfo tempinfo;
+
+ // If we're receiving data the sim connection is open
+ connected = true;
+
+ // Update the disconnect flag so this sim doesn't time out
+ DisconnectCandidate = false;
+ UserAgentInfo User_info=null;
+
+ lock (RecvBuffer)
+ {
+ // Retrieve the incoming packet
+ try
+ {
+ numBytes = Connection.EndReceiveFrom(result, ref epSender);
+
+ //find user_agent_info
+
+ int packetEnd = numBytes - 1;
+ packet = Packet.BuildPacket(RecvBuffer, ref packetEnd, ZeroBuffer);
+
+ Console.WriteLine("INCOMING PACKET" + packet.TickCount.ToString() + " " + packet.Header.Sequence.ToString());
+ Console.WriteLine(packet.ToString());
+ libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket();
+ ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
+ ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
+ ack_it.Packets[0].ID = packet.Header.ID;
+ ack_it.Header.Reliable = false;
+
+ tempinfo = new UserAgentInfo();
+ tempinfo.endpoint = epSender;
+ this.SendPacket(ack_it, false, tempinfo);
+ if (packet.Header.Resent)
+ {
+ this.CallbackObject.ErrorCallback("resent");
+ }
+
+ if ((packet.Type == PacketType.StartPingCheck) && (packet.Header.Resent == false))
+ {
+ //reply to pingcheck
+ libsecondlife.Packets.StartPingCheckPacket startping = (libsecondlife.Packets.StartPingCheckPacket)packet;
+ libsecondlife.Packets.CompletePingCheckPacket endping = new CompletePingCheckPacket();
+ endping.PingID.PingID = startping.PingID.PingID;
+ endping.Header.Reliable = false;
+ tempinfo = new UserAgentInfo();
+ tempinfo.endpoint = epSender;
+ this.SendPacket(endping, true, tempinfo);
+ }
+
+ //should check if login/useconnection packet first
+ if ((packet.Type == PacketType.UseCircuitCode) && (packet.Header.Resent == false))
+ {
+ Console.WriteLine("Got UseCircuitCode, confirming with grid...");
+ UseCircuitCodePacket cir_pack=(UseCircuitCodePacket)packet;
+
+ ArrayList requestParams = new ArrayList();
+ requestParams.Add(Globals.Instance.GridSendKey);
+ requestParams.Add(cir_pack.CircuitCode.SessionID.ToString());
+ requestParams.Add(cir_pack.CircuitCode.ID.ToString());
+
+
+ Nwc.XmlRpc.XmlRpcRequest GridSessionInfo = new Nwc.XmlRpc.XmlRpcRequest("get_session_info",requestParams);
+
+ Nwc.XmlRpc.XmlRpcResponse gridresponse = GridSessionInfo.Send(Globals.Instance.GridURL, 5000);
+
+ Console.WriteLine("Processing response from grid server...");
+ Hashtable gridreply = (Hashtable)gridresponse.Value;
+ if (gridresponse.IsFault)
+ {
+ Console.WriteLine("XML-RPC error when talking to grid: " + gridresponse.FaultString);
+ Connection.Disconnect(false);
+ }
+ if (((string)gridreply["agent_id"]).ToLower().Equals(cir_pack.CircuitCode.ID.ToString()) == false)
+ {
+ Console.WriteLine("Bad agent ID!");
+ Connection.Disconnect(false);
+ }
+ else if (((string)gridreply["session_id"]).ToLower().Equals(cir_pack.CircuitCode.SessionID.ToString()) == false)
+ {
+ Console.WriteLine("Bad session ID!");
+ Connection.Disconnect(false);
+ }
+ UserAgentInfo new_user = new UserAgentInfo();
+
+ new_user.AgentID = cir_pack.CircuitCode.ID;
+ new_user.circuitCode=cir_pack.CircuitCode.Code;
+ new_user.AgentID=cir_pack.CircuitCode.ID;
+ new_user.SessionID=cir_pack.CircuitCode.SessionID;
+ new_user.endpoint=epSender;
+ new_user.Inbox = new Queue(Settings.INBOX_SIZE);
+ new_user.first_name = (string)gridreply["firstname"];
+ new_user.first_name = (string)gridreply["lastname"];
+
+
+ this.CallbackObject.NewUserCallback(new_user);
+ this.User_agents.Add(new_user);
+
+ }
+
+
+ UserAgentInfo temp_agent=null;
+ IPEndPoint send_ip=(IPEndPoint)epSender;
+ Console.WriteLine("incoming: address is "+send_ip.Address +"port number is: "+send_ip.Port.ToString());
+
+ for(int ii=0; ii Settings.MAX_PENDING_ACKS)
+ {
+ SendAcks(User_info);
+ }
+
+ // Check if we already received this packet
+ if (User_info.Inbox.Contains(packet.Header.Sequence))
+ {
+ //Client.Log("Received a duplicate " + packet.Type.ToString() + ", sequence=" +
+ // packet.Header.Sequence + ", resent=" + ((packet.Header.Resent) ? "Yes" : "No") +
+ // ", Inbox.Count=" + Inbox.Count + ", NeedAck.Count=" + NeedAck.Count,
+ // Helpers.LogLevel.Info);
+
+ // Send an ACK for this packet immediately
+
+
+ // TESTING: Try just queuing up ACKs for resent packets instead of immediately triggering an ACK
+ /* lock (User_info.PendingAcks)
+ {
+ uint sequence = (uint)packet.Header.Sequence;
+ if (!User_info.PendingAcks.ContainsKey(sequence)) { User_info.PendingAcks[sequence] = sequence; }
+ }*/
+
+ // Avoid firing a callback twice for the same packet
+ this.CallbackObject.ErrorCallback("Avoiding callback");
+ // this.callback_object.error("avoiding callback");
+ return;
+ }
+ else
+ {
+ lock (User_info.PendingAcks)
+ {
+ uint sequence = (uint)packet.Header.Sequence;
+ // if (!User_info.PendingAcks.ContainsKey(sequence)) { User_info.PendingAcks[sequence] = sequence; }
+ }
+ }
+ }
+
+ // Add this packet to our inbox
+ lock (User_info.Inbox)
+ {
+ while (User_info.Inbox.Count >= Settings.INBOX_SIZE)
+ {
+ User_info.Inbox.Dequeue();
+ }
+ User_info.Inbox.Enqueue(packet.Header.Sequence);
+ }
+
+ // Handle appended ACKs
+ if (packet.Header.AppendedAcks)
+ {
+ lock (User_info.NeedAck)
+ {
+ foreach (uint ack in packet.Header.AckList)
+ {
+ User_info.NeedAck.Remove(ack);
+ }
+ }
+ }
+
+ // Handle PacketAck packets
+ if (packet.Type == PacketType.PacketAck)
+ {
+ PacketAckPacket ackPacket = (PacketAckPacket)packet;
+
+ lock (User_info.NeedAck)
+ {
+ foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
+ {
+ User_info.NeedAck.Remove(block.ID);
+ }
+ }
+ }
+
+ this.CallbackObject.MainCallback(packet,User_info);
+
+ }
+
+ private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea)
+ {
+ if (connected)
+ {
+
+ //TODO for each user_agent_info
+ for(int i=0; iThe version of libsecondlife (not the SL protocol itself)
+ public string VERSION = "libsecondlife 0.0.9";
+ /// XML-RPC login server to connect to
+ public string LOGIN_SERVER = "http://www.garethnelson.com/ogs/login/";
+
+ /// Millisecond interval between ticks, where all ACKs are
+ /// sent out and the age of unACKed packets is checked
+ public readonly int NETWORK_TICK_LENGTH = 500;
+ /// The maximum value of a packet sequence number. After that
+ /// we assume the sequence number just rolls over? Or maybe the
+ /// protocol isn't able to sustain a connection past that
+ public readonly int MAX_SEQUENCE = 0xFFFFFF;
+ /// Number of milliseconds before a teleport attempt will time
+ /// out
+ public readonly int TELEPORT_TIMEOUT = 18 * 1000;
+
+ /// Number of milliseconds before NetworkManager.Logout() will time out
+ public int LOGOUT_TIMEOUT = 5 * 1000;
+ /// Number of milliseconds for xml-rpc to timeout
+ public int LOGIN_TIMEOUT = 30 * 1000;
+ /// The maximum size of the sequence number inbox, used to
+ /// check for resent and/or duplicate packets
+ public int INBOX_SIZE = 100;
+ /// Milliseconds before a packet is assumed lost and resent
+ public int RESEND_TIMEOUT = 4000;
+ /// Milliseconds before the connection to a simulator is
+ /// assumed lost
+ public int SIMULATOR_TIMEOUT = 15000;
+ /// Maximum number of queued ACKs to be sent before SendAcks()
+ /// is forced
+ public int MAX_PENDING_ACKS = 10;
+ /// Maximum number of ACKs to append to a packet
+ public int MAX_APPENDED_ACKS = 10;
+ /// Cost of uploading an asset
+ public int UPLOAD_COST { get { return priceUpload; } }
+
+
+ private int priceUpload = 0;
+
+ public Server_Settings()
+ {
+
+ }
+ }
+
+ public class UserAgentInfo
+ {
+ public EndPoint endpoint;
+ public LLUUID AgentID;
+ public LLUUID SessionID;
+ public uint circuitCode;
+ public string name;
+ public uint localID;
+ public string first_name;
+ public string last_name;
+
+ public Dictionary NeedAck = new Dictionary();
+ // Sequence numbers of packets we've received from the simulator
+ public Queue Inbox;
+ // ACKs that are queued up to be sent to the simulator
+ public Dictionary PendingAcks = new Dictionary();
+
+ public UserAgentInfo()
+ {
+
+ }
+ }
+
+}
diff --git a/src/StorageManager.cs b/src/StorageManager.cs
new file mode 100644
index 0000000..05ef782
--- /dev/null
+++ b/src/StorageManager.cs
@@ -0,0 +1,53 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+* All rights reserved.
+*
+* 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 System.Collections.Generic;
+using libsecondlife;
+using System.Collections;
+using libsecondlife.Packets;
+using libsecondlife.AssetSystem;
+using System.IO;
+
+namespace OpenSim
+{
+ ///
+ /// Description of StorageManager.
+ ///
+ public class StorageManager
+ {
+ public StorageManager()
+ {
+ }
+ }
+
+ public class AssetStorage
+ {
+ public LLUUID Full_ID;
+ public byte Type;
+ }
+}
diff --git a/src/Texture_manager.cs b/src/Texture_manager.cs
new file mode 100644
index 0000000..6d3f1db
--- /dev/null
+++ b/src/Texture_manager.cs
@@ -0,0 +1,238 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+
+* Copyright (c) ,
+* All rights reserved.
+*
+* 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 System.Collections.Generic;
+using libsecondlife;
+using System.Collections;
+using libsecondlife.Packets;
+using libsecondlife.AssetSystem;
+using System.IO;
+
+
+namespace OpenSim
+{
+ ///
+ /// Description of Texture_manager.
+ ///
+ public class TextureManager
+ {
+ public Dictionary textures;
+ public ArrayList requests=new ArrayList(); //should change to a generic
+ public ArrayList uploads=new ArrayList();
+ private Server server;
+
+ public TextureManager(Server serve)
+ {
+ server=serve;
+ textures=new Dictionary ();
+ this.initialise();
+ }
+
+ public void AddRequest(User_Agent_info user, LLUUID image_id)
+ {
+
+ if(!this.textures.ContainsKey(image_id))
+ {
+ //not found image so send back image not in data base message
+ ImageNotInDatabasePacket im_not=new ImageNotInDatabasePacket();
+ im_not.ImageID.ID=image_id;
+ server.SendPacket(im_not,true,user);
+ return;
+ }
+ TextureImage imag=this.textures[image_id];
+ TextureRequest req=new TextureRequest();
+ req.RequestUser=user;
+ req.RequestImage=image_id;
+ req.image_info=imag;
+
+ if(imag.data.LongLength>1000) //should be bigger or smaller?
+ {
+ //over 1000 bytes so split up file
+ req.num_packets=(int)imag.data.LongLength/1000;
+ req.num_packets++;
+ }
+ else
+ {
+ req.num_packets=1;
+ }
+
+ this.requests.Add(req);
+
+ }
+
+ public void AddTexture(LLUUID image_id, string name, byte[] data)
+ {
+
+ }
+ public void DoWork(ulong time)
+ {
+ if(this.requests.Count==0)
+ {
+ //no requests waiting
+ return;
+ }
+ int num;
+ //should be running in its own thread but for now is called by timer
+ if(this.requests.Count<5)
+ {
+ //lower than 5 so do all of them
+ num=this.requests.Count;
+ }
+ else
+ {
+ num=5;
+ }
+ TextureRequest req;
+ for(int i=0; i,
+* All rights reserved.
+*
+* 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 System.Collections.Generic;
+using System.Threading;
+using libsecondlife;
+using libsecondlife.Packets;
+
+namespace OpenSim
+{
+ ///
+ ///
+ public class QueItem {
+ public QueItem()
+ {
+ }
+
+ public Packet Packet;
+ public bool Incoming;
+ }
+
+
+ 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();
+ }
+ }
+ }
+
+}
diff --git a/src/VersionInfo.cs.template b/src/VersionInfo.cs.template
new file mode 100644
index 0000000..e4e1b95
--- /dev/null
+++ b/src/VersionInfo.cs.template
@@ -0,0 +1,37 @@
+/*
+Copyright (c) OpenSim project, http://osgrid.org/
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are met:
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the distribution.
+* * Neither the name of the 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
+{
+ ///
+ ///
+ public class VersionInfo
+ {
+ public static string Version = "@@VERSION";
+ }
+}
diff --git a/src/types/BitPack.cs b/src/types/BitPack.cs
new file mode 100644
index 0000000..1abbcf0
--- /dev/null
+++ b/src/types/BitPack.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenSim.types
+{
+ /* New Method
+ *
+ * 1. Get all the individual bytes and their bitlength, put them in a dictionary
+ * 2. Mash together when wanted.
+ *
+ * */
+ public class Bits {
+ public byte[] data;
+ public int len;
+ }
+
+ public class InverseBitPack
+ {
+ private List bits;
+
+ public InverseBitPack()
+ {
+ bits = new List();
+ }
+ }
+
+ public class BitPack
+ {
+ private const int MAX_BITS = 8;
+
+ private byte[] Data;
+ private int bytePos;
+ private int bitPos;
+
+ public BitPack(byte[] data, int pos) // For libsl compatibility
+ {
+ Data = data;
+ bytePos = pos;
+ }
+
+ public BitPack() // Encoding version
+ {
+
+ }
+
+ public void LoadData(byte[] data, int pos) {
+ Data = data;
+ bytePos = pos;
+ bitPos = 0;
+ }
+
+ private void PackBitsArray(byte[] bits, int bitLen)
+ {
+ int offset = bitPos % MAX_BITS;
+ int i;
+ byte temp1;
+ byte temp2;
+
+ for (i = 0; i < bits.Length; i++)
+ {
+ int Byte = bits[i];
+ Byte <<= offset;
+ temp1 = (byte)(Byte & 0xFF);
+ temp2 = (byte)((Byte >> 8) & 0xFF);
+
+ Data[Data.Length - 1] |= temp1;
+// Data
+
+ bitPos += bitLen;
+ }
+ }
+
+ public float UnpackFloat()
+ {
+ byte[] output = UnpackBitsArray(32);
+
+ if (!BitConverter.IsLittleEndian) Array.Reverse(output);
+ return BitConverter.ToSingle(output, 0);
+ }
+
+ public int UnpackBits(int totalCount)
+ {
+ byte[] output = UnpackBitsArray(totalCount);
+
+ if (!BitConverter.IsLittleEndian) Array.Reverse(output);
+ return BitConverter.ToInt32(output, 0);
+ }
+
+ private byte[] UnpackBitsArray(int totalCount)
+ {
+ int count = 0;
+ byte[] output = new byte[4];
+ int curBytePos = 0;
+ int curBitPos = 0;
+
+ while (totalCount > 0)
+ {
+ if (totalCount > MAX_BITS)
+ {
+ count = MAX_BITS;
+ totalCount -= MAX_BITS;
+ }
+ else
+ {
+ count = totalCount;
+ totalCount = 0;
+ }
+
+ while (count > 0)
+ {
+ // Shift the previous bits
+ output[curBytePos] <<= 1;
+
+ // Grab one bit
+ if ((Data[bytePos] & (0x80 >> bitPos++)) != 0)
+ ++output[curBytePos];
+
+ --count;
+ ++curBitPos;
+
+ if (bitPos >= MAX_BITS)
+ {
+ bitPos = 0;
+ ++bytePos;
+ }
+ if (curBitPos >= MAX_BITS)
+ {
+ curBitPos = 0;
+ ++curBytePos;
+ }
+ }
+ }
+
+ return output;
+ }
+ }
+}
diff --git a/src/types/Mesh.cs b/src/types/Mesh.cs
new file mode 100644
index 0000000..3e00c91
--- /dev/null
+++ b/src/types/Mesh.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenSim.types
+{
+ // TODO: This will need some performance tuning no doubt.
+ public class Mesh
+ {
+ public List mesh;
+
+ public Mesh()
+ {
+ mesh = new List();
+ }
+
+ public void AddTri(Triangle tri)
+ {
+ mesh.Add(tri);
+ }
+
+ public static Mesh operator +(Mesh a, Mesh b)
+ {
+ a.mesh.AddRange(b.mesh);
+ return a;
+ }
+ }
+}
diff --git a/src/types/Triangle.cs b/src/types/Triangle.cs
new file mode 100644
index 0000000..8dfea6e
--- /dev/null
+++ b/src/types/Triangle.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Axiom.MathLib;
+
+namespace OpenSim.types
+{
+ public class Triangle
+ {
+ Vector3 a;
+ Vector3 b;
+ Vector3 c;
+
+ public Triangle()
+ {
+ a = new Vector3();
+ b = new Vector3();
+ c = new Vector3();
+ }
+
+ public Triangle(Vector3 A, Vector3 B, Vector3 C)
+ {
+ a = A;
+ b = B;
+ c = C;
+ }
+ }
+}
diff --git a/src/world/Avatar.cs b/src/world/Avatar.cs
new file mode 100644
index 0000000..863ce29
--- /dev/null
+++ b/src/world/Avatar.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using libsecondlife;
+using libsecondlife.Packets;
+
+namespace OpenSim.world
+{
+ public class Avatar : Entity
+ {
+ public string firstname;
+ public string lastname;
+ public OpenSimClient ControllingClient;
+
+ public Avatar(OpenSimClient TheClient) {
+ Console.WriteLine("Avatar.cs - Loading details from grid (DUMMY)");
+ ControllingClient=TheClient;
+ }
+
+ public void CompleteMovement(World RegionInfo) {
+ Console.WriteLine("Avatar.cs:CompleteMovement() - Constructing AgentMovementComplete packet");
+ AgentMovementCompletePacket mov = new AgentMovementCompletePacket();
+ mov.AgentData.SessionID = this.ControllingClient.SessionID;
+ mov.AgentData.AgentID = this.ControllingClient.AgentID;
+ mov.Data.RegionHandle = OpenSim_Main.cfg.RegionHandle;
+ // TODO - dynamicalise this stuff
+ mov.Data.Timestamp = 1169838966;
+ mov.Data.Position = new LLVector3(100f, 100f, 22f);
+ mov.Data.LookAt = new LLVector3(0.99f, 0.042f, 0);
+
+ Console.WriteLine("Sending AgentMovementComplete packet");
+ ControllingClient.OutPacket(mov);
+ }
+
+ public void SendRegionHandshake(World RegionInfo) {
+ Console.WriteLine("Avatar.cs:SendRegionHandshake() - Creating empty RegionHandshake packet");
+ System.Text.Encoding _enc = System.Text.Encoding.ASCII;
+ RegionHandshakePacket handshake = new RegionHandshakePacket();
+
+ Console.WriteLine("Avatar.cs:SendRegionhandshake() - Filling in RegionHandshake details");
+ handshake.RegionInfo.BillableFactor = 0;
+ handshake.RegionInfo.IsEstateManager = false;
+ handshake.RegionInfo.TerrainHeightRange00 = 60;
+ handshake.RegionInfo.TerrainHeightRange01 = 60;
+ handshake.RegionInfo.TerrainHeightRange10 = 60;
+ handshake.RegionInfo.TerrainHeightRange11 = 60;
+ handshake.RegionInfo.TerrainStartHeight00 = 20;
+ handshake.RegionInfo.TerrainStartHeight01 = 20;
+ handshake.RegionInfo.TerrainStartHeight10 = 20;
+ handshake.RegionInfo.TerrainStartHeight11 = 20;
+ handshake.RegionInfo.SimAccess = 13;
+ handshake.RegionInfo.WaterHeight = 5;
+ handshake.RegionInfo.RegionFlags = 72458694;
+ handshake.RegionInfo.SimName = _enc.GetBytes(OpenSim_Main.cfg.RegionName + "\0");
+ handshake.RegionInfo.SimOwner = new LLUUID("00000000-0000-0000-0000-000000000000");
+ handshake.RegionInfo.TerrainBase0 = new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975");
+ handshake.RegionInfo.TerrainBase1 = new LLUUID("abb783e6-3e93-26c0-248a-247666855da3");
+ handshake.RegionInfo.TerrainBase2 = new LLUUID("179cdabd-398a-9b6b-1391-4dc333ba321f");
+ handshake.RegionInfo.TerrainBase3 = new LLUUID("beb169c7-11ea-fff2-efe5-0f24dc881df2");
+ handshake.RegionInfo.TerrainDetail0 = new LLUUID("00000000-0000-0000-0000-000000000000");
+ handshake.RegionInfo.TerrainDetail1 = new LLUUID("00000000-0000-0000-0000-000000000000");
+ handshake.RegionInfo.TerrainDetail2 = new LLUUID("00000000-0000-0000-0000-000000000000");
+ handshake.RegionInfo.TerrainDetail3 = new LLUUID("00000000-0000-0000-0000-000000000000");
+ handshake.RegionInfo.CacheID = new LLUUID("545ec0a5-5751-1026-8a0b-216e38a7ab37");
+
+ Console.WriteLine("Avatar.cs:SendRegionHandshake() - Sending RegionHandshake packet");
+ this.ControllingClient.OutPacket(handshake);
+ }
+ }
+}
diff --git a/src/world/Entity.cs b/src/world/Entity.cs
new file mode 100644
index 0000000..ab07fd6
--- /dev/null
+++ b/src/world/Entity.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Axiom.MathLib;
+using OpenSim.types;
+
+namespace OpenSim.world
+{
+ public class Entity
+ {
+ protected libsecondlife.LLUUID uuid;
+ protected Vector3 position;
+ protected Vector3 velocity;
+ protected Quaternion rotation;
+ protected string name;
+ protected List children;
+
+ public Entity()
+ {
+ uuid = new libsecondlife.LLUUID();
+ position = new Vector3();
+ velocity = new Vector3();
+ rotation = new Quaternion();
+ name = "(basic entity)";
+ children = new List();
+ }
+
+ public virtual void update() {
+ // Do any per-frame updates needed that are applicable to every type of entity
+ foreach (Entity child in children)
+ {
+ child.update();
+ }
+ }
+
+ public virtual string getName()
+ {
+ return name;
+ }
+
+ public virtual Mesh getMesh()
+ {
+ Mesh mesh = new Mesh();
+
+ foreach (Entity child in children)
+ {
+ mesh += child.getMesh();
+ }
+
+ return mesh;
+ }
+ }
+}
diff --git a/src/world/Primitive.cs b/src/world/Primitive.cs
new file mode 100644
index 0000000..143fa55
--- /dev/null
+++ b/src/world/Primitive.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using OpenSim.types;
+
+namespace OpenSim.world
+{
+ public class Primitive : Entity
+ {
+ protected float mesh_cutbegin;
+ protected float mesh_cutend;
+
+ public Primitive()
+ {
+ mesh_cutbegin = 0.0f;
+ mesh_cutend = 1.0f;
+ }
+
+ public override Mesh getMesh()
+ {
+ Mesh mesh = new Mesh();
+ Triangle tri = new Triangle(
+ new Axiom.MathLib.Vector3(0.0f, 1.0f, 1.0f),
+ new Axiom.MathLib.Vector3(1.0f, 0.0f, 1.0f),
+ new Axiom.MathLib.Vector3(1.0f, 1.0f, 0.0f));
+
+ mesh.AddTri(tri);
+ mesh += base.getMesh();
+
+ return mesh;
+ }
+ }
+}
diff --git a/src/world/ScriptEngine.cs b/src/world/ScriptEngine.cs
new file mode 100644
index 0000000..f20a08e
--- /dev/null
+++ b/src/world/ScriptEngine.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenSim.world
+{
+ public class ScriptEngine
+ {
+ public ScriptEngine(World env)
+ {
+ }
+
+ public void LoadScript()
+ {
+
+ }
+ }
+}
diff --git a/src/world/SurfacePatch.cs b/src/world/SurfacePatch.cs
new file mode 100644
index 0000000..71e4116
--- /dev/null
+++ b/src/world/SurfacePatch.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenSim.world
+{
+ public class SurfacePatch
+ {
+ public float[] HeightMap;
+
+ public SurfacePatch() {
+ HeightMap = new float[16*16];
+
+ int xinc;
+ int yinc;
+ for(xinc=0; xinc<16; xinc++) for(yinc=0; yinc<16; yinc++) {
+ HeightMap[xinc+(yinc*16)]=100.0f;
+ }
+
+ }
+ }
+}
diff --git a/src/world/World.cs b/src/world/World.cs
new file mode 100644
index 0000000..cf337a8
--- /dev/null
+++ b/src/world/World.cs
@@ -0,0 +1,57 @@
+using System;
+using libsecondlife;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenSim.world
+{
+ public class World
+ {
+ public Dictionary Entities;
+ public SurfacePatch[] LandMap;
+ public ScriptEngine Scripts;
+
+ public World()
+ {
+ Console.WriteLine("World.cs - creating new entitities instance");
+ Entities = new Dictionary();
+
+ // We need a 16x16 array of 16m2 surface patches for a 256m2 sim
+ Console.WriteLine("World.cs - creating LandMap");
+ LandMap = new SurfacePatch[16*16];
+ int xinc;
+ int yinc;
+ for(xinc=0; xinc<16; xinc++) for(yinc=0; yinc<16; yinc++) {
+ LandMap[xinc+(yinc*16)]=new SurfacePatch();
+ }
+
+ Console.WriteLine("World.cs - Creating script engine instance");
+ // Initialise this only after the world has loaded
+ Scripts = new ScriptEngine(this);
+ }
+
+ public void Update()
+ {
+ foreach (libsecondlife.LLUUID UUID in Entities.Keys)
+ {
+ Entities[UUID].update();
+ }
+ }
+
+ public void AddViewerAgent(OpenSimClient AgentClient) {
+ Console.WriteLine("World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent");
+ Avatar NewAvatar = new Avatar(AgentClient);
+ Console.WriteLine("World.cs:AddViewerAgent() - Adding new avatar to world");
+ this.Entities.Add(AgentClient.AgentID, NewAvatar);
+ Console.WriteLine("World.cs:AddViewerAgent() - Starting RegionHandshake ");
+ NewAvatar.SendRegionHandshake(this);
+ this.Update(); // will work for now, but needs to be optimised so we don't update everything in the sim for each new user
+ }
+
+ public bool Backup() {
+ /* TODO: Save the current world entities state. */
+
+ return false;
+ }
+ }
+}
diff --git a/src/world/scripting/IScript.cs b/src/world/scripting/IScript.cs
new file mode 100644
index 0000000..550594d
--- /dev/null
+++ b/src/world/scripting/IScript.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenSim.world.scripting
+{
+ public interface IScriptHost {
+ bool Register(IScript iscript);
+ }
+ public interface IScript
+ {
+ string Name{get;set;}
+ IScriptHost Host{get;set;}
+ void Show();
+ }
+}
--
cgit v1.1