From fe46b045f75dec5ecdd0a29273c70df3e6ea540e Mon Sep 17 00:00:00 2001 From: MW Date: Mon, 21 May 2007 16:06:58 +0000 Subject: Start of a redesign of SimClient (now renamed ClientView)/World/Avatar/Prim , switching to a event based system (World/Avatar register as event handlers). It is possible that I've broke something with this commit but it doesn't matter as I'll just hide and no one will find me. --- OpenSim.RegionServer/AgentAssetUpload.cs | 4 +- OpenSim.RegionServer/Assets/AssetCache.cs | 6 +- OpenSim.RegionServer/Assets/InventoryCache.cs | 20 +- OpenSim.RegionServer/ClientView.Grid.cs | 157 +++++ OpenSim.RegionServer/ClientView.PacketHandlers.cs | 184 ++++++ OpenSim.RegionServer/ClientView.ProcessPackets.cs | 443 ++++++++++++++ OpenSim.RegionServer/ClientView.cs | 421 +++++++++++++ OpenSim.RegionServer/ClientViewBase.cs | 299 ++++++++++ OpenSim.RegionServer/OpenSim.RegionServer.csproj | 24 +- .../OpenSim.RegionServer.dll.build | 10 +- OpenSim.RegionServer/PacketServer.cs | 15 +- OpenSim.RegionServer/SimClient.Grid.cs | 157 ----- OpenSim.RegionServer/SimClient.PacketHandlers.cs | 184 ------ OpenSim.RegionServer/SimClient.ProcessPackets.cs | 419 ------------- OpenSim.RegionServer/SimClient.cs | 662 --------------------- OpenSim.RegionServer/SimClientBase.cs | 32 - OpenSim.RegionServer/UDPServer.cs | 2 +- OpenSim.RegionServer/world/Avatar.Update.cs | 57 +- OpenSim.RegionServer/world/Avatar.cs | 8 +- OpenSim.RegionServer/world/Primitive.cs | 16 +- OpenSim.RegionServer/world/Primitive2.cs | 27 +- OpenSim.RegionServer/world/SceneObject.cs | 4 +- OpenSim.RegionServer/world/World.PacketHandlers.cs | 56 +- OpenSim.RegionServer/world/World.cs | 34 +- OpenSim.RegionServer/world/WorldBase.cs | 10 +- 25 files changed, 1645 insertions(+), 1606 deletions(-) create mode 100644 OpenSim.RegionServer/ClientView.Grid.cs create mode 100644 OpenSim.RegionServer/ClientView.PacketHandlers.cs create mode 100644 OpenSim.RegionServer/ClientView.ProcessPackets.cs create mode 100644 OpenSim.RegionServer/ClientView.cs create mode 100644 OpenSim.RegionServer/ClientViewBase.cs delete mode 100644 OpenSim.RegionServer/SimClient.Grid.cs delete mode 100644 OpenSim.RegionServer/SimClient.PacketHandlers.cs delete mode 100644 OpenSim.RegionServer/SimClient.ProcessPackets.cs delete mode 100644 OpenSim.RegionServer/SimClient.cs delete mode 100644 OpenSim.RegionServer/SimClientBase.cs (limited to 'OpenSim.RegionServer') diff --git a/OpenSim.RegionServer/AgentAssetUpload.cs b/OpenSim.RegionServer/AgentAssetUpload.cs index cdf49c5..dd2b2a9 100644 --- a/OpenSim.RegionServer/AgentAssetUpload.cs +++ b/OpenSim.RegionServer/AgentAssetUpload.cs @@ -12,11 +12,11 @@ namespace OpenSim public class AgentAssetUpload { private Dictionary transactions = new Dictionary(); - private SimClient ourClient; + private ClientView ourClient; private AssetCache m_assetCache; private InventoryCache m_inventoryCache; - public AgentAssetUpload(SimClient client, AssetCache assetCache, InventoryCache inventoryCache) + public AgentAssetUpload(ClientView client, AssetCache assetCache, InventoryCache inventoryCache) { this.ourClient = client; m_assetCache = assetCache; diff --git a/OpenSim.RegionServer/Assets/AssetCache.cs b/OpenSim.RegionServer/Assets/AssetCache.cs index e8bf292..ccebb24 100644 --- a/OpenSim.RegionServer/Assets/AssetCache.cs +++ b/OpenSim.RegionServer/Assets/AssetCache.cs @@ -324,7 +324,7 @@ namespace OpenSim.Assets /// /// /// - public void AddAssetRequest(SimClient userInfo, TransferRequestPacket transferRequest) + public void AddAssetRequest(ClientView userInfo, TransferRequestPacket transferRequest) { LLUUID requestID = new LLUUID(transferRequest.TransferInfo.Params, 0); //check to see if asset is in local cache, if not we need to request it from asset server. @@ -464,7 +464,7 @@ namespace OpenSim.Assets /// /// /// - public void AddTextureRequest(SimClient userInfo, LLUUID imageID) + public void AddTextureRequest(ClientView userInfo, LLUUID imageID) { //check to see if texture is in local cache, if not request from asset server if (!this.Textures.ContainsKey(imageID)) @@ -517,7 +517,7 @@ namespace OpenSim.Assets public class AssetRequest { - public SimClient RequestUser; + public ClientView RequestUser; public LLUUID RequestAssetID; public AssetInfo AssetInf; public TextureImage ImageInfo; diff --git a/OpenSim.RegionServer/Assets/InventoryCache.cs b/OpenSim.RegionServer/Assets/InventoryCache.cs index 136ae53..64a7a32 100644 --- a/OpenSim.RegionServer/Assets/InventoryCache.cs +++ b/OpenSim.RegionServer/Assets/InventoryCache.cs @@ -94,12 +94,12 @@ namespace OpenSim.Assets } } - public bool CreateNewInventoryFolder(SimClient remoteClient, LLUUID folderID) + public bool CreateNewInventoryFolder(ClientView remoteClient, LLUUID folderID) { return this.CreateNewInventoryFolder(remoteClient, folderID, 0); } - public bool CreateNewInventoryFolder(SimClient remoteClient, LLUUID folderID, ushort type) + public bool CreateNewInventoryFolder(ClientView remoteClient, LLUUID folderID, ushort type) { bool res = false; if (folderID != LLUUID.Zero) //don't create a folder with a zero id @@ -112,7 +112,7 @@ namespace OpenSim.Assets return res; } - public bool CreateNewInventoryFolder(SimClient remoteClient, LLUUID folderID, ushort type, string folderName, LLUUID parent) + public bool CreateNewInventoryFolder(ClientView remoteClient, LLUUID folderID, ushort type, string folderName, LLUUID parent) { bool res = false; if (folderID != LLUUID.Zero) //don't create a folder with a zero id @@ -125,7 +125,7 @@ namespace OpenSim.Assets return res; } - public LLUUID AddNewInventoryItem(SimClient remoteClient, LLUUID folderID, OpenSim.Framework.Types.AssetBase asset) + public LLUUID AddNewInventoryItem(ClientView remoteClient, LLUUID folderID, OpenSim.Framework.Types.AssetBase asset) { LLUUID newItem = null; if (this._agentsInventory.ContainsKey(remoteClient.AgentID)) @@ -140,7 +140,7 @@ namespace OpenSim.Assets return newItem; } - public bool DeleteInventoryItem(SimClient remoteClient, LLUUID itemID) + public bool DeleteInventoryItem(ClientView remoteClient, LLUUID itemID) { bool res = false; if (this._agentsInventory.ContainsKey(remoteClient.AgentID)) @@ -161,7 +161,7 @@ namespace OpenSim.Assets return res; } - public bool UpdateInventoryItemAsset(SimClient remoteClient, LLUUID itemID, OpenSim.Framework.Types.AssetBase asset) + public bool UpdateInventoryItemAsset(ClientView remoteClient, LLUUID itemID, OpenSim.Framework.Types.AssetBase asset) { if (this._agentsInventory.ContainsKey(remoteClient.AgentID)) { @@ -177,7 +177,7 @@ namespace OpenSim.Assets return false; } - public bool UpdateInventoryItemDetails(SimClient remoteClient, LLUUID itemID, UpdateInventoryItemPacket.InventoryDataBlock packet) + public bool UpdateInventoryItemDetails(ClientView remoteClient, LLUUID itemID, UpdateInventoryItemPacket.InventoryDataBlock packet) { if (this._agentsInventory.ContainsKey(remoteClient.AgentID)) { @@ -193,7 +193,7 @@ namespace OpenSim.Assets return false; } - public void FetchInventoryDescendents(SimClient userInfo, FetchInventoryDescendentsPacket FetchDescend) + public void FetchInventoryDescendents(ClientView userInfo, FetchInventoryDescendentsPacket FetchDescend) { if (this._agentsInventory.ContainsKey(userInfo.AgentID)) { @@ -250,7 +250,7 @@ namespace OpenSim.Assets } } - public void FetchInventory(SimClient userInfo, FetchInventoryPacket FetchItems) + public void FetchInventory(ClientView userInfo, FetchInventoryPacket FetchItems) { if (this._agentsInventory.ContainsKey(userInfo.AgentID)) { @@ -291,7 +291,7 @@ namespace OpenSim.Assets } } - private void SendItemUpdateCreate(SimClient remoteClient, InventoryItem Item) + private void SendItemUpdateCreate(ClientView remoteClient, InventoryItem Item) { UpdateCreateInventoryItemPacket InventoryReply = new UpdateCreateInventoryItemPacket(); diff --git a/OpenSim.RegionServer/ClientView.Grid.cs b/OpenSim.RegionServer/ClientView.Grid.cs new file mode 100644 index 0000000..a3b191c --- /dev/null +++ b/OpenSim.RegionServer/ClientView.Grid.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; +using Nwc.XmlRpc; +using System.Net; +using System.Net.Sockets; +using System.IO; +using System.Threading; +using System.Timers; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Utilities; +using OpenSim.world; +using OpenSim.Assets; + +namespace OpenSim +{ + public partial class ClientView + { + + public void EnableNeighbours() + { + if ((this.m_gridServer.GetName() == "Remote") && (!this.m_child)) + { + Hashtable SimParams; + ArrayList SendParams; + XmlRpcRequest GridReq; + XmlRpcResponse GridResp; + List enablePackets = new List(); + + RemoteGridBase gridServer = (RemoteGridBase)this.m_gridServer; + + foreach (Hashtable neighbour in gridServer.neighbours) + { + string neighbourIPStr = (string)neighbour["sim_ip"]; + System.Net.IPAddress neighbourIP = System.Net.IPAddress.Parse(neighbourIPStr); + ushort neighbourPort = (ushort)Convert.ToInt32(neighbour["sim_port"]); + string reqUrl = "http://" + neighbourIPStr + ":" + neighbourPort.ToString(); + + Console.WriteLine(reqUrl); + + SimParams = new Hashtable(); + SimParams["session_id"] = this.SessionID.ToString(); + SimParams["secure_session_id"] = this.SecureSessionID.ToString(); + SimParams["firstname"] = this.ClientAvatar.firstname; + SimParams["lastname"] = this.ClientAvatar.lastname; + SimParams["agent_id"] = this.AgentID.ToString(); + SimParams["circuit_code"] = (Int32)this.CircuitCode; + SimParams["child_agent"] = "1"; + SendParams = new ArrayList(); + SendParams.Add(SimParams); + + GridReq = new XmlRpcRequest("expect_user", SendParams); + GridResp = GridReq.Send(reqUrl, 3000); + EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket(); + enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock(); + enablesimpacket.SimulatorInfo.Handle = Helpers.UIntsToLong((uint)(Convert.ToInt32(neighbour["region_locx"]) * 256), (uint)(Convert.ToInt32(neighbour["region_locy"]) * 256)); + + + byte[] byteIP = neighbourIP.GetAddressBytes(); + enablesimpacket.SimulatorInfo.IP = (uint)byteIP[3] << 24; + enablesimpacket.SimulatorInfo.IP += (uint)byteIP[2] << 16; + enablesimpacket.SimulatorInfo.IP += (uint)byteIP[1] << 8; + enablesimpacket.SimulatorInfo.IP += (uint)byteIP[0]; + enablesimpacket.SimulatorInfo.Port = neighbourPort; + enablePackets.Add(enablesimpacket); + } + Thread.Sleep(3000); + foreach (Packet enable in enablePackets) + { + this.OutPacket(enable); + } + enablePackets.Clear(); + + } + } + + public void CrossSimBorder(LLVector3 avatarpos) + { // VERY VERY BASIC + + LLVector3 newpos = avatarpos; + uint neighbourx = this.m_regionData.RegionLocX; + uint neighboury = this.m_regionData.RegionLocY; + + if (avatarpos.X < 0) + { + neighbourx -= 1; + newpos.X = 254; + } + if (avatarpos.X > 255) + { + neighbourx += 1; + newpos.X = 1; + } + if (avatarpos.Y < 0) + { + neighboury -= 1; + newpos.Y = 254; + } + if (avatarpos.Y > 255) + { + neighboury += 1; + newpos.Y = 1; + } + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "SimClient.cs:CrossSimBorder() - Crossing border to neighbouring sim at [" + neighbourx.ToString() + "," + neighboury.ToString() + "]"); + + Hashtable SimParams; + ArrayList SendParams; + XmlRpcRequest GridReq; + XmlRpcResponse GridResp; + foreach (Hashtable borderingSim in ((RemoteGridBase)m_gridServer).neighbours) + { + if (((string)borderingSim["region_locx"]).Equals(neighbourx.ToString()) && ((string)borderingSim["region_locy"]).Equals(neighboury.ToString())) + { + SimParams = new Hashtable(); + SimParams["firstname"] = this.ClientAvatar.firstname; + SimParams["lastname"] = this.ClientAvatar.lastname; + SimParams["circuit_code"] = this.CircuitCode.ToString(); + SimParams["pos_x"] = newpos.X.ToString(); + SimParams["pos_y"] = newpos.Y.ToString(); + SimParams["pos_z"] = newpos.Z.ToString(); + SendParams = new ArrayList(); + SendParams.Add(SimParams); + + GridReq = new XmlRpcRequest("agent_crossing", SendParams); + GridResp = GridReq.Send("http://" + borderingSim["sim_ip"] + ":" + borderingSim["sim_port"], 3000); + + CrossedRegionPacket NewSimPack = new CrossedRegionPacket(); + NewSimPack.AgentData = new CrossedRegionPacket.AgentDataBlock(); + NewSimPack.AgentData.AgentID = this.AgentID; + NewSimPack.AgentData.SessionID = this.SessionID; + NewSimPack.Info = new CrossedRegionPacket.InfoBlock(); + NewSimPack.Info.Position = newpos; + NewSimPack.Info.LookAt = new LLVector3(0.99f, 0.042f, 0); // copied from Avatar.cs - SHOULD BE DYNAMIC!!!!!!!!!! + NewSimPack.RegionData = new libsecondlife.Packets.CrossedRegionPacket.RegionDataBlock(); + NewSimPack.RegionData.RegionHandle = Helpers.UIntsToLong((uint)(Convert.ToInt32(borderingSim["region_locx"]) * 256), (uint)(Convert.ToInt32(borderingSim["region_locy"]) * 256)); + System.Net.IPAddress neighbourIP = System.Net.IPAddress.Parse((string)borderingSim["sim_ip"]); + byte[] byteIP = neighbourIP.GetAddressBytes(); + NewSimPack.RegionData.SimIP = (uint)byteIP[3] << 24; + NewSimPack.RegionData.SimIP += (uint)byteIP[2] << 16; + NewSimPack.RegionData.SimIP += (uint)byteIP[1] << 8; + NewSimPack.RegionData.SimIP += (uint)byteIP[0]; + NewSimPack.RegionData.SimPort = (ushort)Convert.ToInt32(borderingSim["sim_port"]); + NewSimPack.RegionData.SeedCapability = new byte[0]; + lock (PacketQueue) + { + ProcessOutPacket(NewSimPack); + DowngradeClient(); + } + } + } + } + } +} diff --git a/OpenSim.RegionServer/ClientView.PacketHandlers.cs b/OpenSim.RegionServer/ClientView.PacketHandlers.cs new file mode 100644 index 0000000..070c200 --- /dev/null +++ b/OpenSim.RegionServer/ClientView.PacketHandlers.cs @@ -0,0 +1,184 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; +using Nwc.XmlRpc; +using System.Net; +using System.Net.Sockets; +using System.IO; +using System.Threading; +using System.Timers; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Utilities; +using OpenSim.world; +using OpenSim.Assets; + +namespace OpenSim +{ + public partial class ClientView + { + protected virtual void RegisterLocalPacketHandlers() + { + this.AddLocalPacketHandler(PacketType.LogoutRequest, this.Logout); + this.AddLocalPacketHandler(PacketType.AgentCachedTexture, this.AgentTextureCached); + this.AddLocalPacketHandler(PacketType.MultipleObjectUpdate, this.MultipleObjUpdate); + } + + protected virtual bool Logout(ClientView simClient, Packet packet) + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:ProcessInPacket() - Got a logout request"); + //send reply to let the client logout + LogoutReplyPacket logReply = new LogoutReplyPacket(); + logReply.AgentData.AgentID = this.AgentID; + logReply.AgentData.SessionID = this.SessionID; + logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; + logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); + logReply.InventoryData[0].ItemID = LLUUID.Zero; + OutPacket(logReply); + //tell all clients to kill our object + KillObjectPacket kill = new KillObjectPacket(); + kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; + kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); + kill.ObjectData[0].ID = this.ClientAvatar.localid; + foreach (ClientView client in m_clientThreads.Values) + { + client.OutPacket(kill); + } + if (this.m_userServer != null) + { + this.m_inventoryCache.ClientLeaving(this.AgentID, this.m_userServer); + } + else + { + this.m_inventoryCache.ClientLeaving(this.AgentID, null); + } + + m_gridServer.LogoutSession(this.SessionID, this.AgentID, this.CircuitCode); + /*lock (m_world.Entities) + { + m_world.Entities.Remove(this.AgentID); + }*/ + m_world.RemoveViewerAgent(this); + //need to do other cleaning up here too + m_clientThreads.Remove(this.CircuitCode); + m_networkServer.RemoveClientCircuit(this.CircuitCode); + this.ClientThread.Abort(); + return true; + } + + protected bool AgentTextureCached(ClientView simclient, Packet packet) + { + // Console.WriteLine(packet.ToString()); + AgentCachedTexturePacket chechedtex = (AgentCachedTexturePacket)packet; + AgentCachedTextureResponsePacket cachedresp = new AgentCachedTextureResponsePacket(); + cachedresp.AgentData.AgentID = this.AgentID; + cachedresp.AgentData.SessionID = this.SessionID; + cachedresp.AgentData.SerialNum = this.cachedtextureserial; + this.cachedtextureserial++; + cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[chechedtex.WearableData.Length]; + for (int i = 0; i < chechedtex.WearableData.Length; i++) + { + cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); + cachedresp.WearableData[i].TextureIndex = chechedtex.WearableData[i].TextureIndex; + cachedresp.WearableData[i].TextureID = LLUUID.Zero; + cachedresp.WearableData[i].HostName = new byte[0]; + } + this.OutPacket(cachedresp); + return true; + } + + protected bool MultipleObjUpdate(ClientView simClient, Packet packet) + { + MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; + for (int i = 0; i < multipleupdate.ObjectData.Length; i++) + { + if (multipleupdate.ObjectData[i].Type == 9) //change position + { + libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID) + { + ((OpenSim.world.Primitive)ent).UpdatePosition(pos); + + } + } + //should update stored position of the prim + } + else if (multipleupdate.ObjectData[i].Type == 10)//rotation + { + libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true); + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID) + { + ent.rotation = new Axiom.MathLib.Quaternion(rot.W, rot.X, rot.Y, rot.Z); + ((OpenSim.world.Primitive)ent).UpdateFlag = true; + } + } + } + else if (multipleupdate.ObjectData[i].Type == 13)//scale + { + + libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID) + { + ((OpenSim.world.Primitive)ent).Scale = scale; + } + } + } + } + return true; + } + + public void RequestMapLayer() //should be getting the map layer from the grid server + { + //send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area) + MapLayerReplyPacket mapReply = new MapLayerReplyPacket(); + mapReply.AgentData.AgentID = this.AgentID; + mapReply.AgentData.Flags = 0; + mapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1]; + mapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock(); + mapReply.LayerData[0].Bottom = 800; + mapReply.LayerData[0].Left = 800; + mapReply.LayerData[0].Top = 1200; + mapReply.LayerData[0].Right = 1200; + mapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-9999-000000000006"); + this.OutPacket(mapReply); + } + + public void RequestMapBlocks(int minX, int minY, int maxX, int maxY) + { + IList simMapProfiles = m_gridServer.RequestMapBlocks(minX, minY, maxX, maxY); + MapBlockReplyPacket mbReply = new MapBlockReplyPacket(); + mbReply.AgentData.AgentID = this.AgentID; + int len; + if (simMapProfiles == null) + len = 0; + else + len = simMapProfiles.Count; + + mbReply.Data = new MapBlockReplyPacket.DataBlock[len]; + int iii; + for (iii = 0; iii < len; iii++) + { + Hashtable mp = (Hashtable)simMapProfiles[iii]; + mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock(); + mbReply.Data[iii].Name = System.Text.Encoding.UTF8.GetBytes((string)mp["name"]); + mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]); + mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]); + mbReply.Data[iii].MapImageID = new LLUUID((string)mp["map-image-id"]); + mbReply.Data[iii].RegionFlags = System.Convert.ToUInt32(mp["region-flags"]); + mbReply.Data[iii].WaterHeight = System.Convert.ToByte(mp["water-height"]); + mbReply.Data[iii].X = System.Convert.ToUInt16(mp["x"]); + mbReply.Data[iii].Y = System.Convert.ToUInt16(mp["y"]); + } + this.OutPacket(mbReply); + } + } +} diff --git a/OpenSim.RegionServer/ClientView.ProcessPackets.cs b/OpenSim.RegionServer/ClientView.ProcessPackets.cs new file mode 100644 index 0000000..0079d96 --- /dev/null +++ b/OpenSim.RegionServer/ClientView.ProcessPackets.cs @@ -0,0 +1,443 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; +using Nwc.XmlRpc; +using System.Net; +using System.Net.Sockets; +using System.IO; +using System.Threading; +using System.Timers; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Utilities; +using OpenSim.world; +using OpenSim.Assets; + +namespace OpenSim +{ + public partial class ClientView + { + public delegate void ChatFromViewer(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID); + + + public event ChatFromViewer OnChatFromViewer; + + protected override void ProcessInPacket(Packet Pack) + { + ack_pack(Pack); + if (debug) + { + if (Pack.Type != PacketType.AgentUpdate) + { + Console.WriteLine(Pack.Type.ToString()); + } + } + + if (this.ProcessPacketMethod(Pack)) + { + //there is a handler registered that handled this packet type + return; + } + else + { + System.Text.Encoding _enc = System.Text.Encoding.ASCII; + + switch (Pack.Type) + { + #region New Event system + case PacketType.ChatFromViewer: + ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack; + if (Util.FieldToString(inchatpack.ChatData.Message) == "") + { + //empty message so don't bother with it + break; + } + string fromName = ClientAvatar.firstname + " " + ClientAvatar.lastname; + byte[] message = inchatpack.ChatData.Message; + byte type = inchatpack.ChatData.Type; + LLVector3 fromPos = ClientAvatar.Pos; + LLUUID fromAgentID = AgentID; + this.OnChatFromViewer(message, type, fromPos, fromName, fromAgentID); + break; + #endregion + + #region World/Avatar/Primitive related packets + case PacketType.CompleteAgentMovement: + if (this.m_child) this.UpgradeClient(); + ClientAvatar.CompleteMovement(m_world); + ClientAvatar.SendInitialPosition(); + this.EnableNeighbours(); + break; + case PacketType.RegionHandshakeReply: + m_world.SendLayerData(this); + break; + case PacketType.AgentWearablesRequest: + ClientAvatar.SendInitialAppearance(); + foreach (ClientView client in m_clientThreads.Values) + { + if (client.AgentID != this.AgentID) + { + ObjectUpdatePacket objupdate = client.ClientAvatar.CreateUpdatePacket(); + this.OutPacket(objupdate); + client.ClientAvatar.SendAppearanceToOtherAgent(this.ClientAvatar); + } + } + m_world.GetInitialPrims(this); + break; + case PacketType.AgentIsNowWearing: + AgentIsNowWearingPacket wear = (AgentIsNowWearingPacket)Pack; + //Console.WriteLine(Pack.ToString()); + break; + case PacketType.AgentSetAppearance: + AgentSetAppearancePacket appear = (AgentSetAppearancePacket)Pack; + // Console.WriteLine(appear.ToString()); + this.ClientAvatar.SetAppearance(appear); + break; + case PacketType.ObjectAdd: + m_world.AddNewPrim((ObjectAddPacket)Pack, this); + break; + case PacketType.ObjectLink: + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, Pack.ToString()); + ObjectLinkPacket link = (ObjectLinkPacket)Pack; + uint parentprimid = 0; + OpenSim.world.Primitive parentprim = null; + if (link.ObjectData.Length > 1) + { + parentprimid = link.ObjectData[0].ObjectLocalID; + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == parentprimid) + { + parentprim = (OpenSim.world.Primitive)ent; + + } + } + for (int i = 1; i < link.ObjectData.Length; i++) + { + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == link.ObjectData[i].ObjectLocalID) + { + ((OpenSim.world.Primitive)ent).MakeParent(parentprim); + } + } + } + } + break; + case PacketType.ObjectScale: + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, Pack.ToString()); + break; + case PacketType.ObjectShape: + ObjectShapePacket shape = (ObjectShapePacket)Pack; + for (int i = 0; i < shape.ObjectData.Length; i++) + { + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == shape.ObjectData[i].ObjectLocalID) + { + ((OpenSim.world.Primitive)ent).UpdateShape(shape.ObjectData[i]); + } + } + } + break; + case PacketType.AgentUpdate: + ClientAvatar.HandleUpdate((AgentUpdatePacket)Pack); + break; + case PacketType.ObjectImage: + ObjectImagePacket imagePack = (ObjectImagePacket)Pack; + for (int i = 0; i < imagePack.ObjectData.Length; i++) + { + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == imagePack.ObjectData[i].ObjectLocalID) + { + ((OpenSim.world.Primitive)ent).UpdateTexture(imagePack.ObjectData[i].TextureEntry); + } + } + } + break; + case PacketType.ObjectFlagUpdate: + ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket)Pack; + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == flags.AgentData.ObjectLocalID) + { + ((OpenSim.world.Primitive)ent).UpdateObjectFlags(flags); + } + } + break; + case PacketType.AgentAnimation: + if (!m_child) + { + AgentAnimationPacket AgentAni = (AgentAnimationPacket)Pack; + for (int i = 0; i < AgentAni.AnimationList.Length; i++) + { + if (AgentAni.AnimationList[i].StartAnim) + { + ClientAvatar.current_anim = AgentAni.AnimationList[i].AnimID; + ClientAvatar.anim_seq = 1; + ClientAvatar.SendAnimPack(); + } + } + } + break; + case PacketType.ObjectSelect: + ObjectSelectPacket incomingselect = (ObjectSelectPacket)Pack; + for (int i = 0; i < incomingselect.ObjectData.Length; i++) + { + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == incomingselect.ObjectData[i].ObjectLocalID) + { + ((OpenSim.world.Primitive)ent).GetProperites(this); + break; + } + } + } + break; + case PacketType.ViewerEffect: + ViewerEffectPacket viewer = (ViewerEffectPacket)Pack; + foreach (ClientView client in m_clientThreads.Values) + { + if (client.AgentID != this.AgentID) + { + viewer.AgentData.AgentID = client.AgentID; + viewer.AgentData.SessionID = client.SessionID; + client.OutPacket(viewer); + } + } + break; + #endregion + + #region Inventory/Asset/Other related packets + case PacketType.RequestImage: + RequestImagePacket imageRequest = (RequestImagePacket)Pack; + for (int i = 0; i < imageRequest.RequestImage.Length; i++) + { + m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image); + } + break; + case PacketType.TransferRequest: + //Console.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request"); + TransferRequestPacket transfer = (TransferRequestPacket)Pack; + m_assetCache.AddAssetRequest(this, transfer); + break; + case PacketType.AssetUploadRequest: + AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; + this.UploadAssets.HandleUploadPacket(request, request.AssetBlock.TransactionID.Combine(this.SecureSessionID)); + break; + case PacketType.RequestXfer: + //Console.WriteLine(Pack.ToString()); + break; + case PacketType.SendXferPacket: + this.UploadAssets.HandleXferPacket((SendXferPacketPacket)Pack); + break; + case PacketType.CreateInventoryFolder: + CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket)Pack; + m_inventoryCache.CreateNewInventoryFolder(this, invFolder.FolderData.FolderID, (ushort)invFolder.FolderData.Type, Util.FieldToString(invFolder.FolderData.Name), invFolder.FolderData.ParentID); + //Console.WriteLine(Pack.ToString()); + break; + case PacketType.CreateInventoryItem: + //Console.WriteLine(Pack.ToString()); + CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack; + if (createItem.InventoryBlock.TransactionID != LLUUID.Zero) + { + this.UploadAssets.CreateInventoryItem(createItem); + } + else + { + // Console.Write(Pack.ToString()); + this.CreateInventoryItem(createItem); + } + break; + case PacketType.FetchInventory: + //Console.WriteLine("fetch item packet"); + FetchInventoryPacket FetchInventory = (FetchInventoryPacket)Pack; + m_inventoryCache.FetchInventory(this, FetchInventory); + break; + case PacketType.FetchInventoryDescendents: + FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket)Pack; + m_inventoryCache.FetchInventoryDescendents(this, Fetch); + break; + case PacketType.UpdateInventoryItem: + UpdateInventoryItemPacket update = (UpdateInventoryItemPacket)Pack; + //Console.WriteLine(Pack.ToString()); + for (int i = 0; i < update.InventoryData.Length; i++) + { + if (update.InventoryData[i].TransactionID != LLUUID.Zero) + { + AssetBase asset = m_assetCache.GetAsset(update.InventoryData[i].TransactionID.Combine(this.SecureSessionID)); + if (asset != null) + { + // Console.WriteLine("updating inventory item, found asset" + asset.FullID.ToStringHyphenated() + " already in cache"); + m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset); + } + else + { + asset = this.UploadAssets.AddUploadToAssetCache(update.InventoryData[i].TransactionID); + if (asset != null) + { + //Console.WriteLine("updating inventory item, adding asset" + asset.FullID.ToStringHyphenated() + " to cache"); + m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset); + } + else + { + //Console.WriteLine("trying to update inventory item, but asset is null"); + } + } + } + else + { + m_inventoryCache.UpdateInventoryItemDetails(this, update.InventoryData[i].ItemID, update.InventoryData[i]); ; + } + } + break; + case PacketType.RequestTaskInventory: + // Console.WriteLine(Pack.ToString()); + RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket)Pack; + ReplyTaskInventoryPacket replytask = new ReplyTaskInventoryPacket(); + bool foundent = false; + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == requesttask.InventoryData.LocalID) + { + replytask.InventoryData.TaskID = ent.uuid; + replytask.InventoryData.Serial = 0; + replytask.InventoryData.Filename = new byte[0]; + foundent = true; + } + } + if (foundent) + { + this.OutPacket(replytask); + } + break; + case PacketType.UpdateTaskInventory: + // Console.WriteLine(Pack.ToString()); + UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket)Pack; + AgentInventory myinventory = this.m_inventoryCache.GetAgentsInventory(this.AgentID); + if (myinventory != null) + { + if (updatetask.UpdateData.Key == 0) + { + if (myinventory.InventoryItems[updatetask.InventoryData.ItemID] != null) + { + if (myinventory.InventoryItems[updatetask.InventoryData.ItemID].Type == 7) + { + LLUUID noteaid = myinventory.InventoryItems[updatetask.InventoryData.ItemID].AssetID; + AssetBase assBase = this.m_assetCache.GetAsset(noteaid); + if (assBase != null) + { + foreach (Entity ent in m_world.Entities.Values) + { + if (ent.localid == updatetask.UpdateData.LocalID) + { + if (ent is OpenSim.world.Primitive) + { + this.m_world.AddScript(ent, Util.FieldToString(assBase.Data)); + } + } + } + } + } + } + } + } + break; + case PacketType.MapLayerRequest: + this.RequestMapLayer(); + break; + case PacketType.MapBlockRequest: + MapBlockRequestPacket MapRequest = (MapBlockRequestPacket)Pack; + + this.RequestMapBlocks(MapRequest.PositionData.MinX, MapRequest.PositionData.MinY, MapRequest.PositionData.MaxX, MapRequest.PositionData.MaxY); + break; + case PacketType.TeleportLandmarkRequest: + TeleportLandmarkRequestPacket tpReq = (TeleportLandmarkRequestPacket)Pack; + + TeleportStartPacket tpStart = new TeleportStartPacket(); + tpStart.Info.TeleportFlags = 8; // tp via lm + this.OutPacket(tpStart); + + TeleportProgressPacket tpProgress = new TeleportProgressPacket(); + tpProgress.Info.Message = (new System.Text.ASCIIEncoding()).GetBytes("sending_landmark"); + tpProgress.Info.TeleportFlags = 8; + tpProgress.AgentData.AgentID = tpReq.Info.AgentID; + this.OutPacket(tpProgress); + + // Fetch landmark + LLUUID lmid = tpReq.Info.LandmarkID; + AssetBase lma = this.m_assetCache.GetAsset(lmid); + if (lma != null) + { + AssetLandmark lm = new AssetLandmark(lma); + + if (lm.RegionID == m_regionData.SimUUID) + { + TeleportLocalPacket tpLocal = new TeleportLocalPacket(); + + tpLocal.Info.AgentID = tpReq.Info.AgentID; + tpLocal.Info.TeleportFlags = 8; // Teleport via landmark + tpLocal.Info.LocationID = 2; + tpLocal.Info.Position = lm.Position; + OutPacket(tpLocal); + } + else + { + TeleportCancelPacket tpCancel = new TeleportCancelPacket(); + tpCancel.Info.AgentID = tpReq.Info.AgentID; + tpCancel.Info.SessionID = tpReq.Info.SessionID; + OutPacket(tpCancel); + } + } + else + { + Console.WriteLine("Cancelling Teleport - fetch asset not yet implemented"); + + TeleportCancelPacket tpCancel = new TeleportCancelPacket(); + tpCancel.Info.AgentID = tpReq.Info.AgentID; + tpCancel.Info.SessionID = tpReq.Info.SessionID; + OutPacket(tpCancel); + } + break; + case PacketType.TeleportLocationRequest: + TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack; + Console.WriteLine(tpLocReq.ToString()); + + tpStart = new TeleportStartPacket(); + tpStart.Info.TeleportFlags = 16; // Teleport via location + Console.WriteLine(tpStart.ToString()); + OutPacket(tpStart); + + if (m_regionData.RegionHandle != tpLocReq.Info.RegionHandle) + { + /* m_gridServer.getRegion(tpLocReq.Info.RegionHandle); */ + Console.WriteLine("Inter-sim teleport not yet implemented"); + TeleportCancelPacket tpCancel = new TeleportCancelPacket(); + tpCancel.Info.SessionID = tpLocReq.AgentData.SessionID; + tpCancel.Info.AgentID = tpLocReq.AgentData.AgentID; + + OutPacket(tpCancel); + } + else + { + Console.WriteLine("Local teleport"); + TeleportLocalPacket tpLocal = new TeleportLocalPacket(); + tpLocal.Info.AgentID = tpLocReq.AgentData.AgentID; + tpLocal.Info.TeleportFlags = tpStart.Info.TeleportFlags; + tpLocal.Info.LocationID = 2; + tpLocal.Info.LookAt = tpLocReq.Info.LookAt; + tpLocal.Info.Position = tpLocReq.Info.Position; + OutPacket(tpLocal); + + } + break; + #endregion + } + } + } + } +} diff --git a/OpenSim.RegionServer/ClientView.cs b/OpenSim.RegionServer/ClientView.cs new file mode 100644 index 0000000..a97049d --- /dev/null +++ b/OpenSim.RegionServer/ClientView.cs @@ -0,0 +1,421 @@ +/* +Copyright (c) OpenSim project, http://osgrid.org/ +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +using System; +using System.Collections; +using System.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; +using Nwc.XmlRpc; +using System.Net; +using System.Net.Sockets; +using System.IO; +using System.Threading; +using System.Timers; +using OpenSim.Framework.Interfaces; +using OpenSim.Framework.Types; +using OpenSim.Framework.Inventory; +using OpenSim.Framework.Utilities; +using OpenSim.world; +using OpenSim.Assets; + +namespace OpenSim +{ + public delegate bool PacketMethod(ClientView simClient, Packet packet); + + /// + /// Handles new client connections + /// Constructor takes a single Packet and authenticates everything + /// + public partial class ClientView : ClientViewBase + { + public LLUUID AgentID; + public LLUUID SessionID; + public LLUUID SecureSessionID = LLUUID.Zero; + public bool m_child; + public world.Avatar ClientAvatar; + private UseCircuitCodePacket cirpack; + public Thread ClientThread; + public LLVector3 startpos; + + private AgentAssetUpload UploadAssets; + private LLUUID newAssetFolder = LLUUID.Zero; + private bool debug = false; + private World m_world; + private Dictionary m_clientThreads; + private AssetCache m_assetCache; + private IGridServer m_gridServer; + private IUserServer m_userServer = null; + private InventoryCache m_inventoryCache; + public bool m_sandboxMode; + private int cachedtextureserial = 0; + private RegionInfo m_regionData; + protected AuthenticateSessionsBase m_authenticateSessionsHandler; + + protected static Dictionary PacketHandlers = new Dictionary(); //Global/static handlers for all clients + + protected Dictionary m_packetHandlers = new Dictionary(); //local handlers for this instance + + public IUserServer UserServer + { + set + { + this.m_userServer = value; + } + } + + public ClientView(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, World world, Dictionary clientThreads, AssetCache assetCache, IGridServer gridServer, OpenSimNetworkHandler application, InventoryCache inventoryCache, bool sandboxMode, bool child, RegionInfo regionDat, AuthenticateSessionsBase authenSessions) + { + m_world = world; + m_clientThreads = clientThreads; + m_assetCache = assetCache; + m_gridServer = gridServer; + m_networkServer = application; + m_inventoryCache = inventoryCache; + m_sandboxMode = sandboxMode; + m_child = child; + m_regionData = regionDat; + m_authenticateSessionsHandler = authenSessions; + + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs - Started up new client thread to handle incoming request"); + cirpack = initialcirpack; + userEP = remoteEP; + + if (m_gridServer.GetName() == "Remote") + { + this.m_child = m_authenticateSessionsHandler.GetAgentChildStatus(initialcirpack.CircuitCode.Code); + this.startpos = m_authenticateSessionsHandler.GetPosition(initialcirpack.CircuitCode.Code); + //Console.WriteLine("start pos is " + this.startpos.X + " , " + this.startpos.Y + " , " + this.startpos.Z); + } + else + { + this.startpos = new LLVector3(128, 128, m_world.Terrain[(int)128, (int)128] + 15.0f); // new LLVector3(128.0f, 128.0f, 60f); + } + + PacketQueue = new BlockingQueue(); + + this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache); + AckTimer = new System.Timers.Timer(500); + AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed); + AckTimer.Start(); + + this.RegisterLocalPacketHandlers(); + + ClientThread = new Thread(new ThreadStart(AuthUser)); + ClientThread.IsBackground = true; + ClientThread.Start(); + } + + # region Client Methods + public void UpgradeClient() + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "SimClient.cs:UpgradeClient() - upgrading child to full agent"); + this.m_child = false; + this.m_world.RemoveViewerAgent(this); + if (!this.m_sandboxMode) + { + this.startpos = m_authenticateSessionsHandler.GetPosition(CircuitCode); + m_authenticateSessionsHandler.UpdateAgentChildStatus(CircuitCode, false); + //Console.WriteLine("upgrade start pos is " + this.startpos.X + " , " + this.startpos.Y + " , " + this.startpos.Z); + } + this.InitNewClient(); + } + + public void DowngradeClient() + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "SimClient.cs:UpgradeClient() - changing full agent to child"); + this.m_child = true; + this.m_world.RemoveViewerAgent(this); + this.m_world.AddViewerAgent(this); + } + + public void KillClient() + { + KillObjectPacket kill = new KillObjectPacket(); + kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; + kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); + kill.ObjectData[0].ID = this.ClientAvatar.localid; + foreach (ClientView client in m_clientThreads.Values) + { + client.OutPacket(kill); + } + if (this.m_userServer != null) + { + this.m_inventoryCache.ClientLeaving(this.AgentID, this.m_userServer); + } + else + { + this.m_inventoryCache.ClientLeaving(this.AgentID, null); + } + + m_world.RemoveViewerAgent(this); + + m_clientThreads.Remove(this.CircuitCode); + m_networkServer.RemoveClientCircuit(this.CircuitCode); + this.ClientThread.Abort(); + } + #endregion + + # region Packet Handling + public static bool AddPacketHandler(PacketType packetType, PacketMethod handler) + { + bool result = false; + lock (PacketHandlers) + { + if (!PacketHandlers.ContainsKey(packetType)) + { + PacketHandlers.Add(packetType, handler); + result = true; + } + } + return result; + } + + public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler) + { + bool result = false; + lock (m_packetHandlers) + { + if (!m_packetHandlers.ContainsKey(packetType)) + { + m_packetHandlers.Add(packetType, handler); + result = true; + } + } + return result; + } + + protected virtual bool ProcessPacketMethod(Packet packet) + { + bool result = false; + bool found = false; + PacketMethod method; + if (m_packetHandlers.TryGetValue(packet.Type, out method)) + { + //there is a local handler for this packet type + result = method(this, packet); + } + else + { + //there is not a local handler so see if there is a Global handler + lock (PacketHandlers) + { + found = PacketHandlers.TryGetValue(packet.Type, out method); + } + if (found) + { + result = method(this, packet); + } + } + return result; + } + + # endregion + + protected virtual void ClientLoop() + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:ClientLoop() - Entered loop"); + while (true) + { + QueItem nextPacket = PacketQueue.Dequeue(); + if (nextPacket.Incoming) + { + //is a incoming packet + ProcessInPacket(nextPacket.Packet); + } + else + { + //is a out going packet + ProcessOutPacket(nextPacket.Packet); + } + } + } + + # region Setup + + protected virtual void InitNewClient() + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:InitNewClient() - Adding viewer agent to world"); + + m_world.AddViewerAgent(this); + world.Entity tempent = m_world.Entities[this.AgentID]; + + this.ClientAvatar = (world.Avatar)tempent; + } + + protected virtual void AuthUser() + { + // AuthenticateResponse sessionInfo = m_gridServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code); + AuthenticateResponse sessionInfo = this.m_networkServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code); + if (!sessionInfo.Authorised) + { + //session/circuit not authorised + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.NORMAL, "OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString()); + ClientThread.Abort(); + } + else + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.NORMAL, "OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString()); + //session is authorised + this.AgentID = cirpack.CircuitCode.ID; + this.SessionID = cirpack.CircuitCode.SessionID; + this.CircuitCode = cirpack.CircuitCode.Code; + InitNewClient(); //shouldn't be called here as we might be a child agent and not want a full avatar + this.ClientAvatar.firstname = sessionInfo.LoginInfo.First; + this.ClientAvatar.lastname = sessionInfo.LoginInfo.Last; + if (sessionInfo.LoginInfo.SecureSession != LLUUID.Zero) + { + this.SecureSessionID = sessionInfo.LoginInfo.SecureSession; + } + + // Create Inventory, currently only works for sandbox mode + if (m_sandboxMode) + { + this.SetupInventory(sessionInfo); + } + + ClientLoop(); + } + } + # endregion + + + protected override void KillThread() + { + this.ClientThread.Abort(); + } + + #region World/Avatar To Viewer Methods + + public void SendChatMessage(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) + { + System.Text.Encoding enc = System.Text.Encoding.ASCII; + libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket(); + reply.ChatData.Audible = 1; + reply.ChatData.Message = message; + reply.ChatData.ChatType = type; + reply.ChatData.SourceType = 1; + reply.ChatData.Position = fromPos; + reply.ChatData.FromName = enc.GetBytes(fromName + "\0"); + reply.ChatData.OwnerID = fromAgentID; + reply.ChatData.SourceID = fromAgentID; + + this.OutPacket(reply); + } + #endregion + + #region Inventory Creation + private void SetupInventory(AuthenticateResponse sessionInfo) + { + AgentInventory inventory = null; + if (sessionInfo.LoginInfo.InventoryFolder != null) + { + inventory = this.CreateInventory(sessionInfo.LoginInfo.InventoryFolder); + if (sessionInfo.LoginInfo.BaseFolder != null) + { + if (!inventory.HasFolder(sessionInfo.LoginInfo.BaseFolder)) + { + m_inventoryCache.CreateNewInventoryFolder(this, sessionInfo.LoginInfo.BaseFolder); + } + this.newAssetFolder = sessionInfo.LoginInfo.BaseFolder; + AssetBase[] inventorySet = m_assetCache.CreateNewInventorySet(this.AgentID); + if (inventorySet != null) + { + for (int i = 0; i < inventorySet.Length; i++) + { + if (inventorySet[i] != null) + { + m_inventoryCache.AddNewInventoryItem(this, sessionInfo.LoginInfo.BaseFolder, inventorySet[i]); + } + } + } + } + } + } + private AgentInventory CreateInventory(LLUUID baseFolder) + { + AgentInventory inventory = null; + if (this.m_userServer != null) + { + // a user server is set so request the inventory from it + Console.WriteLine("getting inventory from user server"); + inventory = m_inventoryCache.FetchAgentsInventory(this.AgentID, m_userServer); + } + else + { + inventory = new AgentInventory(); + inventory.AgentID = this.AgentID; + inventory.CreateRootFolder(this.AgentID, false); + m_inventoryCache.AddNewAgentsInventory(inventory); + m_inventoryCache.CreateNewInventoryFolder(this, baseFolder); + } + return inventory; + } + + private void CreateInventoryItem(CreateInventoryItemPacket packet) + { + if (!(packet.InventoryBlock.Type == 3 || packet.InventoryBlock.Type == 7)) + { + System.Console.WriteLine("Attempted to create " + Util.FieldToString(packet.InventoryBlock.Name) + " in inventory. Unsupported type"); + return; + } + + //lets try this out with creating a notecard + AssetBase asset = new AssetBase(); + + asset.Name = Util.FieldToString(packet.InventoryBlock.Name); + asset.Description = Util.FieldToString(packet.InventoryBlock.Description); + asset.InvType = packet.InventoryBlock.InvType; + asset.Type = packet.InventoryBlock.Type; + asset.FullID = LLUUID.Random(); + + switch (packet.InventoryBlock.Type) + { + case 7: // Notecard + asset.Data = new byte[0]; + break; + + case 3: // Landmark + String content; + content = "Landmark version 2\n"; + content += "region_id " + m_regionData.SimUUID + "\n"; + String strPos = String.Format("%.2f %.2f %.2f>", + this.ClientAvatar.Pos.X, + this.ClientAvatar.Pos.Y, + this.ClientAvatar.Pos.Z); + content += "local_pos " + strPos + "\n"; + asset.Data = (new System.Text.ASCIIEncoding()).GetBytes(content); + break; + default: + break; + } + m_assetCache.AddAsset(asset); + m_inventoryCache.AddNewInventoryItem(this, packet.InventoryBlock.FolderID, asset); + } + #endregion + + } +} diff --git a/OpenSim.RegionServer/ClientViewBase.cs b/OpenSim.RegionServer/ClientViewBase.cs new file mode 100644 index 0000000..814b025 --- /dev/null +++ b/OpenSim.RegionServer/ClientViewBase.cs @@ -0,0 +1,299 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using libsecondlife; +using libsecondlife.Packets; +using System.Net; +using System.Net.Sockets; +using System.IO; +using System.Threading; +using System.Timers; +using OpenSim.Framework.Utilities; + + +namespace OpenSim +{ + public class ClientViewBase + { + protected BlockingQueue PacketQueue; + protected Dictionary PendingAcks = new Dictionary(); + protected Dictionary NeedAck = new Dictionary(); + + protected System.Timers.Timer AckTimer; + protected uint Sequence = 0; + protected object SequenceLock = new object(); + protected const int MAX_APPENDED_ACKS = 10; + protected const int RESEND_TIMEOUT = 4000; + protected const int MAX_SEQUENCE = 0xFFFFFF; + + public uint CircuitCode; + public EndPoint userEP; + + protected OpenSimNetworkHandler m_networkServer; + + public ClientViewBase() + { + + } + + protected virtual void ProcessInPacket(Packet Pack) + { + + } + + protected virtual void ProcessOutPacket(Packet Pack) + { + // Keep track of when this packet was sent out + Pack.TickCount = Environment.TickCount; + + if (!Pack.Header.Resent) + { + // Set the sequence number + lock (SequenceLock) + { + if (Sequence >= MAX_SEQUENCE) + Sequence = 1; + else + Sequence++; + Pack.Header.Sequence = Sequence; + } + + if (Pack.Header.Reliable) //DIRTY HACK + { + lock (NeedAck) + { + if (!NeedAck.ContainsKey(Pack.Header.Sequence)) + { + try + { + NeedAck.Add(Pack.Header.Sequence, Pack); + } + catch (Exception e) // HACKY + { + e.ToString(); + // Ignore + // Seems to throw a exception here occasionally + // of 'duplicate key' despite being locked. + // !?!?!? + } + } + else + { + // Client.Log("Attempted to add a duplicate sequence number (" + + // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + + // packet.Type.ToString(), Helpers.LogLevel.Warning); + } + } + + // Don't append ACKs to resent packets, in case that's what was causing the + // delivery to fail + if (!Pack.Header.Resent) + { + // Append any ACKs that need to be sent out to this packet + lock (PendingAcks) + { + if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS && + Pack.Type != PacketType.PacketAck && + Pack.Type != PacketType.LogoutRequest) + { + Pack.Header.AckList = new uint[PendingAcks.Count]; + int i = 0; + + foreach (uint ack in PendingAcks.Values) + { + Pack.Header.AckList[i] = ack; + i++; + } + + PendingAcks.Clear(); + Pack.Header.AppendedAcks = true; + } + } + } + } + } + + byte[] ZeroOutBuffer = new byte[4096]; + byte[] sendbuffer; + sendbuffer = Pack.ToBytes(); + + try + { + if (Pack.Header.Zerocoded) + { + int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); + m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP); + } + else + { + m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP); + } + } + catch (Exception) + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread"); + this.KillThread(); + } + + } + + public virtual void InPacket(Packet NewPack) + { + // Handle appended ACKs + if (NewPack.Header.AppendedAcks) + { + lock (NeedAck) + { + foreach (uint ack in NewPack.Header.AckList) + { + NeedAck.Remove(ack); + } + } + } + + // Handle PacketAck packets + if (NewPack.Type == PacketType.PacketAck) + { + PacketAckPacket ackPacket = (PacketAckPacket)NewPack; + + lock (NeedAck) + { + foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) + { + NeedAck.Remove(block.ID); + } + } + } + else if ((NewPack.Type == PacketType.StartPingCheck)) + { + //reply to pingcheck + libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack; + libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket(); + endPing.PingID.PingID = startPing.PingID.PingID; + OutPacket(endPing); + } + else + { + QueItem item = new QueItem(); + item.Packet = NewPack; + item.Incoming = true; + this.PacketQueue.Enqueue(item); + } + + } + + public virtual void OutPacket(Packet NewPack) + { + QueItem item = new QueItem(); + item.Packet = NewPack; + item.Incoming = false; + this.PacketQueue.Enqueue(item); + } + + # region Low Level Packet Methods + + protected void ack_pack(Packet Pack) + { + if (Pack.Header.Reliable) + { + libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket(); + ack_it.Packets = new PacketAckPacket.PacketsBlock[1]; + ack_it.Packets[0] = new PacketAckPacket.PacketsBlock(); + ack_it.Packets[0].ID = Pack.Header.Sequence; + ack_it.Header.Reliable = false; + + OutPacket(ack_it); + + } + /* + if (Pack.Header.Reliable) + { + lock (PendingAcks) + { + uint sequence = (uint)Pack.Header.Sequence; + if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; } + } + }*/ + } + + protected void ResendUnacked() + { + int now = Environment.TickCount; + + lock (NeedAck) + { + foreach (Packet packet in NeedAck.Values) + { + if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent)) + { + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.VERBOSE, "Resending " + packet.Type.ToString() + " packet, " + + (now - packet.TickCount) + "ms have passed"); + + packet.Header.Resent = true; + OutPacket(packet); + } + } + } + } + + protected void SendAcks() + { + lock (PendingAcks) + { + if (PendingAcks.Count > 0) + { + if (PendingAcks.Count > 250) + { + // FIXME: Handle the odd case where we have too many pending ACKs queued up + OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.VERBOSE, "Too many ACKs queued up!"); + return; + } + + //OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Sending PacketAck"); + + + int i = 0; + PacketAckPacket acks = new PacketAckPacket(); + acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count]; + + foreach (uint ack in PendingAcks.Values) + { + acks.Packets[i] = new PacketAckPacket.PacketsBlock(); + acks.Packets[i].ID = ack; + i++; + } + + acks.Header.Reliable = false; + OutPacket(acks); + + PendingAcks.Clear(); + } + } + } + + protected void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) + { + SendAcks(); + ResendUnacked(); + } + #endregion + + protected virtual void KillThread() + { + + } + + #region Nested Classes + + public class QueItem + { + public QueItem() + { + } + + public Packet Packet; + public bool Incoming; + } + #endregion + } +} diff --git a/OpenSim.RegionServer/OpenSim.RegionServer.csproj b/OpenSim.RegionServer/OpenSim.RegionServer.csproj index 93285b4..512ee88 100644 --- a/OpenSim.RegionServer/OpenSim.RegionServer.csproj +++ b/OpenSim.RegionServer/OpenSim.RegionServer.csproj @@ -136,40 +136,40 @@ Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code - + Code diff --git a/OpenSim.RegionServer/OpenSim.RegionServer.dll.build b/OpenSim.RegionServer/OpenSim.RegionServer.dll.build index 35985ac..4ec3537 100644 --- a/OpenSim.RegionServer/OpenSim.RegionServer.dll.build +++ b/OpenSim.RegionServer/OpenSim.RegionServer.dll.build @@ -15,6 +15,11 @@ + + + + + @@ -22,11 +27,6 @@ - - - - - diff --git a/OpenSim.RegionServer/PacketServer.cs b/OpenSim.RegionServer/PacketServer.cs index b60d10f..cb7de11 100644 --- a/OpenSim.RegionServer/PacketServer.cs +++ b/OpenSim.RegionServer/PacketServer.cs @@ -10,7 +10,7 @@ namespace OpenSim { private OpenSimNetworkHandler _networkHandler; private World _localWorld; - public Dictionary ClientThreads = new Dictionary(); + public Dictionary ClientThreads = new Dictionary(); public PacketServer(OpenSimNetworkHandler networkHandler) { @@ -44,7 +44,7 @@ namespace OpenSim } - public virtual void SendPacketToAllExcept(Packet packet, SimClient simClient) + public virtual void SendPacketToAllExcept(Packet packet, ClientView simClient) { } @@ -58,17 +58,16 @@ namespace OpenSim { if (this._localWorld != null) { - SimClient.AddPacketHandler(PacketType.ModifyLand, _localWorld.ModifyTerrain); - SimClient.AddPacketHandler(PacketType.ChatFromViewer, _localWorld.SimChat); - SimClient.AddPacketHandler(PacketType.RezObject, _localWorld.RezObject); - SimClient.AddPacketHandler(PacketType.DeRezObject, _localWorld.DeRezObject); - SimClient.AddPacketHandler(PacketType.UUIDNameRequest, this.RequestUUIDName); + ClientView.AddPacketHandler(PacketType.ModifyLand, _localWorld.ModifyTerrain); + ClientView.AddPacketHandler(PacketType.RezObject, _localWorld.RezObject); + ClientView.AddPacketHandler(PacketType.DeRezObject, _localWorld.DeRezObject); + ClientView.AddPacketHandler(PacketType.UUIDNameRequest, this.RequestUUIDName); } } #region Client Packet Handlers - public bool RequestUUIDName(SimClient simClient, Packet packet) + public bool RequestUUIDName(ClientView simClient, Packet packet) { System.Text.Encoding enc = System.Text.Encoding.ASCII; Console.WriteLine(packet.ToString()); diff --git a/OpenSim.RegionServer/SimClient.Grid.cs b/OpenSim.RegionServer/SimClient.Grid.cs deleted file mode 100644 index 493d4d7..0000000 --- a/OpenSim.RegionServer/SimClient.Grid.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using libsecondlife; -using libsecondlife.Packets; -using Nwc.XmlRpc; -using System.Net; -using System.Net.Sockets; -using System.IO; -using System.Threading; -using System.Timers; -using OpenSim.Framework.Interfaces; -using OpenSim.Framework.Types; -using OpenSim.Framework.Inventory; -using OpenSim.Framework.Utilities; -using OpenSim.world; -using OpenSim.Assets; - -namespace OpenSim -{ - public partial class SimClient - { - - public void EnableNeighbours() - { - if ((this.m_gridServer.GetName() == "Remote") && (!this.m_child)) - { - Hashtable SimParams; - ArrayList SendParams; - XmlRpcRequest GridReq; - XmlRpcResponse GridResp; - List enablePackets = new List(); - - RemoteGridBase gridServer = (RemoteGridBase)this.m_gridServer; - - foreach (Hashtable neighbour in gridServer.neighbours) - { - string neighbourIPStr = (string)neighbour["sim_ip"]; - System.Net.IPAddress neighbourIP = System.Net.IPAddress.Parse(neighbourIPStr); - ushort neighbourPort = (ushort)Convert.ToInt32(neighbour["sim_port"]); - string reqUrl = "http://" + neighbourIPStr + ":" + neighbourPort.ToString(); - - Console.WriteLine(reqUrl); - - SimParams = new Hashtable(); - SimParams["session_id"] = this.SessionID.ToString(); - SimParams["secure_session_id"] = this.SecureSessionID.ToString(); - SimParams["firstname"] = this.ClientAvatar.firstname; - SimParams["lastname"] = this.ClientAvatar.lastname; - SimParams["agent_id"] = this.AgentID.ToString(); - SimParams["circuit_code"] = (Int32)this.CircuitCode; - SimParams["child_agent"] = "1"; - SendParams = new ArrayList(); - SendParams.Add(SimParams); - - GridReq = new XmlRpcRequest("expect_user", SendParams); - GridResp = GridReq.Send(reqUrl, 3000); - EnableSimulatorPacket enablesimpacket = new EnableSimulatorPacket(); - enablesimpacket.SimulatorInfo = new EnableSimulatorPacket.SimulatorInfoBlock(); - enablesimpacket.SimulatorInfo.Handle = Helpers.UIntsToLong((uint)(Convert.ToInt32(neighbour["region_locx"]) * 256), (uint)(Convert.ToInt32(neighbour["region_locy"]) * 256)); - - - byte[] byteIP = neighbourIP.GetAddressBytes(); - enablesimpacket.SimulatorInfo.IP = (uint)byteIP[3] << 24; - enablesimpacket.SimulatorInfo.IP += (uint)byteIP[2] << 16; - enablesimpacket.SimulatorInfo.IP += (uint)byteIP[1] << 8; - enablesimpacket.SimulatorInfo.IP += (uint)byteIP[0]; - enablesimpacket.SimulatorInfo.Port = neighbourPort; - enablePackets.Add(enablesimpacket); - } - Thread.Sleep(3000); - foreach (Packet enable in enablePackets) - { - this.OutPacket(enable); - } - enablePackets.Clear(); - - } - } - - public void CrossSimBorder(LLVector3 avatarpos) - { // VERY VERY BASIC - - LLVector3 newpos = avatarpos; - uint neighbourx = this.m_regionData.RegionLocX; - uint neighboury = this.m_regionData.RegionLocY; - - if (avatarpos.X < 0) - { - neighbourx -= 1; - newpos.X = 254; - } - if (avatarpos.X > 255) - { - neighbourx += 1; - newpos.X = 1; - } - if (avatarpos.Y < 0) - { - neighboury -= 1; - newpos.Y = 254; - } - if (avatarpos.Y > 255) - { - neighboury += 1; - newpos.Y = 1; - } - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "SimClient.cs:CrossSimBorder() - Crossing border to neighbouring sim at [" + neighbourx.ToString() + "," + neighboury.ToString() + "]"); - - Hashtable SimParams; - ArrayList SendParams; - XmlRpcRequest GridReq; - XmlRpcResponse GridResp; - foreach (Hashtable borderingSim in ((RemoteGridBase)m_gridServer).neighbours) - { - if (((string)borderingSim["region_locx"]).Equals(neighbourx.ToString()) && ((string)borderingSim["region_locy"]).Equals(neighboury.ToString())) - { - SimParams = new Hashtable(); - SimParams["firstname"] = this.ClientAvatar.firstname; - SimParams["lastname"] = this.ClientAvatar.lastname; - SimParams["circuit_code"] = this.CircuitCode.ToString(); - SimParams["pos_x"] = newpos.X.ToString(); - SimParams["pos_y"] = newpos.Y.ToString(); - SimParams["pos_z"] = newpos.Z.ToString(); - SendParams = new ArrayList(); - SendParams.Add(SimParams); - - GridReq = new XmlRpcRequest("agent_crossing", SendParams); - GridResp = GridReq.Send("http://" + borderingSim["sim_ip"] + ":" + borderingSim["sim_port"], 3000); - - CrossedRegionPacket NewSimPack = new CrossedRegionPacket(); - NewSimPack.AgentData = new CrossedRegionPacket.AgentDataBlock(); - NewSimPack.AgentData.AgentID = this.AgentID; - NewSimPack.AgentData.SessionID = this.SessionID; - NewSimPack.Info = new CrossedRegionPacket.InfoBlock(); - NewSimPack.Info.Position = newpos; - NewSimPack.Info.LookAt = new LLVector3(0.99f, 0.042f, 0); // copied from Avatar.cs - SHOULD BE DYNAMIC!!!!!!!!!! - NewSimPack.RegionData = new libsecondlife.Packets.CrossedRegionPacket.RegionDataBlock(); - NewSimPack.RegionData.RegionHandle = Helpers.UIntsToLong((uint)(Convert.ToInt32(borderingSim["region_locx"]) * 256), (uint)(Convert.ToInt32(borderingSim["region_locy"]) * 256)); - System.Net.IPAddress neighbourIP = System.Net.IPAddress.Parse((string)borderingSim["sim_ip"]); - byte[] byteIP = neighbourIP.GetAddressBytes(); - NewSimPack.RegionData.SimIP = (uint)byteIP[3] << 24; - NewSimPack.RegionData.SimIP += (uint)byteIP[2] << 16; - NewSimPack.RegionData.SimIP += (uint)byteIP[1] << 8; - NewSimPack.RegionData.SimIP += (uint)byteIP[0]; - NewSimPack.RegionData.SimPort = (ushort)Convert.ToInt32(borderingSim["sim_port"]); - NewSimPack.RegionData.SeedCapability = new byte[0]; - lock (PacketQueue) - { - ProcessOutPacket(NewSimPack); - DowngradeClient(); - } - } - } - } - } -} diff --git a/OpenSim.RegionServer/SimClient.PacketHandlers.cs b/OpenSim.RegionServer/SimClient.PacketHandlers.cs deleted file mode 100644 index 62919ba..0000000 --- a/OpenSim.RegionServer/SimClient.PacketHandlers.cs +++ /dev/null @@ -1,184 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using libsecondlife; -using libsecondlife.Packets; -using Nwc.XmlRpc; -using System.Net; -using System.Net.Sockets; -using System.IO; -using System.Threading; -using System.Timers; -using OpenSim.Framework.Interfaces; -using OpenSim.Framework.Types; -using OpenSim.Framework.Inventory; -using OpenSim.Framework.Utilities; -using OpenSim.world; -using OpenSim.Assets; - -namespace OpenSim -{ - public partial class SimClient - { - protected virtual void RegisterLocalPacketHandlers() - { - this.AddLocalPacketHandler(PacketType.LogoutRequest, this.Logout); - this.AddLocalPacketHandler(PacketType.AgentCachedTexture, this.AgentTextureCached); - this.AddLocalPacketHandler(PacketType.MultipleObjectUpdate, this.MultipleObjUpdate); - } - - protected virtual bool Logout(SimClient simClient, Packet packet) - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:ProcessInPacket() - Got a logout request"); - //send reply to let the client logout - LogoutReplyPacket logReply = new LogoutReplyPacket(); - logReply.AgentData.AgentID = this.AgentID; - logReply.AgentData.SessionID = this.SessionID; - logReply.InventoryData = new LogoutReplyPacket.InventoryDataBlock[1]; - logReply.InventoryData[0] = new LogoutReplyPacket.InventoryDataBlock(); - logReply.InventoryData[0].ItemID = LLUUID.Zero; - OutPacket(logReply); - //tell all clients to kill our object - KillObjectPacket kill = new KillObjectPacket(); - kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; - kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); - kill.ObjectData[0].ID = this.ClientAvatar.localid; - foreach (SimClient client in m_clientThreads.Values) - { - client.OutPacket(kill); - } - if (this.m_userServer != null) - { - this.m_inventoryCache.ClientLeaving(this.AgentID, this.m_userServer); - } - else - { - this.m_inventoryCache.ClientLeaving(this.AgentID, null); - } - - m_gridServer.LogoutSession(this.SessionID, this.AgentID, this.CircuitCode); - /*lock (m_world.Entities) - { - m_world.Entities.Remove(this.AgentID); - }*/ - m_world.RemoveViewerAgent(this); - //need to do other cleaning up here too - m_clientThreads.Remove(this.CircuitCode); - m_networkServer.RemoveClientCircuit(this.CircuitCode); - this.ClientThread.Abort(); - return true; - } - - protected bool AgentTextureCached(SimClient simclient, Packet packet) - { - // Console.WriteLine(packet.ToString()); - AgentCachedTexturePacket chechedtex = (AgentCachedTexturePacket)packet; - AgentCachedTextureResponsePacket cachedresp = new AgentCachedTextureResponsePacket(); - cachedresp.AgentData.AgentID = this.AgentID; - cachedresp.AgentData.SessionID = this.SessionID; - cachedresp.AgentData.SerialNum = this.cachedtextureserial; - this.cachedtextureserial++; - cachedresp.WearableData = new AgentCachedTextureResponsePacket.WearableDataBlock[chechedtex.WearableData.Length]; - for (int i = 0; i < chechedtex.WearableData.Length; i++) - { - cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex = chechedtex.WearableData[i].TextureIndex; - cachedresp.WearableData[i].TextureID = LLUUID.Zero; - cachedresp.WearableData[i].HostName = new byte[0]; - } - this.OutPacket(cachedresp); - return true; - } - - protected bool MultipleObjUpdate(SimClient simClient, Packet packet) - { - MultipleObjectUpdatePacket multipleupdate = (MultipleObjectUpdatePacket)packet; - for (int i = 0; i < multipleupdate.ObjectData.Length; i++) - { - if (multipleupdate.ObjectData[i].Type == 9) //change position - { - libsecondlife.LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID) - { - ((OpenSim.world.Primitive)ent).UpdatePosition(pos); - - } - } - //should update stored position of the prim - } - else if (multipleupdate.ObjectData[i].Type == 10)//rotation - { - libsecondlife.LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true); - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID) - { - ent.rotation = new Axiom.MathLib.Quaternion(rot.W, rot.X, rot.Y, rot.Z); - ((OpenSim.world.Primitive)ent).UpdateFlag = true; - } - } - } - else if (multipleupdate.ObjectData[i].Type == 13)//scale - { - - libsecondlife.LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == multipleupdate.ObjectData[i].ObjectLocalID) - { - ((OpenSim.world.Primitive)ent).Scale = scale; - } - } - } - } - return true; - } - - public void RequestMapLayer() //should be getting the map layer from the grid server - { - //send a layer covering the 800,800 - 1200,1200 area (should be covering the requested area) - MapLayerReplyPacket mapReply = new MapLayerReplyPacket(); - mapReply.AgentData.AgentID = this.AgentID; - mapReply.AgentData.Flags = 0; - mapReply.LayerData = new MapLayerReplyPacket.LayerDataBlock[1]; - mapReply.LayerData[0] = new MapLayerReplyPacket.LayerDataBlock(); - mapReply.LayerData[0].Bottom = 800; - mapReply.LayerData[0].Left = 800; - mapReply.LayerData[0].Top = 1200; - mapReply.LayerData[0].Right = 1200; - mapReply.LayerData[0].ImageID = new LLUUID("00000000-0000-0000-9999-000000000006"); - this.OutPacket(mapReply); - } - - public void RequestMapBlocks(int minX, int minY, int maxX, int maxY) - { - IList simMapProfiles = m_gridServer.RequestMapBlocks(minX, minY, maxX, maxY); - MapBlockReplyPacket mbReply = new MapBlockReplyPacket(); - mbReply.AgentData.AgentID = this.AgentID; - int len; - if (simMapProfiles == null) - len = 0; - else - len = simMapProfiles.Count; - - mbReply.Data = new MapBlockReplyPacket.DataBlock[len]; - int iii; - for (iii = 0; iii < len; iii++) - { - Hashtable mp = (Hashtable)simMapProfiles[iii]; - mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock(); - mbReply.Data[iii].Name = System.Text.Encoding.UTF8.GetBytes((string)mp["name"]); - mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]); - mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]); - mbReply.Data[iii].MapImageID = new LLUUID((string)mp["map-image-id"]); - mbReply.Data[iii].RegionFlags = System.Convert.ToUInt32(mp["region-flags"]); - mbReply.Data[iii].WaterHeight = System.Convert.ToByte(mp["water-height"]); - mbReply.Data[iii].X = System.Convert.ToUInt16(mp["x"]); - mbReply.Data[iii].Y = System.Convert.ToUInt16(mp["y"]); - } - this.OutPacket(mbReply); - } - } -} diff --git a/OpenSim.RegionServer/SimClient.ProcessPackets.cs b/OpenSim.RegionServer/SimClient.ProcessPackets.cs deleted file mode 100644 index c9592c2..0000000 --- a/OpenSim.RegionServer/SimClient.ProcessPackets.cs +++ /dev/null @@ -1,419 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using libsecondlife; -using libsecondlife.Packets; -using Nwc.XmlRpc; -using System.Net; -using System.Net.Sockets; -using System.IO; -using System.Threading; -using System.Timers; -using OpenSim.Framework.Interfaces; -using OpenSim.Framework.Types; -using OpenSim.Framework.Inventory; -using OpenSim.Framework.Utilities; -using OpenSim.world; -using OpenSim.Assets; - -namespace OpenSim -{ - public partial class SimClient - { - protected virtual void ProcessInPacket(Packet Pack) - { - ack_pack(Pack); - if (debug) - { - if (Pack.Type != PacketType.AgentUpdate) - { - Console.WriteLine(Pack.Type.ToString()); - } - } - - if (this.ProcessPacketMethod(Pack)) - { - //there is a handler registered that handled this packet type - return; - } - else - { - System.Text.Encoding _enc = System.Text.Encoding.ASCII; - - switch (Pack.Type) - { - case PacketType.CompleteAgentMovement: - if (this.m_child) this.UpgradeClient(); - ClientAvatar.CompleteMovement(m_world); - ClientAvatar.SendInitialPosition(); - this.EnableNeighbours(); - break; - case PacketType.RegionHandshakeReply: - m_world.SendLayerData(this); - break; - case PacketType.AgentWearablesRequest: - ClientAvatar.SendInitialAppearance(); - foreach (SimClient client in m_clientThreads.Values) - { - if (client.AgentID != this.AgentID) - { - ObjectUpdatePacket objupdate = client.ClientAvatar.CreateUpdatePacket(); - this.OutPacket(objupdate); - client.ClientAvatar.SendAppearanceToOtherAgent(this); - } - } - m_world.GetInitialPrims(this); - break; - case PacketType.AgentIsNowWearing: - AgentIsNowWearingPacket wear = (AgentIsNowWearingPacket)Pack; - //Console.WriteLine(Pack.ToString()); - break; - case PacketType.AgentSetAppearance: - AgentSetAppearancePacket appear = (AgentSetAppearancePacket)Pack; - // Console.WriteLine(appear.ToString()); - this.ClientAvatar.SetAppearance(appear); - break; - case PacketType.ObjectAdd: - m_world.AddNewPrim((ObjectAddPacket)Pack, this); - break; - case PacketType.ObjectLink: - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, Pack.ToString()); - ObjectLinkPacket link = (ObjectLinkPacket)Pack; - uint parentprimid = 0; - OpenSim.world.Primitive parentprim = null; - if (link.ObjectData.Length > 1) - { - parentprimid = link.ObjectData[0].ObjectLocalID; - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == parentprimid) - { - parentprim = (OpenSim.world.Primitive)ent; - - } - } - for (int i = 1; i < link.ObjectData.Length; i++) - { - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == link.ObjectData[i].ObjectLocalID) - { - ((OpenSim.world.Primitive)ent).MakeParent(parentprim); - } - } - } - } - break; - case PacketType.ObjectScale: - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, Pack.ToString()); - break; - case PacketType.ObjectShape: - ObjectShapePacket shape = (ObjectShapePacket)Pack; - for (int i = 0; i < shape.ObjectData.Length; i++) - { - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == shape.ObjectData[i].ObjectLocalID) - { - ((OpenSim.world.Primitive)ent).UpdateShape(shape.ObjectData[i]); - } - } - } - break; - case PacketType.RequestImage: - RequestImagePacket imageRequest = (RequestImagePacket)Pack; - for (int i = 0; i < imageRequest.RequestImage.Length; i++) - { - m_assetCache.AddTextureRequest(this, imageRequest.RequestImage[i].Image); - } - break; - case PacketType.TransferRequest: - //Console.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request"); - TransferRequestPacket transfer = (TransferRequestPacket)Pack; - m_assetCache.AddAssetRequest(this, transfer); - break; - case PacketType.AgentUpdate: - ClientAvatar.HandleUpdate((AgentUpdatePacket)Pack); - break; - case PacketType.ObjectImage: - ObjectImagePacket imagePack = (ObjectImagePacket)Pack; - for (int i = 0; i < imagePack.ObjectData.Length; i++) - { - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == imagePack.ObjectData[i].ObjectLocalID) - { - ((OpenSim.world.Primitive)ent).UpdateTexture(imagePack.ObjectData[i].TextureEntry); - } - } - } - break; - case PacketType.ObjectFlagUpdate: - ObjectFlagUpdatePacket flags = (ObjectFlagUpdatePacket)Pack; - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == flags.AgentData.ObjectLocalID) - { - ((OpenSim.world.Primitive)ent).UpdateObjectFlags(flags); - } - } - break; - case PacketType.AssetUploadRequest: - AssetUploadRequestPacket request = (AssetUploadRequestPacket)Pack; - this.UploadAssets.HandleUploadPacket(request, request.AssetBlock.TransactionID.Combine(this.SecureSessionID)); - break; - case PacketType.RequestXfer: - //Console.WriteLine(Pack.ToString()); - break; - case PacketType.SendXferPacket: - this.UploadAssets.HandleXferPacket((SendXferPacketPacket)Pack); - break; - case PacketType.CreateInventoryFolder: - CreateInventoryFolderPacket invFolder = (CreateInventoryFolderPacket)Pack; - m_inventoryCache.CreateNewInventoryFolder(this, invFolder.FolderData.FolderID, (ushort)invFolder.FolderData.Type, Util.FieldToString(invFolder.FolderData.Name), invFolder.FolderData.ParentID); - //Console.WriteLine(Pack.ToString()); - break; - case PacketType.CreateInventoryItem: - //Console.WriteLine(Pack.ToString()); - CreateInventoryItemPacket createItem = (CreateInventoryItemPacket)Pack; - if (createItem.InventoryBlock.TransactionID != LLUUID.Zero) - { - this.UploadAssets.CreateInventoryItem(createItem); - } - else - { - // Console.Write(Pack.ToString()); - this.CreateInventoryItem(createItem); - } - break; - case PacketType.FetchInventory: - //Console.WriteLine("fetch item packet"); - FetchInventoryPacket FetchInventory = (FetchInventoryPacket)Pack; - m_inventoryCache.FetchInventory(this, FetchInventory); - break; - case PacketType.FetchInventoryDescendents: - FetchInventoryDescendentsPacket Fetch = (FetchInventoryDescendentsPacket)Pack; - m_inventoryCache.FetchInventoryDescendents(this, Fetch); - break; - case PacketType.UpdateInventoryItem: - UpdateInventoryItemPacket update = (UpdateInventoryItemPacket)Pack; - //Console.WriteLine(Pack.ToString()); - for (int i = 0; i < update.InventoryData.Length; i++) - { - if (update.InventoryData[i].TransactionID != LLUUID.Zero) - { - AssetBase asset = m_assetCache.GetAsset(update.InventoryData[i].TransactionID.Combine(this.SecureSessionID)); - if (asset != null) - { - // Console.WriteLine("updating inventory item, found asset" + asset.FullID.ToStringHyphenated() + " already in cache"); - m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset); - } - else - { - asset = this.UploadAssets.AddUploadToAssetCache(update.InventoryData[i].TransactionID); - if (asset != null) - { - //Console.WriteLine("updating inventory item, adding asset" + asset.FullID.ToStringHyphenated() + " to cache"); - m_inventoryCache.UpdateInventoryItemAsset(this, update.InventoryData[i].ItemID, asset); - } - else - { - //Console.WriteLine("trying to update inventory item, but asset is null"); - } - } - } - else - { - m_inventoryCache.UpdateInventoryItemDetails(this, update.InventoryData[i].ItemID, update.InventoryData[i]); ; - } - } - break; - case PacketType.ViewerEffect: - ViewerEffectPacket viewer = (ViewerEffectPacket)Pack; - foreach (SimClient client in m_clientThreads.Values) - { - if (client.AgentID != this.AgentID) - { - viewer.AgentData.AgentID = client.AgentID; - viewer.AgentData.SessionID = client.SessionID; - client.OutPacket(viewer); - } - } - break; - case PacketType.RequestTaskInventory: - // Console.WriteLine(Pack.ToString()); - RequestTaskInventoryPacket requesttask = (RequestTaskInventoryPacket)Pack; - ReplyTaskInventoryPacket replytask = new ReplyTaskInventoryPacket(); - bool foundent = false; - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == requesttask.InventoryData.LocalID) - { - replytask.InventoryData.TaskID = ent.uuid; - replytask.InventoryData.Serial = 0; - replytask.InventoryData.Filename = new byte[0]; - foundent = true; - } - } - if (foundent) - { - this.OutPacket(replytask); - } - break; - case PacketType.UpdateTaskInventory: - // Console.WriteLine(Pack.ToString()); - UpdateTaskInventoryPacket updatetask = (UpdateTaskInventoryPacket)Pack; - AgentInventory myinventory = this.m_inventoryCache.GetAgentsInventory(this.AgentID); - if (myinventory != null) - { - if (updatetask.UpdateData.Key == 0) - { - if (myinventory.InventoryItems[updatetask.InventoryData.ItemID] != null) - { - if (myinventory.InventoryItems[updatetask.InventoryData.ItemID].Type == 7) - { - LLUUID noteaid = myinventory.InventoryItems[updatetask.InventoryData.ItemID].AssetID; - AssetBase assBase = this.m_assetCache.GetAsset(noteaid); - if (assBase != null) - { - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == updatetask.UpdateData.LocalID) - { - if (ent is OpenSim.world.Primitive) - { - this.m_world.AddScript(ent, Util.FieldToString(assBase.Data)); - } - } - } - } - } - } - } - } - break; - case PacketType.AgentAnimation: - if (!m_child) - { - AgentAnimationPacket AgentAni = (AgentAnimationPacket)Pack; - for (int i = 0; i < AgentAni.AnimationList.Length; i++) - { - if (AgentAni.AnimationList[i].StartAnim) - { - ClientAvatar.current_anim = AgentAni.AnimationList[i].AnimID; - ClientAvatar.anim_seq = 1; - ClientAvatar.SendAnimPack(); - } - } - } - break; - case PacketType.ObjectSelect: - ObjectSelectPacket incomingselect = (ObjectSelectPacket)Pack; - for (int i = 0; i < incomingselect.ObjectData.Length; i++) - { - foreach (Entity ent in m_world.Entities.Values) - { - if (ent.localid == incomingselect.ObjectData[i].ObjectLocalID) - { - ((OpenSim.world.Primitive)ent).GetProperites(this); - break; - } - } - } - break; - case PacketType.MapLayerRequest: - this.RequestMapLayer(); - break; - case PacketType.MapBlockRequest: - MapBlockRequestPacket MapRequest = (MapBlockRequestPacket)Pack; - - this.RequestMapBlocks(MapRequest.PositionData.MinX, MapRequest.PositionData.MinY, MapRequest.PositionData.MaxX, MapRequest.PositionData.MaxY); - break; - - case PacketType.TeleportLandmarkRequest: - TeleportLandmarkRequestPacket tpReq = (TeleportLandmarkRequestPacket)Pack; - - TeleportStartPacket tpStart = new TeleportStartPacket(); - tpStart.Info.TeleportFlags = 8; // tp via lm - this.OutPacket(tpStart); - - TeleportProgressPacket tpProgress = new TeleportProgressPacket(); - tpProgress.Info.Message = (new System.Text.ASCIIEncoding()).GetBytes("sending_landmark"); - tpProgress.Info.TeleportFlags = 8; - tpProgress.AgentData.AgentID = tpReq.Info.AgentID; - this.OutPacket(tpProgress); - - // Fetch landmark - LLUUID lmid = tpReq.Info.LandmarkID; - AssetBase lma = this.m_assetCache.GetAsset(lmid); - if (lma != null) - { - AssetLandmark lm = new AssetLandmark(lma); - - if (lm.RegionID == m_regionData.SimUUID) - { - TeleportLocalPacket tpLocal = new TeleportLocalPacket(); - - tpLocal.Info.AgentID = tpReq.Info.AgentID; - tpLocal.Info.TeleportFlags = 8; // Teleport via landmark - tpLocal.Info.LocationID = 2; - tpLocal.Info.Position = lm.Position; - OutPacket(tpLocal); - } - else - { - TeleportCancelPacket tpCancel = new TeleportCancelPacket(); - tpCancel.Info.AgentID = tpReq.Info.AgentID; - tpCancel.Info.SessionID = tpReq.Info.SessionID; - OutPacket(tpCancel); - } - } - else - { - Console.WriteLine("Cancelling Teleport - fetch asset not yet implemented"); - - TeleportCancelPacket tpCancel = new TeleportCancelPacket(); - tpCancel.Info.AgentID = tpReq.Info.AgentID; - tpCancel.Info.SessionID = tpReq.Info.SessionID; - OutPacket(tpCancel); - } - break; - - case PacketType.TeleportLocationRequest: - TeleportLocationRequestPacket tpLocReq = (TeleportLocationRequestPacket)Pack; - Console.WriteLine(tpLocReq.ToString()); - - tpStart = new TeleportStartPacket(); - tpStart.Info.TeleportFlags = 16; // Teleport via location - Console.WriteLine(tpStart.ToString()); - OutPacket(tpStart); - - if (m_regionData.RegionHandle != tpLocReq.Info.RegionHandle) - { - /* m_gridServer.getRegion(tpLocReq.Info.RegionHandle); */ - Console.WriteLine("Inter-sim teleport not yet implemented"); - TeleportCancelPacket tpCancel = new TeleportCancelPacket(); - tpCancel.Info.SessionID = tpLocReq.AgentData.SessionID; - tpCancel.Info.AgentID = tpLocReq.AgentData.AgentID; - - OutPacket(tpCancel); - } - else - { - Console.WriteLine("Local teleport"); - TeleportLocalPacket tpLocal = new TeleportLocalPacket(); - tpLocal.Info.AgentID = tpLocReq.AgentData.AgentID; - tpLocal.Info.TeleportFlags = tpStart.Info.TeleportFlags; - tpLocal.Info.LocationID = 2; - tpLocal.Info.LookAt = tpLocReq.Info.LookAt; - tpLocal.Info.Position = tpLocReq.Info.Position; - OutPacket(tpLocal); - - } - - break; - } - } - } - } -} diff --git a/OpenSim.RegionServer/SimClient.cs b/OpenSim.RegionServer/SimClient.cs deleted file mode 100644 index 3b243cf..0000000 --- a/OpenSim.RegionServer/SimClient.cs +++ /dev/null @@ -1,662 +0,0 @@ -/* -Copyright (c) OpenSim project, http://osgrid.org/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are met: -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* * Neither the name of the nor the -* names of its contributors may be used to endorse or promote products -* derived from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY ``AS IS'' AND ANY -* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY -* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -using System; -using System.Collections; -using System.Collections.Generic; -using libsecondlife; -using libsecondlife.Packets; -using Nwc.XmlRpc; -using System.Net; -using System.Net.Sockets; -using System.IO; -using System.Threading; -using System.Timers; -using OpenSim.Framework.Interfaces; -using OpenSim.Framework.Types; -using OpenSim.Framework.Inventory; -using OpenSim.Framework.Utilities; -using OpenSim.world; -using OpenSim.Assets; - -namespace OpenSim -{ - public delegate bool PacketMethod(SimClient simClient, Packet packet); - - /// - /// Handles new client connections - /// Constructor takes a single Packet and authenticates everything - /// - public partial class SimClient - { - public LLUUID AgentID; - public LLUUID SessionID; - public LLUUID SecureSessionID = LLUUID.Zero; - public bool m_child; - public uint CircuitCode; - public world.Avatar ClientAvatar; - private UseCircuitCodePacket cirpack; - public Thread ClientThread; - public EndPoint userEP; - public LLVector3 startpos; - private BlockingQueue PacketQueue; - private Dictionary PendingAcks = new Dictionary(); - private Dictionary NeedAck = new Dictionary(); - //private Dictionary UploadedAssets = new Dictionary(); - private System.Timers.Timer AckTimer; - private uint Sequence = 0; - private object SequenceLock = new object(); - private const int MAX_APPENDED_ACKS = 10; - private const int RESEND_TIMEOUT = 4000; - private const int MAX_SEQUENCE = 0xFFFFFF; - private AgentAssetUpload UploadAssets; - private LLUUID newAssetFolder = LLUUID.Zero; - private bool debug = false; - private World m_world; - private Dictionary m_clientThreads; - private AssetCache m_assetCache; - private IGridServer m_gridServer; - private IUserServer m_userServer = null; - private OpenSimNetworkHandler m_networkServer; - private InventoryCache m_inventoryCache; - public bool m_sandboxMode; - private int cachedtextureserial = 0; - private RegionInfo m_regionData; - protected AuthenticateSessionsBase m_authenticateSessionsHandler; - - protected static Dictionary PacketHandlers = new Dictionary(); //Global/static handlers for all clients - - protected Dictionary m_packetHandlers = new Dictionary(); //local handlers for this instance - - public IUserServer UserServer - { - set - { - this.m_userServer = value; - } - } - - public SimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack, World world, Dictionary clientThreads, AssetCache assetCache, IGridServer gridServer, OpenSimNetworkHandler application, InventoryCache inventoryCache, bool sandboxMode, bool child, RegionInfo regionDat, AuthenticateSessionsBase authenSessions) - { - m_world = world; - m_clientThreads = clientThreads; - m_assetCache = assetCache; - m_gridServer = gridServer; - m_networkServer = application; - m_inventoryCache = inventoryCache; - m_sandboxMode = sandboxMode; - m_child = child; - m_regionData = regionDat; - m_authenticateSessionsHandler = authenSessions; - - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs - Started up new client thread to handle incoming request"); - cirpack = initialcirpack; - userEP = remoteEP; - - if (m_gridServer.GetName() == "Remote") - { - this.m_child = m_authenticateSessionsHandler.GetAgentChildStatus(initialcirpack.CircuitCode.Code); - this.startpos = m_authenticateSessionsHandler.GetPosition(initialcirpack.CircuitCode.Code); - //Console.WriteLine("start pos is " + this.startpos.X + " , " + this.startpos.Y + " , " + this.startpos.Z); - } - else - { - this.startpos = new LLVector3(128, 128, m_world.Terrain[(int)128, (int)128] + 15.0f); // new LLVector3(128.0f, 128.0f, 60f); - } - - PacketQueue = new BlockingQueue(); - - this.UploadAssets = new AgentAssetUpload(this, m_assetCache, m_inventoryCache); - AckTimer = new System.Timers.Timer(500); - AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed); - AckTimer.Start(); - - this.RegisterLocalPacketHandlers(); - - ClientThread = new Thread(new ThreadStart(AuthUser)); - ClientThread.IsBackground = true; - ClientThread.Start(); - } - - # region Client Methods - public void UpgradeClient() - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "SimClient.cs:UpgradeClient() - upgrading child to full agent"); - this.m_child = false; - this.m_world.RemoveViewerAgent(this); - if (!this.m_sandboxMode) - { - this.startpos = m_authenticateSessionsHandler.GetPosition(CircuitCode); - m_authenticateSessionsHandler.UpdateAgentChildStatus(CircuitCode, false); - //Console.WriteLine("upgrade start pos is " + this.startpos.X + " , " + this.startpos.Y + " , " + this.startpos.Z); - } - this.InitNewClient(); - } - - public void DowngradeClient() - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "SimClient.cs:UpgradeClient() - changing full agent to child"); - this.m_child = true; - this.m_world.RemoveViewerAgent(this); - this.m_world.AddViewerAgent(this); - } - - public void KillClient() - { - KillObjectPacket kill = new KillObjectPacket(); - kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; - kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); - kill.ObjectData[0].ID = this.ClientAvatar.localid; - foreach (SimClient client in m_clientThreads.Values) - { - client.OutPacket(kill); - } - if (this.m_userServer != null) - { - this.m_inventoryCache.ClientLeaving(this.AgentID, this.m_userServer); - } - else - { - this.m_inventoryCache.ClientLeaving(this.AgentID, null); - } - - m_world.RemoveViewerAgent(this); - - m_clientThreads.Remove(this.CircuitCode); - m_networkServer.RemoveClientCircuit(this.CircuitCode); - this.ClientThread.Abort(); - } - #endregion - - # region Packet Handling - public static bool AddPacketHandler(PacketType packetType, PacketMethod handler) - { - bool result = false; - lock (PacketHandlers) - { - if (!PacketHandlers.ContainsKey(packetType)) - { - PacketHandlers.Add(packetType, handler); - result = true; - } - } - return result; - } - - public bool AddLocalPacketHandler(PacketType packetType, PacketMethod handler) - { - bool result = false; - lock (m_packetHandlers) - { - if (!m_packetHandlers.ContainsKey(packetType)) - { - m_packetHandlers.Add(packetType, handler); - result = true; - } - } - return result; - } - - protected virtual bool ProcessPacketMethod(Packet packet) - { - bool result = false; - bool found = false; - PacketMethod method; - if (m_packetHandlers.TryGetValue(packet.Type, out method)) - { - //there is a local handler for this packet type - result = method(this, packet); - } - else - { - //there is not a local handler so see if there is a Global handler - lock (PacketHandlers) - { - found = PacketHandlers.TryGetValue(packet.Type, out method); - } - if (found) - { - result = method(this, packet); - } - } - return result; - } - - # endregion - - # region Low Level Packet Methods - - private void ack_pack(Packet Pack) - { - if (Pack.Header.Reliable) - { - libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket(); - ack_it.Packets = new PacketAckPacket.PacketsBlock[1]; - ack_it.Packets[0] = new PacketAckPacket.PacketsBlock(); - ack_it.Packets[0].ID = Pack.Header.Sequence; - ack_it.Header.Reliable = false; - - OutPacket(ack_it); - - } - /* - if (Pack.Header.Reliable) - { - lock (PendingAcks) - { - uint sequence = (uint)Pack.Header.Sequence; - if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; } - } - }*/ - } - - private void ResendUnacked() - { - int now = Environment.TickCount; - - lock (NeedAck) - { - foreach (Packet packet in NeedAck.Values) - { - if ((now - packet.TickCount > RESEND_TIMEOUT) && (!packet.Header.Resent)) - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.VERBOSE, "Resending " + packet.Type.ToString() + " packet, " + - (now - packet.TickCount) + "ms have passed"); - - packet.Header.Resent = true; - OutPacket(packet); - } - } - } - } - - private void SendAcks() - { - lock (PendingAcks) - { - if (PendingAcks.Count > 0) - { - if (PendingAcks.Count > 250) - { - // FIXME: Handle the odd case where we have too many pending ACKs queued up - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.VERBOSE, "Too many ACKs queued up!"); - return; - } - - //OpenSim.Framework.Console.MainConsole.Instance.WriteLine("Sending PacketAck"); - - - int i = 0; - PacketAckPacket acks = new PacketAckPacket(); - acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count]; - - foreach (uint ack in PendingAcks.Values) - { - acks.Packets[i] = new PacketAckPacket.PacketsBlock(); - acks.Packets[i].ID = ack; - i++; - } - - acks.Header.Reliable = false; - OutPacket(acks); - - PendingAcks.Clear(); - } - } - } - - private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea) - { - SendAcks(); - ResendUnacked(); - } - - # endregion - - #region Packet Queue Processing - - protected virtual void ProcessOutPacket(Packet Pack) - { - // Keep track of when this packet was sent out - Pack.TickCount = Environment.TickCount; - - if (!Pack.Header.Resent) - { - // Set the sequence number - lock (SequenceLock) - { - if (Sequence >= MAX_SEQUENCE) - Sequence = 1; - else - Sequence++; - Pack.Header.Sequence = Sequence; - } - - if (Pack.Header.Reliable) //DIRTY HACK - { - lock (NeedAck) - { - if (!NeedAck.ContainsKey(Pack.Header.Sequence)) - { - try - { - NeedAck.Add(Pack.Header.Sequence, Pack); - } - catch (Exception e) // HACKY - { - e.ToString(); - // Ignore - // Seems to throw a exception here occasionally - // of 'duplicate key' despite being locked. - // !?!?!? - } - } - else - { - // Client.Log("Attempted to add a duplicate sequence number (" + - // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " + - // packet.Type.ToString(), Helpers.LogLevel.Warning); - } - } - - // Don't append ACKs to resent packets, in case that's what was causing the - // delivery to fail - if (!Pack.Header.Resent) - { - // Append any ACKs that need to be sent out to this packet - lock (PendingAcks) - { - if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS && - Pack.Type != PacketType.PacketAck && - Pack.Type != PacketType.LogoutRequest) - { - Pack.Header.AckList = new uint[PendingAcks.Count]; - int i = 0; - - foreach (uint ack in PendingAcks.Values) - { - Pack.Header.AckList[i] = ack; - i++; - } - - PendingAcks.Clear(); - Pack.Header.AppendedAcks = true; - } - } - } - } - } - - byte[] ZeroOutBuffer = new byte[4096]; - byte[] sendbuffer; - sendbuffer = Pack.ToBytes(); - - try - { - if (Pack.Header.Zerocoded) - { - int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer); - m_networkServer.SendPacketTo(ZeroOutBuffer, packetsize, SocketFlags.None, CircuitCode);//userEP); - } - else - { - m_networkServer.SendPacketTo(sendbuffer, sendbuffer.Length, SocketFlags.None, CircuitCode); //userEP); - } - } - catch (Exception) - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.MEDIUM, "OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread"); - ClientThread.Abort(); - } - - } - - public virtual void InPacket(Packet NewPack) - { - // Handle appended ACKs - if (NewPack.Header.AppendedAcks) - { - lock (NeedAck) - { - foreach (uint ack in NewPack.Header.AckList) - { - NeedAck.Remove(ack); - } - } - } - - // Handle PacketAck packets - if (NewPack.Type == PacketType.PacketAck) - { - PacketAckPacket ackPacket = (PacketAckPacket)NewPack; - - lock (NeedAck) - { - foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) - { - NeedAck.Remove(block.ID); - } - } - } - else if ((NewPack.Type == PacketType.StartPingCheck)) - { - //reply to pingcheck - libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack; - libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket(); - endPing.PingID.PingID = startPing.PingID.PingID; - OutPacket(endPing); - } - else - { - QueItem item = new QueItem(); - item.Packet = NewPack; - item.Incoming = true; - this.PacketQueue.Enqueue(item); - } - - } - - public virtual void OutPacket(Packet NewPack) - { - QueItem item = new QueItem(); - item.Packet = NewPack; - item.Incoming = false; - this.PacketQueue.Enqueue(item); - } - - protected virtual void ClientLoop() - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:ClientLoop() - Entered loop"); - while (true) - { - QueItem nextPacket = PacketQueue.Dequeue(); - if (nextPacket.Incoming) - { - //is a incoming packet - ProcessInPacket(nextPacket.Packet); - } - else - { - //is a out going packet - ProcessOutPacket(nextPacket.Packet); - } - } - } - - #endregion - - # region Setup - - protected virtual void InitNewClient() - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "OpenSimClient.cs:InitNewClient() - Adding viewer agent to world"); - - m_world.AddViewerAgent(this); - world.Entity tempent = m_world.Entities[this.AgentID]; - - this.ClientAvatar = (world.Avatar)tempent; - } - - protected virtual void AuthUser() - { - // AuthenticateResponse sessionInfo = m_gridServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code); - AuthenticateResponse sessionInfo = this.m_networkServer.AuthenticateSession(cirpack.CircuitCode.SessionID, cirpack.CircuitCode.ID, cirpack.CircuitCode.Code); - if (!sessionInfo.Authorised) - { - //session/circuit not authorised - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.NORMAL, "OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString()); - ClientThread.Abort(); - } - else - { - OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.NORMAL, "OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString()); - //session is authorised - this.AgentID = cirpack.CircuitCode.ID; - this.SessionID = cirpack.CircuitCode.SessionID; - this.CircuitCode = cirpack.CircuitCode.Code; - InitNewClient(); //shouldn't be called here as we might be a child agent and not want a full avatar - this.ClientAvatar.firstname = sessionInfo.LoginInfo.First; - this.ClientAvatar.lastname = sessionInfo.LoginInfo.Last; - if (sessionInfo.LoginInfo.SecureSession != LLUUID.Zero) - { - this.SecureSessionID = sessionInfo.LoginInfo.SecureSession; - } - - // Create Inventory, currently only works for sandbox mode - if (m_sandboxMode) - { - this.SetupInventory(sessionInfo); - } - - ClientLoop(); - } - } - # endregion - - #region Inventory Creation - private void SetupInventory(AuthenticateResponse sessionInfo) - { - AgentInventory inventory = null; - if (sessionInfo.LoginInfo.InventoryFolder != null) - { - inventory = this.CreateInventory(sessionInfo.LoginInfo.InventoryFolder); - if (sessionInfo.LoginInfo.BaseFolder != null) - { - if (!inventory.HasFolder(sessionInfo.LoginInfo.BaseFolder)) - { - m_inventoryCache.CreateNewInventoryFolder(this, sessionInfo.LoginInfo.BaseFolder); - } - this.newAssetFolder = sessionInfo.LoginInfo.BaseFolder; - AssetBase[] inventorySet = m_assetCache.CreateNewInventorySet(this.AgentID); - if (inventorySet != null) - { - for (int i = 0; i < inventorySet.Length; i++) - { - if (inventorySet[i] != null) - { - m_inventoryCache.AddNewInventoryItem(this, sessionInfo.LoginInfo.BaseFolder, inventorySet[i]); - } - } - } - } - } - } - private AgentInventory CreateInventory(LLUUID baseFolder) - { - AgentInventory inventory = null; - if (this.m_userServer != null) - { - // a user server is set so request the inventory from it - Console.WriteLine("getting inventory from user server"); - inventory = m_inventoryCache.FetchAgentsInventory(this.AgentID, m_userServer); - } - else - { - inventory = new AgentInventory(); - inventory.AgentID = this.AgentID; - inventory.CreateRootFolder(this.AgentID, false); - m_inventoryCache.AddNewAgentsInventory(inventory); - m_inventoryCache.CreateNewInventoryFolder(this, baseFolder); - } - return inventory; - } - - private void CreateInventoryItem(CreateInventoryItemPacket packet) - { - if (!(packet.InventoryBlock.Type == 3 || packet.InventoryBlock.Type == 7)) - { - System.Console.WriteLine("Attempted to create " + Util.FieldToString(packet.InventoryBlock.Name) + " in inventory. Unsupported type"); - return; - } - - //lets try this out with creating a notecard - AssetBase asset = new AssetBase(); - - asset.Name = Util.FieldToString(packet.InventoryBlock.Name); - asset.Description = Util.FieldToString(packet.InventoryBlock.Description); - asset.InvType = packet.InventoryBlock.InvType; - asset.Type = packet.InventoryBlock.Type; - asset.FullID = LLUUID.Random(); - - switch (packet.InventoryBlock.Type) - { - case 7: // Notecard - asset.Data = new byte[0]; - break; - - case 3: // Landmark - String content; - content = "Landmark version 2\n"; - content += "region_id " + m_regionData.SimUUID + "\n"; - String strPos = String.Format("%.2f %.2f %.2f>", - this.ClientAvatar.Pos.X, - this.ClientAvatar.Pos.Y, - this.ClientAvatar.Pos.Z); - content += "local_pos " + strPos + "\n"; - asset.Data = (new System.Text.ASCIIEncoding()).GetBytes(content); - break; - default: - break; - } - m_assetCache.AddAsset(asset); - m_inventoryCache.AddNewInventoryItem(this, packet.InventoryBlock.FolderID, asset); - } - #endregion - - #region Nested Classes - - public class QueItem - { - public QueItem() - { - } - - public Packet Packet; - public bool Incoming; - } - #endregion - } -} diff --git a/OpenSim.RegionServer/SimClientBase.cs b/OpenSim.RegionServer/SimClientBase.cs deleted file mode 100644 index d0dd381..0000000 --- a/OpenSim.RegionServer/SimClientBase.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using libsecondlife; -using libsecondlife.Packets; - -namespace OpenSim -{ - public class SimClientBase - { - - protected virtual void ProcessInPacket(Packet Pack) - { - - } - - protected virtual void ProcessOutPacket(Packet Pack) - { - - } - - public virtual void InPacket(Packet NewPack) - { - - } - - public virtual void OutPacket(Packet NewPack) - { - - } - } -} diff --git a/OpenSim.RegionServer/UDPServer.cs b/OpenSim.RegionServer/UDPServer.cs index 0bab05a..3a93e66 100644 --- a/OpenSim.RegionServer/UDPServer.cs +++ b/OpenSim.RegionServer/UDPServer.cs @@ -133,7 +133,7 @@ namespace OpenSim this.clientCircuits.Add(epSender, useCircuit.CircuitCode.Code); bool isChildAgent = false; - SimClient newuser = new SimClient(epSender, useCircuit, m_localWorld, _packetServer.ClientThreads, m_assetCache, m_gridServers.GridServer, this, m_inventoryCache, m_sandbox, isChildAgent, this.m_regionData, m_authenticateSessionsClass); + ClientView newuser = new ClientView(epSender, useCircuit, m_localWorld, _packetServer.ClientThreads, m_assetCache, m_gridServers.GridServer, this, m_inventoryCache, m_sandbox, isChildAgent, this.m_regionData, m_authenticateSessionsClass); if ((this.m_gridServers.UserServer != null) && (user_accounts)) { newuser.UserServer = this.m_gridServers.UserServer; diff --git a/OpenSim.RegionServer/world/Avatar.Update.cs b/OpenSim.RegionServer/world/Avatar.Update.cs index ba2965d..75f0bb4 100644 --- a/OpenSim.RegionServer/world/Avatar.Update.cs +++ b/OpenSim.RegionServer/world/Avatar.Update.cs @@ -28,9 +28,10 @@ namespace OpenSim.world terse.RegionData.TimeDilation = 64096; terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; terse.ObjectData[0] = terseBlock; - foreach (SimClient client in m_clientThreads.Values) + List avList = this.m_world.RequestAvatarList(); + foreach (Avatar client in avList) { - client.OutPacket(terse); + client.SendPacketToViewer(terse); } updateflag = false; @@ -51,9 +52,10 @@ namespace OpenSim.world terse.RegionData.TimeDilation = 64096; terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; terse.ObjectData[0] = terseBlock; - foreach (SimClient client in m_clientThreads.Values) + List avList = this.m_world.RequestAvatarList(); + foreach (Avatar client in avList) { - client.OutPacket(terse); + client.SendPacketToViewer(terse); } _updateCount = 0; } @@ -134,15 +136,13 @@ namespace OpenSim.world byte[] pb = pos2.GetBytes(); Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); m_world._localNumber++; - foreach (SimClient client in m_clientThreads.Values) + + List avList = this.m_world.RequestAvatarList(); + foreach (Avatar client in avList) { - client.OutPacket(objupdate); - if (client.AgentID != ControllingClient.AgentID) + client.SendPacketToViewer(objupdate); + if (client.ControllingClient.AgentID != this.ControllingClient.AgentID) { - //the below line is already in Simclient.cs at line number 245 , directly below the call to this method - //if there is a problem/bug with that , then lets fix it there rather than duplicating it here - //client.ClientAvatar.SendAppearanceToOtherAgent(this.ControllingClient); - SendAppearanceToOtherAgent(client); } } @@ -169,30 +169,12 @@ namespace OpenSim.world ControllingClient.OutPacket(aw); } - public void SendAppearanceToOtherAgent(SimClient userInfo) + public void SendAppearanceToOtherAgent(Avatar avatarInfo) { AvatarAppearancePacket avp = new AvatarAppearancePacket(); avp.VisualParam = new AvatarAppearancePacket.VisualParamBlock[218]; avp.ObjectData.TextureEntry = this.avatarAppearanceTexture.ToBytes(); - //a wearable update packets should only be sent about the viewers/agents own avatar not for other avatars - //but it seems that the following code only created the packets and never actually sent them anyway - /*AgentWearablesUpdatePacket aw = new AgentWearablesUpdatePacket(); - aw.AgentData.AgentID = this.ControllingClient.AgentID; - aw.AgentData.SessionID = userInfo.SessionID; - aw.AgentData.SerialNum = 0; //removed the use of a random number as a random number could be less than the last number, should have a counter variable for this - - aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[13]; - AgentWearablesUpdatePacket.WearableDataBlock awb; - for (int i = 0; i < 13; i++) - { - awb = new AgentWearablesUpdatePacket.WearableDataBlock(); - awb.WearableType = (byte)i; - awb.AssetID = this.Wearables[i].AssetID; - awb.ItemID = this.Wearables[i].ItemID; - aw.WearableData[i] = awb; - }*/ - AvatarAppearancePacket.VisualParamBlock avblock = null; for (int i = 0; i < 218; i++) { @@ -203,7 +185,7 @@ namespace OpenSim.world avp.Sender.IsTrial = false; avp.Sender.ID = ControllingClient.AgentID; - userInfo.OutPacket(avp); + avatarInfo.SendPacketToViewer(avp); } public void SetAppearance(AgentSetAppearancePacket appear) @@ -214,9 +196,11 @@ namespace OpenSim.world { this.visualParams[i] = appear.VisualParam[i].ParamValue; } - foreach (SimClient client in m_clientThreads.Values) + + List avList = this.m_world.RequestAvatarList(); + foreach (Avatar client in avList) { - if (client.AgentID != ControllingClient.AgentID) + if (client.ControllingClient.AgentID != this.ControllingClient.AgentID) { SendAppearanceToOtherAgent(client); } @@ -320,11 +304,12 @@ namespace OpenSim.world ani.AnimationList[0].AnimID = this.current_anim; ani.AnimationList[0].AnimSequenceID = this.anim_seq; - //ControllingClient.OutPacket(ani); - foreach (SimClient client in m_clientThreads.Values) + List avList = this.m_world.RequestAvatarList(); + foreach (Avatar client in avList) { - client.OutPacket(ani); + client.SendPacketToViewer(ani); } + } } diff --git a/OpenSim.RegionServer/world/Avatar.cs b/OpenSim.RegionServer/world/Avatar.cs index c684c45..55e5ae4 100644 --- a/OpenSim.RegionServer/world/Avatar.cs +++ b/OpenSim.RegionServer/world/Avatar.cs @@ -16,7 +16,7 @@ namespace OpenSim.world public static AvatarAnimations Animations; public string firstname; public string lastname; - public SimClient ControllingClient; + public ClientView ControllingClient; public LLUUID current_anim; public int anim_seq; private static libsecondlife.Packets.ObjectUpdatePacket.ObjectDataBlock AvatarTemplate; @@ -30,16 +30,16 @@ namespace OpenSim.world private AvatarWearable[] Wearables; private LLVector3 positionLastFrame = new LLVector3(0, 0, 0); private ulong m_regionHandle; - private Dictionary m_clientThreads; + //private Dictionary m_clientThreads; private string m_regionName; private ushort m_regionWaterHeight; private bool m_regionTerraform; //private bool childShadowAvatar = false; - public Avatar(SimClient TheClient, World world, string regionName, Dictionary clientThreads, ulong regionHandle, bool regionTerraform, ushort regionWater) + public Avatar(ClientView TheClient, World world, string regionName, Dictionary clientThreads, ulong regionHandle, bool regionTerraform, ushort regionWater) { m_world = world; - m_clientThreads = clientThreads; + // m_clientThreads = clientThreads; m_regionName = regionName; m_regionHandle = regionHandle; m_regionTerraform = regionTerraform; diff --git a/OpenSim.RegionServer/world/Primitive.cs b/OpenSim.RegionServer/world/Primitive.cs index 4f861f7..e048a9e 100644 --- a/OpenSim.RegionServer/world/Primitive.cs +++ b/OpenSim.RegionServer/world/Primitive.cs @@ -22,7 +22,7 @@ namespace OpenSim.world private bool physicsEnabled = false; private bool physicstest = false; private LLVector3 positionLastFrame = new LLVector3(0, 0, 0); - private Dictionary m_clientThreads; + private Dictionary m_clientThreads; private ulong m_regionHandle; private const uint FULL_MASK_PERMISSIONS = 2147483647; @@ -75,7 +75,7 @@ namespace OpenSim.world } } - public Primitive(Dictionary clientThreads, ulong regionHandle, World world) + public Primitive(Dictionary clientThreads, ulong regionHandle, World world) { mesh_cutbegin = 0.0f; mesh_cutend = 1.0f; @@ -104,7 +104,7 @@ namespace OpenSim.world return this.primData.ToBytes(); } - public void GetProperites(SimClient client) + public void GetProperites(ClientView client) { ObjectPropertiesPacket proper = new ObjectPropertiesPacket(); proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[1]; @@ -164,7 +164,7 @@ namespace OpenSim.world } if (this.newPrimFlag) { - foreach (SimClient client in m_clientThreads.Values) + foreach (ClientView client in m_clientThreads.Values) { client.OutPacket(OurPacket); } @@ -177,7 +177,7 @@ namespace OpenSim.world terse.RegionData.TimeDilation = 64096; terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; terse.ObjectData[0] = this.CreateImprovedBlock(); - foreach (SimClient client in m_clientThreads.Values) + foreach (ClientView client in m_clientThreads.Values) { client.OutPacket(terse); } @@ -185,7 +185,7 @@ namespace OpenSim.world } else if (this.dirtyFlag) { - foreach (SimClient client in m_clientThreads.Values) + foreach (ClientView client in m_clientThreads.Values) { UpdateClient(client); } @@ -202,7 +202,7 @@ namespace OpenSim.world terse.RegionData.TimeDilation = 64096; terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[1]; terse.ObjectData[0] = this.CreateImprovedBlock(); - foreach (SimClient client in m_clientThreads.Values) + foreach (ClientView client in m_clientThreads.Values) { client.OutPacket(terse); } @@ -220,7 +220,7 @@ namespace OpenSim.world } } - public void UpdateClient(SimClient RemoteClient) + public void UpdateClient(ClientView RemoteClient) { LLVector3 lPos; diff --git a/OpenSim.RegionServer/world/Primitive2.cs b/OpenSim.RegionServer/world/Primitive2.cs index 3b39456..6d071d4 100644 --- a/OpenSim.RegionServer/world/Primitive2.cs +++ b/OpenSim.RegionServer/world/Primitive2.cs @@ -16,7 +16,7 @@ namespace OpenSim.world protected PrimData primData; //private ObjectUpdatePacket OurPacket; private LLVector3 positionLastFrame = new LLVector3(0, 0, 0); - private Dictionary m_clientThreads; + private Dictionary m_clientThreads; private ulong m_regionHandle; private const uint FULL_MASK_PERMISSIONS = 2147483647; private bool physicsEnabled = false; @@ -58,7 +58,7 @@ namespace OpenSim.world } #endregion - public Primitive2(Dictionary clientThreads, ulong regionHandle, World world) + public Primitive2(Dictionary clientThreads, ulong regionHandle, World world) { m_clientThreads = clientThreads; m_regionHandle = regionHandle; @@ -66,6 +66,17 @@ namespace OpenSim.world inventoryItems = new Dictionary(); } + public Primitive2(Dictionary clientThreads, ulong regionHandle, World world, LLUUID owner) + { + m_clientThreads = clientThreads; + m_regionHandle = regionHandle; + m_world = world; + inventoryItems = new Dictionary(); + this.primData = new PrimData(); + this.primData.CreationDate = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; + this.primData.OwnerID = owner; + } + public byte[] GetByteArray() { byte[] result = null; @@ -159,7 +170,7 @@ namespace OpenSim.world } - public void GetProperites(SimClient client) + public void GetProperites(ClientView client) { ObjectPropertiesPacket proper = new ObjectPropertiesPacket(); proper.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[1]; @@ -202,12 +213,12 @@ namespace OpenSim.world return null; } - public void RequestInventoryInfo(SimClient simClient, RequestTaskInventoryPacket packet) + public void RequestInventoryInfo(ClientView simClient, RequestTaskInventoryPacket packet) { } - public void RequestXferInventory(SimClient simClient, ulong xferID) + public void RequestXferInventory(ClientView simClient, ulong xferID) { //will only currently work if the total size of the inventory data array is under about 1000 bytes SendXferPacketPacket send = new SendXferPacketPacket(); @@ -246,7 +257,7 @@ namespace OpenSim.world #region Update viewers Methods //should change these mehtods, so that outgoing packets are sent through the avatar class - public void SendFullUpdateToClient(SimClient remoteClient) + public void SendFullUpdateToClient(ClientView remoteClient) { LLVector3 lPos; if (this._physActor != null && this.physicsEnabled) @@ -273,7 +284,7 @@ namespace OpenSim.world } - public void SendTerseUpdateToClient(SimClient RemoteClient) + public void SendTerseUpdateToClient(ClientView RemoteClient) { } @@ -316,7 +327,7 @@ namespace OpenSim.world PData.PathTwist = addPacket.ObjectData.PathTwist; PData.PathTwistBegin = addPacket.ObjectData.PathTwistBegin; LLVector3 pos1 = addPacket.ObjectData.RayEnd; - this.primData.FullID = this.uuid = LLUUID.Random(); + this.primData.FullID = this.uuid = LLUUID.Random(); this.localid = (uint)(localID); this.primData.Position = this.Pos = pos1; } diff --git a/OpenSim.RegionServer/world/SceneObject.cs b/OpenSim.RegionServer/world/SceneObject.cs index 5b5a7b2..a846fb5 100644 --- a/OpenSim.RegionServer/world/SceneObject.cs +++ b/OpenSim.RegionServer/world/SceneObject.cs @@ -15,7 +15,7 @@ namespace OpenSim.world { private LLUUID rootUUID; private Dictionary ChildPrimitives = new Dictionary(); - private Dictionary m_clientThreads; + private Dictionary m_clientThreads; private World m_world; public SceneObject() @@ -42,7 +42,7 @@ namespace OpenSim.world } - public void GetProperites(SimClient client) + public void GetProperites(ClientView client) { /* ObjectPropertiesPacket proper = new ObjectPropertiesPacket(); diff --git a/OpenSim.RegionServer/world/World.PacketHandlers.cs b/OpenSim.RegionServer/world/World.PacketHandlers.cs index 175b777..27f200f 100644 --- a/OpenSim.RegionServer/world/World.PacketHandlers.cs +++ b/OpenSim.RegionServer/world/World.PacketHandlers.cs @@ -16,7 +16,7 @@ namespace OpenSim.world public partial class World { - public bool ModifyTerrain(SimClient simClient, Packet packet) + public bool ModifyTerrain(ClientView simClient, Packet packet) { ModifyLandPacket modify = (ModifyLandPacket)packet; @@ -42,68 +42,44 @@ namespace OpenSim.world return true; } - public bool SimChat(SimClient simClient, Packet packet) - { - System.Text.Encoding enc = System.Text.Encoding.ASCII; - ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)packet; - if (Util.FieldToString(inchatpack.ChatData.Message) == "") - { - //empty message so don't bother with it - return true; - } - - string fromName = simClient.ClientAvatar.firstname + " " + simClient.ClientAvatar.lastname; - byte[] message = inchatpack.ChatData.Message; - byte type = inchatpack.ChatData.Type; - LLVector3 fromPos = simClient.ClientAvatar.Pos; - LLUUID fromAgentID = simClient.AgentID; - - libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket(); - reply.ChatData.Audible = 1; - reply.ChatData.Message = message; - reply.ChatData.ChatType = type; - reply.ChatData.SourceType = 1; - reply.ChatData.Position = fromPos; - reply.ChatData.FromName = enc.GetBytes(fromName + "\0"); - reply.ChatData.OwnerID = fromAgentID; - reply.ChatData.SourceID = fromAgentID; - - foreach (SimClient client in m_clientThreads.Values) + public void SimChat(byte[] message, byte type, LLVector3 fromPos, string fromName, LLUUID fromAgentID) + { + foreach (ClientView client in m_clientThreads.Values) { // int dis = Util.fast_distance2d((int)(client.ClientAvatar.Pos.X - simClient.ClientAvatar.Pos.X), (int)(client.ClientAvatar.Pos.Y - simClient.ClientAvatar.Pos.Y)); - int dis = (int)client.ClientAvatar.Pos.GetDistanceTo(simClient.ClientAvatar.Pos); + int dis = (int)client.ClientAvatar.Pos.GetDistanceTo(fromPos); - switch (inchatpack.ChatData.Type) + switch (type) { case 0: // Whisper if ((dis < 10) && (dis > -10)) { - client.OutPacket(reply); + //should change so the message is sent through the avatar rather than direct to the ClientView + client.SendChatMessage(message, type, fromPos, fromName, fromAgentID); } break; case 1: // Say if ((dis < 30) && (dis > -30)) { - client.OutPacket(reply); + client.SendChatMessage(message, type, fromPos, fromName, fromAgentID); } break; case 2: // Shout if ((dis < 100) && (dis > -100)) { - client.OutPacket(reply); + client.SendChatMessage(message, type, fromPos, fromName, fromAgentID); } break; case 0xff: // Broadcast - client.OutPacket(reply); + client.SendChatMessage(message, type, fromPos, fromName, fromAgentID); break; } } - return true; } - public bool RezObject(SimClient simClient, Packet packet) + public bool RezObject(ClientView simClient, Packet packet) { RezObjectPacket rezPacket = (RezObjectPacket)packet; AgentInventory inven = this._inventoryCache.GetAgentsInventory(simClient.AgentID); @@ -126,7 +102,7 @@ namespace OpenSim.world return true; } - public bool DeRezObject(SimClient simClient, Packet packet) + public bool DeRezObject(ClientView simClient, Packet packet) { DeRezObjectPacket DeRezPacket = (DeRezObjectPacket)packet; @@ -151,7 +127,7 @@ namespace OpenSim.world kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); kill.ObjectData[0].ID = ent.localid; - foreach (SimClient client in m_clientThreads.Values) + foreach (ClientView client in m_clientThreads.Values) { client.OutPacket(kill); } @@ -201,7 +177,7 @@ namespace OpenSim.world kill.ObjectData = new KillObjectPacket.ObjectDataBlock[1]; kill.ObjectData[0] = new KillObjectPacket.ObjectDataBlock(); kill.ObjectData[0].ID = selectedEnt.localid; - foreach (SimClient client in m_clientThreads.Values) + foreach (ClientView client in m_clientThreads.Values) { client.OutPacket(kill); } @@ -215,7 +191,7 @@ namespace OpenSim.world return true; } - public void RequestMapBlock(SimClient simClient, int minX, int minY, int maxX, int maxY) + public void RequestMapBlock(ClientView simClient, int minX, int minY, int maxX, int maxY) { System.Text.Encoding _enc = System.Text.Encoding.ASCII; if (((m_regInfo.RegionLocX > minX) && (m_regInfo.RegionLocX < maxX)) && ((m_regInfo.RegionLocY > minY) && (m_regInfo.RegionLocY < maxY))) diff --git a/OpenSim.RegionServer/world/World.cs b/OpenSim.RegionServer/world/World.cs index 983e66d..c90e3f6 100644 --- a/OpenSim.RegionServer/world/World.cs +++ b/OpenSim.RegionServer/world/World.cs @@ -57,7 +57,7 @@ namespace OpenSim.world /// Dictionary to contain client threads /// Region Handle for this region /// Region Name for this region - public World(Dictionary clientThreads, RegionInfo regInfo, ulong regionHandle, string regionName) + public World(Dictionary clientThreads, RegionInfo regInfo, ulong regionHandle, string regionName) { try { @@ -324,7 +324,7 @@ namespace OpenSim.world } this.localStorage.SaveMap(this.Terrain.getHeights1D()); - foreach (SimClient client in m_clientThreads.Values) + foreach (ClientView client in m_clientThreads.Values) { this.SendLayerData(client); } @@ -355,7 +355,7 @@ namespace OpenSim.world } this.localStorage.SaveMap(this.Terrain.getHeights1D()); - foreach (SimClient client in m_clientThreads.Values) + foreach (ClientView client in m_clientThreads.Values) { this.SendLayerData(client); } @@ -389,7 +389,7 @@ namespace OpenSim.world } this.localStorage.SaveMap(this.Terrain.getHeights1D()); - foreach (SimClient client in m_clientThreads.Values) + foreach (ClientView client in m_clientThreads.Values) { this.SendLayerData(pointx, pointy, client); } @@ -437,7 +437,7 @@ namespace OpenSim.world /// Sends prims to a client /// /// Client to send to - public void GetInitialPrims(SimClient RemoteClient) + public void GetInitialPrims(ClientView RemoteClient) { try { @@ -495,7 +495,7 @@ namespace OpenSim.world } } - public void AddNewPrim(ObjectAddPacket addPacket, SimClient AgentClient) + public void AddNewPrim(ObjectAddPacket addPacket, ClientView AgentClient) { AddNewPrim(addPacket, AgentClient.AgentID); } @@ -530,8 +530,9 @@ namespace OpenSim.world #region Add/Remove Avatar Methods - public override void AddViewerAgent(SimClient agentClient) + public override void AddViewerAgent(ClientView agentClient) { + agentClient.OnChatFromViewer += new ClientView.ChatFromViewer(this.SimChat); try { OpenSim.Framework.Console.MainConsole.Instance.WriteLine(OpenSim.Framework.Console.LogPriority.LOW, "World.cs:AddViewerAgent() - Creating new avatar for remote viewer agent"); @@ -576,7 +577,7 @@ namespace OpenSim.world } } - public override void RemoveViewerAgent(SimClient agentClient) + public override void RemoveViewerAgent(ClientView agentClient) { try { @@ -600,6 +601,23 @@ namespace OpenSim.world } #endregion + #region Request Avatars List Methods + //The idea is to have a group of method that return a list of avatars meeting some requirement + // ie it could be all Avatars within a certain range of the calling prim/avatar. + + public List RequestAvatarList() + { + List result = new List(); + + foreach (Avatar avatar in Avatars.Values) + { + result.Add(avatar); + } + + return result; + } + #endregion + #region ShutDown /// /// Tidy before shutdown diff --git a/OpenSim.RegionServer/world/WorldBase.cs b/OpenSim.RegionServer/world/WorldBase.cs index b8c086d..edc5518 100644 --- a/OpenSim.RegionServer/world/WorldBase.cs +++ b/OpenSim.RegionServer/world/WorldBase.cs @@ -20,7 +20,7 @@ namespace OpenSim.world public class WorldBase { public Dictionary Entities; - protected Dictionary m_clientThreads; + protected Dictionary m_clientThreads; protected ulong m_regionHandle; protected string m_regionName; protected InventoryCache _inventoryCache; @@ -90,7 +90,7 @@ namespace OpenSim.world /// Send the region heightmap to the client /// /// Client to send to - public virtual void SendLayerData(SimClient RemoteClient) + public virtual void SendLayerData(ClientView RemoteClient) { try { @@ -122,7 +122,7 @@ namespace OpenSim.world /// Patch coordinate (x) 0..16 /// Patch coordinate (y) 0..16 /// The client to send to - public void SendLayerData(int px, int py, SimClient RemoteClient) + public void SendLayerData(int px, int py, ClientView RemoteClient) { try { @@ -148,7 +148,7 @@ namespace OpenSim.world /// Add a new Agent's avatar /// /// - public virtual void AddViewerAgent(SimClient agentClient) + public virtual void AddViewerAgent(ClientView agentClient) { } @@ -157,7 +157,7 @@ namespace OpenSim.world /// Remove a Agent's avatar /// /// - public virtual void RemoveViewerAgent(SimClient agentClient) + public virtual void RemoveViewerAgent(ClientView agentClient) { } -- cgit v1.1