Home - gusta7w7/PocketMine-API-2.0.0-Wiki GitHub Wiki

Bem-vindo a Wiki!

Essa Te Ensina a Como Criar um Plugin de Pocketmine Api 2.0.0 Do Zero.

Criador da Wiki: PeMapModder em 2016

Quem Traduziu e Melhorou essa Wiki? Sr_abelha ou abelha7w7

Discord: @abelha7w7

Inicio em 03/03/24 as 11:42

Termino em 03/03/24 as 20:37

youtube logo

ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ ㅤㅤㅤㅤㅤㅤㅤㅤ

Avisos

  • Este é um lugar para contribuições públicas. Todos podem editar essa wiki, mas por favor tenha em mente que enquanto edita, o wiki deve ser puramente informativo e neutro.

  • Essa Wiki Pode Estar Com Algumas Coisas Desatualizadas ja que essa wiki foi criada em 2016 Então Eu Sr_abelha Estou Fazendo de Tudo para deixar a Wiki Atualizada E Traduzida Para o Publico Que Quer Programar e Fazer Um Plugin da Forma Facil E Eficiente.

  • Se Voce Quiser Converter Essa Wiki Para O Formato .Pdf Eu Não Recomendo Pois a Visualizacão Não Fica Muito Legal 😥

ㅤㅤㅤㅤㅤ

Introducão

Este tutorial, ao contrário de alguns outros tutoriais, é baseado em testar e depois explicar. Como entender tudo sobre os plugins do PocketMine requer um profundo conhecimento de programação, este tutorial tenta explicar tudo e tornar tudo sensato, mas às vezes eu simplesmente digo Faça isso no seu código, eu não vou explicar. Nesses pontos, é porque você não tem conhecimento suficiente da base. Explicarei quando tiver conhecimento suficiente para entender.

Outra caraterística deste tutorial é que ele incentiva o pensamento crítico. Quando aprende algo novo, é encorajado a pensar em questões sobre o assunto, ou a desafiar a exatidão do tutorial, descobrindo possíveis contradições. Pensar nestas questões pode ajudá-lo a aprender e a clarificar a sua mente. A curto prazo, reforça a sua memória e ajuda a construir uma estrutura mais sólida. A longo prazo, treina as suas capacidades de raciocínio, e o pensamento crítico é bastante útil na vida real.

Requisitos

Este tutorial foi escrito para o "público em geral", o que significa que se espera que seja lido por todos. Entretanto, há algumas coisas muito básicas que você precisa entender:

  • Como rodar um servidor PocketMine básico.
  • Como instalar plugins no PocketMine.
  • Conhecimentos básicos de informática, tais como a noção de arquivos.
  • Saber a Profundamente a Programar Em PHP Que Nem Eu disse Na Introducão.
  • Não Ter Um Dispositivo Tão Antigo Para Não Ter Problemas De Compatibilidade.

Introdução à programação.

Deixem-me explicar o que é a programação. O que nois vem com à cabeça quando falo de "programação"? Um programador com um computador que mostra um monitor preto como o de um console de um servidor PocketMine? Um monte de caracteres e símbolos sem sentido?

Vamos lá perceber a ideia correcta de "programar", pelo menos em termos de plugins PocketMine. Aqui, vamos escrever código PHP, que é uma linguagem bastante fácil de aprender. A codificação é um processo muito lógico e legível para o ser humano.

Como prova, vejamos este exemplo de linha de código:

$player->sendMessage("Hello world!");

Na linha acima significa sendMessage (enviar uma mensagem) para um jogador $player com a mensagem Hello world!.

Voce Tambem Pode Usar Cores Na Mensagem Utlizando Esse Simbolo: §

Por Exemplo Esse Codigo:

$player->sendMessage("§aHello world!");

Que Significa Que Mandara Uma Mensagem Usando o sendMessage e Mandara Essa Mensagem Para O Jogador No Caso $player-> E Vai Mandar Uma Mensagem No Chat Com A Cor Verde

Os códigos de formatação permitem personalizar o texto no jogo. Eles são baseados no símbolo §

Se Voce não Souber As Cores e Estilos de Letra Tipo Negrito Ou O Italico Dentro do Minecraft PE Voce Pode Consultar a Wiki Do Minecraft.

So Avisando que Alguns Codigos de Formatacão Não funcionará Direito Nas Versões Antigas Ou Versões como 0.14.x & 0.15.x

Isso Porcausa Das Atualizações do Minecraft PE Que Ao Longo do Tempo Foi Adcionando Novas Cores e Estilos de Letra.

Como pode ver, desde que não tenha fobia a monospace (o tipo de letra normalmente usado para codificação, que é também o tipo de letra usado no console do PocketMine), codificar pode ser muito fácil e divertido. É como trabalhar com redstone no Minecraft; podes fazer uma simples configuração de alavanca para abrir portas, mas também podes fazer uma complicada "calculadora" Minecraft ou arenas de mob. A única diferença é que, na codificação, não temos tantos gráficos, mas sim palavras e símbolos. No entanto, é óbvio que a programação é muito mais poderosa.

A documentação oficial do PHP dizia em qualquer lugar

... é muito perigoso porque permite a execução de código PHP não autorizado.

Ser capaz de escrever e executar código dá-nos um poder ilimitado. Leva-nos ao topo do mundo. Depois de finalmente terminar uma peça de software após um longo período de tentativas e erros, parece que voou através das estrelas e agora está lá, a realizar o seu sonho. Estás pronto para isso?

Criando Arquivo plugin.yml

Agora vamos criar o nosso primeiro plugin. Vou chamar ele de MyPlugin.

Aviso: Voce Pode Colocar Qualquer Nome Para Seu Plugin.

Em primeiro lugar, em qualquer lugar do seu dispositivo, crie um diretório vazio (pasta, caso não perceba) chamado MyPlugin. Por uma questão de conveniência, vou assumir que a diretorio é /plugins/MyPlugin. No entanto, seria conveniente para testes se o criasse na pasta de plugins do seu servidor de testes.

Este diretório MyPlugin conterá todos os arquivos necessários em um plugin, ou seja, plugin.yml, src (código fonte) e resources.

As informações básicas do plugin, incluindo o nome do plugin, versão e autor (Seu Nome), são especificadas em um arquivo chamado plugin.yml. Aqui está um exemplo:

name: MyPlugin
version: 1.0.0
author: Seu_Nome
api: 2.0.0
main: yourname\myplugin\MyPlugin

As três primeiras linhas são óbvias, mas acho que as duas últimas linhas precisam de uma pequena explicação.

api é a versão da API do PocketMine com a qual o plugin é compatível. Você não precisa entender isso no momento; simplesmente copie essa linha. Basicamente, significa se o plugin pode rodar na versão atual do PocketMine, mas não está relacionado ao código de lançamento como 1.5.

main é o nome totalmente qualificado da sua classe principal. Sim, eu sei, você entendeu cada palavra, mas não entendeu o que eu quis dizer. Isso será explicado na próxima secção.

Então, crie um arquivo chamado plugin.yml em /plugins/MyPlugin e copie as coisas acima para ele.

Editores de Codigo.

Para Usuarios De Windows, Mac, Linux Eu Recomendo Utilizar o Visual Studio Code ou o JetBrains (PHP Storm)

Ambos os Editores de codigo são muito bons para criar plugins para pocketmine e outras linguagens de programacão.

Para Usuarios De Android Recomendo Utilizar o Acode Ou Tambem Voce Pode Usar O Editor De Codigo Chamado QuickEdit Ambos os 2 São Otimos Para Modificar Codigos Mas O QuickEdit tem Anuncios e isso pode afetar a sua programacão a maioria das vezes. Então se voce quiser o QuickEdit Sem Anuncios Ou Voce Tera que Pagar a Versão Pro Ou Voce Tera Que Pesquisar o Apk do QuickEdit Pro No Google Nesse Link A Mesma Coisa Com o Acode Tem Uma Versão Paga Que e Muito Boa Tambem.

E Para Usuarios de Iphone (Ios) Eu não sei Qual e o Bom e o Recomendado Mas Voce Pode Usar Qualquer Um Que de Para Editar Arquivos de Linguagem de Programacão como arquivos .php, .yml etc.

Aviso: Voce Tambem Pode Usar Outro Editor de Codigo de Sua Preferencia Tanto

Windows, Mac, Linux, Android e Iphone (Ios)

Truque

Crie um novo arquivo no seu gerenciador de arquivos, copie o conteúdo para ele e clique em Salvar como. Navegue até /plugins/MyPlugin e coloque plugin.yml como nome do arquivo, então e so salvar não tem segredo nenhum.

Primeiro Arquivo PHP

Calma, Não é tão assustador assim.

Agora, crie os seguintes diretórios:

/plugins/MyPlugin/src/
/plugins/MyPlugin/src/yourname/
/plugins/MyPlugin/src/yourname/myplugin/

Agora, crie um arquivo vazio em /plugins/MyPlugin/src/yourname/myplugin/, chamado MyPlugin.php. Isso é familiar? Sim, é o atributo main: no plugin.yml mencionado acima. Agora vamos falar sobre o que tudo isso significa.

Para organizar melhor o código, o PHP nos permite agrupar nosso código utilizando classes. O conceito real de classes é bastante complicado, mas por enquanto, apenas assuma-o como a maneira de agrupar código.

O nome de uma classe pode ser a combinação de {A-Z a-z 0-9 _}, mas não deve começar com um número. É prática comum de muitos desenvolvedores que as classes sejam nomeadas usando o estilo "camel hump", e o primeiro caractere é sempre maiúsculo, assim:

Escrito No Brasil nome da classe
Ola Mundo OlaMundo
my plugin MyPlugin
Meu Primeiro Plugin MyFirstPMPlugin
Anti 3P Anti3P
Erro Interno No Servidor 500 _ErroInternoNoServidor500 or ErroInternoServidor500

Não existe uma regra rígida sobre isso, mas se você nomear sua classe como meu_plugin, as pessoas podem não perceber que ela é uma classe. Isso confunde as pessoas quando elas estão tentando ajudá-lo.

Voltando ao nosso plugin, vamos dar à nossa classe principal um nome que a descreva. Então, qual é o melhor nome? O nome do plugin, claro. A melhor coisa sobre ele é que é único. Cada execução do servidor (termo técnico: PHP runtime) só carrega uma classe com o mesmo nome. Por isso, é importante ter um nome de classe único.

Espera aí. O que é essa coisa antes do nome da classe principal?

É chamado de namespace. A partir do PHP Versão 5.3.0 ou Superior Que é possível agrupar nomes de classes usando namespaces.

A coisa toda sobre namespaces e classes é como um sistema de arquivos. Namespaces são diretórios, e classes são arquivos. Na mesmo diretorio não podem existir dois arquivos ou diretorios com o mesmo nome. No entanto, se colocar os arquivos em diretorios diferentes, não haverá conflito desde que diga às pessoas de que o diretorio está pegando o arquivo. Vice-versa para os espaços de nomes. Portanto, eu estava mentindo. Um ponto a ser observado é que o separador de diretórios para arquivos é / (tudo bem, eu sei que é / ou \ no Windows), mas no PHP, as partes em namespaces são sempre separadas por \, independente do sistema operacional.

E o fato é que, não apenas é como um sistema de arquivos, mas também é baseado em um sistema de arquivos. Você deve colocar seus arquivos PHP no caminho correto de acordo com seu nome completo (também conhecido como nome totalmente qualificado, ou seja, nome de classe do namespace \), com o separador de namespace (\) alterado para o separador de diretório, dentro da pasta fonte (src). Por exemplo:

