Fixed: Temporary fix Concurrent access disconnected player game (nextPlayerSetup)
This commit is contained in:
@@ -40,7 +40,7 @@ public class GameController {
|
|||||||
* {@code false} if no player with the specified username exists
|
* {@code false} if no player with the specified username exists
|
||||||
* or if the operation fails.
|
* or if the operation fails.
|
||||||
*/
|
*/
|
||||||
public boolean DisconnectedPlayer(String username)
|
public synchronized boolean DisconnectedPlayer(String username)
|
||||||
{
|
{
|
||||||
Player player= model.getPlayerByUsername(username);
|
Player player= model.getPlayerByUsername(username);
|
||||||
if(player==null)
|
if(player==null)
|
||||||
@@ -56,7 +56,7 @@ public class GameController {
|
|||||||
* {@code false} if no player with the specified username exists
|
* {@code false} if no player with the specified username exists
|
||||||
* or if the operation fails.
|
* or if the operation fails.
|
||||||
*/
|
*/
|
||||||
public boolean ReconnectPlayer(String username)
|
public synchronized boolean ReconnectPlayer(String username)
|
||||||
{
|
{
|
||||||
Player player= model.getPlayerByUsername(username);
|
Player player= model.getPlayerByUsername(username);
|
||||||
if(player==null)
|
if(player==null)
|
||||||
@@ -89,7 +89,7 @@ public class GameController {
|
|||||||
* @return {@code true} if the player is successfully added,
|
* @return {@code true} if the player is successfully added,
|
||||||
* {@code false} otherwise.
|
* {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean addPlayer(String username) {
|
public synchronized boolean addPlayer(String username) {
|
||||||
return model.addPlayer(new Player(username));
|
return model.addPlayer(new Player(username));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ public class GameController {
|
|||||||
* @return {@code true} if the action succeeds,
|
* @return {@code true} if the action succeeds,
|
||||||
* {@code false} if the player does not exist or if the draw operation fails.
|
* {@code false} if the player does not exist or if the draw operation fails.
|
||||||
*/
|
*/
|
||||||
public boolean drawUpperTribeCard(String playerUsername,int pos) {
|
public synchronized boolean drawUpperTribeCard(String playerUsername,int pos) {
|
||||||
Player player= model.getPlayerByUsername(playerUsername);
|
Player player= model.getPlayerByUsername(playerUsername);
|
||||||
if(player==null)
|
if(player==null)
|
||||||
return false;
|
return false;
|
||||||
@@ -118,7 +118,7 @@ public class GameController {
|
|||||||
* @return {@code true} if the action succeeds,
|
* @return {@code true} if the action succeeds,
|
||||||
* {@code false} if the player does not exist or if the draw operation fails.
|
* {@code false} if the player does not exist or if the draw operation fails.
|
||||||
*/
|
*/
|
||||||
public boolean drawLowerTribeCard(String playerUsername,int pos) {
|
public synchronized boolean drawLowerTribeCard(String playerUsername,int pos) {
|
||||||
Player player= model.getPlayerByUsername(playerUsername);
|
Player player= model.getPlayerByUsername(playerUsername);
|
||||||
if(player==null)
|
if(player==null)
|
||||||
return false;
|
return false;
|
||||||
@@ -134,7 +134,7 @@ public class GameController {
|
|||||||
* @return {@code true} if the action succeeds,
|
* @return {@code true} if the action succeeds,
|
||||||
* {@code false} if the player does not exist or if the draw operation fails.
|
* {@code false} if the player does not exist or if the draw operation fails.
|
||||||
*/
|
*/
|
||||||
public boolean drawUpperBuildingCard(String playerUsername,int pos) {
|
public synchronized boolean drawUpperBuildingCard(String playerUsername,int pos) {
|
||||||
Player player= model.getPlayerByUsername(playerUsername);
|
Player player= model.getPlayerByUsername(playerUsername);
|
||||||
if(player==null)
|
if(player==null)
|
||||||
return false;
|
return false;
|
||||||
@@ -150,7 +150,7 @@ public class GameController {
|
|||||||
* @return {@code true} if the action succeeds,
|
* @return {@code true} if the action succeeds,
|
||||||
* {@code false} if the player does not exist or if the draw operation fails.
|
* {@code false} if the player does not exist or if the draw operation fails.
|
||||||
*/
|
*/
|
||||||
public boolean drawLowerBuildingCard(String playerUsername,int pos) {
|
public synchronized boolean drawLowerBuildingCard(String playerUsername,int pos) {
|
||||||
Player player= model.getPlayerByUsername(playerUsername);
|
Player player= model.getPlayerByUsername(playerUsername);
|
||||||
if(player==null)
|
if(player==null)
|
||||||
return false;
|
return false;
|
||||||
@@ -165,7 +165,7 @@ public class GameController {
|
|||||||
* @return {@code true} if the skip action is valid and successfully performed,
|
* @return {@code true} if the skip action is valid and successfully performed,
|
||||||
* {@code false} if the player does not exist or if the action is not valid.
|
* {@code false} if the player does not exist or if the action is not valid.
|
||||||
*/
|
*/
|
||||||
public boolean SkipTurn(String playerUsername) {
|
public synchronized boolean SkipTurn(String playerUsername) {
|
||||||
Player player= model.getPlayerByUsername(playerUsername);
|
Player player= model.getPlayerByUsername(playerUsername);
|
||||||
if(player==null)
|
if(player==null)
|
||||||
return false;
|
return false;
|
||||||
@@ -183,7 +183,7 @@ public class GameController {
|
|||||||
* @return {@code true} if the action succeeds,
|
* @return {@code true} if the action succeeds,
|
||||||
* {@code false} if the player does not exist or if the slot choice operation fails.
|
* {@code false} if the player does not exist or if the slot choice operation fails.
|
||||||
*/
|
*/
|
||||||
public boolean slotChoice(String playerUsername,int pos) {
|
public synchronized boolean slotChoice(String playerUsername,int pos) {
|
||||||
Player player= model.getPlayerByUsername(playerUsername);
|
Player player= model.getPlayerByUsername(playerUsername);
|
||||||
if(player==null)
|
if(player==null)
|
||||||
return false;
|
return false;
|
||||||
@@ -199,10 +199,15 @@ public class GameController {
|
|||||||
* {@code false} if no player with the specified username exists
|
* {@code false} if no player with the specified username exists
|
||||||
* or if the choice operation fails.
|
* or if the choice operation fails.
|
||||||
*/
|
*/
|
||||||
public boolean TotemChoice(String playerUsername,String totem) {
|
public synchronized boolean TotemChoice(String playerUsername,String totem) {
|
||||||
Player player= model.getPlayerByUsername(playerUsername);
|
Player player= model.getPlayerByUsername(playerUsername);
|
||||||
if(player==null)
|
if(player==null)
|
||||||
return false;
|
return false;
|
||||||
return model.TotemChoice(player, Totems.valueOf(totem));
|
return model.TotemChoice(player, Totems.valueOf(totem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
public synchronized void EndGameForFeit(){
|
||||||
|
model.EndGameForFeit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ public class Game implements Serializable {
|
|||||||
* @param totem the selected totem.
|
* @param totem the selected totem.
|
||||||
* @return {@code true} if the choice is applied successfully, {@code false} otherwise.
|
* @return {@code true} if the choice is applied successfully, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean TotemChoice(Player player,Totems totem) {
|
public synchronized boolean TotemChoice(Player player,Totems totem) {
|
||||||
if(!currentState.getGameStage().equals(GameStages.TOTEM_CHOICE))
|
if(!currentState.getGameStage().equals(GameStages.TOTEM_CHOICE))
|
||||||
return false;
|
return false;
|
||||||
if(!getCurrentState().getCurrentPlayer().equals(player))
|
if(!getCurrentState().getCurrentPlayer().equals(player))
|
||||||
@@ -135,7 +135,7 @@ public class Game implements Serializable {
|
|||||||
* @return {@code true} if the disconnection is handled successfully,
|
* @return {@code true} if the disconnection is handled successfully,
|
||||||
* {@code false} if the player was already marked as disconnected.
|
* {@code false} if the player was already marked as disconnected.
|
||||||
*/
|
*/
|
||||||
public boolean DisconnectedPlayer(Player player)
|
public synchronized boolean DisconnectedPlayer(Player player)
|
||||||
{
|
{
|
||||||
if(disconnetedPlayers.containsKey(player) && disconnetedPlayers.get(player))
|
if(disconnetedPlayers.containsKey(player) && disconnetedPlayers.get(player))
|
||||||
{
|
{
|
||||||
@@ -177,7 +177,7 @@ public class Game implements Serializable {
|
|||||||
* @return {@code true} if the reconnection is handled successfully,
|
* @return {@code true} if the reconnection is handled successfully,
|
||||||
* {@code false} if the player was not previously marked as disconnected.
|
* {@code false} if the player was not previously marked as disconnected.
|
||||||
*/
|
*/
|
||||||
public boolean ReconnectPlayer(Player player)
|
public synchronized boolean ReconnectPlayer(Player player)
|
||||||
{
|
{
|
||||||
if(!disconnetedPlayers.containsKey(player))
|
if(!disconnetedPlayers.containsKey(player))
|
||||||
{
|
{
|
||||||
@@ -198,7 +198,7 @@ public class Game implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Clears the collection of disconnected players.
|
* Clears the collection of disconnected players.
|
||||||
*/
|
*/
|
||||||
public void ClearDisconnected()
|
public synchronized void ClearDisconnected()
|
||||||
{
|
{
|
||||||
disconnetedPlayers.clear();
|
disconnetedPlayers.clear();
|
||||||
}
|
}
|
||||||
@@ -689,7 +689,7 @@ public class Game implements Serializable {
|
|||||||
* If the current stage is {@code OPTIONAL_CARD_EFFECT}, the next player is taken from the optional card queue.
|
* If the current stage is {@code OPTIONAL_CARD_EFFECT}, the next player is taken from the optional card queue.
|
||||||
* If no player is available, the game stage is updated to {@code RESOLVING_EVENT}.
|
* If no player is available, the game stage is updated to {@code RESOLVING_EVENT}.
|
||||||
*/
|
*/
|
||||||
private void nextPlayerSetup() {
|
private synchronized void nextPlayerSetup() {
|
||||||
|
|
||||||
if (GameStages.SLOT_CHOICE == currentState.getGameStage()) {
|
if (GameStages.SLOT_CHOICE == currentState.getGameStage()) {
|
||||||
Player tempPlayer = orderLogicCard.pull();
|
Player tempPlayer = orderLogicCard.pull();
|
||||||
@@ -796,7 +796,7 @@ public class Game implements Serializable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO
|
//TODO
|
||||||
private void transitionToOptionalOrNextRound() {
|
private synchronized void transitionToOptionalOrNextRound() {
|
||||||
currentState.GameStageUpdate(GameStages.OPT_CARD_E);
|
currentState.GameStageUpdate(GameStages.OPT_CARD_E);
|
||||||
|
|
||||||
OptionalCardQueue = new LinkedList<>();
|
OptionalCardQueue = new LinkedList<>();
|
||||||
@@ -986,7 +986,7 @@ public class Game implements Serializable {
|
|||||||
* in the first position of the final ranking. The remaining players are
|
* in the first position of the final ranking. The remaining players are
|
||||||
* ordered by prestige value and, in case of a tie, by food value.
|
* ordered by prestige value and, in case of a tie, by food value.
|
||||||
*/
|
*/
|
||||||
public void EndGameForFeit() {
|
public synchronized void EndGameForFeit() {
|
||||||
Player winner=playersList.stream().filter(x->!disconnetedPlayers.containsKey(x)||!disconnetedPlayers.get(x)).toList().get(0);
|
Player winner=playersList.stream().filter(x->!disconnetedPlayers.containsKey(x)||!disconnetedPlayers.get(x)).toList().get(0);
|
||||||
currentState.GameStageUpdate(GameStages.ENDED);
|
currentState.GameStageUpdate(GameStages.ENDED);
|
||||||
playerStanding=new ArrayList<>(playersList);
|
playerStanding=new ArrayList<>(playersList);
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ public class ServerLauncher {
|
|||||||
disconnectionTimer = timerExecutor.schedule(() -> {
|
disconnectionTimer = timerExecutor.schedule(() -> {
|
||||||
synchronized (gameController)
|
synchronized (gameController)
|
||||||
{
|
{
|
||||||
game.EndGameForFeit();
|
gameController.EndGameForFeit();
|
||||||
serverRMI.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
|
serverRMI.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
|
||||||
serverTCP.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
|
serverTCP.notifyAll(new EndedGame(game.getSlotMap(), game.orderLogicCard, game.getCurrentState(),game.getPlayerStanding()));
|
||||||
System.out.println("Timer expired: no player reconnected in 60s.");
|
System.out.println("Timer expired: no player reconnected in 60s.");
|
||||||
@@ -283,7 +283,8 @@ public class ServerLauncher {
|
|||||||
new Thread(()-> {
|
new Thread(()-> {
|
||||||
try {
|
try {
|
||||||
launcher.run();
|
launcher.run();
|
||||||
} catch (Exception e)
|
}
|
||||||
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
System.out.println("Generic exception occurred");
|
System.out.println("Generic exception occurred");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -310,6 +311,10 @@ public class ServerLauncher {
|
|||||||
try{
|
try{
|
||||||
this.doFirstEvent();
|
this.doFirstEvent();
|
||||||
}
|
}
|
||||||
|
catch (ConcurrentModificationException e)
|
||||||
|
{
|
||||||
|
System.err.println("Concurrent Exception");
|
||||||
|
}
|
||||||
catch(InterruptedException e){
|
catch(InterruptedException e){
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user