private void buildPerceptions() { playersToRemove.clear(); /** We reset the cache at Perceptions */ MessageS2CPerception.clearPrecomputedPerception(); for (PlayerEntry entry : playerContainer) { try { // Before creating the perception we check the player is still there. if (entry.isTimeout()) { logger.info("Request (TIMEOUT) disconnection of Player " + entry.getAddress()); playersToRemove.add(entry); continue; } if (entry.state == ClientState.GAME_BEGIN) { Perception perception = getPlayerPerception(entry); sendPlayerPerception(entry, perception, entry.object); } } catch (Exception e) { logger.error( "Removing player(" + entry.clientid + ") because it caused a Exception while contacting it", e); playersToRemove.add(entry); } } for (PlayerEntry entry : playersToRemove) { logger.warn("RP Disconnecting entry: " + entry); netMan.disconnectClient(entry.channel); } }
private void sendPlayerPerception( PlayerEntry entry, Perception perception, RPObject playerObject) { if (perception == null) { /** Until player enters game perception is null */ return; } MessageS2CPerception messages2cPerception = new MessageS2CPerception(entry.channel, perception); stats.add("Perceptions " + (perception.type == 0 ? "DELTA" : "SYNC"), 1); /* * The perception is build of two parts: the general information and the * private information about our object. This private information * consists only of attributes that are not visible to every player but * the owner, because visible attributes are already stored in the * perception. */ if (perception.type == Perception.SYNC) { RPObject copy = new RPObject(); copy.fill(playerObject); if (!playerObject.isHidden()) { copy.clearVisible(true); } messages2cPerception.setMyRPObject(copy, null); } else { RPObject added = new RPObject(); RPObject deleted = new RPObject(); try { playerObject.getDifferences(added, deleted); if (!playerObject.isHidden()) { added.clearVisible(false); deleted.clearVisible(false); } if (added.size() == 0) { added = null; } if (deleted.size() == 0) { deleted = null; } } catch (Exception e) { logger.error("Error getting object differences", e); logger.error(playerObject); added = null; deleted = null; } messages2cPerception.setMyRPObject(added, deleted); } messages2cPerception.setClientID(entry.clientid); messages2cPerception.setPerceptionTimestamp(entry.getPerceptionTimestamp()); messages2cPerception.setProtocolVersion(entry.getProtocolVersion()); netMan.sendMessage(messages2cPerception); }
/** * This method disconnects a player from the server. * * @param object the player object that we want to disconnect from world */ public void disconnectPlayer(RPObject object) { PlayerEntry entry = playerContainer.get(object); if (entry == null) { /* * There is no player entry for such channel This is not necesaryly * an error, as the connection could be anything else but an arianne * client or we are just disconnecting a player that logout * correctly. */ logger.warn("There is no PlayerEntry associated to this RPObject."); return; } netMan.disconnectClient(entry.channel); }
private void deliverTransferContent() { synchronized (contentsToTransfer) { for (Map.Entry<RPObject, List<TransferContent>> val : contentsToTransfer.entrySet()) { RPObject target = val.getKey(); List<TransferContent> content = val.getValue(); PlayerEntry entry = playerContainer.get(target); if (entry == null) { logger.warn( "Entry for player (" + target + ") does not exist: " + playerContainer, new Throwable()); continue; } if (content == null) { logger.warn("content is null"); } if (!entry.contentToTransfer.isEmpty()) { // prevent DoS if the client never confirms the Transfer offer if (entry.contentToTransfer.size() > 30) { synchronized (entry.contentToTransfer) { for (int i = 0; i < 10; i++) { entry.contentToTransfer.remove(0); } } } logger.warn( "Adding to existing contentToTransfer for player " + entry.character + " old: " + entry.contentToTransfer + " added " + content); } entry.contentToTransfer.addAll(content); MessageS2CTransferREQ mes = new MessageS2CTransferREQ(entry.channel, content); mes.setClientID(entry.clientid); mes.setProtocolVersion(entry.getProtocolVersion()); netMan.sendMessage(mes); } contentsToTransfer.clear(); } }
/** * This method exposes network layer connection validator so game logic can handle it. * * @return the connection validator */ public ConnectionValidator getValidator() { return netMan.getValidator(); }