File: commandqueues

package info (click to toggle)
epic5 3.0.3-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 5,328 kB
  • sloc: ansic: 75,810; makefile: 648; ruby: 227; python: 215; sh: 78; perl: 13
file content (197 lines) | stat: -rw-r--r-- 6,037 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
if (word(2 $loadinfo()) != [pf]) { load -pf $word(1 $loadinfo()); return; };

# All these aliases take commands as arguments and have the property that
# they will not exand those commands prior to execution, making them safe.
#
# This may require some explanation:
#
# The ircii language has the concept of "expansion", whereby variable
# references are replaced with the variable values and escaped characters
# are unescaped.  This is one of the side effects of an eval.  In the
# following two commands, if entered from the command line, the first will
# whois the nick "\\`anderer", and the second will whois "\`anderer",
# because the eval will unescape it.
#
#  /whois \\`anderer
#  /eval whois \\`anderer
#
# This is from the command line.  If these commands are executed from an
# alias, the first command will whois "\`anderer", and the second will
# whois "`anderer".  This is because commands within an alias are always
# expanded prior to execution.  There is no way to stop this, but you can
# control it by passing a variable to the whois command instead of the raw
# text.  Since expansion only occurs once, the variables expansion will
# "shelter" the text from being expanded.
#
# If you wish to add more levels of expansion, you use more evals.  If you
# wish to have _no_ expansion, you keep all your text in variables, and
# avoid using eval.
#
# It is easy to see that there may be occasions where you may want to whois
# someone from within a hook without having to worry about expansion.  This
# is easy enough.  /whois does not expand its arguments, however, hooks can
# generate floods, so you put the whois in a timer say.  The problem with
# this is that /timer _does_ expand its arguments, so you end up with an
# extra level of expansion to deal with.
#
# These aliases solve these problems.  Commands are given as arguments and
# are normally not expanded, just as if they had been given to a built in
# command.  If you wish to have them expanded when they are run, precede
# them with /eval, or use a /timer or a /queue instead.

package qcmd;

#
# Synonym for /timer, but which doesn't expand args.
#
# This is less than perfect and will break if numbers are used for commands.
#
alias timer.ue (args) {
	while (word(0 $args) =~ [-*]) {
		push :pre $shift(args);
		if (isnumber(b10 $word(1 $args))) {
			push :pre $shift(args);
		};
	};
	timer $pre $shift(args) \$decode\($encode($args)\);
};

#
# Usage:
#  scmd [server [command]]
#
# Execute command on server _without_ expanding command.
#
alias scmd (args) fe ($split(, $shift(args))) serv {
	xeval -s $serv -w $serverwin($serv) {$args};
};

#
# Usage:
#  1cmd [time,reset [command]]
#
# command will not be executed if the same command has been executed in
# the last time seconds.
#
# The time of the last execution of the command will be set to the current time
# if it was executed, or if the last execution was less than "reset" seconds
# ago.  This is useful for riding events which occur in waves.
#
alias 1cmd (sec,cmd) {
	@ :foo = encode($tolower($cmd));
	@ :time = time();
	@ :eserv = 0 > servernum() ? [] : servernum();
	@ :reset = split(, $sec);
	@ :sec = shift(reset);
	@ :reset = shift(reset);
	if (!sec) {
		$cmd;
		return;
	} elsif (time - onecmd[$eserv][$foo][t] <= reset) {
		@ onecmd[$eserv][$foo][e] = time + sec;
		@ onecmd[$eserv][$foo][t] = time;
	} elsif (time - onecmd[$eserv][$foo][t] >= sec) {
		@ onecmd[$eserv][$foo][e] = time + sec;
		@ onecmd[$eserv][$foo][t] = time;
		$cmd;
	};
	if (time != onecmd[$eserv][lp] && !(++onecmd[$eserv][cnt] % 10)) {
		@ onecmd[$eserv] = time;
		foreach onecmd[$eserv] bar {
			if (onecmd[$eserv][$bar][e] < time) {
				@ onecmd[$eserv][$bar][t] = [];
				@ onecmd[$eserv][$bar][e] = [];
			};
		};
	};
};

#
# Usage:
#  qcmd [queue [command]]
#  fqcmd [queue [command]]
#
# Queue command, and schedule a timer for later execution.  Prevents flooding.
# fqcmd adds the command to the beginning of the queue instead of the end.
#
#  q1cmd [time [queue [command]]]
#  fq1cmd [time [queue [command]]]
#
# The same as "1cmd {time} qcmd {queue} {command}", only, the command also
# won't be scheduled if the same command is already scheduled.
#
# Also, with [f]q1cmd, you can specify a coma separated list of queues for
# the second argument.  All these queues will be searched for duplicates but
# the first will be the queue given to qcmd.
#
stack push alias alias.tt;
alias alias.tt (cmd,op,args) {
	@ sar(gr/\${cmd}/${cmd}/args);
	@ sar(gr/\${op}/${op}/args);
	alias $args;
};
fe (q push fq unshift) cmd op {
	alias.tt $cmd $op ${cmd}1cmd (qo,qc,args) {
		@ :oxd = xdebug(dword);
		xdebug dword;
		@ :sn = servernum();
		@ :sn = sn < 0 ? [_] : sn;
		@ :argz = args;
		#@ sar(gr/\\/\\\\/argz);
		#@ sar(gr/\"/\\\"/argz);
		@ :qc = split(, $qc);
		fe ($qc) qqcc {
			if (0 <= findw("$argz" $qcmd[$sn][$qqcc])) {
				xdebug $oxd;
				return;
			};
		};
		xdebug -dword;
		1cmd $qo ${cmd}cmd $shift(qc) $args;
		xdebug $oxd;
	};
	alias.tt $cmd $op ${cmd}cmd {
		@ :oxd = xdebug(dword);
		@ :sn = servernum();
		@ :sn = sn < 0 ? [_] : sn;
		xdebug dword;
		if (1 < #) {
			@ :foo = [$1-];
			#@ :foo = ${op}(qcmd.${sn}.$0 "$msar(gr/\\/\\\\/\"/\\\"/foo)");
			@ :foo = ${op}(qcmd.${sn}.$0 $foo);
		} else {
			if (1 == #) {
				@ :foo = [qcmd.${sn}.$0];
				@ :foo = aliasctl(assign match $foo);
				@ :foo = shift(foo);
				@ :foo = after(2 . $foo);
			} elsif (islagged()) {
				@ :bar = [ ];
				# Do nothing if we're lagged.
				# This is meant to be a link to a
				# fictitious lag measurement script.
			} elsif (0 == #) {
				foreach qcmd[$sn] bar {
					@ :foo = bar;
					break;
				};
			};
			@ :bar = shift(qcmd[$sn][$foo]);
		};
		xdebug $oxd;
		if (functioncall()) {
			#return $msar(gr/\\\\/\\/\\\"/\"/bar);
			return $msar(gr/\\\"/\"/bar);
			#return $bar;
		} elsif (@bar) {
			#$msar(gr/\\\\/\\/\\\"/\"/bar);
			$msar(gr/\\\"/\"/bar);
			#$bar;
			^timer -ref qcmd.$sn -update 5 qcmd;
		} elsif (@foo) {
			^timer -ref qcmd.$sn 5 qcmd;
		};
	};
};
stack pop alias alias.tt;