feat: switch over to jetty
This commit is contained in:
parent
6ed3dc5ce4
commit
a7f3038261
|
@ -16,7 +16,14 @@ dependencies {
|
|||
|
||||
implementation files('/home/tcf/MinecraftDev/craftbukkit-1.1-R5-SNAPSHOT.jar')
|
||||
|
||||
implementation 'org.java-websocket:Java-WebSocket:1.5.4'
|
||||
implementation 'org.eclipse.jetty:jetty-server:9.4.52.v20230823'
|
||||
implementation 'org.eclipse.jetty:jetty-servlet:9.4.52.v20230823'
|
||||
implementation 'org.eclipse.jetty.websocket:websocket-server:9.4.52.v20230823'
|
||||
implementation 'org.eclipse.jetty.websocket:websocket-servlet:9.4.52.v20230823'
|
||||
|
||||
implementation 'javax.servlet:javax.servlet-api:4.0.1'
|
||||
implementation 'javax.websocket:javax.websocket-api:1.1'
|
||||
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
}
|
||||
|
||||
|
|
|
@ -1,37 +1,48 @@
|
|||
package me.theclashfruit.crss;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import me.theclashfruit.crss.api.ChatServlet;
|
||||
import me.theclashfruit.crss.api.ChatSocket;
|
||||
import me.theclashfruit.crss.listener.ChatListener;
|
||||
import me.theclashfruit.crss.listener.FunListener;
|
||||
import me.theclashfruit.crss.models.SystemData;
|
||||
import me.theclashfruit.crss.models.SystemMessage;
|
||||
import me.theclashfruit.crss.models.SocketData;
|
||||
import me.theclashfruit.crss.models.SocketMessage;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
|
||||
public class Plugin extends JavaPlugin {
|
||||
ChatSocket chatSocket;
|
||||
|
||||
Server server = new Server(25580);
|
||||
Connector connector = new ServerConnector(server);
|
||||
ServletHandler handler = new ServletHandler();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
getLogger().info("Plugin enabled!");
|
||||
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
|
||||
// create chat socket
|
||||
try {
|
||||
chatSocket = new ChatSocket(25580);
|
||||
// create api server
|
||||
// ContextHandler context = new ContextHandler(new ApiHandler(), "/v1");
|
||||
|
||||
chatSocket.start();
|
||||
} catch (UnknownHostException e) {
|
||||
handler.addServletWithMapping(ChatServlet.class, "/v1/chat");
|
||||
|
||||
server.addConnector(connector);
|
||||
server.setHandler(handler);
|
||||
|
||||
try {
|
||||
server.start();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// register events
|
||||
pluginManager.registerEvents(new FunListener(), this);
|
||||
pluginManager.registerEvents(new ChatListener(chatSocket), this);
|
||||
pluginManager.registerEvents(new ChatListener(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -40,20 +51,17 @@ public class Plugin extends JavaPlugin {
|
|||
|
||||
// stop chat socket
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
|
||||
String chatMessage = gson.toJson(new SystemMessage(
|
||||
ChatSocket.broadcast(new SocketMessage(
|
||||
"serverStop",
|
||||
new SystemData(
|
||||
new SocketData(
|
||||
null,
|
||||
"Server stopped.",
|
||||
0xFF5555
|
||||
false
|
||||
)
|
||||
));
|
||||
|
||||
chatSocket.broadcast(chatMessage);
|
||||
|
||||
chatSocket.stop();
|
||||
} catch (InterruptedException e) {
|
||||
server.stop();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
|
15
src/main/java/me/theclashfruit/crss/api/ChatServlet.java
Normal file
15
src/main/java/me/theclashfruit/crss/api/ChatServlet.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package me.theclashfruit.crss.api;
|
||||
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketServlet;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
|
||||
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
|
||||
@WebServlet(name = "Chat WebSocket API")
|
||||
public class ChatServlet extends WebSocketServlet {
|
||||
@Override
|
||||
public void configure(WebSocketServletFactory factory) {
|
||||
factory.register(ChatSocket.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +1,75 @@
|
|||
package me.theclashfruit.crss.api;
|
||||
|
||||
import org.java_websocket.WebSocket;
|
||||
import org.java_websocket.handshake.ClientHandshake;
|
||||
import org.java_websocket.server.WebSocketServer;
|
||||
import com.google.gson.Gson;
|
||||
import me.theclashfruit.crss.models.SocketData;
|
||||
import me.theclashfruit.crss.models.SocketMessage;
|
||||
import org.eclipse.jetty.websocket.api.Session;
|
||||
import org.eclipse.jetty.websocket.api.annotations.*;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import javax.websocket.EncodeException;
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
import static org.bukkit.Bukkit.getLogger;
|
||||
import static org.bukkit.Bukkit.getPlayer;
|
||||
|
||||
public class ChatSocket extends WebSocketServer {
|
||||
public ChatSocket(int port) throws UnknownHostException {
|
||||
super(new InetSocketAddress(port));
|
||||
@WebSocket
|
||||
public class ChatSocket {
|
||||
private static Set<ChatSocket> chatConnections = new CopyOnWriteArraySet<>();
|
||||
|
||||
private Session session;
|
||||
|
||||
@OnWebSocketConnect
|
||||
public void onConnect(Session session) throws IOException {
|
||||
this.session = session;
|
||||
|
||||
SocketMessage greeting = new SocketMessage(
|
||||
"connectionGreet",
|
||||
new SocketData(
|
||||
null,
|
||||
"Greetings!",
|
||||
true
|
||||
)
|
||||
);
|
||||
|
||||
Gson gson = new Gson();
|
||||
|
||||
session.getRemote().sendString(
|
||||
gson.toJson(greeting)
|
||||
);
|
||||
|
||||
chatConnections.add(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket conn, ClientHandshake handshake) {
|
||||
|
||||
@OnWebSocketMessage
|
||||
public void onMessage(String message) throws IOException, EncodeException {
|
||||
getLogger().info(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
|
||||
|
||||
@OnWebSocketClose
|
||||
public void onClose(int statusCode, String reason) throws IOException {
|
||||
chatConnections.remove(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket conn, String message) {
|
||||
|
||||
@OnWebSocketError
|
||||
public void onError(Throwable throwable) {
|
||||
getLogger().throwing(ChatSocket.class.getName(), "WebSocket", throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebSocket conn, Exception ex) {
|
||||
public static void broadcast(SocketMessage message) {
|
||||
chatConnections.forEach(endpoint -> {
|
||||
try {
|
||||
Gson gson = new Gson();
|
||||
|
||||
endpoint
|
||||
.session
|
||||
.getRemote()
|
||||
.sendString(
|
||||
gson.toJson(message)
|
||||
);
|
||||
} catch (IOException e) {
|
||||
getLogger().throwing(ChatSocket.class.getName(), "WebSocket", e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
getLogger().info("WebSocket server started on port " + getAddress().getPort() + "!");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package me.theclashfruit.crss.listener;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import me.theclashfruit.crss.Plugin;
|
||||
import me.theclashfruit.crss.api.ChatSocket;
|
||||
import me.theclashfruit.crss.models.ChatData;
|
||||
import me.theclashfruit.crss.models.ChatMessage;
|
||||
import me.theclashfruit.crss.models.SystemData;
|
||||
import me.theclashfruit.crss.models.SystemMessage;
|
||||
import me.theclashfruit.crss.models.*;
|
||||
import me.theclashfruit.crss.util.StringUtil;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
|
@ -17,88 +14,67 @@ import org.bukkit.event.player.PlayerQuitEvent;
|
|||
import org.bukkit.event.server.ServerCommandEvent;
|
||||
|
||||
public class ChatListener implements Listener {
|
||||
private final ChatSocket chatSocket;
|
||||
|
||||
public ChatListener(ChatSocket chatSocket) {
|
||||
this.chatSocket = chatSocket;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChat(PlayerChatEvent event) {
|
||||
Gson gson = new Gson();
|
||||
|
||||
String chatMessage = gson.toJson(new ChatMessage(
|
||||
ChatSocket.broadcast(new SocketMessage(
|
||||
"chatMessage",
|
||||
new ChatData(
|
||||
event.getMessage(),
|
||||
new SocketData(
|
||||
event.getPlayer().getName(),
|
||||
0xFFFFFF
|
||||
event.getMessage(),
|
||||
false
|
||||
)
|
||||
));
|
||||
|
||||
chatSocket.broadcast(chatMessage);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
Gson gson = new Gson();
|
||||
|
||||
String chatMessage = gson.toJson(new SystemMessage(
|
||||
ChatSocket.broadcast(new SocketMessage(
|
||||
"playerJoin",
|
||||
new SystemData(
|
||||
new SocketData(
|
||||
null,
|
||||
event.getPlayer().getName() + " joined the game.",
|
||||
0xFFFF55
|
||||
false
|
||||
)
|
||||
));
|
||||
|
||||
chatSocket.broadcast(chatMessage);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
Gson gson = new Gson();
|
||||
|
||||
String chatMessage = gson.toJson(new SystemMessage(
|
||||
ChatSocket.broadcast(new SocketMessage(
|
||||
"playerQuit",
|
||||
new SystemData(
|
||||
new SocketData(
|
||||
null,
|
||||
event.getPlayer().getName() + " left the game.",
|
||||
0xFFFF55
|
||||
false
|
||||
)
|
||||
));
|
||||
|
||||
chatSocket.broadcast(chatMessage);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onDeath(PlayerDeathEvent event) {
|
||||
Gson gson = new Gson();
|
||||
|
||||
String chatMessage = gson.toJson(new SystemMessage(
|
||||
ChatSocket.broadcast(new SocketMessage(
|
||||
"playerDeath",
|
||||
new SystemData(
|
||||
new SocketData(
|
||||
null,
|
||||
event.getDeathMessage(),
|
||||
0xFFFFFF
|
||||
false
|
||||
)
|
||||
));
|
||||
|
||||
chatSocket.broadcast(chatMessage);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onServerCommand(ServerCommandEvent event) {
|
||||
switch (event.getCommand().substring(0, 3)) {
|
||||
switch (StringUtil.getFirstPartBeforeSpace(event.getCommand())) {
|
||||
case "say":
|
||||
Gson gson = new Gson();
|
||||
|
||||
String chatMessage = gson.toJson(new SystemMessage(
|
||||
ChatSocket.broadcast(new SocketMessage(
|
||||
"serverSay",
|
||||
new SystemData(
|
||||
new SocketData(
|
||||
null,
|
||||
ChatColor.stripColor(event.getCommand().substring(4)),
|
||||
0xAA00AA
|
||||
false
|
||||
)
|
||||
));
|
||||
|
||||
chatSocket.broadcast(chatMessage);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
37
src/main/java/me/theclashfruit/crss/models/SocketData.java
Normal file
37
src/main/java/me/theclashfruit/crss/models/SocketData.java
Normal file
|
@ -0,0 +1,37 @@
|
|||
package me.theclashfruit.crss.models;
|
||||
|
||||
public class SocketData {
|
||||
private String username;
|
||||
private String message;
|
||||
private Boolean isSystemMessage;
|
||||
|
||||
public SocketData(String username, String message, Boolean isSystemMessage) {
|
||||
this.username = username;
|
||||
this.message = message;
|
||||
this.isSystemMessage = isSystemMessage;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public Boolean getIsSystemMessage() {
|
||||
return isSystemMessage;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public void setIsSystemMessage(Boolean isSystemMessage) {
|
||||
this.isSystemMessage = isSystemMessage;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package me.theclashfruit.crss.models;
|
||||
|
||||
public class SocketMessage {
|
||||
private String event;
|
||||
private SocketData data;
|
||||
|
||||
public SocketMessage(String event, SocketData data) {
|
||||
this.event = event;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public SocketData getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setEvent(String event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public void setData(SocketData data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
33
src/main/java/me/theclashfruit/crss/util/MessageDecoder.java
Normal file
33
src/main/java/me/theclashfruit/crss/util/MessageDecoder.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package me.theclashfruit.crss.util;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import me.theclashfruit.crss.models.SocketMessage;
|
||||
|
||||
import javax.websocket.DecodeException;
|
||||
import javax.websocket.Decoder;
|
||||
import javax.websocket.EndpointConfig;
|
||||
|
||||
public class MessageDecoder implements Decoder.Text<SocketMessage> {
|
||||
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
@Override
|
||||
public SocketMessage decode(String s) throws DecodeException {
|
||||
return gson.fromJson(s, SocketMessage.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean willDecode(String s) {
|
||||
return (s != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EndpointConfig endpointConfig) {
|
||||
// Custom initialization logic
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// Close resources
|
||||
}
|
||||
}
|
28
src/main/java/me/theclashfruit/crss/util/MessageEncoder.java
Normal file
28
src/main/java/me/theclashfruit/crss/util/MessageEncoder.java
Normal file
|
@ -0,0 +1,28 @@
|
|||
package me.theclashfruit.crss.util;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import me.theclashfruit.crss.models.SocketMessage;
|
||||
|
||||
import javax.websocket.EncodeException;
|
||||
import javax.websocket.Encoder;
|
||||
import javax.websocket.EndpointConfig;
|
||||
|
||||
public class MessageEncoder implements Encoder.Text<SocketMessage> {
|
||||
|
||||
private static final Gson gson = new Gson();
|
||||
|
||||
@Override
|
||||
public String encode(SocketMessage message) throws EncodeException {
|
||||
return gson.toJson(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(EndpointConfig endpointConfig) {
|
||||
// Custom initialization logic
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
// Close resources
|
||||
}
|
||||
}
|
8
src/main/java/me/theclashfruit/crss/util/StringUtil.java
Normal file
8
src/main/java/me/theclashfruit/crss/util/StringUtil.java
Normal file
|
@ -0,0 +1,8 @@
|
|||
package me.theclashfruit.crss.util;
|
||||
|
||||
public interface StringUtil {
|
||||
static String getFirstPartBeforeSpace(String input) {
|
||||
int index = input.contains(" ") ? input.indexOf(" ") : 0;
|
||||
return input.substring(0, index);
|
||||
}
|
||||
}
|
Reference in a new issue