diff --git a/README b/README
deleted file mode 100644
index a290336..0000000
--- a/README
+++ /dev/null
@@ -1,22 +0,0 @@
-Whisper OpenSim Voice Module
-============================
-
-For a detailed documentation, please check doc/Whisper_Murmur_Config.pdf
-
-Many thanks to Snoopy Pfeffer, Justin Clark-Casey, and Brian Becker for making this release possible.
-
-Release Notes
-=============
-0.2.0
------
-- updated to compile for OpenSim 0.7.1+ (thanks to Justin)
-- grid support (thanks Snoopy)
-- glacier2 support (thanks Brian)
-
-0.1.0
------
-- initial version
-- for OpenSim standalone configuration
-
----------------------------------
-Contact: volker.gaessler@vcomm.ch
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b46aee1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,56 @@
+#Whisper OpenSim Voice Module#
+
+For detailed documentation please check [CONFIG].
+
+#Building#
+
+To use Whisper, one has to
+
+1. Build and/or install the OpenSimulator module.
+2. Build and/or install the Murmur viewer executable (which currently replaces SLVoice.exe in the viewer)
+3. Run a murmur server to route voice data between viewers after channels have been established via the
+OpenSimulator module.
+
+For detailed instructions on 2 and 3, please see [CONFIG]. Here, we will describe the process of building and
+configuring the OpenSimulator module in a bit more detail.
+
+##Building the OpenSimulator module##
+
+1. Copy this directory to $OPENSIM_BASE/addon-modules/Whisper
+2. Follow the instructions at [MODULE BUILD] to build the module. This will copy the generated DLL automatically
+into your $OPENSIM_BASE/bin directory.
+
+##Installing the OpenSimulator module##
+
+Alternatively, you can install the prebuilt bin/Whisper.dll into $OPENSIM_BASE/bin. This was built under
+Mono but should work on other systems. You will also need to copy over bin/Ice.dll and bin/Glacier2.dll if you
+are going to use the Glacier option.
+
+## Configuring the module##
+
+1. Copy the contents of the OpenSim.ini.include file into your OpenSim.ini
+
+#References#
+
+[CONFIG] - doc/Whisper_Murmur_Config.pdf
+[MODULE BUILD] - http://opensimulator.org/wiki/IRegionModule#Building_Region_Modules
+
+#Release Notes#
+
+##Development##
+- updated to compile from OpenSim 0.7.3 to 0.8 and current OpenSimulator dev code.
+
+##0.2.0##
+- updated to compile for OpenSim 0.7.1+ (thanks to Justin)
+- grid support (thanks Snoopy)
+- glacier2 support (thanks Brian)
+
+##0.1.0##
+- initial version
+- for OpenSim standalone configuration
+
+#Credits#
+* Volker Gaessler (vcomm.ch)
+* Snoopy Pfeffer (dreamlandmetaverse.com)
+* Justin Clark-Casey (justincc.org)
+* Brian Becker
diff --git a/Whisper/Modules/Murmur.cs b/Whisper/Modules/Murmur.cs
index dd5be15..2d5d2f3 100644
--- a/Whisper/Modules/Murmur.cs
+++ b/Whisper/Modules/Murmur.cs
@@ -10,8 +10,6 @@
// Ice version 3.3.1
// Generated from file `Murmur.ice'
-/// Original source at https://github.com/vgaessler/whisper_server
-
#if __MonoCS__
using _System = System;
diff --git a/Whisper/Modules/MurmurVoiceModule.cs b/Whisper/Modules/MurmurVoiceModule.cs
index 58de7ed..14aca4c 100644
--- a/Whisper/Modules/MurmurVoiceModule.cs
+++ b/Whisper/Modules/MurmurVoiceModule.cs
@@ -18,7 +18,6 @@
* along with this program. If not, see .
*/
-/// Original source at https://github.com/vgaessler/whisper_server
using Mono.Addins;
using System;
using System.IO;
@@ -27,6 +26,7 @@
using System.Threading;
using System.Collections.Generic;
using System.Reflection;
+using System.Xml;
using log4net;
using Nini.Config;
using OpenMetaverse;
@@ -366,13 +366,17 @@ public Agent GetOrCreate(UUID uuid, Scene scene)
{
string name = Agent.Name(uuid);
lock (name_to_agent)
+ {
if (name_to_agent.ContainsKey(name))
+ {
return (name_to_agent[name].session < 0 ? null : name_to_agent[name]);
+ }
else
{
Agent a = Add(uuid, scene);
return a;
}
+ }
}
public void RemoveAgent(UUID uuid)
@@ -382,8 +386,7 @@ public void RemoveAgent(UUID uuid)
m_log.DebugFormat("[MurmurVoice] Removing registered user {0}", user.name);
lock (name_to_agent)
- if (name_to_agent.ContainsKey(user.name))
- name_to_agent.Remove(user.name);
+ name_to_agent.Remove(user.name);
}
private Agent Add(UUID uuid, Scene scene)
@@ -398,12 +401,16 @@ private Agent Add(UUID uuid, Scene scene)
if (user.name == agent.name)
{
- m_log.DebugFormat("[MurmurVoice] Found previously registered user {0} {1} {2} {3}", user.name, user.userid, user.session, user.channel);
+ m_log.DebugFormat(
+ "[MurmurVoice] Found previously registered user {0} {1} {2} {3}",
+ user.name, user.userid, user.session, user.channel);
if ((user.userid >= 0) && (user.session >= 0))
{
// Reuse Murmur User
- m_log.DebugFormat("[MurmurVoice] Reusing previously registered user {0} {1} {2} {3}", user.name, user.userid, user.session, user.channel);
+ m_log.DebugFormat(
+ "[MurmurVoice] Reusing previously registered user {0} {1} {2} {3}",
+ user.name, user.userid, user.session, user.channel);
agent.userid = user.userid;
agent.session = user.session;
@@ -441,15 +448,26 @@ private Agent Add(UUID uuid, Scene scene)
try
{
+ m_log.DebugFormat(
+ "[MurmurVoice]: Registering user {0} {1} password {2} with Murmur server",
+ agent.name, agent.uuid, agent.pass);
+
int r = m_server.registerUser(agent.user_info);
- if (r >= 0) agent.userid = r;
+ if (r >= 0)
+ agent.userid = r;
}
- catch (Murmur.InvalidUserException)
+ catch (Murmur.InvalidUserException e)
{
- m_log.Warn("[MurmurVoice] InvalidUserException; continuing to recover later");
+ m_log.WarnFormat(
+ "[MurmurVoice] InvalidUserException; {0}{1}",
+ e.Message, e.StackTrace);
+
+ return null;
}
- m_log.DebugFormat("[MurmurVoice] Registered {0} (uid {1}) identified by {2}", agent.uuid.ToString(), agent.userid, agent.pass);
+ m_log.DebugFormat(
+ "[MurmurVoice] Registered {0} {1} (Murmur uid {2}) identified by {3}",
+ agent.name, agent.uuid, agent.userid, agent.pass);
return agent;
}
@@ -542,7 +560,7 @@ public class MurmurVoiceModule : ISharedRegionModule
private static string m_glacier_user;
private static string m_glacier_pass;
private static string m_murmur_ice_cb;
- private static string m_channel_name;
+ private static string m_parent_channel_name;
private static Dictionary m_managers = new Dictionary();
private static Dictionary m_servercallbacks = new Dictionary();
private static bool m_enabled = false;
@@ -584,13 +602,13 @@ public void Initialise(IConfigSource config)
if (null == m_config)
{
- m_log.Info("[MurmurVoice] no config found, plugin disabled");
+ m_log.Info("[MurmurVoice] No config found, plugin disabled");
return;
}
if (!m_config.GetBoolean("enabled", false))
{
- m_log.Info("[MurmurVoice] plugin disabled by configuration");
+ m_log.Info("[MurmurVoice] Plugin disabled by configuration");
return;
}
@@ -600,7 +618,7 @@ public void Initialise(IConfigSource config)
m_murmurd_ice = "Meta:" + m_config.GetString("murmur_ice", String.Empty);
m_murmur_ice_cb = m_config.GetString("murmur_ice_cb", "tcp -h 127.0.0.1");
- m_channel_name = m_config.GetString("channel_name", "Channel").Replace(" ","_");
+ m_parent_channel_name = m_config.GetString("channel_name", "Channel").Replace(" ","_");
m_glacier_enabled = m_config.GetBoolean("glacier", false);
m_glacier_ice = m_config.GetString("glacier_ice", String.Empty);
@@ -611,11 +629,11 @@ public void Initialise(IConfigSource config)
if (String.IsNullOrEmpty(m_murmurd_ice) ||
String.IsNullOrEmpty(m_murmurd_host) )
{
- m_log.Error("[MurmurVoice] plugin disabled: incomplete configuration");
+ m_log.Error("[MurmurVoice] Plugin disabled: incomplete configuration");
return;
}
- m_log.Info("[MurmurVoice] enabled");
+ m_log.Info("[MurmurVoice] Enabled");
m_enabled = true;
}
@@ -629,13 +647,13 @@ public void Initialize(Scene scene)
{
m_started = true;
- scene.AddCommand(this, "mumble report", "mumble report",
+ scene.AddCommand("Mumble", this, "mumble report", "mumble report",
"Returns mumble report", MumbleReport);
- scene.AddCommand(this, "mumble unregister", "mumble unregister ",
+ scene.AddCommand("Mumble", this, "mumble unregister", "mumble unregister ",
"Unregister User by userid", UnregisterUser);
- scene.AddCommand(this, "mumble remove", "mumble remove ",
+ scene.AddCommand("Mumble", this, "mumble remove", "mumble remove ",
"Remove Agent by UUID", RemoveAgent);
Ice.Communicator comm = Ice.Util.initialize();
@@ -647,14 +665,23 @@ public void Initialize(Scene scene)
m_router.createSession(m_glacier_user, m_glacier_pass);
}
+ m_log.DebugFormat("[MurmurVoice] Setting up connection to mumble server at {0}", m_murmurd_ice);
+
MetaPrx meta = MetaPrxHelper.checkedCast(comm.stringToProxy(m_murmurd_ice));
// Create the adapter
comm.getProperties().setProperty("Ice.PrintAdapterReady", "0");
if (m_glacier_enabled)
- m_adapter = comm.createObjectAdapterWithRouter("Callback.Client", comm.getDefaultRouter() );
+ {
+ m_log.DebugFormat("[MurmurVoice] Setting up Glacier callback");
+ m_adapter = comm.createObjectAdapterWithRouter("Callback.Client", comm.getDefaultRouter());
+ }
else
+ {
+ m_log.DebugFormat("[MurmurVoice] Setting up non-Glacier callback listener {0}", m_murmur_ice_cb);
m_adapter = comm.createObjectAdapterWithEndpoints("Callback.Client", m_murmur_ice_cb);
+ }
+
m_adapter.activate();
// Create identity and callback for Metaserver
@@ -662,10 +689,11 @@ public void Initialize(Scene scene)
metaCallbackIdent.name = "metaCallback";
if (m_router != null)
metaCallbackIdent.category = m_router.getCategoryForClient();
- MetaCallbackPrx meta_callback = MetaCallbackPrxHelper.checkedCast(m_adapter.add(new MetaCallbackImpl(), metaCallbackIdent));
+ MetaCallbackPrx meta_callback
+ = MetaCallbackPrxHelper.checkedCast(m_adapter.add(new MetaCallbackImpl(), metaCallbackIdent));
meta.addCallback(meta_callback);
- m_log.InfoFormat("[MurmurVoice] using murmur server ice '{0}'", m_murmurd_ice);
+ m_log.InfoFormat("[MurmurVoice] Using murmur server ice '{0}'", m_murmurd_ice);
// create a server and figure out the port name
Dictionary defaults = meta.getDefaultConf();
@@ -692,11 +720,11 @@ public void Initialize(Scene scene)
{
}
- m_log.Info("[MurmurVoice] started");
+ m_log.Info("[MurmurVoice] Started");
}
// starts the server and gets a callback
- ServerManager manager = new ServerManager(m_server, m_channel_name);
+ ServerManager manager = new ServerManager(m_server, m_parent_channel_name);
// Create identity and callback for this current server
AddServerCallback(scene, new ServerCallbackImpl(manager));
@@ -707,16 +735,23 @@ public void Initialize(Scene scene)
if (m_router != null)
serverCallbackIdent.category = m_router.getCategoryForClient();
- m_server.addCallback(ServerCallbackPrxHelper.checkedCast(m_adapter.add(GetServerCallback(scene), serverCallbackIdent)));
+ m_log.DebugFormat(
+ "[MurmurVoice] Adding murmur ICE ServerCallback {0} at listener {1}",
+ serverCallbackIdent.name, m_murmur_ice_cb);
+ m_server.addCallback(
+ ServerCallbackPrxHelper.checkedCast(m_adapter.add(GetServerCallback(scene), serverCallbackIdent)));
// Show information on console for debugging purposes
- m_log.InfoFormat("[MurmurVoice] using murmur server '{0}:{1}', sid '{2}'", m_murmurd_host, m_murmurd_port, m_server_id);
- m_log.Info("[MurmurVoice] plugin enabled");
+ m_log.InfoFormat(
+ "[MurmurVoice] Murmur server address for clients is '{0}:{1}', sid '{2}'",
+ m_murmurd_host, m_murmurd_port, m_server_id);
+
+ m_log.Info("[MurmurVoice] Plugin enabled");
m_enabled = true;
}
catch (Exception e)
{
- m_log.ErrorFormat("[MurmurVoice] plugin initialization failed: {0}", e.ToString());
+ m_log.Error("[MurmurVoice] Plugin initialization failed, ", e);
return;
}
}
@@ -758,11 +793,12 @@ public void RemovePresence(UUID agentID)
public void ClientClosed(UUID agentID, Scene scene)
{
- m_log.DebugFormat("[MurmurVoice]: ClientClosed {0}", agentID);
+ m_log.DebugFormat("[MurmurVoice]: ClientClosed {0} on {1}", agentID, scene.RegionInfo.RegionName);
ScenePresence avatar = scene.GetScenePresence(agentID);
- if ((avatar == null) || (avatar.IsChildAgent)) return;
+ if ((avatar == null) || (avatar.IsChildAgent))
+ return;
GetServerManager(scene).Agent.RemoveAgent(agentID);
}
@@ -824,19 +860,18 @@ private string ChannelName(Scene scene, LandData land)
{
// Create parcel voice channel. If no parcel exists, then the voice channel ID is the same
// as the directory ID. Otherwise, it reflects the parcel's ID.
+ string channelName;
if (land.LocalID != 1 && (land.Flags & (uint)ParcelFlags.UseEstateVoiceChan) == 0)
- {
- m_log.DebugFormat("[MurmurVoice]: Region: parcel \"{0}:{1}\": parcel id {2} {3}",
- scene.RegionInfo.RegionName, land.Name, land.LocalID, land.GlobalID.ToString().Replace("-",""));
- return land.GlobalID.ToString().Replace("-","");
- }
+ channelName = land.GlobalID.ToString().Replace("-","");
else
- {
- m_log.DebugFormat("[MurmurVoice]: Region: parcel \"{0}:{1}\": parcel id {2} {3}",
- scene.RegionInfo.RegionName, scene.RegionInfo.RegionName, land.LocalID, scene.RegionInfo.RegionID.ToString().Replace("-",""));
- return scene.RegionInfo.RegionID.ToString().Replace("-","");
- }
+ channelName = scene.RegionInfo.RegionID.ToString().Replace("-","");
+
+ m_log.DebugFormat(
+ "[MurmurVoice]: Channel name {0} for region:parcel \"{1}:{2}\": parcel id {3}",
+ scene.RegionInfo.RegionName, land.Name, land.LocalID, channelName);
+
+ return channelName;
}
// OnRegisterCaps is invoked via the scene.EventManager
@@ -863,7 +898,7 @@ public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps)
caps.RegisterHandler("ProvisionVoiceAccountRequest",
new RestStreamHandler("POST", capsBase + m_provisionVoiceAccountRequestPath,
delegate(string request, string path, string param,
- OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
return ProvisionVoiceAccountRequest(scene, request, path, param,
agentID);
@@ -871,7 +906,7 @@ public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps)
caps.RegisterHandler("ParcelVoiceInfoRequest",
new RestStreamHandler("POST", capsBase + m_parcelVoiceInfoRequestPath,
delegate(string request, string path, string param,
- OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
return ParcelVoiceInfoRequest(scene, request, path, param,
agentID);
@@ -879,7 +914,7 @@ public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps)
caps.RegisterHandler("ChatSessionRequest",
new RestStreamHandler("POST", capsBase + m_chatSessionRequestPath,
delegate(string request, string path, string param,
- OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
return ChatSessionRequest(scene, request, path, param,
agentID);
@@ -889,13 +924,21 @@ public void OnRegisterCaps(Scene scene, UUID agentID, Caps caps)
caps.RegisterHandler("mumble_server_info",
new RestStreamHandler("GET", capsBase + m_chatSessionRequestPath,
delegate(string request, string path, string param,
- OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
return RestGetMumbleServerInfo(scene, request, path, param, httpRequest, httpResponse);
}));
}
+ ///
/// Callback for a client request for Voice Account Details.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
public string ProvisionVoiceAccountRequest(Scene scene, string request, string path, string param,
UUID agentID)
{
@@ -931,12 +974,20 @@ public string ProvisionVoiceAccountRequest(Scene scene, string request, string p
}
catch (Exception e)
{
- m_log.DebugFormat("[MurmurVoice] {0} failed", e.ToString());
+ m_log.DebugFormat("[MurmurVoice] Exception {0}{1}", e.Message, e.StackTrace);
return "";
}
}
- /// Callback for a client request for ParcelVoiceInfo
+ ///
+ /// Handle the client request to the ParcelVoiceInfoRequest capability.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
public string ParcelVoiceInfoRequest(Scene scene, string request, string path, string param,
UUID agentID)
{
@@ -970,7 +1021,9 @@ public string ParcelVoiceInfoRequest(Scene scene, string request, string path, s
if (agent == null)
{
- m_log.ErrorFormat("[MurmurVoice] Agent not connected {0}", agentID);
+ m_log.WarnFormat(
+ "[MurmurVoice] Agent {0} not registered with Murmur server. Waiting for retry by viewer.",
+ agentID);
return "";
}
@@ -983,7 +1036,8 @@ public string ParcelVoiceInfoRequest(Scene scene, string request, string path, s
{
if (++retry > 50)
{
- m_log.ErrorFormat("[MurmurVoice] Connecting failed {0} (uid {1}) identified by {2}", agent.uuid.ToString(), agent.userid, agent.pass);
+ m_log.ErrorFormat("[MurmurVoice] Connecting failed {0} (uid {1}) identified by {2}",
+ agent.uuid, agent.userid, agent.pass);
return "";
}
@@ -997,7 +1051,7 @@ public string ParcelVoiceInfoRequest(Scene scene, string request, string path, s
Murmur.User state = manager.Server.getState(agent.session);
GetServerCallback(scene).AddUserToChan(state, agent.channel);
- m_log.DebugFormat("[MurmurVoice] {0}", channel_uri);
+// m_log.DebugFormat("[MurmurVoice] {0}", channel_uri);
}
else
{
@@ -1007,7 +1061,8 @@ public string ParcelVoiceInfoRequest(Scene scene, string request, string path, s
Hashtable creds = new Hashtable();
creds["channel_uri"] = channel_uri;
- LLSDParcelVoiceInfoResponse parcelVoiceInfo = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds);
+ LLSDParcelVoiceInfoResponse parcelVoiceInfo
+ = new LLSDParcelVoiceInfoResponse(scene.RegionInfo.RegionName, land.LocalID, creds);
string r = LLSDHelpers.SerialiseLLSDReply(parcelVoiceInfo);
m_log.DebugFormat("[MurmurVoice] Parcel: {0}", r);
@@ -1015,7 +1070,7 @@ public string ParcelVoiceInfoRequest(Scene scene, string request, string path, s
}
catch (Exception e)
{
- m_log.ErrorFormat("[MurmurVoice] Exception: " + e.ToString());
+ m_log.Error("[MurmurVoice] Exception, ", e);
return "";
}
}
@@ -1042,7 +1097,7 @@ public string ChatSessionRequest(Scene scene, string request, string path, strin
/// HTTP response header object
/// Information about the mumble server in http response headers
public string RestGetMumbleServerInfo(Scene scene, string request, string path, string param,
- OSHttpRequest httpRequest, OSHttpResponse httpResponse)
+ IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
{
if (m_murmurd_host == null)
{
@@ -1053,6 +1108,7 @@ public string RestGetMumbleServerInfo(Scene scene, string request, string path,
m_log.Warn(message);
return "Mumble server info is not available.";
}
+
if (httpRequest.Headers.GetValues("avatar_uuid") == null)
{
httpResponse.StatusCode = 400;
@@ -1102,7 +1158,7 @@ public string RestGetMumbleServerInfo(Scene scene, string request, string path,
GetServerCallback(scene).AddUserToChan(state, agent.channel);
}
- m_log.InfoFormat("[MurmurVoice] {0}", channel_uri);
+ m_log.InfoFormat("[MurmurVoice] channel_uri {0}", channel_uri);
}
else
{
@@ -1158,6 +1214,8 @@ private void MumbleReport(string module, string[] args)
Dictionary users = m_server.getUsers();
+ m_log.InfoFormat("Users Connected: {0}", users.Count);
+
foreach (var v in users)
{
User user = v.Value;
@@ -1207,4 +1265,4 @@ private void RemoveAgent(string module, string[] args)
}
#endregion
-}
+}
\ No newline at end of file
diff --git a/bin/Whisper.dll b/bin/Whisper.dll
index b01abac..cc6663f 100644
Binary files a/bin/Whisper.dll and b/bin/Whisper.dll differ
diff --git a/Whisper/prebuild.xml b/prebuild.xml
similarity index 61%
rename from Whisper/prebuild.xml
rename to prebuild.xml
index efd6611..55c7a43 100644
--- a/Whisper/prebuild.xml
+++ b/prebuild.xml
@@ -1,37 +1,37 @@
-
+
- ../../../bin/
+ ../../../../bin/
- ../../../bin/
+ ../../../../bin/
- ../../../bin/
+ ../../../../bin/
- ../../../bin/
+ ../../../../bin/
- ../../../bin/
+ ../../../../bin/
- ../../../bin/
+ ../../../../bin/
- ../../../bin/
+ ../../../../bin/
@@ -40,9 +40,9 @@
-
-
-
+
+
+
@@ -51,11 +51,11 @@
-
-
-
-
-
+
+
+
+
+