Select Git revision
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
plugin.cpp 32.82 KiB
/*
* TeamSpeak 3 demo plugin
*
* Copyright (c) 2008-2016 TeamSpeak Systems GmbH
*/
#ifdef _WIN32
#pragma warning (disable : 4100) /* Disable Unreferenced parameter warning */
#include <Windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "teamspeak/public_errors.h"
#include "teamspeak/public_errors_rare.h"
#include "teamspeak/public_definitions.h"
#include "teamspeak/public_rare_definitions.h"
#include "teamspeak/clientlib_publicdefinitions.h"
#include "ts3_functions.h"
#include "plugin.h"
#include <QMap>
#pragma region defines, global variables
static struct TS3Functions ts3Functions;
#ifdef _WIN32
#define _strcpy(dest, destSize, src) strcpy_s(dest, destSize, src)
#define snprintf sprintf_s
#else
#define _strcpy(dest, destSize, src) { strncpy(dest, src, destSize-1); (dest)[destSize-1] = '\0'; }
#endif
#define PLUGIN_API_VERSION 21
#define PATH_BUFSIZE 512
#define COMMAND_BUFSIZE 128
#define INFODATA_BUFSIZE 128
#define SERVERINFO_BUFSIZE 256
#define CHANNELINFO_BUFSIZE 512
#define RETURNCODE_BUFSIZE 128
static char* pluginID = NULL;
QMap<uint64, OverlayController*> g_serverList;
#ifdef _WIN32
/* Helper function to convert wchar_T to Utf-8 encoded strings on Windows */
static int wcharToUtf8(const wchar_t* str, char** result) {
int outlen = WideCharToMultiByte(CP_UTF8, 0, str, -1, 0, 0, 0, 0);
*result = (char*)malloc(outlen);
if (WideCharToMultiByte(CP_UTF8, 0, str, -1, *result, outlen, 0, 0) == 0) {
*result = NULL;
return -1;
}
return 0;
}
#endif
#pragma endregion
/****************************** Helper functions ********************************/
/*
* Following functions are helper for the callbacks.
*/
#pragma region helper functions
uint64 getCurrentChannel(uint64 serverConnectionHandlerID)
{
uint64 curChannel;
anyID curClient;
ts3Functions.getClientID(serverConnectionHandlerID, &curClient);
ts3Functions.getChannelOfClient(serverConnectionHandlerID, curClient, &curChannel);
return curChannel;
}
QString clientID2Name(uint64 serverConnectionHandlerID, anyID clientID)
{
char* tmp;
if (ts3Functions.getClientVariableAsString(serverConnectionHandlerID, clientID, CLIENT_NICKNAME, &tmp) != ERROR_ok)
return QString();
QString name(tmp);
ts3Functions.freeMemory(tmp);
return name;
}
QString channelID2Name(uint64 serverConnectionHandlerID, uint64 channelID)
{
char* tmp;
if (ts3Functions.getChannelVariableAsString(serverConnectionHandlerID, channelID, CHANNEL_NAME, &tmp) != ERROR_ok)
return QString();
QString name(tmp);
ts3Functions.freeMemory(tmp);
return name;
}
OverlayController* getController(uint64 serverConnectionHandlerID = 0)
{
if (serverConnectionHandlerID == 0)
{
OverlayController* ret = NULL;
for (auto it : g_serverList.keys())
{
int tmp;
if (ts3Functions.getClientSelfVariableAsInt(it, CLIENT_INPUT_HARDWARE, &tmp) == ERROR_ok)
if (tmp == 1)
ret = g_serverList.find(it).value();
}
return ret;
}
auto tmp = g_serverList.find(serverConnectionHandlerID);
if (tmp == g_serverList.end())
{
OverlayController* ret = new OverlayController(ts3Functions, serverConnectionHandlerID);
g_serverList.insert(serverConnectionHandlerID, ret);
return ret;
}
return tmp.value();
}
void setActiveServer(uint64 serverConnectionHanderlID)
{
// mute all server
for (auto& it : g_serverList)
it->mute(true);
// unmute the current server
getController(serverConnectionHanderlID)->mute(false);
}
/* Helper function to create a hotkey */
static struct PluginHotkey* createHotkey(const char* keyword, const char* description) {
struct PluginHotkey* hotkey = (struct PluginHotkey*)malloc(sizeof(struct PluginHotkey));
_strcpy(hotkey->keyword, PLUGIN_HOTKEY_BUFSZ, keyword);
_strcpy(hotkey->description, PLUGIN_HOTKEY_BUFSZ, description);
return hotkey;
}
/* Some makros to make the code to create hotkeys a bit more readable */
#define BEGIN_CREATE_HOTKEYS(x) const size_t sz = x + 1; size_t n = 0; *hotkeys = (struct PluginHotkey**)malloc(sizeof(struct PluginHotkey*) * sz);
#define CREATE_HOTKEY(a, b) (*hotkeys)[n++] = createHotkey(a, b);
#define END_CREATE_HOTKEYS (*hotkeys)[n++] = NULL; assert(n == sz);
#pragma endregion
/*********************************** Required functions ************************************/
/*
* If any of these required functions is not implemented, TS3 will refuse to load the plugin
*/
#pragma region required functions
/* Unique name identifying this plugin */
const char* ts3plugin_name() {
#ifdef _WIN32
/* TeamSpeak expects UTF-8 encoded characters. Following demonstrates a possibility how to convert UTF-16 wchar_t into UTF-8. */
static char* result = NULL; /* Static variable so it's allocated only once */
if (!result) {
const wchar_t* name = L"Cute Overlay";
if (wcharToUtf8(name, &result) == -1) { /* Convert name into UTF-8 encoded result */
result = "Cute Overlay"; /* Conversion failed, fallback here */
}
}
return result;
#else
return "Cute Overlay";
#endif
}
/* Plugin version */
const char* ts3plugin_version() {
return "1.1";
}
/* Plugin API version. Must be the same as the clients API major version, else the plugin fails to load. */
int ts3plugin_apiVersion() {
return PLUGIN_API_VERSION;
}
/* Plugin author */
const char* ts3plugin_author() {
/* If you want to use wchar_t, see ts3plugin_name() on how to use */
return "GT-Anakin";
}
/* Plugin description */
const char* ts3plugin_description() {
/* If you want to use wchar_t, see ts3plugin_name() on how to use */
return "This plugin is a simple overlay based on Qt";
}
/* Set TeamSpeak 3 callback functions */
void ts3plugin_setFunctionPointers(const struct TS3Functions funcs) {
ts3Functions = funcs;
}
/*
* Custom code called right after loading the plugin. Returns 0 on success, 1 on failure.
* If the function returns 1 on failure, the plugin will be unloaded again.
*/
int ts3plugin_init() {
char pluginPath[PATH_BUFSIZE];
ts3Functions.getPluginPath(pluginPath, PATH_BUFSIZE, pluginID);
return 0; /* 0 = success, 1 = failure, -2 = failure but client will not show a "failed to load" warning */
/* -2 is a very special case and should only be used if a plugin displays a dialog (e.g. overlay) asking the user to disable
* the plugin again, avoiding the show another dialog by the client telling the user the plugin failed to load.
* For normal case, if a plugin really failed to load because of an error, the correct return value is 1. */
}
/* Custom code called right before the plugin is unloaded */
void ts3plugin_shutdown() {
while (g_serverList.size() > 0)
delete g_serverList.take(g_serverList.firstKey());
if (pluginID) {
free(pluginID);
pluginID = NULL;
}
/*
* Note:
* If your plugin implements a settings dialog, it must be closed and deleted here, else the
* TeamSpeak client will most likely crash (DLL removed but dialog from DLL code still open).
*/
}
#pragma endregion
/****************************** Optional functions ********************************/
/*
* Following functions are optional, if not needed you don't need to implement them.
*/
#pragma region optional functions
/* Tell client if plugin offers a configuration window. If this function is not implemented, it's an assumed "does not offer" (PLUGIN_OFFERS_NO_CONFIGURE). */
int ts3plugin_offersConfigure() {
/*
* Return values:
* PLUGIN_OFFERS_NO_CONFIGURE - Plugin does not implement ts3plugin_configure
* PLUGIN_OFFERS_CONFIGURE_NEW_THREAD - Plugin does implement ts3plugin_configure and requests to run this function in an own thread
* PLUGIN_OFFERS_CONFIGURE_QT_THREAD - Plugin does implement ts3plugin_configure and requests to run this function in the Qt GUI thread
*/
return PLUGIN_OFFERS_NO_CONFIGURE; /* In this case ts3plugin_configure does not need to be implemented */
}
/* Plugin might offer a configuration window. If ts3plugin_offersConfigure returns 0, this function does not need to be implemented. */
void ts3plugin_configure(void* handle, void* qParentWidget) {
}
/*
* If the plugin wants to use error return codes, plugin commands, hotkeys or menu items, it needs to register a command ID. This function will be
* automatically called after the plugin was initialized. This function is optional. If you don't use these features, this function can be omitted.
* Note the passed pluginID parameter is no longer valid after calling this function, so you must copy it and store it in the plugin.
*/
void ts3plugin_registerPluginID(const char* id) {
const size_t sz = strlen(id) + 1;
pluginID = (char*)malloc(sz * sizeof(char));
_strcpy(pluginID, sz, id);
}
/* Plugin command keyword. Return NULL or "" if not used. */
const char* ts3plugin_commandKeyword() {
return NULL;
}
/* Plugin processes console command. Return 0 if plugin handled the command, 1 if not handled. */
int ts3plugin_processCommand(uint64 serverConnectionHandlerID, const char* command) {
return 1; /* Plugin handled command */
}
/* Client changed current server connection handler */
void ts3plugin_currentServerConnectionChanged(uint64 serverConnectionHandlerID) {
}
/*
* Implement the following three functions when the plugin should display a line in the server/channel/client info.
* If any of ts3plugin_infoTitle, ts3plugin_infoData or ts3plugin_freeMemory is missing, the info text will not be displayed.
*/
/* Static title shown in the left column in the info frame */
const char* ts3plugin_infoTitle() {
return "";
}
/*
* Dynamic content shown in the right column in the info frame. Memory for the data string needs to be allocated in this
* function. The client will call ts3plugin_freeMemory once done with the string to release the allocated memory again.
* Check the parameter "type" if you want to implement this feature only for specific item types. Set the parameter
* "data" to NULL to have the client ignore the info data.
*/
void ts3plugin_infoData(uint64 serverConnectionHandlerID, uint64 id, enum PluginItemType type, char** data) {
}
/* Required to release the memory for parameter "data" allocated in ts3plugin_infoData and ts3plugin_initMenus */
void ts3plugin_freeMemory(void* data) {
free(data);
}
/*
* Plugin requests to be always automatically loaded by the TeamSpeak 3 client unless
* the user manually disabled it in the plugin dialog.
* This function is optional. If missing, no autoload is assumed.
*/
int ts3plugin_requestAutoload() {
return 0; /* 1 = request autoloaded, 0 = do not request autoload */
}
/*
* Initialize plugin hotkeys. If your plugin does not use this feature, this function can be omitted.
* Hotkeys require ts3plugin_registerPluginID and ts3plugin_freeMemory to be implemented.
* This function is automatically called by the client after ts3plugin_init.
*/
void ts3plugin_initHotkeys(struct PluginHotkey*** hotkeys) {
/* Register hotkeys giving a keyword and a description.
* The keyword will be later passed to ts3plugin_onHotkeyEvent to identify which hotkey was triggered.
* The description is shown in the clients hotkey dialog. */
BEGIN_CREATE_HOTKEYS(1); /* Create 3 hotkeys. Size must be correct for allocating memory. */
CREATE_HOTKEY("Channellist", "Displays a simple channellist of the server");
END_CREATE_HOTKEYS;
/* The client will call ts3plugin_freeMemory to release all allocated memory */
}
#pragma endregion
/************************** TeamSpeak callbacks ***************************/
/*
* Following functions are optional, feel free to remove unused callbacks.
* See the clientlib documentation for details on each function.
*/
#pragma region callbacks clientlib
/* Clientlib */
void ts3plugin_onConnectStatusChangeEvent(uint64 serverConnectionHandlerID, int newStatus, unsigned int errorNumber) {
if (newStatus == STATUS_DISCONNECTED)
{
auto tmp = g_serverList.take(serverConnectionHandlerID);
delete tmp;
}
else if (newStatus == STATUS_CONNECTED)
{
// let helper insert new controller to avoid double entries
getController(serverConnectionHandlerID);
}
else if (newStatus == STATUS_CONNECTION_ESTABLISHED)
{
getController(serverConnectionHandlerID)->updateChannelList();
getController(serverConnectionHandlerID)->updateClientList();
getController(serverConnectionHandlerID)->displayChannelList();
}
}
void ts3plugin_onNewChannelEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 channelParentID) {
}
void ts3plugin_onNewChannelCreatedEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 channelParentID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier) {
getController(serverConnectionHandlerID)->updateChannelList();
getController(serverConnectionHandlerID)->updateClientList();
}
void ts3plugin_onDelChannelEvent(uint64 serverConnectionHandlerID, uint64 channelID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier) {
getController(serverConnectionHandlerID)->updateChannelList();
getController(serverConnectionHandlerID)->updateClientList();
}
void ts3plugin_onChannelMoveEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 newChannelParentID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier) {
getController(serverConnectionHandlerID)->updateChannelList();
getController(serverConnectionHandlerID)->updateClientList();
}
void ts3plugin_onUpdateChannelEvent(uint64 serverConnectionHandlerID, uint64 channelID) {
}
void ts3plugin_onUpdateChannelEditedEvent(uint64 serverConnectionHandlerID, uint64 channelID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier) {
getController(serverConnectionHandlerID)->updateChannelList();
getController(serverConnectionHandlerID)->updateClientList();
}
void ts3plugin_onUpdateClientEvent(uint64 serverConnectionHandlerID, anyID clientID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier) {
}
void ts3plugin_onClientMoveEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility, const char* moveMessage) {
getController(serverConnectionHandlerID)->updateClientList();
QString ClientName = clientID2Name(serverConnectionHandlerID, clientID);
QString oldChannel = channelID2Name(serverConnectionHandlerID, oldChannelID);
QString newChannel = channelID2Name(serverConnectionHandlerID, newChannelID);
anyID myID;
ts3Functions.getClientID(serverConnectionHandlerID, &myID);
if (!ClientName.isEmpty() && !oldChannel.isEmpty() && !newChannel.isEmpty())
{
// joined my channel
if (newChannelID == getCurrentChannel(serverConnectionHandlerID))
getController(serverConnectionHandlerID)->addChatLine(QString("<font color=\"#00FFFF\">%1 <font size=\"-5\">entered from</font> %2</font>").arg(ClientName.toHtmlEscaped()).arg(oldChannel));
// quit my channel
else if (oldChannelID == getCurrentChannel(serverConnectionHandlerID))
getController(serverConnectionHandlerID)->addChatLine(QString("<font color=\"#00FFFF\">%1 <font size=\"-5\">left to</font> %2</font>").arg(ClientName.toHtmlEscaped()).arg(newChannel));
// somewhere else
else
getController(serverConnectionHandlerID)->addChatLine(QString("<font size=\"-5\">%1 moved from %2 to %3</font>").arg(ClientName.toHtmlEscaped()).arg(oldChannel).arg(newChannel));
}
else if (!ClientName.isEmpty() && oldChannel.isEmpty() && !newChannel.isEmpty())
{
getController(serverConnectionHandlerID)->addChatLine(QString("%1 <font size=\"-5\">connected to</font> %2").arg(ClientName.toHtmlEscaped()).arg(newChannel));
}
}
void ts3plugin_onClientMoveSubscriptionEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility) {
}
void ts3plugin_onClientMoveTimeoutEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility, const char* timeoutMessage) {
}
void ts3plugin_onClientMoveMovedEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility, anyID moverID, const char* moverName, const char* moverUniqueIdentifier, const char* moveMessage) {
getController(serverConnectionHandlerID)->updateClientList();
QString ClientName = clientID2Name(serverConnectionHandlerID, clientID);
QString oldChannel = channelID2Name(serverConnectionHandlerID, oldChannelID);
QString newChannel = channelID2Name(serverConnectionHandlerID, newChannelID);
anyID myID;
ts3Functions.getClientID(serverConnectionHandlerID, &myID);
if (!ClientName.isEmpty() && !oldChannel.isEmpty() && !newChannel.isEmpty())
{
// joined my channel
if (newChannelID == getCurrentChannel(serverConnectionHandlerID))
getController(serverConnectionHandlerID)->addChatLine(QString("<font color=\"#00FFFF\">%1 <font size=\"-5\">entered from</font> %2 <font size=\"-5\">by</font> %3</font>").arg(ClientName.toHtmlEscaped()).arg(oldChannel).arg(QString(moverName).toHtmlEscaped()));
// quit my channel
else if (oldChannelID == getCurrentChannel(serverConnectionHandlerID))
getController(serverConnectionHandlerID)->addChatLine(QString("<font color=\"#00FFFF\">%1 <font size=\"-5\">left to</font> %2 <font size=\"-5\">left by</font> %3</font>").arg(ClientName.toHtmlEscaped()).arg(newChannel).arg(QString(moverName).toHtmlEscaped()));
// somewhere else
else
getController(serverConnectionHandlerID)->addChatLine(QString("<font size=\"-5\">%1 moved from %2 to %3 by %4</font>").arg(ClientName.toHtmlEscaped()).arg(oldChannel).arg(newChannel).arg(QString(moverName).toHtmlEscaped()));
}
}
void ts3plugin_onClientKickFromChannelEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility, anyID kickerID, const char* kickerName, const char* kickerUniqueIdentifier, const char* kickMessage) {
getController(serverConnectionHandlerID)->updateClientList();
QString ClientName = clientID2Name(serverConnectionHandlerID, clientID);
QString oldChannel = channelID2Name(serverConnectionHandlerID, oldChannelID);
QString newChannel = channelID2Name(serverConnectionHandlerID, newChannelID);
if (!ClientName.isEmpty() && !oldChannel.isEmpty() && !newChannel.isEmpty())
{
getController(serverConnectionHandlerID)->addChatLine(QString("<font color=\"#FF0000\">%1 <font size=\"-5\">was from</font> %2 <font size=\"-5\">to</font> %3 <font size=\"-5\">by</font> %4 <font size=\"-5\">because</font> %5</font>").arg(ClientName.toHtmlEscaped()).arg(oldChannel).arg(newChannel).arg(QString(kickerName).toHtmlEscaped()).arg(kickMessage));
}
}
void ts3plugin_onClientKickFromServerEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility, anyID kickerID, const char* kickerName, const char* kickerUniqueIdentifier, const char* kickMessage) {
getController(serverConnectionHandlerID)->updateClientList();
QString ClientName = clientID2Name(serverConnectionHandlerID, clientID);
if (!ClientName.isEmpty())
{
getController(serverConnectionHandlerID)->addChatLine(QString("<font color=\"#FF0000\">%1 <font size=\"-5\">was from Server by</font> %2 <font size=\"-5\">because</font> %3</font>").arg(ClientName.toHtmlEscaped()).arg(QString(kickerName).toHtmlEscaped()).arg(kickMessage));
}
}
void ts3plugin_onClientIDsEvent(uint64 serverConnectionHandlerID, const char* uniqueClientIdentifier, anyID clientID, const char* clientName) {
}
void ts3plugin_onClientIDsFinishedEvent(uint64 serverConnectionHandlerID) {
}
void ts3plugin_onServerEditedEvent(uint64 serverConnectionHandlerID, anyID editerID, const char* editerName, const char* editerUniqueIdentifier) {
}
void ts3plugin_onServerUpdatedEvent(uint64 serverConnectionHandlerID) {
}
int ts3plugin_onServerErrorEvent(uint64 serverConnectionHandlerID, const char* errorMessage, unsigned int error, const char* returnCode, const char* extraMessage) {
return 0; /* If no plugin return code was used, the return value of this function is ignored */
}
void ts3plugin_onServerStopEvent(uint64 serverConnectionHandlerID, const char* shutdownMessage) {
}
int ts3plugin_onTextMessageEvent(uint64 serverConnectionHandlerID, anyID targetMode, anyID toID, anyID fromID, const char* fromName, const char* fromUniqueIdentifier, const char* message, int ffIgnored) {
getController(serverConnectionHandlerID)->addChatLine(QString("<font size=\"-5\"><%1></font> %2").arg(QString(fromName).toHtmlEscaped()).arg(message));
return 0; /* 0 = handle normally, 1 = client will ignore the text message */
}
void ts3plugin_onTalkStatusChangeEvent(uint64 serverConnectionHandlerID, int status, int isReceivedWhisper, anyID clientID) {
char name[512];
if (ts3Functions.getClientDisplayName(serverConnectionHandlerID, clientID, name, 512) == ERROR_ok)
{
if (status == STATUS_TALKING)
getController(serverConnectionHandlerID)->addSpeaker(name);
else
getController(serverConnectionHandlerID)->removeSpeaker(name);
}
}
void ts3plugin_onConnectionInfoEvent(uint64 serverConnectionHandlerID, anyID clientID) {
}
void ts3plugin_onServerConnectionInfoEvent(uint64 serverConnectionHandlerID) {
}
void ts3plugin_onChannelSubscribeEvent(uint64 serverConnectionHandlerID, uint64 channelID) {
}
void ts3plugin_onChannelSubscribeFinishedEvent(uint64 serverConnectionHandlerID) {
getController(serverConnectionHandlerID)->updateClientList();
}
void ts3plugin_onChannelUnsubscribeEvent(uint64 serverConnectionHandlerID, uint64 channelID) {
}
void ts3plugin_onChannelUnsubscribeFinishedEvent(uint64 serverConnectionHandlerID) {
}
void ts3plugin_onChannelDescriptionUpdateEvent(uint64 serverConnectionHandlerID, uint64 channelID) {
}
void ts3plugin_onChannelPasswordChangedEvent(uint64 serverConnectionHandlerID, uint64 channelID) {
}
void ts3plugin_onPlaybackShutdownCompleteEvent(uint64 serverConnectionHandlerID) {
}
void ts3plugin_onSoundDeviceListChangedEvent(const char* modeID, int playOrCap) {
}
void ts3plugin_onEditPlaybackVoiceDataEvent(uint64 serverConnectionHandlerID, anyID clientID, short* samples, int sampleCount, int channels) {
}
void ts3plugin_onEditPostProcessVoiceDataEvent(uint64 serverConnectionHandlerID, anyID clientID, short* samples, int sampleCount, int channels, const unsigned int* channelSpeakerArray, unsigned int* channelFillMask) {
}
void ts3plugin_onEditMixedPlaybackVoiceDataEvent(uint64 serverConnectionHandlerID, short* samples, int sampleCount, int channels, const unsigned int* channelSpeakerArray, unsigned int* channelFillMask) {
}
void ts3plugin_onEditCapturedVoiceDataEvent(uint64 serverConnectionHandlerID, short* samples, int sampleCount, int channels, int* edited) {
}
void ts3plugin_onCustom3dRolloffCalculationClientEvent(uint64 serverConnectionHandlerID, anyID clientID, float distance, float* volume) {
}
void ts3plugin_onCustom3dRolloffCalculationWaveEvent(uint64 serverConnectionHandlerID, uint64 waveHandle, float distance, float* volume) {
}
void ts3plugin_onUserLoggingMessageEvent(const char* logMessage, int logLevel, const char* logChannel, uint64 logID, const char* logTime, const char* completeLogString) {
}
#pragma endregion
/* Clientlib rare */
#pragma region callbacks clientlib rare
void ts3plugin_onClientBanFromServerEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility, anyID kickerID, const char* kickerName, const char* kickerUniqueIdentifier, uint64 time, const char* kickMessage) {
}
int ts3plugin_onClientPokeEvent(uint64 serverConnectionHandlerID, anyID fromClientID, const char* pokerName, const char* pokerUniqueIdentity, const char* message, int ffIgnored) {
getController(serverConnectionHandlerID)->addChatLine(QString("<font color=\"#00FF00\"><font size=\"-5\">%1</font> Wake up! %2</font>").arg(pokerName).arg(message));
return 0; /* 0 = handle normally, 1 = client will ignore the poke */
}
void ts3plugin_onClientSelfVariableUpdateEvent(uint64 serverConnectionHandlerID, int flag, const char* oldValue, const char* newValue) {
if (flag == CLIENT_INPUT_HARDWARE)
{
// from mute to speak
if (atoi(oldValue) == 0 && atoi(newValue) == 1)
setActiveServer(serverConnectionHandlerID);
// this should not happen
else
getController(serverConnectionHandlerID)->debugPrint("This should not happen");
}
}
void ts3plugin_onFileListEvent(uint64 serverConnectionHandlerID, uint64 channelID, const char* path, const char* name, uint64 size, uint64 datetime, int type, uint64 incompletesize, const char* returnCode) {
}
void ts3plugin_onFileListFinishedEvent(uint64 serverConnectionHandlerID, uint64 channelID, const char* path) {
}
void ts3plugin_onFileInfoEvent(uint64 serverConnectionHandlerID, uint64 channelID, const char* name, uint64 size, uint64 datetime) {
}
void ts3plugin_onServerGroupListEvent(uint64 serverConnectionHandlerID, uint64 serverGroupID, const char* name, int type, int iconID, int saveDB) {
}
void ts3plugin_onServerGroupListFinishedEvent(uint64 serverConnectionHandlerID) {
}
void ts3plugin_onServerGroupByClientIDEvent(uint64 serverConnectionHandlerID, const char* name, uint64 serverGroupList, uint64 clientDatabaseID) {
}
void ts3plugin_onServerGroupPermListEvent(uint64 serverConnectionHandlerID, uint64 serverGroupID, unsigned int permissionID, int permissionValue, int permissionNegated, int permissionSkip) {
}
void ts3plugin_onServerGroupPermListFinishedEvent(uint64 serverConnectionHandlerID, uint64 serverGroupID) {
}
void ts3plugin_onServerGroupClientListEvent(uint64 serverConnectionHandlerID, uint64 serverGroupID, uint64 clientDatabaseID, const char* clientNameIdentifier, const char* clientUniqueID) {
}
void ts3plugin_onChannelGroupListEvent(uint64 serverConnectionHandlerID, uint64 channelGroupID, const char* name, int type, int iconID, int saveDB) {
}
void ts3plugin_onChannelGroupListFinishedEvent(uint64 serverConnectionHandlerID) {
}
void ts3plugin_onChannelGroupPermListEvent(uint64 serverConnectionHandlerID, uint64 channelGroupID, unsigned int permissionID, int permissionValue, int permissionNegated, int permissionSkip) {
}
void ts3plugin_onChannelGroupPermListFinishedEvent(uint64 serverConnectionHandlerID, uint64 channelGroupID) {
}
void ts3plugin_onChannelPermListEvent(uint64 serverConnectionHandlerID, uint64 channelID, unsigned int permissionID, int permissionValue, int permissionNegated, int permissionSkip) {
}
void ts3plugin_onChannelPermListFinishedEvent(uint64 serverConnectionHandlerID, uint64 channelID) {
}
void ts3plugin_onClientPermListEvent(uint64 serverConnectionHandlerID, uint64 clientDatabaseID, unsigned int permissionID, int permissionValue, int permissionNegated, int permissionSkip) {
}
void ts3plugin_onClientPermListFinishedEvent(uint64 serverConnectionHandlerID, uint64 clientDatabaseID) {
}
void ts3plugin_onChannelClientPermListEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 clientDatabaseID, unsigned int permissionID, int permissionValue, int permissionNegated, int permissionSkip) {
}
void ts3plugin_onChannelClientPermListFinishedEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 clientDatabaseID) {
}
void ts3plugin_onClientChannelGroupChangedEvent(uint64 serverConnectionHandlerID, uint64 channelGroupID, uint64 channelID, anyID clientID, anyID invokerClientID, const char* invokerName, const char* invokerUniqueIdentity) {
}
int ts3plugin_onServerPermissionErrorEvent(uint64 serverConnectionHandlerID, const char* errorMessage, unsigned int error, const char* returnCode, unsigned int failedPermissionID) {
return 0; /* See onServerErrorEvent for return code description */
}
void ts3plugin_onPermissionListGroupEndIDEvent(uint64 serverConnectionHandlerID, unsigned int groupEndID) {
}
void ts3plugin_onPermissionListEvent(uint64 serverConnectionHandlerID, unsigned int permissionID, const char* permissionName, const char* permissionDescription) {
}
void ts3plugin_onPermissionListFinishedEvent(uint64 serverConnectionHandlerID) {
}
void ts3plugin_onPermissionOverviewEvent(uint64 serverConnectionHandlerID, uint64 clientDatabaseID, uint64 channelID, int overviewType, uint64 overviewID1, uint64 overviewID2, unsigned int permissionID, int permissionValue, int permissionNegated, int permissionSkip) {
}
void ts3plugin_onPermissionOverviewFinishedEvent(uint64 serverConnectionHandlerID) {
}
void ts3plugin_onServerGroupClientAddedEvent(uint64 serverConnectionHandlerID, anyID clientID, const char* clientName, const char* clientUniqueIdentity, uint64 serverGroupID, anyID invokerClientID, const char* invokerName, const char* invokerUniqueIdentity) {
}
void ts3plugin_onServerGroupClientDeletedEvent(uint64 serverConnectionHandlerID, anyID clientID, const char* clientName, const char* clientUniqueIdentity, uint64 serverGroupID, anyID invokerClientID, const char* invokerName, const char* invokerUniqueIdentity) {
}
void ts3plugin_onClientNeededPermissionsEvent(uint64 serverConnectionHandlerID, unsigned int permissionID, int permissionValue) {
}
void ts3plugin_onClientNeededPermissionsFinishedEvent(uint64 serverConnectionHandlerID) {
}
void ts3plugin_onFileTransferStatusEvent(anyID transferID, unsigned int status, const char* statusMessage, uint64 remotefileSize, uint64 serverConnectionHandlerID) {
}
void ts3plugin_onClientChatClosedEvent(uint64 serverConnectionHandlerID, anyID clientID, const char* clientUniqueIdentity) {
}
void ts3plugin_onClientChatComposingEvent(uint64 serverConnectionHandlerID, anyID clientID, const char* clientUniqueIdentity) {
}
void ts3plugin_onServerLogEvent(uint64 serverConnectionHandlerID, const char* logMsg) {
}
void ts3plugin_onServerLogFinishedEvent(uint64 serverConnectionHandlerID, uint64 lastPos, uint64 fileSize) {
}
void ts3plugin_onMessageListEvent(uint64 serverConnectionHandlerID, uint64 messageID, const char* fromClientUniqueIdentity, const char* subject, uint64 timestamp, int flagRead) {
}
void ts3plugin_onMessageGetEvent(uint64 serverConnectionHandlerID, uint64 messageID, const char* fromClientUniqueIdentity, const char* subject, const char* message, uint64 timestamp) {
}
void ts3plugin_onClientDBIDfromUIDEvent(uint64 serverConnectionHandlerID, const char* uniqueClientIdentifier, uint64 clientDatabaseID) {
}
void ts3plugin_onClientNamefromUIDEvent(uint64 serverConnectionHandlerID, const char* uniqueClientIdentifier, uint64 clientDatabaseID, const char* clientNickName) {
}
void ts3plugin_onClientNamefromDBIDEvent(uint64 serverConnectionHandlerID, const char* uniqueClientIdentifier, uint64 clientDatabaseID, const char* clientNickName) {
}
void ts3plugin_onComplainListEvent(uint64 serverConnectionHandlerID, uint64 targetClientDatabaseID, const char* targetClientNickName, uint64 fromClientDatabaseID, const char* fromClientNickName, const char* complainReason, uint64 timestamp) {
}
void ts3plugin_onBanListEvent(uint64 serverConnectionHandlerID, uint64 banid, const char* ip, const char* name, const char* uid, uint64 creationTime, uint64 durationTime, const char* invokerName,
uint64 invokercldbid, const char* invokeruid, const char* reason, int numberOfEnforcements, const char* lastNickName) {
}
void ts3plugin_onClientServerQueryLoginPasswordEvent(uint64 serverConnectionHandlerID, const char* loginPassword) {
}
void ts3plugin_onPluginCommandEvent(uint64 serverConnectionHandlerID, const char* pluginName, const char* pluginCommand) {
}
void ts3plugin_onIncomingClientQueryEvent(uint64 serverConnectionHandlerID, const char* commandText) {
}
void ts3plugin_onServerTemporaryPasswordListEvent(uint64 serverConnectionHandlerID, const char* clientNickname, const char* uniqueClientIdentifier, const char* description, const char* password, uint64 timestampStart, uint64 timestampEnd, uint64 targetChannelID, const char* targetChannelPW) {
}
#pragma endregion
/* Client UI callbacks */
#pragma region callbacks client UI
/*
* Called from client when an avatar image has been downloaded to or deleted from cache.
* This callback can be called spontaneously or in response to ts3Functions.getAvatar()
*/
void ts3plugin_onAvatarUpdated(uint64 serverConnectionHandlerID, anyID clientID, const char* avatarPath) {
}
/*
* Called when a plugin menu item (see ts3plugin_initMenus) is triggered. Optional function, when not using plugin menus, do not implement this.
*
* Parameters:
* - serverConnectionHandlerID: ID of the current server tab
* - type: Type of the menu (PLUGIN_MENU_TYPE_CHANNEL, PLUGIN_MENU_TYPE_CLIENT or PLUGIN_MENU_TYPE_GLOBAL)
* - menuItemID: Id used when creating the menu item
* - selectedItemID: Channel or Client ID in the case of PLUGIN_MENU_TYPE_CHANNEL and PLUGIN_MENU_TYPE_CLIENT. 0 for PLUGIN_MENU_TYPE_GLOBAL.
*/
void ts3plugin_onMenuItemEvent(uint64 serverConnectionHandlerID, enum PluginMenuType type, int menuItemID, uint64 selectedItemID) {
}
/* This function is called if a plugin hotkey was pressed. Omit if hotkeys are unused. */
void ts3plugin_onHotkeyEvent(const char* keyword) {
printf("PLUGIN: Hotkey event: %s\n", keyword);
if (QString(keyword) == "Channellist")
{
auto controller = getController();
if (controller != NULL)
{
controller->displayChannelList();
}
}
}
/* Called when recording a hotkey has finished after calling ts3Functions.requestHotkeyInputDialog */
void ts3plugin_onHotkeyRecordedEvent(const char* keyword, const char* key) {
}
/* Called when client custom nickname changed */
void ts3plugin_onClientDisplayNameChanged(uint64 serverConnectionHandlerID, anyID clientID, const char* displayName, const char* uniqueClientIdentifier) {
}
#pragma endregion