]> git.rmz.io Git - dotfiles.git/blob - weechat/perl/parse_relayed_msg.pl
lazyvim: remove which-key
[dotfiles.git] / weechat / perl / parse_relayed_msg.pl
1 #
2 # Copyright (c) 2011-2019 by w8rabbit (w8rabbit[at]mail[dot]i2p)
3 # or from outside i2p: w8rabbit[at]i2pmail[dot]org
4 #
5 # Script is under GPL3.
6 #
7 # Script is inspired by NullPointerException's xchat script
8 #
9 # thanks to darrob for hard beta-testing
10 #
11 # 1.9.7: fix: a warning about declaration in same scope
12 # remove: unnecessary callback function
13 # 1.9.6: fix: nick parsing with messages containing @ and >
14 # 1.9.5: add compatibility with matrix-appservice-irc
15 # 1.9.4: add compatibility with other kind of messages than irc
16 # 1.9.3: add compatibility with new weechat_print modifier data (WeeChat >= 2.9)
17 # 1.9.2: add: i2pr-support
18 # 1.9.1: fix: uninitialized value (by arza)
19 # fix: indentation
20 # 1.9: add: Gitter support
21 # 1.8: fix: regex on tags
22 # 1.7: add: support of colors with format "${color:xxx}" (>= WeeChat 0.4.2)
23 # 1.6: add: wildcard "*" for supported_bot_names.
24 # 1.5: cleaned up code and make it more readable
25 # 1.4: fix: problem with tag "prefix_nick_ccc"
26 # improved: Nicks will be displayed the same way in Nicklist like in channel buffer.
27 # 1.3: fix: action message (/me) was printed twice for some remote server
28 # 1.2.1: fix: add_relay_nick_to_nicklist()
29 # 1.2: add: a warning will be displayed if a wrecked message was received
30 # add: debug mode (especially for darrob :-)
31 # improved: whitespaces will be removed in front of message-text
32 # 1.1: cleaned up code and made it more readable!!!
33 # add: ACTION messages for "uuu" will be displayed now
34 # improved: relaynet_color option (read online help)
35 # fix: quoted "relaynet/relaynick" in cloudc2sd
36 # 1.0.1: add: new option "relaynet_color" and "relaynet_to_nicklist"
37 # fix: network for cloudc2sd relaybot wasn't displayed
38 # 1.0: add: cloudc2sd relaybot. (thanks to killyourtv for beta-testing)
39 # 0.9: improved: tag-regex for latest weechat version (v0.3.8)
40 # add: option "blacklist" to ignore relaynicks (suggested by darrob)
41 # fix: regex for FLIP (by operhiem1)
42 # improved: nick-modes from relaynicks will not be displayed in nicklist/nickname anymore (for nick auto-completion)
43 # NOTE: weechat can handle more than one nick-mode internally, but it will only display the highest rated nick-mode in nicklist.
44 # 0.8: improved: regex for FLIP bot (reported by user)
45 # fix: problem with nicks in nicklist (thanks to KillYourTV and user)
46 # fix: weechat crash when closing buffer with relay nicks in nicklist
47 # fix: problem with not displaying first relay nick in nicklist
48 # improved: support of colorize_lines script.
49 # 0.7: relay nicks will be displayed in nicklist (in its own group)
50 # new option "unexpected_msg_handling".
51 # 0.6: FLIPRelayBot implemented (suggested by darrob)
52 # 0.5: relay indicator for actions added
53 # 0.4: hardcoded code removed (weechat 0.3.4 and higher required)
54 # 0.3: option suppress_relaynet and suppress_relaynet_channels added.
55 # multi-server support added.
56 # 0.2: scriptname changed from parse_bot_msg to parse_relayed_msg (suggested by darrob)
57 # added version check to use prio for hook_modifier()
58 # 0.1: - initial release -
59
60
61 # http://w8rabbit.i2p/parse_relayed_msg.html
62 # http://h4pf2ydu43jadhckgzign5u4m4gfesbjt3uyne575adx7lh7xeuq.b32.i2p/
63
64 # ^(:)(\S+)(!\S+@\S+ )(PRIVMSG #thechannel :)<(\S+)> (.*)
65 # /rmodifier add relay irc_in_privmsg 1,5,3,4,6 ^(:)(\S+)(!\S+@\S+ )(PRIVMSG #thechannel :)<(\S+)> (.*)
66 # replace the first \S+ with the bot's nick
67 # flip bot:
68 # :FLIPRelayBot!RelayBot@irc2p PRIVMSG #flip-bridge :[nickname] here comes the message
69 # uuu bot:
70 # :u!u@public.chat.cloud PRIVMSG #anonet :\0305/IcannNet/Name\0308\0308> \0FWell it doesn't work on windows ...
71
72 use strict;
73 my $SCRIPT_NAME = "parse_relayed_msg";
74 my $SCRIPT_VERSION = "1.9.7";
75 my $SCRIPT_DESCR = "proper integration of remote users' nicknames in channel and nicklist";
76 my $SCRIPT_AUTHOR = "w8rabbit";
77 my $SCRIPT_LICENCE = "GPL3";
78
79 # =============== options ===============
80 my %option = ( "supported_bot_names" => "i2pr,cloudrelay*,MultiRelay*,FLIPRelayBot*,i2pRelay,u2,uuu,RelayBot,lll,iRelay,fox,wolf,hawk,muninn,gribble,vulpine,*GitterBot",
81 "supported_message_kinds" => "irc_privmsg,matrix_message",
82 "debug" => "off",
83 "blacklist" => "",
84 "servername" => "i2p,freenet",
85 "nick_mode" => "⇅",
86 "nick_mode_color" => "yellow",
87 "suppress_relaynet" => "off",
88 "relaynet_color" => "blue",
89 "relaynet_to_nicklist" => "off",
90 "suppress_relaynet_channels" => "",
91 "timer" => "600",
92 "unexpected_msg_handling" => "unchanged", # drop, decrease notification level, unchanged
93 );
94
95 my %script_desc = ( "blacklist" => "Comma-separated list of relayed nicknames to be ignored (similar to /ignore). The format is case-sensitive: <server>.<relaynick>",
96 "supported_bot_names" => "Comma-separated list of relay bots.",
97 "supported_message_kinds" => "Comma-separated list of message kinds.",
98 "debug" => "Enable output of raw IRC messages. This is a developer feature and should generally be turned off. The format is: <servername>:<botname> (default: off)",
99 "servername" => "Comma-separated list of internal servers to enable $SCRIPT_NAME for. (default: i2p,freenet)",
100 "nick_mode" => "Prefix character used to mark relayed nicknames. (default: ⇅). Since WeeChat 0.4.2 you can use format \${color:xxx} but this doesn't affect nicklist.",
101 "nick_mode_color" => "Color of the prefix character. (default: yellow)",
102 "suppress_relaynet" => "Hide nicknames' network part (if applicable). (default: off)",
103 "suppress_relaynet_channels" => "Comma-separated list of channels to activate suppress_relaynet in. Format: \"servername.channel\", e.g. \"i2p.#i2p-dev,freenode.#weechat\". (default: \"\" (i.e. global))",
104 "relaynet_color" => "Color of nicknames' network part. Leave blank for altering colors. (default: \"\")",
105 "relaynet_to_nicklist" => "Include relaynets in the nicklist. (default: off)",
106 "timer" => "Time (in s) after which relayed nicknames get removed from the nicklist. (default: 600)",
107 "unexpected_msg_handling" => "Ignore relay bot messages with unexpected syntax (drop/unchanged). (default: unchanged)",
108 );
109 # =============== internal values ===============
110 my $weechat_version = "";
111 my @bot_nicks = "";
112 my @message_kinds = "";
113 my @list_of_server = "";
114 my @suppress_relaynet_channels = "";
115 my @blacklist = "";
116
117 my $group_name = "relay_nicks"; # group name for nicklist
118 my %nick_timer = ();
119 my %Hooks = ();
120
121 # =============== callback from hook_print() ===============
122 sub parse_relayed_msg_cb
123 {
124 my ( $data, $modifier, $modifier_data, $string ) = @_;
125
126 # its neither a channel nor a query buffer
127 my $result = should_handle_modifier($modifier_data);
128 return $string unless ($result);
129
130 my $buffer = "";
131 my $tags = "";
132 if ($modifier_data =~ /0x/)
133 {
134 # WeeChat >= 2.9
135 $modifier_data =~ m/([^;]*);(.*)/;
136 $buffer = $1;
137 $tags = $2;
138 }
139 else {
140 # WeeChat <= 2.8
141 $modifier_data =~ m/([^;]*);([^;]*);(.*)/;
142 $buffer = weechat::buffer_search($1, $2);
143 $tags = $3;
144 }
145 my $servername = weechat::buffer_get_string($buffer, "localvar_server");
146 my $channelname = weechat::buffer_get_string($buffer, "localvar_channel");
147
148 return $string if ($servername eq "" or $channelname eq "");
149
150 return $string if ( !grep /^$servername$/, @list_of_server ); # does server exists?
151
152 my $buf_ptr = $buffer;
153
154 $string =~ m/^(.*)\t(.*)/; # nick[tab]string
155 my $nick = $1; # get the nick name (with prefix!)
156 my $line = $2; # get written text
157 # $nick = weechat::string_remove_color($nick,""); # remove color-codes from nick
158 $line = weechat::string_remove_color($line,""); # remove color-codes from line
159
160 $modifier_data =~ m/(^|,)nick_([^,]*)(,|$)/; # get the nick name from modifier_data (without nick_mode and color codes!)
161 $nick = $2;
162
163 # display_mode : 0 = /, 1 = @
164 my $result_smtr = string_mask_to_regex($nick);
165 if ($result_smtr)
166 # if ( grep /^$nick$/, @bot_nicks ) # does a bot exists?
167 {
168 my $blacklist_raw = weechat::config_get_plugin("blacklist");
169 @blacklist = split( /,/,$blacklist_raw);
170 # message from muninn bot!
171 if ( $line =~ m/^<([^@>]+)@([^>]+)\>\s(.+)$/ )
172 {
173 my ($relaynick, $relaynet, $relaymsg) = ($1,$2,$3);
174 if ( grep /^$servername.$relaynick$/, @blacklist ) # check for ignored relay nicks
175 {
176 return ''; # delete message from ignored relaynick
177 }
178 my $nick_mode = "";
179 ($relaynick,$nick_mode) = check_nick_mode($buf_ptr,$relaynick);
180 add_relay_nick_to_nicklist($buf_ptr,$relaynick,$relaynet,1);
181 (undef,$relaymsg) = colorize_lines($modifier_data,$relaynick,$relaymsg);
182
183 $string = create_string_with_relaynet($servername,$channelname,$relaynick,$relaynet,$nick_mode,$relaymsg,1);
184
185 $modifier_data = change_tags_for_message($buf_ptr,$relaynick,$relaynet,$modifier_data,1);
186 weechat::print_date_tags($buf_ptr,0,$modifier_data,$string);
187 return "";
188 }
189 # message from fox, wolf, hawk bot!
190 elsif ( $line =~ m/^<([^\s]+)\>\s(.+)$/ )
191 {
192 my ($relaynick, $relaymsg) = ($1,$2);
193 if ( grep /^$servername.$relaynick$/, @blacklist ) # check for ignored relay nicks
194 {
195 return ''; # delete message from ignored relaynick
196 }
197 my $nick_mode = "";
198 ($relaynick,$nick_mode) = check_nick_mode($buf_ptr,$relaynick);
199 add_relay_nick_to_nicklist($buf_ptr,$relaynick,"");
200 (undef,$relaymsg) = colorize_lines($modifier_data,$relaynick,$relaymsg);
201
202 $string = create_string_without_relaynet($servername,$channelname,$relaynick,$nick_mode,$relaymsg);
203
204 $modifier_data = change_tags_for_message( $buf_ptr,$relaynick,"",$modifier_data, "" );
205 weechat::print_date_tags($buf_ptr,0,$modifier_data,$string);
206 return "";
207 }
208 # PRIVMSG #i2p :[Freenode/nickname] here is the message.
209 elsif ( $line =~ m/^[\(\[`](.+?)\/(.+?)[\)\]`] (.+)$/ )
210 {
211 my ($relayserver,$relaynick,$relaymsg) = ($1,$2,$3);
212 if ( grep /^$servername.$relaynick$/, @blacklist ) # check for ignored relay nicks
213 {
214 return ''; # delete message from ignored relaynick
215 }
216 my $nick_mode = "";
217 ($relaynick,$nick_mode) = check_nick_mode($buf_ptr,$relaynick);
218 add_relay_nick_to_nicklist($buf_ptr,$relaynick,"");
219 (undef, $relaymsg) = colorize_lines($modifier_data,$relaynick, $relaymsg);
220
221 $string = create_string_without_relaynet($servername,$channelname,$relaynick,$nick_mode,$relaymsg);
222
223 $modifier_data = change_tags_for_message( $buf_ptr,$relaynick,"",$modifier_data,"" );
224 weechat::print_date_tags($buf_ptr,0,$modifier_data,$string);
225 return "";
226 }
227 # message from matrix-appservice-irc
228 elsif ( $line =~ m/^\[\w\] <@([^>]+)> (.+)$/ )
229 {
230 my ($relaynick,$relaymsg) = ($1,$2);
231 if ( grep /^$servername.$relaynick$/, @blacklist ) # check for ignored relay nicks
232 {
233 return ''; # delete message from ignored relaynick
234 }
235 my $nick_mode = "";
236 ($relaynick,$nick_mode) = check_nick_mode($buf_ptr,$relaynick);
237 add_relay_nick_to_nicklist($buf_ptr,$relaynick,"");
238 (undef, $relaymsg) = colorize_lines($modifier_data,$relaynick, $relaymsg);
239
240 $string = create_string_without_relaynet($servername,$channelname,$relaynick,$nick_mode,$relaymsg);
241
242 $modifier_data = change_tags_for_message( $buf_ptr,$relaynick,"",$modifier_data,"" );
243 weechat::print_date_tags($buf_ptr,0,$modifier_data,$string);
244 return "";
245 }
246 # message from FLIP & Gitter
247 elsif ( $line =~ m/^[\(\[`](.+?)[\)\]`] (.+)$/ )
248 {
249 my ($relaynick,$relaymsg) = ($1,$2);
250 if ( grep /^$servername.$relaynick$/, @blacklist ) # check for ignored relay nicks
251 {
252 return ''; # delete message from ignored relaynick
253 }
254 my $nick_mode = "";
255 ($relaynick,$nick_mode) = check_nick_mode($buf_ptr,$relaynick);
256 add_relay_nick_to_nicklist($buf_ptr,$relaynick,"");
257 (undef, $relaymsg) = colorize_lines($modifier_data,$relaynick, $relaymsg);
258
259 $string = create_string_without_relaynet($servername,$channelname,$relaynick,$nick_mode,$relaymsg);
260
261 $modifier_data = change_tags_for_message( $buf_ptr,$relaynick,"",$modifier_data,"" );
262 weechat::print_date_tags($buf_ptr,0,$modifier_data,$string);
263 return "";
264 }
265 # message from cloudc2sd
266 # :u2!u@irc2p PRIVMSG #relaytest :/botname/nickname> here comes the message
267 elsif ( $line =~ m/^([^\/]+)\/([^\>]+)\>\s(.+)$/ )
268 {
269 my ($relaynet,$relaynick,$relaymsg) = ($1,$2,$3);
270
271 if ( grep /^$servername.$relaynick$/, @blacklist ) # check for ignored relay nicks
272 {
273 return ""; # delete message from ignored relaynick
274 }
275 my $nick_mode = "";
276 ($relaynick,$nick_mode) = check_nick_mode($buf_ptr,$relaynick);
277 add_relay_nick_to_nicklist($buf_ptr,$relaynick,$relaynet,0);
278 (undef, $relaymsg) = colorize_lines($modifier_data,$relaynick, $relaymsg);
279
280 $string = create_string_with_relaynet($servername,$channelname,$relaynick,$relaynet,$nick_mode,$relaymsg,0);
281
282 $modifier_data = change_tags_for_message( $buf_ptr,$relaynick,$relaynet,$modifier_data,0 );
283 weechat::print_date_tags($buf_ptr,0,$modifier_data,$string);
284 return "";
285 }
286
287 # =============== ACTION (/me) messages ===============
288 # from gribble
289 elsif ( $line =~ /\*\s(.+)@([^\s]+)\s(.+)/ )
290 {
291 my ($relaynick, $relaynet, $relaymsg) = ($1,$2,$3);
292 if ( grep /^$servername.$relaynick$/, @blacklist ) # check for ignored relay nicks
293 {
294 return ''; # delete message from ignored relaynick
295 }
296 my $nick_mode = "";
297 ($relaynick,$nick_mode) = check_nick_mode($buf_ptr,$relaynick);
298 add_relay_nick_to_nicklist($buf_ptr,$relaynick,$relaynet,1);
299 (undef, $relaymsg) = colorize_lines($modifier_data,$relaynick, $relaymsg);
300
301 $string = create_action_string_with_relaynet($servername,$channelname,$relaynick,$relaynet,$nick_mode,$relaymsg,1);
302 return "" if ( $string eq "");
303
304 $modifier_data = change_tags_for_message( $buf_ptr,$relaynick,$relaynet,$modifier_data,1 );
305 weechat::print_date_tags($buf_ptr,0,$modifier_data,$string);
306 return "";
307 }
308 # from fox, wolf, hawk bot
309 elsif ( $line =~ /\*\s([^\s]+)\s(.+)/ )
310 {
311 my ($relaynick, $relaymsg) = ($1,$2);
312 if ( grep /^$servername.$relaynick$/, @blacklist ) # check for ignored relay nicks
313 {
314 return ""; # delete message from ignored relaynick
315 }
316 my $nick_mode = "";
317 ($relaynick,$nick_mode) = check_nick_mode($buf_ptr,$relaynick);
318 add_relay_nick_to_nicklist($buf_ptr,$relaynick,"");
319 (undef, $relaymsg) = colorize_lines($modifier_data,$relaynick, $relaymsg);
320
321 $string = create_action_string_without_relaynet($servername,$channelname,$relaynick,$nick_mode,$relaymsg);
322
323 $modifier_data = change_tags_for_message( $buf_ptr,$relaynick,"",$modifier_data,"" );
324 weechat::print_date_tags($buf_ptr,0,$modifier_data,$string);
325 return "";
326 }
327 # from uuu
328 #:u!u@public.chat.cloud PRIVMSG #relaytest :\0305/irc2p2/KillYourTV\0308\0308> \0F\01ACTION tests...again\01
329 elsif ( $line =~ m/^\/(.+)\/(.+)>\sACTION\s(.*)/ )
330 {
331 my ($relaynet,$relaynick,$relaymsg) = ($1,$2,$3);
332
333 if ( grep /^$servername.$relaynick$/, @blacklist ) # check for ignored relay nicks
334 {
335 return ""; # delete message from ignored relaynick
336 }
337 my $nick_mode = "";
338 ($relaynick,$nick_mode) = check_nick_mode($buf_ptr,$relaynick);
339 add_relay_nick_to_nicklist($buf_ptr,$relaynick,$relaynet,0);
340 (undef, $relaymsg) = colorize_lines($modifier_data,$relaynick, $relaymsg);
341
342 $string = create_action_string_with_relaynet($servername,$channelname,$relaynick,$relaynet,$nick_mode,$relaymsg,0);
343
344 $modifier_data = change_tags_for_message( $buf_ptr,$relaynick,$relaynet,$modifier_data,0 );
345 weechat::print_date_tags($buf_ptr,0,$modifier_data,$string);
346 return "";
347 }
348
349 # drop, decrease notification level, unchanged
350 return "" if ( $option{unexpected_msg_handling} eq "drop");
351 } # end of BOT
352 return $string;
353 }
354
355 # =============== create string to display in weechat ===============
356 sub create_string_without_relaynet
357 {
358 my ($servername,$channelname,$relaynick,$nick_mode,$relaymsg) = @_;
359 my $string;
360 $relaymsg =~ s/^\s+//; # kill leading space
361 if ($relaymsg eq "")
362 {
363 $string = wrecked_msg($servername,$channelname,$relaynick,"","");
364 return $string;
365 }
366 my $nick_color = weechat::info_get('irc_nick_color', $relaynick);# get nick-color
367 $string = _color_str( $option{nick_mode_color}, $option{nick_mode} ) .
368 $nick_mode .
369 $nick_color .
370 $relaynick .
371 "\t" .
372 $relaymsg;
373 return $string;
374 }
375
376 sub create_string_with_relaynet
377 {
378 my ($servername,$channelname,$relaynick,$relaynet,$nick_mode,$relaymsg,$display_mode) = @_;
379 my $string;
380 $relaymsg =~ s/^\s+//; # kill leading space
381 if ($relaymsg eq "")
382 {
383 $string = wrecked_msg($servername,$channelname,$relaynick,$relaynet,$display_mode);
384 return $string;
385 }
386 my $nick_color = weechat::info_get('irc_nick_color', $relaynick);# get nick-color
387
388 if ( $option{suppress_relaynet} eq "on" and $option{suppress_relaynet_channels} eq "" or ( grep /^$servername.$channelname$/, @suppress_relaynet_channels) ){
389 # suppress relaynet
390 $string = _color_str( $option{nick_mode_color}, $option{nick_mode} ) .
391 $nick_mode .
392 $nick_color .
393 $relaynick .
394 "\t" .
395 $relaymsg;
396 }else
397 {
398 # show relaynet
399 my $relay_and_nick = relay_and_nick($relaynet,$relaynick,$display_mode);
400 $string = _color_str( $option{nick_mode_color}, $option{nick_mode} ) .
401 $nick_mode .
402 $relay_and_nick.
403 "\t" .
404 $relaymsg;
405 }
406 return $string;
407 }
408
409 sub create_action_string_without_relaynet
410 {
411 my ($servername,$channelname,$relaynick,$nick_mode,$relaymsg) = @_;
412 my $string;
413 $relaymsg =~ s/^\s+//; # kill leading space
414 if ($relaymsg eq "")
415 {
416 $string = wrecked_msg($servername,$channelname,$relaynick,"","");
417 return $string;
418 }
419 my $nick_color = weechat::info_get('irc_nick_color', $relaynick);# get nick-color
420 my $prefix_action = weechat::config_string(weechat::config_get("weechat.look.prefix_action"));
421 my $prefix_color = weechat::color(weechat::config_color(weechat::config_get("weechat.color.chat_prefix_action")));
422 $string = _color_str($prefix_color, $prefix_action) .
423 $nick_mode .
424 "\t" .
425 _color_str( $option{nick_mode_color}, $option{nick_mode} ) .
426 $nick_color .
427 $relaynick .
428 weechat::color("default") .
429 " " .
430 $relaymsg;
431 return $string;
432 }
433
434 sub create_action_string_with_relaynet
435 {
436 my ($servername,$channelname,$relaynick,$relaynet,$nick_mode,$relaymsg,$display_mode) = @_;
437 my $string;
438 $relaymsg =~ s/^\s+//; # kill leading space
439 if ($relaymsg eq "")
440 {
441 $string = wrecked_msg($servername,$channelname,$relaynick,$relaynet,$display_mode);
442 return $string;
443 }
444 my $nick_color = weechat::info_get('irc_nick_color', $relaynick);
445 my $prefix_action = weechat::config_string(weechat::config_get("weechat.look.prefix_action"));
446 my $prefix_color = weechat::color(weechat::config_color(weechat::config_get("weechat.color.chat_prefix_action")));
447
448 if ( $option{suppress_relaynet} eq "on" and $option{suppress_relaynet_channels} eq "" or ( grep /^$servername.$channelname$/, @suppress_relaynet_channels) )
449 {
450 $string = _color_str($prefix_color, $prefix_action) .
451 $nick_mode .
452 "\t" .
453 _color_str( $option{nick_mode_color}, $option{nick_mode} ) .
454 $nick_color .
455 $relaynick .
456 weechat::color("default") .
457 " " .
458 $relaymsg;
459 }else
460 {
461 # show relaynet
462 my $relay_and_nick = relay_and_nick($relaynet,$relaynick,$display_mode);
463 $string = _color_str($prefix_color, $prefix_action) .
464 $nick_mode .
465 "\t" .
466 _color_str( $option{nick_mode_color}, $option{nick_mode} ) .
467 $relay_and_nick .
468 weechat::color("default") .
469 " " .
470 $relaymsg;
471 }
472 return $string;
473 }
474
475 sub wrecked_msg
476 {
477 my ($servername,$channelname,$relaynick,$relaynet,$display_mode) = @_;
478 return "" if ( $option{unexpected_msg_handling} eq "drop");
479 my $string;
480 my $nick_color = weechat::info_get('irc_nick_color', $relaynick);
481 my $relay_and_nick;
482
483 if (not defined $relaynet or $relaynet eq "")
484 {
485 $relay_and_nick = $nick_color . $relaynick;
486 }else
487 {
488 if ( $option{suppress_relaynet} eq "off" )
489 {
490 $relay_and_nick = relay_and_nick($relaynet,$relaynick,$display_mode);
491 }elsif ( $option{suppress_relaynet} eq "on" )
492 {
493 unless ( $option{suppress_relaynet_channels} eq "" or ( grep /^$servername.$channelname$/, @suppress_relaynet_channels) ){
494 $relay_and_nick = relay_and_nick($relaynet,$relaynick,$display_mode);
495 }else
496 {
497 return "";
498 }
499 }
500 }
501
502 my $prefix_error = weechat::config_string(weechat::config_get("weechat.look.prefix_error"));
503 my $prefix_color = weechat::color(weechat::config_color(weechat::config_get("weechat.color.chat_prefix_error")));
504
505 $string = _color_str($prefix_color, $prefix_error) .
506 "\t" .
507 "wrecked message from: ".
508 $relay_and_nick;
509 return $string;
510 }
511
512 sub relay_and_nick
513 {
514 my ($relaynet,$relaynick,$display_mode) = @_;
515 my $nick_color = weechat::info_get('irc_nick_color', $relaynick);
516 my $relaynet_color;
517 if ( $option{relaynet_color} eq "")
518 {
519 $relaynet_color = weechat::color(weechat::info_get('irc_nick_color_name', $relaynet));
520 }else
521 {
522 $relaynet_color = weechat::color($option{relaynet_color});
523 }
524 my $relay_and_nick;
525
526 if ($display_mode eq 0)
527 {
528 $relay_and_nick = $relaynet_color .
529 $relaynet .
530 weechat::color("default") .
531 "/".
532 $nick_color .
533 $relaynick;
534 }elsif ($display_mode eq 1)
535 {
536 $relay_and_nick = $nick_color .
537 $relaynick .
538 weechat::color("default") .
539 "@" .
540 $relaynet_color .
541 $relaynet;
542 }
543 return $relay_and_nick;
544 }
545 # =============== check for a nick mode and extract it ===============
546 sub check_nick_mode
547 {
548 my ($buf_ptr, $relaynick) = @_;
549 $relaynick = weechat::string_remove_color($relaynick,""); # remove color-codes from nick
550 my $nick_mode = "";
551
552 if ($relaynick =~ m/^\@|^\%|^\+|^\~|^\*|^\&|^\!|^\-/) # check for nick modes (@%+~*&!-) in nickname (without color)
553 {
554 $nick_mode = substr($relaynick,0,1); # get original nick_mode
555 $relaynick = substr($relaynick,1,length($relaynick)-1); # remove original nick-mode
556 }
557 return $relaynick,$nick_mode;
558 }
559 # =============== change message tags() ===============
560 sub change_tags_for_message
561 {
562 my ( $buf_ptr,$relaynick, $relaynet, $modifier_data, $display_mode ) = @_;
563
564 my $servername = weechat::buffer_get_string($buf_ptr,"localvar_server");
565 my $channelname = weechat::buffer_get_string($buf_ptr,"localvar_channel");
566
567 if (not defined $relaynet or $relaynet eq "")
568 {
569 $relaynick = $relaynick;
570 }elsif ( $option{suppress_relaynet} eq "off" and $option{relaynet_to_nicklist} eq "on" )
571 {
572 $relaynick = $relaynick . "/" . $relaynet if ($display_mode eq 0);
573 $relaynick = $relaynick . "@" . $relaynet if ($display_mode eq 1);
574 }elsif ( $option{suppress_relaynet} eq "on" and $option{relaynet_to_nicklist} eq "on")
575 {
576 unless ( $option{suppress_relaynet_channels} eq "" or ( grep /^$servername.$channelname$/, @suppress_relaynet_channels) ){
577 $relaynick = $relaynick . "/" . $relaynet if ($display_mode eq 0);
578 $relaynick = $relaynick . "@" . $relaynet if ($display_mode eq 1);
579 }
580 }
581 my $nick_color = weechat::info_get('irc_nick_color_name', $relaynick);
582 if (($weechat_version ne "") && ($weechat_version >= 0x00030800))
583 {
584 $modifier_data =~ s/(^|,)prefix_nick_(.*),/,prefix_nick_$nick_color,nick_$relaynick,/;
585 }
586 else
587 {
588 $modifier_data =~ s/(^|,)nick_(.*),/nick_$relaynick,/;
589 }
590 return $modifier_data;
591 }
592
593 # =============== nicklist ===============
594 sub add_relay_nick_to_nicklist
595 {
596 my ( $buf_ptr, $relaynick , $relaynet ,$display_mode ) = @_;
597 return if ($buf_ptr eq "");
598 return if ($relaynick eq "");
599 my $current_time = time();
600 # search for group.
601 my $ptr_group = "";
602 $ptr_group = weechat::nicklist_search_group($buf_ptr,"",$group_name);
603 # create group if it does not exists.
604 if ( $ptr_group eq "")
605 {
606 $ptr_group = weechat::nicklist_add_group($buf_ptr,"",$group_name,"weechat.color.nicklist_group",1);
607 }
608 return if ( $ptr_group eq "");
609
610 my $servername = weechat::buffer_get_string($buf_ptr,"localvar_server");
611 my $channelname = weechat::buffer_get_string($buf_ptr,"localvar_channel");
612
613 if (not defined $relaynet or $relaynet eq ""){
614 $relaynick = $relaynick;
615 }elsif ( $option{suppress_relaynet} eq "off" and $option{relaynet_to_nicklist} eq "on" )
616 {
617 if (defined $display_mode and $display_mode eq 0)
618 {
619 $relaynick = $relaynick . "/" . $relaynet;
620 }elsif (defined $display_mode and $display_mode eq 1)
621 {
622 $relaynick = $relaynick . "@" . $relaynet;
623 }
624 }elsif ( $option{suppress_relaynet} eq "on" and $option{relaynet_to_nicklist} eq "on")
625 {
626 unless ( $option{suppress_relaynet_channels} eq "" or ( grep /^$servername.$channelname$/, @suppress_relaynet_channels) )
627 {
628 if (defined $display_mode and $display_mode eq 0)
629 {
630 $relaynick = $relaynick . "/" . $relaynet;
631 }elsif (defined $display_mode and $display_mode eq 1)
632 {
633 $relaynick = $relaynick . "@" . $relaynet;
634 }
635 }
636 }
637
638 $nick_timer{$buf_ptr.".".$relaynick} = $current_time; # set new timer
639 # get nick color
640 my $nick_color = weechat::info_get('irc_nick_color_name', $relaynick);
641 # nick already exists in group?
642 my $ptr_nick_gui = weechat::nicklist_search_nick($buf_ptr,$ptr_group,$relaynick);
643 # add nick to nicklist, if my $group exists
644 if ( $ptr_nick_gui eq "" )
645 {
646 my $test = weechat::string_remove_color( _color_str($option{nick_mode_color},$option{nick_mode}),"" );
647 weechat::nicklist_add_nick($buf_ptr,$ptr_group,$relaynick,$nick_color,$test,$option{nick_mode_color},1);
648 # weechat::nicklist_add_nick($buf_ptr,$ptr_group,$relaynick,$nick_color,$option{nick_mode},$option{nick_mode_color},1);
649 weechat::nicklist_nick_set($buf_ptr,$ptr_nick_gui,"prefix",$option{nick_mode});
650 weechat::nicklist_nick_set($buf_ptr,$ptr_nick_gui,"prefix_color",$option{nick_mode_color});
651 }
652 }
653
654 # check out every x minutes if nick is not too old
655 sub check_own_nicklist
656 {
657 my $current_time = time();
658 my $timer = $option{"timer"};
659 while (my ($name, $time) = each %nick_timer)
660 {
661 if ( $current_time - $time >= $timer )
662 {
663 # delete nick from %hash and from nicklist
664 my ($buf_ptr, $relaynick) = split( /\./, $name );
665 my $ptr_group = weechat::nicklist_search_group($buf_ptr,"",$group_name);
666 next if ( $ptr_group eq "" );
667 my $ptr_nick_gui = weechat::nicklist_search_nick($buf_ptr, $ptr_group, $relaynick);
668 if ( $ptr_nick_gui ne "" )
669 {
670 weechat::nicklist_remove_nick($buf_ptr,$ptr_nick_gui);
671 delete $nick_timer{$name};
672 }
673 }
674 }
675 }
676 sub _color_str
677 {
678 my ($color_name, $string) = @_;
679 # use eval for colors-codes (${color:red} eg in weechat.look.prefix_error)
680 $string = weechat::string_eval_expression($string, {}, {},{}) if ($weechat_version >= 0x00040200);
681 return weechat::color($color_name) . $string . weechat::color('reset');
682 }
683
684 # =============== config ===============
685 sub init_config
686 {
687 foreach my $opt (keys %option)
688 {
689 if (!weechat::config_is_set_plugin($opt))
690 {
691 weechat::config_set_plugin($opt, $option{$opt});
692 }else
693 {
694 $option{$opt} = weechat::config_get_plugin($opt);
695 }
696 }
697
698 @bot_nicks = split( /,/, $option{supported_bot_names} ); # read bot names
699 @message_kinds = split( /,/, $option{supported_message_kinds} ); # read supported_message_kinds
700 @list_of_server = split( /,/, $option{servername} ); # read server
701 @suppress_relaynet_channels = split( /,/, $option{suppress_relaynet_channels} ); # read channels
702 @blacklist = split( /,/, $option{blacklist} ); # read blacklist of relay nicks
703
704 if (($weechat_version ne "") && ($weechat_version >= 0x00030500))
705 {
706 foreach my $option ( keys %script_desc )
707 {
708 weechat::config_set_desc_plugin( $option,$script_desc{$option} );
709 }
710
711 }
712 }
713 # =============== hooks() and shutdown ===============
714 sub toggle_config_by_set
715 {
716 my ( $pointer, $name, $value ) = @_;
717 $name = substr($name,length("plugins.var.perl.".$SCRIPT_NAME."."),length($name)); # don't forget the "."
718 $option{$name} = $value;
719
720 if ( $name eq "supported_bot_names" )
721 {
722 @bot_nicks = "";
723 @bot_nicks = split( /,/, $option{supported_bot_names} );
724 }
725 if ( $name eq "supported_message_kinds" )
726 {
727 @message_kinds = "";
728 @message_kinds = split( /,/, $option{supported_message_kinds} );
729 }
730 if ( $name eq "servername" )
731 {
732 @list_of_server = "";
733 @list_of_server = split( /,/, $option{servername} );
734 }
735 if ( $name eq "suppress_relaynet_channels" )
736 {
737 @suppress_relaynet_channels = "";
738 @suppress_relaynet_channels = split( /,/, $option{suppress_relaynet_channels} );
739 }
740 if ( $name eq "timer" )
741 {
742 hook_timer($value);
743 }
744 if ( $name eq "debug" )
745 {
746 hook_debug($value);
747 }
748 return weechat::WEECHAT_RC_OK;
749 }
750
751 sub hook_timer
752 {
753 my $value = $_[0];
754 if ( $value eq 0 )
755 {
756 weechat::unhook($Hooks{timer}) if $Hooks{timer};
757 $Hooks{timer} = "";
758 }
759 else
760 {
761 weechat::unhook($Hooks{timer}) if $Hooks{timer};
762 $Hooks{timer} = weechat::hook_timer( $value * 1000, 60, 0, "check_own_nicklist", "");
763 }
764 return weechat::WEECHAT_RC_OK;
765 }
766
767 sub hook_debug
768 {
769 my $value = $_[0];
770 if ( lc($value) eq "off" or $value eq "")
771 {
772 weechat::unhook($Hooks{debug}) if $Hooks{debug};
773 $Hooks{debug} = "";
774 }else
775 {
776 weechat::unhook($Hooks{debug}) if $Hooks{debug};
777 my ($server, $nick) = split(/\:/,$option{"debug"});
778 $Hooks{debug} = weechat::hook_signal( $server . ",irc_raw_in_PRIVMSG","debug_cb","") if (defined $server and $server ne "");
779 }
780 return weechat::WEECHAT_RC_OK;
781 }
782
783 sub buffer_closing
784 {
785 my ($signal, $callback, $callback_data) = @_;
786
787 while (my ($name, $time) = each %nick_timer)
788 {
789 my ($buf_ptr, $relaynick) = split( /\./, $name );
790 my $ptr_group = weechat::nicklist_search_group($buf_ptr,"",$group_name);
791 # remove nicks before closing buffer
792 delete $nick_timer{$name} if ($buf_ptr eq $callback_data);
793 if ($buf_ptr eq $callback_data and $ptr_group ne "")
794 {
795 weechat::nicklist_remove_group($buf_ptr,$ptr_group);
796 }
797 }
798 return weechat::WEECHAT_RC_OK;
799 }
800
801 # shutting down script will remove the relay nicks from nicklist
802 sub shutdown
803 {
804 while (my ($name, $time) = each %nick_timer)
805 {
806 my ($buf_ptr, $relaynick) = split( /\./, $name );
807 my $ptr_group = weechat::nicklist_search_group($buf_ptr,"",$group_name);
808 next if ( $ptr_group eq "" );
809
810 my $ptr_nick_gui = weechat::nicklist_search_nick($buf_ptr, $ptr_group, $relaynick);
811 weechat::nicklist_remove_nick($buf_ptr,$ptr_nick_gui);
812 }
813 return weechat::WEECHAT_RC_OK;
814 }
815
816 sub should_handle_modifier
817 {
818 my ($modifier_data) = @_;
819
820 foreach ( @message_kinds ){
821 my $message_kind = weechat::string_mask_to_regex($_);
822 if (index( $modifier_data,$message_kind ) != -1)
823 {
824 return 1;
825 }
826 }
827
828 return 0;
829 }
830
831 # ========= string_mask_to_regex() =========
832 sub string_mask_to_regex
833 {
834 my ($nick) = @_;
835 foreach ( @bot_nicks ){
836 my $bot_nick = weechat::string_mask_to_regex($_);
837 if ($nick =~ /^$bot_nick$/i)
838 {
839 return 1;
840 }
841 }
842 return 0;
843 }
844
845 # ========= colorize_lines =========
846 sub colorize_lines
847 {
848 my ( $modifier_data, $nick, $string ) = @_;
849 # change nick name in modifier_data! Take care of tag "prefix_nick_ccc"
850 if (($weechat_version ne "") && ($weechat_version >= 0x00030800))
851 {
852 $modifier_data =~ s/(^|,)nick_(.*),/,nick_$nick,/;
853 }
854 else
855 {
856 $modifier_data =~ s/(^|,)nick_(.*),/nick_$nick,/;
857 }
858
859 my $infolist = weechat::infolist_get("perl_script","","colorize_lines");
860 weechat::infolist_next($infolist);
861
862 if ( "colorize_lines" eq weechat::infolist_string($infolist,"name") )
863 {
864 $string = weechat::hook_modifier_exec( "colorize_lines",$modifier_data,"$nick\t$string");
865 if ($string ne "")
866 {
867 $string =~ m/^(.*)\t(.*)/; # get the nick name: nick[tab]string
868 $nick = $1; # nick
869 $string = $2; # message
870 }
871 # my @array = "";
872 # my $color_code_reset = weechat::color('reset');
873 # @array=split(/$color_code_reset/,$line);
874 # my $new_line = "";
875 # foreach (@array){
876 # $new_line .= $nick_color . $_ . weechat::color('reset');
877 # }
878 # $new_line =~ s/\s+$//g; # remove space at end
879 # $line = $new_line;
880 }
881 weechat::infolist_free($infolist);
882 return ($nick,$string);
883 }
884
885 sub debug_cb
886 {
887 my ($signal, $callback, $callback_data) = @_;
888 # "nick": nick
889 # "host": host
890 # "command": command
891 # "channel": channel
892 # "arguments": arguments (includes channel)
893 if (($weechat_version eq "") or ($weechat_version < 0x00030400))
894 {
895 weechat::print("",weechat::prefix("error").
896 "$SCRIPT_NAME: Debug mode needs WeeChat >= 0.3.4");
897 return weechat::WEECHAT_RC_OK;
898 }
899
900 my $hashtable = weechat::info_get_hashtable("irc_message_parse" => + { "message" => $callback_data });
901 my ($server, $nick) = split(/\:/,$option{"debug"});
902 my @split = split(/\,/,$callback);
903 if (defined $server and $server eq $split[0]){
904 if ( not defined $nick or $nick eq ""){
905 weechat::print("","raw message: $callback_data");
906 }elsif ($nick eq $hashtable->{nick}){
907 weechat::print("","raw message: $callback_data");
908 }
909 }
910 return weechat::WEECHAT_RC_OK;
911 }
912 # ========= main =========
913 weechat::register($SCRIPT_NAME, $SCRIPT_AUTHOR, $SCRIPT_VERSION,
914 $SCRIPT_LICENCE, $SCRIPT_DESCR, "shutdown", "") || return;
915 $weechat_version = weechat::info_get("version_number", "");
916
917 init_config();
918
919 weechat::hook_config( "plugins.var.perl.$SCRIPT_NAME.*", "toggle_config_by_set", "" );
920 weechat::hook_signal("buffer_closing", "buffer_closing", "");
921
922 if (($weechat_version ne "") && ($weechat_version >= 0x00030400)){ # v0.3.4
923 weechat::hook_modifier("500|weechat_print","parse_relayed_msg_cb", ""); # use lower prio (standard: 1000)
924 }
925 else
926 {
927 weechat::hook_modifier("weechat_print","parse_relayed_msg_cb", "");
928 }
929
930 $Hooks{timer} = weechat::hook_timer( $option{"timer"} * 1000, 60, 0, "check_own_nicklist", "");