ChatQueue.pm
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:21k
- #########################################################################
- # This software is open source, licensed under the GNU General Public
- # License, version 2.
- # Basically, this means that you're allowed to modify and distribute
- # this software. However, if you distribute modified versions, you MUST
- # also distribute the source code.
- # See http://www.gnu.org/licenses/gpl.html for the full license.
- #########################################################################
- ##
- # MODULE DESCRIPTION: Processing of incoming chat commands
- #
- # Kore has a feature called 'chat commands': you command your bot to
- # do certain things by using PM or public chat. This module processes
- # chat input and executes chat commands when necessary.
- package ChatQueue;
- use strict;
- use Time::HiRes qw(time);
- use AI;
- use Commands;
- use Globals qw($accountID $AI %ai_v $char @chatResponses %cities_lut
- %config %field %itemChange @monsters_Killed %maps_lut $net %overallAuth
- %players %responseVars %skillsSP_lut $startTime_EXP %timeout
- $totalBaseExp $totalJobExp $messageSender
- );
- use Log qw(message error);
- use Misc qw(auth avoidGM_talk avoidList_talk configModify getIDFromChat
- getResponse quit relog sendMessage setTimeout look parseReload);
- use Plugins;
- use Translation;
- use Utils qw(formatNumber getFormattedDate parseArgs swrite timeConvert timeOut);
- our @queue;
- our $wordSplitters = qr/(b| |,|.|!)/;
- our %lastInput;
- # use SelfLoader; 1;
- # __DATA__
- ##
- # void ChatQueue::add(String type, Bytes userID, String user, String msg)
- # type: 'c' (public chat), 'pm' (private message), 'p' (party chat) or 'g' (guild chat)
- # userID: the account ID of the user who sent this message.
- # user: the name of the user who sent this message.
- # msg: the message.
- #
- # Add a chat message to the chat queue. The messages in the queue will be processed later.
- sub add {
- my %item = (
- type => shift,
- userID => shift,
- user => shift,
- msg => shift,
- time => time
- );
- push @queue, %item;
- Plugins::callHook('ChatQueue::add', %item);
- }
- ##
- # void ChatQueue::clear()
- #
- # Clear the chat queue, if there are any unprocessed messages.
- sub clear {
- @queue = ();
- %lastInput = ();
- }
- ##
- # void ChatQueue::processFirst()
- #
- # Process the first message in the queue, if any.
- # That message will be removed from the queue.
- sub processFirst {
- return unless @queue;
- my $cmd = shift @queue;
- return if ($cmd->{user} eq $char->{name});
- my $type = $cmd->{type};
- my $user = $cmd->{user};
- my $msg = $cmd->{msg};
- return if ( $user ne ""
- && (avoidGM_talk($user, $msg) || avoidList_talk($user, $msg, unpack("V1", $cmd->{userID}))) );
- # If the user is not authorized to use chat commands,
- # check whether he's trying to authenticate
- if (( $type eq "pm" || $type eq "p" || $type eq "g" ) && !$overallAuth{$user} && $config{adminPassword}) {
- if ($msg eq $config{adminPassword}) {
- auth($user, 1);
- sendMessage($messageSender, "pm", getResponse("authS"), $user);
- }
- # We don't notify the user if login failed; people use it
- # to check whether you're a bot.
- }
- # If the user is authorized to use chat commands,
- # check whether his message is a chat command, and execute it.
- my $callSign = quotemeta $config{callSign};
- if ($overallAuth{$user} && ( $type eq "pm" || $msg =~ /^b*$callSignb*/i )) {
- my $msg2 = $msg;
- $msg2 =~ s/^b*$callSignb* *//i;
- $msg2 =~ s/ *$//;
- return if processChatCommand($type, $user, $msg2);
- }
- # Not a chat command; attempt to reply with a message
- processChatResponse($cmd) if ($config{autoResponse});
- }
- sub processChatCommand {
- my ($type, $user, $msg) = @_;
- my ($switch, $after) = split / +/, $msg, 2;
- $after =~ s/ *$//;
- my @args = parseArgs($after);
- my $vars = %responseVars;
- $vars->{cmd_user} = $user;
- if ($switch eq "conf") {
- if ($args[0] eq "") {
- sendMessage($messageSender, $type, getResponse("confF1"), $user) if $config{verbose};
- } elsif (!exists $config{$args[0]}) {
- sendMessage($messageSender, $type, getResponse("confF2"), $user) if $config{verbose};
- } elsif ($args[1] eq "") {
- if (lc($args[0]) eq "username" || lc($args[0] eq "password")) {
- sendMessage($messageSender, $type, getResponse("confF3"), $user) if $config{verbose};
- } else {
- $vars->{key} = $args[0];
- $vars->{value} = $config{$args[0]};
- sendMessage($messageSender, $type, getResponse("confS1"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- }
- } else {
- $args[1] = "" if ($args[1] eq "none");
- configModify($args[0], $args[1]);
- sendMessage($messageSender, $type, getResponse("confS2"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- }
- } elsif ($switch eq "date") {
- $vars->{date} = getFormattedDate(int(time));
- sendMessage($messageSender, $type, getResponse("dateS"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- } elsif ($switch eq "exp") {
- if ($args[0] eq "") {
- my ($endTime_EXP, $w_sec);
- $endTime_EXP = time;
- $w_sec = int($endTime_EXP - $startTime_EXP);
- if ($w_sec > 0) {
- $vars->{bExpPerHour} = int($totalBaseExp / $w_sec * 3600);
- $vars->{jExpPerHour} = int($totalJobExp / $w_sec * 3600);
- if ($char->{exp_max} && $vars->{bExpPerHour}){
- $vars->{percentBExp} = "(".sprintf("%.2f",$totalBaseExp * 100 / $char->{exp_max})."%)";
- $vars->{percentBExpPerHour} = "(".sprintf("%.2f",$vars->{bExpPerHour} * 100 / $char->{exp_max})."%)";
- $vars->{bLvlUp} = timeConvert(int(($char->{exp_max} - $char->{exp})/($vars->{bExpPerHour}/3600)));
- }
- if ($char->{exp_job_max} && $vars->{jExpPerHour}){
- $vars->{percentJExp} = "(".sprintf("%.2f",$totalJobExp * 100 / $char->{exp_job_max})."%)";
- $vars->{percentJExpPerHour} = "(".sprintf("%.2f",$vars->{jExpPerHour} * 100 / $char->{exp_job_max})."%)";
- $vars->{jLvlUp} = timeConvert(int(($char->{'exp_job_max'} - $char->{exp_job})/($vars->{jExpPerHour}/3600)));
- }
- }
- $vars->{time} = timeConvert($w_sec);
- $vars->{bExp} = formatNumber($totalBaseExp);
- $vars->{jExp} = formatNumber($totalJobExp);
- $vars->{bExpPerHour} = formatNumber($vars->{bExpPerHour});
- $vars->{jExpPerHour} = formatNumber($vars->{jExpPerHour});
- $vars->{numDeaths} = (defined $char->{deathCount})? $char->{deathCount} : 0;
- sendMessage($messageSender, $type, getResponse("expS"), $user) if $config{verbose};
- } elsif ($args[0] eq "monster") {
- $vars->{numKilledMonsters} = 0;
- sendMessage($messageSender, $type, getResponse("expMonsterS1"), $user) if $config{verbose};
- for (my $i = 0; $i < @monsters_Killed; $i++) {
- next if ($monsters_Killed[$i] eq "");
- $vars->{killedMonsters} = swrite(
- "@<< @<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<",
- [$i, $monsters_Killed[$i]{name}, $monsters_Killed[$i]{count}]);
- $vars->{killedMonsters} = substr($vars->{killedMonsters}, 0, length($vars->{killedMonsters}) - 1);
- $vars->{numKilledMonsters} += $monsters_Killed[$i]{count};
- sendMessage($messageSender, $type, getResponse("expMonsterS2"), $user) if $config{verbose};
- }
- sendMessage($messageSender, $type, getResponse("expMonsterS3"), $user) if $config{verbose};
- } elsif ($args[0] eq "item") {
- sendMessage($messageSender, $type, getResponse("expItemS1"), $user) if $config{verbose};
- for my $item (sort keys %itemChange) {
- next unless $itemChange{$item};
- $vars->{gotItems} = sprintf("%-40s %5d", $item, $itemChange{$item});
- sendMessage($messageSender, $type, getResponse("expItemS2"), $user) if $config{verbose};
- }
-
- } else {
- sendMessage($messageSender, $type, getResponse("expF"), $user) if $config{verbose};
- }
- } elsif ($switch eq "follow") {
- if ($args[0] eq "stop") {
- if ($config{follow}) {
- AI::clear("follow");
- configModify("follow", 0);
- sendMessage($messageSender, $type, getResponse("followStopS"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- } else {
- sendMessage($messageSender, $type, getResponse("followStopF"), $user) if $config{verbose};
- }
- } else {
- my $targetID = getIDFromChat(%players, $user, $after);
- if (defined $targetID) {
- AI::clear("follow");
- main::ai_follow($players{$targetID}{name});
- configModify("follow", 1);
- configModify("followTarget", $players{$targetID}{name});
- sendMessage($messageSender, $type, getResponse("followS"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- } else {
- sendMessage($messageSender, $type, getResponse("followF"), $user) if $config{verbose};
- }
- }
- } elsif ($switch eq "logout") {
- sendMessage($messageSender, $type, getResponse("quitS"), $user) if $config{verbose};
- quit();
- $timeout{ai_thanks_set}{time} = time;
- } elsif ($switch eq "look") {
- my ($body, $head) = @args;
- if ($body ne "") {
- look($body, $head);
- sendMessage($messageSender, $type, getResponse("lookS"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- } else {
- sendMessage($messageSender, $type, getResponse("lookF"), $user) if $config{verbose};
- }
- } elsif (($switch eq "move" && $args[0] eq "stop") || $switch eq "stop") {
- AI::clear("move", "route", "mapRoute");
- sendMessage($messageSender, $type, getResponse("moveS"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- } elsif ($switch eq "move") {
- my ($map, $x, $y);
- if ($args[0] =~ /^d+$/) {
- # x y map
- ($x, $y, $map) = @args;
- } else {
- # map x y
- ($map, $x, $y) = @args;
- }
- if ($map eq "") {
- $x eq "" || $y eq ""
- } else {
- $x ne "" && $y ne ""
- }
- if ($map ne "" || ($x ne "" && $y ne "")) {
- $map = $field{name} if ($map eq "");
- my $rsw = "${map}.rsw";
- if ($maps_lut{$rsw}) {
- if ($x ne "" && $y ne "") {
- message TF("Calculating route to: %s(%s): %d, %dn", $maps_lut{$rsw}, $map, $x, $y), "route";
- } else {
- message TF("Calculating route to: %s(%s)n", $maps_lut{$rsw}, $map), "route";
- }
- sendMessage($messageSender, $type, getResponse("moveS"), $user) if $config{verbose};
- main::ai_route($map, $x, $y, attackOnRoute => 1);
- $timeout{ai_thanks_set}{time} = time;
- } else {
- error TF("Map %s does not existn", $map);
- sendMessage($messageSender, $type, getResponse("moveF"), $user) if $config{verbose};
- }
- } else {
- sendMessage($messageSender, $type, getResponse("moveF"), $user) if $config{verbose};
- }
- } elsif ($switch eq "reload") {
- parseReload($after);
- sendMessage($messageSender, $type, getResponse("reloadS"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- } elsif ($switch eq "relog") {
- sendMessage($messageSender, $type, getResponse("relogS"), $user) if $config{verbose};
- relog($args[0]);
- $timeout{ai_thanks_set}{time} = time;
- } elsif ($msg =~ /bshut[sS]*upb/) {
- if ($config{verbose}) {
- configModify("verbose", 0);
- sendMessage($messageSender, $type, getResponse("verboseOffS"), $user);
- $timeout{ai_thanks_set}{time} = time;
- } else {
- sendMessage($messageSender, $type, getResponse("verboseOffF"), $user);
- }
- } elsif ($switch eq "speak") {
- if (!$config{verbose}) {
- configModify("verbose", 1);
- sendMessage($messageSender, $type, getResponse("verboseOnS"), $user);
- $timeout{ai_thanks_set}{time} = time;
- } else {
- sendMessage($messageSender, $type, getResponse("verboseOnF"), $user);
- }
- } elsif ($switch eq "sit") {
- Commands::run("sit");
- sendMessage($messageSender, $type, getResponse("sitS"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- } elsif ($switch eq "stand") {
- Commands::run("stand");
- sendMessage($messageSender, $type, getResponse("standS"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- } elsif ($switch eq "status") {
- $vars->{char_sp} = $char->{sp};
- $vars->{char_hp} = $char->{hp};
- $vars->{char_sp_max} = $char->{sp_max};
- $vars->{char_hp_max} = $char->{hp_max};
- $vars->{char_lv} = $char->{lv};
- $vars->{char_lv_job} = $char->{lv_job};
- $vars->{char_exp} = formatNumber($char->{exp});
- $vars->{char_exp_max} = formatNumber($char->{exp_max});
- $vars->{char_exp_job} = formatNumber($char->{exp_job});
- $vars->{char_exp_job_max} = formatNumber($char->{exp_job_max});
- $vars->{char_weight} = $char->{weight};
- $vars->{char_weight_max} = $char->{weight_max};
- $vars->{zenny} = formatNumber($char->{zenny});
- sendMessage($messageSender, $type, getResponse("statusS"), $user) if $config{verbose};
- } elsif ($switch eq "tank") {
- if ($args[0] eq "stop") {
- if (!$config{tankMode}) {
- sendMessage($messageSender, $type, getResponse("tankStopF"), $user) if $config{verbose};
- } else {
- sendMessage($messageSender, $type, getResponse("tankStopS"), $user) if $config{verbose};
- configModify("tankMode", 0);
- $timeout{ai_thanks_set}{time} = time;
- }
- } else {
- my $targetID = getIDFromChat(%players, $user, $after);
- if ($targetID ne "") {
- sendMessage($messageSender, $type, getResponse("tankS"), $user) if $config{verbose};
- configModify("tankMode", 1);
- configModify("tankModeTarget", $players{$targetID}{name});
- $timeout{ai_thanks_set}{time} = time;
- } else {
- sendMessage($messageSender, $type, getResponse("tankF"), $user) if $config{verbose};
- }
- }
- } elsif ($switch eq "thank" || $switch eq "thn" || $switch eq "thx") {
- if (!timeOut($timeout{ai_thanks_set})) {
- $timeout{ai_thanks_set}{time} -= $timeout{ai_thanks_set}{timeout};
- sendMessage($messageSender, $type, getResponse("thankS"), $user) if $config{verbose};
- }
- } elsif ($switch eq "timeout") {
- if ($args[0] eq "") {
- sendMessage($messageSender, $type, getResponse("timeoutF1"), $user) if $config{verbose};
- } elsif (!exists $timeout{$args[0]}{timeout}) {
- sendMessage($messageSender, $type, getResponse("timeoutF2"), $user) if $config{verbose};
- } elsif ($args[1] eq "") {
- $vars->{key} = $args[0];
- $vars->{value} = $timeout{$args[0]}{timeout};
- sendMessage($messageSender, $type, getResponse("timeoutS1"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- } else {
- $args[1] = "" if ($args[1] eq "none");
- setTimeout($args[0], $args[1]);
- sendMessage($messageSender, $type, getResponse("timeoutS2"), $user) if $config{verbose};
- $timeout{ai_thanks_set}{time} = time;
- }
- } elsif ($switch eq "town") {
- sendMessage($messageSender, $type, getResponse("moveS"), $user);
- main::useTeleport(2);
-
- } elsif ($switch eq "version") {
- $vars->{ver} = $Settings::VERSION;
- sendMessage($messageSender, $type, getResponse("versionS"), $user) if $config{verbose};
- } elsif ($switch eq "where") {
- my $rsw = "$field{name}.rsw";
- $vars->{x} = $char->{pos_to}{x};
- $vars->{y} = $char->{pos_to}{y};
- $vars->{map} = "$maps_lut{$rsw} ($field{name})";
- $timeout{ai_thanks_set}{time} = time;
- sendMessage($messageSender, $type, getResponse("whereS"), $user) if $config{verbose};
- # Support Skills
- } elsif ($switch eq "agi"){
- my $targetID = getIDFromChat(%players, $user, $after);
- if ($targetID eq "") {
- sendMessage($messageSender, $type, getResponse("healF1"), $user) if $config{verbose};
- } elsif ($char->{skills}{AL_INCAGI}{lv} > 0) {
- my $failed = 1;
- for (my $i = $char->{skills}{AL_INCAGI}{lv}; $i >=1; $i--) {
- if ($char->{sp} >= $skillsSP_lut{AL_INCAGI}{$i}) {
- main::ai_skillUse('AL_INCAGI', $i, 0, 0, $targetID);
- $failed = 0;
- last;
- }
- }
- if (!$failed) {
- sendMessage($messageSender, $type, getResponse("healS"), $user) if $config{verbose};
- }else{
- sendMessage($messageSender, $type, getResponse("healF2"), $user) if $config{verbose};
- }
- } else {
- sendMessage($messageSender, $type, getResponse("healF3"), $user) if $config{'verbose'};
- }
- $timeout{ai_thanks_set}{time} = time;
- } elsif ($switch eq "bless" || $switch eq "blessing"){
- my $targetID = getIDFromChat(%players, $user, $after);
- if ($targetID eq "") {
- sendMessage($messageSender, $type, getResponse("healF1"), $user) if $config{verbose};
- } elsif ($char->{skills}{AL_BLESSING}{lv} > 0) {
- my $failed = 1;
- for (my $i = $char->{skills}{AL_BLESSING}{lv}; $i >=1; $i--) {
- if ($char->{sp} >= $skillsSP_lut{AL_BLESSING}{$i}) {
- main::ai_skillUse('AL_BLESSING', $i, 0, 0, $targetID);
- $failed = 0;
- last;
- }
- }
- if (!$failed) {
- sendMessage($messageSender, $type, getResponse("healS"), $user) if $config{verbose};
- }else{
- sendMessage($messageSender, $type, getResponse("healF2"), $user) if $config{verbose};
- }
- } else {
- sendMessage($messageSender, $type, getResponse("healF3"), $user) if $config{verbose};
- }
- $timeout{ai_thanks_set}{time} = time;
- } elsif ($switch eq "heal") {
- my $amount;
- my $targetID;
- if ($args[0] =~ /^d+$/) {
- $amount = $args[0];
- $targetID = getIDFromChat(%players, $user, $args[1]);
- } else {
- $amount = $args[1];
- $targetID = getIDFromChat(%players, $user, $args[0]);
- }
- if ($targetID eq "") {
- sendMessage($messageSender, $type, getResponse("healF1"), $user) if $config{verbose};
- } elsif ($char->{skills}{AL_HEAL}{lv} > 0) {
- my $amount_healed;
- my $sp_needed;
- my $sp_used;
- my $failed;
- my @skillCasts;
- # Calculate what skill level is needed to heal $amount HP
- while ($amount_healed < $amount) {
- my ($sp, $amount_this);
- for (my $i = 1; $i <= $char->{skills}{AL_HEAL}{lv}; $i++) {
- $sp = 10 + ($i * 3);
- $amount_this = int(($char->{lv} + $char->{int}) / 8)
- * (4 + $i * 8);
- last if ($amount_healed + $amount_this >= $amount);
- }
- $sp_needed += $sp;
- $amount_healed += $amount_this;
- }
- while ($sp_used < $sp_needed && !$failed) {
- my ($lv, $sp);
- for (my $i = 1; $i <= $char->{skills}{AL_HEAL}{lv}; $i++) {
- $lv = $i;
- $sp = 10 + ($i * 3);
- if ($sp_used + $sp > $char->{sp}) {
- $lv--;
- $sp = 10 + ($lv * 3);
- last;
- }
- last if ($sp_used + $sp >= $sp_needed);
- }
- if ($lv > 0) {
- my %skill;
- $sp_used += $sp;
- $skill{skill} = 'AL_HEAL';
- $skill{lv} = $lv;
- $skill{maxCastTime} = 0;
- $skill{minCastTime} = 0;
- $skill{ID} = $targetID;
- unshift @skillCasts, %skill;
- } else {
- $vars->{char_sp} = $char->{sp} - $sp_used;
- sendMessage($messageSender, $type, getResponse("healF2"), $user) if $config{verbose};
- $failed = 1;
- }
- }
- if (!$failed) {
- sendMessage($messageSender, $type, getResponse("healS"), $user) if $config{verbose};
- }
- foreach (@skillCasts) {
- main::ai_skillUse($_->{skill}, $_->{lv}, $_->{maxCastTime}, $_->{minCastTime}, $_->{ID});
- }
- } else {
- sendMessage($messageSender, $type, getResponse("healF3"), $user) if $config{verbose};
- }
- } elsif ($switch eq "kyrie"){
- my $targetID = getIDFromChat(%players, $user, $after);
- if ($targetID eq "") {
- sendMessage($messageSender, $type, getResponse("healF1"), $user) if $config{verbose};
- } elsif ($char->{skills}{PR_KYRIE}{lv} > 0) {
- my $failed = 1;
- for (my $i = $char->{skills}{PR_KYRIE}{lv}; $i >= 1; $i--) {
- if ($char->{sp} >= $skillsSP_lut{PR_KYRIE}{$i}) {
- main::ai_skillUse('PR_KYRIE', $i, 0, 0, $targetID);
- $failed = 0;
- last;
- }
- }
- if (!$failed) {
- sendMessage($messageSender, $type, getResponse("healS"), $user) if $config{verbose};
- }else{
- sendMessage($messageSender, $type, getResponse("healF2"), $user) if $config{verbose};
- }
- } else {
- sendMessage($messageSender, $type, getResponse("healF3"), $user) if $config{verbose};
- }
- $timeout{ai_thanks_set}{time} = time;
- } elsif ($switch eq "mag"){
- my $targetID = $accountID;
- if ($char->{skills}{PR_MAGNIFICAT}{lv} > 0) {
- my $failed = 1;
- for (my $i = $char->{skills}{PR_MAGNIFICAT}{lv}; $i >= 1; $i--) {
- if ($char->{sp} >= $skillsSP_lut{PR_MAGNIFICAT}{$i}) {
- main::ai_skillUse('PR_MAGNIFICAT', $i, 0, 0, $targetID);
- $failed = 0;
- last;
- }
- }
- if (!$failed) {
- sendMessage($messageSender, $type, getResponse("healS"), $user) if $config{verbose};
- }else{
- sendMessage($messageSender, $type, getResponse("healF2"), $user) if $config{verbose};
- }
- } else {
- sendMessage($messageSender, $type, getResponse("healF3"), $user) if $config{verbose};
- }
- $timeout{ai_thanks_set}{time} = time;
- } else {
- return 0;
- }
- return 1;
- }
- # Automatically reply to a chat message
- sub processChatResponse {
- return unless ($AI == 2);
- my $cmd = shift;
- my $msg = lc $cmd->{msg};
- my $reply;
- my $repeating;
- # Check whether the user is repeating itself
- $msg =~ s/^ +//;
- $msg =~ s/ +$//;
- if (defined $lastInput{msg} && $lastInput{user} eq $cmd->{user} && $lastInput{msg} eq $msg) {
- $repeating = $cmd->{repeating} = 1;
- }
- # Determine a reply
- Plugins::callHook('ChatQueue::processChatResponse', $cmd);
- if (defined $cmd->{reply}) {
- $reply = $cmd->{reply};
- } elsif (!$repeating && ($cmd->{type} eq "c" || $cmd->{type} eq "pm") && !$cities_lut{$field{name}.'.rsw'}) {
- foreach my $item (@chatResponses) {
- my $word = quotemeta $item->{word};
- if ($msg =~ /${wordSplitters}${word}${wordSplitters}/) {
- my $max = @{$item->{responses}};
- $reply = $item->{responses}[rand($max)];
- last;
- }
- }
- }
- return unless (defined $reply);
- # Calculate a small delay (to simulate typing)
- # The average typing speed is 65 words per minute.
- # The average length of a word used by RO players is 4.25 characters (yes I measured it).
- # So the average user types 65 * 4.25 = 276.25 charcters per minute, or
- # 276.25 / 60 = 4.6042 characters per second
- # We also add a random delay of 0.5-1.5 seconds.
- my $timeout = 0.5 + rand(1) + length($reply) / 4.6042;
- my %args = (
- time => time,
- timeout => $timeout,
- type => $cmd->{type},
- from => $cmd->{user},
- reply => $reply
- );
- AI::queue("autoResponse", %args);
- $lastInput{msg} = $msg;
- $lastInput{user} = $cmd->{user};
- }
- 1;