Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- use warnings;
- use strict;
- use IO::Select;
- use IO::Socket;
- use User;
- use Connections;
- use Chat;
- # Rehash/die password
- my $password = "bleh";
- # Enable verbose server debugging? (1 yes, 0 no)
- my $DEBUG=1;
- # Server address
- my $serv_addr = "65.75.157.170";
- # Server port
- my $ezim_serv_port = 8080;
- # HL Listen port
- my $hl_serv_port = 1234;
- # Command Handlers
- my @handlers=('halflife_handler.pm', 'admin_handler.pm', 'buddy_handler.pm', 'chat_handler.pm');
- # Objects
- my ($cons, $usr, $chat, $sel, $hl_socket, $lsn);
- foreach (@handlers) {
- require $_;
- }
- $|=1;
- exit(&main(@ARGV));
- sub main {
- my @argv = @_;
- my ($fh, $hl_input, $hl_peerport, $hl_peerhost);
- &init();
- while(1) {
- print '.';
- ## Loop through the socket handles that can read
- foreach $fh ($sel->can_read(10)) {
- # Is the socket_handle the hl listen socket? Process seperately
- if ($fh == $hl_socket) {
- $hl_socket->recv($hl_input, 1024);
- $hl_peerhost = $hl_socket->peerhost;
- $hl_peerport = $hl_socket->peerport;
- halflife_parse($cons, $hl_socket, $hl_input, $hl_peerhost, $hl_peerport);
- next;
- }
- # Is the socket_handle the listen server? if so process new connections
- if($fh == $lsn) {
- # Create a new socket
- my $new = $lsn->accept;
- $sel->add($new);
- $cons->add($new, undef);
- logme("Client connecting");
- $cons->Greet($new);
- } else {
- # Soocket handle is sending us data, or disconnected.
- my $data = <$fh>;
- if (defined $data && length $data) {
- parse_line($fh,$data);
- } else {
- disconnect($fh)
- }
- }
- }
- # Loop through socket handles that can write
- foreach $fh ($sel->can_write(10)) {
- # Do we have anything to write to this socket? If not next;
- next if (!$cons->{$fh}->{'out_buffer'});
- if (syswrite($fh,$cons->{$fh}->{'out_buffer'}) > 0) {
- delete $cons->{$fh}->{'out_buffer'};
- # is this socket marked for DEATH?! if so kill it
- if ($cons->{$fh}->{'kill'} eq 1) {
- disconnect($fh);
- }
- } else {
- next;
- }
- }
- }
- }
- ## void init ()
- # Initiates the ezim class objects and listen sockets
- sub init {
- logme("Creating connections obj");
- $cons = Connections->new();
- logme("Creating user obj");
- $usr = User->new();
- logme("Creating chat obj");
- $chat = Chat->new();
- logme("Creating EZIM Listen Socket");
- $lsn = new IO::Socket::INET(Listen => 1, LocalPort => $ezim_serv_port) or die "Unable to open listen socket: $!";
- logme("Creating HL Listen Socket");
- $hl_socket = IO::Socket::INET->new(Proto => "udp", LocalPort => $hl_serv_port) or die "Can't setup UDP socket: $!";
- logme("Creating Select() obj");
- $sel = new IO::Select( $lsn );
- $sel->add($hl_socket);
- logme("Waiting for new connections...");
- return;
- }
- ## void logme ($line)
- # Prints line with timestamp if verbose debugging == 1
- sub logme {
- my ($line) = @_;
- print "[".scalar(localtime)."] ".$line."\n" if ($DEBUG == 1);
- }
- ## void disconnect ($socket_handle)
- # Disconnects $socket_handle
- sub disconnect {
- my $sh = $_[0];
- if (exists $usr->{lc($cons->{$sh}->{'username'})}) {
- $cons->SendAllExcept("11 ".$cons->{$sh}->{'username'}.":0:0", $sh);
- logme("User ".$cons->{$sh}->{'username'}." disconnected");
- }else{
- logme("Client disconnected");
- }
- delete $usr->{lc($cons->{$sh}->{'username'})} if (exists $usr->{lc($cons->{$sh}->{'username'})});
- delete $cons->{$sh};
- $sel->remove($sh);
- $sh->close;
- }
- ## void parse_line ($socket_handle, $raw_line)
- # Parses raw lines and sends em off to the proper handler
- # Takes two arguments, $socket_handle and $raw_line
- sub parse_line {
- my ($sh, $line)=@_;
- chomp($line);
- # Received die command w/ password
- # Kill off the listen server, and exit
- # ToDo: kill off all existing sockets, then exit;
- if ($line =~ /^die \$password$/) {
- shutdown($lsn, 2);
- $lsn = undef;
- exit;
- }
- # Received details command w/ username
- # Sends commander the elements and values of the users hash
- if ($line =~ /^details ([^:]+)$/i) {
- foreach my $key (keys %{$usr->{$1}}) {
- $cons->SendMsg($sh,"12 Details for ".$1.": \$key \= ".$key." value \= ".$usr->{$1}->{$key});
- }
- return;
- }
- # Received rehash command w/ password
- # Reloads handler modules defined at the top of this file
- if ($line =~ /^rehash \$password$/) {
- foreach (@handlers) {
- delete $INC{$_};
- require $_;
- }
- return;
- }
- # Received who command
- # Sends commander a list of every user connected
- if ($line =~ /^who$/i) {
- foreach my $key (keys %{$usr}) {
- $cons->SendMsg($sh,"12 WHO: ".$key);
- }
- return;
- }
- # Main EZIM command parser. this will handle authentication
- if ($line=~/^\w+/) {
- # Has the user authenticated?
- if ($usr->IsLoggedOn($cons,$sh) == 0) {
- # Nope, check if they are sending the AUTH command
- if ($line =~ /^auth ([^:]+):(.+)$/i) {
- # Got AUTH, try to login() with username/password
- if ($usr->login($1,$2,$sh)) {
- # Got a correct login, send em login greeting and such
- # Also notify everyone else that this user is now online
- logme("Logged in $1 on socket $sh");
- $cons->{$sh}->{'username'} = $1;
- $cons->SendMsg($sh, "04 Login successful");
- $cons->SendMsg($sh, "06 ".scalar(keys %{$usr}));
- $cons->SendMsg($sh, "07 EZ-Company.net Message Of The Day:");
- $cons->SendMsg($sh, "08 This is the motm body");
- $cons->SendMsg($sh, "08 This is more motm body");
- $cons->SendMsg($sh, "09 This is the motm end");
- if ($usr->IsAdminBySock($cons, $sh) != 0) {
- $cons->SendMsg($sh, "10");
- }
- $usr->GetUsers($cons, $sh);
- $cons->SendAll("11 ".$1.":".$usr->IsAdminBySock($cons, $sh).":".$usr->{lc($1)}->{'status'});
- return;
- }else{
- # User gave invalid login/password. tell em, and mark them for DEATH!
- $cons->SendMsg($sh, "05 Invalid username or password");
- $cons->{$sh}->{'kill'} = 1;
- logme("Invalid login attempt for $1 (password: $2)");
- } # end login()
- } #end auth
- # unknown connection didn't send auth, no other commands can be used in this state
- logme("Unknown line from faulty user: $line");
- return;
- }
- # Checks if the line starts with admin_, buddy_ or chat_
- # and passes the line to the proper handler
- if ($line =~ /^admin_/i) {
- admin_command($cons, $usr, $sh, $line);
- }elsif($line =~ /^buddy_/i) {
- buddy_command($cons, $usr, $sh, $line);
- }elsif($line=~/^chat_/i) {
- chat_command($chat, $cons, $usr, $sh, $line);
- }elsif ($line=~ /^status\s(\d)/i) {
- my $status = $1+1;
- $usr->ChangeStatus($cons, $sh, $status);
- logme("Changing status of ".$cons->UserBySock($sh)." to ".$status);
- }else{
- logme("Unknown line, trying to send to joker as a message");
- if ($usr->{'joker'} ne '') {
- buddy_msg_user('joker', "Server", $line);
- }
- }
- return;
- } # end EZIM command parser
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement