From f9e078349e712b8f8456f9eafdb3a37c42e9ed22 Mon Sep 17 00:00:00 2001 From: div0 Date: Mon, 1 Jun 2009 15:21:41 +0000 Subject: [PATCH] rcon2irc enhancements by merlijn git-svn-id: svn://svn.icculus.org/nexuiz/trunk@6835 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- server/rcon2irc/joinsparts.pl | 58 ++++++++++++++++++++ server/rcon2irc/ping-pl.pl | 78 +++++++++++++++++++++++++++ server/rcon2irc/rcon2irc-example.conf | 5 ++ server/rcon2irc/rcon2irc.pl | 37 ++++++++++--- server/rcon2irc/suggestmap.pl | 13 +++++ 5 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 server/rcon2irc/joinsparts.pl create mode 100644 server/rcon2irc/ping-pl.pl create mode 100644 server/rcon2irc/suggestmap.pl diff --git a/server/rcon2irc/joinsparts.pl b/server/rcon2irc/joinsparts.pl new file mode 100644 index 000000000..886134761 --- /dev/null +++ b/server/rcon2irc/joinsparts.pl @@ -0,0 +1,58 @@ +# Nexuiz rcon2irc plugin by Merlijn Hofstra licensed under GPL - joinsparts.pl +# Place this file inside the same directory as rcon2irc.pl and add the full filename to the plugins. +# Don't forget to edit the options below to suit your needs. + +my %pj = ( + irc_announce_joins => 1, + irc_announce_parts => 1, + irc_show_playerip => 0, + irc_show_mapname => 0, + irc_show_amount_of_players => 0 +); + +$store{plugin_joinsparts} = \%pj; + +sub out($$@); + +sub get_player_count +{ + my $count = 0; + for (1 .. $store{slots_max}) { + my $id = $store{"playerid_byslot_$_"}; + $count++ if (defined $id && $store{"playerip_byid_$id"} ne 'bot'); + } + return $count; +} + +# chat: Nexuiz server -> IRC channel, nick set +[ dp => q{:join:(\d+):(\d+):([^:]*):(.*)} => sub { + my ($id, $slot, $ip, $nick) = @_; + my $pj = $store{plugin_joinsparts}; + $store{"playernickraw_byid_$id"} = $nick; + $nick = color_dp2irc $nick; + if ($pj->{irc_announce_joins} && !$store{"playerid_byslot_$slot"} && $ip ne 'bot') { + out irc => 0, "PRIVMSG $config{irc_channel} :\00309+ join\017: $nick\017" . + ($pj->{irc_show_playerip} ? " (\00304$ip\017)" : '') . + ($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}" : ''); + } + return 0; +} ], +# Record parts so the info in $store is always up to date +[ dp => q{:part:(\d+)} => sub { + my ($id) = @_; + my $pj = $store{plugin_joinsparts}; + if ($pj->{irc_announce_parts} && defined $store{"playernick_byid_$id"} && $store{"playerip_byid_$id"} ne 'bot') { + out irc => 0, "PRIVMSG $config{irc_channel} :\00304- part\017: " . $store{"playernick_byid_$id"} . "\017" . + ($pj->{irc_show_playerip} ? " (\00304" . $store{"playerip_byid_$id"} . "\017)" : '') . + ($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}" : ''); + } + my $slot = $store{"playerslot_byid_$id"}; + $store{"playernickraw_byid_$id"} = undef; + $store{"playernick_byid_$id"} = undef; + $store{"playerip_byid_$id"} = undef; + $store{"playerslot_byid_$id"} = undef; + $store{"playerid_byslot_$slot"} = undef; + return 0; +} ], diff --git a/server/rcon2irc/ping-pl.pl b/server/rcon2irc/ping-pl.pl new file mode 100644 index 000000000..627eb3ddd --- /dev/null +++ b/server/rcon2irc/ping-pl.pl @@ -0,0 +1,78 @@ +# Nexuiz rcon2irc plugin by Merlijn Hofstra licensed under GPL - ping-pl.pl +# Place this file inside the same directory as rcon2irc.pl and add the full filename to the plugins. +# Don't forget to edit the options below to suit your needs. + +# This script monitors players ping and packet loss, people with really large values here are +# lagging a lot, and this lag appears to other players as well as seeing the lagging player move +# with lots of stutter. Bare in mind that even those of us on very good connections may lose a +# packet or have a high ping every once in the while. +# PLEASE CHOOSE SANE VALUES HERE !!! + +my %pp = ( + max_ping => 300, + max_pl => 15, + 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 + kick => 0, # how many times must ping/pl exceed the limit before a kick (0 to disable) + timeframe => 20, # minutes until a count is forgotten + warnmsg => 'You are having connection problems, causing you to lag - please fix them', + kickmsg => 'You are getting kicked for having connection problems.' +); + +$store{plugin_ping-pl} = \%pp; + +sub out($$@); + +# Check users ping and packet loss +[ dp => q{\^\d(\S+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(-?\d+)\s+\#(\d+)\s+\^\d(.*)} => sub { + my ($ip, $pl, $ping, $time, $frags, $no, $name) = ($1, $2, $3, $4, $5, $6, $7); + my $id = $store{"playerid_byslot_$no"}; + return 0 unless ( defined $id ); + return 0 if ($frags == -666 || $ip eq 'bot'); + my $pp = $store{plugin_ping-pl}; + + #does the player violate one of our limits? + my $warn = 0; + if ($ping >= $pp->{max_ping} || $pl >= $pp->{max_pl}) { + #add a violation + push @{ $pp->{"violation_$id"} }, time(); + $warn = 1; + } + + #maybe we need to clear the oldest violation + shift @{ $pp->{"violation_$id"} } if (defined ${ $pp->{"violation_$id"} }[0] && (${ $pp->{"violation_$id"} }[0] + (60 * $pp->{timeframe})) <= time()); + + #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}; + } + if ($pp->{warn_irc}) { + out irc => 0, "PRIVMSG $config{irc_channel} :* \00304kicking\017 " . $store{"playernick_byid_$id"} . "\017 for having a bad connection"; + } + out dp => 0, "kick # $no bad connection"; + $pp->{"violation_$id"} = undef; + return 0; + } + + #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}"; + } + if ($pp->{warn_irc}) { + out irc => 0, "PRIVMSG $config{irc_channel} :* \00308warning\017 " . $store{"playernick_byid_$id"} . "\017 for having a bad connection"; + } + } + return 0; +} ], + +# For now will just empty our data at the end of a match +[ dp => q{^:end} => sub { + my $pp = $store{plugin_ping-pl}; + foreach ( keys %{ $pp } ) { + $pp->{$_} = undef if ($_ =~ m/^violation/); + } + return 0; +} ], diff --git a/server/rcon2irc/rcon2irc-example.conf b/server/rcon2irc/rcon2irc-example.conf index d8993729f..e9eac8d51 100644 --- a/server/rcon2irc/rcon2irc-example.conf +++ b/server/rcon2irc/rcon2irc-example.conf @@ -25,6 +25,11 @@ irc_channel = #Nexuiz-Pwayers # Alternate IRC trigger (can be used instead of nickname to send stuff to the server) #irc_trigger = nexnexnex +# Custom output options +#irc_announce_slotsfree = 1 +# The var irc_announce_mapchange can be set to either never, notempty or always +#irc_announce_mapchange = always + # Tuning #dp_secure = 1 #dp_server_from_wan = diff --git a/server/rcon2irc/rcon2irc.pl b/server/rcon2irc/rcon2irc.pl index 02f1069f2..be341493c 100755 --- a/server/rcon2irc/rcon2irc.pl +++ b/server/rcon2irc/rcon2irc.pl @@ -664,6 +664,9 @@ our %config = ( irc_quakenet_challengeauth => 'PRIVMSG Q@CServe.quakenet.org :CHALLENGEAUTH', irc_quakenet_challengeprefix => ':Q!TheQBot@CServe.quakenet.org NOTICE [^:]+ :CHALLENGE', + irc_announce_slotsfree => 1, + irc_announce_mapchange => 'always', + dp_server => undef, dp_secure => 1, dp_listen => "", @@ -1050,8 +1053,8 @@ sub cond($) if($full != ($store{slots_full} || 0)) { $store{slots_full} = $full; - return 0 - if $store{lms_blocked}; + return 0 if $store{lms_blocked}; + return 0 if !$config{irc_announce_slotsfree}; if($full) { out irc => 0, "PRIVMSG $config{irc_channel} :\001ACTION is full!\001"; @@ -1142,7 +1145,7 @@ sub cond($) $dpreason =~ s/(["\\])/\\$1/g; out dp => 0, "kick # $id $dpreason"; my $slotnik = "playerslot_$id"; - out irc => 0, "PRIVMSG $nick :kicked #$id (@{[color_dp2irc $store{$slotnik}{name}]} @ $store{$slotnik}{ip}) ($reason)"; + out irc => 0, "PRIVMSG $nick :kicked #$id (@{[color_dp2irc $store{$slotnik}{name}]}\017 @ $store{$slotnik}{ip}) ($reason)"; return 0; } @@ -1154,7 +1157,7 @@ sub cond($) $dpreason =~ s/(["\\])/\\$1/g; out dp => 0, "kickban # $id $bantime $mask $dpreason"; my $slotnik = "playerslot_$id"; - out irc => 0, "PRIVMSG $nick :kickbanned #$id (@{[color_dp2irc $store{$slotnik}{name}]} @ $store{$slotnik}{ip}), netmask $mask, for $bantime seconds ($reason)"; + out irc => 0, "PRIVMSG $nick :kickbanned #$id (@{[color_dp2irc $store{$slotnik}{name}]}\017 @ $store{$slotnik}{ip}), netmask $mask, for $bantime seconds ($reason)"; return 0; } @@ -1178,6 +1181,24 @@ sub cond($) return 0; } + if($command =~ /^mute (\d+)$/) + { + my $id = $1; + out dp => 0, "mute $id"; + my $slotnik = "playerslot_$id"; + out irc => 0, "PRIVMSG $nick :muted $id (@{[color_dp2irc $store{$slotnik}{name}]}\017 @ $store{$slotnik}{ip})"; + return 0; + } + + if($command =~ /^unmute (\d+)$/) + { + my ($id) = ($1); + out dp => 0, "unmute $id"; + my $slotnik = "playerslot_$id"; + out irc => 0, "PRIVMSG $nick :unmuted $id (@{[color_dp2irc $store{$slotnik}{name}]}\017 @ $store{$slotnik}{ip})"; + return 0; + } + if($command =~ /^quote (.*)$/) { my ($cmd) = ($1); @@ -1193,7 +1214,7 @@ sub cond($) return 0; } - out irc => 0, "PRIVMSG $nick :unknown command (supported: status [substring], kick # id reason, kickban # id bantime mask reason, bans, unban banid)"; + out irc => 0, "PRIVMSG $nick :unknown command (supported: status [substring], kick # id reason, kickban # id bantime mask reason, bans, unban banid, mute id, unmute id)"; return -1; } ], @@ -1402,8 +1423,10 @@ sub cond($) $store{playing} = 1; $store{map} = $map; $store{map_starttime} = time(); - my $slotsstr = nex_slotsstring(); - out irc => 0, "PRIVMSG $config{irc_channel} :\00304" . $map . "\017 has begun$slotsstr"; + if ($config{irc_announce_mapchange} eq 'always' || ($config{irc_announce_mapchange} eq 'notempty' && $store{slots_active} > 0)) { + my $slotsstr = nex_slotsstring(); + out irc => 0, "PRIVMSG $config{irc_channel} :\00304" . $map . "\017 has begun$slotsstr"; + } delete $store{lms_blocked}; return 0; } ], diff --git a/server/rcon2irc/suggestmap.pl b/server/rcon2irc/suggestmap.pl new file mode 100644 index 000000000..0acd66f59 --- /dev/null +++ b/server/rcon2irc/suggestmap.pl @@ -0,0 +1,13 @@ +# Nexuiz rcon2irc plugin by Merlijn Hofstra licensed under GPL - suggestmap.pl +# Place this file inside the same directory as rcon2irc.pl and add the full filename to the plugins. + +sub out($$@); + +#read the suggest vote +[ dp => q{:vote:suggested:(.+):(\d+)} => sub { + my ($map, $id) = @_; + my $nick = color_dp2irc $store{"playernick_byid_$id"}; + $nick ||= '(console)'; + out irc => 0, "PRIVMSG $config{irc_channel} :* map suggested: \00304$map\017 by $nick\017"; + return 0; +} ], -- 2.39.2