mirror of
https://github.com/TotalFreedomMC/TotalFreedomMod.git
synced 2024-06-28 08:50:35 +00:00
848f103afa
Mass Refractoring, now uses me.totalfreedom.totalfreedommod as package Uses Aero https://github.com/Pravian/Aero Revamped command system Remove all TFM_ prefixes Revamp rank system Use new service based system Cleanup
282 lines
8.1 KiB
Java
282 lines
8.1 KiB
Java
package me.totalfreedom.totalfreedommod.httpd;
|
|
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.IOException;
|
|
import java.util.concurrent.Callable;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
|
|
import me.totalfreedom.totalfreedommod.httpd.NanoHTTPD.HTTPSession;
|
|
import me.totalfreedom.totalfreedommod.httpd.NanoHTTPD.Response;
|
|
import me.totalfreedom.totalfreedommod.util.FLog;
|
|
import me.totalfreedom.totalfreedommod.TotalFreedomMod;
|
|
import net.pravian.aero.component.service.AbstractService;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.exception.ExceptionUtils;
|
|
import org.bukkit.Bukkit;
|
|
|
|
public class HTTPDaemon extends AbstractService<TotalFreedomMod>
|
|
{
|
|
public static String MIME_DEFAULT_BINARY = "application/octet-stream";
|
|
//
|
|
private static final Pattern EXT_REGEX = Pattern.compile("\\.([^\\.\\s]+)$");
|
|
//
|
|
public static final int PORT = ConfigEntry.HTTPD_PORT.getInteger();
|
|
//
|
|
private static final TFM_HTTPD HTTPD = new TFM_HTTPD(PORT);
|
|
|
|
private HTTPDaemon(TotalFreedomMod plugin)
|
|
{
|
|
super(plugin);
|
|
}
|
|
|
|
@Override
|
|
public void onStart()
|
|
{
|
|
if (!ConfigEntry.HTTPD_ENABLED.getBoolean())
|
|
{
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
HTTPD.start();
|
|
|
|
if (HTTPD.isAlive())
|
|
{
|
|
FLog.info("TFM HTTPd started. Listening on port: " + HTTPD.getListeningPort());
|
|
}
|
|
else
|
|
{
|
|
FLog.info("Error starting TFM HTTPd.");
|
|
}
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
FLog.severe(ex);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onStop()
|
|
{
|
|
if (!ConfigEntry.HTTPD_ENABLED.getBoolean())
|
|
{
|
|
return;
|
|
}
|
|
|
|
HTTPD.stop();
|
|
|
|
FLog.info("TFM HTTPd stopped.");
|
|
}
|
|
|
|
private static enum ModuleType
|
|
{
|
|
DUMP(new ModuleExecutable(false, "dump")
|
|
{
|
|
@Override
|
|
public Response getResponse(HTTPSession session)
|
|
{
|
|
return new Response(Response.Status.OK, NanoHTTPD.MIME_PLAINTEXT, "The DUMP module is disabled. It is intended for debugging use only.");
|
|
}
|
|
}),
|
|
HELP(new ModuleExecutable(true, "help")
|
|
{
|
|
@Override
|
|
public Response getResponse(HTTPSession session)
|
|
{
|
|
return new Module_help(session).getResponse();
|
|
}
|
|
}),
|
|
LIST(new ModuleExecutable(true, "list")
|
|
{
|
|
@Override
|
|
public Response getResponse(HTTPSession session)
|
|
{
|
|
return new Module_list(session).getResponse();
|
|
}
|
|
}),
|
|
FILE(new ModuleExecutable(false, "file")
|
|
{
|
|
@Override
|
|
public Response getResponse(HTTPSession session)
|
|
{
|
|
return new Module_file(session).getResponse();
|
|
}
|
|
}),
|
|
SCHEMATIC(new ModuleExecutable(false, "schematic")
|
|
{
|
|
@Override
|
|
public Response getResponse(HTTPSession session)
|
|
{
|
|
return new Module_schematic(session).getResponse();
|
|
}
|
|
}),
|
|
PERMBANS(new ModuleExecutable(false, "permbans")
|
|
{
|
|
@Override
|
|
public Response getResponse(HTTPSession session)
|
|
{
|
|
return new Module_permbans(session).getResponse();
|
|
}
|
|
}),
|
|
PLAYERS(new ModuleExecutable(true, "players")
|
|
{
|
|
@Override
|
|
public Response getResponse(HTTPSession session)
|
|
{
|
|
return new Module_players(session).getResponse();
|
|
}
|
|
}),
|
|
LOGS(new ModuleExecutable(false, "logs")
|
|
{
|
|
@Override
|
|
public Response getResponse(HTTPSession session)
|
|
{
|
|
return new Module_logs(session).getResponse();
|
|
}
|
|
});
|
|
//
|
|
private final ModuleExecutable moduleExecutable;
|
|
|
|
private ModuleType(ModuleExecutable moduleExecutable)
|
|
{
|
|
this.moduleExecutable = moduleExecutable;
|
|
}
|
|
|
|
private abstract static class ModuleExecutable
|
|
{
|
|
private final boolean runOnBukkitThread;
|
|
private final String name;
|
|
|
|
private ModuleExecutable(boolean runOnBukkitThread, String name)
|
|
{
|
|
this.runOnBukkitThread = runOnBukkitThread;
|
|
this.name = name;
|
|
}
|
|
|
|
public Response execute(final HTTPSession session)
|
|
{
|
|
try
|
|
{
|
|
if (this.runOnBukkitThread)
|
|
{
|
|
return Bukkit.getScheduler().callSyncMethod(TotalFreedomMod.plugin, new Callable<Response>()
|
|
{
|
|
@Override
|
|
public Response call() throws Exception
|
|
{
|
|
return getResponse(session);
|
|
}
|
|
}).get();
|
|
}
|
|
else
|
|
{
|
|
return getResponse(session);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
FLog.severe(ex);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public abstract Response getResponse(HTTPSession session);
|
|
|
|
public String getName()
|
|
{
|
|
return name;
|
|
}
|
|
}
|
|
|
|
public ModuleExecutable getModuleExecutable()
|
|
{
|
|
return moduleExecutable;
|
|
}
|
|
|
|
private static ModuleType getByName(String needle)
|
|
{
|
|
for (ModuleType type : values())
|
|
{
|
|
if (type.getModuleExecutable().getName().equalsIgnoreCase(needle))
|
|
{
|
|
return type;
|
|
}
|
|
}
|
|
return FILE;
|
|
}
|
|
}
|
|
|
|
private static class TFM_HTTPD extends NanoHTTPD
|
|
{
|
|
public TFM_HTTPD(int port)
|
|
{
|
|
super(port);
|
|
}
|
|
|
|
public TFM_HTTPD(String hostname, int port)
|
|
{
|
|
super(hostname, port);
|
|
}
|
|
|
|
@Override
|
|
public Response serve(HTTPSession session)
|
|
{
|
|
Response response;
|
|
|
|
try
|
|
{
|
|
final String[] args = StringUtils.split(session.getUri(), "/");
|
|
final ModuleType moduleType = args.length >= 1 ? ModuleType.getByName(args[0]) : ModuleType.FILE;
|
|
response = moduleType.getModuleExecutable().execute(session);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
response = new Response(Response.Status.INTERNAL_ERROR, MIME_PLAINTEXT, "Error 500: Internal Server Error\r\n" + ex.getMessage() + "\r\n" + ExceptionUtils.getStackTrace(ex));
|
|
}
|
|
|
|
if (response == null)
|
|
{
|
|
response = new Response(Response.Status.NOT_FOUND, MIME_PLAINTEXT, "Error 404: Not Found - The requested resource was not found on this server.");
|
|
}
|
|
|
|
return response;
|
|
}
|
|
}
|
|
|
|
public static Response serveFileBasic(File file)
|
|
{
|
|
Response response = null;
|
|
|
|
if (file != null && file.exists())
|
|
{
|
|
try
|
|
{
|
|
String mimetype = null;
|
|
|
|
Matcher matcher = EXT_REGEX.matcher(file.getCanonicalPath());
|
|
if (matcher.find())
|
|
{
|
|
mimetype = Module_file.MIME_TYPES.get(matcher.group(1));
|
|
}
|
|
|
|
if (mimetype == null || mimetype.trim().isEmpty())
|
|
{
|
|
mimetype = MIME_DEFAULT_BINARY;
|
|
}
|
|
|
|
response = new Response(Response.Status.OK, mimetype, new FileInputStream(file));
|
|
response.addHeader("Content-Length", "" + file.length());
|
|
}
|
|
catch (IOException ex)
|
|
{
|
|
FLog.severe(ex);
|
|
}
|
|
}
|
|
|
|
return response;
|
|
}
|
|
}
|