# #Irssi script to complement chess backend server # use strict; use Irssi; use Irssi::Irc; use IO::Socket; use vars qw($VERSION %IRSSI); $VERSION="0.2"; %IRSSI = ( authors => "kodgehopper (kodgehopper\@netscape.net)", contact => "kodgehopper\@netscape.net", name => "IRC-Chess", description => "Chess server for IRC. Allows for multiple 2-player games to be played simultaneously", license => "GNU GPL", url => "http://irc-chess.sourceforge.net/", ); my $gameRunning=0; my $SERVER='127.0.0.1'; my $PORT=1234; sub processColors { $_=$_[0]; #replace foreground/background colors my @fgbg; my $numFgBg=(@fgbg=/()/g); for (my $j=0; $j < $numFgBg; $j++) { my $t=$fgbg[$j]; my ($background, $foreground)=($t=~/()()/); my $orig=$background.$foreground; $foreground=~s//\\cc1/g; $foreground=~s//\\cc0/g; $background=~s//,2/g; $background=~s//,7/g; my $result=$foreground.$background; s/$orig/$result/; } #replace background-only colors s//\\cc0,2/g; s//\\cc0,7/g; #replace rest of colors s//\\co/g; return $_; }#processColors # #message formats: #1. simple format: #[username]Message # #2. complex format: #[user1]msg1<:=:>[user2]msg2<:=:>commonMessage # sub processMsgFromServer { my ($server, $msg, $nick)=@_; my $delimiter="<:=:>"; $_=$msg; #determine the type of message from the number of delimiters my $numDelims=(my @list=/$delimiter/g); if ($numDelims==0) { #simple message my ($username, $message)=/^\s*\[(.+?)\](.*?)$/; $message=processColors($message); #send message to player $server->command("eval msg $nick $message"); } else { #complex message my ($user1, $msg1, $user2, $msg2, $commonMessage)=/^\s*\[(.+?)\](.*?)$delimiter\[(.+?)\](.*?)$delimiter(.*)$/s; #split message into seperate lines my @commonMessageList=split(/\n/, $commonMessage); #send common message to both users Irssi::print("Sending common message to both users"); my $numStrings; my @list; #print out blank lines since the string was split on newlines so #now they're lost. an extra space == blank line $server->command("eval msg $user1 \\co"); $server->command("eval msg $user2 \\co"); my $commonListSize=@commonMessageList; for (my $j=0; $j<$commonListSize; $j++) { $commonMessageList[$j]=processColors($commonMessageList[$j]); if ($commonMessageList[$j] ne '') { $server->command("eval msg $user1 $commonMessageList[$j]"); $server->command("eval msg $user2 $commonMessageList[$j]"); } } $server->command("eval msg $user1 \\co"); $server->command("eval msg $user2 \\co"); #send messages for each user my @msg1List=split(/\n/, $msg1); my $msg1ListSize=@msg1List; for (my $j=0; $j<$msg1ListSize; $j++) { $server->command("eval msg $user1 \\cb$msg1List[$j]\\co"); } my @msg2List=split(/\n/, $msg2); my $msg2ListSize=@msg2List; for (my $j=0; $j<$msg2ListSize; $j++) { $server->command("eval msg $user2 \\cb$msg2List[$j]\\co"); } } #else }#processOutput # #process a message received from the user. #this will be something like "game start k" #this will have to be changed to something like #"game start k k1", where k1 is the user. #if the format of the message is not correct, #return INVALID. format checking is minimal. #basically, if the first word is "game", then #slap on the nickname and send it to the server. # sub processMsgFromClient { my ($server, $msg, $nick)=@_; #Irssi::print("msg from client:\n$msg\n"); $msg=lc($msg); if ($msg=~/^game\b/) { $msg = $msg." $nick"; return $msg; } else { Irssi::print("sending: msg $nick Error: Invalid Message"); $server->command("msg $nick Error: Invalid Message"); return "INVALID"; } }#processMsgFromClient # #private messages received from other users eg. if they want to #register a new game sub sig_processPvt { my($server, $msg, $nick, $address)=@_; my $msgToSend=processMsgFromClient($server, $msg, $nick); if ($msgToSend !~ /^INVALID$/) { Irssi::print("Sending message now"); send(SOCKET,$msgToSend,0); Irssi::print("Waiting for message from server\n"); my $buffer; recv(SOCKET,$buffer,32678,0); #read a max of 32k. processMsgFromServer($server, $buffer, $nick); } }#sig_processPvt # #function to terminate game. it basically just closes #the connection to the server # sub cmd_endGame { shutdown(SOCKET,2); close(SOCKET); Irssi::print("Game ended. Socket shut down"); $gameRunning=0; }#cmd_endGame sub connect_server { Irssi::print("connecting to server"); my $tcpProtocolNumber = getprotobyname('tcp') || 6; socket(SOCKET, PF_INET(), SOCK_STREAM(), $tcpProtocolNumber) or return("socket: $!"); my $internetPackedAddress = pack_sockaddr_in($PORT, inet_aton($SERVER)); connect(SOCKET, $internetPackedAddress) or return("connect: $!"); Irssi::print("Game is now running"); $gameRunning=1; return ''; } sub cmd_connect_server { my $err = connect_server(); if ($err ne '') { Irssi::print($err); if ($err =~ m/^connect/) { Irssi::print("Server: $SERVER Port: $PORT"); Irssi::print("see: ".$IRSSI{url}); Irssi::print("reconnect by reload the script (/run irc_chess.pl) "); } } } cmd_connect_server(); Irssi::signal_add("message private","sig_processPvt"); Irssi::command_bind("end_game", "cmd_endGame");