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:
-rw-r--r--plugins/link/CMakeLists.txt19
-rw-r--r--plugins/link/LinkedMem.h58
-rw-r--r--plugins/link/link-posix.cpp189
-rw-r--r--plugins/link/link.cpp326
4 files changed, 264 insertions, 328 deletions
diff --git a/plugins/link/CMakeLists.txt b/plugins/link/CMakeLists.txt
index feb5e2c27..146657f89 100644
--- a/plugins/link/CMakeLists.txt
+++ b/plugins/link/CMakeLists.txt
@@ -3,15 +3,14 @@
# that can be found in the LICENSE file at the root of the
# Mumble source tree or at <https://www.mumble.info/LICENSE>.
-add_library(link SHARED)
+add_library(link SHARED
+ "link.cpp"
+ "SharedMemory.cpp"
+)
-if(WIN32)
- target_sources(link PRIVATE "link.cpp")
-elseif(UNIX)
- target_sources(link PRIVATE "link-posix.cpp")
-
- if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
- find_library(LIB_RT "rt")
- target_link_libraries(link PRIVATE ${LIB_RT})
- endif()
+if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+ find_library(LIB_RT "rt")
+ target_link_libraries(link PRIVATE ${LIB_RT})
endif()
+
+target_include_directories(link PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
diff --git a/plugins/link/LinkedMem.h b/plugins/link/LinkedMem.h
new file mode 100644
index 000000000..552867fd8
--- /dev/null
+++ b/plugins/link/LinkedMem.h
@@ -0,0 +1,58 @@
+// 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>.
+
+#ifndef MUMBLE_PLUGINS_LINK_LINKEDMEM_H_
+#define MUMBLE_PLUGINS_LINK_LINKEDMEM_H_
+
+#ifdef _WIN32
+# ifndef NOMINMAX
+# define NOMINMAX
+# endif
+# include "windows.h"
+#else
+# include <cstdint>
+# include <cstdio>
+
+# include <unistd.h>
+#endif
+
+struct LinkedMem {
+#ifdef _WIN32
+ UINT32 uiVersion;
+ DWORD uiTick;
+#else
+ uint32_t uiVersion;
+ uint32_t uiTick;
+#endif
+ float fAvatarPosition[3];
+ float fAvatarFront[3];
+ float fAvatarTop[3];
+ wchar_t name[256];
+ float fCameraPosition[3];
+ float fCameraFront[3];
+ float fCameraTop[3];
+ wchar_t identity[256];
+#ifdef _WIN32
+ UINT32 context_len;
+#else
+ uint32_t context_len;
+#endif
+ unsigned char context[256];
+ wchar_t description[2048];
+};
+
+static const char *getLinkedMemoryName() {
+#ifdef _WIN32
+ return "MumbleLink";
+#else
+ static char name[256] = {};
+
+ snprintf(name, 256, "/MumbleLink.%d", getuid());
+
+ return name;
+#endif
+}
+
+#endif // MUMBLE_PLUGINS_LINK_LINKEDMEM_H_
diff --git a/plugins/link/link-posix.cpp b/plugins/link/link-posix.cpp
deleted file mode 100644
index efa67c804..000000000
--- a/plugins/link/link-posix.cpp
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2008-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>.
-
-#define MUMBLE_ALLOW_DEPRECATED_LEGACY_PLUGIN_API
-#include "mumble_legacy_plugin.h"
-
-#include <stdint.h>
-#include <stdio.h>
-#include <wchar.h>
-
-#include <fcntl.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <time.h>
-#include <unistd.h>
-
-static std::wstring wsPluginName(L"Link");
-static std::wstring wsDescription;
-static char memname[256];
-
-struct LinkedMem {
- uint32_t uiVersion;
- uint32_t ui32count;
- float fAvatarPosition[3];
- float fAvatarFront[3];
- float fAvatarTop[3];
- wchar_t name[256];
- float fCameraPosition[3];
- float fCameraFront[3];
- float fCameraTop[3];
- wchar_t identity[256];
- uint32_t context_len;
- unsigned char context[256];
- wchar_t description[2048];
-};
-
-/// Non-monotonic tick count in ms resolution
-static int64_t GetTickCount() {
- struct timeval tv;
- gettimeofday(&tv, nullptr);
-
- return tv.tv_usec / 1000 + tv.tv_sec * 1000;
-}
-
-#define lm_invalid reinterpret_cast< struct LinkedMem * >(-1)
-static struct LinkedMem *lm = lm_invalid;
-static int shmfd = -1;
-
-static int64_t last_tick = 0;
-static uint32_t last_count = 0;
-
-static void unlock() {
- lm->ui32count = last_count = 0;
- lm->uiVersion = 0;
- lm->name[0] = 0;
- wsPluginName.assign(L"Link");
- wsDescription.clear();
-}
-
-static int trylock() {
- if (lm == lm_invalid)
- return false;
-
- if ((lm->uiVersion == 1) || (lm->uiVersion == 2)) {
- if (lm->ui32count != last_count) {
- last_tick = GetTickCount();
- last_count = lm->ui32count;
-
- wchar_t buff[2048];
-
- if (lm->name[0]) {
- wcsncpy(buff, lm->name, 256);
- buff[255] = 0;
- wsPluginName.assign(buff);
- }
- if (lm->description[0]) {
- wcsncpy(buff, lm->description, 2048);
- buff[2047] = 0;
- wsDescription.assign(buff);
- }
- return true;
- }
- }
- return false;
-}
-
-static const std::wstring longdesc() {
- return wsDescription;
-}
-
-static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front,
- float *camera_top, std::string &context, std::wstring &identity) {
- if (lm->ui32count != last_count) {
- last_tick = GetTickCount();
- last_count = lm->ui32count;
- } else if ((GetTickCount() - last_tick) > 5000)
- return false;
-
- if ((lm->uiVersion != 1) && (lm->uiVersion != 2))
- return false;
-
- for (int i = 0; i < 3; ++i) {
- avatar_pos[i] = lm->fAvatarPosition[i];
- avatar_front[i] = lm->fAvatarFront[i];
- avatar_top[i] = lm->fAvatarTop[i];
- }
-
- if (lm->uiVersion == 2) {
- for (int i = 0; i < 3; ++i) {
- camera_pos[i] = lm->fCameraPosition[i];
- camera_front[i] = lm->fCameraFront[i];
- camera_top[i] = lm->fCameraTop[i];
- }
-
- if (lm->context_len > 255)
- lm->context_len = 255;
- lm->identity[255] = 0;
-
- context.assign(reinterpret_cast< const char * >(lm->context), lm->context_len);
- identity.assign(lm->identity);
- } else {
- for (int i = 0; i < 3; ++i) {
- camera_pos[i] = lm->fAvatarPosition[i];
- camera_front[i] = lm->fAvatarFront[i];
- camera_top[i] = lm->fAvatarTop[i];
- }
- context.clear();
- identity.clear();
- }
-
- return true;
-}
-
-__attribute__((constructor)) static void load_plugin() {
- bool bCreated = false;
-
- snprintf(memname, 256, "/MumbleLink.%d", getuid());
-
- shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR);
- if (shmfd < 0) {
- bCreated = true;
- shmfd = shm_open(memname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
- }
-
- if (shmfd < 0) {
- fprintf(stderr, "Mumble Link plugin: error creating shared memory\n");
- return;
- }
-
- if (bCreated) {
- if (ftruncate(shmfd, sizeof(struct LinkedMem)) != 0) {
- fprintf(stderr, "Mumble Link plugin: failed to resize shared memory\n");
- close(shmfd);
- shmfd = -1;
- return;
- }
- }
-
- lm = static_cast< struct LinkedMem * >(
- mmap(nullptr, sizeof(struct LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0));
-
- if ((lm != lm_invalid) && bCreated)
- memset(lm, 0, sizeof(struct LinkedMem));
-}
-
-__attribute__((destructor)) static void unload_plugin() {
- if (lm != lm_invalid)
- munmap(lm, sizeof(struct LinkedMem));
-
- if (shmfd > -1)
- close(shmfd);
-
- shm_unlink(memname);
-}
-
-static std::wstring description(L"Link v1.2.0");
-
-static MumblePlugin linkplug = {
- MUMBLE_PLUGIN_MAGIC, description, wsPluginName, nullptr, nullptr, trylock, unlock, longdesc, fetch
-};
-
-extern "C" MUMBLE_PLUGIN_EXPORT MumblePlugin *getMumblePlugin() {
- return &linkplug;
-}
diff --git a/plugins/link/link.cpp b/plugins/link/link.cpp
index c51bfcb60..908e914d5 100644
--- a/plugins/link/link.cpp
+++ b/plugins/link/link.cpp
@@ -1,175 +1,243 @@
-// Copyright 2007-2021 The Mumble Developers. All rights reserved.
+// Copyright 2008-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>.
-#ifndef QT_NO_DEBUG
-# include <stdio.h>
-# include <stdlib.h>
-#endif
-#include <windows.h>
-#include <math.h>
-
-#define MUMBLE_ALLOW_DEPRECATED_LEGACY_PLUGIN_API
-#include "mumble_legacy_plugin.h"
-
-static std::wstring wsPluginName;
-static std::wstring wsDescription;
-
-struct LinkedMem {
- UINT32 uiVersion;
- DWORD dwcount;
- float fAvatarPosition[3];
- float fAvatarFront[3];
- float fAvatarTop[3];
- wchar_t name[256];
- float fCameraPosition[3];
- float fCameraFront[3];
- float fCameraTop[3];
- wchar_t identity[256];
- UINT32 context_len;
- unsigned char context[256];
- wchar_t description[2048];
-};
-
-static void about(void *h) {
- ::MessageBox(reinterpret_cast< HWND >(h), L"Reads audio position information from linked game",
- L"Mumble Link Plugin", MB_OK);
+#include <chrono>
+#include <codecvt>
+#include <cstdint>
+#include <cstring>
+#include <iostream>
+#include <locale>
+#include <string>
+
+#include "LinkedMem.h"
+#include "MumbleAPI_v_1_0_x.h"
+#include "MumblePlugin_v_1_1_x.h"
+#include "SharedMemory.h"
+
+#define UNUSED(x) (void) x
+
+
+constexpr const char *defaultName = "Link";
+constexpr const char *defaultDescription = "Reads positional data from a linked game/software";
+
+std::string pluginName(defaultName);
+std::string applicationName;
+std::string pluginDescription(defaultDescription);
+std::string pluginContext;
+std::string pluginIdentity;
+
+SharedMemory sharedMem;
+LinkedMem *lm = nullptr;
+
+std::uint32_t last_tick = 0;
+std::int64_t last_tick_time = 0;
+
+/**
+ * @returns Time in ms since Epoch
+ */
+static std::uint64_t getTimeSinceEpoch() {
+ return std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1);
+}
+
+mumble_error_t mumble_init(mumble_plugin_id_t id) {
+ UNUSED(id);
+
+ lm = static_cast< LinkedMem * >(sharedMem.mapMemory(getLinkedMemoryName(), sizeof(LinkedMem)));
+
+ if (!lm) {
+ std::cerr << "Link plugin: Failed to setup shared memory: " << sharedMem.lastError() << std::endl;
+
+ return MUMBLE_EC_INTERNAL_ERROR;
+ }
+
+ return MUMBLE_STATUS_OK;
+}
+
+void mumble_shutdown() {
+ sharedMem.close();
+}
+
+MumbleStringWrapper mumble_getName() {
+ MumbleStringWrapper wrapper;
+ wrapper.data = pluginName.c_str();
+ wrapper.size = pluginName.size();
+ wrapper.needsReleasing = false;
+
+ return wrapper;
+}
+
+mumble_version_t mumble_getAPIVersion() {
+ return MUMBLE_PLUGIN_API_VERSION;
+}
+
+void mumble_registerAPIFunctions(void *apiStruct) {
+ UNUSED(apiStruct);
+}
+
+void mumble_releaseResource(const void *pointer) {
+ // This function should never be called
+ UNUSED(pointer);
+
+ std::terminate();
+}
+
+mumble_version_t mumble_getVersion() {
+ return { 1, 3, 0 };
+}
+
+MumbleStringWrapper mumble_getAuthor() {
+ static const char *author = "Mumble Developers";
+
+ MumbleStringWrapper wrapper;
+ wrapper.data = author;
+ wrapper.size = std::strlen(author);
+ wrapper.needsReleasing = false;
+
+ return wrapper;
+}
+
+MumbleStringWrapper mumble_getDescription() {
+ MumbleStringWrapper wrapper;
+ wrapper.data = pluginDescription.c_str();
+ wrapper.size = pluginDescription.size();
+ wrapper.needsReleasing = false;
+
+ return wrapper;
}
-static HANDLE hMapObject = nullptr;
-static LinkedMem *lm = nullptr;
-static DWORD last_count = 0;
-static DWORD last_tick = 0;
-
-static void unlock() {
- lm->dwcount = last_count = 0;
- lm->uiVersion = 0;
- lm->name[0] = 0;
- wsPluginName.assign(L"Link");
- wsDescription.clear();
+uint32_t mumble_getFeatures() {
+ return MUMBLE_FEATURE_POSITIONAL;
}
-static int trylock() {
+uint8_t mumble_initPositionalData(const char *const *programNames, const uint64_t *programPIDs, size_t programCount) {
+ UNUSED(programNames);
+ UNUSED(programPIDs);
+ UNUSED(programCount);
+
+ if (!lm) {
+ return MUMBLE_PDEC_ERROR_TEMP;
+ }
+
if ((lm->uiVersion == 1) || (lm->uiVersion == 2)) {
- if (lm->dwcount != last_count) {
- last_count = lm->dwcount;
- last_tick = GetTickCount();
+ if (lm->uiTick != last_tick) {
+ last_tick = lm->uiTick;
+ last_tick_time = getTimeSinceEpoch();
- errno_t err = 0;
wchar_t buff[2048];
if (lm->name[0]) {
- err = wcscpy_s(buff, 256, lm->name);
- if (!err)
- wsPluginName.assign(buff);
- }
- if (!err && lm->description[0]) {
- err = wcscpy_s(buff, 2048, lm->description);
- if (!err)
- wsDescription.assign(buff);
+ wcsncpy(buff, lm->name, 256);
+ buff[255] = 0;
+ applicationName = std::wstring_convert< std::codecvt_utf8< wchar_t > >().to_bytes(buff);
+
+ // Call the plugin itself "Link (<whatever>)"
+ pluginName += " (" + applicationName + ")";
}
- if (err) {
- wsPluginName.assign(L"Link");
- wsDescription.clear();
- return false;
+
+ if (lm->description[0]) {
+ wcsncpy(buff, lm->description, 2048);
+ buff[2047] = 0;
+ pluginDescription = std::wstring_convert< std::codecvt_utf8< wchar_t > >().to_bytes(buff);
}
- return true;
+
+ return MUMBLE_PDEC_OK;
}
}
- return false;
-}
+ return MUMBLE_PDEC_ERROR_TEMP;
+}
-static int fetch(float *avatar_pos, float *avatar_front, float *avatar_top, float *camera_pos, float *camera_front,
- float *camera_top, std::string &context, std::wstring &identity) {
- if (lm->dwcount != last_count) {
- last_count = lm->dwcount;
- last_tick = GetTickCount();
- } else if ((GetTickCount() - last_tick) > 5000)
+#define SET_TO_ZERO(name) \
+ name[0] = 0.0f; \
+ name[1] = 0.0f; \
+ name[2] = 0.0f
+bool mumble_fetchPositionalData(float *avatarPos, float *avatarDir, float *avatarAxis, float *cameraPos,
+ float *cameraDir, float *cameraAxis, const char **context, const char **identity) {
+ SET_TO_ZERO(avatarPos);
+ SET_TO_ZERO(avatarDir);
+ SET_TO_ZERO(avatarAxis);
+ SET_TO_ZERO(cameraPos);
+ SET_TO_ZERO(cameraDir);
+ SET_TO_ZERO(cameraAxis);
+
+ if (lm->uiTick != last_tick) {
+ last_tick = lm->uiTick;
+ last_tick_time = getTimeSinceEpoch();
+ } else if ((getTimeSinceEpoch() - last_tick_time) > 5000) {
return false;
+ }
- if ((lm->uiVersion != 1) && (lm->uiVersion != 2))
+ if ((lm->uiVersion != 1) && (lm->uiVersion != 2)) {
return false;
+ }
for (int i = 0; i < 3; ++i) {
- avatar_pos[i] = lm->fAvatarPosition[i];
- avatar_front[i] = lm->fAvatarFront[i];
- avatar_top[i] = lm->fAvatarTop[i];
+ avatarPos[i] = lm->fAvatarPosition[i];
+ avatarDir[i] = lm->fAvatarFront[i];
+ avatarAxis[i] = lm->fAvatarTop[i];
}
if (lm->uiVersion == 2) {
for (int i = 0; i < 3; ++i) {
- camera_pos[i] = lm->fCameraPosition[i];
- camera_front[i] = lm->fCameraFront[i];
- camera_top[i] = lm->fCameraTop[i];
+ cameraPos[i] = lm->fCameraPosition[i];
+ cameraDir[i] = lm->fCameraFront[i];
+ cameraAxis[i] = lm->fCameraTop[i];
}
- if (lm->context_len > 255)
+ if (lm->context_len > 255) {
lm->context_len = 255;
+ }
lm->identity[255] = 0;
- context.assign(reinterpret_cast< const char * >(lm->context), lm->context_len);
- identity.assign(lm->identity);
+ pluginContext.assign(reinterpret_cast< const char * >(lm->context), lm->context_len);
+ pluginIdentity = std::wstring_convert< std::codecvt_utf8< wchar_t > >().to_bytes(lm->identity);
} else {
for (int i = 0; i < 3; ++i) {
- camera_pos[i] = lm->fAvatarPosition[i];
- camera_front[i] = lm->fAvatarFront[i];
- camera_top[i] = lm->fAvatarTop[i];
+ cameraPos[i] = lm->fAvatarPosition[i];
+ cameraDir[i] = lm->fAvatarFront[i];
+ cameraAxis[i] = lm->fAvatarTop[i];
}
- context.clear();
- identity.clear();
+
+ pluginContext.clear();
+ pluginIdentity.clear();
}
- return true;
-}
+ *context = pluginContext.c_str();
+ *identity = pluginIdentity.c_str();
-static const std::wstring getdesc() {
- return wsDescription;
+ return true;
}
-BOOL WINAPI DllMain(HINSTANCE, DWORD fdwReason, LPVOID) {
- bool bCreated = false;
- switch (fdwReason) {
- case DLL_PROCESS_ATTACH:
- wsPluginName.assign(L"Link");
- hMapObject = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");
- if (!hMapObject) {
- hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, sizeof(LinkedMem),
- L"MumbleLink");
- bCreated = true;
- if (!hMapObject)
- return false;
- }
- lm = static_cast< LinkedMem * >(MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, 0));
- if (!lm) {
- CloseHandle(hMapObject);
- hMapObject = nullptr;
- return false;
- }
- if (bCreated)
- memset(lm, 0, sizeof(LinkedMem));
- break;
- case DLL_PROCESS_DETACH:
- if (lm) {
- UnmapViewOfFile(lm);
- lm = nullptr;
- }
- if (hMapObject) {
- CloseHandle(hMapObject);
- hMapObject = nullptr;
- }
- break;
+#undef SET_TO_ZERO
+
+void mumble_shutdownPositionalData() {
+ if (!applicationName.empty()) {
+ // We know that pluginName is in the format "Link (<whatever>)" where <whatever> is the applicationName
+ pluginName.erase(pluginName.size() - applicationName.size() - 3, std::string::npos);
+ } else if (applicationName.size() != std::strlen(defaultName)) {
+ // This code part should actually never run, since we expect the pluginName to be modified in the described way
+ // as soon as applicationName is defined.
+ pluginName.clear();
+ pluginName.append(defaultName);
}
- return true;
-}
-static std::wstring description(L"Link v1.2.0");
+ applicationName.clear();
+ pluginDescription = std::string(defaultDescription);
+ pluginContext.clear();
+ pluginIdentity.clear();
+
+ lm->uiTick = last_tick = 0;
+ lm->uiVersion = 0;
+ lm->name[0] = 0;
+}
-static MumblePlugin linkplug = {
- MUMBLE_PLUGIN_MAGIC, description, wsPluginName, about, nullptr, trylock, unlock, getdesc, fetch
-};
+MumbleStringWrapper mumble_getPositionalDataContextPrefix() {
+ MumbleStringWrapper wrapper;
+ wrapper.data = applicationName.c_str();
+ wrapper.size = applicationName.size();
+ wrapper.needsReleasing = false;
-extern "C" MUMBLE_PLUGIN_EXPORT MumblePlugin *getMumblePlugin() {
- return &linkplug;
+ return wrapper;
}