Utilities.PM - Enable the range numbers in (?:auto|)macroopenkore - Revision 6696: /plugins/macro/trunk
Code: Select all
--- https://openkore.svn.sourceforge.net/svnroot/openkore/plugins/macro/trunk/Macro/Utilities.pm	Wed May 20 12:10:04 2009
+++ C:/.../plugins/Macro/Utilities.pm	My working copy
@@ -64,6 +64,28 @@
 		return 0
 	}
 
+	if ($a =~ /^\s*(-?[\d.]+)\s*\.{2}\s*(-?[\d.]+)\s*$/) {
+		my ($a1, $a2) = ($1, $2);
+		if ($b =~ /^-?[\d.]+$/) {
+			if ($cond eq "!=") {return 1 unless $a1 <= $b && $b <= $a2}
+			if ($cond eq "=" || $cond eq "==" || $cond eq "=~" || $cond eq "~") {
+				return 1 if $a1 <= $b && $b <= $a2
+			}
+		}
+		return 0
+	}
+
+	if ($b =~ /^\s*(-?[\d.]+)\s*\.{2}\s*(-?[\d.]+)\s*$/) {
+		my ($b1, $b2) = ($1, $2);
+		if ($a =~ /^-?[\d.]+$/) {
+			if ($cond eq "!=") {return 1 unless $b1 <= $a && $a <= $b2}
+			if ($cond eq "=" || $cond eq "==" || $cond eq "=~" || $cond eq "~") {
+				return 1 if $b1 <= $a && $a <= $b2
+			}
+		}
+		return 0
+	}
+
 	if ($a =~ /^-?[\d.]+$/ && $b =~ /^-?[\d.]+$/) {
 		if (($cond eq "=" || $cond eq "==") && $a == $b) {return 1}
 		if ($cond eq ">=" && $a >= $b) {return 1}
@@ -80,6 +102,7 @@
 		$a = lc($a);
 		foreach my $e (split(/,/, $b)) {return 1 if $a eq lc($e)}
 	}
+
 	return 0
 }
 
@@ -396,4 +419,4 @@
 	}
 }
 
-1;
\ No newline at end of file
+1;Script.PM - Vision: Perl-A-Like Macro Script
Code: Select all
--- https://openkore.svn.sourceforge.net/svnroot/openkore/plugins/macro/trunk/Macro/Script.pm	Wed May 20 12:09:38 2009
+++ C:/.../plugins/Macro/Script.pm	My working copy
@@ -1,3 +1,4 @@
+# ezza's Latest Patch: 04/06/2009 @ 12:00pm
 # $Id: Script.pm 5939 2007-08-29 12:09:28Z arachnophobia $
 package Macro::Script;
 
@@ -13,37 +14,49 @@
 use Macro::Parser qw(parseCmd);
 use Macro::Utilities qw(cmpr);
 use Macro::Automacro qw(releaseAM lockAM);
-use Log qw(message);
+use Log qw(message warning);
 
 our ($rev) = q$Revision: 5939 $ =~ /(\d+)/;
 
 # constructor
 sub new {
-	my ($class, $name, $repeat) = @_;
+	my ($class, $name, $repeat, $lastname, $lastline) = @_;
 	$repeat = 0 unless ($repeat && $repeat =~ /^\d+$/);
 	return unless defined $macro{$name};
 	my $self = {
-		name => $name,
-		registered => 0,
-		submacro => 0,
-		macro_delay => $timeout{macro_delay}{timeout},
-		timeout => 0,
-		time => time,
-		finished => 0,
-		overrideAI => 0,
-		line => 0,
-		label => {scanLabels($macro{$name})},
-		repeat => $repeat,
-		subcall => undef,
-		error => undef,
-		orphan => $::config{macro_orphans},
-		interruptible => 1,
-		macro_block => 0
+			name => $name,
+			lastname => undef,
+			registered => 0,
+			submacro => 0,
+			macro_delay => $timeout{macro_delay}{timeout},
+			timeout => 0,
+			mainline_delay => undef,
+			subline_delay => undef,
+			result => undef,
+			time => time,
+			finished => 0,
+			overrideAI => 0,
+			line => 0,
+			lastline => undef,
+			label => {scanLabels($macro{$name})},
+			repeat => $repeat,
+			subcall => undef,
+			error => undef,
+			orphan => $::config{macro_orphans},
+			interruptible => 1,
+			macro_block => 0
+
 	};
+	if (defined $lastname && defined $lastline) {
+		$self->{lastname} = $lastname;
+		$self->{lastline} = $lastline;
+		$self->{interruptible} = 0;
+	}
 	bless ($self, $class);
 	return $self
 }
 
+
 # destructor
 sub DESTROY {
 	AI::clear('macro') if (AI::inQueue('macro') && !$_[0]->{submacro})
@@ -164,37 +177,36 @@
 		$self->{error} = $self->{subcall}->{error};
 		return
 	}
