Merge pull request #5 from Nemmyz/patch-2

We're doing it exact RSC replica right?
This commit is contained in:
Travis Burtrum 2011-06-21 07:56:03 -07:00
commit 9fa8583303

View File

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