package com.teefun.model;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import com.teefun.model.teeworlds.TeeworldsConfig;
import com.teefun.model.teeworlds.TeeworldsServer;
import com.teefun.util.TeeworldsConfigUtil;
/**
* A queue representation.
*
* @author Choupom
*
*/
public class Queue {
/**
* Queue counter to generate id.
*/
private static final AtomicInteger QUEUE_COUNTER = new AtomicInteger();
/**
* Queue id.
*/
private final Integer id;
/**
* Queue name.
*/
private String name;
/**
* Queue capacity.
*/
private int maxSize;
/**
* Map.
*/
private String map;
/**
* Game type.
*/
private String gametype;
/**
* Score limit.
*/
private int scoreLimit;
/**
* Time limit.
*/
private int timeLimit;
/**
* Teeworlds server associated when the game is started.
*/
private TeeworldsServer server;
/**
* Queue state.
*/
private QueueState state = QueueState.WAITING_PLAYERS;
/**
* Is the queue permanent ?. If true it will automatically reset after the game as finised.
*/
private boolean permanent;
/**
* List of players which joined the queue.
*/
private final List<Player> players = new CopyOnWriteArrayList<Player>();
/**
* List of player ready.
*/
private final List<Player> playersReady = new ArrayList<Player>();
/**
* List of player not ready.
*/
private final List<Player> playersNotReady = new ArrayList<Player>();
/**
* Default constructor.
*/
public Queue() {
this.id = QUEUE_COUNTER.getAndAdd(1);
}
/**
* Make a config for this server.
*
* @return the configuration
*/
public TeeworldsConfig makeConfig() {
final TeeworldsConfig config = TeeworldsConfigUtil.getDefaultConfig();
config.setVariable("sv_name", String.format("TeeFun #%d", this.id));
config.setVariable("sv_map", this.map);
config.setVariable("sv_max_clients", this.maxSize);
config.setVariable("sv_scorelimit", this.scoreLimit);
config.setVariable("sv_timelimit", this.timeLimit);
config.setVariable("sv_gametype", this.gametype);
return config;
}
/**
* @return the {@link #id}
*/
public Integer getId() {
return this.id;
}
/**
* @return the {@link #name}
*/
public String getName() {
return this.name;
}
/**
* @return the {@link #maxSize}
*/
public int getMaxSize() {
return this.maxSize;
}
/**
* @return the {@link #map}
*/
public String getMap() {
return this.map;
}
/**
* @return the {@link #gametype}
*/
public String getGametype() {
return this.gametype;
}
/**
* @return the {@link #scoreLimit}
*/
public int getScoreLimit() {
return this.scoreLimit;
}
/**
* @return the {@link #timeLimit}
*/
public int getTimeLimit() {
return this.timeLimit;
}
/**
* @return the current size
*/
public int getSize() {
return this.players.size();
}
/**
* Add a player to queue.
*
* @param player the player to be added
*/
public void addPlayer(final Player player) {
if (QueueState.WAITING_PLAYERS != this.state) {
return;
}
if (this.players.size() < this.maxSize && !this.players.contains(player)) {
this.players.add(player);
}
}
/**
* Remove a player from queue.
*
* @param player the player to be removed
*/
public boolean removePlayer(final Player player) {
if (QueueState.WAITING_PLAYERS != this.state) {
return false;
}
return this.players.remove(player);
}
/**
* Is the player in this queue ?
*
* @param player the player
* @return true if the player is in this queue
*/
public boolean containsPlayer(final Player player) {
return this.players.contains(player);
}
/**
* @return the {@link #players}
*/
public List<Player> getPlayers() {
return this.players;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(this.name).append(this.id).toHashCode();
}
@Override
public boolean equals(final Object obj) {
if (obj instanceof Queue) {
final Queue other = (Queue) obj;
return new EqualsBuilder().append(this.id, other.id).isEquals();
} else {
return false;
}
}
/**
* @return true if the queue is full
*/
public boolean isFull() {
return this.players.size() == this.maxSize;
}
/**
* @return the {@link #server}
*/
public TeeworldsServer getServer() {
return this.server;
}
/**
* @param server the {@link #server} to set
*/
public void setServer(final TeeworldsServer server) {
this.server = server;
}
/**
* @return the {@link #state}
*/
public QueueState getState() {
return this.state;
}
/**
* @param queueState the {@link #state} to set
*/
public void setState(final QueueState queueState) {
this.state = queueState;
}
/**
* @return the {@link #permanent}
*/
public boolean isPermanent() {
return this.permanent;
}
/**
* @return the {@link #playersReady}
*/
public List<Player> getPlayersReady() {
return this.playersReady;
}
/**
* @return the {@link #playersNotReady}
*/
public List<Player> getPlayersNotReady() {
return this.playersNotReady;
}
/**
* @param name the {@link #name} to set
*/
public void setName(final String name) {
this.name = name;
}
/**
* @param maxSize the {@link #maxSize} to set
*/
public void setMaxSize(final int maxSize) {
this.maxSize = maxSize;
}
/**
* @param map the {@link #map} to set
*/
public void setMap(final String map) {
this.map = map;
}
/**
* @param gametype the {@link #gametype} to set
*/
public void setGametype(final String gametype) {
this.gametype = gametype;
}
/**
* @param scoreLimit the {@link #scoreLimit} to set
*/
public void setScoreLimit(final int scoreLimit) {
this.scoreLimit = scoreLimit;
}
/**
* @param timeLimit the {@link #timeLimit} to set
*/
public void setTimeLimit(final int timeLimit) {
this.timeLimit = timeLimit;
}
/**
* @param permanent the {@link #permanent} to set
*/
public void setPermanent(final boolean permanent) {
this.permanent = permanent;
}
/**
* Reset the queue to waiting player state.
*/
public void reset() {
this.state = QueueState.WAITING_PLAYERS;
// Shall we make sure the server is shutdown ?
this.server = null;
this.players.clear();
this.playersNotReady.clear();
this.playersReady.clear();
}
/**
* Set the player ready state.
*
* @param player the player
* @param isReady is the player ready
* @return true if applied
*/
public boolean setPlayerReady(final Player player, final Boolean isReady) {
if (!this.containsPlayer(player)) {
return false;
}
if (this.playersReady.contains(player) || this.playersNotReady.contains(player)) {
return false;
}
if (isReady) {
this.playersReady.add(player);
} else {
this.playersNotReady.add(player);
}
return true;
}
/**
* @return true if every players in queue has respond to ready question
*/
public boolean hasEveryResponse() {
return this.playersReady.size() + this.playersNotReady.size() == this.players.size();
}
/**
* @return true if every players are ready
*/
public boolean isEveryoneReady() {
return this.playersReady.size() == this.players.size();
}
/**
* Remove leavers from queue.
*/
public void removeLeavers() {
for (final Player player : this.players) {
if (!this.playersReady.contains(player)) {
this.players.remove(player);
}
}
this.playersNotReady.clear();
this.playersReady.clear();
}
}