felixms / arma-rcon-class-php

A lightweight client for sending commands easily to a BattlEye server.
MIT License
46 stars 22 forks source link

Bug with long answer in function get_answer() #1

Closed JaG-v2 closed 8 years ago

JaG-v2 commented 8 years ago

There is an issue with this function, when the answer is longer than 1024 characters. The answer is truncated to the first 1024 characters. I found the issue when I tried to retrieve my ban list, which contains 48 lines. BTW thanks for the great job, very usefull class

felixms commented 8 years ago

Thank you for reporting the issue! Fixed the problem, up to 65536 characters are now possible :smile:

JaG-v2 commented 8 years ago

Thanks for prompt answering :). I just made a test, but I still have the same problem. It still only contains 1024 characters

I made an adjustment, which is working, but probably not the best. Here is my content for the get_answer function :

$answer = fread($this->socket, 6553600);
$output = substr($answer, 9);
while ( $answer != '' ) 
{
        $answer = fread($this->socket, 6553600);
        $output .= substr($answer, 12);
}
return $output;

Then the output is correct I also put the substr to 12 in the while, otherwise, I had a weird output

felixms commented 8 years ago

Mmmh, alright, anyway thanks for your help! I can't test this at the moment, but may you try this please:

private function get_answer()
        {
            $get = function() { return substr(fread($this->socket, 102400), strlen($this->RCONpassword) + 1); };
            $answer = $get();
            $output = $answer;

            /* Remove the admin-login message */
            while ( strpos($answer,'RCon admin') !== false ) {
                $answer = $get();
                $output = $answer;
            }

            /* If the answer from the server is longer, get the other parts */
            do {
                $answer = $get();
                $output .= $answer;
            } while ( $answer != '' );

            return $output;
        }
JaG-v2 commented 8 years ago

Things getting better :) A few issue at the begin of the output and when the output is concatenated. I fixed the concatenated part with :

 $get = function() { return substr(fread($this->socket, 102400), 12); };

But the begin is still not pretty :

n admin #0 (XXX.XXX.XXX.XXX:52172) logged inGUID Bans:
felixms commented 8 years ago

The problem is, that we want to remove the head from the message, and the head has a different length in your case. May you test another thing for me please? Add the private class var $head and add to the send function:

            $msg = $head.$command;
            $this->head = $head; //add this

and finally the $get function in get_answer() should be:

$get = function() { return substr(fread($this->socket, 102400), strlen($this->head)); };

This should do the work, I used it in earlier versions. Thank you for your help! :smile:

JaG-v2 commented 8 years ago

Yes it's working great thanks a lot :) Just, when I view the source, I still got those weird signs, like if the data of a character was split But it isn't a problem, as the string doesn't not contains those signs when I var dump the var and is still usable in the rest of the app without any issue. I've got another question :). I would like to find a way to receive the message from the server console. Basically, I want to keep an opened rcon connection, and retrieve each message from the console, in order to store them in a database. Like for example, connection and disconnection message. Do you have any idea for the best way to perform this action ?

felixms commented 8 years ago

Nice to hear, that it works! I understand your question, have you tried to set get_answer() public and run the function, e.g. in a loop. Otherwise there isn't any possibility to do this in PHP, if you want a static connection to the server, you should give NodeJS a try. If you try it the PHP way, you'd better use socket_create(), but it should not make any big difference.

JaG-v2 commented 8 years ago

I was maybe a little too quick in my analysis :( Still got an unwanted Rcon admin in the string Unfortunately, I don't have any skill in NodeJS. Though about the socket, will try this way. Thanks for advice :)

felixms commented 8 years ago

This should finally do the trick:

private function get_answer()
        {
            $get = function() { return substr(fread($this->socket, 102400), strlen($this->head)); };
            $output = '';

            do {
                $answer = $get();
                while ( strpos($answer,'RCon admin') !== false ) $answer = $get();
                $output .= $answer;
            } while ( $answer != '' );

            return $output;
        }

Sorry, that you have to test it, I don't have any Arma server ready at the moment :+1:

JaG-v2 commented 8 years ago

Working like a charm :) BTW, I'm using it on a DayZ Standalone server, so you can add it to the supported server list. Note that ATM, RCON is only usable on Privates Hives of DayZ SA Servers My next step is to try to log the console, I'll keep you informed if I managed to do it. :) Last thing, I made a small change in order to give a reason when you kick someone :

public function kick_player($player, $reason = 'Admin Kick')
        {
            return $this->send("kick ".$player." ".$reason);
        }
felixms commented 8 years ago

Thank you for the enhancement :) I've added it to v1.3.4. I'd like to hear more about your try, I also got an idea, might be useful for you. If you are interested, you may add me on steam, so we can talk a little bit more :smile: http://steamcommunity.com/id/nizarii/

JaG-v2 commented 8 years ago

Nice :) I'd be please to discuss about this. I'll add you on steam asap :)