Simplify how the change notification is done in HallServer.

This commit is contained in:
marcins78
2013-01-18 16:31:53 +00:00
parent 51571c8f55
commit 411086adc3
3 changed files with 75 additions and 123 deletions

View File

@@ -445,7 +445,7 @@ public class HallRequestHandler extends LotroServerRequestHandler implements Uri
@Override
public boolean isChanged() {
try {
return _hallServer.getCommunicationChannel(_resourceOwner, _channelNumber).hasChangesInCommunicationChannel(_hallServer, _resourceOwner);
return _hallServer.getCommunicationChannel(_resourceOwner, _channelNumber).hasChangesInCommunicationChannel();
} catch (SubscriptionExpiredException e) {
return true;
} catch (SubscriptionConflictException e) {

View File

@@ -2,7 +2,6 @@ package com.gempukku.lotro.hall;
import com.gempukku.lotro.game.Player;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.mutable.MutableBoolean;
import org.apache.commons.lang.mutable.MutableObject;
import java.util.*;
@@ -15,11 +14,16 @@ public class HallCommunicationChannel {
private Map<String, Map<String, String>> _tournamentPropsOnClient = new LinkedHashMap<String, Map<String, String>>();
private Map<String, Map<String, String>> _tablePropsOnClient = new LinkedHashMap<String, Map<String, String>>();
private Set<String> _playedGames = new HashSet<String>();
private boolean _changed;
public HallCommunicationChannel(int channelNumber) {
_channelNumber = channelNumber;
}
public synchronized void hallChanged() {
_changed = true;
}
public int getChannelNumber() {
return _channelNumber;
}
@@ -32,116 +36,10 @@ public class HallCommunicationChannel {
return _lastConsumed;
}
public synchronized boolean hasChangesInCommunicationChannel(HallServer hallServer, final Player player) {
public synchronized boolean hasChangesInCommunicationChannel() {
updateLastAccess();
final MutableObject newMotd = new MutableObject();
final Map<String, Map<String, String>> tournamentQueuesOnServer = new LinkedHashMap<String, Map<String, String>>();
final Map<String, Map<String, String>> tablesOnServer = new LinkedHashMap<String, Map<String, String>>();
final Map<String, Map<String, String>> tournamentsOnServer = new LinkedHashMap<String, Map<String, String>>();
final MutableBoolean hasNewGames = new MutableBoolean(false);
hallServer.processHall(player,
new HallInfoVisitor() {
@Override
public void serverTime(String time) {
}
@Override
public void motd(String motd) {
newMotd.setValue(motd);
}
@Override
public void visitTable(String tableId, String gameId, boolean watchable, TableStatus status, String statusDescription, String formatName, String tournamentName, List<String> playerIds, String winner) {
Map<String, String> props = new HashMap<String, String>();
props.put("gameId", gameId);
props.put("watchable", String.valueOf(watchable));
props.put("status", String.valueOf(status));
props.put("statusDescription", statusDescription);
props.put("format", formatName);
props.put("tournament", tournamentName);
props.put("players", StringUtils.join(playerIds, ","));
props.put("playing", String.valueOf(playerIds.contains(player.getName())));
if (winner != null)
props.put("winner", winner);
tablesOnServer.put(tableId, props);
}
@Override
public void visitTournamentQueue(String tournamentQueueKey, int cost, String collectionName, String formatName, String tournamentQueueName,
String tournamentPrizes, String pairingDescription, String startCondition, int playerCount, boolean playerSignedUp, boolean joinable) {
Map<String, String> props = new HashMap<String, String>();
props.put("cost", String.valueOf(cost));
props.put("collection", collectionName);
props.put("format", formatName);
props.put("queue", tournamentQueueName);
props.put("playerCount", String.valueOf(playerCount));
props.put("prizes", tournamentPrizes);
props.put("system", pairingDescription);
props.put("start", startCondition);
props.put("signedUp", String.valueOf(playerSignedUp));
props.put("joinable", String.valueOf(joinable));
tournamentQueuesOnServer.put(tournamentQueueKey, props);
}
@Override
public void visitTournament(String tournamentKey, String collectionName, String formatName, String tournamentName, String pairingDescription,
String tournamentStage, int round, int playerCount, boolean playerInCompetition) {
Map<String, String> props = new HashMap<String, String>();
props.put("collection", collectionName);
props.put("format", formatName);
props.put("name", tournamentName);
props.put("system", pairingDescription);
props.put("stage", tournamentStage);
props.put("round", String.valueOf(round));
props.put("playerCount", String.valueOf(playerCount));
props.put("signedUp", String.valueOf(playerInCompetition));
tournamentsOnServer.put(tournamentKey, props);
}
@Override
public void runningPlayerGame(String gameId) {
if (!_playedGames.contains(gameId))
hasNewGames.setValue(true);
}
});
if (hasNewGames.booleanValue())
return true;
if (newMotd.getValue() != null && !newMotd.getValue().equals(_lastMotd))
return true;
if (_tournamentQueuePropsOnClient.size() != tournamentQueuesOnServer.size())
return true;
if (_tournamentPropsOnClient.size() != tournamentsOnServer.size())
return true;
if (_tablePropsOnClient.size() != tablesOnServer.size())
return true;
for (Map.Entry<String, Map<String, String>> tournamentQueuePropsOnClientPair: _tournamentQueuePropsOnClient.entrySet()){
if (!tournamentQueuePropsOnClientPair.getValue().equals(tournamentQueuesOnServer.get(tournamentQueuePropsOnClientPair.getKey())))
return true;
}
for (Map.Entry<String, Map<String, String>> tournamentPropsOnClientPair: _tournamentPropsOnClient.entrySet()){
if (!tournamentPropsOnClientPair.getValue().equals(tournamentQueuesOnServer.get(tournamentPropsOnClientPair.getKey())))
return true;
}
for (Map.Entry<String, Map<String, String>> tablePropsOnClientPair : _tablePropsOnClient.entrySet()){
if (!tablePropsOnClientPair.getValue().equals(tablesOnServer.get(tablePropsOnClientPair.getKey())))
return true;
}
return false;
return _changed;
}
public synchronized void processCommunicationChannel(HallServer hallServer, final Player player, final HallChannelVisitor hallChannelVisitor) {
@@ -244,6 +142,8 @@ public class HallCommunicationChannel {
hallChannelVisitor.newPlayerGame(gameId);
}
_playedGames = playedGamesOnServer;
_changed = false;
}
private void notifyAboutTables(HallChannelVisitor hallChannelVisitor, Map<String, Map<String, String>> tablesOnServer) {

View File

@@ -60,6 +60,7 @@ public class HallServer extends AbstractServer {
private Map<String, TournamentQueue> _tournamentQueues = new LinkedHashMap<String, TournamentQueue>();
private final ChatRoomMediator _hallChat;
private final GameResultListener _notifyHallListeners = new NotifyHallListenersGameResultListener();
public HallServer(LotroServer lotroServer, ChatServer chatServer, LeagueService leagueService, TournamentService tournamentService, LotroCardBlueprintLibrary library,
LotroFormatLibrary formatLibrary, CollectionsManager collectionsManager, TournamentPrizeSchemeRegistry tournamentPrizeSchemeRegistry,
@@ -106,6 +107,11 @@ public class HallServer extends AbstractServer {
}
}
private void hallChanged() {
for (HallCommunicationChannel hallCommunicationChannel : _playerChannelCommunication.values())
hallCommunicationChannel.hallChanged();
}
@Override
protected void doAfterStartup() {
for (Tournament tournament : _tournamentService.getLiveTournaments())
@@ -120,6 +126,7 @@ public class HallServer extends AbstractServer {
cancelWaitingTables();
cancelTournamentQueues();
_chatServer.sendSystemMessageToAllChatRooms("System is entering shutdown mode and will be restarted when all games are finished");
hallChanged();
}
} finally {
_hallDataAccessLock.writeLock().unlock();
@@ -127,13 +134,19 @@ public class HallServer extends AbstractServer {
}
public void setMOTD(String motd) {
_motd = motd;
_hallDataAccessLock.writeLock().lock();
try {
_motd = motd;
hallChanged();
} finally {
_hallDataAccessLock.writeLock().unlock();
}
}
public int getTablesCount() {
_hallDataAccessLock.readLock().lock();
try {
return _awaitingTables.size() + _runningTables.size();
return _runningTables.size();
} finally {
_hallDataAccessLock.readLock().unlock();
}
@@ -192,6 +205,7 @@ public class HallServer extends AbstractServer {
_awaitingTables.put(tableId, table);
joinTableInternal(tableId, player.getName(), table, lotroDeck);
hallChanged();
} finally {
_hallDataAccessLock.writeLock().unlock();
}
@@ -233,6 +247,8 @@ public class HallServer extends AbstractServer {
tournamentQueue.joinPlayer(_collectionsManager, player, lotroDeck);
hallChanged();
return true;
} finally {
_hallDataAccessLock.writeLock().unlock();
@@ -262,6 +278,8 @@ public class HallServer extends AbstractServer {
joinTableInternal(tableId, player.getName(), awaitingTable, lotroDeck);
hallChanged();
return true;
} finally {
_hallDataAccessLock.writeLock().unlock();
@@ -272,20 +290,26 @@ public class HallServer extends AbstractServer {
_hallDataAccessLock.writeLock().lock();
try {
TournamentQueue tournamentQueue = _tournamentQueues.get(queueId);
if (tournamentQueue != null && tournamentQueue.isPlayerSignedUp(player.getName()))
if (tournamentQueue != null && tournamentQueue.isPlayerSignedUp(player.getName())) {
tournamentQueue.leavePlayer(_collectionsManager, player);
hallChanged();
}
} finally {
_hallDataAccessLock.writeLock().unlock();
}
}
private void leaveQueues(Player player) {
private boolean leaveQueuesForLeavingPlayer(Player player) {
_hallDataAccessLock.writeLock().lock();
try {
boolean result = false;
for (TournamentQueue tournamentQueue : _tournamentQueues.values()) {
if (tournamentQueue.isPlayerSignedUp(player.getName()))
if (tournamentQueue.isPlayerSignedUp(player.getName())) {
tournamentQueue.leavePlayer(_collectionsManager, player);
result = true;
}
}
return result;
} finally {
_hallDataAccessLock.writeLock().unlock();
}
@@ -295,8 +319,10 @@ public class HallServer extends AbstractServer {
_hallDataAccessLock.writeLock().lock();
try {
Tournament tournament = _runningTournaments.get(tournamentId);
if (tournament != null)
if (tournament != null) {
tournament.dropPlayer(player.getName());
hallChanged();
}
} finally {
_hallDataAccessLock.writeLock().unlock();
}
@@ -399,23 +425,27 @@ public class HallServer extends AbstractServer {
boolean empty = table.removePlayer(player.getName());
if (empty)
_awaitingTables.remove(tableId);
hallChanged();
}
} finally {
_hallDataAccessLock.writeLock().unlock();
}
}
public void leaveAwaitingTables(Player player) {
public boolean leaveAwaitingTablesForLeavingPlayer(Player player) {
_hallDataAccessLock.writeLock().lock();
try {
boolean result = false;
Map<String, AwaitingTable> copy = new HashMap<String, AwaitingTable>(_awaitingTables);
for (Map.Entry<String, AwaitingTable> table : copy.entrySet()) {
if (table.getValue().hasPlayer(player.getName())) {
boolean empty = table.getValue().removePlayer(player.getName());
if (empty)
_awaitingTables.remove(table.getKey());
result = true;
}
}
return result;
} finally {
_hallDataAccessLock.writeLock().unlock();
}
@@ -432,7 +462,7 @@ public class HallServer extends AbstractServer {
}
}
public HallCommunicationChannel getCommunicationChannel(Player player, int channelNumber) throws SubscriptionExpiredException, SubscriptionConflictException {
public HallCommunicationChannel getCommunicationChannel(Player player, int channelNumber) throws SubscriptionExpiredException, SubscriptionConflictException {
_hallDataAccessLock.readLock().lock();
try {
HallCommunicationChannel communicationChannel = _playerChannelCommunication.get(player);
@@ -625,9 +655,22 @@ public class HallServer extends AbstractServer {
if (listener != null)
lotroGameMediator.addGameResultListener(listener);
lotroGameMediator.startGame();
lotroGameMediator.addGameResultListener(_notifyHallListeners);
_runningTables.put(tableId, new RunningTable(gameId, lotroFormat.getName(), tournamentName, league, leagueSerie));
}
private class NotifyHallListenersGameResultListener implements GameResultListener {
@Override
public void gameCancelled() {
hallChanged();
}
@Override
public void gameFinished(String winnerPlayerId, String winReason, Map<String, String> loserPlayerIdsWithReasons) {
hallChanged();
}
}
private void joinTableInternal(String tableId, String player, AwaitingTable awaitingTable, LotroDeck lotroDeck) throws HallException {
League league = awaitingTable.getLeague();
if (league != null) {
@@ -651,8 +694,10 @@ public class HallServer extends AbstractServer {
// Remove finished games
HashMap<String, RunningTable> copy = new HashMap<String, RunningTable>(_runningTables);
for (Map.Entry<String, RunningTable> runningTable : copy.entrySet()) {
if (_lotroServer.getGameById(runningTable.getValue().getGameId()) == null)
if (_lotroServer.getGameById(runningTable.getValue().getGameId()) == null) {
_runningTables.remove(runningTable.getKey());
hallChanged();
}
}
long currentTime = System.currentTimeMillis();
@@ -661,8 +706,10 @@ public class HallServer extends AbstractServer {
if (currentTime > lastVisitedPlayer.getValue().getLastAccessed() + _playerInactivityPeriod) {
Player player = lastVisitedPlayer.getKey();
_playerChannelCommunication.remove(player);
leaveAwaitingTables(player);
leaveQueues(player);
boolean leftTables = leaveAwaitingTablesForLeavingPlayer(player);
boolean leftQueues = leaveQueuesForLeavingPlayer(player);
if (leftTables || leftQueues)
hallChanged();
}
}
@@ -671,15 +718,19 @@ public class HallServer extends AbstractServer {
TournamentQueue tournamentQueue = runningTournamentQueue.getValue();
HallTournamentQueueCallback queueCallback = new HallTournamentQueueCallback();
// If it's finished, remove it
if (tournamentQueue.process(queueCallback, _collectionsManager))
if (tournamentQueue.process(queueCallback, _collectionsManager)) {
_tournamentQueues.remove(tournamentQueueKey);
hallChanged();
}
}
for (Map.Entry<String, Tournament> tournamentEntry : new HashMap<String, Tournament>(_runningTournaments).entrySet()) {
Tournament runningTournament = tournamentEntry.getValue();
runningTournament.advanceTournament(new HallTournamentCallback(runningTournament), _collectionsManager);
if (runningTournament.getTournamentStage() == Tournament.Stage.FINISHED)
if (runningTournament.getTournamentStage() == Tournament.Stage.FINISHED) {
_runningTournaments.remove(tournamentEntry.getKey());
hallChanged();
}
}
if (_tickCounter == 60) {
@@ -695,6 +746,7 @@ public class HallServer extends AbstractServer {
_pairingMechanismRegistry.getPairingMechanism(unstartedTournamentQueue.getPlayOffSystem()),
_tournamentPrizeSchemeRegistry.getTournamentPrizes(unstartedTournamentQueue.getPrizeScheme()), unstartedTournamentQueue.getMinimumPlayers());
_tournamentQueues.put(scheduledTournamentId, scheduledQueue);
hallChanged();
}
}
}