Bry8Star

repeatedly check irc srvr connection, reconnect if necessary

Mar 16th, 2013
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 31.99 KB | None | 0 0
  1. #
  2. # REPEAT
  3. # Author: Bry8Star. <bry 8 s tar a.t ya hoo d.o.t c om>
  4. #
  5. # Copyright (C) 2013 Bright Star, Bry8Star.
  6. #
  7. # You Must obtain explicit permission from Author, before using this code.
  8. #
  9. # This "REPEAT" plugin for XChat IRC Client Software can Repeat a
  10. # (or set of) task either with fixed-length time, or with variable
  11. # (and random) amount of time. This Plugin can be turned off or on,
  12. # max repeatation number can be set, fixed or variable amount of time
  13. # duration can also be set, main xchat command-name for this plugin
  14. # can also be changed, etc.
  15. #
  16. #
  17. # Search (Ctrl+F) for the word YOUR-CODES
  18. # then add your own custom codes, in that section,
  19. # which you want to repeat.
  20. #
  21. #
  22. # Many "prnt" command lines added for debug purpose, that is, to show
  23. # what is going on, once working fine or expected, then disable those
  24. # lines by placing a "#" symbol in front of "prnt" command.
  25. # or use this command to turn of messages:
  26. # /COMMAND_NAME ShowDbgMsg 0
  27. #
  28. #
  29. # If you will use same plugin for multiple IRC network, then you will
  30. # have to change /COMMAND name. or else they will conflict.
  31. # Simple way would be to add _NetworkName after /COMMAND
  32. # For example, if my IRC network list entry for freenode is
  33. # "Freenode-Bry8Star", then i would set command like this:
  34. # /REPEAT_FN_Bry8
  35. # or, /RECONNECT_FN_Bry8
  36. # or, /AUTO_RECONNECT_FN_Bry8
  37. # (keep command name under 33 characters)
  38. #
  39. #
  40. # ToDO:
  41. # Add a "CheckViaPM" method, for checking irc network server connection
  42. # status. Then IRC server which are behind BNC would also work via
  43. # using this script/plugin.
  44. # Detect the "* Stopped previous connection attempt..." message and
  45. # then attempt to issue "RECONNECT" command.
  46. # Change "Counting"/"Showing-number" into "Checking Server Connection Status"
  47. # Show actual local system time when showing elapsed time.
  48. #
  49.  
  50.  
  51.  
  52. use strict;
  53. use warnings;
  54. use Xchat qw(:all);
  55.  
  56.  
  57.  
  58. # sub-prototypes:
  59. sub rInt(); # convert any +/- non+/-fractional into correct +/- Integer.
  60. sub ms2sec(); # converts ms(milli-seconds) into sec with fractional NUMBER.
  61. sub ms2iSec(); # converts ms into sec(seconds) with no fraction, NUMBER.
  62. sub ms2fSec(); # converts ms into sec STRING with 3 fraction after point.
  63. sub sec2ms(); # converts sec into ms number, 1 sec is 1000 ms.
  64. sub usrFSec2ms(); # convert user given fractional-second into ms.
  65. sub prnt_on(); # prnt_on( $r->{sDbgMsg} , "message" , $r->{NtwrkLstNm} );
  66.  
  67.  
  68.  
  69. # Controlling Global Variables: (requires perl 5.10+):
  70. my $r //= { #
  71. cmdNm => "AUTO_RECONNECT_YourIRC", # main command name of this XChat plugin,
  72. # for FN-bry8 IRC Net (Freenode-for-bry8star).
  73. # my($mainCmd)="REPEAT"; # name of XChat main command, for this plugin.
  74. enbl => 0, # indicator for REPEAT: Enable(1) or Disable(0) ?
  75. upto => 10, # initially max number of repeatation amount is set on 10.
  76. # if $r->{upto} is 0, then plugin will repeat unlimited number of times.
  77. tmrTyp => 2, # 1 = fixed-length timer, 2 = variable-length timer.
  78. rptTm => 62000, # user given main repeat time interval. 60000ms=60sec.
  79. varTm => 5000, # variable fluctuating time amount. Max Half of $timeIntrvl.
  80. rndmTm => 62000, # random time = (+/-~$r->{varTm} + $r->{rptTm} ).
  81. sDbgMsg => 2, # show debug message. 1 = yes. 0 = no. 2 = network-servr-tab.
  82. # if $r->{sDbgMsg} = 2 then show dbg msg only on given network's main/srvr tab
  83. countr => 0, # it stores counting/loop number.
  84. tmrExist => 0, # Whan a hook_timer is created then this is set to 1.
  85. hkPnt => 0, # used for storing timer's ref-/mem-location-point.
  86. #
  87. # Enter name of IRC NETWORK NAME which you used inside your
  88. # XChat NETWORK LIST, (or SERVER LIST) for repeatedly checking
  89. # if its connected or not, with IRC Server, if not connected
  90. # then this plugin will RECONNECT back.
  91. NtwrkLstNm => 'YourIRC', # target irc net name to check & reconnect
  92. #
  93. cntxLocOfNtwrkSvTb => "", # Target IRC Network's main server tab location
  94. usrContxtPosn => "", # user's current context position
  95. elapsTm => 0, # elapsed time, in between now and previous repeatation
  96. };
  97.  
  98. $r->{usrContxtPosn} => Xchat::get_context();
  99. $r->{elapsTm} = ( $r->{tmrTyp} == 2 )? $r->{rndmTm} : $r->{rptTm};
  100.  
  101.  
  102. Xchat::register($r->{cmdNm} ,'1.0.6',"$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) allows to repeat tasks. Such as checking servr connection status. More info, type: /". $r->{cmdNm} );
  103.  
  104.  
  105.  
  106. prnt("\x{2}". $r->{cmdNm} ."\x{2} plugin \(for ". $r->{NtwrkLstNm} ."\) for XChat, started. \(A plugin for repeating tasks\). To see more info, you may type: /". $r->{cmdNm} );
  107.  
  108.  
  109.  
  110. # This portion developed by Bry8Star:
  111. Xchat::hook_command( $r->{cmdNm} , sub{
  112. # Xchat::hook_command( "COUNTER", sub{
  113. # Xchat::hook_command( "REPEAT", sub{
  114. my($mS)="";
  115. my($userDat1)="";
  116. my($userDat2)="";
  117. my($uV)=0;
  118. if (not defined $_[0][1]) {
  119. # User did not specify any sub-command option or value after main command:
  120. # Main command is /REPEAT
  121. # or, Main command is /$r->{cmdNm}
  122. $mS .= "\x{2}". $r->{cmdNm} ."\x{2} --> Currently this REPEAT \(". $r->{cmdNm} ."\) Plugin is \x{2}". (($r->{enbl} )? "ON" : "OFF") ."\x{2} \(for \"". $r->{NtwrkLstNm} ."\" IRC Network\)\.\n";
  123. $mS .= "Command Examples\:\n";
  124. $mS .= " \x{2}/$r->{cmdNm} ON\x{2} <-- Enable this \"Repeat\" plugin\. It will start to repeat ". (($r->{upto} >= 1 )? "upto $r->{upto} " : "unlimited ") ."times/number, and will check connection status with given IRC Server \(or repeat/do your other codes\)\.\n";
  125. $mS .= " \x{2}/$r->{cmdNm} OFF\x{2} <-- disables/stops repeatations/counting and stops checking connection status, \(or if you have added your codes, then it will stop executing those codes\)\.\n";
  126. $mS .= " \x{2}/$r->{cmdNm} upto 20\x{2} <-- will do total 20 repeatations for showing counting numbers upto 20, or it will do your codes 20 times\. And then stop\. Current \"upto\" value is ". (($r->{upto} >= 1 )? "$r->{upto} \(" : "$r->{upto} \(means, unlimited number of ") ."repeatations\)\.\n";
  127. $mS .= " \x{2}/$r->{cmdNm} variable 5\x{2} <-- Start randomly add or subtract variable time-legth in between +/- 5 seconds with main Interval time of ". ms2fSec($r->{rptTm}) ." seconds \(this given \"5\" seconds will be accepted if it is not more than the half of main Interval time\)\. Current value is ". ms2fSec($r->{varTm}) ." seconds\. It can be upto +/- ". ms2fSec("". ($r->{rptTm}/ 2)) ." \(half of main Time Interval ". ms2fSec($r->{rptTm}) ."\) seconds\.\n";
  128. $mS .= " \x{2}/$r->{cmdNm} interval 30\x{2} <-- start to repeatedly check connection status with given IRC server, after each 30 seconds of main Time Interval, if/when enabled\. Current value is ". ms2fSec($r->{rptTm}) ." seconds\.\n";
  129. $mS .= " \x{2}/$r->{cmdNm} timerType 2\x{2} <-- use variable-length of time for checking connection status with given IRC server, \(or for doing your codes\)\. Current value is $r->{tmrTyp} \(". (($r->{tmrTyp} == 2 )? "variable-time" : "fixed-time") ."\)\.\n";
  130. $mS .= " \x{2}/$r->{cmdNm} showDbgMsg 0\x{2} <-- turn off showing debug messages on screen\. To turn on use 1, or, 2\. Current value is ". $r->{sDbgMsg} ." \(". (($r->{sDbgMsg} == 2 )? ("Show Debug Messages inside main/server tab of \"". $r->{NtwrkLstNm} ."\" IRC Network") : (($r->{sDbgMsg} == 1 )? "Show Debug Messages inside user\'s/your current tab position" : "Do Not Show Debug Messages")) ."\)\.\n";
  131. $mS .= " \x{2}/$r->{cmdNm} showDbgMsg 2\x{2} <-- show debug messages only inside the \"". $r->{NtwrkLstNm} ."\" IRC network\'s main/server tab\. \(If mentioned destination IRC Network\'s tab is not found, then messages will be shown inside user\'s current tab/context location\)\.\n";
  132. prnt($mS);
  133. $mS = "";
  134. } else { # Section: /CMD Sub-Cmd Value
  135. # User has specified a sub-command (option) or a value after main command:
  136. $userDat1 = lc((not defined $_[0][1] )? "" : $_[0][1]);
  137. # Checking single sub-command (SSC) or single value (SV) based options:
  138. if ($userDat1 eq 'off' or $userDat1 eq '0') {
  139. $r->{enbl} = 0; # disable REPEAT ( $r->{cmdNm} )
  140. if ($r->{hkPnt} or $r->{tmrExist} ) {
  141. if ($r->{sDbgMsg} ) {
  142. $mS=""; $mS .= "$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> Stopped a previously running Timer. \(\$r->{tmrExist}=$r->{tmrExist} , \$r->{hkPnt}=$r->{hkPnt} \) \(h_c\)";
  143. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  144. };
  145. Xchat::unhook( $r->{hkPnt} );
  146. # $r->{hkPnt} = 0;
  147. $r->{tmrExist} = 0; # 0 = No. 1 = yes.
  148. };
  149. prnt("\x{2}". $r->{cmdNm} ."\x{2} \(for ". $r->{NtwrkLstNm} ."\) --> is now \x{2}OFF\x{2}/disabled. Repeatation/Counting task is stopped, \(for checking connection status with \"". $r->{NtwrkLstNm} ."\" IRC Network\)\.");
  150. $r->{countr} = 0;
  151. return EAT_ALL;
  152. } elsif ($userDat1 eq 'on' or $userDat1 eq '1') {
  153. if ($r->{hkPnt} or $r->{tmrExist} ) {
  154. if ($r->{sDbgMsg} ) {
  155. $mS=""; $mS .= "$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> Stopped a previously running Timer. \(\$r->{tmrExist}=$r->{tmrExist} , \$r->{hkPnt}=$r->{hkPnt} \) \(h_c\)";
  156. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  157. };
  158. Xchat::unhook( $r->{hkPnt} );
  159. # $r->{hkPnt} = 0;
  160. $r->{tmrExist} = 0;
  161. };
  162. $r->{enbl} = 1; # enable REPEAT ( $r->{cmdNm} ).
  163. $r->{countr} = 0;
  164. prnt("\x{2}". $r->{cmdNm} ."\x{2} \(for ". $r->{NtwrkLstNm} ."\) --> is now \x{2}ON\x{2}/enabled, \(for \"". $r->{NtwrkLstNm} ."\" IRC Network\)\. Starting to repeat ". (($r->{upto} >= 1 )? ("upto ". $r->{upto} ) : "unlimited number of") ." times, after every ". (($r->{tmrTyp} == 2 )? "$r->{rndmTm} +/- ~$r->{varTm} seconds of variable-time" : "$r->{rptTm} seconds of fixed-time") ." based repeatations\.");
  165. &start_timer();
  166. return EAT_ALL;
  167. # } elsif ($userDat1 eq 'new-option') { list your other SSC, SV options #
  168. } else { # Section: Sub-Cmd Value
  169. # Checking options which requires a sub-command and also requires a value:
  170. if (defined $_[0][2]) { # Section: Value (after Sub-Cmd exist)
  171. # User has specified a non-empty value for sub-commands:
  172. $userDat2 = lc((not defined $_[0][2] )? "" : $_[0][2]);
  173. # Start to check given sub-commands, and their given values:
  174. if ($userDat1 eq "upto") {
  175. # Grabbing only positive integer portion:
  176. $uV=0; $uV = int(abs(0 + $userDat2));
  177. if ($uV >= 1) {
  178. $r->{upto} = $uV;
  179. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> will repeat upto $r->{upto} times, if/when enabled\.");
  180. } elsif ($uV == 0) {
  181. $r->{upto} = $uV;
  182. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> plugin will repeat unlimited times, for checking connection status with given IRC Server without stopping, unless you set it to any limited value, like\: 1\.");
  183. } else {
  184. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> This \"". $userDat2 ."\" is empty or not a valid value for \"upto\" sub-command, please specify \(number of limited/finite repeatation number\) 1 or more\. If you specify 0, then plugin will repeat without stopping, for unlimited number of times\. Current \"upto\" value is\: $r->{upto} \(". (($r->{upto} >= 0 )? "means, unlimited number of " : "") ." repeatations\)\.");
  185. };
  186. return EAT_ALL;
  187. } elsif ($userDat1 eq "showdbgmsg") {
  188. # Grabbing only positive integer portion:
  189. $uV=0; $uV = int(abs(0 + $userDat2));
  190. if ($uV == 1 or $uV == 0) {
  191. $r->{sDbgMsg} = $uV;
  192. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> will ". (($r->{sDbgMsg} )? "" : "not ") ."show debug messages on screen, if/when enabled\.");
  193. } elsif ($uV == 2) {
  194. $r->{sDbgMsg} = $uV;
  195. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> will show debug messages only inside the \"". $r->{NtwrkLstNm} ."\" IRC Network\'s main/server tab, if/when enabled\.");
  196. } else {
  197. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> This \"". $userDat2 ."\" is empty or not a valid value for \"showDbgMsg\" sub-command, please specify either 0 or 1\. Current value is\: $r->{sDbgMsg} \(". (($r->{sDbgMsg} == 2 )? ("Show Debug Messages inside main/server tab of \"". $r->{NtwrkLstNm} ."\" IRC Network") : (($r->{sDbgMsg} == 1 )? "Show Debug Messages on user\'s/your current tab position" : "Do Not Show Debug Messages")) ."\)\.\n");
  198. };
  199. return EAT_ALL;
  200. } elsif ($userDat1 eq "variable") {
  201. $uV=0; $uV = usrFSec2ms( ("".$userDat2) );
  202. if ($uV) {
  203. if ($uV <= rInt( ($r->{rptTm} / 2) )) {
  204. $r->{varTm} = sec2ms($uV);
  205. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> plugin will start to randomly add or subtract variable time-length in betwenn +/- ". ms2fSec($r->{varTm} ) ." seconds with main time interval of ". ms2fSec($r->{rptTm} ) ." seconds, and then check IRC server connection status for ". (($r->{upto} >= 1 )? ("upto $r->{upto} " ) : "limitless number of ") ."times\. Currently \"TimerType\" option has\: $r->{tmrTyp} \(". (($r->{tmrTyp} == 2 )? "variable-timer" : "fixed-timer") ."\), means this \"Variable\" time will ". (($r->{tmrTyp} == 2 )? "" : "not ") ."be used\.");
  206. } else {
  207. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> acceptable value \(for \"variable\"\) can be maximum ". ms2fSec($r->{rptTm} / 2) ." seconds \(which is, Half of current main Time Interval\)\. \(If you want to, you can set \"timerType\" sub-command\'s value to 1, to use fixed-length time for each repeatation\)\. Currently \"variable\" has value of\: ". ms2fSec($r->{varTm} ) ." seconds\.");
  208. };
  209. # } elsif ($userDat1 eq 'new-option') { list your other options #
  210. } else {
  211. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> you/user have/has specified this \"". $userDat2 ."\" is empty or not a valid value for \"variable\" sub-command, please specify a different number\. \(If you want to, you can set \"timerType\" sub-command\'s value to 1, to use fixed-length time for each repeatation\)\. Current \"variable\" time value is\: ". ms2fSec($r->{varTm} ) ." seconds\.");
  212. };
  213. return EAT_ALL;
  214. } elsif ($userDat1 eq "interval") {
  215. $uV=0; $uV = usrFSec2ms($userDat2);
  216. if ($uV >= 2) {
  217. $r->{rptTm} = sec2ms($uV);
  218. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> plugin will start to check connection status repeatedly \(for given IRC server, if/when enabled\), after each main Time Interval of around ~ ". ms2fSec($r->{rptTm} ) ." seconds, ". (($r->{upto} >= 1 )? ("until counting or max-repeatation number reaches ". $r->{upto} ) : "for unlimited number of times") ."\.");
  219. if ($r->{varTm} > rInt($r->{rptTm} / 2)) {
  220. $mS="";
  221. $mS .= "$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> previous \"Variable\" Time amount was ". ms2fSec($r->{varTm} ) ." seconds \($r->{varTm} milli-seconds\), and it was higher than half of currently specified main Time Interval amount, so lowered Variable Time and set to ";
  222. $r->{varTm} = rInt($r->{rptTm} / 2);
  223. $mS .= "". ms2fSec($r->{varTm} ) ." seconds \($r->{varTm} milli-seconds\)\.";
  224. prnt($mS);
  225. $mS="";
  226. };
  227. # On first repeatation, $r->{rndmTm} should be = to $r->{rptTm} :
  228. $r->{rndmTm} = $r->{rptTm};
  229. } else {
  230. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> This \(sub-command\) value \"". $userDat2 ."\" is empty or not a valid \(sub-command\) value for \"interval\" sub-command, please specify a different number\. Number must be at-least\: 2 \(seconds\), or more. Current \"interval\" value is\: ". ms2fSec($r->{rptTm} ) ." seconds\.");
  231. };
  232. return EAT_ALL;
  233. } elsif ($userDat1 eq "timertype") {
  234. $uV=0; $uV = int(abs(0 + $userDat2));
  235. if ($uV >= 1 and $uV <= 2) {
  236. $r->{tmrTyp} = $uV;
  237. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> plugin will use ". (($r->{tmrTyp} == 2 )? "random and variable-time" : "fixed-time") ." for each repeatation \(". (($r->{tmrTyp} == 2 )? (ms2fSec($r->{rptTm} ) ." +/- 0 to ". ms2fSec($r->{varTm} )) : ms2fSec($r->{rptTm} )) ." seconds\) before checking connection status with \(given\) IRC Server \(or before doing your codes\)\.");
  238. } else {
  239. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> This \(sub-command\) value \"". $userDat2 ."\" is empty or not a valid \(sub-command\) value for \"timerType\" sub-command, please specify a different number\. Number 1 tells this plugin to use a fixed-length time for each repeatation, and number 2 tells the plugin to use variable-length time on each repeatation\. Current \"timerType\" value is\: $r->{tmrTyp} \(". (($r->{tmrTyp} == 2 )? "variable-time" : "fixed-time") ."\)\.");
  240. };
  241. return EAT_ALL;
  242. } else { # Section: /CMD No-Value_or_No-Sub-Cmd
  243. # User has not specified a valid/known sub-command/option,
  244. # or user has not specified a known value after main command:
  245. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> This \"". ((defined $_[0][1] )? $_[0][1] : "") ."\" is empty or not a valid value or not a valid sub-command for this Plugin\. Valid sub-commands can be \"upto\", \"variable\", \"interval\", \"timerType\", \"showDbgMsg\", etc \(and then each of these sub-command also requires you/user specify at-least it\'s one valid value\)\. And \(other\) valid value after this plugin\'s main command currently can be\: ON, 1, OFF, 0, to enable or disable this plugin, etc\.");
  246. return EAT_ALL;
  247. }; # END of Section: /CMD No-Value_or_No-Sub-Cmd
  248. } # END of Section: Value (after Sub-Cmd exist)
  249. else { # Section: Value (after Sub-Cmd does not exist)
  250. # User has specified empty or non-valid or no value for sub-commands:
  251. prnt("$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> This \"". ((defined $_[0][2] )? $_[0][2] : "") ."\" is empty or not a valid value, for these sub-commands\: \"upto\", \"variable\", \"interval\", \"timerType\", \"showDbgMsg\", etc\. Please specify positive integer number without \+ symbol\. Negative numbers are not accepted\.");
  252. }; # END of Section: Value (after Sub-Cmd does not exist)
  253. }; # END of Section: Sub-Cmd Value
  254. }; # END of Section: /CMD Sub-Cmd Value
  255. return EAT_ALL;
  256. }, {data => "", help_text => "$r->{cmdNm} \: Plugin for repeating any tasks\. Like, checking connection status to \"". $r->{NtwrkLstNm} ."\"\. To see more info, type /$r->{cmdNm} "});
  257. # END of hook_command( $r->{cmdNm} , ...)
  258.  
  259.  
  260.  
  261.  
  262. # Below sections developed by Bry8Star:
  263. #
  264. # Simple small (and frequently used) functions:
  265.  
  266. sub rInt ($) {
  267. # Convert given number or string, into a correctly
  268. # rounded INTEGER number:
  269. # (Output wil have no fraction, that is, no number after point)
  270. my($n) = ((defined $_[0] )? (((0 + $_[0]) != 0 )? (0 + $_[0]) : 0) : 0);
  271. # Thanks to user RET for below main code, then modified by Bry8Star:
  272. return int($n + (($n != 0 )? ($n / abs($n * 2)) : 0));
  273. }
  274.  
  275. sub ms2sec ($) {
  276. # convert milli-seconds to seconds (including fractions) :
  277. return ((defined $_[0] )? (((0 + $_[0]) != 0 )? ((0 + $_[0]) / 1000) : 0) : 0);
  278. }
  279.  
  280. sub ms2iSec ($) {
  281. # Convert milli-seconds into non-fractional seconds:
  282. # First, converting given STRING sec, into NUMBER sec:
  283. my($f) = ((defined $_[0] )? (((0 + $_[0]) != 0 )? ((0 + $_[0]) / 1000) : 0.0) : 0.0);
  284. # return int(( 0 + $_[0] )? ((0 + $_[0]) / 1000) : 0); # simple (but not correct)
  285. # converting into correctly rounded (non-fractional) integer number:
  286. return rInt($f);
  287. }
  288.  
  289. sub ms2fSec ($) {
  290. # convert milli-seconds to fractional seconds
  291. # with upto max 3 numbers after dot/point:
  292. my($fsec) = 0.0;
  293. if (defined $_[0] ) {
  294. if ((0 + $_[0]) != 0 ) {
  295. $fsec = (0 + $_[0]) / 1000;
  296. };
  297. };
  298. # round it to fraction with upto 3 numbers only:
  299. my($sec3f) = 0.000;
  300. if ($fsec != 0) {
  301. $sec3f = sprintf("%.3f", ($fsec * 1.0));
  302. };
  303. # converting to string:
  304. my($sT) = "". $sec3f;
  305. # replacing multiple leading zero with one zero:
  306. $sT =~ s/^[0]+/"0"/e;
  307. # removing that one leading zero if a digit exist after it:
  308. $sT =~ s/^[0]([1-9])/$1/;
  309. # adding .000 text-string after number
  310. # which only had non-fraction portion:
  311. $sT =~ s/^(\d+)$/$1.".000"/e;
  312. # adding 2 zeroes (like .N00) after a fractional number
  313. # which only had 1 digit after the point:
  314. $sT =~ s/(\d+\.[1-9])$/$1."00"/e;
  315. # adding 1 zero (like .NN0) after a fractional-second
  316. # which only had 2 digits after the point:
  317. $sT =~ s/(\d+\.\d[1-9])$/$1."0"/e;
  318. # adding a zero in front when there is no zero before a point:
  319. $sT =~ s/^(\.\d+)/"0".$1/e;
  320. return $sT;
  321. }
  322.  
  323. sub usrFSec2ms ($) {
  324. # Convert user given fractional second into milli-seconds:
  325. # (round & accept only 3 digits after point, if point exist)
  326. # First converting user given string input into a
  327. # fractional positive number:
  328. my($fsec) = 0.0;
  329. if (defined $_[0] ) {
  330. if ((0 + $_[0]) != 0 ) {
  331. $fsec = abs(0 + $_[0]);
  332. };
  333. };
  334. # Rounding it to fraction with upto 3 numbers only after the point:
  335. my($sec3f) = 0.0;
  336. if ($fsec != 0) {
  337. $sec3f = sprintf("%.3f", $fsec);
  338. };
  339. # converting into a milli-second NUMBER, and returning it back:
  340. my($iMS) = 0;
  341. if ($sec3f != 0 ) {
  342. $iMS = int($sec3f * 1000);
  343. };
  344. return $iMS;
  345. }
  346.  
  347. sub sec2ms ($) {
  348. # convert seconds into milli-seconds :
  349. my($iMS) = 0;
  350. if (defined $_[0] ) {
  351. if ((0 + $_[0]) != 0 ) {
  352. $iMS = int((0 + $_[0]) * 1000);
  353. };
  354. };
  355. return $iMS;
  356. }
  357.  
  358.  
  359. # This section developed by Bry8Star:
  360. # portion of codes were contributed by nightfrog, Khisanth:
  361. sub prnt_on {
  362. my($sMsg, $uMsg, $ircNetNm) = @_;
  363. # my($sMsg)=(defined $_[0][1] )? (0 + $_[0][1]) : 0;
  364. if (defined $sMsg) { if ($sMsg) {
  365. # my($uMsg)=((defined $_[0][2] )? "". $_[0][2] : "");
  366. # my($rt) = 0;
  367. if ($sMsg == 1) {
  368. #$rt = prnt($uMsg);
  369. prnt($uMsg);
  370. #return $rt;
  371. } else {
  372. if ($sMsg == 2) {
  373. # my($ircNetNm)=((defined $_[0][3] )? "". $_[0][3] : "");
  374. my($uCurContxtLoc)= Xchat::get_context();
  375. if (defined $ircNetNm) {
  376. if ($ircNetNm) {
  377. if ((not defined $r->{cntxLocOfNtwrkSvTb} ) or not $r->{cntxLocOfNtwrkSvTb} ) {
  378. # This/below "for" loop portion of codes are based on script
  379. # from user "nightfrog". Which in turn based on codes from
  380. # user "Khisanth".
  381. for my $tab (Xchat::get_list "channels") {
  382. if ($tab->{type} == 1) {
  383. if (lc($tab->{network} ) eq lc($ircNetNm)) {
  384. $r->{cntxLocOfNtwrkSvTb} = $tab->{context};
  385. last; # by Bry8Star.
  386. };
  387. };
  388. }; # END of for loop
  389. };
  390. };
  391. };
  392. if (defined $r->{cntxLocOfNtwrkSvTb} ) {
  393. if ( $r->{cntxLocOfNtwrkSvTb} ) {
  394. prnt($uMsg) if (Xchat::set_context($r->{cntxLocOfNtwrkSvTb} ));
  395. #$rt = prnt($uMsg) if (Xchat::set_context($r->{cntxLocOfNtwrkSvTb} ));
  396. };
  397. } else {
  398. prnt($uMsg);
  399. #$rt = prnt($uMsg);
  400. };
  401. Xchat::set_context( $uCurContxtLoc );
  402. #return $rt;
  403. };
  404. };
  405. }; };
  406. return Xchat::EAT_NONE;
  407. } # END of sub prnt_on
  408.  
  409.  
  410.  
  411.  
  412. # This portion developed by Bry8Star:
  413. sub call_and_do_something {
  414. my($mS)="";
  415. $r->{countr} = $r->{countr} +1;
  416. #
  417. # BEGIN or place user's codes or YOUR-CODES or other
  418. # codes here, which you want to execute repeatedly based
  419. # on this REPEAT ($r->{cmdNm} ) plugin.
  420. # ...
  421. if ($r->{sDbgMsg} ) {
  422. $mS .= "$r->{countr} \(\$r->{hkPnt}=$r->{hkPnt} , \$r->{rndmTm}=$r->{rndmTm} , \$r->{rptTm}=$r->{rptTm} \) \(c_a_d_s\)";
  423. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  424. };
  425. $r->{elapsTm} = ($r->{tmrTyp} == 2 )? $r->{rndmTm} : $r->{rptTm};
  426.  
  427. $r->{usrContxtPosn} = Xchat::get_context();
  428.  
  429. if ((not defined $r->{cntxLocOfNtwrkSvTb} ) or not $r->{cntxLocOfNtwrkSvTb} ) {
  430. # Below "for" loop coding portion contributed by nightfrog,
  431. # which was based on user Khisanth's script.
  432. # Then further modified by Bry8Star.
  433. for my $tab (Xchat::get_list "channels") {
  434. if ($tab->{type} == 1) {
  435. if (lc( $tab->{network} ) eq lc( $r->{NtwrkLstNm} )) {
  436. $r->{cntxLocOfNtwrkSvTb} = $tab->{context};
  437. last; # by Bry8Star.
  438. };
  439. };
  440. }; # END of for loop
  441. };
  442.  
  443. Xchat::set_context( $r->{cntxLocOfNtwrkSvTb} );
  444.  
  445. if (defined Xchat::get_info "server") {
  446. if ($r->{sDbgMsg} ) {
  447. $mS=""; $mS .= "Internet connection status checking \(to IRC server\) is\: \x{2}ok\x{2} \:\) \(Last repeatation time period or duration was around ". ms2fSec($r->{elapsTm} ) ." seconds\) \(Checked total $r->{countr} times\) <-- \x{2}". $r->{cmdNm} ."\x{2} \(for ". $r->{NtwrkLstNm} ."\)";
  448. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  449. };
  450. Xchat::set_context( $r->{usrContxtPosn} );
  451. } else {
  452. if ($r->{sDbgMsg} ) {
  453. $mS=""; $mS .= "Internet connection status checking indicating\: \x{2}disconnected or Stopped\x{2} ! \:\( Trying to reconnect... \(Last repeatation time period or duration was around ". ms2fSec($r->{elapsTm} ) ." seconds\) \(Checked total $r->{countr} times\) <-- \x{2}". $r->{cmdNm} ."\x{2} \(for ". $r->{NtwrkLstNm} ."\)";
  454. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  455. };
  456. Xchat::command("RECONNECT") if (Xchat::set_context($r->{cntxLocOfNtwrkSvTb} ));
  457. Xchat::set_context( $r->{usrContxtPosn} );
  458. };
  459.  
  460. # ...
  461. # END of YOUR-CODES.
  462. #
  463. # Adding below codes as safe-guard for not allowing a timer
  464. # to keep on running. Even if there is a coding mistake,
  465. # a timer should stop by itself and to force it to stop.
  466. # (But if $r->{upto} is set on to 0, then looping will be done
  467. # unlimited number of times: unless plugin is disabled/OFF,
  468. # or, unless a limited/finite number is set inside $r->{upto} ).
  469. if ($r->{enbl} == 0 or ($r->{upto} >= 1 and $r->{countr} >= $r->{upto} )) {
  470. # If REPEAT/$r->{cmdNm} is set to OFF, or when loop exceeds, then:
  471. if ($r->{sDbgMsg} ) {
  472. $mS=""; $mS .= "\x{2}". $r->{cmdNm} ."\x{2} \(for ". $r->{NtwrkLstNm} ."\) --> Repeatation/Counting \x{2}finished\x{2}\. \(c_a_d_s\)";
  473. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  474. };
  475. $r->{enbl} = 0; # disable REPEAT/$r->{cmdNm} plugin.
  476. if ($r->{hkPnt} or $r->{tmrExist} ) {
  477. if ($r->{sDbgMsg} ) {
  478. $mS=""; $mS .= "$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> Stopped a running Timer\. \(\$r->{tmrExist}=$r->{tmrExist} , \$r->{hkPnt}=$r->{hkPnt} \) \(c_a_d_s\)";
  479. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  480. };
  481. Xchat::unhook( $r->{hkPnt} );
  482. # $r->{hkPnt} = 0;
  483. $r->{tmrExist} = 0; # 0 = no. 1 = yes.
  484. };
  485. } else {
  486. \&start_timer();
  487. };
  488. } # END of sub call_and_do_something
  489.  
  490.  
  491.  
  492.  
  493. # This portion developed by Bry8Star:
  494. sub start_timer {
  495. # if $r->{tmrTyp} or $_[0] is 1, then keep on loop with
  496. # fixed time length based timer.
  497. # if $r->{tmrTyp} or $_[0] is 2, then loop with variable timer
  498. # once only, and then close previous timer and start another
  499. # timer with different time length again.
  500. # When variable-length timer is used for once, then it is
  501. # easier to stop them, and also easier to start with new
  502. # values if user has changed any options/parameters/values.
  503. my($mS)="";
  504. if ($r->{enbl} == 1 && ($r->{upto} == 0 or $r->{countr} < $r->{upto} )) {
  505. if ($r->{hkPnt} or $r->{tmrExist} ) {
  506. if ($r->{sDbgMsg} ) {
  507. $mS=""; $mS .= "$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> Stopped a previously running \(". (($r->{tmrTyp} == 2 )? "variable-time-length" : "fixed-timed") ."\) Timer\. \(\$r->{tmrExist}=$r->{tmrExist} , \$r->{hkPnt}=$r->{hkPnt} \) \(s_t\)";
  508. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  509. };
  510. Xchat::unhook( $r->{hkPnt} );
  511. # $r->{hkPnt} = 0;
  512. $r->{tmrExist} = 0;
  513. };
  514. if ($r->{tmrTyp} == 2) {
  515. # Creating a random amount of time in between from 0
  516. # to $r->{varTm} amount of time, then randomly either
  517. # adding or subtracting that from/with $r->{rptTm} ,
  518. # and then placing result inside $r->{rndmTm} :
  519. variate_repeat_time();
  520. };
  521. if ($r->{sDbgMsg} ) {
  522. $mS=""; $mS .= "$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> Creating a new \(". (($r->{tmrTyp} == 2 )? "variable-time-length" : "fixed-timed") ."\) Timer for ". ms2fSec(($r->{tmrTyp} == 2 )? $r->{rndmTm} : $r->{rptTm} ) ." seconds \(". (($r->{tmrTyp} == 2 )? $r->{rndmTm} : $r->{rptTm} ) ." milli-seconds\)\. \(s_t\)";
  523. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  524. };
  525. # WARNING:
  526. # Make sure to use "\" and "&" immediately before the sub-function
  527. # name, used inside the hook_timer command, to create one timer only,
  528. # or else, it will create $r->{upto} number ($r->{upto} = 0 means,
  529. # "unlimited" number) of multiple Timers at the same time and XChat
  530. # may crash or or become non-responsive very soon or instantly.
  531. $r->{tmrExist} += 1;
  532. $r->{hkPnt} = Xchat::hook_timer ( int(($r->{tmrTyp} == 2 )? $r->{rndmTm} : $r->{rptTm} ) , \&call_and_do_something ,{data => ""});
  533. }; # End of checking if repeatation allowed or not
  534.  
  535. # Completely stop even the last timer, when followings are true:
  536. if ($r->{enbl} == 0 or ($r->{upto} >= 1 and $r->{countr} >= $r->{upto} )) {
  537. if ($r->{sDbgMsg} ) {
  538. $mS=""; $mS .= "$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> Repeatation \x{2}finished\x{2}\. \(s_t\)";
  539. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  540. };
  541. $r->{enbl} = 0;
  542. if ($r->{hkPnt} or $r->{tmrExist} ) {
  543. if ($r->{sDbgMsg} ) {
  544. $mS=""; $mS .= "$r->{cmdNm} \(for ". $r->{NtwrkLstNm} ."\) --> Stopped a previously running Timer\. \(\$r->{tmrExist}=$r->{tmrExist} , \$r->{hkPnt}=$r->{hkPnt} \) \(s_t\)";
  545. prnt_on( $r->{sDbgMsg}, $mS, $r->{NtwrkLstNm} );
  546. };
  547. Xchat::unhook( $r->{hkPnt} );
  548. # $r->{hkPnt} = 0;
  549. $r->{tmrExist} = 0;
  550. };
  551. };
  552. # return 0;
  553. return Xchat::EAT_NONE;
  554. } # END of sub start_timer
  555.  
  556.  
  557.  
  558. # This portion developed by Bry8Star:
  559. sub variate_repeat_time {
  560. # Creating a random time-duration between 0 to $r->{varTm}
  561. # milli-seconds, and then randomly either subtracting it or
  562. # adding it with user's given main time-duration $r->{rptTm} ,
  563. # to variate/fluctuate total timer duration.
  564. # XChat internally uses milli-seconds.
  565. my($maxFluctuateRange) = int(1 + ((abs($r->{varTm} ) )? (abs($r->{varTm} )) : 0 )); # using milli-seconds
  566. # Generate a random (1st-)number, from 0 to 10000 (milli-seconds):
  567. my($randomNumB2inZroAndVarTime) = rand( $maxFluctuateRange );
  568. # Create another (2nd-)random/any number starting from 0 to 7:
  569. my($randomPlusMinus) = rand( 8);
  570. # If 2nd random Num is from 0 to 3 only then (try to) multiply with -1:
  571. if ($randomPlusMinus <= 3) {
  572. # If 1st random Num is not 0, then multiply with -1:
  573. if ($randomNumB2inZroAndVarTime > 0) {
  574. # Converting to a Negative number:
  575. $r->{rndmTm} = -1 * $randomNumB2inZroAndVarTime;
  576. };
  577. } else {
  578. $r->{rndmTm} = $randomNumB2inZroAndVarTime;
  579. };
  580. # Add +/- 0 to $r->{varTm} amount of variation, with main $r->{rptTm} :
  581. $r->{rndmTm} = int( abs( $r->{rndmTm} + abs( $r->{rptTm} ) ));
  582. return Xchat::EAT_NONE;
  583. } # END of sub variate_repeat_time
  584.  
  585.  
  586. # summary/short form : my($enabled) = 0; my($hookPoint) = 0; my($variableTime) = 10000; my($randomTime) = $variableTime; Xchat::hook_command("REPEAT", sub{ my($t)=0; if ($_[0][1] eq 'on') { $enabled=1; Xchat::unhook($hookPoint); &start_timer();}; if ($_[0][1] eq 'off') { Xchat::unhook($hookPoint); $enabled=0;}; $t=int(0 + $_[0][2]); if ($_[0][1] eq 'variableTime' and $t >= 2) { $variableTime = int($t * 1000);}; return Xchat::EAT_ALL;}); sub call_and_do_something { my_codes_which_needed_to_be_repeated(); if ($enabled) { \&start_timer();}; } sub start_timer { Xchat::unhook($hookPoint); variate_time(); if ($enabled) { $hookPoint = Xchat::hook_timer ( int($randomTime) , \&call_and_do_something );}; return Xchat::EAT_NONE; } sub variate_time { my($rT) = rand($variableRandomTime * 0.4); $randomTime = $variableTime; if(rand(1)){ $randomTime = $randomTime+$rT;} else{ $randomTime = $randomTime-$rT;}; return Xchat::EAT_NONE; }
Advertisement
Add Comment
Please, Sign In to add comment