Frug / AJAX-Chat

A fully customizable web chat implemented in JavaScript, PHP and MySQL which integrates nicely with common forum systems like phpBB, MyBB, FluxBB, SMF and vBulletin. A Flash and Ruby based socket connection can be used to boost performance.
http://frug.github.io/AJAX-Chat/
548 stars 300 forks source link

SMF Karma patch #54

Open shermdog opened 11 years ago

shermdog commented 11 years ago

I've extended chat to support SMF karma. The code is not the cleanest or most secure (not checking if users are allowed to modify karma or limiting how many times per hour they modify), but my user base is small and trusted.

Hopefully this is a good start for anyone wanting to build on this.

The syntax in chat is /points (username) /crisp username /soggy username

(That's what we call good and bad :)

lib/class/CustomAjaxChat.php

    function karma ($name, $uid, $mode) {
        global $db_prefix;
        if ($mode == 1) {
            $sql = 'UPDATE
                        '.$db_prefix.'members
                    SET
                        karma_good  = karma_good + 1                                    
                    WHERE
                        id_member = '.$this->db->makeSafe($uid).';';
        }
        else if ($mode == 2) {
            $sql = 'UPDATE
                        '.$db_prefix.'members
                    SET
                        karma_bad   = karma_bad + 1                                 
                    WHERE
                        id_member = '.$this->db->makeSafe($uid).';';
        }
        // Create a new SQL query:
        $result = $this->db->sqlQuery($sql);

        // Stop if an error occurs:
        if($result->error()) {
            $this->insertChatBotMessage(
            $this->getPrivateMessageID(),
            '/error Database '.$result->getError()
            );
            return true;
        }                           

        $sql = 'SELECT
                    karma_good,
                    karma_bad
            FROM
                '.$db_prefix.'members
            WHERE
                id_member = '.$this->db->makeSafe($uid).';';                        

        // Create a new SQL query:
        $result = $this->db->sqlQuery($sql);

        // Stop if an error occurs:
        if($result->error()) {
            $this->insertChatBotMessage(
            $this->getPrivateMessageID(),
            '/error Database '.$result->getError()
            );
            return true;
        }
        if($result->numRows() > 0){
            while($row = $result->fetch()) {    
                $good = $row['karma_good'];
                $bad = $row['karma_bad'];
            }
            //Send out message
            if ($mode == 1){
                $this->insertChatBotMessage(
                    $this->getChannel(),
                    '/crisp '.$this->getUserName().' '.$name.' '.$good.' '.$bad
                );
            }
            else if ($mode == 2){
                $this->insertChatBotMessage(
                    $this->getChannel(),
                    '/soggy '.$this->getUserName().' '.$name.' '.$good.' '.$bad
                );
            }               
            return true;        
        }   
    }

    function parseCustomCommands($text, $textParts) {
        global $db_prefix;

        switch($textParts[0]) {
            case '/points':
                if(count($textParts) == 1) {
                    $uid = $this->getUserID();
                    $name = $this->getUserName();

                } else {
                    // Get users karma:
                    $uid = $this->getIDFromName($textParts[1]);
                    $name = $textParts[1];
                }
                if($uid === null) {
                    $this->insertChatBotMessage(
                        $this->getPrivateMessageID(),
                        '/error UserNameNotFound '.$textParts[1]
                    );
                    return true;
                } else {
                    $sql = 'SELECT
                                karma_good,
                                karma_bad
                        FROM
                            '.$db_prefix.'members
                        WHERE
                            id_member = '.$this->db->makeSafe($uid).';';                        

                    // Create a new SQL query:
                    $result = $this->db->sqlQuery($sql);

                    // Stop if an error occurs:
                    if($result->error()) {
                        $this->insertChatBotMessage(
                        $this->getPrivateMessageID(),
                        '/error Database '.$result->getError()
                        );
                        return true;
                    }
                    if($result->numRows() > 0){
                        while($row = $result->fetch()) {    
                            $good = $row['karma_good'];
                            $bad = $row['karma_bad'];
                        }
                        //Send out points
                        $this->insertChatBotMessage(
                            $this->getChannel(),
                            '/points '.$name.' '.$good.' '.$bad
                        );
                        return true;    
                    }
                }

            case '/crisp':
                if(count($textParts) == 1) {
                    $this->insertChatBotMessage(
                        $this->getPrivateMessageID(),
                        '/error MissingUserName'
                    );
                    return true;
                } else {
                    if ($this->getUserName() == $textParts[1]){
                            $this->insertChatBotMessage(
                            $this->getPrivateMessageID(),
                            '/error SelfKarma'
                        );
                        return true;
                    }
                    else {                  
                        // Update users karma:
                        $uid = $this->getIDFromName($textParts[1]);

                        if($uid === null) {
                            $this->insertChatBotMessage(
                                $this->getPrivateMessageID(),
                                '/error UserNameNotFound '.$textParts[1]
                            );
                            return true;
                        } else {
                            return($this->karma($textParts[1],$uid,1));
                        }
                    }
                }                       
            case '/soggy':
                if(count($textParts) == 1) {
                    $this->insertChatBotMessage(
                        $this->getPrivateMessageID(),
                        '/error MissingUserName'
                    );
                    return true;
                } else {
                    if ($this->getUserName() == $textParts[1]){
                            $this->insertChatBotMessage(
                            $this->getPrivateMessageID(),
                            '/error SelfKarma'
                        );
                        return true;
                    }
                    else {                  
                        // Update users karma:
                        $uid = $this->getIDFromName($textParts[1]);

                        if($uid === null) {
                            $this->insertChatBotMessage(
                                $this->getPrivateMessageID(),
                                '/error UserNameNotFound '.$textParts[1]
                            );
                            return true;
                        } else {
                            return($this->karma($textParts[1],$uid,2));
                        }
                    }
                }   
            default:
                return false;
        }
    }

js/custom.js

ajaxChat.replaceCustomCommands = function(text, textParts) {
   switch(textParts[0]) {
      case '/points':
        var pointText = this.lang['points'].replace(/%s/, textParts[1]);
        pointText = pointText.replace(/%s/, textParts[2]);
        pointText = pointText.replace(/%s/, textParts[3]);
        return  '<span class="chatBotMessage">'
                + pointText
                + '</span>';

      case '/crisp':
        var crispText = this.lang['crisp'].replace(/%s/, textParts[1]);
        crispText = crispText.replace(/%s/, textParts[2]);
        crispText = crispText.replace(/%s/, textParts[3]);
        crispText = crispText.replace(/%s/, textParts[4]);
        return  '<span class="chatBotMessage">'
                + crispText
                + '</span>';    

      case '/soggy':
        var soggyText = this.lang['soggy'].replace(/%s/, textParts[1]);
        soggyText = soggyText.replace(/%s/, textParts[2]);
        soggyText = soggyText.replace(/%s/, textParts[3]);
        soggyText = soggyText.replace(/%s/, textParts[4]);
        return  '<span class="chatBotMessage">'
                + soggyText
                + '</span>';    

        default:
            return text;
   }
}

js/lang/en.js (whatever languages you support.

var ajaxChatLang = {

    points: '%s: +%s/-%s',
    crisp: '%s says %s is crisp! +%s/-%s',
    soggy: '%s says %s is soggy! +%s/-%s',
    errorDatabase: 'Error: Database: %s',
    errorSelfKarma: 'Cannot modify your own points!'
Frug commented 11 years ago

Thanks. I encourage you to share this with the SMF community if you have a place there you can show them. Glad chat is working for you. I hear there are session issues with the SMF integration, if you have any input on that issue it would be appreciated.

shermdog commented 11 years ago

The only issue I've had w/ SMF was having logout set as_POST (didn't work for me). I based my install off the older SMF module floating around and then updated the chat source files. (I manually merge changes now as I've tweaked too many files to wholesale replace. I also don't use Shoutbox, so I think that helps quite a bit.

Frug commented 11 years ago

Cool, thanks.

I'll be removing the change to logout as POST and instead adding a security token to the logout to handle the exploit.

siameze commented 10 years ago

UPDATE: The code in js/lang/en.js seems to cause issues for me as well. I found that it causes the chat to blank out, and no one is able to log in or out.

Nice concept, and I hope someone more talented than I gets a similar script working.