EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Quests::Q&A (https://www.eqemulator.org/forums/forumdisplay.php?f=599)
-   -   Perl Plugin Issue with RoF2 (https://www.eqemulator.org/forums/showthread.php?t=39348)

Nibiuno 02-11-2015 12:43 PM

Perl Plugin Issue with RoF2
 
The following quest causes character to desync in such a way that they can no longer communicate with the server after hailing. Tells do not work, but global chat does. This persists until server restart. It has something to do with plugin::check_hasitem, when there is an elsif - removing it removes the issue.

Quote:

# Discord Progression: Access to Txevu
# Created by Gonner

sub EVENT_SAY {
if ($text=~/hail/i) {
if (plugin::check_hasitem($client, 60253) && plugin::check_hasitem($client, 60252) && plugin::check_hasitem($client, 60176)) { # Splinter of the High Temple, Fragment of the High Temple, Sliver of the High Temple
quest::say("I've been expecting you. You have all three pieces to complete the mystery of Txevu. Give them to me and I will use what geomantic knowledge I have to form them into a totem of stone that will carry the trusik essence.");
} elsif (plugin::check_hasitem($client, 60253) || plugin::check_hasitem($client, 60252) || plugin::check_hasitem($client, 60176)) {
quest::say("Hello. I see you've been busy. I've heard of your exploits from the scouts in the mountains and it seems you're close to uncovering the mystery of Txevu. Return to me when you have more information");
} else {
quest::say("Greetings. I'd love to chat but I must get back to my studies. I've been learning as much as I can about geomancy and its uses. Good day.");
}
}
}

sub EVENT_ITEM {
if (plugin::check_handin(\%itemcount, 60252 => 1, 60176 => 1, 60253 => 1)) { # Splinter of the High Temple, Fragment of the High Temple, Sliver of the High Temple
quest::emote("takes the three stone pieces from you and wraps them in a soft hide covered with glyphs. He mutters some strange words and the stones begin to glow and undulate beneath the hide. You see a wind of souls swirl around you and become absorbed in the stone.");
quest::say("The essence of the trusik has been imbued into this stone. With one touch of this totem, the guardian of Txevu will recognize the spirit of its masters and let you pass.");
quest::summonitem(60254); # Cipher of Txevu
quest::setglobal("god_txevu_access",1,5,"F");
}
plugin::return_items(\%itemcount);
}
#END of FILE zone:abysmal ID:279009 -- Brevik_Kalaner.pl

Kingly_Krab 02-11-2015 03:33 PM

Find your file that has "sub check_hasitem" in it and post it, please.

Nibiuno 02-11-2015 03:42 PM

Here is the file, dated 12/10/2014:
Quote:

#checks to see if player has item
#useage plugin::check_hasitem($client, itemid);
sub check_hasitem {
my $client = shift;
my $itmchk = shift;
my $slot1;
my $itemid1;
my $augid1;
my $i;
my $body_count = $client->GetCorpseCount();
my $body_id;

#Check main inventory and cursor
for($slot1=0; $slot1<=30; $slot1++) {
$itemid1=$client->GetItemIDAt($slot1);
for($i=0; $i<5; $i++) {
$augid1=$client->GetAugmentIDAt($slot1, $i);
if($augid1==$itmchk) {
return 1;
}
}
if($itemid1==$itmchk) {
return 1;
}
}
#Check main inventory's and cursor's containers
for($slot1=251; $slot1<=340; $slot1++) {
$itemid1=$client->GetItemIDAt($slot1);
for($i=0; $i<5; $i++) {
$augid1=$client->GetAugmentIDAt($slot1, $i);
if($augid1==$itmchk) {
return 1;
}
}
if($itemid1==$itmchk) {
return 1;
}
}
#Check bank slots
for($slot1=2000; $slot1<=2015; $slot1++) {
$itemid1=$client->GetItemIDAt($slot1);
for($i=0; $i<5; $i++) {
$augid1=$client->GetAugmentIDAt($slot1, $i);
if($augid1==$itmchk) {
return 1;
}
}
if($itemid1==$itmchk) {
return 1;
}
}
#Check bank's containers
for($slot1=2030; $slot1<=2190; $slot1++) {
$itemid1=$client->GetItemIDAt($slot1);
for($i=0; $i<5; $i++) {
$augid1=$client->GetAugmentIDAt($slot1, $i);
if($augid1==$itmchk) {
return 1;
}
}
if($itemid1==$itmchk) {
return 1;
}
}
#Check shared bank
for($slot1=2500; $slot1<=2501; $slot1++) {
$itemid1=$client->GetItemIDAt($slot1);
for($i=0; $i<5; $i++) {
$augid1=$client->GetAugmentIDAt($slot1, $i);
if($augid1==$itmchk) {
return 1;
}
}
if($itemid1==$itmchk) {
return 1;
}
}
#Check shared bank's containers
for($slot1=2531; $slot1<=2550; $slot1++) {
$itemid1=$client->GetItemIDAt($slot1);
for($i=0; $i<5; $i++) {
$augid1=$client->GetAugmentIDAt($slot1, $i);
if($augid1==$itmchk) {
return 1;
}
}
if($itemid1==$itmchk) {
return 1;
}
}
#Check corpses
if ($body_count > 0) {
for ($i=1; $i<=$body_count; $i++) {
$body_id = $client->GetCorpseID($i);
for ($slot1=0; $slot1<=30; $slot1++) {
$itemid1 = $client->GetCorpseItemAt($body_id, $slot1);
if ($itemid1 == $itmchk) {
return 1;
}
}
for ($slot1=251; $slot1<=340; $slot1++) {
$itemid1 = $client->GetCorpseItemAt($body_id, $slot1);
if ($itemid1 == $itmchk) {
return 1;
}
}
}
}
return 0;
}

1;

epilz 02-11-2015 03:42 PM

I am having the same exact problem. Below is my check_hasitem plugin.
File dated 1/16/15.

Code:

#checks to see if player has item
#useage plugin::check_hasitem($client, itemid);
sub check_hasitem {
    my $client = shift;
    my $itmchk = shift;
    my $slot1;
    my $itemid1;
    my $augid1;
    my $i;
    my $body_count = $client->GetCorpseCount();
    my $body_id;

#Check main inventory and cursor
    for($slot1=0; $slot1<=30; $slot1++) {
        $itemid1=$client->GetItemIDAt($slot1);
      for($i=0; $i<5; $i++) {
        $augid1=$client->GetAugmentIDAt($slot1, $i);
        if($augid1==$itmchk) {
            return 1;
        }
      }
        if($itemid1==$itmchk) {
            return 1;
        }
    }
#Check main inventory's and cursor's containers
    for($slot1=251; $slot1<=340; $slot1++) {
        $itemid1=$client->GetItemIDAt($slot1);
      for($i=0; $i<5; $i++) {
        $augid1=$client->GetAugmentIDAt($slot1, $i);
        if($augid1==$itmchk) {
            return 1;
        }
      }
        if($itemid1==$itmchk) {
            return 1;
        }
    }
#Check bank slots
    for($slot1=2000; $slot1<=2015; $slot1++) {
        $itemid1=$client->GetItemIDAt($slot1);
      for($i=0; $i<5; $i++) {
        $augid1=$client->GetAugmentIDAt($slot1, $i);
        if($augid1==$itmchk) {
            return 1;
        }
      }
        if($itemid1==$itmchk) {
            return 1;
        }
    }
#Check bank's containers
    for($slot1=2030; $slot1<=2190; $slot1++) {
        $itemid1=$client->GetItemIDAt($slot1);
      for($i=0; $i<5; $i++) {
        $augid1=$client->GetAugmentIDAt($slot1, $i);
        if($augid1==$itmchk) {
            return 1;
        }
      }
        if($itemid1==$itmchk) {
            return 1;
        }
    }
#Check shared bank
    for($slot1=2500; $slot1<=2501; $slot1++) {
        $itemid1=$client->GetItemIDAt($slot1);
      for($i=0; $i<5; $i++) {
        $augid1=$client->GetAugmentIDAt($slot1, $i);
        if($augid1==$itmchk) {
            return 1;
        }
      }
        if($itemid1==$itmchk) {
            return 1;
        }
    }
#Check shared bank's containers
    for($slot1=2531; $slot1<=2550; $slot1++) {
        $itemid1=$client->GetItemIDAt($slot1);
      for($i=0; $i<5; $i++) {
        $augid1=$client->GetAugmentIDAt($slot1, $i);
        if($augid1==$itmchk) {
            return 1;
        }
      }
        if($itemid1==$itmchk) {
            return 1;
        }
    }
#Check corpses
  if ($body_count > 0) {
    for ($i=1; $i<=$body_count; $i++) {
      $body_id = $client->GetCorpseID($i);
      for ($slot1=0; $slot1<=30; $slot1++) {
        $itemid1 = $client->GetCorpseItemAt($body_id, $slot1);
        if ($itemid1 == $itmchk) {
          return 1;
        }
      }
      for ($slot1=251; $slot1<=340; $slot1++) {
        $itemid1 = $client->GetCorpseItemAt($body_id, $slot1);
        if ($itemid1 == $itmchk) {
          return 1;
        }
      }
    }
  }
  return 0;
}

1;


NatedogEZ 02-11-2015 04:05 PM

This was a modified version ... from Kinglykrab.

Checking corpses is buggy as hell.. and this doesnt do that :p


Code:

#checks to see if player has item
#useage plugin::check_hasitem($client, itemid);
sub check_hasitem {
    my $client = shift;
    my $itemid = shift;

        my @slots = (0..30, 251..340, 2000..2023, 2030..2270, 2500..2501, 2531..2550, 9999);
        foreach $slot (@slots) {
                if ($client->GetItemIDAt($slot) == $itemid) {
                        return 1;
                }

                for ($i = 0; $i < 5; $i++) {
                        if ($client->GetAugmentIDAt($slot, $i) == $itemid) {
                                return 1;
                        }
                }
    }
        return 0;
}

1;


Kingly_Krab 02-11-2015 04:08 PM

Yeah, the version Natedog posted is a lot better, just now had checked back, didn't expect a fast response, haha.

Nibiuno 02-11-2015 04:19 PM

Updated it. Do I have to fully restart the server for the new version to be used?

NatedogEZ 02-11-2015 04:20 PM

just need to #reloadquests or whatever for the current zone.. or #reloadworld for everywhere.. (which can be laggy if lots of people are online)

epilz 02-11-2015 08:00 PM

Have not seen anymore desyncs.........yet

Uleat 02-11-2015 08:52 PM

Code:

my @slots = (0..30, 251..340, 2000..2023, 2030..2270, 2500..2501, 2531..2550, 9999);
Pretty sure that '2030..2270' starts at '2031.'


It shouldn't cause any issues, though..since it will just return -1 (not found)

NatedogEZ 02-11-2015 09:14 PM

The normal plugin checked that slot as well.. was just a copy of the slots.. minus the corpse checking. :p

c0ncrete 02-21-2018 11:15 PM

This was a re-write I'd been using without the corpse check as well. It'll let you specify which slots to check via optional bitmask.

Code:

#!/usr/bin/perl

use Switch;

# item identifier bits
use constant
{
        INVALID_ID => 0xFFFFFFFF
};

# client version bits
use constant
{
        BIT_TitaniumAndEarlier        => 0x03,
        BIT_SoFAndLater                => 0xFFFFFFFC
};

# inventory location bits
use constant
{
        invWhereWorn                => 0x01,
        invWherePersonal        => 0x02,
        invWhereBank                => 0x04,
        invWhereSharedBank        => 0x08,
        invWhereTrading                => 0x10,
        invWhereCursor                => 0x20,
        invWhereCorpse                => 0x40
};

# returns first and last slot number available in container
sub getContainerRange
{
        my $verBit        = shift->GetClientVersionBit();
        my $slotID        = shift;
        my @contSR        = (); # container slot range

        switch($slotID)
        {
                # 22-29 are personal inventory slots
                case 22 { @contSR = (251, 260); }
                case 23 { @contSR = (261, 270); }
                case 24 { @contSR = (271, 280); }
                case 25 { @contSR = (281, 290); }
                case 26 { @contSR = (291, 300); }
                case 27 { @contSR = (301, 310); }
                case 28 { @contSR = (311, 320); }
                case 29 { @contSR = (321, 330); }
                # 30 is the cursor slot
                case 30 { @contSR = (331, 340); }
                # 400-??? are tribute slots
                # 2000-2023 are bank slots
                case 2000 { @contSR = (2031, 2040); }
                case 2001 { @contSR = (2041, 2050); }
                case 2002 { @contSR = (2051, 2060); }
                case 2003 { @contSR = (2061, 2070); }
                case 2004 { @contSR = (2071, 2080); }
                case 2005 { @contSR = (2081, 2090); }
                case 2006 { @contSR = (2091, 2100); }
                case 2007 { @contSR = (2101, 2110); }
                case 2008 { @contSR = (2111, 2120); }
                case 2009 { @contSR = (2121, 2130); }
                case 2010 { @contSR = (2131, 2140); }
                case 2011 { @contSR = (2141, 2150); }
                case 2012 { @contSR = (2151, 2160); }
                case 2013 { @contSR = (2161, 2170); }
                case 2014 { @contSR = (2171, 2180); }
                case 2015 { @contSR = (2181, 2190); }
                case 2016 { @contSR = (2191, 2200); } # >= Secrets of Faydwer only
                case 2017 { @contSR = (2201, 2210); } # >= Secrets of Faydwer only
                case 2018 { @contSR = (2211, 2220); } # >= Secrets of Faydwer only
                case 2019 { @contSR = (2221, 2230); } # >= Secrets of Faydwer only
                case 2020 { @contSR = (2231, 2240); } # >= Secrets of Faydwer only
                case 2021 { @contSR = (2241, 2250); } # >= Secrets of Faydwer only
                case 2022 { @contSR = (2251, 2260); } # >= Secrets of Faydwer only
                case 2023 { @contSR = (2261, 2270); } # >= Secrets of Faydwer only
                # 2500-2501 are shared bank slots
                case 2500 { @contSR = (2531, 2540); }
                case 2501 { @contSR = (2541, 2550); }
                # 3000-3007 are character trade slots
                case 3000 { @contSR = (3031, 3040); }
                case 3001 { @contSR = (3041, 3050); }
                case 3002 { @contSR = (3051, 3060); }
                case 3003 { @contSR = (3061, 3070); }
                case 3004 { @contSR = (3071, 3080); }
                case 3005 { @contSR = (3081, 3090); }
                case 3006 { @contSR = (3091, 3100); }
                case 3007 { @contSR = (3101, 3200); }
                # 4000-???? are tradeskill slots
        }

        return @contSR;
}

# 'helper' function for plugin::check_hasitem()
sub HasItem_search
{
        my $client = shift;                                # client object
        my $findID = shift;                                # itemID to find
        my @slotIR =(shift..shift);                        # slotID range to check
        my $checkC = 0;                                        # check for containers?
          $checkC = shift if defined($_[0]);
        my $itemID = INVALID_ID;                        # default value

        # loop through specified slotID range
        for my $slotID(@slotIR)
        {
                $itemID = $client->GetItemIDAt($slotID);
                # don't check container or aug slots if no item was found
                next if $itemID == INVALID_ID;
                return 1 if $itemID == $findID;
                # check inside if item is a container
                if($checkC && $client->GetItemAt($slotID)->IsType(1))
                {
                        my @bRange = getContainerRange($client, $slotID);
                        my @search = ($client, $findID, $bRange[0], $bRange[1]);
                        return 1 if HasItem_search(@search);
                }
                # check aug slots if not a container or book
                elsif(!$client->GetItemAt($slotID)->IsType(2))
                {
                        foreach my $augID(0..4)
                        {
                                $itemID = $client->GetAugmentIDAt($slotID, $augID);
                                return 1 if($itemID == $findID);
                        }
                }
        }

        return 0;
}

# TO DO
sub HasItem_corpse
{
}

# usage: plugin::check_hasitem($client, itemID, [$lookIn]);
sub check_hasitem
{
        # get client info
        my $client = shift;
        my $verBit = $client->GetClientVersionBit();
        my $hasSoF = ($verBit & BIT_SoFAndLater) ? 1 : 0;

        # itemID to find
        my $findID = shift;

        # inventory buckets to search
        # default to all but shared
        my $lookIn = 55;
          $lookIn = shift if defined($_[0]);

        # lower/upper slot num to search
        my $lRange = -1; my $uRange = -1;

        # arguments for HasItem_search
        my @search = ($client, $findID, $lRange, $uRange);

        # check worn inventory slots
        if($lookIn & invWhereWorn)
        {
                $search[-2] = 0; $search[-1] = 21;
                return 1 if(HasItem_search(@search));
        }

        # check for containers from now on
        push(@search, 1);

        # check personal inventory slots
        if($lookIn & invWherePersonal)
        {
                $search[-3] = 22; $search[-2] = 29;
                return 1 if(HasItem_search(@search));
        }

        # check cursor inventory slots
        if($lookIn & invWhereCursor)
        {
                $search[-3] = 30; $search[-2] = 30;
                return 1 if(HasItem_search(@search));
        }

        # check bank invenory slots
        if($lookIn & invWhereBank)
        {
                $search[-3] = 2000; $search[-2] = 2015;
                $search[-2] = 2023 if($hasSoF);
                return 1 if(HasItem_search(@search));
        }

        # check shared bank inventory slots
        if($lookIn & invWhereSharedBank)
        {
                $search[-3] = 2500; $search[-2] = 2501;
                return 1 if(HasItem_search(@search));
        }

        # check character trade slots
        if($lookin & invWhereTrading)
        {
                $search[-3] = 3000; $search[-2] = 3007;
                return 1 if(HasItem_search(@search));
        }

        # check all corpses
        # NOTE: This makes a database read for the itemID 31 times for each corpse!
        if($lookin & invWhereCorpse)
        {
                # my $bodCount = $client->GetCorpseCount();
                # return 0 if(!$bodCount);
                # for (my $bodNum = 1; $bodNum <= $bodCount; $bodNum++)
                # {
                #        return 1 if(HasItem_corpse());
                # }
        }

        return 0;
}

1;



All times are GMT -4. The time now is 03:47 PM.

Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.