Teknik is a suite of services with attractive and functional interfaces. https://www.teknik.io/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SmartIRC.php 86KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938
  1. <?php
  2. /**
  3. * $Id: SmartIRC.php 302734 2010-08-24 01:17:01Z clockwerx $
  4. * $Revision: 302734 $
  5. * $Author: clockwerx $
  6. * $Date: 2010-08-24 10:47:01 +0930 (Tue, 24 Aug 2010) $
  7. *
  8. * Net_SmartIRC
  9. * This is a PHP class for communication with IRC networks,
  10. * which conforms to the RFC 2812 (IRC protocol).
  11. * It's an API that handles all IRC protocol messages.
  12. * This class is designed for creating IRC bots, chats and show irc related info on webpages.
  13. *
  14. * Documenation, a HOWTO and examples are in SmartIRC included.
  15. *
  16. * Here you will find a service bot which I am also developing
  17. * <http://cvs.meebey.net/atbs> and <http://cvs.meebey.net/phpbitch>
  18. * Latest versions of Net_SmartIRC you will find on the project homepage
  19. * or get it through PEAR since SmartIRC is an official PEAR package.
  20. * See <http://pear.php.net/Net_SmartIRC>.
  21. *
  22. * Official Project Homepage: <http://sf.net/projects/phpsmartirc>
  23. *
  24. * Net_SmartIRC conforms to RFC 2812 (Internet Relay Chat: Client Protocol)
  25. *
  26. * Copyright (c) 2002-2005 Mirco Bauer <meebey@meebey.net> <http://www.meebey.net>
  27. *
  28. * Full LGPL License: <http://www.gnu.org/licenses/lgpl.txt>
  29. *
  30. * This library is free software; you can redistribute it and/or
  31. * modify it under the terms of the GNU Lesser General Public
  32. * License as published by the Free Software Foundation; either
  33. * version 2.1 of the License, or (at your option) any later version.
  34. *
  35. * This library is distributed in the hope that it will be useful,
  36. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  37. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  38. * Lesser General Public License for more details.
  39. *
  40. * You should have received a copy of the GNU Lesser General Public
  41. * License along with this library; if not, write to the Free Software
  42. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  43. *
  44. */
  45. // ------- PHP code ----------
  46. require_once 'SmartIRC/defines.php';
  47. define('SMARTIRC_VERSION', '1.1.0-dev ($Revision: 302734 $)');
  48. define('SMARTIRC_VERSIONSTRING', 'Net_SmartIRC '.SMARTIRC_VERSION);
  49. /**
  50. * main SmartIRC class
  51. *
  52. * @package Net_SmartIRC
  53. * @version 0.6.0-dev
  54. * @author Mirco 'meebey' Bauer <mail@meebey.net>
  55. * @access public
  56. */
  57. class Net_SmartIRC_base
  58. {
  59. /**
  60. * @var resource
  61. * @access private
  62. */
  63. var $_socket;
  64. /**
  65. * @var string
  66. * @access private
  67. */
  68. var $_address;
  69. /**
  70. * @var integer
  71. * @access private
  72. */
  73. var $_port;
  74. /**
  75. * @var string
  76. * @access private
  77. */
  78. var $_nick;
  79. /**
  80. * @var string
  81. * @access private
  82. */
  83. var $_username;
  84. /**
  85. * @var string
  86. * @access private
  87. */
  88. var $_realname;
  89. /**
  90. * @var string
  91. * @access private
  92. */
  93. var $_usermode;
  94. /**
  95. * @var string
  96. * @access private
  97. */
  98. var $_password;
  99. /**
  100. * @var boolean
  101. * @access private
  102. */
  103. var $_state = false;
  104. /**
  105. * @var array
  106. * @access private
  107. */
  108. var $_actionhandler = array();
  109. /**
  110. * @var array
  111. * @access private
  112. */
  113. var $_timehandler = array();
  114. /**
  115. * @var integer
  116. * @access private
  117. */
  118. var $_debug = SMARTIRC_DEBUG_NOTICE;
  119. /**
  120. * @var array
  121. * @access private
  122. */
  123. var $_messagebuffer = array();
  124. /**
  125. * @var integer
  126. * @access private
  127. */
  128. var $_messagebuffersize;
  129. /**
  130. * @var boolean
  131. * @access private
  132. */
  133. var $_usesockets = false;
  134. /**
  135. * @var integer
  136. * @access private
  137. */
  138. var $_receivedelay = 100;
  139. /**
  140. * @var integer
  141. * @access private
  142. */
  143. var $_senddelay = 250;
  144. /**
  145. * @var integer
  146. * @access private
  147. */
  148. var $_logdestination = SMARTIRC_STDOUT;
  149. /**
  150. * @var resource
  151. * @access private
  152. */
  153. var $_logfilefp = 0;
  154. /**
  155. * @var string
  156. * @access private
  157. */
  158. var $_logfile = 'Net_SmartIRC.log';
  159. /**
  160. * @var integer
  161. * @access private
  162. */
  163. var $_disconnecttime = 1000;
  164. /**
  165. * @var boolean
  166. * @access private
  167. */
  168. var $_loggedin = false;
  169. /**
  170. * @var boolean
  171. * @access private
  172. */
  173. var $_benchmark = false;
  174. /**
  175. * @var integer
  176. * @access private
  177. */
  178. var $_benchmark_starttime;
  179. /**
  180. * @var integer
  181. * @access private
  182. */
  183. var $_benchmark_stoptime;
  184. /**
  185. * @var integer
  186. * @access private
  187. */
  188. var $_actionhandlerid = 0;
  189. /**
  190. * @var integer
  191. * @access private
  192. */
  193. var $_timehandlerid = 0;
  194. /**
  195. * @var array
  196. * @access private
  197. */
  198. var $_motd = array();
  199. /**
  200. * @var array
  201. * @access private
  202. */
  203. var $_channels = array();
  204. /**
  205. * @var boolean
  206. * @access private
  207. */
  208. var $_channelsyncing = false;
  209. /**
  210. * @var array
  211. * @access private
  212. */
  213. var $_users = array();
  214. /**
  215. * @var boolean
  216. * @access private
  217. */
  218. var $_usersyncing = false;
  219. /**
  220. * Stores the path to the modules that can be loaded.
  221. *
  222. * @var string
  223. * @access privat
  224. */
  225. var $_modulepath = '';
  226. /**
  227. * Stores all objects of the modules.
  228. *
  229. * @var string
  230. * @access privat
  231. */
  232. var $_modules = array();
  233. /**
  234. * @var string
  235. * @access private
  236. */
  237. var $_ctcpversion;
  238. /**
  239. * @var mixed
  240. * @access private
  241. */
  242. var $_mintimer = false;
  243. /**
  244. * @var integer
  245. * @access private
  246. */
  247. var $_maxtimer = 300000;
  248. /**
  249. * @var integer
  250. * @access private
  251. */
  252. var $_txtimeout = 300;
  253. /**
  254. * @var integer
  255. * @access private
  256. */
  257. var $_rxtimeout = 300;
  258. /**
  259. * @var integer
  260. * @access private
  261. */
  262. var $_selecttimeout;
  263. /**
  264. * @var integer
  265. * @access private
  266. */
  267. var $_lastrx;
  268. /**
  269. * @var integer
  270. * @access private
  271. */
  272. var $_lasttx;
  273. /**
  274. * @var boolean
  275. * @access private
  276. */
  277. var $_autoreconnect = false;
  278. /**
  279. * @var integer
  280. * @access private
  281. */
  282. var $_reconnectdelay = 10000;
  283. /**
  284. * @var boolean
  285. * @access private
  286. */
  287. var $_autoretry = false;
  288. /**
  289. * @var integer
  290. * @access private
  291. */
  292. var $_autoretrymax = 5;
  293. /**
  294. * @var integer
  295. * @access private
  296. */
  297. var $_autoretrycount = 0;
  298. /**
  299. * @var boolean
  300. * @access private
  301. */
  302. var $_connectionerror = false;
  303. /**
  304. * @var boolean
  305. * @access private
  306. */
  307. var $_runasdaemon = false;
  308. /**
  309. * All IRC replycodes, the index is the replycode name.
  310. *
  311. * @see $SMARTIRC_replycodes
  312. * @var array
  313. * @access public
  314. */
  315. var $replycodes;
  316. /**
  317. * All numeric IRC replycodes, the index is the numeric replycode.
  318. *
  319. * @see $SMARTIRC_nreplycodes
  320. * @var array
  321. * @access public
  322. */
  323. var $nreplycodes;
  324. /**
  325. * Stores all channels in this array where we are joined, works only if channelsyncing is activated.
  326. * Eg. for accessing a user, use it like this: (in this example the SmartIRC object is stored in $irc)
  327. * $irc->channel['#test']->users['meebey']->nick;
  328. *
  329. * @see setChannelSyncing()
  330. * @see Net_SmartIRC_channel
  331. * @see Net_SmartIRC_channeluser
  332. * @var array
  333. * @access public
  334. */
  335. var $channel;
  336. /**
  337. * Stores all users that had/have contact with us (channel/query/notice etc.), works only if usersyncing is activated.
  338. * Eg. for accessing a user, use it like this: (in this example the SmartIRC object is stored in $irc)
  339. * $irc->user['meebey']->host;
  340. *
  341. * @see setUserSyncing()
  342. * @see Net_SmartIRC_ircuser
  343. * @var array
  344. * @access public
  345. */
  346. var $user;
  347. /**
  348. * Constructor. Initiales the messagebuffer and "links" the replycodes from
  349. * global into properties. Also some PHP runtime settings are configured.
  350. *
  351. * @access public
  352. * @return void
  353. */
  354. function Net_SmartIRC_base()
  355. {
  356. // precheck
  357. $this->_checkPHPVersion();
  358. ob_implicit_flush(true);
  359. @set_time_limit(0);
  360. $this->_messagebuffer[SMARTIRC_CRITICAL] = array();
  361. $this->_messagebuffer[SMARTIRC_HIGH] = array();
  362. $this->_messagebuffer[SMARTIRC_MEDIUM] = array();
  363. $this->_messagebuffer[SMARTIRC_LOW] = array();
  364. $this->replycodes = &$GLOBALS['SMARTIRC_replycodes'];
  365. $this->nreplycodes = &$GLOBALS['SMARTIRC_nreplycodes'];
  366. // hack till PHP allows (PHP5) $object->somemethod($param)->memberofobject
  367. $this->channel = &$this->_channels;
  368. // another hack
  369. $this->user = &$this->_users;
  370. if (isset($_SERVER['REQUEST_METHOD'])) {
  371. // the script is called from a browser, lets set default log destination
  372. // to SMARTIRC_BROWSEROUT (makes browser friendly output)
  373. $this->setLogdestination(SMARTIRC_BROWSEROUT);
  374. }
  375. }
  376. /**
  377. * Enables/disables the usage of real sockets.
  378. *
  379. * Enables/disables the usage of real sockets instead of fsocks
  380. * (works only if your PHP build has loaded the PHP socket extension)
  381. * Default: false
  382. *
  383. * @param bool $boolean
  384. * @return void
  385. * @access public
  386. */
  387. function setUseSockets($boolean)
  388. {
  389. if ($boolean === true) {
  390. if (@extension_loaded('sockets')) {
  391. $this->_usesockets = true;
  392. } else {
  393. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: socket extension not loaded, trying to load it...', __FILE__, __LINE__);
  394. if (strtoupper(substr(PHP_OS, 0,3) == 'WIN')) {
  395. $load_status = @dl('php_sockets.dll');
  396. } else {
  397. $load_status = @dl('sockets.so');
  398. }
  399. if ($load_status) {
  400. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: socket extension succesfully loaded', __FILE__, __LINE__);
  401. $this->_usesockets = true;
  402. } else {
  403. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: couldn\'t load the socket extension', __FILE__, __LINE__);
  404. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: your PHP build doesn\'t support real sockets, will use fsocks instead', __FILE__, __LINE__);
  405. $this->_usesockets = false;
  406. }
  407. }
  408. } else {
  409. $this->_usesockets = false;
  410. }
  411. }
  412. /**
  413. * Sets the level of debug messages.
  414. *
  415. * Sets the debug level (bitwise), useful for testing/developing your code.
  416. * Here the list of all possible debug levels:
  417. * SMARTIRC_DEBUG_NONE
  418. * SMARTIRC_DEBUG_NOTICE
  419. * SMARTIRC_DEBUG_CONNECTION
  420. * SMARTIRC_DEBUG_SOCKET
  421. * SMARTIRC_DEBUG_IRCMESSAGES
  422. * SMARTIRC_DEBUG_MESSAGETYPES
  423. * SMARTIRC_DEBUG_ACTIONHANDLER
  424. * SMARTIRC_DEBUG_TIMEHANDLER
  425. * SMARTIRC_DEBUG_MESSAGEHANDLER
  426. * SMARTIRC_DEBUG_CHANNELSYNCING
  427. * SMARTIRC_DEBUG_MODULES
  428. * SMARTIRC_DEBUG_USERSYNCING
  429. * SMARTIRC_DEBUG_ALL
  430. *
  431. * Default: SMARTIRC_DEBUG_NOTICE
  432. *
  433. * @see DOCUMENTATION
  434. * @see SMARTIRC_DEBUG_NOTICE
  435. * @param integer $level
  436. * @return void
  437. * @access public
  438. */
  439. function setDebug($level)
  440. {
  441. $this->_debug = $level;
  442. }
  443. /**
  444. * Enables/disables the benchmark engine.
  445. *
  446. * @param boolean $boolean
  447. * @return void
  448. * @access public
  449. */
  450. function setBenchmark($boolean)
  451. {
  452. if (is_bool($boolean)) {
  453. $this->_benchmark = $boolean;
  454. } else {
  455. $this->_benchmark = false;
  456. }
  457. }
  458. /**
  459. * Deprecated, use setChannelSyncing() instead!
  460. *
  461. * @deprecated
  462. * @param boolean $boolean
  463. * @return void
  464. * @access public
  465. */
  466. function setChannelSynching($boolean)
  467. {
  468. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: you are using setChannelSynching() which is a deprecated method, use setChannelSyncing() instead!', __FILE__, __LINE__);
  469. $this->setChannelSyncing($boolean);
  470. }
  471. /**
  472. * Enables/disables channel syncing.
  473. *
  474. * Channel syncing means, all users on all channel we are joined are tracked in the
  475. * channel array. This makes it very handy for botcoding.
  476. *
  477. * @param boolean $boolean
  478. * @return void
  479. * @access public
  480. */
  481. function setChannelSyncing($boolean)
  482. {
  483. if (is_bool($boolean)) {
  484. $this->_channelsyncing = $boolean;
  485. } else {
  486. $this->_channelsyncing = false;
  487. }
  488. if ($this->_channelsyncing == true) {
  489. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: Channel syncing enabled', __FILE__, __LINE__);
  490. } else {
  491. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: Channel syncing disabled', __FILE__, __LINE__);
  492. }
  493. }
  494. /**
  495. * Enables/disables user syncing.
  496. *
  497. * User syncing means, all users we have or had contact with through channel, query or
  498. * notice are tracked in the $irc->user array. This is very handy for botcoding.
  499. *
  500. * @param boolean $boolean
  501. * @return void
  502. * @access public
  503. */
  504. function setUserSyncing($boolean)
  505. {
  506. if (is_bool($boolean)) {
  507. $this->_usersyncing = $boolean;
  508. } else {
  509. $this->_usersyncing = false;
  510. }
  511. if ($this->_usersyncing == true) {
  512. $this->log(SMARTIRC_DEBUG_USERSYNCING, 'DEBUG_USERSYNCING: User syncing enabled', __FILE__, __LINE__);
  513. } else {
  514. $this->log(SMARTIRC_DEBUG_USERSYNCING, 'DEBUG_USERSYNCING: User syncing disabled', __FILE__, __LINE__);
  515. }
  516. }
  517. /**
  518. * Sets the CTCP version reply string.
  519. *
  520. * @param string $versionstring
  521. * @return void
  522. * @access public
  523. */
  524. function setCtcpVersion($versionstring)
  525. {
  526. $this->_ctcpversion = $versionstring;
  527. }
  528. /**
  529. * Sets the destination of all log messages.
  530. *
  531. * Sets the destination of log messages.
  532. * $type can be:
  533. * SMARTIRC_FILE for saving the log into a file
  534. * SMARTIRC_STDOUT for echoing the log to stdout
  535. * SMARTIRC_SYSLOG for sending the log to the syslog
  536. * Default: SMARTIRC_STDOUT
  537. *
  538. * @see SMARTIRC_STDOUT
  539. * @param integer $type must be on of the constants
  540. * @return void
  541. * @access public
  542. */
  543. function setLogdestination($type)
  544. {
  545. switch ($type) {
  546. case SMARTIRC_FILE:
  547. case SMARTIRC_STDOUT:
  548. case SMARTIRC_SYSLOG:
  549. case SMARTIRC_BROWSEROUT:
  550. case SMARTIRC_NONE:
  551. $this->_logdestination = $type;
  552. break;
  553. default:
  554. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: unknown logdestination type ('.$type.'), will use STDOUT instead', __FILE__, __LINE__);
  555. $this->_logdestination = SMARTIRC_STDOUT;
  556. }
  557. }
  558. /**
  559. * Sets the file for the log if the destination is set to file.
  560. *
  561. * Sets the logfile, if {@link setLogdestination logdestination} is set to SMARTIRC_FILE.
  562. * This should be only used with full path!
  563. *
  564. * @param string $file
  565. * @return void
  566. * @access public
  567. */
  568. function setLogfile($file)
  569. {
  570. $this->_logfile = $file;
  571. }
  572. /**
  573. * Sets the delaytime before closing the socket when disconnect.
  574. *
  575. * @param integer $milliseconds
  576. * @return void
  577. * @access public
  578. */
  579. function setDisconnecttime($milliseconds)
  580. {
  581. if (is_integer($milliseconds) && $milliseconds >= 100) {
  582. $this->_disconnecttime = $milliseconds;
  583. } else {
  584. $this->_disconnecttime = 100;
  585. }
  586. }
  587. /**
  588. * Sets the delaytime before attempting reconnect.
  589. * Value of 0 disables the delay entirely.
  590. *
  591. * @param integer $milliseconds
  592. * @return void
  593. * @access public
  594. */
  595. function setReconnectdelay($milliseconds)
  596. {
  597. if (is_integer($milliseconds)) {
  598. $this->_reconnectdelay = $milliseconds;
  599. } else {
  600. $this->_reconnectdelay = 10000;
  601. }
  602. }
  603. /**
  604. * Sets the delay for receiving data from the IRC server.
  605. *
  606. * Sets the delaytime between messages that are received, this reduces your CPU load.
  607. * Don't set this too low (min 100ms).
  608. * Default: 100
  609. *
  610. * @param integer $milliseconds
  611. * @return void
  612. * @access public
  613. */
  614. function setReceivedelay($milliseconds)
  615. {
  616. if (is_integer($milliseconds) && $milliseconds >= 100) {
  617. $this->_receivedelay = $milliseconds;
  618. } else {
  619. $this->_receivedelay = 100;
  620. }
  621. }
  622. /**
  623. * Sets the delay for sending data to the IRC server.
  624. *
  625. * Sets the delaytime between messages that are sent, because IRC servers doesn't like floods.
  626. * This will avoid sending your messages too fast to the IRC server.
  627. * Default: 250
  628. *
  629. * @param integer $milliseconds
  630. * @return void
  631. * @access public
  632. */
  633. function setSenddelay($milliseconds)
  634. {
  635. if (is_integer($milliseconds)) {
  636. $this->_senddelay = $milliseconds;
  637. } else {
  638. $this->_senddelay = 250;
  639. }
  640. }
  641. /**
  642. * Enables/disables autoreconnecting.
  643. *
  644. * @param boolean $boolean
  645. * @return void
  646. * @access public
  647. */
  648. function setAutoReconnect($boolean)
  649. {
  650. if (is_bool($boolean)) {
  651. $this->_autoreconnect = $boolean;
  652. } else {
  653. $this->_autoreconnect = false;
  654. }
  655. }
  656. /**
  657. * Enables/disables autoretry for connecting to a server.
  658. *
  659. * @param boolean $boolean
  660. * @return void
  661. * @access public
  662. */
  663. function setAutoRetry($boolean)
  664. {
  665. if (is_bool($boolean)) {
  666. $this->_autoretry = $boolean;
  667. } else {
  668. $this->_autoretry = false;
  669. }
  670. }
  671. /**
  672. * Sets the maximum number of attempts to connect to a server
  673. * before giving up.
  674. *
  675. * @param integer $autoretrymax
  676. * @return void
  677. * @access public
  678. */
  679. function setAutoRetryMax($autoretrymax)
  680. {
  681. if (is_integer($autoretrymax)) {
  682. $this->_autoretrymax = $autoretrymax;
  683. } else {
  684. $this->_autoretrymax = 5;
  685. }
  686. }
  687. /**
  688. * Sets the receive timeout.
  689. *
  690. * If the timeout occurs, the connection will be reinitialized
  691. * Default: 300 seconds
  692. *
  693. * @param integer $seconds
  694. * @return void
  695. * @access public
  696. */
  697. function setReceiveTimeout($seconds)
  698. {
  699. if (is_integer($seconds)) {
  700. $this->_rxtimeout = $seconds;
  701. } else {
  702. $this->_rxtimeout = 300;
  703. }
  704. }
  705. /**
  706. * Sets the transmit timeout.
  707. *
  708. * If the timeout occurs, the connection will be reinitialized
  709. * Default: 300 seconds
  710. *
  711. * @param integer $seconds
  712. * @return void
  713. * @access public
  714. */
  715. function setTransmitTimeout($seconds)
  716. {
  717. if (is_integer($seconds)) {
  718. $this->_txtimeout = $seconds;
  719. } else {
  720. $this->_txtimeout = 300;
  721. }
  722. }
  723. /**
  724. * Sets the paths for the modules.
  725. *
  726. * @param integer $path
  727. * @return void
  728. * @access public
  729. */
  730. function setModulepath($path)
  731. {
  732. $this->_modulepath = $path;
  733. }
  734. /**
  735. * Sets wheter the script should be run as a daemon or not
  736. * ( actually disables/enables ignore_user_abort() )
  737. *
  738. * @param boolean $boolean
  739. * @return void
  740. * @access public
  741. */
  742. function setRunAsDaemon($boolean)
  743. {
  744. if ($boolean === true) {
  745. $this->_runasdaemon = true;
  746. ingore_user_abort(true);
  747. } else {
  748. $this->_runasdaemon = false;
  749. }
  750. }
  751. /**
  752. * Starts the benchmark (sets the counters).
  753. *
  754. * @return void
  755. * @access public
  756. */
  757. function startBenchmark()
  758. {
  759. $this->_benchmark_starttime = $this->_microint();
  760. $this->log(SMARTIRC_DEBUG_NOTICE, 'benchmark started', __FILE__, __LINE__);
  761. }
  762. /**
  763. * Stops the benchmark and displays the result.
  764. *
  765. * @return void
  766. * @access public
  767. */
  768. function stopBenchmark()
  769. {
  770. $this->_benchmark_stoptime = $this->_microint();
  771. $this->log(SMARTIRC_DEBUG_NOTICE, 'benchmark stopped', __FILE__, __LINE__);
  772. if ($this->_benchmark) {
  773. $this->showBenchmark();
  774. }
  775. }
  776. /**
  777. * Shows the benchmark result.
  778. *
  779. * @return void
  780. * @access public
  781. */
  782. function showBenchmark()
  783. {
  784. $this->log(SMARTIRC_DEBUG_NOTICE, 'benchmark time: '.((float)$this->_benchmark_stoptime-(float)$this->_benchmark_starttime), __FILE__, __LINE__);
  785. }
  786. /**
  787. * Adds an entry to the log.
  788. *
  789. * Adds an entry to the log with Linux style log format.
  790. * Possible $level constants (can also be combined with "|"s)
  791. * SMARTIRC_DEBUG_NONE
  792. * SMARTIRC_DEBUG_NOTICE
  793. * SMARTIRC_DEBUG_CONNECTION
  794. * SMARTIRC_DEBUG_SOCKET
  795. * SMARTIRC_DEBUG_IRCMESSAGES
  796. * SMARTIRC_DEBUG_MESSAGETYPES
  797. * SMARTIRC_DEBUG_ACTIONHANDLER
  798. * SMARTIRC_DEBUG_TIMEHANDLER
  799. * SMARTIRC_DEBUG_MESSAGEHANDLER
  800. * SMARTIRC_DEBUG_CHANNELSYNCING
  801. * SMARTIRC_DEBUG_MODULES
  802. * SMARTIRC_DEBUG_USERSYNCING
  803. * SMARTIRC_DEBUG_ALL
  804. *
  805. * @see SMARTIRC_DEBUG_NOTICE
  806. * @param integer $level bit constants (SMARTIRC_DEBUG_*)
  807. * @param string $entry the new log entry
  808. * @return void
  809. * @access public
  810. */
  811. function log($level, $entry, $file = null, $line = null)
  812. {
  813. // prechecks
  814. if (!(is_integer($level)) ||
  815. !($level & SMARTIRC_DEBUG_ALL)) {
  816. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: invalid log level passed to log() ('.$level.')', __FILE__, __LINE__);
  817. return;
  818. }
  819. if (!($level & $this->_debug) ||
  820. ($this->_logdestination == SMARTIRC_NONE)) {
  821. return;
  822. }
  823. if (substr($entry, -1) != "\n") {
  824. $entry .= "\n";
  825. }
  826. if ($file !== null &&
  827. $line !== null) {
  828. $file = basename($file);
  829. $entry = $file.'('.$line.') '.$entry;
  830. } else {
  831. $entry = 'unknown(0) '.$entry;
  832. }
  833. $formatedentry = date('M d H:i:s ').$entry;
  834. switch ($this->_logdestination) {
  835. case SMARTIRC_STDOUT:
  836. echo $formatedentry;
  837. flush();
  838. break;
  839. case SMARTIRC_BROWSEROUT:
  840. echo '<pre>'.htmlentities($formatedentry).'</pre>';
  841. break;
  842. case SMARTIRC_FILE:
  843. if (!is_resource($this->_logfilefp)) {
  844. if ($this->_logfilefp === null) {
  845. // we reconncted and don't want to destroy the old log entries
  846. $this->_logfilefp = fopen($this->_logfile,'a');
  847. } else {
  848. $this->_logfilefp = fopen($this->_logfile,'w');
  849. }
  850. }
  851. fwrite($this->_logfilefp, $formatedentry);
  852. fflush($this->_logfilefp);
  853. break;
  854. case SMARTIRC_SYSLOG:
  855. define_syslog_variables();
  856. if (!is_int($this->_logfilefp)) {
  857. $this->_logfilefp = openlog('Net_SmartIRC', LOG_NDELAY, LOG_DAEMON);
  858. }
  859. syslog(LOG_INFO, $entry);
  860. break;
  861. }
  862. }
  863. /**
  864. * Returns the full motd.
  865. *
  866. * @return array
  867. * @access public
  868. */
  869. function getMotd()
  870. {
  871. return $this->_motd;
  872. }
  873. /**
  874. * Returns the usermode.
  875. *
  876. * @return string
  877. * @access public
  878. */
  879. function getUsermode()
  880. {
  881. return $this->_usermode;
  882. }
  883. /**
  884. * Returns a reference to the channel object of the specified channelname.
  885. *
  886. * @param string $channelname
  887. * @return object
  888. * @access public
  889. */
  890. function &getChannel($channelname)
  891. {
  892. if ($this->_channelsyncing != true) {
  893. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: getChannel() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
  894. return false;
  895. }
  896. if ($this->isJoined($channelname)) {
  897. return $this->_channels[strtolower($channelname)];
  898. } else {
  899. return false;
  900. }
  901. }
  902. /**
  903. * Returns a reference to the user object for the specified username and channelname.
  904. *
  905. * @param string $channelname
  906. * @param string $username
  907. * @return object
  908. * @access public
  909. */
  910. function &getUser($channelname, $username)
  911. {
  912. if ($this->_channelsyncing != true) {
  913. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: getUser() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
  914. return false;
  915. }
  916. if ($this->isJoined($channelname, $username)) {
  917. return $this->_channels[strtolower($channelname)]->users[strtolower($username)];
  918. } else {
  919. return false;
  920. }
  921. }
  922. /**
  923. * Creates the sockets and connects to the IRC server on the given port.
  924. *
  925. * @param string $address
  926. * @param integer $port
  927. * @return boolean
  928. * @access public
  929. */
  930. function connect($address, $port)
  931. {
  932. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connecting', __FILE__, __LINE__);
  933. $this->_address = $address;
  934. $this->_port = $port;
  935. if ($this->_usesockets == true) {
  936. $this->log(SMARTIRC_DEBUG_SOCKET, 'DEBUG_SOCKET: using real sockets', __FILE__, __LINE__);
  937. $this->_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
  938. $result = socket_connect($this->_socket, $this->_address, $this->_port);
  939. } else {
  940. $this->log(SMARTIRC_DEBUG_SOCKET, 'DEBUG_SOCKET: using fsockets', __FILE__, __LINE__);
  941. $result = fsockopen($this->_address, $this->_port, $errno, $errstr);
  942. }
  943. if ($result === false) {
  944. if ($this->_usesockets == true) {
  945. $error = socket_strerror(socket_last_error($this->_socket));
  946. } else {
  947. $error = $errstr.' ('.$errno.')';
  948. }
  949. $error_msg = 'couldn\'t connect to "'.$address.'" reason: "'.$error.'"';
  950. $this->log(SMARTIRC_DEBUG_NOTICE, 'DEBUG_NOTICE: '.$error_msg, __FILE__, __LINE__);
  951. // TODO! needs to be return value
  952. $this->throwError($error_msg);
  953. if (($this->_autoretry == true) &&
  954. ($this->_autoretrycount < $this->_autoretrymax)) {
  955. $this->_delayReconnect();
  956. $this->_autoretrycount++;
  957. $this->reconnect();
  958. } else {
  959. return false;
  960. }
  961. } else {
  962. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connected', __FILE__, __LINE__);
  963. $this->_autoretrycount = 0;
  964. $this->_connectionerror = false;
  965. if ($this->_usesockets != true) {
  966. $this->_socket = $result;
  967. $this->log(SMARTIRC_DEBUG_SOCKET, 'DEBUG_SOCKET: activating nonblocking fsocket mode', __FILE__, __LINE__);
  968. stream_set_blocking($this->_socket, 0);
  969. }
  970. }
  971. $this->_lastrx = time();
  972. $this->_lasttx = $this->_lastrx;
  973. $this->_updatestate();
  974. return $result !== false;
  975. }
  976. /**
  977. * Disconnects from the IRC server nicely with a QUIT or just destroys the socket.
  978. *
  979. * Disconnects from the IRC server in the given quickness mode.
  980. * $quickdisconnect:
  981. * true, just close the socket
  982. * false, send QUIT and wait {@link $_disconnectime $_disconnectime} before closing the socket
  983. *
  984. * @param boolean $quickdisconnect default: false
  985. * @return boolean
  986. * @access public
  987. */
  988. function disconnect($quickdisconnect = false)
  989. {
  990. if ($this->_state() == SMARTIRC_STATE_CONNECTED) {
  991. if ($quickdisconnect == false) {
  992. $this->_send('QUIT', SMARTIRC_CRITICAL);
  993. usleep($this->_disconnecttime*1000);
  994. }
  995. if ($this->_usesockets == true) {
  996. @socket_shutdown($this->_socket);
  997. @socket_close($this->_socket);
  998. } else {
  999. fclose($this->_socket);
  1000. }
  1001. $this->_updatestate();
  1002. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: disconnected', __FILE__, __LINE__);
  1003. } else {
  1004. return false;
  1005. }
  1006. if ($this->_channelsyncing == true) {
  1007. // let's clean our channel array
  1008. $this->_channels = array();
  1009. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: cleaned channel array', __FILE__, __LINE__);
  1010. }
  1011. if ($this->_usersyncing == true) {
  1012. // let's clean our user array
  1013. $this->_users = array();
  1014. $this->log(SMARTIRC_DEBUG_USERSYNCING, 'DEBUG_USERSYNCING: cleaned user array', __FILE__, __LINE__);
  1015. }
  1016. if ($this->_logdestination == SMARTIRC_FILE) {
  1017. fclose($this->_logfilefp);
  1018. $this->_logfilefp = null;
  1019. } else if ($this->_logdestination == SMARTIRC_SYSLOG) {
  1020. closelog();
  1021. }
  1022. return true;
  1023. }
  1024. /**
  1025. * Reconnects to the IRC server with the same login info,
  1026. * it also rejoins the channels
  1027. *
  1028. * @return void
  1029. * @access public
  1030. */
  1031. function reconnect()
  1032. {
  1033. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: reconnecting...', __FILE__, __LINE__);
  1034. // remember in which channels we are joined
  1035. $channels = array();
  1036. foreach ($this->_channels as $value) {
  1037. if (empty($value->key)) {
  1038. $channels[] = array('name' => $value->name);
  1039. } else {
  1040. $channels[] = array('name' => $value->name, 'key' => $value->key);
  1041. }
  1042. }
  1043. $this->disconnect(true);
  1044. $this->connect($this->_address, $this->_port);
  1045. $this->login($this->_nick, $this->_realname, $this->_usermode, $this->_username, $this->_password);
  1046. // rejoin the channels
  1047. foreach ($channels as $value) {
  1048. if (isset($value['key'])) {
  1049. $this->join($value['name'], $value['key']);
  1050. } else {
  1051. $this->join($value['name']);
  1052. }
  1053. }
  1054. }
  1055. /**
  1056. * login and register nickname on the IRC network
  1057. *
  1058. * Registers the nickname and user information on the IRC network.
  1059. *
  1060. * @param string $nick
  1061. * @param string $realname
  1062. * @param integer $usermode
  1063. * @param string $username
  1064. * @param string $password
  1065. * @return void
  1066. * @access public
  1067. */
  1068. function login($nick, $realname, $usermode = 0, $username = null, $password = null)
  1069. {
  1070. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: logging in', __FILE__, __LINE__);
  1071. $this->_nick = str_replace(' ', '', $nick);
  1072. $this->_realname = $realname;
  1073. if ($username !== null) {
  1074. $this->_username = str_replace(' ', '', $username);
  1075. } else {
  1076. $this->_username = str_replace(' ', '', exec('whoami'));
  1077. }
  1078. if ($password !== null) {
  1079. $this->_password = $password;
  1080. $this->_send('PASS '.$this->_password, SMARTIRC_CRITICAL);
  1081. }
  1082. if (!is_numeric($usermode)) {
  1083. $this->log(SMARTIRC_DEBUG_NOTICE, 'DEBUG_NOTICE: login() usermode ('.$usermode.') is not valid, will use 0 instead', __FILE__, __LINE__);
  1084. $usermode = 0;
  1085. }
  1086. $this->_send('NICK '.$this->_nick, SMARTIRC_CRITICAL);
  1087. $this->_send('USER '.$this->_username.' '.$usermode.' '.SMARTIRC_UNUSED.' :'.$this->_realname, SMARTIRC_CRITICAL);
  1088. }
  1089. // </IRC methods>
  1090. /**
  1091. * checks if the passed nickname is our own nickname
  1092. *
  1093. * @param string $nickname
  1094. * @return boolean
  1095. * @access public
  1096. */
  1097. function isMe($nickname)
  1098. {
  1099. if ($nickname == $this->_nick) {
  1100. return true;
  1101. } else {
  1102. return false;
  1103. }
  1104. }
  1105. /**
  1106. * checks if we or the given user is joined to the specified channel and returns the result
  1107. * ChannelSyncing is required for this.
  1108. *
  1109. * @see setChannelSyncing
  1110. * @param string $channel
  1111. * @param string $nickname
  1112. * @return boolean
  1113. * @access public
  1114. */
  1115. function isJoined($channel, $nickname = null)
  1116. {
  1117. if ($this->_channelsyncing != true) {
  1118. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isJoined() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
  1119. return false;
  1120. }
  1121. if ($nickname === null) {
  1122. $nickname = $this->_nick;
  1123. }
  1124. if (isset($this->_channels[strtolower($channel)]->users[strtolower($nickname)])) {
  1125. return true;
  1126. }
  1127. return false;
  1128. }
  1129. /**
  1130. * Checks if we or the given user is opped on the specified channel and returns the result.
  1131. * ChannelSyncing is required for this.
  1132. *
  1133. * @see setChannelSyncing
  1134. * @param string $channel
  1135. * @param string $nickname
  1136. * @return boolean
  1137. * @access public
  1138. */
  1139. function isOpped($channel, $nickname = null)
  1140. {
  1141. if ($this->_channelsyncing != true) {
  1142. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isOpped() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
  1143. return false;
  1144. }
  1145. if ($nickname === null) {
  1146. $nickname = $this->_nick;
  1147. }
  1148. if ($this->isJoined($channel, $nickname)) {
  1149. if ($this->_channels[strtolower($channel)]->users[strtolower($nickname)]->op) {
  1150. return true;
  1151. }
  1152. }
  1153. return false;
  1154. }
  1155. /**
  1156. * Checks if we or the given user is voiced on the specified channel and returns the result.
  1157. * ChannelSyncing is required for this.
  1158. *
  1159. * @see setChannelSyncing
  1160. * @param string $channel
  1161. * @param string $nickname
  1162. * @return boolean
  1163. * @access public
  1164. */
  1165. function isVoiced($channel, $nickname = null)
  1166. {
  1167. if ($this->_channelsyncing != true) {
  1168. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isVoiced() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
  1169. return false;
  1170. }
  1171. if ($nickname === null) {
  1172. $nickname = $this->_nick;
  1173. }
  1174. if ($this->isJoined($channel, $nickname)) {
  1175. if ($this->_channels[strtolower($channel)]->users[strtolower($nickname)]->voice) {
  1176. return true;
  1177. }
  1178. }
  1179. return false;
  1180. }
  1181. /**
  1182. * Checks if the hostmask is on the specified channel banned and returns the result.
  1183. * ChannelSyncing is required for this.
  1184. *
  1185. * @see setChannelSyncing
  1186. * @param string $channel
  1187. * @param string $hostmask
  1188. * @return boolean
  1189. * @access public
  1190. */
  1191. function isBanned($channel, $hostmask)
  1192. {
  1193. if ($this->_channelsyncing != true) {
  1194. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: isBanned() is called and the required Channel Syncing is not activated!', __FILE__, __LINE__);
  1195. return false;
  1196. }
  1197. if ($this->isJoined($channel)) {
  1198. $result = array_search($hostmask, $this->_channels[strtolower($channel)]->bans);
  1199. if ($result !== false) {
  1200. return true;
  1201. }
  1202. }
  1203. return false;
  1204. }
  1205. /**
  1206. * goes into receive mode
  1207. *
  1208. * Goes into receive and idle mode. Only call this if you want to "spawn" the bot.
  1209. * No further lines of PHP code will be processed after this call, only the bot methods!
  1210. *
  1211. * @return boolean
  1212. * @access public
  1213. */
  1214. function listen()
  1215. {
  1216. while ($this->_state() == SMARTIRC_STATE_CONNECTED) {
  1217. $this->listenOnce();
  1218. }
  1219. return false;
  1220. }
  1221. /**
  1222. * goes into receive mode _only_ for one pass
  1223. *
  1224. * Goes into receive mode. It will return when one pass is complete.
  1225. * Use this when you want to connect to multiple IRC servers.
  1226. *
  1227. * @return boolean
  1228. * @access public
  1229. */
  1230. function listenOnce()
  1231. {
  1232. if ($this->_state() == SMARTIRC_STATE_CONNECTED) {
  1233. $this->_rawreceive();
  1234. if ($this->_connectionerror) {
  1235. if ($this->_autoreconnect) {
  1236. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connection error detected, will reconnect!', __FILE__, __LINE__);
  1237. $this->reconnect();
  1238. } else {
  1239. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: connection error detected, will disconnect!', __FILE__, __LINE__);
  1240. $this->disconnect();
  1241. }
  1242. }
  1243. return true;
  1244. } else {
  1245. return false;
  1246. }
  1247. }
  1248. /**
  1249. * waits for a special message type and puts the answer in $result
  1250. *
  1251. * Creates a special actionhandler for that given TYPE and returns the answer.
  1252. * This will only receive the requested type, immediately quit and disconnect from the IRC server.
  1253. * Made for showing IRC statistics on your homepage, or other IRC related information.
  1254. *
  1255. * @param integer $messagetype see in the documentation 'Message Types'
  1256. * @return array answer from the IRC server for this $messagetype
  1257. * @access public
  1258. */
  1259. function listenFor($messagetype)
  1260. {
  1261. $listenfor = &new Net_SmartIRC_listenfor();
  1262. $this->registerActionhandler($messagetype, '.*', $listenfor, 'handler');
  1263. $this->listen();
  1264. $result = $listenfor->result;
  1265. if (isset($listenfor)) {
  1266. unset($listenfor);
  1267. }
  1268. return $result;
  1269. }
  1270. /**
  1271. * registers a new actionhandler and returns the assigned id
  1272. *
  1273. * Registers an actionhandler in Net_SmartIRC for calling it later.
  1274. * The actionhandler id is needed for unregistering the actionhandler.
  1275. *
  1276. * @see example.php
  1277. * @param integer $handlertype bits constants, see in this documentation Message Types
  1278. * @param string $regexhandler the message that has to be in the IRC message in regex syntax
  1279. * @param object $object a reference to the objects of the method
  1280. * @param string $methodname the methodname that will be called when the handler happens
  1281. * @return integer assigned actionhandler id
  1282. * @access public
  1283. */
  1284. function registerActionhandler($handlertype, $regexhandler, &$object, $methodname)
  1285. {
  1286. // precheck
  1287. if (!$this->_isValidType($handlertype)) {
  1288. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: passed invalid handlertype to registerActionhandler()', __FILE__, __LINE__);
  1289. return false;
  1290. }
  1291. $id = $this->_actionhandlerid++;
  1292. $newactionhandler = &new Net_SmartIRC_actionhandler();
  1293. $newactionhandler->id = $id;
  1294. $newactionhandler->type = $handlertype;
  1295. $newactionhandler->message = $regexhandler;
  1296. $newactionhandler->object = &$object;
  1297. $newactionhandler->method = $methodname;
  1298. $this->_actionhandler[] = &$newactionhandler;
  1299. $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') registered', __FILE__, __LINE__);
  1300. return $id;
  1301. }
  1302. /**
  1303. * unregisters an existing actionhandler
  1304. *
  1305. * @param integer $handlertype
  1306. * @param string $regexhandler
  1307. * @param object $object
  1308. * @param string $methodname
  1309. * @return boolean
  1310. * @access public
  1311. */
  1312. function unregisterActionhandler($handlertype, $regexhandler, &$object, $methodname)
  1313. {
  1314. // precheck
  1315. if (!$this->_isValidType($handlertype)) {
  1316. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: passed invalid handlertype to unregisterActionhandler()', __FILE__, __LINE__);
  1317. return false;
  1318. }
  1319. $handler = &$this->_actionhandler;
  1320. $handlercount = count($handler);
  1321. for ($i = 0; $i < $handlercount; $i++) {
  1322. $handlerobject = &$handler[$i];
  1323. if ($handlerobject->type == $handlertype &&
  1324. $handlerobject->message == $regexhandler &&
  1325. $handlerobject->method == $methodname) {
  1326. $id = $handlerobject->id;
  1327. if (isset($this->_actionhandler[$i])) {
  1328. unset($this->_actionhandler[$i]);
  1329. }
  1330. $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') unregistered', __FILE__, __LINE__);
  1331. $this->_reorderactionhandler();
  1332. return true;
  1333. }
  1334. }
  1335. $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: could not find actionhandler type: "'.$handlertype.'" message: "'.$regexhandler.'" method: "'.$methodname.'" from object "'.get_class($object).'" _not_ unregistered', __FILE__, __LINE__);
  1336. return false;
  1337. }
  1338. /**
  1339. * unregisters an existing actionhandler via the id
  1340. *
  1341. * @param integer $id
  1342. * @return boolean
  1343. * @access public
  1344. */
  1345. function unregisterActionid($id)
  1346. {
  1347. $handler = &$this->_actionhandler;
  1348. $handlercount = count($handler);
  1349. for ($i = 0; $i < $handlercount; $i++) {
  1350. $handlerobject = &$handler[$i];
  1351. if ($handlerobject->id == $id) {
  1352. if (isset($this->_actionhandler[$i])) {
  1353. unset($this->_actionhandler[$i]);
  1354. }
  1355. $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler('.$id.') unregistered', __FILE__, __LINE__);
  1356. $this->_reorderactionhandler();
  1357. return true;
  1358. }
  1359. }
  1360. $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: could not find actionhandler id: '.$id.' _not_ unregistered', __FILE__, __LINE__);
  1361. return false;
  1362. }
  1363. /**
  1364. * registers a timehandler and returns the assigned id
  1365. *
  1366. * Registers a timehandler in Net_SmartIRC, which will be called in the specified interval.
  1367. * The timehandler id is needed for unregistering the timehandler.
  1368. *
  1369. * @see example7.php
  1370. * @param integer $interval interval time in milliseconds
  1371. * @param object $object a reference to the objects of the method
  1372. * @param string $methodname the methodname that will be called when the handler happens
  1373. * @return integer assigned timehandler id
  1374. * @access public
  1375. */
  1376. function registerTimehandler($interval, &$object, $methodname)
  1377. {
  1378. $id = $this->_timehandlerid++;
  1379. $newtimehandler = &new Net_SmartIRC_timehandler();
  1380. $newtimehandler->id = $id;
  1381. $newtimehandler->interval = $interval;
  1382. $newtimehandler->object = &$object;
  1383. $newtimehandler->method = $methodname;
  1384. $newtimehandler->lastmicrotimestamp = $this->_microint();
  1385. $this->_timehandler[] = &$newtimehandler;
  1386. $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: timehandler('.$id.') registered', __FILE__, __LINE__);
  1387. if (($interval < $this->_mintimer) || ($this->_mintimer == false)) {
  1388. $this->_mintimer = $interval;
  1389. }
  1390. return $id;
  1391. }
  1392. /**
  1393. * unregisters an existing timehandler via the id
  1394. *
  1395. * @see example7.php
  1396. * @param integer $id
  1397. * @return boolean
  1398. * @access public
  1399. */
  1400. function unregisterTimeid($id)
  1401. {
  1402. $handler = &$this->_timehandler;
  1403. $handlercount = count($handler);
  1404. for ($i = 0; $i < $handlercount; $i++) {
  1405. $handlerobject = &$handler[$i];
  1406. if ($handlerobject->id == $id) {
  1407. if (isset($this->_timehandler[$i])) {
  1408. unset($this->_timehandler[$i]);
  1409. }
  1410. $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: timehandler('.$id.') unregistered', __FILE__, __LINE__);
  1411. $this->_reordertimehandler();
  1412. $this->_updatemintimer();
  1413. return true;
  1414. }
  1415. }
  1416. $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: could not find timehandler id: '.$id.' _not_ unregistered', __FILE__, __LINE__);
  1417. return false;
  1418. }
  1419. function loadModule($name)
  1420. {
  1421. // is the module already loaded?
  1422. if (in_array($name, $this->_modules)) {
  1423. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING! module with the name "'.$name.'" already loaded!', __FILE__, __LINE__);
  1424. return false;
  1425. }
  1426. $filename = $this->_modulepath.'/'.$name.'.php';
  1427. if (!file_exists($filename)) {
  1428. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: couldn\'t load module "'.$filename.'" file doesn\'t exist', __FILE__, __LINE__);
  1429. return false;
  1430. }
  1431. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: loading module: "'.$name.'"...', __FILE__, __LINE__);
  1432. // pray that there is no parse error, it will kill us!
  1433. include_once($filename);
  1434. $classname = 'Net_SmartIRC_module_'.$name;
  1435. if (!class_exists($classname)) {
  1436. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: class '.$classname.' not found in '.$filename, __FILE__, __LINE__);
  1437. return false;
  1438. }
  1439. $methods = get_class_methods($classname);
  1440. if (!in_array('module_init', $methods)) {
  1441. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required method'.$classname.'::module_init not found, aborting...', __FILE__, __LINE__);
  1442. return false;
  1443. }
  1444. if (!in_array('module_exit', $methods)) {
  1445. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required method'.$classname.'::module_exit not found, aborting...', __FILE__, __LINE__);
  1446. return false;
  1447. }
  1448. $vars = array_keys(get_class_vars($classname));
  1449. if (!in_array('name', $vars)) {
  1450. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::name not found, aborting...', __FILE__, __LINE__);
  1451. return false;
  1452. }
  1453. if (!in_array('description', $vars)) {
  1454. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::description not found, aborting...', __FILE__, __LINE__);
  1455. return false;
  1456. }
  1457. if (!in_array('author', $vars)) {
  1458. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::author not found, aborting...', __FILE__, __LINE__);
  1459. return false;
  1460. }
  1461. if (!in_array('license', $vars)) {
  1462. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: required variable '.$classname.'::license not found, aborting...', __FILE__, __LINE__);
  1463. return false;
  1464. }
  1465. // looks like the module satisfies us
  1466. $module = &new $classname;
  1467. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: successful created instance of: '.$classname, __FILE__, __LINE__);
  1468. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: calling '.$classname.'::module_init()', __FILE__, __LINE__);
  1469. $module->module_init($this);
  1470. $this->_modules[$name] = &$module;
  1471. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: successful loaded module: '.$name, __FILE__, __LINE__);
  1472. return true;
  1473. }
  1474. function unloadModule($name)
  1475. {
  1476. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: unloading module: '.$name.'...', __FILE__, __LINE__);
  1477. $modules_keys = array_keys($this->_modules);
  1478. $modulecount = count($modules_keys);
  1479. for ($i = 0; $i < $modulecount; $i++) {
  1480. $module = &$this->_modules[$modules_keys[$i]];
  1481. $modulename = strtolower(get_class($module));
  1482. if ($modulename == 'net_smartirc_module_'.$name) {
  1483. $module->module_exit($this);
  1484. unset($this->_modules[$i]);
  1485. $this->_reordermodules();
  1486. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: successful unloaded module: '.$name, __FILE__, __LINE__);
  1487. return true;
  1488. }
  1489. }
  1490. $this->log(SMARTIRC_DEBUG_MODULES, 'DEBUG_MODULES: couldn\'t unloaded module: '.$name.' (it\'s not loaded!)', __FILE__, __LINE__);
  1491. return false;
  1492. }
  1493. // <private methods>
  1494. /**
  1495. * changes a already used nickname to a new nickname plus 3 random digits
  1496. *
  1497. * @return void
  1498. * @access private
  1499. */
  1500. function _nicknameinuse()
  1501. {
  1502. $newnickname = substr($this->_nick, 0, 5).rand(0, 999);
  1503. $this->changeNick($newnickname, SMARTIRC_CRITICAL);
  1504. }
  1505. /**
  1506. * sends an IRC message
  1507. *
  1508. * Adds a message to the messagequeue, with the optional priority.
  1509. * $priority:
  1510. * SMARTIRC_CRITICAL
  1511. * SMARTIRC_HIGH
  1512. * SMARTIRC_MEDIUM
  1513. * SMARTIRC_LOW
  1514. *
  1515. * @param string $data
  1516. * @param integer $priority must be one of the priority constants
  1517. * @return boolean
  1518. * @access public
  1519. */
  1520. function send($data, $priority = SMARTIRC_MEDIUM)
  1521. {
  1522. return $this->_send($data, $priority);
  1523. }
  1524. /**
  1525. * sends an IRC message
  1526. *
  1527. * Adds a message to the messagequeue, with the optional priority.
  1528. * $priority:
  1529. * SMARTIRC_CRITICAL
  1530. * SMARTIRC_HIGH
  1531. * SMARTIRC_MEDIUM
  1532. * SMARTIRC_LOW
  1533. *
  1534. * @param string $data
  1535. * @param integer $priority must be one of the priority constants
  1536. * @return boolean
  1537. * @access private
  1538. */
  1539. function _send($data, $priority = SMARTIRC_MEDIUM)
  1540. {
  1541. switch ($priority) {
  1542. case SMARTIRC_CRITICAL:
  1543. $this->_rawsend($data);
  1544. break;
  1545. case SMARTIRC_HIGH:
  1546. case SMARTIRC_MEDIUM:
  1547. case SMARTIRC_LOW:
  1548. $this->_messagebuffer[$priority][] = $data;
  1549. break;
  1550. default:
  1551. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: message ('.$data.') with an invalid priority passed ('.$priority.'), message is ignored!', __FILE__, __LINE__);
  1552. return false;
  1553. }
  1554. return true;
  1555. }
  1556. /**
  1557. * checks the buffer if there are messages to send
  1558. *
  1559. * @return void
  1560. * @access private
  1561. */
  1562. function _checkbuffer()
  1563. {
  1564. if (!$this->_loggedin) {
  1565. return;
  1566. }
  1567. static $highsent = 0;
  1568. static $lastmicrotimestamp = 0;
  1569. if ($lastmicrotimestamp == 0) {
  1570. $lastmicrotimestamp = $this->_microint();
  1571. }
  1572. $highcount = count($this->_messagebuffer[SMARTIRC_HIGH]);
  1573. $mediumcount = count($this->_messagebuffer[SMARTIRC_MEDIUM]);
  1574. $lowcount = count($this->_messagebuffer[SMARTIRC_LOW]);
  1575. $this->_messagebuffersize = $highcount+$mediumcount+$lowcount;
  1576. // don't send them too fast
  1577. if ($this->_microint() >= ($lastmicrotimestamp+($this->_senddelay/1000))) {
  1578. $result = null;
  1579. if ($highcount > 0 && $highsent <= 2) {
  1580. $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_HIGH]));
  1581. $lastmicrotimestamp = $this->_microint();
  1582. $highsent++;
  1583. } else if ($mediumcount > 0) {
  1584. $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_MEDIUM]));
  1585. $lastmicrotimestamp = $this->_microint();
  1586. $highsent = 0;
  1587. } else if ($lowcount > 0) {
  1588. $this->_rawsend(array_shift($this->_messagebuffer[SMARTIRC_LOW]));
  1589. $lastmicrotimestamp = $this->_microint();
  1590. }
  1591. }
  1592. }
  1593. /**
  1594. * Checks the running timers and calls the registered timehandler,
  1595. * when the interval is reached.
  1596. *
  1597. * @return void
  1598. * @access private
  1599. */
  1600. function _checktimer()
  1601. {
  1602. if (!$this->_loggedin) {
  1603. return;
  1604. }
  1605. // has to be count() because the array may change during the loop!
  1606. for ($i = 0; $i < count($this->_timehandler); $i++) {
  1607. $handlerobject = &$this->_timehandler[$i];
  1608. $microtimestamp = $this->_microint();
  1609. if ($microtimestamp >= ($handlerobject->lastmicrotimestamp+($handlerobject->interval/1000))) {
  1610. $methodobject = &$handlerobject->object;
  1611. $method = $handlerobject->method;
  1612. $handlerobject->lastmicrotimestamp = $microtimestamp;
  1613. if (@method_exists($methodobject, $method)) {
  1614. $this->log(SMARTIRC_DEBUG_TIMEHANDLER, 'DEBUG_TIMEHANDLER: calling method "'.get_class($methodobject).'->'.$method.'"', __FILE__, __LINE__);
  1615. $methodobject->$method($this);
  1616. }
  1617. }
  1618. }
  1619. }
  1620. /**
  1621. * Checks if a receive or transmit timeout occured and reconnects if configured
  1622. *
  1623. * @return void
  1624. * @access private
  1625. */
  1626. function _checktimeout()
  1627. {
  1628. if ($this->_autoreconnect == true) {
  1629. $timestamp = time();
  1630. if ($this->_lastrx < ($timestamp - $this->_rxtimeout)) {
  1631. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: receive timeout detected, doing reconnect...', __FILE__, __LINE__);
  1632. $this->_delayReconnect();
  1633. $this->reconnect();
  1634. } else if ($this->_lasttx < ($timestamp - $this->_txtimeout)) {
  1635. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: transmit timeout detected, doing reconnect...', __FILE__, __LINE__);
  1636. $this->_delayReconnect();
  1637. $this->reconnect();
  1638. }
  1639. }
  1640. }
  1641. /**
  1642. * sends a raw message to the IRC server (don't use this!!)
  1643. *
  1644. * Use message() or send() instead.
  1645. *
  1646. * @param string $data
  1647. * @return boolean
  1648. * @access private
  1649. */
  1650. function _rawsend($data)
  1651. {
  1652. if ($this->_state() == SMARTIRC_STATE_CONNECTED) {
  1653. $this->log(SMARTIRC_DEBUG_IRCMESSAGES, 'DEBUG_IRCMESSAGES: sent: "'.$data.'"', __FILE__, __LINE__);
  1654. if ($this->_usesockets == true) {
  1655. $result = socket_write($this->_socket, $data.SMARTIRC_CRLF);
  1656. } else {
  1657. $result = fwrite($this->_socket, $data.SMARTIRC_CRLF);
  1658. }
  1659. if ($result === false) {
  1660. // writing to the socket failed, means the connection is broken
  1661. $this->_connectionerror = true;
  1662. return false;
  1663. } else {
  1664. $this->_lasttx = time();
  1665. return true;
  1666. }
  1667. } else {
  1668. return false;
  1669. }
  1670. }
  1671. /**
  1672. * goes into main receive mode _once_ per call and waits for messages from the IRC server
  1673. *
  1674. * @return void
  1675. * @access private
  1676. */
  1677. function _rawreceive()
  1678. {
  1679. $lastpart = '';
  1680. $rawdataar = array();
  1681. $this->_checkbuffer();
  1682. $timeout = $this->_selecttimeout();
  1683. if ($this->_usesockets == true) {
  1684. $sread = array($this->_socket);
  1685. $result = socket_select($sread, $w = null, $e = null, 0, $timeout*1000);
  1686. if ($result == 1) {
  1687. // the socket got data to read
  1688. $rawdata = socket_read($this->_socket, 10240);
  1689. } else if ($result === false) {
  1690. // panic! panic! something went wrong!
  1691. $this->log(SMARTIRC_DEBUG_NOTICE, 'WARNING: socket_select() returned false, something went wrong! Reason: '.socket_strerror(socket_last_error()), __FILE__, __LINE__);
  1692. exit;
  1693. } else {
  1694. // no data
  1695. $rawdata = null;
  1696. }
  1697. } else {
  1698. usleep($this->_receivedelay*1000);
  1699. $rawdata = fread($this->_socket, 10240);
  1700. }
  1701. if ($rawdata === false) {
  1702. // reading from the socket failed, the connection is broken
  1703. $this->_connectionerror = true;
  1704. }
  1705. $this->_checktimer();
  1706. $this->_checktimeout();
  1707. if ($rawdata !== null && !empty($rawdata)) {
  1708. $this->_lastrx = time();
  1709. $rawdata = str_replace("\r", '', $rawdata);
  1710. $rawdata = $lastpart.$rawdata;
  1711. $lastpart = substr($rawdata, strrpos($rawdata ,"\n")+1);
  1712. $rawdata = substr($rawdata, 0, strrpos($rawdata ,"\n"));
  1713. $rawdataar = explode("\n", $rawdata);
  1714. }
  1715. // loop through our received messages
  1716. while (count($rawdataar) > 0) {
  1717. $rawline = array_shift($rawdataar);
  1718. $validmessage = false;
  1719. $this->log(SMARTIRC_DEBUG_IRCMESSAGES, 'DEBUG_IRCMESSAGES: received: "'.$rawline.'"', __FILE__, __LINE__);
  1720. // building our data packet
  1721. $ircdata = &new Net_SmartIRC_data();
  1722. $ircdata->rawmessage = $rawline;
  1723. $lineex = explode(' ', $rawline);
  1724. $ircdata->rawmessageex = $lineex;
  1725. $messagecode = $lineex[0];
  1726. if (substr($rawline, 0, 1) == ':') {
  1727. $validmessage = true;
  1728. $line = substr($rawline, 1);
  1729. $lineex = explode(' ', $line);
  1730. // conform to RFC 2812
  1731. $from = $lineex[0];
  1732. $messagecode = $lineex[1];
  1733. $exclamationpos = strpos($from, '!');
  1734. $atpos = strpos($from, '@');
  1735. $colonpos = strpos($line, ' :');
  1736. if ($colonpos !== false) {
  1737. // we want the exact position of ":" not beginning from the space
  1738. $colonpos += 1;
  1739. }
  1740. $ircdata->nick = substr($from, 0, $exclamationpos);
  1741. $ircdata->ident = substr($from, $exclamationpos+1, ($atpos-$exclamationpos)-1);
  1742. $ircdata->host = substr($from, $atpos+1);
  1743. $ircdata->type = $this->_gettype($rawline);
  1744. $ircdata->from = $from;
  1745. if ($colonpos !== false) {
  1746. $ircdata->message = substr($line, $colonpos+1);
  1747. $ircdata->messageex = explode(' ', $ircdata->message);
  1748. }
  1749. if ($ircdata->type & (SMARTIRC_TYPE_CHANNEL|
  1750. SMARTIRC_TYPE_ACTION|
  1751. SMARTIRC_TYPE_MODECHANGE|
  1752. SMARTIRC_TYPE_TOPICCHANGE|
  1753. SMARTIRC_TYPE_KICK|
  1754. SMARTIRC_TYPE_PART|
  1755. SMARTIRC_TYPE_JOIN)) {
  1756. $ircdata->channel = $lineex[2];
  1757. } else if ($ircdata->type & (SMARTIRC_TYPE_WHO|
  1758. SMARTIRC_TYPE_BANLIST|
  1759. SMARTIRC_TYPE_TOPIC|
  1760. SMARTIRC_TYPE_CHANNELMODE)) {
  1761. $ircdata->channel = $lineex[3];
  1762. } else if ($ircdata->type & SMARTIRC_TYPE_NAME) {
  1763. $ircdata->channel = $lineex[4];
  1764. }
  1765. if ($ircdata->channel !== null) {
  1766. if (substr($ircdata->channel, 0, 1) == ':') {
  1767. $ircdata->channel = substr($ircdata->channel, 1);
  1768. }
  1769. }
  1770. $this->log(SMARTIRC_DEBUG_MESSAGEPARSER, 'DEBUG_MESSAGEPARSER: ircdata nick: "'.$ircdata->nick.
  1771. '" ident: "'.$ircdata->ident.
  1772. '" host: "'.$ircdata->host.
  1773. '" type: "'.$ircdata->type.
  1774. '" from: "'.$ircdata->from.
  1775. '" channel: "'.$ircdata->channel.
  1776. '" message: "'.$ircdata->message.
  1777. '"', __FILE__, __LINE__);
  1778. }
  1779. // lets see if we have a messagehandler for it
  1780. $this->_handlemessage($messagecode, $ircdata);
  1781. if ($validmessage == true) {
  1782. // now the actionhandlers are comming
  1783. $this->_handleactionhandler($ircdata);
  1784. }
  1785. if (isset($ircdata)) {
  1786. unset($ircdata);
  1787. }
  1788. }
  1789. }
  1790. /**
  1791. * sends the pong for keeping alive
  1792. *
  1793. * Sends the PONG signal as reply of the PING from the IRC server.
  1794. *
  1795. * @param string $data
  1796. * @return void
  1797. * @access private
  1798. */
  1799. function _pong($data)
  1800. {
  1801. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: Ping? Pong!', __FILE__, __LINE__);
  1802. $this->_send('PONG '.$data, SMARTIRC_CRITICAL);
  1803. }
  1804. /**
  1805. * returns the calculated selecttimeout value
  1806. *
  1807. * @return integer selecttimeout in microseconds
  1808. * @access private
  1809. */
  1810. function _selecttimeout()
  1811. {
  1812. if ($this->_messagebuffersize == 0) {
  1813. $this->_selecttimeout = null;
  1814. if ($this->_mintimer != false) {
  1815. $this->_calculateselecttimeout($this->_mintimer);
  1816. }
  1817. if ($this->_autoreconnect == true) {
  1818. $this->_calculateselecttimeout($this->_rxtimeout*1000);
  1819. }
  1820. $this->_calculateselecttimeout($this->_maxtimer);
  1821. return $this->_selecttimeout;
  1822. } else {
  1823. return $this->_senddelay;
  1824. }
  1825. }
  1826. /**
  1827. * calculates the selecttimeout value
  1828. *
  1829. * @return void
  1830. * @access private
  1831. */
  1832. function _calculateselecttimeout($microseconds)
  1833. {
  1834. if (($this->_selecttimeout > $microseconds) || $this->_selecttimeout === null) {
  1835. $this->_selecttimeout = $microseconds;
  1836. }
  1837. }
  1838. /**
  1839. * updates _mintimer to the smallest timer interval
  1840. *
  1841. * @return void
  1842. * @access private
  1843. */
  1844. function _updatemintimer()
  1845. {
  1846. $timerarray = array();
  1847. foreach ($this->_timehandler as $values) {
  1848. $timerarray[] = $values->interval;
  1849. }
  1850. $result = array_multisort($timerarray, SORT_NUMERIC, SORT_ASC);
  1851. if ($result == true && isset($timerarray[0])) {
  1852. $this->_mintimer = $timerarray[0];
  1853. } else {
  1854. $this->_mintimer = false;
  1855. }
  1856. }
  1857. /**
  1858. * reorders the actionhandler array, needed after removing one
  1859. *
  1860. * @return void
  1861. * @access private
  1862. */
  1863. function _reorderactionhandler()
  1864. {
  1865. $orderedactionhandler = array();
  1866. foreach ($this->_actionhandler as $value) {
  1867. $orderedactionhandler[] = $value;
  1868. }
  1869. $this->_actionhandler = &$orderedactionhandler;
  1870. }
  1871. /**
  1872. * reorders the timehandler array, needed after removing one
  1873. *
  1874. * @return void
  1875. * @access private
  1876. */
  1877. function _reordertimehandler()
  1878. {
  1879. $orderedtimehandler = array();
  1880. foreach ($this->_timehandler as $value) {
  1881. $orderedtimehandler[] = $value;
  1882. }
  1883. $this->_timehandler = &$orderedtimehandler;
  1884. }
  1885. /**
  1886. * reorders the modules array, needed after removing one
  1887. *
  1888. * @return void
  1889. * @access private
  1890. */
  1891. function _reordermodules()
  1892. {
  1893. $orderedmodules = array();
  1894. foreach ($this->_modules as $value) {
  1895. $orderedmodules[] = $value;
  1896. }
  1897. $this->_modules = &$orderedmodules;
  1898. }
  1899. /**
  1900. * determines the messagetype of $line
  1901. *
  1902. * Analyses the type of an IRC message and returns the type.
  1903. *
  1904. * @param string $line
  1905. * @return integer SMARTIRC_TYPE_* constant
  1906. * @access private
  1907. */
  1908. function _gettype($line)
  1909. {
  1910. if (preg_match('/^:[^ ]+? [0-9]{3} .+$/', $line) == 1) {
  1911. $lineex = explode(' ', $line);
  1912. $code = $lineex[1];
  1913. switch ($code) {
  1914. case SMARTIRC_RPL_WELCOME:
  1915. case SMARTIRC_RPL_YOURHOST:
  1916. case SMARTIRC_RPL_CREATED:
  1917. case SMARTIRC_RPL_MYINFO:
  1918. case SMARTIRC_RPL_BOUNCE:
  1919. return SMARTIRC_TYPE_LOGIN;
  1920. case SMARTIRC_RPL_LUSERCLIENT:
  1921. case SMARTIRC_RPL_LUSEROP:
  1922. case SMARTIRC_RPL_LUSERUNKNOWN:
  1923. case SMARTIRC_RPL_LUSERME:
  1924. case SMARTIRC_RPL_LUSERCHANNELS:
  1925. return SMARTIRC_TYPE_INFO;
  1926. case SMARTIRC_RPL_MOTDSTART:
  1927. case SMARTIRC_RPL_MOTD:
  1928. case SMARTIRC_RPL_ENDOFMOTD:
  1929. return SMARTIRC_TYPE_MOTD;
  1930. case SMARTIRC_RPL_NAMREPLY:
  1931. case SMARTIRC_RPL_ENDOFNAMES:
  1932. return SMARTIRC_TYPE_NAME;
  1933. case SMARTIRC_RPL_WHOREPLY:
  1934. case SMARTIRC_RPL_ENDOFWHO:
  1935. return SMARTIRC_TYPE_WHO;
  1936. case SMARTIRC_RPL_LISTSTART:
  1937. return SMARTIRC_TYPE_NONRELEVANT;
  1938. case SMARTIRC_RPL_LIST:
  1939. case SMARTIRC_RPL_LISTEND:
  1940. return SMARTIRC_TYPE_LIST;
  1941. case SMARTIRC_RPL_BANLIST:
  1942. case SMARTIRC_RPL_ENDOFBANLIST:
  1943. return SMARTIRC_TYPE_BANLIST;
  1944. case SMARTIRC_RPL_TOPIC:
  1945. return SMARTIRC_TYPE_TOPIC;
  1946. case SMARTIRC_RPL_WHOISUSER:
  1947. case SMARTIRC_RPL_WHOISSERVER:
  1948. case SMARTIRC_RPL_WHOISOPERATOR:
  1949. case SMARTIRC_RPL_WHOISIDLE:
  1950. case SMARTIRC_RPL_ENDOFWHOIS:
  1951. case SMARTIRC_RPL_WHOISCHANNELS:
  1952. return SMARTIRC_TYPE_WHOIS;
  1953. case SMARTIRC_RPL_WHOWASUSER:
  1954. case SMARTIRC_RPL_ENDOFWHOWAS:
  1955. return SMARTIRC_TYPE_WHOWAS;
  1956. case SMARTIRC_RPL_UMODEIS:
  1957. return SMARTIRC_TYPE_USERMODE;
  1958. case SMARTIRC_RPL_CHANNELMODEIS:
  1959. return SMARTIRC_TYPE_CHANNELMODE;
  1960. case SMARTIRC_ERR_NICKNAMEINUSE:
  1961. case SMARTIRC_ERR_NOTREGISTERED:
  1962. return SMARTIRC_TYPE_ERROR;
  1963. default:
  1964. $this->log(SMARTIRC_DEBUG_IRCMESSAGES, 'DEBUG_IRCMESSAGES: replycode UNKNOWN ('.$code.'): "'.$line.'"', __FILE__, __LINE__);
  1965. }
  1966. }
  1967. if (preg_match('/^:.*? PRIVMSG .* :'.chr(1).'ACTION .*'.chr(1).'$/', $line) == 1) {
  1968. return SMARTIRC_TYPE_ACTION;
  1969. } else if (preg_match('/^:.*? PRIVMSG .* :'.chr(1).'.*'.chr(1).'$/', $line) == 1) {
  1970. return (SMARTIRC_TYPE_CTCP_REQUEST|SMARTIRC_TYPE_CTCP);
  1971. } else if (preg_match('/^:.*? NOTICE .* :'.chr(1).'.*'.chr(1).'$/', $line) == 1) {
  1972. return (SMARTIRC_TYPE_CTCP_REPLY|SMARTIRC_TYPE_CTCP);
  1973. } else if (preg_match('/^:.*? PRIVMSG (\&|\#|\+|\!).* :.*$/', $line) == 1) {
  1974. return SMARTIRC_TYPE_CHANNEL;
  1975. } else if (preg_match('/^:.*? PRIVMSG .*:.*$/', $line) == 1) {
  1976. return SMARTIRC_TYPE_QUERY;
  1977. } else if (preg_match('/^:.*? NOTICE .* :.*$/', $line) == 1) {
  1978. return SMARTIRC_TYPE_NOTICE;
  1979. } else if (preg_match('/^:.*? INVITE .* .*$/', $line) == 1) {
  1980. return SMARTIRC_TYPE_INVITE;
  1981. } else if (preg_match('/^:.*? JOIN .*$/', $line) == 1) {
  1982. return SMARTIRC_TYPE_JOIN;
  1983. } else if (preg_match('/^:.*? TOPIC .* :.*$/', $line) == 1) {
  1984. return SMARTIRC_TYPE_TOPICCHANGE;
  1985. } else if (preg_match('/^:.*? NICK .*$/', $line) == 1) {
  1986. return SMARTIRC_TYPE_NICKCHANGE;
  1987. } else if (preg_match('/^:.*? KICK .* .*$/', $line) == 1) {
  1988. return SMARTIRC_TYPE_KICK;
  1989. } else if (preg_match('/^:.*? PART .*$/', $line) == 1) {
  1990. return SMARTIRC_TYPE_PART;
  1991. } else if (preg_match('/^:.*? MODE .* .*$/', $line) == 1) {
  1992. return SMARTIRC_TYPE_MODECHANGE;
  1993. } else if (preg_match('/^:.*? QUIT :.*$/', $line) == 1) {
  1994. return SMARTIRC_TYPE_QUIT;
  1995. } else {
  1996. $this->log(SMARTIRC_DEBUG_MESSAGETYPES, 'DEBUG_MESSAGETYPES: SMARTIRC_TYPE_UNKNOWN!: "'.$line.'"', __FILE__, __LINE__);
  1997. return SMARTIRC_TYPE_UNKNOWN;
  1998. }
  1999. }
  2000. /**
  2001. * updates the current connection state
  2002. *
  2003. * @return boolean
  2004. * @access private
  2005. */
  2006. function _updatestate()
  2007. {
  2008. if (is_resource($this->_socket)) {
  2009. $rtype = get_resource_type($this->_socket);
  2010. if (($this->_socket !== false) &&
  2011. ($rtype == 'socket' || $rtype == 'Socket' || $rtype == 'stream')) {
  2012. $this->_state = true;
  2013. return true;
  2014. }
  2015. } else {
  2016. $this->_state = false;
  2017. $this->_loggedin = false;
  2018. return false;
  2019. }
  2020. }
  2021. /**
  2022. * returns the current connection state
  2023. *
  2024. * @return integer SMARTIRC_STATE_CONNECTED or SMARTIRC_STATE_DISCONNECTED
  2025. * @access private
  2026. */
  2027. function _state()
  2028. {
  2029. $result = $this->_updatestate();
  2030. if ($result == true) {
  2031. return SMARTIRC_STATE_CONNECTED;
  2032. } else {
  2033. return SMARTIRC_STATE_DISCONNECTED;
  2034. }
  2035. }
  2036. /**
  2037. * tries to find a messagehandler for the received message ($ircdata) and calls it
  2038. *
  2039. * @param string $messagecode
  2040. * @param object $ircdata
  2041. * @return void
  2042. * @access private
  2043. */
  2044. function _handlemessage($messagecode, &$ircdata)
  2045. {
  2046. $found = false;
  2047. if (is_numeric($messagecode)) {
  2048. if (!array_key_exists($messagecode, $this->nreplycodes)) {
  2049. $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: ignoring unrecognized messagecode! "'.$messagecode.'"', __FILE__, __LINE__);
  2050. $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: this IRC server ('.$this->_address.') doesn\'t conform to the RFC 2812!', __FILE__, __LINE__);
  2051. return;
  2052. }
  2053. $methodname = 'event_'.strtolower($this->nreplycodes[$messagecode]);
  2054. $_methodname = '_'.$methodname;
  2055. $_codetype = 'by numeric';
  2056. } else if (is_string($messagecode)) { // its not numericcode so already a name/string
  2057. $methodname = 'event_'.strtolower($messagecode);
  2058. $_methodname = '_'.$methodname;
  2059. $_codetype = 'by string';
  2060. }
  2061. // if exists call internal method for the handling
  2062. if (@method_exists($this, $_methodname)) {
  2063. $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: calling internal method "'.get_class($this).'->'.$_methodname.'" ('.$_codetype.')', __FILE__, __LINE__);
  2064. $this->$_methodname($ircdata);
  2065. $found = true;
  2066. }
  2067. // if exist, call user defined method for the handling
  2068. if (@method_exists($this, $methodname)) {
  2069. $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: calling user defined method "'.get_class($this).'->'.$methodname.'" ('.$_codetype.')', __FILE__, __LINE__);
  2070. $this->$methodname($ircdata);
  2071. $found = true;
  2072. }
  2073. if ($found == false) {
  2074. $this->log(SMARTIRC_DEBUG_MESSAGEHANDLER, 'DEBUG_MESSAGEHANDLER: no method found for "'.$messagecode.'" ('.$methodname.')', __FILE__, __LINE__);
  2075. }
  2076. }
  2077. /**
  2078. * tries to find a actionhandler for the received message ($ircdata) and calls it
  2079. *
  2080. * @param object $ircdata
  2081. * @return void
  2082. * @access private
  2083. */
  2084. function _handleactionhandler(&$ircdata)
  2085. {
  2086. $handler = &$this->_actionhandler;
  2087. $handlercount = count($handler);
  2088. for ($i = 0; $i < $handlercount; $i++) {
  2089. $handlerobject = &$handler[$i];
  2090. if (substr($handlerobject->message, 0, 1) == '/') {
  2091. $regex = $handlerobject->message;
  2092. } else {
  2093. $regex = '/'.$handlerobject->message.'/';
  2094. }
  2095. if (($handlerobject->type & $ircdata->type) &&
  2096. (preg_match($regex, $ircdata->message) == 1)) {
  2097. $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: actionhandler match found for id: '.$i.' type: '.$ircdata->type.' message: "'.$ircdata->message.'" regex: "'.$regex.'"', __FILE__, __LINE__);
  2098. $methodobject = &$handlerobject->object;
  2099. $method = $handlerobject->method;
  2100. if (@method_exists($methodobject, $method)) {
  2101. $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: calling method "'.get_class($methodobject).'->'.$method.'"', __FILE__, __LINE__);
  2102. $methodobject->$method($this, $ircdata);
  2103. } else {
  2104. $this->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: method doesn\'t exist! "'.get_class($methodobject).'->'.$method.'"', __FILE__, __LINE__);
  2105. }
  2106. }
  2107. }
  2108. }
  2109. /**
  2110. * Delay reconnect
  2111. *
  2112. * @return void
  2113. * @access private
  2114. */
  2115. function _delayReconnect()
  2116. {
  2117. if ($this->_reconnectdelay > 0) {
  2118. $this->log(SMARTIRC_DEBUG_CONNECTION, 'DEBUG_CONNECTION: delaying reconnect for '.$this->_reconnectdelay.' ms', __FILE__, __LINE__);
  2119. usleep($this->_reconnectdelay * 1000);
  2120. }
  2121. }
  2122. /**
  2123. * getting current microtime, needed for benchmarks
  2124. *
  2125. * @return float
  2126. * @access private
  2127. */
  2128. function _microint()
  2129. {
  2130. $tmp = microtime();
  2131. $parts = explode(' ', $tmp);
  2132. $floattime = (float)$parts[0] + (float)$parts[1];
  2133. return $floattime;
  2134. }
  2135. /**
  2136. * adds an user to the channelobject or updates his info
  2137. *
  2138. * @param object $channel
  2139. * @param object $newuser
  2140. * @return void
  2141. * @access private
  2142. */
  2143. function _adduser(&$channel, &$newuser)
  2144. {
  2145. $lowerednick = strtolower($newuser->nick);
  2146. if ($this->isJoined($channel->name, $newuser->nick)) {
  2147. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: updating user: '.$newuser->nick.' on channel: '.$channel->name, __FILE__, __LINE__);
  2148. // lets update the existing user
  2149. $currentuser = &$channel->users[$lowerednick];
  2150. if ($newuser->ident !== null) {
  2151. $currentuser->ident = $newuser->ident;
  2152. }
  2153. if ($newuser->host !== null) {
  2154. $currentuser->host = $newuser->host;
  2155. }
  2156. if ($newuser->realname !== null) {
  2157. $currentuser->realname = $newuser->realname;
  2158. }
  2159. if ($newuser->op !== null) {
  2160. $currentuser->op = $newuser->op;
  2161. }
  2162. if ($newuser->voice !== null) {
  2163. $currentuser->voice = $newuser->voice;
  2164. }
  2165. if ($newuser->ircop !== null) {
  2166. $currentuser->ircop = $newuser->ircop;
  2167. }
  2168. if ($newuser->away !== null) {
  2169. $currentuser->away = $newuser->away;
  2170. }
  2171. if ($newuser->server !== null) {
  2172. $currentuser->server = $newuser->server;
  2173. }
  2174. if ($newuser->hopcount !== null) {
  2175. $currentuser->hopcount = $newuser->hopcount;
  2176. }
  2177. } else {
  2178. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding user: '.$newuser->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
  2179. // he is new just add the reference to him
  2180. $channel->users[$lowerednick] = &$newuser;
  2181. }
  2182. $user = &$channel->users[$lowerednick];
  2183. if ($user->op) {
  2184. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding op: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
  2185. $channel->ops[$user->nick] = true;
  2186. }
  2187. if ($user->voice) {
  2188. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: adding voice: '.$user->nick.' to channel: '.$channel->name, __FILE__, __LINE__);
  2189. $channel->voices[$user->nick] = true;
  2190. }
  2191. }
  2192. /**
  2193. * removes an user from one channel or all if he quits
  2194. *
  2195. * @param object $ircdata
  2196. * @return void
  2197. * @access private
  2198. */
  2199. function _removeuser(&$ircdata)
  2200. {
  2201. if ($ircdata->type & (SMARTIRC_TYPE_PART|SMARTIRC_TYPE_QUIT)) {
  2202. $nick = $ircdata->nick;
  2203. } else if ($ircdata->type & SMARTIRC_TYPE_KICK) {
  2204. $nick = $ircdata->rawmessageex[3];
  2205. } else {
  2206. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: unknown TYPE ('.$ircdata->type.') in _removeuser(), trying default', __FILE__, __LINE__);
  2207. $nick = $ircdata->nick;
  2208. }
  2209. $lowerednick = strtolower($nick);
  2210. if ($this->_nick == $nick) {
  2211. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: we left channel: '.$ircdata->channel.' destroying...', __FILE__, __LINE__);
  2212. unset($this->_channels[strtolower($ircdata->channel)]);
  2213. } else {
  2214. if ($ircdata->type & SMARTIRC_TYPE_QUIT) {
  2215. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: user '.$nick.' quit, removing him from all channels', __FILE__, __LINE__);
  2216. // remove the user from all channels
  2217. $channelkeys = array_keys($this->_channels);
  2218. foreach ($channelkeys as $channelkey) {
  2219. // loop through all channels
  2220. $channel = &$this->_channels[$channelkey];
  2221. foreach ($channel->users as $uservalue) {
  2222. // loop through all user in this channel
  2223. if ($nick == $uservalue->nick) {
  2224. // found him
  2225. // kill him
  2226. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: found him on channel: '.$channel->name.' destroying...', __FILE__, __LINE__);
  2227. unset($channel->users[$lowerednick]);
  2228. if (isset($channel->ops[$nick])) {
  2229. // die!
  2230. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from op list', __FILE__, __LINE__);
  2231. unset($channel->ops[$nick]);
  2232. }
  2233. if (isset($channel->voices[$nick])) {
  2234. // die!!
  2235. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from voice list', __FILE__, __LINE__);
  2236. unset($channel->voices[$nick]);
  2237. }
  2238. // ups this was not DukeNukem 3D
  2239. }
  2240. }
  2241. }
  2242. } else {
  2243. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing user: '.$nick.' from channel: '.$ircdata->channel, __FILE__, __LINE__);
  2244. $channel = &$this->_channels[strtolower($ircdata->channel)];
  2245. unset($channel->users[$lowerednick]);
  2246. if (isset($channel->ops[$nick])) {
  2247. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from op list', __FILE__, __LINE__);
  2248. unset($channel->ops[$nick]);
  2249. }
  2250. if (isset($channel->voices[$nick])) {
  2251. $this->log(SMARTIRC_DEBUG_CHANNELSYNCING, 'DEBUG_CHANNELSYNCING: removing him from voice list', __FILE__, __LINE__);
  2252. unset($channel->voices[$nick]);
  2253. }
  2254. }
  2255. }
  2256. }
  2257. /**
  2258. * @return void
  2259. * @access private
  2260. */
  2261. function _checkPHPVersion()
  2262. {
  2263. // doing nothing at the moment
  2264. }
  2265. /**
  2266. * checks if the passed handlertype is valid
  2267. *
  2268. * @param integer $handlertype
  2269. * @return boolean
  2270. * @access private
  2271. */
  2272. function _isValidType($handlertype) {
  2273. if ($handlertype & SMARTIRC_TYPE_ALL) {
  2274. return true;
  2275. } else {
  2276. return false;
  2277. }
  2278. }
  2279. function _addIrcUser()
  2280. {
  2281. }
  2282. function _updateIrcUser()
  2283. {
  2284. }
  2285. function _removeIrcUser()
  2286. {
  2287. }
  2288. function _addChannelUser()
  2289. {
  2290. }
  2291. function _updateChannelUser()
  2292. {
  2293. }
  2294. function _removeChannelUser()
  2295. {
  2296. }
  2297. // </private methods>
  2298. function isError($object)
  2299. {
  2300. return (bool)(is_object($object) && (strtolower(get_class($object)) == 'net_smartirc_error'));
  2301. }
  2302. function &throwError($message)
  2303. {
  2304. $error = new Net_SmartIRC_Error($message);
  2305. return $error;
  2306. }
  2307. }
  2308. // includes must be after the base class definition, required for PHP5
  2309. require_once 'SmartIRC/irccommands.php';
  2310. require_once 'SmartIRC/messagehandler.php';
  2311. class Net_SmartIRC extends Net_SmartIRC_messagehandler
  2312. {
  2313. // empty
  2314. }
  2315. /**
  2316. * @access public
  2317. */
  2318. class Net_SmartIRC_data
  2319. {
  2320. /**
  2321. * @var string
  2322. * @access public
  2323. */
  2324. var $from;
  2325. /**
  2326. * @var string
  2327. * @access public
  2328. */
  2329. var $nick;
  2330. /**
  2331. * @var string
  2332. * @access public
  2333. */
  2334. var $ident;
  2335. /**
  2336. * @var string
  2337. * @access public
  2338. */
  2339. var $host;
  2340. /**
  2341. * @var string
  2342. * @access public
  2343. */
  2344. var $channel;
  2345. /**
  2346. * @var string
  2347. * @access public
  2348. */
  2349. var $message;
  2350. /**
  2351. * @var array
  2352. * @access public
  2353. */
  2354. var $messageex = array();
  2355. /**
  2356. * @var integer
  2357. * @access public
  2358. */
  2359. var $type;
  2360. /**
  2361. * @var string
  2362. * @access public
  2363. */
  2364. var $rawmessage;
  2365. /**
  2366. * @var array
  2367. * @access public
  2368. */
  2369. var $rawmessageex = array();
  2370. }
  2371. /**
  2372. * @access public
  2373. */
  2374. class Net_SmartIRC_actionhandler
  2375. {
  2376. /**
  2377. * @var integer
  2378. * @access public
  2379. */
  2380. var $id;
  2381. /**
  2382. * @var integer
  2383. * @access public
  2384. */
  2385. var $type;
  2386. /**
  2387. * @var string
  2388. * @access public
  2389. */
  2390. var $message;
  2391. /**
  2392. * @var object
  2393. * @access public
  2394. */
  2395. var $object;
  2396. /**
  2397. * @var string
  2398. * @access public
  2399. */
  2400. var $method;
  2401. }
  2402. /**
  2403. * @access public
  2404. */
  2405. class Net_SmartIRC_timehandler
  2406. {
  2407. /**
  2408. * @var integer
  2409. * @access public
  2410. */
  2411. var $id;
  2412. /**
  2413. * @var integer
  2414. * @access public
  2415. */
  2416. var $interval;
  2417. /**
  2418. * @var integer
  2419. * @access public
  2420. */
  2421. var $lastmicrotimestamp;
  2422. /**
  2423. * @var object
  2424. * @access public
  2425. */
  2426. var $object;
  2427. /**
  2428. * @var string
  2429. * @access public
  2430. */
  2431. var $method;
  2432. }
  2433. /**
  2434. * @access public
  2435. */
  2436. class Net_SmartIRC_channel
  2437. {
  2438. /**
  2439. * @var string
  2440. * @access public
  2441. */
  2442. var $name;
  2443. /**
  2444. * @var string
  2445. * @access public
  2446. */
  2447. var $key;
  2448. /**
  2449. * @var array
  2450. * @access public
  2451. */
  2452. var $users = array();
  2453. /**
  2454. * @var array
  2455. * @access public
  2456. */
  2457. var $ops = array();
  2458. /**
  2459. * @var array
  2460. * @access public
  2461. */
  2462. var $voices = array();
  2463. /**
  2464. * @var array
  2465. * @access public
  2466. */
  2467. var $bans = array();
  2468. /**
  2469. * @var string
  2470. * @access public
  2471. */
  2472. var $topic;
  2473. /**
  2474. * @var string
  2475. * @access public
  2476. */
  2477. var $user_limit = false;
  2478. /**
  2479. * @var string
  2480. * @access public
  2481. */
  2482. var $mode;
  2483. /**
  2484. * @var integer
  2485. * @access public
  2486. */
  2487. var $synctime_start = 0;
  2488. /**
  2489. * @var integer
  2490. * @access public
  2491. */
  2492. var $synctime_stop = 0;
  2493. /**
  2494. * @var integer
  2495. * @access public
  2496. */
  2497. var $synctime;
  2498. }
  2499. /**
  2500. * @access public
  2501. */
  2502. class Net_SmartIRC_user
  2503. {
  2504. /**
  2505. * @var string
  2506. * @access public
  2507. */
  2508. var $nick;
  2509. /**
  2510. * @var string
  2511. * @access public
  2512. */
  2513. var $ident;
  2514. /**
  2515. * @var string
  2516. * @access public
  2517. */
  2518. var $host;
  2519. /**
  2520. * @var string
  2521. * @access public
  2522. */
  2523. var $realname;
  2524. /**
  2525. * @var boolean
  2526. * @access public
  2527. */
  2528. var $ircop;
  2529. /**
  2530. * @var boolean
  2531. * @access public
  2532. */
  2533. var $away;
  2534. /**
  2535. * @var string
  2536. * @access public
  2537. */
  2538. var $server;
  2539. /**
  2540. * @var integer
  2541. * @access public
  2542. */
  2543. var $hopcount;
  2544. }
  2545. /**
  2546. * @access public
  2547. */
  2548. class Net_SmartIRC_channeluser extends Net_SmartIRC_user
  2549. {
  2550. /**
  2551. * @var boolean
  2552. * @access public
  2553. */
  2554. var $op;
  2555. /**
  2556. * @var boolean
  2557. * @access public
  2558. */
  2559. var $voice;
  2560. }
  2561. /**
  2562. * @access public
  2563. */
  2564. class Net_SmartIRC_ircuser extends Net_SmartIRC_user
  2565. {
  2566. /**
  2567. * @var array
  2568. * @access public
  2569. */
  2570. var $joinedchannels = array();
  2571. }
  2572. /**
  2573. * @access public
  2574. */
  2575. class Net_SmartIRC_listenfor
  2576. {
  2577. /**
  2578. * @var array
  2579. * @access public
  2580. */
  2581. var $result = array();
  2582. /**
  2583. * stores the received answer into the result array
  2584. *
  2585. * @param object $irc
  2586. * @param object $ircdata
  2587. * @return void
  2588. */
  2589. function handler(&$irc, &$ircdata)
  2590. {
  2591. $irc->log(SMARTIRC_DEBUG_ACTIONHANDLER, 'DEBUG_ACTIONHANDLER: listenfor handler called', __FILE__, __LINE__);
  2592. $this->result[] = $ircdata;
  2593. $irc->disconnect(true);
  2594. }
  2595. }
  2596. class Net_SmartIRC_Error
  2597. {
  2598. var $error_msg;
  2599. function Net_SmartIRC_Error($message)
  2600. {
  2601. $this->error_msg = $message;
  2602. }
  2603. function getMessage()
  2604. {
  2605. return $this->error_msg;
  2606. }
  2607. }
  2608. ?>