Skip to content

Instantly share code, notes, and snippets.

@T3chArmy
Last active April 7, 2022 19:26
Show Gist options
  • Save T3chArmy/bc2fb5010ff700e675da60f127d027b8 to your computer and use it in GitHub Desktop.
Save T3chArmy/bc2fb5010ff700e675da60f127d027b8 to your computer and use it in GitHub Desktop.
IRC bot
; default servers to send chat messages to
; currently no way to change this in the client
; this functionality will come in the future.
server = "pine"
channel = "#Pine64"
<?php
// Text file for login output
define('logFile', './logs/login.txt');
/*spl_autoload_register(function ($class_name) {
include $class_name . '.php';
});*/
$IRC_Servers = parse_ini_file('servers.ini', true); # Load Config from INI file
$IRC_Config = parse_ini_file('client.ini'); # Load Config from INI file
$swears = array_map('trim', file("http://www.bannedwordlist.com/lists/swearWords.txt"));
$running = true;
foreach($IRC_Servers as $ID => $config) {
if(is_array($config) && isset($config['host'])) {
$Servers[$ID] = new IRC_Server($ID, $config['host'], $config['port'], $config['user'], $config['pass'], $config['channels'], $config['ignored']);
}
}
stream_set_blocking(STDIN, 0);
while($running) {
$active = 0;
foreach($Servers as $ID => $IRC) {
if($IRC->serverActive) {
$IRC->runEvents();
$active++;
} else {
# Connection has failed.
}
}
if($active == 0) {
# All servers closed
exit();
}
$line = stream_get_line(STDIN, 1024, PHP_EOL);
if($line !== false) {
# User Typed Something. handle it!
$Servers[$IRC_Config['server']]->_PRIVMSG($IRC_Config['channel'], $line);
}
}
class IRC_Server {
private $chatServer;
public $serverActive = true;
protected $serverID;
private $username;
private $startChannels;
private $activeChannels;
private $ignoredChannels;
private $eventHandlers = array(
'004' => 'joinStartChannels',
'372' => 'writeMOTD',
'PRIVMSG' => 'handleServerMessage',
#'JOIN' => 'handleJoin',
#'PART' => 'handlePart',
#'QUIT' => 'handlePart'
);
public function __construct($serverID, $host, $port, $user, $pass, $channels, $ignoredChannels){
$this->serverID = $serverID;
$this->username = $user;
$this->ignoredChannels = $ignoredChannels;
$this->chatServer = @fsockopen($host, $port, $errno, $errstr, 15);
stream_set_timeout($this->chatServer, 0, 200000);
if ($this->chatServer) {
// login success
fwrite($this->chatServer, "PASS {$pass}\r\n");
fwrite($this->chatServer, "NICK {$user}\r\n");
fwrite($this->chatServer, "USER {$user} localhost {$host} : T3ch IRC BOT\r\n");
#fwrite($this->chatServer, "JOIN " . $config['channel'] . " \r\n");
$this->startChannels = $channels;
file_put_contents(logFile, "IRC login succeeded at ".date("H:i:s Y-m-d").".\r\n");
echo "IRC login succeeded.\r\n";
} else {
$this->serverActive = false;
file_put_contents(logFile, "IRC login failed at ".date("H:i:s Y-m-d").". Error ".$errno.": ".$errstr."\r\n");
echo "IRC login failed.\r\n";
}
foreach($channels as $channel) {
#$this->_JOIN($channel);
}
}
public function __destruct() {
foreach($channels as $channel) {
#$this->_PART($channel);
}
}
public function runEvents() {
if (!$this->chatServer) {
echo 'not active. ignoring.';
return false;
}
if(feof($this->chatServer)) {
echo 'Connection Closed.';
$this->serverActive = false;
return false;
}
$line = fgets($this->chatServer, 512);
#var_dump($line)
if (strlen($line) > 0) {
$tokens = array_map('trim', explode(' ',$line));
if ($tokens[0] == 'PING') {
fwrite($this->chatServer, "PONG {$tokens[1]}\r\n");
#echo "ping-pong\r\n";
} else {
$fget_userString = array_shift($tokens);
$fget_user = substr($fget_userString, 1, strpos($fget_userString, '!') - 1);
$fget_command = array_shift($tokens);
#$fget_target = substr(array_shift($tokens), 1);
$fget_target = array_shift($tokens);
$fget_text = trim(substr(implode(' ', $tokens), 1));
if(isset($this->eventHandlers[$fget_command])) {
call_user_func(array($this, $this->eventHandlers[$fget_command]), $fget_userString, $fget_user, $fget_command, $fget_target, $fget_text);
}
}
flush();
}
}
public function joinStartChannels() {
foreach($this->startChannels as $channel) {
$this->_JOIN($channel);
}
}
public function writeMOTD($userString, $user, $command, $target, $text) {
echo "motd: {$text}\r\n";
}
public function handleServerMessage($userString, $user, $command, $target, $text) {
echo date("[h:i:s] ") . $this->formatTarget($user) . " @ " . $this->formatTarget($target) . ":\r\n{$text}\r\n";
if($target == $this->username) {
# PM to this user
$target = $user;
}
if(in_array($target, $this->ignoredChannels)) {
#return false;
}
$args = str_getcsv($text, ' ');
if($args[0] == chr(1).'PING') {
$this->_PRIVMSG($target, chr(1)."PONG {$args[1]}");
}
if($args[0] == chr(1).'ACTION') {
if($args[1] == 'slaps' && $args[2] == 'T3charmy') {
$this->_PRIVMSG($target, "How dare you slap my owner. Prepare for PAIN!!!");
$this->_ACTION($target, "punches {$user} square in the face.");
}
}
$lower_args = array_map('strtolower', $args);
$this->hotWords($user, $target, $lower_args);
$this->handleCMD($user, $target, $lower_args);
}
private function hotWords($user, $target, $args) {
if(in_array("pine64", $args) && rand(1, 10) > 8) {
$this->_PRIVMSG($target, "Pine64? That's my favorite!");
}
if(in_array("pi", $args) && rand(1, 10) > 8) {
$this->_PRIVMSG($target, "Talking about Pi? Yuck!!!");
}
if(in_array("windows", $args) && rand(1, 10) > 5) {
$this->_PRIVMSG($target, "Windows? ItsDave hates that word.");
}
if(in_array("linux", $args) && rand(1, 10) > 8) {
$this->_PRIVMSG($target, "Linux? You can't go wrong there.");
}
#swear words
foreach($args as $word) {
if(in_array($word, $GLOBALS['swears']))
{
$this->_PRIVMSG($target, "Whoa {$user}!");
$this->_ACTION($target, "slaps {$user}. Watch the language!");
break;
}
}
}
private function handleCMD($user, $target, $args)
{
#var_dump($args);
if($args[0] != '!t3')
{
return false;
}
switch($args[1])
{
case 'slap':
$this->_ACTION($target, "slaps {$args[2]}");
break;
}
}
private function handleJoin($userString, $user, $command, $target, $text)
{
$target = substr($target, 1);
var_dump($userString, $user, $command, $target, $text);
if($user == $this->username)
return false;
#$this->_PRIVMSG($user, "Welcome {$user}");
}
private function handlePart($userString, $user, $command, $target, $text)
{
var_dump($userString, $user, $command, $target, $text);
if($user == $this->username)
return false;
#$this->_PRIVMSG($target, "Bye {$user}, we didn't like you anyways. :'(");
}
private function _JOIN ($channel) {
$this->activeChannels[] = $channel;
fwrite($this->chatServer, "JOIN #{$channel}\r\n");
}
private function _PART ($channel, $reason) {
fwrite($this->chatServer, "PART #{$channel} {$reason}\r\n");
}
public function _PRIVMSG ($target, $message) {
echo date("[h:i:s] ") . $this->formatTarget($this->username) . " @ " . $this->formatTarget($target) . ":\r\n{$message}\r\n";
fwrite($this->chatServer, "PRIVMSG {$target} {$message}\r\n");
}
public function _ACTION ($target, $action)
{
$this->_PRIVMSG($target, chr(1)."ACTION {$action}".chr(1));
}
private function formatTarget($target, $length = 10) {
if(strlen($target) > $length) {
return substr($target, 0, $length-1) . "+";
} else {
return str_pad($target, $length, " ", STR_PAD_BOTH);
}
}
}
[pine]
host = "pine64.no-ip.info"
port = "6667"
user = "PineBot|Example1"
pass = "Null"
channels[] = "test"
channels[] = "Pine64"
ignored[] = "#Pine64"
ignored[] = "ItsDaveBot"
ignored[] = "CedarBot"
;If you want to log in to a 2nd(or more) server(s) repeat the following Lines
;[servername2]
;host = "pine64.no-ip.info"
;port = "6667"
;user = "PineBot|Example2"
;pass = "Null"
;channels[] = "test"
;channels[] = "Pine64"
;Ignore users and channels
;ignored[] = "#Pine64"
;ignored[] = "ItsDaveBot"
;ignored[] = "CedarBot"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment