summaryrefslogtreecommitdiff
path: root/protocols/Xfire/src/Xfire_voicechat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Xfire/src/Xfire_voicechat.cpp')
-rw-r--r--protocols/Xfire/src/Xfire_voicechat.cpp380
1 files changed, 380 insertions, 0 deletions
diff --git a/protocols/Xfire/src/Xfire_voicechat.cpp b/protocols/Xfire/src/Xfire_voicechat.cpp
new file mode 100644
index 0000000000..ccca22b1a8
--- /dev/null
+++ b/protocols/Xfire/src/Xfire_voicechat.cpp
@@ -0,0 +1,380 @@
+#include "stdafx.h"
+#include "Xfire_voicechat.h"
+
+//konstruktor
+Xfire_voicechat::Xfire_voicechat() {
+ this->resetCurrentvoicestatus();
+ ipport=NULL;
+ tsrDLL=NULL;
+ IpHlpApiDLL=NULL;
+ tsrGetServerInfo=NULL;
+ GetExtendedTcpTable=NULL;
+ pid=0;
+}
+
+//dekonstruktor
+Xfire_voicechat::~Xfire_voicechat() {
+ //geladene tsr remote dll freigeben
+ if(tsrDLL) {
+ FreeLibrary(tsrDLL);
+ tsrDLL=NULL;
+ }
+ //geladene iphlper freigeben
+ if(IpHlpApiDLL) {
+ FreeLibrary(IpHlpApiDLL);
+ IpHlpApiDLL=NULL;
+ }
+}
+
+//init
+void Xfire_voicechat::initVoicechat() {
+ //tsremotedll laden
+ tsrDLL=this->loadTSR();
+ //weitere dll's laden
+ IpHlpApiDLL=LoadLibraryA("IpHlpApi.dll");
+ if(IpHlpApiDLL) {
+ GetExtendedTcpTable=(pGetExtendedTcpTable)GetProcAddress(IpHlpApiDLL,"GetExtendedTcpTable");
+ }
+ else
+ {
+ XFireLog("IpHlpApi.dll load failed!");
+ }
+}
+
+//prüft ob das paket schonmal versendet wurde, soll unnötigen nwtraffic reduzieren, *ÜBERLEGUNG* ob wirklich notwendig
+BOOL Xfire_voicechat::alreadySend(SendGameStatus2Packet* packet) {
+ if(packet==NULL)
+ return FALSE;
+
+ if(packet->ip[3] != lastpacket.ip[3] ||
+ packet->ip[2] != lastpacket.ip[2] ||
+ packet->ip[1] != lastpacket.ip[1] ||
+ packet->ip[0] != lastpacket.ip[0] ||
+ packet->port != lastpacket.port) {
+ lastpacket=*packet;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//prüft nach laufenden voicechat anwendungen
+BOOL Xfire_voicechat::checkVoicechat(SendGameStatus2Packet* packet) {
+ //kein gültiger verweis?
+ if(packet==NULL)
+ return FALSE;
+ //jeh nach letzten status handeln
+ switch(currentvoice) {
+ case XFIREVOICECHAT_TS2:
+ if(checkforTS2(packet)) {
+ return alreadySend(packet);
+ }
+ else
+ {
+ //kein ts2 mehr? dann paket restten
+ resetSendGameStatus2Packet(packet);
+ resetCurrentvoicestatus();
+ //in db schreiben
+ writeToDatabase(packet);
+ return TRUE;
+ }
+ break;
+ case XFIREVOICECHAT_TS3:
+ if(checkforTS3(packet)) {
+ return alreadySend(packet);
+ }
+ else
+ {
+ //kein ts3 mehr? dann paket restten
+ resetSendGameStatus2Packet(packet);
+ resetCurrentvoicestatus();
+ //in db schreiben
+ writeToDatabase(packet);
+ return TRUE;
+ }
+ break;
+ case XFIREVOICECHAT_MUMBLE:
+ if(checkforMumble(packet)) {
+ return alreadySend(packet);
+ }
+ else
+ {
+ //kein mumble mehr? dann paket restten
+ resetSendGameStatus2Packet(packet);
+ resetCurrentvoicestatus();
+ //in db schreiben
+ writeToDatabase(packet);
+ return TRUE;
+ }
+ break;
+ default:
+ //prüfe nach ts3
+ if(checkforTS3(packet)) {
+ return alreadySend(packet);
+ }
+ //prüfe nach ts2
+ else if(checkforTS2(packet)) {
+ return alreadySend(packet);
+ }
+ //prüfe nach mumble
+ else if(checkforMumble(packet)) {
+ return alreadySend(packet);
+ }
+ break;
+ };
+
+ return FALSE;
+}
+
+//setzte currentvoice auf 0 zurück, falls es einen disconnect gab
+void Xfire_voicechat::resetCurrentvoicestatus() {
+ currentvoice=XFIREVOICECHAT_NOVOICE;
+ lastpacket.ip[3]=0;
+ lastpacket.ip[2]=0;
+ lastpacket.ip[1]=0;
+ lastpacket.ip[0]=0;
+ lastpacket.port=0;
+ pid=0;
+}
+
+//resettet das packet auf 0
+void Xfire_voicechat::resetSendGameStatus2Packet(SendGameStatus2Packet* packet) {
+ if(packet==NULL)
+ return;
+ //voiceid
+ packet->gameid=XFIREVOICECHAT_NOVOICE;
+ //ip zuweisen
+ packet->ip[3]=0;
+ packet->ip[2]=0;
+ packet->ip[1]=0;
+ packet->ip[0]=0;
+ //port zuweisen
+ packet->port=0;
+}
+
+//schreibt derzetigen status in die mirandadb für variables usw
+void Xfire_voicechat::writeToDatabase(SendGameStatus2Packet* packet) {
+ //für sprintf
+ char temp[32]="";
+
+ if(packet==NULL || packet->gameid==XFIREVOICECHAT_NOVOICE) {
+ //einträge aus der db entfernen
+ DBDeleteContactSetting(NULL,protocolname, "VServerIP");
+ DBDeleteContactSetting(NULL,protocolname, "currentvoicename");
+ //zurück
+ return;
+ }
+ //ip speichern
+ sprintf_s(temp,32,"%d.%d.%d.%d:%d",(unsigned char)packet->ip[3],(unsigned char)packet->ip[2],(unsigned char)packet->ip[1],(unsigned char)packet->ip[0],packet->port);
+ DBWriteContactSettingTString(NULL, protocolname, "VServerIP", temp);
+ //namen jeh nach id schreiben
+ switch(packet->gameid) {
+ case XFIREVOICECHAT_TS3:
+ DBWriteContactSettingTString(NULL, protocolname, "currentvoicename", "Teamspeak 3");
+ break;
+ case XFIREVOICECHAT_TS2:
+ DBWriteContactSettingTString(NULL, protocolname, "currentvoicename", "Teamspeak 2");
+ break;
+ case XFIREVOICECHAT_MUMBLE:
+ DBWriteContactSettingTString(NULL, protocolname, "currentvoicename", "Mumble");
+ break;
+ case XFIREVOICECHAT_VENTRILO:
+ DBWriteContactSettingTString(NULL, protocolname, "currentvoicename", "Ventrilo");
+ break;
+ };
+}
+
+//versucht die TSR zuladen
+HMODULE Xfire_voicechat::loadTSR(char* path,BOOL nolocaltest) {
+ char pathtotsr[MAX_PATH]="";
+
+ /*if(path)
+ ; was tun*/
+ strcat_s(pathtotsr,MAX_PATH,"TSRemote.dll");
+
+ //versuche dll zuladen
+ HMODULE tsrDLL = LoadLibrary(pathtotsr);
+ //konnte nicht geladen werden
+ if(!tsrDLL)
+ {
+ XFireLog("TSRemote.dll load failed!");
+
+ //bei keinem lokalen test abbruch
+ if(nolocaltest) return NULL;
+
+ //nochmal engl. lokal versuchen
+ tsrDLL = LoadLibrary("C:\\Program Files\\Teamspeak2_RC2\\client_sdk\\TSRemote.dll");
+
+ if(!tsrDLL) {
+ XFireLog("TSRemote.dll load faild (using standard installationpath)!");
+
+ //deutsches sys?
+ tsrDLL = LoadLibrary("C:\\Programme\\Teamspeak2_RC2\\client_sdk\\TSRemote.dll");
+
+ if(!tsrDLL)
+ XFireLog("TSRemote.dll load failed (using standard installationpath2)!");
+
+ //aufgeben
+ return NULL;
+ }
+ }
+
+ XFireLog("TSRemote.dll successfully loaded!");
+
+ //getserverinfo funktion holen
+ tsrGetServerInfo = (LPtsrGetServerInfo)GetProcAddress(tsrDLL,"tsrGetServerInfo");
+
+ return tsrDLL;
+}
+
+
+//teamspeak 3 detection, benötigt ts3plugin
+BOOL Xfire_voicechat::checkforTS3(SendGameStatus2Packet* packet) {
+ ts3IPPORT* ipport=NULL;
+ //kein gültiger verweis?
+ if(packet==NULL)
+ return FALSE;
+ //existiert ein filemap?
+ HANDLE hMapObject = OpenFileMappingA(FILE_MAP_READ, FALSE, "$ts3info4xfire$");
+ //nicht gefunden, dann kein ts3
+ if (hMapObject == NULL)
+ return FALSE;
+ //versuch ipport zubesorgen
+ ipport = (ts3IPPORT *) MapViewOfFile(hMapObject, FILE_MAP_READ, 0, 0, sizeof(ts3IPPORT));
+ //fehler beim zugriff auf filemap?
+ if(ipport==NULL)
+ {
+ CloseHandle(hMapObject);
+ return FALSE;
+ }
+
+ //wenn kein port, dann stimmt was mit der ip nicht, paket resetten
+ if(ipport->port==0) {
+ //packet resetten
+ resetSendGameStatus2Packet(packet);
+ //in db schreiben
+ writeToDatabase(packet);
+ return TRUE;
+ }
+
+ //voiceid zuweisen
+ this->currentvoice=XFIREVOICECHAT_TS3;
+ packet->gameid=XFIREVOICECHAT_TS3;
+ //ip zuweisen
+ packet->ip[3]=ipport->ip[3];
+ packet->ip[2]=ipport->ip[2];
+ packet->ip[1]=ipport->ip[1];
+ packet->ip[0]=ipport->ip[0];
+ //port zuweisen
+ packet->port=ipport->port;
+ //unmap, handle schließem
+ UnmapViewOfFile(ipport);
+ CloseHandle(hMapObject);
+ //in db schreiben
+ writeToDatabase(packet);
+ //ts3 gefunden
+ return TRUE;
+}
+
+//teamspeak 2 detection mit hilfe der tsr
+BOOL Xfire_voicechat::checkforTS2(SendGameStatus2Packet* packet) {
+ TtsrServerInfo serverinfo={0};
+
+ //get funktion ist nicht initialisiert
+ if(this->tsrGetServerInfo==NULL || packet==NULL)
+ {
+ return FALSE;
+ }
+
+ //infos holen
+ this->tsrGetServerInfo(&serverinfo);
+
+ //auswerten wenn serverip gesetzt
+ if(serverinfo.ServerIp[0]!=0)
+ {
+ char * pos=strrchr(serverinfo.ServerIp,':');
+ if(pos==0)
+ {
+ return FALSE;
+ }
+
+ *pos=0;
+ unsigned int ip=inet_addr(serverinfo.ServerIp);
+ pos++;
+ int port=atoi(pos);
+
+ //port zuweisen
+ packet->port=port;
+ //ip zuweisen
+ packet->ip[3]=LOBYTE(LOWORD(ip));
+ packet->ip[2]=HIBYTE(LOWORD(ip));
+ packet->ip[1]=LOBYTE(HIWORD(ip));
+ packet->ip[0]=HIBYTE(HIWORD(ip));
+ //gameid/voice zuweisen
+ packet->gameid=XFIREVOICECHAT_TS2;
+ this->currentvoice=XFIREVOICECHAT_TS2;
+ //ab in die db
+ writeToDatabase(packet);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//detection für mumble
+BOOL Xfire_voicechat::checkforMumble(SendGameStatus2Packet* packet) {
+ //kein gültiger verweis?
+ if(packet==NULL)
+ return FALSE;
+
+ //gültige pid
+ if(this->pid!=0 && !this->isValidPid(this->pid))
+ {
+ this->pid=0;
+ return FALSE;
+ }
+ else {
+ if(!this->getPidByProcessName("mumble.exe",&this->pid)) {
+ return FALSE;
+ }
+ }
+
+ DWORD size=0;
+ MIB_TCPTABLE_OWNER_PID* ptab=NULL;
+ //tcptabelle holen
+ this->GetExtendedTcpTable(NULL,&size,FALSE, AF_INET, TCP_TABLE_OWNER_PID_CONNECTIONS, 0);
+ //überhaupt was drin?
+ if(size) {
+ ptab=(MIB_TCPTABLE_OWNER_PID*)malloc(size);
+ //liste auslesen
+ if(GetExtendedTcpTable(ptab,&size,FALSE, AF_INET, TCP_TABLE_OWNER_PID_CONNECTIONS, 0)==NO_ERROR)
+ {
+ for(unsigned int i=0;i<ptab->dwNumEntries;i++)
+ {
+ if(ptab->table[i].dwOwningPid==this->pid && ptab->table[i].dwLocalAddr!=ptab->table[i].dwRemoteAddr) //verbindung gefunden, hoffentlich
+ {
+ unsigned char*rip=(unsigned char*)&ptab->table[i].dwRemoteAddr;
+ XFireLog("IP %x,%x",ptab->table[i].dwRemoteAddr,ptab->table[i].dwRemotePort);
+ //ipzuweisen
+ packet->ip[3]=rip[0];
+ packet->ip[2]=rip[1];
+ packet->ip[1]=rip[2];
+ packet->ip[0]=rip[3];
+ //portzuweisen
+ packet->port=r(ptab->table[i].dwRemotePort);
+ //mumble
+ packet->gameid=XFIREVOICECHAT_MUMBLE;
+ this->currentvoice=XFIREVOICECHAT_MUMBLE;
+ //table wieder freigeben
+ delete ptab;
+ //mumble läuft + ip gefunden also TRUE
+ return TRUE;
+ }
+ }
+ }
+ delete ptab;
+ }
+
+ return FALSE;
+} \ No newline at end of file