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

« back to all changes in this revision

Viewing changes to src/network/tomconnection.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
 *   Copyright (C) 2009 by The qGo Project                                 *
 
3
 *                                                                         *
 
4
 *   This file is part of qGo.                                             *
 
5
 *                                                                         *
 
6
 *   qGo is free software: you can redistribute it and/or modify           *
 
7
 *   it under the terms of the GNU General Public License as published by  *
 
8
 *   the Free Software Foundation; either version 2 of the License, or     *
 
9
 *   (at your option) any later version.                                   *
 
10
 *                                                                         *
 
11
 *   This program is distributed in the hope that it will be useful,       *
 
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
14
 *   GNU General Public License for more details.                          *
 
15
 *                                                                         *
 
16
 *   You should have received a copy of the GNU General Public License     *
 
17
 *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
 
18
 *   or write to the Free Software Foundation, Inc.,                       *
 
19
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 
20
 ***************************************************************************/
 
21
 
 
22
 
 
23
#include "tomconnection.h"
 
24
#include "room.h"
 
25
#include "playergamelistings.h"
 
26
#include "gamedata.h"
 
27
#include "serverlistdialog.h"
 
28
#include "serverliststorage.h"
 
29
#include "codecwarndialog.h"
 
30
/* Note that Tom either has additional checks on this or simply that one cannot play against
 
31
 * the same username meaning that sendMatchOffers may not be received. */
 
32
 
 
33
 
 
34
TomConnection::TomConnection(const QString & user, const QString & pass)
 
35
: TygemConnection(user, pass, TypeTOM)
 
36
{
 
37
        serverCodec = QTextCodec::codecForName(getCodecString());
 
38
        if(!serverCodec)
 
39
        {
 
40
                new CodecWarnDialog(getCodecString());
 
41
                serverCodec = QTextCodec::codecForLocale();
 
42
        }
 
43
        if(!getServerListStorage().restoreServerList(TypeTOM, serverList))
 
44
                        requestServerInfo();
 
45
        else
 
46
        {
 
47
                if(reconnectToServer() < 0)
 
48
                {
 
49
                        qDebug("User canceled");
 
50
                        connectionState = CANCELED;
 
51
                        return;
 
52
                }
 
53
        }
 
54
}
 
55
 
 
56
const char * TomConnection::getCodecString(void)
 
57
{
 
58
        return "GB2312";
 
59
}
 
60
 
 
61
QString TomConnection::getPlaceString(void)
 
62
{
 
63
        return "Tom: " + serverList[current_server_index]->name;
 
64
}
 
65
 
 
66
int TomConnection::requestServerInfo(void)
 
67
{
 
68
        qDebug("Requesting Tom Server Info");
 
69
        if(!openConnection("61.135.158.147", 80, NOT_MAIN_CONNECTION))
 
70
        {
 
71
                qDebug("Can't get server info");
 
72
                return -1;
 
73
        }
 
74
        unsigned int length = 0x94;
 
75
        unsigned char * packet = new unsigned char[length];  //term 0x00
 
76
        snprintf((char *)packet, length,
 
77
                 "GET /service/files/livebaduk3.cfg HTTP/1.1\r\n" \
 
78
                 "User-Agent: Tygem HTTP\r\n" \
 
79
                 "Host: duiyi.sports.tom.com\r\n" \
 
80
                 "Connection: Keep-Alive\r\n" \
 
81
                 "Cache-Control: no-cache\r\n\r\n");
 
82
#ifdef RE_DEBUG
 
83
        for(int i = 0; i < length; i++)
 
84
                printf("%02x", packet[i]);
 
85
        printf("\n");
 
86
#endif //RE_DEBUG
 
87
        if(write((const char *)packet, length) < 0)
 
88
        {
 
89
                qWarning("*** failed sending server info request");
 
90
                return -1;
 
91
        }
 
92
        delete[] packet;
 
93
        
 
94
        connectionState = INFO;
 
95
        return 0;
 
96
}
 
