[JAVA] Accept the [MineCraft Plugin] command and raise an event

Prerequisites

We will develop the plug-in by adding it to the plug-in created in Creating a Spigot plug-in using Eclipse.

STEP1: Implementation of basic commands

plugin.yml settings

Edit plugin.yml to add the function that the command of the self-made plugin responds to the command.

command:
Command name:
    description:An overview of the command is given here
    usage:Description of command usage

--description – Command description. --usage – How to use the command. If onCommand () returns false here, this usage will be displayed.

Only basic elements are added here. It is possible to play with various things by adding other than description, ʻusage`. If you want to make other detailed settings, [this site](https://mcmodding.jp/modding/index.php/Plugin.yml%E3%81%AE%E8%A8%AD%E5%AE%9A% Please refer to E4% B8% 80% E8% A6% A7).

An example is as follows.

name: "QiitaTest"
version: "${project.version}"
main: "com.github.kubota.qiitatest.QiitaTest"
api-version: "1.13"

commands: #Declare commands for your own plugin
  qiita:
    description: this is a sample command.
    usage: /<command>

Editing the main class

Add the following elements to the main class.

@Override
  public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
    return false;
}

Here is a brief description of the ʻonCommandmethod. This method is executed when the command defined inCommand of plugin.yml` is executed.

There are four arguments, each of which is as follows. --CommandSender sender – Command sender --Command cmd – Contents of the executed command --String commandLabel – Command alias used --String [] args – Array containing command arguments

And since the type of this method is Boolean, the value returned is either true or false. If it is true, it means that it works normally. If it is false, it means that it did not work normally, and the contents described in ʻusage` are displayed.

If you add this method to an existing program, it will be as follows.

package com.github.kubota.qiitatest;

import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;

public class QiitaTest extends JavaPlugin{
    //↓ onEnable is a method that is executed when it is loaded
    @Override
    public void onEnable() {
        //↓ Leave a log on the server
        getLogger().info("Hello, Qiita!");
    }

    //onCommand is a plugin.Executed when the command described in yml is called
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
    	return false;
    }
}

When you do this, it looks like this: スクリーンショット 2019-08-13 23.45.28.png When the command Qiita is executed, the program in the ʻonCommand method is executed and false is returned, so the contents described in ʻUsage in plugin.yml are displayed. I will.

Since it is difficult to understand with just this, add the sendMessage method. This method is a member method of the CommandSender class. The function of this method is to send the character string in the argument as a message to this target person (user of the instance). The difference from the getLogger method used in the previous chapter is that it displays the character string on the console and sends the character string only to the target person.

The following is the edited version.

package com.github.kubota.qiitatest;

import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;

public class QiitaTest extends JavaPlugin{
    //↓ onEnable is a method that is executed when it is loaded
    @Override
    public void onEnable() {
        //↓ Leave a log on the server
        getLogger().info("Hello, Qiita!");
    }

    //onCommand is a plugin.Executed when the command described in yml is called
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
        sender.sendMessage("Command, Qiita!");
    	return true;
    }
}

Due to the nature of the ʻonCommandmethod, its first argument,sender, is the user who executed the command. Therefore, in this program, the message is sent only to the user who executed the command. Also, I changed from false to true` to confirm the change in behavior due to the return value.

The execution result is as follows. スクリーンショット 2019-08-14 0.22.35.png

STEP2: Multiple commands

plugin.yml settings

To set multiple plugins, add them under Command as follows. It looks like this.

name: "QiitaTest"
version: "${project.version}"
main: "com.github.kubota.qiitatest.QiitaTest"
api-version: "1.13"

commands: #Declare commands for your own plugin
  qiita:
    description: this is 1st sample command.
    usage: /<command>
  sample:
    description: this is 2nd sample command.
    usage: /<command>

Editing the main class

ʻOnCommand is a method that is executed when the command described in plugin.ymlis called. If multiple commands are defined inplugin.yml`, they will be executed if any of them is called. If you keep the existing program, even if you prepare multiple commands, they will all perform the same operation.

In this case, it is meaningless to prepare multiple commands, so it is necessary to branch the process according to the executed command.

package com.github.kubota.qiitatest;

import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;

public class QiitaTest extends JavaPlugin{
    //↓ onEnable is a method that is executed when it is loaded
    @Override
    public void onEnable() {
        //↓ Leave a log on the server
        getLogger().info("Hello, Qiita!");
    }

    //onCommand is a plugin.Executed when the command described in yml is called
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
        if(cmd.getName().equalsIgnoreCase("qiita")){
            //Executed when the qiita command is executed
            sender.sendMessage("Command, Qiita!");
            return true;
        }
        if(cmd.getName().equalsIgnoreCase("sample")){
            //Executed when the sample command is executed
            sender.sendMessage("Command, sample!");
            return true;
        }
    	return false;
    }
}

As mentioned above, cmd stores information about the executed command. You can get the executed command as a character string by executing the getName method of this instance. ʻEqualsIgnoreCase` method This is a method that the String type has and returns as a Boolean type whether the argument string matches the executed string.

