Fixing multi-threading issues.

This commit is contained in:
marcins78@gmail.com
2012-07-17 09:40:54 +00:00
parent 8edb3a06d8
commit ef9b267b8e
16 changed files with 292 additions and 217 deletions

View File

@@ -5,6 +5,8 @@ import com.gempukku.lotro.game.GatheringChatRoomListener;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ChatRoomMediator {
private ChatRoom _chatRoom = new ChatRoom();
@@ -14,6 +16,8 @@ public class ChatRoomMediator {
private int _channelInactivityTimeoutPeriod = 1000 * 10; // 10 seconds
private Set<String> _allowedPlayers;
private ReadWriteLock _lock = new ReentrantReadWriteLock();
public ChatRoomMediator(int secondsTimeoutPeriod) {
this(secondsTimeoutPeriod, null);
}
@@ -23,46 +27,76 @@ public class ChatRoomMediator {
_channelInactivityTimeoutPeriod = 1000 * secondsTimeoutPeriod;
}
public synchronized List<ChatMessage> joinUser(String playerId) {
GatheringChatRoomListener value = new GatheringChatRoomListener();
_listeners.put(playerId, value);
_chatRoom.joinChatRoom(playerId, value);
return value.consumeMessages();
}
public synchronized List<ChatMessage> getPendingMessages(String playerId) {
GatheringChatRoomListener gatheringChatRoomListener = _listeners.get(playerId);
if (gatheringChatRoomListener == null)
throw new WebApplicationException(Response.Status.NOT_FOUND);
return gatheringChatRoomListener.consumeMessages();
}
public synchronized void partUser(String playerId) {
_chatRoom.partChatRoom(playerId);
_listeners.remove(playerId);
}
public synchronized void sendMessage(String playerId, String message, boolean admin) {
if (!admin && _allowedPlayers != null && !_allowedPlayers.contains(playerId))
throw new WebApplicationException(Response.Status.FORBIDDEN);
_chatRoom.postMessage(playerId, message);
}
public synchronized void cleanup() {
long currentTime = System.currentTimeMillis();
Map<String, GatheringChatRoomListener> copy = new HashMap<String, GatheringChatRoomListener>(_listeners);
for (Map.Entry<String, GatheringChatRoomListener> playerListener : copy.entrySet()) {
String playerId = playerListener.getKey();
GatheringChatRoomListener listener = playerListener.getValue();
if (currentTime > listener.getLastConsumed().getTime() + _channelInactivityTimeoutPeriod) {
_chatRoom.partChatRoom(playerId);
_listeners.remove(playerId);
}
public List<ChatMessage> joinUser(String playerId) {
_lock.writeLock();
try {
GatheringChatRoomListener value = new GatheringChatRoomListener();
_listeners.put(playerId, value);
_chatRoom.joinChatRoom(playerId, value);
return value.consumeMessages();
} finally {
_lock.writeLock().unlock();
}
}
public synchronized Collection<String> getUsersInRoom() {
return _chatRoom.getUsersInRoom();
public List<ChatMessage> getPendingMessages(String playerId) {
_lock.readLock().lock();
try {
GatheringChatRoomListener gatheringChatRoomListener = _listeners.get(playerId);
if (gatheringChatRoomListener == null)
throw new WebApplicationException(Response.Status.NOT_FOUND);
return gatheringChatRoomListener.consumeMessages();
} finally {
_lock.readLock().unlock();
}
}
public void partUser(String playerId) {
_lock.writeLock().lock();
try {
_chatRoom.partChatRoom(playerId);
_listeners.remove(playerId);
} finally {
_lock.writeLock().unlock();
}
}
public void sendMessage(String playerId, String message, boolean admin) {
_lock.writeLock().lock();
try {
if (!admin && _allowedPlayers != null && !_allowedPlayers.contains(playerId))
throw new WebApplicationException(Response.Status.FORBIDDEN);
_chatRoom.postMessage(playerId, message);
} finally {
_lock.writeLock().unlock();
}
}
public void cleanup() {
_lock.writeLock().lock();
try {
long currentTime = System.currentTimeMillis();
Map<String, GatheringChatRoomListener> copy = new HashMap<String, GatheringChatRoomListener>(_listeners);
for (Map.Entry<String, GatheringChatRoomListener> playerListener : copy.entrySet()) {
String playerId = playerListener.getKey();
GatheringChatRoomListener listener = playerListener.getValue();
if (currentTime > listener.getLastConsumed().getTime() + _channelInactivityTimeoutPeriod) {
_chatRoom.partChatRoom(playerId);
_listeners.remove(playerId);
}
}
} finally {
_lock.writeLock().unlock();
}
}
public Collection<String> getUsersInRoom() {
_lock.readLock().lock();
try {
return _chatRoom.getUsersInRoom();
} finally {
_lock.readLock().unlock();
}
}
}

View File

@@ -1,5 +1,6 @@
package com.gempukku.lotro.collection;
import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.db.CollectionDAO;
import com.gempukku.lotro.db.PlayerDAO;
import com.gempukku.lotro.db.vo.CollectionType;
@@ -10,6 +11,7 @@ import java.io.IOException;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class CollectionsManager {
@@ -20,10 +22,53 @@ public class CollectionsManager {
private CollectionDAO _collectionDAO;
private DeliveryService _deliveryService;
public CollectionsManager(PlayerDAO playerDAO, CollectionDAO collectionDAO, DeliveryService deliveryService) {
private CountDownLatch _collectionReadyLatch = new CountDownLatch(1);
private DefaultCardCollection _defaultCollection;
public CollectionsManager(PlayerDAO playerDAO, CollectionDAO collectionDAO, DeliveryService deliveryService, final LotroCardBlueprintLibrary lotroCardBlueprintLibrary) {
_playerDAO = playerDAO;
_collectionDAO = collectionDAO;
_deliveryService = deliveryService;
_defaultCollection = new DefaultCardCollection();
// Hunters have 1-194 normal cards, 9 "O" cards, and 3 extra to cover the different culture versions of 15_60
Thread thr = new Thread() {
public void run() {
final int[] cardCounts = new int[]{129, 365, 122, 122, 365, 128, 128, 365, 122, 52, 122, 266, 203, 203, 15, 207, 6, 157, 149, 40};
for (int i = 0; i <= 19; i++) {
System.out.println("Loading set " + i);
for (int j = 1; j <= cardCounts[i]; j++) {
String blueprintId = i + "_" + j;
try {
if (lotroCardBlueprintLibrary.getBaseBlueprintId(blueprintId).equals(blueprintId)) {
LotroCardBlueprint cardBlueprint = lotroCardBlueprintLibrary.getLotroCardBlueprint(blueprintId);
CardType cardType = cardBlueprint.getCardType();
if (cardType == CardType.SITE || cardType == CardType.THE_ONE_RING)
_defaultCollection.addItem(blueprintId, 1);
else
_defaultCollection.addItem(blueprintId, 4);
}
} catch (IllegalArgumentException exp) {
}
}
}
_collectionReadyLatch.countDown();
}
};
thr.start();
}
public CardCollection getDefaultCollection() {
try {
_collectionReadyLatch.await();
} catch (InterruptedException exp) {
throw new RuntimeException("Error while awaiting loading a default colleciton", exp);
}
return _defaultCollection;
}
public void clearDBCache() {
@@ -36,6 +81,9 @@ public class CollectionsManager {
if (collectionType.contains("+"))
return createSumCollection(player, collectionType.split("\\+"));
if (collectionType.equals("default"))
return getDefaultCollection();
Map<String, CardCollection> playerCollections = _collections.get(player.getName());
if (playerCollections != null) {
final CardCollection cardCollection = playerCollections.get(collectionType);

View File

@@ -23,11 +23,11 @@ public class DeckDAO {
_library = library;
}
public void clearCache() {
public synchronized void clearCache() {
_decks.clear();
}
public LotroDeck getDeckForPlayer(Player player, String name) {
public synchronized LotroDeck getDeckForPlayer(Player player, String name) {
Map<String, LotroDeck> deckMap = getPlayerDecks(player);
return deckMap.get(name);
}
@@ -59,7 +59,7 @@ public class DeckDAO {
return deck;
}
public Set<String> getPlayerDeckNames(Player player) {
public synchronized Set<String> getPlayerDeckNames(Player player) {
return Collections.unmodifiableSet(getPlayerDecks(player).keySet());
}
@@ -137,7 +137,7 @@ public class DeckDAO {
// }
// }
public LotroDeck buildDeckFromContents(String deckName, String contents) {
public synchronized LotroDeck buildDeckFromContents(String deckName, String contents) {
if (contents.contains("|")) {
return DeckSerialization.buildDeckFromContents(deckName, contents);
} else {

View File

@@ -21,12 +21,12 @@ public class PlayerDAO {
_dbAccess = dbAccess;
}
public void clearCache() {
public synchronized void clearCache() {
_playersByName.clear();
_playersById.clear();
}
public Player getPlayer(int id) {
public synchronized Player getPlayer(int id) {
if (_playersById.containsKey(id))
return _playersById.get(id);
@@ -40,7 +40,7 @@ public class PlayerDAO {
}
}
public Player getPlayer(String playerName) {
public synchronized Player getPlayer(String playerName) {
if (_playersByName.containsKey(playerName))
return _playersByName.get(playerName);
try {
@@ -53,7 +53,7 @@ public class PlayerDAO {
}
}
public Player loginUser(String login, String password) throws SQLException {
public synchronized Player loginUser(String login, String password) throws SQLException {
Connection conn = _dbAccess.getDataSource().getConnection();
try {
PreparedStatement statement = conn.prepareStatement("select id, name, type, last_login_reward from player where name=? and password=?");
@@ -84,7 +84,7 @@ public class PlayerDAO {
}
}
public void setLastReward(Player player, int currentReward) throws SQLException {
public synchronized void setLastReward(Player player, int currentReward) throws SQLException {
Connection conn = _dbAccess.getDataSource().getConnection();
try {
PreparedStatement statement = conn.prepareStatement("update player set last_login_reward =? where id=?");
@@ -101,7 +101,7 @@ public class PlayerDAO {
}
}
public boolean updateLastReward(Player player, int previousReward, int currentReward) throws SQLException {
public synchronized boolean updateLastReward(Player player, int previousReward, int currentReward) throws SQLException {
Connection conn = _dbAccess.getDataSource().getConnection();
try {
PreparedStatement statement = conn.prepareStatement("update player set last_login_reward =? where id=? and last_login_reward=?");

View File

@@ -17,11 +17,13 @@ public class DefaultCardCollection implements MutableCardCollection {
_currency = cardCollection.getCurrency();
}
public void addCurrency(int currency) {
@Override
public synchronized void addCurrency(int currency) {
_currency += currency;
}
public boolean removeCurrency(int currency) {
@Override
public synchronized boolean removeCurrency(int currency) {
if (_currency < currency)
return false;
_currency -= currency;
@@ -29,12 +31,12 @@ public class DefaultCardCollection implements MutableCardCollection {
}
@Override
public int getCurrency() {
public synchronized int getCurrency() {
return _currency;
}
@Override
public void addItem(String itemId, int toAdd) {
public synchronized void addItem(String itemId, int toAdd) {
Item oldCount = _counts.get(itemId);
if (oldCount == null)
_counts.put(itemId, Item.createItem(itemId, toAdd));
@@ -43,7 +45,7 @@ public class DefaultCardCollection implements MutableCardCollection {
}
@Override
public boolean removeItem(String itemId, int toRemove) {
public synchronized boolean removeItem(String itemId, int toRemove) {
Item oldCount = _counts.get(itemId);
if (oldCount == null || oldCount.getCount() < toRemove)
return false;
@@ -54,14 +56,6 @@ public class DefaultCardCollection implements MutableCardCollection {
return true;
}
private boolean hasSelection(String packId, String selection, PacksStorage packsStorage) {
for (Item item : packsStorage.openPack(packId)) {
if (item.getBlueprintId().equals(selection))
return true;
}
return false;
}
@Override
public synchronized CardCollection openPack(String packId, String selection, PacksStorage packsStorage) {
Item count = _counts.get(packId);
@@ -96,15 +90,23 @@ public class DefaultCardCollection implements MutableCardCollection {
}
@Override
public Map<String, Item> getAll() {
public synchronized Map<String, Item> getAll() {
return Collections.unmodifiableMap(_counts);
}
@Override
public int getItemCount(String blueprintId) {
public synchronized int getItemCount(String blueprintId) {
Item count = _counts.get(blueprintId);
if (count == null)
return 0;
return count.getCount();
}
private boolean hasSelection(String packId, String selection, PacksStorage packsStorage) {
for (Item item : packsStorage.openPack(packId)) {
if (item.getBlueprintId().equals(selection))
return true;
}
return false;
}
}

View File

@@ -12,18 +12,18 @@ public class GatheringChatRoomListener implements ChatRoomListener {
private Date _lastConsumed = new Date();
@Override
public void messageReceived(ChatMessage message) {
public synchronized void messageReceived(ChatMessage message) {
_messages.add(message);
}
public List<ChatMessage> consumeMessages() {
public synchronized List<ChatMessage> consumeMessages() {
List<ChatMessage> messages = _messages;
_messages = new LinkedList<ChatMessage>();
_lastConsumed = new Date();
return messages;
}
public Date getLastConsumed() {
public synchronized Date getLastConsumed() {
return _lastConsumed;
}
}

View File

@@ -2,17 +2,15 @@ package com.gempukku.lotro.game;
import com.gempukku.lotro.AbstractServer;
import com.gempukku.lotro.chat.ChatServer;
import com.gempukku.lotro.common.CardType;
import com.gempukku.lotro.db.DeckDAO;
import com.gempukku.lotro.logic.timing.GameResultListener;
import com.gempukku.lotro.logic.vo.LotroDeck;
import org.apache.log4j.Logger;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class LotroServer extends AbstractServer {
private static final Logger log = Logger.getLogger(LotroServer.class);
@@ -29,72 +27,24 @@ public class LotroServer extends AbstractServer {
private int _nextGameId = 1;
private DeckDAO _deckDao;
private GameHistoryService _gameHistoryService;
private DefaultCardCollection _defaultCollection;
private CountDownLatch _collectionReadyLatch = new CountDownLatch(1);
private ChatServer _chatServer;
private boolean _test;
private GameRecorder _gameRecorder;
public LotroServer(DeckDAO deckDao, GameHistoryService gameHistoryService, LotroCardBlueprintLibrary library, ChatServer chatServer, boolean test) {
private ReadWriteLock _lock = new ReentrantReadWriteLock();
public LotroServer(DeckDAO deckDao, LotroCardBlueprintLibrary library, ChatServer chatServer, GameRecorder gameRecorder) {
_deckDao = deckDao;
_gameHistoryService = gameHistoryService;
_lotroCardBlueprintLibrary = library;
_chatServer = chatServer;
_test = test;
_defaultCollection = new DefaultCardCollection();
// Hunters have 1-194 normal cards, 9 "O" cards, and 3 extra to cover the different culture versions of 15_60
Thread thr = new Thread() {
public void run() {
final int[] cardCounts = new int[]{129, 365, 122, 122, 365, 128, 128, 365, 122, 52, 122, 266, 203, 203, 15, 207, 6, 157, 149, 40};
for (int i = 0; i <= 19; i++) {
System.out.println("Loading set " + i);
for (int j = 1; j <= cardCounts[i]; j++) {
String blueprintId = i + "_" + j;
try {
if (_lotroCardBlueprintLibrary.getBaseBlueprintId(blueprintId).equals(blueprintId)) {
LotroCardBlueprint cardBlueprint = _lotroCardBlueprintLibrary.getLotroCardBlueprint(blueprintId);
CardType cardType = cardBlueprint.getCardType();
if (cardType == CardType.SITE || cardType == CardType.THE_ONE_RING)
_defaultCollection.addItem(blueprintId, 1);
else
_defaultCollection.addItem(blueprintId, 4);
}
} catch (IllegalArgumentException exp) {
}
}
}
_collectionReadyLatch.countDown();
}
};
thr.start();
_gameRecorder = new GameRecorder(_gameHistoryService);
}
public InputStream getGameRecording(String playerId, String gameId) throws IOException {
return _gameRecorder.getRecordedGame(playerId, gameId);
}
public CardCollection getDefaultCollection() {
try {
_collectionReadyLatch.await();
} catch (InterruptedException exp) {
throw new RuntimeException("Error while awaiting loading a default colleciton", exp);
}
return _defaultCollection;
_gameRecorder = gameRecorder;
}
protected void cleanup() {
long currentTime = System.currentTimeMillis();
_lock.writeLock().lock();
try {
long currentTime = System.currentTimeMillis();
synchronized (_finishedGamesTime) {
LinkedHashMap<String, Date> copy = new LinkedHashMap<String, Date>(_finishedGamesTime);
for (Map.Entry<String, Date> finishedGame : copy.entrySet()) {
String gameId = finishedGame.getKey();
@@ -112,81 +62,103 @@ public class LotroServer extends AbstractServer {
break;
}
}
}
for (LotroGameMediator lotroGameMediator : _runningGames.values())
lotroGameMediator.cleanup();
for (LotroGameMediator lotroGameMediator : _runningGames.values())
lotroGameMediator.cleanup();
} finally {
_lock.writeLock().unlock();
}
}
private String getChatRoomName(String gameId) {
return "Game" + gameId;
}
public synchronized String createNewGame(LotroFormat lotroFormat, String tournamentName, final LotroGameParticipant[] participants, boolean allowSpectators, boolean allowCancelling, boolean muteSpectators, boolean competitiveTime
) {
if (participants.length < 2)
throw new IllegalArgumentException("There has to be at least two players");
final String gameId = String.valueOf(_nextGameId);
public String createNewGame(LotroFormat lotroFormat, String tournamentName, final LotroGameParticipant[] participants, boolean allowSpectators, boolean allowCancelling, boolean muteSpectators, boolean competitiveTime) {
_lock.writeLock().lock();
try {
if (participants.length < 2)
throw new IllegalArgumentException("There has to be at least two players");
final String gameId = String.valueOf(_nextGameId);
if (muteSpectators) {
Set<String> allowedUsers = new HashSet<String>();
for (LotroGameParticipant participant : participants)
allowedUsers.add(participant.getPlayerId());
_chatServer.createVoicedChatRoom(getChatRoomName(gameId), allowedUsers, 30);
} else
_chatServer.createChatRoom(getChatRoomName(gameId), 30);
if (muteSpectators) {
Set<String> allowedUsers = new HashSet<String>();
for (LotroGameParticipant participant : participants)
allowedUsers.add(participant.getPlayerId());
_chatServer.createVoicedChatRoom(getChatRoomName(gameId), allowedUsers, 30);
} else
_chatServer.createChatRoom(getChatRoomName(gameId), 30);
LotroGameMediator lotroGameMediator = new LotroGameMediator(lotroFormat, participants, _lotroCardBlueprintLibrary,
competitiveTime ? 60 * 40 : 60 * 80, !allowSpectators, allowCancelling);
lotroGameMediator.addGameResultListener(
new GameResultListener() {
@Override
public void gameFinished(String winnerPlayerId, String winReason, Map<String, String> loserPlayerIdsWithReasons) {
synchronized (_finishedGamesTime) {
_finishedGamesTime.put(gameId, new Date());
LotroGameMediator lotroGameMediator = new LotroGameMediator(lotroFormat, participants, _lotroCardBlueprintLibrary,
competitiveTime ? 60 * 40 : 60 * 80, !allowSpectators, allowCancelling);
lotroGameMediator.addGameResultListener(
new GameResultListener() {
@Override
public void gameFinished(String winnerPlayerId, String winReason, Map<String, String> loserPlayerIdsWithReasons) {
_lock.writeLock().lock();
try {
_finishedGamesTime.put(gameId, new Date());
} finally {
_lock.writeLock().unlock();
}
}
@Override
public void gameCancelled() {
_lock.writeLock().lock();
try {
_finishedGamesTime.put(gameId, new Date());
} finally {
_lock.writeLock().unlock();
}
}
});
lotroGameMediator.sendMessageToPlayers("You're starting a game of " + lotroFormat.getName());
StringBuffer players = new StringBuffer();
Map<String, String> deckNames = new HashMap<String, String>();
for (LotroGameParticipant participant : participants) {
deckNames.put(participant.getPlayerId(), participant.getDeck().getDeckName());
if (players.length() > 0)
players.append(", ");
players.append(participant.getPlayerId());
}
lotroGameMediator.sendMessageToPlayers("Players in the game are: " + players.toString());
final GameRecorder.GameRecordingInProgress gameRecordingInProgress = _gameRecorder.recordGame(lotroGameMediator, lotroFormat.getName(), tournamentName, deckNames);
lotroGameMediator.addGameResultListener(
new GameResultListener() {
@Override
public void gameFinished(String winnerPlayerId, String winReason, Map<String, String> loserPlayerIdsWithReasons) {
_lock.writeLock().lock();
try {
final Map.Entry<String, String> loserEntry = loserPlayerIdsWithReasons.entrySet().iterator().next();
gameRecordingInProgress.finishRecording(winnerPlayerId, winReason, loserEntry.getKey(), loserEntry.getValue());
} finally {
_lock.writeLock().unlock();
}
}
@Override
public void gameCancelled() {
_lock.writeLock().lock();
try {
gameRecordingInProgress.finishRecording(participants[0].getPlayerId(), "Game cancelled due to error", participants[1].getPlayerId(), "Game cancelled due to error");
} finally {
_lock.writeLock().unlock();
}
}
}
);
@Override
public void gameCancelled() {
synchronized (_finishedGamesTime) {
_finishedGamesTime.put(gameId, new Date());
}
}
});
lotroGameMediator.sendMessageToPlayers("You're starting a game of " + lotroFormat.getName());
StringBuffer players = new StringBuffer();
Map<String, String> deckNames = new HashMap<String, String>();
for (LotroGameParticipant participant : participants) {
deckNames.put(participant.getPlayerId(), participant.getDeck().getDeckName());
if (players.length() > 0)
players.append(", ");
players.append(participant.getPlayerId());
_runningGames.put(gameId, lotroGameMediator);
_nextGameId++;
return gameId;
} finally {
_lock.writeLock().unlock();
}
lotroGameMediator.sendMessageToPlayers("Players in the game are: " + players.toString());
final GameRecorder.GameRecordingInProgress gameRecordingInProgress = _gameRecorder.recordGame(lotroGameMediator, lotroFormat.getName(), tournamentName, deckNames);
lotroGameMediator.addGameResultListener(
new GameResultListener() {
@Override
public void gameFinished(String winnerPlayerId, String winReason, Map<String, String> loserPlayerIdsWithReasons) {
final Map.Entry<String, String> loserEntry = loserPlayerIdsWithReasons.entrySet().iterator().next();
gameRecordingInProgress.finishRecording(winnerPlayerId, winReason, loserEntry.getKey(), loserEntry.getValue());
}
@Override
public void gameCancelled() {
gameRecordingInProgress.finishRecording(participants[0].getPlayerId(), "Game cancelled due to error", participants[1].getPlayerId(), "Game cancelled due to error");
}
}
);
_runningGames.put(gameId, lotroGameMediator);
_nextGameId++;
return gameId;
}
public LotroDeck getParticipantDeck(Player player, String deckName) {
@@ -217,7 +189,12 @@ public class LotroServer extends AbstractServer {
}
public LotroGameMediator getGameById(String gameId) {
return _runningGames.get(gameId);
_lock.readLock().lock();
try {
return _runningGames.get(gameId);
} finally {
_lock.readLock().unlock();
}
}
}

View File

@@ -99,10 +99,6 @@ public class HallServer extends AbstractServer {
}
}
public Map<String, LotroFormat> getSupportedFormats() {
return _formatLibrary.getHallFormats();
}
private void cancelWaitingTables() {
_awaitingTables.clear();
}

View File

@@ -41,7 +41,7 @@ public class LeagueService {
_collectionsManager = collectionsManager;
}
public void clearCache() {
public synchronized void clearCache() {
_leagueSerieStandings.clear();
_leagueStandings.clear();
_activeLeaguesLoadedDate = 0;
@@ -68,7 +68,7 @@ public class LeagueService {
}
}
public List<League> getActiveLeagues() {
public synchronized List<League> getActiveLeagues() {
if (DateUtils.getCurrentDate() == _activeLeaguesLoadedDate)
return Collections.unmodifiableList(_activeLeagues);
else {
@@ -86,11 +86,11 @@ public class LeagueService {
}
}
public boolean isPlayerInLeague(League league, Player player) {
public synchronized boolean isPlayerInLeague(League league, Player player) {
return _leagueParticipationDAO.getUsersParticipating(league.getType()).contains(player.getName());
}
public boolean playerJoinsLeague(League league, Player player) {
public synchronized boolean playerJoinsLeague(League league, Player player) {
if (isPlayerInLeague(league, player))
return false;
int cost = league.getCost();
@@ -106,7 +106,7 @@ public class LeagueService {
}
}
public League getLeagueByType(String type) {
public synchronized League getLeagueByType(String type) {
for (League league : getActiveLeagues()) {
if (league.getType().equals(type))
return league;
@@ -114,7 +114,7 @@ public class LeagueService {
return null;
}
public CollectionType getCollectionTypeByCode(String collectionTypeCode) {
public synchronized CollectionType getCollectionTypeByCode(String collectionTypeCode) {
for (League league : getActiveLeagues()) {
for (LeagueSerieData leagueSerieData : league.getLeagueData().getSeries()) {
CollectionType collectionType = leagueSerieData.getCollectionType();
@@ -125,7 +125,7 @@ public class LeagueService {
return null;
}
public LeagueSerieData getCurrentLeagueSerie(League league) {
public synchronized LeagueSerieData getCurrentLeagueSerie(League league) {
final int currentDate = DateUtils.getCurrentDate();
for (LeagueSerieData leagueSerieData : league.getLeagueData().getSeries()) {
@@ -136,7 +136,7 @@ public class LeagueService {
return null;
}
public void reportLeagueGameResult(League league, LeagueSerieData serie, String winner, String loser) {
public synchronized void reportLeagueGameResult(League league, LeagueSerieData serie, String winner, String loser) {
_leagueMatchDao.addPlayedMatch(league.getType(), serie.getName(), winner, loser);
_leagueStandings.remove(LeagueMapKeys.getLeagueMapKey(league));
@@ -173,7 +173,7 @@ public class LeagueService {
return result;
}
public List<PlayerStanding> getLeagueStandings(League league) {
public synchronized List<PlayerStanding> getLeagueStandings(League league) {
List<PlayerStanding> leagueStandings = _leagueStandings.get(LeagueMapKeys.getLeagueMapKey(league));
if (leagueStandings == null) {
synchronized (this) {
@@ -184,7 +184,7 @@ public class LeagueService {
return leagueStandings;
}
public List<PlayerStanding> getLeagueSerieStandings(League league, LeagueSerieData leagueSerie) {
public synchronized List<PlayerStanding> getLeagueSerieStandings(League league, LeagueSerieData leagueSerie) {
List<PlayerStanding> serieStandings = _leagueSerieStandings.get(LeagueMapKeys.getLeagueSerieMapKey(league, leagueSerie));
if (serieStandings == null) {
synchronized (this) {
@@ -219,7 +219,7 @@ public class LeagueService {
return StandingsProducer.produceStandings(playersParticipating, matches, 2, 1, Collections.<String, Integer>emptyMap());
}
public boolean canPlayRankedGame(League league, LeagueSerieData season, String player) {
public synchronized boolean canPlayRankedGame(League league, LeagueSerieData season, String player) {
int maxMatches = season.getMaxMatches();
Collection<LeagueMatchResult> playedInSeason = getPlayerMatchesInSerie(league, season, player);
if (playedInSeason.size() >= maxMatches)
@@ -227,7 +227,7 @@ public class LeagueService {
return true;
}
public boolean canPlayRankedGameAgainst(League league, LeagueSerieData season, String playerOne, String playerTwo) {
public synchronized boolean canPlayRankedGameAgainst(League league, LeagueSerieData season, String playerOne, String playerTwo) {
Collection<LeagueMatchResult> playedInSeason = getPlayerMatchesInSerie(league, season, playerOne);
for (LeagueMatchResult leagueMatch : playedInSeason) {
if (playerTwo.equals(leagueMatch.getWinner()) || playerTwo.equals(leagueMatch.getLoser()))

View File

@@ -98,7 +98,7 @@ public class SingleEliminationRecurringQueue implements TournamentQueue {
}
@Override
public void leaveAllPlayers(CollectionsManager collectionsManager) {
public synchronized void leaveAllPlayers(CollectionsManager collectionsManager) {
if (_cost > 0) {
for (String player : _playerDecks.keySet())
collectionsManager.addCurrencyToPlayerCollection(player, _currencyCollection, _cost);

View File

@@ -167,10 +167,7 @@ public class CollectionResource extends AbstractResource {
}
private CardCollection getCollection(Player player, String collectionType) {
if (collectionType.equals("default"))
return _lotroServer.getDefaultCollection();
else
return _collectionsManager.getPlayerCollection(player, collectionType);
return _collectionsManager.getPlayerCollection(player, collectionType);
}
@Path("/{collectionType}")

View File

@@ -3,6 +3,7 @@ package com.gempukku.lotro.server;
import com.gempukku.lotro.common.Side;
import com.gempukku.lotro.db.DeckDAO;
import com.gempukku.lotro.game.*;
import com.gempukku.lotro.game.formats.LotroFormatLibrary;
import com.gempukku.lotro.hall.HallServer;
import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.vo.LotroDeck;
@@ -36,6 +37,8 @@ public class DeckResource extends AbstractResource {
private LotroCardBlueprintLibrary _library;
@Context
private DeckDAO _deckDao;
@Context
private LotroFormatLibrary _formatLibrary;
private SortAndFilterCards _sortAndFilterCards = new SortAndFilterCards();
@@ -217,7 +220,7 @@ public class DeckResource extends AbstractResource {
StringBuilder sb = new StringBuilder();
sb.append("<b>Free People</b>: " + fpCount + ", <b>Shadow</b>: " + shadowCount + "<br/>");
for (LotroFormat format : _hallServer.getSupportedFormats().values()) {
for (LotroFormat format : _formatLibrary.getHallFormats().values()) {
try {
format.validateDeck(resourceOwner, deck);
sb.append("<b>" + format.getName() + "</b>: <font color='green'>valid</font><br/>");

View File

@@ -130,7 +130,7 @@ public class HallResource extends AbstractResource {
hall.setAttribute("motd", motd);
_hallServer.processHall(resourceOwner, new SerializeHallInfoVisitor(doc, hall));
for (Map.Entry<String, LotroFormat> format : _hallServer.getSupportedFormats().entrySet()) {
for (Map.Entry<String, LotroFormat> format : _formatLibrary.getHallFormats().entrySet()) {
Element formatElem = doc.createElement("format");
formatElem.setAttribute("type", format.getKey());
formatElem.appendChild(doc.createTextNode(format.getValue().getName()));

View File

@@ -47,6 +47,8 @@ public class ServerResource extends AbstractResource {
private ChatServer _chatServer;
@Context
private GameHistoryService _gameHistoryService;
@Context
private GameRecorder _gameRecorder;
public ServerResource() {
if (!_test)
@@ -126,7 +128,7 @@ public class ServerResource extends AbstractResource {
return new StreamingOutput() {
@Override
public void write(OutputStream outputStream) throws IOException, WebApplicationException {
final InputStream recordedGame = _lotroServer.getGameRecording(split[0], split[1]);
final InputStream recordedGame = _gameRecorder.getRecordedGame(split[0], split[1]);
if (recordedGame == null)
throw new WebApplicationException(Response.Status.NOT_FOUND);
try {

View File

@@ -34,13 +34,12 @@ public class DaoProvider implements InjectableProvider<Context, Type> {
private DbAccess _dbAccess;
private CollectionSerializer _collectionSerializer;
@Context
private LotroCardBlueprintLibrary _library;
public DaoProvider() {
_dbAccess = new DbAccess();
_collectionSerializer = new CollectionSerializer();
_library = new LotroCardBlueprintLibrary();
}
@Override

View File

@@ -5,6 +5,7 @@ import com.gempukku.lotro.collection.CollectionsManager;
import com.gempukku.lotro.collection.DeliveryService;
import com.gempukku.lotro.db.*;
import com.gempukku.lotro.game.GameHistoryService;
import com.gempukku.lotro.game.GameRecorder;
import com.gempukku.lotro.game.LotroCardBlueprintLibrary;
import com.gempukku.lotro.game.LotroServer;
import com.gempukku.lotro.game.formats.LotroFormatLibrary;
@@ -37,6 +38,7 @@ public class ServerProvider implements InjectableProvider<Context, Type> {
private Injectable<CollectionsManager> _collectionsManagerInjectable;
private Injectable<DeliveryService> _deliveryServiceInjectable;
private Injectable<LotroFormatLibrary> _lotroFormatLibraryInjectable;
private Injectable<GameRecorder> _gameRecorderInjectable;
@Context
private PlayerDAO _playerDao;
@@ -85,6 +87,8 @@ public class ServerProvider implements InjectableProvider<Context, Type> {
return getMerchantServiceInjectable();
if (type.equals(TournamentService.class))
return getTournamentServiceInjectable();
if (type.equals(GameRecorder.class))
return getGameRecorderInjectable();
return null;
}
@@ -135,6 +139,19 @@ public class ServerProvider implements InjectableProvider<Context, Type> {
return _gameHistoryServiceInjectable;
}
private synchronized Injectable<GameRecorder> getGameRecorderInjectable() {
if (_gameRecorderInjectable == null) {
final GameRecorder gameRecorder = new GameRecorder(getGameHistoryServiceInjectable().getValue());
_gameRecorderInjectable = new Injectable<GameRecorder>() {
@Override
public GameRecorder getValue() {
return gameRecorder;
}
};
}
return _gameRecorderInjectable;
}
private synchronized Injectable<MerchantService> getMerchantServiceInjectable() {
if (_merchantServiceInjectable == null) {
final MerchantService merchantService = new MerchantService(_library, getCollectionsManagerInjectable().getValue(), _merchantDao);
@@ -208,7 +225,7 @@ public class ServerProvider implements InjectableProvider<Context, Type> {
private synchronized Injectable<LotroServer> getLotroServerInjectable() {
if (_lotroServerInjectable == null) {
final LotroServer lotroServer = new LotroServer(_deckDao, getGameHistoryServiceInjectable().getValue(), _library, getChatServerInjectable().getValue(), false);
final LotroServer lotroServer = new LotroServer(_deckDao, _library, getChatServerInjectable().getValue(), getGameRecorderInjectable().getValue());
lotroServer.startServer();
_lotroServerInjectable = new Injectable<LotroServer>() {
@Override
@@ -236,7 +253,7 @@ public class ServerProvider implements InjectableProvider<Context, Type> {
private synchronized Injectable<CollectionsManager> getCollectionsManagerInjectable() {
if (_collectionsManagerInjectable == null) {
final CollectionsManager collectionsManager = new CollectionsManager(_playerDao, _collectionDao, getDeliveryServiceInjectable().getValue());
final CollectionsManager collectionsManager = new CollectionsManager(_playerDao, _collectionDao, getDeliveryServiceInjectable().getValue(), _library);
_collectionsManagerInjectable = new Injectable<CollectionsManager>() {
@Override
public CollectionsManager getValue() {