Development > Coding and development discussion

Assistance with AAmon

(1/1)

bitnykk:

--- Quote from: botman on January 02, 2021, 03:17:22 pm ---Hi, I was able to piece together guides and managed to get Bebot working with Php7.3. There are some additional features around the web for adding modules but I don't believe the author is active. I was wondering if anyone could assist me (my lack of knowledge) in correcting the issue that is preventing this module from working.

What it does? The module is suppose to simple keep track of time for characters (AA).
Game? Age of Conan (surprisingly still has some really dedicated players)
Error: Line 63 states it was not expecting an "&"

This line: parent::__construct(&$bot, get_class($this));



--- Code: --- <?php
/***************************************************************************************************
 * BeBot - An Anarchy Online & Age of Conan Chat Automaton
 * Copyright (C) 2004 Jonas Jax
 * Copyright (C) 2005-2010 Thomas Juberg, ShadowRealm Creations and the BeBot development team.
 *
 * Developed by:
 * - Alreadythere (RK2)
 * - Blondengy (RK1)
 * - Blueeagl3 (RK1)
 * - Glarawyn (RK1)
 * - Khalem (RK1)
 * - Naturalistic (RK1)
 * - Temar (RK1)
 *
 * See Credits file for all acknowledgements.
 ***************************************************************************************************
 * AAMon module for Bebot
 * This module lets users keep track of their AA training in a central database.
 * Users can later get hold of their data using external clients (WIP).
 *
 * Author:    Kentarii [Ragnarok] @ EN Fury PvP
 * E-mail:    Does not take a rocket scientist to figure out..
 * Website:    http://aoc.is-better-than.tv/aamon.php
 ***************************************************************************************************
 * Installation:
 *        Copy AAMon.phps to <bebot_dir>/custom/modules/AAMon.php and restart bot
 * Disable module:
 *        Rename AAMon.php to _AAMon.php and restart bot
 * Uninstallation:
 *        Delete <bebot_dir>/custom/modules/AAMon.php and restart bot
 ***************************************************************************************************
 * Changelog:
 *    2011-09-28    0.0.12    Add support for registering an e-mail to a character
 *    2011-06-15    0.0.11    Automatically update apiurl when initializing if changed
 *    2011-06-14    0.0.10    Update AAMon apiurl
 *    2011-03-05    0.0.9    Fix html entity decoding of skillnames.
 *    2010-12-26    0.0.8    Change some info text. Add agent/version string to requests.
 *                        Add fetch_api_data function for querying API.
 *    2010-11-27    0.0.7    Add "AuthKey" for easier copy/paste of authentication from chat to the
 *                        AAMon for Windows client.
 *    2010-11-26    0.0.6    Add new version check. Change some text. First public release.
 *    2010-11-26    0.0.5    Change text for skill which has completed for show.
 *    2010-11-25    0.0.4    Add more info to apikey call. Fix sorting for showall.
 *    2010-11-24    0.0.3    Add function to retrieve API key for character, fixed some colors and bugs.
 *    2010-11-23    0.0.2    First closed beta release.
 *    2010-11-22    0.0.1    Started coding on this module, replicated all functionality of timeraa.
 ***************************************************************************************************
 * Credits:
 *        Getrix for the original TimerAA module
 ***************************************************************************************************
 */

$AAMon = new AAMon($bot);

class AAMon extends BaseActiveModule {
    var $bot;
    var $agent;
    var $version;
    var $aoctv_version;

