Back to vBulletin 4.x Add-ons

IRC Eggdrop Bot <---> vBulletin site
Mod Version: 0.00, by Sarteck

vB Version: 4.x.x Rating: (0 vote - 0 average) Installs: 7
Released: 01 Aug 2012 Last Update: Never Downloads: 0
Not Supported  

A user here recently asked me about my "Users on IRC" modification. It's actually part of a fairly elaborate system of communication between my Eggdrop bots and my vBulletin site.

If you would like communication between your IRC Channel and your vBulletin site, read on.

I'm going to assume that you have an Eggdrop bot running already. If you don't, then none of this will work. I will not cover the installation and configuration of Eggdrop bots here. You can find plenty of articles online to help you there.

Also, I use the Rizon network, though I believe that most networks with NickServ services will work fine.

Okay, first thing you have to do is create some Options in your vBulletin Settings. (To do this, you have to be in Debug Mode.)

We need to create two Options. It doesn't matter if you make a separate group for them or not, and it doesn't matter what the human-readable names for them are--they will only be used for storing and retrieving info. The variable names, however, need to be: ircactivity and irclastcheck.

Next thing we need to do is create a new User Profile Field that your users can edit. This Profile Field is where the users will put their IRC handle(s). If they have more than one handle, they an separate them by commas (no spaces before or after!!!). Take note of the field name created--we'll need to remember it for the PHP Script.

Now, we come to the PHP Script. Take note of the first 15 lines--this will contain the stuff that you need to modify.

PHP Code:
<?php
error_reporting
(E_ALL & ~E_NOTICE);
define('THIS_SCRIPT''irc'); /// Modify this to be whatever you want to name your IRC Script.
define('IRC_HANDLE_FIELD''field123'); /// Modify this to whatever Profile Field on your forum you have for IRC Handles
require_once('./global.php');


$allowed_ip_addresses = array();
/// We will allow connections from the webserver
$allowed_ip_addresses[] = '127.0.0.1'// Modify if necessary.
/// We will allow connections from the server the IRC Bot is running on.
$allowed_ip_addresses[] = '1.2.3.4'// Modify or comment out if the IRC Bot is running on the same server.
/// You can allow other IP Addresses for testing purposes in this manner as well.

if (!in_array($_SERVER['REMOTE_ADDR'],$allowed_ip_addresses)) {print_no_permission(); die();}








/// Retrieves Userinfo given a specific IRC Handle
function get_user_by_irc_handle($handle)
{
  global 
$vbulletin;
  
$result $vbulletin->db->query_read(sprintf("SELECT userid FROM ".TABLE_PREFIX."userfield WHERE FIND_IN_SET('%s',%s)"$vbulletin->db->escape_string($handle),IRC_HANDLE_FIELD));
  if (!
$result) {return false;}
  if (
$vbulletin->db->num_rows($result) < 1) {return false;}
  if (
$vbulletin->db->num_rows($result) > 1) {return 2;}
  
$uid =  0;
  while (
$info $vbulletin->db->fetch_array($result)) {$uid $info['userid'];}
  
$user fetch_userinfo($uid);
  return 
$user;
}

/// Retrieves Userinfo given a Username
function get_user_by_vb_name($name)
{
  global 
$vbulletin;
  
$result $vbulletin->db->query_read(sprintf("SELECT userid FROM ".TABLE_PREFIX."user WHERE username='%s'"$vbulletin->db->escape_string($name)));
  if (!
$result) {return false;}
  if (
$vbulletin->db->num_rows($result) < 1) {return false;}
  if (
$vbulletin->db->num_rows($result) > 1) {return 2;}
  
$uid 0;
  while (
$info $vbulletin->db->fetch_array($result)) {$uid $info['userid'];}
  
$user fetch_userinfo($uid);
  return 
$user;
}











/// This will be called by the IRC Bot every minute.
/// It checks for active users on the channel, and sets the info to the setting table
if ($_REQUEST['do'] == 'irc_activity_check')
{
  
$ircnames $vbulletin->input->clean_gpc('r''users'TYPE_STR);
  
$users = array();
  foreach (
explode(' ',$ircnames) AS $handle)
  {
    
$search  = array('{[',']}','\\\\');
    
$replace = array('['']','\\');
    
$handl_parsed str_replace($search$replace$handle);
    
$user get_user_by_irc_handle($handl_parsed);
    if (
$user)
    {
      
$user['irchandle'] = $handl_parsed;
      
$users[$user['userid']] = $user;
    }
    else {
$user['musername'] = $handl_parsed$users[] = $user;}
  }
  
$irc_users = array();
  foreach (
$users AS $userid => $user) {if ($user['userid']) {$irc_users[] = '<a href="member.php?u='.$user['userid'].'">'.$user['musername'].'</a>';} else {$irc_users[] = $user['musername'];}}
  
$query sprintf("UPDATE setting SET value='%d' WHERE varname='irclastcheck'"TIMENOW);
  
$vbulletin->db->query_write($query);
  
$query sprintf("UPDATE setting SET value='%s' WHERE varname='ircactivity'",$vbulletin->db->escape_string(implode(', ',$irc_users)));
  
$vbulletin->db->query_write($query);
  die(
$query);
}

/// This is for when Users do a "!whois" command on the IRC Channel
if ($_POST['do'] == 'whois')
{
  
$whois $vbulletin->input->clean_gpc('p''whois'TYPE_STR);
  
$user get_user_by_irc_handle($whois);
  if (!
$user)     {die('The IRC Nickname you specified, '.$whois.', does not exist in the Club Bleach Database.');}
  if (
$user == 2) {die('The IRC Nickname you specified, '.$whois.', is taken by more than one account in the Club Bleach Database.  Contact an Admin to get to the bottom of things.');}
  die(
$whois.' has the Club Bleach Username of: '.$user['username']);
}

/// This is for when Users do a "!rwhois" command on the IRC Channel
if ($_POST['do'] == 'rwhois')
{
  
$whois $vbulletin->input->clean_gpc('p''whois'TYPE_STR);
  
$user get_user_by_vb_name($whois);
  if (!
$user)     {die('The IRC Nickname you specified, '.$whois.', is not registered at Club Bleach.');}
  
$names explode(',',$user[IRC_HANDLE_FIELD]);
  if (
sizeof($names) > 1) {die($whois.' has the IRC Nicknames of: '.$user[IRC_HANDLE_FIELD]);}
  die(
$whois.' has the IRC Nickname of: '.$user[IRC_HANDLE_FIELD]);
}

/// If we get this far, something went wrong.
die($_SERVER['QUERY_STRING'] . ' --  ' $_REQUEST['do'] . '  --: ERGH');




?>
(This is a VERY trimmed-down version of what I've got, but the stuff I omitted is largely specific to my particular forum, it's "item" database, it's Triple Triad cards, etc. This includes the check for IRC activity for the stuff in WGO, as well as simple WHOIS and REVERSE WHOIS functions to see who a IRC user is on the forum, or to see what a Forum User's IRC Handle is.)

