From 0b6f8a02a7d0927031bf812429770d6ecc5f483a Mon Sep 17 00:00:00 2001
From: jhurliman
Date: Wed, 7 Mar 2007 05:09:18 +0000
Subject: * Updating libsecondlife.dll to the latest version with a working
LayerData function * Reformatting some source files * Adding a try/catch
sanity check around a phoning home check to osgrid.org * Updating the MSVC
project file * Converted LayerData generation to use the functions built in
to libsecondlife * Removing unused BitPack.cs and TerrainDecoder.cs files *
Added a basic terrain generator (hills algorithm)
---
src/OpenSimClient.cs | 889 +++++++++++++++++++++++++++------------------------
1 file changed, 469 insertions(+), 420 deletions(-)
(limited to 'src/OpenSimClient.cs')
diff --git a/src/OpenSimClient.cs b/src/OpenSimClient.cs
index 655ebfe..497df00 100644
--- a/src/OpenSimClient.cs
+++ b/src/OpenSimClient.cs
@@ -37,425 +37,474 @@ using System.Timers;
namespace OpenSim
{
- ///
- /// Handles new client connections
- /// Constructor takes a single Packet and authenticates everything
- ///
- public class OpenSimClient {
-
- public LLUUID AgentID;
- public LLUUID SessionID;
- public uint CircuitCode;
- public world.Avatar ClientAvatar;
- private UseCircuitCodePacket cirpack;
- private Thread ClientThread;
- public EndPoint userEP;
- private BlockingQueue PacketQueue;
- private BlockingQueue AssetRequests;
- private Dictionary PendingAcks = new Dictionary();
- private Dictionary NeedAck = 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 Queue Inbox;
-
- public void ack_pack(Packet Pack) {
- //libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket();
- //ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
- //ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
- //ack_it.Packets[0].ID = Pack.Header.ID;
- //ack_it.Header.Reliable = false;
-
- //OutPacket(ack_it);
-
- if (Pack.Header.Reliable) {
- lock (PendingAcks) {
- uint sequence = (uint)Pack.Header.Sequence;
- if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
- }
- }
- }
-
- public void AssetLoader() {
- if(OpenSim_Main.cfg.sandbox==false) {
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AssetLoader() - Starting new thread");
- TransferRequestPacket reqPacket = AssetRequests.Dequeue();
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AssetLoader() - Got a request, processing it");
- LLUUID AssetID = new LLUUID(reqPacket.TransferInfo.Params, 0);
- WebRequest AssetLoad = WebRequest.Create(OpenSim_Main.cfg.AssetURL + "getasset/" + OpenSim_Main.cfg.AssetSendKey + "/" + AssetID + "/data");
- WebResponse AssetResponse = AssetLoad.GetResponse();
- byte[] idata = new byte[(int)AssetResponse.ContentLength];
- BinaryReader br = new BinaryReader(AssetResponse.GetResponseStream());
- idata = br.ReadBytes((int)AssetResponse.ContentLength);
- br.Close();
-
- TransferInfoPacket Transfer = new TransferInfoPacket();
- Transfer.TransferInfo.ChannelType = 2;
- Transfer.TransferInfo.Status = 0;
- Transfer.TransferInfo.TargetType = 0;
- Transfer.TransferInfo.Params = reqPacket.TransferInfo.Params;
- Transfer.TransferInfo.Size = (int)AssetResponse.ContentLength;
- Transfer.TransferInfo.TransferID = reqPacket.TransferInfo.TransferID;
-
- OutPacket(Transfer);
-
- TransferPacketPacket TransferPacket = new TransferPacketPacket();
- TransferPacket.TransferData.Packet = 0;
- TransferPacket.TransferData.ChannelType = 2;
- TransferPacket.TransferData.TransferID=reqPacket.TransferInfo.TransferID;
-
- if(AssetResponse.ContentLength>1000) {
- byte[] chunk = new byte[1000];
- Array.Copy(idata,chunk,1000);
- TransferPacket.TransferData.Data = chunk;
- TransferPacket.TransferData.Status = 0;
- OutPacket(TransferPacket);
-
- TransferPacket = new TransferPacketPacket();
- TransferPacket.TransferData.Packet = 1;
- TransferPacket.TransferData.ChannelType = 2;
- TransferPacket.TransferData.TransferID = reqPacket.TransferInfo.TransferID;
- byte[] chunk1 = new byte[(idata.Length-1000)];
- Array.Copy(idata, 1000, chunk1, 0, chunk1.Length);
- TransferPacket.TransferData.Data = chunk1;
- TransferPacket.TransferData.Status = 1;
- OutPacket(TransferPacket);
- } else {
- TransferPacket.TransferData.Status = 1;
- TransferPacket.TransferData.Data = idata;
- OutPacket(TransferPacket);
- }
- AssetResponse.Close();
- }
- }
-
- public void Logout() {
- // TODO - kill any AssetLoaders
- ClientThread.Abort();
- }
-
- public void ProcessInPacket(Packet Pack) {
- ack_pack(Pack);
- switch(Pack.Type) {
- case PacketType.CompleteAgentMovement:
- ClientAvatar.CompleteMovement(OpenSim_Main.local_world);
- ClientAvatar.SendInitialPosition();
- break;
- case PacketType.RegionHandshakeReply:
- OpenSim_Main.local_world.SendLayerData(this);
- break;
- case PacketType.AgentWearablesRequest:
- ClientAvatar.SendInitialAppearance();
- break;
- case PacketType.TransferRequest:
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request");
- // We put transfer requests into a big queue and then spawn a thread for each new one
- TransferRequestPacket transfer = (TransferRequestPacket)Pack;
- AssetRequests.Enqueue(transfer);
- Thread AssetLoaderThread = new Thread(new ThreadStart(AssetLoader));
- AssetLoaderThread.Start();
- break;
- case PacketType.LogoutRequest:
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got a logout request");
- lock(OpenSim_Main.local_world.Entities) {
- OpenSim_Main.local_world.Entities.Remove(this.AgentID);
- }
-
- if(OpenSim_Main.cfg.sandbox==false) {
- WebRequest DeleteSession = WebRequest.Create(OpenSim_Main.cfg.GridURL + "/usersessions/" + OpenSim_Main.cfg.GridSendKey + "/" + this.AgentID.ToString() + this.CircuitCode.ToString() + "/delete");
- WebResponse GridResponse = DeleteSession.GetResponse();
- StreamReader sr = new StreamReader(GridResponse.GetResponseStream());
- String grTest = sr.ReadLine();
- sr.Close();
- GridResponse.Close();
- OpenSim_Main.localcons.WriteLine("DEBUG: " + grTest);
- }
- this.ClientThread.Abort();
- break;
- case PacketType.AgentUpdate:
- ClientAvatar.HandleAgentUpdate((AgentUpdatePacket)Pack);
- break;
- case PacketType.ChatFromViewer:
- ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack;
- if(Helpers.FieldToString(inchatpack.ChatData.Message)=="") break;
-
- System.Text.Encoding _enc = System.Text.Encoding.ASCII;
- libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
- reply.ChatData.Audible = 1;
- reply.ChatData.Message = inchatpack.ChatData.Message;
- reply.ChatData.ChatType = 1;
- reply.ChatData.SourceType = 1;
- reply.ChatData.Position = this.ClientAvatar.position;
- reply.ChatData.FromName = _enc.GetBytes(this.ClientAvatar.firstname + " " + this.ClientAvatar.lastname + "\0");
- reply.ChatData.OwnerID = this.AgentID;
- reply.ChatData.SourceID = this.AgentID;
-
-
-
- foreach(OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values) {
- client.OutPacket(reply);
- }
- break;
- }
- }
-
- private void ResendUnacked()
- {
- int now = Environment.TickCount;
-
- lock (NeedAck)
- {
- foreach (Packet packet in NeedAck.Values)
- {
- if (now - packet.TickCount > RESEND_TIMEOUT)
- {
-
- packet.Header.Resent = true;
- OutPacket(packet);
- }
- }
- }
- }
-
- private void SendAcks()
- {
- lock (PendingAcks)
- {
- if (PendingAcks.Count > 0)
- {
- if (PendingAcks.Count > 250)
- {
- return;
- }
-
-
-
- int i = 0;
- PacketAckPacket acks = new PacketAckPacket();
- acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];
-
- foreach (uint ack in PendingAcks.Values)
- {
- acks.Packets[i] = new PacketAckPacket.PacketsBlock();
- acks.Packets[i].ID = ack;
- i++;
- }
-
- acks.Header.Reliable = false;
- OutPacket(acks);
-
- PendingAcks.Clear();
- }
- }
- }
-
- private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea)
- {
- SendAcks();
- ResendUnacked();
- }
-
- public void ProcessOutPacket(Packet Pack) {
-
- // Keep track of when this packet was sent out
- Pack.TickCount = Environment.TickCount;
-
- if (!Pack.Header.Resent)
- {
- // Set the sequence number
- lock (SequenceLock)
- {
- if (Sequence >= MAX_SEQUENCE)
- Sequence = 1;
- else
- Sequence++;
- Pack.Header.Sequence = Sequence;
- }
-
- if (Pack.Header.Reliable) //DIRTY HACK
- {
- lock (NeedAck)
- {
- if (!NeedAck.ContainsKey(Pack.Header.Sequence))
- {
- NeedAck.Add(Pack.Header.Sequence, Pack);
- }
- else
- {
- // Client.Log("Attempted to add a duplicate sequence number (" +
- // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
- // packet.Type.ToString(), Helpers.LogLevel.Warning);
- }
- }
-
- // Don't append ACKs to resent packets, in case that's what was causing the
- // delivery to fail
- if (!Pack.Header.Resent)
- {
- // Append any ACKs that need to be sent out to this packet
- lock (PendingAcks)
- {
- if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS &&
- Pack.Type != PacketType.PacketAck &&
- Pack.Type != PacketType.LogoutRequest)
- {
- Pack.Header.AckList = new uint[PendingAcks.Count];
- int i = 0;
-
- foreach (uint ack in PendingAcks.Values)
- {
- Pack.Header.AckList[i] = ack;
- i++;
- }
-
- PendingAcks.Clear();
- Pack.Header.AppendedAcks = true;
- }
- }
- }
- }
- }
-
-
- byte[] ZeroOutBuffer = new byte[4096];
- byte[] sendbuffer;
- sendbuffer = Pack.ToBytes();
-
- try {
- if (Pack.Header.Zerocoded) {
- int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
- OpenSim_Main.Server.SendTo(ZeroOutBuffer, packetsize, SocketFlags.None,userEP);
- } else {
- OpenSim_Main.Server.SendTo(sendbuffer, sendbuffer.Length, SocketFlags.None,userEP);
- }
- } catch (Exception) {
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread");
- ClientThread.Abort();
- }
-
- }
-
- public void InPacket(Packet NewPack) {
- // Handle appended ACKs
- if (NewPack.Header.AppendedAcks)
- {
- lock (NeedAck)
- {
- foreach (uint ack in NewPack.Header.AckList)
- {
- OpenSim_Main.localcons.WriteLine("Got appended ack: "+ack);
- NeedAck.Remove(ack);
- }
- }
- }
-
- // Handle PacketAck packets
- if (NewPack.Type == PacketType.PacketAck)
- {
- PacketAckPacket ackPacket = (PacketAckPacket)NewPack;
-
- lock (NeedAck)
- {
- foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
- {
- NeedAck.Remove(block.ID);
- }
- }
- } else if( ( NewPack.Type == PacketType.StartPingCheck ) ) {
- //reply to pingcheck
- libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack;
- libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket();
- endPing.PingID.PingID = startPing.PingID.PingID;
- OutPacket(endPing);
- }
- else
- {
- QueItem item = new QueItem();
- item.Packet = NewPack;
- item.Incoming = true;
- this.PacketQueue.Enqueue(item);
- }
-
- }
-
- public void OutPacket(Packet NewPack) {
- QueItem item = new QueItem();
- item.Packet = NewPack;
- item.Incoming = false;
- this.PacketQueue.Enqueue(item);
- }
-
- public OpenSimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack) {
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs - Started up new client thread to handle incoming request");
- cirpack = initialcirpack;
- userEP = remoteEP;
- PacketQueue = new BlockingQueue();
- AssetRequests = new BlockingQueue();
- AckTimer = new System.Timers.Timer(500);
- AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
- AckTimer.Start();
-
- ClientThread = new Thread(new ThreadStart(AuthUser));
- ClientThread.IsBackground = true;
- ClientThread.Start();
- }
-
- private void ClientLoop() {
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ClientLoop() - Entered loop");
- while(true) {
- QueItem nextPacket = PacketQueue.Dequeue();
- if(nextPacket.Incoming)
- {
- //is a incoming packet
- ProcessInPacket(nextPacket.Packet);
- }
- else
- {
- //is a out going packet
- ProcessOutPacket(nextPacket.Packet);
- }
- }
- }
-
- private void InitNewClient() {
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:InitNewClient() - Adding viewer agent to world");
- OpenSim_Main.local_world.AddViewerAgent(this);
- world.Entity tempent=OpenSim_Main.local_world.Entities[this.AgentID];
- this.ClientAvatar=(world.Avatar)tempent;
- }
-
- private void AuthUser() {
- if(OpenSim_Main.cfg.sandbox==false) {
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - Authenticating new user request with grid");
- WebRequest CheckSession = WebRequest.Create(OpenSim_Main.cfg.GridURL + "/usersessions/" + OpenSim_Main.cfg.GridSendKey + "/" + cirpack.CircuitCode.ID.ToString() + "/" + cirpack.CircuitCode.Code.ToString() + "/exists");
- OpenSim_Main.localcons.WriteLine(OpenSim_Main.cfg.GridURL);
- WebResponse GridResponse = CheckSession.GetResponse();
- StreamReader sr = new StreamReader(GridResponse.GetResponseStream());
- String grTest = sr.ReadLine();
- sr.Close();
- GridResponse.Close();
- if(String.IsNullOrEmpty(grTest) || grTest.Equals("1")) { // YAY! Valid login
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString());
- this.AgentID=cirpack.CircuitCode.ID;
- this.SessionID=cirpack.CircuitCode.SessionID;
- this.CircuitCode=cirpack.CircuitCode.Code;
- InitNewClient();
- ClientLoop();
- } else { // Invalid
- OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString());
- ClientThread.Abort();
- }
- } else {
- this.AgentID=cirpack.CircuitCode.ID;
- this.SessionID=cirpack.CircuitCode.SessionID;
- this.CircuitCode=cirpack.CircuitCode.Code;
- InitNewClient();
- ClientLoop();
- }
- }
- }
+ ///
+ /// Handles new client connections
+ /// Constructor takes a single Packet and authenticates everything
+ ///
+ public class OpenSimClient
+ {
+
+ public LLUUID AgentID;
+ public LLUUID SessionID;
+ public uint CircuitCode;
+ public world.Avatar ClientAvatar;
+ private UseCircuitCodePacket cirpack;
+ private Thread ClientThread;
+ public EndPoint userEP;
+ private BlockingQueue PacketQueue;
+ private BlockingQueue AssetRequests;
+ private Dictionary PendingAcks = new Dictionary();
+ private Dictionary NeedAck = 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 Queue Inbox;
+
+ public void ack_pack(Packet Pack)
+ {
+ //libsecondlife.Packets.PacketAckPacket ack_it = new PacketAckPacket();
+ //ack_it.Packets = new PacketAckPacket.PacketsBlock[1];
+ //ack_it.Packets[0] = new PacketAckPacket.PacketsBlock();
+ //ack_it.Packets[0].ID = Pack.Header.ID;
+ //ack_it.Header.Reliable = false;
+
+ //OutPacket(ack_it);
+
+ if (Pack.Header.Reliable)
+ {
+ lock (PendingAcks)
+ {
+ uint sequence = (uint)Pack.Header.Sequence;
+ if (!PendingAcks.ContainsKey(sequence)) { PendingAcks[sequence] = sequence; }
+ }
+ }
+ }
+
+ public void AssetLoader()
+ {
+ if (OpenSim_Main.cfg.sandbox == false)
+ {
+ WebResponse AssetResponse;
+ byte[] idata;
+
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AssetLoader() - Starting new thread");
+ TransferRequestPacket reqPacket = AssetRequests.Dequeue();
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AssetLoader() - Got a request, processing it");
+ LLUUID AssetID = new LLUUID(reqPacket.TransferInfo.Params, 0);
+
+ try
+ {
+ WebRequest AssetLoad = WebRequest.Create(OpenSim_Main.cfg.AssetURL + "getasset/" + OpenSim_Main.cfg.AssetSendKey + "/" + AssetID + "/data");
+ AssetResponse = AssetLoad.GetResponse();
+ idata = new byte[(int)AssetResponse.ContentLength];
+ BinaryReader br = new BinaryReader(AssetResponse.GetResponseStream());
+ idata = br.ReadBytes((int)AssetResponse.ContentLength);
+ br.Close();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.ToString());
+ return;
+ }
+
+ TransferInfoPacket Transfer = new TransferInfoPacket();
+ Transfer.TransferInfo.ChannelType = 2;
+ Transfer.TransferInfo.Status = 0;
+ Transfer.TransferInfo.TargetType = 0;
+ Transfer.TransferInfo.Params = reqPacket.TransferInfo.Params;
+ Transfer.TransferInfo.Size = (int)AssetResponse.ContentLength;
+ Transfer.TransferInfo.TransferID = reqPacket.TransferInfo.TransferID;
+
+ OutPacket(Transfer);
+
+ TransferPacketPacket TransferPacket = new TransferPacketPacket();
+ TransferPacket.TransferData.Packet = 0;
+ TransferPacket.TransferData.ChannelType = 2;
+ TransferPacket.TransferData.TransferID = reqPacket.TransferInfo.TransferID;
+
+ if (AssetResponse.ContentLength > 1000)
+ {
+ byte[] chunk = new byte[1000];
+ Array.Copy(idata, chunk, 1000);
+ TransferPacket.TransferData.Data = chunk;
+ TransferPacket.TransferData.Status = 0;
+ OutPacket(TransferPacket);
+
+ TransferPacket = new TransferPacketPacket();
+ TransferPacket.TransferData.Packet = 1;
+ TransferPacket.TransferData.ChannelType = 2;
+ TransferPacket.TransferData.TransferID = reqPacket.TransferInfo.TransferID;
+ byte[] chunk1 = new byte[(idata.Length - 1000)];
+ Array.Copy(idata, 1000, chunk1, 0, chunk1.Length);
+ TransferPacket.TransferData.Data = chunk1;
+ TransferPacket.TransferData.Status = 1;
+ OutPacket(TransferPacket);
+ }
+ else
+ {
+ TransferPacket.TransferData.Status = 1;
+ TransferPacket.TransferData.Data = idata;
+ OutPacket(TransferPacket);
+ }
+ AssetResponse.Close();
+ }
+ }
+
+ public void Logout()
+ {
+ // TODO - kill any AssetLoaders
+ ClientThread.Abort();
+ }
+
+ public void ProcessInPacket(Packet Pack)
+ {
+ ack_pack(Pack);
+ switch (Pack.Type)
+ {
+ case PacketType.CompleteAgentMovement:
+ ClientAvatar.CompleteMovement(OpenSim_Main.local_world);
+ ClientAvatar.SendInitialPosition();
+ break;
+ case PacketType.RegionHandshakeReply:
+ OpenSim_Main.local_world.SendLayerData(this);
+ break;
+ case PacketType.AgentWearablesRequest:
+ ClientAvatar.SendInitialAppearance();
+ break;
+ case PacketType.TransferRequest:
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got transfer request");
+ // We put transfer requests into a big queue and then spawn a thread for each new one
+ TransferRequestPacket transfer = (TransferRequestPacket)Pack;
+ AssetRequests.Enqueue(transfer);
+ Thread AssetLoaderThread = new Thread(new ThreadStart(AssetLoader));
+ AssetLoaderThread.Start();
+ break;
+ case PacketType.LogoutRequest:
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessInPacket() - Got a logout request");
+ lock (OpenSim_Main.local_world.Entities)
+ {
+ OpenSim_Main.local_world.Entities.Remove(this.AgentID);
+ }
+
+ if (OpenSim_Main.cfg.sandbox == false)
+ {
+ WebRequest DeleteSession = WebRequest.Create(OpenSim_Main.cfg.GridURL + "/usersessions/" + OpenSim_Main.cfg.GridSendKey + "/" + this.AgentID.ToString() + this.CircuitCode.ToString() + "/delete");
+ WebResponse GridResponse = DeleteSession.GetResponse();
+ StreamReader sr = new StreamReader(GridResponse.GetResponseStream());
+ String grTest = sr.ReadLine();
+ sr.Close();
+ GridResponse.Close();
+ OpenSim_Main.localcons.WriteLine("DEBUG: " + grTest);
+ }
+ this.ClientThread.Abort();
+ break;
+ case PacketType.AgentUpdate:
+ ClientAvatar.HandleAgentUpdate((AgentUpdatePacket)Pack);
+ break;
+ case PacketType.ChatFromViewer:
+ ChatFromViewerPacket inchatpack = (ChatFromViewerPacket)Pack;
+ if (Helpers.FieldToString(inchatpack.ChatData.Message) == "") break;
+
+ System.Text.Encoding _enc = System.Text.Encoding.ASCII;
+ libsecondlife.Packets.ChatFromSimulatorPacket reply = new ChatFromSimulatorPacket();
+ reply.ChatData.Audible = 1;
+ reply.ChatData.Message = inchatpack.ChatData.Message;
+ reply.ChatData.ChatType = 1;
+ reply.ChatData.SourceType = 1;
+ reply.ChatData.Position = this.ClientAvatar.position;
+ reply.ChatData.FromName = _enc.GetBytes(this.ClientAvatar.firstname + " " + this.ClientAvatar.lastname + "\0");
+ reply.ChatData.OwnerID = this.AgentID;
+ reply.ChatData.SourceID = this.AgentID;
+
+
+
+ foreach (OpenSimClient client in OpenSim_Main.sim.ClientThreads.Values)
+ {
+ client.OutPacket(reply);
+ }
+ break;
+ }
+ }
+
+ private void ResendUnacked()
+ {
+ int now = Environment.TickCount;
+
+ lock (NeedAck)
+ {
+ foreach (Packet packet in NeedAck.Values)
+ {
+ if (now - packet.TickCount > RESEND_TIMEOUT)
+ {
+
+ packet.Header.Resent = true;
+ OutPacket(packet);
+ }
+ }
+ }
+ }
+
+ private void SendAcks()
+ {
+ lock (PendingAcks)
+ {
+ if (PendingAcks.Count > 0)
+ {
+ if (PendingAcks.Count > 250)
+ {
+ return;
+ }
+
+
+
+ int i = 0;
+ PacketAckPacket acks = new PacketAckPacket();
+ acks.Packets = new PacketAckPacket.PacketsBlock[PendingAcks.Count];
+
+ foreach (uint ack in PendingAcks.Values)
+ {
+ acks.Packets[i] = new PacketAckPacket.PacketsBlock();
+ acks.Packets[i].ID = ack;
+ i++;
+ }
+
+ acks.Header.Reliable = false;
+ OutPacket(acks);
+
+ PendingAcks.Clear();
+ }
+ }
+ }
+
+ private void AckTimer_Elapsed(object sender, ElapsedEventArgs ea)
+ {
+ SendAcks();
+ ResendUnacked();
+ }
+
+ public void ProcessOutPacket(Packet Pack)
+ {
+
+ // Keep track of when this packet was sent out
+ Pack.TickCount = Environment.TickCount;
+
+ if (!Pack.Header.Resent)
+ {
+ // Set the sequence number
+ lock (SequenceLock)
+ {
+ if (Sequence >= MAX_SEQUENCE)
+ Sequence = 1;
+ else
+ Sequence++;
+ Pack.Header.Sequence = Sequence;
+ }
+
+ if (Pack.Header.Reliable) //DIRTY HACK
+ {
+ lock (NeedAck)
+ {
+ if (!NeedAck.ContainsKey(Pack.Header.Sequence))
+ {
+ NeedAck.Add(Pack.Header.Sequence, Pack);
+ }
+ else
+ {
+ // Client.Log("Attempted to add a duplicate sequence number (" +
+ // packet.Header.Sequence + ") to the NeedAck dictionary for packet type " +
+ // packet.Type.ToString(), Helpers.LogLevel.Warning);
+ }
+ }
+
+ // Don't append ACKs to resent packets, in case that's what was causing the
+ // delivery to fail
+ if (!Pack.Header.Resent)
+ {
+ // Append any ACKs that need to be sent out to this packet
+ lock (PendingAcks)
+ {
+ if (PendingAcks.Count > 0 && PendingAcks.Count < MAX_APPENDED_ACKS &&
+ Pack.Type != PacketType.PacketAck &&
+ Pack.Type != PacketType.LogoutRequest)
+ {
+ Pack.Header.AckList = new uint[PendingAcks.Count];
+ int i = 0;
+
+ foreach (uint ack in PendingAcks.Values)
+ {
+ Pack.Header.AckList[i] = ack;
+ i++;
+ }
+
+ PendingAcks.Clear();
+ Pack.Header.AppendedAcks = true;
+ }
+ }
+ }
+ }
+ }
+
+
+ byte[] ZeroOutBuffer = new byte[4096];
+ byte[] sendbuffer;
+ sendbuffer = Pack.ToBytes();
+
+ try
+ {
+ if (Pack.Header.Zerocoded)
+ {
+ int packetsize = Helpers.ZeroEncode(sendbuffer, sendbuffer.Length, ZeroOutBuffer);
+ OpenSim_Main.Server.SendTo(ZeroOutBuffer, packetsize, SocketFlags.None, userEP);
+ }
+ else
+ {
+ OpenSim_Main.Server.SendTo(sendbuffer, sendbuffer.Length, SocketFlags.None, userEP);
+ }
+ }
+ catch (Exception)
+ {
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread");
+ ClientThread.Abort();
+ }
+
+ }
+
+ public void InPacket(Packet NewPack)
+ {
+ // Handle appended ACKs
+ if (NewPack.Header.AppendedAcks)
+ {
+ lock (NeedAck)
+ {
+ foreach (uint ack in NewPack.Header.AckList)
+ {
+ OpenSim_Main.localcons.WriteLine("Got appended ack: " + ack);
+ NeedAck.Remove(ack);
+ }
+ }
+ }
+
+ // Handle PacketAck packets
+ if (NewPack.Type == PacketType.PacketAck)
+ {
+ PacketAckPacket ackPacket = (PacketAckPacket)NewPack;
+
+ lock (NeedAck)
+ {
+ foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets)
+ {
+ NeedAck.Remove(block.ID);
+ }
+ }
+ }
+ else if ((NewPack.Type == PacketType.StartPingCheck))
+ {
+ //reply to pingcheck
+ libsecondlife.Packets.StartPingCheckPacket startPing = (libsecondlife.Packets.StartPingCheckPacket)NewPack;
+ libsecondlife.Packets.CompletePingCheckPacket endPing = new CompletePingCheckPacket();
+ endPing.PingID.PingID = startPing.PingID.PingID;
+ OutPacket(endPing);
+ }
+ else
+ {
+ QueItem item = new QueItem();
+ item.Packet = NewPack;
+ item.Incoming = true;
+ this.PacketQueue.Enqueue(item);
+ }
+
+ }
+
+ public void OutPacket(Packet NewPack)
+ {
+ QueItem item = new QueItem();
+ item.Packet = NewPack;
+ item.Incoming = false;
+ this.PacketQueue.Enqueue(item);
+ }
+
+ public OpenSimClient(EndPoint remoteEP, UseCircuitCodePacket initialcirpack)
+ {
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs - Started up new client thread to handle incoming request");
+ cirpack = initialcirpack;
+ userEP = remoteEP;
+ PacketQueue = new BlockingQueue();
+ AssetRequests = new BlockingQueue();
+ AckTimer = new System.Timers.Timer(500);
+ AckTimer.Elapsed += new ElapsedEventHandler(AckTimer_Elapsed);
+ AckTimer.Start();
+
+ ClientThread = new Thread(new ThreadStart(AuthUser));
+ ClientThread.IsBackground = true;
+ ClientThread.Start();
+ }
+
+ private void ClientLoop()
+ {
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:ClientLoop() - Entered loop");
+ while (true)
+ {
+ QueItem nextPacket = PacketQueue.Dequeue();
+ if (nextPacket.Incoming)
+ {
+ //is a incoming packet
+ ProcessInPacket(nextPacket.Packet);
+ }
+ else
+ {
+ //is a out going packet
+ ProcessOutPacket(nextPacket.Packet);
+ }
+ }
+ }
+
+ private void InitNewClient()
+ {
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:InitNewClient() - Adding viewer agent to world");
+ OpenSim_Main.local_world.AddViewerAgent(this);
+ world.Entity tempent = OpenSim_Main.local_world.Entities[this.AgentID];
+ this.ClientAvatar = (world.Avatar)tempent;
+ }
+
+ private void AuthUser()
+ {
+ if (OpenSim_Main.cfg.sandbox == false)
+ {
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - Authenticating new user request with grid");
+ WebRequest CheckSession = WebRequest.Create(OpenSim_Main.cfg.GridURL + "/usersessions/" + OpenSim_Main.cfg.GridSendKey + "/" + cirpack.CircuitCode.ID.ToString() + "/" + cirpack.CircuitCode.Code.ToString() + "/exists");
+ OpenSim_Main.localcons.WriteLine(OpenSim_Main.cfg.GridURL);
+ WebResponse GridResponse = CheckSession.GetResponse();
+ StreamReader sr = new StreamReader(GridResponse.GetResponseStream());
+ String grTest = sr.ReadLine();
+ sr.Close();
+ GridResponse.Close();
+ if (String.IsNullOrEmpty(grTest) || grTest.Equals("1"))
+ { // YAY! Valid login
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString());
+ this.AgentID = cirpack.CircuitCode.ID;
+ this.SessionID = cirpack.CircuitCode.SessionID;
+ this.CircuitCode = cirpack.CircuitCode.Code;
+ InitNewClient();
+ ClientLoop();
+ }
+ else
+ { // Invalid
+ OpenSim_Main.localcons.WriteLine("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString());
+ ClientThread.Abort();
+ }
+ }
+ else
+ {
+ this.AgentID = cirpack.CircuitCode.ID;
+ this.SessionID = cirpack.CircuitCode.SessionID;
+ this.CircuitCode = cirpack.CircuitCode.Code;
+ InitNewClient();
+ ClientLoop();
+ }
+ }
+ }
}
--
cgit v1.1