    function __construct (&$bot) {
        parent::__construct(&$bot, get_class($this));

        $this -> agent = 'AAMon module for Bebot';
        $this -> version = '0.0.12';
        $this -> bot -> core('settings') -> create('AAMon', 'apiurl', 'http://aoc.is-better-than.tv/api.php', "URL to AoC>TV API.");
        $this -> bot -> core('settings') -> create('AAMon', 'botkey', '', "AoC>TV API Key.");

        if ($this -> init()) {
            $this -> register_command('all', 'aamon', 'MEMBER');

            $this -> help['description'] = "This module lets users keep track of their AA training in a central database.";
            $this -> help['command']['aamon set <duration> [skillname] [skillrank]'] = "Set the duration for your current AA skill training. Duration should be hours left. Skillname is the name of the skill (optional). Skillrank should be a number from 1 to 5 (optional).";
            $this -> help['command']['aamon show [nickname]'] = "Show how long time left on AA skill training for [nickname].";
            $this -> help['command']['aamon showall [nickname]'] = "Show how long time left on AA skill training for all chars of [nickname].";
            $this -> help['command']['aamon apikey'] = "Retrieve AuthKey/ApiKey for your character so that you can access the data outside of the game.";
            $this -> help['command']['aamon email'] = "Show current registered e-mail and status for your character.";
            $this -> help['command']['aamon register <email>'] = "Register an e-mail address to enable notificiation e-mails to be sent when a skill finishes.";
            $this -> help['notes'] = sprintf("AAMon v##lightbeige##%s##end##, created by Kentarii [Ragnarok] @ EN Fury PvP 2008-%d\nDownload new versions and AAMon for Windows @ http://aoc.is-better-than.tv/aamon.php\n", $this -> version, date('Y'));
        }
        else {
            $this -> bot -> log('AAMon', 'ERROR', 'Bot failed authentication, make sure you set the right botkey in settings. If you have lost your botkey, contact Kentarii @ AoC>TV Forums.');
        }
    }

    /**
     * This function registers with the central database if connected for the first time.
     * If already registered, it validates the apikey.
     * @return bool
     */
    function init() {
        $botkey = $this -> bot -> core('settings') -> get('AAMon', 'botkey');
        $data = $this -> fetch_api_data('aamon/bot/init');
        if (!$data['error'] && $data['content']) {
            try {
                $xml = simplexml_load_string($data['content']);
                if (intval($xml -> status) == 1) {
                    $this -> aoctv_version = (string) $xml -> data -> version;
                    // save new botkey to settings
                    if ($botkey != (string)$xml -> data -> apikey) {
                        $this -> bot -> core('settings') -> save('AAMon', 'botkey', (string)$xml -> data -> apikey);
                    }
                    // update apiurl if needed
                    if ($this -> bot -> core('settings') -> get('AAMon', 'apiurl') != (string)$xml -> data -> apiurl) {
                        $this -> bot -> core('settings') -> save('AAMon', 'apiurl', (string)$xml -> data -> apiurl);
                    }
                    return true;
                }
            }
            catch (Exception $ex) {
                return false;
            }
        }
        return false;
    }

    /**
     * Command handler for module
     * @param string $name
     * @param string $msg
     * @param string $origin
     * @return string
     */
    function command_handler($name, $msg, $origin) {
        if (preg_match("/^aamon set ([\d]+) ([\w\' ]+) ([\d]{1})$/", $msg, $m)) {
            $duration = intval($m[1]);
            $skillname = trim($m[2]);
            $skillrank = intval($m[3]);
            $rv = $this -> aa_set($name, $duration, $skillname, $skillrank) ."##end##";
        }
        else if (preg_match("/^aamon set ([\d]+) ([\w\' ]+)$/i", $msg, $m)) {
            $duration = intval($m[1]);
            $skillname = trim($m[2]);
            $rv = $this -> aa_set($name, $duration, $skillname) ."##end##";
        }
        else if (preg_match("/^aamon set ([\d]+)$/i", $msg, $m)) {
            $duration = intval($m[1]);
            $rv = $this -> aa_set($name, $duration) ."##end##";
        }
        else if (preg_match("/^aamon show ([\w]+)$/i", $msg, $m)) {
            $char_name = ucfirst(strtolower(trim($m[1])));
            $rv = $this -> aa_show($char_name) ."##end##";
        }
        else if (preg_match("/^aamon show$/i", $msg)) {
            $rv = $this -> aa_show($name) ."##end##";
        }
        else if (preg_match("/^aamon showall ([\w]+)$/i", $msg, $m)) {
            $char_name = ucfirst(strtolower(trim($m[1])));
            $rv = $this -> aa_showall($char_name) ."##end##";
        }
        else if (preg_match("/^aamon showall$/i", $msg)) {
            $rv = $this -> aa_showall($name) ."##end##";
        }
        else if (preg_match("/^aamon apikey$/i", $msg)) {
            $this -> bot -> send_tell($name, $this -> apikey_get($name));
            return false;
        }
        else if (preg_match("/^aamon email$/i", $msg)) {
            $this -> bot -> send_tell($name, $this -> email_get($name));
            return false;
        }
        else if (preg_match("/^aamon register (.*)$/i", $msg, $m)) {
            $email = strtolower(trim($m[1]));
            $this -> bot -> send_tell($name, $this -> email_set($name, $email));
            return false;
        }
        else { // show help
            $this -> bot -> send_help($name, 'aamon');
            return false;
        }
        return "##white####clan##[-AAMon-]##end## :: ". $rv;
    }

