<commit_before>package Plugin;

use strict;
use warnings;
use Tools;

##
# Base class for SimpleIRC Plugins
##

sub add_custom_command{
	# add custom IRC command like /ns
	my ($self, $cmd, $code) = @_;
	
	$self->log_debug(4, "Adding custom command: /".uc($cmd));
	
	my $wrapper = sub {
		my $ircd = shift;
		my $nick = shift;
		my $value = join(' ', @_);
		
		$code->( $self, $nick, $value );
		
		return () if wantarray;
		return [];
	};
	
	my $func_name = '_daemon_cmd_' . $cmd;
	eval '*POE::Component::Server::IRC::Simple::'.$func_name.' = $wrapper;';
}

sub send_msg_to_user {
	# send message or notice to user
	my ($self, $nick, $type, $msg) = @_;
	
	my ($package, undef, undef) = caller();
	$package =~ s/^(.+)::(\w+)$/$2/;
	
	my $route_id = $self->{ircd}->_state_user_route($nick);
	if (!$route_id) {
		my $unick = $self->{resident}->get_irc_username( $nick );
		if ($unick) { $route_id = $self->{ircd}->_state_user_route($unick); }
		if (!$route_id) { return; }
	}
	
	$self->log_debug(9, "Sending $type to $nick: $msg");
	
	foreach my $line (split(/\n/, $msg)) {
		next unless $line =~ /\S/;
		$self->{ircd}->_send_output_to_client( $route_id, {
			prefix  => $package,
			command => $type,
			params  => [ $nick, $line ]
		});
	}
	
	$self->{resident}->log_event(
		log => 'transcript',
		package => '0.0.0.0',
		level => $package,
		msg => "$type $nick $msg"
	);
}

sub send_msg_to_channel_user {
	# send message or notice to user inside channel
	# but don't broadcast to any other users in the channel (NEAT TRICK!)
	my ($self, $nick, $chan, $type, $msg) = @_;
	
	my ($package, undef, undef) = caller();
	$package =~ s/^(.+)::(\w+)$/$2/;
	
	my $route_id = $self->{ircd}->_state_user_route($nick);
	if (!$route_id) {
		my $unick = $self->{resident}->get_irc_username( $nick );
		if ($unick) { $route_id = $self->{ircd}->_state_user_route($unick); }
		if (!$route_id) { return; }
	}
	
	$self->log_debug(9, "Sending $type to $nick in $chan: $msg");
	
	foreach my $line (split(/\n/, $msg)) {
		next unless $line =~ /\S/;
		$self->{ircd}->_send_output_to_client( $route_id, {
			prefix  => $self->{ircd}->state_user_full($package),
			command => $type,
			params  => [ nch($chan), $line ]
		});
	}
	
	$self->{resident}->log_event(
		log => 'transcript',
		package => '0.0.0.0',
		level => $package,
		msg => "$type $nick $chan $msg"
	);
}

sub send_msg_to_channel {
	# send message to everyone in channel
	my ($self, $chan, $type, $msg) = @_;
	$chan = nch($chan);
	
	my ($package, undef, undef) = caller();
	$package =~ s/^(.+)::(\w+)$/$2/;
	
	$self->log_debug(9, "Sending $type to $chan: $msg");
	
	$self->{ircd}->_send_output_to_channel( $chan, { 
		prefix => $package, 
		command => $type, 
		params => [$chan, $msg] 
	} );
	
	$self->{resident}->log_event(
		log => 'transcript',
		package => '', # usually source ip
		level => $package,
		msg => "$type $chan $msg"
	);
}

sub do_plugin_help {
	# display help for plugin or specific command
	my ($self, $nick, $msg) = @_;
	
	my ($package, undef, undef) = caller();
	$package =~ s/^(.+)::(\w+)$/$2/;
	
	my $help_content = '';
	
	if ($msg =~ /^help$/i) {
		# general help for plugin
		my $help_file = "conf/help/Plugins/$package.txt";
		if (-e $help_file) { $help_content = load_file($help_file); }
		else { $help_content = "Sorry, there is no help available for $package."; }
	}
	elsif ($msg =~ /^help\s+(\w+)$/i) {
		# help for a specific command
		my $cmd = lc($1);
		my $help_file = "conf/help/Plugins/$package/$cmd.txt";
		if (-e $help_file) { $help_content = load_file($help_file); }
		else { $help_content = "Sorry, there is no help available for the ".uc($cmd)." command."; }
	}
	
	foreach my $line (split(/\n/, $help_content)) {
		if ($line =~ /\S/) {
			my $route_id = $self->{ircd}->_state_user_route($nick);
			if (!$route_id) { return; }
							
			$self->{ircd}->_send_output_to_client( $route_id, {
				prefix  => $package,
				command => 'PRIVMSG',
				params  => [ $nick, $line ]
			});
		} # line has non-whitespace
	} # foreach help line
}