yourplugin\myplugin\MyPlugin 
⬇️
src/yourplugin/myplugin/MyPlugin.php

Na próxima secção, vamos programar o conteúdo do arquivo MyPlugin.php.

Sua Primeira Classe.

O conceito completo de uma classe ou class no ingles. é uma ideia bastante abstrata e sofisticada, por isso estamos a assumi-lo como um grupo de código; e como mencionado acima, dentro de um arquico.

Agora vamos copiar tudo isso para sua primeira classe:

<?php

namespace yourname\myplugin;
use pocketmine\plugin\PluginBase;

class MyPlugin extends PluginBase {

}

?>

Vamos ver se voce e inteligente. Tenta adivinhar o significado de cada linha e de cada palavra. Voce tem alguma ideia?

<?php

Este é o prefixo para todos os arquicos PHP. Isso identifica que este arquivo é um script PHP. Ele deve ser a primeira linha de cada arquivo PHP. Esta é a regra; lembre-se dela porque ela não significa mais nada nos arquivos PHP do PocketMine.

Declaração namespace

Sim, este é o namespace da classe. É óbvio. Esta linha diz que todas as coisas no arquivo estarão no namespace especificado.

Simbolo ?>

Esse e o Símbolo de Fechamento. No final de um codigo PHP, você não precisa incluir um símbolo de fechamento ?>. Isso é opcional. Se você omitir o ?>, evita que espaços em branco indesejados sejam adicionados ao final do arquivo. Além disso, é útil quando você está usando include() ou require(), pois evita que espaços em branco não intencionais sejam enviados como saída.

Não se esqueça do ponto final ; (ponto e vírgula). O ponto-e-vírgula é um dos símbolos mais frequente vistos no PHP. Ele marca o final de uma declaração. Sem o ponto e vírgula, o PHP pensará que a próxima linha também pertence à mesma declaração.

Agora feche os olhos e pense em qualquer pergunta.

A pergunta que eu espero que você faça é:

Qual é o significado de ter novas linhas se elas são separadas por ponto e vírgula?

A resposta é simples. Não tem significado.

A maioria dos programadores, para tornar o código mais limpo, coloca diferentes declarações em diferentes linhas. Por exemplo, uma linha para teletransportar o jogador, depois outra linha para enviar uma mensagem a um jogador. Ficaria confuso se colocasse um monte de coisas na mesma linha, porque isto é codificar, não escrever uma história.

Há outra razão. Bem, talvez não seja uma razão; é um resultado. É a questão da galinha e do ovo (qual veio primeiro?). Mas é uma razão para você separar o código em linhas. Ao programar, é quase impossível evitar cometer erros. Quando um erro acontece, o PHP diz-lhe de que linha vem o erro. Mas não lhe dirá qual é a declaração. Por isso, é necessário separar o código em linhas diferentes.

Para resumir, o formato de uma declaração de namespace é:

namespace your\name\space\here;

Veja que as declarações de namespace devem ser a primeira linha de código (<?php não é código). Existem exceções, mas novamente, você não precisa aprender sobre isso para fazer plugins padrão do PocketMine. (Há outra maneira, mas o PocketMine Forums não aceita plugins para fazer isso)

Declarações use

Lembra quando eu falei sobre a importância dos namespaces? Há uma pergunta que você deveria ter feito.

Por que não podemos usar outra coisa como _ ao invés do irritante não-padrão \ e todas aquelas declarações de namespace?

É por causa das declarações use. Com as declarações use adicionadas no PHP 5.3, é possível abreviar um nome de classe longo e completo (como yourname\myplugin\MyPlugin) em seu nome de classe curto: MyPlugin. Então o formato é:

use the\long\name\space\ClassName;

E no código abaixo, você pode dizer apenas ClassName em vez do nome completo.

Então, você notou como a instrução use foi utilizada no exemplo acima?

use pocketmine\plugin\PluginBase;

E no código abaixo, nós poderíamos escrever PluginBase diretamente, ao invés do nome completo pocketmine\plugin\PluginBase.

Se a classe que você quer usar está no mesmo namespace do seu código atual, você não precisa usá-la.

Note que se você não quer usar use mas quer digitar um caminho completo, e que você está em um namespace, você precisa colocar um \ antes do nome completo, ou então o PHP vai pensar que a classe que você está usando está no seu namespace.

Além disso, declarações de uso DEVEM estar diretamente abaixo da declaração do namespace, e acima de qualquer outro código.

Declaração de classe

Como eu mencionei anteriormente, o código é agrupado usando classes. Para começar o nosso código atual, temos de declarar a nossa primeira classe.

class YourClassName{
}

Como você pode imaginar, o {} (chaves) é usado para conter o código da classe. Então nossa classe principal deve ser declarada como:

class MyPlugin{
}

Espere, não fiques muito entusiasmado. Veja novamente. O código no exemplo acima tem algo mais: extends PluginBase. O que é isso?

Para a classe main do seu plugin, você deve fazer com que ela estenda a classe pocketmine\plugin\PluginBase. O que significa "extend"? Você entenderá mais tarde; agora é muito cedo para aprender.

Para evitar ter que digitar o nome completo da classe, o que faz o código parecer confuso, nós o usado na linha acima.

=== Agora, nós terminamos nossa primeira classe PHP. Na verdade, este é um plugin que pode ser carregado. No próximo capítulo, nós veremos seu plugin sendo carregado.

Rodando um plugin Dentro do Pocketmine (Finalmente Graças a Deus!)

Como recomendei, crie o plugin no local onde todos os seus plugins são executados na pasta (/plugins). Ótimo, já fez isso? Agora, baixe o plugin DevTools, que está disponível Aqui

Agora, você pode estar se perguntando Por que eu preciso desse plugin "DevTools"? Porque o DevTools é capaz de converter seu plugin/código atual em um arquivo .PHAR, que é basicamente um arquivo de plugin para o PocketMine. Ele tambem carrega plugins em pasta, sem compilação.

