Added API driven Rooms

This commit is contained in:
2023-11-12 00:59:17 +01:00
parent 2306308071
commit 5d29c387a3
53 changed files with 313 additions and 25 deletions

View File

@ -1,5 +1,6 @@
package eu.mhsl.minenet.minigames;
import eu.mhsl.minenet.minigames.api.HttpServer;
import eu.mhsl.minenet.minigames.command.Commands;
import eu.mhsl.minenet.minigames.handler.Listeners;
import eu.mhsl.minenet.minigames.lang.Languages;
@ -23,7 +24,7 @@ public class Main {
* Starts minenet minigames services
*/
private final static Logger logger = Logger.getGlobal();
private static ConfigurationNode globalConfig;
public static ConfigurationNode globalConfig;
public static void main(String[] args) throws ConfigurateException {
//noinspection ResultOfMethodCallIgnored
@ -50,6 +51,7 @@ public class Main {
Commands.values();
Listeners.values();
new HttpServer();
MinecraftServer.getSchedulerManager().scheduleTask(new TablistUpdateTask(), TaskSchedule.tick(20), TaskSchedule.tick(20));

View File

@ -0,0 +1,35 @@
package eu.mhsl.minenet.minigames.api;
import com.google.gson.Gson;
import spark.Request;
import spark.Response;
import spark.Route;
import java.lang.reflect.ParameterizedType;
public abstract class Controller<Q, R> implements Route {
private final Class<Q> requestType;
@SuppressWarnings("unchecked")
public Controller() {
this.requestType = ((Class<Q>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
}
@Override
public Object handle(Request request, Response response) throws Exception {
response.header("Access-Control-Allow-Origin", "*");
response.header("Access-Control-Allow-Methods", "*");
Q req;
if(request.body().isEmpty()) {
req = null;
} else {
req = new Gson().fromJson(request.body(), this.requestType);
}
return new Gson().toJson(handle(req, response));
}
public abstract R handle(Q request, Response response) throws Exception;
}

View File

@ -1,6 +1,35 @@
package eu.mhsl.minenet.minigames.api;
import eu.mhsl.minenet.minigames.Main;
import eu.mhsl.minenet.minigames.api.routes.closeRoom.CloseRoom;
import eu.mhsl.minenet.minigames.api.routes.createRoom.CreateRoom;
import eu.mhsl.minenet.minigames.api.routes.queueRoom.QueueRoom;
import org.spongepowered.configurate.ConfigurationNode;
import static spark.Spark.*;
public class HttpServer {
private static final ConfigurationNode apiConfig = Main.globalConfig.node("api");
public HttpServer() {
if(!apiConfig.node("enabled").getBoolean()) return;
port(apiConfig.node("port").getInt());
initExceptionHandler(e -> e.printStackTrace(System.err));
exception(Exception.class, (exception, request, response) -> {
exception.printStackTrace(System.err);
response.status(500);
});
before((request, response) -> {
String userKey = request.headers("Authorization");
String serverKey = apiConfig.node("secret").getString();
if(userKey != null && !userKey.equals(serverKey)) {
halt(401, "Authorization header missing or wrong");
}
});
post("/room", new CreateRoom());
delete("/room", new CloseRoom());
post("/queueRoom", new QueueRoom());
}
}

View File

@ -0,0 +1,17 @@
package eu.mhsl.minenet.minigames.api;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class QueuedPlayerRooms {
private static final Map<UUID, UUID> playersToRoom = new HashMap<>();
public static void queuePlayer(UUID playerUUID, UUID roomUUID) {
playersToRoom.put(playerUUID, roomUUID);
}
public static UUID pullQueue(UUID playerUUID) {
return playersToRoom.remove(playerUUID);
}
}

View File

@ -0,0 +1,17 @@
package eu.mhsl.minenet.minigames.api.routes.closeRoom;
import eu.mhsl.minenet.minigames.api.Controller;
import eu.mhsl.minenet.minigames.instance.room.Room;
import spark.Response;
import java.util.UUID;
record Req(UUID room) {}
record Resp() {}
public class CloseRoom extends Controller<Req, Resp> {
@Override
public Resp handle(Req request, Response response) throws Exception {
Room.deleteRoom(Room.getRoom(request.room()).orElseThrow());
return new Resp();
}
}

View File

@ -0,0 +1,17 @@
package eu.mhsl.minenet.minigames.api.routes.createRoom;
import eu.mhsl.minenet.minigames.api.Controller;
import eu.mhsl.minenet.minigames.instance.room.Room;
import spark.Response;
import java.util.UUID;
record Req() {}
record Resp(UUID uuid) {}
public class CreateRoom extends Controller<Req, Resp> {
@Override
public Resp handle(Req request, Response response) throws Exception {
Room createdRoom = Room.createOwnerlessRoom();
return new Resp(createdRoom.uuid);
}
}

View File

@ -0,0 +1,19 @@
package eu.mhsl.minenet.minigames.api.routes.queueRoom;
import eu.mhsl.minenet.minigames.api.Controller;
import eu.mhsl.minenet.minigames.api.QueuedPlayerRooms;
import eu.mhsl.minenet.minigames.instance.room.Room;
import spark.Response;
import java.util.UUID;
record Req(UUID player, UUID room) {}
record Resp() {}
public class QueueRoom extends Controller<Req, Resp> {
@Override
public Resp handle(Req request, Response response) throws Exception {
if(Room.getRoom(request.room()).isEmpty()) throw new Exception("Room not found");
QueuedPlayerRooms.queuePlayer(request.player(), request.room());
return new Resp();
}
}

View File

@ -5,6 +5,7 @@ import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ActionBarMessage;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
import eu.mhsl.minenet.minigames.message.type.TitleMessage;
import net.minestom.server.entity.Player;
import java.util.ArrayList;
import java.util.List;
@ -33,6 +34,8 @@ public class DebugCommand extends PrivilegedCommand {
.newLine()
.appendTranslated("score#thanks")
.send(sender);
new ChatMessage(Icon.SCIENCE).appendStatic(((Player) sender).getUuid().toString()).send(sender);
});
}

View File

@ -36,6 +36,9 @@ public class SetRoomOwnerCommand extends PrivilegedCommand {
@Override
protected CommandCondition isPrivileged() {
return (sender, commandString) -> super.isPrivileged().canUse(sender, commandString) || Room.getRoom(((Player) sender)).orElseThrow().getOwner() == sender;
return (sender, commandString) -> {
Room playerRoom = Room.getRoom(((Player) sender)).orElse(null);
return super.isPrivileged().canUse(sender, commandString) || (playerRoom != null && playerRoom.getOwner() == sender);
};
}
}

View File

@ -1,5 +1,7 @@
package eu.mhsl.minenet.minigames.handler.global;
import eu.mhsl.minenet.minigames.Main;
import eu.mhsl.minenet.minigames.api.QueuedPlayerRooms;
import eu.mhsl.minenet.minigames.instance.room.Room;
import eu.mhsl.minenet.minigames.message.Icon;
import eu.mhsl.minenet.minigames.message.type.ChatMessage;
@ -11,7 +13,10 @@ import net.minestom.server.event.player.PlayerLoginEvent;
import eu.mhsl.minenet.minigames.instance.hub.Hub;
import net.minestom.server.permission.Permission;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.configurate.serialize.SerializationException;
import java.util.Objects;
import java.util.UUID;
import java.util.logging.Logger;
public class PlayerLoginHandler implements EventListener<PlayerLoginEvent> {
@ -24,15 +29,24 @@ public class PlayerLoginHandler implements EventListener<PlayerLoginEvent> {
public @NotNull Result run(@NotNull PlayerLoginEvent event) {
Player p = event.getPlayer();
p.setRespawnPoint(Hub.INSTANCE.getSpawn());
event.setSpawningInstance(Hub.INSTANCE);
UUID pushQueue = QueuedPlayerRooms.pullQueue(event.getPlayer().getUuid());
if(pushQueue != null) {
Room target = Room.getRoom(pushQueue).orElseThrow();
p.setRespawnPoint(target.getSpawn());
event.setSpawningInstance(Hub.INSTANCE);
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> Room.setRoom(p, target));
} else {
p.setRespawnPoint(Hub.INSTANCE.getSpawn());
event.setSpawningInstance(Hub.INSTANCE);
}
SkinCache.applySkin(p);
if(p.getUsername().equalsIgnoreCase("minetec")) {
p.addPermission(new Permission("admin"));
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> Room.createRoom(p));
}
try {
if(Objects.requireNonNull(Main.globalConfig.node("admins").getList(String.class)).stream().anyMatch(s -> s.equalsIgnoreCase(p.getUsername()))) {
p.addPermission(new Permission("admin"));
}
} catch (SerializationException | NullPointerException ignored) {}
Logger.getLogger("user").info(p.getUsername() + " joined");

View File

@ -17,7 +17,6 @@ import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerBlockBreakEvent;
import net.minestom.server.event.player.PlayerDisconnectEvent;
import net.minestom.server.event.player.PlayerEntityInteractEvent;
import net.minestom.server.instance.AnvilLoader;
import java.util.*;
@ -53,6 +52,10 @@ public class Room extends MineNetInstance implements Spawnable {
return Optional.ofNullable(players.get(p));
}
public static Optional<Room> getRoom(UUID uuid) {
return rooms.stream().filter(room -> room.uuid.equals(uuid)).findFirst();
}
public static void setOwnRoom(Player p) {
setRoom(p, getRoom(p).orElseThrow());
}
@ -144,12 +147,6 @@ public class Room extends MineNetInstance implements Spawnable {
.collect(Collectors.toSet());
}
@Override
protected boolean onPlayerJoin(Player p) {
this.gameSelector.onInteract(new PlayerEntityInteractEvent(p, gameSelector, Player.Hand.MAIN, p.getPosition()));
return super.onPlayerJoin(p);
}
@Override
public Pos getSpawn() {
return new Pos(0.5, 50, 0.5);