#!/usr/bin/perl -w use IO::Socket::INET;use IO::Select; $SIG{PIPE}=IGNORE; $l=IO::Socket::INET->new(Listen=>5,LocalPort=>10000,Proto=>'tcp',Reuse=>1)||die; $s=new IO::Select;$s->add($l); sub b{for(@p){$_->{N}ne''&&$_->{S}->print($_[0],"\n")}} for(;;){for($s->can_read()){ if($_ eq $l) { $_ = $_->accept(); push@p,{S=>$_,N=>''}; $s->add($_); $_->print("Enter a username: "); next } $p=$_; ($p)=grep{$_->{S}eq$p}@p; $c=$_->getline(); defined($c)&&$c=~s/\r?\n//; if($p->{N}eq''){ if(!defined($c)) { @p=grep{$_ ne$p}@p; $s->remove($_); $_->close(); } elsif($c!~/^[a-z]+$/i){ $_->print("Bad username. Try again: "); } elsif(grep{lc($c)eq lc($_->{N})}@p) { $_->print("Already taken. Try again: "); } else { $p->{N}=$c; b($c." enters"); } } elsif(!defined($c)||$c=~/^ *quit *$/i) { b($p->{N}." leaves"); @p=grep{$_ ne$p}@p; $s->remove($_); $_->close(); } elsif($c=~/^ *('|"|say ) *([!-~][ -~]*)$/i) { b($p->{N}." says '".$2."'"); } elsif($c=~/^ *(:|;|emote ) *([!-~][ -~]*)$/i) { b($p->{N}." ".$2); } elsif($c!~/^ *$/){ $_->print("Bad command.\n"); } }}