aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTrumeet <yuuta@yuuta.moe>2022-07-26 19:06:11 -0700
committerTrumeet <yuuta@yuuta.moe>2022-07-26 19:06:11 -0700
commitd8fe269327a1a51f2588a3573a4764613da16388 (patch)
tree97bd20983700bb13eba7f7d524d3c6d529303b46 /src
parent31a5d2990ba666ce5ef4a1f79f7999a9bdfaac2a (diff)
downloadacron-d8fe269327a1a51f2588a3573a4764613da16388.tar
acron-d8fe269327a1a51f2588a3573a4764613da16388.tar.gz
acron-d8fe269327a1a51f2588a3573a4764613da16388.tar.bz2
acron-d8fe269327a1a51f2588a3573a4764613da16388.zip
Move the mod to mod/
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java272
-rw-r--r--src/main/java/moe/ymc/acron/Acron.java32
-rw-r--r--src/main/java/moe/ymc/acron/MinecraftServerHolder.java28
-rw-r--r--src/main/java/moe/ymc/acron/auth/Action.java10
-rw-r--r--src/main/java/moe/ymc/acron/auth/Client.java9
-rw-r--r--src/main/java/moe/ymc/acron/auth/PolicyChecker.java42
-rw-r--r--src/main/java/moe/ymc/acron/auth/Rule.java10
-rw-r--r--src/main/java/moe/ymc/acron/c2s/ReqCmd.java51
-rw-r--r--src/main/java/moe/ymc/acron/c2s/ReqSetConfig.java63
-rw-r--r--src/main/java/moe/ymc/acron/c2s/Request.java6
-rw-r--r--src/main/java/moe/ymc/acron/cmd/CmdOut.java53
-rw-r--r--src/main/java/moe/ymc/acron/cmd/CmdQueue.java17
-rw-r--r--src/main/java/moe/ymc/acron/cmd/CmdResConsumer.java33
-rw-r--r--src/main/java/moe/ymc/acron/cmd/CmdSrc.java34
-rw-r--r--src/main/java/moe/ymc/acron/common/Vec2f.java25
-rw-r--r--src/main/java/moe/ymc/acron/common/Vec3d.java34
-rw-r--r--src/main/java/moe/ymc/acron/common/WorldKey.java35
-rw-r--r--src/main/java/moe/ymc/acron/config/Config.java30
-rw-r--r--src/main/java/moe/ymc/acron/config/ConfigReloadCmd.java41
-rw-r--r--src/main/java/moe/ymc/acron/config/json/Client.java45
-rw-r--r--src/main/java/moe/ymc/acron/config/json/Config.java103
-rw-r--r--src/main/java/moe/ymc/acron/config/json/ConfigDeserializationException.java18
-rw-r--r--src/main/java/moe/ymc/acron/config/json/ConfigDeserializer.java27
-rw-r--r--src/main/java/moe/ymc/acron/config/json/ConfigJsonObject.java7
-rw-r--r--src/main/java/moe/ymc/acron/config/json/Rule.java35
-rw-r--r--src/main/java/moe/ymc/acron/jvav/Pair.java4
-rw-r--r--src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java38
-rw-r--r--src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java41
-rw-r--r--src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java21
-rw-r--r--src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java33
-rw-r--r--src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java47
-rw-r--r--src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java65
-rw-r--r--src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java43
-rw-r--r--src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java32
-rw-r--r--src/main/java/moe/ymc/acron/net/AcronInitializer.java25
-rw-r--r--src/main/java/moe/ymc/acron/net/Attributes.java13
-rw-r--r--src/main/java/moe/ymc/acron/net/AuthHandler.java98
-rw-r--r--src/main/java/moe/ymc/acron/net/ClientConfiguration.java20
-rw-r--r--src/main/java/moe/ymc/acron/net/ClientIdentification.java11
-rw-r--r--src/main/java/moe/ymc/acron/net/HandshakeComplete.java7
-rw-r--r--src/main/java/moe/ymc/acron/net/WSFrameHandler.java174
-rw-r--r--src/main/java/moe/ymc/acron/s2c/Entity.java26
-rw-r--r--src/main/java/moe/ymc/acron/s2c/Event.java4
-rw-r--r--src/main/java/moe/ymc/acron/s2c/EventQueue.java28
-rw-r--r--src/main/java/moe/ymc/acron/s2c/event/EventDisconnected.java12
-rw-r--r--src/main/java/moe/ymc/acron/s2c/event/EventEntityDeath.java12
-rw-r--r--src/main/java/moe/ymc/acron/s2c/event/EventLagging.java9
-rw-r--r--src/main/java/moe/ymc/acron/s2c/event/EventPlayerJoined.java10
-rw-r--r--src/main/java/moe/ymc/acron/s2c/event/EventPlayerMessage.java12
-rw-r--r--src/main/java/moe/ymc/acron/s2c/response/EventCmdOut.java13
-rw-r--r--src/main/java/moe/ymc/acron/s2c/response/EventCmdRes.java10
-rw-r--r--src/main/java/moe/ymc/acron/s2c/response/EventError.java22
-rw-r--r--src/main/java/moe/ymc/acron/s2c/response/EventOk.java8
-rw-r--r--src/main/java/moe/ymc/acron/serialization/Serializer.java60
-rw-r--r--src/main/resources/acron.mixins.json21
-rw-r--r--src/main/resources/fabric.mod.json24
56 files changed, 0 insertions, 2003 deletions
diff --git a/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java b/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java
deleted file mode 100644
index 51f05ff..0000000
--- a/src/main/java/com/google/gson/typeadapters/RuntimeTypeAdapterFactory.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.gson.typeadapters;
-
-import com.google.gson.*;
-import com.google.gson.reflect.TypeToken;
-import com.google.gson.stream.JsonReader;
-import com.google.gson.stream.JsonWriter;
-
-import java.io.IOException;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-/**
- * Adapts values whose runtime type may differ from their declaration type. This
- * is necessary when a field's type is not the same type that GSON should create
- * when deserializing that field. For example, consider these types:
- * <pre> {@code
- * abstract class Shape {
- * int x;
- * int y;
- * }
- * class Circle extends Shape {
- * int radius;
- * }
- * class Rectangle extends Shape {
- * int width;
- * int height;
- * }
- * class Diamond extends Shape {
- * int width;
- * int height;
- * }
- * class Drawing {
- * Shape bottomShape;
- * Shape topShape;
- * }
- * }</pre>
- * <p>Without additional type information, the serialized JSON is ambiguous. Is
- * the bottom shape in this drawing a rectangle or a diamond? <pre> {@code
- * {
- * "bottomShape": {
- * "width": 10,
- * "height": 5,
- * "x": 0,
- * "y": 0
- * },
- * "topShape": {
- * "radius": 2,
- * "x": 4,
- * "y": 1
- * }
- * }}</pre>
- * This class addresses this problem by adding type information to the
- * serialized JSON and honoring that type information when the JSON is
- * deserialized: <pre> {@code
- * {
- * "bottomShape": {
- * "type": "Diamond",
- * "width": 10,
- * "height": 5,
- * "x": 0,
- * "y": 0
- * },
- * "topShape": {
- * "type": "Circle",
- * "radius": 2,
- * "x": 4,
- * "y": 1
- * }
- * }}</pre>
- * Both the type field name ({@code "type"}) and the type labels ({@code
- * "Rectangle"}) are configurable.
- *
- * <h3>Registering Types</h3>
- * Create a {@code RuntimeTypeAdapterFactory} by passing the base type and type field
- * name to the {@link #of} factory method. If you don't supply an explicit type
- * field name, {@code "type"} will be used. <pre> {@code
- * RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory
- * = RuntimeTypeAdapterFactory.of(Shape.class, "type");
- * }</pre>
- * Next register all of your subtypes. Every subtype must be explicitly
- * registered. This protects your application from injection attacks. If you
- * don't supply an explicit type label, the type's simple name will be used.
- * <pre> {@code
- * shapeAdapterFactory.registerSubtype(Rectangle.class, "Rectangle");
- * shapeAdapterFactory.registerSubtype(Circle.class, "Circle");
- * shapeAdapterFactory.registerSubtype(Diamond.class, "Diamond");
- * }</pre>
- * Finally, register the type adapter factory in your application's GSON builder:
- * <pre> {@code
- * Gson gson = new GsonBuilder()
- * .registerTypeAdapterFactory(shapeAdapterFactory)
- * .create();
- * }</pre>
- * Like {@code GsonBuilder}, this API supports chaining: <pre> {@code
- * RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class)
- * .registerSubtype(Rectangle.class)
- * .registerSubtype(Circle.class)
- * .registerSubtype(Diamond.class);
- * }</pre>
- *
- * <h3>Serialization and deserialization</h3>
- * In order to serialize and deserialize a polymorphic object,
- * you must specify the base type explicitly.
- * <pre> {@code
- * Diamond diamond = new Diamond();
- * String json = gson.toJson(diamond, Shape.class);
- * }</pre>
- * And then:
- * <pre> {@code
- * Shape shape = gson.fromJson(json, Shape.class);
- * }</pre>
- */
-public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
- private final Class<?> baseType;
- private final String typeFieldName;
- private final Map<String, Class<?>> labelToSubtype = new LinkedHashMap<>();
- private final Map<Class<?>, String> subtypeToLabel = new LinkedHashMap<>();
- private final boolean maintainType;
-
- private RuntimeTypeAdapterFactory(Class<?> baseType, String typeFieldName, boolean maintainType) {
- if (typeFieldName == null || baseType == null) {
- throw new NullPointerException();
- }
- this.baseType = baseType;
- this.typeFieldName = typeFieldName;
- this.maintainType = maintainType;
- }
-
- /**
- * Creates a new runtime type adapter using for {@code baseType} using {@code
- * typeFieldName} as the type field name. Type field names are case sensitive.
- * {@code maintainType} flag decide if the type will be stored in pojo or not.
- */
- public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName, boolean maintainType) {
- return new RuntimeTypeAdapterFactory<>(baseType, typeFieldName, maintainType);
- }
-
- /**
- * Creates a new runtime type adapter using for {@code baseType} using {@code
- * typeFieldName} as the type field name. Type field names are case sensitive.
- */
- public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName) {
- return new RuntimeTypeAdapterFactory<>(baseType, typeFieldName, false);
- }
-
- /**
- * Creates a new runtime type adapter for {@code baseType} using {@code "type"} as
- * the type field name.
- */
- public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType) {
- return new RuntimeTypeAdapterFactory<>(baseType, "type", false);
- }
-
- /**
- * Registers {@code type} identified by {@code label}. Labels are case
- * sensitive.
- *
- * @throws IllegalArgumentException if either {@code type} or {@code label}
- * have already been registered on this type adapter.
- */
- public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type, String label) {
- if (type == null || label == null) {
- throw new NullPointerException();
- }
- if (subtypeToLabel.containsKey(type) || labelToSubtype.containsKey(label)) {
- throw new IllegalArgumentException("types and labels must be unique");
- }
- labelToSubtype.put(label, type);
- subtypeToLabel.put(type, label);
- return this;
- }
-
- /**
- * Registers {@code type} identified by its {@link Class#getSimpleName simple
- * name}. Labels are case sensitive.
- *
- * @throws IllegalArgumentException if either {@code type} or its simple name
- * have already been registered on this type adapter.
- */
- public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type) {
- return registerSubtype(type, type.getSimpleName());
- }
-
- @Override
- public <R> TypeAdapter<R> create(Gson gson, TypeToken<R> type) {
- // Workaround found at https://github.com/google/gson/issues/712#issuecomment-148955110
- if (null == type || !baseType.isAssignableFrom(type.getRawType())) {
- // if (type.getRawType() != baseType) {
- return null;
- }
-
- final TypeAdapter<JsonElement> jsonElementAdapter = gson.getAdapter(JsonElement.class);
- final Map<String, TypeAdapter<?>> labelToDelegate = new LinkedHashMap<>();
- final Map<Class<?>, TypeAdapter<?>> subtypeToDelegate = new LinkedHashMap<>();
- for (Map.Entry<String, Class<?>> entry : labelToSubtype.entrySet()) {
- TypeAdapter<?> delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue()));
- labelToDelegate.put(entry.getKey(), delegate);
- subtypeToDelegate.put(entry.getValue(), delegate);
- }
-
- return new TypeAdapter<R>() {
- @Override public R read(JsonReader in) throws IOException {
- JsonElement jsonElement = jsonElementAdapter.read(in);
- JsonElement labelJsonElement;
- if (maintainType) {
- labelJsonElement = jsonElement.getAsJsonObject().get(typeFieldName);
- } else {
- labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName);
- }
-
- if (labelJsonElement == null) {
- throw new JsonParseException("cannot deserialize " + baseType
- + " because it does not define a field named " + typeFieldName);
- }
- String label = labelJsonElement.getAsString();
- @SuppressWarnings("unchecked") // registration requires that subtype extends T
- TypeAdapter<R> delegate = (TypeAdapter<R>) labelToDelegate.get(label);
- if (delegate == null) {
- throw new JsonParseException("cannot deserialize " + baseType + " subtype named "
- + label + "; did you forget to register a subtype?");
- }
- return delegate.fromJsonTree(jsonElement);
- }
-
- @Override public void write(JsonWriter out, R value) throws IOException {
- Class<?> srcType = value.getClass();
- String label = subtypeToLabel.get(srcType);
- @SuppressWarnings("unchecked") // registration requires that subtype extends T
- TypeAdapter<R> delegate = (TypeAdapter<R>) subtypeToDelegate.get(srcType);
- if (delegate == null) {
- throw new JsonParseException("cannot serialize " + srcType.getName()
- + "; did you forget to register a subtype?");
- }
- JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject();
-
- if (maintainType) {
- jsonElementAdapter.write(out, jsonObject);
- return;
- }
-
- JsonObject clone = new JsonObject();
-
- if (jsonObject.has(typeFieldName)) {
- throw new JsonParseException("cannot serialize " + srcType.getName()
- + " because it already defines a field named " + typeFieldName);
- }
- clone.add(typeFieldName, new JsonPrimitive(label));
-
- for (Map.Entry<String, JsonElement> e : jsonObject.entrySet()) {
- clone.add(e.getKey(), e.getValue());
- }
- jsonElementAdapter.write(out, clone);
- }
- }.nullSafe();
- }
-}
diff --git a/src/main/java/moe/ymc/acron/Acron.java b/src/main/java/moe/ymc/acron/Acron.java
deleted file mode 100644
index d6f6214..0000000
--- a/src/main/java/moe/ymc/acron/Acron.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package moe.ymc.acron;
-
-import moe.ymc.acron.config.Config;
-import moe.ymc.acron.config.json.ConfigDeserializer;
-import net.fabricmc.api.ModInitializer;
-import net.fabricmc.loader.api.FabricLoader;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.IOException;
-import java.nio.file.Path;
-
-public class Acron implements ModInitializer {
- private static final Logger LOGGER = LogManager.getLogger();
-
- @Override
- public void onInitialize() {
- LOGGER.debug("onInitialize");
- try {
- final Path config = FabricLoader
- .getInstance().getConfigDir()
- .resolve("acron.json");
- if (!config.toFile().exists()) {
- throw new IllegalStateException("Cannot find config/acron.json.");
- }
- final Config cfg = ConfigDeserializer.deserialize(config.toFile(), true);
- Config.setGlobalConfig(cfg);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/src/main/java/moe/ymc/acron/MinecraftServerHolder.java b/src/main/java/moe/ymc/acron/MinecraftServerHolder.java
deleted file mode 100644
index f522884..0000000
--- a/src/main/java/moe/ymc/acron/MinecraftServerHolder.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package moe.ymc.acron;
-
-import net.minecraft.server.dedicated.MinecraftDedicatedServer;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-
-public class MinecraftServerHolder {
- private static final Logger LOGGER = LogManager.getLogger();
- public static MinecraftDedicatedServer server;
-
- public static void setServer(@NotNull MinecraftDedicatedServer server) {
- if (MinecraftServerHolder.server != null) {
- throw new IllegalStateException();
- }
- LOGGER.debug("Got MinecraftDedicatedServer on thread {}.",
- Thread.currentThread().getName());
- MinecraftServerHolder.server = server;
- }
-
- public static @NotNull MinecraftDedicatedServer getServer() {
- if (server == null) {
- throw new IllegalStateException(String.format("[%s] getServer() called before a server is ready.",
- Thread.currentThread().getName()));
- }
- return server;
- }
-}
diff --git a/src/main/java/moe/ymc/acron/auth/Action.java b/src/main/java/moe/ymc/acron/auth/Action.java
deleted file mode 100644
index 17d29a3..0000000
--- a/src/main/java/moe/ymc/acron/auth/Action.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package moe.ymc.acron.auth;
-
-import com.google.gson.annotations.SerializedName;
-
-public enum Action {
- @SerializedName("allow")
- ALLOW,
- @SerializedName("deny")
- DENY
-}
diff --git a/src/main/java/moe/ymc/acron/auth/Client.java b/src/main/java/moe/ymc/acron/auth/Client.java
deleted file mode 100644
index 2124ad4..0000000
--- a/src/main/java/moe/ymc/acron/auth/Client.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package moe.ymc.acron.auth;
-
-import org.jetbrains.annotations.NotNull;
-
-public record Client(@NotNull String id,
- @NotNull String token,
- @NotNull Action policyMode,
- @NotNull Rule[] rules) {
-}
diff --git a/src/main/java/moe/ymc/acron/auth/PolicyChecker.java b/src/main/java/moe/ymc/acron/auth/PolicyChecker.java
deleted file mode 100644
index 2ab7b97..0000000
--- a/src/main/java/moe/ymc/acron/auth/PolicyChecker.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package moe.ymc.acron.auth;
-
-import moe.ymc.acron.jvav.Pair;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-
-public class PolicyChecker {
- private static final Logger LOGGER = LogManager.getLogger();
-
- public static Pair<Action, Boolean> check(@NotNull Client client,
- @NotNull String command) {
- final String commandToMatch = command.startsWith("/") ?
- command.substring(1) :
- command;
- for (int i = 0; i < client.rules().length; i++) {
- final Rule rule = client.rules()[i];
- if (rule.cmdPattern().matcher(commandToMatch).matches()) {
- if (rule.action() == Action.DENY) {
- LOGGER.warn("The command from client {}, `{}`, was " +
- "explicitly denied by rule #{} (starting from 1).",
- client.id(),
- command,
- i + 1);
- } else {
- LOGGER.warn("The command from client {}, `{}`, was " +
- "explicitly allowed by rule #{} (starting from 1).",
- client.id(),
- command,
- i + 1);
- }
- return new Pair<>(rule.action(), rule.display());
- }
- }
- LOGGER.warn("The command from client {}, `{}`, was " +
- "implicitly {} by the default policy mode.",
- client.id(),
- command,
- client.policyMode() == Action.ALLOW ? "allowed" : "denied");
- return new Pair<>(client.policyMode() == Action.ALLOW ? Action.ALLOW : Action.DENY, false);
- }
-}
diff --git a/src/main/java/moe/ymc/acron/auth/Rule.java b/src/main/java/moe/ymc/acron/auth/Rule.java
deleted file mode 100644
index 55ad0d7..0000000
--- a/src/main/java/moe/ymc/acron/auth/Rule.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package moe.ymc.acron.auth;
-
-import org.jetbrains.annotations.NotNull;
-
-import java.util.regex.Pattern;
-
-public record Rule(@NotNull Pattern cmdPattern,
- @NotNull Action action,
- boolean display) {
-}
diff --git a/src/main/java/moe/ymc/acron/c2s/ReqCmd.java b/src/main/java/moe/ymc/acron/c2s/ReqCmd.java
deleted file mode 100644
index 6f34b07..0000000
--- a/src/main/java/moe/ymc/acron/c2s/ReqCmd.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package moe.ymc.acron.c2s;
-
-import com.google.gson.*;
-import com.google.gson.annotations.SerializedName;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.lang.reflect.Type;
-
-public record ReqCmd(@SerializedName("id") int id,
- @SerializedName("cmd") @NotNull String cmd,
- @SerializedName("config") @Nullable ReqSetConfig config)
- implements Request {
- @Override
- public void validate() {
- if (cmd == null) {
- throw new IllegalArgumentException("Property 'cmd' cannot be null.");
- }
- }
-
- @Override
- public int getId() {
- return id;
- }
-
- public static class ReqCmdDeserializer implements JsonDeserializer<ReqCmd> {
- @Override
- public ReqCmd deserialize(JsonElement json,
- Type typeOfT,
- JsonDeserializationContext context) throws JsonParseException {
- final JsonObject object = json.getAsJsonObject();
- final int id = object.has("id") ?
- object.get("id").getAsInt() :
- -1;
- final String cmd = object.has("cmd") ?
- object.get("cmd").getAsString() :
- null;
- // We cannot use context#deserialize here
- // because RuntimeTypeAdapterFactory keeps kicking in
- // and asking for the 'type' property
- // which is obviously redundant for an inner field.
- // Thus, I pass it directly to the deserializer
- // to bypass the RuntimeTypeAdapterFactory.
- final ReqSetConfig reqSetConfig = object.has("config") ?
- new ReqSetConfig.ReqSetConfigDeserializer()
- .deserialize(object.get("config"), ReqSetConfig.class, context) :
- null;
- return new ReqCmd(id, cmd, reqSetConfig);
- }
- }
-}
diff --git a/src/main/java/moe/ymc/acron/c2s/ReqSetConfig.java b/src/main/java/moe/ymc/acron/c2s/ReqSetConfig.java
deleted file mode 100644
index fcddf35..0000000
--- a/src/main/java/moe/ymc/acron/c2s/ReqSetConfig.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package moe.ymc.acron.c2s;
-
-import com.google.gson.*;
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.common.Vec2f;
-import moe.ymc.acron.common.Vec3d;
-import moe.ymc.acron.common.WorldKey;
-import org.jetbrains.annotations.Nullable;
-
-import java.lang.reflect.Type;
-
-public record ReqSetConfig(@SerializedName("id") int id,
- @SerializedName("world") @Nullable WorldKey world,
- @SerializedName("pos") @Nullable Vec3d pos,
- @SerializedName("rot") @Nullable Vec2f rot,
- @SerializedName("name") @Nullable String name)
- implements Request {
- @Override
- public void validate() {
- }
-
- @Override
- public int getId() {
- return id;
- }
-
- public static class ReqSetConfigDeserializer implements JsonDeserializer<ReqSetConfig> {
- @Override
- public ReqSetConfig deserialize(JsonElement json,
- Type typeOfT,
- JsonDeserializationContext context) throws JsonParseException {
- final JsonObject object = json.getAsJsonObject();
- final int id = object.has("id") ?
- object.get("id").getAsInt() :
- -1;
- final WorldKey world;
- if (object.has("world")) {
- world = context.deserialize(object.get("world"), WorldKey.class);
- // https://stackoverflow.com/a/49574019
- if (world == null) {
- throw new JsonParseException("Invalid world");
- }
- } else {
- world = null;
- }
- final Vec3d pos = object.has("pos") ?
- context.deserialize(object.get("pos"), Vec3d.class) :
- null;
- final Vec2f rot = object.has("rot") ?
- context.deserialize(object.get("rot"), Vec2f.class) :
- null;
- final String name = object.has("name") ?
- object.get("name").getAsString() :
- null;
- return new ReqSetConfig(id,
- world,
- pos,
- rot,
- name);
- }
- }
-
-} \ No newline at end of file
diff --git a/src/main/java/moe/ymc/acron/c2s/Request.java b/src/main/java/moe/ymc/acron/c2s/Request.java
deleted file mode 100644
index af81705..0000000
--- a/src/main/java/moe/ymc/acron/c2s/Request.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package moe.ymc.acron.c2s;
-
-public interface Request {
- int getId();
- void validate() throws IllegalArgumentException;
-}
diff --git a/src/main/java/moe/ymc/acron/cmd/CmdOut.java b/src/main/java/moe/ymc/acron/cmd/CmdOut.java
deleted file mode 100644
index 55eadf1..0000000
--- a/src/main/java/moe/ymc/acron/cmd/CmdOut.java
+++ /dev/null
@@ -1,53 +0,0 @@
-package moe.ymc.acron.cmd;
-
-import io.netty.channel.Channel;
-import moe.ymc.acron.s2c.response.EventCmdOut;
-import moe.ymc.acron.serialization.Serializer;
-import net.minecraft.server.command.CommandOutput;
-import net.minecraft.text.Text;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.UUID;
-
-public class CmdOut implements CommandOutput {
- private static final Logger LOGGER = LogManager.getLogger();
-
- private final @NotNull Channel channel;
- private final int id;
- private final boolean display;
-
- public CmdOut(@NotNull Channel channel,
- int id,
- boolean display) {
- this.channel = channel;
- this.id = id;
- this.display = display;
- }
-
- @Override
- public void sendSystemMessage(Text message, UUID sender) {
- LOGGER.debug("sendSystemMessage[{}]: {}",
- id,
- message.getString());
- channel.writeAndFlush(
- Serializer.serialize(new EventCmdOut(id, sender, message.getString()))
- );
- }
-
- @Override
- public boolean shouldReceiveFeedback() {
- return true;
- }
-
- @Override
- public boolean shouldTrackOutput() {
- return true;
- }
-
- @Override
- public boolean shouldBroadcastConsoleToOps() {
- return display;
- }
-}
diff --git a/src/main/java/moe/ymc/acron/cmd/CmdQueue.java b/src/main/java/moe/ymc/acron/cmd/CmdQueue.java
deleted file mode 100644
index 3c49143..0000000
--- a/src/main/java/moe/ymc/acron/cmd/CmdQueue.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package moe.ymc.acron.cmd;
-
-import io.netty.channel.Channel;
-import moe.ymc.acron.MinecraftServerHolder;
-import moe.ymc.acron.net.ClientConfiguration;
-import org.jetbrains.annotations.NotNull;
-
-public class CmdQueue {
- public static void enqueue(int id,
- boolean display,
- @NotNull final Channel channel,
- @NotNull final ClientConfiguration configuration,
- @NotNull final String command) {
- MinecraftServerHolder.getServer().enqueueCommand(command,
- new CmdSrc(channel, id, display, configuration, MinecraftServerHolder.getServer()));
- }
-}
diff --git a/src/main/java/moe/ymc/acron/cmd/CmdResConsumer.java b/src/main/java/moe/ymc/acron/cmd/CmdResConsumer.java
deleted file mode 100644
index d22b77e..0000000
--- a/src/main/java/moe/ymc/acron/cmd/CmdResConsumer.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package moe.ymc.acron.cmd;
-
-import com.mojang.brigadier.ResultConsumer;
-import com.mojang.brigadier.context.CommandContext;
-import io.netty.channel.Channel;
-import moe.ymc.acron.s2c.response.EventCmdRes;
-import moe.ymc.acron.serialization.Serializer;
-import net.minecraft.server.command.ServerCommandSource;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-
-public class CmdResConsumer implements ResultConsumer<ServerCommandSource> {
- private static final Logger LOGGER = LogManager.getLogger();
-
- private final @NotNull Channel channel;
- private final int id;
-
- public CmdResConsumer(@NotNull Channel channel,
- int id) {
- this.channel = channel;
- this.id = id;
- }
-
- @Override
- public void onCommandComplete(CommandContext<ServerCommandSource> context, boolean success, int result) {
- LOGGER.debug("onCommandComplete[{}]: {} {}",
- id,
- success,
- result);
- channel.writeAndFlush(Serializer.serialize(new EventCmdRes(id, success, result)));
- }
-}
diff --git a/src/main/java/moe/ymc/acron/cmd/CmdSrc.java b/src/main/java/moe/ymc/acron/cmd/CmdSrc.java
deleted file mode 100644
index 983b4ed..0000000
--- a/src/main/java/moe/ymc/acron/cmd/CmdSrc.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package moe.ymc.acron.cmd;
-
-import io.netty.channel.Channel;
-import moe.ymc.acron.net.ClientConfiguration;
-import net.minecraft.command.argument.EntityAnchorArgumentType;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.command.ServerCommandSource;
-import net.minecraft.text.LiteralText;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-
-class CmdSrc extends ServerCommandSource {
- private static final Logger LOGGER = LogManager.getLogger();
-
- public CmdSrc(@NotNull Channel channel,
- int id,
- boolean display,
- @NotNull ClientConfiguration configuration,
- @NotNull MinecraftServer server) {
- super(new CmdOut(channel, id, display),
- configuration.pos(),
- configuration.rot(),
- configuration.world(),
- 4,
- configuration.name(),
- new LiteralText(configuration.name()),
- server,
- null,
- false,
- new CmdResConsumer(channel, id),
- EntityAnchorArgumentType.EntityAnchor.FEET);
- }
-}
diff --git a/src/main/java/moe/ymc/acron/common/Vec2f.java b/src/main/java/moe/ymc/acron/common/Vec2f.java
deleted file mode 100644
index 5ab3dfd..0000000
--- a/src/main/java/moe/ymc/acron/common/Vec2f.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package moe.ymc.acron.common;
-
-import com.google.gson.*;
-import com.google.gson.annotations.SerializedName;
-
-import java.lang.reflect.Type;
-
-public record Vec2f(@SerializedName("x") float x,
- @SerializedName("y") float y) {
- public static class Vec2fDeserializer implements JsonDeserializer<Vec2f> {
- @Override
- public Vec2f deserialize(JsonElement json,
- Type typeOfT,
- JsonDeserializationContext context) throws JsonParseException {
- final JsonObject object = json.getAsJsonObject();
- final float x = object.has("x") ?
- object.get("x").getAsFloat() :
- 0.0f;
- final float y = object.has("y") ?
- object.get("y").getAsFloat() :
- 0.0f;
- return new Vec2f(x, y);
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/moe/ymc/acron/common/Vec3d.java b/src/main/java/moe/ymc/acron/common/Vec3d.java
deleted file mode 100644
index 593019f..0000000
--- a/src/main/java/moe/ymc/acron/common/Vec3d.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package moe.ymc.acron.common;
-
-import com.google.gson.*;
-import com.google.gson.annotations.SerializedName;
-import org.jetbrains.annotations.NotNull;
-
-import java.lang.reflect.Type;
-
-public record Vec3d(@SerializedName("x") double x,
- @SerializedName("y") double y,
- @SerializedName("z") double z) {
- public Vec3d(@NotNull net.minecraft.util.math.Vec3d vec3d) {
- this(vec3d.x, vec3d.y, vec3d.z);
- }
-
- public static class Vec3dDeserializer implements JsonDeserializer<Vec3d> {
- @Override
- public Vec3d deserialize(JsonElement json,
- Type typeOfT,
- JsonDeserializationContext context) throws JsonParseException {
- final JsonObject object = json.getAsJsonObject();
- final double x = object.has("x") ?
- object.get("x").getAsDouble() :
- 0.0;
- final double y = object.has("y") ?
- object.get("y").getAsDouble() :
- 0.0;
- final double z = object.has("z") ?
- object.get("z").getAsDouble() :
- 0.0;
- return new Vec3d(x, y, z);
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/moe/ymc/acron/common/WorldKey.java b/src/main/java/moe/ymc/acron/common/WorldKey.java
deleted file mode 100644
index fa10d54..0000000
--- a/src/main/java/moe/ymc/acron/common/WorldKey.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package moe.ymc.acron.common;
-
-import com.google.gson.annotations.SerializedName;
-import net.minecraft.util.Identifier;
-import net.minecraft.world.dimension.DimensionType;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public enum WorldKey {
- @SerializedName("overworld")
- OVERWORLD,
- @SerializedName("nether")
- NETHER,
- @SerializedName("end")
- END;
-
- private static final Logger LOGGER = LogManager.getLogger();
-
- public static @Nullable WorldKey create(@NotNull Identifier identifier) {
- if (identifier.equals(DimensionType.OVERWORLD_ID)) {
- return OVERWORLD;
- } else if (identifier.equals(DimensionType.THE_NETHER_ID)) {
- return NETHER;
- } else if (identifier.equals(DimensionType.THE_END_ID)) {
- return END;
- } else {
- LOGGER.warn("Unknown world {}:{}. Returning NULL to the client.",
- identifier.getNamespace(),
- identifier.getPath());
- return null;
- }
- }
-} \ No newline at end of file
diff --git a/src/main/java/moe/ymc/acron/config/Config.java b/src/main/java/moe/ymc/acron/config/Config.java
deleted file mode 100644
index 3749c25..0000000
--- a/src/main/java/moe/ymc/acron/config/Config.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package moe.ymc.acron.config;
-
-import moe.ymc.acron.auth.Client;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-
-import java.net.InetAddress;
-import java.util.Map;
-
-public record Config(@NotNull InetAddress address,
- int port,
- boolean useNativeTransport,
- @NotNull Map<String, Client> clients) {
- private static final Logger LOGGER = LogManager.getLogger();
- private static Config globalConfig;
-
- @NotNull
- public static Config getGlobalConfig() {
- return globalConfig;
- }
-
- public static void setGlobalConfig(@NotNull Config globalConfig) {
- Config.globalConfig = globalConfig;
- LOGGER.info("Config loaded with {} clients. Listening on {}:{}.",
- globalConfig.clients.size(),
- globalConfig.address.toString(),
- globalConfig.port);
- }
-} \ No newline at end of file
diff --git a/src/main/java/moe/ymc/acron/config/ConfigReloadCmd.java b/src/main/java/moe/ymc/acron/config/ConfigReloadCmd.java
deleted file mode 100644
index 2774c4d..0000000
--- a/src/main/java/moe/ymc/acron/config/ConfigReloadCmd.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package moe.ymc.acron.config;
-
-import com.mojang.brigadier.Command;
-import com.mojang.brigadier.context.CommandContext;
-import com.mojang.brigadier.exceptions.CommandSyntaxException;
-import moe.ymc.acron.config.json.ConfigDeserializationException;
-import moe.ymc.acron.config.json.ConfigDeserializer;
-import net.fabricmc.loader.api.FabricLoader;
-import net.minecraft.server.command.ServerCommandSource;
-import net.minecraft.text.LiteralText;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.IOException;
-import java.nio.file.Path;
-
-public class ConfigReloadCmd implements Command<ServerCommandSource> {
- private static final Logger LOGGER = LogManager.getLogger();
-
- @Override
- public int run(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
- LOGGER.info("Reloading rules.");
- try {
- final Path config = FabricLoader
- .getInstance().getConfigDir()
- .resolve("acron.json");
- if (!config.toFile().exists()) {
- throw new IllegalStateException("Cannot find config/acron.json.");
- }
- final Config cfg = ConfigDeserializer.deserialize(config.toFile(), false);
- Config.setGlobalConfig(cfg);
- context.getSource().sendFeedback(new LiteralText("Rules reloaded."), true);
- return 0;
- } catch (IOException | ConfigDeserializationException e) {
- LOGGER.error("Cannot reload config.", e);
- context.getSource().sendError(new LiteralText("Cannot reload rules: " +
- e.getMessage()));
- return 1;
- }
- }
-}
diff --git a/src/main/java/moe/ymc/acron/config/json/Client.java b/src/main/java/moe/ymc/acron/config/json/Client.java
deleted file mode 100644
index 4d31308..0000000
--- a/src/main/java/moe/ymc/acron/config/json/Client.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package moe.ymc.acron.config.json;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.auth.Action;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.List;
-
-class Client implements ConfigJsonObject<moe.ymc.acron.auth.Client> {
- @SerializedName("id")
- private final String id;
-
- @SerializedName("token")
- private final String token;
-
- @SerializedName("policy_mode")
- private final Action policyMode;
-
- @SerializedName("rules")
- private final List<Rule> rules;
-
- private Client(String id,
- String token,
- Action policyMode,
- List<Rule> rules) {
- this.id = id;
- this.token = token;
- this.policyMode = policyMode;
- this.rules = rules;
- }
-
- @Override
- public @NotNull moe.ymc.acron.auth.Client create(boolean startup) throws ConfigDeserializationException {
- if (id == null || id.trim().equals("") ||
- token == null || token.trim().equals("")) {
- throw new ConfigDeserializationException(".clients[].id or .clients[].token is not supplied.");
- }
- return new moe.ymc.acron.auth.Client(id,
- token,
- policyMode == null ? Action.DENY : policyMode,
- rules == null ? new moe.ymc.acron.auth.Rule[]{} :
- rules.stream().map(rule -> rule.create(startup)).toList()
- .toArray(new moe.ymc.acron.auth.Rule[rules.size()]));
- }
-}
diff --git a/src/main/java/moe/ymc/acron/config/json/Config.java b/src/main/java/moe/ymc/acron/config/json/Config.java
deleted file mode 100644
index e8c5a83..0000000
--- a/src/main/java/moe/ymc/acron/config/json/Config.java
+++ /dev/null
@@ -1,103 +0,0 @@
-package moe.ymc.acron.config.json;
-
-import com.google.gson.annotations.SerializedName;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-class Config implements ConfigJsonObject<moe.ymc.acron.config.Config> {
- private static final Logger LOGGER = LogManager.getLogger();
-
- @SerializedName("listen")
- private final String listen;
-
- @SerializedName("port")
- private final Integer port;
-
- @SerializedName("native_transport")
- private final boolean nativeTransport;
-
- @SerializedName("clients")
- private final List<Client> clients;
-
- private Config(String listen,
- Integer port,
- boolean nativeTransport,
- List<Client> clients) {
- this.listen = listen;
- this.port = port;
- this.nativeTransport = nativeTransport;
- this.clients = clients;
- }
-
- @Override
- public @NotNull moe.ymc.acron.config.Config create(boolean startup) throws ConfigDeserializationException {
- final InetAddress address;
- final int p;
- final boolean nt;
- if (!startup) {
- address = moe.ymc.acron.config.Config.getGlobalConfig().address();
- p = moe.ymc.acron.config.Config.getGlobalConfig().port();
- nt = moe.ymc.acron.config.Config.getGlobalConfig().useNativeTransport();
- } else {
- if (listen == null || listen.trim().equals("")) {
- address = InetAddress.getLoopbackAddress();
- } else {
- try {
- address = InetAddress.getByName(listen);
- } catch (UnknownHostException e) {
- throw new ConfigDeserializationException("Cannot parse address: " + e.getMessage(),
- true);
- }
- }
- if (port == null) {
- p = 25575;
- } else {
- if (port < 0 || port > 65535) {
- throw new ConfigDeserializationException("The port is out of range.", true);
- }
- p = port;
- }
- nt = nativeTransport;
- }
-
-
- Map<String, moe.ymc.acron.auth.Client> map;
- try {
- if (clients != null) {
- map = clients.stream()
- .collect(Collectors.<Client, String, moe.ymc.acron.auth.Client>
- toMap(client -> client.create(startup).id(),
- client -> client.create(startup)));
- } else {
- map = new HashMap<>(0);
- }
- } catch (IllegalStateException e) {
- // Collision.
- LOGGER.error("Duplicate clients with the same ID in the Acron configuration. All clients are ignored. " +
- "Fix the configuration and reload.", e);
- if (!startup) {
- throw new ConfigDeserializationException("Duplicate clients with the same ID: " + e.getMessage());
- }
- map = new HashMap<>(0);
- } catch (ConfigDeserializationException e) {
- LOGGER.error("Cannot parse the Acron configuration. All clients are ignored. " +
- "Fix the configuration and reload.", e);
- if (!startup) {
- throw e;
- }
- map = new HashMap<>(0);
- }
- return new moe.ymc.acron.config.Config(address,
- p,
- nt,
- map);
- }
-}
diff --git a/src/main/java/moe/ymc/acron/config/json/ConfigDeserializationException.java b/src/main/java/moe/ymc/acron/config/json/ConfigDeserializationException.java
deleted file mode 100644
index baf5b35..0000000
--- a/src/main/java/moe/ymc/acron/config/json/ConfigDeserializationException.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package moe.ymc.acron.config.json;
-
-public class ConfigDeserializationException extends RuntimeException {
- private final boolean fetal;
-
- public ConfigDeserializationException(String message) {
- this(message, false);
- }
-
- public ConfigDeserializationException(String message, boolean fetal) {
- super(message);
- this.fetal = fetal;
- }
-
- public boolean isFetal() {
- return fetal;
- }
-}
diff --git a/src/main/java/moe/ymc/acron/config/json/ConfigDeserializer.java b/src/main/java/moe/ymc/acron/config/json/ConfigDeserializer.java
deleted file mode 100644
index e91b355..0000000
--- a/src/main/java/moe/ymc/acron/config/json/ConfigDeserializer.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package moe.ymc.acron.config.json;
-
-import com.google.gson.Gson;
-import moe.ymc.acron.config.Config;
-import org.jetbrains.annotations.NotNull;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-
-public class ConfigDeserializer {
- public static @NotNull Config deserialize(@NotNull File file, boolean startup)
- throws ConfigDeserializationException, IOException {
- final Reader reader = new FileReader(file);
- final moe.ymc.acron.config.json.Config config;
- try {
- config = new Gson()
- .fromJson(reader, moe.ymc.acron.config.json.Config.class);
- } catch (Throwable e) {
- throw new ConfigDeserializationException("Cannot parse JSON: " + e.getMessage(),
- true);
- }
- reader.close();
- return config.create(startup);
- }
-}
diff --git a/src/main/java/moe/ymc/acron/config/json/ConfigJsonObject.java b/src/main/java/moe/ymc/acron/config/json/ConfigJsonObject.java
deleted file mode 100644
index 0efd9a9..0000000
--- a/src/main/java/moe/ymc/acron/config/json/ConfigJsonObject.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package moe.ymc.acron.config.json;
-
-import org.jetbrains.annotations.NotNull;
-
-public interface ConfigJsonObject<T> {
- @NotNull T create(boolean startup) throws ConfigDeserializationException;
-}
diff --git a/src/main/java/moe/ymc/acron/config/json/Rule.java b/src/main/java/moe/ymc/acron/config/json/Rule.java
deleted file mode 100644
index 114e17d..0000000
--- a/src/main/java/moe/ymc/acron/config/json/Rule.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package moe.ymc.acron.config.json;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.auth.Action;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.regex.Pattern;
-
-class Rule implements ConfigJsonObject<moe.ymc.acron.auth.Rule> {
- @SerializedName("regex")
- private final String regex;
-
- @SerializedName("action")
- private final Action action;
-
- @SerializedName("display")
- private final boolean display;
-
- private Rule(String regex,
- Action action,
- boolean display) {
- this.regex = regex;
- this.action = action;
- this.display = display;
- }
-
- public @NotNull moe.ymc.acron.auth.Rule create(boolean startup) throws ConfigDeserializationException {
- if (regex == null || regex.trim().equals("") ||
- action == null) throw new ConfigDeserializationException(".clients.[]rules.regex or .clients.[]rules.action is" +
- "not specified.");
- return new moe.ymc.acron.auth.Rule(Pattern.compile(regex),
- action,
- display);
- }
-}
diff --git a/src/main/java/moe/ymc/acron/jvav/Pair.java b/src/main/java/moe/ymc/acron/jvav/Pair.java
deleted file mode 100644
index 29b83dc..0000000
--- a/src/main/java/moe/ymc/acron/jvav/Pair.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package moe.ymc.acron.jvav;
-
-public record Pair<L, R>(L l, R r) {
-} \ No newline at end of file
diff --git a/src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java b/src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java
deleted file mode 100644
index 9aaed2e..0000000
--- a/src/main/java/moe/ymc/acron/mixin/CommandManagerMixin.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package moe.ymc.acron.mixin;
-
-import com.mojang.brigadier.CommandDispatcher;
-import moe.ymc.acron.config.ConfigReloadCmd;
-import net.minecraft.server.command.CommandManager;
-import net.minecraft.server.command.ServerCommandSource;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-import static net.minecraft.server.command.CommandManager.literal;
-
-
-@Mixin(CommandManager.class)
-public abstract class CommandManagerMixin {
- private static final Logger AC_LOGGER = LogManager.getLogger();
-
- @Shadow
- @Final
- private CommandDispatcher<ServerCommandSource> dispatcher;
-
- @Inject(method = "<init>", at = @At("RETURN"))
- private void onRegister(CommandManager.RegistrationEnvironment arg, CallbackInfo ci) {
- AC_LOGGER.debug("onRegister");
- dispatcher.register(
- literal("acron").requires(player -> player.hasPermissionLevel(4)).then(
- literal("rule").then(
- literal("update")
- .executes(new ConfigReloadCmd()))
- )
- );
- }
-}
diff --git a/src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java b/src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java
deleted file mode 100644
index 9e16569..0000000
--- a/src/main/java/moe/ymc/acron/mixin/LivingEntityMixin.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package moe.ymc.acron.mixin;
-
-import moe.ymc.acron.s2c.Entity;
-import moe.ymc.acron.s2c.EventQueue;
-import moe.ymc.acron.s2c.event.EventEntityDeath;
-import net.minecraft.entity.EntityType;
-import net.minecraft.entity.LivingEntity;
-import net.minecraft.entity.damage.DamageSource;
-import net.minecraft.entity.damage.DamageTracker;
-import net.minecraft.world.World;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(LivingEntity.class)
-public abstract class LivingEntityMixin extends net.minecraft.entity.Entity {
- private static final Logger AC_LOGGER = LogManager.getLogger();
-
- @Shadow public abstract DamageTracker getDamageTracker();
-
- public LivingEntityMixin(EntityType<?> type, World world) {
- super(type, world);
- }
-
- // The original onDeath() will call getDamageTracker().update(),
- // which clears all recent damages, making the getDeathMessage()
- // output always generic.
- // Thus, we need to use @At("HEAD") to get the injection called
- // before it does anything else.
- @Inject(at = @At("HEAD"), method = "onDeath")
- public void onDeath(DamageSource source, CallbackInfo ci) {
- AC_LOGGER.debug("onDeath[{}]",
- getUuid());
- EventQueue.enqueue(new EventEntityDeath(new Entity(this),
- getDamageTracker().getDeathMessage().getString()));
- }
-} \ No newline at end of file
diff --git a/src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java b/src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java
deleted file mode 100644
index 32d2fbf..0000000
--- a/src/main/java/moe/ymc/acron/mixin/MinecraftDedicatedServerMixin.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package moe.ymc.acron.mixin;
-
-import moe.ymc.acron.MinecraftServerHolder;
-import net.minecraft.server.dedicated.MinecraftDedicatedServer;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(MinecraftDedicatedServer.class)
-public class MinecraftDedicatedServerMixin {
- private static final Logger AC_LOGGER = LogManager.getLogger();
-
- @Inject(at = @At("RETURN"), method = "<init>")
- private void init(CallbackInfo info) {
- AC_LOGGER.debug("init");
- MinecraftServerHolder.setServer((MinecraftDedicatedServer) (Object) this);
- }
-}
diff --git a/src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java b/src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java
deleted file mode 100644
index cb813b4..0000000
--- a/src/main/java/moe/ymc/acron/mixin/MinecraftServerMixin.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package moe.ymc.acron.mixin;
-
-import moe.ymc.acron.s2c.EventQueue;
-import moe.ymc.acron.s2c.event.EventLagging;
-import net.minecraft.server.MinecraftServer;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Redirect;
-
-@Mixin(MinecraftServer.class)
-public class MinecraftServerMixin {
- private static final Logger AC_LOGGER = LogManager.getLogger();
-
- @Redirect(method = "runServer()V",
- remap = false,
- at = @At(value = "INVOKE",
- target = "Lorg/apache/logging/log4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V"))
- private void startServer(Logger instance, String s, Object o1, Object o2) {
- instance.warn(s, o1, o2);
- if (s.equals("Can't keep up! " +
- "Is the server overloaded? " +
- "Running {}ms or {} ticks behind") &&
- o1 instanceof Long &&
- o2 instanceof Long) {
- AC_LOGGER.debug("Lag: {}ms, {} ticks",
- o1,
- o2);
- EventQueue.enqueue(new EventLagging((long) o1, (long) o2));
- }
- }
-}
diff --git a/src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java b/src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java
deleted file mode 100644
index 94a48b5..0000000
--- a/src/main/java/moe/ymc/acron/mixin/ServerLoginNetworkHandlerMixin.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package moe.ymc.acron.mixin;
-
-import com.mojang.authlib.GameProfile;
-import moe.ymc.acron.s2c.Entity;
-import moe.ymc.acron.s2c.EventQueue;
-import moe.ymc.acron.s2c.event.EventDisconnected;
-import moe.ymc.acron.s2c.event.EventPlayerJoined;
-import net.minecraft.network.ClientConnection;
-import net.minecraft.server.network.ServerLoginNetworkHandler;
-import net.minecraft.server.network.ServerPlayerEntity;
-import net.minecraft.text.Text;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(ServerLoginNetworkHandler.class)
-public class ServerLoginNetworkHandlerMixin {
- private static final Logger AC_LOGGER = LogManager.getLogger();
-
- @Shadow
- @Nullable
- GameProfile profile;
-
- @Shadow
- @Final
- public ClientConnection connection;
-
- @Inject(at = @At("RETURN"), method = "onDisconnected")
- private void onDisconnected(Text reason, CallbackInfo ci) {
- EventQueue.enqueue(new EventDisconnected(profile == null ? null :
- new Entity(profile),
- reason.getString()));
- }
-
- @Inject(at = @At("RETURN"), method = "addToServer")
- private void addToServer(ServerPlayerEntity entity, CallbackInfo ci) {
- AC_LOGGER.debug("addToServer: {}",
- entity.getUuid());
- EventQueue.enqueue(new EventPlayerJoined(new Entity(entity)));
- }
-}
diff --git a/src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java b/src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java
deleted file mode 100644
index f49914e..0000000
--- a/src/main/java/moe/ymc/acron/mixin/ServerNetworkIoMixin.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package moe.ymc.acron.mixin;
-
-import io.netty.bootstrap.ServerBootstrap;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.MultithreadEventLoopGroup;
-import io.netty.channel.ServerChannel;
-import io.netty.channel.epoll.Epoll;
-import io.netty.channel.epoll.EpollServerSocketChannel;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.nio.NioServerSocketChannel;
-import moe.ymc.acron.config.Config;
-import moe.ymc.acron.net.AcronInitializer;
-import net.minecraft.server.ServerNetworkIo;
-import net.minecraft.util.Lazy;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-import java.util.List;
-
-import static net.minecraft.server.ServerNetworkIo.EPOLL_CHANNEL;
-
-@Mixin(ServerNetworkIo.class)
-public class ServerNetworkIoMixin {
- private static final Logger AC_LOGGER = LogManager.getLogger();
-
- @Shadow
- @Final
- private List<ChannelFuture> channels;
-
- @Shadow
- @Final
- public static Lazy<NioEventLoopGroup> DEFAULT_CHANNEL;
-
- @Inject(at = @At("RETURN"), method = "<init>")
- private void init(CallbackInfo info) {
- AC_LOGGER.debug("Adding Acron channel.");
- Lazy<? extends MultithreadEventLoopGroup> group;
- Class<? extends ServerChannel> channel;
- if (Epoll.isAvailable() && Config.getGlobalConfig().useNativeTransport()) {
- channel = EpollServerSocketChannel.class;
- group = EPOLL_CHANNEL;
- AC_LOGGER.info("Using native transport.");
- } else {
- channel = NioServerSocketChannel.class;
- group = DEFAULT_CHANNEL;
- AC_LOGGER.info("Not using native transport due to " +
- "it is either disabled in acron.json or not available.");
- }
- channels.add(new ServerBootstrap()
- .channel(channel)
- .childHandler(new AcronInitializer())
- .group(group.get())
- .localAddress(Config.getGlobalConfig().address(),
- Config.getGlobalConfig().port())
- .bind()
- .syncUninterruptibly());
-
- }
-}
diff --git a/src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java b/src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java
deleted file mode 100644
index 58bef78..0000000
--- a/src/main/java/moe/ymc/acron/mixin/ServerPlayNetworkHandlerMixin.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package moe.ymc.acron.mixin;
-
-import moe.ymc.acron.s2c.Entity;
-import moe.ymc.acron.s2c.EventQueue;
-import moe.ymc.acron.s2c.event.EventDisconnected;
-import moe.ymc.acron.s2c.event.EventPlayerMessage;
-import net.minecraft.network.ClientConnection;
-import net.minecraft.server.filter.TextStream;
-import net.minecraft.server.network.ServerPlayNetworkHandler;
-import net.minecraft.server.network.ServerPlayerEntity;
-import net.minecraft.text.Text;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(ServerPlayNetworkHandler.class)
-public class ServerPlayNetworkHandlerMixin {
- private static final Logger AC_LOGGER = LogManager.getLogger();
-
- @Shadow
- public ServerPlayerEntity player;
-
- @Shadow
- @Final
- public ClientConnection connection;
-
- @Inject(at = @At("RETURN"), method = "handleMessage")
- private void handleMessage(TextStream.Message message, CallbackInfo ci) {
- EventQueue.enqueue(new EventPlayerMessage(new Entity(player),
- message.getRaw()));
- }
-
- @Inject(at = @At("RETURN"), method = "onDisconnected")
- private void onDisconnected(Text reason, CallbackInfo ci) {
- EventQueue.enqueue(new EventDisconnected(new Entity(player),
- reason.getString()));
- }
-}
diff --git a/src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java b/src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java
deleted file mode 100644
index 4c6758b..0000000
--- a/src/main/java/moe/ymc/acron/mixin/ServerPlayerEntityMixin.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package moe.ymc.acron.mixin;
-
-import moe.ymc.acron.s2c.EventQueue;
-import moe.ymc.acron.s2c.event.EventEntityDeath;
-import net.minecraft.entity.EntityType;
-import net.minecraft.entity.LivingEntity;
-import net.minecraft.entity.damage.DamageSource;
-import net.minecraft.server.network.ServerPlayerEntity;
-import net.minecraft.world.World;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(ServerPlayerEntity.class)
-public abstract class ServerPlayerEntityMixin extends LivingEntity {
- private static final Logger AC_LOGGER = LogManager.getLogger();
-
- public ServerPlayerEntityMixin(EntityType<? extends LivingEntity> entityType, World world) {
- super(entityType, world);
- }
-
- @Inject(at = @At("HEAD"), method = "onDeath")
- public void onDeath(DamageSource source, CallbackInfo ci) {
- AC_LOGGER.debug("onDeath: {}",
- getUuid());
- EventQueue.enqueue(new EventEntityDeath(new moe.ymc.acron.s2c.Entity(this),
- getDamageTracker().getDeathMessage().getString()));
- }
-} \ No newline at end of file
diff --git a/src/main/java/moe/ymc/acron/net/AcronInitializer.java b/src/main/java/moe/ymc/acron/net/AcronInitializer.java
deleted file mode 100644
index c9953e3..0000000
--- a/src/main/java/moe/ymc/acron/net/AcronInitializer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package moe.ymc.acron.net;
-
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.handler.codec.http.HttpObjectAggregator;
-import io.netty.handler.codec.http.HttpServerCodec;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-/**
- * A channel initializer for all Acron handlers.
- */
-public class AcronInitializer extends ChannelInitializer<SocketChannel> {
- private static final Logger LOGGER = LogManager.getLogger();
-
- @Override
- protected void initChannel(SocketChannel ch) throws Exception {
- LOGGER.debug("initChannel");
- ch.pipeline()
- .addLast(new HttpServerCodec())
- .addLast(new HttpObjectAggregator(65536))
- .addLast(new AuthHandler())
- ;
- }
-}
diff --git a/src/main/java/moe/ymc/acron/net/Attributes.java b/src/main/java/moe/ymc/acron/net/Attributes.java
deleted file mode 100644
index ddb0f5c..0000000
--- a/src/main/java/moe/ymc/acron/net/Attributes.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package moe.ymc.acron.net;
-
-import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
-import io.netty.util.AttributeKey;
-
-final class Attributes {
- public static final AttributeKey<ClientIdentification> ID =
- AttributeKey.newInstance("CLENT_ID");
- public static final AttributeKey<ClientConfiguration> CONFIGURATION =
- AttributeKey.newInstance("CLIENT_CONFIG");
- public static final AttributeKey<WebSocketServerHandshaker> HANDSHAKER =
- AttributeKey.newInstance("HANDSHAKER");
-}
diff --git a/src/main/java/moe/ymc/acron/net/AuthHandler.java b/src/main/java/moe/ymc/acron/net/AuthHandler.java
deleted file mode 100644
index 3e42e14..0000000
--- a/src/main/java/moe/ymc/acron/net/AuthHandler.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package moe.ymc.acron.net;
-
-import io.netty.channel.ChannelFutureListener;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-import io.netty.handler.codec.http.*;
-import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
-import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
-import moe.ymc.acron.auth.Client;
-import moe.ymc.acron.config.Config;
-import org.apache.commons.codec.digest.DigestUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-/**
- * Handle handshake request and authentication.
- * We cannot use WebSocketServerProtocolHandler because it does not allow
- * us doing anything before handshaking.
- */
-public class AuthHandler extends SimpleChannelInboundHandler<HttpRequest> {
- private static final Logger LOGGER = LogManager.getLogger();
-
- @Override
- protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {
- LOGGER.debug("channelRead0: {}", msg.uri());
- if (msg.method() != HttpMethod.GET) {
- ctx.channel().writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
- HttpResponseStatus.BAD_REQUEST))
- .addListener(ChannelFutureListener.CLOSE);
- return;
- }
- HttpHeaders headers = msg.headers();
-
- if (!"Upgrade".equalsIgnoreCase(headers.get(HttpHeaderNames.CONNECTION)) ||
- !"WebSocket".equalsIgnoreCase(headers.get(HttpHeaderNames.UPGRADE))) {
- ctx.channel().writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
- HttpResponseStatus.BAD_REQUEST))
- .addListener(ChannelFutureListener.CLOSE);
- return;
- }
-
- final QueryStringDecoder decoder = new QueryStringDecoder(msg.uri());
- if (!decoder.path().equals("/ws")) {
- ctx.fireChannelRead(msg);
- return;
- }
- if (decoder.parameters().isEmpty() ||
- decoder.parameters().get("id") == null ||
- decoder.parameters().get("id").size() != 1 ||
- decoder.parameters().get("token") == null ||
- decoder.parameters().get("token").size() != 1) {
- ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
- HttpResponseStatus.BAD_REQUEST))
- .addListener(ChannelFutureListener.CLOSE);
- return;
- }
-
- final String id = decoder.parameters().get("id").get(0);
- final String token = decoder.parameters().get("token").get(0);
- final String versionRaw = (decoder.parameters().get("version") == null ||
- decoder.parameters().get("version").isEmpty()) ? "0" :
- decoder.parameters().get("version").get(0);
- try {
- if (Integer.parseInt(versionRaw) != 0) {
- ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
- HttpResponseStatus.BAD_REQUEST))
- .addListener(ChannelFutureListener.CLOSE);
- return;
- }
- } catch (NumberFormatException ignored) {
- ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
- HttpResponseStatus.BAD_REQUEST))
- .addListener(ChannelFutureListener.CLOSE);
- return;
- }
-
- final Client client = Config.getGlobalConfig().clients().get(id);
- if (client == null ||
- !client.token().equals(DigestUtils.sha256Hex(token))) {
- ctx.writeAndFlush(new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
- HttpResponseStatus.UNAUTHORIZED))
- .addListener(ChannelFutureListener.CLOSE);
- return;
- }
- ctx.channel().attr(Attributes.ID).set(new ClientIdentification(0, client));
- WebSocketServerHandshakerFactory wsFactory =
- new WebSocketServerHandshakerFactory("/ws", null, true);
- final WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(msg);
- if (handshaker == null) {
- WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
- return;
- }
- ctx.channel().attr(Attributes.HANDSHAKER).set(handshaker);
- handshaker.handshake(ctx.channel(), msg);
- ctx.pipeline().replace(this, "websocketHandler", new WSFrameHandler());
- ctx.fireUserEventTriggered(new HandshakeComplete());
- }
-}
diff --git a/src/main/java/moe/ymc/acron/net/ClientConfiguration.java b/src/main/java/moe/ymc/acron/net/ClientConfiguration.java
deleted file mode 100644
index 450ccd4..0000000
--- a/src/main/java/moe/ymc/acron/net/ClientConfiguration.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package moe.ymc.acron.net;
-
-import net.minecraft.server.world.ServerWorld;
-import net.minecraft.util.math.Vec2f;
-import net.minecraft.util.math.Vec3d;
-import org.jetbrains.annotations.NotNull;
-
-public record ClientConfiguration(@NotNull Vec3d pos,
- @NotNull Vec2f rot,
- @NotNull ServerWorld world,
- @NotNull String name) {
- public ClientConfiguration(@NotNull ServerWorld world,
- @NotNull String name) {
- // Rcon defaults. @see RconCommandOutput
- this(Vec3d.of(world.getSpawnPos()),
- Vec2f.ZERO,
- world,
- name);
- }
-}
diff --git a/src/main/java/moe/ymc/acron/net/ClientIdentification.java b/src/main/java/moe/ymc/acron/net/ClientIdentification.java
deleted file mode 100644
index 1cb4375..0000000
--- a/src/main/java/moe/ymc/acron/net/ClientIdentification.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package moe.ymc.acron.net;
-
-import moe.ymc.acron.auth.Client;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * Read only client configurations.
- */
-public record ClientIdentification(int version,
- @NotNull Client client) {
-}
diff --git a/src/main/java/moe/ymc/acron/net/HandshakeComplete.java b/src/main/java/moe/ymc/acron/net/HandshakeComplete.java
deleted file mode 100644
index 348b5e2..0000000
--- a/src/main/java/moe/ymc/acron/net/HandshakeComplete.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package moe.ymc.acron.net;
-
-/**
- * User event used to tell WSFrameHandler that the handshake is complete.
- */
-public class HandshakeComplete {
-}
diff --git a/src/main/java/moe/ymc/acron/net/WSFrameHandler.java b/src/main/java/moe/ymc/acron/net/WSFrameHandler.java
deleted file mode 100644
index 912e73a..0000000
--- a/src/main/java/moe/ymc/acron/net/WSFrameHandler.java
+++ /dev/null
@@ -1,174 +0,0 @@
-package moe.ymc.acron.net;
-
-import com.google.gson.JsonParseException;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.SimpleChannelInboundHandler;
-import io.netty.handler.codec.http.websocketx.*;
-import moe.ymc.acron.MinecraftServerHolder;
-import moe.ymc.acron.auth.Action;
-import moe.ymc.acron.auth.PolicyChecker;
-import moe.ymc.acron.c2s.ReqCmd;
-import moe.ymc.acron.c2s.ReqSetConfig;
-import moe.ymc.acron.c2s.Request;
-import moe.ymc.acron.cmd.CmdQueue;
-import moe.ymc.acron.jvav.Pair;
-import moe.ymc.acron.s2c.Event;
-import moe.ymc.acron.s2c.EventQueue;
-import moe.ymc.acron.s2c.response.EventError;
-import moe.ymc.acron.s2c.response.EventOk;
-import moe.ymc.acron.serialization.Serializer;
-import net.minecraft.server.world.ServerWorld;
-import net.minecraft.util.math.Vec2f;
-import net.minecraft.util.math.Vec3d;
-import net.minecraft.world.World;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-
-/**
- * The handler for WebSocket requests.
- */
-public class WSFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
- private static final Logger LOGGER = LogManager.getLogger();
-
- @Override
- public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
- super.handlerAdded(ctx);
- }
-
- @Override
- protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame msg) throws Exception {
- LOGGER.debug("channelRead0: {} {}",
- this,
- ctx.channel());
- final WebSocketServerHandshaker handshaker =
- ctx.channel().attr(Attributes.HANDSHAKER).get();
- if (msg instanceof CloseWebSocketFrame) {
- handshaker.close(ctx.channel(), (CloseWebSocketFrame) msg.retain());
- return;
- }
- if (msg instanceof PingWebSocketFrame) {
- ctx.write(new PongWebSocketFrame(msg.content().retain()));
- return;
- }
- if (msg instanceof BinaryWebSocketFrame) {
- throw new UnsupportedOperationException("Only text frames are accepted.");
- }
- final TextWebSocketFrame frame = (TextWebSocketFrame) msg;
-
- final ClientIdentification identification = ctx.channel().attr(Attributes.ID).get();
- final ClientConfiguration configuration = ctx.channel().attr(Attributes.CONFIGURATION).get();
- int id;
- final Request request;
- try {
- request = Serializer.deserialize(frame);
- id = request.getId();
- } catch (JsonParseException | IllegalArgumentException | IllegalStateException e) {
- ctx.channel().writeAndFlush(
- Serializer.serialize(new EventError(-2, EventError.Code.BAD_REQUEST.value, e.getMessage()))
- );
- return;
- }
- try {
- ctx.channel().writeAndFlush(Serializer.serialize(handle(request,
- identification,
- configuration,
- ctx.channel())));
- } catch (Throwable e) {
- LOGGER.info("An error occurred while processing the request. " +
- "This may just be a malformed request. " +
- "It is reported to the client.",
- e);
- ctx.channel().writeAndFlush(
- Serializer.serialize(new EventError(id, EventError.Code.SERVER_ERROR.value, e.getMessage()))
- );
- }
- }
-
- @NotNull
- private Event handle(@NotNull Request request,
- @NotNull ClientIdentification identification,
- @NotNull ClientConfiguration configuration,
- @NotNull Channel channel) throws Throwable {
- if (request instanceof final ReqCmd reqCmd) {
- LOGGER.info("Client {} executed a command: `{}`.",
- identification.client().id(),
- reqCmd.cmd());
- final Pair<Action, Boolean> res = PolicyChecker.check(identification.client(),
- reqCmd.cmd());
- if (res.l() == Action.DENY) {
- return new EventError(reqCmd.id(),
- EventError.Code.FORBIDDEN.value, "This client is not allowed to " +
- "execute this command.");
- }
- // TODO: Ok event may be sent after executing the command.
- CmdQueue.enqueue(reqCmd.id(),
- res.r(),
- channel,
- reqCmd.config() == null ?
- configuration :
- convertConfiguration(reqCmd.config()),
- reqCmd.cmd());
- return new EventOk(request.getId());
- } else if (request instanceof final ReqSetConfig reqSetConfig) {
- channel.attr(Attributes.CONFIGURATION).set(convertConfiguration(reqSetConfig));
- return new EventOk(request.getId());
- }
- // This should not occur.
- throw new IllegalStateException("This should not occur.");
- }
-
- private ClientConfiguration convertConfiguration(@NotNull ReqSetConfig request) {
- final ServerWorld world;
- if (request.world() != null) {
- switch (request.world()) {
- case OVERWORLD -> world = MinecraftServerHolder.getServer().getWorld(World.OVERWORLD);
- case NETHER -> world = MinecraftServerHolder.getServer().getWorld(World.NETHER);
- case END -> world = MinecraftServerHolder.getServer().getWorld(World.END);
- default -> throw new IllegalArgumentException();
- }
- } else {
- world = MinecraftServerHolder.getServer().getOverworld();
- }
- if (world == null) {
- throw new IllegalStateException(String.format("The requested world %s is not available at this time.",
- request.world()));
- }
- return new ClientConfiguration(
- request.pos() == null ?
- Vec3d.of(world.getSpawnPos()) :
- new Vec3d(request.pos().x(), request.pos().y(), request.pos().z()),
- request.rot() == null ?
- Vec2f.ZERO :
- new Vec2f(request.rot().x(), request.rot().y()),
- world,
- request.name() == null ? this.toString() : request.name()
- );
- }
-
- @Override
- public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
- LOGGER.debug("handshakeComplete: {} {}",
- this,
- ctx.channel());
- if (evt instanceof HandshakeComplete) {
- final ClientIdentification identification = ctx.channel().attr(Attributes.ID).get();
- LOGGER.info("Client {} connected. It has {} rules with {} policy mode.",
- identification.client().id(),
- identification.client().rules().length,
- identification.client().policyMode());
- final ServerWorld defaultWorld = MinecraftServerHolder.getServer().getOverworld();
- if (defaultWorld == null) {
- throw new IllegalStateException("The default world is not available at this time.");
- }
- final ClientConfiguration configuration =
- new ClientConfiguration(defaultWorld,
- identification.client().id());
- ctx.channel().attr(Attributes.CONFIGURATION).set(configuration);
- EventQueue.registerMessageRecipient(ctx.channel());
- } else {
- ctx.fireUserEventTriggered(evt);
- }
- }
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/Entity.java b/src/main/java/moe/ymc/acron/s2c/Entity.java
deleted file mode 100644
index 3e0add1..0000000
--- a/src/main/java/moe/ymc/acron/s2c/Entity.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package moe.ymc.acron.s2c;
-
-import com.google.gson.annotations.SerializedName;
-import com.mojang.authlib.GameProfile;
-import moe.ymc.acron.common.Vec3d;
-import moe.ymc.acron.common.WorldKey;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.UUID;
-
-public record Entity(@SerializedName("name") @NotNull String name,
- @SerializedName("uuid") @NotNull UUID uuid,
- @SerializedName("pos") @Nullable Vec3d pos,
- @SerializedName("world") @Nullable WorldKey world) {
- public Entity(@NotNull net.minecraft.entity.Entity entity) {
- this(entity.getName().getString(),
- entity.getUuid(),
- new Vec3d(entity.getPos()),
- WorldKey.create(entity.world.getRegistryKey().getValue()));
- }
-
- public Entity(@NotNull GameProfile profile) {
- this(profile.getName(), profile.getId(), null, null);
- }
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/Event.java b/src/main/java/moe/ymc/acron/s2c/Event.java
deleted file mode 100644
index 1abc35c..0000000
--- a/src/main/java/moe/ymc/acron/s2c/Event.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package moe.ymc.acron.s2c;
-
-public interface Event {
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/EventQueue.java b/src/main/java/moe/ymc/acron/s2c/EventQueue.java
deleted file mode 100644
index 8c470a1..0000000
--- a/src/main/java/moe/ymc/acron/s2c/EventQueue.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package moe.ymc.acron.s2c;
-
-import io.netty.channel.Channel;
-import io.netty.channel.group.ChannelGroup;
-import io.netty.channel.group.DefaultChannelGroup;
-import io.netty.util.concurrent.GlobalEventExecutor;
-import moe.ymc.acron.serialization.Serializer;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.NotNull;
-
-public class EventQueue {
- private static final Logger LOGGER = LogManager.getLogger();
-
- private static final ChannelGroup sMessageRecipients =
- new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
-
- public static void registerMessageRecipient(@NotNull Channel channel) {
- sMessageRecipients.add(channel);
- }
-
- public static void enqueue(@NotNull Event message) {
- LOGGER.debug("Enqueue: {} ({} channels)",
- message,
- sMessageRecipients.size());
- sMessageRecipients.writeAndFlush(Serializer.serialize(message));
- }
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/event/EventDisconnected.java b/src/main/java/moe/ymc/acron/s2c/event/EventDisconnected.java
deleted file mode 100644
index 610fc58..0000000
--- a/src/main/java/moe/ymc/acron/s2c/event/EventDisconnected.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package moe.ymc.acron.s2c.event;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.s2c.Entity;
-import moe.ymc.acron.s2c.Event;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public record EventDisconnected(@SerializedName("player") @Nullable Entity player,
- @SerializedName("reason") @NotNull String reason)
- implements Event {
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/event/EventEntityDeath.java b/src/main/java/moe/ymc/acron/s2c/event/EventEntityDeath.java
deleted file mode 100644
index 4735241..0000000
--- a/src/main/java/moe/ymc/acron/s2c/event/EventEntityDeath.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package moe.ymc.acron.s2c.event;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.s2c.Entity;
-import moe.ymc.acron.s2c.Event;
-import org.jetbrains.annotations.NotNull;
-
-// TODO: More detailed death report.
-public record EventEntityDeath(@SerializedName("entity") @NotNull Entity entity,
- @SerializedName("message") @NotNull String message)
- implements Event {
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/event/EventLagging.java b/src/main/java/moe/ymc/acron/s2c/event/EventLagging.java
deleted file mode 100644
index 30974df..0000000
--- a/src/main/java/moe/ymc/acron/s2c/event/EventLagging.java
+++ /dev/null
@@ -1,9 +0,0 @@
-package moe.ymc.acron.s2c.event;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.s2c.Event;
-
-public record EventLagging(@SerializedName("ms") long ms,
- @SerializedName("ticks") long ticks)
- implements Event {
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/event/EventPlayerJoined.java b/src/main/java/moe/ymc/acron/s2c/event/EventPlayerJoined.java
deleted file mode 100644
index 408680b..0000000
--- a/src/main/java/moe/ymc/acron/s2c/event/EventPlayerJoined.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package moe.ymc.acron.s2c.event;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.s2c.Entity;
-import moe.ymc.acron.s2c.Event;
-import org.jetbrains.annotations.NotNull;
-
-public record EventPlayerJoined(@SerializedName("player") @NotNull Entity player)
- implements Event {
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/event/EventPlayerMessage.java b/src/main/java/moe/ymc/acron/s2c/event/EventPlayerMessage.java
deleted file mode 100644
index 2769493..0000000
--- a/src/main/java/moe/ymc/acron/s2c/event/EventPlayerMessage.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package moe.ymc.acron.s2c.event;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.s2c.Entity;
-import moe.ymc.acron.s2c.Event;
-import org.jetbrains.annotations.NotNull;
-
-public record EventPlayerMessage(@SerializedName("player") @NotNull Entity player,
- @SerializedName("text") @NotNull String text)
- implements Event {
-
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/response/EventCmdOut.java b/src/main/java/moe/ymc/acron/s2c/response/EventCmdOut.java
deleted file mode 100644
index a4cb798..0000000
--- a/src/main/java/moe/ymc/acron/s2c/response/EventCmdOut.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package moe.ymc.acron.s2c.response;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.s2c.Event;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.UUID;
-
-public record EventCmdOut(@SerializedName("id") int id,
- @SerializedName("sender") @NotNull UUID sender,
- @SerializedName("out") @NotNull String out)
- implements Event {
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/response/EventCmdRes.java b/src/main/java/moe/ymc/acron/s2c/response/EventCmdRes.java
deleted file mode 100644
index 8c1b6a9..0000000
--- a/src/main/java/moe/ymc/acron/s2c/response/EventCmdRes.java
+++ /dev/null
@@ -1,10 +0,0 @@
-package moe.ymc.acron.s2c.response;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.s2c.Event;
-
-public record EventCmdRes(@SerializedName("id") int id,
- @SerializedName("success") boolean success,
- @SerializedName("result") int result)
- implements Event {
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/response/EventError.java b/src/main/java/moe/ymc/acron/s2c/response/EventError.java
deleted file mode 100644
index 370e8f3..0000000
--- a/src/main/java/moe/ymc/acron/s2c/response/EventError.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package moe.ymc.acron.s2c.response;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.s2c.Event;
-import org.jetbrains.annotations.Nullable;
-
-public record EventError(@SerializedName("id") int id,
- @SerializedName("code") int code,
- @SerializedName("message") @Nullable String message)
- implements Event {
- public enum Code {
- SERVER_ERROR(500),
- BAD_REQUEST(400),
- FORBIDDEN(403)
- ;
-
- public final int value;
- Code(int value) {
- this.value = value;
- }
- }
-}
diff --git a/src/main/java/moe/ymc/acron/s2c/response/EventOk.java b/src/main/java/moe/ymc/acron/s2c/response/EventOk.java
deleted file mode 100644
index eb8c82d..0000000
--- a/src/main/java/moe/ymc/acron/s2c/response/EventOk.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package moe.ymc.acron.s2c.response;
-
-import com.google.gson.annotations.SerializedName;
-import moe.ymc.acron.s2c.Event;
-
-public record EventOk(@SerializedName("id") int id)
- implements Event {
-}
diff --git a/src/main/java/moe/ymc/acron/serialization/Serializer.java b/src/main/java/moe/ymc/acron/serialization/Serializer.java
deleted file mode 100644
index 8091c25..0000000
--- a/src/main/java/moe/ymc/acron/serialization/Serializer.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package moe.ymc.acron.serialization;
-
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonParseException;
-import com.google.gson.typeadapters.RuntimeTypeAdapterFactory;
-import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
-import moe.ymc.acron.c2s.ReqCmd;
-import moe.ymc.acron.c2s.ReqSetConfig;
-import moe.ymc.acron.c2s.Request;
-import moe.ymc.acron.common.Vec2f;
-import moe.ymc.acron.common.Vec3d;
-import moe.ymc.acron.s2c.Event;
-import moe.ymc.acron.s2c.event.*;
-import moe.ymc.acron.s2c.response.EventCmdOut;
-import moe.ymc.acron.s2c.response.EventCmdRes;
-import moe.ymc.acron.s2c.response.EventError;
-import moe.ymc.acron.s2c.response.EventOk;
-import org.jetbrains.annotations.NotNull;
-
-public class Serializer {
- @NotNull
- public static Request deserialize(@NotNull TextWebSocketFrame frame)
- throws JsonParseException, IllegalArgumentException, IllegalStateException {
- final String text = frame.text();
- final RuntimeTypeAdapterFactory<Request> adapter =
- RuntimeTypeAdapterFactory.of(Request.class, "type")
- .registerSubtype(ReqSetConfig.class, "set_config")
- .registerSubtype(ReqCmd.class, "cmd");
- final Gson gson = new GsonBuilder()
- .registerTypeAdapter(ReqSetConfig.class, new ReqSetConfig.ReqSetConfigDeserializer())
- .registerTypeAdapter(Vec3d.class, new Vec3d.Vec3dDeserializer())
- .registerTypeAdapter(Vec2f.class, new Vec2f.Vec2fDeserializer())
- .registerTypeAdapter(ReqCmd.class, new ReqCmd.ReqCmdDeserializer())
- .registerTypeAdapterFactory(adapter)
- .create();
- final Request request = gson.fromJson(text, Request.class);
- request.validate();
- return request;
- }
-
- @NotNull
- public static TextWebSocketFrame serialize(@NotNull Event message) {
- final RuntimeTypeAdapterFactory<Event> adapter =
- RuntimeTypeAdapterFactory.of(Event.class, "type")
- .registerSubtype(EventDisconnected.class, "disconnect")
- .registerSubtype(EventPlayerMessage.class, "message")
- .registerSubtype(EventPlayerJoined.class, "join")
- .registerSubtype(EventEntityDeath.class, "death")
- .registerSubtype(EventCmdOut.class, "cmd_out")
- .registerSubtype(EventCmdRes.class, "cmd_result")
- .registerSubtype(EventLagging.class, "lagging")
- .registerSubtype(EventError.class, "error")
- .registerSubtype(EventOk.class, "ok");
- final Gson gson = new GsonBuilder()
- .registerTypeAdapterFactory(adapter)
- .create();
- return new TextWebSocketFrame(gson.toJson(message, message.getClass()));
- }
-}
diff --git a/src/main/resources/acron.mixins.json b/src/main/resources/acron.mixins.json
deleted file mode 100644
index 5d0911f..0000000
--- a/src/main/resources/acron.mixins.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "required": true,
- "minVersion": "0.8",
- "package": "moe.ymc.acron.mixin",
- "compatibilityLevel": "JAVA_8",
- "mixins": [
- "CommandManagerMixin",
- "LivingEntityMixin",
- "MinecraftDedicatedServerMixin",
- "MinecraftServerMixin",
- "ServerLoginNetworkHandlerMixin",
- "ServerNetworkIoMixin",
- "ServerPlayerEntityMixin",
- "ServerPlayNetworkHandlerMixin"
- ],
- "client": [
- ],
- "injectors": {
- "defaultRequire": 1
- }
-}
diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json
deleted file mode 100644
index 999aeeb..0000000
--- a/src/main/resources/fabric.mod.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "schemaVersion": 1,
- "id": "acron",
- "version": "${version}",
- "name": "Acron",
- "description": "WebSocket based remote server management",
- "authors": ["YuutaW"],
- "contact": {},
- "license": "GPL-2.0",
- "icon": "assets/acron/icon.png",
- "environment": "server",
- "entrypoints": {
- "main": [
- "moe.ymc.acron.Acron"
- ]
- },
- "mixins": [
- "acron.mixins.json"
- ],
- "depends": {
- "fabricloader": ">=0.14.4",
- "minecraft": "1.17.1"
- }
-}