Files
opensim/OpenSim/Region/Environment/Modules/VoiceChat/VoiceClient.cs
2008-03-04 04:11:37 +00:00

197 lines
6.7 KiB
C#

/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* 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 OpenSim Project 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 THE DEVELOPERS ``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 THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using OpenSim.Region.Environment.Scenes;
using libsecondlife;
namespace OpenSim.Region.Environment.Modules.VoiceChat
{
/**
* Represents a single voiceclient instance
**/
public class VoiceClient
{
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public Socket m_socket;
public LLUUID m_clientId;
public bool m_authenticated = false;
protected VoicePacketHeader m_header = null;
protected int m_headerBytesReceived = 0;
protected int m_offset = 0;
protected int m_supportedCodecs = 0;
protected byte[] m_buffer = null;
protected byte[] m_headerBytes = new byte[5];
protected bool m_enabled = true;
protected VoiceChatServer m_server;
public VoiceClient(Socket socket, VoiceChatServer server)
{
m_socket = socket;
m_server = server;
}
public void OnDataReceived(byte[] data, int byteCount)
{
int offset = 0;
while (offset < byteCount)
{
if (m_header == null)
{
if (m_headerBytesReceived < 5)
{
m_headerBytes[m_headerBytesReceived++] = data[offset++];
}
else if (m_headerBytesReceived == 5)
{
m_header = new VoicePacketHeader();
m_header.Parse(m_headerBytes);
if (m_header.length > 65535)
{
throw new Exception("Packet size " + m_header.length + " > 65535");
}
m_buffer = new byte[m_header.length];
m_offset = 0;
m_headerBytesReceived = 0;
}
}
else
{
int bytesToCopy = m_header.length-m_offset;
if (bytesToCopy > byteCount - offset)
bytesToCopy = byteCount - offset;
Buffer.BlockCopy(data, offset, m_buffer, m_offset, bytesToCopy);
offset += bytesToCopy;
m_offset += bytesToCopy;
if (m_offset == m_header.length)
{
ParsePacket(m_header.type, m_buffer);
m_header = null;
}
}
}
}
void ParsePacket(byte type, byte[] data)
{
switch (type)
{
case 0: //LOGIN
ParseLogin(data);
break;
case 1: //AUDIODATA
if (m_authenticated)
{
VoicePacket packet = new VoicePacket(data);
packet.m_clientId = m_clientId;
m_server.BroadcastVoice(packet);
}
else
{
m_log.Warn("[VOICECHAT]: Got unauthorized audio data from " +
m_socket.RemoteEndPoint.ToString());
m_socket.Close();
}
break;
case 3: //ENABLEVOIP
if (data[0] == 0)
{
m_log.Warn("[VOICECHAT]: VoiceChat has been disabled for " + m_clientId);
m_enabled = false;
}
else
{
m_log.Warn("[VOICECHAT]: VoiceChat has been enabled for " + m_clientId);
m_enabled = true;
}
break;
default:
throw new Exception("Invalid packet received");
}
}
void ParseLogin(byte[] data)
{
m_clientId = new LLUUID(data, 0);
m_supportedCodecs = data[16];
m_supportedCodecs |= data[17] << 8;
m_supportedCodecs |= data[18] << 16;
m_supportedCodecs |= data[19] << 24;
if (m_server.AddClient(this, m_clientId))
{
m_log.Info("[VOICECHAT]: Client authenticated succesfully: " + m_clientId);
m_authenticated = true;
}
else
{
throw new Exception("Unable to authenticate with id " + m_clientId);
}
}
public bool IsEnabled()
{
return m_enabled;
}
public bool IsCodecSupported(int codec)
{
if ((m_supportedCodecs & codec) != 0)
return true;
return false;
}
public void SendTo(byte[] data)
{
if (m_authenticated)
{
//ServerStatus.ReportOutPacketTcp(m_socket.Send(data));
}
}
}
}