This repository has been archived on 2024-07-18. You can view files and clone it, but cannot push or open issues or pull requests.
lwb5/ircbot/dcc.php

580 lines
13 KiB
PHP
Raw Permalink Normal View History

2016-01-10 11:01:49 +01:00
<?php
/*
+---------------------------------------------------------------------------
| PHP-IRC v2.2.1 Service Release
| ========================================================
| by Manick
| (c) 2001-2005 by http://www.phpbots.org/
| Contact: manick@manekian.com
| irc: #manekian@irc.rizon.net
| ========================================
+---------------------------------------------------------------------------
| > dcc module
| > Module written by Manick
| > Module Version Number: 2.2.0
+---------------------------------------------------------------------------
| > This program is free software; you can redistribute it and/or
| > modify it under the terms of the GNU General Public License
| > as published by the Free Software Foundation; either version 2
| > of the License, or (at your option) any later version.
| >
| > This program is distributed in the hope that it will be useful,
| > but WITHOUT ANY WARRANTY; without even the implied warranty of
| > MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| > GNU General Public License for more details.
| >
| > You should have received a copy of the GNU General Public License
| > along with this program; if not, write to the Free Software
| > Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+---------------------------------------------------------------------------
| Changes
| =======-------
| > If you wish to suggest or submit an update/change to the source
| > code, email me at manick@manekian.com with the change, and I
| > will look to adding it in as soon as I can.
+---------------------------------------------------------------------------
*/
class dcc {
private $dccList = array(); //holds all connected sockets
private $dccChangedList = array();
private $dccChangedCount = 0;
private $fileDlCount = 0;
private $fileUlCount = 0;
private $chatCount = 0;
//Classes
private $timerClass;
private $socketClass;
private $ircClass;
private $parserClass;
//Bytes Transferred
private $bytesUp = 0;
private $bytesDown = 0;
//Process Queue
private $procQueue;
public function __construct()
{
// do nothing...
}
public function setProcQueue($class)
{
$this->procQueue = $class;
}
public function setIrcClass($class)
{
$this->ircClass = $class;
}
public function setParserClass($class)
{
$this->parserClass = $class;
$this->parserClass->setDccClass($this);
}
public function setSocketClass($class)
{
$this->socketClass = $class;
}
public function setTimerClass($class)
{
$this->timerClass = $class;
}
public function getDownloadCount()
{
return $this->fileDlCount;
}
public function getUploadCount()
{
return $this->fileUlCount;
}
public function getChatCount()
{
return $this->chatCount;
}
public function closeAll()
{
foreach ($this->dccList AS $dcc)
{
$dcc->disconnect("Owner Requsted Close");
}
}
public function addBytesUp($num)
{
$this->bytesUp += $num;
}
public function addBytesDown($num)
{
$this->bytesDown += $num;
}
public function getBytesDown()
{
return $this->bytesDown;
}
public function getBytesUp()
{
return $this->bytesUp;
}
public function getDcc($someDcc)
{
if (isset($this->dccList[$someDcc]))
{
return $this->dccList[$someDcc];
}
return false;
}
public function dccInform($data, $from = null)
{
foreach ($this->dccList AS $dcc)
{
if ($dcc->type == CHAT && $dcc->verified == true && $dcc->isAdmin == true)
{
if ($from != null)
{
if ($dcc->sockInt != $from->sockInt)
{
$dcc->dccSend($data);
}
}
else
{
$dcc->dccSend($data);
}
}
}
}
//Works in conjunction with $oldConn->connected
public function accepted($oldConn, $newConn)
{
$sockInt = $oldConn->getSockInt();
$hasAccepted = $newConn->getSockInt();
$dcc = $this->dccList[$sockInt];
$this->dccList[$hasAccepted] = $dcc;
$dcc->status = DCC_CONNECTED;
$dcc->sockInt = $hasAccepted;
unset($this->dccList[$sockInt]);
}
//CheckDccTimeout function
public function checkDccTimeout($dcc)
{
if (!is_object($dcc) || $dcc->removed == true)
{
return false;
}
if ($dcc->status != DCC_LISTENING)
{
return false;
}
switch ($dcc->timeOutLevel)
{
case 0:
$dcc->timeOutLevel++;
break;
case 1:
$dcc->timeOutLevel++;
$this->ircClass->notice($dcc->nick, "You have a DCC session pending. Set your client to connect. 60 seconds before timeout.", 1);
break;
case 2:
$dcc->timeOutLevel++;
$this->ircClass->notice($dcc->nick, "You have a DCC session pending. Set your client to connect. 30 seconds before timeout.", 1);
break;
case 3:
$dcc->timeOutLevel = 0;
$dcc->disconnect("DCC Session timed out (90 Seconds)");
return false;
break;
default:
break;
}
return true;
}
public function getDccList()
{
return $this->dccList;
}
private function removeDcc($dcc)
{
$sockInt = $dcc->sockInt;
unset($this->dccList[$sockInt]);
}
public function dccSend($to, $data)
{
if (($len = $this->socketClass->sendSocket($to->sockInt, $data)) === false)
{
$to->disconnect();
}
return $len;
}
private function highestId()
{
$highest = 0;
foreach ($this->dccList AS $index => $dcc)
{
$highest = ($dcc->id > $highest ? $dcc->id : $highest);
}
return $highest + 1;
}
public function addChat($nick, $host, $port, $admin, $handler, $fromTimer = false)
{
$lnick = irc::myStrToLower($nick);
foreach ($this->dccList AS $index => $dcc)
{
if ($dcc->type == CHAT)
{
if (irc::myStrToLower($dcc->nick) == $lnick)
{
$dcc->disconnect();
break;
}
}
}
$reverse = false;
if ($this->ircClass->getClientConf("mircdccreverse") != "" && $fromTimer == false)
{
$port = intval($this->ircClass->getClientConf("mircdccreverse"));
if ($port == 0)
{
return NULL;
}
$args = new argClass;
$args->arg1 = $nick;
$args->arg2 = $host;
$args->arg3 = $port;
$args->arg4 = $admin;
$args->arg5 = $handler;
$args->arg7 = time();
$args->arg8 = CHAT;
$this->ircClass->notice($nick, "DCC: NOTICE: This server is using the mIRC Chat Server Protocol. Please use ' /dccserver +c on " . $this->ircClass->getClientConf("mircdccreverse") . " ' to chat with me! Starting 6 second delay...", 0);
$this->ircClass->sendRaw("WHOIS " . $nick);
$this->timerClass->addTimer(irc::randomHash(), $this, "reverseTimer", $args, 6, false);
return;
}
if ($fromTimer == true)
{
$reverse = DCC_REVERSE; // using mIRC dcc reverse protocol
}
if ($host == NULL || $port == NULL)
{
$conn = new connection(null, null, 0);
$listening = true;
$status = DCC_LISTENING;
}
else
{
$conn = new connection($host, $port, CONNECT_TIMEOUT);
$listening = false;
$status = DCC_CONNECTING;
}
$conn->setSocketClass($this->socketClass);
$conn->setIrcClass($this->ircClass);
$conn->setCallbackClass($this);
$conn->setTimerClass($this->timerClass);
$port = $conn->init();
if ($conn->getError())
{
$this->ircClass->log("Start Chat Error: " . $conn->getErrorMsg());
return false;
}
$sockInt = $conn->getSockInt();
$this->chatCount++;
$id = $this->highestId();
$chat = new chat($id, $nick, $admin, $sockInt, $host, $port, $handler, $reverse);
$chat->setIrcClass($this->ircClass);
$chat->setDccClass($this);
$chat->setParserClass($this->parserClass);
$chat->setSocketClass($this->socketClass);
$chat->setTimerClass($this->timerClass);
$chat->connection = $conn;
$chat->status = $status;
$chat->removed = false;
$this->dccList[$sockInt] = $chat;
$chat->initialize();
$conn->setCallbackClass($chat);
if ($listening == true)
{
$this->timerClass->addTimer(irc::randomHash(), $this, "checkDccTimeout", $chat, 30, true);
}
else
{
$conn->connect();
}
return $port;
}
public function addFile($nick, $host, $port, $type, $filename, $size, $fromTimer = false) // <-- ignore fromTimer, it is sent by reverseTimer() above
{
$reverse = false;
if ($this->ircClass->getClientConf("mircdccreverse") != "" && $fromTimer == false && $type != DOWNLOAD)
{
$port = intval($this->ircClass->getClientConf("mircdccreverse"));
if ($port == 0)
{
return NULL;
}
$args = new argClass;
$args->arg1 = $nick;
$args->arg2 = $host;
$args->arg3 = $port;
$args->arg4 = $type;
$args->arg5 = $filename;
$args->arg6 = $size;
$args->arg7 = time();
$args->arg8 = FILE;
$this->ircClass->notice($nick, "DCC: NOTICE: This server is using the mIRC File Server Protocol. Please use ' /dccserver +s on " . $this->ircClass->getClientConf("mircdccreverse") . " ' to recieve files from me! Starting 6 second delay...", 0);
$this->ircClass->sendRaw("WHOIS " . $nick);
$this->timerClass->addTimer(irc::randomHash(), $this, "reverseTimer", $args, 6);
return;
}
if ($fromTimer == true)
{
$reverse = DCC_REVERSE; // using mIRC dcc reverse protocol
}
if ($host == NULL || $port == NULL)
{
$conn = new connection(null, null, 0);
$listening = true;
$status = DCC_LISTENING;
}
else
{
$conn = new connection($host, $port, CONNECT_TIMEOUT);
$listening = false;
$status = DCC_CONNECTING;
}
$conn->setSocketClass($this->socketClass);
$conn->setIrcClass($this->ircClass);
$conn->setCallbackClass($this);
$conn->setTransTimeout(30);
$conn->setTimerClass($this->timerClass);
$port = $conn->init();
if ($conn->getError())
{
$this->ircClass->log("File transfer start error: " . $conn->getErrorMsg());
return false;
}
$sockInt = $conn->getSockInt();
$id = $this->highestId();
$file = new file($id, $nick, $sockInt, $host, $port, $type, $reverse);
if ($file->transferType == UPLOAD)
{
$this->fileUlCount++;
}
else
{
$this->fileDlCount++;
}
$file->setIrcClass($this->ircClass);
$file->setDccClass($this);
$file->setSocketClass($this->socketClass);
$file->setProcQueue($this->procQueue);
$file->setTimerClass($this->timerClass);
$file->connection = $conn;
$file->status = $status;
$file->removed = false;
$this->dccList[$sockInt] = $file;
$file->initialize($filename, $size);
$conn->setCallbackClass($file);
if ($listening == true)
{
$this->timerClass->addTimer(irc::randomHash(), $this, "checkDccTimeout", $file, 30, true);
}
if ($reverse == true)
{
$conn->connect();
}
return $port;
}
public function alterSocket($sockInt, $level, $opt, $val)
{
return $this->socketClass->alterSocket($sockInt, $level, $opt, $val);
}
public function reverseTimer($args)
{
$memData = $this->ircClass->getUserData($args->arg1);
if ($memData == NULL || ($memData->host == "" || $memData->host == NULL))
{
$this->ircClass->notice($args->arg1, "DCC: ERROR: Couldn't resolve your hostname. Try again?");
}
else
{
if ($args->arg8 == FILE)
{
$this->addFile( $args->arg1,
$memData->host,
$this->ircClass->getClientConf("mircdccreverse"),
$args->arg4,
$args->arg5,
$args->arg6,
true);
}
else
{
$this->addChat( $args->arg1,
$memData->host,
$this->ircClass->getClientConf("mircdccreverse"),
$args->arg4,
$args->arg5,
true);
}
}
return false;
}
public function sendFile($nick, $file)
{
return $this->addFile($nick, null, null, UPLOAD, $file, NULL);
}
public function dccResume($port, $size)
{
foreach ($this->dccList AS $dcc)
{
if ($dcc->type == FILE)
{
if ($dcc->port == $port)
{
$dcc->resume($size);
break;
}
}
}
}
public function dccAccept($port)
{
foreach ($this->dccList AS $dcc)
{
if ($dcc->type == FILE)
{
if ($dcc->port == $port)
{
$dcc->accepted();
break;
}
}
}
}
public function disconnect($dcc)
{
switch ($dcc->type)
{
case CHAT:
$this->chatCount--;
break;
case FILE:
switch($dcc->transferType)
{
case UPLOAD:
$this->fileUlCount--;
break;
case DOWNLOAD:
$this->fileDlCount--;
break;
}
break;
default:
break;
}
$dcc->removed = true;
$dcc->connection->disconnect();
$this->removeDcc($dcc);
return true;
}
}
?>