This commit is contained in:
parent
24aff565fb
commit
f41b75b9f3
78
README.md
78
README.md
@ -28,49 +28,81 @@
|
||||
2. 使用破坏操作需要拥有下届合金镐(作为一种使用门槛),并且消耗耐久度,同时支持耐久附魔效果;
|
||||
3. 当合金镐耐久度不足10时会自动终止任务(暂不支持恢复);
|
||||
4. 支持填充操作,填充操作需要消耗玩家物品栏中的物品;
|
||||
5. 禁止超视距操作(128以外),防止玩家利用创世神插件加载大量区块导致服务器卡顿;
|
||||
5. 支持自动从背包中的盒子里提取物品;
|
||||
6. 禁止超视距操作(128以外),防止玩家利用创世神插件加载大量区块导致服务器卡顿;
|
||||
6. 支持自动从背包里的潜影盒补充材料;
|
||||
7. 支持设置是否产生掉落物;
|
||||
8. 支持设置速度倍率(整数,默认1表示每tick操作一个方块,设置为2则每次操作两个方块)
|
||||
|
||||
## 支持版本
|
||||
|
||||
- 1.20.1+ (Folia Paper)
|
||||
- 1.20.1+ (Folia、Paper)
|
||||
|
||||
## 使用方法
|
||||
## 安装方法
|
||||
|
||||
1. 将插件放入服务器的 `plugins` 目录下
|
||||
1. 将插件放入服务器# 标题的 `plugins` 目录下
|
||||
2. 重启服务器
|
||||
3. 在 `plugins/LiteWorldEdit/config.yml` 中配置
|
||||
4. 控制台或OP输入 `/lwe reload` 重载配置
|
||||
|
||||
## 玩家使用方法
|
||||
|
||||
### 1. 指令选区
|
||||
|
||||
所有的操作均以**选区**为基础进行,因此需要先确定选区。而选区又是由点构成,因此需要先选点。
|
||||
根据小学知识,可以通过立方体对角线两点确定立方体。因此我们在进行选区操作前需要至少准备两个点。通过`/lwe point [点序号(整数)] [x] [y] [z]`
|
||||
或者 `/lwe p [点序号(整数)] [x] [y] [z]` 来选择空间中的点,点序号可以是任意想要的整数。
|
||||
|
||||
### 2. 操作
|
||||
|
||||
准备好点后即可使用对应的指令对点组成的选区进行具体的操作。如果不指定选点则默认使用 1 号 2 号点构成的区域。
|
||||
|
||||
### 3. 快捷选区
|
||||
|
||||
使用指令 `/lwe select` 打开快速选区模式,然后使用下届合金镐左键选择第一个点、右键选择第二个点,即可快速创建 1 号 2 号选点。
|
||||
|
||||
![](https://ssl.lunadeer.cn:14437/i/2024/03/20/65fa94193f11a.gif)
|
||||
|
||||
## 管理员指南
|
||||
|
||||
### Multiplier
|
||||
|
||||
默认为 1,表示每个玩家每 tick 操作1个方块,设置为 2 则表示每 tick 操作两个方块。根据服务器实际配置与玩家数量调整此配置。
|
||||
|
||||
### DropItems
|
||||
|
||||
默认为 false,如果开启则 `empty` 等清理方块的操作会像普通挖掘那样生成掉落物。建议不开启,避免滥用此功能挖矿或短时间内产生大量掉落物品造成服务器卡顿。
|
||||
|
||||
## 指令
|
||||
|
||||
以下指令尖括号`<>`表示必填参数,方括号`[]`表示可选参数。
|
||||
|
||||
### 玩家指令
|
||||
|
||||
`/lwe help` 查看帮助
|
||||
| 指令 | 功能描述 |
|
||||
|------------------------------------|---------------------------|
|
||||
| `/lwe help` | 查看帮助 |
|
||||
| `/lwe point <点序号(整数)> <x> <y> <z>` | 创建点 |
|
||||
| `/lwe p <点序号(整数)> <x> <y> <z>` | 创建点 |
|
||||
| `lwe select` | 开启/关闭选点模式 使用下届合金镐选择点 |
|
||||
| `/lwe points` | 查看当前添加的所有点 |
|
||||
| `/lwe fill [点序号A] [点序号B]` | 在AB点对角线间放置方块 - 需要手持被放置的方块 |
|
||||
| `/lwe empty [点序号A] [点序号B]` | 破坏AB点对角线间方块 - 需要拥有下届合金镐 |
|
||||
| `/lwe overlay [点序号A] [点序号B]` | 在选区地面上铺一层方块 - 需要手持被放置的方块 |
|
||||
| `/lwe drain [点序号A] [点序号B]` | 排干AB点对角线间的流体 - 需要背包里有一个海绵 |
|
||||
| `/lwe cancel` | 取消(终止)所有任务 |
|
||||
| `/lwe pause` | 暂停所有任务 |
|
||||
| `/lwe resume` | 恢复所有任务 |
|
||||
|
||||
`/lwe point [点序号(整数)] [x] [y] [z]` 创建点
|
||||
> 选区操作不填写点序号则默认使用 1 号 2 号点构成的区域。
|
||||
|
||||
`/lwe p [点序号(整数)] [x] [y] [z]` 创建点
|
||||
### 管理员指令
|
||||
|
||||
`/lwe points` 查看当前添加的所有点
|
||||
`/lwe reload` 重载配置
|
||||
|
||||
`/lwe fill [点序号A] [点序号B]` 在AB点对角线间放置方块 - 需要手持被放置的方块
|
||||
|
||||
`/lwe empty [点序号A] [点序号B]` 破坏AB点对角线间方块 - 需要拥有下届合金镐
|
||||
|
||||
`/lwe overlay [点序号A] [点序号B]` 在选区地面上铺一层方块 - 需要手持被放置的方块
|
||||
|
||||
`/lwe drain [点序号A] [点序号B]` 排干AB点对角线间的流体 - 需要背包里有一个海绵
|
||||
|
||||
`/lwe cancel` 取消(终止)所有任务
|
||||
|
||||
`/lwe pause` 暂停所有任务
|
||||
|
||||
`/lwe resume` 恢复所有任务
|
||||
|
||||
`/lwe reload` 重载配置(仅管理员)
|
||||
| 指令 | 功能描述 |
|
||||
|---------------|------|
|
||||
| `/lwe reload` | 重载配置 |
|
||||
|
||||
## 配置文件参考
|
||||
|
||||
|
2
pom.xml
2
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>site.deercloud</groupId>
|
||||
<artifactId>LiteWorldEdit</artifactId>
|
||||
<version>2.3.6.1</version>
|
||||
<version>2.4.0.2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>LiteWorldEdit</name>
|
||||
|
@ -27,7 +27,11 @@ public class Commands implements TabExecutor {
|
||||
return true;
|
||||
}
|
||||
if (Objects.equals(args[0], "point") || Objects.equals(args[0], "p")) {
|
||||
return addPoint(sender, args);
|
||||
addPoint(sender, args);
|
||||
return true;
|
||||
} else if (Objects.equals(args[0], "select")) {
|
||||
selectModeToggle(sender, args);
|
||||
return true;
|
||||
} else if (Objects.equals(args[0], "points")) {
|
||||
listPoints(sender);
|
||||
return true;
|
||||
@ -127,19 +131,14 @@ public class Commands implements TabExecutor {
|
||||
return;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
if (args.length == 3) {
|
||||
try {
|
||||
Vector2 diagonalPoint = getVector2(sender, args, player);
|
||||
if (diagonalPoint == null) return;
|
||||
Empty.empty(player, player.getWorld(), diagonalPoint.pointA, diagonalPoint.pointB);
|
||||
Notification.info(player, "已添加任务。");
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
Notification.error(player, "参数错误。");
|
||||
}
|
||||
} else {
|
||||
Notification.error(player, "参数错误。");
|
||||
}
|
||||
}
|
||||
|
||||
private static void drainTask(CommandSender sender, String[] args) {
|
||||
@ -148,19 +147,14 @@ public class Commands implements TabExecutor {
|
||||
return;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
if (args.length == 3) {
|
||||
try {
|
||||
Vector2 diagonalPoint = getVector2(sender, args, player);
|
||||
if (diagonalPoint == null) return;
|
||||
Drain.drain(player, player.getWorld(), diagonalPoint.pointA, diagonalPoint.pointB);
|
||||
Notification.info(player, "已添加任务。");
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
Notification.error(player, "参数错误。");
|
||||
}
|
||||
} else {
|
||||
Notification.error(player, "参数错误。");
|
||||
}
|
||||
}
|
||||
|
||||
private static void overlayTask(CommandSender sender, String[] args) {
|
||||
@ -169,7 +163,6 @@ public class Commands implements TabExecutor {
|
||||
return;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
if (args.length == 3) {
|
||||
try {
|
||||
Vector2 diagonalPoint = getVector2(sender, args, player);
|
||||
if (diagonalPoint == null) return;
|
||||
@ -185,9 +178,6 @@ public class Commands implements TabExecutor {
|
||||
} catch (NumberFormatException e) {
|
||||
Notification.error(player, "参数错误。");
|
||||
}
|
||||
} else {
|
||||
Notification.error(player, "参数错误。");
|
||||
}
|
||||
}
|
||||
|
||||
private static void fillTask(CommandSender sender, String[] args) {
|
||||
@ -196,7 +186,6 @@ public class Commands implements TabExecutor {
|
||||
return;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
if (args.length == 3) {
|
||||
try {
|
||||
Vector2 diagonalPoint = getVector2(sender, args, player);
|
||||
if (diagonalPoint == null) return;
|
||||
@ -212,14 +201,18 @@ public class Commands implements TabExecutor {
|
||||
} catch (NumberFormatException e) {
|
||||
Notification.error(player, "参数错误。");
|
||||
}
|
||||
} else {
|
||||
Notification.error(player, "参数错误。");
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector2 getVector2(CommandSender sender, String[] args, Player player) {
|
||||
Integer indexA = Integer.parseInt(args[1]);
|
||||
Integer indexB = Integer.parseInt(args[2]);
|
||||
int indexA;
|
||||
int indexB;
|
||||
if (args.length == 3) {
|
||||
indexA = Integer.parseInt(args[1]);
|
||||
indexB = Integer.parseInt(args[2]);
|
||||
} else {
|
||||
indexA = 1;
|
||||
indexB = 2;
|
||||
}
|
||||
Map<Integer, Point> points = LiteWorldEdit.instance.getCache().getPlayer(player).getPoints();
|
||||
if (points == null) {
|
||||
Notification.error(player, "你没有设置任何点。");
|
||||
@ -228,7 +221,7 @@ public class Commands implements TabExecutor {
|
||||
Point pointA = points.get(indexA);
|
||||
Point pointB = points.get(indexB);
|
||||
if (pointA == null || pointB == null) {
|
||||
Notification.error(player, "点不存在。");
|
||||
Notification.error(player, "点不存在,使用 /lwe points 查看所有已添加的点。");
|
||||
return null;
|
||||
}
|
||||
if (out_of_region(pointA, pointB)) {
|
||||
@ -266,10 +259,10 @@ public class Commands implements TabExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean addPoint(CommandSender sender, String[] args) {
|
||||
private static void addPoint(CommandSender sender, String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
LoggerX.err("该命令只能由玩家执行。");
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
if (args.length == 5) {
|
||||
@ -280,12 +273,12 @@ public class Commands implements TabExecutor {
|
||||
int z = Integer.parseInt(args[4]);
|
||||
// 选择的点不允许超过128格范围
|
||||
if (!Job.in_range(player, new Location(player.getWorld(), x, y, z))) {
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
Point point = new Point(x, y, z, player);
|
||||
if (!LiteWorldEdit.instance.getCache().getPlayer(player).addPoint(index, point)) {
|
||||
Notification.error(player, "点的数量不允许超过20,请使用已有点序号覆盖已有点。");
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
Notification.info(player, "点 " + index + " 已设置为 " + x + ", " + y + ", " + z + "。");
|
||||
} catch (NumberFormatException e) {
|
||||
@ -294,18 +287,26 @@ public class Commands implements TabExecutor {
|
||||
} else {
|
||||
Notification.error(player, "参数错误。");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void selectModeToggle(CommandSender sender, String[] args) {
|
||||
if (!(sender instanceof Player)) {
|
||||
LoggerX.err("该命令只能由玩家执行。");
|
||||
return;
|
||||
}
|
||||
Player player = (Player) sender;
|
||||
LiteWorldEdit.instance.getCache().getPlayer(player).toggleSelectMode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, String[] args) {
|
||||
if (args.length == 1) {
|
||||
return Arrays.asList("point", "p", "points", "fill", "empty", "overlay", "drain", "cancel", "pause", "resume", "help", "reload");
|
||||
return Arrays.asList("point", "p", "select", "points", "fill", "empty", "overlay", "drain", "cancel", "pause", "resume", "help", "reload");
|
||||
} else if (args.length == 2) {
|
||||
if (args[0].equals("point") || args[0].equals("p")) {
|
||||
return Collections.singletonList("[点序号(整数)] [x] [y] [z] - 创建点");
|
||||
return Collections.singletonList("<点序号(整数)> <x> <y> <z> - 创建点");
|
||||
} else if (args[0].equals("fill") || args[0].equals("empty") || args[0].equals("overlay") || args[0].equals("drain")) {
|
||||
return Collections.singletonList("[点序号A] [点序号B]");
|
||||
return Collections.singletonList("[点序号A] [点序号B] - 不填写默认为 1 2");
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
@ -318,7 +319,8 @@ public class Commands implements TabExecutor {
|
||||
}
|
||||
Notification.info((Player) sender, "LiteWorldEdit 帮助");
|
||||
Notification.info((Player) sender, "/lwe help - 查看帮助");
|
||||
Notification.info((Player) sender, "/lwe point|p [点序号(整数)] [x] [y] [z] - 创建点");
|
||||
Notification.info((Player) sender, "/lwe point|p <点序号(整数)> <x> <y> <z> - 创建点");
|
||||
Notification.info((Player) sender, "/lwe select - 开启/关闭选点模式 使用下届合金镐选择点");
|
||||
Notification.info((Player) sender, "/lwe points - 查看所有点");
|
||||
Notification.info((Player) sender, "/lwe fill [点序号A] [点序号B] - (在AB点对角线间放置方块 - 需要手持被放置的方块)");
|
||||
Notification.info((Player) sender, "/lwe empty [点序号A] [点序号B] - (破坏AB点对角线间方块 - 需要拥有下届合金镐)");
|
||||
|
@ -1,9 +1,17 @@
|
||||
package site.deercloud.liteworldedit;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.block.Action;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import site.deercloud.liteworldedit.Managers.Point;
|
||||
|
||||
public class Events implements Listener {
|
||||
@EventHandler
|
||||
@ -15,4 +23,37 @@ public class Events implements Listener {
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
LiteWorldEdit.instance.getCache().playerJoin(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST)
|
||||
public void selectPoint(PlayerInteractEvent event) {
|
||||
XPlayer xplayer = LiteWorldEdit.instance.getCache().getPlayer(event.getPlayer());
|
||||
if (!xplayer.isSelectMode()) {
|
||||
return;
|
||||
}
|
||||
Player player = event.getPlayer();
|
||||
ItemStack item = player.getInventory().getItemInMainHand();
|
||||
if (item.getType() != Material.NETHERITE_PICKAXE) {
|
||||
return;
|
||||
}
|
||||
Block block = event.getClickedBlock();
|
||||
Action action = event.getAction();
|
||||
if (block == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int x = block.getX();
|
||||
int y = block.getY();
|
||||
int z = block.getZ();
|
||||
Point point = new Point(x, y, z, player);
|
||||
|
||||
if (action == Action.LEFT_CLICK_BLOCK) {
|
||||
event.setCancelled(true);
|
||||
Notification.info(player, "已选择第一个点: " + x + " " + y + " " + z);
|
||||
xplayer.addPoint(1, point);
|
||||
} else if (action == Action.RIGHT_CLICK_BLOCK) {
|
||||
event.setCancelled(true);
|
||||
Notification.info(player, "已选择第二个点: " + x + " " + y + " " + z);
|
||||
xplayer.addPoint(2, point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.deercloud.liteworldedit.Jobs.Absorb;
|
||||
import site.deercloud.liteworldedit.Jobs.Remove;
|
||||
import site.deercloud.liteworldedit.LiteWorldEdit;
|
||||
import site.deercloud.liteworldedit.Managers.Point;
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
package site.deercloud.liteworldedit.JobGenerator;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.deercloud.liteworldedit.Jobs.Place;
|
||||
import site.deercloud.liteworldedit.LiteWorldEdit;
|
||||
|
@ -7,7 +7,6 @@ import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.block.SpongeAbsorbEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import site.deercloud.liteworldedit.LoggerX;
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
package site.deercloud.liteworldedit.Jobs;
|
||||
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.ShulkerBox;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -5,13 +5,9 @@ import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockBreakEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.Damageable;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import site.deercloud.liteworldedit.LiteWorldEdit;
|
||||
import site.deercloud.liteworldedit.LoggerX;
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package site.deercloud.liteworldedit.Managers;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import site.deercloud.liteworldedit.Jobs.Job;
|
||||
import site.deercloud.liteworldedit.XPlayer;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
@ -7,7 +7,7 @@ import net.kyori.adventure.title.Title;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import static site.deercloud.liteworldedit.LoggerX.*;
|
||||
import static site.deercloud.liteworldedit.LoggerX.debug;
|
||||
|
||||
public class Notification {
|
||||
private static final Style i_style = Style.style(TextColor.color(139, 255, 123));
|
||||
|
@ -3,7 +3,6 @@ package site.deercloud.liteworldedit;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.scheduler.BukkitTask;
|
||||
|
||||
public class SchedulerUtil {
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package site.deercloud.liteworldedit;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.entity.Player;
|
||||
import site.deercloud.liteworldedit.Jobs.Job;
|
||||
import site.deercloud.liteworldedit.Jobs.JobErrCode;
|
||||
|
@ -12,12 +12,14 @@ import static site.deercloud.liteworldedit.SchedulerUtil.runAtFixedRateEntity;
|
||||
|
||||
public class XPlayer {
|
||||
|
||||
private boolean select_mode = false;
|
||||
private final Map<Integer, Point> points;
|
||||
private final Player player;
|
||||
private final JobQueue queue;
|
||||
private final Task task;
|
||||
|
||||
public XPlayer(Player player) {
|
||||
Notification.info(player, "当前选点模式: 关闭");
|
||||
this.player = player;
|
||||
this.points = new HashMap<>();
|
||||
this.queue = new JobQueue(player);
|
||||
@ -25,6 +27,20 @@ public class XPlayer {
|
||||
runAtFixedRateEntity(player, LiteWorldEdit.instance, task, 1);
|
||||
}
|
||||
|
||||
public boolean isSelectMode() {
|
||||
return select_mode;
|
||||
}
|
||||
|
||||
public void toggleSelectMode() {
|
||||
select_mode = !select_mode;
|
||||
if (select_mode) {
|
||||
Notification.info(player, "当前选点模式: 开启");
|
||||
Notification.info(player, "左键选择第一个点, 右键选择第二个点");
|
||||
} else {
|
||||
Notification.info(player, "当前选点模式: 关闭");
|
||||
}
|
||||
}
|
||||
|
||||
public void addJob(Job job) {
|
||||
queue.add(job);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user