Brought in code from branches/gareth

brokenplugins
gareth 2007-02-27 23:00:49 +00:00
parent 5453580d55
commit 09dd4bd683
38 changed files with 5350 additions and 0 deletions

22
README Normal file
View File

@ -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

BIN
bin/Axiom.MathLib.dll Normal file

Binary file not shown.

BIN
bin/Db4objects.Db4o.dll Executable file

Binary file not shown.

BIN
bin/libsecondlife.dll Executable file

Binary file not shown.

BIN
bin/log4net.dll Normal file

Binary file not shown.

9
genvers.sh Executable file
View File

@ -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

62
opensim.build Normal file
View File

@ -0,0 +1,62 @@
<?xml version="1.0"?>
<project name="OpenSim" default="build" basedir=".">
<description>First nant buildfile for OpenSim</description>
<property name="debug" value="true" overwrite="false" />
<target name="clean" description="remove all generated files">
<delete file="bin/OpenSim.exe" failonerror="false" />
<delete file="bin/OpenSim.pdb" failonerror="false" />
</target>
<target name="svnupdate" description="updates to latest SVN">
<exec program="svn">
<arg value="update" />
</exec>
</target>
<target name="upgrade" description="updates from SVN and then builds" depends="clean,svnupdate,build">
</target>
<target name="build" description="compiles the source code">
<exec program="genvers.sh" />
<loadfile file="VERSION" property="svnver"/>
<asminfo output="src/AssemblyInfo.cs" language="CSharp">
<imports>
<import namespace="System" />
<import namespace="System.Reflection" />
<import namespace="System.Runtime.InteropServices" />
</imports>
<attributes>
<attribute type="ComVisibleAttribute" value="false" />
<attribute type="CLSCompliantAttribute" value="false" />
<attribute type="AssemblyVersionAttribute" value="${svnver}" />
<attribute type="AssemblyTitleAttribute" value="opensim" />
<attribute type="AssemblyDescriptionAttribute" value="The C# implementation of the simulator portion of OGS" />
<attribute type="AssemblyCopyrightAttribute" value="Copyright © OGS development team 2007"/>
</attributes>
</asminfo>
<csc target="exe" output="bin/OpenSim.exe" debug="${debug}" verbose="true">
<references basedir="bin/" failonempty="true">
<include name="System" />
<include name="System.Data" />
<include name="System.Xml" />
<include name="Axiom.MathLib.dll" />
<include name="libsecondlife.dll" />
<include name="log4net.dll" />
<include name="Db4objects.Db4o.dll" />
</references>
<sources basedir="src/">
<include name="AssemblyInfo.cs" />
<include name="Config.cs" />
<include name="VersionInfo.cs" />
<include name="Util.cs" />
<include name="types/*.cs" />
<include name="world/*.cs" />
<include name="OpenSimClient.cs" />
<include name="Main.cs" />
</sources>
</csc>
</target>
</project>

