Advertisement
Guest User

Untitled

a guest
Oct 4th, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 6.86 KB | None | 0 0
  1. #!/usr/bin/perl
  2.  
  3. use warnings;
  4. use strict;
  5. use IO::Select;
  6. use IO::Socket;
  7. use User;
  8. use Connections;
  9. use Chat;
  10.  
  11. # Rehash/die password
  12. my $password = "bleh";
  13. # Enable verbose server debugging? (1 yes, 0 no)
  14. my $DEBUG=1;
  15. # Server address
  16. my $serv_addr = "65.75.157.170";
  17. # Server port
  18. my $ezim_serv_port = 8080;
  19. # HL Listen port
  20. my $hl_serv_port = 1234;
  21. # Command Handlers
  22. my @handlers=('halflife_handler.pm', 'admin_handler.pm', 'buddy_handler.pm', 'chat_handler.pm');
  23. # Objects
  24. my ($cons, $usr, $chat, $sel, $hl_socket, $lsn);
  25.  
  26. foreach (@handlers) {
  27.     require $_;
  28. }
  29.  
  30.  
  31. $|=1;
  32.  
  33.  
  34. exit(&main(@ARGV));
  35.  
  36.  
  37. sub main {
  38.     my @argv = @_;
  39.     my ($fh, $hl_input, $hl_peerport, $hl_peerhost);
  40.    
  41.     &init();
  42.  
  43.     while(1) {
  44.         print '.';
  45.         ## Loop through the socket handles that can read
  46.         foreach $fh ($sel->can_read(10)) {
  47.             # Is the socket_handle the hl listen socket? Process seperately
  48.             if ($fh == $hl_socket) {
  49.                 $hl_socket->recv($hl_input, 1024);
  50.                 $hl_peerhost = $hl_socket->peerhost;
  51.                 $hl_peerport = $hl_socket->peerport;
  52.        
  53.                 halflife_parse($cons, $hl_socket, $hl_input, $hl_peerhost, $hl_peerport);
  54.                 next;
  55.             }
  56.  
  57.             # Is the socket_handle the listen server? if so process new connections
  58.             if($fh == $lsn) {
  59.                 # Create a new socket
  60.                 my $new = $lsn->accept;
  61.                 $sel->add($new);
  62.                 $cons->add($new, undef);
  63.                 logme("Client connecting");
  64.                 $cons->Greet($new);
  65.             } else {
  66.                 # Soocket handle is sending us data, or disconnected.
  67.                 my $data = <$fh>;
  68.                 if (defined $data && length $data) {
  69.                     parse_line($fh,$data);
  70.                 } else {
  71.                     disconnect($fh)
  72.                 }
  73.             }
  74.         }
  75.  
  76.         # Loop through socket handles that can write
  77.         foreach $fh ($sel->can_write(10)) {
  78.             # Do we have anything to write to this socket? If not next;
  79.             next if (!$cons->{$fh}->{'out_buffer'});
  80.             if (syswrite($fh,$cons->{$fh}->{'out_buffer'}) > 0) {
  81.                 delete $cons->{$fh}->{'out_buffer'};
  82.                 # is this socket marked for DEATH?! if so kill it
  83.                 if ($cons->{$fh}->{'kill'} eq 1) {
  84.                     disconnect($fh);
  85.                 }
  86.             } else {
  87.                 next;
  88.             }
  89.         }
  90.     }
  91. }
  92.  
  93. ## void init ()
  94. # Initiates the ezim class objects and listen sockets
  95.  
  96. sub init {
  97.  
  98.     logme("Creating connections obj");
  99.     $cons = Connections->new();
  100.     logme("Creating user obj");
  101.     $usr = User->new();
  102.     logme("Creating chat obj");
  103.     $chat = Chat->new();
  104.  
  105.     logme("Creating EZIM Listen Socket");
  106.     $lsn = new IO::Socket::INET(Listen => 1, LocalPort => $ezim_serv_port) or die "Unable to open listen socket: $!";
  107.     logme("Creating HL Listen Socket");
  108.     $hl_socket = IO::Socket::INET->new(Proto => "udp", LocalPort => $hl_serv_port) or die "Can't setup UDP socket: $!";
  109.     logme("Creating Select() obj");
  110.     $sel = new IO::Select( $lsn );
  111.     $sel->add($hl_socket);
  112.  
  113.     logme("Waiting for new connections...");
  114.  
  115.     return;
  116. }
  117.  
  118. ## void logme ($line)
  119. # Prints line with timestamp if verbose debugging == 1
  120.  
  121. sub logme {
  122.     my ($line) = @_;
  123.     print "[".scalar(localtime)."] ".$line."\n" if ($DEBUG == 1);
  124. }
  125.  
  126.  
  127. ## void disconnect ($socket_handle)
  128. # Disconnects $socket_handle
  129.  
  130. sub disconnect {
  131.     my $sh = $_[0];
  132.     if (exists $usr->{lc($cons->{$sh}->{'username'})}) {
  133.         $cons->SendAllExcept("11 ".$cons->{$sh}->{'username'}.":0:0", $sh);
  134.         logme("User ".$cons->{$sh}->{'username'}." disconnected");
  135.     }else{
  136.         logme("Client disconnected");
  137.     }
  138.  
  139.     delete $usr->{lc($cons->{$sh}->{'username'})} if (exists $usr->{lc($cons->{$sh}->{'username'})});
  140.     delete $cons->{$sh};
  141.  
  142.     $sel->remove($sh);
  143.     $sh->close;
  144. }
  145.  
  146.  
  147. ## void parse_line ($socket_handle, $raw_line)
  148. # Parses raw lines and sends em off to the proper handler
  149. # Takes two arguments, $socket_handle and $raw_line
  150.  
  151. sub parse_line {
  152.     my ($sh, $line)=@_;
  153.  
  154.     chomp($line);
  155.     # Received die command w/ password
  156.     # Kill off the listen server, and exit
  157.     # ToDo: kill off all existing sockets, then exit;
  158.     if ($line =~ /^die \$password$/) {
  159.         shutdown($lsn, 2);
  160.         $lsn = undef;
  161.         exit;
  162.     }
  163.     # Received details command w/ username
  164.     # Sends commander the elements and values of the users hash
  165.     if ($line =~ /^details ([^:]+)$/i) {
  166.         foreach my $key (keys %{$usr->{$1}}) {
  167.             $cons->SendMsg($sh,"12 Details for ".$1.": \$key \= ".$key." value \= ".$usr->{$1}->{$key});
  168.         }
  169.         return;
  170.     }
  171.     # Received rehash command w/ password
  172.     # Reloads handler modules defined at the top of this file
  173.     if ($line =~ /^rehash \$password$/) {
  174.         foreach (@handlers) {
  175.             delete $INC{$_};
  176.             require $_;
  177.         }
  178.         return;
  179.     }
  180.     # Received who command
  181.     # Sends commander a list of every user connected
  182.     if ($line =~ /^who$/i) {
  183.         foreach my $key (keys %{$usr}) {
  184.             $cons->SendMsg($sh,"12 WHO: ".$key);
  185.         }
  186.         return;
  187.     }
  188.     # Main EZIM command parser. this will handle authentication
  189.     if ($line=~/^\w+/) {
  190.         # Has the user authenticated?
  191.         if ($usr->IsLoggedOn($cons,$sh) == 0) {
  192.             # Nope, check if they are sending the AUTH command
  193.  
  194.             if ($line =~ /^auth ([^:]+):(.+)$/i) {
  195.                 # Got AUTH, try to login() with username/password
  196.  
  197.                 if ($usr->login($1,$2,$sh)) {
  198.                     # Got a correct login, send em login greeting and such
  199.                     # Also notify everyone else that this user is now online
  200.  
  201.                     logme("Logged in $1 on socket $sh");
  202.  
  203.                     $cons->{$sh}->{'username'} = $1;
  204.                     $cons->SendMsg($sh, "04 Login successful");
  205.                     $cons->SendMsg($sh, "06 ".scalar(keys %{$usr}));
  206.                     $cons->SendMsg($sh, "07 EZ-Company.net Message Of The Day:");
  207.                     $cons->SendMsg($sh, "08 This is the motm body");
  208.                     $cons->SendMsg($sh, "08 This is more motm body");
  209.                     $cons->SendMsg($sh, "09 This is the motm end");
  210.                     if ($usr->IsAdminBySock($cons, $sh) != 0) {
  211.                         $cons->SendMsg($sh, "10");
  212.                     }
  213.                     $usr->GetUsers($cons, $sh);
  214.                     $cons->SendAll("11 ".$1.":".$usr->IsAdminBySock($cons, $sh).":".$usr->{lc($1)}->{'status'});
  215.  
  216.                     return;
  217.  
  218.                 }else{
  219.                     # User gave invalid login/password. tell em, and mark them for DEATH!
  220.                     $cons->SendMsg($sh, "05 Invalid username or password");
  221.                     $cons->{$sh}->{'kill'} = 1;
  222.                     logme("Invalid login attempt for $1 (password: $2)");
  223.  
  224.                 } # end login()
  225.  
  226.             } #end auth
  227.  
  228.             # unknown connection didn't send auth, no other commands can be used in this state
  229.             logme("Unknown line from faulty user: $line");
  230.             return;
  231.         }
  232.  
  233.         # Checks if the line starts with admin_, buddy_ or chat_
  234.         # and passes the line to the proper handler
  235.  
  236.         if ($line =~ /^admin_/i) {
  237.             admin_command($cons, $usr, $sh, $line);
  238.         }elsif($line =~ /^buddy_/i) {
  239.             buddy_command($cons, $usr, $sh, $line);
  240.         }elsif($line=~/^chat_/i) {
  241.             chat_command($chat, $cons, $usr, $sh, $line);
  242.         }elsif ($line=~ /^status\s(\d)/i) {
  243.             my $status = $1+1;
  244.             $usr->ChangeStatus($cons, $sh, $status);
  245.             logme("Changing status of ".$cons->UserBySock($sh)." to ".$status);
  246.         }else{
  247.             logme("Unknown line, trying to send to joker as a message");
  248.             if ($usr->{'joker'} ne '') {
  249.                 buddy_msg_user('joker', "Server", $line);
  250.             }
  251.         }
  252.         return;
  253.     } # end EZIM command parser
  254.    
  255.    
  256. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement