$chat_buffer->signal_connect(insert_text => sub { $chat_textview->scroll_to_mark( $chat_buffer->get_mark('end'), 0.0, TRUE, 0, 0.5 ); }); #### #!/usr/local/bin/perl -w use strict; use Gtk2 '-init'; use Glib qw/TRUE FALSE/; use Net::IRC; use threads; use threads::shared; my $irc = new Net::IRC; my $chat_state = 'Connect'; my $chat_entry; my $chat_send_sig; my $chat_textview; my $chat_button; my $sys_msg; my $tag; my $job = 1; my $die:shared = 0; my $chat_start:shared = 0; my $channel:shared = "#GRRUVI"; my $irc_server:shared = "irc.servercentral.net"; my $nick:shared = "VCBase"; my $msg:shared; my $post:shared = 0; my $name:shared = 0; my $list:shared; ################################################# #Threads my $thread_chat = threads->new(\&chat); ################################################# ################################################# #Timeout my $timer_post = Glib::Timeout->add(100, \&post); ################################################# #-------------------Main Loop------------------- &chat_build; Gtk2->main; ####################CHAT BLOCK#################### #-------------------chat Build------------------- sub chat_build { my $chat_window = Gtk2::Window->new('toplevel'); $chat_window->set_title('Chat Client'); $chat_window->set_position('center'); $chat_window->set_default_size( 300, 300 ); $chat_window->signal_connect(delete_event=> sub{ $die = 1; $thread_chat->join; Gtk2->main_quit; }); $chat_entry = Gtk2::Entry->new; my $chat_vbox = Gtk2::VBox->new; my $chat_scroll = Gtk2::ScrolledWindow->new; $chat_scroll->set_shadow_type( 'etched-out'); $chat_textview = Gtk2::TextView->new; my $chat_buffer = $chat_textview->get_buffer; $chat_buffer->create_mark( 'end', $chat_buffer->get_end_iter, FALSE ); $chat_buffer->signal_connect(insert_text => sub { $chat_textview->scroll_to_mark( $chat_buffer->get_mark('end'), 0.0, TRUE, 0, 0.5 ); }); $chat_button = Gtk2::Button->new; $chat_button->set_label($chat_state); # allows for sending each line with an enter keypress $chat_send_sig = $chat_entry->signal_connect ('key-press-event' => sub { my ($widget,$event)= @_; if( $event->keyval() == 65293){ # a return key press $msg = $chat_entry->get_text; $chat_entry->set_text(''); $chat_entry->set_position(0); $chat_start = 2; $name = $nick; $post = 6; #print "$chat_start\n"; } }); $chat_entry->signal_handler_block($chat_send_sig); #not connected yet $chat_entry->set_editable(0); $chat_textview->set_editable(0); $chat_textview->set_cursor_visible(0); $chat_textview->set_wrap_mode('word'); $chat_scroll->add($chat_textview); $chat_vbox->add($chat_scroll); $chat_vbox->pack_start( $chat_entry, FALSE, FALSE, 0 ); $chat_vbox->pack_start( $chat_button, FALSE, FALSE, 0 ); $chat_window->add($chat_vbox); $chat_window->show_all; $chat_button->signal_connect("clicked" => sub { if ($chat_state eq 'Connect') { $chat_button->set_label('Disconnect'); $chat_state='Disconnect'; $chat_start = 1; $post = 1; } else { $chat_button->set_label('Connect'); $chat_state='Connect'; $chat_start = 0; $post = 5; } }); return 1; } #-------------------Post to Textview------------------- sub post { #my ($name, $msg) = @_; my @time = gmtime; my $hour = $time[2]; my $min = $time[1]; my $sec = $time[0]; $hour = "0$time[2]" if $time[2] < 10; $min = "0$time[1]" if $time[1] < 10; $sec = "0$time[0]" if $time[0] < 10; my $post_time = "($hour:$min:$sec)"; my $chat_buffer = $chat_textview->get_buffer; #connecting if ($post == 1){ $chat_buffer->insert( $chat_buffer->get_end_iter, "Connecting to $irc_server..\n" ); $post = 0; print CHAT "Connecting to $irc_server..\n" if $job == 3; } #Connected if ($post == 2){ $chat_buffer->insert( $chat_buffer->get_end_iter, "Connected to $irc_server\n" ); $chat_entry->set_editable(1); $chat_entry->grab_focus; $chat_entry->signal_handler_unblock ($chat_send_sig); $post = 0; print CHAT "Connected to $irc_server\n" if $job == 3; } #Joined if ($post == 3){ if ($name ne $nick){ $chat_buffer->insert_with_tags( $chat_buffer->get_end_iter, "$name Joined $channel$post_time\n", $chat_buffer->create_tag($tag, foreground=>'red')); } else{ $chat_buffer->insert( $chat_buffer->get_end_iter, "$name Joined $channel$post_time\n"); } $post = 0; print CHAT "$name Joined $channel$post_time\n" if $job == 3; } #Users if ($post == 4){ #print "$list\n"; $chat_buffer->insert( $chat_buffer->get_end_iter, "Users on $channel: $list\n" ); $post = 0; print CHAT "Users on $channel: $list\n" if $job == 3; } #disconnect if ($post == 5){ $chat_buffer->insert( $chat_buffer->get_end_iter, "Disconnecting$post_time\n" ); $chat_entry->set_editable(0); $chat_entry->grab_focus; $chat_entry->signal_handler_block ($chat_send_sig); $post = 0; print CHAT "Disconnecting$post_time\n" if $job == 3; } #Posts if ($post == 6){ if ($name ne $nick){ $chat_buffer->insert_with_tags( $chat_buffer->get_end_iter, "$name$post_time: $msg\n", $chat_buffer->create_tag($tag, foreground=>'red')); } else{ $chat_buffer->insert( $chat_buffer->get_end_iter, "$name$post_time: $msg\n"); } print CHAT "$name$post_time: $msg\n" if $job == 3; $post = 0; } #Disconnected if ($post == 7){ $chat_buffer->insert( $chat_buffer->get_end_iter, "Disconnected->Reconnecting$post_time\n"); print CHAT "Disconnected->Reconnecting$post_time\n" if $job == 3; $post = 0; } #Nick taken if ($post == 8){ $chat_buffer->insert( $chat_buffer->get_end_iter, "Nick is Taken->Please Change\n"); $chat_entry->set_editable(0); $chat_entry->grab_focus; $chat_entry->signal_handler_block ($chat_send_sig); $chat_start = 0; $chat_state = 'Connect'; $chat_button->set_label($chat_state); $chat_buffer->insert( $chat_buffer->get_end_iter, "Nick is Taken->Please Change\n" ); print CHAT "Connecting to $irc_server..\n" if $job == 3; $post = 0; } #Quit if ($post == 9){ $chat_buffer->insert_with_tags( $chat_buffer->get_end_iter, "$name has QUIT$post_time\n", $chat_buffer->create_tag($tag, foreground=>'red')); print CHAT "$name has QUIT$post_time\n" if $job == 3; $post = 0; } return 1; } ################################################## ####################Threads#################### sub chat{ while (1){ my $conn; goto END if $die == 1; if ($chat_start == 1){ print "starting...\n"; $conn = $irc->newconn(Server => $irc_server, Port => 6667, Nick => $nick, Ircname => "CoCoNUE Member $nick") or die "Can't connect to IRC server\n"; #Install Handlers $conn->add_handler('cping', \&on_ping); # $conn->add_handler('crping', \&on_ping_reply); # $conn->add_handler('join', \&on_join); #3 $conn->add_handler('quit', \&on_quit); #9 $conn->add_handler('public', \&on_public); #6 $conn->add_global_handler([ 251,252,253,254,302,255 ], \&on_init); $conn->add_global_handler('disconnect', \&on_disconnect); #7 $conn->add_global_handler(376, \&on_connect); #2 $conn->add_global_handler(433, \&on_nick_taken); #8 $conn->add_global_handler(353, \&on_names); #4 for (;;){ $irc->do_one_loop; #print "Looped: Reading\n"; if ($chat_start == 2){ #print "Looped: Sending\n"; $conn->privmsg("$channel", "$msg"); $chat_start = 1 if $chat_start != 0; } goto END if $die == 1; last if $chat_start == 0; } $irc->removeconn($conn); } } END: } #-------------------Handlers------------------- # What to do when the bot successfully connects. sub on_connect { my $self = shift; $post = 2; sleep 1; print "Joining $channel...\n"; $self->join("$channel"); } # Handles some messages you get when you connect:::For testing sub on_init { my ($self, $event) = @_; my (@args) = ($event->args); shift (@args); print "*** @args\n"; } # What to do when someone leaves a channel the bot is on. sub on_quit { my ($self, $event) = @_; #my ($channel) = ($event->to)[0]; $name = $event->nick; $post = 9; printf "*** %s has left channel %s\n", $event->nick, $channel; } # What to do when someone joins a channel the bot is on. sub on_join { my ($self, $event) = @_; #my ($channel) = ($event->to)[0]; $name = $event->nick; $post = 3; sleep 1; printf "*** %s (%s) has joined channel %s\n", $event->nick, $event->userhost, $channel; if ($event->userhost =~ /^corbeau\@.*execpc\.com/) { # Auto-ops anyone who $self->mode("#IRC.pm", "+o", $event->nick); # matches hostmask. } } # Prints the names of people in a channel when we enter. sub on_names { my ($self, $event) = @_; my (@list) = ($event->args); # eat yer heart out, mjd! # splice() only works on real arrays. Sigh. ($channel, @list) = splice @list, 2; $list = join(" ", @list); print "$list\n"; $post = 4; print "Users on $channel: @list\n"; } # Yells about incoming CTCP PINGs. sub on_ping { my ($self, $event) = @_; my $name = $event->nick; $self->ctcp_reply($name, join (' ', ($event->args))); print "*** CTCP PING request from $name received\n"; } # Gives lag results for outgoing PINGs. sub on_ping_reply { my ($self, $event) = @_; my ($args) = ($event->args)[1]; my ($name) = $event->nick; $args = time - $args; print "*** CTCP PING reply from $name: $args sec.\n"; } # Change our nick if someone stole it. sub on_nick_taken { my ($self) = shift; #$chat_start = 0; #$chat_state = 'Connect'; $post = 8; #$self->nick(substr($self->nick, -1) . substr($self->nick, 0, 8)); } # Reconnect to the server when we die. sub on_disconnect { my ($self, $event) = @_; $post = 7; print "Disconnected from ", $event->from(), " (", ($event->args())[0], "). Attempting to reconnect...\n"; $self->connect(); } # What to do when we receive channel text. sub on_public { my ($self, $event) = @_; my @to = $event->to; my ($them, $me) = ($event->nick, $self->nick); ($msg) = ($event->args); $name = $event->nick; #$msg = $arg; $post = 6; # Note that $event->to() returns a list (or arrayref, in scalar # context) of the message's recipients, since there can easily be # more than one. print "<$them> $msg\n"; }