/** Pulse this session, performing any updates needed. */ void pulse() { // drop the previous placement if needed if (previousPlacementTicks > 0 && --previousPlacementTicks == 0) { previousPlacement = null; } // process messages Message message; while ((message = messageQueue.poll()) != null) { if (disconnected) { // disconnected, we are just seeing extra messages now continue; } super.messageReceived(message); } // check if the client is disconnected if (disconnected) { connectionManager.sessionInactivated(this); if (player == null) { return; } player.remove(); Message userListMessage = UserListItemMessage.removeOne(player.getUniqueId()); for (GlowPlayer player : server.getOnlinePlayers()) { if (player.canSee(this.player)) { player.getSession().send(userListMessage); } else { player.stopHidingDisconnectedPlayer(this.player); } } GlowServer.logger.info(player.getName() + " [" + address + "] lost connection"); if (player.isSleeping()) { player.leaveBed(false); } final String text = EventFactory.onPlayerQuit(player).getQuitMessage(); if (online && text != null && !text.isEmpty()) { server.broadcastMessage(text); } player = null; // in case we are disposed twice } }
/** * Disconnects the session with the specified reason. This causes a KickMessage to be sent. When * it has been delivered, the channel is closed. * * @param reason The reason for disconnection. * @param overrideKick Whether to skip the kick event. */ public void disconnect(String reason, boolean overrideKick) { if (player != null && !overrideKick) { PlayerKickEvent event = EventFactory.onPlayerKick(player, reason); if (event.isCancelled()) { return; } reason = event.getReason(); if (player.isOnline() && event.getLeaveMessage() != null) { server.broadcastMessage(event.getLeaveMessage()); } } // log that the player was kicked if (player != null) { GlowServer.logger.info(player.getName() + " kicked: " + reason); } else { GlowServer.logger.info("[" + address + "] kicked: " + reason); } if (quitReason == null) { quitReason = "kicked"; } // perform the kick, sending a kick message if possible if (isActive() && (getProtocol() instanceof LoginProtocol || getProtocol() instanceof PlayProtocol)) { // channel is both currently connected and in a protocol state allowing kicks sendWithFuture(new KickMessage(reason)).addListener(ChannelFutureListener.CLOSE); } else { getChannel().close(); } }
public void refreshCommands() { for (Object c : new ArrayList(reader.getCompletors())) { reader.removeCompletor((Completor) c); } Completor[] list = new Completor[] {new SimpleCompletor(server.getAllCommands()), new NullCompletor()}; reader.addCompletor(new ArgumentCompletor(list)); sender.recalculatePermissions(); }
/** * Creates a new server on TCP port 25565 and starts listening for connections. * * @param args The command-line arguments. */ public static void main(String[] args) { try { storeQueue.start(); if (!configDir.exists() || !configDir.isDirectory()) configDir.mkdirs(); config.load(); config.options().indent(4); ConfigurationSerialization.registerClass(GlowOfflinePlayer.class); GlowServer server = new GlowServer(); server.start(); List<String> binds = config.getStringList("server.bind"); boolean hasBound = false; if (binds != null) { for (String bind : binds) { String[] split = bind.split("@"); if (split.length != 2) { split = bind.split(":"); } if (split.length > 2) continue; int port = 25565; try { if (split.length > 1) { port = Integer.parseInt(split[1]); } } catch (NumberFormatException e) { } server.bind(new InetSocketAddress(split[0], port)); hasBound = true; } } if (!hasBound) { server.bind(new InetSocketAddress(config.getInt("server.port", 25565))); } logger.info("Ready for connections."); } catch (Throwable t) { logger.log(Level.SEVERE, "Error during server startup.", t); } }
public void writePlayerData(GlowPlayer player) { File playerDir = new File(world.getName(), "players"); if (!playerDir.exists()) playerDir.mkdirs(); File playerFile = new File(playerDir, player.getName() + ".dat"); if (!playerFile.exists()) try { playerFile.createNewFile(); } catch (IOException e) { player.getSession().disconnect("Failed to access player.dat"); server .getLogger() .severe( "Failed to access player.dat for player " + player.getName() + " in world " + world.getName() + "!"); } Map<String, Tag> out = EntityStoreLookupService.find(GlowPlayer.class).save(player); try { NBTOutputStream outStream = new NBTOutputStream(new FileOutputStream(playerFile)); outStream.writeTag(new CompoundTag("", out)); outStream.close(); } catch (IOException e) { player.getSession().disconnect("Failed to write player.dat", true); server .getLogger() .severe( "Failed to write player.dat for player " + player.getName() + " in world " + world.getName() + "!"); } }
/** * Creates a new server on TCP port 25565 and starts listening for connections. * * @param args The command-line arguments. */ public static void main(String[] args) { try { ConfigurationSerialization.registerClass(GlowOfflinePlayer.class); GlowPotionEffect.register(); // parse arguments and read config final ServerConfig config = parseArguments(args); if (config == null) { return; } // start server final GlowServer server = new GlowServer(config); server.start(); server.bind(); server.bindQuery(); server.bindRcon(); logger.info("Ready for connections."); } catch (Throwable t) { logger.log(Level.SEVERE, "Error during server startup.", t); System.exit(1); } }
public void readPlayerData(GlowPlayer player) { Map<String, Tag> playerData = new HashMap<String, Tag>(); CompoundTag playerTag = null; // Map<PlayerData, Object> ret = new HashMap<PlayerData, Object>(); File playerDir = new File(world.getName(), "players"); if (!playerDir.exists()) playerDir.mkdirs(); File playerFile = new File(playerDir, player.getName() + ".dat"); if (!playerFile.exists()) { try { playerFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } else { try { NBTInputStream in = new NBTInputStream(new FileInputStream(playerFile)); playerTag = (CompoundTag) in.readTag(); in.close(); if (playerTag != null) playerData.putAll(playerTag.getValue()); } catch (EOFException e) { } catch (IOException e) { player.kickPlayer("Failed to read " + player.getName() + ".dat!"); server .getLogger() .severe( "Failed to read player.dat for player " + player.getName() + " in world " + world.getName() + "!"); e.printStackTrace(); } } if (playerTag == null) playerTag = new CompoundTag("", new HashMap<String, Tag>()); EntityStoreLookupService.find(GlowPlayer.class).load(player, playerTag); }
private void handleWorldException(String file, IOException e) { server.unloadWorld(world, false); server.getLogger().severe("Unable to access " + file + " for world " + world.getName()); e.printStackTrace(); }
/** * Sets the player associated with this session. * * @param profile The player's profile with name and UUID information. * @throws IllegalStateException if there is already a player associated with this session. */ public void setPlayer(PlayerProfile profile) { if (player != null) { throw new IllegalStateException("Cannot set player twice"); } // isActive check here in case player disconnected during authentication if (!isActive()) { // no need to call onDisconnect() since it only does anything if there's a player set return; } // initialize the player PlayerDataService.PlayerReader reader = server.getPlayerDataService().beginReadingData(profile.getUniqueId()); player = new GlowPlayer(this, profile, reader); // isActive check here in case player disconnected after authentication, // but before the GlowPlayer initialization was completed if (!isActive()) { onDisconnect(); return; } // login event PlayerLoginEvent event = EventFactory.onPlayerLogin(player, hostname); if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { disconnect(event.getKickMessage(), true); return; } // joins the player player.join(this, reader); // Kick other players with the same UUID for (GlowPlayer other : getServer().getOnlinePlayers()) { if (other != player && other.getUniqueId().equals(player.getUniqueId())) { other.getSession().disconnect("You logged in from another location.", true); break; } } player.getWorld().getRawPlayers().add(player); online = true; GlowServer.logger.info( player.getName() + " [" + address + "] connected, UUID: " + player.getUniqueId()); // message and user list String message = EventFactory.onPlayerJoin(player).getJoinMessage(); if (message != null && !message.isEmpty()) { server.broadcastMessage(message); } // todo: display names are included in the outgoing messages here, but // don't show up on the client. A workaround or proper fix is needed. Message addMessage = new UserListItemMessage(UserListItemMessage.Action.ADD_PLAYER, player.getUserListEntry()); List<UserListItemMessage.Entry> entries = new ArrayList<>(); for (GlowPlayer other : server.getOnlinePlayers()) { if (other != player && other.canSee(player)) { other.getSession().send(addMessage); } if (player.canSee(other)) { entries.add(other.getUserListEntry()); } } send(new UserListItemMessage(UserListItemMessage.Action.ADD_PLAYER, entries)); }
@Override public void sessionInactivated(Session session) { server.getSessionRegistry().remove((GlowSession) session); }
@Override public GlowSession newSession(Channel c) { GlowSession session = new GlowSession(server, c, this); server.getSessionRegistry().add(session); return session; }
public ConsoleManager(GlowServer server, String mode) { this.server = server; if (mode.equalsIgnoreCase("gui")) { JTerminalListener listener = new JTerminalListener(); jFrame = new JFrame("Glowstone"); jTerminal = new JTerminal(); jInput = new JTextField(80) { @Override public void setBorder(Border border) {} }; jInput.paint(null); jInput.setFont(new Font("Monospaced", Font.PLAIN, 12)); jInput.setBackground(Color.BLACK); jInput.setForeground(Color.WHITE); jInput.setMargin(new Insets(0, 0, 0, 0)); jInput.addKeyListener(listener); JLabel caret = new JLabel("> "); caret.setFont(new Font("Monospaced", Font.PLAIN, 12)); caret.setForeground(Color.WHITE); JPanel ipanel = new JPanel(); ipanel.add(caret, BorderLayout.WEST); ipanel.add(jInput, BorderLayout.EAST); ipanel.setBorder(BorderFactory.createEmptyBorder()); ipanel.setBackground(Color.BLACK); ipanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); ipanel.setSize(jTerminal.getWidth(), ipanel.getHeight()); jFrame.getContentPane().add(jTerminal, BorderLayout.NORTH); jFrame.getContentPane().add(ipanel, BorderLayout.SOUTH); jFrame.addWindowListener(listener); jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); jFrame.setLocationRelativeTo(null); jFrame.pack(); jFrame.setVisible(true); } else if (mode.equalsIgnoreCase("jline")) { jLine = true; } consoleHandler = new FancyConsoleHandler(); String logFile = server.getLogFile(); if (new File(logFile).getParentFile() != null) { new File(logFile).getParentFile().mkdirs(); } fileHandler = new RotatingFileHandler(logFile); consoleHandler.setFormatter(new DateOutputFormatter(new SimpleDateFormat("HH:mm:ss"))); fileHandler.setFormatter(new DateOutputFormatter(new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"))); Logger logger = Logger.getLogger(""); for (Handler h : logger.getHandlers()) { logger.removeHandler(h); } logger.addHandler(consoleHandler); logger.addHandler(fileHandler); try { reader = new ConsoleReader(); } catch (IOException ex) { server .getLogger() .log(Level.SEVERE, "Exception inintializing console reader: {0}", ex.getMessage()); ex.printStackTrace(); } Runtime.getRuntime().addShutdownHook(new ServerShutdownThread()); System.setOut(new PrintStream(new LoggerOutputStream(Level.INFO), true)); System.setErr(new PrintStream(new LoggerOutputStream(Level.SEVERE), true)); }