さて、コマンドが実行されたとき行う処理を記述する部分です。ここが核となります。
長くなるので先に書いておきます。
public function ip($cmd, $params, $issuer, $alias) {
$user = strtolower($params[0]);
$player = $this->api->player->get($user);
if ($player instanceof Player) { //Playerオブジェクトかどうか
$pip=$player->ip;
return $user."'s IP :".$pip;
}else{
return "Player doesn't exist"
}
}
順々に説明しておきます。
まずはメソッドを追加しましょう。
public function メソッド(引数1,引数2,…) {
}
メソッド…緑部分で決めた「メソッド」です。
引数…この「メソッド内」で使用したい(正確に言えば本体から取得したい)「変数」を記述します。変数にはいろいろなものがあります。プラグインとPocketmine本体は様々なデータのやり取りをします。
※変数…数学で言うところの「x」や「y」など、この中に何か数字が代入されるものです。なお、プログラムは数学ではないので、「数字」だけでなく関数の中は「文字」や「データ」にもなります。phpの「変数」には、必ず先頭に「$」が付いています。例えば数学で「y=ax+b」という式がありますね。これをphpで記述させようと思うと、「$y == $a * $x + $b」としないと認識しません。プログラム側からすれば、「x」と書かれただけではそれが「文字」だか「関数」だか分からなくなるため、差別化させるためです。どうして「=」ではなく「==」とするのか、また「*」とはなんなのかなどは後ほど説明します。
引数には様々ありますが、今回使うのは$cmd, $params, $issuer, $aliasです。
軽く説明しておきます。
$cmd…ここには、実行されたコマンドの文字列が代入されます。たとえば「/tp Gonbe34 Jin113」とした場合、$cmdの中身は「tp」になります。
$params…ここにはコマンドの後ろに付いた「パラメータ」が代入されます。たとえば「/tp Gonbe34 Jin113」とした場合、$paramsの中身は「Gonbe34 Jin113」となります(正確には違うかもしれません)。【重要】ここで$paramsから文字列を取り出す(取得する)、例えば「Gonbe34」という文字列だけを取り出したい場合には「$params[0]」とすると出すことができます。勘のいい人は分かるかも知れませんが、「$params[1]」は「Jin113」です。
$issuer…このコマンドを実行したプレイヤーのデータが代入されます。
$alias…よくわかりませんがどんなプラグインにも書いてありますので一応入れておきましょう。わかってなくてもプラグインは作れます、多分。
他によく使われるものは「$event」や「$data」ですかね。ここでは使いませんので説明は省きます。
public function commandH($cmd, $params, $issuer, $alias) {
}
こんな感じになりますね。まだまだです。
人に説明するというのは難しいですね。構成を考えるのに時間がかかりました。
大まかな構造についてです。
このコマンドは、始めに説明したように、「/ip <プレイヤー名>」と打つことで使えるようにしますよね。
たとえばGonbe34さんのIPを表示させたい場合、/ip Gonbe34と使えば出るようにしたいわけです。
そしてその指定したユーザーに関するデータを取得し、そのデータの中からIPアドレスのデータを抜き取り、表示させるというわけです。
順番で言うと、
- 1、コマンドで指定されたユーザーを探す
- 2、そのユーザーに関するデータを取得
- 3、データの中からIPアドレスのデータを抜き取る
- 4、表示
とこんな具合です。
まず「ユーザー名のデータ」を格納するための関数を作りましょう。
$usernameとしましょうか。
先ほどの例を使って言うならば、/ip Gonbe34としたときの、「Gonbe34」という文字を保持させるための変数です。
もうちょっと簡単にいうならば、とりあえずいろんなプレイヤーのユーザー名が入る関数を作るんだな、と思えばいいかもです。
$username = params[0];
こうすると、/ip Gonbe34としたときには$usernameの中にGonbe34が入ります。
ユーザーネームを保存したら、今度はそのユーザーに関するデータを入手しなくてはいけません。
それには、
$player = $this->api->player->get(ユーザー名);
これを使います。$playerもPocketmineとやり取りする変数のうちのひとつです。
ユーザー名は、先ほど$username変数を作ったので
$username = params[0];
$player = $this->api->player->get($username);
こうすればいいですね。
これで、現在$playerの中には指定されたユーザーに関する様々なデータが入っていることになります。
$player->ip;
を使うと、そのプレイヤーのIPが取得できます。
これもわかりやすくプレイヤーのIPを格納するための変数を作っておきましょう。
$pipとします。
$username = params[0];
$player = $this->api->player->get($username);
$pip = $player->ip;
IPが取得できたら今度は表示させましょう。
表示させるのには「return 文字列が代入された変数」とすればokです。
ここでは「return $pip」でOKですね。
$username = params[0];
$player = $this->api->player->get($username);
$pip = $player->ip;
return $pip
表示させるといっても、ただ単に数字が出るだけではつまらないですね。
ここで「文字の足し算」について少し解説します。
まず大体どんなプログラム言語でも、文字列というのは「""」で囲まれます。
「return あいす」と打っても、「あいす」とは表示されません。
ただしくは「return "あいす"」です。
「""」は、この中に囲われたものは文字列である、と認識させるためです。
$a = "あ"
$b = "い"
$c = "す"
とします。ここで、この関数を使って「あいす」と表示させるためにはどうすればいいか?
「return $a + $b + $c」ではだめですよ、これは数字ではないですからね。
「$a.$b.$c」とすれば「あいす」となり、OKです。
文字列と混ぜる場合、たとえば
「$a."き".$c」とすると「あきす」となります。
「$a."き".$c."こ".$b」とすれば「あきすこい」になります。
話を戻しましょう。
「IP: 000.000.000.00」と表示させたい場合、「"IP:".$pip」とすればOK。
それだけでもひねりはありますが、「Gonbe34's IP : 000.000.000.00」となるともうちょっと面白くなりますよね。
こうする場合、ユーザーネームは$usernameを既に指定してあるので
「$username."'s IP :".$pip;」とすればOK。ここの部分は正直どうでもいいとは思いますが。
どうでもいいことに時間をかけてこそのプログラミングだと、勝手に思っています。
さて、コードはこうなりました。
$username = params[0];
$player = $this->api->player->get($username);
$pip = $player->ip;
return $username."'s IP :".$pip;
これで動くか?いえ、動きません。
動かないというのは違いますね。正確に言えば、動かなくもないですがエラーが出る可能性があります。
まず、pocketmineではユーザーネームは
「大文字はなく全て小文字か数字」で格納されています。
(PMMP本体の中の「players」フォルダを見てみると、プレイヤー名は全て小文字なのが分かりますね。)
つまり最初の方で例に挙げた「/ip Gonbe34」では、「G」が大文字なので正しくプレイヤーデータが取得できません。
「/ip gonbe34」とすれば、大丈夫なのですが・・・
「じゃあ大文字は絶対使わず小文字で打てばいいんだね!」
…まあそういうことですが、誰かが大文字を打ってしまうたびにエラーが出るのではたまったもんじゃないですよね。
ここでいいものがあります。
$username = strtolower(params[0]);
こうすることで、「指定部分の大文字は全て小文字にしてくれる」んです。
素晴らしいですね。まあ普通といえば普通ですが。
「/ip Gonbe34」と打った場合も、本体側、格納される$username変数の中身は「gonbe34」になります。
「/ip gONbE34」でも同じです。
他の場合も考えて見ます。
まず、もしサーバー内に「Gonbe34」さんが居なかったらどうなってしまうのか。
居ないプレイヤーのデータを取得するわけですから、$playerの中が空になります。
ここまではエラーが起きませんが、おそらく$player->usernameをすると死にます。
プレイヤーの場合実行させ、そうでない場合は実行させないためにはif文を使います。
if文とは、条件式と呼ばれ、たとえば「$a=1なら実行」とか、「$a=1以外なら実行そうでないならそこで終了」と
ある条件を満たしたときだけ、動作させることができるわけです。
if(条件式){
実行する部分
}
これがif文の基本です。これを使います。
プレイヤーオブジェクトであるかどうか判断させるためには
if ($player instanceof Player) {
を使えばいいわけです。
こうします。
$user = strtolower($params[0]);
$player = $this->api->player->get($user);
if ($player instanceof Player) {
$pip=$player->ip;
return $user."'s IP :".$pip;
}
こうすることで$pip=…の部分とreturn…の部分は、$playerがプレイヤーオブジェクトの場合(プレイヤーデータが入っているとき)のみ実行するようになります。
これでもいいのですが、これでは間違ったプレイヤー名を打った場合何も出ません。
少し悲しいので、「そうでない場合、プレイヤーオブジェクトでなかった場合実行する部分」を追加します。
$user = strtolower($params[0]);
$player = $this->api->player->get($user);
if ($player instanceof Player) {
$pip=$player->ip;
return $user."'s IP :".$pip;
}else{
そうでない場合実行される
}
elseで囲まれた部分は、上の条件に当てはまらなかった場合、実行される部分になります。
return "Player doesn't exist"としましょう。
(この英文の意味は、「プレイヤーが存在していません」という意味になります)
$user = strtolower($params[0]);
$player = $this->api->player->get($user);
if ($player instanceof Player) {
$pip=$player->ip;
return $user."'s IP :".$pip;
}else{
return "player doesn't exist";
}
さて、紫部分のdestructの部分には用はないので、これで完成ですね。
<?php
/*
__PocketMine Plugin__
name=IPplugin
version=0.1.0
author=Gonbe34
class=IPPlugin
apiversion=12
*/
class IPPlugin implements Plugin{
private $api;
public function __construct(ServerAPI $api, $server = false){
$this->api = $api;
}
public function init(){
$this->api->console->register("ip", "<player> see player's IP", array($this, "commandH"));
}
public function commandH($cmd, $params, $issuer, $alias) {
$user = strtolower($params[0]);
$player = $this->api->player->get($user);
if ($player instanceof Player) {
$pip=$player->ip;
return $user."'s IP :".$pip;
}else{
return "player doesn't exist";
}
}
public function __destruct(){
}
}
長々と付き合ってくださって有難うございました。
自分が答えれる範囲でなら質問に答えますので、疑問などありましたらコメント欄でよろしくお願いいたします。