summaryrefslogtreecommitdiff
path: root/protocols/Xfire/src/client.cpp
diff options
context:
space:
mode:
authorRobert Pösel <robyer@seznam.cz>2012-11-05 21:11:48 +0000
committerRobert Pösel <robyer@seznam.cz>2012-11-05 21:11:48 +0000
commit048aaf0c4e77402adf584e3318e5aae6f1cdd749 (patch)
treedef343da80e282ae43164e45e672a1386db66546 /protocols/Xfire/src/client.cpp
parent35a9af527f9b7ec35e81455784cd0a795be910c5 (diff)
XFire adoption (crashes on login, no 64bit)
git-svn-id: http://svn.miranda-ng.org/main/trunk@2212 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'protocols/Xfire/src/client.cpp')
-rw-r--r--protocols/Xfire/src/client.cpp296
1 files changed, 296 insertions, 0 deletions
diff --git a/protocols/Xfire/src/client.cpp b/protocols/Xfire/src/client.cpp
new file mode 100644
index 0000000000..4800482e27
--- /dev/null
+++ b/protocols/Xfire/src/client.cpp
@@ -0,0 +1,296 @@
+/*
+ * 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 "xdebug.h"
+#include "client.h"
+#include "clientinformationpacket.h"
+#include "clientversionpacket.h"
+#include "xfirepacket.h"
+#include "authpacket.h"
+#include "clientloginpacket.h"
+#include "buddylistnamespacket.h"
+#include "messagepacket.h"
+#include "sendmessagepacket.h"
+#include "messageackpacket.h"
+#include "recvoldversionpacket.h"
+#include "sendkeepalivepacket.h"
+
+#include "baseProtocol.h"
+
+#include <iostream>
+
+//#define XFIRE_HOST "cs.xfire.com"
+#define XFIRE_HOST "206.220.42.147"
+#define XFIRE_PORT 25999
+
+extern BOOL mySleep(int ms,HANDLE evt);
+extern HANDLE hConnectionClose;
+extern WINBASEAPI
+BOOL
+WINAPI
+ResetEvent(
+ __in HANDLE hEvent
+ );
+
+//#define UINT_8 unsigned char
+//#define UINT_32 unsigned long
+
+namespace xfirelib {
+
+using namespace std;
+
+ Client::Client() {
+ XDEBUG(("Client constructor ...\n"));
+ gameResolver = NULL;
+ packetReader = new PacketReader(NULL);
+ packetReader->addPacketListener( this );
+ buddyList = new BuddyList( this );
+ socket=NULL;
+#ifndef NO_PTHREAD
+ sendpingthread.p=NULL;
+ readthread.p=NULL;
+#endif
+ }
+
+ Client::~Client(){
+ XDEBUG(("Client destructor ...\n"));
+ delete username;
+ delete password;
+ delete buddyList;
+ delete packetReader;
+ delete socket;
+ }
+
+ void Client::connect( string username, string password, int useproxy, string proxyip, int proxyport) {
+ try {
+ this->gotBudduyList=FALSE;
+ this->username = new string(username);
+ this->password = new string(password);
+ socket = new Socket( XFIRE_HOST, XFIRE_PORT,useproxy,proxyip,proxyport );
+
+ //bevors losgeht, erstmal die localaddr sichern
+ struct sockaddr_in sa;
+ int iLen = sizeof(sa);
+ getsockname(socket->m_sock, (SOCKADDR*)&sa, &iLen);
+ strcpy(this->localaddr,inet_ntoa(sa.sin_addr));
+ this->llocaladdr=inet_addr(this->localaddr);
+
+ packetReader->setSocket(socket);
+
+ ResetEvent(hConnectionClose);
+
+ startThreads();
+ //packetReader->startListening();
+
+
+ socket->send("UA01");
+ XDEBUG(("Sent UA01\n"));
+ ClientInformationPacket *infoPacket = new ClientInformationPacket();
+ this->send( infoPacket );
+ delete infoPacket;
+ XINFO(("sent ClientInformationPacket\n"));
+
+ ClientVersionPacket *versionPacket = new ClientVersionPacket();
+ versionPacket->setProtocolVersion( protocolVersion);
+ this->send( versionPacket );
+ delete versionPacket;
+
+ XINFO(("sent ClientVersionPacket\n"));
+ this->connected=TRUE;
+ } catch( SocketException ex ) {
+ XERROR(("Socket Exception ?! %s \n",ex.description().c_str() ));
+ this->connected=FALSE;
+ }
+ }
+ XFireGameResolver *Client::getGameResolver() {
+ return gameResolver;
+ }
+ void Client::startThreads() {
+ XINFO(("About to start thread\n"));
+#ifndef NO_PTHREAD
+ void* (*func)(void*) = &xfirelib::Client::startReadThread;
+ pthread_create( &readthread, NULL, func, (void*)this );
+ void* (*func2)(void*) = &xfirelib::Client::startSendPingThread;
+ pthread_create( &sendpingthread, NULL, func2, (void*)this );
+#else
+ //mir_create!!!!
+ mir_forkthread(xfirelib::Client::startReadThread,(LPVOID)this);
+ mir_forkthread(xfirelib::Client::startSendPingThread,(LPVOID)this);
+#endif
+ }
+#ifndef NO_PTHREAD
+ void *Client::startReadThread(void *ptr) {
+#else
+ void Client::startReadThread(LPVOID lParam) {
+ void* ptr=(void*)lParam;
+#endif
+ if(ptr==NULL||((Client*)ptr)->packetReader==NULL)
+#ifndef NO_PTHREAD
+ return NULL;
+#else
+ return;
+#endif
+ try {
+ ((Client*)ptr)->packetReader->run();
+ } catch (SocketException ex) {
+ XERROR(("Socket Exception ?! %s \n",ex.description().c_str() ));
+
+ //miranda bescheid geben, wir haben verbindung verloren
+ if(ptr==NULL||((Client*)ptr)->connected) SetStatus(ID_STATUS_OFFLINE,NULL);
+
+ //((Client*)ptr)->disconnect();
+ }
+#ifndef NO_PTHREAD
+ return NULL;
+#else
+ return;
+#endif
+ }
+
+#ifndef NO_PTHREAD
+ void *Client::startSendPingThread(void *ptr) {
+ Client *me = (Client*)ptr;
+#else
+ void Client::startSendPingThread(LPVOID lParam) {
+ Client *me = (Client*)lParam;
+#endif
+ SendKeepAlivePacket packet;
+
+ while(1) {
+#ifndef NO_PTHREAD
+ pthread_testcancel();
+#endif
+ //Sleep(60000); // Sleep for 40 sek
+ if(mySleep(60000,hConnectionClose))
+ {
+#ifndef NO_PTHREAD
+ return NULL;
+#else
+ return;
+#endif
+ }
+#ifndef NO_PTHREAD
+ pthread_testcancel();
+#endif
+ XDEBUG(( "Sending KeepAlivePacket\n" ));
+ if(!me->send( &packet )) {
+ XINFO(( "Could not send KeepAlivePacket... exiting thread.\n" ));
+ break;
+ }
+ }
+#ifndef NO_PTHREAD
+ return NULL;
+#else
+ return;
+#endif
+ }
+
+ void Client::disconnect() {
+ this->connected=FALSE;
+
+ //socket vom packetreader auf NULL, damit die readschleife geschlossen wird
+ if(this->packetReader!=NULL)
+ this->packetReader->setSocket(NULL);
+
+ XDEBUG( "cancelling readthread ... \n");
+#ifndef NO_PTHREAD
+ if(readthread.p!=NULL) pthread_cancel (readthread);
+ readthread.p=NULL;
+
+ XDEBUG( "cancelling sendpingthread ... \n");
+ if(sendpingthread.p!=NULL) pthread_cancel (sendpingthread);
+ sendpingthread.p=NULL;
+#endif
+
+ XDEBUG( "deleting socket ...\n" );
+ if(socket){
+ delete socket;
+ socket = NULL;
+ }
+ XDEBUG(( "done\n" ));
+ }
+
+ bool Client::send( XFirePacketContent *content ) {
+ if(!socket) {
+ XERROR(( "Trying to send content packet altough socket is NULL ! (ignored)\n" ));
+ return false;
+ }
+ XFirePacket *packet = new XFirePacket(content);
+ packet->sendPacket( socket );
+ delete packet;
+ return true;
+ }
+
+ void Client::addPacketListener( PacketListener *listener ) {
+ packetReader->addPacketListener( listener );
+ }
+
+
+ void Client::receivedPacket( XFirePacket *packet ) {
+ XDEBUG(("Client::receivedPacket\n"));
+ if( packet == NULL ) {
+ XERROR(("packet is NULL !!!\n"));
+ return;
+ }
+ if( packet->getContent() == NULL ) {
+ XERROR(("ERRRR getContent() returns null ?!\n"));
+ return;
+ }
+ XFirePacketContent *content = packet->getContent();
+
+ switch( content->getPacketId() ) {
+ case XFIRE_PACKET_AUTH_ID: {
+ XINFO(("Got Auth Packet .. Sending Login\n"));
+ AuthPacket *authPacket = (AuthPacket*)packet->getContent();
+
+ ClientLoginPacket *login = new ClientLoginPacket();
+ login->setSalt( authPacket->getSalt() );
+ login->setUsername( *username );
+ login->setPassword( *password );
+ send( login );
+ delete login;
+ break;
+ }
+
+ case XFIRE_MESSAGE_ID: {
+ XDEBUG(( "Got Message, sending ACK\n" ));
+ MessagePacket *message = (MessagePacket*)packet->getContent();
+ if(message->getMessageType() == 0){
+ MessageACKPacket *ack = new MessageACKPacket();
+ memcpy(ack->sid,message->getSid(),16);
+ ack->imindex = message->getImIndex();
+ send( ack );
+ delete ack;
+ }else if(message->getMessageType() == 2){
+ send(message);
+ }
+ break;
+ }
+
+ default:
+ //cout << "Nothing here ... " << endl;
+ break;
+ }
+
+ }
+};