summaryrefslogtreecommitdiff
path: root/protocols/Xfire/src/buddylist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'protocols/Xfire/src/buddylist.cpp')
-rw-r--r--protocols/Xfire/src/buddylist.cpp373
1 files changed, 373 insertions, 0 deletions
diff --git a/protocols/Xfire/src/buddylist.cpp b/protocols/Xfire/src/buddylist.cpp
new file mode 100644
index 0000000000..ea7e264502
--- /dev/null
+++ b/protocols/Xfire/src/buddylist.cpp
@@ -0,0 +1,373 @@
+/*
+ * xfirelib - C++ Library for the xfire protocol.
+ * Copyright (C) 2006 by
+ * Beat Wolf <asraniel@fryx.ch> / http://gfire.sf.net
+ * Herbert Poul <herbert.poul@gmail.com> / http://goim.us
+ * http://xfirelib.sphene.net
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "stdafx.h"
+
+#include <iostream>
+#include <vector>
+#include "buddylist.h"
+#include "buddylistonlinepacket.h"
+#include "buddylistgamespacket.h"
+#include "buddylistgames2packet.h"
+#include "recvremovebuddypacket.h"
+#include "recvstatusmessagepacket.h"
+#include "recvbuddychangednick.h"
+#include "xdebug.h"
+
+//buddylist verarbeitung von der main in buddylist verschoben, um doppelte schleifenverarbeitung zuunterbinden
+#include "baseProtocol.h"
+
+extern HANDLE handlingBuddys(xfirelib::BuddyListEntry *entry, int clan=0,char* group=NULL,BOOL dontscan=FALSE);
+extern void setBuddyStatusMsg(xfirelib::BuddyListEntry *entry,std::string statusmsg);
+
+namespace xfirelib {
+
+ using namespace std;
+
+ BuddyList::BuddyList(Client *client) {
+ entries = new vector<BuddyListEntry *>;
+
+ //clan entries initialisieren - dufte
+ entriesClan = new vector<BuddyListEntry *>;
+
+ this->client = client;
+ this->client->addPacketListener( this );
+ }
+ BuddyList::~BuddyList() {
+ for(vector<BuddyListEntry *>::iterator it = entries->begin();
+ it != entries->end(); it++) {
+ delete *it;
+ }
+ delete entries;
+
+ //clan entries entfernen - dufte
+ for(vector<BuddyListEntry *>::iterator it = entriesClan->begin();
+ it != entriesClan->end(); it++) {
+ delete *it;
+ }
+ delete entriesClan;
+ }
+
+ BuddyListEntry *BuddyList::getBuddyById(long userid) {
+ for(uint i = 0 ; i < entries->size() ; i++) {
+ BuddyListEntry *entry = entries->at(i);
+ if(entry->userid == userid)
+ return entry;
+ }
+
+ //clan entries durchsuchen - dufte
+ for(uint i = 0 ; i < entriesClan->size() ; i++) {
+ BuddyListEntry *entry = entriesClan->at(i);
+ if(entry->userid == userid)
+ return entry;
+ }
+
+ return 0;
+ }
+
+ BuddyListEntry *BuddyList::getBuddyByName(string username) {
+ for(uint i = 0 ; i < entries->size() ; i++) {
+ BuddyListEntry *entry = entries->at(i);
+ if(entry->username == username)
+ return entry;
+ }
+
+ //clan entries durchsuchen - dufte
+ for(uint i = 0 ; i < entriesClan->size() ; i++) {
+ BuddyListEntry *entry = entriesClan->at(i);
+ if(entry->username == username)
+ return entry;
+ }
+
+ return 0;
+ }
+
+ BuddyListEntry *BuddyList::getBuddyBySid(const char *sid) {
+ for(uint i = 0 ; i < entries->size() ; i++) {
+ BuddyListEntry *entry = entries->at(i);
+
+ if(memcmp((void *)sid,(void *)entry->sid,16) == 0)
+ return entry;
+
+ }
+
+ //clan entries durchsuchen - dufte
+ for(uint i = 0 ; i < entriesClan->size() ; i++) {
+ BuddyListEntry *entry = entriesClan->at(i);
+
+ if(memcmp((void *)sid,(void *)entry->sid,16) == 0)
+ return entry;
+
+ }
+
+ return 0;
+ }
+
+
+ void BuddyList::initEntries(BuddyListNamesPacket *buddyNames) {
+ for(uint i = 0 ; i < buddyNames->usernames->size() ; i++) {
+ BuddyListEntry *entry = new BuddyListEntry;
+ entry->username = buddyNames->usernames->at(i);
+ entry->userid = buddyNames->userids->at(i);
+ entry->nick = buddyNames->nicks->at(i);
+ //buddies in miranda verarbeiten
+ handlingBuddys(entry,0,NULL);
+ entries->push_back(entry);
+ }
+ }
+
+ // funktion zum initialisieren der clanliste - dufte
+ void BuddyList::initEntriesClan(ClanBuddyListNamesPacket *buddyNames) {
+ for(uint i = 0 ; i < buddyNames->usernames->size() ; i++) {
+ BuddyListEntry *entry = new BuddyListEntry;
+ entry->username = buddyNames->usernames->at(i);
+ entry->userid = buddyNames->userids->at(i);
+ entry->nick = buddyNames->nicks->at(i);
+ entry->clanid = buddyNames->clanid;
+ /* ## buddies im miranda verarbietn */
+ char temp[255];
+ char * dummy;
+ sprintf_s(temp,255,"Clan_%d",entry->clanid);
+
+ DBVARIANT dbv;
+ if(!DBGetContactSetting(NULL,protocolname,temp,&dbv))
+ {
+ dummy=dbv.pszVal;
+ }
+ else
+ dummy=NULL;
+
+ handlingBuddys(entry,entry->clanid,dummy);
+ /* ## ende */
+ entriesClan->push_back(entry);
+ }
+ }
+
+ void BuddyList::updateFriendsofFriend(FriendsBuddyListNamesPacket* friends)
+ {
+ for(uint i = 0 ; i < friends->sids->size() ; i++) {
+ BuddyListEntry *entry = getBuddyBySid( friends->sids->at(i) );
+ if(entry){
+ XDEBUG2("Friends of Friend %s!\n",friends->usernames->at(i).c_str());
+ entry->nick=friends->nicks->at(i);
+ entry->username=friends->usernames->at(i);
+ entry->userid=friends->userids->at(i);
+ }else{
+ XERROR(("updateFriendsofFriendBuddies: sid not found!\n"));
+ }
+ }
+ }
+
+ void BuddyList::updateOnlineBuddies(BuddyListOnlinePacket* buddiesOnline) {
+ for(uint i = 0 ; i < buddiesOnline->userids->size() ; i++) {
+ BuddyListEntry *entry = getBuddyById( buddiesOnline->userids->at(i) );
+ if(entry){
+ entry->setSid( buddiesOnline->sids->at(i) );
+ //buddies in miranda verarbeiten
+ handlingBuddys(entry,0,NULL);
+ }else{
+ XERROR(("updateOnlineBuddies: Could not find buddy with this sid!\n"));
+ }
+ }
+ }
+
+ void BuddyList::updateBuddiesGame(BuddyListGamesPacket* buddiesGames) {
+ bool isFirst = buddiesGames->getPacketId() == XFIRE_BUDDYS_GAMES_ID;
+ for(uint i = 0 ; i < buddiesGames->sids->size() ; i++) {
+ BuddyListEntry *entry = getBuddyBySid( buddiesGames->sids->at(i) );
+ if(!entry) {
+ //nicht zuordbare sids zuordnen
+ XERROR("Add dummy Contact in buddylist for friends of friends!\n");
+ BuddyListEntry *newentry = new BuddyListEntry;
+ newentry->username = "";
+ newentry->userid = 0;
+ newentry->nick = "";
+ newentry->setSid(buddiesGames->sids->at(i));
+ entries->push_back(newentry);
+ //nochmal entry suchen
+ entry = newentry; //getBuddyBySid( buddiesGames->sids->at(i) );
+ }
+ if(entry){
+ if(isFirst) {
+ entry->game = buddiesGames->gameids->at(i);
+ delete entry->gameObj; entry->gameObj = NULL;
+ } else {
+ entry->game2 = buddiesGames->gameids->at(i);
+ delete entry->game2Obj; entry->game2Obj = NULL;
+ }
+ XDEBUG(( "Resolving Game ... \n" ));
+ XFireGameResolver *resolver = client->getGameResolver();
+ if(resolver) {
+ XDEBUG(( "Resolving Game ... \n" ));
+ if(isFirst)
+ entry->gameObj = resolver->resolveGame( entry->game, i, buddiesGames );
+ else
+ entry->game2Obj = resolver->resolveGame( entry->game2, i, buddiesGames );
+ } else {
+ XDEBUG(( "No GameResolver ? :(\n" ));
+ }
+ XDEBUG(( "%s: Game (%ld): %s / Game2 (%ld): %s\n",
+ entry->username.c_str(),
+ entry->game,
+ (entry->gameObj == NULL ? "UNKNOWN" : entry->gameObj->getGameName().c_str()),
+ entry->game2,
+ (entry->game2Obj== NULL ? "UNKNOWN" :entry->game2Obj->getGameName().c_str())
+ ));
+ }else{
+ XERROR("updateBuddiesGame: Could not find buddy with this sid!\n");
+ }
+ }
+ }
+
+ void BuddyList::receivedPacket(XFirePacket *packet) {
+ XFirePacketContent *content = packet->getContent();
+ if(content == 0) return;
+ XDEBUG2( "hmm... %d\n", content->getPacketId() );
+ switch(content->getPacketId()) {
+ case XFIRE_BUDDYS_NAMES_ID: {
+ XINFO(( "Received Buddy List..\n" ));
+ this->initEntries( (BuddyListNamesPacket*)content );
+ break;
+ }
+ case XFIRE_CLAN_BUDDYS_NAMES_ID: {
+ XINFO(( "Received Clan Buddy List..\n" ));
+ this->initEntriesClan( (ClanBuddyListNamesPacket*)content );
+ break;
+ }
+ //neue nicks updaten, dufte
+ case XFIRE_RECVBUDDYCHANGEDNICK: {
+ RecvBuddyChangedNick* recvchangednick=(RecvBuddyChangedNick*)content;
+ XINFO(( "Received new nick of a buddy..\n" ));
+ BuddyListEntry* entry=NULL;
+ entry=this->getBuddyById(recvchangednick->userid);
+ if(entry) {
+ entry->nick=recvchangednick->newnick;
+ recvchangednick->entry=(void*)entry;
+ handlingBuddys(entry,0,NULL);
+ }
+ break;
+ }
+ case XFIRE_BUDDYS_ONLINE_ID: {
+ XINFO(( "Received Buddy Online Packet..\n" ));
+ this->updateOnlineBuddies( (BuddyListOnlinePacket *)content );
+ break;
+ }
+ case XFIRE_FRIENDS_BUDDYS_NAMES_ID: {
+ XINFO(( "Received Friends of Friend..\n" ));
+ this->updateFriendsofFriend( (FriendsBuddyListNamesPacket *)content );
+ break;
+ }
+ case XFIRE_BUDDYS_GAMES2_ID:
+ case XFIRE_BUDDYS_GAMES_ID: {
+ XINFO(( "Recieved the game a buddy is playing..\n" ));
+ this->updateBuddiesGame( (BuddyListGamesPacket *)content );
+ break;
+ }
+ case XFIRE_RECVREMOVEBUDDYPACKET: {
+ RecvRemoveBuddyPacket *p = (RecvRemoveBuddyPacket*)content;
+ XDEBUG2( "Buddy was removed from contact list (userid: %ld)\n", p->userid );
+ std::vector<BuddyListEntry *>::iterator i = entries->begin();
+ while( i != entries->end() ) {
+ if((*i)->userid == p->userid) {
+ BuddyListEntry *buddy = *i;
+ XINFO(( "%s (%s) was removed from BuddyList.\n", buddy->username.c_str(), buddy->nick.c_str() ));
+ p->username = buddy->username;
+ p->handle = buddy->hcontact; // handle übergeben - dufte
+ entries->erase(i);
+ // i.erase();
+ break; // we are done.
+ }
+ ++i;
+ }
+ break;
+ }
+ case XFIRE_RECV_STATUSMESSAGE_PACKET_ID: {
+ RecvStatusMessagePacket *status = (RecvStatusMessagePacket*) content;
+
+ //status->entries=new PBuddyListEntry[status->sids->size];
+
+ for(uint i = 0 ; i < status->sids->size() ; i++) {
+ BuddyListEntry *entry = getBuddyBySid( status->sids->at(i) );
+ //status->entries[i]=entry;
+
+ if(entry == NULL) {
+ XERROR(( "No such Entry - Got StatusMessage from someone who is not in the buddylist ??\n" ));
+ return;
+ }
+ else
+ {
+ entry->statusmsg = status->msgs->at(i).c_str();
+ setBuddyStatusMsg(entry,entry->statusmsg); //auf eine funktion reduziert, verringert cpuauslastung und beseitigt das
+ //das problem der fehlenden statusmsg
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ BuddyListEntry::~BuddyListEntry() {
+ if(lastpopup) {
+ delete[] lastpopup;
+ lastpopup=NULL;
+ }
+ }
+
+ BuddyListEntry::BuddyListEntry() {
+ memset(sid,0,16);
+ statusmsg = std::string();
+ game = 0;
+ game2 = 0;
+ gameObj = NULL;
+ game2Obj = NULL;
+ hcontact = NULL;
+ clanid = 0;
+ lastpopup=NULL;
+ }
+ bool BuddyListEntry::isOnline() {
+ for(int i = 0 ; i < 16 ; i++) {
+ if(sid[i]) return true;
+ }
+ return false;
+ }
+ void BuddyListEntry::setSid(const char *sid) {
+ int s=0;
+ for(int i = 0 ; i < 16 ; i++) { //wenn buddy offline geht, seine gameinfos zurücksetzen - dufte
+ if(sid[i])
+ {
+ s=1;
+ break;
+ }
+ }
+ if(s)
+ {
+ this->statusmsg = std::string();
+ this->game = 0;
+ this->game2 = 0;
+ this->gameObj = NULL;
+ this->game2Obj = NULL;
+ }
+ memcpy(this->sid,sid,16);
+ }
+};
+