97
 
 
98
/* We need to write a tygem parser that doesn't need to be different for tom FIXME */
 
99
void TomConnection::handleServerInfo(unsigned char * msg, unsigned int length)
 
100
{
 
101
        char * p = (char *)msg;
 
102
        int i, j;
 
103
        ServerItem * si;
 
104
 
 
105
#ifdef RE_DEBUG
 
106
        for(i = 0; i < length; i++)
 
107
                printf("%c", p[i]);
 
108
        printf("\n");
 
109
#endif //RE_DEBUG
 
110
        
 
111
        while(p < ((char *)msg + length))
 
112
        {
 
113
                while(p < ((char *)msg + length - 1) && p[0] != '\n')
 
114
                        p++;
 
115
                p++;
 
116
                //FIXME, check for size
 
117
                if(strncmp(p, "/LIVE ", 6) == 0)
 
118
                {
 
119
                        //same as for /SERVER but with only 2 [], name and ip
 
120
                }
 
121
                else if(strncmp(p, "/LECTURE ", 9) == 0)
 
122
                {
 
123
                        //same as for /SERVER but with only 2 [], name and ip
 
124
                }
 
125
                else if(strncmp(p, "/SERVER ", 8) == 0 ||
 
126
                        strncmp(p, "/_SERVER ", 9) == 0)        //whats the "_" FIXME
 
127
                {
 
128
                        //TOM has only 2 [], name and ip
 
129
                        if(p[1] == '_')
 
130
                                p++;
 
131
                        p += 8;
 
132
                        unsigned char ipaddr[16];
 
133
                        unsigned char name[20];
 
134
                        i = 0;
 
135
                        while(i < 2 && p < ((char *)msg + length))
 
136
                        {
 
137
                                if(*p != '[')
 
138
                                {
 
139
                                        qDebug("Server info parse error");
 
140
                                        closeConnection();
 
141
                                        return;
 
142
                                }
 
143
                                p++;
 
144
                                si = new ServerItem();
 
145
                                unsigned char * dest;
 
146
                                if(i == 1)
 
147
                                        dest = ipaddr;
 
148
                                else if(i == 0)
 
149
                                        dest = name;
 
150
                                j = 0;
 
151
                                while(*p != ']' && p < ((char *)msg + length))
 
152
                                {
 
153
                                        if((i == 1 && j < 15) || (i == 0 && j < 19))
 
154
                                                dest[j++] = *p;
 
155
                                        p++;
 
156
                                }
 
157
                                if(i == 0 || i == 1)
 
158
                                {
 
159
                                        dest[j++] = 0x00;
 
160
                                }
 
161
                                p += 2;
 
162
                                if(i == 1)
 
163
                                {
 
164
                                        strncpy(si->ipaddress, (const char *)ipaddr, 16);
 
165
                                        si->name =  serverCodec->toUnicode((char *)name, strlen((char *)name));
 
166
                                        qDebug("Server: %s", ipaddr);
 
167
                                        serverList.push_back(si);
 
168
                                }
 
169
                                i++;
 
170
                                if(i == 7)
 
171
                                        p--;    //no space
 
172
                        }
 
173
                }
 
174
                else if(strncmp(p, "/ENCRYPT ", 9) == 0)
 
175
                {
 
176
                        //FIXME
 
177
                        //[encode] [on] 
 
178
                }
 
179
        }
 
180
        /* We close here because this first time, its going to close
 
181
        * anyway, and if we don't close here, we'll get an error
 
182
        * and lose the object */
 
183
        connectionState = RECONNECTING;
 
184
        closeConnection(false);
 
185
        
 
186
        if(reconnectToServer() < 0)
 
187
        {
 
188
                qDebug("User canceled");
 
189
                closeConnection(false);
 
190
                connectionState = CANCELED;
 
191
                //if(dispatch)
 
192
                //      dispatch->onError();    //not great... FIXME
 
193
                return;
 
194
        }
 
195
        //sendLogin();
 
196
}
 
197
 
 
198
QByteArray TomConnection::getTygemGameRecordQByteArray(GameData * game)
 
