ServerAPI/src/main/java/xyz/etztech/serverapi/web/Web.java

118 lines
3.7 KiB
Java

package xyz.etztech.serverapi.web;
import io.javalin.Javalin;
import io.javalin.core.event.EventListener;
import io.javalin.core.plugin.Plugin;
import io.javalin.core.util.RouteOverviewPlugin;
import io.javalin.http.Context;
import io.javalin.http.UnauthorizedResponse;
import io.javalin.plugin.graphql.GraphQLOptions;
import io.javalin.plugin.graphql.GraphQLPlugin;
import io.javalin.plugin.json.JavalinJson;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.helpers.NOPLogger;
import xyz.etztech.serverapi.ServerAPI;
import xyz.etztech.serverapi.web.api.ErrorAPI;
public class Web {
private final IProvider provider;
private String password;
private Javalin app;
public Web(IProvider provider) {
this.provider = provider;
}
public void start(int port, String password) {
Javalin.log = NOPLogger.NOP_LOGGER;
app = Javalin.create(config -> {
config.registerPlugin(graphql());
config.registerPlugin(new RouteOverviewPlugin("/"));
config.enableCorsForAllOrigins();
}).events(this::events).exception(Exception.class, this::exception);
this.password = password;
if (!"".equals(password)) {
app.before(this::access);
}
app.get("/bans", this::bans);
app.get("/players", this::players);
app.get("/query", this::query);
app.get("/tps", this::tps);
app.get("/worlds", this::worlds);
app.get("/worlds/:name", this::world);
// What in the actual fuck... https://github.com/tipsy/javalin/issues/358
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(ServerAPI.class.getClassLoader());
app.start(port);
Thread.currentThread().setContextClassLoader(classLoader);
}
public void stop() {
if (app != null) {
app.stop();
}
}
public void events(EventListener event) {
event.serverStarting(() -> provider.log("Starting API..."));
event.serverStarted(() -> provider.log("API is ready!"));
event.serverStartFailed(() -> provider.log("Could not start API..."));
event.serverStopping(() -> provider.log("Stopping API..."));
event.serverStopped(() -> provider.log("API is stopped!"));
}
public void exception(Exception exception, Context ctx) {
provider.log(String.format("API Exception at %s:\n%s",
ctx.req.getRequestURI(),
ExceptionUtils.getStackTrace(exception)));
ctx.status(500);
ctx.json(new ErrorAPI(500, "Internal Error"));
}
public void access(Context ctx) {
String pw = ctx.header("X-ServerAPI-Password");
if (pw == null) {
pw = ctx.queryParam("password");
}
if (!password.equals(pw)) {
throw new UnauthorizedResponse(JavalinJson.toJson(new ErrorAPI(401, "Unauthorized")));
}
}
public Plugin graphql() {
GraphQLOptions options = new GraphQLOptions("/graphql", null)
.addPackage("xyz.etztech.serverapi.web.api")
.register(new GraphQL(provider));
return new GraphQLPlugin(options);
}
public void tps(Context ctx) {
ctx.json(provider.TPS());
}
public void worlds(Context ctx) {
ctx.json(provider.worlds());
}
public void world(Context ctx) {
ctx.json(provider.world(ctx.pathParam("name")));
}
public void players(Context ctx) {
ctx.json(provider.players());
}
public void bans(Context ctx) {
ctx.json(provider.bans());
}
public void query(Context ctx) {
ctx.json(provider.query());
}
}