/**
*
*/
package com.teefun.controller.websocket;
import javax.annotation.Resource;
import javax.validation.Valid;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import com.google.common.eventbus.EventBus;
import com.teefun.bean.matchmaking.Matchmaking;
import com.teefun.bean.usercontext.WebsocketUserContext;
import com.teefun.controller.AbstractController;
import com.teefun.controller.websocket.bean.PlayerReadyRequest;
import com.teefun.events.event.PlayerModifiedEvent;
import com.teefun.events.event.PlayerReadyEvent;
import com.teefun.exception.JsonErrorException;
import com.teefun.model.Player;
import com.teefun.model.Queue;
import com.teefun.model.QueueState;
/**
* WebSocket controller.
*
* @author Rajh
*
*/
@Controller
public class WebSocketController extends AbstractController {
/**
* User context.
*/
@Resource
private WebsocketUserContext wsUserContext;
/**
* Matchmaking system.
*/
@Resource
private Matchmaking matchmaking;
/**
* Event bus.
*/
@Resource
private EventBus eventBus;
/**
* Keep active a player.
*/
@MessageMapping("/keepAlive")
public void keepAlive() {
this.wsUserContext.getPlayer().keepAlive();
}
/**
* Change a player's name.
*
* @param name the new name
*/
@MessageMapping(value = "/changeName")
public void changeName(final String name) {
this.wsUserContext.getPlayer().setName(name);
this.eventBus.post(new PlayerModifiedEvent(this.wsUserContext.getPlayer()));
}
/**
* Join a queue.
*
* @param queueId the queue id
* @param bindingResult the binding result
*/
@MessageMapping(value = "/joinQueue")
public void joinQueue(final Integer queueId) {
if (queueId == null) {
throw new JsonErrorException("Queue id is null");
}
final Player player = this.wsUserContext.getPlayer();
final Queue queue = this.matchmaking.getQueueById(queueId);
if (queue == null) {
throw new JsonErrorException("Queue does not exist");
}
if (queue.isFull()) {
throw new JsonErrorException("Queue is full");
}
if (queue.containsPlayer(player)) {
throw new JsonErrorException("Player already in queue");
}
if (queue.getState() != QueueState.WAITING_PLAYERS) {
throw new JsonErrorException("Incorrect queue state");
}
this.matchmaking.joinQueue(player, queue);
}
/**
* Quit a queue.
*
* @param queueId the queue id
* @param bindingResult the binding result
*/
@MessageMapping(value = "/quitQueue")
public void quitQueue(final Integer queueId) {
if (queueId == null) {
throw new JsonErrorException("Queue id is null");
}
final Player player = this.wsUserContext.getPlayer();
final Queue queue = this.matchmaking.getQueueById(queueId);
if (queue == null) {
throw new JsonErrorException("Queue does not exist");
}
if (queue.isFull()) {
throw new JsonErrorException("Queue is full");
}
if (!queue.containsPlayer(player)) {
throw new JsonErrorException("Player is not in this queue");
}
if (queue.getState() != QueueState.WAITING_PLAYERS) {
throw new JsonErrorException("Incorrect queue state");
}
this.matchmaking.quitQueue(player, queue);
}
/**
* Quit all queues.
*/
@MessageMapping(value = "/quitAllQueues")
public void quitAllQueues() {
final Player player = this.wsUserContext.getPlayer();
this.matchmaking.quitAllQueues(player);
}
/**
* Player is ready/notready.
*
* @param queueId the queue id
* @param bindingResult the binding result
* @return the password
*/
@MessageMapping(value = "/askPassword")
public String askPassword(final Integer queueId) {
if (queueId == null) {
throw new JsonErrorException("Queue id is null");
}
final Queue queue = this.matchmaking.getQueueById(queueId);
if (queue == null) {
throw new JsonErrorException("Queue does not exist");
}
if (!queue.containsPlayer(this.wsUserContext.getPlayer())) {
throw new JsonErrorException("Player is not in this queue");
}
if (queue.getState() != QueueState.IN_GAME) {
throw new JsonErrorException("Game not ready");
}
return queue.getServer().getConfig().getVariableAsString("password");
}
/**
* Player is ready/notready.
*
* @param playerReadyRequest the request
* @param bindingResult the binding result
*/
@MessageMapping(value = "/playerReady")
public void playerReady(@RequestBody @Valid final PlayerReadyRequest playerReadyRequest, final BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
throw new JsonErrorException("Request validation failed", bindingResult);
}
final Queue queue = this.matchmaking.getQueueById(playerReadyRequest.getQueueId());
if (queue == null) {
throw new JsonErrorException("Queue does not exist", bindingResult);
}
if (!queue.containsPlayer(this.wsUserContext.getPlayer())) {
throw new JsonErrorException("Player is not in this queue", bindingResult);
}
if (queue.getState() != QueueState.WAITING_READY) {
throw new JsonErrorException("Incorrect queue state", bindingResult);
}
queue.setPlayerReady(this.wsUserContext.getPlayer(), playerReadyRequest.getReady());
this.eventBus.post(new PlayerReadyEvent(this.wsUserContext.getPlayer(), queue));
}
}