When this is executed, it will be as follows. スクリーンショット 2019-08-14 15.30.19.png

Tips

The method is forcibly terminated without executing return and subsequent processing.

STEP3: Subcommand

plugin.yml settings

This is not a mast, but in order to accept arguments as a function of the qiita command, change ʻusage` as follows.

name: "QiitaTest"
version: "${project.version}"
main: "com.github.kubota.qiitatest.QiitaTest"
api-version: "1.13"

commands: #Declare commands for your own plugin
  qiita:
    description: this is 1st sample command.
    usage: /<command> [text]
  sample:
    description: this is 2nd sample command.
    usage: /<command>

Editing the main class

Arguments at the time of command execution are stored in a variable called ʻargs. This is a String type array. Since it is an array, you can get it by typing ʻargs [x], etc. The x part starts from 0 and increments by 1.

> qiita a wa ka

If you execute the command

argument args[0] args[1] args[2]
value "a" "wa" "ka"

It is stored like this.

Let's use this to write the following code.

package com.github.kubota.qiitatest;

import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;

public class QiitaTest extends JavaPlugin{
    //↓ onEnable is a method that is executed when it is loaded
    @Override
    public void onEnable() {
        //↓ Leave a log on the server
        getLogger().info("Hello, Qiita!");
    }

    //onCommand is a plugin.Executed when the command described in yml is called
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
    	if(cmd.getName().equalsIgnoreCase("qiita")) {
    		if(args.length == 0)return false;
    		sender.sendMessage("Command, Qiita by " + args[0]);
    		return true;
    	}
    	if(cmd.getName().equalsIgnoreCase("sample")) {
    		sender.sendMessage("Command, Sample");
    		return true;
    	}
    	return false;
    }
}

ʻArgs.length contains the number of elements stored in the array of ʻargs. If it is 0, it means that no argument is entered when the command is executed. This time, such a state is not suitable, so the ʻonCommandmethod returnsfalse`.

If the condition is exceeded (if an argument exists), the character string entered as the first argument will be displayed after the message Command, Qiita by is displayed. When this is executed, the result will be as follows. スクリーンショット 2019-08-14 17.21.11.png

That's it for this time!

STEP4: Sample plug-in (rock-paper-scissors)

Finally, create a sample plug-in using this knowledge.

As a function, it is a program that plays rock-paper-scissors on a computer. The opponent's hand is determined to be a random hand when the plugin is activated, and will not change after that.

The function implemented by the command is

--Play rock-paper-scissors --Check the opponent's hand

There are two.

plugin.yml

name: "QiitaTest"
version: "${project.version}"
main: "com.github.kubota.qiitatest.QiitaTest"
api-version: "1.13"

commands: #Declare commands for your own plugin
  janken:
    discription: play the game of scissors-paper-roc.
    usage: /<command> [your choice]
  enemy:
    discription: check enemy choice.
    usage: /<command>
    

Function of the command of the plug-in to be implemented

command function
/janken [Hand to put out] Play rock-paper-scissors
/enemy Check the opponent's hand

main class

package com.github.kubota.qiitatest;

//Library for random number generation
import java.util.Random;

import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;

public class QiitaTest extends JavaPlugin{
	String enemy = "";

	//onEnable is the method that will be executed when it is loaded
	//In this method enemy(Opponent's hand)Randomly determine
	@Override
	public void onEnable() {
		//Array with hand information
		String[] hand = {"goo","tyo","paa"};

		//Instantiate a class for random number generation
		Random r = new Random();
		//Generate a random number between 0 and 3 with the nextInt method,Store the corresponding hand in enemy
		enemy = hand[r.nextInt(3)];
	}


    //onCommand is a plugin.Executed when the command described in yml is called
    @Override
    public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {

    	//Play rock-paper-scissors with enemy by executing the janken command
    	//Enter your hand as an argument
    	if(cmd.getName().equalsIgnoreCase("janken")) {

    		//No arguments passed
    		if(args.length == 0)return false;

    		if(args[0].equalsIgnoreCase("paa") && enemy.equalsIgnoreCase("tyo") ||
    			args[0].equalsIgnoreCase("tyo") && enemy.equalsIgnoreCase("goo") ||
    			args[0].equalsIgnoreCase("goo") && enemy.equalsIgnoreCase("paa")){
    			//Defeat pattern
    			sender.sendMessage("My win!Think about why you lost until tomorrow");

    		}else if(args[0].equalsIgnoreCase("tyo") && enemy.equalsIgnoreCase("paa") ||
    			args[0].equalsIgnoreCase("goo") && enemy.equalsIgnoreCase("tyo") ||
        		args[0].equalsIgnoreCase("paa") && enemy.equalsIgnoreCase("goo")) {
    			//Victory pattern
    			sender.sendMessage("Do it!Let me revenge tomorrow");

    		}else if(args[0].equalsIgnoreCase(enemy)) {
    			//Aiko pattern
    			sender.sendMessage("Aikoyan!What's this?");

    		}else {
    			//Patterns other than goo tyo paa
    			return false;
    		}
    		return true;
    	}

    	//Display the opponent's hand with the enemy command
    	if(cmd.getName().equalsIgnoreCase("enemy")) {
    		sender.sendMessage("Enemy choice is " + enemy + ".");
    		return true;
    	}

    	return false;
    }
}

