aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs')
-rw-r--r--OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs686
1 files changed, 343 insertions, 343 deletions
diff --git a/OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs b/OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs
index 68197bb..5ec0ca8 100644
--- a/OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs
+++ b/OpenSim/Region/Environment/Modules/VoiceChat/VoiceChatServer.cs
@@ -1,343 +1,343 @@
1using System; 1using System;
2using System.Collections.Generic; 2using System.Collections.Generic;
3using System.Text; 3using System.Text;
4using System.Threading; 4using System.Threading;
5using System.Net.Sockets; 5using System.Net.Sockets;
6using System.Net; 6using System.Net;
7using OpenSim.Region.Environment.Scenes; 7using OpenSim.Region.Environment.Scenes;
8using OpenSim.Framework; 8using OpenSim.Framework;
9using OpenSim.Region.Environment.Modules; 9using OpenSim.Region.Environment.Modules;
10using OpenSim.Region.Environment.Interfaces; 10using OpenSim.Region.Environment.Interfaces;
11using Nini; 11using Nini;
12using libsecondlife; 12using libsecondlife;
13 13
14namespace OpenSim.Region.Environment.Modules.VoiceChat 14namespace OpenSim.Region.Environment.Modules.VoiceChat
15{ 15{
16 public class VoiceChatServer : IRegionModule 16 public class VoiceChatServer : IRegionModule
17 { 17 {
18 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); 18 private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
19 19
20 int m_dummySocketPort = 53134; 20 int m_dummySocketPort = 53134;
21 21
22 Thread m_listenerThread; 22 Thread m_listenerThread;
23 Thread m_mainThread; 23 Thread m_mainThread;
24 List<Scene> m_scenes = new List<Scene>(); 24 List<Scene> m_scenes = new List<Scene>();
25 Socket m_server; 25 Socket m_server;
26 Socket m_selectCancel; 26 Socket m_selectCancel;
27 bool m_enabled = false; 27 bool m_enabled = false;
28 28
29 Dictionary<Socket, VoiceClient> m_clients = new Dictionary<Socket,VoiceClient>(); 29 Dictionary<Socket, VoiceClient> m_clients = new Dictionary<Socket,VoiceClient>();
30 Dictionary<LLUUID, VoiceClient> m_uuidToClient = new Dictionary<LLUUID,VoiceClient>(); 30 Dictionary<LLUUID, VoiceClient> m_uuidToClient = new Dictionary<LLUUID,VoiceClient>();
31 31
32 32
33 #region IRegionModule Members 33 #region IRegionModule Members
34 34
35 public void Initialise(Scene scene, Nini.Config.IConfigSource source) 35 public void Initialise(Scene scene, Nini.Config.IConfigSource source)
36 { 36 {
37 try 37 try
38 { 38 {
39 m_enabled = source.Configs["Voice"].GetBoolean("enabled", m_enabled); 39 m_enabled = source.Configs["Voice"].GetBoolean("enabled", m_enabled);
40 } 40 }
41 catch (Exception) 41 catch (Exception)
42 { } 42 { }
43 43
44 if (m_enabled) 44 if (m_enabled)
45 { 45 {
46 if (!m_scenes.Contains(scene)) 46 if (!m_scenes.Contains(scene))
47 m_scenes.Add(scene); 47 m_scenes.Add(scene);
48 48
49 scene.EventManager.OnNewClient += NewClient; 49 scene.EventManager.OnNewClient += NewClient;
50 scene.EventManager.OnRemovePresence += RemovePresence; 50 scene.EventManager.OnRemovePresence += RemovePresence;
51 } 51 }
52 } 52 }
53 53
54 public void PostInitialise() 54 public void PostInitialise()
55 { 55 {
56 if (m_enabled != true) 56 if (m_enabled != true)
57 return; 57 return;
58 58
59 try 59 try
60 { 60 {
61 CreateListeningSocket(); 61 CreateListeningSocket();
62 } 62 }
63 catch (Exception) 63 catch (Exception)
64 { 64 {
65 m_log.Error("[VOICECHAT]: Unable to start listening"); 65 m_log.Error("[VOICECHAT]: Unable to start listening");
66 return; 66 return;
67 } 67 }
68 68
69 m_listenerThread = new Thread(new ThreadStart(ListenIncomingConnections)); 69 m_listenerThread = new Thread(new ThreadStart(ListenIncomingConnections));
70 m_listenerThread.IsBackground = true; 70 m_listenerThread.IsBackground = true;
71 m_listenerThread.Start(); 71 m_listenerThread.Start();
72 72
73 m_mainThread = new Thread(new ThreadStart(RunVoiceChat)); 73 m_mainThread = new Thread(new ThreadStart(RunVoiceChat));
74 m_mainThread.IsBackground = true; 74 m_mainThread.IsBackground = true;
75 m_mainThread.Start(); 75 m_mainThread.Start();
76 76
77 Thread.Sleep(500); 77 Thread.Sleep(500);
78 m_selectCancel = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 78 m_selectCancel = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
79 m_selectCancel.Connect("localhost", m_dummySocketPort); 79 m_selectCancel.Connect("localhost", m_dummySocketPort);
80 } 80 }
81 81
82 public void Close() 82 public void Close()
83 { 83 {
84 throw new NotImplementedException(); 84 throw new NotImplementedException();
85 } 85 }
86 86
87 public string Name 87 public string Name
88 { 88 {
89 get { return "VoiceChatModule"; } 89 get { return "VoiceChatModule"; }
90 } 90 }
91 91
92 public bool IsSharedModule 92 public bool IsSharedModule
93 { 93 {
94 get { return true; } // I think we can share this one. 94 get { return true; } // I think we can share this one.
95 } 95 }
96 96
97 #endregion 97 #endregion
98 98
99 public void NewClient(IClientAPI client) 99 public void NewClient(IClientAPI client)
100 { 100 {
101 m_log.Info("[VOICECHAT]: New client: " + client.AgentId); 101 m_log.Info("[VOICECHAT]: New client: " + client.AgentId);
102 lock (m_uuidToClient) 102 lock (m_uuidToClient)
103 { 103 {
104 m_uuidToClient[client.AgentId] = null; 104 m_uuidToClient[client.AgentId] = null;
105 } 105 }
106 } 106 }
107 107
108 public void RemovePresence(LLUUID uuid) 108 public void RemovePresence(LLUUID uuid)
109 { 109 {
110 lock (m_uuidToClient) 110 lock (m_uuidToClient)
111 { 111 {
112 if (m_uuidToClient.ContainsKey(uuid)) 112 if (m_uuidToClient.ContainsKey(uuid))
113 { 113 {
114 if (m_uuidToClient[uuid] != null) 114 if (m_uuidToClient[uuid] != null)
115 { 115 {
116 RemoveClient(m_uuidToClient[uuid].m_socket); 116 RemoveClient(m_uuidToClient[uuid].m_socket);
117 } 117 }
118 m_uuidToClient.Remove(uuid); 118 m_uuidToClient.Remove(uuid);
119 } 119 }
120 else 120 else
121 { 121 {
122 m_log.Error("[VOICECHAT]: Presence not found on RemovePresence: " + uuid); 122 m_log.Error("[VOICECHAT]: Presence not found on RemovePresence: " + uuid);
123 } 123 }
124 } 124 }
125 } 125 }
126 126
127 public bool AddClient(VoiceClient client, LLUUID uuid) 127 public bool AddClient(VoiceClient client, LLUUID uuid)
128 { 128 {
129 lock (m_uuidToClient) 129 lock (m_uuidToClient)
130 { 130 {
131 if (m_uuidToClient.ContainsKey(uuid)) 131 if (m_uuidToClient.ContainsKey(uuid))
132 { 132 {
133 if (m_uuidToClient[uuid] != null) { 133 if (m_uuidToClient[uuid] != null) {
134 m_log.Warn("[VOICECHAT]: Multiple login attempts for " + uuid); 134 m_log.Warn("[VOICECHAT]: Multiple login attempts for " + uuid);
135 return false; 135 return false;
136 } 136 }
137 m_uuidToClient[uuid] = client; 137 m_uuidToClient[uuid] = client;
138 return true; 138 return true;
139 } 139 }
140 } 140 }
141 return false; 141 return false;
142 } 142 }
143 143
144 public void RemoveClient(Socket socket) 144 public void RemoveClient(Socket socket)
145 { 145 {
146 m_log.Info("[VOICECHAT]: Removing client"); 146 m_log.Info("[VOICECHAT]: Removing client");
147 lock(m_clients) 147 lock(m_clients)
148 { 148 {
149 VoiceClient client = m_clients[socket]; 149 VoiceClient client = m_clients[socket];
150 150
151 lock(m_uuidToClient) 151 lock(m_uuidToClient)
152 { 152 {
153 if (m_uuidToClient.ContainsKey(client.m_clientId)) 153 if (m_uuidToClient.ContainsKey(client.m_clientId))
154 { 154 {
155 m_uuidToClient[client.m_clientId] = null; 155 m_uuidToClient[client.m_clientId] = null;
156 } 156 }
157 } 157 }
158 158
159 m_clients.Remove(socket); 159 m_clients.Remove(socket);
160 client.m_socket.Close(); 160 client.m_socket.Close();
161 } 161 }
162 } 162 }
163 163
164 protected void CreateListeningSocket() 164 protected void CreateListeningSocket()
165 { 165 {
166 IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 12000); 166 IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 12000);
167 m_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 167 m_server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
168 m_server.Bind(listenEndPoint); 168 m_server.Bind(listenEndPoint);
169 m_server.Listen(50); 169 m_server.Listen(50);
170 } 170 }
171 171
172 void ListenIncomingConnections() 172 void ListenIncomingConnections()
173 { 173 {
174 m_log.Info("[VOICECHAT]: Listening connections..."); 174 m_log.Info("[VOICECHAT]: Listening connections...");
175 //ServerStatus.ReportThreadName("VoiceChat: Connection listener"); 175 //ServerStatus.ReportThreadName("VoiceChat: Connection listener");
176 176
177 byte[] dummyBuffer = new byte[1]; 177 byte[] dummyBuffer = new byte[1];
178 178
179 while (true) 179 while (true)
180 { 180 {
181 try 181 try
182 { 182 {
183 Socket connection = m_server.Accept(); 183 Socket connection = m_server.Accept();
184 lock (m_clients) 184 lock (m_clients)
185 { 185 {
186 m_clients[connection] = new VoiceClient(connection, this); 186 m_clients[connection] = new VoiceClient(connection, this);
187 m_selectCancel.Send(dummyBuffer); 187 m_selectCancel.Send(dummyBuffer);
188 m_log.Info("[VOICECHAT]: Voicechat connection from " + connection.RemoteEndPoint.ToString()); 188 m_log.Info("[VOICECHAT]: Voicechat connection from " + connection.RemoteEndPoint.ToString());
189 } 189 }
190 } 190 }
191 catch (SocketException e) 191 catch (SocketException e)
192 { 192 {
193 m_log.Error("[VOICECHAT]: During accept: " + e.ToString()); 193 m_log.Error("[VOICECHAT]: During accept: " + e.ToString());
194 } 194 }
195 } 195 }
196 } 196 }
197 197
198 Socket ListenLoopbackSocket() 198 Socket ListenLoopbackSocket()
199 { 199 {
200 IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), m_dummySocketPort); 200 IPEndPoint listenEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), m_dummySocketPort);
201 Socket dummyListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 201 Socket dummyListener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
202 dummyListener.Bind(listenEndPoint); 202 dummyListener.Bind(listenEndPoint);
203 dummyListener.Listen(1); 203 dummyListener.Listen(1);
204 Socket socket = dummyListener.Accept(); 204 Socket socket = dummyListener.Accept();
205 dummyListener.Close(); 205 dummyListener.Close();
206 return socket; 206 return socket;
207 } 207 }
208 208
209 void RunVoiceChat() 209 void RunVoiceChat()
210 { 210 {
211 m_log.Info("[VOICECHAT]: Connection handler started..."); 211 m_log.Info("[VOICECHAT]: Connection handler started...");
212 //ServerStatus.ReportThreadName("VoiceChat: Connection handler"); 212 //ServerStatus.ReportThreadName("VoiceChat: Connection handler");
213 213
214 //Listen a loopback socket for aborting select call 214 //Listen a loopback socket for aborting select call
215 Socket dummySocket = ListenLoopbackSocket(); 215 Socket dummySocket = ListenLoopbackSocket();
216 216
217 List<Socket> sockets = new List<Socket>(); 217 List<Socket> sockets = new List<Socket>();
218 byte[] buffer = new byte[65536]; 218 byte[] buffer = new byte[65536];
219 219
220 while (true) 220 while (true)
221 { 221 {
222 if (m_clients.Count == 0) 222 if (m_clients.Count == 0)
223 { 223 {
224 Thread.Sleep(100); 224 Thread.Sleep(100);
225 continue; 225 continue;
226 } 226 }
227 227
228 lock (m_clients) 228 lock (m_clients)
229 { 229 {
230 foreach (Socket s in m_clients.Keys) 230 foreach (Socket s in m_clients.Keys)
231 { 231 {
232 sockets.Add(s); 232 sockets.Add(s);
233 } 233 }
234 } 234 }
235 sockets.Add(dummySocket); 235 sockets.Add(dummySocket);
236 236
237 try 237 try
238 { 238 {
239 Socket.Select(sockets, null, null, 200000); 239 Socket.Select(sockets, null, null, 200000);
240 } 240 }
241 catch (SocketException e) 241 catch (SocketException e)
242 { 242 {
243 m_log.Warn("[VOICECHAT]: " + e.Message); 243 m_log.Warn("[VOICECHAT]: " + e.Message);
244 } 244 }
245 245
246 foreach (Socket s in sockets) 246 foreach (Socket s in sockets)
247 { 247 {
248 try 248 try
249 { 249 {
250 if (s.RemoteEndPoint != dummySocket.RemoteEndPoint) 250 if (s.RemoteEndPoint != dummySocket.RemoteEndPoint)
251 { 251 {
252 ReceiveFromSocket(s, buffer); 252 ReceiveFromSocket(s, buffer);
253 } 253 }
254 else 254 else
255 { 255 {
256 //Receive data and check if there was an error with select abort socket 256 //Receive data and check if there was an error with select abort socket
257 if (s.Receive(buffer) <= 0) 257 if (s.Receive(buffer) <= 0)
258 { 258 {
259 //Just give a warning for now 259 //Just give a warning for now
260 m_log.Error("[VOICECHAT]: Select abort socket was closed"); 260 m_log.Error("[VOICECHAT]: Select abort socket was closed");
261 } 261 }
262 } 262 }
263 } 263 }
264 catch(ObjectDisposedException e) 264 catch(ObjectDisposedException e)
265 { 265 {
266 m_log.Warn("[VOICECHAT]: Connection has been already closed"); 266 m_log.Warn("[VOICECHAT]: Connection has been already closed");
267 } 267 }
268 catch (Exception e) 268 catch (Exception e)
269 { 269 {
270 m_log.Error("[VOICECHAT]: Exception: " + e.Message); 270 m_log.Error("[VOICECHAT]: Exception: " + e.Message);
271 271
272 RemoveClient(s); 272 RemoveClient(s);
273 } 273 }
274 } 274 }
275 275
276 sockets.Clear(); 276 sockets.Clear();
277 } 277 }
278 } 278 }
279 279
280 private void ReceiveFromSocket( Socket s, byte[] buffer ) 280 private void ReceiveFromSocket( Socket s, byte[] buffer )
281 { 281 {
282 int byteCount = s.Receive(buffer); 282 int byteCount = s.Receive(buffer);
283 if (byteCount <= 0) 283 if (byteCount <= 0)
284 { 284 {
285 m_log.Info("[VOICECHAT]: Connection lost to " + s.RemoteEndPoint); 285 m_log.Info("[VOICECHAT]: Connection lost to " + s.RemoteEndPoint);
286 lock (m_clients) 286 lock (m_clients)
287 { 287 {
288 RemoveClient(s); 288 RemoveClient(s);
289 } 289 }
290 } 290 }
291 else 291 else
292 { 292 {
293 //ServerStatus.ReportInPacketTcp(byteCount); 293 //ServerStatus.ReportInPacketTcp(byteCount);
294 lock (m_clients) 294 lock (m_clients)
295 { 295 {
296 if (m_clients.ContainsKey(s)) 296 if (m_clients.ContainsKey(s))
297 { 297 {
298 m_clients[s].OnDataReceived(buffer, byteCount); 298 m_clients[s].OnDataReceived(buffer, byteCount);
299 } 299 }
300 else 300 else
301 { 301 {
302 m_log.Warn("[VOICECHAT]: Got data from " + s.RemoteEndPoint + 302 m_log.Warn("[VOICECHAT]: Got data from " + s.RemoteEndPoint +
303 ", but source is not a valid voice client"); 303 ", but source is not a valid voice client");
304 } 304 }
305 } 305 }
306 } 306 }
307 } 307 }
308 308
309 public LLVector3 getScenePresencePosition(LLUUID clientID) 309 public LLVector3 getScenePresencePosition(LLUUID clientID)
310 { 310 {
311 foreach (Scene scene in m_scenes) 311 foreach (Scene scene in m_scenes)
312 { 312 {
313 ScenePresence x; 313 ScenePresence x;
314 if ((x = scene.GetScenePresence(clientID)) != null) 314 if ((x = scene.GetScenePresence(clientID)) != null)
315 { 315 {
316 return x.AbsolutePosition + new LLVector3(Constants.RegionSize * scene.RegionInfo.RegionLocX, 316 return x.AbsolutePosition + new LLVector3(Constants.RegionSize * scene.RegionInfo.RegionLocX,
317 Constants.RegionSize * scene.RegionInfo.RegionLocY, 0); 317 Constants.RegionSize * scene.RegionInfo.RegionLocY, 0);
318 } 318 }
319 } 319 }
320 return LLVector3.Zero; 320 return LLVector3.Zero;
321 } 321 }
322 322
323 public void BroadcastVoice(VoicePacket packet) 323 public void BroadcastVoice(VoicePacket packet)
324 { 324 {
325 libsecondlife.LLVector3 origPos = getScenePresencePosition(packet.m_clientId); 325 libsecondlife.LLVector3 origPos = getScenePresencePosition(packet.m_clientId);
326 326
327 byte[] bytes = packet.GetBytes(); 327 byte[] bytes = packet.GetBytes();
328 foreach (VoiceClient client in m_clients.Values) 328 foreach (VoiceClient client in m_clients.Values)
329 { 329 {
330 if (client.IsEnabled() && client.m_clientId != packet.m_clientId && 330 if (client.IsEnabled() && client.m_clientId != packet.m_clientId &&
331 client.m_authenticated && client.IsCodecSupported(packet.m_codec)) 331 client.m_authenticated && client.IsCodecSupported(packet.m_codec))
332 { 332 {
333 LLVector3 presenceLoc = getScenePresencePosition(client.m_clientId); 333 LLVector3 presenceLoc = getScenePresencePosition(client.m_clientId);
334 334
335 if (presenceLoc != LLVector3.Zero && Util.GetDistanceTo(presenceLoc, origPos) < 20) 335 if (presenceLoc != LLVector3.Zero && Util.GetDistanceTo(presenceLoc, origPos) < 20)
336 { 336 {
337 client.SendTo(bytes); 337 client.SendTo(bytes);
338 } 338 }
339 } 339 }
340 } 340 }
341 } 341 }
342 } 342 }
343} 343}