├── .gitignore ├── README.md ├── build.xml ├── lib ├── gson-2.8.1-SNAPSHOT.jar └── java_websocket.jar ├── manifest.mf ├── nbbuild.xml └── src └── mcpews ├── MCClient.java ├── MCListener.java ├── MCSocketServer.java ├── WSEncrypt.java ├── command ├── BasicOrigin.java ├── CloseWebSocketCommand.java ├── CommandInput.java ├── CommandOrigin.java ├── CommandParser.java ├── CommandType.java ├── EmptyInput.java ├── EnchantCommand.java ├── ExecuteCommand.java ├── FillCommand.java ├── ListCommand.java ├── ListDetailCommand.java ├── SayCommand.java ├── SetBlockCommand.java ├── SummonCommand.java ├── TestForBlockCommand.java ├── TimeAddCommand.java ├── TimeQueryCommand.java ├── TimeSetCommand.java ├── TitleCommand.java └── WSServerCommand.java ├── event ├── EventMeasurements.java ├── EventProperties.java ├── EventType.java ├── PerformanceMetricsEvent.java ├── PlayerMessageEvent.java ├── PlayerTransformEvent.java └── PlayerTravelledEvent.java ├── listeners ├── BiomeListener.java ├── ChatListener.java ├── CommandsListener.java ├── DebugListener.java ├── ElytraListener.java ├── HideAndSeekListener.java ├── ServerGUI.form ├── ServerGUI.java └── TextToBlockListener.java ├── logger └── LogLevel.java ├── mcenum ├── BlockPos.java ├── BlockType.java ├── CommandTarget.java ├── DimensionType.java ├── EnchantType.java ├── EntityType.java ├── FeatureType.java ├── GameModeType.java ├── GameRuleType.java └── ItemType.java ├── message ├── EventSerializer.java ├── MCBody.java ├── MCCommand.java ├── MCError.java ├── MCEvent.java ├── MCHeader.java ├── MCMessage.java ├── MCResponse.java ├── MCResult.java ├── MCSubscribe.java ├── MCUnsubscribe.java ├── MessagePurposeType.java ├── MessageSerializer.java ├── ResponseSerializer.java └── StatusCodes.java ├── response ├── CloseWebSocketResponse.java ├── EnchantResponse.java ├── FillResponse.java ├── ListDetailResponse.java ├── ListResponse.java ├── SayResponse.java ├── SetBlockResponse.java ├── SummonResponse.java ├── TestForBlockResponse.java ├── TimeResponse.java └── WSServerResponse.java └── util ├── Biome.java ├── BiomeType.java ├── ChatFormatCode.java └── StringArray.java /.gitignore: -------------------------------------------------------------------------------- 1 | nbproject/private/ 2 | nbproject/ 3 | build/ 4 | nbbuild/ 5 | dist/ 6 | nbdist/ 7 | .nb-gradle/ 8 | /src/mcpews/listeners/ServerGUIFX.java 9 | /src/resources/fxml/ServerGUI.fxml 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Pocket Edition WebSocket Server API 2 | 3 | This API is meant to communicate with the C++ versions of Minecraft, namely Pocket Edition, Windows 10 Edition, and Education Edition using WebSockets. This is not a full multiplayer server, and does not share the same capabilities as multiplayer servers do. 4 | 5 | Minecraft uses WebSockets to communicate with external programs (such as the Classroom Mode App for Edu Edition) and developer tools. To connect to a WebSocket server, a user must use the `/connect` or `/wsserver` commands from the in-game chat screen. Once connected, the WebSocket server can listen for telemetry events from the game and send slash-commands (i.e. like `/kill`). A full list of all telemetry events the game tracks can be found here: https://gist.github.com/jocopa3/5f718f4198f1ea91a37e3a9da468675c 6 | 7 | Internally, Minecraft sends JSON messages through the WebSocket to communicate to servers. A basic outline of the JSON structure of each message can be found here: https://gist.github.com/jocopa3/54b42fb6361952997c4a6e38945e306f 8 | 9 | # Build Requirements 10 | 11 | * [Java-WebSocket](https://github.com/TooTallNate/Java-WebSocket) by TooTallNate 12 | * [GSON](https://github.com/google/gson) by Google 13 | 14 | Note: this project was built with JDK 1.8, but should be compatible with 1.7. 15 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Builds, tests, and runs the project MCPEWS. 12 | 13 | 73 | 74 | -------------------------------------------------------------------------------- /lib/gson-2.8.1-SNAPSHOT.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jocopa3/PEWS-API/31ced3e132c1b1f2f46b66e340331b6ef121cc6d/lib/gson-2.8.1-SNAPSHOT.jar -------------------------------------------------------------------------------- /lib/java_websocket.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jocopa3/PEWS-API/31ced3e132c1b1f2f46b66e340331b6ef121cc6d/lib/java_websocket.jar -------------------------------------------------------------------------------- /manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /nbbuild.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Builds, tests, and runs the project PEWS-API. 12 | 13 | 73 | 74 | -------------------------------------------------------------------------------- /src/mcpews/MCClient.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews; 7 | 8 | import java.io.UnsupportedEncodingException; 9 | import java.util.ArrayList; 10 | import java.util.HashMap; 11 | import java.util.LinkedList; 12 | import java.util.Queue; 13 | import java.util.TimerTask; 14 | import java.util.UUID; 15 | import java.util.Timer; 16 | import java.util.logging.Level; 17 | import java.util.logging.Logger; 18 | import mcpews.command.CloseWebSocketCommand; 19 | import mcpews.event.EventType; 20 | import mcpews.message.*; 21 | import org.java_websocket.WebSocket; 22 | import org.java_websocket.framing.CloseFrame; 23 | 24 | /** 25 | * 26 | * @author Jocopa3 27 | */ 28 | public class MCClient { 29 | 30 | private final WebSocket socket; 31 | private final boolean requiresEncryption; 32 | private final String clientName; 33 | 34 | private ArrayList subscribedEvents; 35 | 36 | private HashMap requestQuery; 37 | 38 | // Requests that were temporarily rejected get stored here 39 | private Queue requestWaitList; 40 | 41 | private Timer requestTimer; 42 | private int requestTimeout = 60000; // Wait 60 seconds before kicking out requests 43 | 44 | public MCClient(WebSocket socket) { 45 | this(socket, socket.getDraft() instanceof WSEncrypt); 46 | } 47 | 48 | public MCClient(WebSocket socket, boolean encrypted) { 49 | subscribedEvents = new ArrayList<>(); 50 | requestQuery = new HashMap<>(); 51 | requestWaitList = new LinkedList<>(); 52 | requestTimer = new Timer(); 53 | 54 | this.socket = socket; 55 | this.requiresEncryption = encrypted; 56 | clientName = socket.getRemoteSocketAddress().getHostString() + ":" + socket.getRemoteSocketAddress().getPort(); 57 | } 58 | 59 | public WebSocket getSocket() { 60 | return socket; 61 | } 62 | 63 | public boolean requiresEncryption() { 64 | return requiresEncryption; 65 | } 66 | 67 | public void subscribeToEvent(EventType event) { 68 | subscribedEvents.add(event); 69 | send(new MCSubscribe(event)); 70 | } 71 | 72 | public void unsubscribeFromEvent(EventType event) { 73 | subscribedEvents.remove(event); 74 | send(new MCUnsubscribe(event)); 75 | } 76 | 77 | public void unsubscribeFromAll() { 78 | for (EventType event : subscribedEvents) { 79 | send(new MCUnsubscribe(event)); 80 | } 81 | } 82 | 83 | public boolean isSubscribedToEvent(EventType event) { 84 | return subscribedEvents.contains(event); 85 | } 86 | 87 | public boolean isSubscribedToEvent(String eventName) { 88 | return isSubscribedToEvent(EventType.fromString(eventName)); 89 | } 90 | 91 | // Server sends close command to client 92 | public void closeServerSide() { 93 | socket.close(CloseFrame.NORMAL); 94 | } 95 | 96 | // Close the websocket using the client's closewebsocket command 97 | public void closeClientSide() { 98 | MCCommand close = new CloseWebSocketCommand(); 99 | send(close); 100 | } 101 | 102 | public void close() { 103 | unsubscribeFromAll(); // Clean up for the next server the client connects to 104 | closeClientSide(); 105 | } 106 | 107 | /* 108 | public String decryptMessage(String message) { 109 | try { 110 | byte[] bytes = Base64.decode(message); 111 | } catch (Base64DecodingException ex) { 112 | Logger.getLogger(MCClient.class.getName()).log(Level.SEVERE, null, ex); 113 | return ""; 114 | } 115 | 116 | return ""; 117 | } 118 | 119 | public String encrypttMessage(String message) { 120 | String encrypted; 121 | try { 122 | encrypted = Base64.encode(message.getBytes("UTF-8")); 123 | } catch (UnsupportedEncodingException ex) { 124 | encrypted = Base64.encode(message.getBytes()); 125 | } 126 | 127 | return encrypted; 128 | } 129 | */ 130 | 131 | public void send(MCBody body) { 132 | send(null, body); 133 | } 134 | 135 | public void send(MCMessage message) { 136 | send(null, message); 137 | } 138 | 139 | public void send(MCListener listener, MCBody body) { 140 | send(listener, body.getAsMessage()); 141 | } 142 | 143 | public void send(MCListener listener, MCMessage message) { 144 | if (message == null) { 145 | return; 146 | } 147 | 148 | String messageJson = message.getMessageText(); 149 | System.out.println(messageJson); 150 | 151 | // Add Command messages to the request map 152 | if (message.getPurpose() == MessagePurposeType.COMMAND_REQUEST) { 153 | ListenerRequest request = new ListenerRequest(listener, message); 154 | requestQuery.put(message.getHeader().getRequestId(), request); 155 | } 156 | 157 | socket.send(messageJson); 158 | } 159 | 160 | private void send(ListenerRequest request) { 161 | if (request == null || request.getRequestMessage() == null) { 162 | return; 163 | } 164 | 165 | MCMessage message = request.getRequestMessage(); 166 | String messageJson = message.getMessageText(); 167 | 168 | if (message.getPurpose() == MessagePurposeType.COMMAND_REQUEST) { 169 | request.reset(); 170 | requestQuery.put(message.getHeader().getRequestId(), request); 171 | } 172 | 173 | socket.send(messageJson); 174 | } 175 | 176 | protected ListenerRequest getCorrespondingRequest(MCMessage response) { 177 | switch (response.getPurpose()) { 178 | case COMMAND_RESPONSE: 179 | case ERROR: 180 | return requestQuery.remove(response.getHeader().getRequestId()); 181 | default: 182 | return null; 183 | } 184 | } 185 | 186 | protected ListenerRequest getRequestByUUID(UUID requestId) { 187 | return requestQuery.get(requestId); 188 | } 189 | 190 | protected ListenerRequest removeRequest(UUID requestId) { 191 | return requestQuery.remove(requestId); 192 | } 193 | 194 | public int getRequestTimeoutTime() { 195 | return requestTimeout; 196 | } 197 | 198 | public void setRequestTimeoutTime(int millis) { 199 | this.requestTimeout = millis; 200 | } 201 | 202 | protected void sendWaitlisted() { 203 | if (requestWaitList.size() > 0) { 204 | send(requestWaitList.remove()); 205 | } 206 | } 207 | 208 | @Override 209 | public String toString() { 210 | return clientName; 211 | } 212 | 213 | protected class ListenerRequest { 214 | 215 | private MCListener requestor; 216 | private MCMessage request; 217 | private TimerTask timer; 218 | 219 | private ListenerRequest(MCListener listener, MCMessage request) { 220 | requestor = listener; 221 | this.request = request; 222 | timer = createRemoveTimer(request); 223 | 224 | requestTimer.schedule(timer, requestTimeout); 225 | } 226 | 227 | private TimerTask createRemoveTimer(MCMessage request) { 228 | return new TimerTask() { 229 | @Override 230 | public void run() { 231 | requestQuery.remove(request.getHeader().getRequestId()); 232 | } 233 | }; 234 | } 235 | 236 | private TimerTask createResendTimer(MCMessage request) { 237 | return new TimerTask() { 238 | @Override 239 | public void run() { 240 | send(requestor, request); 241 | } 242 | }; 243 | } 244 | 245 | public MCListener getRequestor() { 246 | return requestor; 247 | } 248 | 249 | public MCMessage getRequestMessage() { 250 | return request; 251 | } 252 | 253 | protected void resetTimer() { 254 | timer.cancel(); 255 | timer = createRemoveTimer(request); 256 | requestTimer.schedule(timer, requestTimeout); 257 | } 258 | 259 | protected void addToWaitList() { 260 | timer.cancel(); 261 | requestWaitList.add(this); 262 | } 263 | 264 | private void reset() { 265 | timer = createRemoveTimer(request); 266 | requestTimer.schedule(timer, requestTimeout); 267 | } 268 | } 269 | 270 | } 271 | -------------------------------------------------------------------------------- /src/mcpews/MCListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews; 7 | 8 | import mcpews.message.*; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public interface MCListener { 15 | public void onResponse(MCClient client, MCMessage responseMessage, MCMessage requestMessage); 16 | public void onEvent(MCClient client, MCMessage eventMessage); 17 | public void onError(MCClient client, MCMessage errorMessage, MCMessage requestMessage); 18 | 19 | public void onConnected(MCClient client); 20 | public void onDisconnected(MCClient client); 21 | } 22 | -------------------------------------------------------------------------------- /src/mcpews/MCSocketServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews; 7 | 8 | import com.google.gson.JsonElement; 9 | import com.google.gson.JsonObject; 10 | import com.google.gson.JsonParser; 11 | import java.io.IOException; 12 | import java.net.BindException; 13 | import java.net.InetSocketAddress; 14 | import java.net.UnknownHostException; 15 | import java.nio.channels.ClosedByInterruptException; 16 | import java.util.ArrayList; 17 | import java.util.Arrays; 18 | import java.util.Collection; 19 | import java.util.Collections; 20 | import java.util.List; 21 | import java.util.UUID; 22 | import java.util.concurrent.ConcurrentHashMap; 23 | import java.util.logging.Level; 24 | import java.util.logging.Logger; 25 | import mcpews.logger.LogLevel; 26 | import mcpews.message.MCCommand; 27 | import mcpews.message.MCMessage; 28 | import mcpews.message.MessagePurposeType; 29 | import mcpews.message.ResponseSerializer; 30 | import org.java_websocket.WebSocket; 31 | import org.java_websocket.drafts.Draft; 32 | import org.java_websocket.drafts.Draft_17; 33 | import org.java_websocket.framing.Framedata; 34 | import org.java_websocket.handshake.ClientHandshake; 35 | import org.java_websocket.server.WebSocketServer; 36 | 37 | /** 38 | * 39 | * @author Jocopa3 40 | */ 41 | public class MCSocketServer extends WebSocketServer { 42 | 43 | private ArrayList listeners; 44 | 45 | private ConcurrentHashMap clients; 46 | 47 | public static final Logger messageLogger = Logger.getLogger("PEWS-MessageLog"); 48 | private static final ArrayList drafts; 49 | 50 | static { 51 | drafts = new ArrayList<>(); 52 | drafts.add(new WSEncrypt()); // RFC 6455 with subprotocol com.microsoft.minecraft.wsencrypt; encrypted 53 | drafts.add(new Draft_17()); // Default RFC 6455 protocol; no encryption 54 | } 55 | 56 | public MCSocketServer(InetSocketAddress address) { 57 | super(address, drafts); 58 | 59 | listeners = new ArrayList<>(); 60 | clients = new ConcurrentHashMap<>(); 61 | } 62 | 63 | @Override 64 | public void onOpen(WebSocket conn, ClientHandshake handshake) { 65 | MCClient client = new MCClient(conn); 66 | clients.put(conn, client); 67 | 68 | messageLogger.log(Level.INFO, "New connection: {0}; Encryption Status: {1}", 69 | new Object[] { 70 | conn.getRemoteSocketAddress().getHostString() + ":" + conn.getRemoteSocketAddress().getPort(), 71 | (client.requiresEncryption() ? "required" : "none") 72 | }); 73 | 74 | for (MCListener l : listeners) { 75 | l.onConnected(client); 76 | } 77 | } 78 | 79 | @Override 80 | public void onClose(WebSocket conn, int code, String reason, boolean remote) { 81 | messageLogger.log(Level.INFO, "Closed {0} with exit code {1} additional info: {2}", new Object[]{conn.getRemoteSocketAddress(), code, reason}); 82 | MCClient client = clients.get(conn); 83 | 84 | for (MCListener l : listeners) { 85 | l.onDisconnected(client); 86 | } 87 | 88 | clients.remove(conn); 89 | } 90 | 91 | private JsonParser parser = new JsonParser(); 92 | 93 | // TODO: split this function up so it isn't a cluttered mess 94 | // TODO: add process queue (if Java-WebSocket doesn't implement one already) 95 | @Override 96 | public void onMessage(WebSocket conn, String message) { 97 | if (message == null) { 98 | return; 99 | } 100 | 101 | boolean shouldSendWaitlisted = true; 102 | 103 | MCMessage mess; 104 | MCClient.ListenerRequest request = null; 105 | 106 | MCClient client = clients.get(conn); 107 | 108 | if (client.requiresEncryption()) { 109 | //message = client.decryptMessage(message); 110 | } 111 | 112 | try { 113 | JsonObject messageJson = parser.parse(message).getAsJsonObject(); 114 | JsonObject headerJson = messageJson.get("header").getAsJsonObject(); 115 | 116 | // Parse enough of the message to get the purpose 117 | MessagePurposeType purpose = MessagePurposeType.fromString( 118 | headerJson.get("messagePurpose").getAsString()); 119 | 120 | if (purpose == MessagePurposeType.COMMAND_RESPONSE) { 121 | // Parse enough of the message to get the requestId 122 | UUID requestId = UUID.fromString(messageJson.get("header").getAsJsonObject() 123 | .get("requestId").getAsString()); 124 | request = client.getRequestByUUID(requestId); 125 | 126 | MCMessage requestMessage = request.getRequestMessage(); 127 | 128 | if (requestMessage != null && purpose == MessagePurposeType.COMMAND_RESPONSE && requestMessage.getBody() instanceof MCCommand) { 129 | // Add a tip to the deserializer about what command triggered the response 130 | JsonObject body = messageJson.get("body").getAsJsonObject(); 131 | JsonElement statusCodeJson = body.get("statusCode"); 132 | 133 | if (statusCodeJson != null) { 134 | int statusCode = statusCodeJson.getAsInt(); 135 | 136 | body.addProperty(ResponseSerializer.PROPERTY_HINT_COMMAND, 137 | ((MCCommand) requestMessage.getBody()).getName()); 138 | body.addProperty(ResponseSerializer.PROPERTY_HINT_OVERLOAD, 139 | ((MCCommand) requestMessage.getBody()).getOverload()); 140 | 141 | if (statusCode == 131075) { 142 | request.resetTimer(); 143 | shouldSendWaitlisted = false; 144 | } else { 145 | client.removeRequest(requestId); 146 | } 147 | } 148 | } else { 149 | throw new Exception("Response with no corresponding request"); 150 | } 151 | } else if (purpose == MessagePurposeType.ERROR) { 152 | UUID requestId = UUID.fromString(messageJson.get("header").getAsJsonObject() 153 | .get("requestId").getAsString()); 154 | 155 | request = client.getRequestByUUID(requestId); 156 | 157 | JsonObject body = messageJson.get("body").getAsJsonObject(); 158 | JsonElement statusCodeJson = body.get("statusCode"); 159 | 160 | if (statusCodeJson != null && request != null) { 161 | int statusCode = statusCodeJson.getAsInt(); 162 | 163 | if (statusCode == -2147418109) { 164 | //System.out.println("Resending: " + requestId); 165 | request.addToWaitList(); 166 | shouldSendWaitlisted = false; 167 | } 168 | } 169 | } 170 | 171 | mess = MCMessage.getAsMessage(messageJson); 172 | } catch (Exception e) { 173 | messageLogger.log(LogLevel.DEBUG, "Failed to parse message; Reason: {0}; Message: {1}", new Object[]{e.getMessage(), message}); 174 | e.printStackTrace(); 175 | 176 | return; 177 | } 178 | 179 | if (mess == null) { 180 | // Couldn't parse the message or it's empty; don't bother alerting listeners 181 | return; 182 | } 183 | 184 | if (shouldSendWaitlisted && (mess.getPurpose() != MessagePurposeType.EVENT)) { 185 | client.sendWaitlisted(); 186 | } 187 | 188 | //System.out.println(message); 189 | // If the request was made by a specific listener, send the response directly to it 190 | if (request != null && request.getRequestor() != null) { 191 | switch (mess.getPurpose()) { 192 | case EVENT: 193 | request.getRequestor().onEvent(client, mess); 194 | break; 195 | case COMMAND_RESPONSE: 196 | request.getRequestor().onResponse(client, mess, request.getRequestMessage()); 197 | break; 198 | case ERROR: 199 | request.getRequestor().onError(client, mess, request.getRequestMessage()); 200 | break; 201 | } 202 | } else { 203 | switch (mess.getPurpose()) { 204 | case EVENT: 205 | System.out.println(message); 206 | for (MCListener l : listeners) { 207 | l.onEvent(client, mess); 208 | } 209 | break; 210 | case COMMAND_RESPONSE: 211 | for (MCListener l : listeners) { 212 | l.onResponse(client, mess, request.getRequestMessage()); 213 | } 214 | break; 215 | case ERROR: 216 | for (MCListener l : listeners) { 217 | l.onError(client, mess, request.getRequestMessage()); 218 | } 219 | break; 220 | } 221 | } 222 | } 223 | 224 | @Override 225 | public void onError(WebSocket conn, Exception ex) { 226 | if (conn != null) { 227 | String clientAddress = conn.getRemoteSocketAddress().getHostString() + ":" + conn.getRemoteSocketAddress().getPort(); 228 | 229 | if (ex instanceof ClosedByInterruptException) { 230 | messageLogger.log(Level.WARNING, "Server took to long to stop; forcibly stopped the server."); 231 | return; 232 | } else if (ex instanceof IOException) { 233 | if (ex.getMessage().endsWith("forcibly closed by the remote host")) { 234 | messageLogger.log(Level.INFO, "Client {0} forcibly quit.", clientAddress); 235 | } 236 | } else { 237 | messageLogger.log(LogLevel.DEBUG, "An error occured on connection {0}: {1}", 238 | new Object[]{clientAddress, ex}); 239 | } 240 | 241 | ex.printStackTrace(); 242 | } else { 243 | if (ex instanceof BindException) { 244 | messageLogger.log(Level.SEVERE, "Failed to start server. Another server is likely running on the same port."); 245 | return; 246 | } else if (ex instanceof ClosedByInterruptException) { 247 | messageLogger.log(Level.WARNING, "Server took to long to stop; forcibly stopped the server."); 248 | return; 249 | } 250 | 251 | messageLogger.log(LogLevel.DEBUG, "An error occured: {0}", new Object[]{ex}); 252 | ex.printStackTrace(); 253 | } 254 | } 255 | 256 | @Override 257 | public void run() { 258 | messageLogger.log(Level.INFO, "Starting server on: {0}:" + getAddress().getPort(), new Object[]{getAddress().getHostString()}); 259 | 260 | super.run(); 261 | } 262 | 263 | @Override 264 | public void onFragment(WebSocket conn, Framedata data) { 265 | System.out.println(Arrays.toString(data.getPayloadData().array())); 266 | } 267 | 268 | public Collection getClients() { 269 | return clients.values(); 270 | } 271 | 272 | public void addListener(MCListener m) { 273 | listeners.add(m); 274 | } 275 | 276 | public void removeListener(MCListener m) { 277 | listeners.remove(m); 278 | } 279 | 280 | public static Logger getLog() { 281 | return messageLogger; 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /src/mcpews/WSEncrypt.java: -------------------------------------------------------------------------------- 1 | package mcpews; 2 | 3 | import org.java_websocket.drafts.Draft; 4 | import org.java_websocket.drafts.Draft_17; 5 | import org.java_websocket.exceptions.InvalidHandshakeException; 6 | import org.java_websocket.handshake.*; 7 | 8 | public class WSEncrypt extends Draft_17 { 9 | 10 | public static final String WSENCRYPT_PROTOCOL_NAME = "com.microsoft.minecraft.wsencrypt"; 11 | 12 | @Override 13 | public HandshakeState acceptHandshakeAsServer(ClientHandshake handshakedata) throws InvalidHandshakeException { 14 | if (super.acceptHandshakeAsServer(handshakedata) == HandshakeState.NOT_MATCHED) { 15 | return HandshakeState.NOT_MATCHED; 16 | } 17 | 18 | if (!handshakedata.hasFieldValue("Sec-WebSocket-Protocol")) { 19 | return HandshakeState.NOT_MATCHED; 20 | } 21 | 22 | if (handshakedata.getFieldValue("Sec-WebSocket-Protocol").equalsIgnoreCase(WSENCRYPT_PROTOCOL_NAME)) { 23 | return HandshakeState.MATCHED; 24 | } else { 25 | return HandshakeState.NOT_MATCHED; 26 | } 27 | } 28 | 29 | @Override 30 | public HandshakeState acceptHandshakeAsClient(ClientHandshake request, ServerHandshake response) throws InvalidHandshakeException { 31 | if (super.acceptHandshakeAsClient(request, response) == HandshakeState.NOT_MATCHED) { 32 | return HandshakeState.NOT_MATCHED; 33 | } 34 | 35 | if (!request.hasFieldValue("Sec-WebSocket-Protocol")) { 36 | return HandshakeState.NOT_MATCHED; 37 | } 38 | 39 | if (request.getFieldValue("Sec-WebSocket-Protocol").equalsIgnoreCase(WSENCRYPT_PROTOCOL_NAME)) { 40 | return HandshakeState.MATCHED; 41 | } 42 | return HandshakeState.NOT_MATCHED; 43 | } 44 | 45 | @Override 46 | public ClientHandshakeBuilder postProcessHandshakeRequestAsClient(ClientHandshakeBuilder request) { 47 | super.postProcessHandshakeRequestAsClient(request); 48 | request.put("Sec-WebSocket-Protocol", WSENCRYPT_PROTOCOL_NAME); 49 | return request; 50 | } 51 | 52 | @Override 53 | public HandshakeBuilder postProcessHandshakeResponseAsServer(ClientHandshake request, ServerHandshakeBuilder response) throws InvalidHandshakeException { 54 | HandshakeBuilder result = super.postProcessHandshakeResponseAsServer(request, response); 55 | result.put("Sec-WebSocket-Protocol", WSENCRYPT_PROTOCOL_NAME); 56 | return result; 57 | } 58 | 59 | @Override 60 | public Draft copyInstance() { 61 | return new WSEncrypt(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/mcpews/command/BasicOrigin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | /** 9 | * 10 | * @author Jocopa3 11 | */ 12 | public class BasicOrigin extends CommandOrigin { 13 | 14 | public BasicOrigin(String type) { 15 | super(type); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/mcpews/command/CloseWebSocketCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.message.MCCommand; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class CloseWebSocketCommand extends MCCommand { 15 | 16 | public CloseWebSocketCommand() { 17 | super(new EmptyInput(), 18 | new BasicOrigin("player"), 19 | CommandType.CLOSE_WEBSOCKET.getName(), 20 | 1 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/mcpews/command/CommandInput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | /** 9 | * 10 | * @author Jocopa3 11 | */ 12 | public abstract class CommandInput { 13 | transient String overloadName = "default"; 14 | 15 | public String getOverload() { 16 | return overloadName; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/mcpews/command/CommandOrigin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | /** 9 | * 10 | * @author Jocopa3 11 | */ 12 | public abstract class CommandOrigin { 13 | private String type; 14 | 15 | public CommandOrigin(String type) { 16 | this.type = type; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/mcpews/command/CommandParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import java.lang.reflect.Array; 9 | import java.lang.reflect.Constructor; 10 | import java.util.ArrayList; 11 | import java.util.Arrays; 12 | import mcpews.MCSocketServer; 13 | import mcpews.logger.LogLevel; 14 | import mcpews.message.MCCommand; 15 | 16 | /** 17 | * This class is only intended to parse user input. If you want to create 18 | * MCCommand objects, please create them directly rather than use this class. 19 | * 20 | * @author Jocopa3 21 | */ 22 | public class CommandParser { 23 | 24 | private MCSocketServer server; 25 | 26 | public CommandParser(MCSocketServer server) { 27 | this.server = server; 28 | } 29 | 30 | /* 31 | * Splits a string by spaces, but ignores spaces when inside brackets or quotes 32 | * This is meant to be faster and less error-prone than using regex. 33 | * 34 | * For example, the string: @a[name=Monkey Wrench, m = -1 ] "Super User" one two 35 | * 36 | * returns an array of strings containing: 37 | * 38 | * @a[name=Monkey Wrench, m = -1 ] 39 | * "Super User" 40 | * one 41 | * two 42 | */ 43 | private String[] splitCommandText(String commandText) { 44 | commandText = commandText.trim(); 45 | 46 | int length = commandText.length(); 47 | ArrayList parameters = new ArrayList<>(); 48 | 49 | StringBuilder currentString = new StringBuilder(); 50 | int inBrackets = 0; 51 | boolean inQuotes = false; 52 | 53 | for (int i = 0; i < length; i++) { 54 | char c = commandText.charAt(i); 55 | 56 | switch (c) { 57 | case '"': 58 | inQuotes = !inQuotes; 59 | break; 60 | case '[': 61 | inBrackets++; 62 | break; 63 | case ']': 64 | inBrackets--; 65 | break; 66 | } 67 | 68 | if (inBrackets == 0 && !inQuotes && c == ' ') { 69 | parameters.add(currentString.toString()); 70 | currentString.delete(0, currentString.length()); 71 | } else { 72 | currentString.append(c); 73 | 74 | if (i == length - 1) { 75 | parameters.add(currentString.toString()); 76 | } 77 | } 78 | } 79 | 80 | return parameters.toArray(new String[0]); 81 | } 82 | 83 | /* 84 | * Attempts to parse command text into an MCCommand object 85 | * The input string must follow the same conventions as normal Minecraft commands 86 | * For more info about commands, see: https://minecraft.gamepedia.com/Commands 87 | * 88 | * Examples of valid input strings: 89 | * 90 | * /kill @e[type=!sheep,r=20] 91 | * /time set day 92 | * /enchant Jocopa3 sharpness 5 93 | * /execute @a ~ ~ ~ summon lightning ~ ~ ~ 94 | */ 95 | // Ugliest, function, ever. 96 | // This method is horridly slow; please only use it when the user types in commands and nothing else 97 | public MCCommand parseCommand(String input) { 98 | if (!input.startsWith("/")) { 99 | return null; 100 | } 101 | 102 | CommandType command = CommandType.fromChatString(input); 103 | 104 | if (command == null) { 105 | server.getLog().log(LogLevel.INFO, "Unknown command: {0}", input); 106 | return null; 107 | } 108 | 109 | // Parameters should store all string parameters following the /command input 110 | // Possible bug when typing a space between '/' and the command name like: / summon tnt 111 | String[] parameters = splitCommandText(input.replaceFirst("/" + command.getName(), "")); 112 | System.out.println("Parsing command: " + input); 113 | System.out.println("Command parameters: \n" + Arrays.toString(parameters)); 114 | MCCommand commandRequest = null; 115 | 116 | Class commandClass = command.getRequestClass(); 117 | 118 | if (parameters.length == 0) { 119 | try { 120 | Constructor constructor = commandClass.getConstructor(); 121 | commandRequest = (MCCommand) constructor.newInstance(); 122 | } catch (Exception e) { 123 | } 124 | } 125 | 126 | // Get all constructors and loop through them 127 | // Try to initialize the command object using each constructor 128 | Constructor[] constructors = commandClass.getConstructors(); 129 | 130 | mainLoop: 131 | for (Constructor constructor : constructors) { 132 | Class[] commandParams = constructor.getParameterTypes(); 133 | 134 | if (commandParams.length == 1 && commandParams[0].getSuperclass().equals(CommandInput.class)) { 135 | Constructor[] inputConstructors = commandParams[0].getConstructors(); 136 | 137 | for (Constructor inputConstructor : inputConstructors) { 138 | Class[] inputParams = inputConstructor.getParameterTypes(); 139 | int paramIndx = 0, objIndx = 0; 140 | Object[] objects = new Object[inputParams.length]; 141 | 142 | // Try to create each object in the constructor by passing the parameter strings 143 | // This is a horrid hack and should be replaced... 144 | try { 145 | for (Class paramType : inputParams) { 146 | Constructor paramCtor = null; 147 | String[] paramList = null; 148 | 149 | if (paramType.isArray()) { 150 | Object param = Array.newInstance(paramType.getComponentType(), parameters.length - paramIndx); 151 | int len = Array.getLength(param); 152 | Constructor componentConstructor = paramType.getComponentType().getConstructor(String.class); 153 | 154 | for (int i = 0; i < len; i++) { 155 | Object obj = componentConstructor.newInstance(parameters[paramIndx + i]); 156 | Array.set(param, i, obj); 157 | } 158 | 159 | objects[objIndx] = param; 160 | objIndx++; 161 | paramIndx += len; 162 | } else { 163 | int i; 164 | for (i = 1; i <= parameters.length; i++) { 165 | try { 166 | Class[] constructorObjects = new Class[i]; 167 | Arrays.fill(constructorObjects, String.class); 168 | 169 | paramCtor = paramType.getConstructor(constructorObjects); 170 | if (paramCtor != null) { 171 | paramList = new String[i]; 172 | System.arraycopy(parameters, paramIndx, paramList, 0, i); 173 | break; 174 | } 175 | } catch (Exception e) { 176 | } 177 | } 178 | 179 | if (paramCtor != null && paramList != null) { 180 | try { 181 | objects[objIndx] = paramCtor.newInstance((Object[]) paramList); 182 | } catch (Exception e) { 183 | break; 184 | } 185 | 186 | objIndx++; 187 | paramIndx += i; 188 | } else { 189 | break; 190 | } 191 | } 192 | } 193 | 194 | // Check if all the parameters the user typed were used 195 | if (paramIndx != parameters.length) { 196 | continue; 197 | } 198 | 199 | CommandInput commandInput = (CommandInput) inputConstructor.newInstance(objects); 200 | commandRequest = (MCCommand) constructor.newInstance(commandInput); 201 | break mainLoop; 202 | } catch (Exception e) { 203 | continue; 204 | } 205 | } 206 | } 207 | } 208 | 209 | // Inform the user if the command couldn't be parsed 210 | if (commandRequest == null) { 211 | server.getLog().log(LogLevel.INFO, "Couldn't parse command: " + input); 212 | } 213 | 214 | return commandRequest; 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /src/mcpews/command/CommandType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import java.util.HashMap; 9 | import mcpews.message.MCResponse; 10 | import mcpews.response.*; 11 | 12 | /** 13 | * 14 | * @author Jocopa3 15 | */ 16 | public enum CommandType { 17 | // Command classes must not be null! 18 | 19 | CLOSE_WEBSOCKET("closewebsocket", CloseWebSocketCommand.class, CloseWebSocketResponse.class), 20 | CONNECT("connect", WSServerCommand.class, WSServerResponse.class), 21 | ENCHANT("enchant", EnchantCommand.class, EnchantResponse.class), 22 | EXECUTE("execute", ExecuteCommand.class, MCResponse.class), 23 | FILL("fill", FillCommand.class, FillResponse.class), 24 | LIST("list", ListCommand.class, ListResponse.class), 25 | LISTD("listd", ListDetailCommand.class, ListDetailResponse.class), 26 | SAY("say", SayCommand.class, SayResponse.class), 27 | SETBLOCK("setblock", SetBlockCommand.class, SetBlockResponse.class), 28 | SUMMON("summon", SummonCommand.class, SummonResponse.class), 29 | TESTFORBLOCK("testforblock", TestForBlockCommand.class, TestForBlockResponse.class), 30 | TIME_ADD("time add", TimeAddCommand.class, TimeResponse.class), 31 | TIME_QUERY("time query", TimeQueryCommand.class, TimeResponse.class), 32 | TIME_SET("time set", TimeSetCommand.class, TimeResponse.class), 33 | WSSERVER("wsserver", WSServerCommand.class, WSServerResponse.class); 34 | 35 | private String name; 36 | private Class requestBodyClass; 37 | private Class responseBodyClass; 38 | 39 | private static HashMap commands; 40 | static { 41 | commands = new HashMap<>(); 42 | for (CommandType command : values()) { 43 | commands.put(command.getName(), command); 44 | } 45 | } 46 | 47 | CommandType(String name, Class requestClass, Class responseClass) { 48 | this.name = name; 49 | requestBodyClass = requestClass; 50 | responseBodyClass = responseClass; 51 | } 52 | 53 | public String getName() { 54 | return name; 55 | } 56 | 57 | public Class getRequestClass() { 58 | return requestBodyClass; 59 | } 60 | 61 | public Class getResponseClass() { 62 | return responseBodyClass; 63 | } 64 | 65 | public static CommandType fromString(String name) { 66 | return commands.get(name); 67 | } 68 | 69 | public static CommandType fromChatString(String chat) { 70 | chat = chat.trim(); 71 | 72 | if (chat.startsWith("/")) { 73 | chat = chat.replaceFirst("/", ""); 74 | } 75 | 76 | for (CommandType type : values()) { 77 | if (chat.startsWith(type.getName())) { 78 | return type; 79 | } 80 | } 81 | 82 | return null; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/mcpews/command/EmptyInput.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | /** 9 | * 10 | * @author Jocopa3 11 | */ 12 | public class EmptyInput extends CommandInput { 13 | // This isn't happening, everyone look away please; nothing to see here 14 | } 15 | -------------------------------------------------------------------------------- /src/mcpews/command/EnchantCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.command.TimeSetCommand.TimeOfDay; 9 | import mcpews.mcenum.CommandTarget; 10 | import mcpews.mcenum.EnchantType; 11 | import mcpews.message.MCCommand; 12 | 13 | /** 14 | * 15 | * @author Jocopa3 16 | */ 17 | public class EnchantCommand extends MCCommand { 18 | 19 | public static class EnchantByIdInput extends CommandInput { 20 | 21 | CommandTarget player; 22 | int enchantmentId; 23 | int level = 1; // Default level 24 | 25 | public EnchantByIdInput(CommandTarget player, Integer id) { 26 | this(player, id, 1); 27 | } 28 | 29 | public EnchantByIdInput(CommandTarget player, Integer id, Integer level) { 30 | overloadName = "byId"; 31 | this.player = player; 32 | enchantmentId = id; 33 | this.level = level; 34 | } 35 | } 36 | 37 | public static class EnchantByNameInput extends CommandInput { 38 | 39 | CommandTarget player; 40 | String enchantmentName; 41 | int level; 42 | 43 | public EnchantByNameInput(CommandTarget player, String name) { 44 | this(player, name, 1); 45 | } 46 | 47 | public EnchantByNameInput(CommandTarget player, String name, Integer level) { 48 | overloadName = "byName"; 49 | this.player = player; 50 | enchantmentName = name; 51 | this.level = level; 52 | } 53 | } 54 | 55 | public EnchantCommand(EnchantByNameInput input) { 56 | setInput(input); 57 | setOrigin(new BasicOrigin("player")); 58 | setName(CommandType.ENCHANT.getName()); 59 | setVersion(1); 60 | } 61 | 62 | public EnchantCommand(EnchantByIdInput input) { 63 | setInput(input); 64 | setOrigin(new BasicOrigin("player")); 65 | setName(CommandType.ENCHANT.getName()); 66 | setVersion(1); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/mcpews/command/ExecuteCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.mcenum.BlockPos; 9 | import mcpews.mcenum.BlockType; 10 | import mcpews.mcenum.CommandTarget; 11 | import mcpews.message.MCCommand; 12 | import mcpews.util.StringArray; 13 | 14 | /** 15 | * 16 | * @author Jocopa3 17 | */ 18 | public class ExecuteCommand extends MCCommand { 19 | 20 | public enum DetectType { 21 | detect; 22 | } 23 | 24 | public static class ExecuteDetectInput extends CommandInput { 25 | private CommandTarget origin; 26 | private BlockPos position; 27 | private DetectType detect; 28 | private String detectBlock; 29 | private int detectData; 30 | private String command; 31 | 32 | public ExecuteDetectInput(CommandTarget target, BlockPos position, DetectType detect, String block, int data, String command) { 33 | this.overloadName = "detect"; 34 | this.origin = target; 35 | this.position = position; 36 | this.detect = detect; 37 | this.detectBlock = block; 38 | this.detectData = data; 39 | this.command = command; 40 | } 41 | 42 | public ExecuteDetectInput(CommandTarget target, BlockPos position, DetectType detect, BlockType block, String command) { 43 | this(target, position, detect, block.getName(), block.getData(), command); 44 | } 45 | } 46 | 47 | public static class ExecuteAsOtherInput extends CommandInput { 48 | private CommandTarget origin; 49 | private BlockPos position; 50 | private String command; 51 | 52 | public ExecuteAsOtherInput(CommandTarget target, BlockPos position, String command) { 53 | this.overloadName = "asOther"; 54 | this.origin = target; 55 | this.position = position; 56 | this.command = command; 57 | } 58 | 59 | public ExecuteAsOtherInput(CommandTarget target, BlockPos position, String... command) { 60 | this.overloadName = "asOther"; 61 | this.origin = target; 62 | this.position = position; 63 | this.command = String.join(" ", command); 64 | } 65 | } 66 | 67 | public ExecuteCommand(ExecuteAsOtherInput input) { 68 | setInput(input); 69 | setOrigin(new BasicOrigin("player")); 70 | setName(CommandType.EXECUTE.getName()); 71 | setVersion(1); 72 | } 73 | 74 | public ExecuteCommand(ExecuteDetectInput input) { 75 | setInput(input); 76 | setOrigin(new BasicOrigin("player")); 77 | setName(CommandType.EXECUTE.getName()); 78 | setVersion(1); 79 | } 80 | } -------------------------------------------------------------------------------- /src/mcpews/command/FillCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.mcenum.BlockPos; 9 | import mcpews.mcenum.BlockType; 10 | import mcpews.message.MCCommand; 11 | 12 | /** 13 | * 14 | * @author Jocopa3 15 | */ 16 | public class FillCommand extends MCCommand { 17 | 18 | public enum OldBlockHandling { 19 | destroy, 20 | hollow, 21 | keep, 22 | outline, 23 | replace 24 | } 25 | 26 | public static class FillCommandInput extends CommandInput { 27 | 28 | BlockPos from; 29 | BlockPos to; 30 | String tileName; 31 | Integer tileData; 32 | String oldBlockHandling; 33 | String replaceTileName; 34 | Integer replaceDataValue; 35 | 36 | public FillCommandInput(BlockPos from, BlockPos to, String tileName) { 37 | overloadName = "byName"; 38 | this.from = from; 39 | this.to = to; 40 | this.tileName = tileName; 41 | } 42 | 43 | public FillCommandInput(BlockPos from, BlockPos to, String tileName, Integer tileData) { 44 | overloadName = "byName"; 45 | this.from = from; 46 | this.to = to; 47 | this.tileName = tileName; 48 | this.tileData = tileData; 49 | } 50 | 51 | public FillCommandInput(BlockPos from, BlockPos to, BlockType block) { 52 | this(from, to, block.getName(), block.getData()); 53 | } 54 | 55 | public FillCommandInput(BlockPos from, BlockPos to, String tileName, Integer tileData, String oldBlockHandling) { 56 | this(from, to, tileName, tileData); 57 | this.oldBlockHandling = oldBlockHandling; 58 | } 59 | 60 | public FillCommandInput(BlockPos from, BlockPos to, String tileName, Integer tileData, OldBlockHandling oldBlockHandling) { 61 | this(from, to, tileName, tileData, oldBlockHandling.name()); 62 | } 63 | 64 | public FillCommandInput(BlockPos from, BlockPos to, String tileName, Integer tileData, OldBlockHandling oldBlockHandling, String replaceTileName) { 65 | this(from, to, tileName, tileData, oldBlockHandling.name()); 66 | this.replaceTileName = replaceTileName; 67 | } 68 | 69 | public FillCommandInput(BlockPos from, BlockPos to, String tileName, Integer tileData, String oldBlockHandling, String replaceTileName) { 70 | this(from, to, tileName, tileData, oldBlockHandling); 71 | this.replaceTileName = replaceTileName; 72 | } 73 | 74 | public FillCommandInput(BlockPos from, BlockPos to, String tileName, Integer tileData, OldBlockHandling oldBlockHandling, String replaceTileName, int replaceDataValue) { 75 | this(from, to, tileName, tileData, oldBlockHandling.name(), replaceTileName); 76 | this.replaceDataValue = replaceDataValue; 77 | } 78 | } 79 | 80 | public FillCommand(FillCommandInput input) { 81 | super(); 82 | 83 | setInput(input); 84 | setOrigin(new BasicOrigin("player")); 85 | setName(CommandType.FILL.getName()); 86 | setVersion(1); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/mcpews/command/ListCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.message.MCCommand; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class ListCommand extends MCCommand { 15 | 16 | public ListCommand() { 17 | super(new EmptyInput(), 18 | new BasicOrigin("player"), 19 | CommandType.LIST.getName(), 20 | 1 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/mcpews/command/ListDetailCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.message.MCCommand; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class ListDetailCommand extends MCCommand { 15 | 16 | public enum Detail { 17 | ids, 18 | stats, 19 | uuids; 20 | } 21 | 22 | public static class ListDetailsInput extends CommandInput { 23 | private String details; 24 | 25 | public ListDetailsInput(Detail detail) { 26 | this(detail.name()); 27 | } 28 | 29 | public ListDetailsInput(String detail) { 30 | details = detail; 31 | } 32 | } 33 | 34 | public ListDetailCommand() { 35 | super(new EmptyInput(), 36 | new BasicOrigin("player"), 37 | CommandType.LISTD.getName(), 38 | 1 39 | ); 40 | } 41 | 42 | public ListDetailCommand(ListDetailsInput input) { 43 | setInput(input); 44 | setOrigin(new BasicOrigin("player")); 45 | setName(CommandType.LISTD.getName()); 46 | setVersion(1); 47 | } 48 | } -------------------------------------------------------------------------------- /src/mcpews/command/SayCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.message.MCCommand; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class SayCommand extends MCCommand { 15 | 16 | public static class SayCommandInput extends CommandInput { 17 | String message; 18 | 19 | public SayCommandInput(String message) { 20 | this.message = message; 21 | } 22 | } 23 | 24 | public SayCommand(SayCommandInput input) { 25 | setInput(input); 26 | setOrigin(new BasicOrigin("player")); 27 | setName(CommandType.SAY.getName()); 28 | setVersion(1); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/mcpews/command/SetBlockCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.mcenum.BlockPos; 9 | import mcpews.mcenum.BlockType; 10 | import mcpews.message.MCCommand; 11 | 12 | /** 13 | * 14 | * @author Jocopa3 15 | */ 16 | public class SetBlockCommand extends MCCommand { 17 | 18 | public enum OldBlockHandling { 19 | destroy, 20 | keep, 21 | replace; 22 | } 23 | 24 | public static class SetBlockInput extends CommandInput { 25 | 26 | private BlockPos position; 27 | private String tileName; 28 | private int tileData; 29 | private String oldBlockHandling; 30 | 31 | public SetBlockInput(BlockPos pos, BlockType block) { 32 | position = pos; 33 | tileName = block.getName(); 34 | tileData = block.getData(); 35 | } 36 | 37 | public SetBlockInput(BlockPos pos, BlockType block, OldBlockHandling blockHandling) { 38 | this(pos, block, blockHandling.name()); 39 | } 40 | 41 | public SetBlockInput(BlockPos pos, BlockType block, String blockHandling) { 42 | position = pos; 43 | tileName = block.getName(); 44 | tileData = block.getData(); 45 | oldBlockHandling = blockHandling; 46 | } 47 | 48 | public SetBlockInput(BlockPos pos, String blockId) { 49 | this(pos, BlockType.fromString(blockId)); 50 | } 51 | 52 | public SetBlockInput(BlockPos pos, String blockId, Integer data) { 53 | this(pos, BlockType.fromString(blockId, data)); 54 | } 55 | 56 | public SetBlockInput(BlockPos pos, String blockId, OldBlockHandling handling) { 57 | this(pos, BlockType.fromString(blockId), handling); 58 | } 59 | 60 | public SetBlockInput(BlockPos pos, String blockId, Integer data, String handling) { 61 | this(pos, BlockType.fromString(blockId, data), handling); 62 | } 63 | } 64 | 65 | public SetBlockCommand(SetBlockInput input) { 66 | setInput(input); 67 | setOrigin(new BasicOrigin("player")); 68 | setName(CommandType.SETBLOCK.getName()); 69 | setVersion(1); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/mcpews/command/SummonCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.mcenum.BlockPos; 9 | import mcpews.mcenum.EntityType; 10 | import mcpews.message.MCCommand; 11 | 12 | /** 13 | * 14 | * @author Jocopa3 15 | */ 16 | public class SummonCommand extends MCCommand { 17 | 18 | public static class SummonCommandInput extends CommandInput { 19 | 20 | String entityType; 21 | BlockPos spawnPos; 22 | 23 | public SummonCommandInput(String entity) { 24 | this.entityType = entity; 25 | } 26 | 27 | public SummonCommandInput(String entity, BlockPos pos) { 28 | this.entityType = entity; 29 | this.spawnPos = pos; 30 | } 31 | 32 | public SummonCommandInput(EntityType entity) { 33 | this(entity.getName()); 34 | } 35 | 36 | public SummonCommandInput(EntityType entity, BlockPos pos) { 37 | this(entity.getName(), pos); 38 | } 39 | } 40 | 41 | public SummonCommand(SummonCommandInput input) { 42 | setInput(input); 43 | setOrigin(new BasicOrigin("player")); 44 | setName(CommandType.SUMMON.getName()); 45 | setVersion(1); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/mcpews/command/TestForBlockCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.mcenum.BlockPos; 9 | import mcpews.mcenum.BlockType; 10 | import mcpews.message.MCCommand; 11 | 12 | /** 13 | * 14 | * @author Jocopa3 15 | */ 16 | public class TestForBlockCommand extends MCCommand { 17 | 18 | public static class TestForBlockInput extends CommandInput { 19 | 20 | private BlockPos position; 21 | private String tileName; 22 | private int dataValue; 23 | 24 | public TestForBlockInput(BlockPos pos, String block) { 25 | this(pos, block, 0); 26 | } 27 | 28 | public TestForBlockInput(BlockPos pos, String block, Integer data) { 29 | position = pos; 30 | tileName = block; 31 | dataValue = data; 32 | } 33 | 34 | public TestForBlockInput(BlockPos pos, BlockType block) { 35 | this(pos, block.getName(), block.getData()); 36 | } 37 | } 38 | 39 | public TestForBlockCommand(TestForBlockInput input) { 40 | setInput(input); 41 | setOrigin(new BasicOrigin("player")); 42 | setName(CommandType.TESTFORBLOCK.getName()); 43 | setVersion(1); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/mcpews/command/TimeAddCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.message.MCCommand; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class TimeAddCommand extends MCCommand { 15 | 16 | public static class TimeAddCommandInput extends CommandInput { 17 | int amount; 18 | 19 | public TimeAddCommandInput(Integer amount) { 20 | this.amount = amount; 21 | } 22 | } 23 | 24 | public TimeAddCommand(TimeAddCommandInput input) { 25 | setInput(input); 26 | setOrigin(new BasicOrigin("player")); 27 | setName(CommandType.TIME_ADD.getName()); 28 | setVersion(1); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/mcpews/command/TimeQueryCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.message.MCCommand; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class TimeQueryCommand extends MCCommand { 15 | 16 | public enum TimeType { 17 | daytime, 18 | gametime, 19 | day; 20 | } 21 | 22 | public static class TimeQueryCommandInput extends CommandInput { 23 | String time; 24 | 25 | public TimeQueryCommandInput(TimeType time) { 26 | this(time.name()); 27 | } 28 | 29 | public TimeQueryCommandInput(String time) { 30 | this.time = time; 31 | } 32 | } 33 | 34 | public TimeQueryCommand(TimeQueryCommandInput input) { 35 | setInput(input); 36 | setOrigin(new BasicOrigin("player")); 37 | setName(CommandType.TIME_QUERY.getName()); 38 | setVersion(1); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/mcpews/command/TimeSetCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.message.MCCommand; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class TimeSetCommand extends MCCommand { 15 | 16 | public enum TimeOfDay { 17 | night, 18 | day; 19 | } 20 | 21 | public static class TimeSetByNumberInput extends CommandInput { 22 | int time; 23 | 24 | public TimeSetByNumberInput(Integer time) { 25 | overloadName = "byNumber"; 26 | this.time = time; 27 | } 28 | } 29 | 30 | public static class TimeSetByNameInput extends CommandInput { 31 | String time; 32 | 33 | public TimeSetByNameInput(TimeOfDay time) { 34 | overloadName = "byName"; 35 | this.time = time.name(); 36 | } 37 | 38 | public TimeSetByNameInput(String time) { 39 | overloadName = "byName"; 40 | this.time = time; 41 | } 42 | } 43 | 44 | public TimeSetCommand(TimeSetByNameInput input) { 45 | setInput(input); 46 | setOrigin(new BasicOrigin("player")); 47 | setName(CommandType.TIME_SET.getName()); 48 | setVersion(1); 49 | } 50 | 51 | public TimeSetCommand(TimeSetByNumberInput input) { 52 | setInput(input); 53 | setOrigin(new BasicOrigin("player")); 54 | setName(CommandType.TIME_SET.getName()); 55 | setVersion(1); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/mcpews/command/TitleCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.command.TimeSetCommand.TimeOfDay; 9 | import mcpews.mcenum.CommandTarget; 10 | import mcpews.mcenum.EnchantType; 11 | import mcpews.message.MCCommand; 12 | 13 | /** 14 | * 15 | * @author Jocopa3 16 | */ 17 | public class TitleCommand extends MCCommand { 18 | 19 | public static class EnchantByIdInput extends CommandInput { 20 | 21 | CommandTarget player; 22 | int enchantmentId; 23 | int level = 1; // Default level 24 | 25 | public EnchantByIdInput(CommandTarget player, Integer id) { 26 | this(player, id, 1); 27 | } 28 | 29 | public EnchantByIdInput(CommandTarget player, Integer id, Integer level) { 30 | overloadName = "byId"; 31 | this.player = player; 32 | enchantmentId = id; 33 | this.level = level; 34 | } 35 | } 36 | 37 | public static class EnchantByNameInput extends CommandInput { 38 | 39 | CommandTarget player; 40 | String enchantmentName; 41 | int level; 42 | 43 | public EnchantByNameInput(CommandTarget player, String name) { 44 | this(player, name, 1); 45 | } 46 | 47 | public EnchantByNameInput(CommandTarget player, String name, Integer level) { 48 | overloadName = "byName"; 49 | this.player = player; 50 | enchantmentName = name; 51 | this.level = level; 52 | } 53 | } 54 | 55 | public TitleCommand(EnchantByNameInput input) { 56 | setInput(input); 57 | setOrigin(new BasicOrigin("player")); 58 | setName(CommandType.ENCHANT.getName()); 59 | setVersion(1); 60 | } 61 | 62 | public TitleCommand(EnchantByIdInput input) { 63 | setInput(input); 64 | setOrigin(new BasicOrigin("player")); 65 | setName(CommandType.ENCHANT.getName()); 66 | setVersion(1); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/mcpews/command/WSServerCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.command; 7 | 8 | import mcpews.message.MCCommand; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class WSServerCommand extends MCCommand { 15 | 16 | public class WSServerCommandInput extends CommandInput { 17 | String serverUri; 18 | 19 | public WSServerCommandInput(String uri) { 20 | serverUri = uri; 21 | } 22 | } 23 | 24 | public WSServerCommand(WSServerCommandInput input) { 25 | setInput(input); 26 | setOrigin(new BasicOrigin("player")); 27 | setName(CommandType.WSSERVER.getName()); 28 | setVersion(1); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/mcpews/event/EventMeasurements.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.event; 7 | 8 | /** 9 | * 10 | * @author Jocopa3 11 | */ 12 | public class EventMeasurements { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/mcpews/event/EventProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header; choose License Headers in Project Properties. 3 | * To change this template file; choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.event; 7 | 8 | import mcpews.util.Biome; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class EventProperties { 15 | 16 | private int Biome; 17 | private String Build; 18 | private int BuildPlat; 19 | private boolean Cheevos; 20 | private String ClientId; 21 | private int Dim; 22 | private int Dimension; 23 | private String Flavor; 24 | private int Mode; 25 | private String MultiplayerCorrelationId; 26 | private int NetworkType; 27 | private String Plat; 28 | private String PlayerId; 29 | private String PlayerSessionID; 30 | private String ServerId; 31 | private String UserId; 32 | private int gameMode; 33 | private boolean vrMode; 34 | 35 | public Biome getBiome() { 36 | return mcpews.util.Biome.fromId(Biome); 37 | } 38 | 39 | /** 40 | * @return the Build 41 | */ 42 | public String getBuild() { 43 | return Build; 44 | } 45 | 46 | /** 47 | * @return the BuildPlat 48 | */ 49 | public int getBuildPlat() { 50 | return BuildPlat; 51 | } 52 | 53 | /** 54 | * @return the Cheevos 55 | */ 56 | public boolean isCheevos() { 57 | return Cheevos; 58 | } 59 | 60 | /** 61 | * @return the ClientId 62 | */ 63 | public String getClientId() { 64 | return ClientId; 65 | } 66 | 67 | /** 68 | * @return the Dim 69 | */ 70 | public int getDim() { 71 | return Dim; 72 | } 73 | 74 | /** 75 | * @return the Dimension 76 | */ 77 | public int getDimension() { 78 | return Dimension; 79 | } 80 | 81 | /** 82 | * @return the Flavor 83 | */ 84 | public String getFlavor() { 85 | return Flavor; 86 | } 87 | 88 | /** 89 | * @return the Mode 90 | */ 91 | public int getMode() { 92 | return Mode; 93 | } 94 | 95 | /** 96 | * @return the MultiplayerCorrelationId 97 | */ 98 | public String getMultiplayerCorrelationId() { 99 | return MultiplayerCorrelationId; 100 | } 101 | 102 | /** 103 | * @return the NetworkType 104 | */ 105 | public int getNetworkType() { 106 | return NetworkType; 107 | } 108 | 109 | /** 110 | * @return the Plat 111 | */ 112 | public String getPlat() { 113 | return Plat; 114 | } 115 | 116 | /** 117 | * @return the PlayerId 118 | */ 119 | public String getPlayerId() { 120 | return PlayerId; 121 | } 122 | 123 | /** 124 | * @return the PlayerSessionID 125 | */ 126 | public String getPlayerSessionID() { 127 | return PlayerSessionID; 128 | } 129 | 130 | /** 131 | * @return the ServerId 132 | */ 133 | public String getServerId() { 134 | return ServerId; 135 | } 136 | 137 | /** 138 | * @return the UserId 139 | */ 140 | public String getUserId() { 141 | return UserId; 142 | } 143 | 144 | /** 145 | * @return the gameMode 146 | */ 147 | public int getGameMode() { 148 | return gameMode; 149 | } 150 | 151 | /** 152 | * @return the vrMode 153 | */ 154 | public boolean isVrMode() { 155 | return vrMode; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/mcpews/event/EventType.java: -------------------------------------------------------------------------------- 1 | package mcpews.event; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 7 | * @author Jocopa3 8 | */ 9 | public enum EventType { 10 | // Event classes must not be null! 11 | ADDITIONAL_CONTENT_LOADED("AdditionalContentLoaded", null, EventProperties.class, EventMeasurements.class), 12 | AGENT_COMMAND("AgentCommand", null, EventProperties.class, EventMeasurements.class), 13 | AGENT_CREATED("AgentCreated", null, EventProperties.class, EventMeasurements.class), 14 | API_INIT("ApiInit", null, EventProperties.class, EventMeasurements.class), 15 | APP_PAUSED("AppPaused", null, EventProperties.class, EventMeasurements.class), 16 | APP_RESUMED("AppResumed", null, EventProperties.class, EventMeasurements.class), 17 | APP_SUSPENDED("AppSuspended", null, EventProperties.class, EventMeasurements.class), 18 | AWARD_ACHIEVEMENT("AwardAchievement", null, EventProperties.class, EventMeasurements.class), 19 | BLOCK_BROKEN("BlockBroken", null, EventProperties.class, EventMeasurements.class), 20 | BLOCK_PLACED("BlockPlaced", null, EventProperties.class, EventMeasurements.class), 21 | BOARD_TEXT_UPDATED("BoardTextUpdated", null, EventProperties.class, EventMeasurements.class), 22 | BOSS_KILLED("BossKilled", null, EventProperties.class, EventMeasurements.class), 23 | CAMERA_USED("CameraUsed", null, EventProperties.class, EventMeasurements.class), 24 | CAULDRON_USED("CauldronUsed", null, EventProperties.class, EventMeasurements.class), 25 | CHUNK_CHANGED("ChunkChanged", null, EventProperties.class, EventMeasurements.class), 26 | CHUNK_LOADED("ChunkLoaded", null, EventProperties.class, EventMeasurements.class), 27 | CHUNK_UNLOADED("ChunkUnloaded", null, EventProperties.class, EventMeasurements.class), 28 | CONFIGURATION_CHANGED("ConfigurationChanged", null, EventProperties.class, EventMeasurements.class), 29 | CONNECTION_FAILED("ConnectionFailed", null, EventProperties.class, EventMeasurements.class), 30 | CRAFTING_SESSION_COMPLETED("CraftingSessionCompleted", null, EventProperties.class, EventMeasurements.class), 31 | END_OF_DAY("EndOfDay", null, EventProperties.class, EventMeasurements.class), 32 | ENTITY_SPAWNED("EntitySpawned", null, EventProperties.class, EventMeasurements.class), 33 | FILE_TRANSMISSION_CANCELLED("FileTransmissionCancelled", null, EventProperties.class, EventMeasurements.class), 34 | FILE_TRANSMISSION_COMPLETED("FileTransmissionCompleted", null, EventProperties.class, EventMeasurements.class), 35 | FILE_TRANSMISSION_STARTED("FileTransmissionStarted", null, EventProperties.class, EventMeasurements.class), 36 | FIRST_TIME_CLIENT_OPEN("FirstTimeClientOpen", null, EventProperties.class, EventMeasurements.class), 37 | FOCUS_GAINED("FocusGained", null, EventProperties.class, EventMeasurements.class), 38 | FOCUS_LOST("FocusLost", null, EventProperties.class, EventMeasurements.class), 39 | GAME_SESSION_COMPLETE("GameSessionComplete", null, EventProperties.class, EventMeasurements.class), 40 | GAME_SESSION_START("GameSessionStart", null, EventProperties.class, EventMeasurements.class), 41 | HARDWARE_INFO("HardwareInfo", null, EventProperties.class, EventMeasurements.class), 42 | HAS_NEW_CONTENT("HasNewContent", null, EventProperties.class, EventMeasurements.class), 43 | ITEM_ACQUIRED("ItemAcquired", null, EventProperties.class, EventMeasurements.class), 44 | ITEM_CRAFTED("ItemCrafted", null, EventProperties.class, EventMeasurements.class), 45 | ITEM_DESTROYED("ItemDestroyed", null, EventProperties.class, EventMeasurements.class), 46 | ITEM_DROPPED("ItemDropped", null, EventProperties.class, EventMeasurements.class), 47 | ITEM_ENCHANTED("ItemEnchanted", null, EventProperties.class, EventMeasurements.class), 48 | ITEM_SMELTED("ItemSmelted", null, EventProperties.class, EventMeasurements.class), 49 | ITEM_USED("ItemUsed", null, EventProperties.class, EventMeasurements.class), 50 | JOIN_CANCELED("JoinCanceled", null, EventProperties.class, EventMeasurements.class), 51 | JUKEBOX_USED("JukeboxUsed", null, EventProperties.class, EventMeasurements.class), 52 | LICENSE_CENSUS("LicenseCensus", null, EventProperties.class, EventMeasurements.class), 53 | MASCOT_CREATED("MascotCreated", null, EventProperties.class, EventMeasurements.class), 54 | MENU_SHOWN("MenuShown", null, EventProperties.class, EventMeasurements.class), 55 | MOB_INTERACTED("MobInteracted", null, EventProperties.class, EventMeasurements.class), 56 | MOB_KILLED("MobKilled", null, EventProperties.class, EventMeasurements.class), 57 | MULTIPLAYER_CONNECTION_STATE_CHANGED("MultiplayerConnectionStateChanged", null, EventProperties.class, EventMeasurements.class), 58 | MULTIPLAYER_ROUND_END("MultiplayerRoundEnd", null, EventProperties.class, EventMeasurements.class), 59 | MULTIPLAYER_ROUND_START("MultiplayerRoundStart", null, EventProperties.class, EventMeasurements.class), 60 | NPC_PROPERTIES_UPDATED("NpcPropertiesUpdated", null, EventProperties.class, EventMeasurements.class), 61 | OPTIONS_UPDATED("OptionsUpdated", null, EventProperties.class, EventMeasurements.class), 62 | PERFORMANCE_METRICS("performanceMetrics", null, EventProperties.class, EventMeasurements.class), 63 | PACK_IMPORT_STAGE("PackImportStage", null, EventProperties.class, EventMeasurements.class), 64 | PLAYER_BOUNCED("PlayerBounced", null, EventProperties.class, EventMeasurements.class), 65 | PLAYER_DIED("PlayerDied", null, EventProperties.class, EventMeasurements.class), 66 | PLAYER_JOIN("PlayerJoin", null, EventProperties.class, EventMeasurements.class), 67 | PLAYER_LEAVE("PlayerLeave", null, EventProperties.class, EventMeasurements.class), 68 | PLAYER_MESSAGE("PlayerMessage", PlayerMessageEvent.class, PlayerMessageEvent.PlayerMessageProperties.class, EventMeasurements.class), 69 | PLAYER_TELEPORTED("PlayerTeleported", null, EventProperties.class, EventMeasurements.class), 70 | PLAYER_TRANSFORM("PlayerTransform", PlayerTransformEvent.class, PlayerTransformEvent.PlayerTransformProperties.class, EventMeasurements.class), 71 | PLAYER_TRAVELLED("PlayerTravelled", PlayerTravelledEvent.class, PlayerTravelledEvent.PlayerTravelledProperties.class, PlayerTravelledEvent.PlayerTravelledMeasurements.class), 72 | PORTAL_BUILT("PortalBuilt", null, EventProperties.class, EventMeasurements.class), 73 | PORTAL_USED("PortalUsed", null, EventProperties.class, EventMeasurements.class), 74 | PORTFOLIO_EXPORTED("PortfolioExported", null, EventProperties.class, EventMeasurements.class), 75 | POTION_BREWED("PotionBrewed", null, EventProperties.class, EventMeasurements.class), 76 | PURCHASE_ATTEMPT("PurchaseAttempt", null, EventProperties.class, EventMeasurements.class), 77 | PURCHASE_RESOLVED("PurchaseResolved", null, EventProperties.class, EventMeasurements.class), 78 | REGIONAL_POPUP("RegionalPopup", null, EventProperties.class, EventMeasurements.class), 79 | RESPONDED_TO_ACCEPT_CONTENT("RespondedToAcceptContent", null, EventProperties.class, EventMeasurements.class), 80 | SCREEN_CHANGED("ScreenChanged", null, EventProperties.class, EventMeasurements.class), 81 | SCREEN_HEARTBEAT("ScreenHeartbeat", null, EventProperties.class, EventMeasurements.class), 82 | SIGN_IN_TO_EDU("SignInToEdu", null, EventProperties.class, EventMeasurements.class), 83 | SIGN_IN_TO_XBOX_LIVE("SignInToXboxLive", null, EventProperties.class, EventMeasurements.class), 84 | SIGN_OUT_OF_XBOX_LIVE("SignOutOfXboxLive", null, EventProperties.class, EventMeasurements.class), 85 | SPECIAL_MOB_BUILT("SpecialMobBuilt", null, EventProperties.class, EventMeasurements.class), 86 | START_CLIENT("StartClient", null, EventProperties.class, EventMeasurements.class), 87 | START_WORLD("StartWorld", null, EventProperties.class, EventMeasurements.class), 88 | TEXT_TO_SPEECH_TOGGLED("TextToSpeechToggled", null, EventProperties.class, EventMeasurements.class), 89 | UGC_DOWNLOAD_COMPLETED("UgcDownloadCompleted", null, EventProperties.class, EventMeasurements.class), 90 | UGC_DOWNLOAD_STARTED("UgcDownloadStarted", null, EventProperties.class, EventMeasurements.class), 91 | UPLOAD_SKIN("UploadSkin", null, EventProperties.class, EventMeasurements.class), 92 | VEHICLE_EXITED("VehicleExited", null, EventProperties.class, EventMeasurements.class), 93 | WORLD_EXPORTED("WorldExported", null, EventProperties.class, EventMeasurements.class), 94 | WORLD_FILES_LISTED("WorldFilesListed", null, EventProperties.class, EventMeasurements.class), 95 | WORLD_GENERATED("WorldGenerated", null, EventProperties.class, EventMeasurements.class), 96 | WORLD_LOADED("WorldLoaded", null, EventProperties.class, EventMeasurements.class), 97 | WORLD_UNLOADED("WorldUnloaded", null, EventProperties.class, EventMeasurements.class); 98 | 99 | private static HashMap events = new HashMap<>(); 100 | 101 | static { 102 | for (EventType event : values()) { 103 | events.put(event.getName(), event); 104 | } 105 | } 106 | 107 | private String eventName; 108 | private Class eventClass; 109 | private Class propertiesClass; 110 | private Class measurementsClass; 111 | 112 | EventType(String name, Class eventClass, Class propertiesClass, Class measurementsClass) { 113 | eventName = name; 114 | this.eventClass = eventClass; 115 | this.propertiesClass = propertiesClass; 116 | this.measurementsClass = measurementsClass; 117 | } 118 | 119 | public String getName() { 120 | return eventName; 121 | } 122 | 123 | public Class getEventClassType() { 124 | return eventClass; 125 | } 126 | 127 | public Class getPropertiesClassType() { 128 | return propertiesClass; 129 | } 130 | 131 | public Class getMeasurementsClassType() { 132 | return measurementsClass; 133 | } 134 | 135 | public static EventType fromString(String name) { 136 | return events.get(name); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/mcpews/event/PerformanceMetricsEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.event; 7 | 8 | import mcpews.message.MCEvent; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class PerformanceMetricsEvent extends MCEvent { 15 | 16 | public PerformanceMetricsEvent(EventType type, EventProperties properties, EventMeasurements measurements) { 17 | super(type, properties, measurements); 18 | } 19 | 20 | protected class PerformanceMetricsMeasurements extends EventMeasurements { 21 | protected String Message; 22 | protected String Sender; 23 | } 24 | 25 | @Override 26 | public String toString() { 27 | return ""; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/mcpews/event/PlayerMessageEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.event; 7 | 8 | import mcpews.message.MCEvent; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class PlayerMessageEvent extends MCEvent { 15 | 16 | public PlayerMessageEvent(EventType type, EventProperties properties, EventMeasurements measurements) { 17 | super(type, properties, measurements); 18 | } 19 | 20 | protected class PlayerMessageProperties extends EventProperties { 21 | protected String Message; 22 | protected String Sender; 23 | } 24 | 25 | public String getSender() { 26 | return ((PlayerMessageProperties) properties).Sender; 27 | } 28 | 29 | public String getMessage() { 30 | return ((PlayerMessageProperties) properties).Message; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return getSender() + ": " + getMessage(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/mcpews/event/PlayerTransformEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.event; 7 | 8 | import mcpews.mcenum.BlockPos; 9 | import mcpews.message.MCEvent; 10 | 11 | /** 12 | * 13 | * @author Jocopa3 14 | */ 15 | public class PlayerTransformEvent extends MCEvent { 16 | 17 | public PlayerTransformEvent(EventType type, EventProperties properties, EventMeasurements measurements) { 18 | super(type, properties, measurements); 19 | } 20 | 21 | protected class PlayerTransformProperties extends EventProperties { 22 | protected double PlayerYRot; 23 | protected double PosX; 24 | protected double PosY; 25 | protected double PosZ; 26 | } 27 | 28 | public BlockPos getPosition() { 29 | PlayerTransformProperties props = (PlayerTransformProperties)properties; 30 | return new BlockPos(props.PosX, props.PosY, props.PosZ); 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return getPosition().toString(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/mcpews/event/PlayerTravelledEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.event; 7 | 8 | import mcpews.mcenum.BlockPos; 9 | import mcpews.message.MCEvent; 10 | 11 | /** 12 | * 13 | * @author Jocopa3 14 | */ 15 | public class PlayerTravelledEvent extends MCEvent { 16 | 17 | public PlayerTravelledEvent(EventType type, EventProperties properties, EventMeasurements measurements) { 18 | super(type, properties, measurements); 19 | } 20 | 21 | protected class PlayerTravelledMeasurements extends EventMeasurements { 22 | 23 | protected double MetersTravelled; 24 | protected int NewBiome; 25 | protected double PosXAvg, PosYAvg, PosZAvg; 26 | } 27 | 28 | protected class PlayerTravelledProperties extends EventProperties { 29 | 30 | boolean HasRelevantBuff; 31 | int MobType; 32 | int TravelMethodType; // 2 = Elytra, 5 = creative mode flying 33 | int WorldFeature; 34 | } 35 | 36 | public int getTravelMethod() { 37 | return ((PlayerTravelledProperties) properties).TravelMethodType; 38 | } 39 | 40 | public BlockPos getAvgPos() { 41 | PlayerTravelledMeasurements meas = (PlayerTravelledMeasurements) measurements; 42 | return new BlockPos(meas.PosXAvg, meas.PosYAvg, meas.PosZAvg); 43 | } 44 | 45 | public double getMetersTravelled() { 46 | return ((PlayerTravelledMeasurements) measurements).MetersTravelled; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return super.toString(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/mcpews/listeners/BiomeListener.java: -------------------------------------------------------------------------------- 1 | package mcpews.listeners; 2 | 3 | /* 4 | * This is a basic example of a global chatroom for Minecraft PE/Win10 made 5 | * using the Pocket Edition WebSocket API. 6 | */ 7 | import java.util.HashMap; 8 | 9 | import mcpews.MCClient; 10 | import mcpews.MCListener; 11 | import mcpews.MCSocketServer; 12 | import mcpews.command.SayCommand; 13 | import mcpews.event.EventType; 14 | import mcpews.logger.LogLevel; 15 | import mcpews.message.MCEvent; 16 | import mcpews.message.MCMessage; 17 | import mcpews.message.MCResponse; 18 | import mcpews.response.*; 19 | import mcpews.util.Biome; 20 | 21 | public class BiomeListener implements MCListener { 22 | 23 | private HashMap clientBiomes; 24 | private MCSocketServer server; 25 | 26 | /* 27 | * This listener requires a reference to the server in-order to get all 28 | * conncted clients. 29 | */ 30 | public BiomeListener(MCSocketServer server) { 31 | this.server = server; 32 | clientBiomes = new HashMap<>(); 33 | } 34 | 35 | /* 36 | * This method is called anytime a new client connects to the server 37 | */ 38 | @Override 39 | public void onConnected(MCClient client) { 40 | client.subscribeToEvent(EventType.PLAYER_TRAVELLED); 41 | } 42 | 43 | /* 44 | * This method is called >after< a client disconnects from the server. 45 | */ 46 | @Override 47 | public void onDisconnected(MCClient client) { 48 | } 49 | 50 | /* 51 | * This method is called whenever the server recieves an Event message. 52 | * The eventMessage parameter will contain an MCEvent as the body. 53 | */ 54 | @Override 55 | public void onEvent(MCClient client, MCMessage eventMessage) { 56 | MCEvent event = (MCEvent) eventMessage.getBody(); 57 | 58 | switch (event.getEventType()) { 59 | case PLAYER_TRAVELLED: 60 | Biome current = clientBiomes.get(client); 61 | Biome latest = event.getProperties().getBiome(); 62 | if (current == null || current != latest) { 63 | client.send(new SayCommand(new SayCommand.SayCommandInput("Biome: " + latest.getType().getChatColor() + latest.getName()))); 64 | clientBiomes.put(client, latest); 65 | } 66 | break; 67 | } 68 | } 69 | 70 | /* 71 | * This method is called whenever the server recieves a command response. 72 | * 73 | * The responseMessage parameter will contain an MCResponse as the body. 74 | * The requestMessage parameter is the original MCCommand request that 75 | * triggered the response. 76 | */ 77 | @Override 78 | public void onResponse(MCClient client, MCMessage responseMessage, MCMessage requestMessage) { 79 | MCResponse response = (MCResponse) responseMessage.getBody(); 80 | 81 | switch (response.getResponseType()) { 82 | case SAY: 83 | server.getLog().log(LogLevel.DEBUG, ((SayResponse) response).toString()); 84 | break; 85 | case LIST: 86 | server.getLog().log(LogLevel.DEBUG, ((ListResponse) response).toString()); 87 | break; 88 | case LISTD: 89 | server.getLog().log(LogLevel.DEBUG, ((ListDetailResponse) response).toString()); 90 | break; 91 | } 92 | } 93 | 94 | /* 95 | * This method is called whenever the server recieves an error from a client. 96 | * 97 | * The errorMessage parameter will contain an MCError as the body. 98 | * The requestMessage parameter is the original MCCommand request that 99 | * triggered the error. 100 | */ 101 | @Override 102 | public void onError(MCClient client, MCMessage errorMessage, MCMessage requestMessage) { 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /src/mcpews/listeners/ChatListener.java: -------------------------------------------------------------------------------- 1 | package mcpews.listeners; 2 | 3 | /* 4 | * This is a basic example of a global chatroom for Minecraft PE/Win10 made 5 | * using the Pocket Edition WebSocket API. 6 | */ 7 | import java.io.IOException; 8 | import java.net.InetAddress; 9 | import java.net.InetSocketAddress; 10 | import java.net.UnknownHostException; 11 | import java.util.Collection; 12 | import java.util.logging.Level; 13 | import java.util.Scanner; 14 | 15 | import mcpews.MCClient; 16 | import mcpews.MCListener; 17 | import mcpews.MCSocketServer; 18 | import mcpews.command.SayCommand; 19 | import mcpews.event.EventType; 20 | import mcpews.event.PlayerMessageEvent; 21 | import mcpews.logger.LogLevel; 22 | import mcpews.message.MCCommand; 23 | import mcpews.message.MCEvent; 24 | import mcpews.message.MCMessage; 25 | import mcpews.message.MCResponse; 26 | import mcpews.response.*; 27 | 28 | public class ChatListener implements MCListener { 29 | 30 | private MCSocketServer server; 31 | 32 | /* 33 | * This listener requires a reference to the server in-order to get all 34 | * conncted clients. 35 | */ 36 | public ChatListener(MCSocketServer server) { 37 | this.server = server; 38 | } 39 | 40 | /* 41 | * Sends a message using /say to a specific client only. 42 | */ 43 | private void sendMessageToClient(MCClient client, String message) { 44 | if (server == null) { 45 | return; 46 | } 47 | 48 | // Create a new /say command and send it to the client 49 | MCCommand say = new SayCommand(new SayCommand.SayCommandInput(message)); 50 | client.send(this, say); 51 | } 52 | 53 | /* 54 | * Sends a message using /say to all connected clients except the sender. 55 | */ 56 | private void sendMessageToOthers(MCClient sender, String message) { 57 | if (server == null) { 58 | return; 59 | } 60 | 61 | MCCommand say = new SayCommand(new SayCommand.SayCommandInput(message)); 62 | 63 | Collection clients = server.getClients(); 64 | 65 | synchronized (clients) { 66 | for (MCClient client : clients) { 67 | if (!client.equals(sender)) { 68 | client.send(this, say); 69 | } 70 | } 71 | } 72 | 73 | // Optional: log the chat message 74 | server.getLog().log(LogLevel.CHAT, message); 75 | } 76 | 77 | /* 78 | * This method is called anytime a new client connects to the server 79 | */ 80 | @Override 81 | public void onConnected(MCClient client) { 82 | // Subscribe to player message events to recieve messages from the client 83 | client.subscribeToEvent(EventType.PLAYER_MESSAGE); 84 | 85 | sendMessageToClient(client, "§eWelcome to §bPEWS§e chat! Say hi!"); 86 | sendMessageToOthers(client, "§eSomeone has joined the chat!"); 87 | } 88 | 89 | /* 90 | * This method is called >after< a client disconnects from the server. 91 | */ 92 | @Override 93 | public void onDisconnected(MCClient client) { 94 | // Inform other clients that someone has disconnected 95 | sendMessageToOthers(client, "§eSomeone has left the chat!"); 96 | } 97 | 98 | /* 99 | * This method is called whenever the server recieves an Event message. 100 | * The eventMessage parameter will contain an MCEvent as the body. 101 | */ 102 | @Override 103 | public void onEvent(MCClient client, MCMessage eventMessage) { 104 | MCEvent event = (MCEvent) eventMessage.getBody(); 105 | 106 | switch (event.getEventType()) { 107 | case PLAYER_MESSAGE: 108 | if (event instanceof PlayerMessageEvent) { 109 | PlayerMessageEvent pme = (PlayerMessageEvent) event; 110 | 111 | // Ignore messages from External which are sent by the WebSocket server 112 | if (!pme.getSender().equals("External")) { 113 | sendMessageToOthers(client, pme.getSender() + ": " + pme.getMessage()); 114 | } 115 | } 116 | break; 117 | } 118 | } 119 | 120 | /* 121 | * This method is called whenever the server recieves a command response. 122 | * 123 | * The responseMessage parameter will contain an MCResponse as the body. 124 | * The requestMessage parameter is the original MCCommand request that 125 | * triggered the response. 126 | */ 127 | @Override 128 | public void onResponse(MCClient client, MCMessage responseMessage, MCMessage requestMessage) { 129 | MCResponse response = (MCResponse) responseMessage.getBody(); 130 | 131 | switch (response.getResponseType()) { 132 | case SAY: 133 | server.getLog().log(LogLevel.DEBUG, ((SayResponse) response).toString()); 134 | break; 135 | case LIST: 136 | server.getLog().log(LogLevel.DEBUG, ((ListResponse) response).toString()); 137 | break; 138 | case LISTD: 139 | server.getLog().log(LogLevel.DEBUG, ((ListDetailResponse) response).toString()); 140 | break; 141 | } 142 | } 143 | 144 | /* 145 | * This method is called whenever the server recieves an error from a client. 146 | * 147 | * The errorMessage parameter will contain an MCError as the body. 148 | * The requestMessage parameter is the original MCCommand request that 149 | * triggered the error. 150 | */ 151 | @Override 152 | public void onError(MCClient client, MCMessage errorMessage, MCMessage requestMessage) { 153 | } 154 | 155 | /** 156 | * ***********************************************************************\ 157 | * |* Everything after this point is just to test the listener. *| 158 | * \************************************************************************ 159 | */ 160 | // Proper way to stop a server 161 | public static void stopServer(MCSocketServer server) { 162 | server.getLog().log(Level.INFO, "Stopping server: {0}:" + server.getAddress().getPort(), server.getAddress().getHostString()); 163 | MCCommand cm = new SayCommand(new SayCommand.SayCommandInput("§cPEWS chat server is shutting down...")); 164 | 165 | Collection con = server.getClients(); 166 | synchronized (con) { 167 | for (MCClient client : con) { 168 | client.send(cm); // Send warning to the client 169 | 170 | // Close the client using the /closewebsocket command 171 | // Also unsubscribes the client from all subscribed events 172 | client.close(); 173 | } 174 | } 175 | 176 | try { 177 | // Wait half a second to ensure all closing requests get sent to clients 178 | Thread.sleep(500); 179 | } catch (InterruptedException ex) { 180 | 181 | } 182 | 183 | try { 184 | // Give the server 5 seconds to fully shutdown 185 | server.stop(5000); 186 | } catch (InterruptedException ex) { 187 | server.getLog().log(Level.SEVERE, "Server shutdown was interrupted.", ex); 188 | } 189 | } 190 | 191 | /* 192 | * Creates a new MCSocketServer and adds a ChatListener to the server 193 | */ 194 | public static void main(String[] args) throws UnknownHostException { 195 | //String host = "localhost"; 196 | String host = InetAddress.getLocalHost().getHostAddress(); 197 | int port = 1789; 198 | 199 | MCSocketServer server = new MCSocketServer(new InetSocketAddress(host, port)); 200 | server.addListener(new ChatListener(server)); 201 | 202 | // Start the server on a new thread 203 | Thread t = new Thread(server); 204 | t.start(); 205 | 206 | Scanner cmdline = new Scanner(System.in); 207 | 208 | // Continue until "stop" is typed in the command line 209 | while (!cmdline.next().toLowerCase().trim().equals("stop")) { 210 | } 211 | 212 | stopServer(server); 213 | System.exit(0); 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/mcpews/listeners/CommandsListener.java: -------------------------------------------------------------------------------- 1 | package mcpews.listeners; 2 | 3 | import mcpews.MCClient; 4 | import mcpews.MCListener; 5 | import mcpews.command.SayCommand; 6 | import mcpews.command.SummonCommand; 7 | import mcpews.command.TimeSetCommand; 8 | import mcpews.command.TimeSetCommand.TimeOfDay; 9 | import mcpews.event.EventType; 10 | import mcpews.event.PlayerMessageEvent; 11 | import mcpews.mcenum.EntityType; 12 | import mcpews.message.MCCommand; 13 | import mcpews.message.MCEvent; 14 | import mcpews.message.MCMessage; 15 | 16 | public class CommandsListener implements MCListener { 17 | 18 | @Override 19 | public void onConnected(MCClient client) { 20 | client.subscribeToEvent(EventType.PLAYER_MESSAGE); 21 | } 22 | 23 | @Override 24 | public void onDisconnected(MCClient client) { 25 | } 26 | 27 | @Override 28 | public void onEvent(MCClient client, MCMessage eventMessage) { 29 | MCEvent event = (MCEvent) eventMessage.getBody(); 30 | 31 | switch (event.getEventType()) { 32 | case PLAYER_MESSAGE: 33 | if (event instanceof PlayerMessageEvent) { 34 | PlayerMessageEvent pme = (PlayerMessageEvent) event; 35 | 36 | if (pme.getMessage().toLowerCase().equals("blow me up") 37 | || pme.getMessage().toLowerCase().equals("send me to space")) { 38 | SummonCommand tnt; 39 | client.send(this, new SayCommand(new SayCommand.SayCommandInput("Boom goes the dynamite"))); 40 | for (int i = 0; i < 100; i++) { 41 | tnt = new SummonCommand(new SummonCommand.SummonCommandInput(EntityType.TNT)); 42 | client.send(this, tnt); 43 | } 44 | return; 45 | } 46 | 47 | if (pme.getMessage().toLowerCase().startsWith("spawn")) { 48 | SummonCommand tnt; 49 | String entity = pme.getMessage().toLowerCase().replaceFirst("spawn ", ""); 50 | EntityType entityT = EntityType.fromString(entity); 51 | if (entityT == null) { 52 | client.send(this, new SayCommand(new SayCommand.SayCommandInput("\"" + entity + "\" is not a valid entity name"))); 53 | return; 54 | } 55 | client.send(this, new SayCommand(new SayCommand.SayCommandInput("Spawning " + entity))); 56 | tnt = new SummonCommand(new SummonCommand.SummonCommandInput(EntityType.fromString(entity))); 57 | client.send(this, tnt); 58 | return; 59 | } 60 | 61 | if (pme.getMessage().toLowerCase().equals("day pls")) { 62 | client.send(this, new SayCommand(new SayCommand.SayCommandInput("Makin it day time"))); 63 | client.send(this, new TimeSetCommand(new TimeSetCommand.TimeSetByNameInput(TimeOfDay.day))); 64 | return; 65 | } 66 | 67 | if (pme.getMessage().toLowerCase().equals("night pls")) { 68 | client.send(this, new SayCommand(new SayCommand.SayCommandInput("Makin it night time"))); 69 | client.send(this, new TimeSetCommand(new TimeSetCommand.TimeSetByNameInput(TimeOfDay.night))); 70 | return; 71 | } 72 | 73 | if (pme.getMessage().toLowerCase().equals("all")) { 74 | SummonCommand tnt; 75 | client.send(this, new SayCommand(new SayCommand.SayCommandInput("Spawning all entities"))); 76 | for (EntityType type : EntityType.values()) { 77 | tnt = new SummonCommand(new SummonCommand.SummonCommandInput(type)); 78 | client.send(this, tnt); 79 | } 80 | return; 81 | } 82 | } 83 | break; 84 | } 85 | } 86 | 87 | @Override 88 | public void onResponse(MCClient client, MCMessage responseMessage, MCMessage requestMessage) { 89 | } 90 | 91 | @Override 92 | public void onError(MCClient client, MCMessage errorMessage, MCMessage requestMessage) { 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/mcpews/listeners/DebugListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.listeners; 7 | 8 | import java.util.ArrayList; 9 | import java.util.logging.Level; 10 | import java.util.logging.Logger; 11 | import mcpews.*; 12 | import mcpews.event.*; 13 | import mcpews.logger.LogLevel; 14 | import mcpews.message.*; 15 | 16 | /** 17 | * 18 | * @author Jocopa3 S. 19 | */ 20 | public class DebugListener implements MCListener { 21 | 22 | private ArrayList events = new ArrayList<>(); 23 | 24 | public void addEvent(EventType event) { 25 | if (!events.contains(event)) { 26 | events.add(event); 27 | } 28 | } 29 | 30 | @Override 31 | public void onEvent(MCClient client, MCMessage message) { 32 | MCSocketServer.messageLogger.log(LogLevel.DEBUG, "Received event from {0}; ToString: {1}; Message Text: {2}", 33 | new Object[]{ 34 | client.toString(), 35 | message.toString(), 36 | message.getMessageText() 37 | }); 38 | } 39 | 40 | @Override 41 | public void onConnected(MCClient client) { 42 | for (EventType event : events) { 43 | client.subscribeToEvent(event); 44 | } 45 | } 46 | 47 | @Override 48 | public void onDisconnected(MCClient client) { 49 | } 50 | 51 | @Override 52 | public void onResponse(MCClient client, MCMessage responseMessage, MCMessage requestMessage) { 53 | MCSocketServer.messageLogger.log(LogLevel.DEBUG, "Received response from {0}; Message: {1}; Request message: {2}", 54 | new Object[]{ 55 | client.toString(), 56 | responseMessage.getBody().toString(), 57 | requestMessage.getMessageText() 58 | }); 59 | } 60 | 61 | @Override 62 | public void onError(MCClient client, MCMessage errorMessage, MCMessage requestMessage) { 63 | MCSocketServer.messageLogger.log(LogLevel.DEBUG, "Received error from {0}; Message: {1}; Request message: {2}", 64 | new Object[]{ 65 | client.toString(), 66 | errorMessage.getBody().toString(), 67 | requestMessage.getMessageText() 68 | }); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/mcpews/listeners/ElytraListener.java: -------------------------------------------------------------------------------- 1 | package mcpews.listeners; 2 | 3 | import java.util.HashMap; 4 | import java.util.logging.Level; 5 | import java.util.logging.Logger; 6 | import mcpews.MCClient; 7 | import mcpews.MCListener; 8 | import mcpews.MCSocketServer; 9 | import mcpews.command.ExecuteCommand; 10 | import mcpews.command.FillCommand; 11 | import mcpews.command.SayCommand; 12 | import mcpews.command.SetBlockCommand; 13 | import mcpews.command.TestForBlockCommand; 14 | import mcpews.event.EventType; 15 | import mcpews.event.PlayerMessageEvent; 16 | import mcpews.event.PlayerTransformEvent; 17 | import mcpews.event.PlayerTravelledEvent; 18 | import mcpews.logger.LogLevel; 19 | import mcpews.mcenum.BlockPos; 20 | import mcpews.mcenum.BlockType; 21 | import mcpews.mcenum.CommandTarget; 22 | import mcpews.message.MCEvent; 23 | import mcpews.message.MCMessage; 24 | import mcpews.message.MCResponse; 25 | import mcpews.response.TestForBlockResponse; 26 | import mcpews.util.ChatFormatCode; 27 | 28 | /** 29 | * 30 | * @author Jocopa3 31 | */ 32 | public class ElytraListener implements MCListener { 33 | 34 | private MCSocketServer server; 35 | 36 | private HashMap playerPositions; 37 | private HashMap flyers; 38 | 39 | public ElytraListener(MCSocketServer server) { 40 | this.server = server; 41 | playerPositions = new HashMap<>(); 42 | flyers = new HashMap<>(); 43 | } 44 | 45 | private BlockPos getClientPosition(MCClient client) { 46 | return playerPositions.get(client); 47 | } 48 | 49 | private void setClientPosition(MCClient client, BlockPos pos) { 50 | playerPositions.put(client, pos); 51 | } 52 | 53 | BlockPos radius = new BlockPos(10, 7, 10); 54 | 55 | private void doElytraFlying(MCClient client, BlockPos pos, double metersTravelled) { 56 | BlockPos clientPosition = getClientPosition(client); 57 | 58 | if (clientPosition == null) { 59 | setClientPosition(client, pos); 60 | return; 61 | } 62 | 63 | BlockPos lowerBound = pos.sub(radius); 64 | BlockPos upperBound = pos.add(radius); 65 | 66 | //FillCommand fill = new FillCommand(new FillCommand.FillCommandInput(lowerBound, upperBound, BlockType.AIR)); 67 | //client.send(fill); 68 | //SetBlockCommand setBlock 69 | setClientPosition(client, pos); 70 | } 71 | 72 | @Override 73 | public void onResponse(MCClient client, MCMessage responseMessage, MCMessage requestMessage) { 74 | } 75 | 76 | @Override 77 | public void onEvent(MCClient client, MCMessage eventMessage) { 78 | MCEvent event = (MCEvent) eventMessage.getBody(); 79 | 80 | switch (event.getEventType()) { 81 | case PLAYER_TRAVELLED: 82 | if (event instanceof PlayerTravelledEvent) { 83 | PlayerTravelledEvent pte = (PlayerTravelledEvent) event; 84 | 85 | int travelMethod = pte.getTravelMethod(); 86 | server.getLog().log(LogLevel.DEBUG, "TravelMethodType: {0}", travelMethod); 87 | switch (travelMethod) { 88 | case 2: 89 | flyers.get(client).setFlying(true); 90 | //doElytraFlying(client, pte.getAvgPos(), pte.getMetersTravelled()); 91 | break; 92 | default: 93 | flyers.get(client).setFlying(false); 94 | break; 95 | } 96 | } 97 | break; 98 | } 99 | } 100 | 101 | @Override 102 | public void onError(MCClient client, MCMessage errorMessage, MCMessage requestMessage) { 103 | } 104 | 105 | @Override 106 | public void onConnected(MCClient client) { 107 | client.subscribeToEvent(EventType.PLAYER_TRAVELLED); 108 | ElytraFlyer flyer = new ElytraFlyer(client); 109 | flyers.put(client, flyer); 110 | Thread t = new Thread(flyer); 111 | t.start(); 112 | } 113 | 114 | @Override 115 | public void onDisconnected(MCClient client) { 116 | } 117 | 118 | private class ElytraFlyer implements Runnable { 119 | 120 | private MCClient client; 121 | 122 | public ElytraFlyer(MCClient client) { 123 | this.client = client; 124 | } 125 | 126 | boolean flying = false; 127 | private BlockPos relative = new BlockPos("~", "~", "~"); 128 | private CommandTarget localPlayer = new CommandTarget("@p"); 129 | 130 | @Override 131 | public void run() { 132 | while (true) { 133 | if (flying) { 134 | ExecuteCommand exec = new ExecuteCommand(new ExecuteCommand.ExecuteAsOtherInput(localPlayer, relative, "fill ~-4 ~-4 ~-4 ~4 ~4 ~4 air")); 135 | client.send(exec); 136 | } 137 | try { 138 | Thread.sleep(40); 139 | } catch (InterruptedException ex) { 140 | Logger.getLogger(ElytraListener.class.getName()).log(Level.SEVERE, null, ex); 141 | } 142 | } 143 | } 144 | 145 | public void setFlying(boolean flying) { 146 | this.flying = flying; 147 | } 148 | } 149 | } 150 | -------------------------------------------------------------------------------- /src/mcpews/listeners/HideAndSeekListener.java: -------------------------------------------------------------------------------- 1 | package mcpews.listeners; 2 | 3 | import java.util.HashMap; 4 | import mcpews.MCClient; 5 | import mcpews.MCListener; 6 | import mcpews.MCSocketServer; 7 | import mcpews.command.SayCommand; 8 | import mcpews.command.SetBlockCommand; 9 | import mcpews.command.TestForBlockCommand; 10 | import mcpews.event.EventType; 11 | import mcpews.event.PlayerMessageEvent; 12 | import mcpews.event.PlayerTransformEvent; 13 | import mcpews.mcenum.BlockPos; 14 | import mcpews.mcenum.BlockType; 15 | import mcpews.message.MCEvent; 16 | import mcpews.message.MCMessage; 17 | import mcpews.message.MCResponse; 18 | import mcpews.response.TestForBlockResponse; 19 | import mcpews.util.ChatFormatCode; 20 | 21 | /** 22 | * 23 | * @author Jocopa3 24 | */ 25 | public class HideAndSeekListener implements MCListener { 26 | 27 | private MCSocketServer server; 28 | 29 | private HashMap runningGames; 30 | 31 | public HideAndSeekListener(MCSocketServer server) { 32 | this.server = server; 33 | runningGames = new HashMap<>(); 34 | } 35 | 36 | @Override 37 | public void onResponse(MCClient client, MCMessage responseMessage, MCMessage requestMessage) { 38 | MCResponse response = (MCResponse) responseMessage.getBody(); 39 | 40 | switch (response.getResponseType()) { 41 | case TESTFORBLOCK: 42 | if (response instanceof TestForBlockResponse) { 43 | TestForBlockResponse tfbr = (TestForBlockResponse) response; 44 | HideAndSeekRunner game = runningGames.get(client); 45 | 46 | if (game != null) { 47 | game.setPlaying(tfbr.matches()); 48 | } 49 | } 50 | break; 51 | } 52 | } 53 | 54 | @Override 55 | public void onEvent(MCClient client, MCMessage eventMessage) { 56 | MCEvent event = (MCEvent) eventMessage.getBody(); 57 | 58 | switch (event.getEventType()) { 59 | case PLAYER_MESSAGE: 60 | if (event instanceof PlayerMessageEvent) { 61 | PlayerMessageEvent pme = (PlayerMessageEvent) event; 62 | 63 | if (pme.getMessage().toLowerCase().equals("play hide and seek")) { 64 | HideAndSeekRunner game = new HideAndSeekRunner(this, client); 65 | runningGames.put(client, game); 66 | new Thread(game).start(); 67 | return; 68 | } 69 | } 70 | break; 71 | case PLAYER_TRANSFORM: 72 | if (event instanceof PlayerTransformEvent) { 73 | PlayerTransformEvent pte = (PlayerTransformEvent) event; 74 | HideAndSeekRunner game = runningGames.get(client); 75 | 76 | if (game != null) { 77 | game.setPlayerPos(pte.getPosition()); 78 | } 79 | } 80 | break; 81 | } 82 | } 83 | 84 | @Override 85 | public void onError(MCClient client, MCMessage errorMessage, MCMessage requestMessage) { 86 | } 87 | 88 | @Override 89 | public void onConnected(MCClient client) { 90 | client.subscribeToEvent(EventType.PLAYER_MESSAGE); 91 | client.subscribeToEvent(EventType.PLAYER_TRANSFORM); 92 | } 93 | 94 | @Override 95 | public void onDisconnected(MCClient client) { 96 | } 97 | 98 | private void finishGame(MCClient client) { 99 | runningGames.remove(client); 100 | } 101 | 102 | private class HideAndSeekRunner implements Runnable { 103 | 104 | private HideAndSeekListener listener; 105 | private MCClient client; 106 | private boolean playing; 107 | private BlockPos randomPos; 108 | private BlockPos playerPos; 109 | private double distanceDelta = 0; 110 | 111 | private BlockPos randomPos() { 112 | return new BlockPos(Math.random() * 200 - 100, Math.random() * 64 + 4, Math.random() * 200 - 100); 113 | } 114 | 115 | HideAndSeekRunner(HideAndSeekListener listener, MCClient client) { 116 | this.listener = listener; 117 | this.client = client; 118 | playing = true; 119 | randomPos = randomPos(); 120 | playerPos = new BlockPos(10000, 10000, 10000); 121 | client.send(listener, new SetBlockCommand(new SetBlockCommand.SetBlockInput(randomPos, BlockType.DIAMOND_BLOCK))); 122 | } 123 | 124 | @Override 125 | public void run() { 126 | int a = 0; 127 | while (playing) { 128 | client.send(listener, new TestForBlockCommand(new TestForBlockCommand.TestForBlockInput(randomPos, BlockType.DIAMOND_BLOCK))); 129 | 130 | String message; 131 | 132 | if (distanceDelta < -1.1) { 133 | message = ChatFormatCode.BLUE_STRING + ChatFormatCode.BOLD_STRING + "Getting Super Cold"; 134 | } else if (distanceDelta < -0.6) { 135 | message = ChatFormatCode.BLUE_STRING + "Getting Colder"; 136 | } else if (distanceDelta < -0.1) { 137 | message = ChatFormatCode.AQUA_STRING + "Getting Cooler"; 138 | } else if (distanceDelta > 1.1) { 139 | message = ChatFormatCode.RED_STRING + ChatFormatCode.BOLD_STRING + "Getting Extremly Hot"; 140 | } else if (distanceDelta > 0.6) { 141 | message = ChatFormatCode.RED_STRING + "Getting Hotter"; 142 | } else if (distanceDelta > 0.1) { 143 | message = ChatFormatCode.YELLOW_STRING + "Getting Warmer"; 144 | } else { 145 | double dist = playerPos.distance(randomPos); 146 | 147 | if (dist < 4.0) { 148 | message = ChatFormatCode.RED_STRING + ChatFormatCode.BOLD_STRING + "On Fire!"; 149 | } else if (dist < 8.5) { 150 | message = ChatFormatCode.RED_STRING + ChatFormatCode.BOLD_STRING + "Super Hot"; 151 | } else if (dist < 15.0) { 152 | message = ChatFormatCode.RED_STRING + "Hot"; 153 | } else if (dist < 25.0) { 154 | message = ChatFormatCode.YELLOW_STRING + "Warm"; 155 | } else if (dist < 50.0) { 156 | message = ChatFormatCode.AQUA_STRING + "Cold"; 157 | } else { 158 | message = ChatFormatCode.BLUE_STRING + "Super Cold"; 159 | } 160 | } 161 | 162 | distanceDelta = 0.0; 163 | 164 | a++; 165 | if (a % 2 == 0) { 166 | client.send(listener, new SayCommand(new SayCommand.SayCommandInput(message))); 167 | } 168 | 169 | try { 170 | Thread.sleep(500); 171 | } catch (InterruptedException ex) { 172 | } 173 | } 174 | 175 | client.send(listener, new SayCommand(new SayCommand.SayCommandInput(ChatFormatCode.GREEN_STRING + "You won!"))); 176 | listener.finishGame(client); 177 | } 178 | 179 | public void setPlaying(boolean playing) { 180 | this.playing = playing; 181 | } 182 | 183 | public void setPlayerPos(BlockPos pos) { 184 | double distance = playerPos.distance(randomPos); 185 | this.playerPos = pos; 186 | distanceDelta = distance - playerPos.distance(randomPos); 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/mcpews/listeners/ServerGUI.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | -------------------------------------------------------------------------------- /src/mcpews/listeners/TextToBlockListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.listeners; 7 | 8 | import java.awt.Color; 9 | import java.awt.Font; 10 | import java.awt.FontMetrics; 11 | import java.awt.Graphics; 12 | import java.awt.image.BufferedImage; 13 | import java.util.Arrays; 14 | import mcpews.MCClient; 15 | import mcpews.MCListener; 16 | import mcpews.MCSocketServer; 17 | import mcpews.command.SayCommand; 18 | import mcpews.command.SetBlockCommand; 19 | import mcpews.event.EventType; 20 | import mcpews.event.PlayerMessageEvent; 21 | import mcpews.logger.LogLevel; 22 | import mcpews.mcenum.BlockPos; 23 | import mcpews.mcenum.BlockType; 24 | import mcpews.message.MCCommand; 25 | import mcpews.message.MCEvent; 26 | import mcpews.message.MCMessage; 27 | import mcpews.message.MCResponse; 28 | import mcpews.response.ListDetailResponse; 29 | import mcpews.response.ListResponse; 30 | import mcpews.response.SayResponse; 31 | 32 | /** 33 | * 34 | * @author Jocopa3 35 | */ 36 | public class TextToBlockListener implements MCListener { 37 | 38 | private MCSocketServer server; 39 | 40 | /* 41 | * This listener requires a reference to the server in-order to get all 42 | * conncted clients. 43 | */ 44 | public TextToBlockListener(MCSocketServer server) { 45 | this.server = server; 46 | } 47 | 48 | /* 49 | * Sends a message using /say to a specific client only. 50 | */ 51 | private void sendMessageToClient(MCClient client, String message) { 52 | if (server == null) { 53 | return; 54 | } 55 | 56 | // Create a new /say command and send it to the client 57 | MCCommand say = new SayCommand(new SayCommand.SayCommandInput(message)); 58 | client.send(this, say); 59 | } 60 | 61 | private BlockType[] blocks = new BlockType[]{BlockType.DIAMOND_BLOCK, BlockType.REDSTONE_BLOCK, BlockType.EMERALD_BLOCK, BlockType.IRON_BLOCK, BlockType.GOLD_BLOCK, BlockType.LAPIS_BLOCK}; 62 | 63 | /* 64 | * Sends a message using /say to a specific client only. 65 | */ 66 | private void setBlock(MCClient client, BlockType block, int x, int y, int z) { 67 | y += 4; 68 | 69 | // Create a new /say command and send it to the client 70 | MCCommand say = new SetBlockCommand(new SetBlockCommand.SetBlockInput(new BlockPos(x, y, z), block)); 71 | client.send(this, say); 72 | } 73 | 74 | /* 75 | * This method is called anytime a new client connects to the server 76 | */ 77 | @Override 78 | public void onConnected(MCClient client) { 79 | // Subscribe to player message events to recieve messages from the client 80 | client.subscribeToEvent(EventType.PLAYER_MESSAGE); 81 | } 82 | 83 | /* 84 | * This method is called >after< a client disconnects from the server. 85 | */ 86 | @Override 87 | public void onDisconnected(MCClient client) { 88 | } 89 | 90 | private String fontName = "Sans Serif"; 91 | private Integer fontSize = 12; 92 | private int fontType = Font.PLAIN; 93 | private BlockType block = BlockType.STONE; 94 | 95 | private void drawText(MCClient client, String message) { 96 | Font font = new Font(fontName, fontType, fontSize); 97 | BufferedImage f = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_BINARY); 98 | Graphics g = f.getGraphics(); 99 | FontMetrics metrics = g.getFontMetrics(font); 100 | 101 | BufferedImage img = new BufferedImage((int) (metrics.stringWidth(message) * 1.2), metrics.getHeight() + 8, BufferedImage.TYPE_INT_ARGB); 102 | g = img.createGraphics(); 103 | g.setColor(Color.WHITE); 104 | g.fillRect(0, 0, img.getWidth(), img.getHeight()); 105 | g.setColor(Color.BLACK); 106 | g.setFont(font); 107 | g.drawString(message, fontSize / 16, fontSize / 2 + fontSize / 4); 108 | 109 | // Reverted to old setblock algorithm. New algorithm was slower. 110 | // Todo: implement a better algorithm 111 | 112 | int cycle = 1; 113 | int y = 0; 114 | for (int x = 0; y < img.getHeight();) { 115 | int rgb = img.getRGB(x, y); 116 | if ((rgb & 1) == 0) { 117 | setBlock(client, block, x, img.getHeight() - y, 0); 118 | cycle++; 119 | } 120 | x++; 121 | System.out.print((rgb & 1) == 0 ? "\u2593" : "\u2591"); 122 | 123 | if (x == img.getWidth() - 1) { 124 | x = 0; 125 | y++; 126 | System.out.println(); 127 | } 128 | } 129 | } 130 | 131 | /* 132 | * This method is called whenever the server recieves an Event message. 133 | * The eventMessage parameter will contain an MCEvent as the body. 134 | */ 135 | @Override 136 | public void onEvent(MCClient client, MCMessage eventMessage) { 137 | MCEvent event = (MCEvent) eventMessage.getBody(); 138 | 139 | switch (event.getEventType()) { 140 | case PLAYER_MESSAGE: 141 | if (event instanceof PlayerMessageEvent) { 142 | PlayerMessageEvent pme = (PlayerMessageEvent) event; 143 | 144 | // Ignore the event if the sender is named External 145 | if (!pme.getSender().equals("External")) { 146 | String m = pme.getMessage(); 147 | if (m.toLowerCase().startsWith("setfont:")) { 148 | fontName = m.replace("setfont:", "").trim(); 149 | 150 | if (Font.decode(fontName) != null) { 151 | sendMessageToClient(client, "Set font to: " + fontName); 152 | } else { 153 | sendMessageToClient(client, "Invalid font name"); 154 | } 155 | } 156 | if (m.toLowerCase().startsWith("setsize:")) { 157 | try { 158 | fontSize = Integer.parseInt(m.replace("setsize:", "").trim()); 159 | sendMessageToClient(client, "Set font size to: " + fontSize); 160 | } catch (Exception e) { 161 | sendMessageToClient(client, "Invalid font size"); 162 | } 163 | } 164 | if (m.toLowerCase().startsWith("setblock:")) { 165 | try { 166 | String[] b = m.replace("setblock:", "").trim().split(" "); 167 | System.out.println(Arrays.toString(b)); 168 | if (b.length == 1) { 169 | block = BlockType.fromString(b[0].trim()); 170 | } else if (b.length == 2) { 171 | block = BlockType.fromString(b[0].trim(), Integer.parseInt(b[1].trim())); 172 | } 173 | sendMessageToClient(client, "Set block to: " + block); 174 | } catch (Exception e) { 175 | sendMessageToClient(client, "Invalid block"); 176 | } 177 | } 178 | if (m.toLowerCase().startsWith("drawtext:")) { 179 | String text = m.replace("drawtext:", "").trim(); 180 | try { 181 | drawText(client, text); 182 | } catch (Exception e) { 183 | sendMessageToClient(client, "Couldn't draw text"); 184 | } 185 | } 186 | } 187 | } 188 | break; 189 | } 190 | } 191 | 192 | /* 193 | * This method is called whenever the server recieves a command response. 194 | * 195 | * The responseMessage parameter will contain an MCResponse as the body. 196 | * The requestMessage parameter is the original MCCommand request that 197 | * triggered the response. 198 | */ 199 | @Override 200 | public void onResponse(MCClient client, MCMessage responseMessage, MCMessage requestMessage) { 201 | MCResponse response = (MCResponse) responseMessage.getBody(); 202 | 203 | switch (response.getResponseType()) { 204 | } 205 | } 206 | 207 | /* 208 | * This method is called whenever the server recieves an error from a client. 209 | * 210 | * The errorMessage parameter will contain an MCError as the body. 211 | * The requestMessage parameter is the original MCCommand request that 212 | * triggered the error. 213 | */ 214 | @Override 215 | public void onError(MCClient client, MCMessage errorMessage, MCMessage requestMessage) { 216 | //server.getLog().log(LogLevel.WARNING, errorMessage.toString()); 217 | System.out.println(errorMessage); 218 | } 219 | } 220 | 221 | class CoordinatePair { 222 | 223 | int x, y; 224 | 225 | public CoordinatePair(int x, int y) { 226 | this.x = x; 227 | this.y = y; 228 | } 229 | 230 | @Override 231 | public int hashCode() { 232 | int A = (int) (x >= 0 ? 2 * x : -2 * x - 1); 233 | int B = (int) (y >= 0 ? 2 * y : -2 * y - 1); 234 | int C = (int) ((A >= B ? A * A + A + B : A + B * B) / 2); 235 | return x < 0 && y < 0 || x >= 0 && y >= 0 ? C : -C - 1; 236 | } 237 | 238 | @Override 239 | public boolean equals(Object obj) { 240 | if (obj == null) { 241 | return false; 242 | } 243 | if (getClass() != obj.getClass()) { 244 | return false; 245 | } 246 | final CoordinatePair other = (CoordinatePair) obj; 247 | if (this.x != other.x) { 248 | return false; 249 | } 250 | if (this.y != other.y) { 251 | return false; 252 | } 253 | return true; 254 | } 255 | 256 | public int getX() { 257 | return x; 258 | } 259 | 260 | public int getY() { 261 | return y; 262 | } 263 | 264 | public long getXY() { 265 | return x << 31 | y; 266 | } 267 | } 268 | 269 | class AABB { 270 | CoordinatePair A; 271 | CoordinatePair B; 272 | 273 | public AABB(CoordinatePair A, CoordinatePair B) { 274 | this.A = A; 275 | this.B = B; 276 | } 277 | 278 | public CoordinatePair getLower() { 279 | return A; 280 | } 281 | 282 | public CoordinatePair getUpper() { 283 | return B; 284 | } 285 | 286 | public boolean contains(CoordinatePair C) { 287 | return C.x >= A.x && C.x <= B.x && C.y >= A.y && C.y <= B.y; 288 | } 289 | } -------------------------------------------------------------------------------- /src/mcpews/logger/LogLevel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.logger; 7 | 8 | import java.util.logging.Level; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class LogLevel extends Level { 15 | 16 | public static final LogLevel CHAT = new LogLevel("CHAT", Level.INFO.intValue() + 5); 17 | public static final LogLevel DEBUG = new LogLevel("DEBUG", Level.INFO.intValue() + 1); 18 | public static final LogLevel DINFO = new LogLevel("DINFO", Level.INFO.intValue() + 2); 19 | public static final LogLevel DWARNING = new LogLevel("DWARNING", Level.INFO.intValue() + 3); 20 | public static final LogLevel DSEVERE = new LogLevel("DSEVERE", Level.INFO.intValue() + 4); 21 | 22 | public LogLevel(String name, int level) { 23 | super(name, level); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/mcpews/mcenum/BlockPos.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.mcenum; 7 | 8 | /** 9 | * 10 | * @author Jocopa3 11 | */ 12 | public class BlockPos { 13 | 14 | Object x, y, z; 15 | transient double xPos, yPos, zPos; 16 | 17 | public BlockPos(String x, String y, String z) { 18 | if (x.equals("~")) { 19 | this.x = "~"; 20 | } else { 21 | this.x = Integer.parseInt(x); 22 | } 23 | //xPos = Double.parseDouble(x.replace("~", "")); 24 | if (y.equals("~")) { 25 | this.y = "~"; 26 | } else { 27 | this.y = Integer.parseInt(y); 28 | } 29 | //yPos = Double.parseDouble(y.replace("~", "")); 30 | if (z.equals("~")) { 31 | this.z = "~"; 32 | } else { 33 | this.z = Integer.parseInt(z); 34 | } 35 | //zPos = Double.parseDouble(z.replace("~", "")); 36 | } 37 | 38 | public BlockPos(double x, double y, double z) { 39 | xPos = x; 40 | this.x = (int) Math.floor(x); 41 | yPos = y; 42 | this.y = (int) Math.floor(y); 43 | zPos = z; 44 | this.z = (int) Math.floor(z); 45 | } 46 | 47 | public double getX() { 48 | return xPos; 49 | } 50 | 51 | public double getY() { 52 | return yPos; 53 | } 54 | 55 | public double getZ() { 56 | return zPos; 57 | } 58 | 59 | public BlockPos delta(BlockPos position) { 60 | return new BlockPos(xPos - position.xPos, yPos - position.yPos, zPos - position.zPos); 61 | } 62 | 63 | public BlockPos sub(BlockPos position) { 64 | return new BlockPos(xPos - position.xPos, yPos - position.yPos, zPos - position.zPos); 65 | } 66 | 67 | public BlockPos add(BlockPos position) { 68 | return new BlockPos(xPos + position.xPos, yPos + position.yPos, zPos + position.zPos); 69 | } 70 | 71 | public double distance(BlockPos pos) { 72 | return Math.sqrt(Math.pow(xPos - pos.xPos, 2.0) + Math.pow(yPos - pos.yPos, 2.0) + Math.pow(zPos - pos.zPos, 2.0)); 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return "X: " + xPos + ", Y: " + yPos + ", Z: " + zPos; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/mcpews/mcenum/CommandTarget.java: -------------------------------------------------------------------------------- 1 | package mcpews.mcenum; 2 | 3 | import com.google.gson.JsonElement; 4 | import com.google.gson.JsonObject; 5 | import com.google.gson.JsonParser; 6 | import java.util.ArrayList; 7 | import java.util.HashMap; 8 | import java.util.Map.Entry; 9 | import java.util.regex.Pattern; 10 | 11 | /** 12 | * 13 | * @author Jocopa3 14 | */ 15 | public class CommandTarget { 16 | 17 | public enum TargetSelector { 18 | 19 | ALL_ENTITIES("allEntities", 'e'), 20 | ALL_PLAYERS("allPlayers", 'a'), 21 | NEAREST_PLAYER("nearestPlayer", 'p'), 22 | RANDOM_PLAYER("randomPlayer", 'r'); 23 | 24 | private static HashMap fromCode; 25 | 26 | static { 27 | fromCode = new HashMap<>(); 28 | for (TargetSelector selector : values()) { 29 | fromCode.put(selector.selectorCode, selector.type); 30 | } 31 | } 32 | 33 | private String type; 34 | private char selectorCode; 35 | 36 | TargetSelector(String type, char code) { 37 | this.type = type; 38 | selectorCode = code; 39 | } 40 | 41 | public String getTypeString() { 42 | return type; 43 | } 44 | 45 | public char getTypeCode() { 46 | return selectorCode; 47 | } 48 | 49 | public static String fromCode(char code) { 50 | return fromCode.get(code); 51 | } 52 | 53 | public static String fromCode(String s) { 54 | if (s.startsWith("@")) { 55 | return fromCode(s.charAt(1)); 56 | } 57 | 58 | return null; 59 | } 60 | } 61 | 62 | public enum RuleType { 63 | 64 | name("Name"), // Entity/Player name 65 | type("Type"), // Entity type 66 | r("Max Radius"), // Max Radius 67 | rm("Min Radius"), // Min Radius 68 | m("Game Mode"), // Gamemode 69 | x("X-Pos"), // X-pos 70 | y("Y-Pos"), // Y-pos 71 | z("Z-Pos"); // Z-pos 72 | 73 | private transient String description; 74 | 75 | private static HashMap fromString; 76 | 77 | static { 78 | fromString = new HashMap<>(); 79 | for (RuleType rule : values()) { 80 | fromString.put(rule.name(), rule); 81 | } 82 | } 83 | 84 | RuleType(String desc) { 85 | description = desc; 86 | } 87 | 88 | public static RuleType fromString(String type) { 89 | return fromString.get(type); 90 | } 91 | } 92 | 93 | public class TargetRule { 94 | 95 | private boolean inverted; 96 | private String name; 97 | private String value; 98 | 99 | public TargetRule(String name, String value) { 100 | this.name = name; 101 | this.value = value; 102 | } 103 | 104 | public TargetRule(String name, String value, boolean inverted) { 105 | this.name = name; 106 | this.value = value; 107 | this.inverted = inverted; 108 | } 109 | 110 | public RuleType getRule() { 111 | return RuleType.fromString(name); 112 | } 113 | 114 | @Override 115 | public String toString() { 116 | RuleType rule = getRule(); 117 | String val = rule.description + (inverted ? " != " : " = "); 118 | 119 | switch (rule) { 120 | case m: 121 | switch (value) { 122 | case "0": 123 | case "s": 124 | val += "Survival"; 125 | break; 126 | case "1": 127 | case "c": 128 | val += "Creative"; 129 | break; 130 | case "2": 131 | case "a": 132 | val += "Adventure"; 133 | break; 134 | default: 135 | val += "Invalid"; 136 | break; 137 | } 138 | break; 139 | default: 140 | val += value; 141 | } 142 | 143 | return val; 144 | } 145 | } 146 | 147 | private String selector; 148 | private ArrayList rules; 149 | 150 | private static final JsonParser parser = new JsonParser(); 151 | private static final Pattern outerQuotes = Pattern.compile("(((?<=[\\[,])\\s*)|(?<=[a-zA-Z0-9_])\\s*(?=[,\\]]))"); 152 | private static final Pattern innerQuotes = Pattern.compile("\\s*=\\s*"); 153 | 154 | public CommandTarget(String targetString) { 155 | 156 | selector = TargetSelector.fromCode(targetString); 157 | 158 | if (selector == null) { 159 | selector = TargetSelector.ALL_PLAYERS.getTypeString(); 160 | addRule(RuleType.name, targetString); 161 | } else { 162 | String targetSpecifiers = targetString.replaceFirst("@[aeprAEPR]", ""); 163 | 164 | if (!targetSpecifiers.isEmpty()) { 165 | targetSpecifiers = innerQuotes.matcher(outerQuotes.matcher(targetSpecifiers).replaceAll("\"")) 166 | .replaceAll("\":\"") 167 | .replace("[", "{") 168 | .replace("]", "}"); 169 | 170 | try { 171 | JsonObject ele = parser.parse(targetSpecifiers).getAsJsonObject(); 172 | 173 | for (Entry entry : ele.entrySet()) { 174 | String value = entry.getValue().getAsString(); 175 | if (value.startsWith("!")) { 176 | addRule(entry.getKey(), value.substring(value.indexOf('!') + 1), true); 177 | } else { 178 | addRule(entry.getKey(), value); 179 | } 180 | } 181 | } catch (Exception e) { 182 | rules = null; 183 | } 184 | } else { 185 | rules = null; 186 | } 187 | } 188 | } 189 | 190 | public CommandTarget(TargetSelector selector, TargetRule... rules) { 191 | this.selector = selector.getTypeString(); 192 | 193 | for (TargetRule rule : rules) { 194 | addRule(rule); 195 | } 196 | } 197 | 198 | public void addRule(TargetRule rule) { 199 | if (rules == null) { 200 | rules = new ArrayList<>(); 201 | } 202 | 203 | rules.add(rule); 204 | } 205 | 206 | public void addRule(String name, String value) { 207 | addRule(new TargetRule(name, value)); 208 | } 209 | 210 | public void addRule(String name, String value, boolean inverted) { 211 | addRule(new TargetRule(name, value, inverted)); 212 | } 213 | 214 | public void addRule(RuleType type, String value) { 215 | addRule(new TargetRule(type.name(), value)); 216 | } 217 | 218 | public void addRule(RuleType type, String value, boolean inverted) { 219 | addRule(new TargetRule(type.name(), value, inverted)); 220 | } 221 | 222 | public String getSelector() { 223 | return selector; 224 | } 225 | 226 | public TargetRule[] getRules() { 227 | return rules.toArray(new TargetRule[0]); 228 | } 229 | 230 | public String toString() { 231 | StringBuilder b = new StringBuilder(); 232 | b.append("Selector: ").append(selector).append("; Rules: "); 233 | int i; 234 | for (i = 0; i < rules.size() - 1; i++) { 235 | b.append(rules.get(0).toString()).append(", "); 236 | } 237 | 238 | b.append(rules.get(i).toString()); 239 | 240 | return b.toString(); 241 | } 242 | 243 | public static void main(String[] args) { 244 | String target1 = "@e[type=!sheep,r=10]"; 245 | String target2 = "@p[m=s]"; 246 | 247 | CommandTarget tar1 = new CommandTarget(target1); 248 | CommandTarget tar2 = new CommandTarget(target2); 249 | 250 | System.out.println("Target 1:\n" + tar1); 251 | System.out.println("Target 2:\n" + tar2); 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /src/mcpews/mcenum/DimensionType.java: -------------------------------------------------------------------------------- 1 | package mcpews.mcenum; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 7 | * @author Jocopa3 8 | */ 9 | public enum DimensionType { 10 | OVERWORLD("overworld", 0), 11 | NETHER("nether", 1), 12 | END("end", 2); 13 | 14 | private String name; 15 | private int id; 16 | 17 | private static HashMap fromString; 18 | 19 | static { 20 | fromString = new HashMap<>(); 21 | for (DimensionType dimension : values()) { 22 | fromString.put(dimension.getName(), dimension); 23 | } 24 | } 25 | 26 | DimensionType(String name, int id) { 27 | this.name = name; 28 | this.id = id; 29 | } 30 | 31 | public String getName() { 32 | return name; 33 | } 34 | 35 | public int getId() { 36 | return id; 37 | } 38 | 39 | public static DimensionType fromString(String name) { 40 | return fromString.get(name); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/mcpews/mcenum/EnchantType.java: -------------------------------------------------------------------------------- 1 | package mcpews.mcenum; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 7 | * @author Jocopa3 8 | */ 9 | public enum EnchantType { 10 | PROTECTION("protection", 0), 11 | FIRE_PROTECTION("fire_protection", 1), 12 | FEATHER_FALLING("feather_falling", 2), 13 | BLAST_PROTECTION("blast_protection", 3), 14 | PROJECTILE_PROTECTION("projectile_protection", 4), 15 | THORNS("thorns", 5), 16 | RESPIRATION("respiration", 6), 17 | DEPTH_STRIDER("depth_strider", 7), 18 | AQUA_AFFINITY("aqua_affinity", 8), 19 | SHARPNESS("sharpness", 9), 20 | SMITE("smite", 10), 21 | BANE_OF_ARTHROPODS("bane_of_arthropods", 11), 22 | KNOCKBACK("knockback", 12), 23 | FIRE_ASPECT("fire_aspect", 13), 24 | LOOTING("looting", 14), 25 | EFFICIENCY("efficiency", 15), 26 | SILK_TOUCH("silk_touch", 16), 27 | DURABILITY("durability", 17), 28 | FORTUNE("fortune", 18), 29 | POWER("power", 19), 30 | PUNCH("punch", 20), 31 | FLAME("flame", 21), 32 | INFINITY("infinity", 22), 33 | LUCK_OF_THE_SEA("luck_of_the_sea", 23), 34 | LURE("lure", 24); 35 | 36 | private String name; 37 | private int id; 38 | 39 | private static HashMap fromString; 40 | 41 | static { 42 | fromString = new HashMap<>(); 43 | for (EnchantType enchant : values()) { 44 | fromString.put(enchant.getName(), enchant); 45 | } 46 | } 47 | 48 | EnchantType(String name, int id) { 49 | this.name = name; 50 | this.id = id; 51 | } 52 | 53 | public String getName() { 54 | return name; 55 | } 56 | 57 | public int getId() { 58 | return id; 59 | } 60 | 61 | public static EnchantType fromString(String name) { 62 | return fromString.get(name); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/mcpews/mcenum/EntityType.java: -------------------------------------------------------------------------------- 1 | package mcpews.mcenum; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 7 | * @author Jocopa3 8 | */ 9 | public enum EntityType { 10 | // 1.0.4.0 11 | CHICKEN("chicken", 0x130A), 12 | COW("cow", 0x130B), 13 | PIG("pig", 0x130C), 14 | SHEEP("sheep", 0x130D), 15 | WOLF("wolf", 0x530E), 16 | VILLAGER("villager", 0x30F), 17 | MUSHROOMCOW("mushroomcow", 0x1310), 18 | SQUID("squid", 0x2311), 19 | RABBIT("rabbit", 0x1312), 20 | BAT("bat", 0x8113), 21 | IRONGOLEM("irongolem", 0x314), 22 | SNOWGOLEM("snowgolem", 0x315), 23 | OCELOT("ocelot", 0x5316), 24 | HORSE("horse", 0x5317), 25 | DONKEY("donkey", 0x5318), 26 | MULE("mule", 0x5319), 27 | SKELETONHORSE("skeletonhorse", 0x5B1A), 28 | ZOMBIEHORSE("zombiehorse", 0x5B1B), 29 | POLARBEAR("polarbear", 0x131C), 30 | ZOMBIE("zombie", 0xB20), 31 | CREEPER("creeper", 0xB21), 32 | SKELETON("skeleton", 0xB22), 33 | SPIDER("spider", 0xB23), 34 | PIG_ZOMBIE("pig_zombie", 0xB24), 35 | SLIME("slime", 0xB25), 36 | ENDERMAN("enderman", 0xB26), 37 | SILVERFISH("silverfish", 0xB27), 38 | CAVESPIDER("cavespider", 0xB28), 39 | GHAST("ghast", 0xB29), 40 | MAGMACUBE("magmacube", 0xB2A), 41 | BLAZE("blaze", 0xB2B), 42 | ZOMBIE_VILLAGER("zombie_villager", 0xB2C), 43 | WITCH("witch", 0xB2D), 44 | STRAY("skeleton.stray", 0xB2E), 45 | HUSK("husk", 0xB2F), 46 | WITHER_SKELETON("skeleton.wither", 0xB30), 47 | GUARDIAN("guardian", 0xB31), 48 | ELDER_GUARDIAN("guardian.elder", 0xB32), 49 | WITHER_BOSS("wither.boss", 0xB34), 50 | DRAGON("dragon", 0xB35), 51 | SHULKER("shulker", 0xB36), 52 | ENDERMITE("endermite", 0xB37), 53 | PLAYER("player", 0x13F), 54 | ITEM("item", 64), 55 | TNT("tnt", 65), 56 | FALLING_BLOCK("falling_block", 66), 57 | EXPERIENCE_POTION("potion.experience", 68), 58 | XPORB("xporb", 69), 59 | EYEOF("eyeofEnder", 70), 60 | ENDERCRYSTAL("endercrystal", 71), 61 | SHULKER_BULLET("shulker_bullet", 76), 62 | FISHINGHOOK("fishinghook", 77), 63 | FIREBALL_DRAGON("fireball.dragon", 79), 64 | ARROW_SKELETON("arrow.skeleton", 80), 65 | SNOWBALL("snowball", 81), 66 | THROWNEGG("thrownegg", 82), 67 | PAINTING("painting", 83), 68 | MINECART("minecart", 84), 69 | FIREBALL_LARGE("fireball.large", 85), 70 | THROWNPOTION("thrownpotion", 86), 71 | THROWNENDERPEARL("thrownenderpearl", 87), 72 | LEASHKNOT("leashknot", 88), 73 | WITHER_SKULL("wither.skull", 89), 74 | BOAT("boat", 90), 75 | LIGHTNINGBOLT("lightningbolt", 93), 76 | FIREBALL_SMALL("fireball.small", 94), 77 | AREAEFFECTCLOUD("areaeffectcloud", 95), 78 | MINECARTHOPPER("minecarthopper", 96), 79 | MINECARTTNT("minecarttnt", 97), 80 | MINECARTCHEST("minecartchest", 98), 81 | LINGERINGPOTION("lingeringpotion", 101), 82 | UNKNOWN("unknown", -1); 83 | 84 | private String name; 85 | private int id; 86 | 87 | private static HashMap fromString; 88 | static { 89 | fromString = new HashMap<>(); 90 | for(EntityType entity : values()) { 91 | fromString.put(entity.getName(), entity); 92 | } 93 | } 94 | 95 | EntityType(String name, int id) { 96 | this.name = name; 97 | this.id = id; 98 | } 99 | 100 | public int getId() { 101 | return id & 0xFF; 102 | } 103 | 104 | public int getFullId() { 105 | return id; 106 | } 107 | 108 | public String getName() { 109 | return name; 110 | } 111 | 112 | public static EntityType fromString(String name) { 113 | return fromString.get(name); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /src/mcpews/mcenum/FeatureType.java: -------------------------------------------------------------------------------- 1 | package mcpews.mcenum; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 7 | * @author Jocopa3 8 | */ 9 | public enum FeatureType { 10 | ENDCITY("endcity", 0), 11 | FORTRESS("fortress", 1), 12 | MINESHAFT("mineshaft", 2), 13 | MONUMENT("monument", 3), 14 | STRONGHOLD("stronghold", 4), 15 | TEMPLE("temple", 5), 16 | VILLAGE("village", 6); 17 | 18 | private String name; 19 | private int id; 20 | 21 | private static HashMap fromString; 22 | 23 | static { 24 | fromString = new HashMap<>(); 25 | 26 | for (FeatureType feature : values()) { 27 | fromString.put(feature.getName(), feature); 28 | } 29 | } 30 | 31 | FeatureType(String name, int id) { 32 | this.name = name; 33 | this.id = id; 34 | } 35 | 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | public int getId() { 41 | return id; 42 | } 43 | 44 | public static FeatureType fromString(String name) { 45 | return fromString.get(name); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/mcpews/mcenum/GameModeType.java: -------------------------------------------------------------------------------- 1 | 2 | package mcpews.mcenum; 3 | 4 | import java.util.HashMap; 5 | 6 | /** 7 | * 8 | * @author Jocopa3 9 | */ 10 | public enum GameModeType { 11 | ALL("a", -1), 12 | SURVIVAL("s", 0), 13 | CREATIVE("c", 1); 14 | 15 | private String name; 16 | private int id; 17 | 18 | private static HashMap fromString; 19 | 20 | static { 21 | fromString = new HashMap<>(); 22 | 23 | for (GameModeType feature : values()) { 24 | fromString.put(feature.getName(), feature); 25 | } 26 | } 27 | 28 | GameModeType(String name, int id) { 29 | this.name = name; 30 | this.id = id; 31 | } 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | public int getId() { 38 | return id; 39 | } 40 | 41 | public static GameModeType fromString(String name) { 42 | return fromString.get(name); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/mcpews/mcenum/GameRuleType.java: -------------------------------------------------------------------------------- 1 | package mcpews.mcenum; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 7 | * @author Jocopa3 8 | */ 9 | public enum GameRuleType { 10 | FALL_DAMAGE("falldamage"), 11 | PVP("pvp"), 12 | DROWNING_DAMAGE("drowningdamage"), 13 | FIRE_DAMAGE("firedamage"), 14 | IMMUTABLE_WORLD("immutableworld"); 15 | 16 | private String name; 17 | 18 | private static HashMap fromString; 19 | 20 | static { 21 | fromString = new HashMap<>(); 22 | for (GameRuleType gameRule : values()) { 23 | fromString.put(gameRule.getName(), gameRule); 24 | } 25 | } 26 | 27 | GameRuleType(String name) { 28 | this.name = name; 29 | } 30 | 31 | public String getName() { 32 | return name; 33 | } 34 | 35 | public static GameRuleType fromString(String name) { 36 | return fromString.get(name); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/mcpews/message/EventSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import com.google.gson.JsonDeserializationContext; 9 | import com.google.gson.JsonDeserializer; 10 | import mcpews.message.*; 11 | import com.google.gson.JsonElement; 12 | import com.google.gson.JsonObject; 13 | import com.google.gson.JsonParseException; 14 | import com.google.gson.JsonSerializationContext; 15 | import com.google.gson.JsonSerializer; 16 | import java.lang.reflect.Constructor; 17 | import java.lang.reflect.Type; 18 | import mcpews.event.EventMeasurements; 19 | import mcpews.event.EventProperties; 20 | import mcpews.event.EventType; 21 | import mcpews.message.MCMessage; 22 | 23 | /** 24 | * 25 | * @author Jocopa3 26 | */ 27 | public class EventSerializer implements JsonSerializer, JsonDeserializer { 28 | 29 | @Override 30 | public JsonElement serialize(MCEvent event, Type type, JsonSerializationContext jsc) { 31 | if(event == null) { 32 | return null; 33 | } 34 | 35 | JsonObject messageObj = new JsonObject(); 36 | 37 | // Get the class representing the body object from the purpose enum 38 | Class measurementsClassType = event.getEventType().getMeasurementsClassType(); 39 | Class propertiesClassType = event.getEventType().getPropertiesClassType(); 40 | 41 | messageObj.add("properties", jsc.serialize(event.getProperties(), propertiesClassType)); 42 | messageObj.add("measurements", jsc.serialize(event.getMeasurements(), measurementsClassType)); 43 | messageObj.add("eventName", jsc.serialize(event.getEventType().getName())); 44 | 45 | return messageObj; 46 | } 47 | 48 | @Override 49 | public MCEvent deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException { 50 | EventType eventType = EventType.fromString(je.getAsJsonObject().get("eventName").getAsString()); 51 | 52 | EventProperties properties = jdc.deserialize(je.getAsJsonObject().get("properties"), eventType.getPropertiesClassType()); 53 | EventMeasurements measurements = jdc.deserialize(je.getAsJsonObject().get("measurements"), eventType.getMeasurementsClassType()); 54 | 55 | Constructor ctor; 56 | MCEvent event; 57 | try { 58 | ctor = eventType.getEventClassType().getConstructor(EventType.class, EventProperties.class, EventMeasurements.class); 59 | event = (MCEvent)eventType.getEventClassType().cast(ctor.newInstance(new Object[] { eventType, properties, measurements })); 60 | } catch (Exception ex) { 61 | //ex.printStackTrace(); 62 | event = new MCEvent(eventType, properties, measurements); 63 | } 64 | 65 | return event; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/mcpews/message/MCBody.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | /** 9 | * 10 | * @author Jocopa3 11 | */ 12 | public abstract class MCBody { 13 | 14 | private transient MCMessage parentMessage; 15 | private transient MessagePurposeType purpose; 16 | 17 | public MCBody(MessagePurposeType purpose) { 18 | this.purpose = purpose; 19 | parentMessage = new MCMessage(this); 20 | } 21 | 22 | protected MessagePurposeType getPurpose() { 23 | return purpose; 24 | } 25 | 26 | public MCMessage getAsMessage() { 27 | return parentMessage; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/mcpews/message/MCCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import mcpews.command.*; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class MCCommand extends MCBody { 15 | 16 | CommandInput input; 17 | CommandOrigin origin; 18 | String name; 19 | int version; 20 | String overload; 21 | 22 | public MCCommand(CommandInput input, CommandOrigin origin, String name, int version) { 23 | super(MessagePurposeType.COMMAND_REQUEST); 24 | 25 | this.input = input; 26 | this.origin = origin; 27 | this.name = name; 28 | this.version = version; 29 | this.overload = input.getOverload(); 30 | } 31 | 32 | protected MCCommand() { 33 | super(MessagePurposeType.COMMAND_REQUEST); 34 | } 35 | 36 | protected void setInput(CommandInput input) { 37 | this.input = input; 38 | this.overload = input.getOverload(); 39 | } 40 | 41 | protected void setOrigin(CommandOrigin origin) { 42 | this.origin = origin; 43 | } 44 | 45 | public String getName() { 46 | return name; 47 | } 48 | 49 | protected void setName(String name) { 50 | this.name = name; 51 | } 52 | 53 | protected void setVersion(int version) { 54 | this.version = version; 55 | } 56 | 57 | public String getOverload() { 58 | return overload; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/mcpews/message/MCError.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | /** 9 | * 10 | * @author Jocopa3 11 | */ 12 | public class MCError extends MCBody { 13 | 14 | String statusMessage; 15 | int statusCode; 16 | 17 | protected MCError() { 18 | super(MessagePurposeType.ERROR); 19 | } 20 | 21 | public String getStatusMessage() { 22 | return statusMessage; 23 | } 24 | 25 | public int getStatusCode() { 26 | return statusCode; 27 | } 28 | 29 | public String toString() { 30 | return "Error (" + statusCode + "): " + statusMessage; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/mcpews/message/MCEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import mcpews.event.*; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class MCEvent extends MCBody { 15 | 16 | private final String eventName; 17 | protected EventProperties properties; 18 | protected EventMeasurements measurements; 19 | 20 | protected MCEvent(EventType type, EventProperties properties, EventMeasurements measurements) { 21 | super(MessagePurposeType.EVENT); 22 | 23 | eventName = type.getName(); 24 | this.properties = properties; 25 | this.measurements = measurements; 26 | } 27 | 28 | public EventType getEventType() { 29 | return EventType.fromString(eventName); 30 | } 31 | 32 | public EventProperties getProperties() { 33 | return properties; 34 | } 35 | 36 | public EventMeasurements getMeasurements() { 37 | return measurements; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return ""; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/mcpews/message/MCHeader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import java.util.UUID; 9 | import mcpews.message.MessagePurposeType; 10 | 11 | /** 12 | * 13 | * @author Jocopa3 14 | */ 15 | public class MCHeader { 16 | protected int version; 17 | protected String requestId; 18 | protected String messagePurpose; 19 | protected String messageType; 20 | 21 | public MCHeader(int version, UUID requestId, MessagePurposeType purpose) { 22 | this.version = version; 23 | this.requestId = requestId.toString(); 24 | messagePurpose = purpose.getPurposeName(); 25 | } 26 | 27 | public MCHeader(int version, UUID requestId, MessagePurposeType purpose, MessagePurposeType type) { 28 | this(version, requestId, purpose); 29 | messageType = type.getPurposeName(); 30 | } 31 | 32 | public UUID getRequestId() { 33 | return UUID.fromString(requestId); 34 | } 35 | 36 | public MessagePurposeType getPurpose() { 37 | return MessagePurposeType.fromString(messagePurpose); 38 | } 39 | 40 | public MessagePurposeType getType() { 41 | return MessagePurposeType.fromString(messageType); 42 | } 43 | 44 | public int getVersion() { 45 | return version; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/mcpews/message/MCMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import com.google.gson.Gson; 9 | import com.google.gson.GsonBuilder; 10 | import com.google.gson.JsonObject; 11 | import java.util.UUID; 12 | import mcpews.event.*; 13 | 14 | /** 15 | * 16 | * @author Jocopa3 17 | */ 18 | public class MCMessage { 19 | 20 | protected static final Gson gson; 21 | 22 | static { 23 | GsonBuilder gb = new GsonBuilder() 24 | .registerTypeAdapter(MCEvent.class, new EventSerializer()) 25 | .registerTypeAdapter(MCMessage.class, new MessageSerializer()) 26 | .registerTypeAdapter(MCResponse.class, new ResponseSerializer()); 27 | 28 | gson = gb.create(); 29 | } 30 | 31 | private MCBody body; 32 | private MCHeader header; 33 | 34 | protected MCMessage() { 35 | 36 | } 37 | 38 | public MCMessage(MCBody body, MCHeader header) { 39 | this.body = body; 40 | this.header = header; 41 | } 42 | 43 | public MCMessage(MCBody body) { 44 | MessagePurposeType purpose = body.getPurpose(); 45 | switch (purpose) { 46 | case COMMAND_REQUEST: 47 | case SUBSCRIBE: 48 | case UNSUBSCRIBE: 49 | header = new MCHeader(1, UUID.randomUUID(), purpose, MessagePurposeType.COMMAND_REQUEST); 50 | break; 51 | default: 52 | header = new MCHeader(1, new UUID(0, 0), purpose); 53 | } 54 | this.body = body; 55 | } 56 | 57 | public static MCMessage getAsMessage(String messageJSON) { 58 | return gson.fromJson(messageJSON, MCMessage.class); 59 | } 60 | 61 | public static MCMessage getAsMessage(JsonObject JSON) { 62 | return gson.fromJson(JSON, MCMessage.class); 63 | } 64 | 65 | public String getMessageText() { 66 | return gson.toJson(this); 67 | } 68 | 69 | public MessagePurposeType getPurpose() { 70 | return header.getPurpose(); 71 | } 72 | 73 | public MessagePurposeType getType() { 74 | if (header.getType() == null) { 75 | return MessagePurposeType.COMMAND_RESPONSE; 76 | } 77 | 78 | return header.getType(); 79 | } 80 | 81 | public MCBody getBody() { 82 | return body; 83 | } 84 | 85 | public MCHeader getHeader() { 86 | return header; 87 | } 88 | 89 | @Override 90 | public String toString() { 91 | return body.toString(); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/mcpews/message/MCResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import mcpews.command.*; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class MCResponse extends MCBody { 15 | 16 | protected int statusCode; 17 | protected String statusMessage; // This may be null 18 | protected transient CommandType type; 19 | 20 | protected MCResponse() { 21 | super(MessagePurposeType.COMMAND_RESPONSE); 22 | } 23 | 24 | protected void setCommandType(CommandType type) { 25 | this.type = type; 26 | } 27 | 28 | public CommandType getResponseType() { 29 | return type; 30 | } 31 | 32 | public int getStatusCode() { 33 | return statusCode; 34 | } 35 | 36 | public String getStatusMessage() { 37 | return statusMessage; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | if(statusMessage != null) { 43 | return statusMessage; 44 | } 45 | 46 | return ""; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/mcpews/message/MCResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | 7 | package mcpews.message; 8 | 9 | /** 10 | * 11 | * @author Jocopa3 12 | */ 13 | public class MCResult { 14 | private int value; 15 | 16 | public boolean isSuccess() { 17 | return value > -1; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/mcpews/message/MCSubscribe.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import mcpews.event.EventType; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class MCSubscribe extends MCBody { 15 | 16 | private String eventName; 17 | 18 | public MCSubscribe(EventType type) { 19 | super(MessagePurposeType.SUBSCRIBE); 20 | 21 | eventName = type.getName(); 22 | } 23 | 24 | public EventType getEventType() { 25 | return EventType.fromString(eventName); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/mcpews/message/MCUnsubscribe.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import mcpews.event.EventType; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class MCUnsubscribe extends MCBody { 15 | 16 | private String eventName; 17 | 18 | public MCUnsubscribe(EventType type) { 19 | super(MessagePurposeType.UNSUBSCRIBE); 20 | 21 | eventName = type.getName(); 22 | } 23 | 24 | public EventType getEventType() { 25 | return EventType.fromString(eventName); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/mcpews/message/MessagePurposeType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import java.util.concurrent.ConcurrentHashMap; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public enum MessagePurposeType { 15 | COMMAND_RESPONSE("commandResponse", MCResponse.class), 16 | COMMAND_REQUEST("commandRequest", MCCommand.class), 17 | ERROR("error", MCError.class), 18 | EVENT("event", MCEvent.class), 19 | SUBSCRIBE("subscribe", MCSubscribe.class), 20 | UNSUBSCRIBE("unsubscribe", MCUnsubscribe.class); 21 | 22 | private final String purpose; 23 | private final Class classi; // With an I 24 | 25 | private static ConcurrentHashMap messagePurposeTypes = new ConcurrentHashMap(); 26 | 27 | static { 28 | for(MessagePurposeType type : values()) { 29 | messagePurposeTypes.put(type.getPurposeName(), type); 30 | } 31 | } 32 | 33 | MessagePurposeType(String purpose, Class classi) { 34 | this.purpose = purpose; 35 | this.classi = classi; 36 | } 37 | 38 | public String getPurposeName() { 39 | return purpose; 40 | } 41 | 42 | public Class getBodyClass() { 43 | return classi; 44 | } 45 | 46 | public static MessagePurposeType fromString(String typeName) { 47 | if(typeName == null) { 48 | return null; 49 | } 50 | 51 | return messagePurposeTypes.get(typeName); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/mcpews/message/MessageSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import com.google.gson.JsonDeserializationContext; 9 | import com.google.gson.JsonDeserializer; 10 | import com.google.gson.JsonElement; 11 | import com.google.gson.JsonObject; 12 | import com.google.gson.JsonParseException; 13 | import com.google.gson.JsonSerializationContext; 14 | import com.google.gson.JsonSerializer; 15 | import java.lang.reflect.Type; 16 | 17 | /** 18 | * 19 | * @author Jocopa3 20 | */ 21 | public class MessageSerializer implements JsonSerializer, JsonDeserializer { 22 | 23 | @Override 24 | public JsonElement serialize(MCMessage message, Type type, JsonSerializationContext jsc) { 25 | if (message == null) { 26 | return null; 27 | } 28 | 29 | JsonObject messageObj = new JsonObject(); 30 | 31 | // Get the class representing the body object from the purpose enum 32 | Class bodyClassType = message.getPurpose().getBodyClass(); 33 | messageObj.add("body", jsc.serialize(message.getBody(), bodyClassType)); 34 | messageObj.add("header", jsc.serialize(message.getHeader(), MCHeader.class)); 35 | 36 | return messageObj; 37 | } 38 | 39 | @Override 40 | public MCMessage deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException { 41 | MCHeader header = jdc.deserialize(je.getAsJsonObject().get("header"), MCHeader.class); 42 | 43 | Class bodyClassType = header.getPurpose().getBodyClass(); 44 | MCBody body = jdc.deserialize(je.getAsJsonObject().get("body"), bodyClassType); 45 | 46 | return new MCMessage(body, header); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/mcpews/message/ResponseSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.message; 7 | 8 | import com.google.gson.JsonDeserializationContext; 9 | import com.google.gson.JsonDeserializer; 10 | import com.google.gson.JsonElement; 11 | import com.google.gson.JsonObject; 12 | import com.google.gson.JsonParseException; 13 | import com.google.gson.JsonSerializationContext; 14 | import com.google.gson.JsonSerializer; 15 | import java.lang.reflect.Constructor; 16 | import java.lang.reflect.Type; 17 | import mcpews.command.CommandType; 18 | import mcpews.event.EventMeasurements; 19 | import mcpews.event.EventProperties; 20 | import mcpews.event.EventType; 21 | import mcpews.message.MCMessage; 22 | 23 | /** 24 | * 25 | * @author Jocopa3 26 | */ 27 | public class ResponseSerializer implements JsonDeserializer { 28 | 29 | public static final String PROPERTY_HINT_COMMAND = "COMMANDNAME"; 30 | public static final String PROPERTY_HINT_OVERLOAD = "OVERLOAD"; 31 | 32 | @Override 33 | public MCResponse deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException { 34 | String responseName = je.getAsJsonObject().remove(PROPERTY_HINT_COMMAND).getAsString(); 35 | String responseOverload = je.getAsJsonObject().remove(PROPERTY_HINT_OVERLOAD).getAsString(); 36 | 37 | CommandType commandType = CommandType.fromString(responseName); 38 | 39 | MCResponse response = jdc.deserialize(je, commandType.getResponseClass()); 40 | response.setCommandType(commandType); 41 | 42 | return response; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/mcpews/message/StatusCodes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | 7 | package mcpews.message; 8 | 9 | /** 10 | * 11 | * @author Jocopa3 12 | */ 13 | public enum StatusCodes { 14 | SUCCESS(0), 15 | PROCESSING_COMMAND(131075), 16 | TOO_MANY_REQUESTS(-2147418109); 17 | 18 | int value; 19 | 20 | StatusCodes(int code) { 21 | value = code; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/mcpews/response/CloseWebSocketResponse.java: -------------------------------------------------------------------------------- 1 | package mcpews.response; 2 | 3 | import mcpews.message.MCResponse; 4 | 5 | /** 6 | * 7 | * @author Jocopa3 8 | */ 9 | public class CloseWebSocketResponse extends MCResponse { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/mcpews/response/EnchantResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.response; 7 | 8 | import com.google.gson.JsonObject; 9 | import mcpews.message.MCResponse; 10 | 11 | /** 12 | * 13 | * @author Jocopa3 14 | */ 15 | public class EnchantResponse extends MCResponse { 16 | 17 | private String result; 18 | 19 | public String result() { 20 | return result; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return statusMessage; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/mcpews/response/FillResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.response; 7 | 8 | import mcpews.mcenum.BlockPos; 9 | import mcpews.mcenum.EntityType; 10 | import mcpews.message.MCResponse; 11 | 12 | /** 13 | * 14 | * @author Jocopa3 15 | */ 16 | public class FillResponse extends MCResponse { 17 | private String blockName; 18 | private int fillCount; 19 | 20 | public String getBlockName() { 21 | return blockName; 22 | } 23 | 24 | public int getFillCount() { 25 | return fillCount; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | return statusMessage == null ? "" : statusMessage; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/mcpews/response/ListDetailResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.response; 7 | 8 | import com.google.gson.JsonObject; 9 | import mcpews.message.MCResponse; 10 | 11 | /** 12 | * 13 | * @author Jocopa3 14 | */ 15 | public class ListDetailResponse extends MCResponse { 16 | 17 | private String details; 18 | private int currentPlayerCount; 19 | private int maxPlayerCount; 20 | private String players; 21 | 22 | public String details() { 23 | return details; 24 | } 25 | 26 | public int currentPlayerCount() { 27 | return currentPlayerCount; 28 | } 29 | 30 | public int maxPlayerCount() { 31 | return maxPlayerCount; 32 | } 33 | 34 | public String players() { 35 | return players; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return statusMessage; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/mcpews/response/ListResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.response; 7 | 8 | import mcpews.message.MCResponse; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class ListResponse extends MCResponse { 15 | 16 | private int currentPlayerCount; 17 | private int maxPlayerCount; 18 | private String players; 19 | 20 | public int currentPlayerCount() { 21 | return currentPlayerCount; 22 | } 23 | 24 | public int maxPlayerCount() { 25 | return maxPlayerCount; 26 | } 27 | 28 | public String players() { 29 | return players; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return statusMessage; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/mcpews/response/SayResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.response; 7 | 8 | import mcpews.message.MCResponse; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class SayResponse extends MCResponse { 15 | private String message; 16 | 17 | public String getMessage() { 18 | return message; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return message; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/mcpews/response/SetBlockResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.response; 7 | 8 | import mcpews.message.MCResponse; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class SetBlockResponse extends MCResponse { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/mcpews/response/SummonResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.response; 7 | 8 | import mcpews.mcenum.BlockPos; 9 | import mcpews.mcenum.EntityType; 10 | import mcpews.message.MCResponse; 11 | 12 | /** 13 | * 14 | * @author Jocopa3 15 | */ 16 | public class SummonResponse extends MCResponse { 17 | private String entityType; 18 | private BlockPos spawnPos; 19 | private boolean wasSpawned; 20 | 21 | public EntityType getEntityType() { 22 | return EntityType.fromString(entityType); 23 | } 24 | 25 | public BlockPos getSpawnPos() { 26 | return spawnPos; 27 | } 28 | 29 | public boolean wasSpawned() { 30 | return wasSpawned; 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | if(statusCode != 0) { 36 | return statusMessage; 37 | } 38 | 39 | return statusMessage.toLowerCase().replace("object", entityType); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/mcpews/response/TestForBlockResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.response; 7 | 8 | import mcpews.mcenum.BlockPos; 9 | import mcpews.message.MCResponse; 10 | 11 | /** 12 | * 13 | * @author Jocopa3 14 | */ 15 | public class TestForBlockResponse extends MCResponse { 16 | BlockPos position; 17 | boolean matches; 18 | 19 | public BlockPos getPosition() { 20 | return position; 21 | } 22 | 23 | public boolean matches() { 24 | return matches; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/mcpews/response/TimeResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.response; 7 | 8 | import mcpews.message.MCResponse; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class TimeResponse extends MCResponse { 15 | private int time; 16 | 17 | public int getTime() { 18 | return time; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/mcpews/response/WSServerResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.response; 7 | 8 | import mcpews.message.MCResponse; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class WSServerResponse extends MCResponse { 15 | private String requestedUri; 16 | 17 | public String getRequestedUri() { 18 | return requestedUri; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/mcpews/util/Biome.java: -------------------------------------------------------------------------------- 1 | package mcpews.util; 2 | 3 | import java.util.HashMap; 4 | 5 | /** 6 | * 7 | * @author Jocopa3 8 | */ 9 | public enum Biome { 10 | 11 | OCEAN(0, "Ocean", BiomeType.NEUTRAL), 12 | PLAINS(1, "Plains", BiomeType.TEMPERATE), 13 | DESERT(2, "Desert", BiomeType.HOT), 14 | EXTREME_HILLS(3, "Extreme Hills", BiomeType.COLD), 15 | FOREST(4, "Forest", BiomeType.TEMPERATE), 16 | TAIGA(5, "Taiga", BiomeType.COLD), 17 | SWAMPLAND(6, "Swampland", BiomeType.TEMPERATE), 18 | RIVER(7, "River", BiomeType.TEMPERATE), 19 | NETHER(8, "Nether", BiomeType.HOT), 20 | THE_END(9, "The End", BiomeType.COLD), 21 | FROZEN_OCEAN(10, "Frozen Ocean", BiomeType.SNOWY), 22 | FROZEN_RIVER(11, "Frozen River", BiomeType.SNOWY), 23 | ICE_PLAINS(12, "Ice Plains", BiomeType.SNOWY), 24 | ICE_MOUNTAINS(13, "Ice Mountains", BiomeType.SNOWY), 25 | MUSHROOM_ISLAND(14, "Mushroom Island", BiomeType.NEUTRAL), 26 | MUSHROOM_ISLAND_SHORE(15, "Mushroom Island Shore", BiomeType.NEUTRAL), 27 | BEACH(16, "Beach", BiomeType.TEMPERATE), 28 | DESERT_HILLS(17, "Desert Hills", BiomeType.HOT), 29 | FOREST_HILLS(18, "Forest Hills", BiomeType.TEMPERATE), 30 | TAIGA_HILLS(19, "Taiga Hills", BiomeType.COLD), 31 | EXTREME_HILLS_EDGE(20, "Extreme Hills Edge", BiomeType.COLD), 32 | JUNGLE(21, "Jungle", BiomeType.TEMPERATE), 33 | JUNGLE_HILLS(22, "Jungle Hills", BiomeType.TEMPERATE), 34 | JUNGLE_EDGE(23, "Jungle Edge", BiomeType.TEMPERATE), 35 | DEEP_OCEAN(24, "Deep Ocean", BiomeType.NEUTRAL), 36 | STONE_BEACH(25, "Stone Beach", BiomeType.COLD), 37 | COLD_BEACH(26, "Cold Beach", BiomeType.SNOWY), 38 | BIRCH_FOREST(27, "Birch Forest", BiomeType.TEMPERATE), 39 | BIRCH_FOREST_HILLS(28, "Birch Forest Hills", BiomeType.TEMPERATE), 40 | ROOFED_FOREST(29, "Roofed Forest", BiomeType.TEMPERATE), 41 | COLD_TAIGA(30, "Cold Taiga", BiomeType.SNOWY), 42 | COLD_TAIGA_HILLS(31, "Cold Taiga Hills", BiomeType.SNOWY), 43 | MEGA_TAIGA(32, "Mega Taiga", BiomeType.COLD), 44 | MEGA_TAIGA_HILLS(33, "Mega Taiga Hills", BiomeType.COLD), 45 | EXTREME_HILLS_PLUS(34, "Extreme Hills+", BiomeType.COLD), 46 | SAVANNA(35, "Savanna", BiomeType.HOT), 47 | SAVANNA_PLATEAU(36, "Savanna Plateau", BiomeType.HOT), 48 | MESA(37, "Mesa", BiomeType.HOT), 49 | MESA_PLATEAU_F(38, "Mesa Plateau F", BiomeType.HOT), 50 | MESA_PLATEAU(39, "Mesa Plateau", BiomeType.HOT), 51 | SUNFLOWER_PLAINS(129, "Sunflower Plains", BiomeType.TEMPERATE), 52 | DESERT_M(130, "Desert M", BiomeType.HOT), 53 | EXTREME_HILLS_M(131, "Extreme Hills M", BiomeType.COLD), 54 | FLOWER_FOREST(132, "Flower Forest", BiomeType.TEMPERATE), 55 | TAIGA_M(133, "Taiga M", BiomeType.COLD), 56 | SWAMPLAND_M(134, "Swampland M", BiomeType.TEMPERATE), 57 | ICE_PLAINS_SPIKES(140, "Ice Plains Spikes", BiomeType.COLD), 58 | JUNGLE_M(149, "Jungle M", BiomeType.TEMPERATE), 59 | JUNGLE_EDGE_M(151, "Jungle Edge M", BiomeType.TEMPERATE), 60 | BIRCH_FOREST_M(155, "Birch Forest M", BiomeType.TEMPERATE), 61 | BIRCH_FOREST_HILLS_M(156, "Birch Forest Hills M", BiomeType.TEMPERATE), 62 | ROOFED_FOREST_M(157, "Roofed Forest M", BiomeType.TEMPERATE), 63 | COLD_TAIGA_M(158, "Cold Taiga M", BiomeType.SNOWY), 64 | MEGA_SPRUCE_TAIGA(160, "Mega Spruce Taiga", BiomeType.COLD), 65 | REDWOOD_TAIGA_HILLS_M(161, "Redwood Taiga Hills M", BiomeType.COLD), 66 | EXTREME_HILLS_PLUS_M(162, "Extreme Hills+ M", BiomeType.COLD), 67 | SAVANNA_M(163, "Savanna M", BiomeType.HOT), 68 | SAVANNA_PLATEAU_M(164, "Savanna Plateau M", BiomeType.HOT), 69 | MESA_BRYCE(165, "Mesa (Bryce)", BiomeType.HOT), 70 | MESA_PLATEAU_F_M(166, "Mesa Plateau F M", BiomeType.HOT), 71 | MESA_PLATEAU_M(167, "Mesa Plateau M", BiomeType.HOT); 72 | 73 | private static final HashMap fromId; 74 | 75 | static { 76 | fromId = new HashMap<>(); 77 | 78 | for(Biome biome : Biome.values()){ 79 | fromId.put(biome.id, biome); 80 | } 81 | } 82 | 83 | private int id; 84 | private String name; 85 | private BiomeType type; 86 | 87 | Biome(int id, String name, BiomeType type){ 88 | this.id = id; 89 | this.name = name; 90 | this.type = type; 91 | } 92 | 93 | public int getId() { 94 | return id; 95 | } 96 | 97 | public String getName() { 98 | return name; 99 | } 100 | 101 | public BiomeType getType() { 102 | return type; 103 | } 104 | 105 | public static Biome fromId(int id){ 106 | return fromId.get(id); 107 | } 108 | } -------------------------------------------------------------------------------- /src/mcpews/util/BiomeType.java: -------------------------------------------------------------------------------- 1 | package mcpews.util; 2 | 3 | public enum BiomeType { 4 | NEUTRAL(ChatFormatCode.WHITE_STRING), 5 | SNOWY(ChatFormatCode.BLUE_STRING), 6 | COLD(ChatFormatCode.GREEN_STRING), 7 | TEMPERATE(ChatFormatCode.GOLD_STRING), 8 | HOT(ChatFormatCode.RED_STRING); 9 | 10 | private String chatCode; 11 | 12 | BiomeType(String code) { 13 | this.chatCode = code; 14 | } 15 | 16 | public String getChatColor() { 17 | return chatCode; 18 | } 19 | } -------------------------------------------------------------------------------- /src/mcpews/util/ChatFormatCode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package mcpews.util; 7 | 8 | import java.awt.Color; 9 | 10 | /** 11 | * 12 | * @author Jocopa3 13 | */ 14 | public class ChatFormatCode { 15 | public static final char ESCAPE_CHAR = '\u00a7'; 16 | public static final String ESCAPE_STRING = Character.toString(ESCAPE_CHAR); 17 | 18 | public static final Color BLACK = new Color(0, 0, 0); 19 | public static final Color DARK_BLUE = new Color(0, 0, 170); 20 | public static final Color DARK_GREEN = new Color(0, 170, 0); 21 | public static final Color DARK_AQUA = new Color(0, 170, 170); 22 | public static final Color DARK_RED = new Color(170, 0, 0); 23 | public static final Color DARK_PURPLE = new Color(170, 0, 170); 24 | public static final Color GOLD = new Color(255, 170, 0); 25 | public static final Color GRAY = new Color(170, 170, 170); 26 | public static final Color DARK_GRAY = new Color(85, 85, 85); 27 | public static final Color BLUE = new Color(85, 85, 255); 28 | public static final Color GREEN = new Color(85, 255, 85); 29 | public static final Color AQUA = new Color(85, 255, 255); 30 | public static final Color RED = new Color(255, 85, 85); 31 | public static final Color LIGHT_PURPLE = new Color(255, 85, 255); 32 | public static final Color YELLOW = new Color(255, 255, 85); 33 | public static final Color WHITE = new Color(255, 255, 255); 34 | 35 | public static final char BLACK_CHAR = '0'; 36 | public static final char DARK_BLUE_CHAR = '1'; 37 | public static final char DARK_GREEN_CHAR = '2'; 38 | public static final char DARK_AQUA_CHAR = '3'; 39 | public static final char DARK_RED_CHAR = '4'; 40 | public static final char DARK_PURPLE_CHAR = '5'; 41 | public static final char GOLD_CHAR = '6'; 42 | public static final char GRAY_CHAR = '7'; 43 | public static final char DARK_GRAY_CHAR = '8'; 44 | public static final char BLUE_CHAR = '9'; 45 | public static final char GREEN_CHAR = 'a'; 46 | public static final char AQUA_CHAR = 'b'; 47 | public static final char RED_CHAR = 'c'; 48 | public static final char LIGHT_PURPLE_CHAR = 'd'; 49 | public static final char YELLOW_CHAR = 'e'; 50 | public static final char WHITE_CHAR = 'f'; 51 | 52 | public static final char OBFUSCATED_CHAR = 'k'; 53 | public static final char BOLD_CHAR = 'l'; 54 | public static final char STRIKETHROUGH_CHAR = 'm'; 55 | public static final char UNDERLINE_CHAR = 'n'; 56 | public static final char ITALIC_CHAR = 'o'; 57 | public static final char RESET_CHAR = 'r'; 58 | 59 | public static final String BLACK_STRING = ESCAPE_CHAR + "0"; 60 | public static final String DARK_BLUE_STRING = ESCAPE_CHAR + "1"; 61 | public static final String DARK_GREEN_STRING = ESCAPE_CHAR + "2"; 62 | public static final String DARK_AQUA_STRING = ESCAPE_CHAR + "3"; 63 | public static final String DARK_RED_STRING = ESCAPE_CHAR + "4"; 64 | public static final String DARK_PURPLE_STRING = ESCAPE_CHAR + "5"; 65 | public static final String GOLD_STRING = ESCAPE_CHAR + "6"; 66 | public static final String GRAY_STRING = ESCAPE_CHAR + "7"; 67 | public static final String DARK_GRAY_STRING = ESCAPE_CHAR + "8"; 68 | public static final String BLUE_STRING = ESCAPE_CHAR + "9"; 69 | public static final String GREEN_STRING = ESCAPE_CHAR + "a"; 70 | public static final String AQUA_STRING = ESCAPE_CHAR + "b"; 71 | public static final String RED_STRING = ESCAPE_CHAR + "c"; 72 | public static final String LIGHT_PURPLE_STRING = ESCAPE_CHAR + "d"; 73 | public static final String YELLOW_STRING = ESCAPE_CHAR + "e"; 74 | public static final String WHITE_STRING = ESCAPE_CHAR + "f"; 75 | 76 | public static final String OBFUSCATED_STRING = ESCAPE_CHAR + "k"; 77 | public static final String BOLD_STRING = ESCAPE_CHAR + "l"; 78 | public static final String STRIKETHROUGH_STRING = ESCAPE_CHAR + "m"; 79 | public static final String UNDERLINE_STRING = ESCAPE_CHAR + "n"; 80 | public static final String ITALIC_STRING = ESCAPE_CHAR + "o"; 81 | public static final String RESET_STRING = ESCAPE_CHAR + "r"; 82 | 83 | public static String formatString(String format, String s) { 84 | return s.replaceAll(format, ESCAPE_STRING); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/mcpews/util/StringArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | 7 | package mcpews.util; 8 | 9 | /** 10 | * 11 | * @author Jocopa3 12 | */ 13 | public class StringArray { 14 | String[] arr; 15 | 16 | public StringArray(String... strings) { 17 | arr = strings; 18 | } 19 | 20 | @Override 21 | public String toString() { 22 | return String.join(" ", arr); 23 | } 24 | } 25 | --------------------------------------------------------------------------------