Skip to content

Commit

Permalink
添加特性,commandTodo,commandHere,commandWhereis,commandLoc
Browse files Browse the repository at this point in the history
  • Loading branch information
Gu-ZT committed Oct 28, 2024
1 parent 99700ca commit 31f4ab0
Show file tree
Hide file tree
Showing 17 changed files with 947 additions and 98 deletions.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ dependencies {

// fabric-carpet
modImplementation("curse.maven:carpet-349239:${project.carpet_core_version}")
// xaeromap
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
modImplementation("curse.maven:xaeros-world-map-317780:5658242")
modImplementation("curse.maven:xaeros-mini-map-263420:5437650")
}

processResources {
Expand Down
7 changes: 5 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@
org.gradle.jvmargs=-Xmx2G
# Fabric Properties
# check these on https://modmuss50.me/fabric.html
minecraft_version=1.21
loader_version=0.15.11
minecraft_version=1.21.1
loader_version=0.16.7

# Fabric API
fabric_version=0.107.0+1.21.1
# parchment_version=2022.08.14
# Mod Properties
mod_version=2.9.0
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/dev/dubhe/gugle/carpet/GcaExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,19 @@
import dev.dubhe.gugle.carpet.api.Consumer;
import dev.dubhe.gugle.carpet.api.tools.text.ComponentTranslate;
import dev.dubhe.gugle.carpet.commands.BotCommand;
import dev.dubhe.gugle.carpet.commands.HereCommand;
import dev.dubhe.gugle.carpet.commands.LocCommand;
import dev.dubhe.gugle.carpet.commands.TodoCommand;
import dev.dubhe.gugle.carpet.commands.WhereisCommand;
import dev.dubhe.gugle.carpet.tools.DimTypeSerializer;
import dev.dubhe.gugle.carpet.tools.FakePlayerEnderChestContainer;
import dev.dubhe.gugle.carpet.tools.FakePlayerInventoryContainer;
import dev.dubhe.gugle.carpet.tools.FakePlayerResident;
import net.fabricmc.api.ModInitializer;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
Expand All @@ -40,7 +46,10 @@

@SuppressWarnings("unused")
public class GcaExtension implements CarpetExtension, ModInitializer {
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static final Gson GSON = new GsonBuilder()
.setPrettyPrinting()
.registerTypeHierarchyAdapter(ResourceKey.class, new DimTypeSerializer())
.create();
public static String MOD_ID = "gca";
public static final Logger LOGGER = LogManager.getLogger(MOD_ID);

Expand Down Expand Up @@ -70,7 +79,7 @@ public void onPlayerLoggedOut(ServerPlayer player) {
@Override
public void onGameStarted() {
CarpetServer.settingsManager.parseSettingsClass(GcaSetting.class);
BotCommand.init(CarpetServer.minecraft_server);
BotCommand.BOT_INFO.init(CarpetServer.minecraft_server);
}

@Override
Expand Down Expand Up @@ -109,13 +118,18 @@ public void onServerLoadedWorlds(MinecraftServer server) {
} catch (IOException e) {
GcaExtension.LOGGER.error(e.getMessage(), e);
}
//noinspection ResultOfMethodCallIgnored
file.delete();
}
}

@Override
public void registerCommands(CommandDispatcher<CommandSourceStack> dispatcher, CommandBuildContext commandBuildContext) {
BotCommand.register(dispatcher);
LocCommand.register(dispatcher);
HereCommand.register(dispatcher);
WhereisCommand.register(dispatcher);
TodoCommand.register(dispatcher);
}

@Override
Expand Down
41 changes: 39 additions & 2 deletions src/main/java/dev/dubhe/gugle/carpet/GcaSetting.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package dev.dubhe.gugle.carpet;

import carpet.CarpetSettings;
import carpet.api.settings.Rule;
import carpet.api.settings.Validators;

public class GcaSetting {

public static final String GCA = "GCA";
public static final String EXPERIMENTAL = "experimental";
public static final String BOT = "BOT";
public static final String COMMAND = "command";

// 允许玩家打开假人背包
@Rule(
Expand Down Expand Up @@ -68,9 +71,43 @@ public class GcaSetting {

// 方便快捷的假人管理菜单
@Rule(
categories = {GCA, EXPERIMENTAL, BOT}
categories = {GCA, EXPERIMENTAL, BOT, COMMAND},
options = {"ops", "0", "1", "2", "3", "4", "true", "false"},
validators = Validators.CommandLevel.class
)
public static boolean commandBot = false;
public static String commandBot = "ops";

// 待办事项清单
@Rule(
categories = {GCA, EXPERIMENTAL, BOT, COMMAND},
options = {"ops", "0", "1", "2", "3", "4", "true", "false"},
validators = Validators.CommandLevel.class
)
public static String commandTodo = "ops";

// 快速发送坐标
@Rule(
categories = {GCA, EXPERIMENTAL, BOT, COMMAND},
options = {"ops", "0", "1", "2", "3", "4", "true", "false"},
validators = Validators.CommandLevel.class
)
public static String commandHere = "ops";

// 快速定位玩家
@Rule(
categories = {GCA, EXPERIMENTAL, BOT, COMMAND},
options = {"ops", "0", "1", "2", "3", "4", "true", "false"},
validators = Validators.CommandLevel.class
)
public static String commandWhereis = "ops";

// 地标管理菜单
@Rule(
categories = {GCA, EXPERIMENTAL, BOT, COMMAND},
options = {"ops", "0", "1", "2", "3", "4", "true", "false"},
validators = Validators.CommandLevel.class
)
public static String commandLoc = "ops";

// 让放置的栅栏门与你点击的栅栏门拥有相同的方块状态
@Rule(
Expand Down
118 changes: 27 additions & 91 deletions src/main/java/dev/dubhe/gugle/carpet/commands/BotCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,8 @@

import carpet.fakes.ServerPlayerInterface;
import carpet.patches.EntityPlayerMPFake;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import carpet.utils.CommandHelper;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.annotations.SerializedName;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.IntegerArgumentType;
Expand All @@ -23,50 +15,33 @@
import dev.dubhe.gugle.carpet.GcaExtension;
import dev.dubhe.gugle.carpet.GcaSetting;
import dev.dubhe.gugle.carpet.tools.FakePlayerSerializer;
import dev.dubhe.gugle.carpet.tools.FilesUtil;
import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.Style;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.storage.LevelResource;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

public class BotCommand {
private static MinecraftServer server = null;
private static final Map<String, BotInfo> BOT_INFO_MAP = new HashMap<>();
private static final String BOT_GCA_JSON = "bot.gca.json";
private static final Gson GSON = new GsonBuilder()
.setPrettyPrinting()
.registerTypeHierarchyAdapter(ResourceKey.class, new DimTypeSerializer())
.create();
public static final FilesUtil<String, BotInfo> BOT_INFO = new FilesUtil<>("bot", Object::toString, BotInfo.class);

public static void register(@NotNull CommandDispatcher<CommandSourceStack> dispatcher) {
dispatcher.register(Commands.literal("bot").requires(sourceStack -> GcaSetting.commandBot)
dispatcher.register(Commands.literal("bot")
.requires(stack -> CommandHelper.canUseCommand(stack, GcaSetting.commandBot))
.then(
Commands.literal("list").executes(BotCommand::listBot)
.then(
Expand All @@ -79,7 +54,7 @@ public static void register(@NotNull CommandDispatcher<CommandSourceStack> dispa
.then(
Commands.argument("player", EntityArgument.player())
.then(
Commands.argument("desc", StringArgumentType.string())
Commands.argument("desc", StringArgumentType.greedyString())
.executes(BotCommand::addBot)
)
)
Expand All @@ -104,19 +79,19 @@ public static void register(@NotNull CommandDispatcher<CommandSourceStack> dispa
}

private static int listBot(CommandContext<CommandSourceStack> context) {
BotCommand.init(context);
BOT_INFO.init(context);
int page;
try {
page = IntegerArgumentType.getInteger(context, "page");
} catch (IllegalArgumentException ignored) {
page = 1;
}
final int pageSize = 8;
int size = BOT_INFO_MAP.size();
int size = BOT_INFO.map.size();
int maxPage = size / pageSize + 1;
BotInfo[] botInfos = BOT_INFO_MAP.values().toArray(new BotInfo[0]);
BotInfo[] botInfos = BOT_INFO.map.values().toArray(new BotInfo[0]);
context.getSource().sendSystemMessage(
Component.literal("===== Bot List (Page %s/%s) =====".formatted(page, maxPage))
Component.literal("======= Bot List (Page %s/%s) =======".formatted(page, maxPage))
.withStyle(ChatFormatting.YELLOW)
);
for (int i = (page - 1) * pageSize; i < size && i < page * pageSize; i++) {
Expand Down Expand Up @@ -179,21 +154,21 @@ private static MutableComponent botToComponent(BotInfo botInfo) {
}

private static int loadBot(CommandContext<CommandSourceStack> context) {
BotCommand.init(context);
BOT_INFO.init(context);
CommandSourceStack source = context.getSource();
String name = StringArgumentType.getString(context, "player");
if (server.getPlayerList().getPlayerByName(name) != null) {
if (FilesUtil.server.getPlayerList().getPlayerByName(name) != null) {
source.sendFailure(Component.literal("player %s is already exist.".formatted(name)));
return 0;
}
BotInfo botInfo = BOT_INFO_MAP.getOrDefault(name, null);
BotInfo botInfo = BOT_INFO.map.getOrDefault(name, null);
if (botInfo == null) {
source.sendFailure(Component.literal("%s is not exist."));
return 0;
}
boolean success = EntityPlayerMPFake.createFake(
name,
server,
FilesUtil.server,
botInfo.pos,
botInfo.facing.y,
botInfo.facing.x,
Expand All @@ -217,19 +192,19 @@ private static int loadBot(CommandContext<CommandSourceStack> context) {
}

private static int addBot(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
BotCommand.init(context);
BOT_INFO.init(context);
CommandSourceStack source = context.getSource();
ServerPlayer p;
if (!((p = EntityArgument.getPlayer(context, "player")) instanceof EntityPlayerMPFake player)) {
source.sendFailure(Component.literal("%s is not a fake player.".formatted(p.getGameProfile().getName())));
return 0;
}
String name = player.getGameProfile().getName();
if (BOT_INFO_MAP.containsKey(name)) {
if (BOT_INFO.map.containsKey(name)) {
source.sendFailure(Component.literal("%s is already save.".formatted(name)));
return 0;
}
BotCommand.BOT_INFO_MAP.put(
BotCommand.BOT_INFO.map.put(
name,
new BotInfo(
name,
Expand All @@ -242,53 +217,26 @@ private static int addBot(CommandContext<CommandSourceStack> context) throws Com
FakePlayerSerializer.actionPackToJson(((ServerPlayerInterface) player).getActionPack())
)
);
BotCommand.save();
BOT_INFO.save();
source.sendSuccess(() -> Component.literal("%s is added.".formatted(name)), false);
return 1;
}

private static int removeBot(CommandContext<CommandSourceStack> context) {
BotCommand.init(context);
BOT_INFO.init(context);
String name = StringArgumentType.getString(context, "player");
BotCommand.BOT_INFO_MAP.remove(name);
CommandSourceStack source = context.getSource();
source.sendSuccess(() -> Component.literal("%s is removed.".formatted(name)), false);
BotCommand.save();
return 1;
}

private static void init(@NotNull CommandContext<CommandSourceStack> context) {
MinecraftServer server1 = context.getSource().getServer();
BotCommand.init(server1);
}

public static void init(MinecraftServer server1) {
if (server1 == server) return;
BotCommand.server = server1;
BotCommand.BOT_INFO_MAP.clear();
File file = BotCommand.server.getWorldPath(LevelResource.ROOT).resolve(BotCommand.BOT_GCA_JSON).toFile();
if (!file.isFile()) return;
try (BufferedReader bfr = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) {
for (Map.Entry<String, JsonElement> entry : BotCommand.GSON.fromJson(bfr, JsonObject.class).entrySet()) {
BotCommand.BOT_INFO_MAP.put(entry.getKey(), BotCommand.GSON.fromJson(entry.getValue(), BotInfo.class));
}
} catch (IOException e) {
GcaExtension.LOGGER.error(e.getMessage(), e);
BotInfo remove = BotCommand.BOT_INFO.map.remove(name);
if (remove == null) {
context.getSource().sendFailure(Component.literal("Bot %s is not exist.".formatted(name)));
return 0;
}
context.getSource().sendSuccess(() -> Component.literal("%s is removed.".formatted(name)), false);
BOT_INFO.save();
return 1;
}

private static @NotNull CompletableFuture<Suggestions> suggestPlayer(final CommandContext<CommandSourceStack> context, final SuggestionsBuilder builder) {
return SharedSuggestionProvider.suggest(BOT_INFO_MAP.keySet(), builder);
}

private static void save() {
if (BotCommand.server == null) return;
File file = BotCommand.server.getWorldPath(LevelResource.ROOT).resolve(BotCommand.BOT_GCA_JSON).toFile();
try (BufferedWriter bw = Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8)) {
BotCommand.GSON.toJson(BotCommand.BOT_INFO_MAP, bw);
} catch (IOException e) {
GcaExtension.LOGGER.error(e.getMessage(), e);
}
return SharedSuggestionProvider.suggest(BOT_INFO.map.keySet(), builder);
}

public record BotInfo(
Expand All @@ -302,16 +250,4 @@ public record BotInfo(
JsonObject actions
) {
}

public static class DimTypeSerializer implements JsonSerializer<ResourceKey<Level>>, JsonDeserializer<ResourceKey<Level>> {
@Override
public ResourceKey<Level> deserialize(@NotNull JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return ResourceKey.create(Registries.DIMENSION, ResourceLocation.parse(json.getAsString()));
}

@Override
public JsonElement serialize(@NotNull ResourceKey<Level> src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.location().toString());
}
}
}
Loading

0 comments on commit 31f4ab0

Please sign in to comment.