package org.moparscape.msc.gs.core; import java.util.ArrayList; import java.util.List; import org.moparscape.msc.gs.Instance; import org.moparscape.msc.gs.builders.GameObjectPositionPacketBuilder; import org.moparscape.msc.gs.builders.ItemPositionPacketBuilder; import org.moparscape.msc.gs.builders.NpcPositionPacketBuilder; import org.moparscape.msc.gs.builders.NpcUpdatePacketBuilder; import org.moparscape.msc.gs.builders.PlayerPositionPacketBuilder; import org.moparscape.msc.gs.builders.PlayerUpdatePacketBuilder; import org.moparscape.msc.gs.builders.WallObjectPositionPacketBuilder; import org.moparscape.msc.gs.connection.RSCPacket; import org.moparscape.msc.gs.model.ChatMessage; import org.moparscape.msc.gs.model.Npc; import org.moparscape.msc.gs.model.Player; import org.moparscape.msc.gs.model.World; import org.moparscape.msc.gs.model.snapshot.Chatlog; import org.moparscape.msc.gs.tools.DataConversions; import org.moparscape.msc.gs.util.EntityList; import org.moparscape.msc.gs.util.Logger; import org.moparscape.msc.gs.util.Processor; public final class ClientUpdater implements Processor { public static int pktcount = 0; private static World world = Instance.getWorld(); private GameObjectPositionPacketBuilder gameObjectPositionBuilder = new GameObjectPositionPacketBuilder(); private ItemPositionPacketBuilder itemPositionBuilder = new ItemPositionPacketBuilder(); private NpcUpdatePacketBuilder npcApperanceBuilder = new NpcUpdatePacketBuilder(); private NpcPositionPacketBuilder npcPositionPacketBuilder = new NpcPositionPacketBuilder(); private EntityList npcs = world.getNpcs(); private PlayerUpdatePacketBuilder playerApperanceBuilder = new PlayerUpdatePacketBuilder(); private PlayerPositionPacketBuilder playerPositionBuilder = new PlayerPositionPacketBuilder(); private WallObjectPositionPacketBuilder wallObjectPositionPacketBuilder = new WallObjectPositionPacketBuilder(); private EntityList players = world.getPlayers(); public ClientUpdater() { world.setClientUpdater(this); } /** * Sends queued packets to each player */ public void sendQueuedPackets() { try { for (Player p : players) { List packets = p.getActionSender().getPackets(); for (RSCPacket packet : packets) { p.getSession().write(packet); } p.getActionSender().clearPackets(); if (p.destroyed()) { p.getSession().close(); p.remove(); } } } catch (Exception e) { e.printStackTrace(); } } /** * Update player/npc appearances, game objects, items, wall objects, ping */ public void doMinor() { for (Player p : players) { p.updateAppearanceID(); } for (Player p : players) { if (p.isFirstMajorUpdateSent()) { updatePlayerApperances(p); } updateNpcApperances(p); } for (Player p : players) { if (p.isFirstMajorUpdateSent()) { p.setAppearnceChanged(false); p.clearProjectilesNeedingDisplayed(); p.clearPlayersNeedingHitsUpdate(); p.clearNpcsNeedingHitsUpdate(); p.clearChatMessagesNeedingDisplayed(); p.clearNpcMessagesNeedingDisplayed(); p.clearBubblesNeedingDisplayed(); } } for (Npc n : npcs) { n.setAppearnceChanged(false); } } public static boolean threaded = false; public volatile boolean updatingCollections; public void doMajor() { Long delay; Long now = System.currentTimeMillis(); updateNpcPositions(); delay = System.currentTimeMillis() - now; if (delay > 299) Logger.println("updateNpcPositions() is taking longer than it should, exactly " + delay + "ms"); now = System.currentTimeMillis(); updatePlayersPositions(); delay = System.currentTimeMillis() - now; if (delay > 299) Logger.println("updatePlayersPositions() is taking longer than it should, exactly " + delay + "ms"); now = System.currentTimeMillis(); updateMessageQueues(); delay = System.currentTimeMillis() - now; if (delay > 299) Logger.println("updateMessageQueues() is taking longer than it should, exactly " + delay + "ms"); now = System.currentTimeMillis(); updateOffers(); for (Player p : players) { // Logging.debug("Process for player " + p.getUsername() + // " | threaded: " + threaded); updateTimeouts(p); updatePlayerPositions(p); updateNpcPositions(p); updateGameObjects(p); updateWallObjects(p); updateItems(p); p.setFirstMajorUpdateSent(true); } updateCollections(); } public void process(Player p) { // Logging.debug("Process for player " + p.getUsername() + // " | threaded: " + threaded); updateTimeouts(p); updatePlayerPositions(p); // Must be done before updating any // objects/items/npcs! updateNpcPositions(p); updateGameObjects(p); updateWallObjects(p); updateItems(p); p.setFirstMajorUpdateSent(true); } /** * Updates collections, new becomes known, removing is removed etc. */ public void updateCollections() { updatingCollections = true; for (Player p : players) { if (p.isRemoved() && p.initialized()) { world.unregisterPlayer(p); } } for (Player p : players) { p.getWatchedPlayers().update(); p.getWatchedObjects().update(); p.getWatchedItems().update(); p.getWatchedNpcs().update(); // p.clearProjectilesNeedingDisplayed(); // p.clearPlayersNeedingHitsUpdate(); // p.clearNpcsNeedingHitsUpdate(); // p.clearChatMessagesNeedingDisplayed(); // p.clearNpcMessagesNeedingDisplayed(); // p.clearBubblesNeedingDisplayed(); p.resetSpriteChanged(); // p.setAppearnceChanged(false); } for (Npc n : npcs) { n.resetSpriteChanged(); // n.setAppearnceChanged(false); } updatingCollections = false; } /** * Sends updates for game objects to the given player */ private void updateGameObjects(Player p) { gameObjectPositionBuilder.setPlayer(p); RSCPacket temp = gameObjectPositionBuilder.getPacket(); if (temp != null) { p.getActionSender().addPacket(temp); // p.getSession().write(temp); } } /** * Sends updates for game items to the given player */ private void updateItems(Player p) { itemPositionBuilder.setPlayer(p); RSCPacket temp = itemPositionBuilder.getPacket(); if (temp != null) { p.getActionSender().addPacket(temp); // p.getSession().write(temp); } } /** * Updates the messages queues for each player */ private void updateMessageQueues() { for (Player sender : players) { ChatMessage message = sender.getNextChatMessage(); if (message == null || !sender.loggedIn()) { continue; } String s = DataConversions.byteToString(message.getMessage(), 0, message.getMessage().length); s = s.toLowerCase(); String k = s; s = s.replace(" ", ""); s = s.replace(".", ""); if (s.contains("#adm#") || s.contains("#mod#") || s.contains("#pmd#")) { sender.getActionSender() .sendMessage( "@red@Your last message was not sent out due to an illegal string"); return; } if (sender.isMuted()) { sender.getActionSender().sendMessage( "You are muted, you cannot send messages"); return; } List recievers = sender.getViewArea().getPlayersInView(); ArrayList recieverUsernames = new ArrayList(); for (Player p : recievers) recieverUsernames.add(p.getUsername()); world.addEntryToSnapshots(new Chatlog(sender.getUsername(), k, recieverUsernames)); for (Player recipient : recievers) { if (sender.getIndex() == recipient.getIndex() || !recipient.loggedIn()) { continue; } if (recipient.getPrivacySetting(0) && !recipient.isFriendsWith(sender.getUsernameHash()) && !sender.isPMod()) { continue; } if (recipient.isIgnoring(sender.getUsernameHash()) && !sender.isPMod()) { continue; } recipient.informOfChatMessage(message); } recievers = null; } } /** * Update appearance of any npcs the given player should be aware of */ private void updateNpcApperances(Player p) { npcApperanceBuilder.setPlayer(p); RSCPacket temp = npcApperanceBuilder.getPacket(); if (temp != null) { p.getActionSender().addPacket(temp); // p.getSession().write(temp); } } /** * Update the position of npcs, and check if who (and what) they are aware * of needs updated */ private void updateNpcPositions() { for (Npc n : npcs) { n.resetMoved(); n.updatePosition(); n.updateAppearanceID(); } } /** * Sends updates for npcs to the given player */ private void updateNpcPositions(Player p) { npcPositionPacketBuilder.setPlayer(p); RSCPacket temp = npcPositionPacketBuilder.getPacket(); if (temp != null) { p.getActionSender().addPacket(temp); // p.getSession().write(temp); } } public void updateOffers() { for (Player player : players) { if (!player.requiresOfferUpdate()) { continue; } player.setRequiresOfferUpdate(false); if (player.isTrading()) { Player affectedPlayer = player.getWishToTrade(); if (affectedPlayer == null) { continue; } affectedPlayer.getActionSender().sendTradeItems(); } else if (player.isDueling()) { Player affectedPlayer = player.getWishToDuel(); if (affectedPlayer == null) { continue; } player.getActionSender().sendDuelSettingUpdate(); affectedPlayer.getActionSender().sendDuelSettingUpdate(); affectedPlayer.getActionSender().sendDuelItems(); } } } /** * Update appearance of the given player, and any players they should be * aware of */ private void updatePlayerApperances(Player p) { playerApperanceBuilder.setPlayer(p); RSCPacket temp = playerApperanceBuilder.getPacket(); if (temp != null) { p.getActionSender().addPacket(temp); // p.getSession().write(temp); } } /** * Update positions of the given player, and any players they should be * aware of */ private void updatePlayerPositions(Player p) { playerPositionBuilder.setPlayer(p); RSCPacket temp = playerPositionBuilder.getPacket(); if (temp != null) { p.getActionSender().addPacket(temp); // p.getSession().write(temp); } } /** * Update the position of players, and check if who (and what) they are * aware of needs updated */ private void updatePlayersPositions() { for (Player p : players) { p.resetMoved(); p.updatePosition(); p.updateAppearanceID(); } for (Player p : players) { p.revalidateWatchedPlayers(); p.revalidateWatchedObjects(); p.revalidateWatchedItems(); p.revalidateWatchedNpcs(); p.updateViewedPlayers(); p.updateViewedObjects(); p.updateViewedItems(); p.updateViewedNpcs(); } } /** * Checks the player has moved within the last 5mins */ private void updateTimeouts(Player p) { if (p.destroyed()) { return; } long curTime = GameEngine.getTime(); if (curTime - p.getLastPing() >= 30000) { p.destroy(false); } else if (p.warnedToMove()) { if (curTime - p.getLastMoved() >= 960000 && p.loggedIn()) { p.destroy(false); } } else if (curTime - p.getLastMoved() >= 900000) { p.getActionSender() .sendMessage( "@cya@You have not moved for 15 mins, please move to a new area to avoid logout."); p.warnToMove(); } } /** * Sends updates for wall objects to the given player */ private void updateWallObjects(Player p) { wallObjectPositionPacketBuilder.setPlayer(p); RSCPacket temp = wallObjectPositionPacketBuilder.getPacket(); if (temp != null) { // p.getSession().write(temp); p.getActionSender().addPacket(temp); } } }