Voce Tambem Pode Usar Um Site que fará a Mesma Coisa Mas Ele So Vai Converter Plugins. Tipo .phar para .zip e Vice-versa. Igual a esse Site ou Esse Que tem Muito Mais Ferramentas.

Terá de instalar o plugin neste diretório: /plugins

Esta é a estrutura básica do seu plugin. Todos os plugins passam por estes passos. No próximo volume, vamos estudar três componentes fundamentais de um plugin, nomeadamente comandos, manipuladores de eventos e tarefas agendadas. que no caso no ingles se chamam "scheduled tasks."

Volume 2

Antes de continuarmos, gostaria de fazer uma pergunta.

O que é que um plugin pode fazer? Para que serve?

Esta é uma pergunta complicada. Toda a gente sabe que os plugins acrescentam coisas ao PocketMine, mas poucos conseguem classificar as suas principais utilizações. Os plugins podem basicamente fazer qualquer coisa, mas três componentes principais são comandos, manuseio de eventos e tarefas programadas. Iremos discuti-los um a um neste volume.

Registrando Comandos.

Vamos registar um comando chamado /bolo.

É muito fácil registar um comando. Você não precisa nem mesmo escrever código PHP. Lembra do nosso velho plugin.yml? É hora de abri-lo novamente. Da última vez que o salvamos, ele deveria estar assim:

name: MyPlugin
version: 1.0.0
author: YourName
api: 2.0.0
main: yourname\myplugin\MyPlugin

A próxima parte será sobre comandos, então adicione uma nova linha commands:

name: MyPlugin
version: 1.0.0
author: YourName
api: 2.0.0
main: yourname\myplugin\MyPlugin
commands:

Para adicionar um comando, escreva o nome do comando no caso do exemplo: bolo, A descrição (como mostrado em /help) Envia uma Mensagem Devolta e mensagem de uso /bolo <usage here>:

name: MyPlugin
version: 1.0.0
author: YourName
api: 2.0.0
main: yourname\myplugin\MyPlugin
commands:
  bolo:
    description: Envia uma Mensagem Devolta
    usage: /bolo <usage here>

É bastante simples. Perceba o que isto significa mesmo que eu não te ensinasse.

Pode adicionar vários comandos:

name: MyPlugin
version: 1.0.0
author: YourName
api: 2.0.0
main: yourname\myplugin\MyPlugin
commands:
  bolo:
    description: Envia uma Mensagem Devolta
    usage: /bolo <usage here>
  another-command:
    description: This is another command
    usage: /another-command <argument> <another argument>

Hmm, digitar /bolo todas as vezes parece ser muito incómodo. Que tal adicionar apelidos? ou no ingles aliases Desta forma, escrever /delicia ou /ola seria convertido em /bolo automaticamente.

name: MyPlugin
version: 1.0.0
author: YourName
api: 2.0.0
main: yourname\myplugin\MyPlugin
commands:
  hi:
    description: Envia uma Mensagem Devolta
    usage: /bolo <usage here>
    aliases: [delicia, ola]
  another-command:
    description: This is another command
    usage: /another-command <argument> <another argument>

Note que ele deve ser chamado de aliases e não alias. Utilize um par de colchetes ([]) para conter os aliases, e separe os aliases por vírgulas (,).

Nota: os comandos não devem conter dois pontos (:) ou espaços. Isso ocorre porque os dois pontos são usados para especificar o proprietário de um comando (você não precisa se preocupar com isso, pois raramente acontece), e os espaços são usados para separar o nome do comando e os argumentos por trás dele. LA ELE MIL VEZES

E Hora de Aprender Voce Esta Aqui Para Isso Não Para Zoar.

De qualquer modo, registramos o comando, mas ainda não adicionámos a função para o tratar. Agora, estamos indo para nossa primeira função PHP. Vamos escrever código real, onde estamos a ver infinitas possibilidades.

Comandos de funcionamento

Nós lidamos com comandos em uma function na sua classe principal chamada onCommand.

Antes de fazer qualquer outra coisa, novamente, olhe para este código e copie-o para o corpo da sua classe principal, ou seja, entre a linha class ... PluginBase{ e a linha }.

  public function onCommand(CommandSender $sender, Command $command, $label, array $args) : bool{
    $commandName = $command->getName();
    if($commandName === "bolo"){
      $sender->sendMessage("Hum que Delicia de Bolo :D");
      return true;
    }
    return false;
  }

Voce Tambem Podera Usar Os Codigos de Formatacão Nas Mensagens Igual Eu Citei No Inicio Da Wiki.

Além disso, nas declarações use no início, use as seguintes classes:

use pocketmine\command\Command;
use pocketmine\command\ComamndSender;

Não leia abaixo ainda. Lê o código acima. O que é que voce percebeu?

Agora vamos ver se está correto.

Funções

As funções têm origem na matemática. Uma notação comum para uma função matemática é f(x). Por exemplo, f(x) = 3x + 2, o que significa que escrever f(x) é equivalente a escrever 3x + 2, e escrever f(12) é equivalente a 3 * 12 + 2, que é 38.

Em PHP, escrevemos f(x) = 3x + 2 assim:

function f($x){
  return 3 * $x + 2;
}
  • Na primeira linha, function significa que está definindo uma função.
  • A palavra seguinte, f, é o nome da função.
  • As coisas dentro dos parênteses () são conhecidas como parâmetros ou argumentos. $x é um exemplo de um parâmetro. Todos os parâmetros devem começar com $, seguido de um nome do parâmetro. As regras para um nome de parâmetro são as mesmas que as de um nome de classe (A-Z a-z 0-9 _), exceto que a convenção para variáveis é começar com uma palavra minúscula (como thisIsName ao invés de ThisIsName). $x representa o valor passado. Por exemplo, se alguém usa f(12), $x representará o 12.
  • Se houver mais de um parâmetro, separe-os com vírgulas ,.
  • O conteúdo entre o { e o } é chamado de corpo da função. Quando alguém utiliza a função, o código dentro do corpo da função é executado.

