Adding chat to the server.
This commit is contained in:
@@ -11,13 +11,14 @@ import java.util.List;
|
||||
public class GameEvent {
|
||||
public enum Type {
|
||||
PARTICIPANT, GAME_PHASE_CHANGE, TURN_CHANGE, PLAYER_POSITION, TWILIGHT_POOL,
|
||||
PUT_CARD_IN_PLAY, MOVE_CARD_IN_PLAY, REMOVE_CARD_FROM_PLAY, ATTACH_CARD,
|
||||
PUT_CARD_IN_PLAY, MOVE_CARD_IN_PLAY, REMOVE_CARD_FROM_PLAY,
|
||||
ADD_ASSIGNMENT, REMOVE_ASSIGNMENT,
|
||||
START_SKIRMISH, END_SKIRMISH,
|
||||
ADD_TOKENS, REMOVE_TOKENS
|
||||
ADD_TOKENS, REMOVE_TOKENS,
|
||||
MESSAGE
|
||||
}
|
||||
|
||||
private String _warning;
|
||||
private String _message;
|
||||
private Type _type;
|
||||
private Zone _zone;
|
||||
private String _participantId;
|
||||
@@ -66,6 +67,15 @@ public class GameEvent {
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return _message;
|
||||
}
|
||||
|
||||
public GameEvent message(String message) {
|
||||
_message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Integer getCount() {
|
||||
return _count;
|
||||
}
|
||||
@@ -84,15 +94,6 @@ public class GameEvent {
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getWarning() {
|
||||
return _warning;
|
||||
}
|
||||
|
||||
public GameEvent warning(String warning) {
|
||||
_warning = warning;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getParticipantId() {
|
||||
return _participantId;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.gempukku.lotro;
|
||||
|
||||
import com.gempukku.lotro.chat.ChatMessage;
|
||||
import com.gempukku.lotro.chat.ChatRoomListener;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class GatheringChatRoomListener implements ChatRoomListener {
|
||||
private List<ChatMessage> _messages = new LinkedList<ChatMessage>();
|
||||
|
||||
@Override
|
||||
public void messageReceived(ChatMessage message) {
|
||||
_messages.add(message);
|
||||
}
|
||||
|
||||
public List<ChatMessage> consumeMessages() {
|
||||
List<ChatMessage> messages = _messages;
|
||||
_messages = new LinkedList<ChatMessage>();
|
||||
return messages;
|
||||
}
|
||||
}
|
||||
@@ -98,6 +98,10 @@ public class GatheringParticipantCommunicationChannel implements GameStateListen
|
||||
_events.add(new GameEvent(REMOVE_TOKENS).card(card).token(token).count(count));
|
||||
}
|
||||
|
||||
public void sendMessage(String message) {
|
||||
_events.add(new GameEvent(MESSAGE).message(message));
|
||||
}
|
||||
|
||||
public List<GameEvent> consumeGameEvents() {
|
||||
List<GameEvent> result = _events;
|
||||
_events = new LinkedList<GameEvent>();
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.gempukku.lotro.chat;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class ChatMessage {
|
||||
private Date _when;
|
||||
private String _from;
|
||||
private String _message;
|
||||
|
||||
public ChatMessage(Date when, String from, String message) {
|
||||
_when = when;
|
||||
_from = from;
|
||||
_message = message;
|
||||
}
|
||||
|
||||
public String getFrom() {
|
||||
return _from;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return _message;
|
||||
}
|
||||
|
||||
public Date getWhen() {
|
||||
return _when;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.gempukku.lotro.chat;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
public class ChatRoom {
|
||||
private int _maxMessageCount = 10;
|
||||
private LinkedList<ChatMessage> _lastMessages = new LinkedList<ChatMessage>();
|
||||
private Map<String, ChatRoomListener> _chatRoomListeners = new HashMap<String, ChatRoomListener>();
|
||||
|
||||
public void postMessage(String from, String message) {
|
||||
ChatMessage chatMessage = new ChatMessage(new Date(), from, message);
|
||||
_lastMessages.add(chatMessage);
|
||||
shrinkLastMessages();
|
||||
for (Map.Entry<String, ChatRoomListener> listeners : _chatRoomListeners.entrySet())
|
||||
if (!listeners.getKey().equals(from))
|
||||
listeners.getValue().messageReceived(chatMessage);
|
||||
}
|
||||
|
||||
public void joinChatRoom(String playerId, ChatRoomListener listener) {
|
||||
_chatRoomListeners.put(playerId, listener);
|
||||
for (ChatMessage lastMessage : _lastMessages)
|
||||
listener.messageReceived(lastMessage);
|
||||
}
|
||||
|
||||
public void partChatRoom(String playerId) {
|
||||
_chatRoomListeners.remove(playerId);
|
||||
}
|
||||
|
||||
private void shrinkLastMessages() {
|
||||
while (_lastMessages.size() > _maxMessageCount) {
|
||||
_lastMessages.removeFirst();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.gempukku.lotro.chat;
|
||||
|
||||
public interface ChatRoomListener {
|
||||
public void messageReceived(ChatMessage message);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.gempukku.lotro.chat;
|
||||
|
||||
import com.gempukku.lotro.GatheringChatRoomListener;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ChatRoomMediator {
|
||||
private ChatRoom _chatRoom = new ChatRoom();
|
||||
|
||||
private Map<String, GatheringChatRoomListener> _listeners = new HashMap<String, GatheringChatRoomListener>();
|
||||
|
||||
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)
|
||||
return null;
|
||||
return gatheringChatRoomListener.consumeMessages();
|
||||
}
|
||||
|
||||
public synchronized void partUser(String playerId) {
|
||||
_chatRoom.partChatRoom(playerId);
|
||||
_listeners.remove(playerId);
|
||||
}
|
||||
|
||||
public synchronized void sendMessage(String playerId, String message) {
|
||||
_chatRoom.postMessage(playerId, message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.gempukku.lotro.chat;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class ChatServer {
|
||||
private Map<String, ChatRoomMediator> _chatRooms = new ConcurrentHashMap<String, ChatRoomMediator>();
|
||||
|
||||
private boolean _started;
|
||||
private CleaningTask _cleaningTask;
|
||||
|
||||
public void createChatRoom(String name) {
|
||||
_chatRooms.put(name, new ChatRoomMediator());
|
||||
}
|
||||
|
||||
public ChatRoomMediator getChatRoom(String name) {
|
||||
return _chatRooms.get(name);
|
||||
}
|
||||
|
||||
public void destroyChatRoom(String name) {
|
||||
_chatRooms.remove(name);
|
||||
}
|
||||
|
||||
public synchronized void startServer() {
|
||||
if (!_started) {
|
||||
_cleaningTask = new CleaningTask();
|
||||
new Thread(_cleaningTask).start();
|
||||
_started = true;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void stopServer() {
|
||||
if (_started) {
|
||||
_cleaningTask.stop();
|
||||
_started = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void cleanup() {
|
||||
// TODO cleanup server
|
||||
}
|
||||
|
||||
private class CleaningTask implements Runnable {
|
||||
private boolean _running = true;
|
||||
|
||||
public void run() {
|
||||
while (_running) {
|
||||
cleanup();
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
_running = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,9 @@ import com.gempukku.lotro.GameEvent;
|
||||
import com.gempukku.lotro.LotroGameMediator;
|
||||
import com.gempukku.lotro.LotroGameParticipant;
|
||||
import com.gempukku.lotro.LotroServer;
|
||||
import com.gempukku.lotro.chat.ChatMessage;
|
||||
import com.gempukku.lotro.chat.ChatRoomMediator;
|
||||
import com.gempukku.lotro.chat.ChatServer;
|
||||
import com.gempukku.lotro.db.DeckDAO;
|
||||
import com.gempukku.lotro.db.PlayerDAO;
|
||||
import com.gempukku.lotro.db.vo.Deck;
|
||||
@@ -27,6 +30,7 @@ import javax.ws.rs.core.Response;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Singleton
|
||||
@@ -35,6 +39,7 @@ public class ServerResource {
|
||||
private static final Logger _logger = Logger.getLogger(ServerResource.class);
|
||||
|
||||
private LotroServer _lotroServer;
|
||||
private ChatServer _chatServer;
|
||||
|
||||
public ServerResource() {
|
||||
_logger.debug("starting resource");
|
||||
@@ -42,6 +47,10 @@ public class ServerResource {
|
||||
try {
|
||||
_lotroServer = new LotroServer();
|
||||
_lotroServer.startServer();
|
||||
|
||||
_chatServer = new ChatServer();
|
||||
_chatServer.startServer();
|
||||
_chatServer.createChatRoom("default");
|
||||
} catch (RuntimeException exp) {
|
||||
_logger.error("Error while creating resource", exp);
|
||||
exp.printStackTrace();
|
||||
@@ -316,6 +325,72 @@ public class ServerResource {
|
||||
return doc;
|
||||
}
|
||||
|
||||
@Path("/chat/{room}")
|
||||
@GET
|
||||
@Produces(MediaType.APPLICATION_XML)
|
||||
public Document getMessages(
|
||||
@PathParam("room") String room,
|
||||
@QueryParam("participantId") String participantId) throws ParserConfigurationException {
|
||||
ChatRoomMediator chatRoom = _chatServer.getChatRoom(room);
|
||||
if (chatRoom == null)
|
||||
sendError(Response.Status.NOT_FOUND);
|
||||
|
||||
List<ChatMessage> chatMessages = chatRoom.joinUser(participantId);
|
||||
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
|
||||
Document doc = documentBuilder.newDocument();
|
||||
|
||||
Element chatElem = doc.createElement("chat");
|
||||
chatElem.setAttribute("roomName", room);
|
||||
doc.appendChild(chatElem);
|
||||
|
||||
for (ChatMessage chatMessage : chatMessages) {
|
||||
Element message = doc.createElement("message");
|
||||
message.setAttribute("from", chatMessage.getFrom());
|
||||
message.setAttribute("date", String.valueOf(chatMessage.getWhen().getTime()));
|
||||
message.appendChild(doc.createTextNode(chatMessage.getMessage()));
|
||||
chatElem.appendChild(message);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
@Path("/chat/{room}")
|
||||
@POST
|
||||
@Produces(MediaType.APPLICATION_XML)
|
||||
public Document postMessage(
|
||||
@PathParam("room") String room,
|
||||
@FormParam("participantId") String participantId,
|
||||
@FormParam("message") String message) throws ParserConfigurationException {
|
||||
ChatRoomMediator chatRoom = _chatServer.getChatRoom(room);
|
||||
if (chatRoom == null)
|
||||
sendError(Response.Status.NOT_FOUND);
|
||||
|
||||
chatRoom.sendMessage(participantId, message);
|
||||
List<ChatMessage> chatMessages = chatRoom.getPendingMessages(participantId);
|
||||
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
|
||||
Document doc = documentBuilder.newDocument();
|
||||
|
||||
Element chatElem = doc.createElement("chat");
|
||||
chatElem.setAttribute("roomName", room);
|
||||
doc.appendChild(chatElem);
|
||||
|
||||
for (ChatMessage chatMessage : chatMessages) {
|
||||
Element messageElem = doc.createElement("message");
|
||||
messageElem.setAttribute("from", chatMessage.getFrom());
|
||||
messageElem.setAttribute("date", String.valueOf(chatMessage.getWhen().getTime()));
|
||||
messageElem.appendChild(doc.createTextNode(chatMessage.getMessage()));
|
||||
chatElem.appendChild(messageElem);
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
private class SerializationVisitor implements ParticipantCommunicationVisitor {
|
||||
private Document _doc;
|
||||
private Element _element;
|
||||
|
||||
Reference in New Issue
Block a user