    /**
     * Fetch data from the AoC>TV API
     * @param string $op
     * @param array $params
     * @return array
     */
    function fetch_api_data($op, $params = array()) {
        $url = sprintf("%s?op=%s&dimension=%s&botname=%s&botkey=%s&agent=%s&version=%s",
            $this -> bot -> core('settings') -> get('AAMon', 'apiurl'),
            $op,
            urlencode($this -> bot -> dimension),
            urlencode($this -> bot -> botname),
            urlencode($this -> bot -> core('settings') -> get('AAMon', 'botkey')),
            urlencode($this -> agent),
            urlencode($this -> version)
        );
        if (count($params) > 0) {
            foreach ($params as $k => $v) {
                $url .= '&'. $k .'='. urlencode($v);
            }
        }
        return $this -> bot -> core('tools') -> get_site($url, 1);
    }

    /**
     * Set skill training for selected character
     * @param string $char_name
     * @param string $duration
     * @param string $skillname
     * @param string $skillrank
     * @return string
     */
    function aa_set($char_name, $duration, $skillname = 'Unknown Skill', $skillrank = 1) {
        if ($char_id = $this -> bot -> core('chat') -> get_uid($char_name)) {
            $data = $this -> fetch_api_data('aamon/aa/set', array(
                'char_id' => $char_id,
                'nickname' => $char_name,
                'duration' => $duration,
                'skillname' => $skillname,
                'skillrank' => $skillrank,
            ));
            if (!$data['error'] && $data['content']) {
                try {
                    $xml = simplexml_load_string($data['content']);
                    if (intval($xml -> status) == 1) {
                        $this -> aoctv_version = (string) $xml -> data -> version;
                        return sprintf("Timer added for ##seablue##%s##end##. Training ##forestgreen##%s##end## rank ##forestgreen##%d##end## on a ##forestgreen##%dh##end## timer. ETA: ##yellow##%s##end## UTC, time left: ##yellow##%s##end##.", $char_name, $skillname, $skillrank, $duration, $xml -> data -> end_dt, $xml -> data -> countdown);
                    }
                    else {
                        return sprintf("##red##An error occured when trying to add skill training for ##seablue##%s##end##: %s##end##", $char_name, $xml -> message);
                    }
                }
                catch (Exception $ex) {
                    return sprintf("##red##An error occured when parsing xml: %s##end##", $ex->getMessage());
                }
            }
            return "##red##An error occured when fetching info from database, please try again later.##end##";
        }
        return sprintf("##red##Character ##seablue##%s##end## is not a member of this bot.##end##", $char_name);
    }

    /**
     * Show skill training for selected character
     * @param string $char_name
     * @return string
     */
    function aa_show($char_name) {
        if ($char_id = $this -> bot -> core('chat') -> get_uid($char_name)) {
            $data = $this -> fetch_api_data('aamon/aa/get', array('char_id' => $char_id));
            if (!$data['error'] && $data['content']) {
                try {
                    $xml = simplexml_load_string($data['content']);
                    if (intval($xml -> status) == 1) {
                        if ($xml -> data -> character -> current_skill_id == 0) {
                            return sprintf("%s has no skill in training at the moment.", $this -> aa_history($char_name, $xml));
                        }
                        else if ($xml -> data -> character -> current -> seconds == 0) {
                            return sprintf("%s has completed skill training of ##forestgreen##%s##end## rank ##forestgreen##%d##end## @ ##yellow##%s##end## UTC.",
                                $this -> aa_history($char_name, $xml),
                                html_entity_decode($xml -> data -> character -> current -> skillname),
                                $xml -> data -> character -> current -> skillrank,
                                $xml -> data -> character -> current -> end_dt
                            );
                        }
                        else {
                            return sprintf("%s is currently training ##forestgreen##%s##end## rank ##forestgreen##%d##end## on a ##forestgreen##%dh##end## timer. ETA: ##yellow##%s##end## UTC, time left: ##yellow##%s##end##.",
                                $this -> aa_history($char_name, $xml),
                                html_entity_decode($xml -> data -> character -> current -> skillname),
                                $xml -> data -> character -> current -> skillrank,
                                $xml -> data -> character -> current -> duration,
                                $xml -> data -> character -> current -> end_dt,
                                $xml -> data -> character -> current -> countdown
                            );
                        }
                    }
                    else {
                        return sprintf("##red##An error occured when trying to get skill training for ##seablue##%s##end##: %s##end##", $char_name, $xml -> message);
                    }
                }
                catch (Exception $ex) {
                    return sprintf("##red##An error occured when parsing xml: %s", $ex->getMessage());
                }
            }
            return "##red##An error occured when fetching info from database, please try again later.##end##";
        }
        return sprintf("##red##Character ##seablue##%s##end## is not a member of this bot.##end##", $char_name);
    }