Os dois espaços antes de return são apenas para efeito visual. A não ser que os espaços estejam entre aspas "", o PHP só se importa se os espaços separam dois caracteres alfabéticos/numéricos/deslocamentos (por exemplo, os espaços em public function onCommand são importantes, mas outros espaços são ignorados, e quantos espaços entre public e function não são importantes)

Nesta função, o corpo da função é return 3 * $x + 2;. return significa que a expressão entre return e ; será definida como o resultado da função, também conhecido como valor de retorno da função em PHP. Neste caso, o valor de retorno da função é 3 * $x + 2. Se $x representa 12, o valor de retorno da função se tornará 3 * 12 + 2, e portanto o valor de retorno é 38.

A linha return é conhecida como declaracão de retorno. Como pode adivinhar, existem outros tipos de declarações para além do return.

Na verdade, o corpo de uma função pode conter um número teoricamente infinito de instruções. Cada expressão é delimitada (ou seja, marcada como terminada) por um ponto e vírgula ;. Basicamente, um comando executa uma operação. Para uma declaracão de retorno, define o valor de retorno da função para algo e pára a execução da função (ou seja, o código depois do return statement não será executado).

Quando uma função é executada, executa as instruções desde a primeira até à última. Isto parece óbvio, certo? Mas é muito importante. É como se lembrar da regra óbvia x = 1 * x em matemática ajudasse as pessoas a resolver x + x = 1 * x + 1 * x = (1 + 1) * x = 2 * x. É o princípio básico de muitos truques de programação.

Há um aspeto especial a ter em conta relativamente aos parâmetros. Mencionei que pode haver tantos parâmetros quanto possível. Também referi que um parâmetro pode ter qualquer nome. Digamos que, se definirmos uma função função pyth($a, $b){ algo aqui; }, e alguém chamar pyth(3, 4), como é que sabemos qual, entre 3 e 4, é $a, e qual é $b? A resposta é: a ordem. Se o primeiro parâmetro definido é $a e o primeiro parâmetro dado é 3, 3 se tornará $a.

Mais sobre variáveis

Na verdade, um parâmetro (e.g. $x no exemplo acima) é um tipo especial de variável. Uma variável é algo como $varName, onde $ identifica que é uma variável e varName é o nome da sua variável.

