bool NiftyKbFunctions::UnmuteClient(uint64 scHandlerID, anyID client) { if(CheckAndLog(ts3Functions.requestUnmuteClients(scHandlerID, &client, NULL), "Error unmuting client")) return false; return CheckAndLog(ts3Functions.requestClientVariables(scHandlerID, client, NULL), "Error flushing after unmuting client"); }
bool NiftyKbFunctions::ConnectToBookmark(char* label, PluginConnectTab connectTab, uint64* scHandlerID) { // Get the bookmark list PluginBookmarkList* bookmarks; if(CheckAndLog(ts3Functions.getBookmarkList(&bookmarks), "Error getting bookmark list")) return false; // Find the bookmark bool ret = true; for(int i=0; i<bookmarks->itemcount; i++) { PluginBookmarkItem item = bookmarks->items[i]; // Seems pretty useless to try to connect to a folder, skip it if(!item.isFolder) { // If the name matches the label we're looking for if(!strcmp(item.name, label)) { // Connect to the bookmark ret = !CheckAndLog(ts3Functions.guiConnectBookmark(connectTab, item.uuid, scHandlerID), "Failed to connect to bookmark"); } } } ts3Functions.freeMemory(bookmarks); return ret; }
bool NiftyKbFunctions::SetAway(uint64 scHandlerID, bool isAway, char* msg) { if(CheckAndLog(ts3Functions.setClientSelfVariableAsInt(scHandlerID, CLIENT_AWAY, isAway ? AWAY_ZZZ : AWAY_NONE), "Error setting away status")) return false; if(CheckAndLog(ts3Functions.setClientSelfVariableAsString(scHandlerID, CLIENT_AWAY_MESSAGE, isAway && msg != NULL ? msg : ""), "Error setting away message")) return false; return CheckAndLog(ts3Functions.flushClientSelfUpdates(scHandlerID, NULL), "Error flushing after setting away status"); }
bool NiftyKbFunctions::JoinChannel(uint64 scHandlerID, uint64 channel) { anyID self; if(CheckAndLog(ts3Functions.getClientID(scHandlerID, &self), "Error getting own client id")) return false; if(CheckAndLog(ts3Functions.requestClientMove(scHandlerID, self, channel, "", NULL), "Error joining channel")) return false; return true; }
uint64 NiftyKbFunctions::GetChannelIDFromPath(uint64 scHandlerID, char* path) { uint64 parent; // Split the string, following the hierachy char* str = path; char* lastStr = path; std::vector<char*> hierachy; while(str != NULL) { lastStr = str; str = strchr(lastStr, '/'); if(str!=NULL) { *str = NULL; str++; } hierachy.push_back(lastStr); } hierachy.push_back(""); // Add the terminator /* * For efficiency I will violate the vector abstraction and give a direct pointer to its internal C array */ if(CheckAndLog(ts3Functions.getChannelIDFromChannelNames(scHandlerID, &hierachy[0], &parent), "Error getting parent channel ID")) return false; return parent; }
void NiftyKbFunctions::ErrorMessage(uint64 scHandlerID, char* message) { // If an info icon has been found create a styled message if(!infoIcon.empty()) { // Get the time time_t timer; char timeStr[11]; time(&timer); strftime(timeStr, 11, "<%X>", localtime(&timer)); // Format and print the error message, use a transparent underscore because a double space will be collapsed std::stringstream ss; ss << "[img]" << infoIcon << "[/img][color=red]" << timeStr << "[color=transparent]_[/color]" << message << "[/color]"; ts3Functions.printMessageToCurrentTab(ss.str().c_str()); } else { // Format a simplified styled error message std::stringstream ss; ss << "[color=red]" << message << "[/color]"; ts3Functions.printMessageToCurrentTab(ss.str().c_str()); } // If an error sound has been found play it if(!errorSound.empty()) CheckAndLog(ts3Functions.playWaveFile(scHandlerID, errorSound.c_str()), "Error playing error sound"); }
bool NiftyKbFunctions::SetReplyList(uint64 scHandlerID, bool shouldReply) { ReplyIterator list; if(shouldReply) { list = replyLists.find(scHandlerID); if(list == replyLists.end()) shouldReply = false; else { // Add the NULL-terminator list->second.push_back((anyID)NULL); } } /* * For efficiency I will violate the vector abstraction and give a direct pointer to its internal C array */ if(CheckAndLog(ts3Functions.requestClientSetWhisperList(scHandlerID, (anyID)NULL, NULL, shouldReply?&list->second[0]:(anyID*)NULL, NULL), "Error setting reply list")) return false; if(shouldReply) { // Remove the NULL-terminator list->second.pop_back(); } ts3Functions.flushClientSelfUpdates(scHandlerID, NULL); replyActive = shouldReply; if(!shouldReply) return SetWhisperList(scHandlerID, true); return true; }
bool NiftyKbFunctions::SetWhisperList(uint64 scHandlerID, bool shouldWhisper) { WhisperIterator list; if(shouldWhisper) { list = whisperLists.find(scHandlerID); if(list == whisperLists.end()) shouldWhisper = false; else { // Add the NULL-terminator list->second.clients.push_back((anyID)NULL); list->second.channels.push_back((uint64)NULL); } } /* * For efficiency purposes I will violate the vector abstraction and give a direct pointer to its internal C array */ if(CheckAndLog(ts3Functions.requestClientSetWhisperList(scHandlerID, (anyID)NULL, shouldWhisper?&list->second.channels[0]:(uint64*)NULL, shouldWhisper?&list->second.clients[0]:(anyID*)NULL, NULL), "Error setting whisper list")) return false; if(shouldWhisper) { // Remove the NULL-terminator list->second.clients.pop_back(); list->second.channels.pop_back(); } ts3Functions.flushClientSelfUpdates(scHandlerID, NULL); whisperActive = shouldWhisper; return true; }
bool NiftyKbFunctions::SetOutputMute(uint64 scHandlerID, bool shouldMute) { if(CheckAndLog(ts3Functions.setClientSelfVariableAsInt(scHandlerID, CLIENT_OUTPUT_MUTED, shouldMute ? INPUT_DEACTIVATED : INPUT_ACTIVE), "Error toggling output mute")) return false; ts3Functions.flushClientSelfUpdates(scHandlerID, NULL); return true; }
int NiftyKbFunctions::GetConnectionStatus(uint64 scHandlerID) { int status; if(CheckAndLog(ts3Functions.getConnectionStatus(scHandlerID, &status), "Error retrieving connection status")) return STATUS_DISCONNECTED; // Assume we're not connected return status; }
bool NiftyKbFunctions::SetMasterVolume(uint64 scHandlerID, float value) { // Clamp value char str[6]; if(value < -40.0) value = -40.0; if(value > 20.0) value = 20.0; snprintf(str, 6, "%.1f", value); return CheckAndLog(ts3Functions.setPlaybackConfigValue(scHandlerID, "volume_modifier", str), "Error setting master volume"); }
std::string NiftyKbFunctions::GetDefaultCaptureProfile() { char** profiles; int defaultProfile; if(CheckAndLog(ts3Functions.getProfileList(PLUGIN_GUI_SOUND_CAPTURE, &defaultProfile, &profiles), "Error retrieving capture profiles")) return std::string(); std::string profile = profiles[defaultProfile]; ts3Functions.freeMemory(profiles); return profile; }
bool NiftyKbFunctions::SetVoiceActivation(uint64 scHandlerID, bool shouldActivate) { // Activate Voice Activity Detection if(CheckAndLog(ts3Functions.setPreProcessorConfigValue(scHandlerID, "vad", (shouldActivate && !pttActive)?"true":"false"), "Error toggling vad")) return false; // Activate the input, restore the input setting afterwards if(CheckAndLog(ts3Functions.setClientSelfVariableAsInt(scHandlerID, CLIENT_INPUT_DEACTIVATED, (shouldActivate) ? INPUT_ACTIVE : INPUT_DEACTIVATED), "Error toggling input")) return false; // Update the client ts3Functions.flushClientSelfUpdates(scHandlerID, NULL); // Commit the change vadActive = shouldActivate; inputActive = shouldActivate; return true; }
bool NiftyKbFunctions::JoinChannelRelative(uint64 scHandlerID, bool next) { anyID self; uint64 ownId; Channel root; // Get channel hierarchy if(Channel::GetChannelHierarchy(scHandlerID, &root) != 0) return false; // Get own channel if(CheckAndLog(ts3Functions.getClientID(scHandlerID, &self), "Error getting own client id")) return false; if(CheckAndLog(ts3Functions.getChannelOfClient(scHandlerID, self, &ownId), "Error getting own channel id")) return false; // Find own channel in hierarchy Channel* channel = root.find(ownId); // Find a joinable channel bool found = false; while(channel != NULL && !found) { if(next) { // If the channel has subchannels, go deeper if(!channel->subchannels.empty()) channel = channel->first(); else channel = channel->next(); } else channel = channel->prev(); // If this channel is passworded, join the next int pswd; CheckAndLog(ts3Functions.getChannelVariableAsInt(scHandlerID, channel->id, CHANNEL_FLAG_PASSWORD, &pswd), "Error getting channel info"); if(!pswd) found = true; } if(!found) return false; // If a joinable channel was found, attempt to join it return CheckAndLog(ts3Functions.requestClientMove(scHandlerID, self, channel->id, "", NULL), "Error joining channel"); }
uint64 GetActiveServerConnectionHandlerID() { uint64* servers; uint64* server; uint64 handle = NULL; if (CheckAndLog(ts3Functions.getServerConnectionHandlerList(&servers), "Error retrieving list of servers")) return NULL; // Find the first server that matches the criteria for (server = servers; *server != (uint64)NULL && handle == NULL; server++) { int result; if (!CheckAndLog(ts3Functions.getClientSelfVariableAsInt(*server, CLIENT_INPUT_HARDWARE, &result), "Error retrieving client variable")) { if (result) handle = *server; } } ts3Functions.freeMemory(servers); return handle; }
bool SetPushToTalk(uint64 scHandlerID, bool shouldTalk) { // If PTT is inactive, store the current settings if (!pttActive) { // Get the current VAD setting char* vad; if (CheckAndLog(ts3Functions.getPreProcessorConfigValue(scHandlerID, "vad", &vad), "Error retrieving vad setting")) return false; vadActive = !strcmp(vad, "true"); ts3Functions.freeMemory(vad); // Get the current input setting, this will indicate whether VAD is being used in combination with PTT int input; if (CheckAndLog(ts3Functions.getClientSelfVariableAsInt(scHandlerID, CLIENT_INPUT_DEACTIVATED, &input), "Error retrieving input setting")) return false; inputActive = !input; // We want to know when it is active, not when it is inactive } // If VAD is active and the input is active, disable VAD, restore VAD setting afterwards if (CheckAndLog(ts3Functions.setPreProcessorConfigValue(scHandlerID, "vad", (shouldTalk && (vadActive && inputActive)) ? "false" : (vadActive) ? "true" : "false"), "Error toggling vad")) return false; // Activate the input, restore the input setting afterwards if (CheckAndLog(ts3Functions.setClientSelfVariableAsInt(scHandlerID, CLIENT_INPUT_DEACTIVATED, (shouldTalk || inputActive) ? INPUT_ACTIVE : INPUT_DEACTIVATED), "Error toggling input")) return false; // Update the client ts3Functions.flushClientSelfUpdates(scHandlerID, NULL); // Commit the change pttActive = shouldTalk; return true; }
uint64 NiftyKbFunctions::GetServerHandleByVariable(char* value, size_t flag) { char* variable; uint64* servers; uint64* server; uint64 result; if(CheckAndLog(ts3Functions.getServerConnectionHandlerList(&servers), "Error retrieving list of servers")) return (uint64)NULL; // Find the first server that matches the criteria for(server = servers, result = (uint64)NULL; *server != (uint64)NULL && result == (uint64)NULL; server++) { if(!CheckAndLog(ts3Functions.getServerVariableAsString(*server, flag, &variable), "Error retrieving server variable")) { // If the variable matches the value set the result, this will end the loop if(!strcmp(value, variable)) result = *server; ts3Functions.freeMemory(variable); } } ts3Functions.freeMemory(servers); return result; }
anyID NiftyKbFunctions::GetClientIDByVariable(uint64 scHandlerID, char* value, size_t flag) { char* variable; anyID* clients; anyID* client; anyID result; if(CheckAndLog(ts3Functions.getClientList(scHandlerID, &clients), "Error retrieving list of clients")) return (anyID)NULL; // Find the first client that matches the criteria for(client = clients, result = (anyID)NULL; *client != (uint64)NULL && result == (anyID)NULL; client++) { if(!CheckAndLog(ts3Functions.getClientVariableAsString(scHandlerID, *client, flag, &variable), "Error retrieving client variable")) { // If the variable matches the value set the result, this will end the loop if(!strcmp(value, variable)) result = *client; ts3Functions.freeMemory(variable); } } ts3Functions.freeMemory(clients); return result; }
uint64 NiftyKbFunctions::GetChannelIDByVariable(uint64 scHandlerID, char* value, size_t flag) { char* variable; uint64* channels; uint64* channel; uint64 result; if(CheckAndLog(ts3Functions.getChannelList(scHandlerID, &channels), "Error retrieving list of channels")) return (uint64)NULL; // Find the first channel that matches the criteria for(channel = channels, result = (uint64)NULL; *channel != (uint64)NULL && result == NULL; channel++) { if(!CheckAndLog(ts3Functions.getChannelVariableAsString(scHandlerID, *channel, flag, &variable), "Error retrieving channel variable")) { // If the variable matches the value set the result, this will end the loop if(!strcmp(value, variable)) result = *channel; ts3Functions.freeMemory(variable); } } ts3Functions.freeMemory(channels); return result; }
bool NiftyKbFunctions::SetContinuousTransmission(uint64 scHandlerID, bool shouldActivate) { // Activate the input, restore the input setting afterwards if(CheckAndLog(ts3Functions.setClientSelfVariableAsInt(scHandlerID, CLIENT_INPUT_DEACTIVATED, (shouldActivate || pttActive) ? INPUT_ACTIVE : INPUT_DEACTIVATED), "Error toggling input")) return false; // Update the client ts3Functions.flushClientSelfUpdates(scHandlerID, NULL); // Commit the change inputActive = shouldActivate; return true; }
bool NiftyKbFunctions::SetActiveServerRelative(uint64 scHandlerID, bool next) { uint64* servers; uint64* server; int result; // Get server list if(CheckAndLog(ts3Functions.getServerConnectionHandlerList(&servers), "Error retrieving list of servers")) return false; // Find active server in the list for(server = servers; *server != (uint64)NULL && *server!=scHandlerID; server++); // Find the server in the direction given if(next) { if(*(server+1) != NULL) server++; else server = servers; // Wrap around to first server } else { if(server != servers) server--; else { for(server = servers; *server != (uint64)NULL; server++); server--; } } // Check if already active bool ret = !CheckAndLog(ts3Functions.getClientSelfVariableAsInt(*server, CLIENT_INPUT_HARDWARE, &result), "Error retrieving client variable"); if(!result) SetActiveServer(*server); ts3Functions.freeMemory(servers); return ret; }
bool NiftyKbFunctions::SetGlobalAway(bool isAway, char* msg) { uint64* servers; uint64 handle; int i; if(CheckAndLog(ts3Functions.getServerConnectionHandlerList(&servers), "Error retrieving list of servers")) return false; handle = servers[0]; for(i = 1; handle != (uint64)NULL; i++) { SetAway(handle, isAway, msg); handle = servers[i]; } ts3Functions.freeMemory(servers); return true; }
bool NiftyKbFunctions::SetActiveServer(uint64 handle) { return CheckAndLog(ts3Functions.activateCaptureDevice(handle), "Error activating server"); }
bool NiftyKbFunctions::ServerKickClient(uint64 scHandlerID, anyID client) { return CheckAndLog(ts3Functions.requestClientKickFromServer(scHandlerID, client, "", NULL), "Error kicking client from server"); }
bool NiftyKbFunctions::ChannelKickClient(uint64 scHandlerID, anyID client) { return CheckAndLog(ts3Functions.requestClientKickFromChannel(scHandlerID, client, "", NULL), "Error kicking client from channel"); }