+	if (defined $self->{mainline_delay} && defined $self->{subline_delay}) {$self->{line} = $self->{mainline_delay}}
 	my $line = ${$macro{$self->{name}}}[$self->{line}];
 	if (!defined $line) {
-		if ($self->{repeat} > 1) {
-			$self->{repeat}--;
-			$self->{line} = 0
-		} else {
-			$self->{finished} = 1
+		if (defined $self->{lastname} && defined $self->{lastline}) {
+			$self->{line} = $self->{lastline} + 1;
+			$self->{name} = $self->{lastname};
+			$line = ${$macro{$self->{name}}}[$self->{line}];
+			($self->{lastline}, $self->{lastname}) = undef
 		}
-		return ""
+		else {
+			if ($self->{repeat} > 1) {$self->{repeat}--; $self->{line} = 0}
+			else {$self->{finished} = 1}
+			return ""
+		}
 	}
-
+	
 	my $errtpl = "error in ".$self->{line};
 	##########################################
 	# jump to label: goto label
 	if ($line =~ /^goto\s/) {
 		my ($tmp) = $line =~ /^goto\s+([a-zA-Z][a-zA-Z\d]*)/;
-		if (exists $self->{label}->{$tmp}) {
-			$self->{line} = $self->{label}->{$tmp}
-		} else {
-			$self->{error} = "$errtpl: cannot find label $tmp"
-		}
+		if (exists $self->{label}->{$tmp}) {$self->{line} = $self->{label}->{$tmp}}
+		else {$self->{error} = "$errtpl: cannot find label $tmp"}
 		$self->{timeout} = 0
 	##########################################
 	# declare block ending: end label
 	} elsif ($line =~ /^end\s/) {
 		my ($tmp) = $line =~ /^end\s+(.*)/;
-		if (exists $self->{label}->{$tmp}) {
-			$self->{line} = $self->{label}->{$tmp}
-		} else {
-			$self->{error} = "$errtpl: cannot find block start for $tmp"
-		}
+		if (exists $self->{label}->{$tmp}) {$self->{line} = $self->{label}->{$tmp}}
+		else {$self->{error} = "$errtpl: cannot find block start for $tmp"}
 		$self->{timeout} = 0
 	##########################################
 	# macro block: begin
@@ -209,112 +221,102 @@
 		$self->{line}++
 	##########################################
 	# if statement: if (foo = bar) goto label?
+	# Unlimited If Statement by: ezza @ http://forums.openkore.com/
 	} elsif ($line =~ /^if\s/) {
-		my ($first, $cond, $last, $then) = $line =~ /^if\s+\(\s*"?(.*?)"?\s+([<>=!~]+?)\s+"?(.*?)"?\s*\)\s+(.*)/;
-		if (!defined $first || !defined $cond || !defined $last || !defined $then || $then !~ /^(?:goto\s|stop)/) {
-			$self->{error} = "$errtpl: syntax error in if statement"
-		} else {
-			my $pfirst = parseCmd($first); my $plast = parseCmd($last);
-			unless (defined $pfirst && defined $plast) {
-				$self->{error} = "$errtpl: either '$first' or '$last' has failed"
-			} elsif (cmpr($pfirst, $cond, $plast)) {
-				if ($then =~ /^goto\s/) {
-					my ($tmp) = $then =~ /^goto\s+([a-zA-Z][a-zA-Z\d]*)$/;
-					if (exists $self->{label}->{$tmp}) {
-						$self->{line} = $self->{label}->{$tmp}
-					} else {
-						$self->{error} = "$errtpl: cannot find label $tmp"
-					}
-				} elsif ($then eq "stop") {
-					$self->{finished} = 1
-				}
-			} else {
-				$self->{line}++
-			}
-		}
+		my ($text, $then) = $line =~ /^if\s\(\s*(.*)\s*\)\s+(goto\s+.*|call\s+.*|stop)\s*/;
+
+		# The main trick is parse all the @special keyword and vars 1st,
+		$text = parseCmd($text);
+		my $savetxt = particle($text, $self, $errtpl);
+		if (multi($savetxt, $self, $errtpl)) {newThen($then, $self, $errtpl)}
+
+		$self->{line}++;
 		$self->{timeout} = 0
+
 	##########################################
 	# while statement: while (foo <= bar) as label
 	} elsif ($line =~ /^while\s/) {
 		my ($first, $cond, $last, $label) = $line =~ /^while\s+\(\s*"?(.*?)"?\s+([<>=!]+?)\s+"?(.*?)"?\s*\)\s+as\s+(.*)/;
-		if (!defined $first || !defined $cond || !defined $last || !defined $label) {
-			$self->{error} = "$errtpl: syntax error in while statement"
-		} else {
+		if (!defined $first || !defined $cond || !defined $last || !defined $label) {$self->{error} = "$errtpl: syntax error in while statement"}
+		else {
 			my $pfirst = parseCmd($first); my $plast = parseCmd($last);
-			unless (defined $pfirst && defined $plast) {
-				$self->{error} = "$errtpl: either '$first' or '$last' has failed"
-			} elsif (!cmpr($pfirst, $cond, $plast)) {
-				$self->{line} = $self->{label}->{"end ".$label}
-			}
+			unless (defined $pfirst && defined $plast) {$self->{error} = "$errtpl: either '$first' or '$last' has failed"}
+			elsif (!cmpr($pfirst, $cond, $plast)) {$self->{line} = $self->{label}->{"end ".$label}}
 			$self->{line}++
 		}
 		$self->{timeout} = 0
 	##########################################
 	# pop value from variable: $var = [$list]
 	} elsif ($line =~ /^\$[a-z][a-z\d]*\s+=\s+\[\s*\$[a-z][a-z\d]*\s*\]$/i) {
-		my ($var, $list) = $line =~ /^\$([a-z][a-z\d]*?)\s+=\s+\[\s*\$([a-z][a-z\d]*?)\s*\]$/i;
-		my $listitems = ($varStack{$list} or "");
-		my $val;
-		if (($val) = $listitems =~ /^(.*?)(?:,|$)/) {
-			$listitems =~ s/^(?:.*?)(?:,|$)//;
-			$varStack{$list} = $listitems
-		} else {
-			$val = $listitems
+		if ($line =~ /;/) {run_sublines($line, $self)}
+		else {
+			my ($var, $list) = $line =~ /^\$([a-z][a-z\d]*?)\s+=\s+\[\s*\$([a-z][a-z\d]*?)\s*\]$/i;
+			my $listitems = ($varStack{$list} or "");
+			my $val;
+			if (($val) = $listitems =~ /^(.*?)(?:,|$)/) {
+				$listitems =~ s/^(?:.*?)(?:,|$)//;
+				$varStack{$list} = $listitems
+			}
+			else {$val = $listitems}
+			$varStack{$var} = $val;
 		}
-		$varStack{$var} = $val;
 		$self->{line}++;
-		$self->{timeout} = 0;
+		$self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+		return $self->{result} if $self->{result}
 	##########################################
 	# set variable: $variable = value
 	} elsif ($line =~ /^\$[a-z]/i) {
 		my ($var, $val);
-		if (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)\s+=\s+(.*)/i) {
-			my $pval = parseCmd($val);
-			if (defined $pval) {$varStack{$var} = $pval}
-			else {$self->{error} = "$errtpl: $val failed"}
-		} elsif (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)([+-]{2})$/i) {
-			if ($val eq '++') {
-				$varStack{$var} = ($varStack{$var} or 0)+1
-			} else {
-				$varStack{$var} = ($varStack{$var} or 0)-1
+		if ($line =~ /;/) {run_sublines($line, $self)} 
+		else {
+			if (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)\s+=\s+(.*)/i) {
+				my $pval = parseCmd($val);
+				if (defined $pval) {
+					if ($pval =~ /^\s*(?:undef|unset)\s*$/i && exists $varStack{$var}) {undef $varStack{$var}}
+					else {$varStack{$var} = $pval}
+				}
+				else {$self->{error} = "$errtpl: $val failed"}
 			}
-		} else {
-			$self->{error} = "$errtpl: unrecognized assignment"
+			elsif (($var, $val) = $line =~ /^\$([a-z][a-z\d]*?)([+-]{2})$/i) {
+				if ($val eq '++') {$varStack{$var} = ($varStack{$var} or 0)+1}
+				else {$varStack{$var} = ($varStack{$var} or 0)-1}
+			}
+			else {$self->{error} = "$errtpl: unrecognized assignment"}
 		}
 		$self->{line}++;
-		$self->{timeout} = 0
+		$self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+		return $self->{result} if $self->{result}
 	##########################################
 	# set doublevar: ${$variable} = value
 	} elsif ($line =~ /^\$\{\$[.a-z]/i) {
 		my ($dvar, $val);
-		if (($dvar, $val) = $line =~ /^\$\{\$([.a-z][a-z\d]*?)\}\s+=\s+(.*)/i) {
-			my $var = $varStack{$dvar};
-			unless (defined $var) {
-				$self->{error} = "$errtpl: $dvar not defined"
-			} else {
-				my $pval = parseCmd($val);
-				unless (defined $pval) {
-					$self->{error} = "$errtpl: $val failed"
-				} else {
-					$varStack{"#$var"} = parseCmd($val)
+		if ($line =~ /;/) {run_sublines($line, $self)}
+		else {
+			if (($dvar, $val) = $line =~ /^\$\{\$([.a-z][a-z\d]*?)\}\s+=\s+(.*)/i) {
+				my $var = $varStack{$dvar};
+				unless (defined $var) {$self->{error} = "$errtpl: $dvar not defined"}
+				else {
+					my $pval = parseCmd($val);
+					unless (defined $pval) {$self->{error} = "$errtpl: $val failed"}
+					else {
+						if ($pval =~ /^\s*(?:undef|unset)\s*$/i) {undef $varStack{"#$var"}}
+						else {$varStack{"#$var"} = $pval}
+					}
 				}
 			}
-		} elsif (($dvar, $val) = $line =~ /^\$\{\$([.a-z][a-z\d]*?)\}([+-]{2})$/i) {
-			my $var = $varStack{$dvar};
-			unless (defined $var) {
-				$self->{error} = "$errtpl: $dvar undefined"
-			} else {
-				if ($val eq '++') {
-					$varStack{"#$var"} = ($varStack{"#$var"} or 0)+1
-				} else {
-					$varStack{"#$var"} = ($varStack{"#$var"} or 0)-1
+			elsif (($dvar, $val) = $line =~ /^\$\{\$([.a-z][a-z\d]*?)\}([+-]{2})$/i) {
+				my $var = $varStack{$dvar};
+				unless (defined $var) {$self->{error} = "$errtpl: $dvar undefined"}
+				else {
+					if ($val eq '++') {$varStack{"#$var"} = ($varStack{"#$var"} or 0)+1}
+					else {$varStack{"#$var"} = ($varStack{"#$var"} or 0)-1}
 				}
 			}
-		} else {
-			$self->{error} = "$errtpl: unrecognized assignment."
+			else {$self->{error} = "$errtpl: unrecognized assignment."}
 		}
 		$self->{line}++;
-		$self->{timeout} = 0
+		$self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+		return $self->{result} if $self->{result}
 	##########################################
 	# label definition: :label
 	} elsif ($line =~ /^:/) {
@@ -323,59 +325,60 @@
 	##########################################
 	# returns command: do whatever
 	} elsif ($line =~ /^do\s/) {
-		my ($tmp) = $line =~ /^do\s+(.*)/;
-		if ($tmp =~ /^macro\s+/) {
-			my ($arg) = $tmp =~ /^macro\s+(.*)/;
-			if ($arg =~ /^reset/) {
-				$self->{error} = "$errtpl: use 'release' instead of 'macro reset'"
-			} elsif ($arg eq 'pause' || $arg eq 'resume') {
-				$self->{error} = "$errtpl: do not use 'macro pause' or 'macro resume' within a macro"
-			} elsif ($arg =~ /^set\s/) {
-				$self->{error} = "$errtpl: do not use 'macro set'. Use \$foo = bar"
-			} elsif ($arg eq 'stop') {
-				$self->{error} = "$errtpl: use 'stop' instead"
-			} elsif ($arg !~ /^(?:list|status)$/) {
-				$self->{error} = "$errtpl: use 'call $arg' instead of 'macro $arg'"
+		if ($line =~ /;/ && $line =~ /^do eval/ eq "") {
+			run_sublines($line, $self);
+			unless (defined $self->{mainline_delay} && defined $self->{subline_delay}) {$self->{timeout} = $self->{macro_delay}; $self->{line}++}
+			if ($self->{result}) {return $self->{result}}
+		}
+		else {
+			my ($tmp) = $line =~ /^do\s+(.*)/;
+			if ($tmp =~ /^macro\s+/) {
+				my ($arg) = $tmp =~ /^macro\s+(.*)/;
+				if ($arg =~ /^reset/) {$self->{error} = "$errtpl: use 'release' instead of 'macro reset'"}
+				elsif ($arg eq 'pause' || $arg eq 'resume') {$self->{error} = "$errtpl: do not use 'macro pause' or 'macro resume' within a macro"}
+				elsif ($arg =~ /^set\s/) {$self->{error} = "$errtpl: do not use 'macro set'. Use \$foo = bar"}
+				elsif ($arg eq 'stop') {$self->{error} = "$errtpl: use 'stop' instead"}
+				elsif ($arg !~ /^(?:list|status)$/) {$self->{error} = "$errtpl: use 'call $arg' instead of 'macro $arg'"}
 			}
-		} elsif ($tmp =~ /^ai\s+clear$/) {
-			$self->{error} = "$errtpl: do not mess around with ai in macros"
+			elsif ($tmp =~ /^ai\s+clear$/) {$self->{error} = "$errtpl: do not mess around with ai in macros"}
+			return if defined $self->{error};
+			my $result = parseCmd($tmp);
+			unless (defined $result) {$self->{error} = "$errtpl: command $tmp failed";return}
+			$self->{timeout} = $self->{macro_delay};
+			$self->{line}++;
+			return $result
 		}
-		return if defined $self->{error};
-		my $result = parseCmd($tmp);
-		unless (defined $result) {
-			$self->{error} = "$errtpl: command $tmp failed";
-			return
-		}
-		$self->{line}++;
-		$self->{timeout} = $self->{macro_delay};
-		return $result
 	##########################################
 	# log command
 	} elsif ($line =~ /^log\s+/) {
-		my ($tmp) = $line =~ /^log\s+(.*)/;
-		my $result = parseCmd($tmp);
-		unless (defined $result) {
-			$self->{error} = "$errtpl: $tmp failed"
-		} else {
-			message "[macro][log] $result\n", "macro";
+		if ($line =~ /;/) {run_sublines($line, $self)}
+		else {
+			my ($tmp) = $line =~ /^log\s+(.*)/;
+			my $result = parseCmd($tmp);
+			unless (defined $result) {$self->{error} = "$errtpl: $tmp failed"}
+			else {message "[macro log] $result\n", "macro";}
 		}
 		$self->{line}++;
-		$self->{timeout} = $self->{macro_delay}
+		$self->{timeout} = $self->{macro_delay} unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+		return $self->{result} if $self->{result}
 	##########################################
 	# pause command
 	} elsif ($line =~ /^pause/) {
-		my ($tmp) = $line =~ /^pause\s*(.*)/;
-		if (defined $tmp) {
-			my $result = parseCmd($tmp);
-			unless (defined $result) {
-				$self->{error} = "$errtpl: $tmp failed"
-			} else {
-				$self->{timeout} = $result
+		if ($line =~ /;/) {
+			run_sublines($line, $self);
+			$self->{timeout} = $self->{macro_delay} unless defined $self->{mainline_delay} && defined $self->{subline_delay}
+		}
+		else {
+			my ($tmp) = $line =~ /^pause\s*(.*)/;
+			if (defined $tmp) {
+				my $result = parseCmd($tmp);
+				unless (defined $result) {$self->{error} = "$errtpl: $tmp failed"}
+				else {$self->{timeout} = $result}
 			}
-		} else {
-			$self->{timeout} = $self->{macro_delay}
+			else {$self->{timeout} = $self->{macro_delay}}
 		}
-		$self->{line}++
+		$self->{line}++;
+		return $self->{result} if $self->{result}
 	##########################################
 	# stop command
 	} elsif ($line eq "stop") {
@@ -383,21 +386,27 @@
 	##########################################
 	# release command
 	} elsif ($line =~ /^release\s+/) {
-		my ($tmp) = $line =~ /^release\s+(.*)/;
-		if (!releaseAM(parseCmd($tmp))) {
-			$self->{error} = "$errtpl: releasing $tmp failed"
+		if ($line =~ /;/) {run_sublines($line, $self)}
+		else {
+			my ($tmp) = $line =~ /^release\s+(.*)/;
+			if (!releaseAM(parseCmd($tmp))) {
+				$self->{error} = "$errtpl: releasing $tmp failed"
+			}
 		}
 		$self->{line}++;
-		$self->{timeout} = 0
+		$self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+		return $self->{result} if $self->{result}
 	##########################################
 	# lock command
 	} elsif ($line =~ /^lock\s+/) {
-		my ($tmp) = $line =~ /^lock\s+(.*)/;
-		if (!lockAM(parseCmd($tmp))) {
-			$self->{error} = "$errtpl: locking $tmp failed"
+		if ($line =~ /;/) {run_sublines($line, $self)}
+		else {
+			my ($tmp) = $line =~ /^lock\s+(.*)/;
+			if (!lockAM(parseCmd($tmp))) {$self->{error} = "$errtpl: locking $tmp failed"}
 		}
 		$self->{line}++;
-		$self->{timeout} = 0
+		$self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+		return $self->{result} if $self->{result}
 	##########################################
 	# call command
 	} elsif ($line =~ /^call\s+/) {
@@ -405,43 +414,426 @@
 		if ($tmp =~ /\s/) {
 			my ($name, $times) = $tmp =~ /(.*?)\s+(.*)/;
 			my $ptimes = parseCmd($times);
-			if (defined $ptimes) {
-				$self->{subcall} = new Macro::Script($name, $ptimes)
-			}
-		} else {
-			$self->{subcall} = new Macro::Script($tmp)
+			if (defined $ptimes && $ptimes =~ /\d+/) {$self->{subcall} = new Macro::Script($name, $ptimes)}
+			else {$self->{subcall} = new Macro::Script($name)}
 		}
-		unless (defined $self->{subcall}) {
-			$self->{error} = "$errtpl: failed to call script"
-		} else {
+		else {$self->{subcall} = new Macro::Script($tmp)}
+		unless (defined $self->{subcall}) {$self->{error} = "$errtpl: failed to call script"}
+		else {
 			$self->{subcall}->regSubmacro;
 			$self->{timeout} = $self->{macro_delay}
 		}
 	##########################################
 	# set command
 	} elsif ($line =~ /^set\s+/) {
-		my ($var, $val) = $line =~ /^set\s+(\w+)\s+(.*)$/;
-		if ($var eq 'macro_delay' && $val =~ /^[\d\.]*\d+$/) {
-			$self->{macro_delay} = $val
-		} elsif ($var eq 'repeat' && $val =~ /^\d+$/) {
-			$self->{repeat} = $val
-		} elsif ($var eq 'overrideAI' && $val =~ /^[01]$/) {
-			$self->{overrideAI} = $val
-		} elsif ($var eq 'exclusive' && $val =~ /^[01]$/) {
-			$self->{interruptible} = $val?0:1
-		} elsif ($var eq 'orphan' && $val =~ /^(?:terminate|reregister(?:_safe)?)$/) {
-			$self->{orphan} = $val
-		} else {
-			$self->{error} = "$errtpl: unrecognized key or wrong value"
+		if ($line =~ /;/) {run_sublines($line, $self)}
+		else {
+			my ($var, $val) = $line =~ /^set\s+(\w+)\s+(.*)$/;
+			if ($var eq 'macro_delay' && $val =~ /^[\d\.]*\d+$/) {
+				$self->{macro_delay} = $val
+			} elsif ($var eq 'repeat' && $val =~ /^\d+$/) {
+				$self->{repeat} = $val
+			} elsif ($var eq 'overrideAI' && $val =~ /^[01]$/) {
+				$self->{overrideAI} = $val
+			} elsif ($var eq 'exclusive' && $val =~ /^[01]$/) {
+				$self->{interruptible} = $val?0:1
+			} elsif ($var eq 'orphan' && $val =~ /^(?:terminate|reregister(?:_safe)?)$/) {
+				$self->{orphan} = $val
+			} else {
+				$self->{error} = "$errtpl: unrecognized key or wrong value"
+			}
 		}
 		$self->{line}++;
-		$self->{timeout} = 0
+		$self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+		return $self->{result} if $self->{result}
 	##########################################
+	# sub-routine command, still figuring out how to include unclever/fail sub-routine into the error msg
+	} elsif ($line =~ /^(?:\w+)\s*\(.*?\)/) {
+		if ($line =~ /;/) {run_sublines($line, $self)}
+		else {
+			my ($sub) = $line =~ /^(\w+)\s*\(.*?\)$/;
+			my $sub_error = 1;
+			foreach my $e (@macro_block) {if ($e eq $sub) {$sub_error = 0; parseCmd($line)}}
+			$self->{error} = "$errtpl: sub-routine $sub in --> $line <-- not found!!!" if $sub_error;
+		}
+		$self->{line}++;
+		$self->{timeout} = 0 unless defined $self->{mainline_delay} && defined $self->{subline_delay};
+		return $self->{result} if $self->{result}
+	##########################################
 	# unrecognized line
 	} else {
 		$self->{error} = "$errtpl: syntax error"
 	}
+	
 	if (defined $self->{error}) {return} else {return ""}
 }
 
+
+sub run_sublines {
+	my ($real_line, $self) = @_;
+	my ($i, $real_num, @sub_line) = (0, $self->{line}, undef);
+	my @split = split(/\s*;\s*/, $real_line);
+	my ($dvar, $var, $val, $list);
+	
+	foreach my $e (@split) {
+		next if $e eq "";
+		if (defined $self->{subline_delay} && $i < $self->{subline_delay}) {$i++; next}
+		if (defined $self->{subline_delay} && $i == $self->{subline_delay}) {
+			$self->{timeout} = 0;
+			($self->{mainline_delay}, $self->{subline_delay}, $self->{result}) = undef;
+			$i++; next
+		}
+		
+		##########################################
+		# pop value from variable: $var = [$list]
+		if ($e =~ /^\$[a-z][a-z\d]*\s+=\s+\[\s*\$[a-z][a-z\d]*\s*\]$/i) {
+			($var, $list) = $e =~ /^\$([a-z][a-z\d]*?)\s+=\s+\[\s*\$([a-z][a-z\d]*?)\s*\]$/i;
+			my $listitems = ($varStack{$list} or "");
+			if (($val) = $listitems =~ /^(.*?)(?:,|$)/) {
+				$listitems =~ s/^(?:.*?)(?:,|$)//;
+				$varStack{$list} = $listitems
+			}
+			else {$val = $listitems}
+			$varStack{$var} = $val;
+			$i++; next
+				
+		# set variable: $variable = value
+		} elsif ($e =~ /^\$[a-z]/i) {
+			if (($var, $val) = $e =~ /^\$([a-z][a-z\d]*?)\s+=\s+(.*)/i) {
+				my $pval = parseCmd($val);
+				if (defined $pval) {
+					if ($pval =~ /^\s*(?:undef|unset)\s*$/i && exists $varStack{$var}) {undef $varStack{$var}}
+					else {$varStack{$var} = $pval}
+				}
+				else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $e failed"; last}
+			}
+			elsif (($var, $val) = $e =~ /^\$([a-z][a-z\d]*?)([+-]{2})$/i) {
+				if ($val eq '++') {$varStack{$var} = ($varStack{$var} or 0)+1} else {$varStack{$var} = ($varStack{$var} or 0)-1}
+			}
+			else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: unrecognized assignment in ($e)"; last}
+			$i++; next
+				
+		# set doublevar: ${$variable} = value
+		} elsif ($e =~ /^\$\{\$[.a-z]/i) {
+			if (($dvar, $val) = $e =~ /^\$\{\$([.a-z][a-z\d]*?)\}\s+=\s+(.*)/i) {
+				$var = $varStack{$dvar};
+				unless (defined $var) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $dvar not defined in ($e)"; last}
+				else {
+					my $pval = parseCmd($val);
+					unless (defined $pval) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $e failed"; last}
+					else {
+						if ($pval =~ /^\s*(?:undef|unset)\s*$/i) {undef $varStack{"#$var"}}
+						else {$varStack{"#$var"} = $pval}
+					}
+				}
+			}
+			elsif (($dvar, $val) = $e =~ /^\$\{\$([.a-z][a-z\d]*?)\}([+-]{2})$/i) {
+				$var = $varStack{$dvar};
+				unless (defined $var) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: undefined $dvar in ($e)"; last}
+				else {if ($val eq '++') {$varStack{"#$var"} = ($varStack{"#$var"} or 0)+1} else {$varStack{"#$var"} = ($varStack{"#$var"} or 0)-1}}
+				$i++; next
+			}
+			else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: unrecognized assignment in ($e)"; last}
+			$i++; next
+				
+		# stop command
+		} elsif ($e eq "stop") {
+			$self->{finished} = 1; last
+		
+		# set command
+		} elsif (($var, $val) = $e =~ /^set\s+(\w+)\s+(.*)$/) {
+			if ($var eq 'macro_delay' && $val =~ /^[\d\.]*\d+$/) {$self->{macro_delay} = $val}
+			elsif ($var eq 'repeat' && $val =~ /^\d+$/) {$self->{repeat} = $val}
+			elsif ($var eq 'overrideAI' && $val =~ /^[01]$/) {$self->{overrideAI} = $val}
+			elsif ($var eq 'exclusive' && $val =~ /^[01]$/) {$self->{interruptible} = $val?0:1}
+			elsif ($var eq 'orphan' && $val =~ /^(?:terminate|reregister(?:_safe)?)$/) {$self->{orphan} = $val}
+			else {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: unrecognized key or wrong value in ($e)"; last}
+				
+		# lock command
+		} elsif ($e =~ /^lock\s+/) {
+			my ($tmp) = $e =~ /^lock\s+(.*)/;
+			if (!lockAM(parseCmd($tmp))) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: locking $tmp failed in ($e)"; last}
+				
+		# release command
+		} elsif ($e =~ /^release\s+/) {
+			my ($tmp) = $e =~ /^release\s+(.*)/;
+			if (!releaseAM(parseCmd($tmp))) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: releasing $tmp failed in ($e)"; last}
+		
+		# pause command
+		} elsif ($e =~ /^pause/) {
+			my ($tmp) = $e =~ /^pause\s*(.*)/;
+			if (defined $tmp) {
+				my $result = parseCmd($tmp);
+				unless (defined $result) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $tmp failed in ($e)"; last}
+				else {$self->{timeout} = $result}
+			}
+			else {$self->{timeout} = $self->{macro_delay}}
+			$self->{mainline_delay} = $real_num;
+			$self->{subline_delay} = $i;
+			last
+		
+		# log command
+		} elsif ($e =~ /^log\s+/) {
+			my ($tmp) = $e =~ /^log\s+(.*)/;
+			my $result = parseCmd($tmp);
+			unless (defined $result) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: $tmp failed in ($e)"; last}
+			else {message "[macro log] $result\n", "macro"}
+			$self->{timeout} = $self->{macro_delay};
+			$self->{mainline_delay} = $real_num;
+			$self->{subline_delay} = $i;
+			last
+		}
+		
+		# do command
+		elsif ($e =~ /^do\s/) {
+			my ($tmp) = $e =~ /^do\s+(.*)/;
+			if ($tmp =~ /^macro\s+/) {
+				my ($arg) = $tmp =~ /^macro\s+(.*)/;
+				if ($arg =~ /^reset/) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: use 'release' instead of 'macro reset'"}
+				elsif ($arg eq 'pause' || $arg eq 'resume') {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: do not use 'macro pause' or 'macro resume' within a macro"}
+				elsif ($arg =~ /^set\s/) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: do not use 'macro set'. Use \$foo = bar"}
+				elsif ($arg eq 'stop') {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: use 'stop' instead"}
+				elsif ($arg !~ /^(?:list|status)$/) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: use 'call $arg' instead of 'macro $arg'"}
+			}
+			elsif ($tmp =~ /^eval\s+/) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: do not mix eval in the sub-line"}
+			elsif ($tmp =~ /^ai\s+clear$/) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: do not mess around with ai in macros"}
+			last if defined $self->{error};
+			my $result = parseCmd($tmp);
+			unless (defined $result) {$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: command $tmp failed"; last}
+			$self->{timeout} = $self->{macro_delay};
+			$self->{mainline_delay} = $real_num;
+			$self->{subline_delay} = $i;
+			$self->{result} = $result;
+			last
+							
+		# "call", "[", "]", ":", "if", "while", "end" and "goto" commands block
+		} elsif ($e =~ /^(?:call|\[|\]|:|if|end|goto|while)\s*/i) {
+			$self->{error} = "Line $real_num sub-line $i\n[Reason:] Use saperate line for HERE --> $e <-- HERE";
+			last
+		
+		# sub-routine 
+		} elsif (my ($sub) = $e =~ /^(\w+)\s*\(.*?\)$/) {
+			my $sub_error = 1;
+			foreach my $e (@macro_block) {if ($e eq $sub) {$sub_error = 0; parseCmd($e)}}
+			if ($sub_error)	{
+				$self->{error} = "Line $real_num sub-line $i\n[macro] $self->{name} error in sub-line $i: sub-routine $sub in --> $e <-- not found!!!";
+				last
+			}	
+		
+		##################### End ##################
+		} else {
+			#$self->{error} = "Error in line $real_num: $real_line\n[macro] $self->{name} error in sub-line $i: unrecognized assignment in ($e)"
+			message "Error in $self->{line}: $real_line\nWarning: Ignoring Unknown Command in sub-line $i: ($e)\n", "menu";
+		}
+		$i++
+	}
+}
+
+sub newThen {
+	my ($then, $self, $errtpl) = @_;
+
+	if ($then =~ /^goto\s/) {
+		my ($tmp) = $then =~ /^goto\s+([a-zA-Z][a-zA-Z\d]*)$/;
+		if (exists $self->{label}->{$tmp}) {
+			$self->{line} = $self->{label}->{$tmp}
+		}
+		else {$self->{error} = "$errtpl: cannot find label $tmp"}
+	}
+	elsif ($then =~ /^call\s+/) {
+		my ($tmp) = $then =~ /^call\s+(.*)/;
+		if ($tmp =~ /\s/) {
+			my ($name, $times) = $tmp =~ /(.*?)\s+(.*)/;
+			my $ptimes = parseCmd($times);
+			if (defined $ptimes) {
+				if ($ptimes > 1) {
+					$self->{subcall} = new Macro::Script($name, $ptimes)
+				}
+				elsif ($ptimes == 1) {
+					my $lastname = $self->{name};
+					my $lastline = $self->{line};
+					$self->{subcall} = new Macro::Script($name, $ptimes, $lastname, $lastline)
+				}
+				else {
+					$self->{subcall} = new Macro::Script($name)
+				}
+			}
+		}
+		else {$self->{subcall} = new Macro::Script($tmp)}
+		unless (defined $self->{subcall}) {$self->{error} = "$errtpl: failed to call script"}
+		else {
+			$self->{subcall}->regSubmacro;
+			$self->{timeout} = $self->{macro_delay}
+		}
+	}
+	elsif ($then eq "stop") {$self->{finished} = 1}
+}
+
+
+sub statement {
+	my ($temp_multi, $self, $errtpl) = @_;
+	my ($first, $cond, $last) = $temp_multi =~ /^\s*"?(.*?)"?\s+([<>=!~]+?)\s+"?(.*?)"?\s*$/;
+	if (!defined $first || !defined $cond || !defined $last) {$self->{error} = "$errtpl: syntax error in if statement"}
+	else {
+		my $pfirst = parseCmd(refined_macroKeywords($first)); my $plast = parseCmd(refined_macroKeywords($last));
+		unless (defined $pfirst && defined $plast) {$self->{error} = "$errtpl: either '$first' or '$last' has failed"}
+		elsif (cmpr($pfirst, $cond, $plast)) {return 1}
+	}
+	return 0
+}
+
+sub particle {
+	# I need to test this main code alot becoz it will be disastrous if something goes wrong
+	# in the if statement block below
+
+	my ($text, $self, $errtpl) = @_;
+	my @brkt;
+
+	if ($text =~ /\(/) {
+		@brkt = txtPosition($text, $self, $errtpl);
+		$brkt[0] = multi($brkt[0], $self, $errtpl) if !bracket($brkt[0]) && $brkt[0] =~ /[\(\)]/ eq "";
+		$text = extracted($text, @brkt);
+	}
+
+	unless ($text =~ /\(/) {return $text}
+	$text = particle($text, $self, $errtpl)
+}
+
+sub multi {
+	my ($text, $self, $errtpl) = @_;
+	my ($i, $n, $ok, $ok2) = (0, 0, 1, 0);
+	my %save;
+
+	while ($text =~ /(\|{2}|\&{2})/g) {
+		# Check if we put the wrong '&&' or '||' in the statement
+		# Logically, each clean statement(none-bracket statement),
+		# cant use the simbol '&&' or '||' together. Infact, it must be saperated
+		# by using round brackets '(' and ')' in the 1st place
+
+		$save{$i} = $1;
+		if ($i > 0) {
+			$n = $i - 1;
+			if ($save{$i} ne $save{$n}) {
+				my $s = $text;
+				$ok = 0;
+				#$s =~ s/($save{$i})/\($1\) <-- HERE/g;    # Later maybe? ;p
+				$self->{error} = "Wrong Conditions: $errtpl ($save{$n} vs $save{$i})"
+			}
+		}
+		$i++
+	}
+
+	if ($save{$n} eq "||" && $ok && $i > 0) {
+		my @split = split(/\s*\|{2}\s*/, $text);
+		foreach my $e (@split) {
+			next if $e eq "0";
+			return 1 if $e eq "1" || $e =~ /^\d+$/;
+			return 1 if statement($e, $self, $errtpl)
+		}
+		return 0
+	}
+	elsif ($save{$n} eq "&&" && $ok && $i > 0) {
+		my @split = split(/\s*\&{2}\s*/, $text);
+		foreach my $e (@split) {
+			if ($e eq "1" || ($e =~ /^\d+$/ && $e > 0)) {next}
+			elsif ($e eq "0") {return 0}
+			next if statement($e, $self, $errtpl);
+			return 0
+		}
+		return 1
+	}
+	elsif ($i == 0) {
+		return $text if $text =~ /^\d+$/;
+		return statement($text, $self, $errtpl)
+	}
+}
+
+sub txtPosition {
+	# This sub will deal which bracket is belongs to which statement,
+	# Using this, will capture the most correct statement to be checked 1st before the next statement,
+	# Ex: ((((1st statement)2nd statement)3rd statement)4th statement)
+	# will return: $new[0] = "1st statement", $new[1] = 4, $new[2] = 16
+   
+	my ($text, $self, $errtpl) = @_;
+	my ($start, $i) = (0, 0);
+	my (@save, @new, $first, $last);
+	my @w = split(//, $text);
+
+	foreach my $e (@w) {
+		if ($e eq ")" && $start) {
+			 $last = $i; last
+		}
+		elsif ($e eq "(") {
+			if ($start) {undef @save; undef $first}
+			$start = 1; $first = $i;
+		}
+		else {if ($start) {push @save, $e}}
+		$i++
+	}
+
+	$self->{error} = "$errtpl: You probably missed 1 or more closing round-\nbracket ')' in the statement." if !defined $last;
+
+	$new[0] = join('', @save);
+	$new[1] = $first;
+	$new[2] = $last;
+	return @new
+}
+
+sub extracted {
+	# Normally we just do substract s/// or s///g or using while grouping for s{}{} to delete or replace...
+	# but for some cases, the perl substract is failed... atleast for this text
+	# ex: $text = "(1 || 0) && 1 && 0" (or I might missed some info for the substract function?)
+	# so, below code will simply ignore the (1 || 0) but will replace it with $brkt[0] which is either 1 or 0,
+	# in return, the new $text will be in this format: $text = "1 && 1 && 0" if the $brkt[0] happened to be 1.
+
+	my ($text, @brkt) = @_;
+	my @save;
+	my @w = split(//, $text);
+
+	my $txt_lenght = scalar(@w);
+
+	for (my $i = 0; $i < $txt_lenght; $i++) {
+		if ($i == $brkt[1]) {push @save, $brkt[0]; next}
+		next if $i > $brkt[1] && $i <= $brkt[2];
+		push @save, $w[$i];
+		next
+	}
+	
+	$text = join('', @save);
+	return $text
+}
+
+sub refined_macroKeywords {
+	# To make sure if there is really no more @special keywords
+
+	my @pair = $_[0] =~ /\@($macroKeywords)\s*\(\s*(.*)\s*\)/i;
+	return $_[0] unless @pair;
+
+	$pair[1] = parseCmd($pair[1]);
+	my $new = "@".$pair[0]."(".$pair[1].")";	#sorry! cheap code ;p
+	return $new
+}
+
+sub bracket {
+	# Scans $text for @special keywords
+
+	my ($text, $dbg) = @_;
+	my @brkt; my $i = 0;
+
+	while ($text =~ /(\@)?($macroKeywords)?\s*\(\s*([^\)]+)\s*/g) {
+		my ($first, $second, $third) = ($1, $2, $3);
+		unless (defined $first && defined $second && !bracket($third, 1)) {
+			message "Bracket Detected: $text <-- HERE\n", "menu" if $dbg;
+			$brkt[$i] = 1
+		}
+		else {$brkt[$i] = 0}
+		$i++
+	}
+
+	foreach my $e (@brkt) {
+		if ($e == 1) {return 1}
+	}
+
+	return 0
+}
+
 1;
\ No newline at end of fileParser.PM - Enable Perl Sub-Routine In Macro Scripting and Enable comments at the back of macro line.
Code: Select all
--- https://openkore.svn.sourceforge.net/svnroot/openkore/plugins/macro/trunk/Macro/Parser.pm	Wed May 20 12:08:43 2009
+++ C:/.../plugins/Macro/Parser.pm	My working copy
@@ -7,6 +7,7 @@
 require Exporter;
 our @ISA = qw(Exporter);
 our @EXPORT = qw(parseMacroFile parseCmd);
+our @EKSPORT_OK = qw(parseCmd);
 
 use Globals;
 use List::Util qw(max min sum);
@@ -24,17 +25,20 @@
 	my ($file, $no_undef) = @_;
 	unless ($no_undef) {
 		undef %macro;
-		undef %automacro
+		undef %automacro;
+		undef @macro_block
 	}
 
 	my %block;
 	my $tempmacro = 0;
+	my $inBlock = 0;
 	open FILE, "<:utf8", $file or return 0;
 	foreach (<FILE>) {
-		s/^\s*#.*$//;      # remove comments
-		s/^\s*//;          # remove leading whitespaces
-		s/\s*[\r\n]?$//g;  # remove trailing whitespaces and eol
-		s/  +/ /g;         # trim down spaces
+		s/(.*)[\s\t]+#.*$/$1/;	# remove last comments
+		s/^\s*#.*$//;		# remove comments
+		s/^\s*//;		# remove leading whitespaces
+		s/\s*[\r\n]?$//g;	# remove trailing whitespaces and eol
+		s/  +/ /g;		# trim down spaces
 		next unless ($_);
 
 		if (!%block && /{$/) {
@@ -44,6 +48,8 @@
 				$macro{$value} = []
 			} elsif ($key eq 'automacro') {
 				%block = (name => $value, type => "auto")
+			} elsif ($key eq 'sub') {
+				%block = (name => $value, type => "sub")
 			} else {
 				%block = (type => "bogus");
 				warning "$file: ignoring line '$_' (munch, munch, strange block)\n"
@@ -91,6 +97,31 @@
 			next
 		}
 		
+		if (%block && $block{type} eq "sub") {
+			if ($_ eq "}") {
+				if ($inBlock > 0) {
+					$macro_sub = $macro_sub.$_;
+					$inBlock--;
+					next
+				}
+				$macro_sub = "sub ".$block{name}." {".$macro_sub."}";
+				eval $macro_sub;
+				message "[macro] registering sub $block{name} ...\n", "menu";
+				push(@macro_block, $block{name});
+				undef %block, undef $macro_sub;
+				$inBlock = 0
+			} else {
+				if ($_ =~ /{$/) {$inBlock++}
+				if ($macro_sub eq "") {
+					$macro_sub = $_;
+				}
+				else {
+					$macro_sub = $macro_sub.$_;
+				}
+			}
+			next
+		}
+		
 		if (%block && $block{type} eq "bogus") {
 			if ($_ eq "}") {undef %block}
 			next
@@ -162,6 +193,24 @@
 	return @pair
 }
 
+# parses all macro perl sub-routine found in the macro script
+sub parseSub {
+	#Taken from sub parseKw :D
+	my @full = $_[0] =~ /(?:^|\s+)(\w+)s*((s*(.*?)s*).*)$/i;
+	my @pair = ($full[0]);
+	my ($bracketed) = extract_bracketed ($full[1], '()');
+	return unless $bracketed;
+	push @pair, substr ($bracketed, 1, -1);
+
+	return unless @pair;
+
+	while ($pair[1] =~ /(?:^|\s+)(\w+)\s*\(/) {
+		@pair = parseSub ($pair[1])
+	}
+
+	return @pair
+}
+
 # substitute variables
 sub subvars {
 # should be working now
@@ -190,11 +239,11 @@
 sub parseCmd {
 	return "" unless defined $_[0];
 	my $cmd = $_[0];
-	my ($kw, $arg, $targ, $ret);
+	my ($kw, $arg, $targ, $ret, $sub, $val);
 
 	# refresh global vars only once per command line
 	refreshGlobal();
-
+	
 	while (($kw, $targ) = parseKw($cmd)) {
 		$ret = "_%_";
 		# first parse _then_ substitute. slower but more safe
@@ -235,9 +284,20 @@
 			$cmd =~ s/\@$kw\s*\(\s*$targ\s*\)/$ret/
 		}
 	}
+	
+	# any round bracket(pair) found after parseKw sub-routine were treated as macro perl sub-routine
+	undef $ret; undef $arg;
+	while (($sub, $val) = parseSub($cmd)) {
+		$arg = subvars($val);
+		my $sub1 = $sub."(".$arg.")";
+		$ret = eval($sub1);
+		return unless defined $ret;
+		$val = q4rx $val;		
+		$cmd =~ s/$sub\s*\(\s*$val\s*\)/$ret/g
+	}
 
 	$cmd = subvars($cmd);
 	return $cmd
 }
 
-1;
\ No newline at end of file
+1;Data.PM - New playerguild syntax for automacro block(credit: buggless). See also playerguild syntax in Automacro.PM diff and macro.pl diff
Example HERE, with a minor changes to the src/Settings.PM
Code: Select all
--- https://openkore.svn.sourceforge.net/svnroot/openkore/plugins/macro/trunk/Macro/Data.pm   Wed May	Wed May 20 12:08:18 2009
+++ C:/.../plugins/Macro/Data.pm	My Working Copy
@@ -5,13 +5,16 @@
 
 require Exporter;
 our @ISA = qw(Exporter);
-our @EXPORT = qw(%macro %automacro %varStack $queue $onHold %amSingle %amMulti $macroKeywords);
+our @EXPORT = qw(@macro_block $macro_sub $inBlock %macro %automacro %varStack $queue $onHold %amSingle %amMulti $macroKeywords);
 
+our @macro_block;
+our $macro_sub;
 our %macro;
 our %automacro;
 our %varStack;
 our $queue;
 our $onHold;
+our $inBlock;
 
 our %amSingle = (
 	'map' => 1,          # map check
@@ -34,8 +37,9 @@
 	'macro_delay' => 1,  # option: default macro delay
 	'hook' => 1,         # check: openkore hook
 	'priority' => 1,     # option: automacro priority
-	'exclusive' => 1,     # option: is macro interruptible
-	'eval' => 1	     # check : eval 
+	'exclusive' => 1,    # option: is macro interruptible
+	'playerguild' => 1,  # check: player guilds
+	'eval' => 1	         # check : eval
 	
 );
 
@@ -62,7 +66,8 @@
 	'inventory' => 1,    # check: item amount in inventory
 	'storage' => 1,      # check: item amount in storage
 	'shop' => 1,         # check: item amount in shop
-	'cart' => 1          # check: item amount in cart
+	'cart' => 1,         # check: item amount in cart
+	'localtime' => 1     # check: localtime
 );
 
 our $macroKeywords =
@@ -86,7 +91,8 @@
 	"eval"         . "|" .
 	"arg"          . "|" .
 	"listitem"     . "|" .
+   	"pm"		   . "|" .
 	"listlenght"
 ;
 
-1;
\ No newline at end of file
+1;p.s: Continue to the next post due to the exceeded 60, 000+ characters. Sorry.




