Implement server polling

This commit is contained in:
Trever Fischer 2012-10-21 20:04:34 -04:00
parent 3ae4e8349a
commit 7e6b4e9852
6 changed files with 232 additions and 3 deletions

View File

@ -17,6 +17,7 @@ package us.camin;
along with Caminus. If not, see <http://www.gnu.org/licenses/>. along with Caminus. If not, see <http://www.gnu.org/licenses/>.
*/ */
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -36,8 +37,11 @@ import java.util.HashMap;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.logging.Level; import java.util.logging.Level;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.Callable;
import us.camin.api.Server; import us.camin.api.Server;
import us.camin.api.ServerEvent;
import us.camin.api.BroadcastEvent;
public class Plugin extends JavaPlugin { public class Plugin extends JavaPlugin {
@ -46,6 +50,7 @@ public class Plugin extends JavaPlugin {
private JoinListener m_listener; private JoinListener m_listener;
private MOTDCommand m_motdCommand; private MOTDCommand m_motdCommand;
private VomitCommand m_vomitCommand; private VomitCommand m_vomitCommand;
private ServerEventPoller m_eventPoll;
public Server api() { public Server api() {
return m_api; return m_api;
@ -56,6 +61,23 @@ public class Plugin extends JavaPlugin {
m_api = null; m_api = null;
} }
public void handleEvent(ServerEvent e) {
if (e instanceof BroadcastEvent) {
final BroadcastEvent evt = (BroadcastEvent)(e);
getServer().getScheduler().callSyncMethod(this, new Callable<Void>() {
public Void call() {
getServer().broadcastMessage(evt.message);
return null;
}
});
}
try {
m_api.notifyEventHandled(e);
} catch (IOException ex) {
log.severe("Could not close out event. Duplicates will happen!!!");
}
}
public void onEnable() { public void onEnable() {
PluginManager pm = this.getServer().getPluginManager(); PluginManager pm = this.getServer().getPluginManager();
m_listener = new JoinListener(this); m_listener = new JoinListener(this);
@ -74,6 +96,8 @@ public class Plugin extends JavaPlugin {
pm.registerEvents(m_listener, this); pm.registerEvents(m_listener, this);
m_eventPoll = new ServerEventPoller(this);
m_motdCommand = new MOTDCommand(this); m_motdCommand = new MOTDCommand(this);
getCommand("motd").setExecutor(m_motdCommand); getCommand("motd").setExecutor(m_motdCommand);
m_vomitCommand = new VomitCommand(this); m_vomitCommand = new VomitCommand(this);
@ -88,6 +112,7 @@ public class Plugin extends JavaPlugin {
sm.register(Economy.class, econAPI, this, ServicePriority.High); sm.register(Economy.class, econAPI, this, ServicePriority.High);
log.info("[Caminus] Plugin enabled"); log.info("[Caminus] Plugin enabled");
getServer().getScheduler().scheduleAsyncDelayedTask(this, m_eventPoll);
} }
public void checkFreeHalfDoorDay(Player sender) { public void checkFreeHalfDoorDay(Player sender) {

View File

@ -0,0 +1,51 @@
package us.camin;
/*
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 <http://www.gnu.org/licenses/>.
*/
import java.lang.Runnable;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
import us.camin.api.ServerEvent;
import java.io.IOException;
import java.util.logging.Logger;
import org.bukkit.scheduler.BukkitScheduler;
public class ServerEventPoller implements Runnable {
private Plugin m_plugin;
Logger log = Logger.getLogger("CaminusEventPoll");
public ServerEventPoller(Plugin plugin) {
m_plugin = plugin;
}
public void run() {
log.info("Poll events");
ServerEvent[] events = new ServerEvent[0];
try {
events = m_plugin.api().pollEventQueue();
} catch (IOException e) {
}
for(ServerEvent e : events) {
m_plugin.handleEvent(e);
}
final BukkitScheduler scheduler = m_plugin.getServer().getScheduler();
scheduler.scheduleAsyncDelayedTask(m_plugin, this);
log.info("Events handled.");
}
}

View File

@ -0,0 +1,32 @@
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 <http://www.gnu.org/licenses/>.
*/
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
public class BroadcastEvent extends ServerEvent {
public String message;
public static BroadcastEvent fromJSON(JSONObject obj, int id) {
BroadcastEvent ret = new BroadcastEvent();
ret.message = obj.optString("message");
ret.id = id;
return ret;
}
}

View File

@ -0,0 +1,35 @@
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 <http://www.gnu.org/licenses/>.
*/
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
public class PlayerMessageEvent extends ServerEvent {
public String message;
public String player;
public static PlayerMessageEvent fromJSON(JSONObject obj, int id) {
PlayerMessageEvent ret = new PlayerMessageEvent();
ret.message = obj.optString("message");
ret.player = obj.optString("player");
ret.id = id;
return ret;
}
}

View File

@ -47,7 +47,7 @@ import java.util.Random;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
public class Server { public class Server {
Logger log = Logger.getLogger("Caminus.API"); Logger log = Logger.getLogger("Caminus.API");
private String m_url; private String m_url;
private String m_name; private String m_name;
private String m_secret; private String m_secret;
@ -216,13 +216,15 @@ public class Server {
public boolean pingAPI() { public boolean pingAPI() {
log.info("Pinging API server to verify credentials"); log.info("Pinging API server to verify credentials");
JSONObject response;
try { try {
get("server/whoami"); response = get("server/whoami");
} catch (IOException e) { } catch (IOException e) {
log.log(Level.SEVERE, "Could not ping API server.", e); log.log(Level.SEVERE, "Could not ping API server.", e);
return false; return false;
} }
return true; log.info("Connected to server running "+response.optString("server-version")+", api "+response.optInt("api-version"));
return response.optInt("api-version") == 2;
} }
public void closeSession(String player) throws IOException { public void closeSession(String player) throws IOException {
@ -230,6 +232,35 @@ public class Server {
get("server/session/"+player+"/close"); get("server/session/"+player+"/close");
} }
public void notifyEventHandled(ServerEvent event) throws IOException {
log.info("Closing event "+event.id);
HashMap<String, String> params = new HashMap<String, String>();
params.put("job", Integer.toString(event.id));
post("server/events", params);
}
public ServerEvent[] pollEventQueue() throws IOException {
log.info("Polling server for events");
JSONObject jsonObj = get("server/events");
JSONArray eventList;
try {
eventList = jsonObj.getJSONArray("events");
} catch (JSONException e) {
return new ServerEvent[0];
}
ServerEvent[] events = new ServerEvent[eventList.length()];
for (int i = 0;i<eventList.length();i++) {
try{
events[i] = ServerEvent.fromJSON(eventList.getJSONObject(i));
} catch (JSONException e) {
log.log(Level.SEVERE, "Bad JSON", e);
events[i] = null;
}
}
return events;
}
public ValidationResponse openSession(String player, InetSocketAddress sourceAddr) throws IOException { public ValidationResponse openSession(String player, InetSocketAddress sourceAddr) throws IOException {
log.info("Opening session for "+player); log.info("Opening session for "+player);
ValidationResponse resp = new ValidationResponse(); ValidationResponse resp = new ValidationResponse();

View File

@ -0,0 +1,55 @@
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 <http://www.gnu.org/licenses/>.
*/
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ServerEvent {
public int id;
static Logger log = Logger.getLogger("Caminus.api");
public static ServerEvent fromJSON(JSONObject obj) {
int id = obj.optInt("id");
JSONObject event;
try {
event = obj.getJSONObject("event");
} catch (JSONException e) {
log.log(Level.SEVERE, "Bad JSON", e);
return null;
}
String type = event.optString("type");
JSONObject payload;
try {
payload = event.getJSONObject("payload");
} catch (JSONException e) {
log.log(Level.SEVERE, "Bad JSON ", e);
return null;
}
if (type.equals("broadcast")) {
return BroadcastEvent.fromJSON(payload, id);
} else if (type.equals("player-message")) {
return PlayerMessageEvent.fromJSON(payload, id);
} else {
log.log(Level.SEVERE, "Unhandled event type: "+type);
return null;
}
}
}