879
src/Agent_Manager.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
using libsecondlife.AssetSystem;
using System.IO;
using Axiom.MathLib;
namespace OpenSim
{
/// <summary>
/// Description of Agent_Manager.
/// </summary>
public class AgentManager
{
public Dictionary<libsecondlife.LLUUID,AvatarData> AgentList;
public static Dictionary<string, LLUUID> AnimsLLUUID = new Dictionary<string, LLUUID>();
public static Dictionary<LLUUID, string> AnimsNames = new Dictionary<LLUUID, string>();
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;
/// <summary>
///
/// </summary>
/// <param name="serve"></param>
public AgentManager(Server server)
{
AgentList = new Dictionary<libsecondlife.LLUUID,AvatarData>();
_server = server;
this.initialise();
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public AvatarData GetAgent(LLUUID id)
{
if(!this.AgentList.ContainsKey(id))
{
return null;
}
else
{
AvatarData avatar = this.AgentList[id];
return avatar;
}
}
/// <summary>
///
/// </summary>
/// <param name="agent"></param>
public void AddAgent(AvatarData agent)
{
this.AgentList.Add(agent.FullID, agent);
}
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
/// <param name="first"></param>
/// <param name="last"></param>
/// <returns></returns>
///
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
/// <param name="first"></param>
/// <param name="last"></param>
/// <returns></returns>
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);
}
/// <summary>
///
/// </summary>
/// <param name="UserInfo"></param>
public void RemoveAgent(UserAgentInfo userInfo)
{
this.AgentList.Remove(userInfo.AgentID);
//tell other clients to delete this avatar
}
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
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);
}
/// <summary>
///
/// </summary>
public void UpdatePositions()
{
//update positions
foreach (KeyValuePair<libsecondlife.LLUUID, AvatarData> 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<libsecondlife.LLUUID, AvatarData> 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);
}
}
}
}
/// <summary>
///
/// </summary>
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();
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
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<string, LLUUID> kp in AgentManager.AnimsLLUUID)
{
AnimsNames.Add(kp.Value, kp.Key);
}
}
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
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<libsecondlife.LLUUID, AvatarData> kp in this.AgentList)
{
if(kp.Value.NetInfo.AgentID != userInfo.AgentID)
{
this.SendOtherAvatarPosition(userInfo, kp.Value);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
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<libsecondlife.LLUUID, AvatarData> 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);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="user"></param>
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);
}
/// <summary>
///
/// </summary>
/// <param name="user"></param>
/// <param name="id"></param>
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);
}
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
/// <param name="avd"></param>
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);
}
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
/// <param name="line"></param>
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<libsecondlife.LLUUID, AvatarData> kp in this.AgentList)
{
if(kp.Value.NetInfo.AgentID!=userInfo.AgentID)
{
_server.SendPacket(reply, true, kp.Value.NetInfo);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="user"></param>
/// <param name="stop"></param>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="z"></param>
/// <param name="av_id"></param>
/// <param name="body"></param>
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<libsecondlife.LLUUID, AvatarData> 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);
}
}
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
/// <param name="lay"></param>
/// <param name="name"></param>
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()
{
}
}
*/
}

455
src/AssetManagement.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
using System;
using System.Net;
using System.Collections.Generic;
using libsecondlife;
using System.Collections;
using libsecondlife.Packets;
using libsecondlife.AssetSystem;
using System.IO;
namespace OpenSim
{
/// <summary>
/// Asset and Image management
/// </summary>
public class AssetManagement
{
public Dictionary<libsecondlife.LLUUID,AssetInfo> Assets;
public Dictionary<libsecondlife.LLUUID,TextureImage> 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;
/// <summary>
///
/// </summary>
/// <param name="_server"></param>
public AssetManagement(Server server, InventoryManager inventoryManager)
{
this._server = server;
this._inventoryManager = inventoryManager;
Textures = new Dictionary<libsecondlife.LLUUID,TextureImage> ();
Assets = new Dictionary<libsecondlife.LLUUID,AssetInfo> ();
this.initialise();
}
/// <summary>
///
/// </summary>
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);
}
/// <summary>
///
/// </summary>
/// <param name="UserInfo"></param>
/// <param name="AssetID"></param>
/// <param name="TransferRequest"></param>
#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()
{
}
}
}

231
src/Asset_manager.cs Normal file
View File