199
{
 
200
        Room * room = getDefaultRoom();
 
201
        const PlayerListing * black, * white;
 
202
        int black_ordinal, white_ordinal;
 
203
        char black_qualifier, white_qualifier;
 
204
        QByteArray white_qualifier_string, black_qualifier_string;
 
205
        unsigned char black_level, white_level;
 
206
        unsigned short year;
 
207
        unsigned char month, day, hour, minute, second;
 
208
        secondsToDate(year, month, day, hour, minute, second);
 
209
        
 
210
        int margin = 0;
 
211
        
 
212
        black = room->getPlayerListing(game->black_name); 
 
213
        if(!black)
 
214
        {
 
215
                qDebug("Can't get player listing for black: \"%s\"", game->black_name.toLatin1().constData());
 
216
                return QByteArray();
 
217
        }
 
218
        white = room->getPlayerListing(game->white_name); 
 
219
        if(!white)
 
220
        {
 
221
                qDebug("Can't get player listing for white: \"%s\"", game->white_name.toLatin1().constData());
 
222
                return QByteArray();
 
223
        }
 
224
        sscanf(black->rank.toLatin1().constData(), "%d%c", &black_ordinal, &black_qualifier);
 
225
        if(black_qualifier == 'k')
 
226
        {
 
227
                black_level = 0x12 - black_ordinal;
 
228
                black_qualifier_string.append("\xbc\xb6");
 
229
        }
 
230
        else if(black_qualifier == 'p')
 
231
                black_level = black_ordinal + 0x1a;
 
232
        else
 
233
        {
 
234
                black_level = black_ordinal + 0x11;
 
235
                //double check that this isn't the pro tag?
 
236
                black_qualifier_string.append("\xb6\xce");
 
237
        }
 
238
        sscanf(white->rank.toLatin1().constData(), "%d%c", &white_ordinal, &white_qualifier);
 
239
        if(white_qualifier == 'k')
 
240
        {
 
241
                white_level = 0x12 - white_ordinal;
 
242
                white_qualifier_string.append("\xbc\xb6");
 
243
        }
 
244
        else if(white_qualifier == 'p')
 
245
                white_level = white_ordinal + 0x1a;
 
246
        else
 
247
        {
 
248
                white_level = white_ordinal + 0x11;
 
249
                white_qualifier_string.append("\xb6\xce");
 
250
        }
 
251
        
 
252
        QByteArray string;
 
253
        /* GIBOKIND and GAMELECNAME and maybe some others are missing
 
254
         * from Tom record, so there's a question of whether that's only
 
255
         * in the 0672s and is left out of the records or whether that's
 
256
         * just not part of Tom.  I do get the feeling that, except for
 
257
         * a few particular entries, we can be pretty easy going with
 
258
         * this */
 
259
        //string += "\\[GIBOKIND=China\\]\r\n"; //I don't see this in file, necessary?
 
260
        string += "\\[TYPE=0\\]\r\n";
 
261
        string += "\\[GAMECONDITION=";
 
262
        string.append("\xc8\xce\xcf\xc8");
 
263
                                                        //c8c3cfc8 seems suffient for a finished
 
264
                                                        //game
 
265
                                                        //I think cbc0bbee313ab7d6 is possibly
 
266
                                                        //some unfinished game or something
 
267
        string += "\\]\r\n";
 
268
        string += "\\[GAMETIME=";
 
269
        string += "\\]\r\n";
 
270
        string += "\\[GAMERESULT=";     //3f3332353f3f  //w + 325 margin ONLY, no color
 
271
                                                //badac6e5cab1bce4caa4 B + T
 
272
                                                //b0d7c6e5d6d0c5cccaa4 W + R
 
273
                                                //bada38d4d6332f34d7d3caa4   B + margin?
 
274
        switch(game->fullresult->result)
 
275
        {
 
276
                case GameResult::DRAW:
 
277
                        //string += QString(0xb9ab) + QString(0xbdc2) + QString(0xbace);
 
278
                        break;
 
279
                case GameResult::FORFEIT:
 
280
                        //c8e6 20 bdc3 b0a3 20 c3ca b0fa bdc2
 
281
                        
 
282
                        break;
 
283
                case GameResult::TIME:
 
284
                        break;
 
285
                case GameResult::RESIGN:
 
286
                        if(game->fullresult->winner_color == stoneWhite)
 
287
                        {
 
288
                                //string += QString(0xb9e9);
 
289
                        }
 
290
                        else
 
291
                        {
 
292
                                //string += QString(0xc8e6);
 
293
                        }
 
294
                        //string += " " + QString(0xbad2) + QString(0xb0e8) + QString(0xbdc2);
 
295
                        break;
 
296
                case GameResult::SCORE:
 
297
                        {
 
298
                        float fmargin = game->fullresult->winner_score = game->fullresult->loser_score;
 
299
                        margin = (int)fmargin;
 
300
                        if(fmargin > (float)margin)
 
301
                                margin = (margin * 10) + 5;
 
302
                        else
 
303
                                margin *= 10;
 
304
                        qDebug("FIXME margin: %d\n", margin);
 
305
                        string += QByteArray::number(margin);
 
306
                        //string += QString(0x3f) + " " + QByteArray::number(margin) +
 
307
                        //              QString(0x3f3f) + " " + QString(0x3f);
 
308
                        }
 
309
                        break;
 
310
                default:
 
311
                        break;
 
312
        }
 
313
        string += "\\]\r\n";
 
314
        string += "\\[GAMEZIPSU=" + QByteArray::number(margin) + "\\]\r\n";
 
315
        string += "\\[GAMEDUM=0\\]\r\n";
 
316
        string += "\\[GAMEGONGJE=0\\]\r\n";
 
317
        string += "\\[GAMETOTALNUM=";   //0xd7dc: 3335cafd" 35?
 
318
        string += " " + QByteArray::number(game->moves);
 
319
        string += "\\]\r\n";
 
320
        string += "\\[SZAUDIO=0\\]\r\n";
 
321
        string += "\\[GAMENAME=";
 
322
        string.append("\xd3\xd1\xd2\xea\xb6\xd4\xbe\xd6\\]\r\n");
 
323
                        //cdfd bdb5 bcb6 b6d4 bed6 5c5d   //a broadcast game I saw
 
324
        /* Be careful here also, no idea what this says, we should
 
325
         * probably leave it blank */
 
326
        string += "\\[GAMEDATE=" + QByteArray::number(year) + "-";
 
327
        string.append("\xc4\xea");
 
328
        string += QByteArray::number(month) +
 
329
        string.append("xd4\xc2");
 
330
        string += QByteArray::number(day);
 
331
        string.append("\xc8\xd5");
 
332
        string += "  "; /*+ QString(0xcfc2) +
 
333
                        QString(0xcee7) */
 
334
        string += " " + QByteArray::number(hour % 12) +
 
335
                        (minute < 10 ? ":0" : ":") + QByteArray::number(minute) + "\\]\r\n";
 
336
        /* Note that its very likely that one of the above strings contains a PM versus
 
337
         * AM */
 
338
        const char tom_game_place_array[] = {0x54, 0x6f, 0x6d, 0xb6, 0xd4, 0xde, 0xc4};
 
339
        QByteArray tom_game_place(tom_game_place_array, 7);
 
340
        string += "\\[GAMEPLACE=" + tom_game_place + "\\]\r\n";
 
341
        string += "\\[GAMELECNAME=\\]\r\n";
 
342
        /* FIXME, note that this is very likely going to be different on the korean
 
343
         * server.  This is for eweiqi really */
 
344
        string += "\\[GAMEWHITENAME=" + serverCodec->fromUnicode(white->notnickname) + "("
 
345
                        + QByteArray::number(white_ordinal)
 
346
                                + white_qualifier_string + ")\\]\r\n";
 
347
        string += "\\[GAMEWHITELEVEL=" + QByteArray::number(white_level)
 
348
                                + white_qualifier_string + "\\]\r\n";
 
349
        string += "\\[GAMEWHITENICK=" + serverCodec->fromUnicode(white->name) + "\\]\r\n";
 
350
        string += "\\[GAMEWHITECOUNTRY=" + QByteArray::number(white->country_id) + "\\]\r\n";
 
351
        string += "\\[GAMEWAVATA=1\\]\r\n";
 
352
        string += "\\[GAMEWIMAGE=\\]\r\n";
 
353
        string += "\\[GAMEBLACKNAME=" + serverCodec->fromUnicode(black->notnickname) + "(" 
 
354
                        + QByteArray::number(black_ordinal)
 
355
                                + black_qualifier_string + ")\\]\r\n";
 
356
        string += "\\[GAMEBLACKLEVEL=" + QByteArray::number(black_level)
 
357
                                + black_qualifier_string + "\\]\r\n";
 
358
        string += "\\[GAMEBLACKNICK=" + serverCodec->fromUnicode(black->name) + "\\]\r\n";
 
359
        string += "\\[GAMEBLACKCOUNTRY=" + QByteArray::number(black->country_id) + "\\]\r\n";
 
360
        string += "\\[GAMEBAVATA=1\\]\r\n";
 
361
        string += "\\[GAMEBIMAGE=\\]\r\n";
 
362
        string += "\\[GAMECOMMENT=\\]\r\n";
 
363
        //country = 2 = gbkind = gibokind
 
364
        string += "\\[GAMEINFOMAIN=GBKIND:2,GTYPE:0,GCDT:1,GTIME:" +
 
365
                        QByteArray::number(game->maintime) + "-" +
 
366
                        QByteArray::number(game->periodtime) + "-" +
 
367
                        QByteArray::number(game->stones_periods) + ",GRLT:0";
 
368
        string += ",ZIPSU:" + QByteArray::number(margin) + 
 
369
                  ",DUM:0,GONGJE:0,TCNT:" +
 
370
                        QByteArray::number(game->moves);
 
371
        string += ",AUSZ:0\\]\r\n";
 
372
        string += "\\[GAMEINFOSUB=GNAMEF:0,GPLCF:0,GNAME:";
 
373
        string += "GDATE:" + QByteArray::number(year) + "- " + QByteArray::number(month)
 
374
                        + "- " + QByteArray::number(day) + "-" + QByteArray::number(hour)
 
375
                        + "-" + QByteArray::number(minute) + "-" + QByteArray::number(second);
 
376
        string += ",GPLC:";
 
377
        string += ",GCMT:\\]\r\n";
 
378
        string += "\\[WUSERINFO=WID:" + serverCodec->fromUnicode(white->notnickname) + ",WLV:" + QByteArray::number(white_level) + 
 
379
                        ",WNICK:" + serverCodec->fromUnicode(white->name) + ",WNCD:" + QByteArray::number(white->country_id) +
 
380
                                ",WAID:60001,WIMG:\\]\r\n";
 
381
        string += "\\[BUSERINFO=BID:" + serverCodec->fromUnicode(black->notnickname) + ",BLV:" + QByteArray::number(black_level) +
 
382
                        ",BNICK:" + serverCodec->fromUnicode(black->name) + ",BNCD:" + QByteArray::number(black->country_id) +
 
383
                                ",BAID:60001,BIMG:\\]\r\n";
 
384
        /* Here, I'm thinking S0 is black wins, S1 is white wins
 
385
         * then again, there's also W1 indicating white win with W0 as white loss */
 
386
        /* I've also seen W4 as indicating W + R */
 
387
        /* I've also seen S1 W7 as B + T also with Z0 indicating that's time remaining
 
388
         * or something */
 
389
        /* T is likely time settings, 30 seconds, 3 periods, 1200 total time maybe (20min)*/
 
390
        string += getTygemGameTagQByteArray(game, white_level, black_level, margin);
 
391
                                //tag is simple of earlier info
 
392
 
 
393
        return string;
 
394
}