2014-10-19 59 views
1

我在perl中製作了一個簡單的IRC bot,並且我認爲能夠添加管理員會很有用。 所以我在最頂層,宣佈這個數組,與一些用戶在一起。而且這個工作很好,機器人識別我,並在入門時挑剔我。 我已經聲明瞭數組是這樣的:Perl對陣列的更改不會持續

my @adms=('[email protected]'); 

但是我有機器人在運行一段時間(1)循環,所以它的活躍,以及與睡眠。當我嘗試運行-adduser(這是內部循環)時,變化不會持續,我已經讀過,這是除for()循環以外的任何其他任何內容中的正常行爲,但這非常無用。

if ($funcarg =~ /^-adduser (.*)/) { 
    my $user = "$1"; 
    sendraw($IRC_cur_socket, "PRIVMSG $printl $pn"); 
    push(@adms, $user); 
    my $p = join(", ", @adms); 
    sendraw($IRC_cur_socket, "PRIVMSG $printl Current admins are now $p"); 
} 

我怎樣才能使這些變化持續存在,我能做些什麼來承諾這種變化回來?

感謝

編輯: 我沒有做這清楚。所以我會在澄清的希望中增加更多的代碼和解釋。對不起,任何含糊不清。

my @adms = ("Ducktator", "System69", '[email protected]'); 
# It is a bit further up, but i thought to spare you the IRC connection code, as I took some of that from a public perl bot anyway. 

my $line_temp; 
while (1) { 
    while (!(keys(%irc_servers))) { conectar("$nick", "$servidor", "$porta"); } 
    select(undef, undef, undef, 0.01) 
     ; #sleeping for a fraction of a second keeps the script from running to 100% cpu usage ^_^ 
    delete($irc_servers{''}) if (defined($irc_servers{''})); 
    my @ready = $sel_cliente->can_read(0); 
    next unless (@ready); 
    foreach $fh (@ready) { 
     $IRC_cur_socket = $fh; 
     $meunick  = $irc_servers{$IRC_cur_socket}{'nick'}; 
     $nread   = sysread($fh, $msg, 4096); 
     if ($nread == 0) { 
      $sel_cliente->remove($fh); 
      $fh->close; 
      delete($irc_servers{$fh}); 
     } 
     @lines = split(/\n/, $msg); 
     for (my $c = 0; $c <= $#lines; $c++) { 
      $line  = $lines[$c]; 
      $line  = $line_temp . $line if ($line_temp); 
      $line_temp = ''; 
      $line =~ s/\r$//; 
      unless ($c == $#lines) { 
       parse("$line"); 
      } else { 
       if ($#lines == 0) { 
        parse("$line"); 
       } elsif ($lines[$c] =~ /\r$/) { 
        parse("$line"); 
       } elsif ($line =~ /^(\S+) NOTICE AUTH :\*\*\*/) { 
        parse("$line"); 
       } else { 
        $line_temp = $line; 
       } 
      } 
     } 
    } 
} 

sub parse { 
    my $servarg = shift; 
    if ($servarg =~ /^PING \:(.*)/) { 
     sendraw("PONG :$1"); 
    } elsif ($servarg =~ /^\:(.+?)\!(.+?)\@(.+?) PRIVMSG (.+?) \:(.+)/) { 
     my $pn  = $1; 
     my $hostmask = $3; 
     my $onde  = $4; 
     my $args  = $5; 
     if ($args =~ /^\001VERSION\001$/) { 
      notice("$pn", "\001VERSION mIRC v7.25 CyberBot\001"); 
     } 
     # Check for what the nick is being used 
     if (grep { $_ =~ /^\Q$pn\E$/i } @adms) { 

      #Now check for the vhost being valid 
      if (grep { $_ =~ /$hostmask/i } @adms) { 

       if ($onde eq "$meunick") { 
        shell("$pn", "$args"); 
       } 
       #End of Connect 
       if ($args =~ /^(\Q$meunick\E|\-bot)\s+(.*)/) { 
        my $natrix = $1; 
        my $arg = $2; 
        if ($arg =~ /^\!(.*)/) { 
         #Here we get to set the calling command 
         ircase("$pn", "$onde", "$1") 
          unless ($natrix eq "-bot" and $arg =~ /^\!nick/); 
        } elsif ($arg =~ /^\-(.*)/) { # @ changed to - 
         $ondep = $onde; 
         $ondep = $pn if $onde eq $meunick; 
         bfunc("$ondep", "$1"); 
        } 
       } 
      } 
     } 

    } elsif ($servarg =~ /^\:(.+?)\!(.+?)\@-(.+?)\s+NICK\s+\:(\S+)/i) { 
     if (lc($1) eq lc($meunick)) { 
      $meunick = $4; 
      $irc_servers{$IRC_cur_socket}{'nick'} = $meunick; 
     } 
    } elsif ($servarg =~ m/^\:(.+?)\s+433/i) { 
     nick("$meunick|" . int rand(999999)); 
    } elsif ($servarg =~ m/^\:(.+?)\s+001\s+(\S+)\s/i) { 
     $meunick        = $2; 
     $irc_servers{$IRC_cur_socket}{'nick'} = $meunick; 
     $irc_servers{$IRC_cur_socket}{'nome'} = "$1"; 
     foreach my $canal (@canais) { 
      sendraw("JOIN $canal $chanpass"); 
     } 
    } 
} 
# This is where i have bot functions going on, and it's when i do this code below, it doesn't update the main @adms array, the change seems to dissapear instantly. 
sub bfunc { 
    my $printl = $_[0]; 
    my $funcarg = $_[1]; 
    if (my $pid = fork) { 
     waitpid($pid, 0); 
    } else { 
     if (fork) { 
      exit; 
     } else { 

      if ($funcarg =~ /^-adduser (.*)/) { 
       my $user = "$1"; 
       push(@adms, $user); 
       my $p = join(", ", @adms); 
       sendraw($IRC_cur_socket, "PRIVMSG $printl Current admins are now $p"); 
      } 
     } 
    } 
} 
+0

不,這沒有任何意義。也許你正在重置循環內的'@ adms'的值? – hobbs 2014-10-19 03:49:17

+0

你能解釋一點嗎?你在一個數組中聲明管理員,你在數組中添加一個管理員,並且當你下次運行這個程序時,你的管理列表沒有改變? – 2014-10-19 03:49:38

+0

不,下次我運行它時,如果我立即運行後--listusers它將讀取默認值,而不是新值。不,我沒有故意重置它,像我上面這樣的可能是這樣的嗎?在這種情況下,我如何才能使它以默認數據開始呢? – user3407675 2014-10-19 03:56:19

回答

1

您正在分支並修改子進程中的值,並且子進程所做的更改無法更改父進程中的值。

考慮你的功能,你確定問題:

# This is where I have bot functions going on, and it's when I do this code, 
# it doesn't update the main @adms array; the change seems to dissapear instantly. 

sub bfunc { 
    my $printl = $_[0]; 
    my $funcarg = $_[1]; 
    if (my $pid = fork) { 
     waitpid($pid, 0); 
    } else { 
     if (fork) { 
     exit; 
     } else { 
     if ($funcarg =~ /^-adduser (.*)/) { 
     my $user="$1"; 
      push(@adms, $user); 
     my $p= join(", ", @adms); 
      sendraw($IRC_cur_socket, "PRIVMSG $printl Current admins are now $p"); 
     } 
     } 
    } 
} 

父進程派生和等待;孩子也分叉,並退出。孫子過程然後修改它自己的@adms數組,但是它所做的更改將反映在父進程中。