Jump to content

PHP need help with a few things

Joveice
Go to solution Solved by Mr_KoKa,

you read 128 bytes from socket, so even your example (295) will be fragmented and read after 3 fgets.

Hello,

 

I have a few things I need help with.

 

How do I put everything from @ to the first space in a string to a new string? then how do I turn that string into a array where each key=variable is separated with ; until last which is not separated and ends with = or =something.

 

Thats it for now :P

Back-end developer, electronics "hacker"

Link to comment
Share on other sites

Link to post
Share on other sites

For the first part, you use explode()

 

$email = 'username@domain.com';
$e = explode("@",$email)[0];
echo $e;

output

 

Quote

username

 

                     ¸„»°'´¸„»°'´ Vorticalbox `'°«„¸`'°«„¸
`'°«„¸¸„»°'´¸„»°'´`'°«„¸Scientia Potentia est  ¸„»°'´`'°«„¸`'°«„¸¸„»°'´

Link to comment
Share on other sites

Link to post
Share on other sites

2 minutes ago, vorticalbox said:

For the first part, you use explode()

 


$email = 'username@domain.com';
$e = explode("@",$email)[0];
echo $e;

output

 

 

Oh, string will start with a @ so there is nothing in front of it

Back-end developer, electronics "hacker"

Link to comment
Share on other sites

Link to post
Share on other sites

@badges=moderator/1;color=#008000;display-name=joveice;emotes=;id=5e290206-79cf-45cc-83da-8d49a26fc152;mod=1;room-id=170536778;sent-ts=1503421860968;subscriber=0;tmi-sent-ts=1503421858315;turbo=0;user-id=30332954;user-type=mod :joveice!joveice@joveice.tmi.twitch.tv PRIVMSG #digitalarcbot :dassa

@ is the start, I need everything behind into variables, where ; separates them and it stops at " ". Notice there is no ; at the last one.

Back-end developer, electronics "hacker"

Link to comment
Share on other sites

Link to post
Share on other sites

Use a regex!

<?php
    /* Regex Explanation 
     * ([^=@;]+) matches all charachter except '=@;' 
     * Example: badges
     *
     * then 'a' = is required
     * 
     * ([^[:space:];]+)? matches everithing except 'space' and ';' one or 0 times
     * Example: moderator/1
     * 
     * Full Match => badges=moderator/1
    */
    $regex = '/([^=@;]+)=([^[:space:];]+)?/';
	
    $str = '@badges=moderator/1;color=#008000;display-name=joveice;emotes=;id=5e290206-79cf-45cc-83da-8d49a26fc152;mod=1;room-id=170536778;sent-ts=1503421860968;subscriber=0;tmi-sent-ts=1503421858315;turbo=0;user-id=30332954;user-type=mod :joveice!joveice@joveice.tmi.twitch.tv PRIVMSG #digitalarcbot :dassa';
    
    /* Preg Match */
    preg_match_all($regex, $str, $matches, PREG_SET_ORDER, 0);

    /* Get as key->value array, this will ignore rows where the value is not set */
    $array = array_column($matches,2,1);

Working example: https://repl.it/KUpk/2

Business Management Student @ University St. Gallen (Switzerland)

HomeServer: i7 4930k - GTX 1070ti - ASUS Rampage IV Gene - 32Gb Ram

Laptop: MacBook Pro Retina 15" 2018

Operating Systems (Virtualised using VMware): Windows Pro 10, Cent OS 7

Occupation: Software Engineer

Link to comment
Share on other sites

Link to post
Share on other sites

$s = '@badges=moderator/1;color=#008000;display-name=joveice;emotes=;id=5e290206-79cf-45cc-83da-8d49a26fc152;mod=1;room-id=170536778;sent-ts=1503421860968;subscriber=0;tmi-sent-ts=1503421858315;turbo=0;user-id=30332954;user-type=mod :joveice!joveice@joveice.tmi.twitch.tv PRIVMSG #digitalarcbot :dassa';

$spacePos = strpos($s, ' ');
if($spacePos !== false){
  $s = substr($s, 1, $spacePos - 1); // Skipping first character (@) and not including found space
  $vars = explode(';', $s);
  
  $keyValue = array();
  foreach($vars as $var){
    $parts = explode('=', $var);
    if(count($parts) == 2){
      $keyValue[$parts[0]] = $parts[1];
    } else {
      echo 'Invalid variable: '.$var;
    }
  }
  
  var_dump($keyValue);
  
} else {
  echo 'Space not found.';
}

I used strpos to find first space and then substr to skip @ and extract string to the position of the space found. then I just explode string by ; and then each by =

