From c7e29b9411cd6dce0708bb90e7da4d2a1f7c198d Mon Sep 17 00:00:00 2001 From: m0rfar Date: Fri, 22 Jan 2010 18:41:23 +0000 Subject: [PATCH] rcon2irc updates by merlijn git-svn-id: svn://svn.icculus.org/nexuiz/trunk@8521 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- server/rcon2irc/bans.pl | 43 +++++++++++++++++------ server/rcon2irc/joinsparts.pl | 19 ++++++++-- server/rcon2irc/ping-pl.pl | 18 +++++----- server/rcon2irc/qnetauth.pl | 62 ++++++++++++++++++++++++++++++++ server/rcon2irc/showlogins.pl | 66 ++++++++++++++++++++++++++--------- 5 files changed, 169 insertions(+), 39 deletions(-) create mode 100644 server/rcon2irc/qnetauth.pl diff --git a/server/rcon2irc/bans.pl b/server/rcon2irc/bans.pl index 1e30bc781..bb526a5d1 100644 --- a/server/rcon2irc/bans.pl +++ b/server/rcon2irc/bans.pl @@ -1,29 +1,50 @@ # Nexuiz rcon2irc plugin by Merlijn Hofstra licensed under GPL - bans.pl # Place this file inside the same directory as rcon2irc.pl and add the full filename to the plugins. -$store{plugin_bans}->{interval} = 300; #interval to displays bans +$store{plugin_bans}->{interval} = 60; #interval to displays bans sub out ($$@); sub schedule($$); -schedule sub { - my ($timer) = @_; - if ($store{plugin_bans}->{attempts}) { - foreach (sort keys %{ $store{plugin_bans}->{attempts} }) { - out irc => 0, "PRIVMSG $config{irc_channel} :\00305* banned client\017 \00304$_\017 was refused to connect \00304" . - $store{plugin_bans}->{attempts}->{$_} . "\017 times"; +if (defined %config) { + schedule sub { + my ($timer) = @_; + if ($store{plugin_bans}->{attempts}) { + foreach (sort keys %{ $store{plugin_bans}->{attempts} }) { + # Generate names + my %temp = undef; + my @names = grep !$temp{$_}++, @{ $store{plugin_bans}->{names}->{$_} }; + + out irc => 0, "PRIVMSG $config{irc_channel} :\00305* banned client\017 \00304$_\017 was denied access \00304" . + $store{plugin_bans}->{attempts}->{$_} . "\017 times" . + (scalar(@names) ? ' with name(s): ' . join("\017, ", @names) : ''); + } + $store{plugin_bans}->{attempts} = undef; + $store{plugin_bans}->{names} = undef; } - $store{plugin_bans}->{attempts} = undef; - } - schedule $timer => $store{plugin_bans}->{interval};; -} => 1; + schedule $timer => $store{plugin_bans}->{interval};; + } => 1; +} + +# old style without names [ dp => q{(?:\^\d)?NOTE:(?:\^\d)? banned client (\d+\.\d+\.\d+\.\d+) just tried to enter} => sub { my ($ip) = @_; $store{plugin_bans}->{attempts}->{$ip} += 1; return 0; } ], +# new style with names if known +[ dp => q{(?:\^\d)?NOTE:(?:\^\d)? banned client (\d+\.\d+\.\d+\.\d+) \((.*)\) just tried to enter} => sub { + my ($ip,$name) = @_; + $name = color_dp2irc $name; + $store{plugin_bans}->{attempts}->{$ip} += 1; + if ($name && $name ne 'unconnected') { + push @{ $store{plugin_bans}->{names}->{$ip} }, $name; + } + return 0; +} ], + [ dp => q{(?:\^\d)?NOTE:(?:\^\d)? banned client (.*) has to go} => sub { my ($name) = @_; $name = color_dp2irc $name; diff --git a/server/rcon2irc/joinsparts.pl b/server/rcon2irc/joinsparts.pl index ce0e96ee2..72bd544ce 100644 --- a/server/rcon2irc/joinsparts.pl +++ b/server/rcon2irc/joinsparts.pl @@ -8,7 +8,8 @@ irc_show_playerip => 0, irc_show_mapname => 0, irc_show_amount_of_players => 0, - irc_show_country => 0 + irc_show_country => 0, + check_clones => 1 ); # current code has been tested against version 0.8 of the Geo::IPfree module @@ -41,13 +42,25 @@ sub get_player_count my $pj = $store{plugin_joinsparts}; $pj->{alive_check}->[$slot] = 1; - my ($cn) = $pj->{geo}->LookUp($ip) if ($pj->{irc_show_country} && $ip ne 'bot'); + return 0 if ($ip eq 'bot'); + + my ($cn) = $pj->{geo}->LookUp($ip) if ($pj->{irc_show_country}); + + my $clonenicks; + if ($pj->{check_clones}) { + for (1 .. $store{slots_max}) { + my $plrid = $store{"playerid_byslot_$_"}; + next if (!defined $plrid || $plrid == $id || $ip ne $store{"playerip_byid_$plrid"}); + $clonenicks .= ' ' . $store{"playernick_byid_$plrid"} . "\017"; + } + } $nick = color_dp2irc $nick; - if ($pj->{irc_announce_joins} && !$store{"playerid_byslot_$slot"} && $ip ne 'bot') { + if ($pj->{irc_announce_joins} && !$store{"playerid_byslot_$slot"}) { out irc => 0, "PRIVMSG $config{irc_channel} :\00309+ join\017: $nick\017" . ($pj->{irc_show_playerip} ? " (\00304$ip\017)" : '') . ($pj->{irc_show_country} && $cn ? " CN: \00304$cn\017" : '') . + ($clonenicks ? " Clone of:$clonenicks" : '') . ($pj->{irc_show_mapname} ? " playing on \00304$store{map}\017" : '') . ($pj->{irc_show_amount_of_players} ? " players: \00304" . (get_player_count()+1) . "\017/$store{slots_max}" : ''); } diff --git a/server/rcon2irc/ping-pl.pl b/server/rcon2irc/ping-pl.pl index 627eb3ddd..dcff14acc 100644 --- a/server/rcon2irc/ping-pl.pl +++ b/server/rcon2irc/ping-pl.pl @@ -8,9 +8,9 @@ # packet or have a high ping every once in the while. # PLEASE CHOOSE SANE VALUES HERE !!! -my %pp = ( - max_ping => 300, - max_pl => 15, +{ my %pp = ( + max_ping => 350, + max_pl => 10, warn_player => 1, # send a tell command to the player to notify of bad connection (0 or 1) warn_irc => 1, # send a warning to irc to notify that a player has a bad connection (0 or 1) warnings => 3, # how many times must ping/pl exceed the limit before a warning @@ -20,7 +20,7 @@ my %pp = ( kickmsg => 'You are getting kicked for having connection problems.' ); -$store{plugin_ping-pl} = \%pp; +$store{plugin_ping-pl} = \%pp; } sub out($$@); @@ -46,10 +46,11 @@ sub out($$@); #do we have to kick the user? if ((scalar @{ $pp->{"violation_$id"} }) >= $pp->{kick} && $pp->{kick} > 0) { if ($pp->{warn_player}) { - out dp => 0, "tell #$no " . $pp{kickmsg}; + out dp => 0, "tell #$no " . $pp->{kickmsg}; } if ($pp->{warn_irc}) { - out irc => 0, "PRIVMSG $config{irc_channel} :* \00304kicking\017 " . $store{"playernick_byid_$id"} . "\017 for having a bad connection"; + out irc => 0, "PRIVMSG $config{irc_channel} :\00304* kicking\017 " . $store{"playernick_byid_$id"} . "\017 for having a bad connection" . + " (current ping/pl: \00304$ping/$pl\017)"; } out dp => 0, "kick # $no bad connection"; $pp->{"violation_$id"} = undef; @@ -59,10 +60,11 @@ sub out($$@); #do we have to warn the user? if ($warn && (scalar @{ $pp->{"violation_$id"} }) && ((scalar @{ $pp->{"violation_$id"} }) % $pp->{warnings}) == 0) { if ($pp->{warn_player}) { - out dp => 0, "tell #$no $pp{warnmsg}"; + out dp => 0, "tell #$no " . $pp->{warnmsg}; } if ($pp->{warn_irc}) { - out irc => 0, "PRIVMSG $config{irc_channel} :* \00308warning\017 " . $store{"playernick_byid_$id"} . "\017 for having a bad connection"; + out irc => 0, "PRIVMSG $config{irc_channel} :\00308* warning\017 " . $store{"playernick_byid_$id"} . "\017 has a bad connection" . + " (current ping/pl: \00304$ping/$pl\017)"; } } return 0; diff --git a/server/rcon2irc/qnetauth.pl b/server/rcon2irc/qnetauth.pl new file mode 100644 index 000000000..f5a75c423 --- /dev/null +++ b/server/rcon2irc/qnetauth.pl @@ -0,0 +1,62 @@ +# Nexuiz rcon2irc plugin by Merlijn Hofstra licensed under GPL - qnetauth.pl +# Place this file inside the same directory as rcon2irc.pl and add the full filename to the plugins. + +# This plugin will automatically authenticate users who have a login for Quakenet (on the Q bot). +# If you login to the Q bot, this plugin will pick this up and users in the list below can automatically +# execute commands on the rcon2irc bot. +{ my @users = qw{merlijn}; + +$store{plugin_qnetauth}->{users} = \@users; } + +sub out($$@); +sub schedule($$); + +if (defined %config) { + schedule sub { + my ($timer) = @_; + out irc => 0, "PRIVMSG Q :users " . $config{irc_channel}; + schedule $timer => 300;; + } => 1; +} + +# Catch joins of people in a channel the bot is in and catch our own joins of a channel +[ irc => q{:(([^! ]*)![^ ]*) JOIN (#.+)} => sub { + my ($hostmask, $nick, $chan) = @_; + my $qa = $store{plugin_qnetauth}; + + if ($nick eq $config{irc_nick}) { + out irc => 0, "PRIVMSG Q :users $chan"; # get auths for all users + } else { + $qa->{hosts}->{$nick} = $hostmask; + out irc => 0, "PRIVMSG Q :whois $nick"; # get auth for single user + } + + return 0; +} ], + +# Catch response of users request +[ irc => q{:Q!TheQBot@CServe.quakenet.org NOTICE [^:]+ :[@\+\s]?(\S+)\s+(\S+)\s*(\S*)\s*\((.*)\)} => sub { + my ($nick, $username, $flags, $host) = @_; + my $qa = $store{plugin_qnetauth}; + + foreach my $user (@{ $qa->{users} }) { + $store{logins}{"$nick!$host"} = time() + 600 if ($user eq $username); + } + + return 0; +} ], + +# Catch response of whois request +[ irc => q{:Q!TheQBot@CServe.quakenet.org NOTICE [^:]+ :-Information for user (.*) \(using account (.*)\):} => sub { + my ($nick, $username) = @_; + my $qa = $store{plugin_qnetauth}; + + foreach my $user (@{ $qa->{users} }) { + if ($user eq $username) { + my $hostmask = $qa->{hosts}->{$nick}; + $store{logins}{$hostmask} = time() + 600; + } + } + + return 0; +} ], diff --git a/server/rcon2irc/showlogins.pl b/server/rcon2irc/showlogins.pl index 716b1360b..0163dcdbe 100644 --- a/server/rcon2irc/showlogins.pl +++ b/server/rcon2irc/showlogins.pl @@ -2,34 +2,54 @@ # Place this file inside the same directory as rcon2irc.pl and add the full filename to the plugins. { my %sl = ( - show_success => 1, - show_failed => 1, + show_success => 1, # only for logins to the irc bot + show_failed => 1, # only for logins to the irc bot + show_rcon_failure => 1, failed_interval => 60, ); $store{plugin_showlogins} = \%sl; } sub out($$@); sub schedule($$); -schedule sub { - my ($timer) = @_; - if ($store{plugin_showlogins}->{failed_attempts}) { - # Generate hostmakes - my %temp = undef; - my @hostmasks = grep !$temp{$_}++, @{ $store{plugin_showlogins}->{failed_attempts} }; +if (defined %config) { + schedule sub { + my ($timer) = @_; + if ($store{plugin_showlogins}->{failed_attempts}) { + # Generate hostmakes + my %temp = undef; + my @hostmasks = grep !$temp{$_}++, @{ $store{plugin_showlogins}->{failed_attempts} }; + + foreach my $mask (@hostmasks) { + my $count = 0; + foreach (@{ $store{plugin_showlogins}->{failed_attempts} }) { + $count++ if ($_ eq $mask); + } + + out irc => 0, "PRIVMSG $config{irc_channel} :\00305* login failed\017 \00304$mask\017 tried to become an IRC admin \00304$count\017 times"; + } + + $store{plugin_showlogins}->{failed_attempts} = undef; + } - foreach my $mask (@hostmasks) { - my $count = 0; - foreach (@{ $store{plugin_showlogins}->{failed_attempts} }) { - $count++ if ($_ eq $mask); + if ($store{plugin_showlogins}->{rcon_fail}) { + my %temp = undef; + my @names = grep !$temp{$_}++, @{ $store{plugin_showlogins}->{rcon_fail} }; + + foreach my $name (@names) { + my $count = 0; + foreach (@{ $store{plugin_showlogins}->{rcon_fail} }) { + $count++ if ($_ eq $name); + } + + out irc => 0, "PRIVMSG $config{irc_channel} :\00305* login failed\017 \00304$name\017 tried to use rcon commands \00304$count\017 times"; } - out irc => 0, "PRIVMSG $config{irc_channel} :\00305* login failed\017 \00304$mask\017 tried to become an IRC admin \00304$count\017 times"; + $store{plugin_showlogins}->{rcon_fail} = undef; } - $store{plugin_showlogins}->{failed_attempts} = undef; - } - schedule $timer => $store{plugin_showlogins}->{failed_interval};; -} => 1; + schedule $timer => $store{plugin_showlogins}->{failed_interval};; + } => 1; +} [ irc => q{:(([^! ]*)![^ ]*) (?i:PRIVMSG) [^&#%]\S* :(.*)} => sub { my ($hostmask, $nick, $command) = @_; @@ -46,3 +66,15 @@ schedule sub { return 0; } ], + +# failed rcon attempts +[ dp => q{server denied rcon access to (.*)} => sub { + my ($name) = map { color_dp2irc $_ } @_; + my $sl = $store{plugin_showlogins}; + + if ($sl->{show_rcon_failure}) { + push @{ $store{plugin_showlogins}->{rcon_fail} }, $name + } + + return 0; +} ], -- 2.39.2