namespace OpenSim
{
///
/// Handles new client connections
/// Constructor takes a single Packet and authenticates everything
///
public class OpenSimClient {
private UseCircuitCodePacket cirpack;
private Thread ClientThread;
private EndPoint userEP;
private BlockingQueue PacketQueue;
//private Queue PacketOutbox;
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);
}
public void ProcessInPacket(Packet Pack) {
ack_pack(Pack);
}
public void ProcessOutPacket(Packet Pack) {
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) {
Console.WriteLine("OpenSimClient.cs:ProcessOutPacket() - WARNING: Socket exception occurred on connection " + userEP.ToString() + " - killing thread");
ClientThread.Abort();
}
}
public void InPacket(Packet NewPack) {
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) {
Console.WriteLine("OpenSimClient.cs - Started up new client thread to handle incoming request");
cirpack = initialcirpack;
userEP = remoteEP;
//PacketInbox = new Queue();
//PacketOutbox = new Queue();
this.PacketQueue = new BlockingQueue();
Thread ClientThread = new Thread(new ThreadStart(AuthUser));
ClientThread.IsBackground = true;
ClientThread.Start();
}
private void ClientLoop() {
Console.WriteLine("OpenSimClient.cs:ClientLoop() - Entered loop");
while(true) {
QueItem nextItem= this.PacketQueue.Dequeue();
if(nextItem.Incoming)
{
ProcessInPacket(InPack);
}
else
{
ProcessOutPacket(OutPack);
}
}
}
}
private void InitNewClient() {
Console.WriteLine("OpenSimClient.cs:InitNewClient() - Sending client initial world state and related data");
}
private void AuthUser() {
Console.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");
WebResponse GridResponse = CheckSession.GetResponse();
StreamReader sr = new StreamReader(GridResponse.GetResponseStream());
String grTest = sr.ReadLine();
sr.Close();
GridResponse.Close();
if(grTest.Equals("1")) { // YAY! Valid login
Console.WriteLine("OpenSimClient.cs:AuthUser() - Got authenticated connection from " + userEP.ToString());
InitNewClient();
ClientLoop();
} else { // Invalid
Console.WriteLine("OpenSimClient.cs:AuthUser() - New user request denied to " + userEP.ToString());
ClientThread.Abort();
}
}
}
public class QueItem
{
public QueItem()
{
}
public Packet Packet;
public bool Incoming;
}
}