mirror of
https://github.com/mumble-voip/mumble.git
synced 2025-10-26 11:19:16 +00:00
190 lines
4.0 KiB
C++
190 lines
4.0 KiB
C++
#define __cdecl
|
|
typedef unsigned long HWND;
|
|
|
|
#include "../mumble_plugin.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <wchar.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
#include <sys/mman.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <time.h>
|
|
|
|
static std::wstring wsPluginName;
|
|
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];
|
|
};
|
|
|
|
static int32_t GetTickCount() {
|
|
struct timeval tv;
|
|
gettimeofday(&tv,NULL);
|
|
|
|
return tv.tv_usec / 1000 + tv.tv_sec * 1000;
|
|
}
|
|
|
|
static struct LinkedMem * const lm_invalid = reinterpret_cast<struct LinkedMem *>(-1);
|
|
static struct LinkedMem *lm = lm_invalid;
|
|
static int shmfd = -1;
|
|
|
|
static uint32_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)
|
|
ftruncate(shmfd, sizeof(struct LinkedMem));
|
|
|
|
lm = static_cast<struct LinkedMem*>(
|
|
mmap(NULL, 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 MumblePlugin linkplug = {
|
|
MUMBLE_PLUGIN_MAGIC,
|
|
std::wstring(L"Link v1.2.0"),
|
|
wsPluginName,
|
|
NULL,
|
|
NULL,
|
|
trylock,
|
|
unlock,
|
|
longdesc,
|
|
fetch
|
|
};
|
|
|
|
extern "C" __attribute__((visibility("default"))) MumblePlugin *getMumblePlugin() {
|
|
return &linkplug;
|
|
}
|