📄 parser.cpp
字号:
/* * parser.cpp */#include "parser.h"#include "qgo_interface.h"#include "tables.h"#include <qregexp.h>// Parsing of Go Server messagesParser::Parser() : QObject(), Misc<QString>(){ // generate buffers aPlayer = new Player; statsPlayer = new Player; aGame = new Game; aGameInfo = new GameInfo; memory = 0; memory_str = QString(); myname = QString(); // init gsName = GS_UNKNOWN;// cmd = NONE;}Parser::~Parser(){ delete aGameInfo; delete aGame; delete aPlayer;}// put a line from host to parser// if info is recognized, a signal is sent, and, however,// the return type indicates the type of informationInfoType Parser::put_line(const QString &txt){ QString line = txt.stripWhiteSpace(); int pos; if (line.length() == 0) { // skip empty lines but write message if // a) not logged in // b) help files if (gsName == GS_UNKNOWN || memory_str && memory_str.contains("File")) { emit signal_message(txt); return MESSAGE; } // white space only return WS; } // skip console commands if (line.find(CONSOLECMDPREFIX,0) != -1) return NONE; // check for connection status if (line.find("Connection closed",0,false) != -1) { emit signal_connclosed(); emit signal_message(txt); gsName = GS_UNKNOWN; return IT_OTHER; } // // LOGON MODE ---------------------- // // try to find out server and set mode if (gsName == GS_UNKNOWN) { if (line.find("IGS entry on",0) != -1) { gsName = IGS; emit signal_svname(gsName); return SERVERNAME; } if (line.find("LGS #",0) != -1) { gsName = LGS; emit signal_svname(gsName); return SERVERNAME; } if (line.find("NNGS #",0) != -1) { gsName = NNGS; emit signal_svname(gsName); return SERVERNAME; } // suggested by Rod Assard for playing with NNGS version 1.1.14 if (line.find("Server (NNGS)",0) != -1) { gsName = NNGS; emit signal_svname(gsName); return SERVERNAME; } if (line.find("WING #",0) != -1) { gsName = WING; emit signal_svname(gsName); return SERVERNAME; } if (line.find("CTN #",0) != -1) { gsName = CTN; emit signal_svname(gsName); return SERVERNAME; } // adapted from NNGS, chinese characters if (line.find("CWS #",0) != -1 || line.find("==CWS",0) != -1) { gsName = CWS; emit signal_svname(gsName); return SERVERNAME; } // critical: TO BE WATCHED.... if (line.find("#>",0) != -1) { gsName = DEFAULT; emit signal_svname(gsName); return SERVERNAME; } // account name if (line.find("Your account name is",0) != -1) { buffer = line.right(line.length() - 21); buffer.replace(QRegExp("[\".]"), ""); emit signal_accname(buffer); return ACCOUNT; } // account name as sent from telnet.cpp if (line.find("...sending:") != -1) { if ((buffer = element(line, 0, "{", "}")) == NULL) return IT_OTHER; emit signal_accname(buffer); return ACCOUNT; } if ((line.find("guest account",0) != -1) || line.contains("logged in as a guest")) { emit signal_status(GUEST); return STATUS; } if (line.at(0) != '9' && !memory) { emit signal_message(txt); return MESSAGE; } } // // LOGON HAS DONE, now parse: ---------------------- // // get command type: bool ok; int cmd_nr = element(line, 0, " ").toInt(&ok); if (!ok && memory_str && memory_str.contains("CHANNEL")) { // special case: channel info cmd_nr = 9; } else if (!ok || memory_str && memory_str.contains("File") && !line.contains("File")) { // memory_str == "File": This is a help message! // skip action if entering client mode if (line.find("Set client to be True", 0, false) != -1) return IT_OTHER; if (memory == 14) // you have message emit signal_shout(tr("msg*"), line); else emit signal_message(txt); if (line.find("#>") != -1 && memory_str && !memory_str.contains("File")) return NOCLIENTMODE; return MESSAGE; } else { // remove command number line = line.remove(0, 2).stripWhiteSpace(); } // correct cmd_nr for special case; if quiet is set to false a game may not end... if (cmd_nr == 9 && line.contains("{Game")) { qDebug("command changed: 9 -> 21 !!!"); cmd_nr = 21; } // case 42 is equal to 7 if (cmd_nr == 42 && gsName != IGS) { // treat as game info cmd_nr = 7; qDebug("command changed: 42 -> 7 !!!"); } // process for different servers has particular solutions // command mode -> expect result switch (cmd_nr) { // PROMPT case 1: if (memory_str && (memory_str.contains("File")||memory_str.contains("STATS"))) // if ready this cannont be a help message memory_str = QString(); emit signal_message("\n"); return READY; break; // BEEP case 2: if (line.contains("Game saved")) { return IT_OTHER; } return BEEP; break; // ERROR message // 5 Player "xxxx" is not open to match requests. // 5 You cannot observe a game that you are playing. // 5 You cannot undo in this game // 5 Opponent's client does not support undoplease case 5: if (line.contains("No user named")) { QString name = element(line, 1, "\""); emit signal_talk(name, "@@@", true); } else if (line.contains("is not open to match requests")) { QString opp = element(line, 0, "\"", "\""); emit signal_notopen(opp); } else if (line.contains("player is currently not accepting matches")) { // IGS: 5 That player is currently not accepting matches. emit signal_notopen(0); } else if (line.contains("You cannot undo") || line.contains("client does not support undoplease")) { // not the cleanest way : we should send this to a messagez box emit signal_kibitz(0, 0, line); return KIBITZ; } // Debug: 5 There is a dispute regarding your match(nmatch): // Debug: 5 yfh2test request: B 3 19 420 900 25 0 0 0 // Debug: 5 yfh22 request: W 3 19 600 900 25 0 0 0 else if (line.contains("request:"))// && (element(line, 0, " ") != myname)) { QString p = element(line, 0, " "); if (p == myname) { memory_str = line ; return MESSAGE; } if (memory_str.contains(myname + " request")) { memory_str = ""; return MESSAGE; } QString nmatch_dispute = element(line, 1, " ", "EOL"); emit signal_dispute(p, nmatch_dispute); return MESSAGE; } emit signal_message(line); return MESSAGE; break; // games // 7 [##] white name [ rk ] black name [ rk ] (Move size H Komi BY FR) (###) // 7 [41] xxxx10 [ 1k*] vs. xxxx12 [ 1k*] (295 19 0 5.5 12 I) ( 1) // 7 [118] larske [ 7k*] vs. T08811 [ 7k*] (208 19 0 5.5 10 I) ( 0) // 7 [255] YK [ 7d*] vs. SOJ [ 7d*] ( 56 19 0 5.5 4 I) ( 18) // 7 [42] TetsuyaK [ 1k*] vs. ezawa [ 1k*] ( 46 19 0 5.5 8 I) ( 0) // 7 [237] s2884 [ 3d*] vs. csc [ 2d*] (123 19 0 0.5 6 I) ( 0) // 7 [67] atsukann [14k*] vs. mitsuo45 [15k*] ( 99 19 0 0.5 10 I) ( 0) // 7 [261] lbeach [ 3k*] vs. yurisuke [ 3k*] (194 19 0 5.5 3 I) ( 0) // 7 [29] ppmmuu [ 1k*] vs. Natta [ 2k*] (141 19 0 0.5 2 I) ( 0) // 7 [105] Clarky [ 2k*] vs. gaosg [ 2k*] ( 65 19 0 5.5 10 I) ( 1) case 7: if (line.contains("##")) // skip first line return GAME7_START;/* if (!line.contains('[')) { // no GAMES result -> leave GAMES mode return IT_OTHER; }*/ // get info line buffer = element(line, 0, "(", ")"); aGame->mv = buffer.left(3); buffer.remove(0, 4); aGame->Sz = element(buffer, 0, " "); aGame->H = element(buffer, 1, " "); aGame->K = element(buffer, 2, " "); aGame->By = element(buffer, 3, " "); aGame->FR = element(buffer, 4, " "); // parameter "true" -> kill blanks aGame->nr = element(line, 0, "[", "]", true); aGame->wname = element(line, 0, "]", "[", true); aGame->wrank = element(line, 1, "[", "]", true); // skip 'vs.' buffer = element(line, 1, "]", "[", true); aGame->bname = buffer.remove(0, 3); aGame->brank = element(line, 2, "[", "]", true); aGame->ob = element(line, 1, "(", ")", true); // indicate game to be running aGame->running = true; aGame->oneColorGo = false ; emit signal_game(aGame); emit signal_move(aGame); return GAME7; break; // "8 File" case 8: if (memory_str && memory_str.contains("File")) { // toggle memory_str = QString(); memory = 0; } else if (memory != 0 && memory_str && memory_str == "CHANNEL") { emit signal_channelinfo(memory, line); memory_str = QString(); return IT_OTHER; } else if (line.contains("File"))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -