Skip to content
This repository has been archived by the owner on Dec 2, 2021. It is now read-only.

Make Plugin With Dyno

Y&SS edited this page Jun 29, 2018 · 9 revisions

To begin with, when we talk about Dyno, we are not talking about DynoPM. Dyno is the program that manages the bases. DynoPM is the plugin for PocketMine that uses the Dyno API.

Connection with Dyno using DynoPM

Yes, to be able to use Dyno, you have to connect to it.

Once DynoPM was installed on your PocketMine server, a configuration was generated in the plugin folder: config.yml.

This file looks like this:

# Configuration Dyno PocketMine !
# Do not delete this line
ConfigVersion: 1.0
    
enabled: true
    
dynos:
 - enabled: false
   ip: 127.0.0.1
   port: 10102
   description: "Dyno PM"
   password: DynoPasswordHere

To be able to connect to Dyno, you must switch Enabled to true in the dynos section. After that, write down your Dyno IDs.

Once the connection is successful, Your Dyno will automatically detect that DynoPM has successfully connected otherwise it will send you an error explaining why it failed.

Information to know

You can connect to more than one Dyno at a time!

Example:

dynos:
     - enabled: true
       ip: 127.0.0.1
       port: 10102
       description: "My Super Dyno A"
       password: BestPasswordA
     - enabled: true
       ip: 127.0.0.1
       port: 10103
       description: "My Super Dyno B"
       password: BestPasswordB

Use DynoPM on my plugin

To connected to dyno on your plugin, there are several solutions. But only one is recommended. You can use:

use dynoPM\DynoPM; //Import
    
$this->dyno = DynoPM::getInstance()->getDynoByDescription($dynoDesc);

But that's really not advisable! Why? Why? If Dyno stops or there is a network problem, your Plugin will still try to send requests to Dyno, and this will cause a lot of bugs and exceptions in your console.

This is why DynoPM has an integrated function to avoid this, it is advisable to do :

//Import
use dynoPM\{
    DynoPM,
    Dyno
}; 
    
/** Dyno */
private $dyno;
    
public function onEnable()
{
    $dynoDesc = "My Super Dyno Desc";
     DynoPM::getInstance()->addPluginSyncWithDynoDescription($this, $dynoDesc);
     if (($this->dyno = DynoPM::getInstance()->getDynoByDescription($dynoDesc)) === null) {
        $this->getServer()->getPluginManager()->disablePlugin($this);
        return;
    }
    $this->getServer()->getLogger()->info("Plugin Started !");
}

The addPluginSyncWithDynoDescription(Plugin $plugin, string $dynoDesc) function allows you to add your plugin to a plugin list. Every 2 seconds this list will be checked to see if the connection is still good with dyno.

With this function your plugin will be automatically disabled if it sees that the dyno you noted has a connection problem. But don't panic! Your plugin will also be automatically reactivated once the connection is found!

Once that done, congratulations your plugin is connected to Dyno!

You can add a function like :

/**
 * @return Dyno
 */
public function getDyno(): Dyno
{
    return $this->dyno;
}

To be able to interact with DynoPM and Dyno.

Interact with Dyno

Now, I suppose you'll tell me "That's very good I managed to connect to dyno but now? How can I use this?" And you'd be totally right.

Before continuing, it should be known that Dyno uses Packets, that's how it happens to manage DynoPM connections etc.. But we, we will only use 1 packet in all: inputPacket.

For real, we'll use two, but we'll see the other later.

inputPacket allows you to send information to Dyno like: "Create a database, create a table, remove a table..."
But this in the form of Json.

It would be far too complicated to use Json directly to communicate with Dyno. That's why Dyno has created a library that facilitates this and that we will use dynoLibPacket (library already in DynoPM, No need to download it)

This library contains many functions, so we will see the base.

Create Base with DynoPM in Dyno

As said before, we will use the packet inputPacket and the library dynoLibPacket. We advise you to use an IDE to facilitate development.

To create a database, you can create it directly on Dyno with commands, but we, for example, will do it directly on plugin.

//Import
use dynoLibPacket\inputPacketLib;
use dynoPM\network\packages\executor\inputPacket;
    
$pk = new inputPacket();
$final = new inputPacketLib();
$final = $final
     ->createBase("Your base name")
     ->finalInput();
$pk->input = $final;
$this->getDyno()->sendDataPacket($pk);

Yes, it will create a base. Except if you do this again, it will send an exception.
Dyno sends a lot of exceptions that allow us to correct mistakes that we can make. (You can see all exceptions on Dyno's readme.md)
Interfaces are available in dynoLibPacket\libOptions for instructions.

//import
use dynoLibPacket\libOptions\BaseOptionsInterface;
    
$pk = new inputPacket();
$final = new inputPacketLib();
$final = $final
     ->createBase("Your base name, [
         BaseOptionsInterface::ONLY_IF_BASE_NOT_EXIST
     ])
     ->finalInput();
$pk->input = $final;
$this->getDyno()->sendDataPacket($pk);

finalInput() transform the requete into json : It is therefore essential to add finalInput() at the end if you want the request to work

Put Key:Value with DynoPM in Dyno

To be able to put a value, it is necessary that the base exists and that the table exists otherwise it will return an exception

In the example below, we will create a value without checking if the table, as well as the base exists! (If the base or table does not exist, there will be an exception!)

$pk = new inputPacket();
$final = new inputPacketLib();
$final = $final
     ->getBase("Your Base Name")
     ->getTable("Your Table Name")
     ->putString("Hello", "YO !")
     ->putBool("I Like Apple", true)
     ->finalInput();
$pk->input = $final;
$this->getDyno()->sendDataPacket($pk);

If you put a key that already exists, the key will be replaced

Get Key:Value with DynoPM in Dyno

Here is the most "complicated" part to understand. It's not hard to understand, you just have to understand how Dyno works when you send inputPacket. We'll send an inputPacket to Dyno that asks him to retrieve an information

$pk = new inputPacket();
$final = new inputPacketLib();
$final = $final
     ->getBase("Your Base Name")
     ->getTable("Your Table Name")
     ->getString("Hello")
     ->getBool("I Like Apple")
     ->finalInput();
$pk->input = $final;
$this->getDyno()->sendDataPacket($pk);

We will get outputPacket with the DynoPM event: OutputPacketReceivedEvent

//event
use dynoPM\event\packet\OutputPacketReceivedEvent;
    
public function outPut(OutputPacketReceivedEvent $event)
{
    $packet = $event->getPacket();
    var_dump($packet);
}

Now you're probably going to ask yourself "Yes, but if I ask for several Packets at a time on several different plugins, how can I be sure that this is the package I want and not another?"

We will assign a key to inputPacket and this key can be retrieved in outputPacket.

$pk = new inputPacket();
$final = new inputPacketLib();
$final = $final
     ->getBase("Your Base Name")
     ->getTable("Your Table Name")
     ->getString("Hello")
     ->getBool("I Like Apple")
     ->finalInput();
$pk->input = $final;
$pk->tunnelKey = "My Key"; //Key to retrieve the packet in outputPacket 
$this->getDyno()->sendDataPacket($pk); 

And now you can retrieve the Packet with the requested information (All requested information is in $packet->getter)

//event
use dynoPM\event\packet\OutputPacketReceivedEvent;
    
public function outPut(OutputPacketReceivedEvent $event)
{
    $packet = $event->getPacket();
    if($packet->tunnelKey == "My Key"){
        echo $packet->getter[0]; //If the value of Hello were "Yo !" (string) it would return "Yo !" (string)
        echo $packet->getter[1] //If the value of "I like Apple" were "true" (bool) it would return "true" (bool)
        var_dump($packet);
    }
}    

That's better, we can get the information now! But you probably noticed that it's not practical, because we have to do $packet->getter[0] without knowing if the value we're asking for is the right one. And in addition to that if we want to retrieve several information not in order this is not practical.
For that we will use the same system, we will give a key to the information that we want to be able to recover it by this key and not by $packet->getter[0].

$pk = new inputPacket();
$final = new inputPacketLib();
$final = $final
     ->getBase("Your Base Name")
     ->getTable("Your Table Name")
     ->getString("Hello", "I want get Hello")
     ->getBool("I Like Apple", "I want get Apple")
     ->finalInput();
$pk->input = $final;
$pk->tunnelKey = "My Key"; //Key to retrieve the packet in outputPacket 
$this->getDyno()->sendDataPacket($pk);

And now we can recover the value

public function outPut(OutputPacketReceivedEvent $event)
{
    $packet = $event->getPacket();
    if($packet->tunnelKey == "My Key"){
        echo $packet->getter["I want get Hello"]; //If the value of "I want get Hello" were "Yo !" (string) it would return "Yo !" (string)
        echo $packet->getter["I want get Apple"] //If the value of "I like Apple" were "true" (bool) it would return "true" (bool)
        var_dump($packet);
    }
}

Now imagine there is a message in your database with key 'send.message.player' that says "Hello" and you want to send this message to the player with her name when he joins the game.
As normal we will use:

//Event
use pocketmine\event\player\PlayerJoinEvent; 
    
public function onJoin(PlayerJoinEvent $event)
{
    $player = $event->getPlayer();
    $pk = new inputPacket();
    $final = new inputPacketLib();
    $final = $final
         ->getBase("Your Base Name")
         ->getTable("Your Table Name")
         ->getString("send.message.player")
         ->finalInput();
    $pk->input = $final;
    $pk->tunnelKey = "My Key"; //Key to retrieve the packet in outputPacket 
    $this->getDyno()->sendDataPacket($pk);
}

And now you're wondering how you're gonna get the player's name back. For this a "$want" function exists for inputPacket that accepts an array, so we'll pass the name of the player from

public function onJoin(PlayerJoinEvent $event)
{
    $player = $event->getPlayer();
    $pk = new inputPacket();
    $final = new inputPacketLib();
    $final = $final
         ->getBase("Your Base Name")
         ->getTable("Your Table Name")
         ->getString("send.message.player", "joinmessage")
         ->finalInput();
    $pk->input = $final;
    $pk->want = array(
        "pn" => $player->getName()
    );
    $pk->tunnelKey = "My Key"; //Key to retrieve the packet in outputPacket 
    $this->getDyno()->sendDataPacket($pk);
}

And now you can send the message with the outputPacket

public function outPut(OutputPacketReceivedEvent $event)
{
    $packet = $event->getPacket();
    if($packet->tunnelKey == "My Key"){
        $this->getServer()->getPlayer($packet->want["pn"])
            ->sendMessage($packet->getter["joinmessage"] . " " . $packet->want["pn"]);
            //Send "Hello {Name of Player}"
    }
}

Math with Dyno

It can be practical to make calculations without having recovered the value and sent it back to Dyno, for that there are calculation functions on dynLibPacket.

$pk = new inputPacket();
$final = new inputPacketLib();
$final = $final
     ->getBase("Your Base Name")
     ->getTable("Your Table Name")
     ->valueMath("Your Key")->addition(2) //If the value of key is 2 (int), it will go to 4 (int)
     ->finalInput();
$pk->input = $final;
$this->getDyno()->sendDataPacket($pk);

FAQ

How DynoPM and Dyno Work when i send inputPacket ?

When you send a Packet (inputPacket) to Dyno it behaves like this:

We will send a Packet (inputPacket) to Dyno from DynoPM; Dyno will analyze the Packet, and return a Packet (outputPacket).

This outputPacket contains information / exceptions that can be taken over if needed.