9a7b3b085d0ce96d5aee4c0d9d3b6b4f8e8054cd
[xonotic/xonotic.git] / server / rcon2irc / joinsparts.pl
1 # Xonotic rcon2irc plugin by Merlijn Hofstra licensed under GPL - joinsparts.pl
2 # Place this file inside the same directory as rcon2irc.pl and add the full filename to the plugins.
3 # Don't forget to edit the options below to suit your needs.
4
5 { my %pj = (
6         irc_announce_joins => 1,
7         irc_announce_parts => 1,
8         irc_show_playerip => 0,
9         irc_show_mapname => 0,
10         irc_show_amount_of_players => 0,
11         irc_show_country => 0,
12         check_clones => 1
13 );
14
15 # current code has been tested against version 0.8 of the Geo::IPfree module
16 # You can obtain a copy here: http://search.cpan.org/~bricas/Geo-IPfree-0.8/lib/Geo/IPfree.pm
17 # Place the 'Geo' dir in the same directory as this plugin or anywhere in @INC.
18 if ($pj{irc_show_country}) {
19         eval { 
20                 require Geo::IPfree;
21                 $pj{geo} = Geo::IPfree->new;
22                 $pj{geo}->Faster; # Due to a relatively large amount of lookups, this is probably a good idea 
23         } or die "joinsparts.pl: requested countrynames, but can't load data, $@";
24
25
26 $store{plugin_joinsparts} = \%pj; }
27
28 sub out($$@);
29
30 sub get_player_count
31 {
32         my $count = 0;
33         for (1 .. $store{slots_max}) {
34                 my $id = $store{"playerid_byslot_$_"};
35                 $count++ if (defined $id && $store{"playerip_byid_$id"} ne 'bot');
36         }
37         return $count;
38 }
39 # Catch joins and display requested info
40 [ dp => q{:join:(\d+):(\d+):([^:]*):(.*)} => sub {
41         my ($id, $slot, $ip, $nick) = @_;
42         my $pj = $store{plugin_joinsparts};
43         $pj->{alive_check}->[$slot] = 1;
44         
45         return 0 if ($ip eq 'bot');
46         
47         my ($cn) = $pj->{geo}->LookUp($ip) if ($pj->{irc_show_country});
48         
49         my $clonenicks;
50         if ($pj->{check_clones}) {
51                 for (1 .. $store{slots_max}) {
52                         my $plrid = $store{"playerid_byslot_$_"};
53                         next if (!defined $plrid || $plrid == $id || $ip ne $store{"playerip_byid_$plrid"});
54                         $clonenicks .= ' ' . $store{"playernick_byid_$plrid"} . "\017";
55                 }
56         }
57         
58         $nick = color_dp2irc $nick;
59         if ($pj->{irc_announce_joins} && !$store{"playerid_byslot_$slot"}) {
60                 out irc => 0, "PRIVMSG $config{irc_channel} :\00309+ join\017: $nick\017" . 
61                         ($pj->{irc_show_playerip} ? " (\00304$ip\017)" : '') .
62                         ($pj->{irc_show_country} && $cn ? " CN: \00304$cn\017" : '') .
63                         ($clonenicks ? " Clone of:$clonenicks" : '') .
64                         ($pj->{irc_show_mapname} ? " playing on \00304$store{map}\017" : '') .
65                         ($pj->{irc_show_amount_of_players} ? " players: \00304" . (get_player_count()+1) . "\017/$store{slots_max}" : '');
66         }
67         return 0;
68 } ],
69
70 # Record parts so the info in $store is always up to date
71 [ dp => q{:part:(\d+)} => sub {
72         my ($id) = @_;
73         my $pj = $store{plugin_joinsparts};
74         
75         my $ip = $store{"playerip_byid_$id"};
76         my ($cn) = $pj->{geo}->LookUp($ip) if ($pj->{irc_show_country} && $ip ne 'bot');
77         
78         if ($pj->{irc_announce_parts} && defined $store{"playernick_byid_$id"} && $store{"playerip_byid_$id"} ne 'bot') {
79                 out irc => 0, "PRIVMSG $config{irc_channel} :\00304- part\017: " . $store{"playernick_byid_$id"} . "\017" . 
80                         ($pj->{irc_show_playerip} ? " (\00304$ip\017)" : '') .
81                         ($pj->{irc_show_country} && $cn ? " CN: \00304$cn\017": '') .
82                         ($pj->{irc_show_mapname} ? " playing on \00304$store{map}\017" : '') .
83                         ($pj->{irc_show_amount_of_players} ? " players: \00304" . (get_player_count()-1) . "\017/$store{slots_max}" : '');
84         }
85         my $slot = $store{"playerslot_byid_$id"};
86         $store{"playernickraw_byid_$id"} = undef;
87         $store{"playernick_byid_$id"} = undef;
88         $store{"playerip_byid_$id"} = undef;
89         $store{"playerslot_byid_$id"} = undef;
90         $store{"playerid_byslot_$slot"} = undef;
91         return 0;
92 } ],
93
94 # Add some functionality that should clear 'ghost' clients that disconnect at unfortunate times
95 [ dp => q{:end} => sub {
96         return 0 unless (time() - $store{map_starttime} > 180); # make sure the map has been played at least 3 minutes
97         
98         my $pj = $store{plugin_joinsparts};
99         for (1 .. $store{slots_max}) {
100                 if ($store{"playerid_byslot_$_"} && !$pj->{alive_check}->[$_]) {
101                         my $id = $store{"playerid_byslot_$_"};
102                         $store{"playernickraw_byid_$id"} = undef;
103                         $store{"playernick_byid_$id"} = undef;
104                         $store{"playerip_byid_$id"} = undef;
105                         $store{"playerslot_byid_$id"} = undef;
106                         $store{"playerid_byslot_$_"} = undef;
107                 }
108         }
109         $pj->{alive_check} = ();
110         
111         return 0;
112 } ],