Java tutorial
/* * This file is part of CraftoPlugin, licensed under the MIT License (MIT). * * Copyright (c) 2017 CraftolutionDE <https://craftolution.de> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Website: http://craftolution.de/ * Contact: support@craftolution.de */ package de.craftolution.craftoplugin4.modules.bot; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ConnectException; import java.net.InetAddress; import java.net.Socket; import java.nio.ByteBuffer; import java.nio.charset.Charset; import com.google.gson.Gson; import com.google.gson.JsonObject; import de.craftolution.craftoplugin4.modules.bot.packets.BotPacket; import de.craftolution.craftoplugin4.modules.bot.result.Result; import de.craftolution.craftoplugin4.modules.bot.result.ResultBotResponse; import de.craftolution.craftoplugin4.modules.bot.packets.ResultPacket; import de.craftolution.craftoplugin4.modules.bot.util.NoConnectionException; import de.craftolution.craftoplugin4.services.config.Config; import de.craftolution.craftoplugin4.services.config.ConfigService; import de.craftolution.craftoplugin4.services.messenger.interfaces.Loggable; import de.craftolution.craftoplugin4.services.module.Component; import de.craftolution.craftoplugin4.services.task.annotations.TaskHandler; /** * TODO: File description for BotConnection.java * * @author Fear837, Pingebam * @since 20.04.2017 * @see <a href="https://github.com/Craftolution">Craftolution on Github</a> */ public class BotConnection extends Component implements Loggable { private final BotModule module; private final Gson gson = new Gson(); private InetAddress address; private int port; private Socket socket; private DataInputStream input; private DataOutputStream output; private boolean listening; public BotConnection(BotModule module) { this.module = module; } @Override protected void onEnable() throws Exception { Config config = ConfigService.instance().get().getOrCreateConfig(this.module); this.address = InetAddress.getByName(config.getString("address")); this.port = config.getInt("port"); try { this.connect(); } catch (ConnectException e) { report("Failed to connect to " + address + " on port " + port + "...", e); } } @Override protected void onDisable() throws Exception { this.disconnect(); } boolean isConnected() { return this.socket != null && !this.socket.isClosed() && this.socket.isConnected() && !this.socket.isInputShutdown() && !this.socket.isOutputShutdown(); } void connect() throws IOException { if (isConnected()) { return; } info("Connecting to %s:%s...", this.address, this.port); this.socket = new Socket(this.address, this.port); this.socket.setKeepAlive(true); this.input = new DataInputStream(this.socket.getInputStream()); this.output = new DataOutputStream(this.socket.getOutputStream()); this.listening = true; } void disconnect() { info("Disconnecting..."); this.listening = false; if (this.socket != null) { try { this.socket.shutdownInput(); } catch (IOException e) { } try { this.socket.shutdownOutput(); } catch (IOException e) { } try { this.socket.close(); } catch (IOException e) { } this.socket = null; } if (this.input != null) { try { this.input.close(); } catch (IOException e) { } this.input = null; } if (this.output != null) { try { this.output.close(); } catch (IOException e) { } this.output = null; } } void send(int packetId, String platform, String packetType, JsonObject packetContent) throws IOException, NoConnectionException { if (!this.isConnected()) { throw new NoConnectionException(); } JsonObject root = new JsonObject(); root.addProperty("platform", platform); root.addProperty("packetType", packetType); root.addProperty("packetId", packetId); root.add("content", packetContent); byte[] packet = root.toString().getBytes(); ByteBuffer buffer = ByteBuffer.allocate(4 + packet.length).putInt(packet.length).put(packet); this.output.write(buffer.array()); this.output.flush(); } void send(BotPacket packet) throws IOException, NoConnectionException { this.send(packet.getId(), packet.getPlatform(), packet.getType(), packet.getContent()); } @TaskHandler(name = "BotConnectionListenerTask", delay = 20, async = true) public void onTask() throws IOException { if (!isConnected() || !this.listening || this.input.available() <= 4) { return; } int packetLength = this.input.readInt(); byte[] packet = new byte[packetLength]; this.input.read(packet); this.parse(packet); } private void parse(byte[] packet) { String string = new String(packet, Charset.forName("UTF8")); JsonObject root = gson.fromJson(string, JsonObject.class); String packetType = root.get("packetType").getAsString(); String platform = root.get("platform").getAsString(); int packetId = root.get("packetId").getAsInt(); JsonObject content = root.getAsJsonObject("content").getAsJsonObject(); if (packetType.equals("result")) { ResultPacket resultPacket = new ResultPacket(packetId, platform, packetType, content); Result result = Result.parse(resultPacket); ResultBotResponse response = new ResultBotResponse(result); this.module.craftobot.scheduleResponse(response); } } }