Avionics
Dropship Simulator
TeamSpeak.cpp
Go to the documentation of this file.
1 #include "TeamSpeak.h"
2 
3 #include "../ts3_sdk_3.0.2/include/public_errors.h"
4 #include "../ts3_sdk_3.0.2/include/clientlib_publicdefinitions.h"
5 #include "../ts3_sdk_3.0.2/include/clientlib.h"
6 
7 namespace Devices
8 {
11 
12  /*
13  * Callback for connection status change.
14  * Connection status switches through the states STATUS_DISCONNECTED, STATUS_CONNECTING, STATUS_CONNECTED and STATUS_CONNECTION_ESTABLISHED.
15  *
16  * Parameters:
17  * serverConnectionHandlerID - Server connection handler ID
18  * newStatus - New connection status, see the enum ConnectStatus in clientlib_publicdefinitions.h
19  * errorNumber - Error code. Should be zero when connecting or actively disconnection.
20  * Contains error state when losing connection.
21  */
22  void TeamSpeak::onConnectStatusChangeEvent(uint64 serverConnectionHandlerID, int newStatus, unsigned int errorNumber)
23  {
24  switch (newStatus)
25  {
26  case STATUS_DISCONNECTED:
27  if (errorNumber == ERROR_failed_connection_initialisation)
28  {
29  teamSpeakInstance->Log("onConnectStatusChangeEvent", "Looks like there is no server running, terminate!", Logger::Error);
30  return;
31  }
32  else if (errorNumber == ERROR_connection_lost)
33  {
34  teamSpeakInstance->Log("onConnectStatusChangeEvent", "Lost connection. We should reconnect, no?");
38  return;
39  }
40 
41  char msg[199];
42  sprintf_s(msg, 199, "Unhandled disconnect: %llu %d %x", static_cast<unsigned long long>(serverConnectionHandlerID), newStatus, errorNumber);
43  teamSpeakInstance->Log("onConnectStatusChangeEvent", msg);
44  break;
45 
46  case STATUS_CONNECTING:
47  teamSpeakInstance->Log("onConnectStatusChangeEvent", "Connecting...");
48  break;
49 
50  case STATUS_CONNECTED:
51  teamSpeakInstance->Log("onConnectStatusChangeEvent", "Connected!");
52  break;
53 
54  case STATUS_CONNECTION_ESTABLISHING:
55  teamSpeakInstance->Log("onConnectStatusChangeEvent", "Connection establishing...");
56  break;
57 
58  case STATUS_CONNECTION_ESTABLISHED:
59  teamSpeakInstance->Log("onConnectStatusChangeEvent", "Connection established!");
60  break;
61  }
62  }
63 
64  /*
65  * Callback for current channels being announced to the client after connecting to a server.
66  *
67  * Parameters:
68  * serverConnectionHandlerID - Server connection handler ID
69  * channelID - ID of the announced channel
70  * channelParentID - ID of the parent channel
71  */
72  void TeamSpeak::onNewChannelEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 channelParentID)
73  {
74  /* Query channel name from channel ID */
75  char* name;
76  unsigned int error;
77  char msg[199];
78 
79  sprintf_s(msg, 199, "%llu %llu %llu", static_cast<unsigned long long>(serverConnectionHandlerID), static_cast<unsigned long long>(channelID), static_cast<unsigned long long>(channelParentID));
80  teamSpeakInstance->Log("onNewChannelEvent", msg);
81 
82  if ((error = ts3client_getChannelVariableAsString(serverConnectionHandlerID, channelID, CHANNEL_NAME, &name)) == ERROR_ok)
83  {
84  sprintf_s(msg, 199, "New channel: %llu %s", static_cast<unsigned long long>(channelID), name);
85  teamSpeakInstance->Log("onNewChannelEvent", msg);
86  ts3client_freeMemory(name); /* Release dynamically allocated memory only if function succeeded */
87  }
88  else
89  {
90  teamSpeakInstance->Log("onNewChannelEvent", "Error getting channel name in onNewChannelEvent", Logger::Error, error);
91  }
92  }
93 
94  /*
95  * Callback for just created channels.
96  *
97  * Parameters:
98  * serverConnectionHandlerID - Server connection handler ID
99  * channelID - ID of the announced channel
100  * channelParentID - ID of the parent channel
101  * invokerID - ID of the client who created the channel
102  * invokerName - Name of the client who created the channel
103  */
104  void TeamSpeak::onNewChannelCreatedEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 channelParentID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier)
105  {
106  char* name;
107 
108  /* Query channel name from channel ID */
109  if (ts3client_getChannelVariableAsString(serverConnectionHandlerID, channelID, CHANNEL_NAME, &name) != ERROR_ok)
110  return;
111 
112  char msg[199];
113  sprintf_s(msg, 199, "New channel created: %s", name);
114  teamSpeakInstance->Log("onNewChannelCreatedEvent", msg);
115 
116  ts3client_freeMemory(name); /* Release dynamically allocated memory only if function succeeded */
117  }
118 
119  /*
120  * Callback when a channel was deleted.
121  *
122  * Parameters:
123  * serverConnectionHandlerID - Server connection handler ID
124  * channelID - ID of the deleted channel
125  * invokerID - ID of the client who deleted the channel
126  * invokerName - Name of the client who deleted the channel
127  */
128  void TeamSpeak::onDelChannelEvent(uint64 serverConnectionHandlerID, uint64 channelID, anyID invokerID, const char* invokerName, const char* invokerUniqueIdentifier)
129  {
130  char msg[199];
131  sprintf_s(msg, 199, "Channel ID %llu deleted by %s (%u)", static_cast<unsigned long long>(channelID), invokerName, invokerID);
132  teamSpeakInstance->Log("onDelChannelEvent", msg);
133  }
134 
135  /*
136  * Called when a client joins, leaves or moves to another channel.
137  *
138  * Parameters:
139  * serverConnectionHandlerID - Server connection handler ID
140  * clientID - ID of the moved client
141  * oldChannelID - ID of the old channel left by the client
142  * newChannelID - ID of the new channel joined by the client
143  * visibility - Visibility of the moved client. See the enum Visibility in clientlib_publicdefinitions.h
144  * Values: ENTER_VISIBILITY, RETAIN_VISIBILITY, LEAVE_VISIBILITY
145  */
146  void TeamSpeak::onClientMoveEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility, const char* moveMessage)
147  {
148  char msg[199];
149  sprintf_s(msg, 199, "ClientID %u moves from channel %llu to %llu with message %s", clientID, static_cast<unsigned long long>(oldChannelID), static_cast<unsigned long long>(newChannelID), moveMessage);
150  teamSpeakInstance->Log("onClientMoveEvent", msg);
151  }
152 
153  /*
154  * Callback for other clients in current and subscribed channels being announced to the client.
155  *
156  * Parameters:
157  * serverConnectionHandlerID - Server connection handler ID
158  * clientID - ID of the announced client
159  * oldChannelID - ID of the subscribed channel where the client left visibility
160  * newChannelID - ID of the subscribed channel where the client entered visibility
161  * visibility - Visibility of the announced client. See the enum Visibility in clientlib_publicdefinitions.h
162  * Values: ENTER_VISIBILITY, RETAIN_VISIBILITY, LEAVE_VISIBILITY
163  */
164  void TeamSpeak::onClientMoveSubscriptionEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility)
165  {
166  char* name;
167 
168  /* Query client nickname from ID */
169  if (ts3client_getClientVariableAsString(serverConnectionHandlerID, clientID, CLIENT_NICKNAME, &name) != ERROR_ok)
170  return;
171 
172  char msg[199];
173  sprintf_s(msg, 199, "New client: %s", name);
174  teamSpeakInstance->Log("onClientMoveSubscriptionEvent", msg);
175 
176  ts3client_freeMemory(name); /* Release dynamically allocated memory only if function succeeded */
177  }
178 
179  /*
180  * Called when a client drops his connection.
181  *
182  * Parameters:
183  * serverConnectionHandlerID - Server connection handler ID
184  * clientID - ID of the moved client
185  * oldChannelID - ID of the channel the leaving client was previously member of
186  * newChannelID - 0, as client is leaving
187  * visibility - Always LEAVE_VISIBILITY
188  * timeoutMessage - Optional message giving the reason for the timeout
189  */
190  void TeamSpeak::onClientMoveTimeoutEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility, const char* timeoutMessage)
191  {
192  char msg[199];
193  sprintf_s(msg, 199, "ClientID %u timeouts with message %s", clientID, timeoutMessage);
194  teamSpeakInstance->Log("onClientMoveTimeoutEvent", msg);
195  }
196 
197  /*
198  * This event is called when a client starts or stops talking.
199  *
200  * Parameters:
201  * serverConnectionHandlerID - Server connection handler ID
202  * status - 1 if client starts talking, 0 if client stops talking
203  * isReceivedWhisper - 1 if this event was caused by whispering, 0 if caused by normal talking
204  * clientID - ID of the client who announced the talk status change
205  */
206  void TeamSpeak::onTalkStatusChangeEvent(uint64 serverConnectionHandlerID, int status, int isReceivedWhisper, anyID clientID)
207  {
208  char* name;
209  char msg[199];
210 
211  /* Query client nickname from ID */
212  if (ts3client_getClientVariableAsString(serverConnectionHandlerID, clientID, CLIENT_NICKNAME, &name) != ERROR_ok)
213  return;
214  if (status == STATUS_TALKING)
215  {
216  sprintf_s(msg, 199, "Client \"%s\" starts talking.", name);
217  }
218  else
219  {
220  sprintf_s(msg, 199, "Client \"%s\" stops talking.", name);
221  }
222  teamSpeakInstance->Log("onTalkStatusChangeEvent", msg);
223 
224  ts3client_freeMemory(name); /* Release dynamically allocated memory only if function succeeded */
225  }
226 
227  /*
228  * This event is called when another client starts whispering to own client. Own client can decide to accept or deny
229  * receiving the whisper by adding the sending client to the whisper allow list. If not added, whispering is blocked.
230  *
231  * Parameters:
232  * serverConnectionHandlerID - Server connection handler ID
233  * clientID - ID of the whispering client
234  */
235  void TeamSpeak::onIgnoredWhisperEvent(uint64 serverConnectionHandlerID, anyID clientID)
236  {
237  unsigned int error;
238 
239  /* Add sending client to whisper allow list so own client will hear the voice data.
240  * It is sufficient to add a clientID only once, not everytime this event is called. However it won't
241  * hurt to add the same clientID to the allow list repeatedly, but is is not necessary. */
242  if ((error = ts3client_allowWhispersFrom(serverConnectionHandlerID, clientID)) != ERROR_ok)
243  {
244  teamSpeakInstance->Log("onIgnoredWhisperEvent", "Error setting client on whisper allow list", Logger::Error, error);
245  }
246 
247  char msg[199];
248  sprintf_s(msg, 199, "Added client %d to whisper allow list", clientID);
249  teamSpeakInstance->Log("onIgnoredWhisperEvent", msg);
250  }
251 
252  void TeamSpeak::onServerErrorEvent(uint64 serverConnectionHandlerID, const char* errorMessage, unsigned int error, const char* returnCode, const char* extraMessage)
253  {
254  char msg[199];
255  sprintf_s(msg, 199, "Error for server %llu: %s (%x) %s", static_cast<unsigned long long>(serverConnectionHandlerID), errorMessage, error, extraMessage);
256  teamSpeakInstance->Log("onServerErrorEvent", msg, Logger::Warn);
257  }
258 
259  /*
260  * Callback for user-defined logging.
261  *
262  * Parameter:
263  * logMessage - Log message text
264  * logLevel - Severity of log message
265  * logChannel - Custom text to categorize the message channel
266  * logID - Virtual server ID giving the virtual server source of the log event
267  * logTime - String with the date and time the log entry occured
268  * completeLogString - Verbose log message including all previous parameters for convinience
269  */
270  void TeamSpeak::onUserLoggingMessageEvent(const char* logMessage, int logLevel, const char* logChannel, uint64 logID, const char* logTime, const char* completeLogString)
271  {
272  Logger::Level level;
273  switch (logLevel)
274  {
275  case LogLevel_CRITICAL: level = Logger::Fatal;
276  break;
277  case LogLevel_ERROR: level = Logger::Error;
278  break;
279  case LogLevel_WARNING: level = Logger::Warn;
280  break;
281  default: level = Logger::Info;
282  break;
283  }
284  teamSpeakInstance->Log("", logMessage, level);
285  }
286 
287  void TeamSpeak::Connect() const
288  {
289  unsigned int error;
290  /* Connect to server on localhost:9987 with nickname "client", no default channel, no default channel password and server password "secret" */
291  if ((error = ts3client_startConnection(scHandlerID, config->identity.c_str(), "reskin.us", 9987, config->handle.c_str(), nullptr, "", "53cr3t")) != ERROR_ok)
292  {
293  Log("Initialize", "ts3client_startConnection", Logger::Error, error);
294  }
295  }
296 
297  void TeamSpeak::Initialize(Logger* prmLogger, TeamSpeakConfig* prmConfig, Bus* prmBus)
298  {
299  logger = prmLogger;
300  config = prmConfig;
301 
302  bus = prmBus;
303 
304  teamSpeakInstance = this;
305 
306  Log("Initialize", "Entering...");
307 
308  unsigned int error;
309 
310  /* Create struct for callback function pointers */
311  struct ClientUIFunctions funcs;
312 
313  /* Initialize all callbacks with NULL */
314  RtlZeroMemory(&funcs, sizeof(struct ClientUIFunctions));
315 
316  /* Callback function pointers */
317  /* It is sufficient to only assign those callback functions you are using. When adding more callbacks, add those function pointers here. */
318  funcs.onConnectStatusChangeEvent = onConnectStatusChangeEvent;
319  funcs.onNewChannelEvent = onNewChannelEvent;
320  funcs.onNewChannelCreatedEvent = onNewChannelCreatedEvent;
321  funcs.onDelChannelEvent = onDelChannelEvent;
322  funcs.onClientMoveEvent = onClientMoveEvent;
323  funcs.onClientMoveSubscriptionEvent = onClientMoveSubscriptionEvent;
324  funcs.onClientMoveTimeoutEvent = onClientMoveTimeoutEvent;
325  funcs.onTalkStatusChangeEvent = onTalkStatusChangeEvent;
326  funcs.onIgnoredWhisperEvent = onIgnoredWhisperEvent;
327  funcs.onServerErrorEvent = onServerErrorEvent;
328  funcs.onUserLoggingMessageEvent = onUserLoggingMessageEvent;
329  //funcs.onCustomPacketEncryptEvent = onCustomPacketEncryptEvent;
330  //funcs.onCustomPacketDecryptEvent = onCustomPacketDecryptEvent;
331  //funcs.onEditMixedPlaybackVoiceDataEvent = onEditMixedPlaybackVoiceDataEvent;
332 
333  /* Initialize client lib with callbacks */
334  /* Resource path points to the SDK\bin directory to locate the soundbackends folder when running from Visual Studio. */
335  /* If you want to run directly from the SDK\bin directory, use an empty string instead to locate the soundbackends folder in the current directory. */
336  if ((error = ts3client_initClientLib(&funcs, nullptr, LogType_USERLOGGING, nullptr, "")) != ERROR_ok)
337  {
338  Log("Initialize", "ts3client_getErrorMessage", Logger::Error, error);
339  return;
340  }
341 
342  /* Spawn a new server connection handler and store the ID */
343  if ((error = ts3client_spawnNewServerConnectionHandler(0, &scHandlerID)) != ERROR_ok)
344  {
345  Log("Initialize", "ts3client_spawnNewServerConnectionHandler", Logger::Error, error);
346  return;
347  }
348 
349  char msg[199];
350  sprintf_s(msg, 199, "Capture mode from configuration: %i", config->captureMode);
351  Log("Initialize", msg);
352  if (config->captureMode == -1)
353  {
354  Log("Initialize", "Enumerating capture modes...");
355  char** array;
356  if ((error = ts3client_getCaptureModeList(&array)) == ERROR_ok)
357  {
358  for (int i = 0; array[i] != nullptr; ++i)
359  {
360  sprintf_s(msg, 199, "Available capture mode %i: %s", i, array[i]);
361  Log("Initialize", msg);
362  ts3client_freeMemory(array[i]); // Free C-string
363  }
364  ts3client_freeMemory(array); // Free the array
365  }
366  else
367  {
368  Log("Initialize", "ts3client_getCaptureModeList", Logger::Error, error);
369  }
370  config->captureMode = 0;
371  sprintf_s(msg, 199, "Capture mode now defaulted: %i", config->captureMode);
372  Log("Initialize", msg);
373  }
374 
375  sprintf_s(msg, 199, "Capture device from configuration: %s", config->captureDevice.c_str());
376  Log("Initialize", msg);
377  if (config->captureDevice == "-1")
378  {
379  Log("Initialize", "Enumerating capture devices...");
380  char*** array;
381  if ((error = ts3client_getCaptureDeviceList(&config->captureMode, &array)) == ERROR_ok)
382  {
383  for (int i = 0; array[i] != nullptr; ++i)
384  {
385  sprintf_s(msg, 199, "Available capture device %s: %s", array[i][1], array[i][0]); /* First element: Device name, Second element: Device ID */
386  Log("Initialize", msg);
387 
388  /* Free element */
389  ts3client_freeMemory(array[i][0]);
390  ts3client_freeMemory(array[i][1]);
391  ts3client_freeMemory(array[i]);
392  }
393  ts3client_freeMemory(array); /* Free complete array */
394  }
395  else
396  {
397  Log("Initialize", "ts3client_getCaptureDeviceList", Logger::Error, error);
398  }
399  config->captureDevice = "";
400  sprintf_s(msg, 199, "Capture device now defaulted: %i", config->captureDevice);
401  Log("Initialize", msg);
402  }
403 
404  /* Open default capture device (Passing NULL for the device parameter opens the default device) */
405  if ((error = ts3client_openCaptureDevice(scHandlerID, &config->captureMode, config->captureDevice.c_str())) != ERROR_ok)
406  {
407  Log("Initialize", "ts3client_openCaptureDevice", Logger::Error, error);
408  return;
409  }
410 
412  error = ts3client_setPreProcessorConfigValue(scHandlerID, "denoise", "false");
413  if (error != ERROR_ok)
414  {
415  Log("Initialize", "ts3client_setPreProcessorConfigValue - denoise", Logger::Error, error);
416  }
417 
419  if (!config->voiceActivated)
420  {
421  error = ts3client_setPreProcessorConfigValue(scHandlerID, "vad", "false");
422  if (error != ERROR_ok)
423  {
424  Log("Initialize", "ts3client_setPreProcessorConfigValue - vad", Logger::Error, error);
425  }
426  SetPTT(false);
427  }
428  else if (config->gain != 0)
429  {
430  _itoa_s(config->gain, msg, sizeof(msg), 10);
431  error = ts3client_setPreProcessorConfigValue(scHandlerID, "voiceactivation_level", msg);
432  if (error != ERROR_ok)
433  {
434  Log("Initialize", "ts3client_setPreProcessorConfigValue - voiceactivation_level", Logger::Error, error);
435  }
436  }
437  error = ts3client_setPreProcessorConfigValue(scHandlerID, "agc", "false");
438  if (error != ERROR_ok)
439  {
440  Log("Initialize", "ts3client_setPreProcessorConfigValue - agc", Logger::Error, error);
441  }
442 
443  sprintf_s(msg, 199, "Playback mode from configuration: %i", config->playbackMode);
444  Log("Initialize", msg);
445  if (config->playbackMode == -1)
446  {
447  Log("Initialize", "Enumerating playback modes...");
448  char** array;
449  if (ts3client_getPlaybackModeList(&array) == ERROR_ok)
450  {
451  for (int i = 0; array[i] != nullptr; ++i)
452  {
453  sprintf_s(msg, 199, "Available playback mode %i: %s", i, array[i]);
454  Log("Initialize", msg);
455  ts3client_freeMemory(array[i]); // Free C-string
456  }
457  ts3client_freeMemory(array); // Free the array
458  }
459  else
460  {
461  Log("Initialize", "ts3client_getPlaybackModeList", Logger::Error, error);
462  }
463  config->playbackMode = 0;
464  sprintf_s(msg, 199, "Playback mode now defaulted: %i", config->playbackMode);
465  Log("Initialize", msg);
466  }
467 
468  sprintf_s(msg, 199, "Playback device from configuration: %s", config->playbackDevice.c_str());
469  Log("Initialize", msg);
470  if (config->playbackDevice == "-1")
471  {
472  Log("Initialize", "Enumerating playback devices...");
473  char*** array;
474  if ((error = ts3client_getPlaybackDeviceList(&config->playbackMode, &array)) == ERROR_ok)
475  {
476  for (int i = 0; array[i] != nullptr; ++i)
477  {
478  sprintf_s(msg, 199, "Available playback device %s: %s", array[i][1], array[i][0]); /* First element: Device name, Second element: Device ID */
479  Log("Initialize", msg);
480 
481  /* Free element */
482  ts3client_freeMemory(array[i][0]);
483  ts3client_freeMemory(array[i][1]);
484  ts3client_freeMemory(array[i]);
485  }
486  ts3client_freeMemory(array); /* Free complete array */
487  }
488  else
489  {
490  Log("Initialize", "ts3client_getPlaybackDeviceList", Logger::Error, error);
491  }
492  config->playbackDevice = "";
493  sprintf_s(msg, 199, "Playback device now defaulted: %i", config->playbackDevice);
494  Log("Initialize", msg);
495  }
496 
497  /* Open default playback device (Passing NULL for the device parameter opens the default device) */
498  if ((error = ts3client_openPlaybackDevice(scHandlerID, &config->playbackMode, config->playbackDevice.c_str())) != ERROR_ok)
499  {
500  Log("Initialize", "ts3client_openPlaybackDevice", Logger::Error, error);
501  return;
502  }
503 
505 
506  if (!config->identity[0])
507  {
508  /* Create a new client identity */
509  char* identity;
510  if ((error = ts3client_createIdentity(&identity)) != ERROR_ok)
511  {
512  Log("Initialize", "ts3client_createIdentity", Logger::Error, error);
513  return;
514  }
515 
516  /* In your real application you should do this only once, store the assigned identity locally and then reuse it. */
517  config->identity = identity;
518 
519  char msgId[999];
520  sprintf_s(msgId, 999, "You should configure this identity in your config.xml file: %s", identity);
521  Log("Initialize", msgId, Logger::Warn);
522 
523  ts3client_freeMemory(identity); /* Release dynamically allocated memory */
524  }
525 
526  Connect();
527 
528  Log("Initialize", "Finished!");
529  }
530 
531  void TeamSpeak::Destroy() const
532  {
533  Log("dtor", "Entering...");
534 
535  unsigned int error;
536 
537  /* Disconnect from server */
538  if ((error = ts3client_stopConnection(scHandlerID, "leaving")) != ERROR_ok)
539  {
540  Log("dtor", "ts3client_stopConnection", Logger::Error, error);
541  }
542 
543  Sleep(200);
544 
545  /* Destroy server connection handler */
546  if ((error = ts3client_destroyServerConnectionHandler(scHandlerID)) != ERROR_ok)
547  {
548  Log("dtor", "ts3client_destroyServerConnectionHandler", Logger::Error, error);
549  }
550 
551  /* Shutdown client lib */
552  if ((error = ts3client_destroyClientLib()) != ERROR_ok)
553  {
554  Log("dtor", "ts3client_destroyClientLib", Logger::Error, error);
555  }
556 
557  Log("dtor", "Finished!");
558  }
559 
560  void TeamSpeak::Log(char* method, const char* msg, Logger::Level level, int errorno) const
561  {
562  char newmsg[999];
563  if (method[0])
564  sprintf_s(newmsg, 199, "TeamSpeak::%s %s", method, msg);
565  else
566  sprintf_s(newmsg, 199, "TeamSpeak::%s", msg);
567 
568  if (errorno != 0)
569  {
570  char* errormsg;
571  if (ts3client_getErrorMessage(errorno, &errormsg) == ERROR_ok)
572  {
573  strcat_s(newmsg, 199, ": ");
574  strcat_s(newmsg, 199, errormsg);
575  }
576  ts3client_freeMemory(errormsg);
577  }
578 
579  logger->Log(newmsg, level, errorno);
580  }
581 
583  {
584  if (lostConnection)
585  {
586  lostConnection = false;
587  Connect();
588  }
589 
591  for (UINT i = 0; i < bus->commandStream.size(); i++)
592  {
593  Command command = bus->commandStream.at(i);
594  if (command.delay != 0.0f) continue;
595 
596  if (command.name == "RtuTransmit")
597  {
598  SetPTT(command.bvalue);
599  bus->commandStream.erase(bus->commandStream.begin() + i);
600  }
601  }
602  }
603 
604  void TeamSpeak::SetPTT(bool shouldTalk) const
605  {
606  unsigned int error;
607  char msg[999];
608 
609  error = ts3client_setClientSelfVariableAsInt(scHandlerID, CLIENT_INPUT_DEACTIVATED, shouldTalk ? INPUT_ACTIVE : INPUT_DEACTIVATED);
610  if (error != ERROR_ok)
611  {
612  char* errorMsg;
613  if (ts3client_getErrorMessage(error, &errorMsg) != ERROR_ok)
614  {
615  sprintf_s(msg, 999, "Error toggling push-to-talk: %s\n", errorMsg);
616  Log("FrameMove", msg, Logger::Error, error);
617  ts3client_freeMemory(errorMsg);
618  }
619  return;
620  }
621  if (ts3client_flushClientSelfUpdates(scHandlerID, nullptr) != ERROR_ok)
622  {
623  char* errorMsg;
624  if (ts3client_getErrorMessage(error, &errorMsg) != ERROR_ok)
625  {
626  sprintf_s(msg, 999, "Error flushing after toggling push-to-talk: %s\n", errorMsg);
627  Log("FrameMove", msg, Logger::Error, error);
628  ts3client_freeMemory(errorMsg);
629  }
630  }
631  }
632 }
static void onNewChannelEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 channelParentID)
Definition: TeamSpeak.cpp:72
std::vector< Command > commandStream
Definition: Bus.h:20
std::string captureDevice
Definition: TeamSpeak.h:14
Definition: Logger.h:5
static void onNewChannelCreatedEvent(uint64 serverConnectionHandlerID, uint64 channelID, uint64 channelParentID, anyID invokerID, const char *invokerName, const char *invokerUniqueIdentifier)
Definition: TeamSpeak.cpp:104
void Initialize(Logger *prmLogger, TeamSpeakConfig *prmConfig, Bus *prmBus)
Definition: TeamSpeak.cpp:297
void SetPTT(bool shouldTalk) const
Definition: TeamSpeak.cpp:604
static void onConnectStatusChangeEvent(uint64 serverConnectionHandlerID, int newStatus, unsigned int errorNumber)
Definition: TeamSpeak.cpp:22
TeamSpeak * teamSpeakInstance
global singleton because TeamSpeak doesn&#39;t support user context pointers
Definition: TeamSpeak.cpp:10
okay, the portable keyboard numbers don&#39;t work like the outside keypad because the outside keypad is ...
Definition: Analog.cpp:3
static void onClientMoveEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility, const char *moveMessage)
Definition: TeamSpeak.cpp:146
void Log(char *method, const char *msg, Logger::Level level=Logger::Level::Info, int errorno=0) const
Definition: TeamSpeak.cpp:560
Definition: Bus.h:12
Logger * logger
Definition: TeamSpeak.h:26
std::string name
command name
Definition: Command.h:11
static void onIgnoredWhisperEvent(uint64 serverConnectionHandlerID, anyID clientID)
Definition: TeamSpeak.cpp:235
void Destroy() const
Definition: TeamSpeak.cpp:531
std::string playbackDevice
Definition: TeamSpeak.h:15
static void onTalkStatusChangeEvent(uint64 serverConnectionHandlerID, int status, int isReceivedWhisper, anyID clientID)
Definition: TeamSpeak.cpp:206
Definition: Command.h:5
static void onUserLoggingMessageEvent(const char *logMessage, int logLevel, const char *logChannel, uint64 logID, const char *logTime, const char *completeLogString)
Definition: TeamSpeak.cpp:270
TeamSpeakConfig * config
Definition: TeamSpeak.h:27
std::string identity
Definition: TeamSpeak.h:16
void Log(const char *msg, Level level=Info, int errorCode=0)
These have to be in this order.
Definition: Logger.cpp:16
bool bvalue
Definition: Command.h:23
void Connect() const
Definition: TeamSpeak.cpp:287
static void onServerErrorEvent(uint64 serverConnectionHandlerID, const char *errorMessage, unsigned int error, const char *returnCode, const char *extraMessage)
Definition: TeamSpeak.cpp:252
static void onDelChannelEvent(uint64 serverConnectionHandlerID, uint64 channelID, anyID invokerID, const char *invokerName, const char *invokerUniqueIdentifier)
Definition: TeamSpeak.cpp:128
Level
Definition: Logger.h:11
float delay
wait number of seconds before executing command
Definition: Command.h:8
uint64 scHandlerID
Definition: TeamSpeak.h:30
static void onClientMoveSubscriptionEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility)
Definition: TeamSpeak.cpp:164
static void onClientMoveTimeoutEvent(uint64 serverConnectionHandlerID, anyID clientID, uint64 oldChannelID, uint64 newChannelID, int visibility, const char *timeoutMessage)
Definition: TeamSpeak.cpp:190