And now, the Tcl script that you'd use for your Eggdrop bot. Again, pay particular attention to the first 15 lines--the Comments tell you what you'll have to Modify.
Code:
### vb.tcl
###
### Our vb.tcl script does the following:
###  -- auto - Keeps an array of IRC Nickname => status.  Status of '3' is 'IDENTIFIED.'
###  -- auto - Sets nickstatus list every other minute to a file for Woogy to read
###  -- !whois checks an IRC handle to see what CB Username it belongs to
###  -- !rwhois checks a vBulletin Username to see what IRC handle it has (can be multiple names)
###  -- FUNCTION: isIdentified - returns true if a nick is ID'd with the Bot, false otherwise.
###
###  NOTE: Find and replace the following:
###  -- http://link.to.your.forum/irc.script.php
###  -- #YourChannel
###  NOTE: If you have Bots on your channel (including the Bot running this!), change the
###        isBot procedure below.
putlog "% Loading Nickname functions"
###############################################################################
###                   Binds (these call the procedures)                     ###
###############################################################################
bind pub - !whois doWhois
bind pub - !rwhois doRWhois
bind notc - "*STATUS*" doSetStatus
bind time - "* * * * *" doSendNames
bind time - "* * * * *" doGetNames
bind time - "* * * * *" doSetNames
###############################################################################
###                Procedures called by public bind events                  ###
###############################################################################
proc doWhois {nick host hand chan text} {
  package require http
  set url http://link.to.your.forum/irc.script.php
  set querystring [http::formatQuery "do" "whois" "whois" $text]
  set token [http::geturl $url -query $querystring]
  set data [http::data $token]
  http::cleanup $token
  putquick "PRIVMSG #YourChannel :$data"
  putloglev p $chan "$data"
  return $data
}
proc doRWhois {nick host hand chan text} {
  package require http
  set url http://link.to.your.forum/irc.script.php
  set querystring [http::formatQuery "do" "rwhois" "whois" $text]
  set token [http::geturl $url -query $querystring]
  set data [http::data $token]
  http::cleanup $token
  putquick "PRIVMSG #YourChannel :$data"
  putloglev p $chan "$data"
  return $data
}
### bind time - "0/2/4/6/8 * * * *" doSendNames
###  -- (once per two minutes)
### saves nickstatus to nickstatus.txt once every other minute (even minutes)
proc doSendNames {min hour day month year} {
  global nickstatus
  set out [open "nickstatus.txt" w]
  puts $out [array get nickstatus]
  close $out
  global nicktime
  set out [open "nicktime.txt" w]
  puts $out [array get nicktime]
  close $out
}
### bind time - "* * * * *" doSetNames
###  -- (once per minute)
### Check each name in the status and time lists
### If the STATUS is 3, add the name to the list send to the database
### If the user has not been checked for 30 minutes, unset them from the arrays
### Set namelist to server (displays in "Who's Online")
proc doSetNames {min hour day month year} {
  global nickstatus
  global nicktime
  set identifiedUsers ""
  foreach userraw [chanlist "#YourChannel"] {
    set username [doGetSafe $userraw]
    if {[info exists nickstatus($username)]} {
      if {$nickstatus($username) == 3} {
        lappend identifiedUsers $username
      }
      if {$nicktime($username) < [clock seconds] - 1800} {
        unset nickstatus($username)
        unset nicktime($username)
      }
    }
  }
  set NamesSet [setVBNames $identifiedUsers]
  putlog "doSetNames: Users -- $identifiedUsers"
}
proc doGetSafe {mystring} {
  return $mystring
}
### Get Names on channel, send Status request to NickServ for each name on nicklist without STATUS of 3, once per minute
### bind time - "* * * * *" doGetNames
###  -- (once per minute)
### If: NICK IS NOT A BOT
###  -- nick does not exist, OR
###  -- nick is not level 3 OR
###  -- nicktime last checked is over 10 minutes
###    THEN -- send a STATUS request to NickServ.
### All nicks (except bots)
proc doGetNames {min hour day month year} {
  global nickstatus
  global nicktime
  foreach userraw [chanlist "#YourChannel"] {
    set username [doGetSafe $userraw]
    set NickIsBot [isBot $username]
    set NickExists [info exists nickstatus($username)]
    set NowTime [clock seconds]
    if {$NickExists} {
      set NickNotIdentified [expr ($nickstatus($username) != 3)]
      set NickLastTime $nicktime($username)
    } else {
      set NickNotIdentified 1
      set NickLastTime 0
    }
    set NickTimesOut [expr $NickLastTime + 600 - $NowTime]
    set NickTimedOut [expr $NickTimesOut < 0]
    ##putlog " --- STATUS Checking :$username -- $NickIsBot - $NickExists - $NickNotIdentified - $NickTimedOut"
    if {!$NickIsBot} {
      if {(!$NickExists || $NickNotIdentified || $NickTimedOut)} {
        puthelp "PRIVMSG NickServ :STATUS $username"
        putlog "doGetNames: Checking $username"
      }
    }
  }
}
### bind notc - "*STATUS*" doSetStatus
### Answers NickServ's status response notice, setting nickstatus and nicktime appropriately.
proc doSetStatus {nick host handle text dest} {
  global nickstatus
  global nicktime
  if {[string tolower $nick] != [string tolower "NickServ"]} {
    return 0;
  }
  regexp {STATUS ([^ ]*) ([0-3])} $text hmm NS_name NS_status
  set nickstatus($NS_name) $NS_status
  set nicktime($NS_name) [clock seconds]
  putlog "doSetStatus: User -- $NS_name"
}
###############################################################################
###              Helper Functions (not called by bind events)               ###
###############################################################################
### If a user is in the global nickstatus as Identified, return true, else return false
proc isIdentified {nick} {
  global nickstatus
  if {[info exists nickstatus($nick)]} {
    if {$nickstatus($nick) == 3} {
      return 1
    }
  }
  return 0
}
### Returns true if nick is a Bot's nickname, else false
proc isBot {nick} {
  if {[string tolower $nick] == [string tolower "Bot1"]} {
    return 1
  }
  if {[string tolower $nick] == [string tolower "Bot2"]} {
    return 1
  }
  if {[string tolower $nick] == [string tolower "Internets"]} {
    return 1
  }
  if {[string tolower $nick] == [string tolower "Quotes"]} {
    return 1
  }
  if {[string tolower $nick] == [string tolower "Stats"]} {
    return 1
  }
  return 0
}
### Sends the IRC Active users list to our page
proc setVBNames {iduserlist} {
  package require http
  set url http://link.to.your.forum/irc.script.php
  set querystring [http::formatQuery "do" "irc_activity_check" "users" $iduserlist]
  set token [http::geturl $url -query $querystring]
  set data [http::data $token]
  http::cleanup $token
  return $data
}