    /**
     * Create a string/blob with AA history for a character
     * @param string $char_name
     * @param SimpleXMLElement $xml
     * @return string
     */
    function aa_history($char_name, $xml) {
        if (count($xml -> data -> character -> history -> skill) > 0) {
            $content = sprintf("<center><font face='hyborianlarge' color='#ff9933'>AA History for %s</font></center><br>", $char_name);
            foreach ($xml -> data -> character -> history -> skill as $skill) {
                if (intval($xml -> data -> character -> current_skill_id) == intval($skill -> id)) {
                    $content .= sprintf("##forestgreen##%s##end## rank ##forestgreen##%d##end## :: ##forestgreen##%dh##end## :: ##yellow##%s##end## -> ##yellow##%s##end## :: ##yellow##%s##end##<br>",
                        html_entity_decode($skill -> skillname),
                        $skill -> skillrank,
                        $skill -> duration,
                        substr($skill -> start_dt, 0, 10),
                        substr($skill -> end_dt, 0, 10),
                        $skill -> countdown
                    );
                }
                else {
                    $content .= sprintf("##forestgreen##%s##end## rank ##forestgreen##%d##end## :: ##forestgreen##%dh##end## :: ##yellow##%s##end## -> ##yellow##%s##end##<br>",
                        html_entity_decode($skill -> skillname),
                        $skill -> skillrank,
                        $skill -> duration,
                        substr($skill -> start_dt, 0, 10),
                        substr($skill -> end_dt, 0, 10)
                    );
                }
            }
            $this -> version_notify($content);
            return $this -> bot -> core('tools') -> make_blob($char_name, '##white##'. $content .'##end##');
        }
        else {
            return sprintf("##seablue##%s##end##", $char_name);
        }
    }

