diff --git a/src/main/java/us/camin/JoinListener.java b/src/main/java/us/camin/JoinListener.java index 4281126..972aac5 100644 --- a/src/main/java/us/camin/JoinListener.java +++ b/src/main/java/us/camin/JoinListener.java @@ -20,16 +20,28 @@ package us.camin; import java.util.logging.Logger; import org.bukkit.entity.Player; +import org.bukkit.entity.Entity; import org.bukkit.event.Listener; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerLoginEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerKickEvent; +import org.bukkit.event.player.PlayerChatEvent; +import org.bukkit.event.entity.PlayerDeathEvent; +import org.bukkit.event.weather.WeatherChangeEvent; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.permissions.PermissionAttachment; import java.io.IOException; import us.camin.api.ValidationResponse; +import us.camin.api.ClientEvent; +import us.camin.api.BlockEvent; +import us.camin.api.ChatEvent; +import us.camin.api.DeathEvent; +import us.camin.api.MurderEvent; +import us.camin.api.WeatherEvent; public class JoinListener implements Listener { Logger log = Logger.getLogger("Caminus.Join"); @@ -98,4 +110,43 @@ public class JoinListener implements Listener { m_plugin.sendMOTD(event.getPlayer()); m_plugin.checkFreeHalfDoorDay(event.getPlayer()); } + + @EventHandler + public void onPlayerChat(PlayerChatEvent event) { + ChatEvent evt = new ChatEvent(event.getPlayer().getName(), event.getMessage()); + m_plugin.sendEvent(evt); + } + + @EventHandler + public void onBlockBreak(BlockBreakEvent event) { + BlockEvent evt = new BlockEvent(event.getPlayer().getName(), event.getBlock(), BlockEvent.Type.BREAK); + m_plugin.sendEvent(evt); + } + + @EventHandler + public void onBlockPlace(BlockPlaceEvent event) { + BlockEvent evt = new BlockEvent(event.getPlayer().getName(), event.getBlock(), BlockEvent.Type.PLACE); + m_plugin.sendEvent(evt); + } + + @EventHandler + public void onWeather(WeatherChangeEvent event) { + WeatherEvent evt = new WeatherEvent(event.getWorld().getName(), event.toWeatherState()); + m_plugin.sendEvent(evt); + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) { + Player target = event.getEntity(); + Entity source = target.getKiller(); + System.out.println("Target: "+target.getName()+" killed by: "+source); + ClientEvent evt = new DeathEvent(target.getName(), event.getDeathMessage()); + m_plugin.sendEvent(evt); + if (source instanceof Player) { + Player killer = (Player)source; + System.out.println("It was MURDER!"); + evt = new MurderEvent(target.getName(), killer.getName()); + m_plugin.sendEvent(evt); + } + } } diff --git a/src/main/java/us/camin/Plugin.java b/src/main/java/us/camin/Plugin.java index 8fa4b15..6c15dfe 100644 --- a/src/main/java/us/camin/Plugin.java +++ b/src/main/java/us/camin/Plugin.java @@ -42,6 +42,9 @@ import java.util.concurrent.Callable; import us.camin.api.Server; import us.camin.api.ServerEvent; import us.camin.api.BroadcastEvent; +import us.camin.api.PlayerMessageEvent; +import us.camin.api.ClientEvent; +import org.json.JSONException; public class Plugin extends JavaPlugin { @@ -58,7 +61,8 @@ public class Plugin extends JavaPlugin { public void onDisable() { log.info("[Caminus] Plugin disabled"); - m_api = null; + m_eventPoll.stop(); + m_api = null; } public void handleEvent(ServerEvent e) { @@ -70,6 +74,14 @@ public class Plugin extends JavaPlugin { return null; } }); + } else if (e instanceof PlayerMessageEvent) { + final PlayerMessageEvent evt = (PlayerMessageEvent)(e); + getServer().getScheduler().callSyncMethod(this, new Callable() { + public Void call() { + getServer().getPlayer(evt.player).sendMessage(evt.message); + return null; + } + }); } try { m_api.notifyEventHandled(e); @@ -78,6 +90,18 @@ public class Plugin extends JavaPlugin { } } + public void sendEvent(ClientEvent event) { + ClientEvent[] events = new ClientEvent[1]; + events[0] = event; + try { + api().sendEvents(events); + } catch (JSONException e) { + log.log(Level.SEVERE, "Could not encode event", e); + } catch (IOException e) { + log.log(Level.SEVERE, "Could not submit event, it is lost forever!", e); + } + } + public void onEnable() { PluginManager pm = this.getServer().getPluginManager(); m_listener = new JoinListener(this); diff --git a/src/main/java/us/camin/ServerEventPoller.java b/src/main/java/us/camin/ServerEventPoller.java index dadb99a..192bc10 100644 --- a/src/main/java/us/camin/ServerEventPoller.java +++ b/src/main/java/us/camin/ServerEventPoller.java @@ -28,10 +28,13 @@ import org.bukkit.scheduler.BukkitScheduler; public class ServerEventPoller implements Runnable { private Plugin m_plugin; + private boolean m_running; + private int m_taskid; Logger log = Logger.getLogger("CaminusEventPoll"); public ServerEventPoller(Plugin plugin) { m_plugin = plugin; + m_running = true; } public void run() { @@ -41,11 +44,19 @@ public class ServerEventPoller implements Runnable { events = m_plugin.api().pollEventQueue(); } catch (IOException e) { } - for(ServerEvent e : events) { - m_plugin.handleEvent(e); + if (m_running) { + for(ServerEvent e : events) { + m_plugin.handleEvent(e); + } + final BukkitScheduler scheduler = m_plugin.getServer().getScheduler(); + m_taskid = scheduler.scheduleAsyncDelayedTask(m_plugin, this); + log.info("Events handled."); } - final BukkitScheduler scheduler = m_plugin.getServer().getScheduler(); - scheduler.scheduleAsyncDelayedTask(m_plugin, this); - log.info("Events handled."); + } + + public void stop() { + BukkitScheduler scheduler = m_plugin.getServer().getScheduler(); + scheduler.cancelTask(m_taskid); + m_running = false; } } diff --git a/src/main/java/us/camin/api/BlockEvent.java b/src/main/java/us/camin/api/BlockEvent.java new file mode 100644 index 0000000..ebb2615 --- /dev/null +++ b/src/main/java/us/camin/api/BlockEvent.java @@ -0,0 +1,68 @@ +package us.camin.api; + +/* + This file is part of Caminus + + Caminus is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Caminus is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Caminus. If not, see . + */ + +import org.json.JSONWriter; +import org.json.JSONException; +import org.bukkit.block.Block; +import org.bukkit.Location; + +public class BlockEvent extends ClientEvent { + public String sender; + public Block block; + public Type type; + + public enum Type { + BREAK, PLACE + } + + public BlockEvent(String player, Block block, Type type) { + this.sender = player; + this.block = block; + this.type = type; + } + + public JSONWriter toJSON(JSONWriter writer) throws JSONException { + writer.key("sender").value(sender); + String evtType; + switch(type) { + case BREAK: + evtType = "break"; + break; + case PLACE: + evtType = "place"; + break; + default: + evtType = "unknown"; + } + writer.key("type").value(evtType); + writer.key("location"); + writer.object(); + Location loc = block.getLocation(); + writer.key("x").value(loc.getBlockX()); + writer.key("y").value(loc.getBlockY()); + writer.key("z").value(loc.getBlockZ()); + writer.endObject(); + return writer; + } + + public String jsonName() { + return "block"; + } +} + diff --git a/src/main/java/us/camin/api/ChatEvent.java b/src/main/java/us/camin/api/ChatEvent.java new file mode 100644 index 0000000..320a783 --- /dev/null +++ b/src/main/java/us/camin/api/ChatEvent.java @@ -0,0 +1,41 @@ +package us.camin.api; + +/* + This file is part of Caminus + + Caminus is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Caminus is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Caminus. If not, see . + */ + +import org.json.JSONWriter; +import org.json.JSONException; + +public class ChatEvent extends ClientEvent { + public String sender; + public String message; + + public ChatEvent(String sender, String message) { + this.sender = sender; + this.message = message; + } + + public JSONWriter toJSON(JSONWriter writer) throws JSONException { + writer.key("sender").value(sender); + writer.key("message").value(message); + return writer; + } + + public String jsonName() { + return "chat"; + } +} diff --git a/src/main/java/us/camin/api/ClientEvent.java b/src/main/java/us/camin/api/ClientEvent.java new file mode 100644 index 0000000..99739f2 --- /dev/null +++ b/src/main/java/us/camin/api/ClientEvent.java @@ -0,0 +1,42 @@ +package us.camin.api; + +/* + This file is part of Caminus + + Caminus is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Caminus is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Caminus. If not, see . + */ + +import org.json.JSONWriter; +import org.json.JSONStringer; +import org.json.JSONException; +import org.json.JSONObject; + +public abstract class ClientEvent { + public JSONObject toJSON() throws JSONException { + JSONWriter s = new JSONStringer(); + s.object(); + s.key("type"); + s.value(jsonName()); + s.key("payload"); + s.object(); + s = toJSON(s); + s.endObject(); + s.endObject(); + return new JSONObject(((JSONStringer)s).toString()); + } + + public abstract String jsonName(); + + public abstract JSONWriter toJSON(JSONWriter writer) throws JSONException; +} diff --git a/src/main/java/us/camin/api/DeathEvent.java b/src/main/java/us/camin/api/DeathEvent.java new file mode 100644 index 0000000..b2c85f2 --- /dev/null +++ b/src/main/java/us/camin/api/DeathEvent.java @@ -0,0 +1,42 @@ +package us.camin.api; + +/* + This file is part of Caminus + + Caminus is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Caminus is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Caminus. If not, see . + */ + +import org.json.JSONWriter; +import org.json.JSONException; + +public class DeathEvent extends ClientEvent { + public String player; + public String message; + + public DeathEvent(String player, String message) { + this.player = player; + this.message = message; + } + + public JSONWriter toJSON(JSONWriter writer) throws JSONException { + writer.key("player").value(player); + writer.key("message").value(message); + return writer; + } + + public String jsonName() { + return "player-death"; + } +} + diff --git a/src/main/java/us/camin/api/MurderEvent.java b/src/main/java/us/camin/api/MurderEvent.java new file mode 100644 index 0000000..5122942 --- /dev/null +++ b/src/main/java/us/camin/api/MurderEvent.java @@ -0,0 +1,44 @@ +package us.camin.api; + +/* + This file is part of Caminus + + Caminus is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Caminus is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Caminus. If not, see . + */ + +import org.json.JSONWriter; +import org.json.JSONException; + +public class MurderEvent extends ClientEvent { + public String player; + public String killer; + public String message; + + public MurderEvent(String player, String killer) { + this.player = player; + this.killer = killer; + } + + public JSONWriter toJSON(JSONWriter writer) throws JSONException { + writer.key("player").value(player); + writer.key("killer").value(killer); + return writer; + } + + public String jsonName() { + return "player-murder"; + } +} + + diff --git a/src/main/java/us/camin/api/Server.java b/src/main/java/us/camin/api/Server.java index d93e96a..2599685 100644 --- a/src/main/java/us/camin/api/Server.java +++ b/src/main/java/us/camin/api/Server.java @@ -42,6 +42,7 @@ import java.security.NoSuchAlgorithmException; import org.json.JSONArray; import org.json.JSONObject; import org.json.JSONException; +import org.json.JSONStringer; import java.util.Random; import org.apache.commons.codec.binary.Hex; @@ -91,7 +92,9 @@ public class Server { DataOutputStream out = new DataOutputStream(conn.getOutputStream()); out.writeBytes(postData); } - return readJSON(conn); + JSONObject ret = readJSON(conn); + conn.disconnect(); + return ret; } public HttpURLConnection open(String path) throws MalformedURLException, IOException { @@ -239,6 +242,22 @@ public class Server { post("server/events", params); } + public void sendEvents(ClientEvent[] event) throws JSONException, IOException { + log.info("Submitting events"); + JSONStringer out = new JSONStringer(); + out.object(); + out.key("events"); + out.array(); + for (ClientEvent evt : event) { + out.value(evt.toJSON()); + } + out.endArray(); + out.endObject(); + HashMap params = new HashMap(); + params.put("events", out.toString()); + put("server/events", params); + } + public ServerEvent[] pollEventQueue() throws IOException { log.info("Polling server for events"); JSONObject jsonObj = get("server/events"); diff --git a/src/main/java/us/camin/api/WeatherEvent.java b/src/main/java/us/camin/api/WeatherEvent.java new file mode 100644 index 0000000..995d03f --- /dev/null +++ b/src/main/java/us/camin/api/WeatherEvent.java @@ -0,0 +1,43 @@ +package us.camin.api; + +/* + This file is part of Caminus + + Caminus is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Caminus is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Caminus. If not, see . + */ + +import org.json.JSONWriter; +import org.json.JSONException; + +public class WeatherEvent extends ClientEvent { + public String world; + public boolean isRaining; + + public WeatherEvent(String world, boolean rain) { + this.world = world; + this.isRaining = rain; + } + + public JSONWriter toJSON(JSONWriter writer) throws JSONException { + writer.key("world").value(world); + writer.key("isRaining").value(isRaining); + return writer; + } + + public String jsonName() { + return "weather"; + } +} + +