sub schedule_idle {
	# run any schedudle items that are due
	my $self = shift;
	my $now = time();
	
	foreach my $id (keys %{$self->{schedule}}) {<commit_msg>Fixed bug where the built-in service bots (NickServ, ChanServ) were not sending notices with the correct sender, resulting in Textual 5 not auto-authenticating users on connect.<commit_after>package Plugin;

use strict;
use warnings;
use Tools;

##
# Base class for SimpleIRC Plugins
##

sub add_custom_command{
	# add custom IRC command like /ns
	my ($self, $cmd, $code) = @_;
	
	$self->log_debug(4, "Adding custom command: /".uc($cmd));
	
	my $wrapper = sub {
		my $ircd = shift;
		my $nick = shift;
		my $value = join(' ', @_);
		
		$code->( $self, $nick, $value );
		
		return () if wantarray;
		return [];
	};
	
	my $func_name = '_daemon_cmd_' . $cmd;
	eval '*POE::Component::Server::IRC::Simple::'.$func_name.' = $wrapper;';
}

sub send_msg_to_user {
	# send message or notice to user
	my ($self, $nick, $type, $msg) = @_;
	
	my ($package, undef, undef) = caller();
	$package =~ s/^(.+)::(\w+)$/$2/;
	
	my $route_id = $self->{ircd}->_state_user_route($nick);
	if (!$route_id) {
		my $unick = $self->{resident}->get_irc_username( $nick );
		if ($unick) { $route_id = $self->{ircd}->_state_user_route($unick); }
		if (!$route_id) { return; }
	}
	
	$self->log_debug(9, "Sending $type to $nick: $msg");
	
	foreach my $line (split(/\n/, $msg)) {
		next unless $line =~ /\S/;
		$self->{ircd}->_send_output_to_client( $route_id, {
			prefix  => $self->{ircd}->state_user_full($package),
			command => $type,
			params  => [ $nick, $line ]
		});
	}
	
	$self->{resident}->log_event(
		log => 'transcript',
		package => '0.0.0.0',
		level => $package,
		msg => "$type $nick $msg"
	);
}

sub send_msg_to_channel_user {
	# send message or notice to user inside channel
	# but don't broadcast to any other users in the channel (NEAT TRICK!)
	my ($self, $nick, $chan, $type, $msg) = @_;
	
	my ($package, undef, undef) = caller();
	$package =~ s/^(.+)::(\w+)$/$2/;
	
	my $route_id = $self->{ircd}->_state_user_route($nick);
	if (!$route_id) {
		my $unick = $self->{resident}->get_irc_username( $nick );
		if ($unick) { $route_id = $self->{ircd}->_state_user_route($unick); }
		if (!$route_id) { return; }
	}
	
	$self->log_debug(9, "Sending $type to $nick in $chan: $msg");
	
	foreach my $line (split(/\n/, $msg)) {
		next unless $line =~ /\S/;
		$self->{ircd}->_send_output_to_client( $route_id, {
			prefix  => $self->{ircd}->state_user_full($package),
			command => $type,
			params  => [ nch($chan), $line ]
		});
	}
	
	$self->{resident}->log_event(
		log => 'transcript',
		package => '0.0.0.0',
		level => $package,
		msg => "$type $nick $chan $msg"
	);
}

sub send_msg_to_channel {
	# send message to everyone in channel
	my ($self, $chan, $type, $msg) = @_;
	$chan = nch($chan);
	
	my ($package, undef, undef) = caller();
	$package =~ s/^(.+)::(\w+)$/$2/;
	
	$self->log_debug(9, "Sending $type to $chan: $msg");
	
	$self->{ircd}->_send_output_to_channel( $chan, { 
		prefix => $self->{ircd}->state_user_full($package),
		command => $type, 
		params => [$chan, $msg] 
	} );
	
	$self->{resident}->log_event(
		log => 'transcript',
		package => '', # usually source ip
		level => $package,
		msg => "$type $chan $msg"
	);
}

sub do_plugin_help {
	# display help for plugin or specific command
	my ($self, $nick, $msg) = @_;
	
	my ($package, undef, undef) = caller();
	$package =~ s/^(.+)::(\w+)$/$2/;
	
	my $help_content = '';
	
	if ($msg =~ /^help$/i) {
		# general help for plugin
		my $help_file = "conf/help/Plugins/$package.txt";
		if (-e $help_file) { $help_content = load_file($help_file); }
		else { $help_content = "Sorry, there is no help available for $package."; }
	}
	elsif ($msg =~ /^help\s+(\w+)$/i) {
		# help for a specific command
		my $cmd = lc($1);
		my $help_file = "conf/help/Plugins/$package/$cmd.txt";
		if (-e $help_file) { $help_content = load_file($help_file); }
		else { $help_content = "Sorry, there is no help available for the ".uc($cmd)." command."; }
	}
	
	foreach my $line (split(/\n/, $help_content)) {
		if ($line =~ /\S/) {
			my $route_id = $self->{ircd}->_state_user_route($nick);
			if (!$route_id) { return; }
							
			$self->{ircd}->_send_output_to_client( $route_id, {
				prefix  => $self->{ircd}->state_user_full($package),
				command => 'PRIVMSG',
				params  => [ $nick, $line ]
			});
		} # line has non-whitespace
	} # foreach help line
}

sub schedule_idle {
	# run any schedudle items that are due
	my $self = shift;
	my $now = time();
	
	foreach my $id (keys %{$self->{schedule}}) {
{'fraction_non_alphanumeric': 0.21196978500871586, 'fraction_numerical': 0.004067402672864613, 'mean_word_length': 3.567940552016985, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 129, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6907523', 'n_tokens_mistral': 3648, 'n_tokens_neox': 3317, 'n_words': 813}