home *** CD-ROM | disk | FTP | other *** search
- /*
- PMICS -- PM interface for playing chess on internet chess server
- Copyright (C) 1994 Kevin Nomura
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Author can be reached at email: chow@netcom.com
- */
- #include "wcomm.hh"
- #include "game.hh"
- #include "pmics.hh"
- #include <stdio.h>
- #include <stdlib.h>
- #include <ithread.hpp>
- #include <icolor.hpp>
- #include <ievtdata.hpp>
- #include <imsgbox.hpp>
- #include <ifont.hpp> // for font dialog
- #include <ifontdlg.hpp>
- #include <ireslib.hpp>
- //#define INCL_WINMESSAGEMGR
- #define INCL_WIN
- #include <os2.h>
- #include <strstrea.h>
- #include "session.hh"
- #include "engcom.hh"
- #include "dlgmatch.h"
-
- #define ICS_PROMPT "aics% "
-
- extern EngineComm *engineComm;
- extern ASession *aSession;
- extern int getIntOption(IString s, int def);
- extern IString getStringOption(IString s, IString def);
- void icshook(IString &);
- IWindowHandle hComm;
- strstream commStream;
-
- static void cancelBackspaces (IString &);
-
- void debugmsg(char *s, IWindow *w)
- {
- IMessageBox mb(w);
- mb.setTitle("debug msg");
- mb.show(s, IMessageBox::informationIcon |
- IMessageBox::yesNoCancelButton |
- IMessageBox::applicationModal |
- IMessageBox::moveable);
- }
-
- /**************************************************************************
- * FUNCTION: constructor (class CommWindow)
- *
- * DESCRIPTION: Build comm window. Uses IComboBox to simulate a
- * scrollable terminal window.
- *
- **************************************************************************/
- CommWindow::CommWindow(unsigned long windowId, //Constructor for this class
- IWindow *parent) :
- IListBox (windowId, parent, parent, IRectangle(),
- (IListBox::classDefaultStyle |
- IControl::tabStop) &
- ~(IListBox::horizontalScroll |
- IListBox::extendedSelect |
- IListBox::multipleSelect))
- {
- IFUNCTRACE_DEVELOP();
- hComm = handle(); // export commWindow handle
-
- /******************************************
- * attach IKeyboardHandler for keypresses
- ******************************************/
- handleEventsFor(this);
-
- /*****************************************
- * attach IEditHandler to see what it does
- ****************************************/
- /* editHandler = new CommEditHandler;
- editHandler->handleEventsFor(this);*/
-
- /**************************************
- * attach IHandler for general events
- **************************************/
- msgHandler = new CommMsgHandler(this);
- msgHandler->handleEventsFor(this);
-
- commFilter = new ACommFilterStyle12;
-
- localecho = getIntOption("localecho", 0) != 0;
-
- // setColor(IEntryField::background, IColor(0xff,0xff,0xcc));
- setFont(IFont(getStringOption("commfont", "System VIO"),
- getIntOption("commfontsize", 14)));
-
- show();
- } /* end PmicsWindow :: PmicsWindow(...) */
-
-
- Boolean CommWindow::key (IKeyboardEvent &evt)
- {
- char c,s[2];
- int i;
-
- if (evt.isUpTransition()) {
- return false;
- }
- IFUNCTRACE_DEVELOP(); // bypassed on up transition
-
- /********************************************************************
- * keyhandler screws up for control chars. they don't show up
- * as character events, but only as scancode events: and who wants
- * to fool with scancodes? we hafta drop down to PM and dig the char
- * out of the event data, sigh.
- ********************************************************************/
- if (evt.isCtrlDown()) {
- ITRACE_DEVELOP("control is down");
- if (evt.isVirtual() && evt.virtualKey() == IKeyboardEvent::ctrl)
- return false; // the ctrl key itself
- c = IEventData(evt.parameter2()).char1();
- ITRACE_DEVELOP("control pressed, data is: " + IString(c)+IString((int)c));
- if (c>='a' && c<='z')
- c = c - 'a' + 1;
- else if (c == '-') c = 31;
- else if (c == ']') c = 29;
- else if (c == '[') c = 27;
- else c = 127;
- s[0] = c;
- s[1] = 0;
- for (i = evt.isRepeat() ? evt.repeatCount() : 1; i; i--)
- aSession->write(s);
- }
-
- if (evt.isVirtual()) {
- ITRACE_DEVELOP("vkey: " + IString((unsigned short)(evt.virtualKey())) +
- " *" + IString(evt.repeatCount()));
- switch(evt.virtualKey()) {
- case IKeyboardEvent::backSpace:
- c = (bs2del) ? 127 : 8;
- ITRACE_DEVELOP("BS: deleting last character with " + IString((int)c));
- s[0] = c;
- s[1] = 0;
- for (i = evt.isRepeat() ? evt.repeatCount() : 1; i; i--)
- aSession->write(s);
- return true;
-
- case IKeyboardEvent::newLine:
- c = (cr2lf) ? 10 : 13;
- ITRACE_DEVELOP("CR: newLine maps to " + IString((int)c));
- s[0] = c;
- s[1] = 0;
- for (i = evt.isRepeat() ? evt.repeatCount() : 1; i; i--)
- aSession->write(s);
- return true;
- }
- //return false; // use default semantics for arrow keys, etc.
- // need fall thru for chars
- }
-
- if (evt.isCharacter()) {
- ITRACE_DEVELOP("key: " + IString((unsigned short)(evt.character())));
- if (evt.isRepeat() || evt.repeatCount() > 0)
- ITRACE_DEVELOP("repeatCount = "+IString(evt.repeatCount())+
- "isRepeat = "+IString(evt.repeatCount()));
- c = evt.character();
- if (evt.isCtrlDown()) {
- ITRACE_DEVELOP(" control: " + IString(c) + "=" + IString((int)c));
- if (c>='a' && c<='z')
- c = c - 'a' + 1;
- }
-
- /*if (c == '\r') {
- c = '\n';
- ITRACE_DEVELOP("<CR> -> <LF>");
- }*/
-
- s[0] = c;
- s[1] = 0;
- for (i = evt.isRepeat() ? evt.repeatCount() : 1; i; i--)
- aSession->write(s);
- timerTick(0); // reset idle counter
-
- /********************************************************
- * implement local echo
- ********************************************************/
- if (localecho) {
- int i = count() - 1;
- setItemText(i, itemText(i) + IString(c));
- }
-
- return true; // suppress listbox jump to line with first letter
- }
- return false;
- }
-
-
- /**************************************************************************
- * FUNCTION: lookForChallenge (class CommWindow)
- *
- * DESCRIPTION: Recognize a match request from another ICS player, and
- * pop up a requester that notifies the user and lets them accept,
- * reject or ignore the match request. Example challenge line:
- *
- * Challenge: DaveS (2068) [white] woof (1813) [un]rated blitz|wild(n)|standard 3 12 [5 0]
- *
- **************************************************************************/
- void CommWindow::lookForChallenge (IString &line)
- {
- int i, oppName, wildType, firstClock, secondClock;
- extern IWindow *mainWin;
- Boolean isRated, isWhite, isBlack;
-
- if (line.subString(1,10) != "Challenge:")
- return;
-
- // parse as blank-separated tokens, starting after "Challenge:"
- i = 2;
- isWhite = isBlack = isRated = false;
- wildType = 0;
-
- oppName = i;
- i++; i++; // consume opponent name and rating
- if (line.word(i)[1] == '[') { // color specification
- if (line.word(i) == "[white]")
- isWhite = true;
- else if (line.word(i) == "[black]")
- isBlack = true;
- i++; // consume color specification
- }
- i++; i++; // consume my name and rating
- isRated = (line.word(i) == "rated");
- i++; // consume rated specification
- if (line.word(i).subString(1,4) == "wild") {
- sscanf(line.word(i), "wild(%d)", &wildType);
- }
- i++; // consume blitz/standard/wild specification
- firstClock = i;
- i++; i++; // consume 1st time specification
- secondClock = 0;
- if (line.numWords() >= i+1) {
- secondClock = i;
- i++; i++; // consume odds time specification
- }
-
- ITRACE_DEVELOP("challenge: <"+line+">");
- AMatchDialog *dw = new AMatchDialog(IWindow::desktopWindow(),
- mainWin,
- this,
- line.words(oppName,2),
- isRated,
- isWhite,
- isBlack,
- wildType,
- line.words(firstClock,2),
- secondClock ? line.words(secondClock,2) : IString(""));
- }
-
- /**************************************************************************
- * FUNCTION: fontDialog (class CommWindow)
- *
- * DESCRIPTION: Let the user select a new text font for the comm window.
- *
- **************************************************************************/
- void CommWindow::fontDialog()
- {
- if (0)
- {
- // rated blitz
- IString s = "Challenge: caesar (1669) woof (1680) rated blitz 3 12";
- lookForChallenge(s);
-
- // unrated wild
- s = "Challenge: caesar (1669) woof (1680) unrated wild(5) 3 12";
- lookForChallenge(s);
-
- // rated wild 14, white, with time odds
- s = "Challenge: caesar (1669) [black] woof (1680) rated wild(14) 3 12 1 0";
- lookForChallenge(s);
- }
-
- IFont curfont(this);
- IFontDialog::Settings fsettings(&curfont);
- IFontDialog fd(IWindow::desktopWindow(),IWindow::desktopWindow(), fsettings);
-
- if (fd.pressedOK())
- setFont(curfont);
- }
-
-
- /**************************************************************************
- * FUNCTION: timerTick (class CommWindow)
- *
- * DESCRIPTION: Send a key to the UNIX host every 3 minutes to prevent
- * idle detection. Driven by 1-second interval timer tick (we share
- * the timer in PmicsWindow).
- *
- * ================ MAKE CONFIGURABLE =======================
- *
- **************************************************************************/
- void CommWindow::timerTick(int setCount)
- {
- static int count = 0;
- if (setCount >= 0)
- count = setCount;
- else
- count++;
- if ((count > 0) && (count % 360 == 0)) {
- ITRACE_DEVELOP("CommWindow::timerTick send keepalive char, count="+
- IString(count));
- aSession->write(" ");
- }
- }
-
-
- /**************************************************************************
- * FUNCTION: edit (class CommEditHandler)
- *
- * DESCRIPTION: This handler is supposed to intercept editing keys
- * inside the IComboBox.
- *
- **************************************************************************/
- Boolean CommEditHandler :: edit (IControlEvent &evt)
- {
- IFUNCTRACE_DEVELOP();
- char s[2], c;
-
- ITRACE_DEVELOP(IString("char1: ") +
- IString((unsigned short)(evt.parameter1().char1())) +
- IString(" char2: ") +
- IString((unsigned short)(evt.parameter1().char2())) +
- IString(" char3: ") +
- IString((unsigned short)(evt.parameter1().char3())) +
- IString(" char4: ") +
- IString((unsigned short)(evt.parameter1().char4())));
- ITRACE_DEVELOP(IString("char1: ") +
- IString((unsigned short)(evt.parameter2().char1())) +
- IString(" char2: ") +
- IString((unsigned short)(evt.parameter2().char2())) +
- IString(" char3: ") +
- IString((unsigned short)(evt.parameter2().char3())) +
- IString(" char4: ") +
- IString((unsigned short)(evt.parameter2().char4())) +
- IString(" *") +
- IString((unsigned short)(evt.parameter1().char3())));
- if (!(evt.parameter1() & KC_KEYUP)) {
- ITRACE_DEVELOP("keydown event");
- }
- if ((evt.parameter1() & KC_CTRL)) {
- ITRACE_DEVELOP("ctrl event");
- }
-
- return false;
- }
-
-
-
- /**************************************************************************
- * FUNCTION: dispatchHandlerEvent (class CommMsgHandler)
- *
- * DESCRIPTION: handler for general window messages
- *
- * MESSAGES: MSG_COM_IN - arbitrary-sized block of incoming data
- * MSG_COM_FONT - user requested to change comm window font
- *
- **************************************************************************/
- Boolean CommMsgHandler::dispatchHandlerEvent (IEvent &evt)
- {
- // IFUNCTRACE_DEVELOP();
- CommWindow *cwin = (CommWindow *)evt.window();
-
- switch (evt.eventId()) {
- case MSG_COM_IN:
- /**************************************************************************
- * Blocks of incoming data are relayed here from the session object for
- * processing. (1) Display the data in the comm window. The comm window
- * works in terms of lines so we must break the data apart at line
- * boundaries, and also know when the last line of the previous block
- * is unfinished and needs to be continued. (2) Build a line stream.
- * Run the resulting complete lines through a filter which looks for
- * challenges.
- *************************************************************************/
- {
- char buf[4000];
- static IString line,prevline;
- static Boolean continued = false; // if last line not terminated
- static Boolean filterNextPrompt = false; // cosmetics
- int linelen, peekc;
-
- while(1) {
-
- commStream.get(buf, sizeof(buf));
- if (commStream.fail()) break;
- line = IString(buf);
- if ((peekc = commStream.peek()) == '\n')
- commStream.get();
-
- // strip trailing CR (getline broke at LF of CRLF pair)
- line.strip("\n\r");
- // line.strip("\r");
-
- ITRACE_DEVELOP("MSG_COM_IN <"+line+">");
-
- /********************************************************
- * if last line was not terminated, append this line to it
- ********************************************************/
- // cwin->setCursorAt(cwin->textLength());
- if (continued) {
- CommWindow::Cursor cur(*commWindow, CommWindow::Cursor::allItems);
- cur.setToLast();
- line = prevline + line;
- ITRACE_DEVELOP("Continuing previous line: now <"+line+">");
- continued = (commStream.peek() == EOF && peekc != '\n');
- cancelBackspaces(line);
- if (line.subString(1,4) != "<12>")
- cwin->replaceAt(line, cur);
- }
- else {
- /**************************************************
- * otherwise add this line as a new line at the end
- **************************************************/
- if (line.subString(1,4) != "<12>")
- cwin->addAsLast(line);
- }
-
- if (filterNextPrompt) {
- // if hit, delete the line. else, clear the bit if line is not
- // a prefix of the prompt, meaning prompt did not follow the move
- // string for some reason.
- if (line == ICS_PROMPT) {
- cwin->remove(cwin->count() - 1);
- filterNextPrompt = false;
- }
- else if (IString(ICS_PROMPT).indexOf(line) != 1)
- filterNextPrompt = false;
- }
-
- /**************************************************************
- * predict if this line is continued, and if not, run through
- * move capture filter
- **************************************************************/
- if (! ((commStream.peek() == EOF && peekc != '\n'))) {
- if (cwin->commFilter->filter(line)) {
- /* cwin->remove(cwin->count() - 1);*/
- filterNextPrompt = true;
- }
- else
- cwin->lookForChallenge(line);
- }
- // could add a hook here to login to a dialup system
- //icshook(line);
- prevline = line;
- }
- continued = (commStream.peek() == EOF && peekc != '\n');
-
- /***************************************************************
- * manage number of lines in listbox and the cursor position
- ***************************************************************/
- if (cwin->count() > 300) {
- // first get down to 300 for sure
- while (cwin->remove(0) > 300) ;
- // now delete 10% more (to prevent thrashing on continuous input)
- for (int i=0; i<30; i++)
- cwin->remove(0);
- }
-
- /**************************************************************
- * scroll listbox to bottom by setting 'top' to the last line
- **************************************************************/
- cwin->setTop(cwin->count());
-
- evt.setResult(0);
- return true;
- }
- break;
-
- case MSG_COM_FONT:
- ITRACE_DEVELOP("comm window: font message has arrived");
- cwin->fontDialog();
- return true;
- }
- return false;
- }
-
-
-
- /**************************************************************************
- * FUNCTION: filter (class ACommFilterStyle12)
- *
- * DESCRIPTION: parse style 12 move messages from ICS
- * This notifies us that a move has been made in the game, and new
- * status information is available (clocks, etc). The information
- * is digested and posted to the stat and board windows for display.
- *
- * ics% help style12
- * A new style 12 now exists. It has all the advantages of style 8 and
- * style 10. Furthermore, style 12 inhibits the messages "OBSERVATION
- * REPORT" and "Game 7 (Quimbee vs. Darooha)". (Actually, I may make
- * this a feature of terse mode. In any event, don't depend on those
- * messages.)
- *
- * The data is all on one line: Here is an example:
- *
- * <12> rnbqkb-r pppppppp -----n-- -------- ----P--- -------- PPPPKPPP RNBQ-BNR B -
- * 1 0 0 1 1 0 7 Quimbee Darooha 1 2 12 39 39 119 122 2 K/e1-e2 (0:06) Ke2
- *
- * This always begins on a new line, and there are always exactly 30
- * non-empty fields separated by blanks. They are:
- *
- * - The string "<12>" to identify this line.
- * - eight fields representing the board position. The first one is file 8,
- * then file 7, etc, regardless of who's move it is.
- * - color whose turn it is to move ("B" or "W")
- * - -1 if the previous move was NOT a double pawn push,
- * otherwise the file (numbered 0--7 for a--h) in which
- * the double push was made
- * - can white still castle short? (0=no, 1=yes)
- * - can white still castle long?
- * - can black still castle short?
- * - can black still castle long?
- * - the number of moves made since the last irreversible move.
- * (0 if last move was irreversible. If this is >= 100, the game
- * can be declared a draw due to the 50 move rule.)
- * - The game number
- * - White's name
- * - Black's name
- * - is it my turn to move in this game? (1=yes, -1=opponent's move,
- * 0=observing)
- * - initial time (in seconds) of the match
- * - increment of the match
- * - white strength
- * - black strength
- * - white's remaining time
- * - black's remaining time
- * - the number of the move about to be made
- * (standard chess numbering -- White's and Black's first moves
- * are both 1, etc.)
- * - verbose coordinate notation for the previous move ("none" if
- * there were none)
- * - time taken to make previous move "(min:sec)".
- * - pretty notation for the previous move ("none" if there is none)
- *
- * New fields may be added to the end in the future, so programs should
- * parse from left to right.
- **************************************************************************/
- Boolean ACommFilterStyle12::filter(IString &line)
- {
- int gameNum, moveNum, timeW, timeB, lastMoveTime, clockRun;
- char playerW[17], playerB[17];
- IString moveAlg, engMove;
-
- struct statData {
- char onMove;
- int wClock, bClock, gameNum;
- char wName[32], bName[32], move[32];
- } *p;
-
- char *pfld[30], *token;
- int min, sec, whosemove;
- enum {S12_ID=0, S12_RANK1, S12_RANK2, S12_RANK3, S12_RANK4, S12_RANK5,
- S12_RANK6, S12_RANK7, S12_RANK8, S12_ONMOVE, S12_ENPASSANT,
- S12_W00, S12_W000, S12_B00, S12_B000, S12_DRAWCTR, S12_GAMENUM,
- S12_WNAME, S12_BNAME, S12_WHOSEMOVE, S12_INITCLOCK, S12_INCR,
- S12_WMATERIAL, S12_BMATERIAL, S12_WTIME, S12_BTIME,
- S12_MOVENUM, S12_MOVERAW, S12_MOVETIME, S12_MOVEALG};
- AGame *currentGame;
- static int failCount = 0;
-
- IFUNCTRACE_DEVELOP();
-
- if (line.subString(1,4) != "<12>")
- return false;
-
- ITRACE_DEVELOP(line);
-
- /************************************************************************
- * tokenize line into blank-separated fields; verify they're all present
- ************************************************************************/
- token = strtok((char *)line, " ");
- for (int i = 0; i < 30; i++) {
- if (token == NULL) {
- // this has been happening lately so we'll recover by issuing
- // a refresh command.
- ITRACE_DEVELOP("error in style12: line ends too soon i=" + IString(i));
- if (++failCount < 3)
- aSession->write("refresh\nrefresh\n");
- return false; // error! recovery: ignore (should warn user)
- }
- pfld[i] = token;
- token = strtok((char *)NULL, " "); // dont care about tokens after 30th
- }
-
- sscanf(pfld[S12_GAMENUM], "%3d", &gameNum);
- sscanf(pfld[S12_WNAME], "%16s", &playerW);
- sscanf(pfld[S12_BNAME], "%16s", &playerB);
- sscanf(pfld[S12_MOVENUM], "%3d", &moveNum);
- sscanf(pfld[S12_WTIME], "%5d", &timeW);
- sscanf(pfld[S12_BTIME], "%5d", &timeB);
- sscanf(pfld[S12_MOVETIME], "(%d:%d)", &min, &sec);
- sscanf(pfld[S12_WHOSEMOVE], "%d", &whosemove);
- lastMoveTime = min*60+sec;
- clockRun = TRUE;
- moveAlg = IString(pfld[S12_MOVEALG]);
-
- /**********************************
- * post stat window with new info
- **********************************/
- p = new struct statData;
- p->wClock = timeW;
- p->bClock = timeB;
- p->onMove = pfld[S12_ONMOVE][0];
- strcpy(p->wName, playerW);
- strcpy(p->bName, playerB);
- p->gameNum = gameNum;
- if (pfld[S12_ONMOVE][0] == 'B')
- strcpy(p->move, IString(moveNum) + ". " + moveAlg);
- else
- strcpy(p->move, IString(moveNum-1) + "... " + moveAlg);
-
- hMain.postEvent(MSG_STAT_UPDATE, (void *)p);
-
- hMain.postEvent(pfld[S12_ONMOVE][0] == 'W' ?
- MSG_STAT_WHITE_ONMOVE :
- MSG_STAT_BLACK_ONMOVE,
- (ULONG) whosemove);
-
- /*************************************************************************
- * send moves of active game to engine
- * reformat as coordinate notation with promotion piece at end, e.g. a7b8q
- *************************************************************************/
- engMove = IString(pfld[S12_MOVERAW]);
- if (whosemove == 1) {
- if (engMove[2] == '/') { // P/e2-e4=Q (castling is sent verbatim)
- int eqpos;
- engMove.remove(1,2);
- engMove.remove(3,1);
- engMove.remove(5);
- if (eqpos = moveAlg.indexOf('=')) { // promotion indicator
- engMove += moveAlg.subString(eqpos+1,1).lowerCase();
- }
- }
- engineComm->sendCommand(engMove);
- }
-
- currentGame = AGame::current();
- for (int rank=0; rank<8; rank++) {
- for (int file=0; file<8; file++) {
- currentGame->setPiece(file, rank,
- AGame::toPiece(pfld[S12_RANK8 - rank][file]));
- }
- }
-
- /********************************************************
- * if initial position, initialize some state objects
- ********************************************************/
- if (moveNum==1 && strcmp("W", pfld[S12_ONMOVE]) == 0) {
- ITRACE_DEVELOP("New game starting. whosemove=" + IString(whosemove));
- if (whosemove == 1) // my move so put white at bottom
- hBoard.postEvent(MSG_BOARD_WHITE_AT_BOTTOM);
- else if (whosemove == -1) // my opponent's move so put black at bottom
- hBoard.postEvent(MSG_BOARD_WHITE_AT_TOP);
- else // observing only. put white at bottom.
- hBoard.postEvent(MSG_BOARD_WHITE_AT_BOTTOM);
-
- engineComm->sendCommand("new");
- }
-
- else
- hBoard.postEvent(MSG_BOARD_UPDATE);
-
- failCount = 0;
- return true;
- }
-
-
- static void cancelBackspaces (IString &s)
- {
- int i;
-
- while ((i = s.indexOf('\b')) > 1) {
- s.remove(i-1,2); // cancel BS and previous char
- }
- }
-
-
- void icshook (IString &s)
- {
- static int next = 0;
- static char *script[] = {
- "help abort",
- "help abuse",
- "help abusers",
- "help accept",
- "help ACM",
- "help addresses",
- "help adjourn",
- "help adjudicate",
- "help admins",
- "help alias",
- "help allobservers",
- "help assess",
- "help atmosphere",
- "help backward",
- "help bell",
- "help best",
- "help bugs",
- "help channel",
- "help clearmessages",
- "help cls",
- "help computers",
- "help courtesyabort",
- "help credits",
- "help date",
- "help decline",
- "help definitions",
- "help doah",
- "help draw",
- "help eco",
- "help examine",
- "help exit",
- "help filters",
- "help finger",
- "help flag",
- "help flip",
- "help formula",
- "help fortune",
- "help forward",
- "help ftp-hints",
- "help games",
- "help GIICS",
- "help GMs",
- "help gnusurf",
- "help goodpasswd",
- "help handle",
- "help help",
- "help history",
- "help i",
- "help ICS",
- "help ICS-InTheNews",
- "help inchannel",
- "help index",
- "help InetChessLibrary",
- "help interfaces",
- "help intro1",
- "help intro10",
- "help intro11",
- "help intro2",
- "help intro3",
- "help intro4",
- "help intro5",
- "help intro6",
- "help intro7",
- "help intro8",
- "help intro9",
- "help Isbjoern",
- "help kibitz",
- "help lag",
- "help lagflag",
- "help lhistory",
- "help LinaresRoundup",
- "help lists",
- "help llogons",
- "help logons",
- "help mailhelp",
- "help mailoldmoves",
- "help mailstored",
- "help match",
- "help messages",
- "help mexamine",
- "help minus",
- "help mood",
- "help moretime",
- "help motd",
- "help moves",
- "help muzzle",
- "help new",
- "help notation",
- "help notify",
- "help nuke",
- "help observe",
- "help odds-games",
- "help oldmoves",
- "help open",
- "help password",
- "help PCA-candidates",
- "help pending",
- "help people",
- "help players",
- "help plus",
- "help programmers",
- "help promote",
- "help quit",
- "help quota",
- "help rank",
- "help rated",
- "help ratings",
- "help records",
- "help refresh",
- "help refresh",
- "help registration",
- "help registration",
- "help resign",
- "help revert",
- "help rules",
- "help say",
- "help server",
- "help set",
- "help shout",
- "help smoves",
- "help splay-tree",
- "help sposition",
- "help sshout",
- "help statistics",
- "help stored",
- "help style",
- "help style",
- "help style10",
- "help style12",
- "help suggestions",
- "help takeback",
- "help team-games",
- "help tell",
- "help terse-mode",
- "help time",
- "help tournaments",
- "help Tourny-Rishi",
- "help TournyWC",
- "help unexamine",
- "help upstatistics",
- "help vars",
- "help vars",
- "help whisper",
- "help who",
- "help who1",
- "help who2",
- "help wild",
- "help wild10",
- "help wild11",
- "help wild12",
- "help wild13",
- "help wild14",
- "help wild5",
- "help wild6",
- "help wild7",
- "help wild8",
- "help wild9",
- "help xtell",
- "help znotl",
- ""};
- if (next == -1) return;
- if (script[next][0] == 0) {next = -1; return;}
- if (s == "aics% ") {
- aSession->write(IString(script[next]) + "\n");
- next++;
- }
- return;
- }
-
- /**************************************************************************
- * FUNCTION: constructor (class AMatchDialog)
- *
- * DESCRIPTION:
- *
- **************************************************************************/
- AMatchDialog:: AMatchDialog(IWindow *parent, // ctor for this class
- IWindow *owner,
- IWindow *commWin,
- IString cName,
- int cIsRated,
- int cWildType,
- int cIsWhite,
- int cIsBlack,
- IString cClock,
- IString cOddsClock) :
- IFrameWindow (DID_MATCH, parent, owner)
- {
- handleEventsFor(this); // set self as command event handler
-
- /**********************************************
- * save comm window to restore focus by
- * setFocus call when dialog is dismissed
- *********************************************/
- commWind = commWin;
-
- /*******************************************
- * set opponent and time control text values
- *******************************************/
- clock = new IEntryField(DID_MATCH_CLOCK, this);
- clock->setText(cClock);
-
- oddsClock = new IEntryField(DID_MATCH_ODDSCLOCK, this);
- if (cOddsClock != "") {
- oddsClock->setText(cOddsClock);
- }
-
- opponent = new IStaticText(DID_MATCH_OPPONENT, this);
- opponent->setText(cName);
-
- /*******************************************
- * set rated, wild, colour buttons
- *******************************************/
- rated = new ICheckBox(DID_MATCH_RATED, this);
- if (cIsRated)
- rated->select();
-
- wild = new ICheckBox(DID_MATCH_WILD, this);
- wildType = new IEntryField(DID_MATCH_WILDTYPE, this);
- if (cWildType) {
- wild->select();
- wildType->setText(IString(cWildType));
- }
-
- white = new IRadioButton(DID_MATCH_WHITE, this);
- black = new IRadioButton(DID_MATCH_BLACK, this);
- neutral = new IRadioButton(DID_MATCH_NEUTRAL, this);
- if (cIsWhite)
- white->select();
- else if (cIsBlack)
- black->select();
- else
- neutral->select();
-
- /******************************************************************
- * attach a handler to process check/radio box selections
- ******************************************************************/
- selectHdr = new AMatchSelectHandler();
- selectHdr->handleEventsFor(this);
-
- /******************************************************************
- * save initial parameters: if final parameters are the same,
- * issue Accept instead of Match, because ics may reject a Match
- * on the basis of Formulae.
- ******************************************************************/
- initialClock = cClock;
- initialOddsClock = cOddsClock;
- initialRated = cIsRated;
- initialWhite = cIsWhite;
- initialBlack = cIsBlack;
- initialWildType = cWildType;
- show();
- }
-
- /**************************************************************************
- * FUNCTION: command (class AMatchDialog)
- *
- * DESCRIPTION: event handler for dialog Accept/Ignore/Decline pushbuttons
- *
- **************************************************************************/
- Boolean AMatchDialog:: command(ICommandEvent &cmdevt)
- {
- IFUNCTRACE_DEVELOP();
- switch(cmdevt.commandId()) {
- case DID_MATCH_ACCEPT:
- {
- IString s;
- ITRACE_DEVELOP("match accepted");
- /******************************************************************
- * figure out if any parameters changed. if identical to the
- * original challenge issue "accept", else issue "match" with
- * all parameters specified explicitly. this distinction is
- * because the opponent can issue a challenge that does not
- * satisfy his own formula (e.g. he issues a rated challenge
- * and his formula says unrated only) and if we echo back the match
- * command ics will reject it.
- ******************************************************************/
- if (clock->text() == initialClock &&
- oddsClock->text() == initialOddsClock &&
-
- wild->isSelected() == (initialWildType != 0) &&
- wildType->text() == IString(initialWildType) &&
-
- rated->isSelected() == initialRated &&
-
- white->isSelected() == initialWhite &&
- black->isSelected() == initialBlack) {
- s = "\naccept "+ opponent->text().word(1) + "\n";
- }
- else {
- //match <name> <time> <increment> <time2> <increment2> <r> <u> <wk> <color>
- s = "\nmatch "+ opponent->text().word(1)+" "+ clock->text()+" ";
- if (oddsClock->text() != IString(""))
- s += oddsClock->text()+" ";
- s += (rated->isSelected()) ? "r " : "u ";
- if (wild->isSelected() && wildType->text() != IString(""))
- s += "w"+wildType->text()+" ";
- if (white->isSelected())
- s += "white ";
- if (black->isSelected())
- s += "black ";
- s += "\n";
- }
- aSession->write(s);
- dismiss();
- commWind->setFocus();
- break;
- }
- case DID_MATCH_IGNORE:
- ITRACE_DEVELOP("match ignored");
- dismiss();
- commWind->setFocus();
- break;
- case DID_MATCH_DECLINE:
- ITRACE_DEVELOP("match declined");
- aSession->write(IString("\ndecline ")+opponent->text().word(1)+"\n");
- dismiss();
- commWind->setFocus();
- break;
- }
- return false; // pass to default processing
- }
-
-
- /**************************************************************************
- * FUNCTION: command (class AMatchSelectHandler)
- *
- * DESCRIPTION: event handler for dialog radiobuttons and checkboxes
- *
- **************************************************************************/
- Boolean AMatchSelectHandler:: selected(IControlEvent &evt)
- {
- AMatchDialog *dlg = (AMatchDialog *)evt.window();
-
- IFUNCTRACE_DEVELOP();
- switch(evt.controlId()) {
- case DID_MATCH_RATED:
- ITRACE_DEVELOP("match rated checked");
- break;
- case DID_MATCH_WILD:
- ITRACE_DEVELOP("match wild checked");
- break;
- case DID_MATCH_WHITE:
- ITRACE_DEVELOP("match white checked");
- dlg->black->deselect();
- dlg->neutral->deselect();
- break;
- case DID_MATCH_BLACK:
- ITRACE_DEVELOP("match black checked");
- dlg->white->deselect();
- dlg->neutral->deselect();
- break;
- case DID_MATCH_NEUTRAL:
- ITRACE_DEVELOP("match neutral checked");
- dlg->white->deselect();
- dlg->black->deselect();
- break;
- }
- return false; // pass to default processing
- }
-