~ubuntu-branches/ubuntu/maverick/qgo/maverick

« back to all changes in this revision

Viewing changes to src/parser.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Martin A. Godisch
  • Date: 2005-01-01 23:07:10 UTC
  • Revision ID: james.westby@ubuntu.com-20050101230710-fhng6yidm47xlb2i
Tags: upstream-1.0.0-r2
Import upstream version 1.0.0-r2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *   parser.cpp
 
3
 */
 
4
 
 
5
#include "parser.h"
 
6
#include "qgo_interface.h"
 
7
#include <qregexp.h>
 
8
 
 
9
 
 
10
// Parsing of Go Server messages
 
11
Parser::Parser() : QObject(), Misc<QString>()
 
12
{
 
13
        // generate buffers
 
14
        aPlayer = new Player;
 
15
        statsPlayer = new Player;
 
16
        aGame = new Game;
 
17
        aGameInfo = new GameInfo;
 
18
        memory = 0;
 
19
        memory_str = QString();
 
20
        myname = QString();
 
21
 
 
22
        // init
 
23
        gsName = GS_UNKNOWN;
 
24
//      cmd = NONE;
 
25
}
 
26
 
 
27
Parser::~Parser()
 
28
{
 
29
        delete aGameInfo;
 
30
        delete aGame;
 
31
        delete aPlayer;
 
32
}
 
33
 
 
34
 
 
35
// put a line from host to parser
 
36
// if info is recognized, a signal is sent, and, however,
 
37
// the return type indicates the type of information
 
38
 
 
39
InfoType Parser::put_line(const QString &txt)
 
40
{
 
41
        
 
42
        QString line = txt.stripWhiteSpace();
 
43
        int pos;
 
44
 
 
45
        if (line.length() == 0)
 
46
        {
 
47
                // skip empty lines but write message if
 
48
                // a) not logged in
 
49
                // b) help files
 
50
                if (gsName == GS_UNKNOWN || memory_str && memory_str.contains("File"))
 
51
                {
 
52
                        emit signal_message(txt);
 
53
                        return MESSAGE;
 
54
                }
 
55
 
 
56
                // white space only
 
57
                return WS;
 
58
        }
 
59
 
 
60
        // skip console commands
 
61
        if (line.find(CONSOLECMDPREFIX,0) != -1)
 
62
                return NONE;
 
63
 
 
64
        // check for connection status
 
65
        if (line.find("Connection closed",0,false) != -1)
 
66
        {
 
67
                emit signal_connclosed();
 
68
                emit signal_message(txt);
 
69
                gsName = GS_UNKNOWN;
 
70
                return IT_OTHER;
 
71
        }
 
72
 
 
73
        //
 
74
        // LOGON MODE ----------------------
 
75
        //
 
76
        // try to find out server and set mode
 
77
        if (gsName == GS_UNKNOWN)
 
78
        {
 
79
                if (line.find("IGS entry on",0) != -1)
 
80
                {
 
81
                        gsName = IGS;
 
82
                        emit signal_svname(gsName);
 
83
                        return SERVERNAME;
 
84
                }
 
85
 
 
86
                if (line.find("LGS #",0) != -1)
 
87
                {
 
88
                        gsName = LGS;
 
89
                        emit signal_svname(gsName);
 
90
                        return SERVERNAME;
 
91
                }
 
92
 
 
93
                if (line.find("NNGS #",0) != -1)
 
94
                {
 
95
                        gsName = NNGS;
 
96
                        emit signal_svname(gsName);
 
97
                        return SERVERNAME;
 
98
                }
 
99
 
 
100
                // suggested by Rod Assard for playing with NNGS version 1.1.14
 
101
                if (line.find("Server (NNGS)",0) != -1)
 
102
                {
 
103
                        gsName = NNGS;
 
104
                        emit signal_svname(gsName);
 
105
                        return SERVERNAME;
 
106
                }
 
107
 
 
108
                if (line.find("WING #",0) != -1)
 
109
                {
 
110
                        gsName = WING;
 
111
                        emit signal_svname(gsName);
 
112
                        return SERVERNAME;
 
113
                }
 
114
 
 
115
                if (line.find("CTN #",0) != -1)
 
116
                {
 
117
                        gsName = CTN;
 
118
                        emit signal_svname(gsName);
 
119
                        return SERVERNAME;
 
120
                }
 
121
 
 
122
                // adapted from NNGS, chinese characters
 
123
                if (line.find("CWS #",0) != -1 || line.find("==CWS",0) != -1)
 
124
                {
 
125
                        gsName = CWS;
 
126
                        emit signal_svname(gsName);
 
127
                        return SERVERNAME;
 
128
                }
 
129
 
 
130
                // critical: TO BE WATCHED....
 
131
                if (line.find("#>",0) != -1)
 
132
                {
 
133
                        gsName = DEFAULT;
 
134
                        emit signal_svname(gsName);
 
135
                        return SERVERNAME;
 
136
                }
 
137
 
 
138
                // account name
 
139
                if (line.find("Your account name is",0) != -1)
 
140
                {
 
141
                        buffer = line.right(line.length() - 21);
 
142
                        buffer.replace(QRegExp("[\".]"), "");
 
143
                        emit signal_accname(buffer);
 
144
                        return ACCOUNT;
 
145
                }
 
146
 
 
147
                // account name as sent from telnet.cpp
 
148
                if (line.find("...sending:") != -1)
 
149
                {
 
150
                        if ((buffer = element(line, 0, "{", "}")) == NULL)
 
151
                                return IT_OTHER;
 
152
                        emit signal_accname(buffer);
 
153
                        return ACCOUNT;
 
154
                }
 
155
 
 
156
                if ((line.find("guest account",0) != -1) || line.contains("logged in as a guest"))
 
157
                {
 
158
                        emit signal_status(GUEST);
 
159
                        return STATUS;
 
160
                }
 
161
 
 
162
                if (line.at(0) != '9' && !memory)
 
163
                {
 
164
                        emit signal_message(txt);
 
165
                        return MESSAGE;
 
166
                }
 
167
        }
 
168
 
 
169
        //
 
170
        // LOGON HAS DONE, now parse: ----------------------
 
171
        //
 
172
        // get command type:
 
173
        bool ok;
 
174
        int cmd_nr = element(line, 0, " ").toInt(&ok);
 
175
        if (!ok && memory_str && memory_str.contains("CHANNEL"))
 
176
        {
 
177
                // special case: channel info
 
178
                cmd_nr = 9;
 
179
        }
 
180
        else if (!ok || memory_str && memory_str.contains("File") && !line.contains("File"))
 
181
        {
 
182
                // memory_str == "File": This is a help message!
 
183
                // skip action if entering client mode
 
184
                if (line.find("Set client to be True", 0, false) != -1)
 
185
                        return IT_OTHER;
 
186
 
 
187
                if (memory == 14)
 
188
                        // you have message
 
189
                        emit signal_shout(tr("msg*"), line);
 
190
                else
 
191
                        emit signal_message(txt);
 
192
 
 
193
                if (line.find("#>") != -1 && memory_str && !memory_str.contains("File"))
 
194
                        return NOCLIENTMODE;
 
195
 
 
196
                return MESSAGE;
 
197
        }
 
198
        else
 
199
        {
 
200
                // remove command number
 
201
                line = line.remove(0, 2).stripWhiteSpace();
 
202
        }
 
203
 
 
204
        // correct cmd_nr for special case; if quiet is set to false a game may not end...
 
205
        if (cmd_nr == 9 && line.contains("{Game"))
 
206
        {
 
207
                qDebug("command changed: 9 -> 21 !!!");
 
208
                cmd_nr = 21;
 
209
        }
 
210
 
 
211
        // case 42 is equal to 7
 
212
        if (cmd_nr == 42 && gsName != IGS)
 
213
        {
 
214
                // treat as game info
 
215
                cmd_nr = 7;
 
216
                qDebug("command changed: 42 -> 7 !!!");
 
217
        }
 
218
 
 
219
        // process for different servers has particular solutions
 
220
        // command mode -> expect result
 
221
        switch (cmd_nr)
 
222
        {
 
223
                // PROMPT
 
224
                case 1:
 
225
                        if (memory_str && (memory_str.contains("File")||memory_str.contains("STATS")))
 
226
                                // if ready this cannont be a help message
 
227
                                memory_str = QString();
 
228
      emit signal_message("\n");  
 
229
                        return READY;
 
230
                        break;
 
231
 
 
232
                // BEEP
 
233
                case 2:
 
234
                        if (line.contains("Game saved"))
 
235
                        {
 
236
                                return IT_OTHER;
 
237
                        }
 
238
                        return BEEP;
 
239
                        break;
 
240
 
 
241
                // ERROR message
 
242
                //      5 Player "xxxx" is not open to match requests.
 
243
                //      5 You cannot observe a game that you are playing.
 
244
                case 5:
 
245
                        if (line.contains("No user named"))
 
246
                        {
 
247
                                QString name = element(line, 1, "\"");
 
248
                                emit signal_talk(name, "@@@", true);
 
249
                        }
 
250
                        else if (line.contains("is not open to match requests"))
 
251
                        {
 
252
                                QString opp = element(line, 0, "\"", "\"");
 
253
                                emit signal_notopen(opp);
 
254
                        }
 
255
                        else if (line.contains("player is currently not accepting matches"))
 
256
                        {
 
257
                                // IGS: 5 That player is currently not accepting matches.
 
258
                                emit signal_notopen(0);
 
259
                        }
 
260
 
 
261
                        emit signal_message(line);
 
262
 
 
263
                        return MESSAGE;
 
264
                        break;
 
265
                        
 
266
                // games
 
267
                // 7 [##] white name [ rk ] black name [ rk ] (Move size H Komi BY FR) (###)
 
268
                // 7 [41]      xxxx10 [ 1k*] vs.      xxxx12 [ 1k*] (295   19  0  5.5 12  I) (  1)
 
269
                // 7 [118]      larske [ 7k*] vs.      T08811 [ 7k*] (208   19  0  5.5 10  I) (  0)
 
270
                // 7 [255]          YK [ 7d*] vs.         SOJ [ 7d*] ( 56   19  0  5.5  4  I) ( 18)
 
271
                // 7 [42]    TetsuyaK [ 1k*] vs.       ezawa [ 1k*] ( 46   19  0  5.5  8  I) (  0)
 
272
                // 7 [237]       s2884 [ 3d*] vs.         csc [ 2d*] (123   19  0  0.5  6  I) (  0)
 
273
                // 7 [67]    atsukann [14k*] vs.    mitsuo45 [15k*] ( 99   19  0  0.5 10  I) (  0)
 
274
                // 7 [261]      lbeach [ 3k*] vs.    yurisuke [ 3k*] (194   19  0  5.5  3  I) (  0)
 
275
                // 7 [29]      ppmmuu [ 1k*] vs.       Natta [ 2k*] (141   19  0  0.5  2  I) (  0)
 
276
                // 7 [105]      Clarky [ 2k*] vs.       gaosg [ 2k*] ( 65   19  0  5.5 10  I) (  1)
 
277
                case 7:
 
278
                        if (line.contains("##"))
 
279
                                // skip first line
 
280
                                return GAME7_START;
 
281
/*                      
 
282
                        if (!line.contains('['))
 
283
                        {
 
284
                                // no GAMES result -> leave GAMES mode
 
285
                                return IT_OTHER;
 
286
                        }
 
287
*/
 
288
                        // get info line
 
289
                        buffer = element(line, 0, "(", ")");
 
290
                        aGame->mv = buffer.left(3);
 
291
                        buffer.remove(0, 4);
 
292
                        aGame->Sz = element(buffer, 0, " ");
 
293
                        aGame->H = element(buffer, 1, " ");
 
294
                        aGame->K = element(buffer, 2, " ");
 
295
                        aGame->By = element(buffer, 3, " ");
 
296
                        aGame->FR = element(buffer, 4, " ");
 
297
                        
 
298
                        // parameter "true" -> kill blanks
 
299
                        aGame->nr = element(line, 0, "[", "]", true);
 
300
                        aGame->wname = element(line, 0, "]", "[", true);
 
301
                        aGame->wrank = element(line, 1, "[", "]", true);
 
302
                        // skip 'vs.'
 
303
                        buffer = element(line, 1, "]", "[", true);
 
304
                        aGame->bname = buffer.remove(0, 3);
 
305
                        aGame->brank = element(line, 2, "[", "]", true);
 
306
                        aGame->ob = element(line, 1, "(", ")", true);
 
307
 
 
308
                        // indicate game to be running
 
309
                        aGame->running = true;
 
310
                        aGame->oneColorGo = false ;
 
311
 
 
312
                        emit signal_game(aGame);
 
313
                        emit signal_move(aGame);
 
314
                        
 
315
                        return GAME7;
 
316
                        break;
 
317
 
 
318
                // "8 File"
 
319
                case 8:
 
320
                        if (memory_str && memory_str.contains("File"))
 
321
                        {
 
322
                                // toggle
 
323
                                memory_str = QString();
 
324
                                memory = 0;
 
325
                        }
 
326
                        else if (memory != 0 && memory_str && memory_str == "CHANNEL")
 
327
                        {
 
328
                                emit signal_channelinfo(memory, line);
 
329
                                memory_str = QString();
 
330
                                return IT_OTHER;
 
331
                        }
 
332
 
 
333
                        else if (line.contains("File"))
 
334
                        {
 
335
                                // the following lines are help messages
 
336
                                memory_str = line;
 
337
                                // check if NNGS message cmd is active -> see '9 Messages:'
 
338
                                if (memory != 14)
 
339
                                        memory = 8;
 
340
                        }
 
341
                        return HELP;
 
342
                        break;
 
343
 
 
344
                // INFO: stats, channelinfo
 
345
                // NNGS, LGS: (NNGS new: 2nd line w/o number!)
 
346
                //      9 Channel 20 Topic: [xxx] don't pay your NIC bill and only get two players connected
 
347
                //      9  xxxx1 xxxx2 xxxx3 xxxx4 frosla
 
348
                //      9 Channel 49 Topic: Der deutsche Kanal (German)
 
349
                //      9  frosla
 
350
                //
 
351
                //      -->  channel 49
 
352
                //      9 Channel 49 turned on.
 
353
                //      9 Channel 49 Title:
 
354
                //
 
355
                //      9 guest has left channel 49.
 
356
                //
 
357
                //      9 Komi set to -3.5 in match 10
 
358
                // - in my game:
 
359
                // -   opponent:
 
360
                //      9 Komi is now set to -3.5
 
361
                // -   me:
 
362
                //      9 Set the komi to -3.5
 
363
                // NNGS, LGS:
 
364
                //      9 I suggest that ditto play White against made:
 
365
                //      9 For 19x19:  Play an even game and set komi to 1.5.
 
366
                //      9 For 13x13:  Play an even game and set komi to 6.5.
 
367
                //      9 For   9x9:  Play an even game and set komi to 4.5.
 
368
                // or:
 
369
                //      9 I suggest that pem play Black against eek:
 
370
                //      For 19x19:  Take 3 handicap stones and set komi to -2.5.
 
371
                //      For 13x13:  Take 1 handicap stones and set komi to -6.5.
 
372
                //      For   9x9:  Take 1 handicap stones and set komi to 0.5.
 
373
                // or:
 
374
                //         I suggest that you play White against Cut:
 
375
                //
 
376
                //      9 Match [19x19] in 1 minutes requested with xxxx as White.
 
377
                //      9 Use <match xxxx B 19 1 10> or <decline xxxx> to respond.
 
378
                //
 
379
                //      9 Match [5] with guest17 in 1 accepted.
 
380
                //      9 Creating match [5] with guest17.
 
381
                //
 
382
                //      9 Requesting match in 10 min with frosla as Black.
 
383
                //      9 guest17 declines your request for a match.
 
384
                //      9 frosla withdraws the match offer.
 
385
                //
 
386
                //      9 You can check your score with the score command
 
387
                //      9 You can check your score with the score command, type 'done' when finished.
 
388
                //      9 Removing @ K8
 
389
                //
 
390
                //      9 Use adjourn to adjourn the game.
 
391
                //
 
392
                // NNGS: cmd 'user' NOT PARSED!
 
393
                //      9  Info     Name       Rank  19  9  Idle Rank Info
 
394
                //      9  -------- ---------- ---- --- --- ---- ---------------------------------
 
395
                //      9  Q  --  5 hhhsss      2k*   0   0  1s  NR                                    
 
396
                //      9     --  5 saturn      2k    0   0 18s  2k                                    
 
397
                //      9     --  6 change1     1k*   0   0  7s  NR                                    
 
398
                //      9 S   -- -- mikke       1d    0  18 30s  shodan in sweden                      
 
399
                //      9   X -- -- ksonney     NR    0   0 56s  NR                                    
 
400
                //      9     -- -- kou         6k*   0   0 23s  NR                                    
 
401
                //      9 SQ! -- -- GnuGo      11k*   0   0  5m  Estimation based on NNGS rating early 
 
402
                //      9   X -- -- Maurice     3k*   0   0 24s  2d at Hamilton Go Club, Canada; 3d in 
 
403
 
 
404
                case 9:
 
405
                        // status messages
 
406
                        if (line.contains("Set open to be"))
 
407
                        {
 
408
                                bool val = (line.find("False") == -1);
 
409
                                emit signal_checkbox(0, val);
 
410
                        }
 
411
                        else if (line.contains("Setting you open for matches"))
 
412
                                emit signal_checkbox(0, true);
 
413
                        else if (line.contains("Set looking to be"))
 
414
                        {
 
415
                                bool val = (line.find("False") == -1);
 
416
                                emit signal_checkbox(1, val);
 
417
                        }
 
418
                        // 9 Set quiet to be False.
 
419
                        else if (line.contains("Set quiet to be"))
 
420
                        {
 
421
                                bool val = (line.find("False") == -1);
 
422
                                emit signal_checkbox(2, val);
 
423
                        }
 
424
                        else if (line.find("Channel") == 0) 
 
425
                        {
 
426
                                // channel messages
 
427
                                QString e1 = element(line, 1, " ");
 
428
                                if (e1.at(e1.length()-1) == ':')
 
429
                                        e1.truncate(e1.length()-1);
 
430
                                int nr = e1.toInt();
 
431
 
 
432
                                if (line.contains("turned on."))
 
433
                                {
 
434
                                        // turn on channel
 
435
                                        emit signal_channelinfo(nr, QString("*on*"));
 
436
                                }
 
437
                                else if (line.contains("turned off."))
 
438
                                {
 
439
                                        // turn off channel
 
440
                                        emit signal_channelinfo(nr, QString("*off*"));
 
441
                                }
 
442
                                else if (!line.contains("Title:") || gsName == GS_UNKNOWN)
 
443
                                {
 
444
                                        // keep in memory to parse next line correct
 
445
                                        memory = nr;
 
446
                                        emit signal_channelinfo(memory, line);
 
447
                                        memory_str = "CHANNEL";
 
448
                                }
 
449
//                              return IT_OTHER;
 
450
                        }
 
451
                        else if (memory != 0 && memory_str && memory_str == "CHANNEL")
 
452
                        {
 
453
                                emit signal_channelinfo(memory, line);
 
454
 
 
455
                                // reset memory
 
456
                                memory = 0;
 
457
                                memory_str = QString();
 
458
//                              return IT_OTHER;
 
459
                        }
 
460
                        // IGS: channelinfo
 
461
                        // 9 #42 Title: Untitled -- Open
 
462
                        // 9 #42    broesel    zero815     Granit
 
463
                        else if (line.contains("#"))
 
464
                        {
 
465
                                int nr = element(line, 0, "#", " ").toInt();
 
466
                                QString msg = element(line, 0, " ", "EOL");
 
467
                                emit signal_channelinfo(nr, msg);
 
468
                        }
 
469
                        // NNGS: channels
 
470
                        else if (line.contains("has left channel") || line.contains("has joined channel"))
 
471
                        {
 
472
                                QString e1 = element(line, 3, " ", ".");
 
473
                                int nr = e1.toInt();
 
474
 
 
475
                                // turn on channel to get full info
 
476
                                emit signal_channelinfo(nr, QString("*on*"));
 
477
                        }
 
478
                        else if (line.contains("Game is titled:"))
 
479
                        {
 
480
                                QString t = element(line, 0, ":", "EOL");
 
481
                                emit signal_title(t);
 
482
                                return IT_OTHER;
 
483
                        }
 
484
                        else if (line.contains("offers a new komi "))
 
485
                        {
 
486
                                // NNGS: 9 physician offers a new komi of 1.5.
 
487
                                QString komi = element(line, 6, " ");
 
488
                                if (komi.at(komi.length()-1) == '.')
 
489
                                        komi.truncate(komi.length() - 1);
 
490
                                QString opponent = element(line, 0, " ");
 
491
 
 
492
                                // true: request
 
493
                                emit signal_komi(opponent, komi, true);
 
494
                        }
 
495
                        else if (line.contains("Komi set to"))
 
496
                        {
 
497
                                // NNGS: 9 Komi set to -3.5 in match 10
 
498
                                QString komi = element(line, 3, " ");
 
499
                                QString game_id = element(line, 6, " ");
 
500
 
 
501
                                // false: no request
 
502
                                emit signal_komi(game_id, komi, false);
 
503
                        }
 
504
                        else if (line.contains("wants the komi to be"))
 
505
                        {
 
506
                                // IGS: 9 qGoDev wants the komi to be  1.5
 
507
                                QString komi = element(line, 6, " ");
 
508
                                QString opponent = element(line, 0, " ");
 
509
 
 
510
                                // true: request
 
511
                                emit signal_komi(opponent, komi, true);
 
512
                        }
 
513
                        else if (line.contains("Komi is now set to"))
 
514
                        {
 
515
                                // 9 Komi is now set to -3.5. -> oppenent set for our game
 
516
                                QString komi = element(line, 5, " ");
 
517
                                // error? "9 Komi is now set to -3.5.9 Komi is now set to -3.5"
 
518
                                if (komi.contains(".9"))
 
519
                                        komi = komi.left(komi.length() - 2);
 
520
 
 
521
                                // false: no request
 
522
                                emit signal_komi(QString(), komi, false);
 
523
                        }
 
524
                        else if (line.contains("Set the komi to"))
 
525
                        {
 
526
                                // NNGS: 9 Set the komi to -3.5 - I set for own game
 
527
                                QString komi = element(line, 4, " ");
 
528
 
 
529
                                // false: no request
 
530
                                emit signal_komi(QString(), komi, false);
 
531
                        }
 
532
                        else if (line.contains("game will count"))
 
533
                        {
 
534
                                // IGS: 9 Game will not count towards ratings.
 
535
                                //      9 Game will count towards ratings.
 
536
                                emit signal_freegame(false);
 
537
                        }
 
538
                        else if (line.contains("game will not count", false))
 
539
                        {
 
540
                                // IGS: 9 Game will not count towards ratings.
 
541
                                //      9 Game will count towards ratings.
 
542
                                emit signal_freegame(true);
 
543
                        }
 
544
                        else if ((line.contains("[") || line.contains("yes")) && line.length() < 6)
 
545
                        {
 
546
                                // 9 [20] ... channelinfo
 
547
                                // 9 yes  ... ayt
 
548
                                return IT_OTHER;
 
549
                        }
 
550
                        else if (line.contains("has restarted your game") ||
 
551
                                 line.contains("has restored your old game"))
 
552
                        {
 
553
                                if (line.contains("restarted"))
 
554
                                        // memory_str -> see case 15 for continuation
 
555
                                        memory_str = element(line, 0, " ");
 
556
                        }
 
557
                        else if (line.contains("I suggest that"))
 
558
                        {
 
559
                                memory_str = line;
 
560
                                return IT_OTHER;
 
561
                        }
 
562
                        else if (line.contains("and set komi to"))
 
563
                        {
 
564
                                // suggest message ...
 
565
                                if (!memory_str)
 
566
                                        // something went wrong...
 
567
                                        return IT_OTHER;
 
568
 
 
569
                                line = line.simplifyWhiteSpace();
 
570
 
 
571
                                QString p1 = element(memory_str, 3, " ");
 
572
                                QString p2 = element(memory_str, 6, " ", ":");
 
573
                                bool p1_play_white = memory_str.contains("play White");
 
574
 
 
575
                                QString h, k;
 
576
                                if (line.contains("even game"))
 
577
                                        h = "0";
 
578
                                else
 
579
                                        h = element(line, 3, " ");
 
580
 
 
581
                                k = element(line, 9, " ", ".");
 
582
 
 
583
                                int size = 19;
 
584
                                if (line.contains("13x13"))
 
585
                                        size = 13;
 
586
                                else if (line.contains("9x 9"))
 
587
                                {
 
588
                                        size = 9;
 
589
                                        memory_str = QString();
 
590
                                }
 
591
 
 
592
                                if (p1_play_white)
 
593
                                        emit signal_suggest(p1, p2, h, k, size);
 
594
                                else
 
595
                                        emit signal_suggest(p2, p1, h, k, size);
 
596
 
 
597
                                return IT_OTHER;
 
598
                        }
 
599
                        // 9 Match [19x19] in 1 minutes requested with xxxx as White.
 
600
                        // 9 Use <match xxxx B 19 1 10> or <decline xxxx> to respond.
 
601
                        else if (line.contains("<decline") && line.contains("<match"))
 
602
                        {
 
603
                                // false -> not my request: used in mainwin.cpp
 
604
                                emit signal_matchrequest(element(line, 0, "<", ">"), false);
 
605
                        }
 
606
                        // 9 Match [5] with guest17 in 1 accepted.
 
607
                        // 9 Creating match [5] with guest17.
 
608
                        else if (line.contains("Creating match"))
 
609
                        {
 
610
                                QString nr = element(line, 0, "[", "]");
 
611
                                // maybe there's a blank within the brackets: ...[ 5]...
 
612
                                QString dummy = element(line, 0, "]", ".").stripWhiteSpace();
 
613
                                QString opp = element(dummy, 1, " ");
 
614
 
 
615
                                emit signal_matchcreate(nr, opp);
 
616
                                // automatic opening of a dialog tab for further conversation
 
617
                                emit signal_talk(opp, "", true);
 
618
                        }
 
619
                        else if (line.contains("Match") && line.contains("accepted"))
 
620
                        {
 
621
                                QString nr = element(line, 0, "[", "]");
 
622
                                QString opp = element(line, 3, " ");
 
623
                                emit signal_matchcreate(nr, opp);
 
624
        
 
625
                        }
 
626
                        // 9 frosla withdraws the match offer.
 
627
                        // 9 guest17 declines your request for a match. 
 
628
                        else if (line.contains("declines your request for a match") ||
 
629
                                 line.contains("withdraws the match offer"))
 
630
                        {
 
631
                                QString opp = element(line, 0, " ");
 
632
                                emit signal_notopen(opp);
 
633
                        }
 
634
                        //9 Requesting match in 10 min with frosla as Black.
 
635
                        else if (line.contains("Requesting match in"))
 
636
                        {
 
637
                                QString opp = element(line, 6, " ");
 
638
                                emit signal_opponentopen(opp);
 
639
                        }
 
640
                        // NNGS: 9 Removing @ K8
 
641
                        // IGS: 9 Removing @ B5
 
642
                        //     49 Game 265 qGoDev is removing @ B5
 
643
                        else if (line.contains("emoving @"))
 
644
                        {
 
645
                                if (gsName != IGS)
 
646
                                {
 
647
                                        QString pt = element(line, 2, " ");
 
648
                                        emit signal_removestones(pt, 0);
 
649
                                }
 
650
                        }
 
651
                        // 9 You can check your score with the score command, type 'done' when finished.
 
652
                        else if (line.contains("check your score with the score command"))
 
653
                        {
 
654
//                              if (gsName == IGS)
 
655
                                        // IGS: store and wait until game number is known
 
656
//                                      memory_str = QString("rmv@"); // -> continuation see 15
 
657
//                              else
 
658
                                        emit signal_removestones(0, 0);
 
659
                        }
 
660
                        // IGS: 9 Board is restored to what it was when you started scoring
 
661
                        else if (line.contains("what it was when you"))
 
662
                        {
 
663
                                emit signal_removestones(0, 0);
 
664
                        }
 
665
                        // WING: 9 Use <adjourn> to adjourn, or <decline adjourn> to decline.
 
666
                        else if (line.contains("Use adjourn to") || line.contains("Use <adjourn> to"))
 
667
                        {
 
668
qDebug("parser->case 9: Use adjourn to");
 
669
                                emit signal_requestDialog("adjourn", 0, 0, 0);
 
670
                        }
 
671
                        // 9 frosla requests to pause the game.
 
672
                        else if (line.contains("requests to pause"))
 
673
                        {
 
674
                                emit signal_requestDialog("pause", 0, 0, 0);
 
675
                        }
 
676
                        else if (line.contains("been adjourned"))
 
677
                        {
 
678
                                // remove game from list - special case: own game
 
679
                                aGame->nr = "@";
 
680
                                aGame->running = false;
 
681
 
 
682
                                emit signal_game(aGame);
 
683
                        }
 
684
                        // 9 Game 22: frosla vs frosla has adjourned.
 
685
                        else if (line.contains("has adjourned"))
 
686
                        {
 
687
                                // remove game from list
 
688
                                aGame->nr = element(line, 0, " ", ":");
 
689
                                aGame->running = false;
 
690
 
 
691
                                // for information
 
692
                                aGame->Sz = "has adjourned.";
 
693
 
 
694
                                emit signal_game(aGame);
 
695
                                emit signal_move(aGame);
 
696
                        }
 
697
                        // 9 Removing game 30 from observation list.
 
698
                        else if (line.contains("from observation list"))
 
699
                        {
 
700
                                // is done from qGoIF
 
701
                                // emit signal_addToObservationList(-1);
 
702
                                aGame->nr = element(line, 2, " ");
 
703
                                aGame->Sz = "-";
 
704
                                aGame->running = false;
 
705
 
 
706
                                emit signal_move(aGame);
 
707
                                return IT_OTHER;
 
708
                        }
 
709
                        // 9 Adding game to observation list.
 
710
                        else if (line.contains("to observation list"))
 
711
                        {
 
712
                                // is done from qGoIF
 
713
                                // emit signal_addToObservationList(-2);
 
714
                                return IT_OTHER;
 
715
                        }
 
716
                        // 9 Games currently being observed:  31, 36, 45.
 
717
                        else if (line.contains("Games currently being observed"))
 
718
                        {
 
719
                                if (line.contains("None"))
 
720
                                {
 
721
                                        emit signal_addToObservationList(0);
 
722
                                }
 
723
                                else
 
724
                                {
 
725
                                        // don't work correct at IGS!!!
 
726
                                        int i = line.contains(',');
 
727
                                        qDebug(QString("observing %1 games").arg(i+1));
 
728
//                                      emit signal_addToObservationList(i+1);
 
729
                                }
 
730
 
 
731
//                              return IT_OTHER;
 
732
                        }
 
733
                        // 9 1 minutes were added to your opponents clock
 
734
                        else if (line.contains("minutes were added"))
 
735
                        {
 
736
                                int t = element(line, 0, " ").toInt();
 
737
                                emit signal_timeAdded(t, false);
 
738
                        }
 
739
                        // 9 Your opponent has added 1 minutes to your clock.
 
740
                        else if (line.contains("opponent has added"))
 
741
                        {
 
742
                                int t = element(line, 4, " ").toInt();
 
743
                                emit signal_timeAdded(t, true);
 
744
                        }
 
745
                        // NNGS: 9 Game clock paused. Use "unpause" to resume.
 
746
                        else if (line.contains("Game clock paused"))
 
747
                        {
 
748
                                emit signal_timeAdded(-1, true);
 
749
                        }
 
750
                        // NNGS: 9 Game clock resumed.
 
751
                        else if (line.contains("Game clock resumed"))
 
752
                        {
 
753
                                emit signal_timeAdded(-1, false);
 
754
                        }
 
755
                        // 9 Increase frosla's time by 1 minute
 
756
                        else if (line.contains("s time by"))
 
757
                        {
 
758
                                int t = element(line, 4, " ").toInt();
 
759
                                if (line.contains(myname))
 
760
                                        emit signal_timeAdded(t, true);
 
761
                                else
 
762
                                        emit signal_timeAdded(t, false);
 
763
                        }
 
764
                        // 9 Setting your . to Banana  [text] (idle: 0 minutes)
 
765
                        else if (line.contains("Setting your . to"))
 
766
                        {
 
767
                                QString busy = element(line, 0, "[", "]");
 
768
                                if (busy)
 
769
                                {
 
770
                                        QString player = element(line, 4, " ");
 
771
                                        // true = player
 
772
                                        emit signal_talk(player, "[" + busy + "]", true);
 
773
                                }
 
774
                        }
 
775
                        // NNGS: 9 Messages: (after 'message' cmd)
 
776
                        //       8 File
 
777
                        //       <msg>
 
778
                        //       8 File
 
779
                        //       9 Please type "erase" to erase your messages after reading
 
780
                        else if (line.contains("Messages:"))
 
781
                        {
 
782
                                // parse like IGS cmd nr 14: Messages
 
783
                                memory = 14;
 
784
                        }
 
785
                        // IGS:  9 You have a message. To read your messages, type:  message
 
786
                        // NNGS: 9 You have 1 messages.  Type "messages" to display them
 
787
                        else if (line.contains("You have") && line.contains("messages"))
 
788
                        {
 
789
                                // remove cmd nr
 
790
                                line = txt.stripWhiteSpace();
 
791
                                line = line.remove(0, 2);
 
792
                                emit signal_message(line);
 
793
                                return YOUHAVEMSG;
 
794
                        }
 
795
                        // 9 Observing game  2 (chmeng vs. myao) :
 
796
                        // 9        shanghai  9k*           henry 15k  
 
797
                        // 9 Found 2 observers.
 
798
                        else if (line.contains("Observing game ", true))
 
799
                        {
 
800
                                // right now: only need for observers of teaching game
 
801
                                // game number
 
802
                                bool ok;
 
803
                                memory = element(line, 2, " ").toInt(&ok);
 
804
                                if (ok)
 
805
                                {
 
806
                                        memory_str = "observe";
 
807
                                        // send as kibitz from "0" -> init
 
808
                                        emit signal_kibitz(memory, "0", "0"); 
 
809
 
 
810
                                        return KIBITZ;
 
811
                                }
 
812
                        }
 
813
                        else if (memory_str && memory_str == "observe" && line.contains("."))
 
814
                        {
 
815
//                              QString cnt = element(line, 1, " ");
 
816
                                emit signal_kibitz(memory, "00", "");
 
817
 
 
818
                                memory = 0;
 
819
                                memory_str = QString();
 
820
 
 
821
                                return KIBITZ;
 
822
                        }
 
823
                        else if (memory_str && memory_str == "observe")
 
824
                        {
 
825
                                QString name;
 
826
                                QString rank;
 
827
                                for (int i = 0; name = element(line, i, " "); i++)
 
828
                                {
 
829
                                        rank = element(line, ++i, " ");
 
830
                                        // send as kibitz from "0"
 
831
                                        emit signal_kibitz(memory, "0", name + " " + rank);
 
832
                                }
 
833
 
 
834
                                return KIBITZ;
 
835
                        }
 
836
                        else if (line.contains("****") && line.contains("Players"))
 
837
                        {
 
838
                                // maybe last line of a 'user' cmd
 
839
                                aPlayer->extInfo = "";
 
840
                                aPlayer->won = "";
 
841
                                aPlayer->lost = "";
 
842
                                aPlayer->country = "";
 
843
                                aPlayer->language = "";
 
844
 
 
845
                                // remove cmd nr
 
846
                                line = txt.stripWhiteSpace();
 
847
                                line = line.remove(0, 2);
 
848
                                emit signal_message(line);
 
849
                                return PLAYER42_END;
 
850
                        }
 
851
                        // 9 qGoDev has resigned the game.
 
852
                        else if (line.contains("has resigned the game."))
 
853
                        {
 
854
                                // make better check
 
855
                                if (element(line, 0, " ", "EOL") != QString("has resigned the game."))
 
856
                                {
 
857
                                        qDebug("'has resigned the game.' ... but pattern wrong");
 
858
                                }
 
859
                                else
 
860
                                        emit signal_kibitz(0, element(line, 0, " "), line);
 
861
                        }
 
862
 
 
863
 
 
864
      //9 Player:      yfh2
 
865
      //9 Game:        go (1)
 
866
      //9 Language:    default
 
867
      //9 Rating:      6k*  23
 
868
      //9 Rated Games:     21
 
869
      //9 Rank:  8k  21
 
870
      //9 Wins:        13
 
871
      //9 Losses:      16
 
872
      //9 Idle Time:  (On server) 0s
 
873
      //9 Address:  yfh2@tiscali.fr
 
874
      //9 Country:  France
 
875
      //9 Reg date: Tue Nov 18 04:01:05 2003
 
876
      //9 Info:  yfh2
 
877
      //9 Defaults (help defs):  time 0, size 0, byo-yomi time 0, byo-yomi stones 0
 
878
      //9 Verbose  Bell  Quiet  Shout  Automail  Open  Looking  Client  Kibitz  Chatter
 
879
      //9     Off    On     On     On        On   Off      Off      On      On   On
 
880
 
 
881
      else if (line.contains("Player:"))
 
882
       {
 
883
        statsPlayer->name = element(line, 1, " ");
 
884
        statsPlayer->extInfo = "";
 
885
        statsPlayer->won = "";
 
886
        statsPlayer->lost = "";
 
887
        statsPlayer->country = "";
 
888
        statsPlayer->language = "";
 
889
        statsPlayer->rank = "";
 
890
        statsPlayer->info = "";
 
891
        statsPlayer->address = "";
 
892
        statsPlayer->play_str = "";
 
893
        statsPlayer->obs_str = "";
 
894
        statsPlayer->idle = "";
 
895
        statsPlayer->rated = "";
 
896
        // not sure it is the best way : above code seem to make use of "signal"
 
897
        // but we don't need this apparently for handling stats
 
898
        memory_str = "STATS";
 
899
        return STATS ;
 
900
        }
 
901
      
 
902
      else if (line.contains("Address:"))
 
903
        {
 
904
         statsPlayer->address = element(line, 1, " ");
 
905
         emit signal_statsPlayer(statsPlayer);
 
906
         return IT_OTHER ;
 
907
        }
 
908
 
 
909
      else if (line.contains("Last Access"))
 
910
        {
 
911
         statsPlayer->idle = element(line, 4, " ")+ " " + element(line, 5, " ")+" " + element(line, 6, " ");
 
912
         emit signal_statsPlayer(statsPlayer);
 
913
         return IT_OTHER ;
 
914
        }
 
915
        
 
916
        else if (line.contains("Rating:"))
 
917
        {
 
918
         statsPlayer->rank = element(line, 1, " ");
 
919
         emit signal_statsPlayer(statsPlayer);
 
920
         return IT_OTHER ;
 
921
        }
 
922
 
 
923
      else if (line.contains("Wins:"))
 
924
        {
 
925
         statsPlayer->won = element(line, 1, " ");
 
926
         emit signal_statsPlayer(statsPlayer);
 
927
         return IT_OTHER ;         
 
928
        }
 
929
        
 
930
      else if (line.contains("Losses:"))
 
931
        {
 
932
         statsPlayer->lost = element(line, 1, " ");
 
933
         emit signal_statsPlayer(statsPlayer);
 
934
         return IT_OTHER ;  
 
935
        }
 
936
 
 
937
      else if ((line.contains("Country:"))||(line.contains("From:")))   //IGS || LGS
 
938
        {
 
939
         statsPlayer->country = element(line, 0, " ","EOL");
 
940
         emit signal_statsPlayer(statsPlayer);
 
941
         return IT_OTHER ; 
 
942
        }
 
943
 
 
944
      else if (line.contains("Defaults"))    //IGS
 
945
        {
 
946
         statsPlayer->extInfo = element(line, 2, " ","EOL");
 
947
         emit signal_statsPlayer(statsPlayer);
 
948
         return IT_OTHER ; 
 
949
        }
 
950
      else if (line.contains("Experience on WING"))  //WING
 
951
        {
 
952
         statsPlayer->extInfo = line ;
 
953
         emit signal_statsPlayer(statsPlayer);
 
954
         return IT_OTHER ;
 
955
        }
 
956
      else if (line.contains("User Level:")) //LGS
 
957
        {
 
958
         statsPlayer->extInfo = line ;
 
959
         emit signal_statsPlayer(statsPlayer);
 
960
         return IT_OTHER ;
 
961
        }
 
962
 
 
963
        
 
964
      else if ((line.contains("Info:"))&& !(line.contains("Rank Info:")))
 
965
        {
 
966
         if (! statsPlayer->info.isEmpty())
 
967
           statsPlayer->info.append("\n");
 
968
         statsPlayer->info.append(line);
 
969
         emit signal_statsPlayer(statsPlayer);
 
970
         return IT_OTHER ;          
 
971
        }
 
972
 
 
973
      else if (line.contains("Playing in game:"))       //IGS and LGS
 
974
        {
 
975
         statsPlayer->play_str = element(line, 3, " ");
 
976
         emit signal_statsPlayer(statsPlayer);
 
977
         return IT_OTHER ;
 
978
        }
 
979
      else if (line.contains("(playing game"))       //WING
 
980
        {
 
981
         statsPlayer->play_str = element(line, 1, " ",":");
 
982
         emit signal_statsPlayer(statsPlayer);
 
983
         return IT_OTHER ;
 
984
        }
 
985
                
 
986
      else if (line.contains("Rated Games:"))
 
987
        {
 
988
         statsPlayer->rated = element(line, 2, " ");
 
989
         emit signal_statsPlayer(statsPlayer);
 
990
         return IT_OTHER ;
 
991
        }
 
992
        
 
993
      else if (line.contains("Games Rated:"))    //WING syntax
 
994
        {
 
995
         statsPlayer->rated = element(line, 2, " ");
 
996
         statsPlayer->won = element(line, 0, "("," ");
 
997
         statsPlayer->lost = element(line, 6, " ");         
 
998
         emit signal_statsPlayer(statsPlayer);
 
999
         return IT_OTHER ;
 
1000
        }
 
1001
 
 
1002
        
 
1003
      else if (line.contains("Idle Time:"))
 
1004
        {
 
1005
 
 
1006
         if    (gsName == WING)
 
1007
            statsPlayer->idle = element(line, 2, " ");
 
1008
         else
 
1009
            statsPlayer->idle = element(line, 4, " ");
 
1010
            
 
1011
         emit signal_statsPlayer(statsPlayer);
 
1012
         return IT_OTHER ;
 
1013
        }
 
1014
 
 
1015
      else if (line.contains("Last Access"))
 
1016
        {
 
1017
         statsPlayer->idle = "not on";
 
1018
         emit signal_statsPlayer(statsPlayer);
 
1019
         return IT_OTHER ;
 
1020
        }
 
1021
        
 
1022
      else if (line.left(5) == "19x19")     //LGS syntax
 
1023
        {
 
1024
         statsPlayer->rank = element(line, 4, " ");
 
1025
         statsPlayer->rated = element(line, 7, " ");
 
1026
         emit signal_statsPlayer(statsPlayer);
 
1027
         return IT_OTHER ;
 
1028
        }
 
1029
 
 
1030
      else if (line.contains("Wins/Losses"))     //LGS syntax
 
1031
        {
 
1032
         statsPlayer->won = element(line, 2, " ");
 
1033
         statsPlayer->lost = element(line, 4, " ");
 
1034
         emit signal_statsPlayer(statsPlayer);
 
1035
         return IT_OTHER ;
 
1036
        }
 
1037
 
 
1038
        
 
1039
              /*
 
1040
      else if (line.contains("Idle"))
 
1041
        {
 
1042
         statsPlayer->extInfo = element(line, 3, " ","EOL");
 
1043
         return STATS ;
 
1044
        }
 
1045
       */ 
 
1046
              
 
1047
                        // remove cmd nr
 
1048
      //                        line = txt.stripWhiteSpace();
 
1049
      //                        line = line.remove(0, 2);
 
1050
      if (memory_str != "STATS")
 
1051
                        emit signal_message(line);
 
1052
                        return MESSAGE;
 
1053
                        break;
 
1054
 
 
1055
                // 11 Kibitz Achim [ 3d*]: Game TELRUZU vs Anacci [379]
 
1056
                // 11    will B resign?
 
1057
                case 11:
 
1058
                        if (line.contains("Kibitz"))
 
1059
                        {
 
1060
                                // who is kibitzer
 
1061
                                memory_str = element(line, 0, " ", ":");
 
1062
                                // game number
 
1063
                                memory = element(line, 1, "[", "]").toInt();
 
1064
                        }
 
1065
                        else
 
1066
                        {
 
1067
                                if (!memory_str)
 
1068
                                        // something went wrong...
 
1069
                                        return IT_OTHER;
 
1070
 
 
1071
                                emit signal_kibitz(memory, memory_str, line);
 
1072
                                memory = 0;
 
1073
                                memory_str = QString();
 
1074
                        }
 
1075
                        return KIBITZ;
 
1076
                        break;
 
1077
 
 
1078
                // messages
 
1079
                // 14 File
 
1080
                // frosla 11/15/02 14:00: Hallo
 
1081
                // 14 File
 
1082
                case 14:
 
1083
                        if (memory_str && memory_str.contains("File"))
 
1084
                        {
 
1085
                                // toggle
 
1086
                                memory_str = QString();
 
1087
                                memory = 0;
 
1088
                        }
 
1089
                        else if (line.contains("File"))
 
1090
                        {
 
1091
                                // the following lines are help messages
 
1092
                                memory_str = line;
 
1093
                                memory = 14;
 
1094
                        }
 
1095
                        return IT_OTHER;
 
1096
                        break;
 
1097
 
 
1098
                // MOVE
 
1099
                // 15 Game 43 I: xxxx (4 223 16) vs yyyy (5 59 13)
 
1100
                // 15 144(B): B12
 
1101
                // IGS: teaching game:
 
1102
                // 15 Game 167 I: qGoDev (0 0 -1) vs qGoDev (0 0 -1)
 
1103
                case 15:
 
1104
                        if (line.contains("Game"))
 
1105
                        {
 
1106
                                aGameInfo->nr = element(line, 1, " ");
 
1107
                                aGameInfo->type = element(line, 1, " ", ":");
 
1108
                                aGameInfo->wname = element(line, 3, " ");
 
1109
                                aGameInfo->wprisoners = element(line, 0, "(", " ");
 
1110
                                aGameInfo->wtime = element(line, 5, " ");
 
1111
                                aGameInfo->wstones = element(line, 5, " ", ")");
 
1112
                                aGameInfo->bname = element(line, 8, " ");
 
1113
                                aGameInfo->bprisoners = element(line, 1, "(", " ");
 
1114
                                aGameInfo->btime = element(line, 10, " ");
 
1115
                                aGameInfo->bstones = element(line, 10, " ", ")");
 
1116
 
 
1117
                                if (memory_str == QString("rmv@"))
 
1118
                                {
 
1119
                                        // contiue removing
 
1120
                                        emit signal_removestones(0, aGameInfo->nr);
 
1121
                                        memory_str = QString();
 
1122
                                }
 
1123
                                else if ((memory_str || gsName == IGS) && (aGameInfo->bname == myname || aGameInfo->wname == myname))
 
1124
                                {
 
1125
                                        // if a stored game is restarted then send start message first
 
1126
                                        // -> continuation of case 9
 
1127
                                        aGame->nr = aGameInfo->nr;
 
1128
                                        aGame->wname = aGameInfo->wname;
 
1129
                                        aGame->bname = aGameInfo->bname;
 
1130
                                        aGame->Sz = "@@";
 
1131
                                        aGame->running = true;
 
1132
 
 
1133
                                        emit signal_move(aGame);
 
1134
 
 
1135
                                        // reset memory
 
1136
                                        memory_str = QString();
 
1137
                                }
 
1138
 
 
1139
                                // it's a kind of time info
 
1140
                                aGameInfo->mv_col = "T";
 
1141
                        }
 
1142
                        else
 
1143
                        {
 
1144
                                aGameInfo->mv_nr = element(line, 0, "(");
 
1145
                                aGameInfo->mv_pt = element(line, 0, " ", "EOL");
 
1146
 
 
1147
                                // it's a move info of color:
 
1148
                                aGameInfo->mv_col = element(line, 0, "(", ")");
 
1149
                        }
 
1150
 
 
1151
                        emit signal_move(aGameInfo);
 
1152
                        return MOVE;
 
1153
                        break;
 
1154
 
 
1155
                // SAY
 
1156
                // 19 *xxxx*: whish you a nice game  :)
 
1157
                // NNGS - new:
 
1158
                //  19 --> frosla hallo
 
1159
                case 19:
 
1160
                        if (line.contains("-->"))
 
1161
                                emit signal_kibitz(0, 0, element(line, 1, " ", "EOL"));
 
1162
                        else
 
1163
                                emit signal_kibitz(0, 0, element(line, 0, ":", "EOL"));
 
1164
                        break;
 
1165
                        
 
1166
                                
 
1167
                //20 yfh2 (W:O): 4.5 to NaiWei (B:#): 4.0
 
1168
                case 20:
 
1169
                        aGame->nr = "@";
 
1170
                        aGame->running = false;
 
1171
                        
 
1172
                        if ( line.find("W:") < line.find("B:"))
 
1173
                                aGame->Sz = "W " + element(line, 2, " ") + " B " + element(line, 6, " ");
 
1174
                        else 
 
1175
                                aGame->Sz = "B " + element(line, 2, " ") + " W " + element(line, 6, " ");                               
 
1176
                        
 
1177
                        emit signal_move(aGame);
 
1178
                        break;
 
1179
                        
 
1180
                        
 
1181
                        
 
1182
                // SHOUT - a info from the server
 
1183
                case 21:
 
1184
                        // case sensitive
 
1185
                        if (line.contains(" connected.}"))
 
1186
                        {
 
1187
                                // {guest1381 [NR ] has connected.}
 
1188
                                //line.replace(QRegExp(" "), "");
 
1189
                                aPlayer->name = element(line, 0, "{", " ");
 
1190
                                aPlayer->rank = element(line, 0, "[", "]", true);
 
1191
                                aPlayer->info = "??";
 
1192
                                aPlayer->play_str = "-";
 
1193
                                aPlayer->obs_str = "-";
 
1194
                                aPlayer->idle = "-";
 
1195
                                aPlayer->online = true;
 
1196
                                
 
1197
                                // false -> no "players" cmd preceded
 
1198
                                emit signal_player(aPlayer, false);
 
1199
                                return PLAYER;
 
1200
                        }
 
1201
                        else if (line.contains("has disconnected"))
 
1202
                        {
 
1203
                                // {xxxx has disconnected}
 
1204
                                aPlayer->name = element(line, 0, "{", " ");
 
1205
                                aPlayer->online = false;
 
1206
                                
 
1207
                                emit signal_player(aPlayer, false);
 
1208
                                return PLAYER;
 
1209
                        }
 
1210
                        else if (line.contains("{Game"))
 
1211
                        {
 
1212
                                // {Game 198: xxxx1 vs xxxx2 @ Move 33}
 
1213
                                if (line.contains("@"))
 
1214
                                {
 
1215
                                        // game has continued
 
1216
                                        aGame->nr = element(line, 0, " ", ":");
 
1217
                                        aGame->wname = element(line, 2, " ");
 
1218
                                        aGame->wrank = "??";
 
1219
                                        aGame->bname = element(line, 4, " ");
 
1220
                                        aGame->brank = "??";
 
1221
                                        aGame->mv = element(line, 6, " ", "}");
 
1222
                                        aGame->Sz = "@";
 
1223
                                        aGame->H = QString();
 
1224
                                        aGame->running = true;
 
1225
                                        
 
1226
                                        emit signal_game(aGame);
 
1227
                                        emit signal_move(aGame);
 
1228
                                        return GAME;
 
1229
                                }
 
1230
 
 
1231
                                // {Game 155: xxxx vs yyyy has adjourned.}
 
1232
                                // {Game 76: xxxx vs yyyy : W 62.5 B 93.0}
 
1233
                                // {Game 173: xxxx vs yyyy : White forfeits on time.}
 
1234
                                // {Game 116: xxxx17 vs yyyy49 : Black resigns.}
 
1235
                                // IGS:
 
1236
                                // 21 {Game 124: Redmond* vs NaiWei* : Black lost by Resign}
 
1237
                                // 21 {Game 184: Redmond* vs NaiWei* : White lost by 1.0}
 
1238
                                if (line.contains("resigns.")           ||
 
1239
                                    line.contains("adjourned.") ||
 
1240
                                    line.contains(" : W ", true)        ||
 
1241
                                    line.contains(" : B ", true)        ||
 
1242
                                    line.contains("forfeits on")        ||
 
1243
                                    line.contains("lost by"))
 
1244
                                {
 
1245
                                        // remove game from list
 
1246
                                        aGame->nr = element(line, 0, " ", ":");
 
1247
                                        aGame->running = false;
 
1248
 
 
1249
                                        // for information
 
1250
                                        aGame->Sz = element(line, 4, " ", "}");
 
1251
                                        if (!aGame->Sz)
 
1252
                                                aGame->Sz = "-";
 
1253
                                        else if (aGame->Sz.find(":") != -1)
 
1254
                                                aGame->Sz.remove(0,2);
 
1255
 
 
1256
                                        emit signal_game(aGame);
 
1257
                                        emit signal_move(aGame);
 
1258
                                        return GAME;
 
1259
                                }
 
1260
                        }
 
1261
                        else if (line.contains("{Match"))
 
1262
                        {
 
1263
                                // {Match 116: xxxx [19k*] vs. yyyy1 [18k*] }
 
1264
                                // {116:xxxx[19k*]yyyy1[18k*]}
 
1265
                                // WING: {Match 41: o4641 [10k*] vs. Urashima [11k*] H:2 Komi:3.5}
 
1266
                                line.replace(QRegExp("vs. "), "");
 
1267
                                line.replace(QRegExp("Match "), "");
 
1268
                                line.replace(QRegExp(" "), "");
 
1269
                                
 
1270
                                aGame->wname = element(line, 0, ":", "[");
 
1271
                                aGame->bname = element(line, 0, "]", "[");
 
1272
/*
 
1273
                                // skip info for own games; full info is coming soon
 
1274
                                if (aGame->wname == myname || aGame->bname == myname)
 
1275
                                {
 
1276
                                        emit signal_message(line);
 
1277
                                        return IT_OTHER;
 
1278
                                }
 
1279
*/
 
1280
                                aGame->nr = element(line, 0, "{", ":");
 
1281
                                aGame->wrank = element(line, 0, "[", "]");
 
1282
                                aGame->brank = element(line, 1, "[", "]");
 
1283
                                aGame->mv = "-";
 
1284
                                aGame->Sz = "-";
 
1285
                                aGame->H = QString();
 
1286
                                aGame->running = true;
 
1287
                                
 
1288
                                if (gsName == WING && aGame->wname == aGame->bname)
 
1289
                                        // WING doesn't send 'create match' msg in case of teaching game
 
1290
                                        emit signal_matchcreate(aGame->nr, aGame->bname);
 
1291
 
 
1292
                                emit signal_game(aGame);
 
1293
                                return GAME;
 
1294
                        }
 
1295
                        // !xxxx!: a game anyone ?
 
1296
                        else if (line.contains("!: "))
 
1297
                        {
 
1298
                                QString player = element(line, 0, "!");
 
1299
                                emit signal_shout(player, line);
 
1300
                                return SHOUT;
 
1301
                        }
 
1302
 
 
1303
                        emit signal_message(line);
 
1304
                        return MESSAGE;
 
1305
                        break;
 
1306
 
 
1307
                // CURRENT GAME STATUS
 
1308
                // 22 Pinkie  3d* 21 218 9 T 5.5 0
 
1309
                // 22 aura  3d* 24 276 16 T 5.5 0
 
1310
                // 22  0: 4441000555033055001
 
1311
                // 22  1: 1441100000011000011
 
1312
                // 22  2: 4141410105013010144
 
1313
                // 22  3: 1411411100113011114
 
1314
                // 22  4: 1131111111100001444
 
1315
                // 22  5: 0100010001005011111
 
1316
                // 22  6: 0055000101105000010
 
1317
                // 22  7: 0050011110055555000
 
1318
                // 22  8: 1005000141005055010
 
1319
                // 22  9: 1100113114105500011
 
1320
                // 22 10: 1111411414105010141
 
1321
                // 22 11: 4144101101100111114
 
1322
                // 22 12: 1411300103100000144
 
1323
                // 22 13: 1100005000101001144
 
1324
                // 22 14: 1050505550101011144
 
1325
                // 22 15: 0505505001111001444
 
1326
                // 22 16: 0050050111441011444
 
1327
                // 22 17: 5550550001410001144
 
1328
                // 22 18: 5555000111411300144
 
1329
                case 22:
 
1330
                        if (!line.contains(":"))
 
1331
                        {
 
1332
                                QString player = element(line, 0, " ");
 
1333
                                QString cap = element(line, 2, " ");
 
1334
                                QString komi = element(line, 6, " ");
 
1335
                                emit signal_result(player, cap, true, komi);
 
1336
                        }
 
1337
                        else
 
1338
                        {
 
1339
                                QString row = element(line, 0, ":");
 
1340
                                QString results = element(line, 1, " ");
 
1341
                                emit signal_result(row, results, false, 0);
 
1342
                        }
 
1343
 
 
1344
//                      emit signal_message(line);
 
1345
                        break;
 
1346
 
 
1347
                // STORED
 
1348
                // 9 Stored games for frosla:
 
1349
                // 23           frosla-physician
 
1350
//TODO          case 23:
 
1351
//TODO                  break;
 
1352
 
 
1353
                //  24 *xxxx*: CLIENT: <cgoban 1.9.12> match xxxx wants handicap 0, komi 5.5, free
 
1354
                //      24 *jirong*: CLIENT: <cgoban 1.9.12> match jirong wants handicap 0, komi 0.5
 
1355
    //  24 *SYSTEM*: shoei canceled the nmatch request.
 
1356
    
 
1357
                // NNGS - new version:
 
1358
                //  24 --> frosla CLIENT: <qGo 0.0.15b7> match frosla wants handicap 0, komi 0.5, free
 
1359
                //  24 --> frosla  Hallo
 
1360
                case 24:
 
1361
                {
 
1362
                        int pos;
 
1363
                        if ((((pos = line.find("*")) != -1) && (pos < 3) || 
 
1364
                                ((pos = line.find("-->")) != -1) && (pos < 3)) &&
 
1365
                                line.contains("CLIENT:"))
 
1366
                        {
 
1367
                                line = line.simplifyWhiteSpace();
 
1368
                                QString opp = element(line, 1, "*");
 
1369
                                int offset = 0;
 
1370
                                if (!opp)
 
1371
                                {
 
1372
                                        offset++;
 
1373
                                        opp = element(line, 1, " ");
 
1374
                                }
 
1375
 
 
1376
                                QString h = element(line, 7+offset, " ", ",");
 
1377
                                QString k = element(line, 10+offset, " ");
 
1378
 
 
1379
                                if (k.at(k.length()-1) == ',')
 
1380
                                        k.truncate(k.length() - 1);
 
1381
                                int komi = (int) (k.toFloat() * 10);
 
1382
 
 
1383
                                bool free;
 
1384
                                if (line.contains("free"))
 
1385
                                        free = true;
 
1386
                                else
 
1387
                                        free = false;
 
1388
 
 
1389
                                emit signal_komirequest(opp, h.toInt(), komi, free);
 
1390
                                emit signal_message(line);
 
1391
 
 
1392
                                // it's tell, but don't open a window for that kind of message...
 
1393
                                return TELL;
 
1394
                        }
 
1395
      
 
1396
      //check for cancelled game offer
 
1397
      if (line.contains("*SYSTEM*"))
 
1398
      {
 
1399
       QString opp = element(line, 1, " ");
 
1400
       line = line.remove(0,10);
 
1401
       emit signal_message(line);
 
1402
 
 
1403
       if  (line.contains("canceled") &&  line.contains("match request"))
 
1404
        emit signal_matchCanceled(opp);
 
1405
       return IT_OTHER ;
 
1406
      }
 
1407
      
 
1408
                        // check for NNGS type of msg
 
1409
                        QString e1,e2;
 
1410
                        if ((pos = line.find("-->")) != -1 && pos < 3)
 
1411
                        {
 
1412
                                e1 = element(line, 1, " ");
 
1413
                                e2 = "> " + element(line, 1, " ", "EOL").stripWhiteSpace();
 
1414
                        }
 
1415
                        else
 
1416
                        {
 
1417
                                e1 = element(line, 0, "*", "*");
 
1418
                                e2 = "> " + element(line, 0, ":", "EOL").stripWhiteSpace();
 
1419
                        }
 
1420
 
 
1421
                        // emit player + message + true (=player)
 
1422
                        emit signal_talk(e1, e2, true);
 
1423
 
 
1424
                        return TELL;
 
1425
                        break;
 
1426
                }
 
1427
 
 
1428
 
 
1429
    // results
 
1430
    //25 File
 
1431
    //curio      [ 5d*](W) : lllgolll   [ 4d*](B) H 0 K  0.5 19x19 W+Resign 22-04-47 R
 
1432
    //curio      [ 5d*](W) : was        [ 4d*](B) H 0 K  0.5 19x19 W+Time 22-05-06 R
 
1433
    //25 File
 
1434
                case 25:
 
1435
                {
 
1436
      break;
 
1437
    }
 
1438
                // who
 
1439
                case 27:
 
1440
                {
 
1441
                        // 27  Info Name Idle Rank | Info Name Idle Rank
 
1442
                        // 27  SX --   -- xxxx03      1m     NR  |  Q! --   -- xxxx101    33s     NR  
 
1443
                        // 0   4 6    11  15         26     33   38 41
 
1444
                        // 27     --  221 DAISUKEY   33s     8k  |   X172   -- hiyocco     2m    19k*
 
1445
                        // 27  Q  --  216 Saiden      7s     1k* |     --   53 toshiao    11s    10k 
 
1446
                        // 27     48   -- kyouji      3m    11k* |     --   95 bengi       5s     4d*
 
1447
                        // IGS:
 
1448
                        //        --   -- kimisa      1m     2k* |  Q  --  206 takabo     45s     1k*
 
1449
                        //      X 39   -- Marin       5m     2k* |     --   53 KT713      18s     2d*
 
1450
                        //        --   34 mat21       2m    14k* |     --    9 entropy    28s     4d 
 
1451
                        // NNGS:
 
1452
                        // 27   X --   -- arndt      21s     5k  |   X --   -- biogeek    58s    20k   
 
1453
                        // 27   X --   -- buffel     21s     4k  |  S  --    5 frosla     12s     7k   
 
1454
                        // 27  S  --   -- GoBot       1m     NR  |     --    5 guest17     0s     NR   
 
1455
                        // 27     --    3 hama        3s    15k  |     --   -- niki        5m     NR   
 
1456
                        // 27   ! --   -- viking4    55s    19k* |  S  --    3 GnuGo       6s    14k*  
 
1457
                        // 27   X --   -- kossa      21m     5k  |   X --   -- leif        5m     3k*  
 
1458
                        // 27     --    6 ppp        18s     2k* |     --    6 chmeng     20s     1d*  
 
1459
                        // 27                 ********  14 Players 3 Total Games ********
 
1460
 
 
1461
                        // WING:
 
1462
                        // 0        9    14                      38      46   51
 
1463
                        // 27   X 13   -- takeo6      1m     2k  |   ! 26   -- ooide       6m     2k*  
 
1464
                        // 27   ! --   -- hide1234    9m     2k* |  QX --   -- yochi       0s     2k*  
 
1465
                        // 27   g --   86 karasu     45s     2k* |  Sg --   23 denakechi  16s     1k*  
 
1466
                        // 27   g 23   43 kH03       11s     1k* |   g --   43 kazusige   24s     1k*  
 
1467
                        // 27   g --   50 jan        24s     1k* |  QX --   -- maigo      32s     1d   
 
1468
                        // 27   g --   105 kume1       5s     1d* |   g --   30 yasumitu   24s     1d   
 
1469
                        // 27  Qf --   13 motono      2m     1d* |   X 13   -- tak7       57s     1d*  
 
1470
                        // 27   ! 50   -- okiek       8m     1d* |   X --   -- DrO        11s     1d*  
 
1471
                        // 27   f --   103 hiratake   35s     8k  |   g --   33 kushinn    21s     8k*
 
1472
                        // 27   g --   102 teacup      1m     1d* |   g --   102 Tadao      32s     1d*  
 
1473
 
 
1474
                        // search for first line
 
1475
                        if (txt.contains("Idle") && (txt.find("Info")) != -1)
 
1476
                        {
 
1477
                                // skip
 
1478
                                return PLAYER27_START;
 
1479
                        }
 
1480
                        else if (txt.contains("**"))
 
1481
                        {
 
1482
                                // no player line
 
1483
                                // xx_END used for correct inserting into player's list
 
1484
                                return PLAYER27_END;
 
1485
                        }
 
1486
 
 
1487
                        // indicate player to be online
 
1488
                        aPlayer->online = true;
 
1489
                        
 
1490
                        if (gsName == WING)
 
1491
                        {
 
1492
                                // shifts take care of too long integers
 
1493
                                int shift1 = (txt[9] == ' ' ? 0 : 1);
 
1494
                                int shift2 = (txt[14+shift1] == ' ' ? shift1 : shift1+1);
 
1495
                                int shift3 = (txt[46+shift2] == ' ' ? shift2 : shift2+1);
 
1496
                                int shift4 = (txt[51+shift3] == ' ' ? shift3 : shift3+1);
 
1497
 
 
1498
                                if (txt[15+shift2] != ' ')
 
1499
                                {
 
1500
                                        // parse line
 
1501
                                        aPlayer->info = txt.mid(4,2);
 
1502
                                        aPlayer->obs_str = txt.mid(7,3);
 
1503
                                        aPlayer->play_str = txt.mid(12+shift1,3).stripWhiteSpace();
 
1504
                                        aPlayer->name = txt.mid(15+shift2,11).stripWhiteSpace();
 
1505
                                        aPlayer->idle = txt.mid(26+shift2,3);
 
1506
                                        if (txt[33+shift2] == ' ')
 
1507
                                        {
 
1508
                                                if (txt[36] == ' ')
 
1509
                                                        aPlayer->rank = txt.mid(34+shift2,2);
 
1510
                                                else
 
1511
                                                        aPlayer->rank = txt.mid(34+shift2,3);
 
1512
                                        }
 
1513
                                        else
 
1514
                                        {
 
1515
                                                if (txt[36+shift2] == ' ')
 
1516
                                                        aPlayer->rank = txt.mid(33+shift2,3);
 
1517
                                                else
 
1518
                                                        aPlayer->rank = txt.mid(33+shift2,4);
 
1519
                                        }
 
1520
                                        
 
1521
                                        // check if line ok, true -> cmd "players" preceded
 
1522
                                        emit signal_player(aPlayer, true);
 
1523
                                }
 
1524
                                else
 
1525
                                        qDebug("WING - player27 dropped (1): " + txt);
 
1526
 
 
1527
                                // position of delimiter between two players
 
1528
                                pos = txt.find('|');
 
1529
                                // check if 2nd player in a line && player (name) exists
 
1530
                                if (pos != -1 && txt[52+shift4] != ' ')
 
1531
                                {
 
1532
                                        // parse line
 
1533
                                        aPlayer->info = txt.mid(41+shift2,2);
 
1534
                                        aPlayer->obs_str = txt.mid(44+shift2,3);
 
1535
                                        aPlayer->play_str = txt.mid(49+shift3,3).stripWhiteSpace();
 
1536
                                        aPlayer->name = txt.mid(52+shift4,11).stripWhiteSpace();
 
1537
                                        aPlayer->idle = txt.mid(63+shift4,3);
 
1538
                                        if (txt[70+shift4] == ' ')
 
1539
                                        {
 
1540
                                                if (txt[73+shift4] == ' ')
 
1541
                                                        aPlayer->rank = txt.mid(71+shift4,2);
 
1542
                                                else
 
1543
                                                        aPlayer->rank = txt.mid(71+shift4,3);
 
1544
                                        }
 
1545
                                        else
 
1546
                                        {
 
1547
                                                if (txt[73+shift4] == ' ')
 
1548
                                                        aPlayer->rank = txt.mid(70+shift4,3);
 
1549
                                                else
 
1550
                                                        aPlayer->rank = txt.mid(70+shift4,4);
 
1551
                                        }
 
1552
 
 
1553
                                        // true -> cmd "players" preceded
 
1554
                                        emit signal_player(aPlayer, true);
 
1555
                                }
 
1556
                                else
 
1557
                                        qDebug("WING - player27 dropped (2): " + txt);
 
1558
                        }
 
1559
                        else
 
1560
                        {
 
1561
                                if (txt[15] != ' ')
 
1562
                                {
 
1563
                                        // parse line
 
1564
                                        aPlayer->info = txt.mid(4,2);
 
1565
                                        aPlayer->obs_str = txt.mid(6,3);
 
1566
                                        aPlayer->play_str = txt.mid(11,3).stripWhiteSpace();
 
1567
                                        aPlayer->name = txt.mid(15,11).stripWhiteSpace();
 
1568
                                        aPlayer->idle = txt.mid(26,3);
 
1569
                                        if (txt[33] == ' ')
 
1570
                                        {
 
1571
                                                if (txt[36] == ' ')
 
1572
                                                        aPlayer->rank = txt.mid(34,2);
 
1573
                                                else
 
1574
                                                        aPlayer->rank = txt.mid(34,3);
 
1575
                                        }
 
1576
                                        else
 
1577
                                        {
 
1578
                                                if (txt[36] == ' ')
 
1579
                                                        aPlayer->rank = txt.mid(33,3);
 
1580
                                                else
 
1581
                                                        aPlayer->rank = txt.mid(33,4);
 
1582
                                        }
 
1583
                                        
 
1584
                                        // check if line ok, true -> cmd "players" preceded
 
1585
                                        emit signal_player(aPlayer, true);
 
1586
                                }
 
1587
                                else
 
1588
                                        qDebug("player27 dropped (1): " + txt);
 
1589
 
 
1590
                                // position of delimiter between two players
 
1591
                                pos = txt.find('|');
 
1592
                                // check if 2nd player in a line && player (name) exists
 
1593
                                if (pos != -1 && txt[52] != ' ')
 
1594
                                {
 
1595
                                        // parse line
 
1596
                                        aPlayer->info = txt.mid(41,2);
 
1597
                                        aPlayer->obs_str = txt.mid(43,3);
 
1598
                                        aPlayer->play_str = txt.mid(48,3).stripWhiteSpace();
 
1599
                                        aPlayer->name = txt.mid(52,11).stripWhiteSpace();
 
1600
                                        aPlayer->idle = txt.mid(63,3);
 
1601
                                        if (txt[70] == ' ')
 
1602
                                        {
 
1603
                                                if (txt[73] == ' ')
 
1604
                                                        aPlayer->rank = txt.mid(71,2);
 
1605
                                                else
 
1606
                                                        aPlayer->rank = txt.mid(71,3);
 
1607
                                        }
 
1608
                                        else
 
1609
                                        {
 
1610
                                                if (txt[73] == ' ')
 
1611
                                                        aPlayer->rank = txt.mid(70,3);
 
1612
                                                else
 
1613
                                                        aPlayer->rank = txt.mid(70,4);
 
1614
                                        }
 
1615
 
 
1616
                                        // true -> cmd "players" preceded
 
1617
                                        emit signal_player(aPlayer, true);
 
1618
                                }
 
1619
                                else
 
1620
                                        qDebug("player27 dropped (2): " + txt);
 
1621
                        }
 
1622
 
 
1623
                        return PLAYER27;
 
1624
                        break;
 
1625
                }
 
1626
 
 
1627
                // 28 guest17 undid the last move (J16).
 
1628
                // 15 Game 7 I: frosla (0 5363 -1) vs guest17 (0 5393 -1)
 
1629
                // 15   2(B): F17
 
1630
                // IGS:
 
1631
                // 28 Undo in game 64: MyMaster vs MyMaster:  N15 
 
1632
                case 28:
 
1633
                {
 
1634
                        if (line.contains("undid the last move"))
 
1635
                        {
 
1636
                                // now: just look in qgo_interface if move_nr has decreased...
 
1637
                                // but send undo-signal anyway: in case of undo while scoring it's necessary
 
1638
                                QString player = element(line, 0, " ");
 
1639
                                QString move = element(line, 0, "(", ")");
 
1640
                                emit signal_undo(player, move);
 
1641
                        }
 
1642
                        else if (line.contains("Undo in game"))
 
1643
                        {
 
1644
                                QString player = element(line, 3, " ");
 
1645
                                player.truncate(player.length() - 1);
 
1646
                                QString move = element(line, 7, " ");
 
1647
                                emit signal_undo(player, move);
 
1648
                        }
 
1649
 
 
1650
                        // message anyway
 
1651
                        emit signal_message(line);
 
1652
                        break;
 
1653
                }
 
1654
 
 
1655
                // IGS
 
1656
                // -->  ; \20
 
1657
                // 32 Changing into channel 20.
 
1658
                // 32 Welcome to cyberspace.
 
1659
                //
 
1660
                // 32 49:qgodev: Title is now: (qgodev) qGo development
 
1661
                // 32 20:qGoDev: Person joining channel
 
1662
                // 32 20:frosla: hi
 
1663
                // 32 20:qGoDev: Person leaving channel
 
1664
 
 
1665
                //
 
1666
                // 1 5
 
1667
                // -->  channels
 
1668
                // 9 #1 Title: Professional Channel -- Open
 
1669
                // 
 
1670
                // 9 #20 Title: Untitled -- Open
 
1671
                // 9 #20     frosla
 
1672
                // #> 23 till: hello all  <-- this is what the members in channel 23 see:
 
1673
                //                      (channel number and who sent the message)
 
1674
                //
 
1675
                // NNGS:
 
1676
                // channel talk: "49:xxxx: hi"
 
1677
                case 32:
 
1678
                {
 
1679
                        // skip welcome message of IGS
 
1680
                        if (line.contains("Changing into channel"))
 
1681
                        {
 
1682
                                int nr = element(line, 3, " ").toInt();
 
1683
                                emit signal_channelinfo(nr, QString("*on*"));
 
1684
                                emit signal_message(line);
 
1685
                                break;
 
1686
                        }
 
1687
                        else if (line.contains("Welcome to cyberspace"))
 
1688
                        {
 
1689
                                emit signal_message(line);
 
1690
                                break;
 
1691
                        }
 
1692
                        else if (line.contains("Person joining channel"))
 
1693
                        {
 
1694
                                int nr = element(line, 0, ":").toInt();
 
1695
                                emit signal_channelinfo(nr, QString("*on*"));
 
1696
                                break;
 
1697
                        }
 
1698
                        else if (line.contains("Person leaving channel"))
 
1699
                        {
 
1700
                                int nr = element(line, 0, ":").toInt();
 
1701
                                emit signal_channelinfo(nr, QString("*on*"));
 
1702
                                break;
 
1703
                        }
 
1704
 
 
1705
                        // emit player + message + false (=channel)
 
1706
                        QString e1,e2;
 
1707
                        switch (gsName)
 
1708
                        {
 
1709
                                case IGS:
 
1710
                                        e1=element(line, 0, ":");
 
1711
                                        e2="> " + element(line, 0, ":", "EOL").stripWhiteSpace();
 
1712
                                        break;
 
1713
 
 
1714
                                default:
 
1715
                                        e1=element(line, 0, ":");
 
1716
                                        e2="> " + element(line, 0, ":", "EOL").stripWhiteSpace();
 
1717
                                        break;
 
1718
                        }
 
1719
                        //emit signal_talk(element(line, 0, ":"), element(line, 0, ":", "EOL").stripWhiteSpace() + "\n", false);
 
1720
                        emit signal_talk(e1, e2, false);
 
1721
                        break;
 
1722
                }
 
1723
 
 
1724
                // Setting your . to xxxx
 
1725
                case 40:
 
1726
                        break;
 
1727
 
 
1728
                // long user report equal to 7
 
1729
                // 7 [255]          YK [ 7d*] vs.         SOJ [ 7d*] ( 56   19  0  5.5  4  I) ( 18)
 
1730
                // 42 [88]          AQ [ 2d*] vs.        lang [ 2d*] (177   19  0  5.5  6  I) (  1)
 
1731
 
 
1732
                // IGS: cmd 'user'
 
1733
                // 42 Name        Info            Country  Rank Won/Lost Obs  Pl Idle Flags Language
 
1734
                // 0  3           15              31       40   45 48    54   59 62   67    72
 
1735
                // 42    guest15                  --        NR    0/   0  -   -   10s    Q- default 
 
1736
                // 42    guest13                  --        NR    0/   0  -   -   24s    Q- default 
 
1737
                // 42         zz  You may be rec  France    NR    0/   0  -   -    0s    -X default 
 
1738
                // 42     zz0002  <none>          Japan     NR    0/   0  -   -    1m    QX default 
 
1739
                // 42     zz0003  <none> ()       Japan     NR    0/   0  -   -    1m    SX default 
 
1740
                // 42       anko                  Taiwan    2k* 168/  97  -   -    1s    -- default 
 
1741
                // 42     MUKO12  1/12 �` 1/15    Japan     4k* 666/ 372  17  -    1m    -X default 
 
1742
                // 42        mof  [Igc2000 1.1]   Sweden    2k* 509/ 463 124  -    0s    -X default 
 
1743
                // 42     obiyan  <None>          Japan     3k* 1018/ 850  -   50  11s    -- default 
 
1744
                // 42    uzumaki                  COM       1k    0/   0  -   -    1s    -X default 
 
1745
                // 42 HansWerner  [Igc2000 1.2]   Germany   1k   11/   3 111  -    1m    QX default 
 
1746
                // 42    genesis                  Germany   1k* 592/ 409  -  136  14s    -- default 
 
1747
                // 42    hamburg                  Germany   3k* 279/ 259  -  334  13s    -- default 
 
1748
                // 42        Sie                  Germany   1k*   6/   7  -   68  39s    -- default 
 
1749
                // 42     borkum                  Germany   4k* 163/ 228  -  100   7s    -- default 
 
1750
                // 42     casumy  45-3            Germany   1d    0/   0  -  133   2s    Q- default 
 
1751
                // 42      stoni                  Germany   2k* 482/ 524  -  166   7s    -- default 
 
1752
                // 42   Beholder  <None>          Germany   NR    0/   0 263  -    5s    QX default 
 
1753
                // 42     xiejun  1/10-15         Germany   3d* 485/ 414 179  -   49s    -X default
 
1754
                // 9                 ******** 1120 Players 247 Total Games ********
 
1755
                case 42:
 
1756
                {
 
1757
                        if (txt[40] == 'R')
 
1758
                        {
 
1759
                                // skip
 
1760
                                return PLAYER42_START;
 
1761
                        }
 
1762
 
 
1763
                        // parse line
 
1764
                        if (txt[40] == ' ')
 
1765
                        {
 
1766
                                if (txt[43] == ' ')
 
1767
                                        aPlayer->rank = txt.mid(41,2);
 
1768
                                else
 
1769
                                        aPlayer->rank = txt.mid(41,3);
 
1770
                        }
 
1771
                        else
 
1772
                        {
 
1773
                                if (txt[43] == ' ')
 
1774
                                        aPlayer->rank = txt.mid(40,3);
 
1775
                                else
 
1776
                                        aPlayer->rank = txt.mid(40,4);
 
1777
                        }
 
1778
                        aPlayer->name = txt.mid(3,10).stripWhiteSpace();
 
1779
                        aPlayer->country = txt.mid(31,8).stripWhiteSpace();
 
1780
                        if (aPlayer->country.contains("--"))
 
1781
                                aPlayer->country = "";
 
1782
                        aPlayer->idle = txt.mid(62,4).stripWhiteSpace();
 
1783
                        aPlayer->extInfo = txt.mid(15,14).stripWhiteSpace().leftJustify(14, ' ');
 
1784
 
 
1785
                        // maybe there's a shift...
 
1786
                        if (txt[49] == '/')
 
1787
                        {
 
1788
                                // yes, shift right
 
1789
                                aPlayer->info = txt.mid(71,2);
 
1790
                                aPlayer->obs_str = txt.mid(55,3);
 
1791
                                aPlayer->play_str = txt.mid(59,3);
 
1792
                                aPlayer->won = txt.mid(45,4);
 
1793
                                aPlayer->lost = txt.mid(50,4).stripWhiteSpace();
 
1794
                                if (txt.mid(73,8).contains("default"))
 
1795
                                        aPlayer->language = "";
 
1796
                                else
 
1797
                                        aPlayer->language = txt.mid(73,8).stripWhiteSpace();
 
1798
                        }
 
1799
                        else
 
1800
                        {
 
1801
                                // no shift
 
1802
                                aPlayer->info = txt.mid(70,2);
 
1803
                                aPlayer->obs_str = txt.mid(54,3);
 
1804
                                aPlayer->play_str = txt.mid(58,3);
 
1805
                                aPlayer->won = txt.mid(45,3).stripWhiteSpace();
 
1806
                                aPlayer->lost = txt.mid(49,4).stripWhiteSpace();
 
1807
                                if (txt.mid(72,8).contains("default"))
 
1808
                                        aPlayer->language = "";
 
1809
                                else
 
1810
                                        aPlayer->language = txt.mid(72,8).stripWhiteSpace();
 
1811
                        }
 
1812
 
 
1813
                        // indicate player to be online
 
1814
                        aPlayer->online = true;
 
1815
                        
 
1816
                        // check if line ok, true -> cmd 'players' or 'users' preceded
 
1817
                        emit signal_player(aPlayer, true);
 
1818
 
 
1819
                        return PLAYER42;
 
1820
                        break;
 
1821
                }
 
1822
 
 
1823
                // IGS:48 Game 354 qGoDev requests an adjournment
 
1824
                case 48:
 
1825
                        // have a look at case 9
 
1826
/*                      if (line.contains("requests an adjournment"))
 
1827
                        {
 
1828
                                QString nr = element(line, 1, " ");
 
1829
                                QString opp = element(line, 2, " ");
 
1830
                                switch (gsName)
 
1831
                                {
 
1832
                                        case IGS:
 
1833
                                                // IGS: you cannot decline, just cancel
 
1834
                                                emit signal_requestDialog("adjourn", 0, nr, opp);
 
1835
                                                break;
 
1836
 
 
1837
                                        case NNGS:
 
1838
                                        default:
 
1839
                                                // we will see if correct...
 
1840
                                                emit signal_requestDialog("adjourn", "decline adjourn", nr, opp);
 
1841
                                                break;
 
1842
                                }
 
1843
                        } */
 
1844
                        break;
 
1845
 
 
1846
                // IGS: 49 Game 42 qGoDev is removing @ C5
 
1847
                case 49:
 
1848
                        if (line.contains("is removing @"))
 
1849
                        {
 
1850
                                QString pt = element(line, 6, " ");
 
1851
                                QString game = element(line, 1, " ");
 
1852
                                QString who = element(line, 2, " ");
 
1853
                                emit signal_removestones(pt, game);
 
1854
                                if (game)
 
1855
                                {
 
1856
                                        pt = "removing @ " + pt;
 
1857
                                        emit signal_kibitz(game.toInt(), who, pt);
 
1858
                                }
 
1859
                        }
 
1860
                        break;
 
1861
                
 
1862
                default:
 
1863
                        emit signal_message(line);
 
1864
                        return MESSAGE;
 
1865
                        
 
1866
                        break;
 
1867
        }
 
1868
 
 
1869
        return IT_OTHER;
 
1870
}
 
1871
 
 
1872
GSName Parser::get_gsname()
 
1873
{
 
1874
        return gsName;
 
1875
}
 
1876
 
 
1877
void Parser::set_gsname(const GSName gs)
 
1878
{
 
1879
        gsName = gs;
 
1880
}