Reformatted some files

This commit is contained in:
Gianlu 2020-05-25 15:55:06 +02:00
parent d051817dfa
commit fefd9022a8
8 changed files with 1383 additions and 1430 deletions

View File

@ -1,16 +1,16 @@
/**
* Copyright (c) 2012-2018, Andy Janata
* All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* <p>
* * Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
@ -25,9 +25,7 @@ package net.socialgamer.cah.customsets;
import net.socialgamer.cah.data.BlackCard;
public class CustomBlackCard extends BlackCard {
private final int id;
private final String text;
private final int draw;

View File

@ -31,9 +31,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
public final class CustomCardFormatHelper {
private CustomCardFormatHelper() {
}

View File

@ -1,16 +1,16 @@
/**
* Copyright (c) 2012-2018, Andy Janata
* All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* <p>
* * Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
@ -23,11 +23,11 @@
package net.socialgamer.cah.customsets;
import net.socialgamer.cah.data.CardSet;
import java.util.HashSet;
import java.util.Set;
import net.socialgamer.cah.data.CardSet;
public class CustomDeck extends CardSet {
private final int id;

View File

@ -1,16 +1,16 @@
/**
* Copyright (c) 2012-2018, Andy Janata
* All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without modification, are permitted
* provided that the following conditions are met:
*
* <p>
* * Redistributions of source code must retain the above copyright notice, this list of conditions
* and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice, this list of
* conditions and the following disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
@ -25,9 +25,7 @@ package net.socialgamer.cah.customsets;
import net.socialgamer.cah.data.WhiteCard;
public class CustomWhiteCard extends WhiteCard {
private final int id;
private final String text;
private final String watermark;

View File

@ -49,12 +49,12 @@ import java.util.concurrent.TimeUnit;
* Game data and logic class. Games are simple finite state machines, with 3 states that wait for
* user input, and 3 transient states that it quickly passes through on the way back to a waiting
* state:
*
* <p>
* ......Lobby.----------->.Dealing.(transient).-------->.Playing
* .......^........................^.........................|....................
* .......|.v----.Win.(transient).<+------.Judging.<---------+....................
* .....Reset.(transient)
*
* <p>
* Lobby is the default state. When the game host sends a start game event, the game moves to the
* Dealing state, where it deals out cards to every player and automatically moves into the Playing
* state. After all players have played a card, the game moves to Judging and waits for the judge to
@ -65,54 +65,18 @@ import java.util.concurrent.TimeUnit;
* @author Andy Janata (ajanata@socialgamer.net)
*/
public class Game {
private static final Logger logger = Logger.getLogger(Game.class);
private final int id;
/**
* All players present in the game.
*/
private final List<Player> players = Collections.synchronizedList(new ArrayList<Player>(10));
/**
* Players participating in the current round.
*/
private final List<Player> roundPlayers = Collections.synchronizedList(new ArrayList<Player>(9));
private final PlayerPlayedCardsTracker playedCards = new PlayerPlayedCardsTracker();
private final List<User> spectators = Collections.synchronizedList(new ArrayList<User>(10));
private final ConnectedUsers connectedUsers;
private final GameManager gameManager;
private Player host;
private final Provider<Session> sessionProvider;
private BlackDeck blackDeck;
private BlackCard blackCard;
private final Object blackCardLock = new Object();
private WhiteDeck whiteDeck;
private GameState state;
private final GameOptions options;
private final Set<Integer> customDecksIds = Collections.synchronizedSet(new HashSet<Integer>());
private final Metrics metrics;
private final Provider<Boolean> showGameLinkProvider;
private final Provider<String> gamePermalinkFormatProvider;
private final Provider<Boolean> showRoundLinkProvider;
private final Provider<String> roundPermalinkFormatProvider;
private final Provider<Boolean> allowBlankCardsProvider;
private final long created = System.currentTimeMillis();
private int judgeIndex = 0;
/**
* The minimum number of black cards that must be added to a game for it to be able to start.
*/
public final static int MINIMUM_BLACK_CARDS = 50;
/**
* The minimum number of white cards per player limit slots that must be added to a game for it to
* be able to start.
*
* <p>
* We need 20 * maxPlayers cards. This allows black cards up to "draw 9" to work correctly.
*/
public final static int MINIMUM_WHITE_CARDS_PER_PLAYER = 20;
// All of these delays could be moved to pyx.properties.
private static final Logger logger = Logger.getLogger(Game.class);
/**
* Time, in milliseconds, to delay before starting a new round.
*/
@ -141,12 +105,39 @@ public class Game {
private final static int JUDGE_TIMEOUT_PER_CARD = 7 * 1000;
private final static int MAX_SKIPS_BEFORE_KICK = 2;
private final static Set<String> FINITE_PLAYTIMES;
static
{
static {
final Set<String> finitePlaytimes = new TreeSet<String>(Arrays.asList(
new String[]{"0.25x", "0.5x", "0.75x", "1x", "1.25x", "1.5x", "1.75x", "2x", "2.5x", "3x", "4x", "5x", "10x"}));
FINITE_PLAYTIMES = Collections.unmodifiableSet(finitePlaytimes);
}
private final int id;
/**
* All players present in the game.
*/
private final List<Player> players = Collections.synchronizedList(new ArrayList<Player>(10));
/**
* Players participating in the current round.
*/
private final List<Player> roundPlayers = Collections.synchronizedList(new ArrayList<Player>(9));
private final PlayerPlayedCardsTracker playedCards = new PlayerPlayedCardsTracker();
private final List<User> spectators = Collections.synchronizedList(new ArrayList<User>(10));
private final ConnectedUsers connectedUsers;
private final GameManager gameManager;
private final Provider<Session> sessionProvider;
private final Object blackCardLock = new Object();
private final GameOptions options;
private final Set<Integer> customDecksIds = Collections.synchronizedSet(new HashSet<Integer>());
private final Metrics metrics;
private final Provider<Boolean> showGameLinkProvider;
private final Provider<String> gamePermalinkFormatProvider;
private final Provider<Boolean> showRoundLinkProvider;
private final Provider<String> roundPermalinkFormatProvider;
// All of these delays could be moved to pyx.properties.
private final Provider<Boolean> allowBlankCardsProvider;
private final long created = System.currentTimeMillis();
/**
* Lock object to prevent judging during idle judge detection and vice-versa.
*/
@ -158,6 +149,12 @@ public class Game {
private final ScheduledThreadPoolExecutor globalTimer;
private final Provider<CustomCardsService> customDecksServiceProvider;
private final Provider<String> uniqueIdProvider;
private Player host;
private BlackDeck blackDeck;
private BlackCard blackCard;
private WhiteDeck whiteDeck;
private GameState state;
private int judgeIndex = 0;
private volatile ScheduledFuture<?> lastScheduledFuture;
private String currentUniqueId;
/**
@ -169,12 +166,9 @@ public class Game {
/**
* Create a new game.
*
* @param id
* The game's ID.
* @param connectedUsers
* The user manager, for broadcasting messages.
* @param gameManager
* The game manager, for broadcasting game list refresh notices and destroying this game
* @param id The game's ID.
* @param connectedUsers The user manager, for broadcasting messages.
* @param gameManager The game manager, for broadcasting game list refresh notices and destroying this game
* when everybody leaves.
* @param hibernateSession Hibernate session from which to load cards.
* @param globalTimer The global timer on which to schedule tasks.
@ -212,6 +206,7 @@ public class Game {
/**
* Adds a permalink to this game to the client request response data, if said permalinks are
* enabled.
*
* @param data A map of data being returned to a client request.
*/
public void maybeAddPermalinkToData(final Map<ReturnableData, Object> data) {
@ -223,15 +218,12 @@ public class Game {
/**
* Add a player to the game.
*
* <p>
* Synchronizes on {@link #players}.
*
* @param user
* Player to add to this game.
* @throws TooManyPlayersException
* Thrown if this game is at its maximum player capacity.
* @throws IllegalStateException
* Thrown if {@code user} is already in a game.
* @param user Player to add to this game.
* @throws TooManyPlayersException Thrown if this game is at its maximum player capacity.
* @throws IllegalStateException Thrown if {@code user} is already in a game.
*/
public void addPlayer(final User user) throws TooManyPlayersException, IllegalStateException {
logger.info(String.format("%s joined game %d.", user.toString(), id));
@ -263,8 +255,7 @@ public class Game {
* Synchronizes on {@link #players}, {@link #playedCards}, {@link #whiteDeck}, and
* {@link #roundTimerLock}.
*
* @param user
* Player to remove from the game.
* @param user Player to remove from the game.
* @return True if {@code user} was the last player in the game.
*/
public boolean removePlayer(final User user) {
@ -358,15 +349,12 @@ public class Game {
/**
* Add a spectator to the game.
*
* <p>
* Synchronizes on {@link #spectators}.
*
* @param user
* Spectator to add to this game.
* @throws TooManySpectatorsException
* Thrown if this game is at its maximum spectator capacity.
* @throws IllegalStateException
* Thrown if {@code user} is already in a game.
* @param user Spectator to add to this game.
* @throws TooManySpectatorsException Thrown if this game is at its maximum spectator capacity.
* @throws IllegalStateException Thrown if {@code user} is already in a game.
*/
public void addSpectator(final User user) throws TooManySpectatorsException,
IllegalStateException {
@ -393,8 +381,7 @@ public class Game {
* <br/>
* Synchronizes on {@link #spectator}.
*
* @param user
* Spectator to remove from the game.
* @param user Spectator to remove from the game.
*/
public void removeSpectator(final User user) {
logger.info(String.format("Removing spectator %s from game %d.", user.toString(), id));
@ -434,11 +421,9 @@ public class Game {
/**
* Broadcast a message to all players in this game.
*
* @param type
* Type of message to broadcast. This determines the order the messages are returned by
* @param type Type of message to broadcast. This determines the order the messages are returned by
* priority.
* @param masterData
* Message data to broadcast.
* @param masterData Message data to broadcast.
*/
public void broadcastToPlayers(final MessageType type,
final HashMap<ReturnableData, Object> masterData) {
@ -448,8 +433,7 @@ public class Game {
/**
* Sends updated player information about a specific player to all players in the game.
*
* @param player
* The player whose information has been changed.
* @param player The player whose information has been changed.
*/
public void notifyPlayerInfoChange(final Player player) {
final HashMap<ReturnableData, Object> data = getEventMap();
@ -516,6 +500,7 @@ public class Game {
* Get information about this game, without the game's password.
* <br/>
* Synchronizes on {@link #players}.
*
* @return This game's general information: ID, host, state, player list, etc.
*/
@Nullable
@ -527,8 +512,8 @@ public class Game {
* Get information about this game.
* <br/>
* Synchronizes on {@link #players}.
* @param includePassword
* Include the actual password with the information. This should only be
*
* @param includePassword Include the actual password with the information. This should only be
* sent to people in the game.
* @return This game's general information: ID, host, state, player list, etc.
*/
@ -566,6 +551,7 @@ public class Game {
/**
* Synchronizes on {@link #players}.
*
* @return Player information for every player in this game: Name, score, status.
*/
public List<Map<GamePlayerInfo, Object>> getAllPlayerInfo() {
@ -588,8 +574,7 @@ public class Game {
/**
* Get player information for a single player.
*
* @param player
* The player for whom to get status.
* @param player The player for whom to get status.
* @return Information for {@code player}: Name, score, status.
*/
public Map<GamePlayerInfo, Object> getPlayerInfo(final Player player) {
@ -608,8 +593,7 @@ public class Game {
/**
* Determine the player status for a given player, based on game state.
*
* @param player
* Player for whom to get the state.
* @param player Player for whom to get the state.
* @return The state of {@code player}, one of {@code HOST}, {@code IDLE}, {@code JUDGE},
* {@code PLAYING}, {@code JUDGING}, or {@code WINNER}, depending on the game's state and
* what the player has done.
@ -1099,11 +1083,10 @@ public class Game {
/**
* Reset the game state to a lobby.
*
* <p>
* TODO change the message sent to the client if the game reset due to insufficient players.
*
* @param lostPlayer
* True if because there are no long enough people to play a game, false if because the
* @param lostPlayer True if because there are no long enough people to play a game, false if because the
* previous game finished.
*/
public void resetState(final boolean lostPlayer) {
@ -1293,8 +1276,7 @@ public class Game {
}
/**
* @param user
* User to return white cards for.
* @param user User to return white cards for.
* @return The white cards the specified user can see, i.e., theirs and face-down cards for
* everyone else.
*/
@ -1328,8 +1310,7 @@ public class Game {
/**
* Convert a list of {@code WhiteCard}s to data suitable for sending to a client.
*
* @param cards
* Cards to convert to client data.
* @param cards Cards to convert to client data.
* @return Client representation of {@code cards}.
*/
private List<Map<WhiteCardData, Object>> getWhiteCardData(final List<WhiteCard> cards) {
@ -1344,10 +1325,8 @@ public class Game {
/**
* Send a list of {@code WhiteCard}s to a player.
*
* @param player
* Player to send the cards to.
* @param cards
* The cards to send the player.
* @param player Player to send the cards to.
* @param cards The cards to send the player.
*/
private void sendCardsToPlayer(final Player player, final List<WhiteCard> cards) {
final Map<ReturnableData, Object> data = getEventMap();
@ -1360,8 +1339,7 @@ public class Game {
/**
* Get a client data representation of a user's hand.
*
* @param user
* User whose hand to convert to client data.
* @param user User whose hand to convert to client data.
* @return Client representation of {@code user}'s hand.
*/
@Nonnull
@ -1408,12 +1386,9 @@ public class Game {
/**
* Play a card.
*
* @param user
* User playing the card.
* @param cardId
* ID of the card to play.
* @param cardText
* User text for a blank card. Ignored for normal cards.
* @param user User playing the card.
* @param cardId ID of the card to play.
* @param cardText User text for a blank card. Ignored for normal cards.
* @return An {@code ErrorCode} if the play was unsuccessful ({@code user} doesn't have the card,
* {@code user} is the judge, etc.), or {@code null} if there was no error and the play
* was successful.
@ -1472,10 +1447,8 @@ public class Game {
* black cards that have multiple selection, however only the first card in the set's ID will be
* passed around to clients.
*
* @param judge
* Judge user.
* @param cardId
* Selected card ID.
* @param judge Judge user.
* @param cardId Selected card ID.
* @return Error code if there is an error, or null if success.
*/
public ErrorCode judgeCard(final User judge, final int cardId) {

View File

@ -1,25 +1,19 @@
package net.socialgamer.cah.handlers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxOperation;
import net.socialgamer.cah.Constants.AjaxResponse;
import net.socialgamer.cah.Constants.CardSetData;
import net.socialgamer.cah.Constants.ErrorCode;
import net.socialgamer.cah.Constants.ReturnableData;
import com.google.inject.Inject;
import net.socialgamer.cah.Constants.*;
import net.socialgamer.cah.RequestWrapper;
import net.socialgamer.cah.customsets.CustomDeck;
import net.socialgamer.cah.customsets.CustomCardsService;
import net.socialgamer.cah.customsets.CustomDeck;
import net.socialgamer.cah.data.Game;
import net.socialgamer.cah.data.GameManager;
import net.socialgamer.cah.data.User;
import com.google.inject.Inject;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ListCardsetsHandler extends GameWithPlayerHandler {

View File

@ -1,26 +1,18 @@
package net.socialgamer.cah.handlers;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpSession;
import net.socialgamer.cah.Constants.AjaxOperation;
import net.socialgamer.cah.Constants.AjaxRequest;
import net.socialgamer.cah.Constants.ErrorCode;
import net.socialgamer.cah.Constants.GameState;
import net.socialgamer.cah.Constants.LongPollEvent;
import net.socialgamer.cah.Constants.LongPollResponse;
import net.socialgamer.cah.Constants.ReturnableData;
import com.google.inject.Inject;
import net.socialgamer.cah.Constants.*;
import net.socialgamer.cah.RequestWrapper;
import net.socialgamer.cah.customsets.CustomDeck;
import net.socialgamer.cah.customsets.CustomCardsService;
import net.socialgamer.cah.customsets.CustomDeck;
import net.socialgamer.cah.data.Game;
import net.socialgamer.cah.data.GameManager;
import net.socialgamer.cah.data.QueuedMessage.MessageType;
import net.socialgamer.cah.data.User;
import com.google.inject.Inject;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
public class RemoveCardsetHandler extends GameWithPlayerHandler {