Files
libremetaverse/libsecondlife-cs/tests/DebugServer.cs

142 lines
4.4 KiB
C#

using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text.RegularExpressions;
using System.Threading;
using System.Xml;
using Nwc.XmlRpc;
using libsecondlife;
namespace libsecondlife.Tests
{
public class DebugServer
{
public bool Initialized = false;
private SecondLife libsl;
private bool done = false;
private Socket Listener;
private IPEndPoint Endpoint;
EndPoint RemoteEndpoint = new IPEndPoint(IPAddress.Loopback, 0);
private ushort Sequence = 0;
public DebugServer(string keywordFile, string mapFile, int port)
{
try
{
libsl = new SecondLife(keywordFile, mapFile);
}
catch (Exception)
{
return;
}
BindSocket(port);
}
private void BindSocket(int port)
{
Endpoint = new IPEndPoint(IPAddress.Loopback, port);
Listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
Console.WriteLine("[SERVER] Binding a UDP socket to " + Endpoint.ToString());
try
{
Listener.Bind(Endpoint);
}
catch (SocketException)
{
Console.WriteLine("[SERVER] Failed to bind to " + Endpoint.ToString());
return;
}
// Start listening for incoming data
Thread thread = new Thread(new ThreadStart(Listen));
thread.Start();
Initialized = true;
}
private void Listen()
{
Packet packet;
int length;
byte[] bytes = new byte[4096];
Console.WriteLine("[SERVER] Listening for incoming data on " + Endpoint.ToString());
while (!done)
{
packet = null;
// Grab the next packet
length = Listener.ReceiveFrom(bytes, ref RemoteEndpoint);
Console.WriteLine("[SERVER] Received a packet from {0}", RemoteEndpoint.ToString());
if (System.Text.ASCIIEncoding.UTF8.GetString(bytes).Substring(0, 10) == "stopserver")
{
Console.WriteLine("[SERVER] Received a shutdown request, stopping the server");
done = true;
break;
}
if ((bytes[0] & Helpers.MSG_APPENDED_ACKS) != 0)
{
byte numAcks = bytes[length - 1];
Console.WriteLine("[SERVER] Found " + numAcks + " appended acks");
length = (length - numAcks * 4) - 1;
}
if ((bytes[0] & Helpers.MSG_ZEROCODED) != 0)
{
// Allocate a temporary buffer for the zerocoded packet
byte[] zeroBuffer = new byte[4096];
int zeroBytes = Helpers.ZeroDecode(bytes, length, zeroBuffer);
length = zeroBytes;
packet = new Packet(zeroBuffer, length, libsl.Protocol);
}
else
{
// Create the packet object from our byte array
packet = new Packet(bytes, length, libsl.Protocol);
}
if ((packet.Data[0] & Helpers.MSG_RELIABLE) != 0)
{
SendACK((uint)packet.Sequence);
}
Console.WriteLine(packet.ToString());
}
Console.WriteLine("[SERVER] Shutting down the socket on " + Endpoint.ToString());
Listener.Close();
}
private void SendACK(uint id)
{
try
{
Packet packet = new Packet("PacketAck", libsl.Protocol, 13);
packet.Data[8] = 1;
Array.Copy(BitConverter.GetBytes(id), 0, packet.Data, 9, 4);
// Set the sequence number
packet.Sequence = ++Sequence;
Listener.SendTo(packet.Data, RemoteEndpoint);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}