Random number generation

//Library for random number generation
import java.util.Random;

By importing this library, you can use the classes used below to generate random numbers.

//Variable to store the opponent's hand
String enemy = "";

//onEnable is the method that will be executed when it is loaded
//In this method enemy(Opponent's hand)Randomly determine
@Override
public void onEnable() {
	//Array with hand information
	String[] hand = {"goo","tyo","paa"};

	//Instantiate a class for random number generation
	Random r = new Random();
	//Generate a random number between 0 and 3 with the nextInt method,Store the corresponding hand in enemy
	enemy = hand[r.nextInt(3)];
}

This is a program that randomly determines the opponent's hand. First, prepare ʻenmy`, which is a variable that stores the other party's hand, as a field of the main class.

After that, the instance of the Random class is initialized as the processing when this program is enabled. This makes it possible to use a method for generating random numbers via this instance. Next, call the nectInt method to get a random number. The argument of this method is the maximum value of the random number generated. This program generates random numbers of 0 or more and less than 3.

By using this as an array subscript, it is possible to randomly obtain one from the three elements of 0 to 2, that is, the hand array.

Play rock-paper-scissors

//Play rock-paper-scissors with enemy by executing the janken command
    //Enter your hand as an argument
    if(cmd.getName().equalsIgnoreCase("janken")) {

    	//No arguments passed
    	if(args.length == 0)return false;

    	if(args[0].equalsIgnoreCase("paa") && enemy.equalsIgnoreCase("tyo") ||
    		args[0].equalsIgnoreCase("tyo") && enemy.equalsIgnoreCase("goo") ||
    		args[0].equalsIgnoreCase("goo") && enemy.equalsIgnoreCase("paa")){
    		//Defeat pattern
    		sender.sendMessage("My win!Think about why you lost until tomorrow");

    	}else if(args[0].equalsIgnoreCase("tyo") && enemy.equalsIgnoreCase("paa") ||
    		args[0].equalsIgnoreCase("goo") && enemy.equalsIgnoreCase("tyo") ||
        	args[0].equalsIgnoreCase("paa") && enemy.equalsIgnoreCase("goo")) {
    		//Victory pattern
    		sender.sendMessage("Do it!Let me revenge tomorrow");

    	}else if(args[0].equalsIgnoreCase(enemy)) {
    		//Aiko pattern
    		sender.sendMessage("Aikoyan!What's this?");

    	}else {
    		//Patterns other than goo tyo paa
    		return false;
    	}
    	return true;
}

And the next one looks very difficult at first glance, but the content is simple because the conditional expression is complicated. We define all the winning patterns and losing patterns in rock-paper-scissors one by one (only Aiko judges that ʻenemy and ʻargs [0] are equal).

Show opponent's hand

//Display the opponent's hand with the enemy command
if(cmd.getName().equalsIgnoreCase("enemy")) {
	sender.sendMessage("Enemy choice is " + enemy + ".");
	return true;
}

It just displays ʻenemy`. I don't think there is any particular difficulty.

Execution result

スクリーンショット 2019-08-14 20.11.54.png

References

-[List of Plugin.yml settings](https://mcmodding.jp/modding/index.php/Plugin.yml%E3%81%AE%E8%A8%AD%E5%AE%9A%E4%B8% 80% E8% A6% A7) -[Bukkit plug-in production course-No. 3] Respond to commands -[[Bukkit Plugin development] Accept command input](http://www.yk-lab.net/archives/%E3%80%90bukkit-plugin%E9%96%8B%E7%99%BA%E3% 80% 91% E3% 82% B3% E3% 83% 9E% E3% 83% B3% E3% 83% 89% E5% 85% A5% E5% 8A% 9B% E3% 82% 92% E5% 8F% 97% E3% 81% 91% E4% BB% 98% E3% 81% 91% E3% 82% 8B /)

Recommended Posts

Accept the [MineCraft Plugin] command and raise an event
Grant an access token with the curl command and POST the API
sphinx-quickstart got messy and I tried to create an alternative command and the stress disappeared