猫史档案馆


【MC服务器】RE:从零开始的基于Bukkit服务器制作生活 3.制作"设置家"插件

用户:Zhe_LearnZhe_Learn查看:0 回复:5 评论:0 创建时间:2019-01-27T14:59:11


我们进入 File -> Project Structure 然后点击左边的Modules 在右边 选择Dependencies

然后点一下“+”号 选择 1.JARs or directories 然后选择之前下载的craftbukkit-xxxxxxxxxxxxxxxxxxx.jar 然后点击下面的OK按钮

 

然后我们在src目录下新建一个包 名字叫做com.minecraft.plugin 在com.minecraft.plugin包下面新建一个叫做Re0Plugin的类

 

我们在类里面写入代码



接下来我们编译这个项目 但是这个项目 还不能正常编译 我们要先在你的项目下面新建一个文件 名字叫做plugin.yml
接下来用我们的IDE打开这个文件 在里面输入
name: {PluginName}
main: com.minecraft.plugin.{PluginClass}
version: {Plugin Version}

然后 我们再次打开File -> Project Structure 然后点击Artifacts 再点一下那个小“+”号 然后选择JAR -> From modules with dependencices
在Main Class输入com.minecraft.plugin.{ClassName}
然后点OK
接下在 在右边的一些选项里 这么填
center_image
还要在输出jar中添喵
然后点击OK就完事了

这时候 你点击 Build -> Build Project然后再次运行服务器 你会发现
center_image
所以说onEnable函数会在服务器开启的时候被客服端调用
当然 onDisable函数相反 是在服务器关闭时的center_image
接下来 你会看到标题 “设置家” 所以接下来我们要写指令了
指令分别是/sethome
和/home
我们接下来在plugin.yml添加一些代码
commands:
  home:
    description: Go Player Home
    usage: /home
  sethome:
    description: Set Player Home
    usage: /sethome

然后呢 为了能让这些只能正常的使用 我们得给他注册个事件

那么有些人就不懂了 事件是什么喵东西woc

那么事件 就是当用户做了某件事的时候 事件会通知你的程序处理用户的事

话说回来 怎么注册事件呢??

我们现在com.minecraft.plugin下创建一个包 名字叫做command 接下在包下面创建类叫做Re0CommandExec(当然名字随便啦)

先别急着写代码 我们先import一下需要的库

package com.minecraft.plugin.command;

import com.minecraft.plugin.Re0Plugin;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

然后我们写一个类

public class Re0CommandExec implements CommandExecutor {}

然后可能又有人不懂了 implements是什么意思??

implements是一个类,实现一个接口用的关键字,它用来实现接口中定义的抽象方法。 实现一个接口,必须实现接口中的所有方法。

然后我们在类下面写一个变量和构造函数

    private final Re0Plugin plugin;

    public Re0CommandExec(Re0Plugin plugin) {
        this.plugin = plugin;
    }

这是要干啥呢? 为啥要一个plugin呢?

这些都不要想 你到后面就明白了

那么接收命令的类写好了 接下来我们就写事件

事件怎么写呢?

很简单 就这样

@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {}

这样 接收事件的函数就写好了

我们现在函数内写一个

return false;

然后我们切回到我们的主类 也就是Re0Plugin类

我们类里面写

public HashMap<String, Location> playerLocation = new HashMap<String, Location>();

别急 还要在onEnable函数内写

this.getCommand("home").setExecutor(new Re0CommandExec(this));
this.getCommand("sethome").setExecutor(new Re0CommandExec(this));

这三行代码的意思是 先定义一个哈希表

然后注册/home和/sethome这两个指令的事件

同时 要记得import你的事件类哦

接下来 我们又切换到Re0CommandExec类里面

在onCommand函数内 return false;前面写以下内容

if (cmd.getName().equalsIgnoreCase("sethome")) {
            if (sender instanceof Player) {
                Player player = (Player)sender;
                this.plugin.playerLocation.put(player.getName(),player.getLocation());
                player.sendMessage(this.plugin.prefix + "设置家成功");
            } else {
                sender.sendMessage(this.plugin.prefix + "此指令只能玩家使用");
            }
            return true;
        } else if (cmd.getName().equalsIgnoreCase("home")) {
            if (sender instanceof Player) {
                Player player = (Player) sender;
                if (this.plugin.playerLocation.containsKey(player.getName())) {
                    player.teleport(this.plugin.playerLocation.get(player.getName()));
                    player.sendMessage(this.plugin.prefix + "传送成功");
                } else {
                    player.sendMessage(this.plugin.prefix + "你还没有设置家 快使用/sethome设置吧");
                }
            } else {
                sender.sendMessage(this.plugin.prefix + "此指令只能玩家使用");
            }
            return true;
        }

乍一看代码有点长 没关系 我们慢慢看

首先是cmd.getName().equalsIgnoreCase(string)

这个的意思是 获得用户输入的指令 然后判断是否和string相等

当然

用户输入 Sethome时 且string = sethome时

他会返回true而不是false

所以就是他判断相等会忽略大小写

总结:

String = string

stRing = String

就是这个意思

接下来我们看

sender instanceof Player

instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例

也就是说 他在判断sender能不能当做Player类来用 能就返回true 不能则返回false

Player player = (Player)sender;
                this.plugin.playerLocation.put(player.getName(),player.getLocation());

这个意思就是说 把sender强制转换成Player类型

然后在哈希表中加入玩家名字 和 玩家地址

然后player.sendMessage

就是提示玩家的信息(只有玩家能看到哦)

 

然后后面的else就是说当sender不是玩家发出的而是命令行(console)发出的要做一个处理 因为命令行是没有位置的

所以要提示命令行不能使用

再看下面

一些类似的我就不多bb了

直接讲HashMap的containsKey(object)什么意思

简单来说 就是说这个哈希表有没有这个key 有就返回true 没有返回false

 

再简单一点 就是看A列有这个object

center_image

(再不懂可以去世了真的不喵你)

也就是说 当玩家没有/sethome的时候 你就无法从哈希表获得数据 就会报错 程序就会有问题

所以必须要做一个判断有没有 不然玩家传送到哪都是个问题啊233333333

然后调用player.teleport()

大家都知道我的世界的/tp指令吧 tp就是teleport的意思

在我们调用teleport的时候 要给他一个Location的参数

刚好 可以从之前的getLocation获得

然后喵家传送到这个Location

就实现了设置家 传送家的功能

-------------------------------Re0的分割线由我组成------------------------------------

Q & A

Q:为什么要HashMap呢? 直接定义一个Location变量不行吗?

A:因为服务器不一定只用一个玩家 当有多个玩家的时候一个Location就不够用了233333333

Q:为什么一定要sender instanceof Player

A:因为你不知道控制台的位置


回复

上一页1 页 / 共 1下一页
Zhe_LearnZhe_Learn

https://github.com/zHElEARN/Re0ServPlugin

源码地址

点赞0


评论


雅人韵士雅人韵士

技术贴支持!

点赞0


评论


无情的AC自动鸡无情的AC自动鸡

支持技术贴

点赞0


评论


FATAL_ERRORFATAL_ERROR

不缺贴的赞b( ̄▽ ̄)d

点赞0


评论


CaTionalCaTional

支持技术贴

 

点赞0


评论