After setting all this up correctly, we'll use a little plugin on the hook process_templates_complete:
PHP Code:
$ircusers $vbulletin->db->query_first("SELECT value FROM ".TABLE_PREFIX."setting WHERE varname='ircactivity'");
$irctime $vbulletin->db->query_first("SELECT value FROM ".TABLE_PREFIX."setting WHERE varname='irclastcheck'");

$irctime vbdate($vbulletin->options['dateformat'], $irctime['value'], 0)
  . 
'--' vbdate($vbulletin->options['timeformat'], $irctime['value'], 0);

$template_hook['forumhome_wgo_pos2'] .= '
<div style="margin:20px;margin-top:6px;margin-bottom:10px;border:3px outset #556655;padding:3px;">
  <h3>Users on IRC as of '
.$irctime.'</h3>
  <div>'
.$ircusers['value'].'</div>
</div>'



This will activate a IRC Users in WGO that looks like this:


You can add additional functions to your Eggdrop--have people PM from IRC to users on your vBulletin, have a function that reports statistics to IRC, etc. Just follow the examples of the !whois and !rwhois functions.

You can even return multi-line data. Take the example procedure below:
Code:
proc example {nick host hand chan text} {
  package require http
  set url http://link.to.your.site/irc.script.php
  set querystring [http::formatQuery "do" "example"]
  set token [http::geturl $url -query $querystring]
  set data [http::data $token]
  foreach $splitline [split $data "\n"] {
    putquick "PRIVMSG #YourChannel :$splitline"
  }
  http::cleanup $token
}
This will print out one line in IRC for each line the page has of content. Great for, say, outputting the members of a usergroup or something similar.

This code is not meant to use "as is," but is rather meant to be a reference for vB owners to be able to interface with their IRC channels. Or at least to give them a shove in the right direction. It will work (as long as you make the noted modifications) to place a IRC User List in "WGO", so I guess I can put it here in the Modifications. X3

Questions, comments? Post them.

Download

No files for download.

Similar Mods

Eggdrop Irc Manager vBulletin 3.5 Add-ons
IRC post bot - No eggdrop vBulletin 2.x Full Releases

vblts.ru supports vBulletin®, 2022-2024