|
| Author |
Message |
Cheater Senior Member

Joined: 10 Jun 2005 Posts: 236
  
|
Posted: Wed Jul 27, 2005 10:41 pm Post subject: External Perl Script |
|
|
| I have a dos based bot, and I want to make it so that it can run perl scripts in a command directory when the user enters a command. The closest I got to this involved opening the file when the user enters the command, putting it into an array, using a foreach loop to get each line into a variable, and using eval on each line. But this messes up the variables in the perl script. Does anyone know how I would do this? Or can someone point me in the right direction? |
|
| Back to top |
|
 |
Cer Upgraded Agent

Joined: 03 Feb 2004 Posts: 3776 Location: Michigan
  votes: 4
|
Posted: Thu Jul 28, 2005 2:07 am Post subject: Re: External Perl Script |
|
|
| Cheater wrote: | | I have a dos based bot, and I want to make it so that it can run perl scripts in a command directory when the user enters a command. The closest I got to this involved opening the file when the user enters the command, putting it into an array, using a foreach loop to get each line into a variable, and using eval on each line. But this messes up the variables in the perl script. Does anyone know how I would do this? Or can someone point me in the right direction? |
Easier way.
When you have the array, you can put it into a scalar and eval it all at once.
| Code: | my $code = join ("\n", @array);
eval ($code); |
_________________ Current Site (2008) http://www.cuvou.com/ |
|
| Back to top |
|
 |
Cheater Senior Member

Joined: 10 Jun 2005 Posts: 236
  
|
Posted: Thu Jul 28, 2005 12:07 pm Post subject: |
|
|
I put your code in there cer, but it still messes up the variables. I have a command called ball.pl. So I type !ball.pl (I will change it so you don't need the extension later), and it evals the script:
| Code: | &ball;
sub ball {
print "Please enter a question for the magic 8 Ball\n";
$question = <STDIN>;
chomp $question;
open (BALL, "8ball_msg.txt");
@ball = <BALL>;
close (BALL);
$randball = $ball[int(rand(scalar(@ball)))];
print "\n\nQuestion: $question\nAnswer: $randball\n";
} |
But when it gets to the last print, it prints:
| Quote: |
Question: MY QUESTION HERE
Answer:
|
When I run the script alone, it works. I also tried running another script (a basic address book). Here is the script:
| Code: | my $abook = ();
open (ABOOK, "abook.txt");
@abook = <ABOOK>;
close (ABOOK);
foreach $person (@abook) {
my ($lname, $fname, $spouse, $child1, $child2, $phone, $state, $city, $zip, $address, $email, $num) = split(/:/, $person);
$abook->{$lname}->{lname} = $lname;
$abook->{$lname}->{fname} = $fname;
$abook->{$lname}->{spouse} = $spouse;
$abook->{$lname}->{child1} = $child1;
$abook->{$lname}->{child2} = $child2;
$abook->{$lname}->{phone} = $phone;
$abook->{$lname}->{state} = $state;
$abook->{$lname}->{city} = $city;
$abook->{$lname}->{zip} = $zip;
$abook->{$lname}->{address} = $address;
$abook->{$lname}->{email} = $email;
$abook->{$lname}->{num} = $num;
}
print "Address Book\n\n";
print "Please enter a last name to look up\n";
$search = <STDIN>;
chomp $search;
$search = lc($search);
print "Searching Adress Book...\n";
if ($abook->{$search}) {
print "Found a match for $search\n\n";
print "Last Name: $abook->{$search}->{lname}\nFirst Name: $abook->{$search}->{fname}\nSpouse: $abook->{$search}->{spouse}\n";
print "Child 1: $abook->{$search}->{child1}\nChild 2: $abook->{$search}->{child2}\nPhone: $abook->{$search}->{phone}\n";
print "EMail: $abook->{$search}->{email}\nAddress: $abook->{$search}->{address}\nCity: $abook->{$search}->{city}\n";
print "State: $abook->{$search}->{state}\nZip: $abook->{$search}->{zip}\nNumber of People: $abook->{$search}->{num}\n";
}
else {
print "No matches for \"$search\"\n";
}
|
It just prints the else statement everytime, even if I enter a name that is in it (It works when I run it on it's own). Here is the script to load the commands:
| Code: |
print "Please enter your command\n";
$msg = <STDIN>;
chomp $msg;
open (COMMCHAR, "char.txt");
$commchar = <COMMCHAR>;
chomp $commchar;
close (COMMCHAR);
opendir (COMMANDS, "./commands");
@files = readdir(COMMANDS);
closedir(COMMANDS);
foreach $file (@files) {
if ($msg =~ /^$commchar$file$/i) {
open (COMMAND, "./commands/$file");
@command = <COMMAND>;
my $code = join ("\n", @command);
eval ($code);
}
} |
$commchar holds a single "!" in case you are wondering. I have tried numerous ways to eval the command but keep the variables working. I don't know what to do anymore. |
|
| Back to top |
|
 |
draget Not Yet a God

Joined: 29 Dec 2004 Posts: 367 Location: Australia
   
|
Posted: Thu Jul 28, 2005 12:15 pm Post subject: |
|
|
| Cheater wrote: |
| Code: | &ball;
sub ball {
print "Please enter a question for the magic 8 Ball\n";
$question = <STDIN>;
chomp $question;
open (BALL, "8ball_msg.txt");
@ball = <BALL>;
close (BALL);
$randball = $ball[int(rand(scalar(@ball)))];
print "\n\nQuestion: $question\nAnswer: $randball\n";
} |
|
errrrrrrrrr, whats with the $ball[ bit, shouldn't it just be
$randball = int(rand(scalar(@ball)));
btw, you need to get used to "my"ing your variables. |
|
| Back to top |
|
 |
darkmonkey The Merovingian

Joined: 18 Apr 2004 Posts: 2557 Location: London, England
     votes: 7
|
Posted: Thu Jul 28, 2005 12:57 pm Post subject: |
|
|
Draget: Both ways work. Also, so that Cheater knows what you mean, refer to "my'ing it" as "using strict" .
Cheater: You need to return your message rather than printing.
| Code: |
$reply = &Sub();
print "Answer: $reply";
sub Sub
{
$reply = "My name is bob.\n";
return $reply;
}
1;
|
That will print $reply after the Sub is eval'd. _________________ ~ Josh
[ Need bot hosting on a dedicated server? PM me. ] |
|
| Back to top |
|
 |
Cheater Senior Member

Joined: 10 Jun 2005 Posts: 236
  
|
Posted: Thu Jul 28, 2005 8:39 pm Post subject: |
|
|
| Yeah, but if you look at the commands, they print instructions to the screen. And ask for input (<STDIN>). I can't just call the sub and return a single variable. And I know about my. I'll add it to a later version |
|
| Back to top |
|
 |
darkmonkey The Merovingian

Joined: 18 Apr 2004 Posts: 2557 Location: London, England
     votes: 7
|
Posted: Thu Jul 28, 2005 9:28 pm Post subject: |
|
|
Then don't call subs, just require the file and it will print stuff. _________________ ~ Josh
[ Need bot hosting on a dedicated server? PM me. ] |
|
| Back to top |
|
 |
Cheater Senior Member

Joined: 10 Jun 2005 Posts: 236
  
|
Posted: Fri Jul 29, 2005 1:07 am Post subject: |
|
|
| Yeah, but if I require the file, how do I tell the script to execute it? |
|
| Back to top |
|
 |
Cer Upgraded Agent

Joined: 03 Feb 2004 Posts: 3776 Location: Michigan
  votes: 4
|
Posted: Fri Jul 29, 2005 3:08 am Post subject: |
|
|
| Cheater wrote: | | Yeah, but if I require the file, how do I tell the script to execute it? |
That's what require does....
When you use require, the script executes that file as if its code was right there in place of the require command. _________________ Current Site (2008) http://www.cuvou.com/ |
|
| Back to top |
|
 |
alienz Almost An Agent

Joined: 22 Mar 2004 Posts: 1436 Location: Mars
 
|
Posted: Fri Jul 29, 2005 6:12 am Post subject: |
|
|
I have no idea why you guys like helping people that would rather hack a script up till it works rather than learn anything about the language they're using. _________________ Check out Botworld! A dev resource for things bot.
Downloads, articles, news, fourm and more.
http://botworld.marzopolis.com |
|
| Back to top |
|
 |
Cheater Senior Member

Joined: 10 Jun 2005 Posts: 236
  
|
Posted: Fri Jul 29, 2005 11:51 am Post subject: |
|
|
Hey, before you start criticizing me, maybe you should ask me what I've read. I've read as many perl tutorials as I could get my hands on, and when I started getting errors with eval, I plugged it into google and read the results. If you look at the second command I posted (abook), that was just a practice command I made as I learned about hashrefs. So just give me a break.
P.S. I even tried learning about require in a few tutorials before and after that post. And now I get the error:
| Quote: | Can't locate ./commands/. in @INC (@INC contains: C:/Perl/lib C:/Perl/site/lib .
) at test_command.pl line 17.
|
|
|
| Back to top |
|
 |
Cer Upgraded Agent

Joined: 03 Feb 2004 Posts: 3776 Location: Michigan
  votes: 4
|
Posted: Fri Jul 29, 2005 3:40 pm Post subject: |
|
|
| Cheater wrote: | P.S. I even tried learning about require in a few tutorials before and after that post. And now I get the error:
| Quote: | Can't locate ./commands/. in @INC (@INC contains: C:/Perl/lib C:/Perl/site/lib .
) at test_command.pl line 17.
|
|
Were you doing a foreach readdir to load external files? Because if so, you need to skip files that start with periods. There's two of them (. and ..)
That looks like what the problem is, trying to require a file named . which doesn't exist. _________________ Current Site (2008) http://www.cuvou.com/ |
|
| Back to top |
|
 |
Cheater Senior Member

Joined: 10 Jun 2005 Posts: 236
  
|
Posted: Fri Jul 29, 2005 9:27 pm Post subject: |
|
|
Well, I've made a few changes. I learned that for some reason when I require a file, it executes the file. So I had to delete the part of my code that called on the sub. Also, I had to make it only put .pl files into the array. And I only required the single file called in the command (after removing the command character and adding .pl to the end). And the reason the variables turned out blank was because the file was trying to open a file in the same folder. So I had to change the path of the file to open to ./commands/filename instead of filename. Here is the final code (sorry for slopiness).
| Code: |
print "Please enter your command\n";
$msg = <STDIN>;
chomp $msg;
open (COMMCHAR, "char.txt");
$commchar = <COMMCHAR>;
chomp $commchar;
close (COMMCHAR);
opendir (COMMANDS, "./commands");
@files = grep (/\.pl$/,readdir(COMMANDS));
closedir(COMMANDS);
foreach $file (@files) {
$file =~ s/\.(pl|txt|cgi|pm)$//ig;
if ($msg =~ /^$commchar$file$/i) {
$msg =~ s/$commchar//;
require "./commands/$msg.pl";
}
}
|
|
|
| Back to top |
|
 |
|