Result is associative array. You can enclosure it into a function and instead of echoing errors return false or throw exceptions. Here is working example: https://repl.it/KUo7/0

Link to comment
Share on other sites

Link to post
Share on other sites

Currently experiencing issues with the data (the string) getting split up for some reason. I var_dump it after it's grabed from the socket, and it spits out 3 strings... it did not do that before, and why on earth does it do that...

Back-end developer, electronics "hacker"

Link to comment
Share on other sites

Link to post
Share on other sites

See if your read buffer is not too small, There is not much to say about it when we don't see source code.

Link to comment
Share on other sites

Link to post
Share on other sites

<?php

//So the bot doesn't stop.

set_time_limit(0);

ini_set('display_errors', 'on');

echo 'boot';

//Example connection stuff.

$config = array(
    'HOST' => 'irc.chat.twitch.tv',
    'PORT' => 6667,
    'AUTH_NICK' => 'nickname',
    'AUTH_PASS' => 'oauth:xxxxxxxxxxxxxxxxxxx',
    'CHANNEL' => 'channeltojoin'
);


class IRCBot {

    private $configarray = array(
            'HOST' => 'irc.chat.twitch.tv',
            'PORT' => 6667,
            'AUTH_NICK' => 'nickname',
            'AUTH_PASS' => 'oauth:xxxxxxxxxxxxxxxxxxx',
            'CHANNEL' => 'channeltojoin'
        );

    //This is going to hold our TCP/IP connection

    var $socket;



    //This is going to hold all of the messages both server and client

    var $ex = array();



    /*

     Construct item, opens the server connection, logs the bot in



     @param array

    */

    function __construct($config)

    {

        $this->socket = fsockopen($config['HOST'], $config['PORT']);

        $this->login($config);

        $this->send_data('JOIN', '#'.$config['CHANNEL']);

        $this->send_data('CAP REQ ', ':twitch.tv/membership');
        $this->send_data('CAP REQ ', ':twitch.tv/commands');
        $this->send_data('CAP REQ ', ':twitch.tv/tags');

        $this->main();

    }



    /*

     Logs the bot in on the server



     @param array

    */

    function login($config)

    {

        $this->send_data('PASS', $config['AUTH_PASS']);

        $this->send_data('NICK', $config['AUTH_NICK']);

    }



    /*

     This is the workhorse function, grabs the data from the server and displays on the browser / aka cmd window

    */

    function main()

    {
        $data = fgets($this->socket, 128);

        echo $data;

        $this->ex = explode(' ', $data);

        if ($data[0] == '@') {
            $s = $data;
            $spacePos = strpos($s, ' ');
            if ($spacePos !== false) {
                $s = substr($s, 1, $spacePos - 1); // Skipping first character (@) and not including found space
                $vars = explode(';', $s);

                $keyValue = array();
                foreach ($vars as $var) {
                    $parts = explode('=', $var);
                    if (count($parts) == 2) {
                        $keyValue[$parts[0]] = $parts[1];
                    }
                }
                if (isset($this->ex[3])) {

                    $command = str_replace(array(chr(10), chr(13)), '', $this->ex[3]);

                    if ($keyValue['user-type'] == 'mod') {

                        switch ($command) //List of commands the bot responds to from a user.

                        {
                            case ':!mod':

                                $this->write('o mod power');

                                break;
                        }
                    }

                    switch($command) //List of commands the bot responds to from a user.

                    {
                        case ':!hello':

                            $this->write('everyone can call me!');

                            break;
                    }
                }
            }
        } elseif ($this->ex[0] == 'PING :tmi.twitch.tv') {
            $this->send_data('PONG :tmi.twitch.tv', $this->ex[1]); //Plays ping-pong with the server to stay connected.
        }

        flush();

        usleep(100000);

        $this->main();

    }



    function send_data($cmd, $msg = null) //displays stuff to the broswer and sends data to the server. / aka cmd window

    {

        if($msg == null)

        {

            fputs($this->socket, $cmd."\r\n");

            echo '> '.$cmd;

        } else {

            fputs($this->socket, $cmd.' '.$msg."\r\n");

            echo $cmd.' :'.$msg;

        }

    }

    function write($msg = null) //send message to channel

    {

        if(!$msg == null)

        {
            $cmd = 'PRIVMSG #'.$this->configarray['CHANNEL'];

            fputs($this->socket, $cmd.' :'.$msg."\r\n");

            echo '> '.$cmd.' :'.$msg;

        }

    }
  
}


	$bot = new IRCBot($config);

@Mr_KoKa

Yes I know it got 2 config arrays but I had issues with it not accepting the first one later in the script and the one inside the class at the start and visa versa

And it's messy.

Back-end developer, electronics "hacker"

Link to comment
Share on other sites

Link to post
Share on other sites

7 minutes ago, Joveice said:

<?php

//So the bot doesn't stop.

set_time_limit(0);

ini_set('display_errors', 'on');

echo 'boot';

//Example connection stuff.

$config = array(
    'HOST' => 'irc.chat.twitch.tv',
    'PORT' => 6667,
    'AUTH_NICK' => 'nickname',
    'AUTH_PASS' => 'oauth:xxxxxxxxxxxxxxxxxxx',
    'CHANNEL' => 'channeltojoin'
);


class IRCBot {

    private $configarray = array(
            'HOST' => 'irc.chat.twitch.tv',
            'PORT' => 6667,
            'AUTH_NICK' => 'nickname',
            'AUTH_PASS' => 'oauth:xxxxxxxxxxxxxxxxxxx',
            'CHANNEL' => 'channeltojoin'
        );

    //This is going to hold our TCP/IP connection

    var $socket;



    //This is going to hold all of the messages both server and client

    var $ex = array();



    /*

     Construct item, opens the server connection, logs the bot in



     @param array

    */

    function __construct($config)

    {

        $this->socket = fsockopen($config['HOST'], $config['PORT']);

        $this->login($config);

        $this->send_data('JOIN', '#'.$config['CHANNEL']);

        $this->send_data('CAP REQ ', ':twitch.tv/membership');
        $this->send_data('CAP REQ ', ':twitch.tv/commands');
        $this->send_data('CAP REQ ', ':twitch.tv/tags');

        $this->main();

    }



    /*

     Logs the bot in on the server



     @param array

    */

    function login($config)

    {

        $this->send_data('PASS', $config['AUTH_PASS']);

        $this->send_data('NICK', $config['AUTH_NICK']);

    }



    /*

     This is the workhorse function, grabs the data from the server and displays on the browser / aka cmd window

    */

    function main()

    {
        $data = fgets($this->socket, 128);

        echo $data;

        $this->ex = explode(' ', $data);

        if ($data[0] == '@') {
            $s = $data;
            $spacePos = strpos($s, ' ');
            if ($spacePos !== false) {
                $s = substr($s, 1, $spacePos - 1); // Skipping first character (@) and not including found space
                $vars = explode(';', $s);

                $keyValue = array();
                foreach ($vars as $var) {
                    $parts = explode('=', $var);
                    if (count($parts) == 2) {
                        $keyValue[$parts[0]] = $parts[1];
                    }
                }
                if (isset($this->ex[3])) {

                    $command = str_replace(array(chr(10), chr(13)), '', $this->ex[3]);

                    if ($keyValue['user-type'] == 'mod') {

                        switch ($command) //List of commands the bot responds to from a user.

                        {
                            case ':!mod':

                                $this->write('o mod power');

                                break;
                        }
                    }

                    switch($command) //List of commands the bot responds to from a user.

                    {
                        case ':!hello':

                            $this->write('everyone can call me!');

                            break;
                    }
                }
            }
        } elseif ($this->ex[0] == 'PING :tmi.twitch.tv') {
            $this->send_data('PONG :tmi.twitch.tv', $this->ex[1]); //Plays ping-pong with the server to stay connected.
        }

        flush();

        usleep(100000);

        $this->main();

    }



    function send_data($cmd, $msg = null) //displays stuff to the broswer and sends data to the server. / aka cmd window

    {

        if($msg == null)

        {

            fputs($this->socket, $cmd."\r\n");

            echo '> '.$cmd;

        } else {

            fputs($this->socket, $cmd.' '.$msg."\r\n");

            echo $cmd.' :'.$msg;

        }

    }

    function write($msg = null) //send message to channel

    {

        if(!$msg == null)

        {
            $cmd = 'PRIVMSG #'.$this->configarray['CHANNEL'];

            fputs($this->socket, $cmd.' :'.$msg."\r\n");

            echo '> '.$cmd.' :'.$msg;

        }

    }
  
}


	$bot = new IRCBot($config);

@Mr_KoKa

Yes I know it got 2 config arrays but I had issues with it not accepting the first one later in the script and the one inside the class at the start and visa versa

And it's messy.

Jupp, I'll have to redo the code, something is really wrong. I just restarted the script and it worked, restarted it again and it dident work..

Back-end developer, electronics "hacker"

Link to comment
Share on other sites

Link to post
Share on other sites

you read 128 bytes from socket, so even your example (295) will be fragmented and read after 3 fgets.

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×