commit a82950672860eedeaa23da75421c74e094b5c0a4 Author: cw Date: Wed Jan 31 22:09:20 2007 +0000 Making trunk; applying appropriate license to each file diff --git a/Agent_Manager.cs b/Agent_Manager.cs new file mode 100644 index 0000000000..934fb57fcb --- /dev/null +++ b/Agent_Manager.cs @@ -0,0 +1,618 @@ +/* +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 Second_server +{ + /// + /// Description of Agent_Manager. + /// + public class Agent_Manager + { + public Dictionary Agent_list; + //public uint number_agents=0; + private uint local_numer=0; + private Server server; + public Prim_manager prim_man; + private byte [] data1; + + private libsecondlife.Packets.RegionHandshakePacket reg; + private System.Text.Encoding enc = System.Text.Encoding.ASCII; + public libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock avatar_template; + //private int appc=0; + + public Agent_Manager(Server serve) + { + Agent_list=new Dictionary(); + server=serve; + this.initialise(); + } + //*************************************************** + public Avatar_data Get_Agent(LLUUID id) + { + + + if(!this.Agent_list.ContainsKey(id)) + { + return null; + } + else + { + Avatar_data ad=this.Agent_list[id]; + return ad; + } + } + + public void Add_Agent(Avatar_data agent) + { + this.Agent_list.Add(agent.Full_ID,agent); + } + + public bool New_Agent(User_Agent_info User_info) + { + Avatar_data ad=new Avatar_data(); + ad.Full_ID=User_info.AgentID; + ad.Net_info=User_info; + ad.pos=new LLVector3(100,100,22); + this.Agent_list.Add(ad.Full_ID,ad); + return(true); + } + + public void Agent_join(User_Agent_info User_info) + { + //send region data + server.SendPacket(reg,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=1096213093147648; + 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 tick() + { + //update positions + foreach (KeyValuePair kp in this.Agent_list) + { + + kp.Value.pos.X+=(kp.Value.vel.X*0.2f); + kp.Value.pos.Y+=(kp.Value.vel.Y*0.2f); + kp.Value.pos.Z+=(kp.Value.vel.Z*0.2f); + } + } + //************************************************************** + private void initialise() + { + //Region data + reg=new RegionHandshakePacket(); + reg.RegionInfo.BillableFactor=0; + reg.RegionInfo.IsEstateManager=false; + reg.RegionInfo.TerrainHeightRange00=60; + reg.RegionInfo.TerrainHeightRange01=60; + reg.RegionInfo.TerrainHeightRange10=60; + reg.RegionInfo.TerrainHeightRange11=60; + reg.RegionInfo.TerrainStartHeight00=20; + reg.RegionInfo.TerrainStartHeight01=20; + reg.RegionInfo.TerrainStartHeight10=20; + reg.RegionInfo.TerrainStartHeight11=20; + reg.RegionInfo.SimAccess=13; + reg.RegionInfo.WaterHeight=5; + reg.RegionInfo.RegionFlags=72458694; + reg.RegionInfo.SimName=enc.GetBytes( "Test Sandbox\0"); + reg.RegionInfo.SimOwner=new LLUUID("00000000-0000-0000-0000-000000000000"); + reg.RegionInfo.TerrainBase0=new LLUUID("b8d3965a-ad78-bf43-699b-bff8eca6c975"); + reg.RegionInfo.TerrainBase1=new LLUUID("abb783e6-3e93-26c0-248a-247666855da3"); + reg.RegionInfo.TerrainBase2=new LLUUID("179cdabd-398a-9b6b-1391-4dc333ba321f"); + reg.RegionInfo.TerrainBase3=new LLUUID("beb169c7-11ea-fff2-efe5-0f24dc881df2"); + reg.RegionInfo.TerrainDetail0=new LLUUID("00000000-0000-0000-0000-000000000000"); + reg.RegionInfo.TerrainDetail1=new LLUUID("00000000-0000-0000-0000-000000000000"); + reg.RegionInfo.TerrainDetail2=new LLUUID("00000000-0000-0000-0000-000000000000"); + reg.RegionInfo.TerrainDetail3=new LLUUID("00000000-0000-0000-0000-000000000000"); + reg.RegionInfo.CacheID=new LLUUID("545ec0a5-5751-1026-8a0b-216e38a7ab33"); + + this.setuptemplate("objectupate168.dat"); + } + + public 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); + + avatar_template=objdata; + + } + //********************************************************** + public void send_intial_data(User_Agent_info User_info) + { + + //shouldn't really have to read all this in from disk for every new client? + string data_path=System.Windows.Forms.Application.StartupPath + @"\layer_data\"; + + //send layerdata + LayerDataPacket layerpack=new LayerDataPacket(); + layerpack.LayerID.Type=76; + //layerpack.LayerData.ReadfromFile(data_path+@"layerdata0.dat"); + this.read_layerdata(User_info,ref layerpack,data_path+@"layerdata0.dat"); + + //server.SendPacket(layerpack,true,User_info); + + LayerDataPacket layerpack1=new LayerDataPacket(); + layerpack1.LayerID.Type=76; + //layerpack1.LayerData.ReadfromFile(data_path+@"layerdata1.dat"); + this.read_layerdata(User_info,ref layerpack,data_path+@"layerdata1.dat"); + //server.SendPacket(layerpack1,true,User_info); + + LayerDataPacket layerpack2=new LayerDataPacket(); + layerpack2.LayerID.Type=56; + //layerpack2.LayerData.ReadfromFile(data_path+@"layerdata2.dat"); + this.read_layerdata(User_info,ref layerpack,data_path+@"layerdata2.dat"); + //server.SendPacket(layerpack2,true,User_info); + + LayerDataPacket layerpack3=new LayerDataPacket(); + layerpack3.LayerID.Type=55; + //layerpack3.LayerData.ReadfromFile(data_path+@"layerdata3.dat"); + this.read_layerdata(User_info,ref layerpack,data_path+@"layerdata3.dat"); + //server.SendPacket(layerpack3,true,User_info); + + LayerDataPacket layerpack4=new LayerDataPacket(); + layerpack4.LayerID.Type=56; + //layerpack4.LayerData.ReadfromFile(data_path+@"layerdata4.dat"); + this.read_layerdata(User_info,ref layerpack,data_path+@"layerdata4.dat"); + //server.SendPacket(layerpack4,true,User_info); + + LayerDataPacket layerpack5=new LayerDataPacket(); + layerpack5.LayerID.Type=55; + //layerpack5.LayerData.ReadfromFile(data_path+@"layerdata5.dat"); + this.read_layerdata(User_info,ref layerpack,data_path+@"layerdata5.dat"); + //server.SendPacket(layerpack5,true,User_info); + + + //send intial set of captured prims data? + this.prim_man.Read_Prim_database( "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.send_intial_avatar_position(User_info); + + //send updates about all other users + //this.send_test_avatar_position(User_info); + foreach (KeyValuePair kp in this.Agent_list) + { + if(kp.Value.Net_info.AgentID!=User_info.AgentID) + { + this.send_other_avatar_position(User_info,kp.Value); + } + } + + + } + public void send_intial_avatar_position(User_Agent_info User_info) + { + //send a objectupdate packet with information about the clients avatar + ObjectUpdatePacket objupdate=new ObjectUpdatePacket(); + objupdate.RegionData.RegionHandle=1096213093147648; + objupdate.RegionData.TimeDilation=64096; + objupdate.ObjectData=new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; + + objupdate.ObjectData[0]=avatar_template; + //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.Get_Agent(User_info.AgentID).started=true; + objupdate.ObjectData[0].FullID=User_info.AgentID; + objupdate.ObjectData[0].NameValue=enc.GetBytes("FirstName STRING RW SV Test"+ this.local_numer+"\nLastName STRING RW SV User \0"); + User_info.name="FirstName STRING RW SV Test"+ this.local_numer+"\nLastName STRING RW SV User \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.Agent_list) + { + if(kp.Value.Net_info.AgentID!=User_info.AgentID) + { + server.SendPacket(objupdate,true,kp.Value.Net_info); + this.send_other_apper(kp.Value.Net_info,objupdate.ObjectData[0].FullID); + } + } + + } + public void send_intial_avatar_apper(User_Agent_info user) + { + + //seems that we don't send a avatarapperance for ourself. + /*AvatarAppearancePacket avp=new AvatarAppearancePacket(); + + avp.VisualParam=new AvatarAppearancePacket.VisualParamBlock[218]; + avp.ObjectData.TextureEntry=this.avatar_template.TextureEntry;// br.ReadBytes((int)numBytes); + + 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=user.AgentID; + */ + + 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("b7878000-0000-0000-0000-000000000000"); + awb.ItemID=new LLUUID("b7878441893b094917f791174bc8401c"); + //awb.ItemID=new LLUUID("00000000-0000-0000-0000-000000000000"); + 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(avp,true,user); + server.SendPacket(aw,true,user); + //System.Console.WriteLine(avp); + + + } + public void send_other_apper(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 send_test_avatar_position(User_Agent_info User_info) + { + //send a objectupdate packet with information about the clients avatar + ObjectUpdatePacket objupdate=new ObjectUpdatePacket(); + objupdate.RegionData.RegionHandle=1096213093147648; + objupdate.RegionData.TimeDilation=64500; + objupdate.ObjectData=new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; + + objupdate.ObjectData[0]=avatar_template; + //give this avatar object a local id and assign the user a name + objupdate.ObjectData[0].ID=8880000+this.local_numer; + objupdate.ObjectData[0].FullID=new LLUUID("00000000-0000-0000-5665-000000000034"); + objupdate.ObjectData[0].NameValue=enc.GetBytes("FirstName STRING RW SV Test"+ this.local_numer+"\nLastName STRING RW SV User \0"); + libsecondlife.LLVector3 pos2=new LLVector3(120f,120.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); + + this.send_other_apper(User_info,new LLUUID("00000000-0000-0000-5665-000000000034")); + + } + + public void send_other_avatar_position(User_Agent_info User_info, Avatar_data avd) + { + //send a objectupdate packet with information about the clients avatar + ObjectUpdatePacket objupdate=new ObjectUpdatePacket(); + objupdate.RegionData.RegionHandle=1096213093147648; + objupdate.RegionData.TimeDilation=64500; + objupdate.ObjectData=new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; + + objupdate.ObjectData[0]=avatar_template; + //give this avatar object a local id and assign the user a name + objupdate.ObjectData[0].ID=avd.Net_info.localID; + objupdate.ObjectData[0].FullID=avd.Net_info.AgentID;//new LLUUID("00000000-0000-0000-5665-000000000034"); + objupdate.ObjectData[0].NameValue=enc.GetBytes(avd.Net_info.name);//enc.GetBytes("FirstName STRING RW SV Test"+ this.local_numer+"\nLastName STRING RW SV User \0"); + libsecondlife.LLVector3 pos2=new LLVector3(avd.pos.X,avd.pos.Y,avd.pos.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.send_other_apper(User_info,avd.Net_info.AgentID);//new LLUUID("00000000-0000-0000-5665-000000000034")); + + } + //************************************************************* + public void send_chat_message(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.Agent_list) + { + if(kp.Value.Net_info.AgentID!=User_info.AgentID) + { + server.SendPacket(reply,true,kp.Value.Net_info); + } + } + } + //************************************************************* + public void send_move_command(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=1096213093147648; + 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=avatar_template.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.Agent_list) + { + if(kp.Value.Net_info.AgentID!=user.AgentID) + { + server.SendPacket(im,true,kp.Value.Net_info); + } + } + } + //************************************************************* + public void read_layerdata(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); + + 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 Avatar_data + { + public User_Agent_info Net_info; + public LLUUID Full_ID; + public LLVector3 pos; + public LLVector3 vel=new LLVector3(0,0,0); + public bool walk=false; + public bool started=false; + + public Avatar_data() + { + + } + } +} diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs new file mode 100644 index 0000000000..2738c9254a --- /dev/null +++ b/AssemblyInfo.cs @@ -0,0 +1,59 @@ +/* +* Copyright (c) , +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Information about this assembly is defined by the following +// attributes. +// +// change them to the information which is associated with the assembly +// you compile. + +[assembly: AssemblyTitle("Second-server")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Second-server")] +[assembly: AssemblyCopyright("")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// This sets the default COM visibility of types in the assembly to invisible. +// If you need to expose a type to COM, use [ComVisible(true)] on that type. +[assembly: ComVisible(false)] + +// The assembly version has following format : +// +// Major.Minor.Build.Revision +// +// You can specify all values by your own or you can build default build and revision +// numbers with the '*' character (the default): + +[assembly: AssemblyVersion("1.0.*")] diff --git a/Asset_manager.cs b/Asset_manager.cs new file mode 100644 index 0000000000..194d28f400 --- /dev/null +++ b/Asset_manager.cs @@ -0,0 +1,167 @@ +/* +Copyright (c) 2007 Michael Wright + +* Copyright (c) , +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + +using System; +using System.Collections.Generic; +using libsecondlife; +using System.Collections; +using libsecondlife.Packets; +using libsecondlife.AssetSystem; +using System.IO; + +namespace Second_server +{ + /// + /// Description of Asset_manager. + /// + public class Asset_manager + { + public Dictionary Assets; + public ArrayList requests=new ArrayList(); //should change to a generic + // public ArrayList uploads=new ArrayList(); + private Server server; + + public Asset_manager(Server serve) + { + server=serve; + Assets=new Dictionary (); + this.initialise(); + } + + public void add_request(User_Agent_info user, LLUUID asset_id, TransferRequestPacket tran_req) + { + + if(!this.Assets.ContainsKey(asset_id)) + { + //not found asset + return; + } + Asset_info 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 tran_i=new TransferInfoPacket(); + tran_i.TransferInfo.ChannelType=2; + tran_i.TransferInfo.Status=0; + tran_i.TransferInfo.TargetType=0; + tran_i.TransferInfo.Params=tran_req.TransferInfo.Params; + tran_i.TransferInfo.Size=info.data.Length; + tran_i.TransferInfo.TransferID=tran_req.TransferInfo.TransferID; + + server.SendPacket(tran_i,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); + } + + + + } + + private void initialise() + { + //for now read in our test image + Asset_info im=new Asset_info(); + im.filename="base_shape.dat"; + im.Full_ID=new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73"); + this.load_asset(im); + this.Assets.Add(im.Full_ID,im); + } + private void load_asset(Asset_info info) + { + string data_path=System.Windows.Forms.Application.StartupPath + @"\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 Asset_request + { + public User_Agent_info req_user; + public LLUUID req_image; + public Asset_info asset_inf; + public long data_pointer=0; + public int num_packets=0; + public int packet_counter=0; + + public Asset_request() + { + + } + } + public class Asset_info + { + 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 Asset_info() + { + + } + } +} diff --git a/Class1.cs b/Class1.cs new file mode 100644 index 0000000000..761a7eb3e1 --- /dev/null +++ b/Class1.cs @@ -0,0 +1,23 @@ +/* + * Created by SharpDevelop. + * User: Ma + * Date: 29/01/2007 + * Time: 18:02 + * + * To change this template use Tools | Options | Coding | Edit Standard Headers. + */ + +using System; + +namespace Second_server +{ + /// + /// Description of Class1. + /// + public class Class1 + { + public Class1() + { + } + } +} diff --git a/Login_manager.cs b/Login_manager.cs new file mode 100644 index 0000000000..84f475d0d0 --- /dev/null +++ b/Login_manager.cs @@ -0,0 +1,163 @@ +/*Copyright (c) 2007 Michael Wright + +* Copyright (c) , +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading; + +namespace Second_server +{ + /// + /// Description of Login_manager. + /// + public class Login_manager + { + public Login_manager() + { + + } + + public ushort loginPort = 8080; + public IPAddress clientAddress = IPAddress.Loopback; + public IPAddress remoteAddress = IPAddress.Any; + private Socket loginServer; + private Random RandomClass = new Random(); + + // 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 != ""); + System.Console.WriteLine(line); + // read the HTTP body into a buffer + char[] content = new char[contentLength]; + reader.Read(content, 0, contentLength); + + + // forward the XML-RPC response to the client + writer.WriteLine("HTTP/1.0 200 OK"); + writer.WriteLine("Content-type: text/xml"); + writer.WriteLine(); + + + StreamReader SR; + string lines; + SR=File.OpenText("login.dat"); + lines=SR.ReadLine(); + writer.WriteLine(lines); + lines=SR.ReadLine(); + int ran=this.RandomClass.Next(1,9999); + + lines="session_id99998888-"+ran.ToString("0000")+"-4f52-8ec1-0b1d5cd6aead"; + writer.WriteLine(lines); + lines=SR.ReadLine(); + writer.WriteLine(lines); + lines=SR.ReadLine(); + ran=this.RandomClass.Next(1,9999); + lines="agent_idaaaabbbb-8932-"+ran.ToString("0000")+"-8664-58f53e442797"; + writer.WriteLine(lines); + lines=SR.ReadLine(); + + while(lines!="end-mfile") + { + writer.WriteLine(lines); + lines=SR.ReadLine(); + } + SR.Close(); + } + } + } +} diff --git a/Main-sever.Designer.cs b/Main-sever.Designer.cs new file mode 100644 index 0000000000..af8cfe88aa --- /dev/null +++ b/Main-sever.Designer.cs @@ -0,0 +1,80 @@ +/* +Copyright (c) 2007 Michael Wright + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +namespace Second_server +{ + partial class Main_server : System.Windows.Forms.Form + { + /// + /// Designer variable used to keep track of non-visual components. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Disposes resources used by the form. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing) { + if (components != null) { + components.Dispose(); + } + } + base.Dispose(disposing); + } + + /// + /// This method is required for Windows Forms designer support. + /// Do not change the method contents inside the source code editor. The Forms designer might + /// not be able to load this method if it was changed manually. + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.timer1 = new System.Windows.Forms.Timer(this.components); + this.SuspendLayout(); + // + // richTextBox1 + // + this.richTextBox1.Location = new System.Drawing.Point(11, 12); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.Size = new System.Drawing.Size(346, 402); + this.richTextBox1.TabIndex = 0; + this.richTextBox1.Text = ""; + // + // timer1 + // + this.timer1.Enabled = true; + this.timer1.Interval = 200; + this.timer1.Tick += new System.EventHandler(this.Timer1Tick); + // + // Main_server + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(596, 426); + this.Controls.Add(this.richTextBox1); + this.Name = "Main_server"; + this.Text = "Main_sever"; + this.ResumeLayout(false); + } + private System.Windows.Forms.Timer timer1; + private System.Windows.Forms.RichTextBox richTextBox1; + } +} diff --git a/Main-sever.cs b/Main-sever.cs new file mode 100644 index 0000000000..911d9d79b8 --- /dev/null +++ b/Main-sever.cs @@ -0,0 +1,270 @@ +/* +Copyright (c) 2007 Michael Wright + +* Copyright (c) , +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; +using libsecondlife; +using libsecondlife.Packets; +using System.Collections; +using System.Text; +using System.IO; +using Axiom.MathLib; + +namespace Second_server +{ + /// + /// Description of MainForm. + /// + public partial class Main_server:Server_callback + { + + [STAThread] + public static void Main(string[] args) + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new Main_server()); + } + public Server server; + + //public bool intin=false; + //private libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock avatar_template; + //private libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock object_template; + + private Agent_Manager agent_man; + private Prim_manager prim_man; + private Texture_manager texture_man; + private Asset_manager asset_man; + private Login_manager login_man; //built in login server + private ulong time; //ticks + + public Main_server() + { + // + // The InitializeComponent() call is required for Windows Forms designer support. + // + InitializeComponent(); + + // + // TODO: Add constructor code after the InitializeComponent() call. + // + + server=new Server(this); + agent_man=new Agent_Manager(this.server); + prim_man=new Prim_manager(this.server); + texture_man=new Texture_manager(this.server); + asset_man=new Asset_manager(this.server); + prim_man.agent_man=agent_man; + agent_man.prim_man=prim_man; + login_man=new Login_manager(); // startup + login_man.startup(); // login server + + } + public void main_callback(Packet pack, User_Agent_info User_info) + { + if((pack.Type!= PacketType.StartPingCheck) && (pack.Type!= PacketType.AgentUpdate)) + { + //System.Console.WriteLine(pack.Type); + //this.richTextBox1.Text=this.richTextBox1.Text+"\n "+pack.Type; + } + if(pack.Type== PacketType.AgentSetAppearance) + { + //System.Console.WriteLine(pack); + //this.richTextBox1.Text=this.richTextBox1.Text+"\n "+pack.Type; + + } + if(pack.Type== PacketType.TransferRequest) + { + TransferRequestPacket tran=(TransferRequestPacket)pack; + LLUUID id=new LLUUID(tran.TransferInfo.Params,0); + + if((id==new LLUUID("66c41e39-38f9-f75a-024e-585989bfab73")) ||(id==new LLUUID("e0ee49b5a4184df8d3c9a65361fe7f49"))) + { + //System.Console.WriteLine(pack); + //System.Console.WriteLine(tran.TransferInfo.TransferID); + asset_man.add_request(User_info,id,tran); + //this.richTextBox1.Text=this.richTextBox1.Text+"\n "+pack.Type; + } + + } + if((pack.Type== PacketType.StartPingCheck) ) + { + //reply to pingcheck + libsecondlife.Packets.StartPingCheckPacket startp=(libsecondlife.Packets.StartPingCheckPacket)pack; + libsecondlife.Packets.CompletePingCheckPacket endping=new CompletePingCheckPacket(); + endping.PingID.PingID=startp.PingID.PingID; + server.SendPacket(endping,true,User_info); + } + if(pack.Type==PacketType.CompleteAgentMovement) + { + // new client + agent_man.Agent_join(User_info); + } + if (pack.Type==PacketType.RequestImage) + { + RequestImagePacket image_req=(RequestImagePacket)pack; + for(int i=0; i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/Physics_manager.cs b/Physics_manager.cs new file mode 100644 index 0000000000..22102a19ee --- /dev/null +++ b/Physics_manager.cs @@ -0,0 +1,43 @@ +/* +Copyright (c) 2007 Michael Wright + +* Copyright (c) , +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +using System; + +namespace Second_server +{ + /// + /// Description of Physics_manager. + /// + public class Physics_manager + { + public Physics_manager() + { + } + } +} diff --git a/Prim_manager.cs b/Prim_manager.cs new file mode 100644 index 0000000000..dff2d24684 --- /dev/null +++ b/Prim_manager.cs @@ -0,0 +1,310 @@ +/* +Copyright (c) 2007 Michael Wright + +* Copyright (c) , +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +using System; +using System.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; +using libsecondlife.AssetSystem; +using System.IO; +using Axiom.MathLib; + +namespace Second_server +{ + /// + /// Description of Prim_manager. + /// + public class Prim_manager + { + private Server server; + public Agent_Manager agent_man; + + private uint prim_count; + + public libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock object_template; + public Dictionary Prim_list; + public Prim_manager(Server serve) + { + server=serve; + Prim_list=new Dictionary (); + this.setuptemplates("objectupate164.dat"); + } + + + //********************************************************************* + public void create_prim(User_Agent_info User_info, libsecondlife.LLVector3 p1, ObjectAddPacket add_pack) + { + ObjectUpdatePacket objupdate=new ObjectUpdatePacket(); + objupdate.RegionData.RegionHandle=1096213093147648; + objupdate.RegionData.TimeDilation=64096; + objupdate.ObjectData=new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[1]; + + objupdate.ObjectData[0]=this.object_template; + objupdate.ObjectData[0].OwnerID=User_info.AgentID; + objupdate.ObjectData[0].PCode=add_pack.ObjectData.PCode; + objupdate.ObjectData[0].PathBegin=add_pack.ObjectData.PathBegin; + objupdate.ObjectData[0].PathEnd=add_pack.ObjectData.PathEnd; + objupdate.ObjectData[0].PathScaleX=add_pack.ObjectData.PathScaleX; + objupdate.ObjectData[0].PathScaleY=add_pack.ObjectData.PathScaleY; + objupdate.ObjectData[0].PathShearX=add_pack.ObjectData.PathShearX; + objupdate.ObjectData[0].PathShearY=add_pack.ObjectData.PathShearY; + objupdate.ObjectData[0].PathSkew=add_pack.ObjectData.PathSkew; + objupdate.ObjectData[0].ProfileBegin=add_pack.ObjectData.ProfileBegin; + objupdate.ObjectData[0].ProfileEnd=add_pack.ObjectData.ProfileEnd; + objupdate.ObjectData[0].Scale=add_pack.ObjectData.Scale;//new LLVector3(1,1,1); + objupdate.ObjectData[0].PathCurve=add_pack.ObjectData.PathCurve; + objupdate.ObjectData[0].ProfileCurve=add_pack.ObjectData.ProfileCurve; + objupdate.ObjectData[0].ParentID=0; + objupdate.ObjectData[0].ProfileHollow=add_pack.ObjectData.ProfileHollow; + //finish off copying rest of shape data + + objupdate.ObjectData[0].ID=(uint)(702000+prim_count); + objupdate.ObjectData[0].FullID=new LLUUID("edba7151-5857-acc5-b30b-f01efefda"+prim_count.ToString("000")); + + //update position + byte[] pb=p1.GetBytes(); + Array.Copy(pb,0,objupdate.ObjectData[0].ObjectData,0,pb.Length); + + prim_count++; + server.SendPacket(objupdate,true,User_info); + + //should send to all users + foreach (KeyValuePair kp in agent_man.Agent_list) + { + if(kp.Value.Net_info.AgentID!=User_info.AgentID) + { + server.SendPacket(objupdate,true,kp.Value.Net_info); + } + } + //should store this infomation + prim_info n_prim=new prim_info(); + n_prim.full_ID=objupdate.ObjectData[0].FullID; + n_prim.local_ID=objupdate.ObjectData[0].ID; + n_prim.pos=p1; + + this.Prim_list.Add(n_prim.full_ID,n_prim); + + //store rest of data + + } + public void update_prim_position(User_Agent_info user,float x, float y, float z,uint l_id) + { + prim_info pri=null; + foreach (KeyValuePair kp in this.Prim_list) + { + if(kp.Value.local_ID==l_id) + { + pri=kp.Value; + } + } + if(pri==null) + { + return; + } + uint ID=pri.local_ID; + byte[] bytes=new byte[60]; + + ImprovedTerseObjectUpdatePacket im=new ImprovedTerseObjectUpdatePacket(); + im.RegionData.RegionHandle=1096213093147648; + 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=object_template.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++]=0;//1; + + // i+=14; + // bytes[i++]=128; + // bytes[i++]=63; + byte[] pb=pos2.GetBytes(); + pri.pos=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); + + //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 agent_man.Agent_list) + { + if(kp.Value.Net_info.AgentID!=user.AgentID) + { + server.SendPacket(im,true,kp.Value.Net_info); + } + } + } + public void send_existing_prims(User_Agent_info user) + { + //send data for already created prims to a new joining user + } + //************************************************************** + public void setuptemplates(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; + this.object_template=objdata; + objdata.UpdateFlags=objdata.UpdateFlags+12-16+32+256; + objdata.OwnerID=new LLUUID("00000000-0000-0000-0000-000000000000"); + //test adding a new texture to object , to test image downloading + LLObject.TextureEntry te=new LLObject.TextureEntry(objdata.TextureEntry,0,objdata.TextureEntry.Length); + te.DefaultTexture.TextureID=new LLUUID("00000000-0000-0000-5005-000000000005"); + + LLObject.TextureEntry ntex=new LLObject.TextureEntry(new LLUUID("00000000-0000-0000-5005-000000000005")); + + objdata.TextureEntry=ntex.ToBytes(); + } + //******************************************************************** + public void Read_Prim_database(string name,User_Agent_info user) + { + 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=1096213093147648; + objupdate.RegionData.TimeDilation=64096; + objupdate.ObjectData=new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock[num]; + + // int count=0; + string data_path=System.Windows.Forms.Application.StartupPath + @"\data\"; + for(int cc=0; cc, +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + */ + +using System; +using System.Collections; +//using LuaInterface; +using libsecondlife; + +namespace Second_server +{ + /// + /// Description of Script_manager. + /// + public class Script_manager + { + //public LuaInterface.Lua Lu; + //private ArrayList scripts; + //private prim_info current_prim; + + public Script_manager() + { + } + + /*public void start_up (Lua lua, App ap) + { + this.Lu=lua; + //register any lua routines , like check finish script one + Lu.OpenMathLib(); + }*/ + public void script_register( script_object_interface script) + { + //called by scripts to register themselves + } + + public void Call_tick(prim_info prim) + { + //set current prim and then call tick function in linked script + } + public void Call_click(prim_info prim) + { + //set current prim and then call clicked function in linked script + + } + private void Register_functions() + { + //lu.RegisterFunction( "register_script",this,this.GetType().GetMethod("script_register")); + //lu.RegisterFunction( "Move_object",this,this.GetType().GetMethod("Move_object")); + + } + //Lua registered functions + public void Move_object(float x ,float y, float z) + { + + } + } + + public interface script_object_interface + { + void Frame_tick(); + void clicked(); + } +} diff --git a/Second-server.csproj b/Second-server.csproj new file mode 100644 index 0000000000..48236115cf --- /dev/null +++ b/Second-server.csproj @@ -0,0 +1,62 @@ + + + Exe + Second_server + Second-server + Debug + AnyCPU + {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E} + + + bin\Debug\ + False + DEBUG;TRACE + True + Full + True + + + bin\Release\ + True + TRACE + False + None + False + + + + + + + + + bin\Release\Axiom.MathLib.dll + False + + + bin\Release\libsecondlife.dll + False + + + + + + Main-sever.cs + + + Form + + + Main-sever.cs + + + + + + + + + + + + \ No newline at end of file diff --git a/Second-server.sln b/Second-server.sln new file mode 100644 index 0000000000..0106f610e4 --- /dev/null +++ b/Second-server.sln @@ -0,0 +1,17 @@ + +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|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Release|Any CPU.Build.0 = Release|Any CPU + {132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/Server.cs b/Server.cs new file mode 100644 index 0000000000..1917922046 --- /dev/null +++ b/Server.cs @@ -0,0 +1,756 @@ +/* + * * Copyright (c) , +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +using System; +using System.Collections.Generic; +using libsecondlife; +using System.Collections; +using libsecondlife.Packets; +using libsecondlife.AssetSystem; +using System.Net; +using System.Net.Sockets; +using System.Timers; + +//really hacked , messy code + +namespace Second_server +{ + /// + /// Description of Server. + /// + public interface Server_callback + { + void main_callback(Packet pack, User_Agent_info User_info); + void new_user(User_Agent_info User_info); + void error(string text); + } + public class Server + { + /// A public reference to the client that this Simulator object + /// is attached to + //public SecondLife Client; + + /// The Region class that this Simulator wraps + // public Region Region; + + /// + /// Used internally to track sim disconnections, do not modify this + /// variable + /// + public bool DisconnectCandidate = false; + + /// + /// The ID number associated with this particular connection to the + /// simulator, used to emulate TCP connections. This is used + /// internally for packets that have a CircuitCode field + /// + public uint CircuitCode + { + get { return circuitCode; } + set { circuitCode = value; } + } + + /// + /// The IP address and port of the server + /// + public IPEndPoint IPEndPoint + { + get { return ipEndPoint; } + } + + /// + /// A boolean representing whether there is a working connection to the + /// simulator or not + /// + public bool Connected + { + get { return connected; } + } + + private Server_callback callback_object; + //private NetworkManager Network; + // private Dictionary> Callbacks; + 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; + // Packets we sent out that need ACKs from the simulator + // private Dictionary NeedAck = new Dictionary(); + // Sequence numbers of packets we've received from the simulator + // private Queue Inbox; + // ACKs that are queued up to be sent to the simulator + //private Dictionary PendingAcks = new Dictionary(); + private bool connected = false; + private uint circuitCode; + private IPEndPoint ipEndPoint; + private EndPoint endPoint; + private IPEndPoint ipeSender; + private EndPoint epSender; + private System.Timers.Timer AckTimer; + private Server_Settings Settings=new Server_Settings(); + public ArrayList User_agents=new ArrayList(); + + /// + /// Constructor for Simulator + /// + /// + /// + /// + /// + /// + public Server(Server_callback s_callback) + { + + this.callback_object=s_callback; + // Client = client; + // Network = client.Network; + // Callbacks = callbacks; + // Region = new Region(client); + // circuitCode = circuit; + // Inbox = new Queue(Settings.INBOX_SIZE); + 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, 1000); + + + 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(); + + + + // Track the current time for timeout purposes + //int start = Environment.TickCount; + + /* while (true) + { + if (connected || Environment.TickCount - start > Settings.SIMULATOR_TIMEOUT) + { + return; + } + System.Threading.Thread.Sleep(10); + }*/ + } + catch (Exception e) + { + // Client.Log(e.ToString(), Helpers.LogLevel.Error); + System.Console.WriteLine(e.Message); + } + } + + /// + /// Disconnect a Simulator + /// + public void Disconnect() + { + if (connected) + { + connected = false; + AckTimer.Stop(); + + // Send the CloseCircuit notice + CloseCircuitPacket close = new CloseCircuitPacket(); + + if (Connection.Connected) + { + try + { + // Connection.Send(close.ToBytes()); + } + catch (SocketException) + { + // There's a high probability of this failing if the network is + // disconnecting, so don't even bother logging the error + } + } + + try + { + // Shut the socket communication down + // Connection.Shutdown(SocketShutdown.Both); + } + catch (SocketException) + { + } + } + } + + /// + /// Sends a packet + /// + /// Packet to be sent + /// Increment sequence number? + public void SendPacket(Packet packet, bool incrementSequence, User_Agent_info User_info) + { + byte[] buffer; + int bytes; + + if (!connected && packet.Type != PacketType.UseCircuitCode) + { + // Client.Log("Trying to send a " + packet.Type.ToString() + " packet when the socket is closed", + // Helpers.LogLevel.Info); + + return; + } + + if (packet.Header.AckList.Length > 0) + { + // Scrub any appended ACKs since all of the ACK handling is done here + packet.Header.AckList = new uint[0]; + } + packet.Header.AppendedAcks = false; + + // Keep track of when this packet was sent out + packet.TickCount = Environment.TickCount; + + if (incrementSequence) + { + // Set the sequence number + lock (SequenceLock) + { + if (Sequence > Settings.MAX_SEQUENCE) + Sequence = 1; + else + Sequence++; + packet.Header.Sequence = Sequence; + } + + if (packet.Header.Reliable) + { + lock (User_info.NeedAck) + { + if (!User_info.NeedAck.ContainsKey(packet.Header.Sequence)) + { + User_info.NeedAck.Add(packet.Header.Sequence, packet); + } + else + { + // Client.Log("Attempted to add a duplicate sequence number (" + + // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + + // packet.Type.ToString(), Helpers.LogLevel.Warning); + } + } + + // Don't append ACKs to resent packets, in case that's what was causing the + // delivery to fail + if (!packet.Header.Resent) + { + // Append any ACKs that need to be sent out to this packet + lock (User_info.PendingAcks) + { + if (User_info.PendingAcks.Count > 0 && User_info.PendingAcks.Count < Settings.MAX_APPENDED_ACKS && + packet.Type != PacketType.PacketAck && + packet.Type != PacketType.LogoutRequest) + { + packet.Header.AckList = new uint[User_info.PendingAcks.Count]; + + int i = 0; + + foreach (uint ack in User_info.PendingAcks.Values) + { + packet.Header.AckList[i] = ack; + i++; + } + + User_info.PendingAcks.Clear(); + packet.Header.AppendedAcks = true; + } + } + } + } + } + + // Serialize the packet + buffer = packet.ToBytes(); + bytes = buffer.Length; + + try + { + // Zerocode if needed + if (packet.Header.Zerocoded) + { + lock (ZeroOutBuffer) + { + bytes = Helpers.ZeroEncode(buffer, bytes, ZeroOutBuffer); + Connection.SendTo(ZeroOutBuffer, bytes, SocketFlags.None,User_info.endpoint); + } + } + else + { + + Connection.SendTo(buffer, bytes, SocketFlags.None,User_info.endpoint); + } + } + catch (SocketException) + { + //Client.Log("Tried to send a " + packet.Type.ToString() + " on a closed socket", + // Helpers.LogLevel.Warning); + + Disconnect(); + } + } + + /// + /// Send a raw byte array payload as a packet + /// + /// The packet payload + /// Whether the second, third, and fourth bytes + /// should be modified to the current stream sequence number + /* public void SendPacket(byte[] payload, bool setSequence) + { + if (connected) + { + try + { + if (setSequence && payload.Length > 3) + { + lock (SequenceLock) + { + payload[1] = (byte)(Sequence >> 16); + payload[2] = (byte)(Sequence >> 8); + payload[3] = (byte)(Sequence % 256); + Sequence++; + } + } + + Connection.Send(payload, payload.Length, SocketFlags.None); + } + catch (SocketException e) + { + // Client.Log(e.ToString(), Helpers.LogLevel.Error); + } + } + else + { + // Client.Log("Attempted to send a " + payload.Length + " byte payload when " + + // "we are disconnected", Helpers.LogLevel.Warning); + } + } + */ + /// + /// Returns Simulator Name as a String + /// + /// + public override string ToString() + { + return( " (" + ipEndPoint.ToString() + ")"); + } + + /// + /// Sends out pending acknowledgements + /// + private void SendAcks(User_Agent_info User_info) + { + lock (User_info.PendingAcks) + { + if (connected && User_info.PendingAcks.Count > 0) + { + if (User_info.PendingAcks.Count > 250) + { + // FIXME: Handle the odd case where we have too many pending ACKs queued up + //Client.Log("Too many ACKs queued up!", Helpers.LogLevel.Error); + return; + } + + int i = 0; + PacketAckPacket acks = new PacketAckPacket(); + acks.Packets = new PacketAckPacket.PacketsBlock[User_info.PendingAcks.Count]; + + foreach (uint ack in User_info.PendingAcks.Values) + { + acks.Packets[i] = new PacketAckPacket.PacketsBlock(); + acks.Packets[i].ID = ack; + i++; + } + + acks.Header.Reliable = false; + SendPacket(acks, true,User_info); + + User_info.PendingAcks.Clear(); + } + } + } + /// + /// Resend unacknowledged packets + /// + private void ResendUnacked(User_Agent_info User_info) + { + if (connected) + { + int now = Environment.TickCount; + + lock (User_info.NeedAck) + { + foreach (Packet packet in User_info.NeedAck.Values) + { + if (now - packet.TickCount > Settings.RESEND_TIMEOUT) + { + // Client.Log("Resending " + packet.Type.ToString() + " packet, " + + // (now - packet.TickCount) + "ms have passed", Helpers.LogLevel.Info); + + packet.Header.Resent = true; + SendPacket(packet, false,User_info); + } + } + } + } + } + /// + /// Callback handler for incomming data + /// + /// + private void OnReceivedData(IAsyncResult result) + { + + ipeSender = new IPEndPoint(IPAddress.Any, 0); + epSender = (EndPoint)ipeSender; + Packet packet = null; + int numBytes; + + // 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; + User_Agent_info 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); + + + //should check if login/useconnection packet first + if (packet.Type == PacketType.UseCircuitCode) + { + UseCircuitCodePacket cir_pack=(UseCircuitCodePacket)packet; + User_Agent_info new_user=new User_Agent_info(); + new_user.circuitCode=cir_pack.CircuitCode.Code; + new_user.AgentID=cir_pack.CircuitCode.ID; + new_user.SessionID=cir_pack.CircuitCode.SessionID; + new_user.endpoint=epSender; + new_user.Inbox = new Queue(Settings.INBOX_SIZE); + + this.callback_object.new_user(new_user); + this.User_agents.Add(new_user); + + } + + + User_Agent_info temp_agent=null; + IPEndPoint send_ip=(IPEndPoint)epSender; + // this.callback_object.error("incoming: address is "+send_ip.Address +"port number is: "+send_ip.Port.ToString()); + + for(int ii=0; ii Settings.MAX_PENDING_ACKS) + { + SendAcks(User_info); + } + + // Check if we already received this packet + if (User_info.Inbox.Contains(packet.Header.Sequence)) + { + //Client.Log("Received a duplicate " + packet.Type.ToString() + ", sequence=" + + // packet.Header.Sequence + ", resent=" + ((packet.Header.Resent) ? "Yes" : "No") + + // ", Inbox.Count=" + Inbox.Count + ", NeedAck.Count=" + NeedAck.Count, + // Helpers.LogLevel.Info); + + // Send an ACK for this packet immediately + //SendAck(packet.Header.Sequence); + + // 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.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.callback_object.error("calling callback"); + this.callback_object.main_callback(packet,User_info); + // this.callback_object.error("finished"); + // Fire the registered packet events + #region FireCallbacks + /* if (Callbacks.ContainsKey(packet.Type)) + { + List callbackArray = Callbacks[packet.Type]; + + // Fire any registered callbacks + foreach (NetworkManager.PacketCallback callback in callbackArray) + { + if (callback != null) + { + try + { + callback(packet, this); + } + catch (Exception e) + { + Client.Log("Caught an exception in a packet callback: " + e.ToString(), + Helpers.LogLevel.Error); + } + } + } + } + + if (Callbacks.ContainsKey(PacketType.Default)) + { + List callbackArray = Callbacks[PacketType.Default]; + + // Fire any registered callbacks + foreach (NetworkManager.PacketCallback callback in callbackArray) + { + if (callback != null) + { + try + { + callback(packet, this); + } + catch (Exception e) + { + Client.Log("Caught an exception in a packet callback: " + e.ToString(), + Helpers.LogLevel.Error); + } + } + } + } + */ + #endregion FireCallbacks + } + + private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) + { + if (connected) + { + + //TODO for each user_agent_info + for(int i=0; iThe version of libsecondlife (not the SL protocol itself) + public string VERSION = "libsecondlife 0.0.9"; + /// XML-RPC login server to connect to + public string LOGIN_SERVER = "https://login.agni.lindenlab.com/cgi-bin/login.cgi"; + + /// Millisecond interval between ticks, where all ACKs are + /// sent out and the age of unACKed packets is checked + public readonly int NETWORK_TICK_LENGTH = 500; + /// The maximum value of a packet sequence number. After that + /// we assume the sequence number just rolls over? Or maybe the + /// protocol isn't able to sustain a connection past that + public readonly int MAX_SEQUENCE = 0xFFFFFF; + /// Number of milliseconds before a teleport attempt will time + /// out + public readonly int TELEPORT_TIMEOUT = 18 * 1000; + + /// Number of milliseconds before NetworkManager.Logout() will time out + public int LOGOUT_TIMEOUT = 5 * 1000; + /// Number of milliseconds for xml-rpc to timeout + public int LOGIN_TIMEOUT = 30 * 1000; + /// The maximum size of the sequence number inbox, used to + /// check for resent and/or duplicate packets + public int INBOX_SIZE = 100; + /// Milliseconds before a packet is assumed lost and resent + public int RESEND_TIMEOUT = 4000; + /// Milliseconds before the connection to a simulator is + /// assumed lost + public int SIMULATOR_TIMEOUT = 15000; + /// Maximum number of queued ACKs to be sent before SendAcks() + /// is forced + public int MAX_PENDING_ACKS = 10; + /// Maximum number of ACKs to append to a packet + public int MAX_APPENDED_ACKS = 10; + /// Cost of uploading an asset + public int UPLOAD_COST { get { return priceUpload; } } + + + private int priceUpload = 0; + + public Server_Settings() + { + + } + } + + public class User_Agent_info + { + public EndPoint endpoint; + public LLUUID AgentID; + public LLUUID SessionID; + public uint circuitCode; + public string name; + public uint localID; + public string first_name; + public string last_name; + + public Dictionary NeedAck = new Dictionary(); + // Sequence numbers of packets we've received from the simulator + public Queue Inbox; + // ACKs that are queued up to be sent to the simulator + public Dictionary PendingAcks = new Dictionary(); + + public User_Agent_info() + { + + } + } + +} diff --git a/Texture_manager.cs b/Texture_manager.cs new file mode 100644 index 0000000000..990557ee6d --- /dev/null +++ b/Texture_manager.cs @@ -0,0 +1,219 @@ +/* +Copyright (c) 2007 Michael Wright + +* Copyright (c) , +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +using System; +using System.Collections.Generic; +using libsecondlife; +using System.Collections; +using libsecondlife.Packets; +using libsecondlife.AssetSystem; +using System.IO; + + +namespace Second_server +{ + /// + /// Description of Texture_manager. + /// + public class Texture_manager + { + public Dictionary textures; + public ArrayList requests=new ArrayList(); //should change to a generic + public ArrayList uploads=new ArrayList(); + private Server server; + + public Texture_manager(Server serve) + { + server=serve; + textures=new Dictionary (); + this.initialise(); + } + + public void add_request(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; + } + Texture_image imag=this.textures[image_id]; + Texture_request req=new Texture_request(); + req.req_user=user; + req.req_image=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 add_texture(LLUUID image_id, string name, byte[] data) + { + + } + public void Do_work(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; + } + Texture_request req; + for(int i=0; i