/***************************************************************************
io_internet . cpp - description
- - - - - - - - - - - - - - - - - - -
begin : Thu Aug 16 2001
copyright : ( C ) 2003 by Troy Corbin Jr .
email : tcorbin @ users . sourceforge . net
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/***************************************************************************
* *
* 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 . *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* KDE */
# include <ksock.h>
# include <kprocess.h>
# include <tdemessagebox.h>
/* TQt */
# include <tqobject.h>
# include <tqwidget.h>
# include <tqregexp.h>
# include <tqdns.h>
# include <tqsocket.h>
# include <tqptrlist.h>
/* Local */
# include "io_internet.moc"
# include "resource.h"
# include "dlg_login.h"
# include "dlg_challenge.h"
# include "match.h"
# include "core.h"
# include "audio.h"
# include "../config.h"
static const int TXT_Std = 0 ;
static const int TXT_Pvt = 1 ;
static const int TXT_Ch = 2 ;
static const int TXT_Sht = 3 ;
static const int TXT_Wsp = 4 ;
static const int TXT_Not = 5 ;
io_internet : : io_internet ( TQWidget * parent , resource * rsrc )
{
myResource = rsrc ;
challenge = NULL ;
myTimeseal = NULL ;
socket = NULL ;
loginStage = LOGIN_STAGE_NAME ;
lineBuffer = " " ;
Log = NULL ;
/* set type */
this - > myType = io_base : : INTERNET ;
/* initialize various variables */
this - > waiting_for_move_list = false ;
this - > myParent = parent ;
connected = false ; /* we are not connected to a server */
/* create the login dialog and show it to the user */
loginDlg = new dlg_login ( myParent , " LoginDialog " , myResource ) ;
connect ( loginDlg , TQT_SIGNAL ( okClicked ( ) ) , this , TQT_SLOT ( connectToServer ( ) ) ) ;
connect ( loginDlg , TQT_SIGNAL ( cancelClicked ( ) ) , this , TQT_SLOT ( selfDestruct ( ) ) ) ;
connect ( loginDlg , TQT_SIGNAL ( login ( TQString , TQString ) ) , this , TQT_SLOT ( setUserInfo ( TQString , TQString ) ) ) ;
}
///////////////////////////////////////////////////////////
// Destructor
///////////////////////////////////////////////////////////
io_internet : : ~ io_internet ( )
{
TabMap : : Iterator i ;
/* Close and remove socket */
if ( socket ! = NULL )
{
if ( socket - > socket ( ) ! = - 1 )
{
send ( " quit " ) ;
}
delete socket ;
}
/* Close and remove logfile */
if ( Log )
{
Log - > close ( ) ;
delete Log ;
Log = NULL ;
}
/* Remove Timeseal */
if ( myTimeseal ! = NULL )
{
myTimeseal - > kill ( ) ;
delete myTimeseal ;
}
/* Close and remove Tabs */
for ( i = myTabList . begin ( ) ; i ! = myTabList . end ( ) ; i + + )
{
if ( myResource - > tabManager - > isTab ( * i ) )
{
myResource - > tabManager - > removeTab ( TQT_TQOBJECT ( * i ) ) ;
}
}
}
void io_internet : : connectToServer ( )
{
serverList : : iterator i ;
TQWidget * tempTab ;
TQWidget * consoleTab ;
TQValueList < Command > : : iterator j ;
tqApp - > mainWidget ( ) - > setCursor ( myResource - > CURSOR_Thinking ) ;
/* Get and parse server config from resource */
myServer = NULL ;
for ( i = myResource - > servers . begin ( ) ; i ! = myResource - > servers . end ( ) ; i + + )
{
if ( ( * i ) . CurrentRef )
{
myServer = & ( * i ) ;
}
}
if ( myServer = = NULL )
{
/* No server configured. Notify User and die gracefully */
tqApp - > mainWidget ( ) - > setCursor ( myResource - > CURSOR_Standard ) ;
kdError ( ) < < " internetio::internetio: Can not find server resource CurrentRef " < < endl ;
KMessageBox : : sorry ( ( TQWidget * ) myParent , i18n ( " There are no servers configured. \n Please make sure you have at least one server configured. " ) , i18n ( " Cannot find a server. " ) ) ;
TQApplication : : postEvent ( tqApp - > mainWidget ( ) , new TQCustomEvent ( EVENT_Del_IO_Net ) ) ;
return ;
}
if ( myServer - > Port = = 0 )
{
myServer - > Port = 5000 ;
}
if ( ! myServer - > Timeseal . isEmpty ( ) )
{
myTimeseal = new TDEProcess ( ) ;
( * myTimeseal ) < < myServer - > Timeseal < < myServer - > URL < < TQString ( ) . setNum ( myServer - > Port )
< < TQString ( " -p " ) < < TQString ( ) . setNum ( myServer - > Port + 1 ) ;
if ( ! myTimeseal - > start ( ) )
{
/* Couldn't start Timeseal. Notify User and die gracefully */
tqApp - > mainWidget ( ) - > setCursor ( myResource - > CURSOR_Standard ) ;
KMessageBox : : sorry ( ( TQWidget * ) myParent , i18n ( " Knights can not start Timeseal. \n Please make sure you have the correct path and filename configured. " ) , i18n ( " Cannot find Timeseal. " ) ) ;
TQApplication : : postEvent ( tqApp - > mainWidget ( ) , new TQCustomEvent ( EVENT_Del_IO_Net ) ) ;
return ;
}
socket = new TDESocket ( " 127.0.0.1 " , myServer - > Port + 1 , 30 ) ;
if ( socket - > socket ( ) = = - 1 )
{
/* try again on a different port, somehow the port hasn't been freed yet */
delete socket ;
myTimeseal - > kill ( ) ;
myTimeseal = new TDEProcess ( ) ;
( * myTimeseal ) < < myServer - > Timeseal < < myServer - > URL < < TQString ( ) . setNum ( myServer - > Port )
< < TQString ( " -p " ) < < TQString ( ) . setNum ( myServer - > Port + 2 ) ;
if ( ! myTimeseal - > start ( ) )
{
/* Couldn't start Timeseal. Notify User and die gracefully */
tqApp - > mainWidget ( ) - > setCursor ( myResource - > CURSOR_Standard ) ;
KMessageBox : : sorry ( ( TQWidget * ) myParent , i18n ( " Knights can not start Timeseal. \n Please make sure you have the correct path and filename configured. " ) , i18n ( " Cannot find Timeseal. " ) ) ;
TQApplication : : postEvent ( tqApp - > mainWidget ( ) , new TQCustomEvent ( EVENT_Del_IO_Net ) ) ;
return ;
}
socket = new TDESocket ( " 127.0.0.1 " , myServer - > Port + 2 , 30 ) ;
if ( socket - > socket ( ) = = - 1 )
{
/* if we can't do it the second time, give up */
/* Couldn't connect to server through Timeseal. Notify User and die gracefully */
tqApp - > mainWidget ( ) - > setCursor ( myResource - > CURSOR_Standard ) ;
KMessageBox : : sorry ( ( TQWidget * ) myParent , i18n ( " Knights is unable to connect to the server. \n Please make sure your internet connection is working and try again. " ) , i18n ( " Cannot connect to server(timeseal). " ) ) ;
TQApplication : : postEvent ( tqApp - > mainWidget ( ) , new TQCustomEvent ( EVENT_Del_IO_Net ) ) ;
return ;
}
}
}
else
{
socket = new TDESocket ( myServer - > URL . utf8 ( ) , myServer - > Port , 30 ) ;
if ( socket - > socket ( ) = = - 1 )
{
/* Couldn't connect to server. Notify User and die gracefully */
tqApp - > mainWidget ( ) - > setCursor ( myResource - > CURSOR_Standard ) ;
KMessageBox : : sorry ( ( TQWidget * ) myParent , i18n ( " Knights is unable to connect to the server. \n Please make sure your internet connection is working and try again. " ) , i18n ( " Cannot connect to server. " ) ) ;
TQApplication : : postEvent ( tqApp - > mainWidget ( ) , new TQCustomEvent ( EVENT_Del_IO_Net ) ) ;
return ;
}
}
socket - > enableRead ( true ) ;
socket - > enableWrite ( true ) ;
/* connect a signal to readReady */
connect ( socket , TQT_SIGNAL ( readEvent ( TDESocket * ) ) , this , TQT_SLOT ( readCommand ( TDESocket * ) ) ) ;
/* setup the seekTimer and turn it off by default */
seekTimer = new TQTimer ( this ) ;
connect ( seekTimer , TQT_SIGNAL ( timeout ( ) ) , this , TQT_SLOT ( processSeekTimer ( ) ) ) ;
/* succesfully connected to the server, turn connected on and flush the command buffer */
connected = true ;
for ( j = myCommandBuffer . begin ( ) ; j ! = myCommandBuffer . end ( ) ; j + + )
{
recvCMD ( * j ) ;
}
/*
Create ICS Related Tabs
These will need to be moved into thier own functions because we want to be able to open
and close these tabs at will , or have multiple open at once . ALL communication to our tabs
needs to be done with SIGNALS & SLOTS to facilitate this .
*/
consoleTab = new Console ( 0 , myServer - > Name . utf8 ( ) , myResource ) ;
myTabList [ consoleTab ] = consoleTab ;
myResource - > tabManager - > addTab ( myTabList [ consoleTab ] , i18n ( " %1 Console " ) . arg ( myServer - > Name ) ) ;
connect ( myTabList [ consoleTab ] , TQT_SIGNAL ( sendCMD ( const Command & ) ) , this , TQT_SLOT ( recvCMD ( const Command & ) ) ) ;
connect ( this , TQT_SIGNAL ( sendCMD ( const Command & ) ) , myTabList [ consoleTab ] , TQT_SLOT ( recvCMD ( const Command & ) ) ) ;
tempTab = new tab_SeekList ( 0 , " seekList " , myResource ) ;
myTabList [ tempTab ] = tempTab ;
myResource - > tabManager - > addTab ( myTabList [ tempTab ] , i18n ( " Sought Matches List " ) ) ;
connect ( myTabList [ tempTab ] , TQT_SIGNAL ( sendCMD ( const Command & ) ) , this , TQT_SLOT ( recvCMD ( const Command & ) ) ) ;
connect ( this , TQT_SIGNAL ( sendCMD ( const Command & ) ) , myTabList [ tempTab ] , TQT_SLOT ( recvCMD ( const Command & ) ) ) ;
tempTab = new Challenge_Graph ( 0 , " seekGraph " , myResource ) ;
myTabList [ tempTab ] = tempTab ;
myResource - > tabManager - > addTab ( myTabList [ tempTab ] , i18n ( " Sought Matches Graph " ) ) ;
connect ( myTabList [ tempTab ] , TQT_SIGNAL ( sendCMD ( const Command & ) ) , this , TQT_SLOT ( recvCMD ( const Command & ) ) ) ;
connect ( this , TQT_SIGNAL ( sendCMD ( const Command & ) ) , myTabList [ tempTab ] , TQT_SLOT ( recvCMD ( const Command & ) ) ) ;
myResource - > tabManager - > showTab ( consoleTab ) ;
/* ...log file */
if ( ! myServer - > LogFile . isEmpty ( ) )
{
Log = new TQFile ( myServer - > LogFile ) ;
if ( ! Log - > open ( IO_WriteOnly | IO_Append ) )
{
if ( ! Log - > open ( IO_WriteOnly ) )
{
kdError ( ) < < " Can not open " < < myServer - > LogFile < < " for writing. " < < endl ;
}
}
}
tqApp - > mainWidget ( ) - > setCursor ( myResource - > CURSOR_Standard ) ;
}
void io_internet : : recvCMD ( const Command & command )
{
TQString error_message ;
if ( ! connected )
{
myCommandBuffer . push_back ( command ) ;
return ;
}
switch ( ( ( Command ) command ) . getCommand ( ) )
{
case CMD_Move :
send ( ( ( Command ) command ) . getMove ( ) . SAN ) ;
break ;
case CMD_Reset_Server :
sendUserSettings ( ) ;
break ;
case CMD_Toggle_Seek :
if ( seekTimer - > isActive ( ) )
{
/* timer running stop it */
seekTimer - > stop ( ) ;
emit sendCMD ( Command ( 0 , CMD_Hide_Sought_List ) ) ;
}
else
{
/* timer not running start it */
seekTimer - > start ( myResource - > Seek_Timer * 100 ) ;
/* send a sought now */
processSeekTimer ( ) ;
}
break ;
case CMD_Player_Finger :
send ( " $finger " + ( ( Command ) command ) . getData ( ) ) ;
break ;
case CMD_Add_Friend :
send ( " $+notify " + ( ( Command ) command ) . getData ( ) ) ;
break ;
case CMD_Ignore_Player :
send ( " $+censor " + ( ( Command ) command ) . getData ( ) ) ;
break ;
case CMD_Player_History :
send ( " $history " + ( ( Command ) command ) . getData ( ) ) ;
break ;
case CMD_Start_Match :
send ( " $play " + ( ( Command ) command ) . getData ( ) ) ;
break ;
case CMD_Assess :
send ( " $assess " + ( ( Command ) command ) . getData ( ) ) ;
break ;
case CMD_Set_Input :
sendCMD ( command ) ;
break ;
case CMD_Send_To_ICS :
if ( ( ( Command ) command ) . getData ( ) . contains ( TQRegExp ( " ^(?: \\ .|tell) " ) ) )
{
writeToConsole ( ( ( Command ) command ) . getData ( ) , " K_PVT " ) ;
}
send ( ( ( Command ) command ) . getData ( ) ) ;
break ;
case CMD_Examine_Forward :
send ( " $forward 1 " ) ;
break ;
case CMD_Examine_Backward :
send ( " $backward 1 " ) ;
break ;
case CMD_White_Resign :
case CMD_Black_Resign :
send ( " $resign " ) ;
break ;
case CMD_Offer_Draw :
send ( " $draw " ) ;
break ;
case CMD_Reject_Draw :
send ( " $decline t draw " ) ;
break ;
default :
/* do nothing unknown command */
kdWarning ( ) < < " InternetIO::sendCMD received an unknown command: " < < ( ( Command ) command ) . getCommand ( ) < < endl ;
}
}
///////////////////////////////////////
//
// io_internet::send
//
///////////////////////////////////////
void io_internet : : send ( const TQString & msg )
{
TQString tmp ( msg ) ;
ssize_t len ;
/* Attach events to specific outgoing text */
if ( ( tmp = = " accept " ) | |
( tmp = = " decline " ) | |
( tmp . left ( 6 ) = = " match " ) )
{
if ( challenge ! = NULL )
{
delete challenge ;
nullifyChallenge ( ) ;
}
}
if ( tmp . right ( 1 ) ! = " \n " )
{
tmp + = " \n " ;
}
len = write ( socket - > socket ( ) , tmp . latin1 ( ) , tmp . length ( ) ) ;
if ( Log )
{
Log - > writeBlock ( TQString ( " << " ) . latin1 ( ) , 3 ) ;
Log - > writeBlock ( tmp . latin1 ( ) , tmp . length ( ) ) ;
}
if ( len < ( signed ) tmp . length ( ) )
{
kdWarning ( ) < < " io_internet::Send: Failed to write full block of data to socket. " < < endl ;
}
}
///////////////////////////////////////
//
// io_internet::readCommand
//
///////////////////////////////////////
void io_internet : : readCommand ( TDESocket * socket )
{
char buffer [ READ_BUFFER_SIZE ] ;
TQString tmp ;
TQStringList lines ;
memset ( buffer , 0 , READ_BUFFER_SIZE ) ;
read ( socket - > socket ( ) , buffer , READ_BUFFER_SIZE ) ;
tmp = buffer ;
tmp = lineBuffer + tmp ;
if ( Log )
{
Log - > writeBlock ( tmp . latin1 ( ) , tmp . length ( ) ) ;
}
if ( loginStage ! = LOGIN_STAGE_LOGGED_IN )
{
// route all the data to the login parser
parseLoginData ( tmp ) ;
this - > parseMode = NORMAL_MODE ;
}
else
{
lines = TQStringList : : split ( TQRegExp ( " \n \r ? " ) , tmp , FALSE ) ;
if ( ! ( tmp . endsWith ( " \n \r " ) | | tmp . endsWith ( " \n " ) ) )
{
lineBuffer = ( * ( - - lines . end ( ) ) ) ;
}
else
{
lineBuffer = " " ;
}
for ( TQStringList : : iterator i = lines . begin ( ) ; i ! = lines . end ( ) ; i + + )
{
if ( lineBuffer = = " " | | i ! = - - lines . end ( ) )
{
( * i ) . replace ( TQRegExp ( " \\ a " ) , " " ) ;
parseLine ( * i ) ;
}
}
}
}
///////////////////////////////////////
//
// io_internet::sendUserName
//
///////////////////////////////////////
void io_internet : : sendUserName ( )
{
loginStage = LOGIN_STAGE_PASSWORD ;
send ( userName ) ;
}
///////////////////////////////////////
//
// io_internet::sendPassword
//
///////////////////////////////////////
void io_internet : : sendPassword ( )
{
send ( passWord ) ;
}
///////////////////////////////////////
//
// io_internet::parseLoginData
//
///////////////////////////////////////
void io_internet : : parseLoginData ( TQString data )
{
TQStringList lines ;
if ( loginStage = = LOGIN_STAGE_NAME )
{
if ( data . contains ( " login: " ) )
{
sendUserName ( ) ;
}
lines = TQStringList : : split ( TQRegExp ( " \n \r ? " ) , data , FALSE ) ;
for ( TQStringList : : iterator i = lines . begin ( ) ; i ! = lines . end ( ) ; i + + )
{
writeToConsole ( ( * i ) , " K_STD " ) ;
}
}
else if ( loginStage = = LOGIN_STAGE_PASSWORD )
{
if ( data . contains ( " **** Invalid password! **** " ) | |
data . contains ( " Sorry, names can only consist of lower and upper case letters. Try again. " ) | |
data . contains ( " If you are not a registered player, enter guest or a unique ID. " ) )
{
loginDlg = new dlg_login ( myParent , " LoginDialog " , myResource ) ;
loginDlg - > disableServerSelect ( ) ;
connect ( loginDlg , TQT_SIGNAL ( okClicked ( ) ) , this , TQT_SLOT ( sendUserName ( ) ) ) ;
connect ( loginDlg , TQT_SIGNAL ( cancelClicked ( ) ) , this , TQT_SLOT ( selfDestruct ( ) ) ) ;
connect ( loginDlg , TQT_SIGNAL ( login ( TQString , TQString ) ) , this , TQT_SLOT ( setUserInfo ( TQString , TQString ) ) ) ;
}
else if ( data . contains ( " Press return to enter the server as " ) )
{
TQRegExp guestName ( " Logging you in as \" ( \\ w*) \ " " ) ;
int pos = guestName . search ( data ) ;
if ( pos > - 1 )
{
userName = guestName . cap ( 1 ) ;
}
send ( " \n " ) ;
}
else if ( data . contains ( " password: " ) )
{
sendPassword ( ) ;
}
else
{
loginStage = LOGIN_STAGE_LOGGED_IN ;
sendUserSettings ( ) ;
}
lines = TQStringList : : split ( TQRegExp ( " \n \r ? " ) , data , FALSE ) ;
for ( TQStringList : : iterator i = lines . begin ( ) ; i ! = lines . end ( ) ; i + + )
{
writeToConsole ( ( * i ) , " K_STD " ) ;
}
}
else
{
lines = TQStringList : : split ( TQRegExp ( " \n \r ? " ) , data , FALSE ) ;
for ( TQStringList : : iterator i = lines . begin ( ) ; i ! = lines . end ( ) ; i + + )
{
writeToConsole ( ( * i ) , " K_STD " ) ;
}
}
}
///////////////////////////////////////
//
// io_internet::ParseLine
//
///////////////////////////////////////
void io_internet : : parseLine ( TQString line )
{
int i , j ;
TQString tmp ;
switch ( parseMode )
{
case NORMAL_MODE : /* determine which mode we should go into */
if ( line . contains ( TQRegExp ( " ^ \\ s* \\ d{1,3} \\ s+(?: \\ d{1,4}| \\ + \\ + \\ + \\ +| \\ - \\ - \\ - \\ -) \\ s+ \\ w{3,17}( \\ (C \\ ))? \\ s+ \\ d{1,3} \\ s+ \\ d{1,3} " ) ) )
{
updateSoughtList ( line ) ;
parseMode = UPDATE_SOUGHT_MODE ;
}
/* CHALLENGE */
else if ( line . contains ( TQRegExp ( " ^ \\ s*Challenge: " ) ) )
{
myResource - > play ( SND_CHALLENGE ) ;
if ( challenge ! = NULL )
{
delete challenge ;
}
challenge = new dlg_challenge ( 0 , " Challenge " , myResource ) ;
connect ( challenge , TQT_SIGNAL ( destroyed ( ) ) , this , TQT_SLOT ( nullifyChallenge ( ) ) ) ;
connect ( challenge , TQT_SIGNAL ( user1Clicked ( ) ) , this , TQT_SLOT ( acceptChallenge ( ) ) ) ;
connect ( challenge , TQT_SIGNAL ( user2Clicked ( ) ) , this , TQT_SLOT ( declineChallenge ( ) ) ) ;
line . replace ( TQRegExp ( " ^ \\ s*Challenge: " ) , " " ) ;
challenge - > setValues ( line , userName ) ;
parseMode = CHALLENGE_MODE ;
}
else if ( ( line . left ( 15 ) = = " Challenge from " ) & & ( line . right ( 9 ) = = " removed. " ) )
{
if ( challenge ! = NULL )
{
delete challenge ;
}
}
/* SOUGHT GAME */
else if ( line . contains ( " seeking " ) )
{
// writeToConsole("seeking", "K_CH");
}
/* PRIVATE TELL */
else if ( line . contains ( TQRegExp ( " .+ tells you: .* " ) ) )
{
/* First grab the user name so we can auto-respond later */
emit sendCMD ( Command ( 0 , CMD_Set_Src_Tell , line . section ( ' ' , 0 , 0 ) ) ) ;
myResource - > play ( SND_TELL ) ;
writeToConsole ( line , " K_PVT " ) ;
}
/* SAY */
else if ( line . contains ( TQRegExp ( " .+ says: .* " ) ) )
{
myResource - > play ( SND_SAY ) ;
writeToConsole ( line , " K_PVT " ) ;
return ;
}
/* WHISPER & KIBITZ */
else if ( line . contains ( TQRegExp ( " .+ whispers: .* " ) ) | | line . contains ( TQRegExp ( " .+ kibitzes: .* " ) ) )
{
writeToConsole ( line , " K_WSP " ) ;
}
/* Important System Messages: Use Whisper Color */
else if ( line . contains ( TQRegExp ( " declines the draw request \\ .$ " ) ) )
{
writeToConsole ( line , " K_WSP " ) ;
}
/* DRAW OFFER */
else if ( line . right ( 19 ) = = " offers you a draw. " )
{
writeToConsole ( line , " K_WSP " ) ;
}
else if ( line . contains ( TQRegExp ( " .+rating adjustment:.+ " ) ) )
{
writeToConsole ( line , " K_WSP " ) ;
}
/* SHOUTS */
else if ( line . contains ( TQRegExp ( " ^c?t?s?-?shouts: " ) ) )
{
writeToConsole ( line , " K_SHT " ) ;
}
/* NOTIFY */
else if ( ( line . contains ( TQRegExp ( " \\ s*Notification: " ) ) ) | |
( line . contains ( TQRegExp ( " \\ s*Present company includes: " ) ) ) | |
( line . contains ( TQRegExp ( " \\ s*Your arrival was noted by: " ) ) ) )
{
writeToConsole ( line , " K_NOT " ) ;
myResource - > play ( SND_NOTIFICATION ) ;
}
/* CHANNEL TELLS */
else if ( line . contains ( TQRegExp ( " . \\ ( \\ d+ \\ ): " ) ) )
{
/* First grab the channel # so we can auto-respond later */
j = line . find ( TQString ( " ): " ) ) ;
i = line . findRev ( TQString ( " ( " ) , j ) + 1 ;
emit sendCMD ( Command ( 0 , CMD_Set_Src_Channel , line . mid ( i , j - i ) ) ) ;
writeToConsole ( line , " K_CH " ) ;
}
else if ( line . contains ( TQRegExp ( " ^<12> \\ s " ) ) )
{
/* a game move */
parseStyle12 ( line , PARSE12_MODE_MOVE ) ;
}
else if ( line . contains ( TQRegExp ( " ^<b1> \\ s " ) ) )
{
/* a bughouse piece has been passed or a piece has been captured in crazyhouse */
writeToConsole ( line , " K_CH " ) ;
}
else if ( line . contains ( TQRegExp ( " ^ \\ \\ " ) ) )
{
writeToConsole ( line , lastTag ) ;
}
else if ( line . contains ( TQRegExp ( " ^ \\ {?Game \\ d+ " ) ) & & line . contains ( " Creating " , TRUE ) )
{
parseMode = NEW_GAME_MODE ;
}
else if ( line . contains ( " You are now observing game " ) )
{
parseMode = OBSERVE_GAME_MODE ;
}
else if ( line . startsWith ( " Movelist for game " ) )
{
TQRegExp gameNumber ( " \\ d+ " ) ;
int pos = gameNumber . search ( line ) ;
if ( pos > - 1 )
{
ficsMoveListNumber = gameNumber . cap ( 0 ) . toInt ( ) ;
}
parseMode = PARSE_MOVE_LIST_MODE ;
}
else if ( ( line . contains ( TQRegExp ( " ^ \\ {?Game \\ d+ " ) ) | | line . contains ( TQRegExp ( " Game \\ d+ " ) ) ) & &
(
line . contains ( " forfeits by disconnection " , TRUE ) | |
line . contains ( " forfeits by disconnection} " , TRUE ) | |
line . contains ( " forfeits on time} " , TRUE ) | |
line . contains ( " forfeits on time " , TRUE ) | |
line . contains ( " resigns} " , TRUE ) | |
line . contains ( " resigns " , TRUE ) | |
line . contains ( " Game drawn by mutual agreement " , TRUE ) | |
line . contains ( " Game drawn by mutual agreement} " , TRUE ) | |
line . contains ( " , has lost contact or quit. " , TRUE ) | |
line . contains ( " checkmated " , TRUE ) | |
line . contains ( " checkmated} " , TRUE ) | |
line . contains ( " lost connection " , TRUE ) | |
line . contains ( " has no material to mate " , TRUE )
)
)
{
sendEndOfGameCommand ( line ) ;
}
else
{
/* don't know what to do with it, just send it to the console */
/* don't write the prompt to the console */
if ( line . contains ( TQRegExp ( " ^a?d?f?g?s?z?ics% " ) ) | |
line . contains ( TQRegExp ( " ^cex% " ) ) | |
line . contains ( TQRegExp ( " ^chess% " ) ) )
break ;
writeToConsole ( line , " K_STD " ) ;
}
break ;
case UPDATE_SOUGHT_MODE :
if ( line . contains ( TQRegExp ( " \\ d+ \\ s+ads? displayed. " ) ) )
{
updateSoughtList ( line ) ;
parseMode = NORMAL_MODE ;
}
else
{
updateSoughtList ( line ) ;
}
break ;
case NEW_GAME_MODE :
if ( line . contains ( TQRegExp ( " <12> \\ s " ) ) )
{
/* a game move */
parseStyle12 ( line , PARSE12_MODE_NEW ) ;
}
else if ( ( line . startsWith ( " fics% " ) & & line . length ( ) = = 6 ) )
{
parseMode = NORMAL_MODE ;
}
break ;
case OBSERVE_GAME_MODE :
if ( line . contains ( TQRegExp ( " <12> \\ s " ) ) )
{
/* a game move */
parseStyle12 ( line , PARSE12_MODE_NEW ) ;
send ( " moves " ) ;
parseMode = NORMAL_MODE ;
}
break ;
case CHALLENGE_MODE :
if ( line . startsWith ( " You can \" accept \" or \" decline \" , or propose " ) )
{
parseMode = NORMAL_MODE ;
}
break ;
case PARSE_MOVE_LIST_MODE :
if ( ! line . contains ( " {Still in progress} " ) )
{
if ( line . contains ( TQRegExp ( " \\ d \\ . " ) ) )
{
parseMoveList ( line ) ;
}
}
else
{
parseMode = NORMAL_MODE ;
}
break ;
default : /* do nothing */
break ;
} ;
}
///////////////////////////////////////
//
// io_internet::ParseStyle12
//
///////////////////////////////////////
void io_internet : : parseStyle12 ( TQString line , const unsigned int Mode )
{
// kdWarning() << line << endl;
struct ChessMove move ;
TQStringList fields ;
TQString position_line = " " ;
match_param * param = NULL ;
Command : : clearMove ( & move ) ;
switch ( Mode )
{
case PARSE12_MODE_NEW :
{
/* a new game that we are playing, or observing */
param = new match_param ( this - > myResource ) ;
fields = TQStringList : : split ( TQChar ( ' ' ) , line , FALSE ) ;
/* set white time control */
TCPList tmpListWhite ( param - > time ( WHITE ) ) ;
TCP tmpTCPWhite = tmpListWhite [ 0 ] ;
tmpTCPWhite . Seconds = fields [ 20 ] . toInt ( ) * 60 ;
tmpTCPWhite . Increment = fields [ 21 ] . toInt ( ) ;
tmpListWhite [ 0 ] = tmpTCPWhite ;
param - > setTime ( WHITE , tmpListWhite ) ;
/* set black time control */
TCPList tmpListBlack ( param - > time ( BLACK ) ) ;
TCP tmpTCPBlack = tmpListBlack [ 0 ] ;
tmpTCPBlack . Seconds = fields [ 20 ] . toInt ( ) * 60 ;
tmpTCPBlack . Increment = fields [ 21 ] . toInt ( ) ;
tmpListBlack [ 0 ] = tmpTCPBlack ;
param - > setTime ( BLACK , tmpListBlack ) ;
if ( ( userName . upper ( ) = = fields [ 17 ] . upper ( ) ) & &
( ( fields [ 19 ] . toInt ( ) = = - 1 ) | | ( fields [ 19 ] . toInt ( ) = = 1 ) ) )
{
/* I am playing white */
param - > setType ( WHITE , PLAYERLOCAL ) ;
}
else if ( fields [ 19 ] . toInt ( ) ! = 2 )
{
/* I am not playing white */
param - > setType ( WHITE , PLAYERTCP ) ;
}
if ( ( userName . upper ( ) = = fields [ 18 ] . upper ( ) ) & &
( ( fields [ 19 ] . toInt ( ) = = - 1 ) | | ( fields [ 19 ] . toInt ( ) = = 1 ) ) )
{
/* I am playing black */
param - > setType ( BLACK , PLAYERLOCAL ) ;
}
else if ( fields [ 19 ] . toInt ( ) ! = 2 )
{
/* I am not playing black */
param - > setType ( BLACK , PLAYERTCP ) ;
}
if ( fields [ 19 ] . toInt ( ) = = 2 )
{
param - > setType ( WHITE , PLAYEREXAMINE ) ;
param - > setType ( BLACK , PLAYEREXAMINE ) ;
}
//param->setVariation(something); figure out how to get the variation
param - > setName ( WHITE , fields [ 17 ] ) ;
param - > setName ( BLACK , fields [ 18 ] ) ;
/* tell core to connect us to a new match */
fics_to_knights [ fields [ 16 ] . toInt ( ) ] = ( ( core * ) myParent ) - > newMatch ( param ) - > getID ( ) ;
}
case PARSE12_MODE_MOVE :
{
fields = TQStringList : : split ( TQChar ( ' ' ) , line , FALSE ) ;
/* various ICS stuff for ChessMove */
move . ICS_ClockTicking = fields [ 31 ] . toInt ( ) ;
move . ICS_PawnPushFile = fields [ 10 ] . toShort ( ) ;
move . ICS_MoveCounter = fields [ 15 ] . toInt ( ) ;
if ( fields [ 9 ] = = " W " )
{
move . ICS_OnMove = BLACK ;
}
else if ( fields [ 9 ] = = " B " )
{
move . ICS_OnMove = WHITE ;
}
switch ( fields [ 19 ] . toInt ( ) )
{
/* Examining a game */
case 2 :
move . ICS_Mode = ICS_Examine ;
if ( fics_to_knights [ fields [ 16 ] . toInt ( ) ] = = 0 )
{
/* no new game started yet, call parsestyle 12 with a different mode */
parseStyle12 ( line , PARSE12_MODE_NEW ) ;
return ;
}
break ;
/* Observing a game */
case - 2 :
case 0 :
move . ICS_Mode = ICS_Observe ;
break ;
/* Playing a game */
default :
move . ICS_Mode = ICS_Normal ;
break ;
}
/* Verbose Coordinate Notation of previous move ( USE AS CAN ) */
strcpy ( move . CAN , fields [ 27 ] . right ( fields [ 27 ] . length ( ) - 2 ) . replace ( TQRegExp ( " - " ) , " " ) . utf8 ( ) ) ;
/* SAN */
strcpy ( move . SAN , fields [ 29 ] . replace ( TQRegExp ( " \\ + " ) , " " ) . replace ( TQRegExp ( " # " ) , " " ) . utf8 ( ) ) ;
/* fill the line for the command */
position_line + = fields [ 1 ] ; /* Internal Rank #7 */
position_line + = fields [ 2 ] ; /* Internal Rank #6 */
position_line + = fields [ 3 ] ; /* Internal Rank #5 */
position_line + = fields [ 4 ] ; /* Internal Rank #4 */
position_line + = fields [ 5 ] ; /* Internal Rank #3 */
position_line + = fields [ 6 ] ; /* Internal Rank #2 */
position_line + = fields [ 7 ] ; /* Internal Rank #1 */
position_line + = fields [ 8 ] ; /* Internal Rank #0 */
/* Can White Castle Short (boolean) */
position_line + = fields [ 11 ] ;
/* Can White Castle Long (boolean) */
position_line + = fields [ 12 ] ;
/* Can Black Castle Short (boolean) */
position_line + = fields [ 13 ] ;
/* Can Black Castle Long (boolean) */
position_line + = fields [ 14 ] ;
Command command ( fics_to_knights [ fields [ 16 ] . toInt ( ) ] , CMD_Move , fields [ 24 ] . toInt ( ) * 100 ,
fields [ 25 ] . toInt ( ) * 100 , move ) ;
command . setData ( position_line ) ;
emit sendCMD ( command ) ;
break ;
}
default :
break ;
}
}
///////////////////////////////////////
//
// io_internet::ParsePlayer
//
///////////////////////////////////////
//void io_internet::ParsePlayer( TQString Handle )
//{
// player.Raw = Handle;
/* SysAdmin */
// if( Handle.contains( TQRegExp("\\(\\*\\)") ) )
// {
// player.SysAdmin = TRUE;
// Handle.replace( TQRegExp("\\(\\*\\)"), TQString("") );
// }
// else player.SysAdmin = FALSE;
/* ServiceRep */
// if( Handle.contains( TQRegExp("\\(SR\\)") ) )
// {
// player.ServiceRep = TRUE;
// Handle.replace( TQRegExp("\\(SR\\)"), TQString("") );
// }
// else player.ServiceRep = FALSE;
/* Computer */
// if( Handle.contains( TQRegExp("\\(C\\)") ) )
// {
// player.Computer = TRUE;
// Handle.replace( TQRegExp("\\(C\\)"), TQString("") );
// }
// else player.Computer = FALSE;
/* Unregistered */
// if( Handle.contains( TQRegExp("\\(U\\)") ) )
// {
// player.Unregistered = TRUE;
// Handle.replace( TQRegExp("\\(U\\)"), TQString("") );
// }
// else player.Unregistered = FALSE;
// return;
//}
///////////////////////////////////////
//
// io_internet::nullifyChallenge
//
///////////////////////////////////////
void io_internet : : nullifyChallenge ( void )
{
challenge = NULL ;
}
///////////////////////////////////////
//
// io_internet::declineChallenge
//
///////////////////////////////////////
void io_internet : : declineChallenge ( void )
{
send ( " decline " ) ;
delete challenge ;
challenge = NULL ;
}
///////////////////////////////////////
//
// io_internet::acceptChallenge
//
///////////////////////////////////////
void io_internet : : acceptChallenge ( void )
{
send ( challenge - > values ( ) ) ;
delete challenge ;
challenge = NULL ;
}
///////////////////////////////////////
//
// io_internet::writeToConsole
//
///////////////////////////////////////
void io_internet : : writeToConsole ( TQString text , TQString tag )
{
lastTag = tag ;
/* Remove Bells */
text . replace ( TQRegExp ( " \\ x0007 " ) , " " ) ;
/* Replace misc characters with rich-text friendly counterparts */
text . replace ( TQRegExp ( " \\ x003c " ) , " < " ) ;
text . replace ( TQRegExp ( " \\ x007c " ) , " | " ) ;
text . replace ( TQRegExp ( " \\ f " ) , " " ) ;
text . replace ( TQRegExp ( " \\ n " ) , " " ) ;
text . replace ( TQRegExp ( " \\ r* " ) , " " ) ;
emit sendCMD ( Command ( 0 , CMD_Append_To_Console , " < " + tag + " > " + text + " </ " + tag + " > " ) ) ;
}
///////////////////////////////////////
//
// io_internet::updateSoughtList
//
///////////////////////////////////////
void io_internet : : updateSoughtList ( TQString soughtLine )
{
/* "ADS DISPLAYED" MESSAGE */
if ( soughtLine . contains ( TQRegExp ( " \\ d+ \\ s+ads? displayed. " ) ) )
{
emit sendCMD ( Command ( 0 , CMD_Show_Sought_List ) ) ;
}
else
{
emit sendCMD ( Command ( 0 , CMD_Add_Sought_Match , soughtLine ) ) ;
}
}
///////////////////////////////////////
//
// io_internet::sendUserSettings()
//
///////////////////////////////////////
void io_internet : : sendUserSettings ( )
{
send ( " set style 12 " ) ;
send ( TQString ( " set interface Knights %1 " ) . arg ( _VERSION_ ) ) ;
send ( TQString ( " set private %1 " ) . arg ( myResource - > OPTION_Private ) ) ;
send ( TQString ( " set kibitz %1 " ) . arg ( myResource - > OPTION_Kibitz ) ) ;
send ( TQString ( " set tell %1 " ) . arg ( myResource - > OPTION_Tell ) ) ;
send ( TQString ( " set shout %1 " ) . arg ( myResource - > OPTION_Shout ) ) ;
send ( TQString ( " set seek %1 " ) . arg ( myResource - > OPTION_Seek ) ) ;
send ( TQString ( " set tolerance %1 " ) . arg ( myResource - > OPTION_Profanity ) ) ;
}
///////////////////////////////////////
//
// io_internet::parseMoveList(TQString data)
//
///////////////////////////////////////
void io_internet : : parseMoveList ( TQString line )
{
TQStringList two_plys ;
struct ChessMove move ;
Command command ;
int move_counter = 0 ;
/* white */
two_plys = TQStringList : : split ( TQRegExp ( " \\ s+ " ) , line , FALSE ) ;
Command : : clearMove ( & move ) ;
move_counter = two_plys [ 0 ] . left ( two_plys [ 0 ] . length ( ) - 1 ) . length ( ) ; /* remove the . */
move . ICS_MoveCounter = move_counter ;
move . ICS_Mode = ICS_Movelist ;
move . ICS_OnMove = WHITE ;
strcpy ( move . SAN , two_plys [ 1 ] . utf8 ( ) ) ;
command . setCommand ( ( int & ) CMD_Move ) ;
command . setID ( fics_to_knights [ ficsMoveListNumber ] ) ;
command . setMove ( move ) ;
emit sendCMD ( command ) ;
/* black */
if ( two_plys . size ( ) > 3 )
{
Command : : clearMove ( & move ) ;
move . ICS_MoveCounter = move_counter ;
move . ICS_Mode = ICS_Movelist ;
move . ICS_OnMove = BLACK ;
strcpy ( move . SAN , two_plys [ 3 ] . utf8 ( ) ) ;
command . setCommand ( ( int & ) CMD_Move ) ;
command . setID ( fics_to_knights [ ficsMoveListNumber ] ) ;
command . setMove ( move ) ;
emit sendCMD ( command ) ;
}
}
///////////////////////////////////////
//
// io_internet::sendEndOfGameCommand(TQString line)
//
///////////////////////////////////////
void io_internet : : sendEndOfGameCommand ( TQString line )
{
TQStringList fields ;
Command command ;
fields = TQStringList : : split ( TQChar ( ' ' ) , line , FALSE ) ;
if ( fields [ 1 ] . endsWith ( " : " ) )
{
fields [ 1 ] = fields [ 1 ] . left ( fields [ 1 ] . length ( ) - 1 ) ;
}
command . setID ( fics_to_knights [ fields [ 1 ] . toInt ( ) ] ) ;
fields [ fields . count ( ) - 1 ] = fields [ fields . count ( ) - 1 ] . stripWhiteSpace ( ) ;
if ( fields [ fields . count ( ) - 1 ] = = " 1-0 " )
{
if ( fields [ fields . count ( ) - 2 ] . contains ( " resigns " ) )
{
command . setCommand ( ( int & ) CMD_Black_Resign ) ;
}
else if ( fields [ fields . count ( ) - 2 ] . contains ( " time " ) )
{
command . setCommand ( ( int & ) CMD_White_Called_Flag ) ;
}
else
{
command . setCommand ( ( int & ) CMD_Result_White ) ;
}
}
else if ( fields [ fields . count ( ) - 1 ] = = " 0-1 " )
{
if ( fields [ fields . count ( ) - 2 ] . contains ( " resigns " ) )
{
command . setCommand ( ( int & ) CMD_White_Resign ) ;
}
else if ( fields [ fields . count ( ) - 2 ] . contains ( " time " ) )
{
command . setCommand ( ( int & ) CMD_Black_Called_Flag ) ;
}
else
{
command . setCommand ( ( int & ) CMD_Result_Black ) ;
}
}
else if ( fields [ fields . count ( ) - 1 ] = = " 1/2-1/2 " )
{
command . setCommand ( ( int & ) CMD_Result_Draw ) ;
}
else
{
command . setCommand ( ( int & ) CMD_Lost_Contact ) ;
}
emit sendCMD ( command ) ;
}
///////////////////////////////////////
//
// io_internet::processSeekTimer()
//
///////////////////////////////////////
void io_internet : : processSeekTimer ( )
{
/* timer timed out, send out a sought */
send ( " sought " ) ;
}
///////////////////////////////////////
//
// io_internet::selfDestruct()
//
///////////////////////////////////////
void io_internet : : selfDestruct ( )
{
/* cause the io_internet to delete itself */
TQApplication : : postEvent ( tqApp - > mainWidget ( ) , new TQCustomEvent ( EVENT_Del_IO_Net ) ) ;
}
///////////////////////////////////////
//
// io_internet::setUserInfo()
//
///////////////////////////////////////
void io_internet : : setUserInfo ( TQString userName , TQString passWord )
{
this - > userName = userName ;
this - > passWord = passWord ;
}