@ -0,0 +1,231 @@
/*
Copyright (c) OpenSim project, http://osgrid.org/
* Copyright (c) <year>, <copyright holder>
* 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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
using System;
using System.Collections.Generic;
using libsecondlife;
using System.Collections;
using libsecondlife.Packets;
using libsecondlife.AssetSystem;
using System.IO;
namespace OpenSim
{
/// <summary>
/// Description of Asset_manager.
/// </summary>
public class AssetManager
{
public Dictionary<libsecondlife.LLUUID,AssetInfo> 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<libsecondlife.LLUUID,AssetInfo> ();
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()
{
}
}
}

140
src/Config.cs Normal file
View File

@ -0,0 +1,140 @@
/*
Copyright (c) OpenSim project, http://osgrid.org/
* Copyright (c) <year>, <copyright holder>
* 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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using Db4objects.Db4o;
using libsecondlife;
using OpenSim.world;
namespace OpenSim
{
/// <summary>
/// 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.
/// </summary>
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();
}
}
}

372
src/GridManager.cs Normal file
View File

@ -0,0 +1,372 @@
/*
Copyright (c) OpenSim project, http://osgrid.org/
* Copyright (c) <year>, <copyright holder>
* 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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using libsecondlife;
using System.Collections;
using libsecondlife.Packets;
using libsecondlife.AssetSystem;
using System.IO;
using System.Xml;
namespace OpenSim
{
/// <summary>
/// Description of GridManager.
/// </summary>
public class GridManager
{
private Server _server;
private System.Text.Encoding _enc = System.Text.Encoding.ASCII;
private AgentManager _agentManager;
public Dictionary<ulong,RegionInfo> Grid;
/// <summary>
///
/// </summary>
/// <param name="serve"></param>
/// <param name="agentManager"></param>
public GridManager(Server server, AgentManager agentManager)
{
Grid = new Dictionary<ulong, RegionInfo>();
_server = server;
_agentManager = agentManager;
LoadGrid();
}
/// <summary>
///
/// </summary>
/// <param name="UserInfo"></param>
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);
}
/// <summary>
///
/// </summary>
/// <param name="UserInfo"></param>
/// <param name="MinX"></param>
/// <param name="MinY"></param>
/// <param name="MaxX"></param>
/// <param name="MaxY"></param>
public void RequestMapBlock(UserAgentInfo userInfo, int minX, int minY,int maxX,int maxY)
{
foreach (KeyValuePair<ulong, RegionInfo> 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);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="UserInfo"></param>
/// <param name="Request"></param>
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);
}
}
/// <summary>
///
/// </summary>
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 <Root>");
XmlNode nodes = root.FirstChild;
if (nodes.Name != "Grid")
throw new Exception("Error: Invalid File. <project> first child should be <Grid>");
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()
{
}
}
}

242
src/InventoryManager.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
using libsecondlife.AssetSystem;
using System.IO;
namespace OpenSim
{
/// <summary>
/// Description of InventoryManager.
/// </summary>
public class InventoryManager
{
public Dictionary<LLUUID, InventoryFolder> Folders;
public Dictionary<LLUUID, InventoryItem> Items;
private Server _server;
private System.Text.Encoding _enc = System.Text.Encoding.ASCII;
private const uint FULL_MASK_PERMISSIONS = 2147483647;
/// <summary>
///
/// </summary>
/// <param name="serve"></param>
public InventoryManager(Server server)
{
_server = server;
Folders=new Dictionary<LLUUID, InventoryFolder>();
Items=new Dictionary<LLUUID, InventoryItem>();
}
/// <summary>
///
/// </summary>
/// <param name="UserInfo"></param>
/// <param name="FolderID"></param>
/// <param name="Asset"></param>
/// <returns></returns>
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);
}
}
/// <summary>
///
/// </summary>
/// <param name="UserInfo"></param>
/// <param name="NewFolder"></param>
/// <returns></returns>
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);
}
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
/// <param name="FetchDescend"></param>
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");
}
}
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
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<InventoryItem> Items;
//public List<InventoryFolder> Subfolders;
public LLUUID FolderID;
public LLUUID OwnerID;
public LLUUID ParentID;
public InventoryFolder()
{
Items = new List<InventoryItem>();
}
}
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()
{
}
}
}

228
src/Login_manager.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using 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
{
/// <summary>
/// Description of Login_manager.
/// </summary>
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();
}
}
}
}

138
src/Main.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.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
{
/// <summary>
/// Description of MainForm.
/// </summary>
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<EndPoint, OpenSimClient> ClientThreads = new Dictionary<EndPoint, OpenSimClient>();
[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);
}
}
}
}

339
src/OpenSimClient.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
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
{
/// <summary>
/// Handles new client connections
/// Constructor takes a single Packet and authenticates everything
/// </summary>
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<QueItem> PacketQueue;
private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
private Dictionary<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
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<QueItem>();
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();
}
}
}
}

41
src/Physics_manager.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
namespace OpenSim
{
/// <summary>
/// Description of Physics_manager.
/// </summary>
public class PhysicsManager
{
public PhysicsManager()
{
}
}
}

382
src/Prim_manager.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using libsecondlife;
using libsecondlife.Packets;
using libsecondlife.AssetSystem;
using System.IO;
using Axiom.MathLib;
namespace OpenSim
{
/// <summary>
/// Description of Prim_manager.
/// </summary>
public class PrimManager
{
private Server _server;
private uint _primCount;
public AgentManager AgentManagement;
public libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock PrimTemplate;
public Dictionary<libsecondlife.LLUUID,PrimInfo> PrimList;
/// <summary>
///
/// </summary>
/// <param name="serve"></param>
public PrimManager(Server server)
{
_server = server;
PrimList = new Dictionary<libsecondlife.LLUUID,PrimInfo> ();
//this.SetupTemplates("objectupate164.dat");
}
/// <summary>
///
/// </summary>
/// <param name="User_info"></param>
/// <param name="p1"></param>
/// <param name="add_pack"></param>
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<libsecondlife.LLUUID, AvatarData> 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
}
/// <summary>
///
/// </summary>
/// <param name="User"></param>
/// <param name="position"></param>
/// <param name="LocalID"></param>
/// <param name="setRotation"></param>
/// <param name="rotation"></param>
public void UpdatePrimPosition(UserAgentInfo userInfo, LLVector3 position, uint localID, bool setRotation, LLQuaternion rotation)
{
PrimInfo pri = null;
foreach (KeyValuePair<libsecondlife.LLUUID,PrimInfo> 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<libsecondlife.LLUUID,AvatarData> kp in AgentManagement.AgentList)
{
if(kp.Value.NetInfo.AgentID!=userInfo.AgentID)
{
_server.SendPacket(im, true, kp.Value.NetInfo);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="user"></param>
public void SendExistingPrims(UserAgentInfo userInfo)
{
//send data for already created prims to a new joining user
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
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();
}
/// <summary>
///
/// </summary>
/// <param name="name"></param>
/// <param name="user"></param>
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()
{
}
}
}

40
src/SceneGraphManager.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
namespace OpenSim
{
/// <summary>
/// Description of SceneGraphManager.
/// </summary>
public class SceneGraphManager
{
public SceneGraphManager()
{
}
}
}

103
src/Script_manager.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
//using LuaInterface;
using libsecondlife;
namespace OpenSim
{
/// <summary>
/// Description of Script_manager.
/// </summary>
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);
}
}

60
src/Second-server.csproj Normal file
View File

@ -0,0 +1,60 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<OutputType>Exe</OutputType>
<RootNamespace>OpenSim</RootNamespace>
<AssemblyName>OpenSim</AssemblyName>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}</ProjectGuid>
<StartupObject>OpenSim.Controller</StartupObject>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<Optimize>False</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugSymbols>True</DebugSymbols>
<DebugType>Full</DebugType>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
<Optimize>True</Optimize>
<DefineConstants>TRACE</DefineConstants>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
</PropertyGroup>
<ItemGroup>
<Reference Include="Axiom.MathLib, Version=0.7.0.25497, Culture=neutral">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\bin\Axiom.MathLib.dll</HintPath>
</Reference>
<Reference Include="libsecondlife, Version=0.9.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\bin\libsecondlife.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\bin\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Agent_Manager.cs" />
<Compile Include="Controller.cs" />
<Compile Include="Prim_manager.cs" />
<Compile Include="Login_manager.cs" />
<Compile Include="Physics_manager.cs" />
<Compile Include="Script_manager.cs" />
<Compile Include="Server.cs" />
<Compile Include="StorageManager.cs" />
<Compile Include="GridManager.cs" />
<Compile Include="Globals.cs" />
<Compile Include="InventoryManager.cs" />
<Compile Include="SceneGraphManager.cs" />
<Compile Include="AssetManagement.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

34
src/Second-server.sln Normal file
View File

@ -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

BIN
src/Second-server.suo Normal file

Binary file not shown.

707
src/Server.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using libsecondlife;
using System.Collections;
using libsecondlife.Packets;
using libsecondlife.AssetSystem;
using System.Net;
using System.Net.Sockets;
using System.Timers;
//really hacked , messy code
namespace OpenSim
{
/// <summary>
/// Description of Server.
/// </summary>
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
{
/// <summary>A public reference to the client that this Simulator object
/// is attached to</summary>
//public SecondLife Client;
/// <summary>The Region class that this Simulator wraps</summary>
// public Region Region;
/// <summary>
/// Used internally to track sim disconnections, do not modify this
/// variable
/// </summary>
public bool DisconnectCandidate = false;
/// <summary>
/// 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
/// </summary>
public uint CircuitCode
{
get { return circuitCode; }
set { circuitCode = value; }
}
/// <summary>
/// The IP address and port of the server
/// </summary>
public IPEndPoint IPEndPoint
{
get { return ipEndPoint; }
}
/// <summary>
/// A boolean representing whether there is a working connection to the
/// simulator or not
/// </summary>
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();
/// <summary>
/// Constructor for Simulator
/// </summary>
/// <param name="client"></param>
/// <param name="callbacks"></param>
/// <param name="circuit"></param>
/// <param name="ip"></param>
/// <param name="port"></param>
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);
}
}
/// <summary>
/// Disconnect a Simulator
/// </summary>
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)
{
}
}
}
/// <summary>
/// Sends a packet
/// </summary>
/// <param name="packet">Packet to be sent</param>
/// <param name="incrementSequence">Increment sequence number?</param>
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();
}
}
/// <summary>
/// Send a raw byte array payload as a packet
/// </summary>
/// <param name="payload">The packet payload</param>
/// <param name="setSequence">Whether the second, third, and fourth bytes
/// should be modified to the current stream sequence number</param>
/// <summary>
/// Returns Simulator Name as a String
/// </summary>
/// <returns></returns>
public override string ToString()
{
return( " (" + ipEndPoint.ToString() + ")");
}
/// <summary>
/// Sends out pending acknowledgements
/// </summary>
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();
}
}
}
/// <summary>
/// Resend unacknowledged packets
/// </summary>
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);
}
}
}
}
}
/// <summary>
/// Callback handler for incomming data
/// </summary>
/// <param name="result"></param>
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<uint>(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<this.User_agents.Count ; ii++)
{
temp_agent=(UserAgentInfo)this.User_agents[ii];
IPEndPoint ag_ip=(IPEndPoint)temp_agent.endpoint;
Console.WriteLine("searching: address is "+ag_ip.Address +"port number is: "+ag_ip.Port.ToString());
if((ag_ip.Address.ToString()==send_ip.Address.ToString()) && (ag_ip.Port.ToString()==send_ip.Port.ToString()))
{
Console.WriteLine("found user");
User_info=temp_agent;
break;
}
}
Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
}
catch (SocketException)
{
// Client.Log(endPoint.ToString() + " socket is closed, shutting down " + this.Region.Name,
// Helpers.LogLevel.Info);
connected = false;
//Network.DisconnectSim(this);
return;
}
}
if(User_info==null)
{
this.CallbackObject.ErrorCallback("no user found");
return;
}
// Fail-safe check
if (packet == null)
{
this.CallbackObject.ErrorCallback("couldn't build packet");
// Client.Log("Couldn't build a message from the incoming data", Helpers.LogLevel.Warning);
return;
}
//this.callback_object.error("past tests");
// Track the sequence number for this packet if it's marked as reliable
if (packet.Header.Reliable)
{
if (User_info.PendingAcks.Count > 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; i<this.User_agents.Count; i++)
{
UserAgentInfo user=(UserAgentInfo)this.User_agents[i];
SendAcks(user);
ResendUnacked(user);
}
}
}
}
public class Server_Settings
{
/// <summary>The version of libsecondlife (not the SL protocol itself)</summary>
public string VERSION = "libsecondlife 0.0.9";
/// <summary>XML-RPC login server to connect to</summary>
public string LOGIN_SERVER = "http://www.garethnelson.com/ogs/login/";
/// <summary>Millisecond interval between ticks, where all ACKs are
/// sent out and the age of unACKed packets is checked</summary>
public readonly int NETWORK_TICK_LENGTH = 500;
/// <summary>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</summary>
public readonly int MAX_SEQUENCE = 0xFFFFFF;
/// <summary>Number of milliseconds before a teleport attempt will time
/// out</summary>
public readonly int TELEPORT_TIMEOUT = 18 * 1000;
/// <summary>Number of milliseconds before NetworkManager.Logout() will time out</summary>
public int LOGOUT_TIMEOUT = 5 * 1000;
/// <summary>Number of milliseconds for xml-rpc to timeout</summary>
public int LOGIN_TIMEOUT = 30 * 1000;
/// <summary>The maximum size of the sequence number inbox, used to
/// check for resent and/or duplicate packets</summary>
public int INBOX_SIZE = 100;
/// <summary>Milliseconds before a packet is assumed lost and resent</summary>
public int RESEND_TIMEOUT = 4000;
/// <summary>Milliseconds before the connection to a simulator is
/// assumed lost</summary>
public int SIMULATOR_TIMEOUT = 15000;
/// <summary>Maximum number of queued ACKs to be sent before SendAcks()
/// is forced</summary>
public int MAX_PENDING_ACKS = 10;
/// <summary>Maximum number of ACKs to append to a packet</summary>
public int MAX_APPENDED_ACKS = 10;
/// <summary>Cost of uploading an asset</summary>
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<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
// Sequence numbers of packets we've received from the simulator
public Queue<uint> Inbox;
// ACKs that are queued up to be sent to the simulator
public Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
public UserAgentInfo()
{
}
}
}

53
src/StorageManager.cs Normal file
View File

@ -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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using libsecondlife;
using System.Collections;
using libsecondlife.Packets;
using libsecondlife.AssetSystem;
using System.IO;
namespace OpenSim
{
/// <summary>
/// Description of StorageManager.
/// </summary>
public class StorageManager
{
public StorageManager()
{
}
}
public class AssetStorage
{
public LLUUID Full_ID;
public byte Type;
}
}

238
src/Texture_manager.cs Normal file
View File

@ -0,0 +1,238 @@
/*
Copyright (c) OpenSim project, http://osgrid.org/
* Copyright (c) <year>, <copyright holder>
* 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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using libsecondlife;
using System.Collections;
using libsecondlife.Packets;
using libsecondlife.AssetSystem;
using System.IO;
namespace OpenSim
{
/// <summary>
/// Description of Texture_manager.
/// </summary>
public class TextureManager
{
public Dictionary<libsecondlife.LLUUID,TextureImage> 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<libsecondlife.LLUUID,TextureImage> ();
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<num; i++)
{
req=(TextureRequest)this.requests[i];
if(req.packet_counter==0)
{
//first time for this request so send imagedata packet
if(req.num_packets==1)
{
//only one packet so send whole file
ImageDataPacket im=new ImageDataPacket();
im.ImageID.Packets=1;
im.ImageID.ID=req.image_info.Full_ID;
im.ImageID.Size=(uint)req.image_info.data.Length;
im.ImageData.Data=req.image_info.data;
im.ImageID.Codec=2;
server.SendPacket(im,true,req.RequestUser);
req.packet_counter++;
req.image_info.last_used=time;
System.Console.WriteLine("sent texture: "+req.image_info.Full_ID);
}
else
{
//more than one packet so split file up
}
}
else
{
//send imagepacket
}
}
//remove requests that have been completed
for(int i=0; i<num; i++)
{
req=(TextureRequest)this.requests[i];
if(req.packet_counter==req.num_packets)
{
this.requests.Remove(req);
}
}
}
public void RecieveTexture(Packet pack)
{
}
private void initialise()
{
TextureImage im=new TextureImage();
im.filename="testpic2.jp2";
im.Full_ID=new LLUUID("00000000-0000-0000-5005-000000000005");
im.Name="test Texture";
this.LoadImage(im);
this.textures.Add(im.Full_ID,im);
//Change these filenames to images you want to use.
im=new TextureImage();
im.filename="map_base.jp2";
im.Full_ID=new LLUUID("00000000-0000-0000-7007-000000000006");
this.LoadImage(im);
this.textures.Add(im.Full_ID,im);
im=new TextureImage();
im.filename="map1.jp2";
im.Full_ID=new LLUUID("00000000-0000-0000-7009-000000000008");
this.LoadImage(im);
this.textures.Add(im.Full_ID,im);
}
private void LoadImage(TextureImage im)
{
//should request Image from StorageManager
//but for now read from file
string data_path=System.AppDomain.CurrentDomain.BaseDirectory + @"\textures\";
string filename=data_path+@im.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();
im.data=idata;
im.loaded=true;
}
}
public class TextureRequest
{
public User_Agent_info RequestUser;
public LLUUID RequestImage;
public TextureImage image_info;
public long data_pointer=0;
public int num_packets=0;
public int packet_counter=0;
public TextureRequest()
{
}
}
public class TextureImage: AssetBase
{
//public byte[] data;
//public LLUUID Full_ID;
//public string name;
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 TextureImage()
{
}
}
}

75
src/Util.cs Normal file
View File

@ -0,0 +1,75 @@
/*
Copyright (c) OpenSim project, http://osgrid.org/
* Copyright (c) <year>, <copyright holder>
* 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 <organization> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Threading;
using libsecondlife;
using libsecondlife.Packets;
namespace OpenSim
{
/// <summary>
/// </summary>
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();
}
}
}
}

View File

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

138
src/types/BitPack.cs Normal file
View File

@ -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> bits;
public InverseBitPack()
{
bits = new List<Bits>();
}
}
public class BitPack
{
private const int MAX_BITS = 8;
private byte[] Data;
private int bytePos;
private int bitPos;
public BitPack(byte[] data, int pos) // For libsl compatibility
{
Data = data;
bytePos = pos;
}
public BitPack() // Encoding version
{
}
public void LoadData(byte[] data, int pos) {
Data = data;
bytePos = pos;
bitPos = 0;
}
private void PackBitsArray(byte[] bits, int bitLen)
{
int offset = bitPos % MAX_BITS;
int i;
byte temp1;
byte temp2;
for (i = 0; i < bits.Length; i++)
{
int Byte = bits[i];
Byte <<= offset;
temp1 = (byte)(Byte & 0xFF);
temp2 = (byte)((Byte >> 8) & 0xFF);
Data[Data.Length - 1] |= temp1;
// Data
bitPos += bitLen;
}
}
public float UnpackFloat()
{
byte[] output = UnpackBitsArray(32);
if (!BitConverter.IsLittleEndian) Array.Reverse(output);
return BitConverter.ToSingle(output, 0);
}
public int UnpackBits(int totalCount)
{
byte[] output = UnpackBitsArray(totalCount);
if (!BitConverter.IsLittleEndian) Array.Reverse(output);
return BitConverter.ToInt32(output, 0);
}
private byte[] UnpackBitsArray(int totalCount)
{
int count = 0;
byte[] output = new byte[4];
int curBytePos = 0;
int curBitPos = 0;
while (totalCount > 0)
{
if (totalCount > MAX_BITS)
{
count = MAX_BITS;
totalCount -= MAX_BITS;
}
else
{
count = totalCount;
totalCount = 0;
}
while (count > 0)
{
// Shift the previous bits
output[curBytePos] <<= 1;
// Grab one bit
if ((Data[bytePos] & (0x80 >> bitPos++)) != 0)
++output[curBytePos];
--count;
++curBitPos;
if (bitPos >= MAX_BITS)
{
bitPos = 0;
++bytePos;
}
if (curBitPos >= MAX_BITS)
{
curBitPos = 0;
++curBytePos;
}
}
}
return output;
}
}
}

28
src/types/Mesh.cs Normal file
View File

@ -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<Triangle> mesh;
public Mesh()
{
mesh = new List<Triangle>();
}
public void AddTri(Triangle tri)
{
mesh.Add(tri);
}
public static Mesh operator +(Mesh a, Mesh b)
{
a.mesh.AddRange(b.mesh);
return a;
}
}
}

28
src/types/Triangle.cs Normal file
View File

@ -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;
}
}
}

70
src/world/Avatar.cs Normal file
View File

@ -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);
}
}
}

53
src/world/Entity.cs Normal file
View File

@ -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<Entity> children;
public Entity()
{
uuid = new libsecondlife.LLUUID();
position = new Vector3();
velocity = new Vector3();
rotation = new Quaternion();
name = "(basic entity)";
children = new List<Entity>();
}
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;
}
}
}

33
src/world/Primitive.cs Normal file
View File

@ -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;
}
}
}

18
src/world/ScriptEngine.cs Normal file
View File

@ -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()
{
}
}
}

22
src/world/SurfacePatch.cs Normal file
View File

@ -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;
}
}
}
}

57
src/world/World.cs Normal file
View File

@ -0,0 +1,57 @@
using System;
using libsecondlife;
using System.Collections.Generic;
using System.Text;
namespace OpenSim.world
{
public class World
{
public Dictionary<libsecondlife.LLUUID, Entity> Entities;
public SurfacePatch[] LandMap;
public ScriptEngine Scripts;
public World()
{
Console.WriteLine("World.cs - creating new entitities instance");
Entities = new Dictionary<libsecondlife.LLUUID, Entity>();
// 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;
}
}
}

View File

@ -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();
}
}