~ubuntu-branches/ubuntu/vivid/qgo/vivid-proposed

« back to all changes in this revision

Viewing changes to src/igsconnection.cpp

  • Committer: Package Import Robot
  • Author(s): Yann Dirson
  • Date: 2012-05-19 19:05:05 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20120519190505-b23f5tzx7y8cu946
Tags: 2~svn764-1
* The "Raise dead" release (Closes: #673520), new maintainer.
* New upstream snapshot with Qt4 support (Closes: #604589), adjusted
  build-deps.
* Switched to source format "3.0 (quilt)", adjusted build-deps.
* Switched to dh and debhelper compat level 9, adjusted build-deps.
* Build with -fpermissive.
* New build-dep libasound2-dev, remove obsolete build-dep on libxinerama-dev.
* Refreshed patches 01_gnugo and 04_desktop, leaving 20_kfreebsd away
  for this release, and removing the remaining ones, now obsolete.
* Added patch 02_usrgames for FHS-correct install location.
* Adjusted icon names in menu file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 /* 
2
 
 * igsconnection.cpp
3
 
 *      
4
 
 * insprired by qigs
5
 
 *
6
 
 * authors: Peter Strempel & Tom Le Duc & Johannes Mesa
7
 
 *
8
 
 * this code is still in experimentational phase
9
 
 */
10
 
 
11
 
 
12
 
#include "igsconnection.h"
13
 
#include <qgbkcodec.h> 
14
 
#include <qtextcodec.h>
15
 
#include <qtimer.h>
16
 
 
17
 
IGSConnection::IGSConnection() : IGSInterface()
18
 
19
 
        authState = LOGIN;
20
 
 
21
 
        qsocket = new QSocket(this);
22
 
        CHECK_PTR(qsocket);
23
 
 
24
 
        textCodec = 0;
25
 
 
26
 
        username = "";
27
 
        password = "";
28
 
        
29
 
        connect(qsocket, SIGNAL(hostFound()), SLOT(OnHostFound()));
30
 
        connect(qsocket, SIGNAL(connected()), SLOT(OnConnected()));
31
 
        connect(qsocket, SIGNAL(readyRead()), SLOT(OnReadyRead()));
32
 
        connect(qsocket, SIGNAL(connectionClosed()), SLOT(OnConnectionClosed()));
33
 
        connect(qsocket, SIGNAL(delayedCloseFinished()), SLOT(OnDelayedCloseFinish()));
34
 
        connect(qsocket, SIGNAL(bytesWritten(int)), SLOT(OnBytesWritten(int)));
35
 
        connect(qsocket, SIGNAL(error(int)), SLOT(OnError(int)));
36
 
}
37
 
 
38
 
IGSConnection::~IGSConnection()
39
 
{
40
 
        delete qsocket;
41
 
}
42
 
 
43
 
// maybe callback should be callback(void)...,
44
 
// any data can be transferred after signalling with normal functions
45
 
void IGSConnection::sendTextToApp(QString txt)
46
 
{
47
 
        if (callbackFP != NULL)
48
 
                (*callbackFP)(txt);
49
 
}
50
 
 
51
 
// check for 'Login:' (and Password)
52
 
bool IGSConnection::checkPrompt()
53
 
{
54
 
        // prompt can be login prompt or usermode prompt
55
 
                
56
 
        if (bufferLineRest.length() < 4)
57
 
        {
58
 
                qDebug(QString("IGSConnection::checkPrompt called with string of size %1").arg(bufferLineRest.length()));
59
 
 
60
 
                if (authState == PASSWORD)
61
 
                {
62
 
                        int b = qsocket->bytesAvailable();
63
 
                        if (!b)
64
 
                        {
65
 
                                qsocket->waitForMore(500);
66
 
                                b = qsocket->bytesAvailable();
67
 
//                              if (!b)
68
 
//                                      return false;
69
 
                        }
70
 
 
71
 
                        while (b-- > 0)
72
 
                                bufferLineRest += qsocket->getch();
73
 
                }
74
 
                else
75
 
                        return false; 
76
 
        }
77
 
 
78
 
        switch (authState)
79
 
        {
80
 
                case LOGIN:
81
 
                        if (bufferLineRest.find("Login:") != -1)
82
 
                        {
83
 
                                qDebug("Login: found");
84
 
                                
85
 
                                // tell application what to send
86
 
                                sendTextToApp(bufferLineRest);
87
 
                                if (!username.isEmpty())
88
 
                                {
89
 
                                        sendTextToApp("...sending: {" + QString(username) + "}");
90
 
                                
91
 
                                        sendTextToHost(username, true);// + '\n');       // CAREFUL : THIS SOMETIMES CHANGES on IGS
92
 
                                }
93
 
 
94
 
                                // next state
95
 
                                if (password)
96
 
                                        authState = PASSWORD;
97
 
                                else
98
 
                                        authState = SESSION;
99
 
                                return true;
100
 
                        }
101
 
                        break;
102
 
 
103
 
                case PASSWORD:
104
 
                        if ((bufferLineRest.find("Password:") != -1) || (bufferLineRest.find("1 1") != -1))
105
 
                        {
106
 
                                qDebug("Password or 1 1: found , strlen = %d", bufferLineRest.length());
107
 
                                sendTextToApp(tr("...send password"));
108
 
                                sendTextToHost(password, true);
109
 
 
110
 
                                // next state
111
 
                                authState = SESSION;
112
 
                                return true;
113
 
                        }
114
 
                        else if (bufferLineRest.find("guest account") != -1)
115
 
                        {
116
 
                                authState = SESSION;
117
 
                                return true;
118
 
                        }
119
 
                        break;
120
 
 
121
 
                default:
122
 
                        break;
123
 
        }
124
 
        
125
 
        return false;
126
 
}
127
 
 
128
 
 
129
 
/*
130
 
 * Slots
131
 
 */
132
 
 
133
 
void IGSConnection::OnHostFound()
134
 
{
135
 
        qDebug("IGSConnection::OnHostFound()");
136
 
}
137
 
 
138
 
void IGSConnection::OnConnected()
139
 
{
140
 
        qDebug("IGSConnection::OnConnected()");
141
 
 
142
 
        sendTextToApp("Connected to " + qsocket->peerAddress().toString() + " " +
143
 
                  QString::number(qsocket->peerPort()));
144
 
}
145
 
// We got data to read
146
 
void IGSConnection::OnReadyRead()
147
 
{
148
 
//*
149
 
//      qDebug("OnReadyRead....");
150
 
        while (qsocket->canReadLine())
151
 
        {
152
 
                int size = qsocket->bytesAvailable() + 1;
153
 
                char *c = new char[size];
154
 
                int bytes = qsocket->readLine(c, size);
155
 
                QString x = textCodec->toUnicode(c);
156
 
                delete[] c;
157
 
                if (x.isEmpty())
158
 
                {
159
 
                        qDebug("READ:NULL");
160
 
                        return;
161
 
                }
162
 
 
163
 
                // some statistics
164
 
//              emit signal_setBytesIn(x.length());
165
 
 
166
 
                x.truncate(x.length()-2);
167
 
 
168
 
                sendTextToApp(x);
169
 
 
170
 
                if (authState == PASSWORD)
171
 
                {
172
 
                        bufferLineRest = x;
173
 
                        checkPrompt();
174
 
                        qDebug("PASSWORD***");
175
 
                }
176
 
        }
177
 
        
178
 
        if (authState == LOGIN && qsocket->bytesAvailable() == 7)
179
 
        {
180
 
                QString y;
181
 
                qDebug("looking for 'Login:'");
182
 
                while (qsocket->bytesAvailable())
183
 
                        y += qsocket->getch();
184
 
                
185
 
                if (y)
186
 
                {
187
 
                        qDebug("Collected: " + y);
188
 
                        bufferLineRest = y;
189
 
                        checkPrompt();
190
 
                }
191
 
        }
192
 
//*/
193
 
//      convertBlockToLines();
194
 
}
195
 
 
196
 
// Connection was closed from host
197
 
void IGSConnection::OnConnectionClosed() 
198
 
{
199
 
        qDebug("CONNECTION CLOSED BY FOREIGN HOST");
200
 
 
201
 
        // read last data that could be in the buffer
202
 
        OnReadyRead();
203
 
        authState = LOGIN;
204
 
        sendTextToApp("Connection closed by foreign host.\n");
205
 
}
206
 
 
207
 
// Connection was closed from application, but delayed
208
 
void IGSConnection::OnDelayedCloseFinish()
209
 
{
210
 
        qDebug("DELAY CLOSED FINISHED");
211
 
        
212
 
        authState = LOGIN;
213
 
        sendTextToApp("Connection closed.\n");
214
 
}
215
 
 
216
 
void IGSConnection::OnBytesWritten(int /*nbytes*/)
217
 
{
218
 
//      qDebug("%d BYTES WRITTEN", nbytes);
219
 
//      emit signal_setBytesOut(nbytes);
220
 
}
221
 
 
222
 
void IGSConnection::OnError(int i)
223
 
{
224
 
        switch (i)
225
 
        {
226
 
                case QSocket::ErrConnectionRefused: qDebug("ERROR: connection refused...");
227
 
                        break;
228
 
                case QSocket::ErrHostNotFound: qDebug("ERROR: host not found...");
229
 
                        break;
230
 
                case QSocket::ErrSocketRead: qDebug("ERROR: socket read...");
231
 
                        break;
232
 
                default: qDebug("ERROR: unknown Error...");
233
 
                        break;
234
 
        }
235
 
        sendTextToApp("ERROR - Connection closed.\n");
236
 
}
237
 
 
238
 
 
239
 
/*
240
 
 * Functions called from the application
241
 
 */
242
 
 
243
 
bool IGSConnection::isConnected()
244
 
{
245
 
//      qDebug("IGSConnection::isConnected()");
246
 
        return qsocket->state() == QSocket::Connection;
247
 
}
248
 
 
249
 
void IGSConnection::sendTextToHost(QString txt, bool ignoreCodec)
250
 
{
251
 
        /*
252
 
        *       This is intended because for weird reasons, if 'username' s given
253
 
        *       with a codec, IGS might reject it and ban the IP (!!!) for several hours.
254
 
        *       This seems to concern only windows users.
255
 
        *       Therefore, we pretend to ignore the codec when passing username or password
256
 
        */
257
 
 
258
 
        if (ignoreCodec)
259
 
        {
260
 
 
261
 
                int len;
262
 
                const char * txt2 = txt.latin1();
263
 
 
264
 
                if ((len = qsocket->writeBlock(txt2, strlen(txt2) * sizeof(char))) != -1)
265
 
                        qsocket->writeBlock("\r\n", 2);
266
 
                else
267
 
                        qWarning(QString("*** failed sending to host: %1").arg(txt2));
268
 
        }
269
 
 
270
 
        else 
271
 
        {
272
 
                QCString raw = textCodec->fromUnicode(txt);
273
 
 
274
 
                if (qsocket->writeBlock(raw.data(), raw.size() - 1) != -1)
275
 
                        qsocket->writeBlock("\r\n", 2);
276
 
                else
277
 
                        qWarning(QString("*** failed sending to host: %1").arg(txt));
278
 
        }
279
 
}
280
 
 
281
 
 
282
 
void IGSConnection::setTextCodec(QString codec)
283
 
{
284
 
        textCodec = QTextCodec::codecForName(codec);
285
 
        if(!textCodec)
286
 
                textCodec = QTextCodec::codecForLocale();
287
 
        CHECK_PTR(textCodec);
288
 
}
289
 
 
290
 
 
291
 
 
292
 
bool IGSConnection::openConnection(const char *host, unsigned int port, const char *user, const char *pass)
293
 
{
294
 
        if (qsocket->state() != QSocket::Idle ) {
295
 
                qDebug("Called IGSConnection::openConnection while in state %d", qsocket->state());
296
 
                return false;
297
 
        }
298
 
 
299
 
        //textCodec = QTextCodec::codecForName(codec);
300
 
        //if(!textCodec)
301
 
        //      textCodec = QTextCodec::codecForLocale();
302
 
        //CHECK_PTR(textCodec);
303
 
 
304
 
        username = user;
305
 
        password = pass;
306
 
        
307
 
        qDebug("Connecting to %s %d as [%s], [%s]...", host, port, username.latin1(), (password ? "***" : "NULL"));
308
 
        sendTextToApp(tr("Trying to connect to %1 %2").arg(host,port));
309
 
 
310
 
        ASSERT(host != 0);
311
 
        ASSERT(port != 0);
312
 
        int len = qstrlen(host);
313
 
        if ((len > 0) && (len < 200)) // otherwise host points to junk
314
 
                qsocket->connectToHost(host, (Q_UINT16) port);
315
 
        return qsocket->state() != QSocket::Idle;
316
 
}
317
 
 
318
 
bool IGSConnection::closeConnection()
319
 
{
320
 
        // We have no connection?
321
 
        if (qsocket->state() == QSocket::Idle)
322
 
                return false;
323
 
 
324
 
        qDebug("Disconnecting...");
325
 
 
326
 
        // Close it.
327
 
        qsocket->close();
328
 
 
329
 
        // Closing succeeded, return message
330
 
        if (qsocket->state() == QSocket::Idle)
331
 
        {
332
 
                authState = LOGIN;
333
 
                sendTextToApp("Connection closed.\n");
334
 
        }
335
 
 
336
 
        // Not yet closed? Data will be written and then slot OnDelayClosedFinish() called
337
 
        return true;
338
 
}
339
 
 
340
 
const char* IGSConnection::getUsername ()
341
 
{
342
 
        return (const char*) username;
343
 
}