Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Adam <dev@robert-adam.de>2021-11-14 21:39:51 +0300
committerRobert Adam <dev@robert-adam.de>2021-11-18 21:25:28 +0300
commit86375de2a61971fd22cf48fe104d73087386030e (patch)
tree0d731d9a75c6863bdad96ea48793fbd1cabb6f7f
parent3d142ac23800347b1f77b97e9d493cd2e00311e6 (diff)
FEAT(plugins): Add option to use context prefix
With the new plugin function, plugins can choose a custom prefix for use in the positional audio context.
-rw-r--r--plugins/MumblePlugin_v_1_1_x.h477
-rw-r--r--src/mumble/Plugin.cpp35
-rw-r--r--src/mumble/Plugin.h10
-rw-r--r--src/mumble/PluginManager.cpp4
4 files changed, 522 insertions, 4 deletions
diff --git a/plugins/MumblePlugin_v_1_1_x.h b/plugins/MumblePlugin_v_1_1_x.h
new file mode 100644
index 000000000..1555dac17
--- /dev/null
+++ b/plugins/MumblePlugin_v_1_1_x.h
@@ -0,0 +1,477 @@
+// Copyright 2021 The Mumble Developers. All rights reserved.
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file at the root of the
+// Mumble source tree or at <https://www.mumble.info/LICENSE>.
+
+/// This header file specifies the Mumble plugin interface
+
+#ifndef EXTERNAL_MUMBLE_PLUGIN_H_
+#define EXTERNAL_MUMBLE_PLUGIN_H_
+
+#include "PluginComponents_v_1_0_x.h"
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#if defined(__GNUC__) && !defined(__MINGW32__) // GCC on Unix-like systems
+# define PLUGIN_EXPORT __attribute__((visibility("default")))
+#elif defined(_MSC_VER)
+# define PLUGIN_EXPORT __declspec(dllexport)
+#elif defined(__MINGW32__)
+# define PLUGIN_EXPORT __attribute__((dllexport))
+#else
+# error No PLUGIN_EXPORT definition available
+#endif
+
+
+// Plugin functions version
+#define MUMBLE_PLUGIN_FUNCTIONS_MAJOR_MACRO 1
+#define MUMBLE_PLUGIN_FUNCTIONS_MINOR_MACRO 1
+#define MUMBLE_PLUGIN_FUNCTIONS_PATCH_MACRO 0
+
+const int32_t MUMBLE_PLUGIN_FUNCTIONS_MAJOR = MUMBLE_PLUGIN_FUNCTIONS_MAJOR_MACRO;
+const int32_t MUMBLE_PLUGIN_FUNCTIONS_MINOR = MUMBLE_PLUGIN_FUNCTIONS_MINOR_MACRO;
+const int32_t MUMBLE_PLUGIN_FUNCTIONS_PATCH = MUMBLE_PLUGIN_FUNCTIONS_PATCH_MACRO;
+const mumble_version_t MUMBLE_PLUGIN_FUNCTIONS_VERSION = { MUMBLE_PLUGIN_FUNCTIONS_MAJOR, MUMBLE_PLUGIN_FUNCTIONS_MINOR,
+ MUMBLE_PLUGIN_FUNCTIONS_PATCH };
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//////////////////////////////////////////////////////////////////////////////////
+////////////////////////////// MANDATORY FUNCTIONS ///////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+
+/// Gets called right after loading the plugin in order to let the plugin initialize.
+///
+/// Registers the ID of this plugin.
+/// @param id The ID for this plugin. This is the ID Mumble will reference this plugin with
+/// and by which this plugin can identify itself when communicating with Mumble.
+/// @returns The status of the initialization. If everything went fine, return STATUS_OK
+PLUGIN_EXPORT mumble_error_t PLUGIN_CALLING_CONVENTION mumble_init(mumble_plugin_id_t id);
+
+/// Gets called when unloading the plugin in order to allow it to clean up after itself.
+/// Note that it is still safe to call API functions from within this callback.
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_shutdown();
+
+/// Gets the name of the plugin.
+///
+/// NOTE: This function may be called without the plugin being loaded
+///
+/// @returns A String-wrapper containing the requested name
+PLUGIN_EXPORT struct MumbleStringWrapper PLUGIN_CALLING_CONVENTION mumble_getName();
+
+/// Gets the Version of the plugin-API this plugin intends to use.
+/// Mumble will decide whether this plugin is loadable or not based on the return value of this function.
+///
+/// NOTE: This function may be called without the plugin being loaded
+///
+/// @returns The respective API Version
+PLUGIN_EXPORT mumble_version_t PLUGIN_CALLING_CONVENTION mumble_getAPIVersion();
+
+/// Provides the MumbleAPI struct to the plugin. This struct contains function pointers that can be used
+/// to interact with the Mumble client. It is up to the plugin to store this struct somewhere if it wants to make use
+/// of it at some point.
+///
+/// NOTE: This function may be called without the plugin being loaded
+///
+/// @param api A pointer to the MumbleAPI struct. The API struct must be cast to the version corresponding to the
+/// user API version. If your plugin is e.g. using the 1.0.x API, then you have to cast this pointer to
+/// MumbleAPI_v_1_0_x. Note also that you **must not store this pointer**. It will become invalid. Therefore
+/// you have to copy the struct in order to use it later on.
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_registerAPIFunctions(void *apiStruct);
+
+/// Releases the resource pointed to by the given pointer. If the respective resource has been allocated before,
+/// this would be the time to free/delete it.
+/// The resources processed by this functions are only those that have been specifically allocated in order to return
+/// them in one of the plugin functions to Mumble (e.g. the String returned by mumble_getName) and has nothing to do
+/// with your plugin's internal resource management.
+/// In short: Only resources passed from the plugin to Mumble via a return value may be processed by this function.
+///
+/// NOTE1: This function may be called without the plugin being loaded
+///
+/// NOTE2: that the pointer might be pointing to memory that had to be allocated without the plugin being loaded.
+/// Therefore you should be very sure that there'll be another callback in which you want to free this memory,
+/// should you decide to not do it here (which is hereby explicitly advised against).
+///
+/// NOTE3: The pointer is const as Mumble won't mess with the memory allocated by the plugin (no modifications).
+/// Nontheless this function is explicitly responsible for freeing the respective memory parts. If the memory has
+/// been allocated using malloc(), it needs to be freed using free() which requires a const-cast. If however the
+/// memory has been created using the new operator you have to cast the pointer back to its original type and then
+/// use the delete operator on it (no const-cast necessary in this case).
+/// See https://stackoverflow.com/questions/2819535/unable-to-free-const-pointers-in-c
+/// and https://stackoverflow.com/questions/941832/is-it-safe-to-delete-a-void-pointer
+///
+/// @param pointer The pointer to the memory that needs free-ing
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_releaseResource(const void *pointer);
+
+
+
+//////////////////////////////////////////////////////////////////////////////////
+///////////////////////////// GENERAL FUNCTIONS //////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+
+/// Tells the plugin some basic information about the Mumble client loading it.
+/// This function will be the first one that is being called on this plugin - even before it is decided whether to load
+/// the plugin at all.
+///
+/// @param mumbleVersion The Version of the Mumble client
+/// @param mumbleAPIVersion The Version of the plugin-API the Mumble client runs with
+/// @param minimumExpectedAPIVersion The minimum Version the Mumble clients expects this plugin to meet in order to load
+/// it
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_setMumbleInfo(mumble_version_t mumbleVersion,
+ mumble_version_t mumbleAPIVersion,
+ mumble_version_t minimumExpectedAPIVersion);
+
+/// Gets the Version of this plugin
+///
+/// NOTE: This function may be called without the plugin being loaded
+///
+/// @returns The plugin's version
+PLUGIN_EXPORT mumble_version_t PLUGIN_CALLING_CONVENTION mumble_getVersion();
+
+/// Gets the name of the plugin author(s).
+///
+/// NOTE: This function may be called without the plugin being loaded
+///
+/// @returns A String-wrapper containing the requested author name(s)
+PLUGIN_EXPORT struct MumbleStringWrapper PLUGIN_CALLING_CONVENTION mumble_getAuthor();
+
+/// Gets the description of the plugin.
+///
+/// NOTE: This function may be called without the plugin being loaded
+///
+/// @returns A String-wrapper containing the requested description
+PLUGIN_EXPORT struct MumbleStringWrapper PLUGIN_CALLING_CONVENTION mumble_getDescription();
+
+/// Gets the feature set of this plugin. The feature set is described by bitwise or'ing the elements of the
+/// Mumble_PluginFeature enum together.
+///
+/// NOTE: This function may be called without the plugin being loaded
+///
+/// @returns The feature set of this plugin
+PLUGIN_EXPORT uint32_t PLUGIN_CALLING_CONVENTION mumble_getFeatures();
+
+/// Requests this plugin to deactivate the given (sub)set of provided features.
+/// If this is not possible, the features that can't be deactivated shall be returned by this function.
+///
+/// Example (check if FEATURE_POSITIONAL shall be deactivated):
+/// @code
+/// if (features & FEATURE_POSITIONAL) {
+/// // positional shall be deactivated
+/// };
+/// @endcode
+///
+/// @param features The feature set that shall be deactivated
+/// @returns The feature set that can't be disabled (bitwise or'ed). If all requested features can be disabled, return
+/// FEATURE_NONE. If none of the requested features can be disabled return the unmodified features parameter.
+PLUGIN_EXPORT uint32_t PLUGIN_CALLING_CONVENTION mumble_deactivateFeatures(uint32_t features);
+
+
+
+//////////////////////////////////////////////////////////////////////////////////
+//////////////////////////// POSITIONAL DATA /////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+// If this plugin wants to provide positional data, the mumble_initPositionalData, mumble_fetchPositionalData
+// and mumble_shutdownPositionalData functions have to be implemented together (implementing only a subset
+// will yield the same result as if no support for positional data was implemened).
+
+/// Indicates that Mumble wants to use this plugin to request positional data. Therefore it should check whether it is
+/// currently able to do so and allocate memory that is needed for that process. As a parameter this function gets an
+/// array of names and an array of PIDs. They are of same length and the PID at index i belongs to a program whose name
+/// is listed at index i in the "name-array".
+///
+/// @param programNames An array of pointers to the program names
+/// @param programPIDs An array of the corresponding program PIDs
+/// @param programCount The length of programNames and programPIDs
+/// @returns The error code. If everything went fine PDEC_OK shall be returned. In that case Mumble will start
+/// frequently calling fetchPositionalData. If this returns anything but PDEC_OK, Mumble will assume that the plugin is
+/// (currently) uncapable of providing positional data. In this case this function must not have allocated any memory
+/// that needs to be cleaned up later on. Depending on the returned error code, Mumble might try to call this function
+/// again at some point.
+PLUGIN_EXPORT uint8_t PLUGIN_CALLING_CONVENTION mumble_initPositionalData(const char *const *programNames,
+ const uint64_t *programPIDs,
+ size_t programCount);
+
+/// Retrieves the positional data. If no data can be fetched, set all float-vectors to 0 and return false.
+///
+/// @param[out] avatarPos A float-array of size 3 representing the cartesian position of the player/avatar in the ingame
+/// world. One unit represents one meter of distance.
+/// @param[out] avatarDir A float-array of size 3 representing the cartesian direction-vector of the player/avatar
+/// ingame (where it is facing).
+/// @param[out] avatarAxis A float-array of size 3 representing the vector pointing from the toes of the character to
+/// its head. One unit represents one meter of distance.
+/// @param[out] cameraPos A float-array of size 3 representing the cartesian position of the camera in the ingame world.
+/// One unit represents one meter of distance.
+/// @param[out] cameraDir A float-array of size 3 representing the cartesian direction-vector of the camera ingame
+/// (where it is facing).
+/// @param[out] cameraAxis A float-array of size 3 representing a vector from the bottom of the camera to its top. One
+/// unit represents one meter of distance.
+/// @param[out] context A pointer to where the pointer to a C-encoded string storing the context of the provided
+/// positional data shall be written. This context should include information about the server (and team) the player is
+/// on. Only players with identical context will be able to hear each other's audio. The returned pointer has to remain
+/// valid until the next invokation of this function or until shutdownPositionalData is called.
+/// @param[out] identity A pointer to where the pointer to a C-encoded string storing the identity of the player shall
+/// be written. It can be polled by external scripts from the server and should uniquely identify the player in the
+/// game. The pointer has to remain valid until the next invokation of this function or until shutdownPositionalData is
+/// called.
+/// @returns Whether this plugin can continue delivering positional data. If this function returns false,
+/// shutdownPositionalData will be called.
+PLUGIN_EXPORT bool PLUGIN_CALLING_CONVENTION mumble_fetchPositionalData(float *avatarPos, float *avatarDir,
+ float *avatarAxis, float *cameraPos,
+ float *cameraDir, float *cameraAxis,
+ const char **context, const char **identity);
+
+/// Indicates that this plugin will not be asked for positional data any longer. Thus any memory allocated for this
+/// purpose should be freed at this point.
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_shutdownPositionalData();
+
+/// The context in positional data is used to determine whether different positional data sets from different
+/// clients belong to the same game (and same server). Only if the contexts matches up across these clients,
+/// will Mumble activate the positional audio effects, as it will assume that these clients are playing the
+/// same game together.
+/// The context is set during fetching of the other positional data and is usually something like e.g. the
+/// current server's name. In order to avoid clashes between different plugins (that most likely work for
+/// different games), the context is prefixed by Mumble. If this function is not implemented, the name of
+/// the plugin is used as a prefix (which tends to be the supported game's name), but sometimes a different
+/// prefix is desirable. For these cases, a custom prefix can be provided through this function.
+///
+/// NOTE that while it is possible to allocate a string for this purpose every time this function is called
+/// and then letting mumble release the resource again (via mumble_releaseResource), it is generally not the
+/// advised way of doing things (it may impact overall performance negatively, since this function will be
+/// called very frequently). Instead you should either return a static string (if your language supports that
+/// and if it actually fits your needs) or you should allocate a string during mumble_initPositionalData and
+/// free it in mumble_shutdownPositionalData and when returning the string in this function, tell Mumble that
+/// the string does not need releasing.
+///
+/// @returns The context prefix to use for positional data fetched by this plugin.
+///
+/// @since Plugin API v1.1.0
+PLUGIN_EXPORT struct MumbleStringWrapper PLUGIN_CALLING_CONVENTION mumble_getPositionalDataContextPrefix();
+
+
+
+//////////////////////////////////////////////////////////////////////////////////
+////////////////////// EVENTHANDLERS / CALLBACK FUNCTIONS ////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+
+/// Called when connecting to a server.
+/// Note that in most cases you'll want to use mumble_onServerSynchronized instead.
+/// Note also that this callback will be called from a DIFFERENT THREAD!
+///
+/// @param connection The ID of the newly established server-connection
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onServerConnected(mumble_connection_t connection);
+
+/// Called when disconnecting from a server.
+/// Note that this callback is called from a DIFFERENT THREAD!
+///
+/// @param connection The ID of the server-connection that has been terminated
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onServerDisconnected(mumble_connection_t connection);
+
+/// Called when the client has finished synchronizing with the server
+///
+/// @param connection The ID of the server-connection that has been terminated
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onServerSynchronized(mumble_connection_t connection);
+
+/// Called whenever any user on the server enters a channel
+/// This function will also be called when freshly connecting to a server as each user on that
+/// server needs to be "added" to the respective channel as far as the local client is concerned.
+///
+/// @param connection The ID of the server-connection this event is connected to
+/// @param userID The ID of the user this event has been triggered for
+/// @param previousChannelID The ID of the chanel the user is coming from. Negative IDs indicate that there is no
+/// previous channel (e.g. the user freshly connected to the server) or the channel isn't available because of any other
+/// reason.
+/// @param newChannelID The ID of the channel the user has entered. If the ID is negative, the new channel could not be
+/// retrieved. This means that the ID is invalid.
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onChannelEntered(mumble_connection_t connection,
+ mumble_userid_t userID,
+ mumble_channelid_t previousChannelID,
+ mumble_channelid_t newChannelID);
+
+/// Called whenever a user leaves a channel.
+/// This includes a client disconnecting from the server as this will also lead to the user not being in that channel
+/// anymore.
+///
+/// @param connection The ID of the server-connection this event is connected to
+/// @param userID The ID of the user that left the channel
+/// @param channelID The ID of the channel the user left. If the ID is negative, the channel could not be retrieved.
+/// This means that the ID is invalid.
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onChannelExited(mumble_connection_t connection,
+ mumble_userid_t userID,
+ mumble_channelid_t channelID);
+
+/// Called when any user changes his/her talking state.
+///
+/// @param connection The ID of the server-connection this event is connected to
+/// @param userID The ID of the user whose talking state has been changed
+/// @param talkingState The new TalkingState the user has switched to.
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onUserTalkingStateChanged(mumble_connection_t connection,
+ mumble_userid_t userID,
+ mumble_talking_state_t talkingState);
+
+/// Called whenever there is audio input.
+/// Note that this callback will be called from the AUDIO THREAD.
+/// Note also that blocking this callback will cause Mumble's audio processing to get suspended.
+///
+/// @param inputPCM A pointer to a short-array holding the pulse-code-modulation (PCM) representing the audio input. Its
+/// length is sampleCount * channelCount. The PCM format for stereo input is [LRLRLR...] where L and R are samples of
+/// the left and right channel respectively.
+/// @param sampleCount The amount of sample points per channel
+/// @param channelCount The amount of channels in the audio
+/// @param sampleRate The used sample rate in Hz
+/// @param isSpeech A boolean flag indicating whether Mumble considers the input as part of speech (instead of
+/// background noise)
+/// @returns Whether this callback has modified the audio input-array
+PLUGIN_EXPORT bool PLUGIN_CALLING_CONVENTION mumble_onAudioInput(short *inputPCM, uint32_t sampleCount,
+ uint16_t channelCount, uint32_t sampleRate,
+ bool isSpeech);
+
+/// Called whenever Mumble fetches data from an active audio source (could be a voice packet or a playing sample).
+/// The provided audio buffer is the raw buffer without any processing applied to it yet.
+/// Note that this callback will be called from the AUDIO THREAD.
+/// Note also that blocking this callback will cause Mumble's audio processing to get suspended.
+///
+/// @param outputPCM A pointer to a float-array holding the pulse-code-modulation (PCM) representing the audio output.
+/// Its length is sampleCount * channelCount. The PCM format for stereo output is [LRLRLR...] where L and R are samples
+/// of the left and right channel respectively.
+/// @param sampleCount The amount of sample points per channel
+/// @param channelCount The amount of channels in the audio
+/// @param sampleRate The used sample rate in Hz
+/// @param isSpeech Whether this audio belongs to a received voice packet (and will thus (most likely) contain speech)
+/// @param userID If isSpeech is true, this contains the ID of the user this voice packet belongs to. If isSpeech is
+/// false, the content of this parameter is unspecified and should not be accessed
+/// @returns Whether this callback has modified the audio output-array
+PLUGIN_EXPORT bool PLUGIN_CALLING_CONVENTION mumble_onAudioSourceFetched(float *outputPCM, uint32_t sampleCount,
+ uint16_t channelCount, uint32_t sampleRate,
+ bool isSpeech, mumble_userid_t userID);
+
+/// Called whenever the fully mixed and processed audio is about to be handed to the audio backend (about to be played).
+/// Note that this happens immediately before Mumble clips the audio buffer.
+/// Note that this callback will be called from the AUDIO THREAD.
+/// Note also that blocking this callback will cause Mumble's audio processing to get suspended.
+///
+/// @param outputPCM A pointer to a float-array holding the pulse-code-modulation (PCM) representing the audio output.
+/// Its length is sampleCount * channelCount. The PCM format for stereo output is [LRLRLR...] where L and R are samples
+/// of the left and right channel respectively.
+/// @param sampleCount The amount of sample points per channel
+/// @param channelCount The amount of channels in the audio
+/// @param sampleRate The used sample rate in Hz
+/// @returns Whether this callback has modified the audio output-array
+PLUGIN_EXPORT bool PLUGIN_CALLING_CONVENTION mumble_onAudioOutputAboutToPlay(float *outputPCM, uint32_t sampleCount,
+ uint16_t channelCount,
+ uint32_t sampleRate);
+
+/// Called whenever data has been received that has been sent by a plugin. This data should only be processed by the
+/// intended plugin. For this reason a dataID is provided that should be used to determine whether the data is intended
+/// for this plugin or not. As soon as the data has been processed, no further plugins will be notified about it.
+///
+/// @param connection The ID of the server-connection the data is coming from
+/// @param sender The ID of the user whose client's plugin has sent the data
+/// @param data The sent data array. This can be an arbitrary sequence of bytes.
+/// @param dataLength The length of the data array
+/// @param dataID The ID of this data (C-encoded)
+/// @return Whether the given data has been processed by this plugin
+PLUGIN_EXPORT bool PLUGIN_CALLING_CONVENTION mumble_onReceiveData(mumble_connection_t connection,
+ mumble_userid_t sender, const uint8_t *data,
+ size_t dataLength, const char *dataID);
+
+/// Called when a new user gets added to the user model. This is the case when that new user freshly connects to the
+/// server the local user is on but also when the local user connects to a server other clients are already connected to
+/// (in this case this method will be called for every client already on that server).
+///
+/// @param connection An object used to identify the current connection
+/// @param userID The ID of the user that has been added
+
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onUserAdded(mumble_connection_t connection, mumble_userid_t userID);
+
+/// Called when a user gets removed from the user model. This is the case when that user disconnects from the server the
+/// local user is on but also when the local user disconnects from a server other clients are connected to (in this case
+/// this method will be called for every client on that server).
+///
+/// @param connection An object used to identify the current connection
+/// @param userID The ID of the user that has been removed
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onUserRemoved(mumble_connection_t connection,
+ mumble_userid_t userID);
+
+/// Called when a new channel gets added to the user model. This is the case when a new channel is created on the server
+/// the local user is on but also when the local user connects to a server that contains channels other than the
+/// root-channel (in this case this method will be called for ever non-root channel on that server).
+///
+/// @param connection An object used to identify the current connection
+/// @param channelID The ID of the channel that has been added
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onChannelAdded(mumble_connection_t connection,
+ mumble_channelid_t channelID);
+
+/// Called when a channel gets removed from the user model. This is the case when a channel is removed on the server the
+/// local user is on but also when the local user disconnects from a server that contains channels other than the
+/// root-channel (in this case this method will be called for ever non-root channel on that server).
+///
+/// @param connection An object used to identify the current connection
+/// @param channelID The ID of the channel that has been removed
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onChannelRemoved(mumble_connection_t connection,
+ mumble_channelid_t channelID);
+
+/// Called when a channel gets renamed. This also applies when a new channel is created (thus assigning it an initial
+/// name is also considered renaming).
+///
+/// @param connection An object used to identify the current connection
+/// @param channelID The ID of the channel that has been renamed
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onChannelRenamed(mumble_connection_t connection,
+ mumble_channelid_t channelID);
+
+/// Called when a key has been pressed or released while Mumble has keyboard focus.
+/// Note that this callback will only work if the user has explicitly given permission to monitor keyboard
+/// events for this plugin. Thus if you want to use this callback, make sure your users know that they have to
+/// enable that.
+///
+/// @param keyCode The key code of the respective key. The character codes are defined
+/// via the Mumble_KeyCode enum. For printable 7-bit ASCII characters these codes conform
+/// to the ASCII code-page with the only difference that case is not distinguished. Therefore
+/// always the upper-case letter code will be used for letters.
+/// @param wasPres Whether the respective key has been pressed (instead of released)
+PLUGIN_EXPORT void PLUGIN_CALLING_CONVENTION mumble_onKeyEvent(uint32_t keyCode, bool wasPress);
+
+
+
+//////////////////////////////////////////////////////////////////////////////////
+////////////////////////////// PLUGIN UPDATES ////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+
+/// This function is used to determine whether the plugin can find an update for itself that is available for download.
+///
+/// NOTE: This function may be called without the plugin being loaded
+///
+/// @return Whether the plugin was able to find an update for itself
+PLUGIN_EXPORT bool PLUGIN_CALLING_CONVENTION mumble_hasUpdate();
+
+/// This function is used to retrieve the URL for downloading the newer/updated version of this plugin.
+///
+/// NOTE: This function may be called without the plugin being loaded
+///
+/// @returns A String-wrapper containing the requested URL
+PLUGIN_EXPORT struct MumbleStringWrapper PLUGIN_CALLING_CONVENTION mumble_getUpdateDownloadURL();
+
+
+
+//////////////////////////////////////////////////////////////////////////////////
+///////////////////////////// DEFAULT FUNCTIONS //////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
+// These functions don't have to be implemented by you
+PLUGIN_EXPORT mumble_version_t mumble_getPluginFunctionsVersion();
+
+#ifndef MUMBLE_PLUGIN_NO_DEFAULT_FUNCTION_DEFINITIONS
+
+PLUGIN_EXPORT mumble_version_t mumble_getPluginFunctionsVersion() {
+ return MUMBLE_PLUGIN_FUNCTIONS_VERSION;
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/src/mumble/Plugin.cpp b/src/mumble/Plugin.cpp
index 432edeb8e..5c5b1cab1 100644
--- a/src/mumble/Plugin.cpp
+++ b/src/mumble/Plugin.cpp
@@ -114,6 +114,12 @@ void Plugin::resolveFunctionPointers() {
return;
}
+ m_pluginFnc.getPluginFunctionsVersion =
+ reinterpret_cast< decltype(MumblePluginFunctions::getPluginFunctionsVersion) >(
+ m_lib.resolve("mumble_getPluginFunctionsVersion"));
+
+ const mumble_version_t pluginFunctionsVersion = getPluginFunctionsVersion();
+
// The mandatory functions are there, now see if any optional functions are implemented as well
m_pluginFnc.setMumbleInfo =
reinterpret_cast< decltype(MumblePluginFunctions::setMumbleInfo) >(m_lib.resolve("mumble_setMumbleInfo"));
@@ -173,6 +179,13 @@ void Plugin::resolveFunctionPointers() {
m_pluginFnc.getUpdateDownloadURL = reinterpret_cast< decltype(MumblePluginFunctions::getUpdateDownloadURL) >(
m_lib.resolve("mumble_getUpdateDownloadURL"));
+ if (pluginFunctionsVersion >= mumble_version_t({ 1, 1, 0 })) {
+ // Functions introduced with plugin functions scheme v1.1.0
+ m_pluginFnc.getPositionalDataContextPrefix =
+ reinterpret_cast< decltype(MumblePluginFunctions::getPositionalDataContextPrefix) >(
+ m_lib.resolve("mumble_getPositionalDataContextPrefix"));
+ }
+
#ifdef MUMBLE_PLUGIN_DEBUG
# define CHECK_AND_LOG(name) \
qDebug("\t" \
@@ -188,6 +201,7 @@ void Plugin::resolveFunctionPointers() {
CHECK_AND_LOG(initPositionalData);
CHECK_AND_LOG(fetchPositionalData);
CHECK_AND_LOG(shutdownPositionalData);
+ CHECK_AND_LOG(getPositionalDataContextPrefix);
CHECK_AND_LOG(onServerConnected);
CHECK_AND_LOG(onServerDisconnected);
CHECK_AND_LOG(onChannelEntered);
@@ -209,7 +223,7 @@ void Plugin::resolveFunctionPointers() {
qDebug("<<<<");
#endif
- // If positional audio is to be supported, all three corresponding functions have to be implemented
+ // If positional audio is to be supported, all three functions (init, fetch, shutdown) have to be implemented
// For PA it is all or nothing
if (!(m_pluginFnc.initPositionalData && m_pluginFnc.fetchPositionalData && m_pluginFnc.shutdownPositionalData)
&& (m_pluginFnc.initPositionalData || m_pluginFnc.fetchPositionalData
@@ -379,6 +393,14 @@ mumble_version_t Plugin::getAPIVersion() const {
}
}
+mumble_version_t Plugin::getPluginFunctionsVersion() const {
+ if (m_pluginFnc.getPluginFunctionsVersion) {
+ return m_pluginFnc.getPluginFunctionsVersion();
+ } else {
+ return mumble_version_t({ 1, 0, 0 });
+ }
+}
+
void Plugin::registerAPIFunctions(void *api) const {
if (m_pluginFnc.registerAPIFunctions) {
m_pluginFnc.registerAPIFunctions(api);
@@ -513,6 +535,17 @@ void Plugin::shutdownPositionalData() {
}
}
+QString Plugin::getPositionalDataContextPrefix() const {
+ assertPluginLoaded(this);
+
+ if (m_pluginFnc.getPositionalDataContextPrefix) {
+ return extractWrappedString(m_pluginFnc.getPositionalDataContextPrefix());
+ } else {
+ // Use plugin's name as default context prefix
+ return getName();
+ }
+}
+
void Plugin::onServerConnected(mumble_connection_t connection) const {
assertPluginLoaded(this);
diff --git a/src/mumble/Plugin.h b/src/mumble/Plugin.h
index 28324cc83..d0312fea1 100644
--- a/src/mumble/Plugin.h
+++ b/src/mumble/Plugin.h
@@ -7,7 +7,8 @@
#define MUMBLE_MUMBLE_PLUGIN_H_
#include "MumbleAPI_v_1_0_x.h"
-#include "MumblePlugin_v_1_0_x.h"
+#define MUMBLE_PLUGIN_NO_DEFAULT_FUNCTION_DEFINITIONS
+#include "MumblePlugin_v_1_1_x.h"
#include "PluginComponents_v_1_0_x.h"
#include "PositionalData.h"
@@ -31,6 +32,8 @@ struct MumblePluginFunctions {
decltype(&mumble_registerAPIFunctions) registerAPIFunctions;
decltype(&mumble_releaseResource) releaseResource;
+ decltype(&mumble_getPluginFunctionsVersion) getPluginFunctionsVersion;
+
// Further utility functions the plugin may implement
decltype(&mumble_setMumbleInfo) setMumbleInfo;
decltype(&mumble_getVersion) getVersion;
@@ -43,6 +46,7 @@ struct MumblePluginFunctions {
decltype(&mumble_initPositionalData) initPositionalData;
decltype(&mumble_fetchPositionalData) fetchPositionalData;
decltype(&mumble_shutdownPositionalData) shutdownPositionalData;
+ decltype(&mumble_getPositionalDataContextPrefix) getPositionalDataContextPrefix;
// Callback functions and EventHandlers
decltype(&mumble_onServerConnected) onServerConnected;
@@ -240,6 +244,8 @@ protected:
QString &identity) const;
/// Shuts down positional data gathering
virtual void shutdownPositionalData();
+ /// @returns The positional data context prefix to be used for this plugin
+ virtual QString getPositionalDataContextPrefix() const;
/// Called to indicate that the client has connected to a server
///
/// @param connection An object used to identify the current connection
@@ -414,6 +420,8 @@ public:
virtual QString getName() const;
/// @returns The API version this plugin intends to use
virtual mumble_version_t getAPIVersion() const;
+ /// @returns The version of the plugins function scheme this plugin is using
+ virtual mumble_version_t getPluginFunctionsVersion() const;
/// @returns The version of this plugin
virtual mumble_version_t getVersion() const;
/// @returns The author of this plugin
diff --git a/src/mumble/PluginManager.cpp b/src/mumble/PluginManager.cpp
index 8ab8859ad..1d376e7fb 100644
--- a/src/mumble/PluginManager.cpp
+++ b/src/mumble/PluginManager.cpp
@@ -417,9 +417,9 @@ bool PluginManager::fetchPositionalData() {
m_positionalData.m_cameraPos, m_positionalData.m_cameraDir, m_positionalData.m_cameraAxis,
m_positionalData.m_context, m_positionalData.m_identity);
- // Add the plugin's name to the context as well to prevent name-clashes between plugins
if (!m_positionalData.m_context.isEmpty()) {
- m_positionalData.m_context = m_activePositionalDataPlugin->getName() + QChar::Null + m_positionalData.m_context;
+ m_positionalData.m_context =
+ m_activePositionalDataPlugin->getPositionalDataContextPrefix() + QChar::Null + m_positionalData.m_context;
}
if (!retStatus) {