Making trunk; applying appropriate license to each file
commit
a829506728
|
@ -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 <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using libsecondlife;
|
||||||
|
using libsecondlife.Packets;
|
||||||
|
using libsecondlife.AssetSystem;
|
||||||
|
using System.IO;
|
||||||
|
using Axiom.MathLib;
|
||||||
|
|
||||||
|
namespace Second_server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Description of Agent_Manager.
|
||||||
|
/// </summary>
|
||||||
|
public class Agent_Manager
|
||||||
|
{
|
||||||
|
public Dictionary<libsecondlife.LLUUID,Avatar_data> 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<libsecondlife.LLUUID,Avatar_data>();
|
||||||
|
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<libsecondlife.LLUUID,Avatar_data> 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<libsecondlife.LLUUID,Avatar_data> 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<libsecondlife.LLUUID,Avatar_data> 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<libsecondlife.LLUUID,Avatar_data> 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<libsecondlife.LLUUID,Avatar_data> 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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) <year>, <copyright holder>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.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.*")]
|
|
@ -0,0 +1,167 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Michael Wright
|
||||||
|
|
||||||
|
* Copyright (c) <year>, <copyright holder>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using libsecondlife;
|
||||||
|
using System.Collections;
|
||||||
|
using libsecondlife.Packets;
|
||||||
|
using libsecondlife.AssetSystem;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Second_server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Description of Asset_manager.
|
||||||
|
/// </summary>
|
||||||
|
public class Asset_manager
|
||||||
|
{
|
||||||
|
public Dictionary<libsecondlife.LLUUID,Asset_info> 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<libsecondlife.LLUUID,Asset_info> ();
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Description of Class1.
|
||||||
|
/// </summary>
|
||||||
|
public class Class1
|
||||||
|
{
|
||||||
|
public Class1()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,163 @@
|
||||||
|
/*Copyright (c) 2007 Michael Wright
|
||||||
|
|
||||||
|
* Copyright (c) <year>, <copyright holder>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Second_server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Description of Login_manager.
|
||||||
|
/// </summary>
|
||||||
|
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="<member><name>session_id</name><value><string>99998888-"+ran.ToString("0000")+"-4f52-8ec1-0b1d5cd6aead</string></value></member>";
|
||||||
|
writer.WriteLine(lines);
|
||||||
|
lines=SR.ReadLine();
|
||||||
|
writer.WriteLine(lines);
|
||||||
|
lines=SR.ReadLine();
|
||||||
|
ran=this.RandomClass.Next(1,9999);
|
||||||
|
lines="<member><name>agent_id</name><value><string>aaaabbbb-8932-"+ran.ToString("0000")+"-8664-58f53e442797</string></value></member>";
|
||||||
|
writer.WriteLine(lines);
|
||||||
|
lines=SR.ReadLine();
|
||||||
|
|
||||||
|
while(lines!="end-mfile")
|
||||||
|
{
|
||||||
|
writer.WriteLine(lines);
|
||||||
|
lines=SR.ReadLine();
|
||||||
|
}
|
||||||
|
SR.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Designer variable used to keep track of non-visual components.
|
||||||
|
/// </summary>
|
||||||
|
private System.ComponentModel.IContainer components = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disposes resources used by the form.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing) {
|
||||||
|
if (components != null) {
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 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.
|
||||||
|
/// </summary>
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,270 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Michael Wright
|
||||||
|
|
||||||
|
* Copyright (c) <year>, <copyright holder>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Description of MainForm.
|
||||||
|
/// </summary>
|
||||||
|
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<image_req.RequestImage.Length ;i++)
|
||||||
|
{
|
||||||
|
this.texture_man.add_request(User_info,image_req.RequestImage[i].Image);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pack.Type==PacketType.RegionHandshakeReply)
|
||||||
|
{
|
||||||
|
//recieved regionhandshake so can now start sending info
|
||||||
|
agent_man.send_intial_data(User_info);
|
||||||
|
//this.setuptemplates("objectupate164.dat",User_info,false);
|
||||||
|
}
|
||||||
|
if(pack.Type== PacketType.ObjectAdd)
|
||||||
|
{
|
||||||
|
ObjectAddPacket ad=(ObjectAddPacket)pack;
|
||||||
|
prim_man.create_prim(User_info,ad.ObjectData.RayEnd, ad);
|
||||||
|
//this.send_prim(User_info,ad.ObjectData.RayEnd, ad);
|
||||||
|
}
|
||||||
|
if(pack.Type== PacketType.ObjectPosition)
|
||||||
|
{
|
||||||
|
//System.Console.WriteLine(pack.ToString());
|
||||||
|
}
|
||||||
|
if(pack.Type== PacketType.MultipleObjectUpdate)
|
||||||
|
{
|
||||||
|
//System.Console.WriteLine(pack.ToString());
|
||||||
|
MultipleObjectUpdatePacket mupd=(MultipleObjectUpdatePacket)pack;
|
||||||
|
|
||||||
|
for(int i=0; i<mupd.ObjectData.Length; i++)
|
||||||
|
{
|
||||||
|
if(mupd.ObjectData[i].Type==9) //change position
|
||||||
|
{
|
||||||
|
libsecondlife.LLVector3 pos=new LLVector3(mupd.ObjectData[i].Data, 0);
|
||||||
|
|
||||||
|
prim_man.update_prim_position(User_info, pos.X,pos.Y,pos.Z,mupd.ObjectData[i].ObjectLocalID);
|
||||||
|
//should update stored position of the prim
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(pack.Type== PacketType.AgentWearablesRequest)
|
||||||
|
{
|
||||||
|
agent_man.send_intial_avatar_apper(User_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pack.Type==PacketType.AgentUpdate)
|
||||||
|
{
|
||||||
|
AgentUpdatePacket ag=(AgentUpdatePacket)pack;
|
||||||
|
uint mask=ag.AgentData.ControlFlags&(1);
|
||||||
|
Avatar_data m_av=agent_man.Get_Agent(User_info.AgentID);
|
||||||
|
if(m_av!=null)
|
||||||
|
{
|
||||||
|
if(m_av.started)
|
||||||
|
{
|
||||||
|
if(mask==(1))
|
||||||
|
{
|
||||||
|
if(!m_av.walk)
|
||||||
|
{
|
||||||
|
//start walking
|
||||||
|
agent_man.send_move_command(User_info,false,m_av.pos.X,m_av.pos.Y,m_av.pos.Z,0,ag.AgentData.BodyRotation);
|
||||||
|
Axiom.MathLib.Vector3 v3=new Axiom.MathLib.Vector3(1,0,0);
|
||||||
|
Axiom.MathLib.Quaternion q=new Axiom.MathLib.Quaternion(ag.AgentData.BodyRotation.W,ag.AgentData.BodyRotation.X,ag.AgentData.BodyRotation.Y,ag.AgentData.BodyRotation.Z);
|
||||||
|
Axiom.MathLib.Vector3 direc=q*v3;
|
||||||
|
direc.Normalize();
|
||||||
|
direc=direc*((0.03f)*128f);
|
||||||
|
|
||||||
|
m_av.vel.X=direc.x;
|
||||||
|
m_av.vel.Y=direc.y;
|
||||||
|
m_av.vel.Z=direc.z;
|
||||||
|
m_av.walk=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if(m_av.walk)
|
||||||
|
{
|
||||||
|
//walking but key not pressed so need to stop
|
||||||
|
agent_man.send_move_command(User_info,true,m_av.pos.X,m_av.pos.Y,m_av.pos.Z,0,ag.AgentData.BodyRotation);
|
||||||
|
m_av.walk=false;
|
||||||
|
m_av.vel.X=0;
|
||||||
|
m_av.vel.Y=0;
|
||||||
|
m_av.vel.Z=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pack.Type==PacketType.ChatFromViewer)
|
||||||
|
{
|
||||||
|
ChatFromViewerPacket chat=(ChatFromViewerPacket)pack;
|
||||||
|
System.Text.Encoding enc = System.Text.Encoding.ASCII;
|
||||||
|
|
||||||
|
string myString = enc.GetString(chat.ChatData.Message );
|
||||||
|
if(myString!="")
|
||||||
|
{
|
||||||
|
string [] comp= new string[10];
|
||||||
|
string delimStr = " , ";
|
||||||
|
char [] delimiter = delimStr.ToCharArray();
|
||||||
|
string line;
|
||||||
|
|
||||||
|
line=myString;
|
||||||
|
comp=line.Split(delimiter);
|
||||||
|
if(comp[0]=="pos")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if(comp[0]=="veloc")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
agent_man.send_chat_message(User_info,line);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void new_user(User_Agent_info User_info)
|
||||||
|
{
|
||||||
|
this.richTextBox1.Text=this.richTextBox1.Text+"\n "+"new user - "+User_info.AgentID.ToString()+" - has joined";
|
||||||
|
this.richTextBox1.Text=this.richTextBox1.Text+"\n "+"session id := "+User_info.SessionID.ToString();
|
||||||
|
agent_man.New_Agent(User_info);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void error(string text)
|
||||||
|
{
|
||||||
|
this.richTextBox1.Text=this.richTextBox1.Text+"\n error report: "+text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Timer1Tick(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
this.time++;
|
||||||
|
agent_man.tick();
|
||||||
|
texture_man.Do_work(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,123 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<metadata name="timer1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>17, 17</value>
|
||||||
|
</metadata>
|
||||||
|
</root>
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Michael Wright
|
||||||
|
|
||||||
|
* Copyright (c) <year>, <copyright holder>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Second_server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Description of Physics_manager.
|
||||||
|
/// </summary>
|
||||||
|
public class Physics_manager
|
||||||
|
{
|
||||||
|
public Physics_manager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,310 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Michael Wright
|
||||||
|
|
||||||
|
* Copyright (c) <year>, <copyright holder>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using libsecondlife;
|
||||||
|
using libsecondlife.Packets;
|
||||||
|
using libsecondlife.AssetSystem;
|
||||||
|
using System.IO;
|
||||||
|
using Axiom.MathLib;
|
||||||
|
|
||||||
|
namespace Second_server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Description of Prim_manager.
|
||||||
|
/// </summary>
|
||||||
|
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<libsecondlife.LLUUID,prim_info> Prim_list;
|
||||||
|
public Prim_manager(Server serve)
|
||||||
|
{
|
||||||
|
server=serve;
|
||||||
|
Prim_list=new Dictionary<libsecondlife.LLUUID,prim_info> ();
|
||||||
|
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<libsecondlife.LLUUID,Avatar_data> 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<libsecondlife.LLUUID,prim_info> 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<libsecondlife.LLUUID,Avatar_data> 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<num; cc++)
|
||||||
|
{
|
||||||
|
string filenam=data_path+@"prim_updates"+start+".dat";
|
||||||
|
int i=0;
|
||||||
|
//FileInfo fInfo = new FileInfo("objectupate"+start+".dat");
|
||||||
|
FileInfo fInfo = new FileInfo(filenam);
|
||||||
|
long numBytes = fInfo.Length;
|
||||||
|
//FileStream fStream = new FileStream("objectupate"+start+".dat", FileMode.Open, FileAccess.Read);
|
||||||
|
FileStream fStream = new FileStream(filenam, FileMode.Open, FileAccess.Read);
|
||||||
|
BinaryReader br = new BinaryReader(fStream);
|
||||||
|
byte [] data1 = br.ReadBytes((int)numBytes);
|
||||||
|
br.Close();
|
||||||
|
fStream.Close();
|
||||||
|
|
||||||
|
libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock objdata=new libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock(data1,ref i);
|
||||||
|
objupdate.ObjectData[cc]=objdata;
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
server.SendPacket(objupdate,true,user);
|
||||||
|
line=SR.ReadLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SR.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class prim_info
|
||||||
|
{
|
||||||
|
public LLVector3 pos;
|
||||||
|
public LLVector3 vel;
|
||||||
|
public uint local_ID;
|
||||||
|
public LLUUID full_ID;
|
||||||
|
public prim_data data;
|
||||||
|
|
||||||
|
public prim_info()
|
||||||
|
{
|
||||||
|
pos=new LLVector3(0,0,0);
|
||||||
|
vel=new LLVector3(0,0,0);
|
||||||
|
data=new prim_data();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class prim_data
|
||||||
|
{
|
||||||
|
public prim_data()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007 Michael Wright
|
||||||
|
|
||||||
|
* Copyright (c) <year>, <copyright holder>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
//using LuaInterface;
|
||||||
|
using libsecondlife;
|
||||||
|
|
||||||
|
namespace Second_server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Description of Script_manager.
|
||||||
|
/// </summary>
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<RootNamespace>Second_server</RootNamespace>
|
||||||
|
<AssemblyName>Second-server</AssemblyName>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{132A6E3E-8F2D-4BF5-BDFB-8555F53F334E}</ProjectGuid>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<Optimize>False</Optimize>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugSymbols>True</DebugSymbols>
|
||||||
|
<DebugType>Full</DebugType>
|
||||||
|
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<Optimize>True</Optimize>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<DebugSymbols>False</DebugSymbols>
|
||||||
|
<DebugType>None</DebugType>
|
||||||
|
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="Axiom.MathLib">
|
||||||
|
<HintPath>bin\Release\Axiom.MathLib.dll</HintPath>
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="libsecondlife">
|
||||||
|
<HintPath>bin\Release\libsecondlife.dll</HintPath>
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Main-sever.Designer.cs">
|
||||||
|
<DependentUpon>Main-sever.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Main-sever.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<EmbeddedResource Include="Main-sever.resx">
|
||||||
|
<DependentUpon>Main-sever.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<Compile Include="Agent_Manager.cs" />
|
||||||
|
<Compile Include="Prim_manager.cs" />
|
||||||
|
<Compile Include="Texture_manager.cs" />
|
||||||
|
<Compile Include="Login_manager.cs" />
|
||||||
|
<Compile Include="Physics_manager.cs" />
|
||||||
|
<Compile Include="Asset_manager.cs" />
|
||||||
|
<Compile Include="Script_manager.cs" />
|
||||||
|
<Compile Include="Server.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
|
||||||
|
</Project>
|
|
@ -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
|
|
@ -0,0 +1,756 @@
|
||||||
|
/*
|
||||||
|
* * Copyright (c) <year>, <copyright holder>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using libsecondlife;
|
||||||
|
using System.Collections;
|
||||||
|
using libsecondlife.Packets;
|
||||||
|
using libsecondlife.AssetSystem;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
//really hacked , messy code
|
||||||
|
|
||||||
|
namespace Second_server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Description of Server.
|
||||||
|
/// </summary>
|
||||||
|
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
|
||||||
|
{
|
||||||
|
/// <summary>A public reference to the client that this Simulator object
|
||||||
|
/// is attached to</summary>
|
||||||
|
//public SecondLife Client;
|
||||||
|
|
||||||
|
/// <summary>The Region class that this Simulator wraps</summary>
|
||||||
|
// public Region Region;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used internally to track sim disconnections, do not modify this
|
||||||
|
/// variable
|
||||||
|
/// </summary>
|
||||||
|
public bool DisconnectCandidate = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The ID number associated with this particular connection to the
|
||||||
|
/// simulator, used to emulate TCP connections. This is used
|
||||||
|
/// internally for packets that have a CircuitCode field
|
||||||
|
/// </summary>
|
||||||
|
public uint CircuitCode
|
||||||
|
{
|
||||||
|
get { return circuitCode; }
|
||||||
|
set { circuitCode = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The IP address and port of the server
|
||||||
|
/// </summary>
|
||||||
|
public IPEndPoint IPEndPoint
|
||||||
|
{
|
||||||
|
get { return ipEndPoint; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A boolean representing whether there is a working connection to the
|
||||||
|
/// simulator or not
|
||||||
|
/// </summary>
|
||||||
|
public bool Connected
|
||||||
|
{
|
||||||
|
get { return connected; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private Server_callback callback_object;
|
||||||
|
//private NetworkManager Network;
|
||||||
|
// private Dictionary<PacketType, List<NetworkManager.PacketCallback>> 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<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
|
||||||
|
// Sequence numbers of packets we've received from the simulator
|
||||||
|
// private Queue<uint> Inbox;
|
||||||
|
// ACKs that are queued up to be sent to the simulator
|
||||||
|
//private Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
|
||||||
|
private bool connected = false;
|
||||||
|
private uint circuitCode;
|
||||||
|
private IPEndPoint ipEndPoint;
|
||||||
|
private EndPoint endPoint;
|
||||||
|
private IPEndPoint ipeSender;
|
||||||
|
private EndPoint epSender;
|
||||||
|
private System.Timers.Timer AckTimer;
|
||||||
|
private Server_Settings Settings=new Server_Settings();
|
||||||
|
public ArrayList User_agents=new ArrayList();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor for Simulator
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client"></param>
|
||||||
|
/// <param name="callbacks"></param>
|
||||||
|
/// <param name="circuit"></param>
|
||||||
|
/// <param name="ip"></param>
|
||||||
|
/// <param name="port"></param>
|
||||||
|
public Server(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<uint>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disconnect a Simulator
|
||||||
|
/// </summary>
|
||||||
|
public void Disconnect()
|
||||||
|
{
|
||||||
|
if (connected)
|
||||||
|
{
|
||||||
|
connected = false;
|
||||||
|
AckTimer.Stop();
|
||||||
|
|
||||||
|
// Send the CloseCircuit notice
|
||||||
|
CloseCircuitPacket close = new CloseCircuitPacket();
|
||||||
|
|
||||||
|
if (Connection.Connected)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Connection.Send(close.ToBytes());
|
||||||
|
}
|
||||||
|
catch (SocketException)
|
||||||
|
{
|
||||||
|
// There's a high probability of this failing if the network is
|
||||||
|
// disconnecting, so don't even bother logging the error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Shut the socket communication down
|
||||||
|
// Connection.Shutdown(SocketShutdown.Both);
|
||||||
|
}
|
||||||
|
catch (SocketException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends a packet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="packet">Packet to be sent</param>
|
||||||
|
/// <param name="incrementSequence">Increment sequence number?</param>
|
||||||
|
public void SendPacket(Packet packet, bool incrementSequence, 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Send a raw byte array payload as a packet
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="payload">The packet payload</param>
|
||||||
|
/// <param name="setSequence">Whether the second, third, and fourth bytes
|
||||||
|
/// should be modified to the current stream sequence number</param>
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/// <summary>
|
||||||
|
/// Returns Simulator Name as a String
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return( " (" + ipEndPoint.ToString() + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sends out pending acknowledgements
|
||||||
|
/// </summary>
|
||||||
|
private void SendAcks(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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Resend unacknowledged packets
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Callback handler for incomming data
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="result"></param>
|
||||||
|
private void OnReceivedData(IAsyncResult result)
|
||||||
|
{
|
||||||
|
|
||||||
|
ipeSender = new IPEndPoint(IPAddress.Any, 0);
|
||||||
|
epSender = (EndPoint)ipeSender;
|
||||||
|
Packet packet = null;
|
||||||
|
int numBytes;
|
||||||
|
|
||||||
|
// 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<uint>(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<this.User_agents.Count ; ii++)
|
||||||
|
{
|
||||||
|
temp_agent=(User_Agent_info)this.User_agents[ii];
|
||||||
|
IPEndPoint ag_ip=(IPEndPoint)temp_agent.endpoint;
|
||||||
|
//this.callback_object.error("searching: address is "+ag_ip.Address +"port number is: "+ag_ip.Port.ToString());
|
||||||
|
|
||||||
|
if((ag_ip.Address.ToString()==send_ip.Address.ToString()) && (ag_ip.Port.ToString()==send_ip.Port.ToString()))
|
||||||
|
{
|
||||||
|
//this.callback_object.error("found user");
|
||||||
|
User_info=temp_agent;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection.BeginReceiveFrom(RecvBuffer, 0, RecvBuffer.Length, SocketFlags.None, ref epSender, ReceivedData, null);
|
||||||
|
}
|
||||||
|
catch (SocketException)
|
||||||
|
{
|
||||||
|
// Client.Log(endPoint.ToString() + " socket is closed, shutting down " + this.Region.Name,
|
||||||
|
// Helpers.LogLevel.Info);
|
||||||
|
|
||||||
|
connected = false;
|
||||||
|
//Network.DisconnectSim(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(User_info==null)
|
||||||
|
{
|
||||||
|
|
||||||
|
//error finding agent
|
||||||
|
this.callback_object.error("no user found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fail-safe check
|
||||||
|
if (packet == null)
|
||||||
|
{
|
||||||
|
this.callback_object.error("couldn't build packet");
|
||||||
|
// Client.Log("Couldn't build a message from the incoming data", Helpers.LogLevel.Warning);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//this.callback_object.error("past tests");
|
||||||
|
// Track the sequence number for this packet if it's marked as reliable
|
||||||
|
if (packet.Header.Reliable)
|
||||||
|
{
|
||||||
|
if (User_info.PendingAcks.Count > Settings.MAX_PENDING_ACKS)
|
||||||
|
{
|
||||||
|
SendAcks(User_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we already received this packet
|
||||||
|
if (User_info.Inbox.Contains(packet.Header.Sequence))
|
||||||
|
{
|
||||||
|
//Client.Log("Received a duplicate " + packet.Type.ToString() + ", sequence=" +
|
||||||
|
// packet.Header.Sequence + ", resent=" + ((packet.Header.Resent) ? "Yes" : "No") +
|
||||||
|
// ", Inbox.Count=" + Inbox.Count + ", NeedAck.Count=" + NeedAck.Count,
|
||||||
|
// Helpers.LogLevel.Info);
|
||||||
|
|
||||||
|
// Send an ACK for this packet immediately
|
||||||
|
//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<NetworkManager.PacketCallback> 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<NetworkManager.PacketCallback> 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; i<this.User_agents.Count; i++)
|
||||||
|
{
|
||||||
|
User_Agent_info user=(User_Agent_info)this.User_agents[i];
|
||||||
|
|
||||||
|
SendAcks(user);
|
||||||
|
ResendUnacked(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Server_Settings
|
||||||
|
{
|
||||||
|
/// <summary>The version of libsecondlife (not the SL protocol itself)</summary>
|
||||||
|
public string VERSION = "libsecondlife 0.0.9";
|
||||||
|
/// <summary>XML-RPC login server to connect to</summary>
|
||||||
|
public string LOGIN_SERVER = "https://login.agni.lindenlab.com/cgi-bin/login.cgi";
|
||||||
|
|
||||||
|
/// <summary>Millisecond interval between ticks, where all ACKs are
|
||||||
|
/// sent out and the age of unACKed packets is checked</summary>
|
||||||
|
public readonly int NETWORK_TICK_LENGTH = 500;
|
||||||
|
/// <summary>The maximum value of a packet sequence number. After that
|
||||||
|
/// we assume the sequence number just rolls over? Or maybe the
|
||||||
|
/// protocol isn't able to sustain a connection past that</summary>
|
||||||
|
public readonly int MAX_SEQUENCE = 0xFFFFFF;
|
||||||
|
/// <summary>Number of milliseconds before a teleport attempt will time
|
||||||
|
/// out</summary>
|
||||||
|
public readonly int TELEPORT_TIMEOUT = 18 * 1000;
|
||||||
|
|
||||||
|
/// <summary>Number of milliseconds before NetworkManager.Logout() will time out</summary>
|
||||||
|
public int LOGOUT_TIMEOUT = 5 * 1000;
|
||||||
|
/// <summary>Number of milliseconds for xml-rpc to timeout</summary>
|
||||||
|
public int LOGIN_TIMEOUT = 30 * 1000;
|
||||||
|
/// <summary>The maximum size of the sequence number inbox, used to
|
||||||
|
/// check for resent and/or duplicate packets</summary>
|
||||||
|
public int INBOX_SIZE = 100;
|
||||||
|
/// <summary>Milliseconds before a packet is assumed lost and resent</summary>
|
||||||
|
public int RESEND_TIMEOUT = 4000;
|
||||||
|
/// <summary>Milliseconds before the connection to a simulator is
|
||||||
|
/// assumed lost</summary>
|
||||||
|
public int SIMULATOR_TIMEOUT = 15000;
|
||||||
|
/// <summary>Maximum number of queued ACKs to be sent before SendAcks()
|
||||||
|
/// is forced</summary>
|
||||||
|
public int MAX_PENDING_ACKS = 10;
|
||||||
|
/// <summary>Maximum number of ACKs to append to a packet</summary>
|
||||||
|
public int MAX_APPENDED_ACKS = 10;
|
||||||
|
/// <summary>Cost of uploading an asset</summary>
|
||||||
|
public int UPLOAD_COST { get { return priceUpload; } }
|
||||||
|
|
||||||
|
|
||||||
|
private int priceUpload = 0;
|
||||||
|
|
||||||
|
public Server_Settings()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class 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<uint, Packet> NeedAck = new Dictionary<uint, Packet>();
|
||||||
|
// Sequence numbers of packets we've received from the simulator
|
||||||
|
public Queue<uint> Inbox;
|
||||||
|
// ACKs that are queued up to be sent to the simulator
|
||||||
|
public Dictionary<uint, uint> PendingAcks = new Dictionary<uint, uint>();
|
||||||
|
|
||||||
|
public User_Agent_info()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,219 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2007 Michael Wright
|
||||||
|
|
||||||
|
* Copyright (c) <year>, <copyright holder>
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the <organization> nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using libsecondlife;
|
||||||
|
using System.Collections;
|
||||||
|
using libsecondlife.Packets;
|
||||||
|
using libsecondlife.AssetSystem;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
|
||||||
|
namespace Second_server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Description of Texture_manager.
|
||||||
|
/// </summary>
|
||||||
|
public class Texture_manager
|
||||||
|
{
|
||||||
|
public Dictionary<libsecondlife.LLUUID,Texture_image> 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<libsecondlife.LLUUID,Texture_image> ();
|
||||||
|
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<num; i++)
|
||||||
|
{
|
||||||
|
req=(Texture_request)this.requests[i];
|
||||||
|
|
||||||
|
if(req.packet_counter==0)
|
||||||
|
{
|
||||||
|
//first time for this request so send imagedata packet
|
||||||
|
if(req.num_packets==1)
|
||||||
|
{
|
||||||
|
//only one packet so send whole file
|
||||||
|
ImageDataPacket im=new ImageDataPacket();
|
||||||
|
im.ImageID.Packets=1;
|
||||||
|
im.ImageID.ID=req.image_info.Full_ID;
|
||||||
|
im.ImageID.Size=(uint)req.image_info.data.Length;
|
||||||
|
im.ImageData.Data=req.image_info.data;
|
||||||
|
im.ImageID.Codec=2;
|
||||||
|
server.SendPacket(im,true,req.req_user);
|
||||||
|
req.packet_counter++;
|
||||||
|
req.image_info.last_used=time;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//more than one packet so split file up
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//send imagepacket
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//remove requests that have been completed
|
||||||
|
for(int i=0; i<num; i++)
|
||||||
|
{
|
||||||
|
req=(Texture_request)this.requests[i];
|
||||||
|
if(req.packet_counter==req.num_packets)
|
||||||
|
{
|
||||||
|
this.requests.Remove(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void recieve_texture(Packet pack)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialise()
|
||||||
|
{
|
||||||
|
//for now read in our test image
|
||||||
|
Texture_image im=new Texture_image();
|
||||||
|
im.filename="testpic2.jp2";
|
||||||
|
im.Full_ID=new LLUUID("00000000-0000-0000-5005-000000000005");
|
||||||
|
this.load_image(im);
|
||||||
|
this.textures.Add(im.Full_ID,im);
|
||||||
|
}
|
||||||
|
private void load_image(Texture_image im)
|
||||||
|
{
|
||||||
|
string data_path=System.Windows.Forms.Application.StartupPath + @"\textures\";
|
||||||
|
string filename=data_path+@im.filename;
|
||||||
|
FileInfo fInfo = new FileInfo(filename);
|
||||||
|
|
||||||
|
long numBytes = fInfo.Length;
|
||||||
|
|
||||||
|
FileStream fStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
||||||
|
byte[] idata=new byte[numBytes];
|
||||||
|
BinaryReader br = new BinaryReader(fStream);
|
||||||
|
idata= br.ReadBytes((int)numBytes);
|
||||||
|
br.Close();
|
||||||
|
fStream.Close();
|
||||||
|
im.data=idata;
|
||||||
|
im.loaded=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Texture_request
|
||||||
|
{
|
||||||
|
public User_Agent_info req_user;
|
||||||
|
public LLUUID req_image;
|
||||||
|
public Texture_image image_info;
|
||||||
|
public long data_pointer=0;
|
||||||
|
public int num_packets=0;
|
||||||
|
public int packet_counter=0;
|
||||||
|
|
||||||
|
public Texture_request()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class Texture_image
|
||||||
|
{
|
||||||
|
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 Texture_image()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue