Solved Error when attempting to store inventory

Discussion in 'Development' started by sheepspringer2004, Jan 8, 2022.

  1. sheepspringer2004

    sheepspringer2004 Creeper

    Messages:
    5
    GitHub:
    joebado
    Purpose
    Store the inentory of a chest, and make it accessibly by players at any time.
    Error
    [LOG]

    [13:46:48.252] [Server thread/CRITICAL]: LogicException: "Serialization of pocketmine\item\enchantment\Enchantment objects is not allowed" (EXCEPTION) in "pmsrc/src/utils/NotSerializable" at line 30
    --- Stack trace ---
    #0 plugins/EnderChest/src/Seeker/EnderChest/data/tasks/SavePlayerDataTask(20): pocketmine\item\enchantment\Enchantment->__serialize()
    #1 plugins/EnderChest/src/Seeker/EnderChest/EventListener(26): Seeker\EnderChest\data\tasks\SavePlayerDataTask->__construct(string[11] seekpop8419, string[73] /home/seeker/Documents/PocketMine/plugin_data/EnderChest/data/seekpop8419, array[1])
    #2 pmsrc/src/event/RegisteredListener(75): Seeker\EnderChest\EventListener->onQuit(object pocketmine\event\player\PlayerQuitEvent#113899)
    #3 pmsrc/src/event/Event(62): pocketmine\event\RegisteredListener->callEvent(object pocketmine\event\player\PlayerQuitEvent#113899)
    #4 pmsrc/src/player/Player(1997): pocketmine\event\Event->call()
    #5 pmsrc/src/network/mcpe/NetworkSession(579): pocketmine\player\Player->onPostDisconnect(string[17] client disconnect, NULL )
    #6 pmsrc/src/network/mcpe/NetworkSession(512): pocketmine\network\mcpe\NetworkSession->pocketmine\network\mcpe\{closure}()
    #7 pmsrc/src/network/mcpe/NetworkSession(581): pocketmine\network\mcpe\NetworkSession->tryDisconnect(object Closure#111410, string[17] client disconnect)
    #8 pmsrc/src/network/mcpe/raklib/RakLibInterface(151): pocketmine\network\mcpe\NetworkSession->onClientDisconnect(string[17] client disconnect)
    #9 pmsrc/vendor/pocketmine/raklib-ipc/src/RakLibToUserThreadMessageReceiver(75): pocketmine\network\mcpe\raklib\RakLibInterface->onClientDisconnect(integer 0, string[17] client disconnect)
    #10 pmsrc/src/network/mcpe/raklib/RakLibInterface(122): raklib\server\ipc\RakLibToUserThreadMessageReceiver->handle(object pocketmine\network\mcpe\raklib\RakLibInterface#23633)
    #11 pmsrc/vendor/pocketmine/snooze/src/SleeperHandler(123): pocketmine\network\mcpe\raklib\RakLibInterface->pocketmine\network\mcpe\raklib\{closure}()
    #12 pmsrc/vendor/pocketmine/snooze/src/SleeperHandler(82): pocketmine\snooze\SleeperHandler->processNotifications()
    #13 pmsrc/src/Server(1657): pocketmine\snooze\SleeperHandler->sleepUntil(double 1641649608.2942)
    #14 pmsrc/src/Server(1044): pocketmine\Server->tickProcessor()
    #15 pmsrc/src/PocketMine(303): pocketmine\Server->__construct(object BaseClassLoader#3, object pocketmine\utils\MainLogger#2, string[34] /home/seeker/Documents/PocketMine/, string[42] /home/seeker/Documents/PocketMine/plugins/)
    #16 pmsrc/src/PocketMine(326): pocketmine\server()
    #17 pmsrc(11): require(string[78] phar:///home/seeker/Documents/PocketMine/PocketMine-MP.phar/src/PocketMine.php)
    [/LOG]
    Summary: Enchanted items and TieredTool s cannot be stored. Normal items do not cause an error but do not store either.
    Relevant code
    PHP:
    // SavePlayerDataTask to save the data
    public function onRun() : void
    {
        if(
    $this->reload === true) {
            
    file_put_contents($this->path, []);
        } else {
            
    $contents = [];
            foreach(
    $this->inventory as $slot => $item) {
                
    $contents[] = $item->nbtSerialize($slot);
            }
            if(!empty(
    $contents)) {
                
    $contents zlib_encode((new BigEndianNbtSerializer())->write(new TreeRoot(CompoundTag::create()->setTag(PlayerData::INVENTORY_TAG, new ListTag($contentsNBT::TAG_Compound)))), ZLIB_ENCODING_GZIP);
            }
            
    var_dump($contents);
            
    file_put_contents($this->path$contents);
        }
    }
    PHP:
    // LoadPlayerDataTask to load the data
    public function onRun() : void
    {
        if(!
    is_file($this->path)){
            
    $this->setResult(self::FILE_NOT_FOUND);
            return;
        }
        
    $data file_get_contents($this->path);
        
    $inventory = [];
        if(
    $data) {
            
    var_dump($data);
            
    $decompressed zlib_decode($data);
            if(
    $decompressed === false) {
                
    Server::getInstance()->getLogger()->error('Could not decode data!');
                return;
            }
            
    $tag = (new BigEndianNbtSerializer())->read(zlib_decode($data))->mustGetCompoundTag();
            foreach(
    $tag->getListTag(PlayerData::INVENTORY_TAG) as $item) {
                
    $inventory[$tag->getByte("Slot")] = Item::nbtDeserialize($item);
            }
        }
        
    $this->setResult([$this->name$inventory]);
    }
    I've been trying to fix this for a while, and took reference from PlayerVaults by Muqsit and pocketmine source code.
    THe version I'm using is API 4.0.3. Thanks.
     
  2. BloodyJohnRus

    BloodyJohnRus Spider

    Messages:
    12
    GitHub:
    GDSHNIK
    It's saying about serialization - it's not allowed. So, you can't serialine Enchantment class at line 30 - search it.
     
  3. sheepspringer2004

    sheepspringer2004 Creeper

    Messages:
    5
    GitHub:
    joebado
    How else am I supposed to save an inventory out of memory?
     
  4. BloodyJohnRus

    BloodyJohnRus Spider

    Messages:
    12
    GitHub:
    GDSHNIK
    When it's out of memory, i think you should save inventory on plugin disabling, but idk, if the players been at the server at plugin disable. I think it's better to make task on every 5-10 min to save items inventory. Example:
    Saving:
    PHP:
    foreach(players as $p)
    {
    $n=$p->getName();
    $items=$p->getInventory()->getContents(true);//saving places with empty slots.
    $this->config->set("$n",$items);//It's important to have config.yml file.
    $this->config->save();
    }
    One minute, i post example of loading inv
     
  5. BloodyJohnRus

    BloodyJohnRus Spider

    Messages:
    12
    GitHub:
    GDSHNIK
    I don't work on API 4, but:
    PHP:
    //login function
    $n=$e->getPlayer()->getName();
    $items=$this->config->get("$n");
    $e->getPlayer()->getInventory()->internalSetContents([]);//Important! You need delete all items from inventory, and then add itrms from config, becuz this all items may not put in inventory.
    $e->getPlayer()->getInventory()->internalSetContents($items);
    I checked imports, this code is OK.
     
  6. sheepspringer2004

    sheepspringer2004 Creeper

    Messages:
    5
    GitHub:
    joebado
    Mankind believed it could not be done (the only opinion mankind shared as a whole), but this man, THIS individual of supreme intellect, managed to do the impossible. He disproved the entirety of the human population, and made them bow their heads in shame. Humanity is now nothing more than a souvenir of his omnipotence.
    Jesus Christ, there is so much wrong with this post.
    "When it's out of memory, I think you should save inventory on plugin disabling.*
    I don't really get why I'd do that though. I can literally just store the inventory as soon as the player quits, to save memory, and assuming I don't do it on the main thread (which why would I?), there is minimal performance impact.
    "I think it's better to make task on every 5-10 min to save items inventory"
    See answer above.
    "The code"
    'players' is a constant instead of a variable, but it's obviously a typo so sorry for the nitpicking. I feel like I don't even have to say what's wrong with directly storing the returned values from getContents() in a database.
    The same goes for the second post.
    P.S: This is all a joke, but your posts obviously do not solve my issue/provide any help. I appreciate the fact that you bothered to reply though, thanks a lot man (please forgive me if you're a woman, ma'dam).
    The issue remains unsolved for now.
     
  7. NTT

    NTT Zombie

    Messages:
    304
    GitHub:
    NTT1906
    I suggest you should go and see how enderchest and some other vault plugin did that...?
     
  8. sheepspringer2004

    sheepspringer2004 Creeper

    Messages:
    5
    GitHub:
    joebado
    sorry, forgot to mention. it's fixed, i just had to read the stack. the error wasn't te one i was expected, it was related to threads. ty.
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.