Forum


Notice to all users

We are migrating towards a new forum system located at community.teamspeak.com, as such this forum will become read-only on January 29, 2020

Results 1 to 3 of 3
  1. #1
    Join Date
    July 2012
    Posts
    1

    Question Strip nicknames from clientlist response using Perl script

    Hi guys

    I wonder if anyone could help point me in the right direction here. I'm trying to setup a script to monitior a 3rd party teamspeak 3 server, and return the list of currently logged in users, by parsing the result of the clientlist command.

    What I've got so far seems to be close, but think the regexp needs adjusting slightly, as its only returning the first user (sorry I'm not great with regular expressions!). Here is what I have so far that was trying to print a comma seperated list of users:

    Code:
    #!/usr/bin/perl
    use IO::Socket; 
    my $sock = new IO::Socket::INET (PeerAddr => 'xxx.xxx.xxx.xxx',PeerPort => 'xxxx',Proto => 'tcp'); 
    die "Could not create socket: $!\n" unless $sock; 
    
    # Login details for TS
    print $sock "login ****** ******\n";
    
    # Virtual TS server ID
    print $sock "use sid=xx\n"; 
    
    # Command to run
    print $sock "clientlist\n";
    
    # Array to hold users online
    @users = ();
    
    # Do text parsing to check for users value
    while (<$sock>) { 
    			/error id=(\d+)/ and 
    				$1 !~ /^0$/ and
    				print "error\n" and
    				close $sock;
    			/client_nickname=(\S+)/ and
    				push(@users,"$1") and
    				close $sock;
    		}
    
    # Output users online
    print join(",",@users);
    Has anyone does this already, or have any advice on the above?

    Thanks!

  2. #2
    Join Date
    June 2012
    Location
    Earth
    Posts
    181
    Try this maybe...

    Tested Code:
    Code:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use IO::Socket; 
    
    my $query_address = "192.168.0.2";
    my $query_port = 10011;
    my $login = "serveradmin";
    my $pass = "*********";
    my $sid = 1;
    
    my $sock = IO::Socket::INET->new(
          PeerAddr    => $query_address,
          PeerPort    => $query_port,
          Proto       => 'TCP',
          Autoflush   => 1,
          Blocking    => 1,
    ) or die "Server Failed to Start : [email protected]";
    
    # Login to TS3
    print $sock "login $login $pass\n";
    print $sock "use sid=$sid\n"; 
    
    # Ask for clientlist
    print $sock "clientlist\n";
    
    # Wait for server/query to receive above socket data
    sleep(1);
    
    # Receive clientlist from socket response
    my ($data);
    $sock->recv($data,4096);
    
    # Not sure if your program continues but just in case...
    close($sock);
    
    if ( $data =~ /error id=([^0?]\d+)/ ) {
        # Error Handler...?
        print "Error Fetching Clientlist\n";
    }
    else {
        # Array to hold users online
        my @users = $data =~ /client_nickname=(.+?) /gi;
        
        # Output Array With Users Online
        print join(', ',@users)."\n"; 
    }
    Last edited by Scor9ioN; July 21st, 2012 at 12:43 AM. Reason: Updated Code.

  3. #3
    Join Date
    June 2012
    Location
    Earth
    Posts
    181
    OR if you need that while(<$sock>) loop instead (I hate adding sleep in that last code, unless it was forked off the parent)..

    I've tested this also..
    Code:
    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use IO::Socket;
    
    my $sock = IO::Socket::INET->new(
          PeerAddr    => "voice.server.com",
          PeerPort    => 10011,
          Proto       => 'TCP',
          Autoflush   => 1,
    ) or die "Socket Failed To Start : [email protected]";
    
    print $sock "login serveradmin *******\n";
    print $sock "use sid=1\n";
    print $sock "clientlist\n";
    
    # Declare undefined array.
    my @users = ();
    
    while(defined(my $data = <$sock>)) {
        if ($data =~ /error id=([^0?]\d+)/) {
            print "Error Fetching Clientlist\n";
            last;
        }
        elsif ($data =~ /client_nickname/) {
            # replace global array with this.
            @users = $data =~ /client_nickname=(.+?) client/gi;
            last;
        }
    }
    
    # Process defined array.
    if (@users) {
        # Some nicknames have \s for a whitespace. replace with our own whitespace.
        s/\\s/ /gi for @users;
        # Take a look at what we did.
        print join(', ',@users)."\n";
    }
    
    close($sock);
    exit(0);
    Last edited by Scor9ioN; July 21st, 2012 at 12:44 AM. Reason: Updated Code.

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •