From 048aaf0c4e77402adf584e3318e5aae6f1cdd749 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20P=C3=B6sel?= Date: Mon, 5 Nov 2012 21:11:48 +0000 Subject: XFire adoption (crashes on login, no 64bit) git-svn-id: http://svn.miranda-ng.org/main/trunk@2212 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c --- protocols/Xfire/src/Xfire_game.cpp | 487 +++++++++++++++++++++++++++++++++++++ 1 file changed, 487 insertions(+) create mode 100644 protocols/Xfire/src/Xfire_game.cpp (limited to 'protocols/Xfire/src/Xfire_game.cpp') diff --git a/protocols/Xfire/src/Xfire_game.cpp b/protocols/Xfire/src/Xfire_game.cpp new file mode 100644 index 0000000000..10ae7bc783 --- /dev/null +++ b/protocols/Xfire/src/Xfire_game.cpp @@ -0,0 +1,487 @@ +#include "stdafx.h" + +#include "Xfire_game.h" +#include "pwd_dlg.h" //passwort eingabe dlg + +//prüft nach, ob das game das nötige extragameargs im launcherstring hat +BOOL Xfire_game::haveExtraGameArgs() { + //kein launcher stirng, dann abbruch + if(!this->launchparams) + return FALSE; + + //wenn platzhalter vorhanden, dann TRUE zurück + if(this->inString(this->launchparams,"%UA_LAUNCHER_EXTRA_ARGS%")) + return TRUE; + + return FALSE; +} + +//startes das spiel +BOOL Xfire_game::start_game(char*ip,unsigned int port,char*pw) { + //launchparam prüfen ob gefüllt? + if(this->launchparams==NULL) + return FALSE; + + //ist launchparam großgenug für eibne urlprüfung? + if(strlen(this->launchparams)>5) + { + //launchparams ne url? dann openurl funktion von miranda verwenden + if(this->launchparams[0]=='h'&& + this->launchparams[1]=='t'&& + this->launchparams[2]=='t'&& + this->launchparams[3]=='p'&& + this->launchparams[4]==':') + { + return CallService( MS_UTILS_OPENURL, 1, (LPARAM)this->launchparams ); + } + } + + //spiel hat netwerkparameter? + int networksize=0; + char* mynetworkparams=NULL; + + if(this->networkparams) + { + if(ip) + { + char portstr[6]=""; + int pwsize=255; + + //größe des netzwerparams berechnen + if(this->pwparams) + pwsize+=strlen(this->pwparams); + + mynetworkparams=new char[strlen(this->networkparams)+pwsize]; + strcpy_s(mynetworkparams,strlen(this->networkparams)+pwsize,this->networkparams); + + //port begrenzen + port=port%65535; + //port in string wandeln + sprintf_s(portstr,6,"%d",port); + + str_replace(mynetworkparams,"%UA_GAME_HOST_NAME%",ip); + str_replace(mynetworkparams,"%UA_GAME_HOST_PORT%",portstr); + + //passwort dialog, nur wenn SHIFT gehalten wird beim join, da sonst immer gefragt wird + if(GetAsyncKeyState(VK_LSHIFT) && this->pwparams){ + char password[256]=""; //passwort maximal 255 zeichen + + if(ShowPwdDlg(password)) { + char* mypwargs=new char[pwsize]; + + //speicher frei? + if(mypwargs!=NULL) { + strcpy_s(mypwargs,pwsize,this->pwparams); + str_replace(mypwargs, "%UA_GAME_HOST_PASSWORD%", password); + str_replace(mynetworkparams,"%UA_LAUNCHER_PASSWORD_ARGS%",mypwargs); + delete[] mypwargs; + } + else + str_replace(mynetworkparams,"%UA_LAUNCHER_PASSWORD_ARGS%",""); + } + else + { + str_replace(mynetworkparams,"%UA_LAUNCHER_PASSWORD_ARGS%",""); + } + } + else + str_replace(mynetworkparams,"%UA_LAUNCHER_PASSWORD_ARGS%",""); + + //bestimmte felder erstmal leer ersetzen + str_replace(mynetworkparams,"%UA_LAUNCHER_RCON_ARGS%",""); + } + + if(mynetworkparams) + networksize=strlen(mynetworkparams)+strlen(this->networkparams); + } + + //extra parameter + int extraparamssize=0; + if(this->extraparams) + { + extraparamssize=strlen(this->extraparams); + } + + //temporäres array anlegen + char*temp=NULL; + temp=new char[strlen(this->launchparams)+networksize+extraparamssize+1]; + + if(temp==NULL) + { + //wenn nwparams gesetzt, leeren + if(mynetworkparams) + delete[] mynetworkparams; + + return FALSE; + } + + //launcherstring ins temporäre array + strcpy_s(temp,strlen(this->launchparams)+1,this->launchparams); + + //netzwerkparameter ? + if(mynetworkparams) + { + str_replace(temp,"%UA_LAUNCHER_NETWORK_ARGS%",mynetworkparams); + delete[] mynetworkparams; + } + else + str_replace(temp,"%UA_LAUNCHER_NETWORK_ARGS%",""); + + if(this->extraparams) + str_replace(temp,"%UA_LAUNCHER_EXTRA_ARGS%",this->extraparams); + else + str_replace(temp,"%UA_LAUNCHER_EXTRA_ARGS%",""); + + //auf createprocess umgebaut + STARTUPINFO si = { sizeof(si) }; + PROCESS_INFORMATION pi; + + // MessageBox(NULL,temp,temp,0); + + //starten + if(CreateProcess(0, temp, 0, 0, FALSE, 0, 0, GetLaunchPath(temp) , &si, &pi)==0) + { + //schlug fehl, dann runas methode verwenden + char*exe=strrchr(temp,'\\'); + if(exe==0) + { + delete[] temp; + return FALSE; + } + *exe=0; + exe++; + char*params=strchr(exe,'.'); + if(params!=0) + { + params=strchr(params,' '); + if(params!=0) + { + *params=0; + params++; + } + } + + + SHELLEXECUTEINFO sei = {0}; + sei.cbSize = sizeof(sei); + sei.hwnd = NULL; + sei.lpVerb = "runas"; + sei.lpFile = exe; + sei.lpParameters = params; + sei.lpDirectory = temp; + sei.nShow = SW_SHOWNORMAL; + ShellExecuteEx(&sei); + } + delete[] temp; + return TRUE; +} + +//prüft den übergebenen pfad, ob es dem spiel vergleichbar +BOOL Xfire_game::checkpath(PROCESSENTRY32* processInfo) +{ + //gibts net, weg mit dir + if(this->path==NULL) + return FALSE; + + //versuche ein processhandle des speils zubekommen + HANDLE op=OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, processInfo->th32ProcessID); + + if(op) + { + //varaibele wohin der pfad eingelesen wird + char fpath[MAX_PATH]=""; + + //lese den pfad des spiels aus + GetModuleFileNameEx(op,NULL,fpath,sizeof(fpath)); + + //8.3 pfade umwandeln, nur wenn sich eine tilde im string befindet + if(strchr(fpath,'~')) + GetLongPathNameA(fpath,fpath,sizeof(fpath)); + + //alles in kelinbuchstaben umwandeln + this->strtolower(fpath); + + if(this->wildcmp(this->path,fpath)) + //if(strcmp(this->path,fpath)==0) + { + //pfad stimmt überein, commandline prüfen + if(checkCommandLine(op,this->mustcontain,this->notcontain)) + { + //handle zuamachen + CloseHandle(op); + //positive antwort an die gamedetection + return TRUE; + } + } + else //prüfe den multipfad + { + int size=mpath.size(); + for(int j=0;jmustcontain,this->notcontain)) + { + //handle zumachen + CloseHandle(op); + //positive antwort an die gamedetection + return TRUE; + } + } + } + } + //is nich das game, handle zumachen + CloseHandle(op); + } + else //if(this->mustcontain==NULL&&this->notcontain==NULL) //spiele die was bestimmtes im pfad benötigen skippen + { + char* exename=strrchr(this->path,'\\')+1; + + //kleiner fix bei fehlerhaften pfaden kann keine exe ermittelt werden also SKIP + if((unsigned int)exename==0x1) + return FALSE; + + //exenamen des process kleinschreiben + this->strtolower(processInfo->szExeFile); + + //vergleich die exenamen + if(strcmp(exename,processInfo->szExeFile)==0) + { + return TRUE; + } + else //anderen pfade des games noch durchprüfen + { + int size=mpath.size(); + for(int j=0;jszExeFile)==0) + { + //positive antwort an die gamedetection + return TRUE; + } + } + } + } + + //keine übereinstimmung + return FALSE; +} + +//icondaten setzen +void Xfire_game::setIcon(HICON hicon,HANDLE handle) { + this->hicon=hicon; + this->iconhandl=handle; +} + +//liest gamewerte aus der db +void Xfire_game::readFromDB(unsigned dbid) +{ + //lese alle string werte aus der db und befülle die passenden variablen damit + this->readStringfromDB("gamepath",dbid,&this->path); + + //8.3 fix, prüfe auf ~ pfad, wenn ja pfad var umwalnd in longname + if(this->path) + { + BOOL found=FALSE; + for(unsigned int i=0;ipath);i++) + { + if(this->path[i] == '~') + { + found=TRUE; + break; + } + } + //gefunden? dann stirng wandeln und in pfad speichern + if(found) { + char ctemp[MAX_PATH]=""; + strcpy_s(ctemp,MAX_PATH,this->path); + GetLongPathNameA(ctemp,ctemp,sizeof(ctemp)); + this->strtolower(ctemp); + this->setString(ctemp,&this->path); + } + } + + this->readStringfromDB("gamelaunch",dbid,&this->launchparams); + this->readStringfromDB("gamenetargs",dbid,&this->networkparams); + this->readStringfromDB("gamepwargs",dbid,&this->pwparams); + this->readStringfromDB("gameuserargs",dbid,&this->userparams); + this->readStringfromDB("gamecmdline",dbid,&this->mustcontain); + this->readStringfromDB("gamencmdline",dbid,&this->notcontain); + + //alle sonstigen werte + this->id=this->readWordfromDB("gameid",dbid); + this->send_gameid=this->readWordfromDB("gamesendid",dbid); + if(this->send_gameid==0) + this->send_gameid=this->id; + this->setstatusmsg=this->readWordfromDB("gamesetsmsg",dbid,0); + this->custom=this->readBytefromDB("gamecustom",dbid,0); + this->skip=this->readBytefromDB("gameskip",this->id,0); + this->notinstartmenu=this->readBytefromDB("notinstartmenu",this->id,0); + this->noicqstatus=this->readBytefromDB("gamenostatus",this->id,0); + this->readStringfromDB("gameextraparams",this->id,&this->extraparams); + this->readStringfromDB("customgamename",this->id,&this->customgamename); + this->readStringfromDB("statusmsg",this->id,&this->statusmsg); + + //mehrere pfade + int size=this->readWordfromDB("gamemulti",dbid,0); + for(int j=0;jreadStringfromDB("gamepath",dbid,j,&tpath); + + if(tpath) + { + mpath.push_back(tpath); + } + } + + //spielname auslesen, wird später für die sortierung gebraucht + setNameandIcon(); +} + +//läd spielnamen aus, sowie icon +void Xfire_game::setNameandIcon() +{ + if(this->customgamename) + { + this->setString(this->customgamename,&this->name); + } + else + { + //std::string game=GetGame(this->id,0,&this->iconhandl,&this->hicon,TRUE); + //zielbuffer für den namen + char buf[XFIRE_MAXSIZEOFGAMENAME]="Unknown Game"; + //name des spiels auslesen + this->getGamename(this->id,buf,XFIRE_MAXSIZEOFGAMENAME); + //namen setzen + this->setString(buf,&this->name); + } +} + +//liest gamewerte aus der db +void Xfire_game::writeToDB(unsigned dbid) +{ + //alle stringwerte schreiben + this->writeStringtoDB("gamepath",dbid,this->path); + this->writeStringtoDB("gamelaunch",dbid,this->launchparams); + this->writeStringtoDB("gamenetargs",dbid,this->networkparams); + this->writeStringtoDB("gamepwargs",dbid,this->pwparams); + this->writeStringtoDB("gameuserargs",dbid,this->userparams); + this->writeStringtoDB("gamecmdline",dbid,this->mustcontain); + this->writeStringtoDB("gamencmdline",dbid,this->notcontain); + + //alle sonstigen werte + this->writeWordtoDB("gameid",dbid,this->id); + if(this->send_gameid!=0&&this->send_gameid!=this->id) this->writeWordtoDB("gamesendid",dbid,this->send_gameid); + if(this->setstatusmsg!=0) this->writeWordtoDB("gamesetsmsg",dbid,this->setstatusmsg); + if(this->custom!=0) this->writeBytetoDB("gamecustom",dbid,this->custom); + //wenn gesetzt, dann eintrag machen + if(this->skip!=0) + this->writeBytetoDB("gameskip",this->id,this->skip); + else //wenn nicht eintrag aus db löschen + this->removeDBEntry("gameskip",this->id); + if(this->notinstartmenu!=0) + this->writeBytetoDB("notinstartmenu",this->id,this->notinstartmenu); + else //wenn nicht eintrag aus db löschen + this->removeDBEntry("notinstartmenu",this->id); + if(this->noicqstatus!=0) + this->writeBytetoDB("gamenostatus",this->id,this->noicqstatus); + else //wenn nicht eintrag aus db löschen + this->removeDBEntry("gamenostatus",this->id); + if(this->extraparams!=0) + this->writeStringtoDB("gameextraparams",this->id,this->extraparams); + else //wenn nicht eintrag aus db löschen + this->removeDBEntry("gameextraparams",this->id); + if(this->customgamename!=0) + this->writeStringtoDB("customgamename",this->id,this->customgamename); + else //wenn nicht eintrag aus db löschen + this->removeDBEntry("customgamename",this->id); + if(this->statusmsg!=0) + this->writeStringtoDB("statusmsg",this->id,this->statusmsg); + else //wenn nicht eintrag aus db löschen + this->removeDBEntry("statusmsg",this->id); + + + + //mehrere pfade + int size=mpath.size(); + if(size>0) + { + this->writeWordtoDB("gamemulti",dbid,mpath.size()); + for(int j=0;jwriteStringtoDB("gamepath",dbid,j,mpath.at(j)); + } + } + + //sendid 0 dann standard id reinladen + if(this->send_gameid==0) + this->send_gameid=this->id; +} + +//erzeugt ein menüpunkt +void Xfire_game::createMenuitem(unsigned int pos,int dbid) +{ + CLISTMENUITEM mi = { 0 }; + char servicefunction[100]; + + if(dbid<0) + dbid=pos; + + memset(&mi,0,sizeof(CLISTMENUITEM)); + strcpy(servicefunction, protocolname); + strcat(servicefunction, "StartGame%d"); + mi.popupPosition = 500084000; + mi.pszPopupName = Translate("Start game"); + mi.pszContactOwner=protocolname; + mi.cbSize = sizeof( mi ); + + sprintf(temp,servicefunction,this->id); + //wenn die servicefunktion schon exisitert vernichten, hehe + if(ServiceExists(temp)) + DestroyServiceFunction(temp); + CreateServiceFunctionParam(temp,StartGame,this->id); + mi.pszService = temp; + mi.position = 500090002+pos; + mi.hIcon = this->hicon?this->hicon:LoadIcon(hinstance,MAKEINTRESOURCE(ID_OP)); + mi.pszName = menuitemtext(this->name); + this->menuhandle=Menu_AddMainMenuItem(&mi); + + //menu aktualisieren ob hidden + this->refreshMenuitem(); +} + +//entfernt menüpunkt +void Xfire_game::remoteMenuitem() +{ + if(menuhandle!=NULL) + { + CallService( MS_CLIST_REMOVEMAINMENUITEM, ( WPARAM )menuhandle, 0 ); + menuhandle=NULL; + } +} + +//aktualisiert menüpunkt ob hidden +void Xfire_game::refreshMenuitem() +{ + if(menuhandle!=NULL) + { + CLISTMENUITEM clmi = { 0 }; + clmi.cbSize = sizeof( clmi ); + clmi.flags = CMIM_FLAGS; + + if(this->notinstartmenu) + clmi.flags|= CMIF_HIDDEN; + + CallService( MS_CLIST_MODIFYMENUITEM, ( WPARAM )menuhandle, ( LPARAM )&clmi ); + } +} \ No newline at end of file -- cgit v1.2.3