/* Copyright (c) 2007 Michael Wright * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; using System.Collections.Generic; using libsecondlife; using libsecondlife.Packets; using libsecondlife.AssetSystem; using System.IO; using Axiom.MathLib; namespace OpenSim { /// /// Description of Agent_Manager. /// public class AgentManager { public Dictionary AgentList; private uint local_numer=0; private Server server; public PrimManager Prim_Manager; private libsecondlife.Packets.RegionHandshakePacket RegionPacket; private System.Text.Encoding enc = System.Text.Encoding.ASCII; public libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock AvatarTemplate; /// /// /// /// public AgentManager(Server serve) { AgentList=new Dictionary(); server=serve; this.initialise(); } /// /// /// /// /// public AvatarData GetAgent(LLUUID id) { if(!this.AgentList.ContainsKey(id)) { return null; } else { AvatarData ad=this.AgentList[id]; return ad; } } /// /// /// /// public void AddAgent(AvatarData agent) { this.AgentList.Add(agent.FullID,agent); } /// /// /// /// /// /// /// /// /// /// /// /// /// /// /// public bool NewAgent(User_Agent_info User_info, string first, string last) { AvatarData agent=new AvatarData(); agent.FullID=User_info.AgentID; agent.NetInfo=User_info; agent.NetInfo.first_name=first; agent.NetInfo.last_name=last; agent.Position=new LLVector3(100,100,22); this.AgentList.Add(agent.FullID,agent); return(true); } /// /// /// /// public void RemoveAgent(User_Agent_info UserInfo) { this.AgentList.Remove(UserInfo.AgentID); //tell other clients to delete this avatar } /// /// /// /// public void AgentJoin(User_Agent_info User_info) { //send region data server.SendPacket(RegionPacket,true,User_info); //inform client of join comlete libsecondlife.Packets.AgentMovementCompletePacket mov=new AgentMovementCompletePacket(); mov.AgentData.SessionID=User_info.SessionID; mov.AgentData.AgentID=User_info.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,User_info); } /// /// /// public void UpdatePositions() { //update positions foreach (KeyValuePair kp in this.AgentList) { kp.Value.Position.X+=(kp.Value.Velocity.X*0.2f); kp.Value.Position.Y+=(kp.Value.Velocity.Y*0.2f); kp.Value.Position.Z+=(kp.Value.Velocity.Z*0.2f); } } /// /// /// 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"); } /// /// /// /// private void SetupTemplate(string name) { /*ObjectUpdatePacket objupdate=new ObjectUpdatePacket(); objupdate.RegionData.RegionHandle=1096213093147648; 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; 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; } /// /// /// /// public void SendInitialData(User_Agent_info User_info) { //shouldn't have to read all this in from disk for every new client string data_path=System.AppDomain.CurrentDomain.BaseDirectory + @"\layer_data\"; //send layerdata LayerDataPacket layerpack=new LayerDataPacket(); layerpack.LayerID.Type=76; this.SendLayerData(User_info,ref layerpack,data_path+@"layerdata0.dat"); LayerDataPacket layerpack1=new LayerDataPacket(); layerpack1.LayerID.Type=76; this.SendLayerData(User_info,ref layerpack,data_path+@"layerdata1.dat"); LayerDataPacket layerpack2=new LayerDataPacket(); layerpack2.LayerID.Type=56; this.SendLayerData(User_info,ref layerpack,data_path+@"layerdata2.dat"); LayerDataPacket layerpack3=new LayerDataPacket(); layerpack3.LayerID.Type=55; this.SendLayerData(User_info,ref layerpack,data_path+@"layerdata3.dat"); LayerDataPacket layerpack4=new LayerDataPacket(); layerpack4.LayerID.Type=56; this.SendLayerData(User_info,ref layerpack,data_path+@"layerdata4.dat"); LayerDataPacket layerpack5=new LayerDataPacket(); layerpack5.LayerID.Type=55; this.SendLayerData(User_info,ref layerpack,data_path+@"layerdata5.dat"); //send intial set of captured prims data? this.Prim_Manager.ReadPrimDatabase( "objectdatabase.ini",User_info); //send prims that have been created by users //prim_man.send_existing_prims(User_info); //send update about clients avatar this.SendInitialAvatarPosition(User_info); //send updates about all other users foreach (KeyValuePair kp in this.AgentList) { if(kp.Value.NetInfo.AgentID!=User_info.AgentID) { this.SendOtherAvatarPosition(User_info,kp.Value); } } } /// /// /// /// public void SendInitialAvatarPosition(User_Agent_info User_info) { //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.local_numer; User_info.localID=objupdate.ObjectData[0].ID; //User_info.name="Test"+this.local_numer+" User"; this.GetAgent(User_info.AgentID).Started=true; objupdate.ObjectData[0].FullID=User_info.AgentID; objupdate.ObjectData[0].NameValue=enc.GetBytes("FirstName STRING RW SV "+User_info.first_name+"\nLastName STRING RW SV "+User_info.last_name+" \0"); User_info.name="FirstName STRING RW SV "+User_info.first_name+"\nLastName STRING RW SV "+User_info.last_name+" \0"; //User_info.last_name="User"; //User_info.first_name="Test"+this.local_numer; 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.local_numer++; server.SendPacket(objupdate,true,User_info); //send this info to other existing clients foreach (KeyValuePair kp in this.AgentList) { if(kp.Value.NetInfo.AgentID!=User_info.AgentID) { server.SendPacket(objupdate,true,kp.Value.NetInfo); this.SendOtherAppearance(kp.Value.NetInfo,objupdate.ObjectData[0].FullID); } } } /// /// /// /// public void SendIntialAvatarAppearance(User_Agent_info user) { AgentWearablesUpdatePacket aw=new AgentWearablesUpdatePacket(); aw.AgentData.AgentID=user.AgentID; aw.AgentData.SerialNum=0;//(uint)appc; //appc++; aw.AgentData.SessionID=user.SessionID;//new LLUUID("00000000-0000-0000-0000-000000000000");//user.SessionID; aw.WearableData= new AgentWearablesUpdatePacket.WearableDataBlock[13]; AgentWearablesUpdatePacket.WearableDataBlock awb=null; awb=new AgentWearablesUpdatePacket.WearableDataBlock(); awb.WearableType=(byte)0; awb.AssetID=new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"); awb.ItemID=new LLUUID("b7878441893b094917f791174bc8401c"); aw.WearableData[0]=awb; /*awb=new AgentWearablesUpdatePacket.WearableDataBlock(); awb.WearableType=(byte)1; awb.AssetID=new LLUUID("e0ee49b5a4184df8d3c9a65361fe7f49"); awb.ItemID=new LLUUID("193f0876fc11d143797454352f9c9c26"); //awb.ItemID=new LLUUID("00000000-0000-0000-0000-000000000000"); aw.WearableData[1]=awb;*/ for(int i=1; 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,user); } /// /// /// /// /// public void SendOtherAppearance(User_Agent_info user,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,user); } /// /// /// /// /// public void SendOtherAvatarPosition(User_Agent_info User_info, AvatarData avd) { //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=avd.NetInfo.localID; objupdate.ObjectData[0].FullID=avd.NetInfo.AgentID;//new LLUUID("00000000-0000-0000-5665-000000000034"); objupdate.ObjectData[0].NameValue=enc.GetBytes(avd.NetInfo.name);//enc.GetBytes("FirstName STRING RW SV Test"+ this.local_numer+"\nLastName STRING RW SV User \0"); libsecondlife.LLVector3 pos2=new LLVector3(avd.Position.X,avd.Position.Y,avd.Position.Z); byte[] pb=pos2.GetBytes(); Array.Copy(pb,0,objupdate.ObjectData[0].ObjectData,16,pb.Length); this.local_numer++; server.SendPacket(objupdate,true,User_info); this.SendOtherAppearance(User_info,avd.NetInfo.AgentID);//new LLUUID("00000000-0000-0000-5665-000000000034")); } /// /// /// /// /// public void SendChatMessage(User_Agent_info User_info, 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(User_info.first_name +" "+User_info.last_name +"\0"); //enc.GetBytes("Echo: \0"); //and actual name reply.ChatData.OwnerID=User_info.AgentID; reply.ChatData.SourceID=User_info.AgentID; //echo to sender server.SendPacket(reply,true,User_info); //send to all users foreach (KeyValuePair kp in this.AgentList) { if(kp.Value.NetInfo.AgentID!=User_info.AgentID) { server.SendPacket(reply,true,kp.Value.NetInfo); } } } /// /// /// /// /// /// /// /// /// /// public void SendMoveCommand(User_Agent_info user, bool stop,float x, float y, float z, uint av_id, libsecondlife.LLQuaternion body) { uint ID=user.localID; //ID=av_id; 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=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,user); //should send to all users. foreach (KeyValuePair kp in this.AgentList) { if(kp.Value.NetInfo.AgentID!=user.AgentID) { server.SendPacket(im,true,kp.Value.NetInfo); } } } /// /// /// /// /// /// public void SendLayerData(User_Agent_info User_info,ref LayerDataPacket lay,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(); lay.LayerData.Data=data1; server.SendPacket(lay,true,User_info); //System.Console.WriteLine("sent"); } } public class AvatarData { public User_Agent_info 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 AvatarData() { } } /* public class AvatarParams { public byte[] Params; public AvatarParams() { } } */ }