Uma variável pode representar/manter/armazenar muitas coisas (ou basicamente qualquer coisa que seja uma coisa 😜). No exemplo acima, espera-se que $x armazene um int (inteiro) como 12. Aqui, int é o tipo do valor 12. Existem vários tipos comuns:

  • string (uma sequência de caracteres, também conhecida como "texto")
  • int (um número inteiro, positivo ou negativo)
  • float/double (um número de vírgula flutuante, ou seja, um número decimal (por exemplo, 3,14) ou um número muito grande representado exponencialmente (por exemplo, 3e+11)
  • boolean (verdadeiro ou falso)
  • array (uma lista de valores, indexada com int ou string)
  • null (um tipo especial que não significa nada, frequentemente devolvido por funções que não têm nada a devolver)
  • resource (coisas especiais do sistema como sockets de internet, que podem ser simplesmente ignorados porque raramente nos deparamos com eles, muito menos para lembrar que é um resource)
  • object (objectos são semelhantes a arrays, que podem armazenar uma estrutura de valores dentro de si; objectos são frequentemente usados para representar coisas abstractas que não podem ser representadas por outros tipos, como um Player que se liga a um servidor, ou um Command usado por um jogador que é algo mais do que um nome)

Não é necessário entender tudo o que foi dito acima. Só precisa de se lembrar:

  • uma string é um texto
  • Um int ou float é um número
  • Um boolean é verdadeiro ou falso
  • um array é um grupo ou estrutura de valores (explicarei como obter os valores do array mais tarde)
  • um objeto é uma estrutura de valores (a definição de objectos sem parâmetros é mais avançada, pelo que não a explicarei tão cedo)
  • null significa que a variável não contém nada, mas a variável ainda está "definida" (isso é tão importante quanto ter um dígito zero no final de 10, porque se você não definir uma variável como nula, o PHP vai pensar que algo está faltando e você vai encontrar erros debaixo da sua cama)

A syntax (formato) para definir um comando:

$varName = expression;

Substitua expression por uma expressão do valor que deseja definir. Por exemplo, para expressar uma string abc é "abc". Para expressar um boolean false é false. Para expressar um valor nulo é null. Também é possível expressar o valor de uma variável $var1 como $var1. Portanto, é assim que se define uma variável chamada $var2 que possui o mesmo valor que $var1:

$var2 = $var1;

Pequeno questionario

  • Temos duas variáveis, $a e $b. Escreva algumas declarações que troquem os valores entre $a e $b.
Solucão:
$c = $a;
$a = $b;
$b = $c;

Explicação:

A parte difícil da questão é que quando você define o valor de $a para o valor de $b, o valor de $a é sobrescrito e fazer $b = $a; depois irá apenas definir $b para o novo valor de $a, que é apenas o valor de $b.

Para resolver este problema, nós primeiro armazenamos o valor de $a em uma nova variável chamada $c, como na primeira linha. Em seguida, podemos definir o valor de $a em $b. Agora você pode definir o valor de $b para o antigo valor de $a utilizando o valor armazenado em $c.

De volta ao Nosso Comando

Vamos dar uma olhada no código do comando novamente:

  public function onCommand(CommandSender $sender, Command $command, $label, array $args) : bool{
    $commandName = $command->getName();
    if($commandName === "bolo"){
      $sender->sendMessage("O Bolo Esta Otimo!");
      return true;
    }
    return false;
  }

😮 😕 Hmm, há algo novo que não sabemos. Obviamente, há muitas coisas novas dentro do corpo do método, mas espera, percebe algo de estranho nos parâmetros da função?

Lembra-se da sintaxe correta para os parâmetros? Ela deve ser do tipo ($sender, $command, $label, $args). Então você deve se perguntar, o que são aquelas palavras antes dos nomes dos parâmetros, como CommandSender, Command e array?

array é a dica. Lembra o que é array? É um tipo de variáveis/parâmetros. array $args significa que $args deve ser um array quando alguém chama a função onCommand. Se a pessoa (neste caso, é o PocketMine) que chama a função não fornecer um array para o quarto parâmetro, erros vermelhos aparecerão no seu console.

Portanto, a palavra antes do nome do parâmetro é o tipo do parâmetro (conhecido tecnicamente como type hint). Entretanto, atualmente, apenas array e object são permitidos para dicas de tipo.

Por isso, deve estar a pensar: CommandSender e Command não são tipos mencionados. Eu nem sequer os mencionei em lado nenhum. De onde é que eles vêm?

Isto remete para a nossa definição de objetos. Cada objeto é "uma instância de uma classe". Uma classe é como um subtipo. Existem diferentes tipos de variáveis, e algumas são objetos. E há diferentes tipos de objetos, e uma classe é um tipo de objeto. (No futuro, aprenderá que as variáveis que são "instância de uma classe" podem ser "instância de diferentes subclasses") As classes são complicadas. De momento, só precisa de saber que uma classe classifica objetos em tipos mais pequenos.

E então, o nome do tipo $sender é CommandSender? Não, você caiu nessa armadilha 😈 Lembra das declarações use? use pocketmine\command\CommandSender;. As declarações use definem aliases para nomes de classes. Portanto, o nome do tipo $sender é pocketmine\command\CommandSender.

O texto acima explica os parâmetros. E no próximo capítulo, vamos estudar o corpo da função linha por linha, aprendendo alguns dos segredos da maravilhosa programação.

Investigando a essência da API a partir do código fonte:

  public function onCommand(CommandSender $sender, Command $command, $label, array $args) : bool{
    $commandName = $command->getName();
    if($commandName === "bolo"){
      $sender->sendMessage("Que Bolo Gostoso!");
      return true;
    }
    return false;
  }

Deves ser capaz de adivinhar o que é a primeira linha. É uma declaração de atribuição de variável. Ela define a variável $commandName, e dá a ela o valor $command->getName(). Agora a questão é, o que significa $command->getName()?

Nós já mencionamos que $command, nesta função, é um objeto Command. Agora, vamos ver o que podemos fazer com um objeto Command. Você pode ir para o Codigo Fonte para ver o código fonte do PocketMine da api 2.0.0

Nós sabemos que Command significa pocketmine\command\Command. (Por causa da declaração use no começo, lembra?) Portanto, nós vamos olhar o código fonte do pocketmine/command/Command.php.

O arquivo fonte contém um monte de código que você não entende. Na verdade, qualquer coisa que tenha uma tag private (modifier) não faz parte da API, e você pode simplesmente ignorá-la. 😏 O PocketMine oferece a maior parte da API em funções. Portanto, você pode procurar a palavra public function no código fonte usando o botão de busca no seu navegador (não a barra de busca no topo da página! Não está pesquisando todo o código fonte do PocketMine!).

  • Se você estiver usando Linux e tiver baixado e extraído o código fonte, é uma boa idéia executar o comando grep "public function" < Command.php.

Agora temos estas linhas extraídas:

public function __construct($name, $description = "", $usageMessage = null, array $aliases = []){
public function getName(){
public function getPermission(){
public function setPermission($permission){
public function testPermission(CommandSender $target){
public function testPermissionSilent(CommandSender $target){
public function getLabel(){
public function setLabel($name){
public function register(CommandMap $commandMap){
public function unregister(CommandMap $commandMap){
public function isRegistered(){
public function getAliases(){
public function getPermissionMessage(){
public function getDescription(){
public function getUsage(){
public function setAliases(array $aliases){
public function setDescription($description){
public function setPermissionMessage($permissionMessage){
public function setUsage($usage){
public function __toString(){

Uma nota é que funções começando com __, como __construct e __toString, são funções especiais no PHP (também conhecidas como funções mágicas). Você não vai querer usá-las diretamente. Nós veremos mais sobre elas mais tarde.

Agora, adivinhe? Tudo que você vê aqui é esperado para ser usado por você! No entanto, algumas funções como register e unregister na verdade não são o que parecem significar.

Funções que começam com get são geralmente para obter um valor sobre o objeto. Como você pode imaginar, getName() retorna o nome do comando, que na verdade é o nome do comando (não do plugin!) que você digitou em plugin.yml.

Se você quer utilizar uma função sobre um objeto, como você já viu, é $object->functionName($parameters). Então, nós temos $command->getName(), que retorna o nome do comando. Nós armazenamos o valor em uma variável chamada $commandName.

Bem Estamos Quase No Final Da Wiki Bem Agora Voce Aprenderá A Como Utilizar Banco de Dados MySQL No Seu Plugin.

Usando Banco De Dado MySQL No Seu Plugin Pocketmine!

Há muitas coisas chatas neste artigo, por isso cruzei-as, por isso, se estiverer com pressa ou se sentir enjoado ao lê-las, e so voce pular. Mas faço voce ter coragem de ler tudo.

Introdução: O que é o MySQL?

MySQL é um popular servidor de base de dados de código aberto que implementa SQL (Structured Query Language). Vamos saltar a definição chata. Ela não tem importância nenhuma.

O que importa é:

  1. O MySQL é um servidor. É claro que é baseado em arquivos (todas as bases de dados neste mundo acabam por armazenar coisas em arquivos, a não ser que não corram em sistemas operativos normais), mas não precisamos de saber os detalhes sobre os arquivos. Só precisamos de saber sobre a parte do servidor - O MySQL é um servidor, o que significa que tem de se ligar a ele através de uma rede. Mesmo que o servidor MySQL esteja alojado na mesma máquina, continua a ligar-se a ele utilizando o localhost, que continua a ser uma espécie de socket de rede, embora não esteja envolvida nenhuma rede externa.
  2. O MySQL é uma base de dados, o que significa que o MySQL armazena dados. (Parece um absurdo, mas tem de se lembrar disto) (E é frequentemente abusado como um comunicador em vez de uma base de dados; mas tudo bem, abuse dele como quiser) (E sim, eu também as vezes abuso dele, e não há realmente nada de errado em ser abusado) (Eu sei, ignore a minha obsessão aqui)
  3. O MySQL utiliza SQL. SQL é uma linguagem. SQL significa Structured Query Language (Linguagem de Consulta Estruturada).
  • SQL é uma linguagem que:
    • define dados. Não se confunda. Definir dados significa definir a estrutura dos dados. Basicamente, diz ao servidor quais os dados que vai colocar na base de dados. Compreenderá mais sobre a estrutura na próxima secção sobre tabelas.
    • manipula os dados. Isto significa que processa os dados reais. Armazena dados na base de dados. Pede dados à base de dados. Apaga dados da base de dados.
  • Portanto, a parte mais importante do uso do MySQL nos plugins PocketMine é a parte da query.
  1. O MySQL é estruturado. Como é que se estruturam as coisas? Você ordena-as. Classifica-as por tipo. Você coloca coisas similares juntas. Em resumo, coloca-as em tabelas.

Tabelas MySQL

Existem dois tipos de coisas que armazenamos numa base de dados MySQL (provavelmente mais, mas eu só conheço dois):

  • tabelas
  • funções/procedimentos

~~Raramente utilizo funções/procedimentos. Penso que também não as utilizaria frequentemente em plugins. São mais úteis para o utilizador. Não tenciono falar sobre elas neste artigo... Por isso, vamos concentrar-nos nas tabelas.

Considere as seguintes informações:

  1. Sr_abelha tinha originalmente 10 moedas e 10 gemas.
  2. gusta_7w7 tinha originalmente 10 moedas e 10 gemas.
  3. o Sr_abelha recebeu 15 gemas de pessoas que lhe pedem pra banir certas pessoas da fuzivel que nunca vão aparecer quando o Sr_abelha entra na fuzivel.
  4. gusta_7w7 gastou 5 moedas para comprar batatas fritas.
  5. ...

À medida que o tempo passa, torna-se muito complicado, por isso armazenaríamos a declaração em 1 uma tabela como esta:

Nome Moedas Gemas
Sr_abelha 10 10

Um novo jogador chamado gusta_7w7 registou-se, por isso vamos adicionar uma linha no final da tabela:

Nome Moedas Gemas
Sr_abelha 10 10
gusta_7w7 10 10

Se considerarmos as afirmações 3 e 4:

Nome Moedas Gemas
Sr_abelha 10 25
gusta_7w7 5 10

Mesmo que os dados continuem a crescer, continua a ser muito conveniente acompanhar o valor final de Moedas e Gemas de cada jogador. Para além disso, também podemos encontrar outros dados interessantes, como a média de Moedas, o número de contas, etc.

Isto é o que significa "estruturado". E este é o princípio do MySQL (e de outras bases de dados da família SQL, como o SQLite).

Linhas

Para as pessoas que não têm a certeza, um conjunto horizontal de dados é uma linha. Na tabela acima, os dados relativos a "Sr_abelha" são uma linha. Coluna é um conjunto vertical de dados. Na tabela acima, todos os nomes são uma coluna; todas as Moedas são outra coluna.

O plugin frequentemente adiciona automaticamente (INSERT) linhas à tabela ou DELETE linhas da tabela, ou UPDATE os valores em diferentes linhas da tabela. Mas raramente adiciona uma coluna, porque adicionar uma coluna afetara todos os dados.

Qual é a diferença entre adicionar uma linha e adicionar uma coluna? A diferença é que adicionar uma coluna é a definição de dados, e adicionar uma linha é a manipulação de dados.

Pode pensar em cada tabela como um bloco (invertido). A linha mais alta (a linha a negrito que defina os dados que se encontram por baixo) é o solo. Cada linha é um piso. É fácil (está bem, eu sei que não é fácil porque tens de transportar os materiais de construção para cima; mas todos nós jogamos Minecraft, e é fácil no jogo.) adicionar um piso no topo, mas é (comparativamente) muito mais difícil adicionar uma divisão na estrutura do piso, porque tem o que fazer para cada edifício; e para adicionar um piso, só precisa de adicionar algumas divisões (não me fales de ilhas flutuantes no Minecraft!).

Mas porque é que temos de considerar a linha mais alta como o chão? Porque não a coluna mais à esquerda? Porque esta é a definição de uma tabela. Isto é indiscutível e é melhor aceitar esse fato. (Se insiste em discutir, pensa porque é que os gráficos de barras são normalmente verticais) (Vês mais gráficos de barras horizontais do que verticais? Culpa as pessoas que fingem ser ecológicas.)

Células

  • Cada célula de uma linha contém um dado.

De modo a fazer com que o MySQL carregue os dados mais rapidamente, o MySQL quer que defina quais os dados que irá armazenar em cada célula. Naturalmente, todas as células numa coluna são sobre a mesma coisa (mas para linhas diferentes), por isso devem ter o mesmo tipo de dados. É uma data? É um número? Ou é um texto imprimível? Ou um arquivo de dados binários?

Não vou perder o meu tempo a explicar os tipos de dados ao detalhe, uma vez que já temos um excelente manual existente que explica os tipos de dados do MySQL Utilize-o apenas como referência sempre que precisar dele. Aqui está uma lista dos meus tipos de dados mais usados, em ordem decrescente:

  • INT (para armazenar números)
  • VARCHAR (para quase todos os textos, como nome do jogador, IP do jogador, etc.)
  • TINYINT (para armazenar dados muito pequenos que são normalmente um número inteiro de 2 dígitos ou -1)
  • TIMESTAMP (para armazenar datas, obviamente)
  • BIGINT (para armazenar datas, quando não quero usar TIMESTAMP por várias razões)
  • BINARY (para armazenar hash de senhas) (note que BINARY não é tão fácil de usar quanto você esperava, então você pode querer usar VARCHAR/CHAR depois de rodar bin2hex ou base64_encode.

Porque é que não existe um tipo de matriz? É porque um dado é um dado, e é singular: sem expressão: É claro que você pode usar um VARCHAR, então implodir um array numa string com um delimitador como , antes de armazenar no banco de dados. Se você simplesmente precisa armazenar um grupo de dados e retirar todo o pedaço de dados mais tarde, isso é correto. Mas e se quiser mexer nos dados diretamente na base de dados (através de SQL)? Há alguns casos em que isso é possível. Vou Mostrar alguns exemplos que experimentei:

  • Lista de amigos. Guardei a lista de amigos de um utilizador Sr_abelha numa string como esta: gusta_7w7,rajador. Então o que acontece quando o Sr_abelha quer remover o gusta_7w7 como amigo? É fácil eliminar gusta_7w7 da lista de amigos de Sr_abelha, mas precisamos de eliminar Sr_abelha da lista de amigos de gusta_7w7 ao mesmo tempo. Como é que podemos fazer isto? Isto é possível de resolver através da função SUBSTRING() do MySQL, mas e se eu precisar de apagar todos os amigos? Ou outro caso é, e se eu quiser apagar o 21º amigo de cada jogador em diante Se transferir os dados um a um, mexermos com código PHP e os carregar um a um, isso criaria um lag excessivo no servidor ("supunhetemos" Zoeira Caralho suponhamos que isto acontece frequentemente).

Então, como é que podemos resolver estes problemas? Criamos outra tabela.

Comparamos estas duas tabelas:

users:

Nome Moedas IP history
Sr_abelha 10 1.2.3.4,2.3.4.5,3.4.5.6
gusta_7w7 5 127.0.0.1,192.168.0.5

VS

users:

Nome Moedas
Sr_abelha 10
gusta_7w7 5

iphistory:

Nome IP
Sr_abelha 1.2.3.4
Sr_abelha 2.3.4.5
Sr_abelha 3.4.5.6
gusta_7w7 127.0.0.1
gusta_7w7 192.168.0.5
rajador 192.177.0.9

Na segunda tabela, uma linha individual contém um endereço IP em vez de um utilizador, pelo que é mais conveniente obter um valor. A questão é: isto não dificultaria o descarregamento dos dados? Quando falarmos de subconsultas mais tarde, aperceber-se-á que ainda é simplesmente possível.

O que é que o MySQL tem de especial nos plugins?

O MySQL é um servidor. Isto significa que precisa de se ligar através da Internet para o utilizar. Isto é uma vantagem, mas também é uma desvantagem. Se o servidor da base de dados estiver ocupado, a rede congestionada ou outras coisas inevitáveis comuns acontecerem, uma consulta demorará muito tempo a ser concluída. Mas espere, você quer um resultado. Como o PHP pode continuar processando seu código se ele não tem um resultado para você? Então, o programa (mais precisamente, a thread em que funciona) é suspenso. Antes que o servidor MySQL retorne um resultado e você o receba, você ficará preso na linha de código em que enviou uma consulta.

Portanto, um plugin de alta qualidade deve usar threads para lidar com consultas MySQL, que é o ponto principal deste wiki.

O que é threading?

Vamos usar uma analogia num restaurante. Temos uma empregada de mesa chamada Alice. Temos um chefe de cozinha chamado Bob. E temos dois clientes chamados Cindy e David.

A coisa toda acontece assim:

  1. A Cindy entra no restaurante.
  2. A Cindy pede um Pedaço de Bolo.
  3. A Alice e a responsavel pelo pedido.
  4. A Alice diz ao Bob para preparar um brinde.
  5. David entra.
  6. A Cindy é uma empregada de mesa inexperiente, mas é a única empregada de mesa no restaurante.
  7. A Cindy não serve o David, porque tava servindo a Alice, e não estava a fazer mais nada senão esperar que o Bob preparasse o Bolo.
  8. David fica zangado por ser ignorado.
  9. A Cindy fica zangada porque também é ignorada; a Alice está à espera do Bob e ignora a Cindy e o David.

A analogia é a seguinte:

Analogia Fato
Alice Servidor PocketMine (especialmente o plugin que usa MySQL)
Bob Servidor de banco de dados MySQL
Cindy Jogador que faz alguma coisa que faz com que o plugin faça uma consulta à base de dados
David Outros jogadores (na verdade, incluindo Cindy)
Um brinde Um pedido que aciona uma consulta ao MySQL
Fica irritado Vê um servidor lento; o TPS do servidor cai porque o plugin está bloqueando a thread
A atenção de Alice thread principal

Agora, e se Alice não colocar toda a sua atenção em Bob? Ou seja, e se Alice disser ao Bob para preparar um Bolo, continuar a servir a Cindy e o David e verificar se o Bob tem o Bolo pronto a cada vários segundos?

Analogia Fato
Desvia a atenção de Bob Inicia uma thread que está encarregada da consulta
Servindo Cindy e David O servidor não é bloqueado pelas consultas MySQL; continua a funcionar sem problemas
Verifica se o brinde está pronto O servidor se comunica com a thread para ver se ela terminou
⚠️ **GitHub.com Fallback** ⚠️