    /**
     * Show skill training for all alts of selected character
     * @param string $char_name
     * @return string
     */
    function aa_showall($char_name) {
        if ($char_id = $this -> bot -> core('chat') -> get_uid($char_name)) {
            $chars = array();
            $rows = $this -> bot -> db -> select(sprintf("SELECT main FROM alts WHERE alt = '%s'", mysql_real_escape_string($char_name)), MYSQL_ASSOC);
            if (is_array($rows) && count($rows) == 1) {
                $main_char_name = $rows[0]['main']; //
                $main_char_id = $this -> bot -> core('chat') -> get_uid($main_char_name);
                if ($main_char_id > 0) {
                    $chars[$main_char_id] = array('char_id' => $main_char_id, 'nickname' => $main_char_name);
                }
            }
            else {
                $main_char_name = $char_name;
                $main_char_id = $char_id;
                $chars[$main_char_id] = array('char_id' => $main_char_id, 'nickname' => $main_char_name);
            }
            $rows = $this -> bot -> db -> select(sprintf("SELECT alt FROM alts WHERE main = '%s'", mysql_real_escape_string($main_char_name)), MYSQL_ASSOC);
            if (is_array($rows) && count($rows) > 0) {
                foreach ($rows as $row) {
                    $cid = $this -> bot -> core('chat') -> get_uid($row['alt']);
                    if ($cid > 0) {
                        $chars[$cid] = array('char_id' => $cid, 'nickname' => $row['alt']);
                    }
                }
            }
            foreach ($chars as $cid => $char) {
                $data = $this -> fetch_api_data('aamon/aa/get', array('char_id' => $cid));
                if (!$data['error'] && $data['content']) {
                    try {
                        $xml = simplexml_load_string($data['content']);
                        if (intval($xml -> status) == 1) {
                            if ($xml -> data -> character -> current_skill_id == 0) {
                                $char['result'] = sprintf("##seablue##%s##end## has no skill in training at the moment.", $char['nickname']);
                                $char['seconds'] = -1;
                            }
                            else if ($xml -> data -> character -> current -> seconds == 0) {
                                $char['result'] = sprintf("##seablue##%s##end## has completed skill training of ##forestgreen##%s##end## rank ##forestgreen##%d##end## @ ##yellow##%s##end## UTC.",
                                    $char['nickname'],
                                    html_entity_decode($xml -> data -> character -> current -> skillname),
                                    $xml -> data -> character -> current -> skillrank,
                                    $xml -> data -> character -> current -> end_dt
                                );
                                $char['seconds'] = 0;
                            }
                            else {
                                $char['result'] = sprintf("##seablue##%s##end## is currently training ##forestgreen##%s##end## rank ##forestgreen##%d##end## on a ##forestgreen##%dh##end## timer.<br>ETA: ##yellow##%s##end## UTC, time left: ##yellow##%s##end##.",
                                    $char['nickname'],
                                    html_entity_decode($xml -> data -> character -> current -> skillname),
                                    $xml -> data -> character -> current -> skillrank,
                                    $xml -> data -> character -> current -> duration,
                                    $xml -> data -> character -> current -> end_dt,
                                    $xml -> data -> character -> current -> countdown
                                );
                                $char['seconds'] = $xml -> data -> character -> current -> seconds;
                            }
                        }
                        else {
                            $char['result'] = sprintf("##seablue##%s##end## has not been registered.", $char['nickname']);
                            $char['seconds'] = 10000000; // sort this at the bottom
                        }
                    }
                    catch (Exception $ex) {
                        $char['result'] = sprintf("##red##An error occured when parsing xml for ##seablue##%s##end##: %s", $char['nickname'], $ex->getMessage());
                        $char['seconds'] = 20000000; // sort this at the bottom
                    }
                }
                else {
                    $char['result'] = sprintf("##red##An error occured when fetching info from database for ##seablue##%s##end##, please try again later.##end##", $char['nickname']);
                    $char['seconds'] = 30000000; // sort this at the bottom
                }
                $chars[$cid] = $char;
            }
            $content = sprintf("<center><font face='hyborianlarge' color='#ff9933'>AA Skill Training for %s and alts</font></center><br>", $main_char_name);
            usort($chars, array($this, 'char_cmp'));
            foreach ($chars as $c) {
                $content .= $c['result'] .'<br><b></b><br>';
            }
            $this -> version_notify($content);
            return sprintf("AA Skill Training for %s and alts", $this -> bot -> core('tools') -> make_blob($main_char_name, '##white##'. $content .'##end##'));
        }
        return sprintf("##red##Character ##seablue##%s##end## is not a member of this bot.##end##", $char_name);
    }

    /**
     * Sort by seconds left or nickname if equal
     * @param array $a
     * @param array $b
     * @return int
     */
    function char_cmp($a, $b) {
        if (intval($a['seconds']) == intval($b['seconds'])) {
            if ($a['nickname'] == $b['nickname']) return 0;
            return ($a['nickname'] < $b['nickname']) ? -1 : 1;
        }
        return (intval($a['seconds']) < intval($b['seconds'])) ? -1 : 1;
    }

    /**
     * Retrieve and send API key to character through tell
     */
    function apikey_get($char_name) {
        if ($char_id = $this -> bot -> core('chat') -> get_uid($char_name)) {
            $data = $this -> fetch_api_data('aamon/char/apikey', array('char_id' => $char_id));
            if (!$data['error'] && $data['content']) {
                try {
                    $xml = simplexml_load_string($data['content']);
                    if (intval($xml -> status) == 1) {
                        return sprintf("Authentication details for ##seablue##%s##end## :: [AuthKey: ##forestgreen##%s;%s;%s##end##] :: [Dimension: ##forestgreen##%s##end##][CharID: ##forestgreen##%s##end##][ApiKey: ##forestgreen##%s##end##]",
                            $char_name,
                            $xml -> data -> dimension,
                            $xml -> data -> char_id,
                            $xml -> data -> apikey,
                            $xml -> data -> dimension,
                            $xml -> data -> char_id,
                            $xml -> data -> apikey
                        );
                    }
                    else {
                        return sprintf("##red##An error occured when trying to get API key for ##seablue##%s##end##: %s##end##", $char_name, $xml -> message);
                    }
                }
                catch (Exception $ex) {
                    return sprintf("##red##An error occured when parsing xml: %s", $ex->getMessage());
                }
            }
            return "##red##An error occured when fetching info from database, please try again later.##end##";
        }
        return sprintf("##red##Character ##seablue##%s##end## is not a member of this bot.##end##", $char_name);
    }

