Java tutorial
/* * Copyright (C) 2013 Joshua Michael Hertlein <jmhertlein@gmail.com> * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */ package net.jmhertlein.adminbuddy.daemon; import net.jmhertlein.core.io.ClientSession; import com.google.common.collect.Sets; import java.io.IOException; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import net.jmhertlein.adminbuddy.client.ChatMessage; import net.jmhertlein.adminbuddy.protocol.ChatUpdatePacket; import net.jmhertlein.adminbuddy.protocol.ClientKickPacket; import net.jmhertlein.adminbuddy.protocol.PlayerDepartPacket; import net.jmhertlein.adminbuddy.protocol.PlayerDepartReason; import net.jmhertlein.adminbuddy.protocol.PlayerLoginPacket; import net.jmhertlein.adminbuddy.protocol.ServerPacket; import org.bukkit.Bukkit; import org.bukkit.ChatColor; /** * * @author Joshua Michael Hertlein <jmhertlein@gmail.com> */ public class DaemonCore { private final Set<ClientSession> sessions; private final Map<Integer, ClientSession> pendingKeyAssociationTokens; public DaemonCore() { this.sessions = Sets.newSetFromMap(new ConcurrentHashMap<ClientSession, Boolean>()); pendingKeyAssociationTokens = new HashMap<>(); } public void addNewClient(final ClientSession session) { sessions.add(session); session.setShutdownHook(new Callable() { @Override public Object call() throws Exception { sessions.remove(session); System.out.println("Removed session " + session + " due to disconnect."); return null; } }); } public void pushChatUpdate(String sender, String message) throws IOException { pushPacket(new ChatUpdatePacket(new ChatMessage(sender, message))); } public void displayChatMessage(String sender, String message) { Bukkit.getServer().broadcastMessage(String.format("%s[%s%s%s]%s: %s", ChatColor.GRAY, ChatColor.DARK_GREEN, sender, ChatColor.GRAY, ChatColor.RESET, message)); } public void pushPlayerDeparted(String playerName, PlayerDepartReason reason) throws IOException { pushPacket(new PlayerDepartPacket(playerName, reason)); } private void pushPacket(ServerPacket p) throws IOException { for (ClientSession s : sessions) { s.getConnection().writeObject(p); } } public void pushPlayerLogin(String playerName) throws IOException { pushPacket(new PlayerLoginPacket(playerName)); } public int prepareNewAssociationToken(ClientSession s) { SecureRandom gen = new SecureRandom(); int token; do { token = gen.nextInt(1000000000); } while (pendingKeyAssociationTokens.containsKey(token)); pendingKeyAssociationTokens.put(token, s); return token; } public Map<Integer, ClientSession> getPendingKeyAssociationTokens() { return pendingKeyAssociationTokens; } public Set<ClientSession> getSessions() { return sessions; } public void kickClient(ClientSession s, String reason) { try { s.getConnection().writeObject(new ClientKickPacket(reason)); } catch (IOException ex) { Logger.getLogger(DaemonCore.class.getName()).log(Level.SEVERE, null, ex); System.err.println("Error sending client kick packet."); } s.getConnection().shutdown(); } }