· 9 years ago · Dec 18, 2016, 11:42 AM
1#!/usr/bin/perl
2
3# +---------------------------------------------------------------------------+
4# ! MEDIABOT (Net::IRC bot) !
5# +---------------------------------------------------------------------------+
6
7# +---------------------------------------------------------------------------+
8# ! MODULES !
9# +---------------------------------------------------------------------------+
10
11use strict;
12use warnings;
13use diagnostics;
14use POSIX 'setsid';
15
16use File::Basename;
17use Date::Language;
18use Date::Format;
19use Date::Manip;
20use Date::Parse;
21use Net::IRC;
22use String::IRC;
23use Data::Dumper;
24use Time::HiRes qw( usleep );
25use Getopt::Long;
26use Config::Simple;
27use IO::Socket::INET;
28use Net::Server::NonBlocking;
29use WordList::Phrase::FR::Proverb::Wikiquote;
30
31use DBI;
32
33# +---------------------------------------------------------------------------+
34# ! SETTINGS !
35# +---------------------------------------------------------------------------+
36
37# Main Settings
38my %Config;
39my $MAIN_PROG_NAME = "Mediabot";
40my $MAIN_PROG_ACCOUNTDIR = "/home/mediabot";
41my $MAIN_PROG_ACCOUNT = "mediabot";
42my $MAIN_PROG_HOMEDIR = "$MAIN_PROG_ACCOUNTDIR";
43my $MAIN_PROG_NAME_LOWER = "mediabot";
44my $CONFIG_FILE = undef;
45my $MAIN_PROG_BIRTHDATE = 1168152430;
46my $MAIN_PROG_VERSION = '1.4i';
47my $MAIN_PROG_VERSION_LIVR = $MAIN_PROG_VERSION;
48my $MAIN_PROG_URL = 'https://teuk.org/mediabot';
49my $MAIN_PROG_DIR="$MAIN_PROG_HOMEDIR";
50my $MAIN_PROG_LOG_DIR="$MAIN_PROG_DIR/log";
51my $MAIN_PROG_BIN_DIR="$MAIN_PROG_DIR/bin";
52my $MAIN_PROG_VAR_DIR="$MAIN_PROG_DIR/var";
53my $MAIN_PROG_INCOMING_DIR="$MAIN_PROG_DIR/incoming";
54my $MAIN_LOG_FILE = "$MAIN_PROG_LOG_DIR/$MAIN_PROG_NAME_LOWER.log";
55my $MAIN_PID_FILE = "$MAIN_PROG_VAR_DIR/run/$MAIN_PROG_NAME_LOWER.pid";
56my $MAIN_PROG_DAEMON_START = "$MAIN_PROG_BIN_DIR/$MAIN_PROG_NAME_LOWER.sh";
57my $MAIN_PROG_DAEMON = 0;
58my $PARTYLINE_TCP_PORT = undef;
59my $MAIN_PROG_DEBUG = $ENV{'MEDIABOT_DEBUG'} || 3;
60
61# MySQL Default Settings
62my $MAIN_PROG_DDBNAME = "mediabot";
63my $MAIN_PROG_DBUSER = "mediabot";
64my $MAIN_PROG_DBPASS = "******";
65my $MAIN_PROG_DBHOST = "localhost";
66my $MAIN_PROG_DBPORT = "3306";
67
68# +---------------------------------------------------------------------------+
69# ! CONSTANT !
70# +---------------------------------------------------------------------------+
71
72# Connection default settings
73my $CONN_SERVER_NETWORK= undef;
74my $CONN_SERVER = undef;
75my $CONN_NICK = undef;
76my $CONN_NICK_ALTERNATE = undef;
77my $CONN_IRCNAME = undef;
78my $CONN_USERNAME = undef;
79my $CONN_DEFAULT_CHANNEL = undef;
80my $CONN_DEFAULT_CHANNEL_KEY = undef;
81my $CONN_USERMODE = undef;
82my $CONN_MAX_RETRY = 3;
83my $CONN_RETRY = 0;
84
85# Undernet default settings
86my $UNET_CSERVICE_LOGIN = "x\@services.radiocapsule.com";
87my $UNET_CSERVICE_USERNAME = "mediacaps";
88my $UNET_CSERVICE_PASSWORD = "******";
89my $UNET_CSERVICE_LOGIN_SLEEP = 3;
90
91# Misc Settings
92my $LEVEL_OWNER = 0;
93my $LEVEL_MASTER = 1;
94my $LEVEL_ADMINISTRATOR = 2;
95my $LEVEL_USER = 3;
96
97# Channel levels
98#500: part
99#450: join set+*
100#400: adduser clearmode* modinfo+ remuser
101#100: op deop invite suspend unsuspend
102# 75: ban* unban*
103# 50: kick+ topic
104# 25: voice devoice
105# 1: banlist status+
106# 0: access chaninfo info help* lbanlist login motd* newpass showcommands showignore verify suspendme
107
108my $DB_AUTORECONNECT_DELAY = 120;
109
110# +---------------------------------------------------------------------------+
111# ! PLUGINS VARS !
112# +---------------------------------------------------------------------------+
113# Scrabble
114my $SCRABBLE_PICK_LEN = 10;
115my $SCRABBLE_PICK_DELAY = 50;
116
117# Main chan settings
118my $RADIO_CHANNEL="#quebec";
119my $RADIO_CHANNEL_SONG_DELAY = 10800;
120my $RADIO_CHANNEL_WIKIQUOTE_DELAY = 25200;
121my $RADIO_CHANNEL_BOTQUOTE_DELAY = 25020;
122
123# +---------------------------------------------------------------------------+
124# ! GLOBAL VARS !
125# +---------------------------------------------------------------------------+
126my $partyLineServer = undef;
127my $iConnectionTimestamp = 0;
128my %hPublicMessagesCount;
129my $iPublicMessagesTriggerCount = 5; # TBD : random message every $iPublicMessagesTriggerCount on $RADIO_CHANNEL
130my $aperal = 0;
131my $aperalStartTime = 0;
132my $sLastNickPing = "";
133my $aperalStartedBy = "";
134my $lastScrabblePick = "";
135my $lastScrabbleLen = 0;
136my $scrabbleStatus = 0;
137my $scrabbleChannel = "";
138my $scrabbleTimestamp = 0;
139my $scrabbleSolution = "";
140my $scrabbleSolutionLen = 0;
141my %scrabbleScores = ();
142my $scrabbleIsWon = 0;
143my $yes_or_no = 0;
144my $sCurrentDjNick = undef;
145
146# +---------------------------------------------------------------------------+
147# ! SUBS DECLARATION !
148# +---------------------------------------------------------------------------+
149
150# +---------------------------------------------------------------------------+
151# ! BOT FUNCTIONS !
152# +---------------------------------------------------------------------------+
153
154# Core functions
155sub usage(@);
156sub readConfigFile(@);
157sub init_log(@);
158sub init_pid(@);
159sub log_message(@);
160sub noticeConsoleChan(@);
161sub clean_and_exit(@);
162sub catch_hup(@);
163sub catch_term(@);
164sub startPartyline(@);
165sub partylineClientConnected(@);
166sub partylineClientDisconnected(@);
167sub partylineClientMessage(@);
168#sub checkPartyLineConnections(@);
169
170# Core IRC Functions
171sub botSQLCommand(@);
172sub botPublicCall(@);
173sub botPrivmsg(@);
174sub botAction(@);
175sub botNotice(@);
176sub botBirthDate(@);
177sub botDieRequest(@);
178sub botRestartRequest(@);
179sub botPingNick(@);
180sub botPublicHelp(@);
181sub botPublicVersion(@);
182sub botChannelSetTopic(@);
183sub botChannelKickUser(@);
184sub botServerLoad(@);
185sub botInsulteChan(@);
186sub botAddInsulte(@);
187sub botAddIvan(@);
188sub botDowjaune(@);
189sub botRandomAnswer(@);
190sub botGetAnswer(@);
191sub botSetPass(@);
192sub botSetNewPass(@);
193sub botAddUser(@);
194sub botOpChanNick(@);
195sub botDeopChanNick(@);
196sub botVoiceChanNick(@);
197sub botDevoiceChanNick(@);
198sub botStatTables(@);
199sub botSayChannel(@);
200sub botActChannel(@);
201sub botDisplayYoutubeUrl(@);
202sub botSeen(@);
203sub botQuote(@);
204sub botChannelPart(@);
205sub botChannelJoin(@);
206sub botChannelSQL(@);
207sub botCheckHosts(@);
208sub botChannelModinfo(@);
209sub botSyntaxChannelModinfo(@);
210sub botChannelUserAccess(@);
211
212# +---------------------------------------------------------------------------+
213# ! DB FUNCTIONS !
214# +---------------------------------------------------------------------------+
215sub dbConnect(@);
216sub dbCheckHandle(@);
217sub checkdbConnection(@);
218sub dbAutoLogout(@);
219sub dbCheckTables(@);
220sub dbLogoutUsers(@);
221sub dbCleanActionsQueue(@);
222sub dbProcessActionsQueue(@);
223sub logbBotAction(@);
224sub logBot(@);
225sub logEvent(@);
226sub getIdChannel(@);
227sub getUserChannelLevel(@);
228sub getUserChannelLevelByName(@);
229
230# +---------------------------------------------------------------------------+
231# ! IRC FUNCTIONS !
232# +---------------------------------------------------------------------------+
233sub getNickInfo(@);
234sub getEventHostmask(@);
235sub userWhoAmI(@);
236
237# SCRABBLE
238sub scrabbleStart(@);
239sub scrabbleStop(@);
240sub scrabbleEnd(@);
241sub scrabbleFind(@);
242sub scrabbleSaveScores(@);
243sub scrabbleScoresDisplay(@);
244
245# Misc PLugin functions (TBD : external .pl)
246sub getTLD(@);
247sub getDepartement(@);
248sub botColuche(@);
249sub botIvan(@);
250sub botRadioTease(@);
251sub Carambar(@);
252sub chanWordStat(@);
253sub botFriendGuess(@);
254sub getUrltitle(@);
255sub botHttpResponseCode(@);
256sub botWikiquote(@);
257
258# Stream Radio functions
259sub getStreamStatus(@);
260sub getRadioCapsuleSong(@);
261sub getRadioCapsuleListeners(@);
262sub getRadioUrl(@);
263sub radioNext(@);
264sub radioNextYoutubeToPLay(@);
265sub radioSetDj(@);
266sub radioSetPlaylist(@);
267sub playYoutube(@);
268
269# +---------------------------------------------------------------------------+
270# ! MAIN !
271# +---------------------------------------------------------------------------+
272
273# Check command line parameters
274my $result = GetOptions (
275 "conf=s" => \$CONFIG_FILE,
276 "daemon" => \$MAIN_PROG_DAEMON,
277);
278
279unless (defined($CONFIG_FILE)) {
280 usage("You must specify a config file");
281}
282
283# Starts LOG MARK in foreground
284unless ( $MAIN_PROG_DAEMON ) {
285 print STDERR "+--------------------------------------------------------------------------------------------------+\n";
286}
287
288# Try to read $CONFIG_FILE
289readConfigFile($CONFIG_FILE);
290
291# Adjust Global variable (TBD => conf)
292my $EVENT_CTCP_VERSION_REPLY = "$MAIN_PROG_NAME v$MAIN_PROG_VERSION, $MAIN_PROG_URL";
293my $CONN_DEFAULT_QUIT_MSG = $EVENT_CTCP_VERSION_REPLY;
294$MAIN_PROG_HOMEDIR = "$MAIN_PROG_ACCOUNTDIR";
295$MAIN_PROG_DIR="$MAIN_PROG_HOMEDIR";
296$MAIN_PROG_LOG_DIR="$MAIN_PROG_DIR/log";
297$MAIN_PROG_BIN_DIR="$MAIN_PROG_DIR/bin";
298$MAIN_PROG_VAR_DIR="$MAIN_PROG_DIR/var";
299$MAIN_PROG_INCOMING_DIR="$MAIN_PROG_DIR/incoming";
300#$MAIN_LOG_FILE = "$MAIN_PROG_LOG_DIR/$MAIN_PROG_NAME_LOWER.log";
301$MAIN_PID_FILE = "$MAIN_PROG_VAR_DIR/run/$MAIN_PROG_NAME_LOWER.pid";
302$MAIN_PROG_DAEMON_START = "$MAIN_PROG_BIN_DIR/$MAIN_PROG_NAME_LOWER.sh";
303
304# Init main log
305init_log($MAIN_LOG_FILE);
306
307# Daemon mode actions
308if ( $MAIN_PROG_DAEMON != 0 ) {
309
310 log_message(1,"Starting in daemon mode");
311 log_message(1,"Daemon mode actions starting");
312
313 chdir '/' or die "Can't chdir to /: $!";
314 umask 0;
315 open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
316 open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
317 open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";
318 defined(my $pid = fork) or die "Can't fork: $!";
319 exit if $pid;
320 setsid or die "Can't start a new session: $!";
321}
322
323# Init pid file
324init_pid(undef,$MAIN_PID_FILE);
325
326# Establish a MySQL connection
327my $dbh = dbConnect($MAIN_PROG_DDBNAME,$MAIN_PROG_DBHOST,$MAIN_PROG_DBPORT,$MAIN_PROG_DBUSER,$MAIN_PROG_DBPASS);
328
329# Check USER table and fail if not present
330dbCheckTables();
331
332# Log out all user at start
333dbLogoutUsers();
334
335# Main starts to log
336log_message(0,'----------------------------------------------------------------------------------');
337log_message(0,"$MAIN_PROG_NAME v$MAIN_PROG_VERSION Starting (pid : $$)");
338
339# Pick a server in db default on $CONN_SERVER_NETWORK
340my $sServerQuery = "SELECT SERVERS.server_hostname FROM NETWORK,SERVERS WHERE NETWORK.id_network=SERVERS.id_network AND NETWORK.network_name like ? ORDER BY RAND() LIMIT 1";
341
342dbCheckHandle($dbh);
343my $sth = $dbh->prepare($sServerQuery);
344unless ($sth->execute($CONN_SERVER_NETWORK)) {
345 log_message(0,"Startup select SERVER, SQL Error : " . $DBI::errstr . " Query : " . $sServerQuery);
346}
347else {
348 if (my $ref = $sth->fetchrow_hashref()) {
349 $CONN_SERVER = $ref->{'server_hostname'};
350 }
351}
352
353# Create a Net::IRC object
354log_message(1,"Creating IRC Instance");
355my $irc = new Net::IRC;
356
357unless (defined($CONN_SERVER) && ($CONN_SERVER ne "")) {
358 log_message(0,"CONN_SERVER is undefined. Check NETWORK AND SERVERS tables.");
359 clean_and_exit(undef,300);
360}
361
362unless (defined($CONN_NICK) && ($CONN_NICK ne "")) {
363 log_message(0,"CONN_NICK is undefined. Check $CONFIG_FILE");
364 clean_and_exit(undef,301);
365}
366
367unless (defined($CONN_NICK_ALTERNATE) && ($CONN_NICK_ALTERNATE ne "")) {
368 log_message(0,"CONN_NICK_ALTERNATE is undefined. Check $CONFIG_FILE");
369 clean_and_exit(undef,302);
370}
371
372unless (defined($CONN_IRCNAME) && ($CONN_IRCNAME ne "")) {
373 log_message(0,"CONN_IRCNAME is undefined. Check $CONFIG_FILE");
374 clean_and_exit(undef,303);
375}
376
377unless (defined($CONN_USERNAME) && ($CONN_USERNAME ne "")) {
378 log_message(0,"CONN_USERNAME is undefined. Check $CONFIG_FILE");
379 clean_and_exit(undef,303);
380}
381
382# Setup a newconn on previous object
383log_message(1,"Creating IRC::Connection Instance for server $CONN_SERVER on $CONN_SERVER_NETWORK");
384my $conn = $irc->newconn(
385 'Server' => $CONN_SERVER,
386 'Port' => 6667,
387 'Nick' => $CONN_NICK,
388 'Ircname' => $CONN_IRCNAME,
389 'Username' => $CONN_USERNAME
390);
391
392log_message(6,"\$conn Initialization: " . Dumper($conn));
393
394log_message(1,"Checking IRC Connection");
395if (defined($conn) && $conn) {
396 log_message(0,"Connected to server : " . $conn->server);
397 # +---------------------------------------------------------------------------+
398 # ! EVENTS HANDLERS !
399 # +---------------------------------------------------------------------------+
400 log_message(1,"Installing event handlers");
401 $conn->add_default_handler(\&on_unmatched_event);
402 $conn->add_handler('welcome', \&on_init); # Welcome
403 $conn->add_handler('yourhost', \&on_init); # yourhost
404 $conn->add_handler('created', \&on_init); # created
405 $conn->add_handler('myinfo', \&on_init); # myinfo
406 $conn->add_handler('map', \&on_init); # map
407 $conn->add_handler('luserclient', \&on_init); # lusers
408 $conn->add_handler('luserop', \&on_init); # luserop
409 $conn->add_handler('luserchannels', \&on_init); # luserchannels
410 $conn->add_handler('luserme', \&on_init); # luserme
411 $conn->add_handler('motdstart', \&on_init); # motdstart
412 $conn->add_handler('motd', \&on_init); # motdstart
413 $conn->add_handler('nomotd', \&on_nomotd); # Fin du MOTD => on est connecte
414 $conn->add_handler('endofmotd', \&on_connect); # Fin du MOTD => on est connecte
415 $conn->add_handler('public', \&on_public); # Sur le chan
416 $conn->add_handler('notice', \&on_notice); # En notice
417 $conn->add_handler('msg', \&on_private); # En prive
418 $conn->add_handler('caction', \&on_caction); # /me
419 $conn->add_handler('cversion', \&on_cversion); # Demande de version
420 $conn->add_handler('cping', \&on_cping); # Demande de PING
421 $conn->add_handler('crping', \&on_ping_reply); # Reponse au PING
422 $conn->add_handler('ctime', \&on_ctime); # Demande de time
423 $conn->add_handler('join', \&on_join); # Join
424 $conn->add_handler('part', \&on_part); # Part
425 $conn->add_handler('umode', \&on_umode); # User Modes
426 $conn->add_handler('mode', \&on_mode); # Modes
427 $conn->add_handler('topic', \&on_topic); # Topic
428 $conn->add_handler('notopic', \&on_topic); # No topic
429 $conn->add_handler('topicinfo', \&on_topicinfo); # Topic info
430 $conn->add_handler('nosuchnick', \&on_nosuchnick); # No such nick
431 $conn->add_handler('namreply', \&on_namreply); # Names reply
432 $conn->add_handler('endofnames', \&on_endofnames); # Names reply
433 $conn->add_handler('nicknameinuse', \&on_nick_taken); # Nick taken
434 $conn->add_handler('cdcc', \&on_dcc);
435 $conn->add_handler('endofwho', \&on_endofwho);
436 $conn->add_handler('quit', \&on_quit);
437 $conn->add_handler('kick', \&on_kick);
438
439 $conn->add_global_handler([ 251,252,253,254,302,255 ], \&on_init); # Server connnection notice
440 $conn->add_global_handler('disconnect', \&on_disconnect); # Disconnect
441
442 $SIG{HUP} = \&catch_hup; # best strategy
443 $SIG{TERM} = \&catch_term; # best strategy
444 # Starting main IRC loop
445 log_message(0,"Starting main IRC loop");
446 log_message(6,"\$conn before IRC loop: " . Dumper($conn));
447 #$partyLineServer = startPartyline($conn);
448 $irc->start();
449
450}
451else {
452 # IRC Connection failed
453 log_message(0,"Sorry I cannot connect to IRC Server : $CONN_SERVER");
454 log_message(0,"Exiting");
455 clean_and_exit(undef,101);
456}
457
458# +---------------------------------------------------------------------------+
459# ! EVENTS !
460# +---------------------------------------------------------------------------+
461sub on_endofwho {
462 my ($conn, $event) = @_;
463 log_message(0,"on_endofwho");
464 log_message(5,"on_endofwho: " . Dumper($event));
465 log_message(6,"on_endofwho: " . Dumper($conn));
466}
467
468sub on_dcc {
469 my ($conn, $event) = @_;
470 my $sArgs = ($event->args)[0];
471 my @args = split(/\s+/,$sArgs);
472 if (defined($args[0])) {
473 if ($args[0] eq 'SEND') {
474 #my $sIncomingFile = "$MAIN_PROG_INCOMING_DIR/incoming" . time;
475 #open INCOMING, ">$sIncomingFile"
476 #or do { warn "Could not open file for writing: $!"; return; };
477 #$conn->new_get($event, \*INCOMING);
478 #($nick, $name, $address, $port, $size, $handle) = @_;
479 #$conn->new_get($event->nick, $args[1], $args[2], $args[3], $args[4], \*INCOMING);
480 my $sNoticeMsg = getEventHostmask($event) . " Incoming DCC SEND : " . join(" ",@args);
481 log_message(0,$sNoticeMsg);
482 noticeConsoleChan($conn,0,$sNoticeMsg);
483 }
484 elsif($args[0] eq 'CHAT') {
485 my $sNoticeMsg = getEventHostmask($event) . " Incoming DCC CHAT : " . join(" ",@args);
486 log_message(0,$sNoticeMsg);
487 noticeConsoleChan($conn,0,$sNoticeMsg);
488 #$conn->new_chat($event);
489 }
490 else {
491 log_message(0,"Unknown DCC type: " . $args[0]);
492 my $sNoticeMsg = getEventHostmask($event) . " Unknown DCC type: " . $args[0];
493 noticeConsoleChan($conn,0,$sNoticeMsg);
494 }
495 }
496 else {
497 log_message(0,"DCC type is undefined");
498 my $sNoticeMsg = getEventHostmask($event) . " DCC type is undefined";
499 noticeConsoleChan($conn,0,$sNoticeMsg);
500 }
501}
502
503sub on_init {
504 my ($conn, $event) = @_;
505 my (@args) = ($event->args);
506 shift (@args);
507 #log_message(0,"[" . event->type() . " ] -" . $event->nick() . "- @args");
508 log_message(0,"on_init() " . $event->type() . " -" . $event->nick() . "- @args");
509 log_message(5,"on_init \$event : " . Dumper($event));
510}
511
512# Change our nick if someone stole it.
513sub on_nick_taken {
514 my ($conn) = shift;
515 log_message(0,"$CONN_NICK Nickname is already in use.");
516 log_message(0,"Trying to use $CONN_NICK_ALTERNATE ...");
517 $conn->nick($CONN_NICK_ALTERNATE);
518}
519
520sub on_endofnames {
521 my ($conn, $event) = @_;
522 my (undef, $channel, @list) = ($event->args);
523 #($channel, @list) = splice @list, 2;
524
525 log_message(0,"$channel: @list");
526 log_message(5,"on_endofnames \$event : " . Dumper($event));
527}
528
529sub on_namreply {
530 my ($conn, $event) = @_;
531 my (@args) = ($event->args);
532
533 my (@list, $channel) = ($event->args);
534 ($channel, @list) = splice @list, 2;
535
536 log_message(0,"$channel: Users on this channel are @list");
537
538 log_message(5,"on_namreply \$event : " . Dumper($event));
539}
540
541sub on_nosuchnick {
542 my ($conn, $event) = @_;
543 my (@args) = ($event->args);
544 shift (@args);
545 log_message(0,"-" . $event->nick() . "- @args");
546 log_message(5,"on_nosuchnick \$event : " . Dumper($event));
547}
548
549sub on_connect {
550 my ($conn, $event) = @_;
551 if (!defined($conn->{'connected'}) || (int($conn->{'connected'}) != 1)) {
552 $conn->{'connected'} = 1;
553 $iConnectionTimestamp = time;
554
555 # Schedule init_pid in 1 second on connect
556 log_message(0,"on_connect() Scheduling init_pid($$): 1s ($MAIN_PID_FILE)");
557 $conn->schedule(1, \&init_pid, $MAIN_PID_FILE);
558
559 # Schedule dbAutoLogout in 300 seconds on connect
560 log_message(0,"on_connect() Scheduling dbAutoLogout: 300s");
561 $conn->schedule(300, \&dbAutoLogout);
562
563 # Schedule checkdbConnection in 120 seconds on connect
564 log_message(0,"on_connect() Scheduling checkdbConnection: 120s");
565 $conn->schedule(120, \&checkdbConnection);
566
567 # Schedule checkPartyLineConnections in 1 second on connect
568 #log_message(0,"Scheduling checkPartyLineConnections: 1s");
569 #$conn->schedule(1, \&checkPartyLineConnections);
570
571 # Authentication to channel service if credentials are defined
572 if (defined($UNET_CSERVICE_LOGIN) && defined($UNET_CSERVICE_USERNAME) && defined($UNET_CSERVICE_PASSWORD)) {
573 log_message(0,"on_connect() Logging to $UNET_CSERVICE_LOGIN");
574 botPrivmsg($conn,$event,"$UNET_CSERVICE_LOGIN","login $UNET_CSERVICE_USERNAME $UNET_CSERVICE_PASSWORD");
575 }
576
577 # Set user modes
578 if (defined($CONN_USERMODE)) {
579 log_message(0,"on_connect() Setting user mode " . $CONN_USERMODE);
580 $conn->mode($conn->nick(), $CONN_USERMODE);
581 }
582
583 if (defined($CONN_DEFAULT_CHANNEL) && ( $CONN_DEFAULT_CHANNEL ne "" )) {
584 # Waiting a bit before joining main channel (usefull for +x TBD wait for correct RAW 396 if needed)
585 if (defined($UNET_CSERVICE_LOGIN_SLEEP)) {
586 log_message(0,"on_connect() Sleeping $UNET_CSERVICE_LOGIN_SLEEP seconds before joining $CONN_DEFAULT_CHANNEL");
587 sleep $UNET_CSERVICE_LOGIN_SLEEP;
588 }
589
590 # Join main channel (TBD : replace it with console channnel that MUST be present in $MAIN_PROG_DDBNAME db table CHANNEL
591 $conn->join($CONN_DEFAULT_CHANNEL . " " . $CONN_DEFAULT_CHANNEL_KEY);
592 log_message(0,"on_connect() $CONN_DEFAULT_CHANNEL: * Joining channel $CONN_DEFAULT_CHANNEL");
593 }
594 else {
595 log_message(0,"on_connect() CONN_DEFAULT_CHANNEL is undefined cannot join. see $CONFIG_FILE");
596 }
597
598 # Auto-join CHANNEL listed in $MAIN_PROG_DDBNAME db table CHANNEL
599 my $sCheckQuery = "SELECT * FROM CHANNEL WHERE auto_join=1";
600 dbCheckHandle($dbh);
601 my $sth = $dbh->prepare($sCheckQuery);
602 unless ($sth->execute ) {
603 log_message(0,"on_connect() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
604 }
605 else {
606 my $iNbChan = 0;
607 while (my $ref = $sth->fetchrow_hashref()) {
608 my $sChanToJoin = $ref->{'name'};
609 my $sChanKey = $ref->{'key'};
610 if (defined($sChanToJoin) && !($sChanToJoin =~ /$CONN_DEFAULT_CHANNEL/)) {
611 log_message(0,"on_connect() Auto-joining " . $sChanToJoin);
612 if ( defined($sChanKey) && ($sChanKey ne "") ) {
613 log_message(1,"on_connect() Chan $sChanToJoin has a key : $sChanKey");
614 $conn->join($sChanToJoin . " " . $sChanKey);
615 }
616 else {
617 $conn->join($sChanToJoin);
618 }
619 }
620 $iNbChan++;
621 if (( $iNbChan % 2 ) == 0) {
622 my $iUsleepDelay = 500;
623 log_message(3,"on_connect() Sleeping $iUsleepDelay before joining next channel");
624 usleep $iUsleepDelay;
625 }
626 }
627
628 }
629 # DEBUG clean_and_exit($conn,200);
630 # Schedule getRadioCapsuleSong in 20 seconds on_connect TBD : channel must be set in $CONFIG_FILE
631 log_message(5,"on_connect() \$event " . Dumper($event));
632 log_message(0,"on_connect() schedule getRadioCapsuleSong on $RADIO_CHANNEL: 20s");
633 my $sNoticeMsg = getEventHostmask($event) . " schedule getRadioCapsuleSong on $RADIO_CHANNEL: 20s";
634 noticeConsoleChan($conn,0,$sNoticeMsg);
635 $conn->schedule($RADIO_CHANNEL_SONG_DELAY, \&getRadioCapsuleSong,$conn,$event,"$RADIO_CHANNEL","schedule");
636
637 # Wikiquote
638 log_message(0,"on_connect() schedule botWikiquote() on $RADIO_CHANNEL: $RADIO_CHANNEL_WIKIQUOTE_DELAY s");
639 $sNoticeMsg = getEventHostmask($event) . " schedule botWikiquote() on $RADIO_CHANNEL: $RADIO_CHANNEL_WIKIQUOTE_DELAY s";
640 noticeConsoleChan($conn,0,$sNoticeMsg);
641 $conn->schedule(($RADIO_CHANNEL_WIKIQUOTE_DELAY * 1.5), \&botWikiquote,$conn,$event,"$RADIO_CHANNEL");
642
643 # botQuote
644 log_message(0,"on_connect() schedule botQuote() on $RADIO_CHANNEL: $RADIO_CHANNEL_BOTQUOTE_DELAY s");
645 $sNoticeMsg = getEventHostmask($event) . " schedule botQuote() on $RADIO_CHANNEL: $RADIO_CHANNEL_BOTQUOTE_DELAY s";
646 noticeConsoleChan($conn,0,$sNoticeMsg);
647 $conn->schedule($RADIO_CHANNEL_BOTQUOTE_DELAY, \&botQuote,$conn,$event,"$RADIO_CHANNEL");
648
649 # TRUNCATE ACTIONS_QUEUE
650 dbCleanActionsQueue();
651
652 # Schedule actions queue processing
653 $conn->schedule(20, \&dbProcessActionsQueue,$conn);
654
655 }
656} # Fin on_connect
657
658sub on_nomotd
659{
660 my ($conn, $event) = @_;
661 log_message(0,"-" . $event->nick() . "- MOTD File is missing");
662 if (!defined($conn->{'connected'}) || (int($conn->{'connected'}) != 1)) {
663 on_connect($conn,$event);
664 }
665}
666
667sub on_public
668{
669 my ($conn, $event) = @_;
670 my $sCurrentNick = $conn->nick();
671 my $sText = $event->{'args'}[0];
672 $sText =~ s/ +/ /g;
673 $sText =~ s/^$sCurrentNick *$/$sCurrentNick/g;
674 my $sChannel = $event->{'to'}[0];
675 my $sNick = $event->{'nick'};
676
677 # Print event to console
678 log_message(3,"$sChannel:<$sNick> $sText");
679
680 if ( $scrabbleStatus && ( $scrabbleChannel eq $sChannel ) && ($lastScrabblePick ne "" ) ) {
681 checkScrableWord($conn,$event,$sNick,$sChannel,$sText);
682 }
683
684 # Insert into database
685 logbBotAction($conn,$event,"public",$sNick,$sChannel,$sText);
686
687# ----------------------------------------------------------------------------------------------------------------
688 # Check for command requests
689 if (substr($sText, 0, 1) eq '.') {
690 my ($sCommand,@tArgs) = split(/\s+/,$sText);
691 $sCommand =~ s/^\.//;
692 $sCommand =~ tr/A-Z/a-z/;
693
694 log_message(2,"Commande publique : $sCommand");
695 my $i = 0;
696 foreach my $item (@tArgs) {
697 log_message(2,"\$tArgs[$i] = $item");
698 $i++;
699 }
700
701 if (defined($sCommand) && ($sCommand ne '')) {
702 if ($sCommand eq 'whoami') {
703 userWhoAmI($conn,$event,$sNick);
704 }
705 elsif ($sCommand eq 'sql') {
706 botChannelSQL($conn,$event,$sNick,$sChannel,@tArgs);
707 }
708 elsif ($sCommand eq 'checkhosts') {
709 botCheckHosts($conn,$event,$sNick,$sChannel,@tArgs);
710 }
711 elsif ($sCommand eq 'say') {
712 botSayChannel($conn,$event,$sNick,$sChannel,@tArgs);
713 }
714 elsif ($sCommand eq 'act') {
715 botActChannel($conn,$event,$sNick,$sChannel,@tArgs);
716 }
717 elsif ($sCommand eq 'op') {
718 botOpChanNick($conn,$event,$sNick,$sChannel,@tArgs);
719 }
720 elsif ($sCommand eq 'deop') {
721 botDeopChanNick($conn,$event,$sNick,$sChannel,@tArgs);
722 }
723 elsif ($sCommand eq 'voice') {
724 botVoiceChanNick($conn,$event,$sNick,$sChannel,@tArgs);
725 }
726 elsif ($sCommand eq 'devoice') {
727 botDevoiceChanNick($conn,$event,$sNick,$sChannel,@tArgs);
728 }
729 elsif ($sCommand eq 'topic') {
730 botChannelSetTopic($conn,$event,$sNick,$sChannel,@tArgs);
731 }
732 elsif ($sCommand eq 'kick') {
733 botChannelKickUser($conn,$event,$sNick,$sChannel,@tArgs);
734 }
735 elsif ($sCommand eq 'modinfo') {
736 botChannelModinfo($conn,$event,$sNick,$sChannel,@tArgs);
737 }
738 elsif ($sCommand eq 'access') {
739 botChannelUserAccess($conn,$event,$sNick,$sChannel,@tArgs);
740 }
741 elsif ($sCommand eq 'part') {
742 botChannelPart($conn,$event,$sNick,$sChannel,@tArgs);
743 }
744 elsif ($sCommand eq 'join') {
745 botChannelJoin($conn,$event,$sNick,$sChannel,@tArgs);
746 }
747 elsif ( $sCommand eq 'cstat' ) {
748 botGetAuthUser($conn,$event,$sNick,$sChannel,@tArgs);
749 }
750 elsif ( $sCommand eq 'ustat' ) {
751 botGetUsers($conn,$event,$sNick,$sChannel,@tArgs);
752 }
753 elsif ( $sCommand eq 'seen') {
754 botSeen($conn,$event,$sNick,$sChannel,@tArgs);
755 }
756 #elsif ($sCommand eq 'info') {
757 # # Deprecated command to be used for sthg else
758 # botPublicInfo($conn,$event,$sNick,$sChannel);
759 #}
760 elsif ($sCommand eq 'bye') {
761 botDieRequest($conn,$event);
762 }
763 elsif ($sCommand eq 'etpaflechien') {
764 botRestartRequest($conn,$event,join(" ",@tArgs));
765 }
766 elsif ($sCommand eq 'version') {
767 botPublicVersion($conn,$event,$sChannel);
768 }
769 #elsif ($sCommand eq 'radio') {
770 # botNotice($conn,$sNick,"This command is unavailable");
771 #}
772
773 elsif (($sCommand eq 'song') || ($sCommand eq 'chanson')) {
774 getRadioCapsuleSong($conn,$event,$sNick,$sChannel,@tArgs);
775 }
776 elsif (($sCommand =~ /^auditeurs$/i) || ($sCommand =~ /^auditrices$/i)) {
777 getRadioCapsuleListeners($conn,$event,$sNick,$sChannel,$sCommand,@tArgs);
778 }
779 #elsif ($sCommand eq 'last') {
780 # botPrivmsg($conn,$event,$sChannel,"http://radiocapsule.com/metadata/tenlastsong.php");
781 #}
782 elsif ($sCommand eq 'next') {
783 radioNext($conn,$event,$sNick,$sChannel,@tArgs);
784 }
785 elsif ($sCommand eq 'setdj') {
786 radioSetDj($conn,$event,$sNick,$sChannel,@tArgs);
787 }
788 elsif ($sCommand eq 'playlist') {
789 radioSetPlaylist($conn,$event,$sNick,$sChannel,@tArgs);
790 }
791 elsif ($sCommand eq 'play') {
792 playYoutube($conn,$event,$sNick,$sChannel,@tArgs);
793 }
794 elsif ($sCommand eq 'quote') {
795 botGetAnswer($conn,$event,$sNick,$sChannel,@tArgs);
796 }
797 elsif ($sCommand eq 'nextyt') {
798 radioNextYoutubeToPLay($conn,$event,$sNick,$sChannel,@tArgs);
799 }
800 elsif (($sCommand eq 'departement') || ( $sCommand eq 'département') ) {
801 getDepartement($conn,$event,$sNick,$sChannel,@tArgs);
802 }
803 elsif ($sCommand eq 'tld') {
804 getTLD($conn,$event,$sNick,$sChannel,@tArgs);
805 }
806 elsif ($sCommand eq 'http') {
807 botHttpResponseCode($conn,$event,$sNick,$sChannel,@tArgs);
808 }
809 elsif ($sCommand eq 'load') {
810 botServerLoad($conn,$event,$sNick,$sChannel,@tArgs);
811 }
812 elsif ($sCommand eq 'carambar') {
813 Carambar($conn,$event,$sNick,$sChannel);
814 }
815 elsif ($sCommand eq 'date') {
816 my $lang = Date::Language->new('French');
817 if (defined($tArgs[0]) && ( $tArgs[0] =~ /fr/i )) {
818 botPrivmsg($conn,$event,$sChannel,"France : " . $lang->time2str("%A %d/%m/%Y %H:%M:%S",time));
819 }
820 else {
821 botPrivmsg($conn,$event,$sChannel,"Québec : " . $lang->time2str("%A %d/%m/%Y %H:%M:%S",(time - 21600)));
822 }
823 }
824 #elsif ($sCommand =~ /^url[s]?$/i) {
825 # getRadioUrl($conn,$event,$sNick,$sChannel);
826 #}
827 #elsif ($sCommand eq 'ping') {
828 # botPingNick($conn,$event,$sNick,@tArgs);
829 #}
830 #elsif ($sCommand eq 'wikipedia') {
831 # botWikipedia($conn,$event,$sNick,$sChannel,@tArgs);
832 #}
833 elsif ($sCommand eq 'str2time') {
834 botStr2Time($conn,$event,$sNick,$sChannel,@tArgs);
835 }
836 elsif ($sCommand eq 'time2str') {
837 botTime2Str($conn,$event,$sNick,$sChannel,@tArgs);
838 }
839 #elsif ($sCommand eq 'bc') {
840 # botBc($conn,$event,$sNick,$sChannel,@tArgs);
841 #}
842 elsif ($sCommand eq 'rr') {
843 botRR($conn,$event,$sNick,$sChannel,@tArgs);
844 }
845 elsif ($sCommand eq 'scrabble') {
846 unless ( $scrabbleStatus ) {
847 scrabbleStart($conn,$event,$sNick,$sChannel,@tArgs);
848 }
849 }
850 elsif ($sCommand eq 'stop') {
851 if ( $scrabbleStatus ) {
852 scrabbleStop($conn,$event,$sNick,$sChannel,@tArgs);
853 }
854 }
855 elsif ($sCommand eq 'r') {
856 if ( $scrabbleStatus ) {
857 botPrivmsg($conn,$event,"$sChannel","Scrabble : " . $lastScrabblePick);
858 }
859 }
860 elsif ($sCommand eq 'top') {
861 scrabbleScoresDisplay($conn,$event,$sNick,$sChannel,@tArgs);
862 }
863 elsif (( $sCommand eq 'scrabblorz' ) || ( $sCommand eq 'scrabblordz' )) {
864 my $scrabbleHint = scrabbleFind($conn,$event,$sNick,$sChannel,@tArgs);
865 botPrivmsg($conn,$event,$sChannel,$scrabbleHint);
866 }
867 elsif ( $sCommand eq 'ami' ) {
868 botFriendGuess($conn,$event,$sNick,$sChannel,@tArgs);
869 }
870 elsif ( $sCommand eq 'saucisse' ) {
871 botSaucisse($conn,$event,$sNick,$sChannel,@tArgs);
872 }
873 #elsif ( $sCommand eq 'dowjaune' ) {
874 # botDowjaune($conn,$event,$sNick,$sChannel,@tArgs);
875 #}
876 #elsif ($sCommand eq 'help') {
877 # botPublicHelp($conn,$event,$sChannel,$sNick);
878 #}
879 elsif ($sCommand eq 'wordstatz') {
880 chanWordStat($conn,$event,$sNick,$sChannel,@tArgs);
881 }
882 elsif ($sCommand =~ /^wheeling$/i) {
883 my $iSpeed = int(rand(151)) + 150;
884 if (defined($tArgs[0])) {
885 botPrivmsg($conn,$event,$sChannel,"\1ACTION fait une roue arrière à $iSpeed à l'heure dans le salon de " . $tArgs[0] . "\1");
886 }
887 else {
888 botPrivmsg($conn,$event,$sChannel,"\1ACTION fait une roue arrière à $iSpeed à l'heure dans le salon de " . $sNick . "\1");
889 }
890 }
891 elsif ($sCommand =~ /^lingwhee$/i) {
892 my $iSpeed = int(rand(151)) + 150;
893 if (defined($tArgs[0])) {
894 botPrivmsg($conn,$event,$sChannel,"\1ACTION fait une roue arrière en marche arrière à $iSpeed à l'heure dans le salon de " . $tArgs[0] . "\1");
895 }
896 else {
897 botPrivmsg($conn,$event,$sChannel,"\1ACTION fait une roue arrière en marche arrière à $iSpeed à l'heure dans le salon de " . $sNick . "\1");
898 }
899 }
900 elsif ($sCommand =~ /^sib[ée]rie$/i) {
901 my $iTemp = int(rand(31)) + 30;
902 if (defined($tArgs[0])) {
903 botPrivmsg($conn,$event,$sChannel,"\1ACTION envoie " . $tArgs[0] . " casser du caillou en Sibérie par -$iTemp degrés\1");
904 }
905 else {
906 botPrivmsg($conn,$event,$sChannel,"\1ACTION envoie " . $sNick . " casser du caillou en Sibérie par -$iTemp degrés\1");
907 }
908 }
909 elsif ($sCommand =~ /^consigne[s]$/i) {
910 my $iTemp = int(rand(80)) + 21;
911 if (defined($tArgs[0])) {
912 botPrivmsg($conn,$event,$sChannel,"\1ACTION suggère à " . $tArgs[0] . " de ramener ses $iTemp caisses de consignes qui trainent sur le balcon\1");
913 }
914 else {
915 botPrivmsg($conn,$event,$sChannel,"\1ACTION suggère à " . $sNick . " de ramener ses $iTemp caisses de consignes qui trainent sur le balcon\1");
916 }
917 }
918 elsif ($sCommand =~ /^poubelle[s]?$/i) {
919 my $iNbPoubelles = int(rand(36)) + 5;
920 if (defined($tArgs[0])) {
921 botPrivmsg($conn,$event,$sChannel,"\1ACTION invite " . $tArgs[0] . " à sortir les $iNbPoubelles poubelles qui traînent dans sa chambre\1");
922 }
923 else {
924 botPrivmsg($conn,$event,$sChannel,"\1ACTION invite " . $sNick . " à sortir les $iNbPoubelles poubelles qui traînent dans sa chambre\1");
925 }
926 }
927 elsif ($sCommand =~ /voyel|vauyel/) {
928 my @tVoyelles = ( 'a','e','i','o','u','y','y\'a plus voyelle\'' );
929 botPrivmsg($conn,$event,$sChannel,$tVoyelles[rand($#tVoyelles + 1)]);
930 }
931 elsif ($sCommand =~ /consonne|consaune/) {
932 my @tConsonnes = ( 'b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','x','x','z','y\'a plus consonne\'' );
933 botPrivmsg($conn,$event,$sChannel,$tConsonnes[rand($#tConsonnes + 1)]);
934 }
935 #elsif ($sCommand eq 'cac') {
936 # mbCAC($conn,$event,$sNick,$sChannel,@tArgs);
937 #}
938 elsif ($sCommand eq 'status') {
939 botPublicInfo($conn,$event,$sNick,$sChannel);
940 #getStreamStatus($conn,$event,$sNick,$sChannel,@tArgs);
941 }
942
943# ----------------------------------------------------------------------------------------------------------------
944 elsif ($sCommand =~ /^picon/i) {
945 if (defined($tArgs[0])) {
946 botPrivmsg($conn,$event,$sChannel,"\1ACTION voit que $sNick est connaisseur! Et un picon pour " . $tArgs[0] . "\1");
947 }
948 else {
949 botPrivmsg($conn,$event,$sChannel,"\1ACTION voit que $sNick est connaisseur! Et un picon pour la " . (int(rand 20) + 1) . "\1");
950 }
951 }
952 elsif ($sCommand =~ /^chimay/i) {
953 if (defined($tArgs[0])) {
954 botPrivmsg($conn,$event,$sChannel,"\1ACTION voit que $sNick est connaisseur! Et une chimay pour " . $tArgs[0] . "\1");
955 }
956 else {
957 botPrivmsg($conn,$event,$sChannel,"\1ACTION voit que $sNick est connaisseur! Et une chimay pour la " . (int(rand 20) + 1) . "\1");
958 }
959 }
960 #elsif ($sCommand =~ /^wordstat/i) {
961 # if (defined($tArgs[0])) {
962 # unless (open SCR,"$MAIN_PROG_BIN_DIR/words_stats.pl " . $tArgs[0] . " |") {
963 # log_message(0,"Error issuing stats");
964 # }
965 # else {
966 # my $line;
967 # while (defined($line=<SCR>)) {
968 # chomp($line);
969 # botPrivmsg($conn,$event,$sChannel,$line);
970 # usleep 500000;
971 # }
972 # }
973 # close SCR;
974 # }
975 #}
976 elsif ($sCommand =~ /^jus(.*)/i) {
977 if (defined($tArgs[0])) {
978 botPrivmsg($conn,$event,$sChannel,"\1ACTION sert un ". $sCommand . " Ã " . $tArgs[0] . "\1");
979 }
980 else {
981 botPrivmsg($conn,$event,$sChannel,"\1ACTION sert un ". $sCommand . " Ã " . $sNick . "\1");
982 }
983 }
984 elsif ($sCommand =~ /^caf.*$|^senseo$|^whatelse$|^nespr|^nesc/i) {
985 my $sMsgCafe = String::IRC->new('c(')->yellow('black')->bold;
986 $sMsgCafe .= String::IRC->new('_')->maroon('black')->bold;
987 $sMsgCafe .= String::IRC->new(')')->yellow('black')->bold;
988 $sMsgCafe .= String::IRC->new('~')->silver('black')->bold;
989 if (defined($tArgs[0])) {
990 botPrivmsg($conn,$event,$sChannel,"\1ACTION sert un $sMsgCafe à " . $tArgs[0] . "\1");
991 }
992 else {
993 botPrivmsg($conn,$event,$sChannel,"\1ACTION sert un $sMsgCafe à " . $sNick . "\1");
994 }
995 }
996 elsif ($sCommand eq "pan") {
997 my $sMsgPan = String::IRC->new("Et tu tires avec quoi $sNick avec tes doigts ?")->red();
998 botPrivmsg($conn,$event,$sChannel,$sMsgPan);
999 }
1000 elsif ($sCommand eq "jesors") {
1001 botPrivmsg($conn,$event,$sChannel,$sNick . " => []");
1002 $conn->sl("KICK $sChannel " . $sNick . " :tu sors");
1003 }
1004 elsif ($sCommand =~ /^xmas/) {
1005 botPrivmsg($conn,$event,$sChannel,"Joyeux Noël à tous, bande de moches!!");
1006 }
1007 elsif ($sCommand =~ /^ap.ro$|ap.ral$/i) {
1008 # Launch happy hour
1009 unless ( $aperal ) {
1010 botPrivmsg($conn,$event,$sChannel,"\1ACTION sets mode +aperal attention c'est parti !biere !1664 !leffe !picon !51 !tipunch\1");
1011 $aperal = 1;
1012 $aperalStartTime = time;
1013 $aperalStartedBy = $sNick;
1014 }
1015 else {
1016 if ( $sNick eq $aperalStartedBy ) {
1017 botPrivmsg($conn,$event,$sChannel,"Hey $sNick t'as déjà lancé l'aperal à " . time2str("%H:%M:%S",$aperalStartTime) . " t'es déjà bourré ma poule !");
1018 }
1019 else {
1020 botPrivmsg($conn,$event,$sChannel,"Hey $sNick l'aperal a été lancé à " . time2str("%H:%M:%S",$aperalStartTime) . " par $aperalStartedBy !");
1021 }
1022 }
1023 }
1024 elsif (($sCommand eq 'insulte') || ($sCommand eq 'insultes')) {
1025 botInsulteChan($conn,$event,$sChannel,@tArgs);
1026 }
1027 elsif ($sCommand eq 'coluche') {
1028 botColuche($conn,$event,$sChannel,@tArgs);
1029 }
1030 elsif ($sCommand eq 'ivan') {
1031 botIvan($conn,$event,$sChannel,@tArgs);
1032 }
1033 elsif ($sCommand =~ /^radiocapsule$/) {
1034 botRadioTease($conn,$event,$sChannel,@tArgs);
1035 }
1036 elsif (($sCommand eq 'addinsulte') || ($sCommand eq 'addinsultes')) {
1037 botAddInsulte($conn,$event,$sChannel,@tArgs);
1038 }
1039 elsif ($sCommand eq 'addivan') {
1040 botAddIvan($conn,$event,$sChannel,@tArgs);
1041 }
1042 elsif ($sCommand eq 'tables') {
1043 botStatTables($conn,$event,$sNick,$sChannel,@tArgs);
1044 }
1045 #elsif ($sCommand eq 'niouininon') {
1046 # if (defined($tArgs[0])) {
1047 # if ( $tArgs[0] =~ /^off$/i ) {
1048 # $yes_or_no = 0;
1049 # botNotice($conn,$sChannel,"Fin du ni oui ni non");
1050 # }
1051 # else {
1052 # $yes_or_no = 1;
1053 # botNotice($conn,$sChannel,"Attention le ni oui ni non a commencé :)");
1054 # }
1055 # }
1056 # else {
1057 # botNotice($conn,$sChannel,"Usage: !niouininon <on|off>");
1058 # if ( $yes_or_no ) {
1059 # botNotice($conn,$sChannel,"Le jeu est activé !");
1060 # }
1061 # else {
1062 # botNotice($conn,$sChannel,"Le jeu n'est pas activé");
1063 # }
1064 # }
1065 #}
1066# ----------------------------------------------------------------------------------------------------------------
1067 else {
1068 if (botSQLCommand($conn,$event,$sNick,$sChannel,$sCommand,@tArgs)) {
1069 log_message(2,"$sNick issued a known public SQL command : $sCommand");
1070 }
1071 else {
1072 log_message(2,"$sNick issued an unknown public command : $sCommand");
1073 }
1074 }
1075 }
1076 }
1077# ------------------- END OF !COMMANDS ---------------------------------------------------------------------------
1078 elsif ( $sText =~ /yé\s*yé\s*yé/i ) {
1079 botPrivmsg($conn,$event,$sChannel,"C'est celui qui dit qui yé yé yé (c) Meza ");
1080 }
1081
1082 #elsif (( $sText =~ /^!bang$/i ) && ($sNick eq "DrHouse^")) {
1083 # $conn->sl("KICK $sChannel $sNick");
1084 #}
1085
1086 #bind pubm - *http*://www.youtube.*/watch* pubm:youtube
1087 #bind pubm - *http*://m.youtube.*/watch* pubm:youtube
1088 #bind pubm - *http*://youtu.be/* pubm:youtube
1089 elsif ( ( $sText =~ /http.*:\/\/www\.youtube\..*\/watch/i ) || ( $sText =~ /http.*:\/\/m\.youtube\..*\/watch/i ) || ( $sText =~ /http.*:\/\/youtu\.be.*/i ) ) {
1090 if ( $sChannel ne "#quebec" ) {
1091 botDisplayYoutubeUrl($conn,$event,$sNick,$sChannel,$sText);
1092 }
1093 }
1094
1095 elsif ( $sText =~ /pleine.*lune.*lac/i ) {
1096 botPrivmsg($conn,$event,$sChannel,"T'as vu ta gueule de moche $sNick ?");
1097 }
1098 #elsif ( $sText =~ /^http[s]?:\/\//i ) {
1099 # log_message(0,"URL triggered " . $sText);
1100 # #my $sUrl = ($sText =~ m/^.*(http:\/\/[^ ]+).*$]/)[0];
1101 # #log_message(1,"\$Url|$sUrl|");
1102 # #if (defined($sUrl)) {
1103 # #log_message(0,getUrltitle($conn,$event,$sNick,$sChannel,$sText));
1104 # #}
1105 # getUrltitle($conn,$event,$sNick,$sChannel,$sText);
1106 #}
1107 elsif ( $sText =~ /sou.*s.*la.*ket/i ) {
1108 if (defined($sNick) && ( $sNick ne $conn->nick )) {
1109 botPrivmsg($conn,$event,$sChannel,$sNick . ' tou sousses la KET de moué et de mon ami!@#');
1110 }
1111 }
1112 elsif ( $sText =~ /petit lapin/i ) {
1113 if (defined($sNick) && ( $sNick ne $conn->nick )) {
1114 botPrivmsg($conn,$event,$sChannel,'\'t\'t\'t\'t');
1115 }
1116 }
1117 elsif ( $sText =~ /^$sCurrentNick/ ) {
1118 my (undef,$sCommand) = split(/ /,$sText,2);
1119 if (defined($sCommand)) {
1120 if ( $sCommand =~ /quel .ge as.*tu.*|t.*as.*quel.*ge|t.*a.*kel.*ge/i ) {
1121 sleep 2;
1122 botBirthDate($conn,$event,$sChannel);
1123 }
1124 elsif ( $sCommand =~ /montre.*sein/i ) {
1125 sleep 2;
1126 botPrivmsg($conn,$event,$sChannel,"( ° ) ( ° )");
1127 }
1128 elsif ( $sCommand =~ /qui.*es.*tu|ki.*es.tu|t.*es.*qui|t.*ki/i ) {
1129 sleep 2;
1130 botPublicVersion($conn,$event,$sChannel);
1131 }
1132 elsif ( $sCommand =~ /je.*t.*aime/i ) {
1133 sleep 2;
1134 botPrivmsg($conn,$event,$sChannel,"Hey tu vas me faire rougir " . $sNick);
1135 }
1136 elsif ( $sCommand =~ /la.*r.ponse.*universelle.*la.*vie.*l.*univers.*et.*tou.*le.*reste/i ) {
1137 sleep 2;
1138 botPrivmsg($conn,$event,$sChannel,"X te dirait 42 " . $sNick . ", mais un bon jeune comme moi sait que la réponse universelle, à la vie, l'univers et tout le reste c'est : $sChannel !!");
1139 }
1140 else {
1141 my ($sCommand,@tArgs) = split(/\s+/,$sCommand);
1142
1143 my $i = 0;
1144 foreach my $cell (@tArgs) {
1145 log_message(2,"tArgs[$i]=$cell|");
1146 $i++;
1147 }
1148
1149 if (defined($sCommand)) {
1150 $sCommand =~ tr/A-Z/a-z/;
1151 if ( $sCommand eq "bye" ) {
1152 botDieRequest($conn,$event);
1153 }
1154 #elsif ( $sCommand eq "info" ) {
1155 # botPublicInfo($conn,$event,$sNick,$sChannel);
1156 #}
1157 elsif ( $sCommand eq "version" ) {
1158 botPublicVersion($conn,$event,$sChannel);
1159 }
1160 else {
1161 sleep 2;
1162 botRandomAnswer($conn,$event,$sNick,$sChannel);
1163 }
1164 }
1165 else {
1166 log_message(1,"\$sCommand is undefined");
1167 }
1168 }
1169 }
1170 else {
1171 sleep 2;
1172 botPrivmsg($conn,$event,$sChannel,"Oui $sNick ?");
1173 }
1174 }
1175 #elsif ( $sText =~ /$sCurrentNick/ ) {
1176 # my $wl = WordList::Phrase::FR::Proverb::Wikiquote->new;
1177 # my $word = $wl->pick;
1178 # sleep 2;
1179 # botPrivmsg($conn,$event,$sChannel,"$word");
1180 #}
1181 else {
1182 if ( $sText =~ /^houston/i ) {
1183 botPrivmsg($conn,$event,$sChannel,"Rodgeure " . $sNick);
1184 }
1185 unless (defined($hPublicMessagesCount{$sChannel})) {
1186 $hPublicMessagesCount{$sChannel} = 1;
1187 }
1188 else {
1189 $hPublicMessagesCount{$sChannel} += 1;
1190 }
1191 log_message(3,"Number of messages in $sChannel " . $hPublicMessagesCount{$sChannel});
1192
1193 unless ( $hPublicMessagesCount{$sChannel} % $iPublicMessagesTriggerCount ) {
1194 log_message(3,"Trigger public reply on $sChannel");
1195 }
1196
1197 }
1198 log_message (4,"sText = |$sText|");
1199
1200}
1201
1202sub on_notice
1203{
1204 my ($conn, $event) = @_;
1205 my $text = $event->{'args'}[0];
1206 log_message(0,"-" . $event->nick() . "- $text");
1207} # Fin on_notice
1208
1209
1210sub on_private
1211{
1212 my ($conn, $event) = @_;
1213 my $sText = $event->{'args'}[0];
1214 my $sNick = $event->{'nick'};
1215 my $sCurrentNick = $conn->nick();
1216
1217 log_message(0,"<$sNick> $sText");
1218
1219 # Check for command requests
1220 my $sCommand = ($sText =~ m/^([^ ]*)/)[0];
1221 my (undef,@tArgs) = split(/ /,$sText);
1222 if ($sCommand ne '') {
1223 if ($sCommand eq 'bye') {
1224 botDieRequest($conn,$event);
1225 }
1226 elsif ( $sCommand eq 'login' ) {
1227 botUserLogin($conn,$event,$sNick,@tArgs);
1228 }
1229 elsif ($sCommand eq 'dump') {
1230 botDumpCmd($conn,$event,$sNick,@tArgs);
1231 }
1232 elsif (( $sCommand eq 'scrabblorz' ) || ( $sCommand eq 'scrabblordz' )) {
1233 my (undef,$sLetters) = split(/ /,$sText);
1234 unless (open SCR,"$MAIN_PROG_BIN_DIR/mlpl.pl $sLetters |") {
1235 log_message(0,"Error issuing mlpl.pl $sLetters");
1236 }
1237 else {
1238 my $line;
1239 while (defined($line=<SCR>)) {
1240 chomp($line);
1241 if ( $line =~ /^Results/ ) {
1242 botPrivmsg($conn,$event,$sNick,$line);
1243 sleep 1;
1244 }
1245 }
1246 close SCR;
1247 }
1248 }
1249 elsif ( $sCommand eq 'pass' ) {
1250 botSetPass($conn,$event,$sNick,@tArgs);
1251 }
1252 elsif ( $sCommand eq 'newpass' ) {
1253 botSetNewPass($conn,$event,$sNick,@tArgs);
1254 }
1255 elsif ( $sCommand eq 'adduser' ) {
1256 botAddUser($conn,$event,$sNick,@tArgs);
1257 }
1258 elsif ( $sCommand eq 'topic' ) {
1259 my $sChannel = $tArgs[0];
1260 shift (@tArgs);
1261 botChannelSetTopic($conn,$event,$sNick,$sChannel,@tArgs);
1262 }
1263 elsif ( $sCommand eq 'cstat' ) {
1264 botGetAuthUser($conn,$event,$sNick,undef,@tArgs);
1265 }
1266 elsif ($sCommand eq 'say') {
1267 botSayChannel($conn,$event,$sNick,undef,@tArgs);
1268 }
1269 elsif ($sCommand eq 'act') {
1270 botActChannel($conn,$event,$sNick,undef,@tArgs);
1271 }
1272 }
1273
1274} # Fin on_private
1275
1276sub on_caction
1277{
1278 my ($conn, $event) = @_;
1279 my $sNick = $event->nick;
1280 my $sText = $event->{'args'}[0];
1281 my $sChannel = $event->{'to'}[0];
1282 if ( $sNick eq $conn->nick ) {
1283 log_message(0,"$sChannel: * $sNick $sText");
1284 }
1285 else {
1286 log_message(3,"$sChannel: * $sNick $sText");
1287 }
1288 logbBotAction($conn,$event,"caction",$sNick,$sChannel,$sText);
1289} # Fin on_caction
1290
1291sub on_cversion
1292{
1293 my ($conn, $event) = @_;
1294 my $nick = $event->nick;
1295 #$conn->ctcp_reply($nick, 'VERSION ' . "$EVENT_CTCP_VERSION_REPLY");
1296 log_message(0,"*** CTCP VERSION request from $nick");
1297} # Fin on_cversion
1298
1299sub on_cping
1300{
1301 my ($conn, $event) = @_;
1302 my $nick = $event->nick;
1303 my $timestamp = $event->{'args'}[0];
1304 #$conn->ctcp_reply($nick, 'PING ' . $timestamp);
1305 log_message(0,"*** CTCP PING request from $nick");
1306} # Fin on_cping
1307
1308# Gives lag results for outgoing PINGs.
1309sub on_ping_reply {
1310 my ($conn, $event) = @_;
1311 my ($args) = ($event->args)[0];
1312 my ($nick) = $event->nick;
1313
1314 $args = time - $args;
1315 log_message(0,"*** CTCP PING reply from $nick: $args sec.");
1316 if ( $sLastNickPing ne "" ) {
1317 botNotice($conn,$sLastNickPing,"CTCP PING reply from $nick: $args sec.");
1318 }
1319}
1320
1321sub on_ctime
1322{
1323 my ($conn, $event) = @_;
1324 my $date = localtime;
1325 my $nick = $event->nick;
1326
1327 my $sNoticeMsg = getEventHostmask($event) . " CTCP TIME request";
1328 noticeConsoleChan($conn,0,$sNoticeMsg);
1329 log_message(0,"*** CTCP TIME request from $nick");
1330
1331 # Reply X joke ;)
1332 #$conn->ctcp_reply($nick, 'TIME ' . $date);
1333 $conn->ctcp_reply($nick, 'TIME ' . "I'm out of time");
1334
1335} # Fin on_ctime
1336
1337sub on_join {
1338 my ($conn, $event) = @_;
1339 my ($sChannel) = ($event->to)[0];
1340 my $sNick = $event->nick;
1341
1342 log_message(5,"on_join : event\n" . Dumper($event). "\n");
1343
1344 if ( $event->nick eq $conn->nick ) {
1345 #if ( $sChannel ne $CONN_DEFAULT_CHANNEL ) {
1346 # my $sNoticeMsg = getEventHostmask($event) . " Joined channel $sChannel";
1347 # noticeConsoleChan($conn,0,$sNoticeMsg);
1348 #}
1349 log_message(0,"$sChannel: * Now talking in $sChannel");
1350 }
1351 else {
1352 log_message(3,"$sChannel: * Joins " . $event->nick . " (" . $event->userhost . ")");
1353 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
1354 my $sEventNick = $event->nick();
1355 if (defined($iMatchingUserId)) {
1356 my $sChannelUserQuery = "SELECT * FROM USER_CHANNEL,CHANNEL WHERE USER_CHANNEL.id_channel=CHANNEL.id_channel AND name=? AND id_user=?";
1357 log_message(3,$sChannelUserQuery);
1358 dbCheckHandle($dbh);
1359 my $sth = $dbh->prepare($sChannelUserQuery);
1360 unless ($sth->execute($sChannel,$iMatchingUserId)) {
1361 log_message(0,"on_join() SQL Error : " . $DBI::errstr . " Query : " . $sChannelUserQuery);
1362 }
1363 else {
1364 if (my $ref = $sth->fetchrow_hashref()) {
1365 my $sAutoMode = $ref->{'automode'};
1366 if (defined($sAutoMode) && ($sAutoMode ne "")) {
1367 $conn->mode($sChannel,$sAutoMode,$sNick);
1368 }
1369 my $sGreetChan = $ref->{'greet'};
1370 if (defined($sGreetChan) && ($sGreetChan ne "")) {
1371 botPrivmsg($conn,$event,$sChannel,$sGreetChan);
1372 }
1373 }
1374 }
1375 }
1376 }
1377 logbBotAction($conn,$event,"join",$sNick,$sChannel,"");
1378
1379 # Someone joins #radiocapsule
1380 if ( $sChannel eq '#radiocapsule') {
1381 #log_message(1,"DEBUG1: Giving op to $sNick on $sChannel");
1382 #$conn->sl("mode $sChannel +o " . $sNick);
1383 if ( $sNick ne $conn->nick ) {
1384 botNotice($conn,$sNick,"Salut $sNick, tu peux taper !url !song !cam !insulte !biere");
1385 if ( $sNick =~ /^milf_/ ) {
1386 botNotice($conn,$sNick,"Tu peux aussi changer ton pseudo en tapant : /nick lepseudoquetuveux");
1387 }
1388 }
1389 }
1390
1391 # Bot joins a channel
1392 if ( $sNick eq $conn->nick ) {
1393 my $sChannelQuery = "SELECT * FROM CHANNEL where name=?";
1394 dbCheckHandle($dbh);
1395 my $sth = $dbh->prepare($sChannelQuery);
1396 unless ($sth->execute($sChannel)) {
1397 log_message(0,"on_join() SQL Error : " . $DBI::errstr . " Query : " . $sChannelQuery);
1398 }
1399 else {
1400 if (my $ref = $sth->fetchrow_hashref()) {
1401 if (defined($ref->{'chanmode'})) {
1402 log_message(2,"Fixing $sChannel modes to " . $ref->{'chanmode'});
1403 $conn->mode($sChannel,$ref->{'chanmode'});
1404 }
1405 }
1406 }
1407 }
1408}
1409
1410sub on_part {
1411 my ($conn, $event) = @_;
1412 my ($sChannel) = ($event->to)[0];
1413 my $sNick = $event->nick;
1414
1415 my $sArgs = ($event->args)[0];
1416 unless (defined($sArgs)) {
1417 $sArgs = "";
1418 }
1419 log_message(3,"$sChannel: * Parts " . $event->nick . " (" . $event->userhost . ")");
1420 logbBotAction($conn,$event,"part",$sNick,$sChannel,"$sArgs");
1421}
1422
1423sub on_disconnect {
1424 my ($conn, $event) = @_;
1425
1426 clean_and_exit($conn,0);
1427}
1428
1429sub on_umode {
1430 my ($conn, $event) = @_;
1431 my @to = $event->to;
1432 my ($nick, $mynick) = ($event->nick, $conn->nick);
1433 my ($arg) = ($event->args);
1434 log_message(0,"UMODE");
1435 log_message(5,Dumper($event));
1436}
1437
1438sub on_mode {
1439 my ($conn, $event) = @_;
1440 my @to = $event->to;
1441 my ($sChannel) = ($event->to)[0];
1442 my ($sNick, $mynick) = ($event->nick, $conn->nick);
1443 my ($sMode,@tModeNicks) = join(" ",($event->args));
1444 #log_message(0,"MODE");
1445 log_message(5,"on_mode : event\n" . Dumper($event). "\n");
1446 if ( $to[0] eq $mynick ) {
1447 log_message(2,"* $sNick sets mode $sMode");
1448 }
1449 else {
1450 log_message(3,$to[0] . ": * $sNick sets mode $sMode" . join(" ",@tModeNicks));
1451 }
1452 logbBotAction($conn,$event,"mode",$sNick,$sChannel,"sets mode $sMode" . join(" ",@tModeNicks));
1453}
1454
1455sub on_kick(@) {
1456 my ($conn, $event) = @_;
1457 my @to = $event->to;
1458 my ($sNickKicked) = ($event->to)[0];
1459 my ($sChannel) = ($event->args)[0];
1460 my ($sReason) = ($event->args)[1];
1461 my ($sNick, $mynick) = ($event->nick, $conn->nick);
1462 log_message(5,"on_kick : event\n" . Dumper($event). "\n");
1463 log_message(0,"$sChannel: * $sNickKicked was kicked by $sNick ($sReason)");
1464 logbBotAction($conn,$event,"kick",$sNickKicked,$sChannel,"$sNickKicked was kicked by $sNick ($sReason)");
1465 if ( $sNickKicked eq $conn->nick ) {
1466 log_message(0,"Re-joining $sChannel");
1467 $conn->sl("join $sChannel");
1468 }
1469}
1470
1471sub on_topic {
1472 my ($conn, $event) = @_;
1473 my @args = $event->args();
1474 my $sFormat = $event->{'format'};
1475
1476 #log_message(5,Dumper($event));
1477
1478 if (defined($sFormat) && ($sFormat eq 'server')) {
1479 # Topic event when joining channel
1480 if (defined($args[1]) && ($args[1] ne '')) {
1481 if (defined($args[2]) && ($args[2] ne '')) {
1482 log_message(0,$args[1] . ": * Topic is \'$args[2]\'");
1483 }
1484 else {
1485 log_message(0,$args[1] . ": No topic is set.");
1486 }
1487 }
1488 }
1489 elsif (defined($sFormat) && ($sFormat eq 'topic')) {
1490 #my $sNick = event->nick;
1491 my $sChannel = $event->{'to'}[0];
1492 my $sTopic = $event->{'args'}[0];
1493 if ( defined($sChannel) && ($sChannel ne '') ) {
1494 if (defined($sTopic)) {
1495 log_message(0,"$sChannel: * " . $event->from . " changes topic to \'$sTopic\'");
1496 }
1497 }
1498 }
1499 else {
1500 log_message(3,"Unknown event " . Dumper($event));
1501 }
1502
1503}
1504
1505sub on_topicinfo {
1506 my ($conn, $event) = @_;
1507 my @args = $event->args();
1508 my $sFormat = $event->{'format'};
1509 #log_message(5,Dumper($event));
1510 if (defined($sFormat) && ($sFormat eq 'server')) {
1511 # Topic event when joining channel
1512 if (defined($args[1]) && ($args[1] ne '')) {
1513 if (defined($args[1]) && ($args[1] ne '') && defined($args[2]) && ($args[2] ne '') && defined($args[3]) && ($args[3] ne '')) {
1514 log_message(0,$args[1] . ": * Set by $args[2] on " . time2str("%c",$args[3]));
1515 }
1516 else {
1517 log_message(0,$args[1] . ": No topic is set.");
1518 }
1519 }
1520 }
1521 else {
1522 log_message(5,"on_topicinfo Unknown event " . Dumper($event));
1523 }
1524}
1525
1526sub on_quit {
1527 my ($conn,$event) = @_;
1528 my $sArgs = ($event->args)[0];
1529 my $sNick = $event->nick;
1530 my ($sUserMask) = ($event->to)[0];
1531 if (defined($sArgs)) {
1532 log_message(3,"Quits: $sNick (" . $sUserMask . ") " . $sArgs);
1533 }
1534 else {
1535 log_message(3,"Quits: $sNick (" . $sUserMask . ") (no reason)");
1536 }
1537
1538 log_message(5,"event: " . Dumper($event));
1539 #log_message(6,Dumper($conn));
1540
1541 logEvent($conn,$event);
1542}
1543
1544sub on_unmatched_event {
1545 my ($conn,$event) = @_;
1546 log_message(3,"Unmatched event " . $event->type);
1547 log_message(3,"event: " . Dumper($event));
1548
1549 log_message(6,"conn: " . Dumper($conn));
1550}
1551
1552# +---------------------------------------------------------------------------+
1553# ! SUBS !
1554# +---------------------------------------------------------------------------+
1555sub init_log(@) {
1556 my ($sLogFilename) = @_;
1557 unless (open LOG, ">>$sLogFilename") {
1558 print STDERR "Could not open $sLogFilename for writing.\n";
1559 clean_and_exit(undef,1);
1560 }
1561 $|=1;
1562 print LOG "+--------------------------------------------------------------------------------------------------+\n";
1563}
1564
1565sub init_pid(@) {
1566 my ($conn,$sPidFilename) = @_;
1567 #log_message(2,"init_pid($sPidFilename)");
1568 unless (open PID, ">$sPidFilename") {
1569 print STDERR "Could not open $sPidFilename for writing.\n";
1570 clean_and_exit(undef,1);
1571 }
1572 else {
1573 if (defined($conn)) {
1574 $conn->schedule(120, \&init_pid, $MAIN_PID_FILE);
1575 }
1576 print PID "$$";
1577 close PID;
1578 }
1579}
1580
1581sub log_message(@) {
1582 my ($iLevel,$sMsg) = @_;
1583 if (defined($sMsg) && ($sMsg ne "")) {
1584 my $sDisplayMsg = time2str("[%d/%m/%Y %H:%M:%S]",time) . " ";
1585 select LOG;
1586 $|=1;
1587 if ( $MAIN_PROG_DEBUG >= $iLevel ) {
1588 if ( $iLevel == 0 ) {
1589 $sDisplayMsg .= "$sMsg\n";
1590 print LOG $sDisplayMsg;
1591 }
1592 else {
1593 $sDisplayMsg .= "[DEBUG" . $iLevel . "] $sMsg\n";
1594 print LOG $sDisplayMsg;
1595 }
1596 select STDOUT;
1597 unless ( $MAIN_PROG_DAEMON ) {
1598 print $sDisplayMsg;
1599 }
1600 }
1601 }
1602}
1603
1604sub clean_and_exit(@) {
1605 my ($conn,$iRetValue) = @_;
1606 log_message(0,"Cleaning and exiting...");
1607 if (defined($conn) && defined($conn->{'connected'})) {
1608 if ( $conn->{'connected'} eq 1 ) {
1609 $conn->quit($CONN_DEFAULT_QUIT_MSG);
1610 log_message(0,"Quits " . $conn->nick() . " : $CONN_DEFAULT_QUIT_MSG");
1611 }
1612 }
1613 if (defined($dbh) && ($dbh != 0)) {
1614 if ( $iRetValue != 1146 ) {
1615 dbLogoutUsers();
1616 }
1617 $dbh->disconnect();
1618 }
1619
1620 if(defined(fileno(LOG))) { close LOG; }
1621
1622 exit $iRetValue;
1623}
1624
1625sub botPublicCall(@) {
1626 my ($sChannel,$sNick) = @_;
1627 log_message(0,"$sChannel:$sNick called me");
1628}
1629
1630sub botPublicVersion(@) {
1631 my ($conn,$event,$sChannel) = @_;
1632 botPrivmsg($conn,$event,$sChannel,"Je run $MAIN_PROG_NAME v$MAIN_PROG_VERSION. Je suis le bot de Te[u]K ok ?");
1633}
1634
1635sub botPrivmsg(@) {
1636 #botPrivmsg($conn,$sChannel,"le texte est ici");
1637 my ($conn,$event,$sTo,$sMsg) = @_;
1638 $conn->privmsg($sTo,$sMsg);
1639 my $eventtype = "public";
1640 if (substr($sTo, 0, 1) eq '#') {
1641 log_message(0,"$sTo:<" . $conn->nick() . "> $sMsg");
1642 }
1643 else {
1644 $eventtype = "private";
1645 log_message(0,"-> *$sTo* $sMsg");
1646 }
1647 logbBotAction($conn,$event,$eventtype,$conn->nick(),$sTo,$sMsg);
1648}
1649
1650sub botAction(@) {
1651 my ($conn,$event,$sTo,$sMsg) = @_;
1652 my $eventtype = "caction";
1653 logbBotAction($conn,$event,$eventtype,$conn->nick(),$sTo,$sMsg);
1654 $conn->privmsg($sTo,"\1ACTION " . $sMsg . "\1");
1655 log_message(0,"$sTo:<" . $conn->nick() . "> ACTION : $sMsg");
1656}
1657
1658#sub botAction(@) {
1659# my ($conn,$event,$sTo,$sMsg) = @_;
1660# botPrivmsg($conn,$event,$sTo,"\1ACTION " . $sMsg . "\1");
1661#}
1662
1663sub botNotice(@) {
1664 my ($conn,$sTo,$sMsg) = @_;
1665 $conn->notice($sTo,$sMsg);
1666 log_message(0,"-> -$sTo- $sMsg");
1667}
1668
1669# !info
1670sub botPublicInfo(@) {
1671 my ($conn,$event,$sNick,$sChannel) = @_;
1672 log_message(1,"$sChannel:$sNick issued a status command on $sChannel");
1673
1674 # Version, CPU an Memory usage
1675 my ($sCpuUsed,$sMemUsed) = ("","");
1676 my $iChildpid = open CHILD, "-|";
1677 unless ( $iChildpid ) {
1678 exec "ps aux | grep -v grep | tr -s \" \" | grep $0";
1679 exit $?;
1680 }
1681 else {
1682 my $sLine;
1683 if (defined($sLine =<CHILD>)) {
1684 chomp($sLine);
1685 (undef,undef,$sCpuUsed,$sMemUsed,undef) = split(/\s+/,$sLine);
1686 }
1687 }
1688 botNotice($conn,$sNick,"I am " . $conn->nick() . " running $MAIN_PROG_NAME v$MAIN_PROG_VERSION (CPU : $sCpuUsed% MEM : $sMemUsed%)");
1689
1690 # Uptime
1691 my $iUptime = time - $iConnectionTimestamp;
1692 my $days = int($iUptime / 86400);
1693 my $hours = int(($iUptime - ( $days * 86400 )) / 3600);
1694 $hours = sprintf("%02d",$hours);
1695 my $minutes = int(($iUptime - ( $days * 86400 ) - ( $hours * 3600 )) / 60);
1696 $minutes = sprintf("%02d",$minutes);
1697
1698 my $sAnswer = "$days days, $hours:$minutes on *.undernet.org";
1699 if (defined($sAnswer)) {
1700 botNotice($conn,$sNick,time2str("%H:%M:%S up ",time) . $sAnswer);
1701 }
1702}
1703
1704sub botBirthDate(@) {
1705 my ($conn,$event,$sChannel) = @_;
1706 my $iSecs = time - $MAIN_PROG_BIRTHDATE;
1707 my $err;
1708 my $delta = DateCalc(time2str("%c",$MAIN_PROG_BIRTHDATE),"today",\$err,1);
1709 my ($years,$months,$weeks,$days,$hours,$minutes,$seconds) = split(/:/,$delta);
1710 my $sBirthDate = time2str("Je suis né le %d/%m/%Y à %H:%M:%S. ",$MAIN_PROG_BIRTHDATE);
1711 my $sAnswer = "J'ai ";
1712 if ( defined($years) ) {
1713 $years =~ s/^\+//;
1714 $sAnswer .= "$years ans ";
1715 }
1716 if ( defined($months) ) {
1717 $sAnswer .= "$months mois ";
1718 }
1719 #if ( defined ($weeks) ) {
1720 # $sAnswer .= "$weeks semaines ";
1721 #}
1722 if ( defined($days) ) {
1723 $sAnswer .= "$days jours ";
1724 }
1725 #$sAnswer .= "$hours heures $minutes minutes et $seconds secondes.";
1726 botPrivmsg($conn,$event,$sChannel, $sBirthDate . $sAnswer);
1727}
1728
1729sub botDieRequest(@) {
1730 my ($conn,$event) = @_;
1731 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
1732 my $answer = "";
1733 my $sEventNick = $event->nick();
1734 if (defined($iMatchingUserId)) {
1735 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
1736 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_MASTER)) {
1737 $answer = "So long and thanks for all the fish ($sEventNick)";
1738 botPrivmsg($conn,$event,$CONN_DEFAULT_CHANNEL,$answer);
1739 log_message(0,"*** die request from $sEventNick");
1740 clean_and_exit($conn,0);
1741 }
1742 else {
1743 botNotice($conn,$sEventNick,"This command is not available for your level. Contact a bot Master.");
1744 }
1745 }
1746 else {
1747 botNotice($conn,$sEventNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
1748 }
1749 }
1750 else {
1751 log_message(0,"$sEventNick issued unauthorized die command");
1752 }
1753}
1754
1755sub botRestartRequest(@) {
1756 my ($conn,$event,$sMsg) = @_;
1757 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
1758 my $answer = "";
1759 my $sEventNick = $event->nick();
1760 if (defined($iMatchingUserId)) {
1761 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
1762 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_MASTER)) {
1763 if (defined($sMsg) && ($sMsg ne "")) {
1764 $answer = "brb dudes, I need to restart ($sMsg)";
1765 }
1766 else {
1767 $answer = "brb dudes, I need to restart ($sEventNick)";
1768 }
1769 botPrivmsg($conn,$event,$CONN_DEFAULT_CHANNEL,$answer);
1770 log_message(0,"*** restart request from $sEventNick");
1771 my $iCHildPid;
1772 if (defined($iCHildPid = fork())) {
1773 unless ($iCHildPid) {
1774 log_message(0,"Restart process: setsid");
1775 setsid;
1776 log_message(0,"Lauching $MAIN_PROG_DAEMON_START");
1777 exec $MAIN_PROG_DAEMON_START;
1778 }
1779 else {
1780 clean_and_exit($conn,0);
1781 }
1782 }
1783 else {
1784 log_message(0,"Could not restart process : fork error $!");
1785 }
1786 }
1787 else {
1788 botNotice($conn,$sEventNick,"This command is not available for your level. Contact a bot Master.");
1789 }
1790 }
1791 else {
1792 botNotice($conn,$sEventNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
1793 }
1794 }
1795 else {
1796 log_message(0,"$sEventNick issued unauthorized restart command");
1797 }
1798}
1799
1800sub botPingNick(@) {
1801 my ($conn,$event,$sNick,@tArgs) = @_;
1802 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
1803 my $sEventNick = $event->nick();
1804 if (defined($iMatchingUserId)) {
1805 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
1806 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_MASTER)) {
1807 if (defined($tArgs[0])) {
1808 $sLastNickPing = $tArgs[0];
1809 my $date = time;
1810 $conn->privmsg($tArgs[0],"\1PING " . $date . "\1");
1811 log_message(0,"-> [". $tArgs[0] ."] PING $date");
1812 }
1813 else {
1814 botNotice($conn,$sNick,"Syntax is !ping <nick>");
1815 }
1816 }
1817 else {
1818 botNotice($conn,$sNick,"This command is not available for your level. Contact a bot Master.");
1819 }
1820 }
1821 else {
1822 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
1823 }
1824 }
1825 else {
1826 log_message(0,"$sNick issued unauthorized restart command");
1827 }
1828
1829}
1830
1831sub botPublicHelp(@) {
1832 my ($conn,$event,$sChannel,$sNick) = @_;
1833 botNotice($conn,$sNick,"Public commands :");
1834 botNotice($conn,$sNick,"!hello : ask for greetings");
1835 botNotice($conn,$sNick,"!status : display stream status and listener count");
1836 sleep(1);
1837 botNotice($conn,$sNick,"!info : display mediabox404 status");
1838 botNotice($conn,$sNick,"!ping <nick> : CTCP <nick> PING");
1839 botNotice($conn,$sNick,"!wikipedia <some key words> : Wikipedia search (fr)");
1840 sleep(1);
1841 botNotice($conn,$sNick,"!str2time <mm/dd/YY HH:MM:SS> : Convert date to timestamp");
1842 botNotice($conn,$sNick,"!time2str <timestamp> : Convert timestamp to date");
1843 botNotice($conn,$sNick,'---------------------------------------------------');
1844 sleep(1);
1845 botNotice($conn,$sNick,"Authenticated commands :");
1846 botNotice($conn,$sNick,"!whoami !cstat !ustat");
1847 botNotice($conn,$sNick,"msg " . $conn->nick() . " login <username> <password> : Login to mediabot");
1848 sleep(1);
1849 botNotice($conn,$sNick,"msg " . $conn->nick() . " pass <new_password> : Set your password after being added");
1850 botNotice($conn,$sNick,"msg " . $conn->nick() . " newpass <new_password> : Change your password");
1851 botNotice($conn,$sNick,"msg " . $conn->nick() . " adduser <username> <hostmask> [level] : Add user");
1852 sleep(1);
1853 botNotice($conn,$sNick,"msg " . $conn->nick() . " say #channel <text> : say <text> on #channel");
1854 botNotice($conn,$sNick,"msg " . $conn->nick() . " act #channel <text> : act <text> on #channel");
1855 botNotice($conn,$sNick,'---------------------------------------------------');
1856 sleep(1);
1857 botNotice($conn,$sNick,"Bonus commands (pour les bons jeunes)");
1858 botNotice($conn,$sNick,"!cafe !biere !picon !clope !joint !jesuismoche !sousslaket");
1859}
1860
1861sub dbConnect(@) {
1862 my ($dbname,$dbhost,$dbport,$dbuser,$dbpasswd) = @_;
1863 my $connectionInfo="DBI:mysql:database=$dbname;$dbhost:$dbport"; # Database connection string
1864 my $dbh; # Database handle
1865
1866 log_message(5,"dbConnect() Connecting to Database : " . $dbname);
1867
1868 unless ( $dbh = DBI->connect($connectionInfo,$dbuser,$dbpasswd) ) {
1869 log_message(0,"dbConnect() DBI Error : " . $DBI::errstr);
1870 log_message(0,"dbConnect() DBI Native error code : " . $DBI::err);
1871 if ( defined( $DBI::err ) && ( $DBI::err == 1049 ) ) {
1872 clean_and_exit(undef,$DBI::err);
1873 }
1874 return undef;
1875 }
1876 log_message(5,"dbConnect() Connected to $dbname.");
1877 return $dbh;
1878}
1879
1880sub getNickInfo(@) {
1881 my ($conn,$event) = @_;
1882 my $iMatchingUserId = undef;
1883 my $iMatchingUserLevel = undef;
1884 my $iMatchingUserLevelDesc = undef;
1885 my $iMatchingUserAuth = undef;
1886 my $sMatchingUserHandle = undef;
1887 my $sMatchingUserPasswd = undef;
1888 my $sMatchingUserInfo1 = undef;
1889 my $sMatchingUserInfo2 = undef;
1890
1891 my $sCheckQuery = "SELECT * FROM USER";
1892 dbCheckHandle($dbh);
1893 my $sth = $dbh->prepare($sCheckQuery);
1894 unless ($sth->execute ) {
1895 log_message(0,"getNickInfo() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
1896 }
1897 else {
1898 while (my $ref = $sth->fetchrow_hashref()) {
1899 my @tHostmasks = split(/,/,$ref->{'hostmasks'});
1900 foreach my $sHostmask (@tHostmasks) {
1901 log_message(4,"getNickInfo() Checking hostmask : " . $sHostmask);
1902 $sHostmask =~ s/\./\\./g;
1903 $sHostmask =~ s/\*/.*/g;
1904 if ( $event->userhost =~ /^$sHostmask/ ) {
1905 log_message(1,"getNickInfo() $sHostmask matches " . $event->userhost);
1906 $sMatchingUserHandle = $ref->{'nickname'};
1907 if (defined($ref->{'password'})) {
1908 $sMatchingUserPasswd = $ref->{'password'};
1909 }
1910 $iMatchingUserId = $ref->{'id_user'};
1911 my $iMatchingUserLevelId = $ref->{'id_user_level'};
1912 my $sGetLevelQuery = "SELECT * FROM USER_LEVEL WHERE id_user_level=?";
1913 my $sth2 = $dbh->prepare($sGetLevelQuery);
1914 unless ($sth2->execute($iMatchingUserLevelId)) {
1915 log_message(0,"getNickInfo() SQL Error : " . $DBI::errstr . " Query : " . $sGetLevelQuery);
1916 }
1917 else {
1918 while (my $ref2 = $sth2->fetchrow_hashref()) {
1919 $iMatchingUserLevel = $ref2->{'level'};
1920 $iMatchingUserLevelDesc = $ref2->{'description'};
1921 }
1922 }
1923 $iMatchingUserAuth = $ref->{'auth'};
1924 if (defined($ref->{'info1'})) {
1925 $sMatchingUserInfo1 = $ref->{'info1'};
1926 }
1927 if (defined($ref->{'info2'})) {
1928 $sMatchingUserInfo2 = $ref->{'info2'};
1929 }
1930 }
1931 }
1932 }
1933 }
1934
1935 if (defined($iMatchingUserId)) {
1936 log_message(2,"getNickInfo() iMatchingUserId : $iMatchingUserId");
1937 }
1938 else {
1939 log_message(3,"getNickInfo() iMatchingUserId is undefined with this host : " . $event->userhost);
1940 return (undef,undef,undef,undef,undef,undef,undef);
1941 }
1942 if (defined($iMatchingUserLevel)) {
1943 log_message(3,"getNickInfo() iMatchingUserLevel : $iMatchingUserLevel");
1944 }
1945 if (defined($iMatchingUserLevelDesc)) {
1946 log_message(3,"getNickInfo() iMatchingUserLevelDesc : $iMatchingUserLevelDesc");
1947 }
1948 if (defined($iMatchingUserAuth)) {
1949 log_message(3,"getNickInfo() iMatchingUserAuth : $iMatchingUserAuth");
1950 }
1951 if (defined($sMatchingUserHandle)) {
1952 log_message(3,"getNickInfo() sMatchingUserHandle : $sMatchingUserHandle");
1953 }
1954 if (defined($sMatchingUserPasswd)) {
1955 log_message(3,"getNickInfo() sMatchingUserPasswd : $sMatchingUserPasswd");
1956 }
1957 if (defined($sMatchingUserInfo1)) {
1958 log_message(3,"getNickInfo() sMatchingUserInfo1 : $sMatchingUserInfo1");
1959 }
1960 if (defined($sMatchingUserInfo2)) {
1961 log_message(3,"getNickInfo() sMatchingUserInfo2 : $sMatchingUserInfo2");
1962 }
1963
1964 return ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2);
1965}
1966
1967sub checkAuth(@) {
1968 my ($iUserId,$sPassword) = @_;
1969 my $sCheckAuthQuery = "SELECT * FROM USER WHERE id_user=? AND password=PASSWORD(?)";
1970 dbCheckHandle($dbh);
1971 my $sth = $dbh->prepare($sCheckAuthQuery);
1972 unless ($sth->execute($iUserId,$sPassword)) {
1973 log_message(0,"checkAuth() SQL Error : " . $DBI::errstr . " Query : " . $sCheckAuthQuery);
1974 return 0;
1975 }
1976 else {
1977 if (my $ref = $sth->fetchrow_hashref()) {
1978 my $sSetAuthQuery = "UPDATE USER SET auth=1 WHERE id_user=?";
1979 my $sth2 = $dbh->prepare($sSetAuthQuery);
1980 unless ($sth2->execute($iUserId)) {
1981 log_message(0,"checkAuth() SQL Error : " . $DBI::errstr . " Query : " . $sSetAuthQuery);
1982 return 0;
1983 }
1984 return 1;
1985 }
1986 else {
1987 return 0;
1988 }
1989 }
1990}
1991
1992sub dbCheckHandle(@) {
1993 my ($dbh) = @_;
1994 my $sCheckConnectionQuery = "SHOW TABLES";
1995 my $sth = $dbh->prepare($sCheckConnectionQuery);
1996 unless ($sth->execute) {
1997 if ( $DBI::errstr eq 'MySQL server has gone away' ) {
1998 log_message(0,"Database connection lost, reconnecting : $MAIN_PROG_DDBNAME,$MAIN_PROG_DBHOST,$MAIN_PROG_DBPORT,$MAIN_PROG_DBUSER,$MAIN_PROG_DBPASS");
1999 $dbh = dbConnect($MAIN_PROG_DDBNAME,$MAIN_PROG_DBHOST,$MAIN_PROG_DBPORT,$MAIN_PROG_DBUSER,$MAIN_PROG_DBPASS);
2000 }
2001 else {
2002 log_message(0,"dbCheckHandle() SQL Error : " . $DBI::errstr . " Query : " . $sCheckConnectionQuery);
2003 }
2004 }
2005}
2006
2007sub dbAutoLogout(@) {
2008 my ($conn) = @_;
2009 if ( $aperal && (( time - $aperalStartTime ) >= 7200 )) {
2010 log_message(0,"Aperal timeout !!");
2011 $aperal = 0;
2012 }
2013
2014 #log_message(3,"dbAutoLogout()");
2015 #my $sCheckAuthQuery = "SELECT * FROM USER WHERE auth=1";
2016 #dbCheckHandle($dbh);
2017 #my $sth = $dbh->prepare($sCheckAuthQuery);
2018 #unless ($sth->execute) {
2019 # log_message(0,"dbAutoLogout() SQL Error : " . $DBI::errstr . " Query : " . $sCheckAuthQuery);
2020 # return 0;
2021 #}
2022 #else {
2023 # while (my $ref = $sth->fetchrow_hashref()) {
2024 # my $sAuthNick = $ref->{'nickname'};
2025 # log_message(3,"$sAuthNick is auth");
2026 # }
2027 #}
2028 $conn->schedule(300, \&dbAutoLogout);
2029}
2030
2031sub dbLogoutUsers(@) {
2032 my $sLogoutQuery = "UPDATE USER SET auth=0 WHERE auth=1";
2033 dbCheckHandle($dbh);
2034 my $sth = $dbh->prepare($sLogoutQuery);
2035 unless ($sth->execute) {
2036 log_message(0,"dbLogoutUsers() SQL Error : " . $DBI::errstr . "(" . $DBI::err . ") Query : " . $sLogoutQuery);
2037 }
2038 else {
2039 log_message(0,"Logged out all users");
2040 }
2041}
2042
2043sub dbCheckTables(@) {
2044 log_message(3,"DEBUG3: Checking USER table");
2045 my $sLogoutQuery = "SELECT * FROM USER";
2046 dbCheckHandle($dbh);
2047 my $sth = $dbh->prepare($sLogoutQuery);
2048 unless ($sth->execute) {
2049 log_message(0,"dbCheckTables() SQL Error : " . $DBI::errstr . "(" . $DBI::err . ") Query : " . $sLogoutQuery);
2050 if (defined($DBI::err) && ($DBI::err == 1146)) {
2051 log_message(3,"USER table does not exist. Check your SQL installation");
2052 clean_and_exit(undef,1146);
2053 }
2054 }
2055 else {
2056 log_message(3,"USER table exists");
2057 }
2058}
2059
2060sub checkdbConnection(@) {
2061 my ($conn) = @_;
2062 $dbh = dbConnect($MAIN_PROG_DDBNAME,$MAIN_PROG_DBHOST,$MAIN_PROG_DBPORT,$MAIN_PROG_DBUSER,$MAIN_PROG_DBPASS);
2063 unless ($dbh) {
2064 log_message(0,"checkdbConnection() DBI Error : " . $DBI::errstr);
2065 }
2066 $conn->schedule($DB_AUTORECONNECT_DELAY, \&checkdbConnection);
2067}
2068
2069sub Carambar(@) {
2070 my ($conn,$event,$sNick,$sChannel) = @_;
2071 my $nb_blagues = 0;
2072 my $sCheckQuery = "SELECT COUNT(*) AS nb_blagues FROM CARAMBAR";
2073 dbCheckHandle($dbh);
2074 my $sth = $dbh->prepare($sCheckQuery);
2075 unless ($sth->execute ) {
2076 log_message(0,"Carambar() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
2077 }
2078 else {
2079 if (my $ref = $sth->fetchrow_hashref()) {
2080 $nb_blagues = $ref->{'nb_blagues'};
2081 my $current_blague = int(rand($nb_blagues)+1);
2082 log_message(0,"$nb_blagues blagues Carambar in database Random picked : $current_blague");
2083 my $sGetQuery = "SELECT * FROM CARAMBAR";
2084 $sth = $dbh->prepare($sGetQuery);
2085 unless ($sth->execute ) {
2086 log_message(0,"Carambar() SQL Error : " . $DBI::errstr . " Query : " . $sGetQuery);
2087 }
2088 else {
2089 my $i = 0;
2090 while ((my $ref2 = $sth->fetchrow_hashref()) && ($i <= ($current_blague-1))) {
2091 $i++
2092 }
2093 if (my $ref3 = $sth->fetchrow_hashref()) {
2094 my $sCurrentBlague = $ref3->{'blague'};
2095 if (defined($sCurrentBlague)) {
2096 botPrivmsg($conn,$event,$sChannel,"Blague carambar[$current_blague] " . $sCurrentBlague);
2097 }
2098 else {
2099 log_message(0,"Could not retrieve blague :(");
2100 }
2101 }
2102 }
2103 }
2104 }
2105}
2106
2107sub userWhoAmI(@) {
2108 my ($conn,$event,$sNick) = @_;
2109 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2110 if (defined($iMatchingUserId)) {
2111 if ( defined($iMatchingUserAuth) && $iMatchingUserAuth ) {
2112 botNotice($conn,$sNick,"Nick : $sNick");
2113 botNotice($conn,$sNick,"Host : " . $event->userhost);
2114 if (defined($sMatchingUserHandle)) {
2115 botNotice($conn,$sNick,"Handle : $sMatchingUserHandle");
2116 }
2117 if (defined($iMatchingUserLevel)) {
2118 botNotice($conn,$sNick,"Level : " . $iMatchingUserLevelDesc);
2119 }
2120 if (defined($sMatchingUserInfo1)) {
2121 botNotice($conn,$sNick,"Info1 : $sMatchingUserInfo1");
2122 }
2123 if (defined($sMatchingUserInfo2)) {
2124 botNotice($conn,$sNick,"Info2 : $sMatchingUserInfo2");
2125 }
2126 }
2127 else {
2128 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2129 }
2130 }
2131}
2132
2133sub botCheckHosts(@) {
2134 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2135 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2136 if (defined($iMatchingUserId)) {
2137 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2138 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_ADMINISTRATOR)) {
2139 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2140 my $ssSQLQuery = "SELECT userhost,count(userhost) as nbHosts FROM CHANNEL,CHANNEL_LOG WHERE CHANNEL.id_channel=CHANNEL_LOG.id_channel AND CHANNEL.name=? AND nick LIKE ? AND (event_type='public' OR event_type='caction' OR event_type='join' OR event_type='part') GROUP BY userhost HAVING COUNT(nbHosts)>5 ORDER by nbHosts DESC LIMIT 10";
2141 dbCheckHandle($dbh);
2142 my $sth = $dbh->prepare($ssSQLQuery);
2143 if (substr($tArgs[0], 0, 1) eq '#') {
2144 unless ($sth->execute($tArgs[0],$tArgs[1])) {
2145 log_message(0,"botCheckHost() SQL Error : " . $DBI::errstr . " Query : " . $ssSQLQuery);
2146 }
2147 else {
2148 my $i = 0;
2149 while (my $ref = $sth->fetchrow_hashref()) {
2150 if ( $i == 0 ) {
2151 botPrivmsg($conn,$event,$sChannel,$tArgs[1] . " user\@host " . $tArgs[0]);
2152 }
2153 my $userhost = $ref->{'userhost'};
2154 my $nbHosts = $ref->{'nbHosts'};
2155 botPrivmsg($conn,$event,$sChannel,"$userhost [$nbHosts]");
2156 sleep 1;
2157 $i++;
2158 }
2159 if ( $i == 0 ) {
2160 botPrivmsg($conn,$event,$sChannel,"Pas de résultats pour " . $tArgs[1] . " user\@host " . $tArgs[0]);
2161 }
2162 else {
2163 botPrivmsg($conn,$event,$sChannel,"$i résultats pour " . $tArgs[1]. " (limite 10)");
2164 }
2165 }
2166 }
2167 else {
2168 unless ($sth->execute($sChannel,$tArgs[0])) {
2169 log_message(0,"botCheckHost() SQL Error : " . $DBI::errstr . " Query : " . $ssSQLQuery);
2170 }
2171 else {
2172 my $i = 0;
2173 while (my $ref = $sth->fetchrow_hashref()) {
2174 if ( $i == 0 ) {
2175 botPrivmsg($conn,$event,$sChannel,$tArgs[0] . " user\@host $sChannel");
2176 }
2177 my $userhost = $ref->{'userhost'};
2178 my $nbHosts = $ref->{'nbHosts'};
2179 botPrivmsg($conn,$event,$sChannel,"$userhost [$nbHosts]");
2180 sleep 1;
2181 $i++;
2182 }
2183 if ( $i == 0 ) {
2184 botPrivmsg($conn,$event,$sChannel,"Pas de résultats pour " . $tArgs[0] . " user\@host $sChannel");
2185 }
2186 else {
2187 botPrivmsg($conn,$event,$sChannel,"$i résultats pour " . $tArgs[0] . " (limite 10)");
2188 }
2189 }
2190 }
2191 }
2192 else {
2193 botNotice($conn,$sNick,"Syntaxe .checkhosts [#channel] <nick>");
2194 }
2195 }
2196 else {
2197 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2198 }
2199 }
2200 else {
2201 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2202 }
2203 }
2204}
2205
2206sub botChannelSQL(@) {
2207 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2208 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2209 if (defined($iMatchingUserId)) {
2210 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2211 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_OWNER)) {
2212 my $ssSQLQuery = join(" ",@tArgs);
2213 dbCheckHandle($dbh);
2214 my $sth = $dbh->prepare($ssSQLQuery);
2215 unless ($sth->execute) {
2216 log_message(0,"botChannelSQL() SQL Error : " . $DBI::errstr . " Query : " . $ssSQLQuery);
2217 }
2218 else {
2219 my $sAuthUserStr;
2220 if (my $ref = $sth->fetchrow_hashref()) {
2221 botNotice($conn,$sNick,"Une ligne fetched");
2222 }
2223 }
2224 }
2225 else {
2226 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2227 }
2228 }
2229 else {
2230 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2231 }
2232 }
2233}
2234
2235sub botChannelSetTopic(@) {
2236 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2237 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2238 if (defined($iMatchingUserId)) {
2239 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2240 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
2241 my $iChannelUserLevel = getUserChannelLevel($sChannel,$iMatchingUserId);
2242 if ( $iChannelUserLevel >= 50 ) {
2243 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2244 $conn->sl("TOPIC " . $sChannel . " :($sMatchingUserHandle) " . join(" ",@tArgs));
2245 logBot($conn,$event,$sChannel,"topic",@tArgs);
2246 }
2247 else {
2248 botNotice($conn,$sNick,"Syntaxe : topic <topic>");
2249 }
2250 }
2251 else {
2252 botNotice($conn,$sNick,"Votre accès est insufisant pour utiliser cette commande");
2253 }
2254 }
2255 else {
2256 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2257 }
2258 }
2259 else {
2260 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2261 }
2262 }
2263}
2264
2265sub botChannelUserAccess(@) {
2266
2267}
2268
2269sub botSyntaxChannelModinfo(@) {
2270 my ($conn,$sNick) = @_;
2271 botNotice($conn,$sNick,"Syntaxe : modinfo [#channel] <ACCESS|AUTOMODE|GREET> <utilisateur> <valeur>");
2272 botNotice($conn,$sNick,"Avec la variable ACCESS vous pouvez changer le niveau d'un utilisateur. De 1 Ã ( votre_niveau - 1 )");
2273 botNotice($conn,$sNick,"La variable AUTOMODE permet de définir NONE, VOICE or OP");
2274 botNotice($conn,$sNick,"La variable GREET permet de définir le message d'accueil lorsque l'utilisateur entre dans le canal");
2275}
2276
2277sub botChannelModinfo(@) {
2278 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2279 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2280 if (defined($iMatchingUserId)) {
2281 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2282 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
2283 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2284 if (substr($tArgs[0], 0, 1) eq '#') {
2285 $sChannel = $tArgs[0];
2286 shift(@tArgs);
2287 }
2288 my $iChannelId = getIdChannel($sChannel);
2289 if (defined($iChannelId)) {
2290 my $iChannelUserLevel = getUserChannelLevel($sChannel,$iMatchingUserId);
2291 if ( $iChannelUserLevel >= 400 ) {
2292 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2293 if ($tArgs[0] =~ /^access$/i) {
2294 if (defined($tArgs[1]) && ($tArgs[1] ne "") && defined($tArgs[2]) && ($tArgs[2] =~ /[0-9]+/)) {
2295 my $iChannelUserLevelMod = getUserChannelLevelByName($sChannel,$tArgs[1]);
2296 if ( $iChannelUserLevelMod == 0 ) {
2297 botNotice($conn,$sNick,"Aucune correspondance trouvée pour " . $tArgs[1]);
2298 }
2299 elsif ( ($iChannelUserLevel == 500) && ($iChannelUserLevelMod == 500) ) {
2300 botNotice($conn,$sNick,"Vous êtes propriétaire du channel, vous ne pouvez pas modifier votre accès");
2301 }
2302 elsif ( $tArgs[2] < $iChannelUserLevel ) {
2303 if ( $iChannelUserLevelMod == $tArgs[2]) {
2304 botNotice($conn,$sNick,"L'accès de " . $tArgs[1] . " est inchangé : $iChannelUserLevelMod");
2305 }
2306 else {
2307 my $sQuery = "UPDATE USER,USER_CHANNEL,CHANNEL SET level=? WHERE CHANNEL.id_channel=USER_CHANNEL.id_channel AND USER.id_user=USER_CHANNEL.id_user AND USER.nickname=? AND CHANNEL.name=?";
2308 my $sth = $dbh->prepare($sQuery);
2309 unless ($sth->execute($tArgs[2],$tArgs[1],$sChannel) ) {
2310 log_message(0,"botChannelModinfo() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
2311 }
2312 else {
2313 botNotice($conn,$sNick,"Accès modifié pour " . $tArgs[1] . " $iChannelUserLevelMod => " . $tArgs[2] . " on $sChannel");
2314 logBot($conn,$event,$sChannel,"modinfo",@tArgs);
2315 }
2316 }
2317 }
2318 else {
2319 botNotice($conn,$sNick,"Vous ne pouvez pas donner un accès supérieur au votre sur $sChannel");
2320 }
2321 }
2322 else {
2323 botSyntaxChannelModinfo($conn,$sNick);
2324 }
2325 }
2326 elsif ($tArgs[0] =~ /^automode$/i) {
2327 if (defined($tArgs[1]) && ($tArgs[1] ne "") && defined($tArgs[2]) && ($tArgs[2] ne "")) {
2328 my $iChannelUserLevelMod = getUserChannelLevelByName($sChannel,$tArgs[1]);
2329 if ( $iChannelUserLevelMod == 0 ) {
2330 botNotice($conn,$sNick,"Aucune correspondance trouvée pour " . $tArgs[1]);
2331 }
2332 elsif ( $iChannelUserLevelMod < $iChannelUserLevel ) {
2333 my $sAutomode = undef;
2334 if ( $tArgs[2] =~/op/i) {
2335 $sAutomode = "+o";
2336 }
2337 elsif ( $tArgs[2] =~/voice/i) {
2338 $sAutomode = "+v";
2339 }
2340 elsif ( $tArgs[2] =~/none/i) {
2341 $sAutomode = "";
2342 }
2343 if (defined($sAutomode)) {
2344 if ($sAutomode eq "" ) {
2345 $sAutomode = undef;
2346 }
2347 my $sQuery = "UPDATE USER,USER_CHANNEL,CHANNEL SET automode=? WHERE CHANNEL.id_channel=USER_CHANNEL.id_channel AND USER.id_user=USER_CHANNEL.id_user AND USER.nickname=? AND CHANNEL.name=?";
2348 my $sth = $dbh->prepare($sQuery);
2349 unless ($sth->execute($sAutomode,$tArgs[1],$sChannel) ) {
2350 log_message(0,"botChannelModinfo() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
2351 }
2352 else {
2353 botNotice($conn,$sNick,"Automode modifié pour " . $tArgs[1] . " " . $tArgs[2] . " on $sChannel");
2354 logBot($conn,$event,$sChannel,"modinfo",@tArgs);
2355 }
2356 }
2357 else {
2358 botSyntaxChannelModinfo($conn,$sNick);
2359 }
2360 }
2361 else {
2362 botNotice($conn,$sNick,"Vous ne pouvez pas modifier l'automode pour un accès supérieur au votre sur $sChannel");
2363 }
2364 botNotice($conn,$sNick,"AUTOMODE $sChannel " . join(" ",@tArgs));
2365 }
2366 else {
2367 botSyntaxChannelModinfo($conn,$sNick);
2368 }
2369 }
2370 elsif ($tArgs[0] =~ /^greet$/i) {
2371 if (defined($tArgs[1]) && ($tArgs[1] ne "") && defined($tArgs[2]) && ($tArgs[2] ne "")) {
2372 my $iChannelUserLevelMod = getUserChannelLevelByName($sChannel,$tArgs[1]);
2373 if ( $iChannelUserLevelMod == 0 ) {
2374 botNotice($conn,$sNick,"Aucune correspondance trouvée pour " . $tArgs[1]);
2375 }
2376 elsif ( $iChannelUserLevelMod < $iChannelUserLevel ) {
2377 shift(@tArgs);
2378 my $sHandleMod = $tArgs[0];
2379 shift(@tArgs);
2380 my $sGreetMsg = join(" ",@tArgs);
2381 my $sQuery = "UPDATE USER,USER_CHANNEL,CHANNEL SET greet=? WHERE CHANNEL.id_channel=USER_CHANNEL.id_channel AND USER.id_user=USER_CHANNEL.id_user AND USER.nickname=? AND CHANNEL.name=?";
2382 my $sth = $dbh->prepare($sQuery);
2383 unless ($sth->execute($sGreetMsg,$sHandleMod,$sChannel) ) {
2384 log_message(0,"botChannelModinfo() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
2385 }
2386 else {
2387 botNotice($conn,$sNick,"Message d'accueil modifié pour $sHandleMod : $sGreetMsg on $sChannel");
2388 logBot($conn,$event,$sChannel,"modinfo",@tArgs);
2389 }
2390 }
2391 else {
2392 botNotice($conn,$sNick,"Vous ne pouvez pas modifier le message d'accueil pour un accès supérieur au votre sur $sChannel");
2393 }
2394 }
2395 else {
2396 botSyntaxChannelModinfo($conn,$sNick);
2397 }
2398 }
2399 else {
2400 botSyntaxChannelModinfo($conn,$sNick);
2401 }
2402 }
2403 else {
2404 botSyntaxChannelModinfo($conn,$sNick);
2405 }
2406 }
2407 else {
2408 botNotice($conn,$sNick,"Votre accès est insufisant pour utiliser cette commande");
2409 }
2410 }
2411 else {
2412 botNotice($conn,$sNick,"Le channel $sChannel n'est pas enregistré");
2413 }
2414 }
2415 else {
2416 botSyntaxChannelModinfo($conn,$sNick);
2417 }
2418 }
2419 else {
2420 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2421 }
2422 }
2423 else {
2424 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2425 }
2426 }
2427}
2428
2429sub botChannelKickUser(@) {
2430 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2431 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2432 if (defined($iMatchingUserId)) {
2433 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2434 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
2435 my $iChannelUserLevel = getUserChannelLevel($sChannel,$iMatchingUserId);
2436 if ( $iChannelUserLevel >= 50 ) {
2437 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2438 my $sNickToKick = $tArgs[0];
2439 shift(@tArgs);
2440 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2441 $conn->sl("KICK $sChannel $sNickToKick :($sMatchingUserHandle) " . join(" ",@tArgs));
2442 logBot($conn,$event,$sChannel,"kick",@tArgs);
2443 }
2444 else {
2445 $conn->sl("KICK $sChannel $sNickToKick :($sMatchingUserHandle) Pas de raison précisée");
2446 logBot($conn,$event,$sChannel,"kick",("Pas de raison précisée"));
2447 }
2448 }
2449 else {
2450 botNotice($conn,$sNick,"Syntaxe : kick <nick>");
2451 }
2452 }
2453 else {
2454 botNotice($conn,$sNick,"Votre accès est insufisant pour utiliser cette commande");
2455 }
2456 }
2457 else {
2458 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2459 }
2460 }
2461 else {
2462 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2463 }
2464 }
2465}
2466
2467sub botOpChanNick(@) {
2468 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2469 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2470 if (defined($iMatchingUserId)) {
2471 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2472 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
2473 my $iChannelUserLevel = getUserChannelLevel($sChannel,$iMatchingUserId);
2474 if ( $iChannelUserLevel >= 100 ) {
2475 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2476 $conn->sl("MODE " . $sChannel . " +o " . $tArgs[0]);
2477 logBot($conn,$event,$sChannel,"op",@tArgs);
2478 }
2479 else {
2480 botNotice($conn,$sNick,"Syntaxe : op <nick>");
2481 }
2482 }
2483 else {
2484 botNotice($conn,$sNick,"Votre accès est insufisant pour utiliser cette commande");
2485 }
2486 }
2487 else {
2488 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2489 }
2490 }
2491 else {
2492 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2493 }
2494 }
2495}
2496
2497sub botDeopChanNick(@) {
2498 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2499 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2500 if (defined($iMatchingUserId)) {
2501 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2502 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
2503 my $iChannelUserLevel = getUserChannelLevel($sChannel,$iMatchingUserId);
2504 if ( $iChannelUserLevel >= 100 ) {
2505 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2506 $conn->sl("MODE " . $sChannel . " -o " . $tArgs[0]);
2507 logBot($conn,$event,$sChannel,"deop",@tArgs);
2508 }
2509 else {
2510 botNotice($conn,$sNick,"Syntaxe : deop <nick>");
2511 }
2512 }
2513 else {
2514 botNotice($conn,$sNick,"Votre accès est insufisant pour utiliser cette commande");
2515 }
2516 }
2517 else {
2518 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2519 }
2520 }
2521 else {
2522 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2523 }
2524 }
2525}
2526
2527sub botVoiceChanNick(@) {
2528 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2529 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2530 if (defined($iMatchingUserId)) {
2531 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2532 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
2533 my $iChannelUserLevel = getUserChannelLevel($sChannel,$iMatchingUserId);
2534 if ( $iChannelUserLevel >= 25 ) {
2535 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2536 $conn->sl("MODE " . $sChannel . " +v " . $tArgs[0]);
2537 logBot($conn,$event,$sChannel,"voice",@tArgs);
2538 }
2539 else {
2540 botNotice($conn,$sNick,"Syntaxe : voice <nick>");
2541 }
2542 }
2543 else {
2544 botNotice($conn,$sNick,"Votre accès est insufisant pour utiliser cette commande");
2545 }
2546 }
2547 else {
2548 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2549 }
2550 }
2551 else {
2552 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2553 }
2554 }
2555}
2556
2557sub botDevoiceChanNick(@) {
2558 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2559 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2560 if (defined($iMatchingUserId)) {
2561 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2562 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
2563 my $iChannelUserLevel = getUserChannelLevel($sChannel,$iMatchingUserId);
2564 if ( $iChannelUserLevel >= 25 ) {
2565 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2566 $conn->sl("MODE " . $sChannel . " -v " . $tArgs[0]);
2567 logBot($conn,$event,$sChannel,"devoice",@tArgs);
2568 }
2569 else {
2570 botNotice($conn,$sNick,"Syntaxe : devoice <nick>");
2571 }
2572 }
2573 else {
2574 botNotice($conn,$sNick,"Votre accès est insufisant pour utiliser cette commande");
2575 }
2576 }
2577 else {
2578 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2579 }
2580 }
2581 else {
2582 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2583 }
2584 }
2585}
2586
2587sub botChannelPart(@) {
2588 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2589 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2590 if (defined($iMatchingUserId)) {
2591 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2592
2593 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
2594 if ( (defined($tArgs[0]) && ($tArgs[0] eq $sChannel)) || (!defined($tArgs[0])) || (defined($tArgs[0]) && ($tArgs[0] eq "")) ) {
2595 my $iChannelUserLevel = getUserChannelLevel($sChannel,$iMatchingUserId);
2596 if ( $iChannelUserLevel >= 500 ) {
2597 $conn->sl("PART $sChannel");
2598 logBot($conn,$event,$sChannel,"part",@tArgs);
2599 }
2600 elsif ($iMatchingUserLevel <= $LEVEL_ADMINISTRATOR) {
2601 $conn->sl("PART $sChannel");
2602 push @tArgs,"(mediabot admin)";
2603 logBot($conn,$event,$sChannel,"part",@tArgs);
2604 }
2605 else {
2606 botNotice($conn,$sNick,"Votre accès est insufisant pour utiliser cette commande");
2607 }
2608 }
2609 else {
2610 my $iChannelUserLevel = getUserChannelLevel($tArgs[0],$iMatchingUserId);
2611 if ( $iChannelUserLevel >= 500 ) {
2612 $conn->sl("PART " . $tArgs[0]);
2613 logBot($conn,$event,$sChannel,"part",@tArgs);
2614 }
2615 elsif ($iMatchingUserLevel <= $LEVEL_ADMINISTRATOR) {
2616 $conn->sl("PART " . $tArgs[0]);
2617 push @tArgs,"(mediabot admin)";
2618 logBot($conn,$event,$sChannel,"part",@tArgs);
2619 }
2620 else {
2621 botNotice($conn,$sNick,"Votre accès est insufisant pour utiliser cette commande");
2622 }
2623 }
2624 }
2625 else {
2626 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2627 }
2628 }
2629 else {
2630 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2631 }
2632 }
2633}
2634
2635sub botChannelJoin(@) {
2636 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2637 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2638 if (defined($iMatchingUserId)) {
2639 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2640 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
2641 if ( (defined($tArgs[0])) && ($tArgs[0] ne "")) {
2642 my $iChannelUserLevel = getUserChannelLevel($tArgs[0],$iMatchingUserId);
2643 if ( $iChannelUserLevel >= 450 ) {
2644 if ( (defined($tArgs[1])) && ($tArgs[1] ne "")) {
2645 $conn->sl("JOIN " . $tArgs[0] . " :" . $tArgs[1]);
2646 }
2647 else {
2648 $conn->sl("JOIN " . $tArgs[0]);
2649 }
2650 logBot($conn,$event,$sChannel,"join",@tArgs);
2651 }
2652 elsif ($iMatchingUserLevel <= $LEVEL_ADMINISTRATOR) {
2653 if ( (defined($tArgs[1])) && ($tArgs[1] ne "")) {
2654 $conn->sl("JOIN " . $tArgs[0] . " :" . $tArgs[1]);
2655 }
2656 else {
2657 $conn->sl("JOIN " . $tArgs[0]);
2658 }
2659 push @tArgs,"(mediabot admin)";
2660 logBot($conn,$event,$sChannel,"join",@tArgs);
2661 }
2662 else {
2663 botNotice($conn,$sNick,"Votre accès est insufisant pour utiliser cette commande");
2664 }
2665 }
2666 else {
2667 botNotice($conn,$sNick,"Syntaxe : join #channel [key]");
2668 }
2669 }
2670 else {
2671 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2672 }
2673 }
2674 else {
2675 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2676 }
2677 }
2678}
2679
2680sub botGetAuthUser(@) {
2681 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2682 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2683 if (defined($iMatchingUserId)) {
2684 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2685 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_ADMINISTRATOR)) {
2686 my $sGetAuthUsers = "SELECT * FROM USER WHERE auth=1";
2687 dbCheckHandle($dbh);
2688 my $sth = $dbh->prepare($sGetAuthUsers);
2689 unless ($sth->execute) {
2690 log_message(0,"botGetAuthUser() SQL Error : " . $DBI::errstr . " Query : " . $sGetAuthUsers);
2691 }
2692 else {
2693 my $sAuthUserStr;
2694 while (my $ref = $sth->fetchrow_hashref()) {
2695 $sAuthUserStr .= $ref->{'nickname'} . " (" . $iMatchingUserLevelDesc . ") ";
2696 }
2697 botNotice($conn,$sNick,"Authenticated users : " . $sAuthUserStr);
2698 }
2699 }
2700 else {
2701 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2702 }
2703 }
2704 else {
2705 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2706 }
2707 }
2708}
2709
2710sub botGetUsers(@) {
2711 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2712 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2713 if (defined($iMatchingUserId)) {
2714 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2715 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_MASTER)) {
2716 my $sGetRegUsers = "SELECT count(*) AS nb_reg_users FROM USER";
2717 dbCheckHandle($dbh);
2718 my $sth = $dbh->prepare($sGetRegUsers);
2719 unless ($sth->execute) {
2720 log_message(0,"botGetUsers() SQL Error : " . $DBI::errstr . " Query : " . $sGetRegUsers);
2721 }
2722 else {
2723 my $iRegUsers;
2724 while (my $ref = $sth->fetchrow_hashref()) {
2725 $iRegUsers .= $ref->{'nb_reg_users'};
2726 }
2727 botNotice($conn,$sNick,"Registered users in database : " . $iRegUsers);
2728 $sGetRegUsers = "SELECT * FROM USER,USER_LEVEL WHERE USER.id_user_level=USER_LEVEL.id_user_level ORDER BY level";
2729 dbCheckHandle($dbh);
2730 my $sth2 = $dbh->prepare($sGetRegUsers);
2731 unless ($sth2->execute) {
2732 log_message(0,"botGetUsers() SQL Error : " . $DBI::errstr . " Query : " . $sGetRegUsers);
2733 }
2734 else {
2735 my $j = 1;
2736 while (my $ref2 = $sth2->fetchrow_hashref()) {
2737 my $iColumnWidth = 15;
2738 my $sSpacer;
2739 for (my $i=0;$i<($iColumnWidth-length($ref2->{'nickname'}));$i++) { $sSpacer .= " "; }
2740 botNotice($conn,$sNick,$ref2->{'nickname'} . $sSpacer . $ref2->{'description'});
2741 if (( $j % 3 )==0) { sleep(1); }
2742 $j++;
2743 }
2744 }
2745 }
2746 }
2747 else {
2748 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2749 }
2750 }
2751 else {
2752 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2753 }
2754 }
2755}
2756
2757sub botServerLoad(@) {
2758 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2759 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2760 if (defined($iMatchingUserId)) {
2761 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2762 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_MASTER)) {
2763 unless (open SERVERLOAD, "uptime | ") {
2764 log_message(0,"Could not guess server load");
2765 }
2766 else {
2767 my $line;
2768 if (defined($line=<SERVERLOAD>)) {
2769 chomp($line);
2770 log_message(2,"load : $line");
2771 $line =~ s/^.*load average\:(.*)$/$1/g;
2772 $line =~ s/,/ /g;
2773 botNotice($conn,$sNick,"load average:$line");
2774 }
2775 close SERVERLOAD;
2776 }
2777 }
2778 else {
2779 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2780 }
2781 }
2782 else {
2783 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2784 }
2785 }
2786 else {
2787 log_message(0,"$sNick issued unauthorized botServerLoad command");
2788 }
2789}
2790
2791sub botWikipedia(@) {
2792 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2793 my $sKeyWords = "";
2794 foreach my $sWord (@tArgs) {
2795 $sKeyWords .= ucfirst ($sWord) . "_";
2796 }
2797 $sKeyWords =~ s/_$//;
2798 unless (defined($sKeyWords)) {
2799 log_message(0,"Undefined key words");
2800 }
2801 else {
2802 my $sWikipediaCommand = '/usr/local/bin/wikipedia -l fr ' . $sKeyWords . ' | egrep -v "^\s*$|^\{" | head -6 |';
2803 unless ( open WIKIPEDIA, "$sWikipediaCommand") {
2804 log_message(0,"Could not issue $sWikipediaCommand command");
2805 }
2806 else {
2807 my $sLine;
2808 while (defined($sLine=<WIKIPEDIA>)) {
2809 chomp($sLine);
2810 botPrivmsg($conn,$event,$sChannel,$sLine);
2811 sleep 1;
2812 }
2813 close WIKIPEDIA;
2814 }
2815 }
2816}
2817
2818sub botStr2Time(@) {
2819 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2820 my $sAnswer = str2time(join(" ",@tArgs));
2821 if (defined($sAnswer) && ($sAnswer ne "")) {
2822 botPrivmsg($conn,$event,$sChannel,$sNick . ' ' . $sAnswer);
2823 }
2824 else {
2825 botPrivmsg($conn,$event,$sChannel,$sNick . ' I could not convert to timestamp.');
2826 }
2827}
2828
2829sub botTime2Str(@) {
2830 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2831 my $sAnswer = time2str("%d/%m/%Y %H:%M:%S",$tArgs[0]);
2832 if (defined($sAnswer) && ($sAnswer ne "")) {
2833 botPrivmsg($conn,$event,$sChannel,$sNick . ' ' . $sAnswer);
2834 }
2835 else {
2836 botPrivmsg($conn,$event,$sChannel,$sNick . ' I could not convert to date string.');
2837 }
2838}
2839
2840sub botBc(@) {
2841 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2842 my $bcCommand = join(" ",@tArgs) . "\n";
2843 unless (open BC, "/bin/echo \"$bcCommand\" | bc -l -q |") {
2844 log_message(0,"bc error");
2845 }
2846 else {
2847 my $sLine;
2848 while(defined($sLine=<BC>)) {
2849 chomp($sLine);
2850 log_message(0,"bc result: " . $sLine);
2851 botPrivmsg($conn,$event,$sChannel,$sNick . " " . $sLine);
2852 }
2853 }
2854}
2855
2856sub botUserLogin(@) {
2857 my ($conn,$event,$sNick,@tArgs) = @_;
2858 #login <username> <password>
2859 if (defined($tArgs[0]) && ($tArgs[0] ne "") && defined($tArgs[1]) && ($tArgs[1] ne "")) {
2860 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2861 if (defined($iMatchingUserId)) {
2862 unless (defined($sMatchingUserPasswd)) {
2863 botNotice($conn,$sNick,"Your password is not set. Use /msg " . $conn->nick() . " pass <new_password>");
2864 }
2865 else {
2866 if (checkAuth($iMatchingUserId,$tArgs[1])) {
2867 botNotice($conn,$sNick,"Login successfull as $sMatchingUserHandle (Level : $iMatchingUserLevelDesc)");
2868 my $sNoticeMsg = getEventHostmask($event) . " Successfull login as $sMatchingUserHandle (Level : $iMatchingUserLevelDesc)";
2869 log_message(2,$sNoticeMsg);
2870 noticeConsoleChan($conn,0,$sNoticeMsg);
2871 }
2872 else {
2873 botNotice($conn,$sNick,"Login failed (Bad password).");
2874 my $sNoticeMsg = getEventHostmask($event) . " Failed login (Bad password)";
2875 log_message(2,$sNoticeMsg);
2876 noticeConsoleChan($conn,0,$sNoticeMsg);
2877 }
2878 }
2879 }
2880 else {
2881 # TBD : add email alert to global configuration
2882 # log_message(2,"\$event Dump: " . Dumper($event));
2883 my $sNoticeMsg = getEventHostmask($event) . " Failed login (hostmask may not be present in database)";
2884 log_message(2,$sNoticeMsg);
2885 noticeConsoleChan($conn,0,$sNoticeMsg);
2886 }
2887 }
2888 else {
2889 botNotice($conn,$sNick,"Syntax error : /msg " . $conn->nick() . " login <username> <password>");
2890 }
2891}
2892
2893sub botDumpCmd(@) {
2894 my ($conn,$event,$sNick,@tArgs) = @_;
2895 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
2896 if (defined($iMatchingUserId)) {
2897 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
2898 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_OWNER)) {
2899 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2900 my $sDumpCommand = join(" ",@tArgs);
2901 log_message(0,"$sNick issued a dump command : $sDumpCommand");
2902 #my $sNoticeMsg = getEventHostmask($event) . " issued a dump command : $sDumpCommand";
2903 #noticeConsoleChan($conn,0,$sNoticeMsg);
2904 $conn->sl($sDumpCommand);
2905 logBot($conn,$event,undef,"dump",@tArgs);
2906 }
2907 else {
2908 botPrivmsg($conn,$event,$sNick,"Syntax error : dump <irc raw command>");
2909 }
2910 }
2911 else {
2912 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
2913 }
2914 }
2915 else {
2916 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
2917 }
2918 }
2919}
2920
2921sub botRR(@) {
2922 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2923 unless ( ( $#tArgs >= 0 ) && ( $tArgs[0] ne "" )) {
2924 botNotice($conn,$sNick,"Usage : !rr <position de la balle dans le 6 coups>");
2925 }
2926 else {
2927 my $position = $tArgs[0];
2928 if ( ($position < 1) || ($position > 6) ) {
2929 botPrivmsg($conn,$event,$sChannel,"Hey $sNick c'est un 6 coups qu'est-ce tu fais ??");
2930 }
2931 else {
2932 my $shoot = int(rand(6)+1);
2933 if ( $shoot == $position ) {
2934 $conn->sl("KICK " . $sChannel . " " . $sNick . " :Boom t'es mort");
2935 }
2936 else {
2937 my $sAnswer = "*Click* ($shoot)";
2938 if ( (( $shoot > $position ) && (( $shoot - $position ) == 1)) || (( $shoot < $position ) && (( $position - $shoot ) == 1)) ) {
2939 $sAnswer .= " Pas loin.. :p";
2940 }
2941 botPrivmsg($conn,$event,$sChannel,$sAnswer);
2942 }
2943 }
2944 }
2945}
2946
2947sub mbCAC(@) {
2948 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
2949
2950 my $sCACCommand = $MAIN_PROG_BIN_DIR . '/plugins/cac40.sh';
2951 unless ( open CAC40, "$sCACCommand |") {
2952 log_message(0,"Could not issue $sCACCommand command");
2953 }
2954 else {
2955 my $sLine;
2956 while (defined($sLine=<CAC40>)) {
2957 chomp($sLine);
2958 $sLine = "CAC40 : " . $sLine;
2959 botPrivmsg($conn,$event,$sChannel,$sLine);
2960 sleep 1;
2961 }
2962 close CAC40;
2963 }
2964
2965}
2966
2967sub botInsulteChan(@) {
2968 my ($conn,$event,$sChannel,@tArgs) = @_;
2969 my $sQuery;
2970 dbCheckHandle($dbh);
2971 unless (defined($tArgs[0]) && ($tArgs[0] ne "")) {
2972 $sQuery = "SELECT * FROM INSULTE ORDER BY rand() LIMIT 1";
2973 my $sth = $dbh->prepare($sQuery);
2974 unless ($sth->execute ) {
2975 log_message(0,"botInsulteChan() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
2976 }
2977 else {
2978 if (my $ref = $sth->fetchrow_hashref()) {
2979 my $sCurrentInsulte = $ref->{'insulte'};
2980 my $iId_insulte = $ref->{'id_insulte'};
2981 if (defined($sCurrentInsulte) && ( $sCurrentInsulte ne "" )) {
2982 botPrivmsg($conn,$event,$sChannel,"[$iId_insulte] $sCurrentInsulte");
2983 }
2984 }
2985 else {
2986 botPrivmsg($conn,$event,$sChannel,"Insulte non trouvée");
2987 log_message(0,"Could not retrieve insulte :( no args");
2988 }
2989 }
2990 }
2991 else {
2992 my $id_insulte = int($tArgs[0]);
2993 $sQuery = "SELECT * FROM INSULTE WHERE id_insulte=?";
2994 my $sth = $dbh->prepare($sQuery);
2995 unless ($sth->execute($id_insulte)) {
2996 log_message(0,"botInsulteChan() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
2997 }
2998 else {
2999 if (my $ref = $sth->fetchrow_hashref()) {
3000 my $sCurrentInsulte = $ref->{'insulte'};
3001 my $iId_insulte = $ref->{'id_insulte'};
3002 if (defined($sCurrentInsulte) && ( $sCurrentInsulte ne "" )) {
3003 botPrivmsg($conn,$event,$sChannel,"[$iId_insulte] $sCurrentInsulte");
3004 }
3005 }
3006 else {
3007 botPrivmsg($conn,$event,$sChannel,"Insulte non trouvée");
3008 log_message(0,"Could not retrieve insulte :(");
3009 }
3010 }
3011 }
3012}
3013
3014sub botAddInsulte(@) {
3015 my ($conn,$event,$sChannel,@tArgs)= @_;
3016 my $sInsulte = join (" ",@tArgs);
3017 $sInsulte =~ s/'/\\'/g;
3018 my $sQuery = "INSERT INTO INSULTE (insulte) VALUES ( ? )";
3019 dbCheckHandle($dbh);
3020 my $sth = $dbh->prepare($sQuery);
3021 unless ($sth->execute($sInsulte) ) {
3022 log_message(0,"botAddInsulte() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
3023 }
3024 else {
3025 my $iInsulteCount = $sth->{mysql_insertid};
3026 if (defined($iInsulteCount)) {
3027 botPrivmsg($conn,$event,$sChannel,"Insulte ajoutée :) [" . $iInsulteCount . "]");
3028 }
3029 else {
3030 log_message(0,"\$iInsulteCount is undefined !");
3031 }
3032 }
3033}
3034
3035sub botAddIvan(@) {
3036 my ($conn,$event,$sChannel,@tArgs)= @_;
3037 my $sIvan = join (" ",@tArgs);
3038 $sIvan =~ s/'/\\'/g;
3039 my $sQuery = "INSERT INTO IVAN (ivan) VALUES ( ? )";
3040 dbCheckHandle($dbh);
3041 my $sth = $dbh->prepare($sQuery);
3042 unless ($sth->execute($sIvan) ) {
3043 log_message(0,"botAddIvan() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
3044 }
3045 else {
3046 my $iIvanCount = $sth->{mysql_insertid};
3047 if (defined($iIvanCount)) {
3048 botPrivmsg($conn,$event,$sChannel,"Quote Ivan ajoutée :) [" . $iIvanCount . "]");
3049 }
3050 else {
3051 log_message(0,"\$iIvanCount is undefined !");
3052 }
3053 }
3054}
3055
3056sub scrabble(@) {
3057 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3058 if ( $scrabbleStatus ) {
3059 my @letters = ('A','A','A','A','A','A','A','A','A','B','B','C','C','D','D','D','E','E','E','E','E','E','E','E','E','E','E','E','E','E','E','F','F','G','G','H','H','I','I','I','I','I','I','I','I','J','K','L','L','L','L','L','M','M','M','N','N','N','N','N','N','O','O','O','O','O','O','P','P','Q','R','R','R','R','R','R','S','S','S','S','S','S','T','T','T','T','T','T','U','U','U','U','U','U','V','V','W','X','Y','Z');
3060 my $sPick = "";
3061 my $sPickDisplay = "";
3062 my $i = 0;
3063 for ($i=0;$i<$SCRABBLE_PICK_LEN;$i++) {
3064 my $c_letter = $letters[rand($#letters + 1)];
3065 $sPick .= $c_letter;
3066 $sPickDisplay .= "$c_letter ";
3067 }
3068 %scrabbleScores = ();
3069 $scrabbleIsWon = 0;
3070 $lastScrabblePick = $sPick;
3071 $lastScrabbleLen = 0;
3072 $scrabbleSolution = scrabbleFind($conn,$event,$sNick,$sChannel,$lastScrabblePick);
3073 if ( $scrabbleSolution =~ /\([0-9]+\)/) {
3074 $scrabbleSolutionLen = $scrabbleSolution;
3075 $scrabbleSolutionLen =~ s/^.*\(([0-9]+)\).*$/$1/;
3076 }
3077 else {
3078 $scrabbleSolutionLen = 0;
3079 }
3080 log_message(0,"Solution : $scrabbleSolution Longueur : $scrabbleSolutionLen");
3081 botPrivmsg($conn,$event,"$sChannel","Scrabble : " . $sPickDisplay . " Il y a au moins un mot de $scrabbleSolutionLen lettres");
3082
3083# if ( $scrabbleStatus ) {
3084# $conn->schedule(30, \&scrabble,$event,$sNick,$sChannel,@tArgs);
3085# }
3086 }
3087 else {
3088 log_message(0,"scrabble() was called though $scrabbleStatus is false. Scrabble has been stopped in the meanwhile");
3089 }
3090}
3091
3092sub checkScrableWord(@) {
3093 my ($conn,$event,$sNick,$sChannel,$sText) = @_;
3094 $sText =~ s/^([A-Z,a-z]*) .*$/$1/;
3095 $sText =~ tr/a-z/A-Z/;
3096 if ( $sText =~ /^[A-Z]+$/) {
3097 my $sTestPick = $lastScrabblePick;
3098 #log_message(0,"Scrabble: pick: $lastScrabblePick and $sNick proposed : $sText");
3099 my $i = 0;
3100 for ($i=0;($i<length($sText) && (length($sTestPick) > 0));$i++) {
3101 #log_message(0,"sTestPick len : " . length($sTestPick));
3102 my $cur_letter = substr($sText,$i,1);
3103 #log_message(0,$cur_letter);
3104 if ( $sTestPick =~ /$cur_letter/ ) {
3105 $sTestPick =~ s/$cur_letter//;
3106 #log_message(0,"Found $cur_letter sTestPick : $sTestPick");
3107 }
3108 else {
3109 log_message(0,"$cur_letter not found in sTestPick : $sTestPick");
3110 return 0;
3111 }
3112 }
3113 if ( $i == length($sText) ) {
3114 dbCheckHandle($dbh);
3115 my $sCheckQuery = "SELECT * FROM DICT WHERE word=?";
3116 my $sth = $dbh->prepare($sCheckQuery);
3117 unless ($sth->execute($sText) ) {
3118 log_message(0,"checkScrableWord() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
3119 }
3120 else {
3121 if (my $ref = $sth->fetchrow_hashref()) {
3122 #my $word = $ref->{'word'};
3123 if ( length($sText) == $scrabbleSolutionLen ) {
3124 $scrabbleIsWon = 1;
3125 botPrivmsg($conn,$event,"$sChannel","Bien joué $sNick ! Il n'y a pas plus long que $sText");
3126 $scrabbleScores{$sNick} = length($sText) + 10;
3127 }
3128 elsif ( length($sText) > $lastScrabbleLen ) {
3129 botPrivmsg($conn,$event,"$sChannel","Je retiens ton mot $sNick : $sText (" . length($sText) .")");
3130 $lastScrabbleLen = length($sText);
3131 $scrabbleScores{$sNick} = length($sText);
3132 }
3133 }
3134 else {
3135 #log_message(0,"$sText Not Found!");
3136 }
3137 }
3138 }
3139 }
3140}
3141
3142sub scrabbleStart(@) {
3143 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3144 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
3145 if (defined($iMatchingUserId)) {
3146 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
3147 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
3148 unless ( $scrabbleStatus ) {
3149 $scrabbleStatus = 1;
3150 $scrabbleChannel = $sChannel;
3151 $scrabbleTimestamp = time;
3152 botPrivmsg($conn,$event,"$sChannel","$sNick a démarré le jeu de Scrabble ! Nombre de lettres : $SCRABBLE_PICK_LEN, Durée du tour : $SCRABBLE_PICK_DELAY secondes");
3153 $conn->schedule(5, \&scrabbleEnd,$event,$sNick,$sChannel,@tArgs);
3154 scrabble($conn,$event,$sNick,$sChannel,"");
3155 }
3156 }
3157 else {
3158 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
3159 }
3160 }
3161 else {
3162 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
3163 }
3164 }
3165}
3166
3167sub scrabbleStop(@) {
3168 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3169 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
3170 if (defined($iMatchingUserId)) {
3171 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
3172 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
3173 if ( $scrabbleStatus ) {
3174 $scrabbleStatus = 0;
3175 botPrivmsg($conn,$event,"$sChannel","$sNick a stoppé le jeu de Scrabble !");
3176 }
3177 }
3178 else {
3179 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
3180 }
3181 }
3182 else {
3183 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
3184 }
3185 }
3186}
3187
3188sub scrabbleEnd(@) {
3189 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3190 #log_message(0,"scrabbleEnd() call at " . time . " started at $scrabbleTimestamp");
3191 if ( $scrabbleStatus ) {
3192 if ( ( ( time - $scrabbleTimestamp ) > $SCRABBLE_PICK_DELAY ) || ( $scrabbleIsWon ) ) {
3193 my $sSolutionDisp = "";
3194 unless ( $scrabbleIsWon ) {
3195 $sSolutionDisp .= "Trop tard ! ";
3196 }
3197 $sSolutionDisp .= $scrabbleSolution;
3198 botPrivmsg($conn,$event,"$sChannel",$sSolutionDisp);
3199 # Display results
3200 my $nbResults = 0;
3201 my $sScoreDisp = "";
3202 foreach my $l (sort {$scrabbleScores{$b} <=> $scrabbleScores{$a}} (keys( %scrabbleScores ))) {
3203 $sScoreDisp .= "$l : " . $scrabbleScores{$l} . ", ";
3204 $nbResults++;
3205 }
3206 unless ( $nbResults ) {
3207 botPrivmsg($conn,$event,"$sChannel","Personne n'a trouvé, aucun point de marqué...");
3208 }
3209 else {
3210 $sScoreDisp =~ s/, $//;
3211 botPrivmsg($conn,$event,"$sChannel",$sScoreDisp);
3212 scrabbleSaveScores($conn,$event,$sNick,$sChannel,@tArgs);
3213 }
3214 sleep 1;
3215 %scrabbleScores =();
3216 $scrabbleTimestamp = time;
3217 scrabble($conn,$event,$sNick,$sChannel,"");
3218 }
3219 $conn->schedule(5, \&scrabbleEnd,$event,$sNick,$sChannel,@tArgs);
3220 }
3221 else {
3222 log_message(0,"scrabble() was called but Scrabble has been stopped");
3223 }
3224}
3225
3226sub scrabbleFind(@) {
3227 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3228
3229 my $sLetters = $tArgs[0];
3230 unless (open SCR,"$MAIN_PROG_BIN_DIR/scrabble.pl $sLetters |") {
3231 log_message(0,"Error issuing scrabble.pl $sLetters");
3232 return "scrabbleFind() error";
3233 }
3234 else {
3235 my $line;
3236 if (defined($line=<SCR>)) {
3237 chomp($line);
3238 }
3239 close SCR;
3240 return $line;
3241 }
3242}
3243
3244sub scrabbleSaveScores(@) {
3245 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3246 # WARNING $sNick may not be used here ..
3247 dbCheckHandle($dbh);
3248 foreach my $l (keys( %scrabbleScores )) {
3249 log_message(0,"Updating score for $l : +" . $scrabbleScores{$l});
3250 my $sCheckQuery = "SELECT * FROM SCRABBLE where nick=?";
3251 my $sth = $dbh->prepare($sCheckQuery);
3252 unless ($sth->execute($l)) {
3253 log_message(0,"scrabbleSaveScores() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
3254 }
3255 else {
3256 if (my $ref = $sth->fetchrow_hashref()) {
3257 my $id_scrabble = $ref->{'id_scrabble'};
3258 my $score = $ref->{'score'};
3259 $score += $scrabbleScores{$l};
3260 log_message(0,"$l has already $score");
3261 my $sUpdateQuery = "UPDATE SCRABBLE SET score=? WHERE id_scrabble=?";
3262 my $sth = $dbh->prepare($sUpdateQuery);
3263 unless ($sth->execute($score,$id_scrabble) ) {
3264 log_message(0,"scrabbleSaveScores() SQL Error : " . $DBI::errstr . " Query : " . $sUpdateQuery);
3265 }
3266 else {
3267 log_message(0,"update $id_scrabble for $l : $score");
3268 }
3269 }
3270 else {
3271 log_message(0,"$l is a new player");
3272 my $sAddQuery = "INSERT INTO SCRABBLE (nick,score) VALUES ( ? , ? )";
3273 my $sth = $dbh->prepare($sAddQuery);
3274 unless ($sth->execute( $l, $scrabbleScores{$l} ) ) {
3275 log_message(0,"scrabbleSaveScores() SQL Error : " . $DBI::errstr . " Query : " . $sAddQuery);
3276 }
3277 else {
3278 log_message(0,"insert $l : " . $scrabbleScores{$l});
3279 }
3280 }
3281 }
3282 }
3283}
3284
3285sub scrabbleScoresDisplay(@) {
3286 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3287 dbCheckHandle($dbh);
3288
3289 my $sCheckQuery = "SELECT * FROM SCRABBLE ORDER BY score DESC";
3290 my $sth = $dbh->prepare($sCheckQuery);
3291 unless ($sth->execute ) {
3292 log_message(0,"scrabbleScoresDisplay() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
3293 }
3294 else {
3295 my $sScoresDisplay = "";
3296 my $iScoresCount = 0;
3297 while (my $ref = $sth->fetchrow_hashref()) {
3298 my $nick = $ref->{'nick'};
3299 my $score = $ref->{'score'};
3300 $sScoresDisplay .= "$nick($score), ";
3301 $iScoresCount++;
3302 }
3303 unless ( $iScoresCount ) {
3304 $sScoresDisplay .= "No scores";
3305 }
3306 $sScoresDisplay =~ s/, $//;
3307 botNotice($conn,"$sNick",$sScoresDisplay);
3308 }
3309}
3310
3311sub getDepartement(@) {
3312 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3313 dbCheckHandle($dbh);
3314
3315 my $search = $tArgs[0];
3316 if ($search =~ /^[0-9]+$/) {
3317 my $sCheckQuery = "SELECT name FROM DEPARTEMENTS WHERE number=?";
3318 my $sth = $dbh->prepare($sCheckQuery);
3319 unless ($sth->execute($search)) {
3320 log_message(0,"getDepartement() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
3321 }
3322 else {
3323 my $sDepartement;
3324 if (my $ref = $sth->fetchrow_hashref()) {
3325 $sDepartement = $ref->{'name'};
3326 botPrivmsg($conn,$event,"$sChannel",$sDepartement);
3327 }
3328 else {
3329 botPrivmsg($conn,$event,"$sChannel","Not found");
3330 }
3331 }
3332 }
3333 else {
3334 $search = join("-",@tArgs);
3335 $search =~ s/\'/\\\'/g;
3336 my $sCheckQuery = "SELECT number FROM DEPARTEMENTS WHERE name LIKE ?";
3337 my $sth = $dbh->prepare($sCheckQuery);
3338 unless ($sth->execute($search)) {
3339 log_message(0,"getDepartement() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
3340 }
3341 else {
3342 my $sDepartement;
3343 if (my $ref = $sth->fetchrow_hashref()) {
3344 $sDepartement = $ref->{'number'};
3345 botPrivmsg($conn,$event,"$sChannel",$sDepartement);
3346 }
3347 else {
3348 botPrivmsg($conn,$event,"$sChannel","Not found");
3349 }
3350 }
3351 }
3352
3353}
3354
3355sub getTLD(@) {
3356 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3357 dbCheckHandle($dbh);
3358 my $search = $tArgs[0];
3359 my $sCheckQuery = "SELECT pays FROM TLD WHERE code=?";
3360 my $sth = $dbh->prepare($sCheckQuery);
3361 unless ($sth->execute($search)) {
3362 log_message(0,"getTLD() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
3363 }
3364 else {
3365 my $sCountry;
3366 if (my $ref = $sth->fetchrow_hashref()) {
3367 $sCountry = $ref->{'pays'};
3368 botPrivmsg($conn,$event,"$sChannel",$sCountry);
3369 }
3370 else {
3371 botPrivmsg($conn,$event,"$sChannel","Not found");
3372 }
3373 }
3374}
3375
3376sub botColuche(@) {
3377 my ($conn,$event,$sChannel,@tArgs) = @_;
3378 my $sQuery = "SELECT citation FROM COLUCHE ORDER BY rand() LIMIT 1";
3379 dbCheckHandle($dbh);
3380 my $sth = $dbh->prepare($sQuery);
3381 unless ($sth->execute ) {
3382 log_message(0,"botColuche() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
3383 }
3384 else {
3385 if (my $ref = $sth->fetchrow_hashref()) {
3386 my $sCurrentBlague = $ref->{'citation'};
3387 if (defined($sCurrentBlague)) {
3388 botPrivmsg($conn,$event,$sChannel,$sCurrentBlague);
3389 }
3390 else {
3391 log_message(0,"Could not retrieve citation :(");
3392 }
3393 }
3394 }
3395}
3396
3397sub botIvan(@) {
3398 my ($conn,$event,$sChannel,@tArgs) = @_;
3399 my $sQuery;
3400 my $id_ivan = int($tArgs[0]);
3401 dbCheckHandle($dbh);
3402
3403 unless (defined($tArgs[0]) && ($tArgs[0] ne "")) {
3404 $sQuery = "SELECT * FROM IVAN ORDER BY rand() LIMIT 1";
3405 my $sth = $dbh->prepare($sQuery);
3406 unless ($sth->execute ) {
3407 log_message(0,"botIvan() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
3408 }
3409 else {
3410 if (my $ref = $sth->fetchrow_hashref()) {
3411 my $sCurrentIvan = $ref->{'ivan'};
3412 my $iId_ivan = $ref->{'id_ivan'};
3413 if (defined($sCurrentIvan)) {
3414 botPrivmsg($conn,$event,$sChannel,"[$iId_ivan] $sCurrentIvan");
3415 }
3416 }
3417 else {
3418 botPrivmsg($conn,$event,$sChannel,"Citation Ivan non trouvée :(");
3419 log_message(0,"Could not retrieve citation :(");
3420 }
3421 }
3422 }
3423 else {
3424 my $id_ivan = int($tArgs[0]);
3425 $sQuery = "SELECT * FROM IVAN WHERE id_ivan=?";
3426 my $sth = $dbh->prepare($sQuery);
3427 unless ($sth->execute($id_ivan)) {
3428 log_message(0,"botIvan() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
3429 }
3430 else {
3431 if (my $ref = $sth->fetchrow_hashref()) {
3432 my $sCurrentIvan = $ref->{'ivan'};
3433 my $iId_ivan = $ref->{'id_ivan'};
3434 if (defined($sCurrentIvan)) {
3435 botPrivmsg($conn,$event,$sChannel,"[$iId_ivan] $sCurrentIvan");
3436 }
3437 }
3438 else {
3439 botPrivmsg($conn,$event,$sChannel,"Citation Ivan non trouvée :(");
3440 log_message(0,"Could not retrieve citation :(");
3441 }
3442 }
3443 }
3444}
3445
3446sub botRadioTease(@) {
3447 my ($conn,$event,$sChannel,@tArgs) = @_;
3448 my $sQuery = "SELECT tease_text FROM RADIO_TEASE ORDER BY rand() LIMIT 1";
3449 dbCheckHandle($dbh);
3450 my $sth = $dbh->prepare($sQuery);
3451 unless ($sth->execute ) {
3452 log_message(0,"botRadioTease() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
3453 }
3454 else {
3455 if (my $ref = $sth->fetchrow_hashref()) {
3456 my $sCurrentBlague = $ref->{'tease_text'};
3457 if (defined($sCurrentBlague)) {
3458 botPrivmsg($conn,$event,$sChannel,$sCurrentBlague);
3459 }
3460 else {
3461 log_message(0,"Could not retrieve citation :(");
3462 }
3463 }
3464 }
3465}
3466
3467sub logbBotAction(@) {
3468 my ($conn,$event,$eventtype,$sNick,$sChannel,$sText) = @_;
3469 unless (defined($sChannel)) { $sChannel = "N/A"; }
3470 unless (defined($sText)) { $sText = "N/A"; }
3471 my $sUserhost;
3472 unless (defined($event->{'userhost'})) {
3473 $sUserhost = "N/A";
3474 }
3475 else {
3476 $sUserhost = $event->{'userhost'};
3477 }
3478 log_message(5,"[logbBotAction] chan = $sChannel nick = $sNick text = $sText");
3479 log_message(5,"[logbBotAction] event\n" . Dumper($event). "\n");
3480
3481 my $sQuery = "SELECT * FROM CHANNEL WHERE name=?";
3482 dbCheckHandle($dbh);
3483 my $sth = $dbh->prepare($sQuery);
3484 unless ($sth->execute($sChannel) ) {
3485 log_message(0,"logbBotAction() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
3486 }
3487 else {
3488 if (my $ref = $sth->fetchrow_hashref()) {
3489 my $id_channel = $ref->{'id_channel'};
3490 if (defined($id_channel)) {
3491 log_message(5,"[logbBotAction] id_channel = $id_channel");
3492 $sText =~ s/'/\\'/g;
3493 log_message(5,"[logbBotAction] ts = " . time2str("%Y-%m-%d %H-%M-%S",time));
3494 my $sEventtype;
3495 if (defined($event)) {
3496 $sEventtype = $eventtype;
3497 }
3498 else {
3499 $sEventtype = "unknown";
3500 }
3501 my $sQuery = "INSERT INTO CHANNEL_LOG (id_channel,ts,event_type,nick,userhost,publictext) VALUES (?,?,?,?,?,?)";
3502 my $sth = $dbh->prepare($sQuery);
3503 unless ($sth->execute($id_channel,time2str("%Y-%m-%d %H-%M-%S",time),$sEventtype,$sNick,$sUserhost,$sText) ) {
3504 log_message(1,"logbBotAction() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
3505 }
3506 else {
3507 log_message(5,"logbBotAction() inserted " . $eventtype . " event into CHANNEL_LOG");
3508 }
3509 }
3510 else {
3511 log_message(1,"logbBotAction() Could not retrieve id_channel : $id_channel");
3512 }
3513 }
3514 }
3515}
3516
3517sub logEvent(@) {
3518 my ($conn,$event) = @_;
3519 my $sArgs = ($event->args)[0];
3520 my $sUserhost;
3521 unless (defined($event->{'userhost'})) {
3522 $sUserhost = "N/A";
3523 }
3524 else {
3525 $sUserhost = $event->{'userhost'};
3526 }
3527 log_message(5,"logEvent event\n" . Dumper($event). "\n");
3528
3529 dbCheckHandle($dbh);
3530 my $sQuery;
3531 my $sth;
3532 if (defined($sArgs) && ($sArgs ne "") ) {
3533 $sQuery = "INSERT INTO EVENT_LOG (ts,event_type,nick,userhost,args) VALUES (?,?,?,?,?)";
3534 $sth = $dbh->prepare($sQuery);
3535 unless ($sth->execute(time2str("%Y-%m-%d %H-%M-%S",time),$event->type(),$event->nick(),$sUserhost,$sArgs)) {
3536 log_message(0,"logEvent() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
3537 }
3538 else {
3539 log_message(3,"inserted event into EVENT_LOG");
3540 }
3541 }
3542 else {
3543 $sQuery = "INSERT INTO EVENT_LOG (ts,event_type,nick,userhost) VALUES (?,?,?,?)";
3544 $sth = $dbh->prepare($sQuery);
3545 unless ($sth->execute(time2str("%Y-%m-%d %H-%M-%S",time),$event->type(),$event->nick(),$sUserhost)) {
3546 log_message(0,"logEvent() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
3547 }
3548 else {
3549 log_message(3,"inserted event into EVENT_LOG");
3550 }
3551 }
3552}
3553
3554sub catch_hup(@) {
3555 my ($signame) = @_;
3556 log_message(0,"$signame signal caught");
3557 log_message(0,"Closing log file $MAIN_LOG_FILE");
3558 if(defined(fileno(LOG))) { close LOG; }
3559 init_log($MAIN_LOG_FILE);
3560}
3561
3562sub catch_term(@) {
3563 my ($signame) = @_;
3564 log_message(0,"$signame signal caught");
3565 clean_and_exit(undef,15);
3566}
3567
3568sub getRadioCapsuleSong(@) {
3569 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3570 my $shoutcast_host = 'radiocapsule.com';
3571 my $shoutcast_port = '8000';
3572 my $adminuser = 'admin';
3573 my $adminpassword = 'w3bradiale';
3574
3575 unless ( open CAPSULE_CURRENT_SONG, "$MAIN_PROG_BIN_DIR/plugins/getIcecastSong.pl |") {
3576 log_message(0,"Could not get Radio Capsule song stats with $MAIN_PROG_BIN_DIR/plugins/getIcecastSong.pl");
3577 }
3578 my $sLine;
3579 if (defined($sLine=<CAPSULE_CURRENT_SONG>)) {
3580 chomp($sLine);
3581
3582 my $sMessageTitle;
3583 if (defined($sCurrentDjNick)) {
3584 $sMessageTitle = "$sCurrentDjNick live ! " . $sLine;
3585 }
3586 else {
3587 $sMessageTitle = $sLine;
3588 }
3589 # Format message with irc colors
3590 my $sMsgSong = "";
3591 $sMsgSong .= String::IRC->new('[ ')->grey('black');
3592 $sMsgSong .= String::IRC->new('https://teuk.org/mediabot | http://teuk.org:8000/radio.mp3')->orange('black');
3593 $sMsgSong .= String::IRC->new(' ] ')->grey('black');
3594 $sMsgSong .= String::IRC->new(' - ')->white('black');
3595 $sMsgSong .= String::IRC->new(' [ ')->orange('black');
3596 $sMsgSong .= String::IRC->new($sMessageTitle)->grey('black');
3597 $sMsgSong .= String::IRC->new(' ]')->orange('black');
3598
3599 unless (defined($sCurrentDjNick)) {
3600 unless ( open REMAINING_SONG, "$MAIN_PROG_BIN_DIR/plugins/radioRemaining.sh |") {
3601 log_message(0,"Could not get Radio Capsule song stats with $MAIN_PROG_BIN_DIR/plugins/radioRemaining.sh");
3602 }
3603 $sLine = "";
3604 if (defined($sLine=<REMAINING_SONG>)) {
3605 chop($sLine);
3606 chop($sLine);
3607 my $siSecondsRemaining = int($sLine);
3608 my $iMinutesRemaining = int($siSecondsRemaining / 60) ;
3609 my $iSecondsRemaining = $siSecondsRemaining - ( $iMinutesRemaining * 60 );
3610 $sMsgSong .= String::IRC->new(' - ')->white('black');
3611 $sMsgSong .= String::IRC->new(' [ ')->orange('black');
3612 my $sTimeRemaining = "";
3613 if ( $iMinutesRemaining > 0 ) {
3614 $sTimeRemaining .= $iMinutesRemaining . " mn";
3615 if ( $iMinutesRemaining > 1 ) {
3616 $sTimeRemaining .= "s";
3617 }
3618 $sTimeRemaining .= " et ";
3619 }
3620 $sTimeRemaining .= $iSecondsRemaining . " sec";
3621 if ( $iSecondsRemaining > 1 ) {
3622 $sTimeRemaining .= "s";
3623 }
3624 $sTimeRemaining .= " restantes";
3625 $sMsgSong .= String::IRC->new($sTimeRemaining)->grey('black');
3626 $sMsgSong .= String::IRC->new(' ]')->orange('black');
3627 }
3628 close REMAINING_SONG;
3629 }
3630 botPrivmsg($conn,$event,$sChannel,$sMsgSong);
3631 }
3632 close CAPSULE_CURRENT_SONG;
3633 if ( defined($tArgs[0]) && ( $tArgs[0] eq "schedule" )) {
3634 $conn->schedule($RADIO_CHANNEL_SONG_DELAY, \&getRadioCapsuleSong,$conn,$event,"$RADIO_CHANNEL","schedule");
3635 log_message(3,"scheduled getRadioCapsuleSong for $RADIO_CHANNEL");
3636 }
3637}
3638
3639sub getRadioCapsuleListeners(@) {
3640 my ($conn,$event,$sNick,$sChannel,$sCommand,@tArgs) = @_;
3641
3642 unless (open LISTENERS, "$MAIN_PROG_BIN_DIR/plugins/getRadioCapsuleListenersHTML.pl |") {
3643 log_message(0,"Could not get Radio Capsule listeners stats with $MAIN_PROG_BIN_DIR/plugins/getRadioCapsuleListenersHTML.pl");
3644 }
3645 my $line;
3646 if (defined($line=<LISTENERS>)) {
3647 chomp($line);
3648 my $strMsgAuditeurs = "Auditeurs";
3649 if ( $sCommand =~ /^auditrices$/i ) {
3650 $strMsgAuditeurs = "Auditrices";
3651 }
3652 log_message(2,"Listeners = $line");
3653
3654 # Format message with irc colors
3655 my $sMsgListeners = String::IRC->new('(')->white('red');
3656 $sMsgListeners .= String::IRC->new(')')->maroon('red');
3657 $sMsgListeners .= String::IRC->new('(')->red('maroon');
3658 $sMsgListeners .= String::IRC->new(')')->black('maroon');
3659 $sMsgListeners .= String::IRC->new('( ')->maroon('black');
3660 $sMsgListeners .= String::IRC->new('( ')->red('black');
3661 $sMsgListeners .= String::IRC->new('Il y a ')->silver('black');
3662 $sMsgListeners .= String::IRC->new(')-( ')->red('black');
3663 $sMsgListeners .= int($line) + int(rand(10));
3664 $sMsgListeners .= String::IRC->new(' )-( ')->red('black');
3665 $sMsgListeners .= String::IRC->new($strMsgAuditeurs)->white('black');
3666 $sMsgListeners .= String::IRC->new(' ) ')->red('black');
3667 $sMsgListeners .= String::IRC->new(')')->maroon('black');
3668 $sMsgListeners .= String::IRC->new('(')->black('maroon');
3669 $sMsgListeners .= String::IRC->new(')')->red('maroon');
3670 $sMsgListeners .= String::IRC->new('(')->maroon('red');
3671 $sMsgListeners .= String::IRC->new(')')->white('red');
3672
3673 botPrivmsg($conn,$event,$sChannel,$sMsgListeners);
3674 }
3675}
3676
3677sub getUrltitle(@) {
3678 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3679 my $http_title_url = $tArgs[0];
3680
3681 if (defined($http_title_url)) {
3682 unless (open GET_URL_TITLE, "/opt/scripts/getYoutubeTitle.pl \"" . $http_title_url . "\" |") {
3683 log_message(0,"Could not get title for " . $http_title_url);
3684 }
3685 my $line;
3686 if (defined($line=<GET_URL_TITLE>)) {
3687 chomp($line);
3688 log_message(2,"URL title = $line");
3689 my $sUrlTitleMsg = String::IRC->new('(')->white('red')->bold;
3690 $sUrlTitleMsg .= String::IRC->new(')')->maroon('red')->bold;
3691 $sUrlTitleMsg .= String::IRC->new('(')->red('maroon')->bold;
3692 $sUrlTitleMsg .= String::IRC->new(')')->black('maroon')->bold;
3693 $sUrlTitleMsg .= String::IRC->new('(')->maroon('black')->bold;
3694 $sUrlTitleMsg .= String::IRC->new(' ( ')->red('black')->bold;
3695 $sUrlTitleMsg .= String::IRC->new('URL : ' . $http_title_url)->silver('black')->bold;
3696 $sUrlTitleMsg .= String::IRC->new(' )-( ')->red('black')->bold;
3697 $sUrlTitleMsg .= String::IRC->new($line)->white('black')->bold;
3698 $sUrlTitleMsg .= String::IRC->new(' ) ')->red('black')->bold;
3699 $sUrlTitleMsg .= String::IRC->new(')')->maroon('black')->bold;
3700 $sUrlTitleMsg .= String::IRC->new('(')->black('maroon')->bold;
3701 $sUrlTitleMsg .= String::IRC->new(')')->red('maroon')->bold;
3702 $sUrlTitleMsg .= String::IRC->new('(')->maroon('red')->bold;
3703 $sUrlTitleMsg .= String::IRC->new(')')->white('red')->bold;
3704 botPrivmsg($conn,$event,$sChannel,$sUrlTitleMsg);
3705 }
3706 }
3707}
3708
3709sub chanWordStat(@) {
3710 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3711 if (defined($tArgs[0])) {
3712 #botPrivmsg($conn,$event,"$sChannel","$sNick a demandé les stats du mot : " . $tArgs[0]);
3713 my $sCheckQuery = "SELECT id_channel FROM CHANNEL where name=?";
3714 dbCheckHandle($dbh);
3715 my $sth = $dbh->prepare($sCheckQuery);
3716 unless ($sth->execute($sChannel)) {
3717 log_message(0,"chanWordStat() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
3718 }
3719 else {
3720 my $wordStatStr = "";
3721 if (my $ref = $sth->fetchrow_hashref()) {
3722 my $id_channel = $ref->{'id_channel'};
3723 if (defined($id_channel)) {
3724 $sCheckQuery = "SELECT nick,count(*) AS wordstat FROM CHANNEL_LOG WHERE id_channel=? and publictext like ? GROUP BY nick ORDER BY wordstat DESC LIMIT 15";
3725 my $sth = $dbh->prepare($sCheckQuery);
3726 unless ($sth->execute($id_channel,$tArgs[0])) {
3727 log_message(0,"chanWordStat() SQL Error : " . $DBI::errstr . " Query : " . $sCheckQuery);
3728 }
3729 else {
3730 while (my $ref = $sth->fetchrow_hashref()) {
3731 my $nickStat = $ref->{'nick'};
3732 my $nickStatCount = $ref->{'wordstat'};
3733 $wordStatStr .= "$nickStat ($nickStatCount) ";
3734 }
3735 botPrivmsg($conn,$event,"$sChannel","$wordStatStr");
3736
3737 }
3738 }
3739 else {
3740 botPrivmsg($conn,$event,"$sChannel","$sChannel is unknown to me sorry");
3741 }
3742 }
3743 }
3744 }
3745 else {
3746 botNotice($conn,"$sNick","Usage: !stats <word>");
3747 }
3748}
3749
3750sub botFriendGuess(@) {
3751 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3752 my $percentFriendGuess = int(rand(100)) + 1;
3753 if (defined($tArgs[0]) && ( $tArgs[0] ne "" )) {
3754 botPrivmsg($conn,$event,$sChannel,"Hey $sNick, t'as " . $percentFriendGuess. "% de chance de baiser avec " . $tArgs[0]);
3755 }
3756 else {
3757 botPrivmsg($conn,$event,$sChannel,"Hey $sNick, choisis qqun d'abord !");
3758 }
3759}
3760
3761
3762sub botSaucisse(@) {
3763 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
3764 my $percentSaucisse = int(rand(100)) + 1;
3765 botPrivmsg($conn,$event,"$sChannel","Hey $sNick, t'as " . $percentSaucisse. "% de chance de manger une bockwurst au fromage avec " . $tArgs[0] . " https://teuk.org/mediabot/saucisse.gif");
3766}
3767
3768sub usage(@) {
3769 my ($strErr) = @_;
3770 if (defined($strErr)) {
3771 print STDERR "Error : " . $strErr . "\n";
3772 }
3773 print STDERR "Usage: " . basename($0) . "--conf <config_file> [--daemon]\n";
3774 exit 4;
3775}
3776
3777sub readConfigFile(@) {
3778 my ($configFile) = @_;
3779 print STDERR time2str("[%d/%m/%Y %H:%M:%S]",time) . " Readind configuration file $configFile\n";
3780 Config::Simple->import_from($configFile, \%Config) or die Config::Simple->error();
3781
3782 # -- main --
3783 if (defined($Config{'main.MAIN_PROG_NAME'})) {
3784 $MAIN_PROG_NAME = $Config{'main.MAIN_PROG_NAME'};
3785 }
3786
3787 if (defined($Config{'main.MAIN_PROG_NAME_LOWER'})) {
3788 $MAIN_PROG_NAME_LOWER = $Config{'main.MAIN_PROG_NAME_LOWER'};
3789 }
3790
3791 if (defined($Config{'main.MAIN_PID_FILE'})) {
3792 $MAIN_PID_FILE = $Config{'main.MAIN_PID_FILE'};
3793 }
3794
3795 if (defined($Config{'main.MAIN_LOG_FILE'})) {
3796 $MAIN_LOG_FILE = $Config{'main.MAIN_LOG_FILE'};
3797 }
3798
3799 if (defined($Config{'main.MAIN_PROG_ACCOUNTDIR'})) {
3800 print STDERR time2str("[%d/%m/%Y %H:%M:%S]",time) . " Reading main.MAIN_PROG_ACCOUNTDIR from conf : " . $Config{'main.MAIN_PROG_ACCOUNTDIR'} . "\n";
3801 $MAIN_PROG_ACCOUNTDIR = $Config{'main.MAIN_PROG_ACCOUNTDIR'};
3802 print STDERR time2str("[%d/%m/%Y %H:%M:%S]",time) . " \$MAIN_PROG_ACCOUNTDIR is set to : $MAIN_PROG_ACCOUNTDIR\n";
3803 }
3804
3805 if (defined($Config{'main.MAIN_PROG_ACCOUNT'})) {
3806 $MAIN_PROG_ACCOUNT = $Config{'main.MAIN_PROG_ACCOUNT'};
3807 }
3808
3809 if (defined($Config{'main.MAIN_PROG_BIRTHDATE'})) {
3810 #print STDERR time2str("[%d/%m/%Y %H:%M:%S]",time) . " Reading main.MAIN_PROG_BIRTHDATE from conf : " . $Config{'main.MAIN_PROG_BIRTHDATE'} . "\n";
3811 $MAIN_PROG_BIRTHDATE = $Config{'main.MAIN_PROG_BIRTHDATE'};
3812 #print STDERR time2str("[%d/%m/%Y %H:%M:%S]",time) . " \$MAIN_PROG_BIRTHDATE is set to : $MAIN_PROG_BIRTHDATE\n";
3813 }
3814
3815 #if (defined($Config{'main.MAIN_PROG_VERSION'})) {
3816 # $MAIN_PROG_VERSION = $Config{'main.MAIN_PROG_VERSION'};
3817 #}
3818
3819 if (defined($Config{'main.MAIN_PROG_URL'})) {
3820 $MAIN_PROG_URL = $Config{'MAIN_PROG_URL'};
3821 }
3822
3823 if (defined($Config{'main.MAIN_PROG_DEBUG'})) {
3824 print STDERR time2str("[%d/%m/%Y %H:%M:%S]",time) . " Reading main.MAIN_PROG_DEBUG from conf : " . $Config{'main.MAIN_PROG_DEBUG'} . "\n";
3825 $MAIN_PROG_DEBUG = $Config{'main.MAIN_PROG_DEBUG'};
3826 print STDERR time2str("[%d/%m/%Y %H:%M:%S]",time) . " \$MAIN_PROG_DEBUG is set to : $MAIN_PROG_DEBUG\n";
3827 }
3828
3829 # -- mysql --
3830 if (defined($Config{'mysql.MAIN_PROG_DDBNAME'})) {
3831 $MAIN_PROG_DDBNAME = $Config{'mysql.MAIN_PROG_DDBNAME'};
3832 }
3833
3834 if (defined($Config{'mysql.MAIN_PROG_DBUSER'})) {
3835 $MAIN_PROG_DBUSER = $Config{'mysql.MAIN_PROG_DBUSER'};
3836 }
3837
3838 if (defined($Config{'mysql.MAIN_PROG_DBPASS'})) {
3839 $MAIN_PROG_DBPASS = $Config{'mysql.MAIN_PROG_DBPASS'};
3840 }
3841
3842 if (defined($Config{'mysql.MAIN_PROG_DBHOST'})) {
3843 $MAIN_PROG_DBHOST = $Config{'mysql.MAIN_PROG_DBHOST'};
3844 }
3845
3846 # -- connection --
3847 if (defined($Config{'connection.CONN_SERVER_NETWORK'})) {
3848 $CONN_SERVER_NETWORK = $Config{'connection.CONN_SERVER_NETWORK'};
3849 }
3850
3851 if (defined($Config{'connection.CONN_NICK'})) {
3852 $CONN_NICK = $Config{'connection.CONN_NICK'};
3853 }
3854
3855 if (defined($Config{'connection.CONN_NICK_ALTERNATE'})) {
3856 $CONN_NICK_ALTERNATE = $Config{'connection.CONN_NICK_ALTERNATE'};
3857 }
3858
3859 if (defined($Config{'connection.CONN_USERNAME'})) {
3860 $CONN_USERNAME = $Config{'connection.CONN_USERNAME'};
3861 }
3862
3863 if (defined($Config{'connection.CONN_IRCNAME'})) {
3864 $CONN_IRCNAME = $Config{'connection.CONN_IRCNAME'};
3865 }
3866
3867 if (defined($Config{'connection.CONN_DEFAULT_CHANNEL'})) {
3868 $CONN_DEFAULT_CHANNEL = $Config{'connection.CONN_DEFAULT_CHANNEL'};
3869 }
3870
3871 if (defined($Config{'connection.CONN_DEFAULT_CHANNEL_KEY'})) {
3872 $CONN_DEFAULT_CHANNEL_KEY = $Config{'connection.CONN_DEFAULT_CHANNEL_KEY'};
3873 }
3874
3875 if (defined($Config{'connection.CONN_USERMODE'})) {
3876 $CONN_USERMODE = $Config{'connection.CONN_USERMODE'};
3877 }
3878
3879 # -- Undernet --
3880 if (defined($Config{'undernet.UNET_CSERVICE_USERNAME'})) {
3881 $UNET_CSERVICE_USERNAME = $Config{'undernet.UNET_CSERVICE_USERNAME'};
3882 }
3883
3884 if (defined($Config{'undernet.UNET_CSERVICE_PASSWORD'})) {
3885 $UNET_CSERVICE_PASSWORD = $Config{'undernet.UNET_CSERVICE_PASSWORD'};
3886 }
3887
3888 if (defined($Config{'undernet.UNET_CSERVICE_LOGIN'})) {
3889 $UNET_CSERVICE_LOGIN = $Config{'undernet.UNET_CSERVICE_LOGIN'};
3890 }
3891
3892 if (defined($Config{'partyline.PARTYLINE_TCP_PORT'})) {
3893 $PARTYLINE_TCP_PORT = $Config{'partyline.PARTYLINE_TCP_PORT'};
3894 }
3895
3896 if (defined($Config{'radio.RADIO_CHANNEL'})) {
3897 $RADIO_CHANNEL = $Config{'radio.RADIO_CHANNEL'};
3898 }
3899
3900 if (defined($Config{'radio.RADIO_CHANNEL_SONG_DELAY'})) {
3901 $RADIO_CHANNEL_SONG_DELAY = $Config{'radio.RADIO_CHANNEL_SONG_DELAY'};
3902 }
3903
3904
3905 print STDERR time2str("[%d/%m/%Y %H:%M:%S]",time) . " $configFile loaded.\n";
3906}
3907
3908sub startPartyline(@) {
3909 my ($conn) = @_;
3910 my $server = undef;
3911 my $pid;
3912 $pid = fork;
3913 unless ($pid) {
3914 log_message(0,"Starting Partyline on port $PARTYLINE_TCP_PORT");
3915 #my $server = IO::Socket::INET->new ( LocalPort => $PARTYLINE_TCP_PORT, Type => SOCK_STREAM, Reuse => 1, Listen => 5) or die "Probleme serveur";
3916 $SIG{PIPE}='IGNORE';
3917 #$SIG{CHLD} = 'IGNORE';
3918 my $server = Net::Server::NonBlocking->new();
3919 $server->add({
3920 server_name => '$MAIN_PROG_NAME Partyline',
3921 local_port => $PARTYLINE_TCP_PORT,
3922 timeout => 300,
3923 delimiter => "\n",
3924 on_connected => \&partylineClientConnected,
3925 on_disconnected => \&partylineClientDisconnected,
3926 on_recv_msg => \&partylineClientMessage,
3927 #on_recv_msg_param => [\$conn],
3928 });
3929 $server->start();
3930 }
3931 return ($server);
3932}
3933
3934sub partylineClientConnected(@) {
3935 my $self=shift;
3936 my $client=shift;
3937 log_message(0,"[Partyline] $client has connected to Partyline");
3938 print $client "welcome to $MAIN_PROG_NAME Partyline\n";
3939}
3940
3941sub partylineClientDisconnected(@) {
3942 my $self=shift;
3943 my $client=shift;
3944 log_message(0,"[Partyline] $client has disconnected from Partyline");
3945}
3946
3947sub partylineClientMessage(@) {
3948 my ($self,$client,$message) = @_;
3949 #my $self=shift;
3950 #my $client=shift;
3951 #my $message=shift;
3952
3953 # process $message
3954 #log_message(0,"self : " . Dumper($self));
3955 log_message(0,"client : " . Dumper($client));
3956 log_message(0,"[Partyline] message from client $client : " . $message);
3957
3958}
3959
3960#sub checkPartyLineConnections(@) {
3961# my $client;
3962# my $chaine;
3963# my $pid;
3964# if ( $client = $partyLineServer->accept ())
3965# {
3966# $pid = fork;
3967# unless ($pid)
3968# {
3969# while ( 1 )
3970# {
3971# print $client "Vous voulez dire ? ";
3972# $chaine = <$client>;
3973# exit unless defined $chaine;
3974#
3975# chomp ($chaine);
3976#
3977# if ( $chaine =~ "quit" )
3978# {
3979# $client->shutdown ( 2 );
3980# exit;
3981# }
3982# else
3983# {
3984# print $client "Vous avez dit : $chaine\n";
3985# }
3986# }
3987# }
3988# }
3989# $conn->schedule(10, \&checkPartyLineConnections);
3990#}
3991
3992sub botSQLCommand(@) {
3993 my ($conn,$event,$sNick,$sChannel,$sCommand,@tArgs) = @_;
3994 log_message(2,"Check SQL command : $sCommand");
3995 #my $sCheckCommand = "SELECT * FROM PUBLIC_COMMANDS WHERE command='" . $sCommand . "'";
3996 my $sCheckCommand = "SELECT * FROM PUBLIC_COMMANDS WHERE command=?";
3997 dbCheckHandle($dbh);
3998 my $sth = $dbh->prepare($sCheckCommand);
3999 unless ($sth->execute($sCommand)) {
4000 log_message(0,"botSQLCommand() SQL Error : " . $DBI::errstr . " Query : " . $sCheckCommand);
4001 }
4002 else {
4003 if (my $ref = $sth->fetchrow_hashref()) {
4004 my $description = $ref->{'description'};
4005 my $action = $ref->{'action'};
4006 log_message(2,"SQL command found : $sCommand description : $description action : $action");
4007 my ($actionType,$actionTo,$actionDo) = split(/ /,$action,3);
4008 if ( $actionType eq 'PRIVMSG' ) {
4009 if ( $actionTo eq '%c' ) {
4010 if (defined($tArgs[0])) {
4011 my $sNickAction = join(" ",@tArgs);
4012 $actionDo =~ s/%n/$sNickAction/g;
4013 }
4014 else {
4015 $actionDo =~ s/%n/$sNick/g;
4016 }
4017 $actionDo =~ s/%c/$sChannel/g;
4018 botPrivmsg($conn,$event,$sChannel,"$actionDo");
4019 }
4020 return 1;
4021 }
4022 elsif ( $actionType eq 'ACTION' ) {
4023 if ( $actionTo eq '%c' ) {
4024 if (defined($tArgs[0])) {
4025 my $sNickAction = join(" ",@tArgs);
4026 $actionDo =~ s/%n/$sNickAction/g;
4027 }
4028 else {
4029 $actionDo =~ s/%n/$sNick/g;
4030
4031 }
4032 botAction($conn,$event,$sChannel,"$actionDo");
4033 }
4034 return 1;
4035 }
4036 else {
4037 log_message(2,"Unknown actionType : $actionType");
4038 return 0;
4039 }
4040 }
4041 else {
4042 return 0;
4043 }
4044 }
4045}
4046
4047sub noticeConsoleChan(@) {
4048 my ($conn,$iLevel,$sMsg) = @_;
4049 botNotice($conn,$CONN_DEFAULT_CHANNEL,$sMsg);
4050}
4051
4052sub getEventHostmask(@) {
4053 my ($event) = @_;
4054 log_message(5,Dumper($event));
4055 my $sEventHostmask = "(Unknown)";
4056 if (defined($event->nick)) {
4057 $sEventHostmask = $event->nick;
4058 }
4059 if (defined($event->userhost)) {
4060 $sEventHostmask .= "!" . $event->userhost;
4061 }
4062 else {
4063 $sEventHostmask .= "(Unknown host)";
4064 }
4065 return $sEventHostmask;
4066}
4067
4068sub getStreamStatus(@) {
4069 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4070 botNotice($conn,$CONN_DEFAULT_CHANNEL,"status command invoked by $sNick");
4071}
4072
4073sub botDowjaune(@) {
4074 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4075 my $dowjauneValue = "N/A";
4076 unless (open DOWJAUNE,"$MAIN_PROG_BIN_DIR/plugins/dowjaune.sh |") {
4077 log_message(0,"Error getting dowjaune value");
4078 log_message(4,"$MAIN_PROG_BIN_DIR/plugins/dowjaune.sh");
4079 return 0;
4080 }
4081
4082 if (defined($dowjauneValue=<DOWJAUNE>)) {
4083 chomp($dowjauneValue);
4084 botPrivmsg($conn,$event,$sChannel,"Le cours du Dowjaune indexé sur le pétrôle BRENT est de " . $dowjauneValue);
4085 }
4086 close DOWJAUNE;
4087 return 1;
4088}
4089
4090sub botRandomAnswer(@) {
4091 my ($conn,$event,$sNick,$sChannel) = @_;
4092 my $sAnswerQuery = "SELECT answer FROM RANDOM_ANSWER ORDER BY RAND() LIMIT 1";
4093 dbCheckHandle($dbh);
4094 my $sth = $dbh->prepare($sAnswerQuery);
4095 unless ($sth->execute ) {
4096 log_message(0,"botRandomAnswer() SQL Error : " . $DBI::errstr . " Query : " . $sAnswerQuery);
4097 }
4098 else {
4099 if (my $ref = $sth->fetchrow_hashref()) {
4100 my $answer = $ref->{'answer'};
4101 botPrivmsg($conn,$event,$sChannel,"$sNick $answer");
4102 }
4103 }
4104}
4105
4106sub botGetAnswer(@) {
4107 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4108 if (defined($tArgs[0]) && ( $tArgs[0] ne "" )) {
4109 my $id_random_answer = int($tArgs[0]);
4110 my $sAnswerQuery = "SELECT answer FROM RANDOM_ANSWER WHERE id_random_answer=?";
4111 dbCheckHandle($dbh);
4112 my $sth = $dbh->prepare($sAnswerQuery);
4113 unless ($sth->execute($id_random_answer)) {
4114 log_message(0,"botGetAnswer() SQL Error : " . $DBI::errstr . " Query : " . $sAnswerQuery);
4115 }
4116 else {
4117 if (my $ref = $sth->fetchrow_hashref()) {
4118 my $answer = $ref->{'answer'};
4119 botPrivmsg($conn,$event,$sChannel,"[$id_random_answer] $answer");
4120 }
4121 else {
4122 botPrivmsg($conn,$event,$sChannel,"Quote non trouvée :(");
4123 }
4124 }
4125 }
4126 else {
4127 botNotice($conn,$sNick,"Syntax .quote <id>");
4128 }
4129}
4130
4131sub botSetPass(@) {
4132 my ($conn,$event,$sNick,@tArgs) = @_;
4133 #pass <new_password>
4134 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
4135 if (defined($iMatchingUserId)) {
4136 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
4137 if (defined($sMatchingUserPasswd)) {
4138 botNotice($conn,$sNick,"Your password is already set. Use /msg " . $conn->nick() . " newpass <new_password> to reset it.");
4139 }
4140 else {
4141 my $sSetQueryPassword = "UPDATE USER SET password=PASSWORD(?) WHERE id_user=?";
4142 dbCheckHandle($dbh);
4143 my $sth = $dbh->prepare($sSetQueryPassword);
4144 unless ($sth->execute($tArgs[0],$iMatchingUserId)) {
4145 log_message(0,"botSetPass() SQL Error : " . $DBI::errstr . " Query : " . $sSetQueryPassword);
4146 }
4147 else {
4148 botNotice($conn,$sNick,"Password set.");
4149 }
4150 }
4151 }
4152 else {
4153 botNotice($conn,$sNick,"Syntax error : /msg " . $conn->nick() . " pass <new_password>");
4154 }
4155 }
4156 else {
4157 my $sNoticeMessage = "$sNick pass command attempt : " . $tArgs[0];
4158 log_message(0,$sNoticeMessage);
4159 noticeConsoleChan($conn,0,$sNoticeMessage);
4160 }
4161}
4162
4163sub botSetNewPass(@) {
4164 my ($conn,$event,$sNick,@tArgs) = @_;
4165 #newpass <new_password>
4166 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
4167 if (defined($iMatchingUserId)) {
4168 if (defined($tArgs[0]) && ($tArgs[0] ne "")) {
4169 my $sSetQueryPassword = "UPDATE USER SET password=PASSWORD(?) WHERE id_user=?";
4170 dbCheckHandle($dbh);
4171 my $sth = $dbh->prepare($sSetQueryPassword);
4172 unless ($sth->execute($tArgs[0],$iMatchingUserId)) {
4173 log_message(0,"botSetNewPass() SQL Error : " . $DBI::errstr . " Query : " . $sSetQueryPassword);
4174 }
4175 else {
4176 botNotice($conn,$sNick,"Password reset.");
4177 }
4178 }
4179 else {
4180 botNotice($conn,$sNick,"Syntax error : /msg " . $conn->nick() . " newpass <new_password>");
4181 }
4182 }
4183}
4184
4185sub getRadioUrl(@) {
4186 my ($conn,$event,$sNick,$sChannel) = @_;
4187
4188 # Format message with irc colors
4189 my $sMsgRadioUrl = String::IRC->new('(')->white('red')->bold;
4190 $sMsgRadioUrl .= String::IRC->new(')')->maroon('red')->bold;
4191 $sMsgRadioUrl .= String::IRC->new('(')->red('maroon')->bold;
4192 $sMsgRadioUrl .= String::IRC->new(')')->black('maroon')->bold;
4193 $sMsgRadioUrl .= String::IRC->new('( ')->maroon('black')->bold;
4194 $sMsgRadioUrl .= String::IRC->new('( ')->red('black')->bold;
4195 $sMsgRadioUrl .= String::IRC->new('Écoute Radio Capsule ')->silver('black')->bold;
4196 $sMsgRadioUrl .= String::IRC->new(')-( ')->red('black')->bold;
4197 $sMsgRadioUrl .= String::IRC->new('http://www.radiocapsule.com/radio.php')->white('black')->bold;
4198 $sMsgRadioUrl .= String::IRC->new(' ) ')->red('black')->bold;
4199 $sMsgRadioUrl .= String::IRC->new(')')->maroon('black')->bold;
4200 $sMsgRadioUrl .= String::IRC->new('(')->black('maroon')->bold;
4201 $sMsgRadioUrl .= String::IRC->new(')')->red('maroon')->bold;
4202 $sMsgRadioUrl .= String::IRC->new('(')->maroon('red')->bold;
4203 $sMsgRadioUrl .= String::IRC->new(')')->white('red')->bold;
4204
4205 botPrivmsg($conn,$event,$sChannel,$sMsgRadioUrl);
4206}
4207
4208sub botAddUser(@) {
4209 my ($conn,$event,$sNick,@tArgs) = @_;
4210 #adduser <username> <hostmask> [level]
4211
4212 log_message(1,"adduser " . $tArgs[0] . " " . $tArgs[1]);
4213 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
4214 if (defined($iMatchingUserId)) {
4215 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
4216 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_MASTER)) {
4217 if (defined($tArgs[0]) && ($tArgs[0] ne "") && defined($tArgs[1]) && ($tArgs[1] ne "")) {
4218 my $iUserLevel = 4;
4219 if ( defined($tArgs[2])) {
4220 if ( $tArgs[2] == 0 ) {
4221 $iUserLevel = 1;
4222 botNotice($conn,$sNick,"You can't add user with level 0, level is set to 1");
4223 }
4224 else {
4225 $iUserLevel = $tArgs[2];
4226 }
4227 }
4228 my $sLevelQuery = "SELECT * FROM USER_LEVEL WHERE level=?";
4229 dbCheckHandle($dbh);
4230 my $sth = $dbh->prepare($sLevelQuery);
4231 unless ($sth->execute($iUserLevel)) {
4232 log_message(0,"botAddUser() SQL Error : " . $DBI::errstr . " Query : " . $sLevelQuery);
4233 }
4234 else {
4235 if (my $ref = $sth->fetchrow_hashref()) {
4236 my $iUserLevelId = $ref->{'id_user_level'};
4237 my $sUserLevelDesc = $ref->{'description'};
4238
4239 my $sQuery = "INSERT INTO USER (hostmasks,nickname,id_user_level) VALUES (?,?,?)";
4240 dbCheckHandle($dbh);
4241 my $sth2 = $dbh->prepare($sQuery);
4242 unless ($sth2->execute($tArgs[1],$tArgs[0],$iUserLevelId) ) {
4243 log_message(0,"botAddUser() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
4244 }
4245 else {
4246 logBot($conn,$event,undef,"adduser",($tArgs[0] . " hostmask " . $tArgs[1] . "level $sUserLevelDesc($iUserLevel)"));
4247 my $sNoticeMsg = "Utilisateur ajouté " . $tArgs[0] . " hostmask " . $tArgs[1] . " level $sUserLevelDesc($iUserLevel)";
4248 botNotice($conn,$sNick,$sNoticeMsg);
4249 }
4250 }
4251 else {
4252 botNotice($conn,$sNick,"Level specified not found in adduser command");
4253 }
4254 }
4255 }
4256 }
4257 else {
4258 my $sNoticeMsg = getEventHostmask($event);
4259 $sNoticeMsg .= " adduser command attempt, (command level [1] for user " . $sMatchingUserHandle . "[" . $iMatchingUserLevel ."])";
4260 noticeConsoleChan($conn,0,$sNoticeMsg);
4261 botNotice($conn,$sNick,"This command is not available for your level. Contact a bot master.");
4262 }
4263 }
4264 else {
4265 my $sNoticeMsg = getEventHostmask($event);
4266 $sNoticeMsg .= " adduser command attempt (user $sMatchingUserHandle is not logged in)";
4267 noticeConsoleChan($conn,0,$sNoticeMsg);
4268 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
4269 }
4270 }
4271}
4272
4273sub botStatTables(@) {
4274 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4275 my $nbInsultes = 0;
4276 my $nbIvan = 0;
4277 my $sTableStatsQuery1 = "SELECT COUNT(*) AS nbInsultes FROM INSULTE ";
4278 log_message(3,$sTableStatsQuery1);
4279 dbCheckHandle($dbh);
4280 my $sth = $dbh->prepare($sTableStatsQuery1);
4281 unless ($sth->execute ) {
4282 log_message(0,"botStatTables() SQL Error : " . $DBI::errstr . " Query : " . $sTableStatsQuery1);
4283 }
4284 else {
4285 if (my $ref = $sth->fetchrow_hashref()) {
4286 $nbInsultes = $ref->{'nbInsultes'};
4287 }
4288 }
4289 my $sTableStatsQuery2 = "SELECT COUNT(*) AS nbIvan FROM IVAN ";
4290 log_message(3,$sTableStatsQuery2);
4291 dbCheckHandle($dbh);
4292 $sth = $dbh->prepare($sTableStatsQuery2);
4293 unless ($sth->execute ) {
4294 log_message(0,"botStatTables() SQL Error : " . $DBI::errstr . " Query : " . $sTableStatsQuery2);
4295 }
4296 else {
4297 if (my $ref = $sth->fetchrow_hashref()) {
4298 $nbIvan = $ref->{'nbIvan'};
4299 }
4300 }
4301 botPrivmsg($conn,$event,$sChannel,"Stats de la base :");
4302 botPrivmsg($conn,$event,$sChannel,"$nbInsultes insultes");
4303 botPrivmsg($conn,$event,$sChannel,"$nbIvan citations d'Ivan");
4304}
4305
4306sub botHttpResponseCode(@) {
4307 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4308 my $sHttpResponseCodeQuery = "SELECT description FROM HTTP_RESPONSE_CODE WHERE code=?";
4309 log_message(3,$sHttpResponseCodeQuery);
4310 dbCheckHandle($dbh);
4311 my $sth = $dbh->prepare($sHttpResponseCodeQuery);
4312 unless ($sth->execute($tArgs[0])) {
4313 log_message(0,"botHttpResponseCode() SQL Error : " . $DBI::errstr . " Query : " . $sHttpResponseCodeQuery);
4314 }
4315 else {
4316 if (my $ref = $sth->fetchrow_hashref()) {
4317 my $sDescription = $ref->{'description'};
4318 botPrivmsg($conn,$event,$sChannel,"HTTP " . $tArgs[0] . ": $sDescription");
4319 }
4320 else {
4321 botPrivmsg($conn,$event,$sChannel,"Code de réponse HTTP invalide");
4322 }
4323 }
4324}
4325
4326sub botSayChannel(@) {
4327 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4328 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
4329 if (defined($iMatchingUserId)) {
4330 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
4331 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_ADMINISTRATOR)) {
4332 if ( defined($sChannel) && ( $sChannel eq "#bquebec" ) && defined($tArgs[0]) && ($tArgs[0] ne "") ) {
4333 my $sChannelText = join(" ",@tArgs);
4334 log_message(0,"$sNick issued a say command on #quebec : $sChannelText");
4335 botPrivmsg($conn,$event,"#quebec",$sChannelText);
4336 my @tArgs2 = ("#quebec");
4337 push @tArgs2,@tArgs;
4338 logBot($conn,$event,$sChannel,"say",@tArgs2);
4339 }
4340 elsif (defined($tArgs[0]) && ($tArgs[0] ne "") && defined($tArgs[1]) && ($tArgs[1] ne "") && ( $tArgs[0] =~ /^#/)) {
4341 my (undef,@tArgsTemp) = @tArgs;
4342 my $sChannelText = join(" ",@tArgsTemp);
4343 log_message(0,"$sNick issued a say command : " . $tArgs[0] . " $sChannelText");
4344 botPrivmsg($conn,$event,$tArgs[0],$sChannelText);
4345 logBot($conn,$event,$sChannel,"say",@tArgs);
4346 }
4347 else {
4348 botNotice($conn,$sNick,"Syntax error : say <#channel> <text>");
4349 }
4350 }
4351 else {
4352 my $sNoticeMsg = getEventHostmask($event) . " say command attempt (command level [2] for user " . $sMatchingUserHandle . "[" . $iMatchingUserLevel ."])";
4353 noticeConsoleChan($conn,0,$sNoticeMsg);
4354 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
4355 }
4356 }
4357 else {
4358 my $sNoticeMsg = getEventHostmask($event) . " say command attempt (user $sMatchingUserHandle is not logged in)";
4359 noticeConsoleChan($conn,0,$sNoticeMsg);
4360 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
4361 }
4362 }
4363}
4364
4365sub botActChannel(@) {
4366 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4367 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
4368 if (defined($iMatchingUserId)) {
4369 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
4370 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_ADMINISTRATOR)) {
4371 if ( defined($sChannel) && ( $sChannel eq "#bquebec" ) && defined($tArgs[0]) && ($tArgs[0] ne "") ) {
4372 my $sChannelText = join(" ",@tArgs);
4373 log_message(0,"$sNick issued a say command on #quebec : $sChannelText");
4374 noticeConsoleChan($conn,0,"$sNick issued a say command on #quebec : $sChannelText");
4375 botPrivmsg($conn,$event,"#quebec","\1ACTION " . $sChannelText . "\1");
4376 }
4377 elsif (defined($tArgs[0]) && ($tArgs[0] ne "") && defined($tArgs[1]) && ($tArgs[1] ne "") && ( $tArgs[0] =~ /^#/)) {
4378 my (undef,@tArgsTemp) = @tArgs;
4379 my $sChannelText = join(" ",@tArgsTemp);
4380 log_message(0,"$sNick issued a act command : " . $tArgs[0] . " $sChannelText");
4381 noticeConsoleChan($conn,0,"$sNick issued a act command : " . $tArgs[0] . " $sChannelText");
4382 botPrivmsg($conn,$event,$tArgs[0],"\1ACTION " . $sChannelText . "\1");
4383 }
4384 else {
4385 botNotice($conn,$sNick,"Syntax error : act <#channel> <text>");
4386 }
4387 }
4388 else {
4389 my $sNoticeMsg = getEventHostmask($event) . " act command attempt (command level [2] for user " . $sMatchingUserHandle . "[" . $iMatchingUserLevel ."])";
4390 noticeConsoleChan($conn,0,$sNoticeMsg);
4391 botNotice($conn,$sNick,"Cette commande n'est pas disponible pour votre niveau. Veuillez contacter un administrateur");
4392 }
4393 }
4394 else {
4395 my $sNoticeMsg = getEventHostmask($event) . " act command attempt (user $sMatchingUserHandle is not logged in)";
4396 noticeConsoleChan($conn,0,$sNoticeMsg);
4397 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
4398 }
4399 }
4400}
4401
4402sub dbCleanActionsQueue(@) {
4403 my $sTruncateQuery = "TRUNCATE TABLE ACTIONS_QUEUE";
4404 log_message(3,"dbCleanActionsQueue() $sTruncateQuery");
4405 dbCheckHandle($dbh);
4406 my $sth = $dbh->prepare($sTruncateQuery);
4407 unless ($sth->execute ) {
4408 log_message(0,"dbCleanActionsQueue() SQL Error : " . $DBI::errstr . " Query : " . $sTruncateQuery);
4409 }
4410 else {
4411 log_message(3,"ACTIONS_QUEUE truncated");
4412 }
4413}
4414
4415sub dbProcessActionsQueue(@) {
4416 my ($conn) = @_;
4417 my $sActionsQueueQuery = "SELECT * FROM ACTIONS_QUEUE WHERE status=0 ORDER BY ts LIMIT 1";
4418 log_message(3,"dbCleanActionsQueue() $sActionsQueueQuery");
4419 dbCheckHandle($dbh);
4420 my $sth = $dbh->prepare($sActionsQueueQuery);
4421 unless ($sth->execute ) {
4422 log_message(0,"dbProcessActionsQueue() SQL Error : " . $DBI::errstr . " Query : " . $sActionsQueueQuery);
4423 }
4424 else {
4425 my $iActionCount = 0;
4426 while (my $ref = $sth->fetchrow_hashref()) {
4427 my $id_actions_queue = $ref->{'id_actions_queue'};
4428 my $ts = $ref->{'ts'};
4429 my $command = $ref->{'command'};
4430 my $params = $ref->{'params'};
4431 log_message(0,"dbProcessActionsQueue() Action id : id_actions_queue ts : $ts command : $command params : $params");
4432 if ( $command eq "DUMP" ) {
4433 $conn->sl("$params");
4434 #$sActionsQueueQuery = "UPDATE ACTIONS_QUEUE SET status=1 WHERE id_actions_queue=$id_actions_queue";
4435 $sActionsQueueQuery = "UPDATE ACTIONS_QUEUE SET status=1 WHERE id_actions_queue=?";
4436 dbCheckHandle($dbh);
4437 $sth = $dbh->prepare($sActionsQueueQuery);
4438 unless ($sth->execute($id_actions_queue)) {
4439 log_message(0,"dbProcessActionsQueue() SQL Error : " . $DBI::errstr . " Query : " . $sActionsQueueQuery);
4440 }
4441 else {
4442 log_message(0,"dbProcessActionsQueue() Process Action id : id_actions_queue ts : $ts command : $command params : $params");
4443 }
4444 }
4445 $iActionCount++;
4446 }
4447 }
4448
4449 # Re-schelude dbProcessActionsQueue($conn)
4450 $conn->schedule(20, \&dbProcessActionsQueue,$conn);
4451 log_message(3,"scheduled dbCleanActionsQueue() 20 sec");
4452}
4453
4454sub radioNext(@) {
4455 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4456 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
4457 if (defined($iMatchingUserId)) {
4458 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
4459 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
4460 unless ( open CAPSULE_CURRENT_SONG, "$MAIN_PROG_BIN_DIR/plugins/radioNext.sh |") {
4461 log_message(0,"Could not get Radio Capsule song stats with $MAIN_PROG_BIN_DIR/plugins/next.sh");
4462 }
4463 my $sLine;
4464 if (defined($sLine=<CAPSULE_CURRENT_SONG>)) {
4465 chomp($sLine);
4466 }
4467 close CAPSULE_CURRENT_SONG;
4468
4469 # Format message with irc colors
4470 my $sMsgSong = "";
4471 $sMsgSong .= String::IRC->new('[ ')->grey('black');
4472 $sMsgSong .= String::IRC->new('https://teuk.org/mediabot | http://teuk.org:8000/radio.mp3')->orange('black');
4473 $sMsgSong .= String::IRC->new(' ] ')->grey('black');
4474 $sMsgSong .= String::IRC->new(' - ')->white('black');
4475 $sMsgSong .= String::IRC->new(' [ ')->orange('black');
4476 $sMsgSong .= String::IRC->new("$sNick est passé à la suivante...")->grey('black');
4477 $sMsgSong .= String::IRC->new(' ]')->orange('black');
4478
4479 my $sNoticeMessage = "$sNick issued a next command on $sChannel";
4480 botPrivmsg($conn,$event,$sChannel,$sMsgSong);
4481
4482 noticeConsoleChan($conn,0,$sNoticeMessage);
4483 }
4484 else {
4485 botNotice($conn,$sNick,"This command is not available for your level ($iMatchingUserLevel). Contact a bot Administrator.");
4486 }
4487 }
4488 else {
4489 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
4490 }
4491 }
4492}
4493
4494sub radioNextYoutubeToPLay(@) {
4495 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4496 unless ( open CAPSULE_CURRENT_SONG, "$MAIN_PROG_BIN_DIR/plugins/radioGetNextYoutube.sh |") {
4497 log_message(0,"Could not get Radio Capsule song stats with $MAIN_PROG_BIN_DIR/plugins/radioGetNextYoutube.sh");
4498 }
4499 my $sLine;
4500 if (defined($sLine=<CAPSULE_CURRENT_SONG>)) {
4501 chomp($sLine);
4502 }
4503 close CAPSULE_CURRENT_SONG;
4504
4505 # Format message with irc colors
4506 my $sMsgSong = "";
4507 $sMsgSong .= String::IRC->new('[ ')->grey('black');
4508 $sMsgSong .= String::IRC->new('https://teuk.org/mediabot | http://teuk.org:8000/radio.mp3')->orange('black');
4509 $sMsgSong .= String::IRC->new(' ] ')->grey('black');
4510 $sMsgSong .= String::IRC->new(' - ')->white('black');
4511 $sMsgSong .= String::IRC->new(' [ ')->orange('black');
4512 $sMsgSong .= String::IRC->new("Track youtube suivante : ")->white('black');
4513 $sMsgSong .= String::IRC->new("$sLine")->grey('black');
4514 $sMsgSong .= String::IRC->new(' ]')->orange('black');
4515
4516 my $sNoticeMessage = "$sNick issued a nextyt command on $sChannel";
4517 botPrivmsg($conn,$event,$sChannel,$sMsgSong);
4518
4519 noticeConsoleChan($conn,0,$sNoticeMessage);
4520
4521}
4522
4523sub radioSetDj(@) {
4524 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4525 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
4526 if (defined($iMatchingUserId)) {
4527 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
4528 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
4529 my $sMsgSong = "";
4530
4531 unless (defined($sCurrentDjNick)) {
4532 $sCurrentDjNick = $sNick;
4533 $sMsgSong .= String::IRC->new('[ ')->grey('black');
4534 $sMsgSong .= String::IRC->new('https://teuk.org/mediabot | http://teuk.org:8000/radio.mp3')->orange('black');
4535 $sMsgSong .= String::IRC->new(' ] ')->grey('black');
4536 $sMsgSong .= String::IRC->new(' - ')->white('black');
4537 $sMsgSong .= String::IRC->new(' [ ')->orange('black');
4538 $sMsgSong .= String::IRC->new("$sNick est le Dj courant ! Live session !")->grey('black');
4539 $sMsgSong .= String::IRC->new(' ]')->orange('black');
4540 botPrivmsg($conn,$event,$sChannel,$sMsgSong);
4541 }
4542 else {
4543 botNotice($conn,$sNick,"Hey $sNick, $sCurrentDjNick is already the current DJ !");
4544 }
4545
4546 my $sNoticeMessage = "$sNick issued a setdj command on $sChannel";
4547 noticeConsoleChan($conn,0,$sNoticeMessage);
4548 }
4549 else {
4550 botNotice($conn,$sNick,"This command is not available for your level ($iMatchingUserLevel). Contact a bot Administrator.");
4551 }
4552 }
4553 else {
4554 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
4555 }
4556 }
4557}
4558
4559sub radioSetPlaylist(@) {
4560 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4561 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
4562 if (defined($iMatchingUserId)) {
4563 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
4564 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
4565 if (defined($sCurrentDjNick)) {
4566 $sCurrentDjNick = undef;
4567 my $sMsgSong .= String::IRC->new('[ ')->grey('black');
4568 $sMsgSong .= String::IRC->new('https://teuk.org/mediabot | http://teuk.org:8000/radio.mp3')->orange('black');
4569 $sMsgSong .= String::IRC->new(' ] ')->grey('black');
4570 $sMsgSong .= String::IRC->new(' - ')->white('black');
4571 $sMsgSong .= String::IRC->new(' [ ')->orange('black');
4572 $sMsgSong .= String::IRC->new("Fin du live ! Retour à la playlist !")->grey('black');
4573 $sMsgSong .= String::IRC->new(' ]')->orange('black');
4574 botPrivmsg($conn,$event,$sChannel,$sMsgSong);
4575 }
4576 else {
4577 botNotice($conn,$sNick,"Hey $sNick, there's not current DJ !");
4578 }
4579
4580 my $sNoticeMessage = "$sNick issued a playlist command on $sChannel";
4581 noticeConsoleChan($conn,0,$sNoticeMessage);
4582 }
4583 else {
4584 botNotice($conn,$sNick,"This command is not available for your level ($iMatchingUserLevel). Contact a bot Administrator.");
4585 }
4586 }
4587 else {
4588 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
4589 }
4590 }
4591}
4592
4593sub playYoutube(@) {
4594 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4595 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
4596 if (defined($iMatchingUserId)) {
4597 if (defined($iMatchingUserAuth) && $iMatchingUserAuth) {
4598 if (defined($iMatchingUserLevel) && ($iMatchingUserLevel <= $LEVEL_USER)) {
4599 my $sMp3File;
4600 noticeConsoleChan($conn,0,"Starting download of " . $tArgs[0]);
4601 unless ( open YT_DL ,"cd /home/mediabot/incoming ; youtube-dl -x --audio-format mp3 --add-metadata " . $tArgs[0] . " |" ) {
4602 log_message(0,"Could not youtube-dl -x --audio-format mp3 " . $tArgs[0]);
4603 my $sNoticeMessage = "$sNick issued a failed play " . $tArgs[0] . " command on $sChannel";
4604 noticeConsoleChan($conn,0,$sNoticeMessage);
4605 }
4606 else {
4607 my $line;
4608 my $i = 0;
4609 while (defined($line=<YT_DL>)) {
4610 chomp($line);
4611 log_message(0,"Ligne $i : $line");
4612 if ( $line =~ /^.*ffmpeg.*Destination:/ ) {
4613 $sMp3File = $line;
4614 $sMp3File =~ s/^.*ffmpeg.*Destination: //;
4615 log_message(0,"Downloading $sMp3File");
4616 noticeConsoleChan($conn,0,"Downloading $sMp3File");
4617 botPrivmsg($conn,$event,$sChannel,"Youtube play request, downloading $sMp3File");
4618 }
4619 $i++;
4620 }
4621 close YT_DL;
4622
4623 noticeConsoleChan($conn,0,"Adding to playlist queue");
4624 unless ( open YT_PL,">/home/mp3/youtube.m3u" ) {
4625 log_message(0,"Could not open /home/mp3/youtube.m3u for writing");
4626 }
4627 else {
4628 print YT_PL "/home/mediabot/incoming/$sMp3File\n";
4629 }
4630 close YT_PL;
4631
4632 log_message(0,"Reloading youtube.m3u");
4633 noticeConsoleChan($conn,0,"Reloading youtube.m3u");
4634 unless ( open LIQUIDSOAP_RELOAD_PL,"/home/mediabot/bin/plugins/radioFlushYoutube.sh |" ) {
4635 log_message(0,"Could not open /home/mediabot/bin/plugins/radioFlushYoutube.sh");
4636 }
4637 else {
4638 my $line;
4639 while(defined($line=<LIQUIDSOAP_RELOAD_PL>)) {
4640 chomp($line);
4641 log_message(0,"$line");
4642 }
4643 }
4644 botPrivmsg($conn,$event,$sChannel,"Youtube play request was successfull, next track " . $sMp3File);
4645 my $sNoticeMessage2 = "$sNick issued a successfull play " . $tArgs[0] . " command on $sChannel";
4646 noticeConsoleChan($conn,0,$sNoticeMessage2);
4647 }
4648 }
4649 else {
4650 botNotice($conn,$sNick,"This command is not available for your level ($iMatchingUserLevel). Contact a bot Administrator.");
4651 }
4652 }
4653 else {
4654 botNotice($conn,$sNick,"Vous devez être authentifié pour utiliser cette commande - /msg mediabot login username password");
4655 }
4656 }
4657}
4658
4659sub botDisplayYoutubeUrl(@) {
4660 my ($conn,$event,$sNick,$sChannel,$sText) = @_;
4661 my $sYoutubeId;
4662 #log_message(0,"botDisplayYoutubeUrl() $sText");
4663 if ( $sText =~ /http.*:\/\/www\.youtube\..*\/watch/i ) {
4664 $sYoutubeId = $sText;
4665 $sYoutubeId =~ s/^.*watch\?v=//;
4666 #my $sTempYoutubeId = ($sText =~ m/^.*(http:\/\/[^ ]+).*$]/)[0];
4667 }
4668 elsif ( $sText =~ /http.*:\/\/m\.youtube\..*\/watch/i ) {
4669 $sYoutubeId = $sText;
4670 $sYoutubeId =~ s/^.*watch\?v=//;
4671 }
4672 elsif ( $sText =~ /http.*:\/\/youtu\.be.*/i ) {
4673 $sYoutubeId = $sText;
4674 $sYoutubeId =~ s/^.*youtu\.be\///;
4675 }
4676 if (defined($sYoutubeId) && ( $sYoutubeId ne "" )) {
4677 log_message(0,"botDisplayYoutubeUrl() sYoutubeId = $sYoutubeId");
4678 unless ( open YOUTUBE_INFOS, "/home/mediabot/bin/plugins/API_Youtube.py --id " . $sYoutubeId . " | " ) {
4679 log_message(0,"Could not open /home/mediabot/bin/plugins/API_Youtube.py");
4680 }
4681 else {
4682 my $line;
4683 my $i = 0;
4684 my $sTitle;
4685 my $sDuration;
4686 my $sViewCount;
4687 while(defined($line=<YOUTUBE_INFOS>)) {
4688 chomp($line);
4689 if ( $i == 0 ) {
4690 $sTitle = $line;
4691 }
4692 elsif ( $i == 1 ) {
4693 $sDuration = $line;
4694 $sDuration =~ s/^PT//;
4695 my $sMin = $sDuration;
4696 $sMin =~ s/M.*$//;
4697 my $sSec = $sDuration;
4698 $sSec =~ s/^.*M//;
4699 $sSec =~ s/S$//;
4700 $sDuration = $sMin . "mn " . $sSec . "s";
4701 }
4702 elsif ( $i == 2 ) {
4703 $sViewCount = "vue $line fois";
4704 }
4705 #log_message(0,"botDisplayYoutubeUrl() $line");
4706 $i++;
4707 }
4708
4709 if (defined($sTitle) && ( $sTitle ne "" ) && defined($sDuration) && ( $sDuration ne "" ) && defined($sViewCount) && ( $sViewCount ne "" )) {
4710 my $sMsgSong .= String::IRC->new('You')->black('white');
4711 $sMsgSong .= String::IRC->new('Tube')->white('red');
4712 $sMsgSong .= String::IRC->new(" $sTitle ")->white('black');
4713 $sMsgSong .= String::IRC->new("- ")->orange('black');
4714 $sMsgSong .= String::IRC->new("$sDuration ")->grey('black');
4715 $sMsgSong .= String::IRC->new("- ")->orange('black');
4716 $sMsgSong .= String::IRC->new("$sViewCount")->grey('black');
4717 botPrivmsg($conn,$event,$sChannel,$sMsgSong);
4718 }
4719 else {
4720 log_message(0,"botDisplayYoutubeUrl() one of the youtube field is undef or empty");
4721 if (defined($sTitle)) {
4722 log_message(0,"botDisplayYoutubeUrl() sTitle=$sTitle");
4723 }
4724 else {
4725 log_message(0,"botDisplayYoutubeUrl() sTitle is undefined");
4726 }
4727
4728 if (defined($sDuration)) {
4729 log_message(0,"botDisplayYoutubeUrl() sDuration=$sDuration");
4730 }
4731 else {
4732 log_message(0,"botDisplayYoutubeUrl() sDuration is undefined");
4733 }
4734 if (defined($sViewCount)) {
4735 log_message(0,"botDisplayYoutubeUrl() sDuration=$sViewCount");
4736 }
4737 else {
4738 log_message(0,"botDisplayYoutubeUrl() sViewCount is undefined");
4739 }
4740 my $sMsgSong .= String::IRC->new('You')->black('white');
4741 $sMsgSong .= String::IRC->new('Tube')->white('red');
4742 $sMsgSong .= String::IRC->new(" Désolé je ne trouve pas les informations pour l'id : $sYoutubeId")->white('black');
4743 botPrivmsg($conn,$event,$sChannel,$sMsgSong);
4744 }
4745 }
4746 }
4747 else {
4748 log_message(0,"botDisplayYoutubeUrl() sYoutubeId could not be determined");
4749 }
4750
4751}
4752
4753sub botWikiquote(@) {
4754 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4755 my $wl = WordList::Phrase::FR::Proverb::Wikiquote->new;
4756 my $word = $wl->pick;
4757 botPrivmsg($conn,$event,$sChannel,"$word");
4758
4759 $conn->schedule($RADIO_CHANNEL_WIKIQUOTE_DELAY, \&botWikiquote,$conn,$event,"$RADIO_CHANNEL");
4760 log_message(3,"Scheduled botWikiquote() on $RADIO_CHANNEL $RADIO_CHANNEL_WIKIQUOTE_DELAY s");
4761}
4762
4763sub botSeen(@) {
4764 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4765 if (defined($tArgs[0]) && ( $tArgs[0] ne "" )) {
4766 my $lastSeenQuery = "SELECT * FROM EVENT_LOG WHERE nick=? ORDER BY ts DESC LIMIT 1";
4767 log_message(4,"botSeen() $lastSeenQuery");
4768 dbCheckHandle($dbh);
4769 my $sth = $dbh->prepare($lastSeenQuery);
4770 unless ($sth->execute($tArgs[0])) {
4771 log_message(0,"botSeen() SQL Error : " . $DBI::errstr . " Query : " . $lastSeenQuery);
4772 }
4773 else {
4774 if (my $ref = $sth->fetchrow_hashref()) {
4775 my $ts = $ref->{'ts'};
4776 my $command = $ref->{'command'};
4777 my $userhost = $ref->{'userhost'};
4778 my $args = $ref->{'args'};
4779 log_message(3,"botSeen() Last seen " . $tArgs[0] . "$userhost $ts $args");
4780 if (defined($ts) && ( $ts ne "")) {
4781 botPrivmsg($conn,$event,$sChannel,$tArgs[0] . " ($userhost) dernière fois vu $ts $args");
4782 }
4783 }
4784 else {
4785 botPrivmsg($conn,$event,$sChannel,"Je ne me souviens pas avoir vu " . $tArgs[0]);
4786 }
4787 }
4788 }
4789 else {
4790 botPrivmsg($conn,$event,$sChannel,"$sNick, erreur de syntaxe .seen nickname");
4791 log_message(0,"botSeen() Missing argument");
4792 }
4793}
4794
4795sub botQuote(@) {
4796 my ($conn,$event,$sNick,$sChannel,@tArgs) = @_;
4797 my $sAnswerQuery = "SELECT answer FROM RANDOM_ANSWER ORDER BY RAND() LIMIT 1";
4798 dbCheckHandle($dbh);
4799 my $sth = $dbh->prepare($sAnswerQuery);
4800 unless ($sth->execute ) {
4801 log_message(0,"botQuote() SQL Error : " . $DBI::errstr . " Query : " . $sAnswerQuery);
4802 }
4803 else {
4804 if (my $ref = $sth->fetchrow_hashref()) {
4805 my $answer = $ref->{'answer'};
4806 botPrivmsg($conn,$event,$sChannel,"$answer");
4807 }
4808 }
4809 $conn->schedule($RADIO_CHANNEL_BOTQUOTE_DELAY, \&botQuote,$conn,$event,"$RADIO_CHANNEL");
4810 log_message(3,"Scheduled botQuote() on $RADIO_CHANNEL $RADIO_CHANNEL_BOTQUOTE_DELAY s");
4811}
4812
4813sub getUserChannelLevel(@) {
4814 my ($sChannel,$iIdUser) = @_;
4815 my $iChannelUserLevel = 0;
4816 my $sGetChannelUserLevel = "SELECT level FROM USER_CHANNEL,CHANNEL WHERE USER_CHANNEL.id_channel=CHANNEL.id_channel AND CHANNEL.name=? AND USER_CHANNEL.id_user=?";
4817 log_message(3,"getUserChannelLevel() $sGetChannelUserLevel");
4818 dbCheckHandle($dbh);
4819 my $sth = $dbh->prepare($sGetChannelUserLevel);
4820 unless ($sth->execute($sChannel,$iIdUser)) {
4821 log_message(0,"getUserChannelLevel() SQL Error : " . $DBI::errstr . " Query : " . $sGetChannelUserLevel);
4822 }
4823 else {
4824 if (my $ref = $sth->fetchrow_hashref()) {
4825 $iChannelUserLevel = $ref->{'level'};
4826 }
4827 log_message(3,"getUserChannelLevel() iChannelUserLevel = $iChannelUserLevel");
4828 }
4829 return $iChannelUserLevel;
4830}
4831
4832sub getUserChannelLevelByName(@) {
4833 my ($sChannel,$sHandle) = @_;
4834 my $iChannelUserLevel = 0;
4835 my $sGetChannelUserLevel = "SELECT level FROM USER,USER_CHANNEL,CHANNEL WHERE USER.id_user=USER_CHANNEL.id_user AND USER_CHANNEL.id_channel=CHANNEL.id_channel AND CHANNEL.name=? AND USER.nickname=?";
4836 log_message(3,"getUserChannelLevel() $sGetChannelUserLevel");
4837 dbCheckHandle($dbh);
4838 my $sth = $dbh->prepare($sGetChannelUserLevel);
4839 unless ($sth->execute($sChannel,$sHandle)) {
4840 log_message(0,"getUserChannelLevelByName() SQL Error : " . $DBI::errstr . " Query : " . $sGetChannelUserLevel);
4841 }
4842 else {
4843 if (my $ref = $sth->fetchrow_hashref()) {
4844 $iChannelUserLevel = $ref->{'level'};
4845 }
4846 log_message(3,"getUserChannelLevelByName() iChannelUserLevel = $iChannelUserLevel");
4847 }
4848 return $iChannelUserLevel;
4849}
4850
4851sub getIdChannel(@) {
4852 my ($sChannel) = @_;
4853 my $id_channel = undef;
4854 my $sQuery = "SELECT * FROM CHANNEL WHERE name=?";
4855 dbCheckHandle($dbh);
4856 my $sth = $dbh->prepare($sQuery);
4857 unless ($sth->execute($sChannel) ) {
4858 log_message(0,"getIdChannel() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
4859 }
4860 else {
4861 if (my $ref = $sth->fetchrow_hashref()) {
4862 $id_channel = $ref->{'id_channel'};
4863 }
4864 }
4865 return $id_channel;
4866}
4867
4868sub logBot(@) {
4869 my ($conn,$event,$sChannel,$action,@tArgs) = @_;
4870 my ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2);
4871 my $sUserhost;
4872 if (defined($event)) {
4873 ($iMatchingUserId,$iMatchingUserLevel,$iMatchingUserLevelDesc,$iMatchingUserAuth,$sMatchingUserHandle,$sMatchingUserPasswd,$sMatchingUserInfo1,$sMatchingUserInfo2) = getNickInfo($conn,$event);
4874 my $sHostmask = getEventHostmask($event);
4875 my $id_user = undef;
4876 my $sUser = "Utilisateur inconnu";
4877 if (defined($iMatchingUserId)) {
4878 $id_user = $iMatchingUserId;
4879 $sUser = $sMatchingUserHandle;
4880 }
4881 my $id_channel = undef;
4882 if (defined($sChannel)) {
4883 $id_channel = getIdChannel($sChannel);
4884 }
4885 my $sQuery = "INSERT INTO ACTIONS_LOG (ts,id_user,id_channel,hostmask,action,args) VALUES (?,?,?,?,?,?)";
4886 my $sth = $dbh->prepare($sQuery);
4887 unless ($sth->execute(time2str("%Y-%m-%d %H-%M-%S",time),$id_user,$id_channel,$sHostmask,$action,join(" ",@tArgs))) {
4888 log_message(0,"logBot() SQL Error : " . $DBI::errstr . " Query : " . $sQuery);
4889 }
4890 else {
4891 log_message(3,"logBot() inserted " . $action . " action into ACTIONS_LOG");
4892 my $sNoticeMsg = "($sUser : $sHostmask) commande $action " . join(" ",@tArgs);
4893 if (defined($sChannel)) {
4894 $sNoticeMsg .= " on $sChannel";
4895 }
4896 noticeConsoleChan($conn,0,$sNoticeMsg);
4897 }
4898 log_message(3,"logBot() sHostmask = $sHostmask action = $action tArgs = " . join(" ",@tArgs));
4899 }
4900 else {
4901 log_message(3,"logBot() event is undefined");
4902 }
4903}