    /**
     * Retrieve and send e-mail info to character through tell
     */
    function email_get($char_name) {
        if ($char_id = $this -> bot -> core('chat') -> get_uid($char_name)) {
            $data = $this -> fetch_api_data('aamon/char/email/get', array('char_id' => $char_id));
            if (!$data['error'] && $data['content']) {
                try {
                    $xml = simplexml_load_string($data['content']);
                    if (intval($xml -> status) == 1) {
                        $email = (string) $xml -> data -> email;
                        return sprintf("E-mail details for ##seablue##%s##end## :: [E-mail address: ##forestgreen##%s##end##] :: [Verified: ##forestgreen##%s##end##]",
                            $char_name,
                            ($email) ? $email : 'not registered',
                            (intval($xml -> data -> verified) == 1) ? 'yes' : 'no'
                        );
                    }
                    else {
                        return sprintf("##red##An error occured when trying to get e-mail details for ##seablue##%s##end##: %s##end##", $char_name, $xml -> message);
                    }
                }
                catch (Exception $ex) {
                    return sprintf("##red##An error occured when parsing xml: %s", $ex->getMessage());
                }
            }
            return "##red##An error occured when fetching info from database, please try again later.##end##";
        }
        return sprintf("##red##Character ##seablue##%s##end## is not a member of this bot.##end##", $char_name);
    }

    /**
     * Register e-mail address for a character
     */
    function email_set($char_name, $email) {
        if ($char_id = $this -> bot -> core('chat') -> get_uid($char_name)) {
            if ($this -> is_email($email)) {
                $data = $this -> fetch_api_data('aamon/char/email/set', array('char_id' => $char_id, 'email' => $email));
                if (!$data['error'] && $data['content']) {
                    try {
                        $xml = simplexml_load_string($data['content']);
                        if (intval($xml -> status) == 1) {
                            return sprintf("E-mail address ##seablue##%s##end## has been registered for ##seablue##%s##end##, please check your e-mail and click on the confirmation link (remember to check your spam folder).",
                                $email,
                                $char_name
                            );
                        }
                        else {
                            return sprintf("##red##An error occured when trying to register ##seablue##%s##end## as e-mail address for ##seablue##%s##end##: %s##end##", $email, $char_name, $xml -> message);
                        }
                    }
                    catch (Exception $ex) {
                        return sprintf("##red##An error occured when parsing xml: %s", $ex->getMessage());
                    }
                }
                return "##red##An error occured when fetching info from database, please try again later.##end##";
            }
            return sprintf("##red####seablue##%s##end## is not a valid e-mail address.##end##", $email);
        }
        return sprintf("##red##Character ##seablue##%s##end## is not a member of this bot.##end##", $char_name);
    }

    function is_email($addr) {
        return preg_match('/[^ @<>][email protected]([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]+$/', $addr);
    }

    function version_notify(&$text) {
        if ($this -> version != $this -> aoctv_version) {
            $text .= sprintf("<b></b><br>AAMon module for Bebot v%s is now available (your Bebot is currently running v%s).<br>", $this -> aoctv_version, $this -> version);
        }
    }
}
?>



--- End code ---

--- End quote ---

bitnykk:
Hi Botman,

From a very quick first look, seems the main element for adapting this module to PHP 7.3 and Bebot 0.7.x is to remove the "&" letter within construct line 63 which will result into :
<<
parent::__construct($bot, get_class($this));
>>

That's the least i had to do over all modules within bot folder :
https://github.com/J-Soft/BeBot/blob/master/Modules/
(PS : btw, this official version was ported to PHP 7+ so you can clone from it ...)

In some specific cases, more codechanging was needed.
Start with this, restart bot and see if you get more warnings/errors.

Please let us know if more issues (or solved ^^).

Navigation

[0] Message Index

Go to full version