Chat messages are now part of the game.

This commit is contained in:
marcins78
2013-01-08 17:13:59 +00:00
parent 68933856d8
commit 3accb1ffa7
10 changed files with 145 additions and 48 deletions

View File

@@ -19,6 +19,8 @@ public class EventSerializer {
eventElem.setAttribute("cardId", gameEvent.getCardId().toString());
if (gameEvent.getIndex() != null)
eventElem.setAttribute("index", gameEvent.getIndex().toString());
if (gameEvent.getDate() != null)
eventElem.setAttribute("date", String.valueOf(gameEvent.getDate().getTime()));
if (gameEvent.getControllerId() != null)
eventElem.setAttribute("controllerId", gameEvent.getControllerId());
if (gameEvent.getParticipantId() != null)

View File

@@ -7,6 +7,7 @@ import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.logic.decisions.AwaitingDecision;
import com.gempukku.lotro.logic.timing.GameStats;
import java.util.Date;
import java.util.List;
public class GameEvent {
@@ -18,10 +19,11 @@ public class GameEvent {
AT, RT,
M, W,
GS,
CAC, EP, CA, D
CAC, EP, CA, D, CH
}
private String _message;
private Date _date;
private String _side;
private Type _type;
private Zone _zone;
@@ -52,6 +54,15 @@ public class GameEvent {
return this;
}
public Date getDate() {
return _date;
}
public GameEvent date(Date date) {
_date = date;
return this;
}
public Type getType() {
return _type;
}

View File

@@ -3,7 +3,6 @@ package com.gempukku.lotro.game;
import com.gempukku.lotro.common.ApplicationConfiguration;
import com.gempukku.lotro.game.state.EventSerializer;
import com.gempukku.lotro.game.state.GameEvent;
import com.gempukku.lotro.game.state.GatheringParticipantCommunicationChannel;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

View File

@@ -1,8 +1,10 @@
package com.gempukku.lotro.game.state;
package com.gempukku.lotro.game;
import com.gempukku.lotro.chat.ChatMessage;
import com.gempukku.lotro.chat.ChatRoomListener;
import com.gempukku.lotro.common.Token;
import com.gempukku.lotro.communication.GameStateListener;
import com.gempukku.lotro.game.PhysicalCard;
import com.gempukku.lotro.game.state.GameEvent;
import com.gempukku.lotro.logic.decisions.AwaitingDecision;
import com.gempukku.lotro.logic.timing.GameStats;
@@ -10,7 +12,7 @@ import java.util.*;
import static com.gempukku.lotro.game.state.GameEvent.Type.*;
public class GatheringParticipantCommunicationChannel implements GameStateListener {
public class GatheringParticipantCommunicationChannel implements GameStateListener, ChatRoomListener {
private List<GameEvent> _events = new LinkedList<GameEvent>();
private String _self;
private Date _lastConsumed = new Date();
@@ -43,6 +45,11 @@ public class GatheringParticipantCommunicationChannel implements GameStateListen
return result;
}
@Override
public void messageReceived(ChatMessage message) {
_events.add(new GameEvent(CH).participantId(message.getFrom()).message(message.getMessage()).date(message.getWhen()));
}
@Override
public void addAssignment(PhysicalCard freePeople, Set<PhysicalCard> minions) {
_events.add(new GameEvent(AA).cardId(freePeople.getCardId()).otherCardIds(getCardIds(minions)));

View File

@@ -3,11 +3,11 @@ package com.gempukku.lotro.game;
import com.gempukku.lotro.PrivateInformationException;
import com.gempukku.lotro.SubscriptionConflictException;
import com.gempukku.lotro.SubscriptionExpiredException;
import com.gempukku.lotro.chat.ChatRoom;
import com.gempukku.lotro.common.*;
import com.gempukku.lotro.communication.GameStateListener;
import com.gempukku.lotro.filters.Filters;
import com.gempukku.lotro.game.state.GameEvent;
import com.gempukku.lotro.game.state.GatheringParticipantCommunicationChannel;
import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.decisions.AwaitingDecision;
import com.gempukku.lotro.logic.decisions.DecisionResultInvalidException;
@@ -40,6 +40,7 @@ public class LotroGameMediator {
private ReentrantReadWriteLock.ReadLock _readLock = _lock.readLock();
private ReentrantReadWriteLock.WriteLock _writeLock = _lock.writeLock();
private int _channelNextIndex = 0;
private ChatRoom _chatRoom;
public LotroGameMediator(LotroFormat lotroFormat, LotroGameParticipant[] participants, LotroCardBlueprintLibrary library, int maxSecondsForGamePerPlayer,
boolean allowSpectators, boolean cancellable) {
@@ -61,6 +62,7 @@ public class LotroGameMediator {
_userFeedback = new DefaultUserFeedback();
_lotroGame = new DefaultLotroGame(lotroFormat, decks, _userFeedback, library);
_userFeedback.setGame(_lotroGame);
_chatRoom = new ChatRoom(false);
}
public boolean isAllowSpectators() {
@@ -77,6 +79,14 @@ public class LotroGameMediator {
_lotroGame.getGameState().sendMessage(message);
}
public void sendMessage(Player player, String message) throws PrivateInformationException {
String playerName = player.getName();
if (!player.getType().contains("a") && !_allowSpectators && !_playersPlaying.contains(playerName))
throw new PrivateInformationException();
_chatRoom.postMessage(playerName, message);
}
public void addGameStateListener(String playerId, GameStateListener listener) {
_lotroGame.addGameStateListener(playerId, listener);
}
@@ -239,6 +249,7 @@ public class LotroGameMediator {
if (currentTime > channel.getLastConsumed().getTime() + _playerDecisionTimeoutPeriod) {
_lotroGame.removeGameStateListener(channel);
_communicationChannels.remove(playerId);
_chatRoom.partChatRoom(playerId);
}
}
@@ -404,6 +415,7 @@ public class LotroGameMediator {
_communicationChannels.put(playerName, participantCommunicationChannel);
_lotroGame.addGameStateListener(playerName, participantCommunicationChannel);
_chatRoom.joinChatRoom(playerName, participantCommunicationChannel);
visitor.visitChannelNumber(number);

View File

@@ -142,6 +142,26 @@ public class GameResource extends AbstractResource {
gameMediator.cancel(resourceOwner);
}
@Path("/{gameId}/chat")
@POST
public void sendMessage(
@PathParam("gameId") String gameId,
@FormParam("message") String message,
@FormParam("participantId") String participantId,
@Context HttpServletRequest request) throws ParserConfigurationException {
Player resourceOwner = getResourceOwnerSafely(request, participantId);
LotroGameMediator gameMediator = _lotroServer.getGameById(gameId);
if (gameMediator == null)
throw new WebApplicationException(Response.Status.NOT_FOUND);
try {
gameMediator.sendMessage(resourceOwner, message);
} catch (PrivateInformationException e) {
throw new WebApplicationException(Response.Status.FORBIDDEN);
}
}
@Path("/{gameId}")
@POST
@Produces(MediaType.APPLICATION_XML)
@@ -174,7 +194,7 @@ public class GameResource extends AbstractResource {
// Use long polling
long start = System.currentTimeMillis();
while (System.currentTimeMillis()< start+_longPollingLength && !gameMediator.hasAnyNewMessages(resourceOwner, channelNumber)) {
while (System.currentTimeMillis() < start + _longPollingLength && !gameMediator.hasAnyNewMessages(resourceOwner, channelNumber)) {
try {
Thread.sleep(_longPollingInterval);
} catch (InterruptedException exp) {

View File

@@ -21,8 +21,9 @@ var ChatBoxUI = Class.extend({
lockChat:false,
stopUpdates: false,
sendMessageFunc: null,
init:function (name, div, url, showList, playerListener, showHideSystemButton, showLockButton) {
init:function (name, div, url, showList, playerListener, showHideSystemButton, showLockButton, startChat) {
var that = this;
this.hiddenClasses = new Array();
this.playerListener = playerListener;
@@ -40,37 +41,37 @@ var ChatBoxUI = Class.extend({
if (showHideSystemButton) {
this.hideSystemButton = $("<button id='showSystemMessages'>Toggle system messages</button>").button(
{icons:{
primary:"ui-icon-zoomin"
}, text:false});
{icons:{
primary:"ui-icon-zoomin"
}, text:false});
this.hideSystemButton.click(
function () {
if (that.isShowingMessageClass("systemMessage")) {
$('#showSystemMessages').button("option", "icons", {primary:'ui-icon-zoomin'});
that.hideMessageClass("systemMessage");
} else {
$('#showSystemMessages').button("option", "icons", {primary:'ui-icon-zoomout'});
that.showMessageClass("systemMessage");
}
});
function () {
if (that.isShowingMessageClass("systemMessage")) {
$('#showSystemMessages').button("option", "icons", {primary:'ui-icon-zoomin'});
that.hideMessageClass("systemMessage");
} else {
$('#showSystemMessages').button("option", "icons", {primary:'ui-icon-zoomout'});
that.showMessageClass("systemMessage");
}
});
this.hideMessageClass("systemMessage");
}
if (showLockButton) {
this.lockButton = $("<button id='lockChatButton'>Toggle lock chat</button>").button(
{icons:{
primary:"ui-icon-locked"
}, text:false});
{icons:{
primary:"ui-icon-locked"
}, text:false});
this.lockButton.click(
function () {
if (that.lockChat) {
$('#lockChatButton').button("option", "icons", {primary:'ui-icon-locked'});
that.lockChat = false;
} else {
$('#lockChatButton').button("option", "icons", {primary:'ui-icon-unlocked'});
that.lockChat = true;
}
});
function () {
if (that.lockChat) {
$('#lockChatButton').button("option", "icons", {primary:'ui-icon-locked'});
that.lockChat = false;
} else {
$('#lockChatButton').button("option", "icons", {primary:'ui-icon-unlocked'});
that.lockChat = true;
}
});
}
if (showList) {
@@ -83,10 +84,12 @@ var ChatBoxUI = Class.extend({
this.div.append(this.lockButton);
this.div.append(this.chatTalkDiv);
this.communication.startChat(this.name,
if (startChat) {
this.communication.startChat(this.name,
function (xml) {
that.processMessages(xml, true);
}, this.chatErrorMap());
}
this.chatTalkDiv.bind("keypress", function (e) {
var code = (e.keyCode ? e.keyCode : e.which);
@@ -150,6 +153,19 @@ var ChatBoxUI = Class.extend({
}
},
appendChatMessage: function(from, dateObj, text) {
var msgClass = "chatMessage";
if (from == "System")
msgClass = "systemMessage";
if (this.showTimestamps) {
var date = new Date(parseInt(dateObj));
var dateStr = this.monthNames[date.getMonth()] + " " + date.getDate() + " " + this.formatToTwoDigits(date.getHours()) + ":" + this.formatToTwoDigits(date.getMinutes()) + ":" + this.formatToTwoDigits(date.getSeconds());
this.appendMessage("<div class='timestamp'>[" + dateStr + "]</div> <b>" + from + ":</b> " + text, msgClass);
} else {
this.appendMessage("<b>" + from + ":</b> " + text, msgClass);
}
},
appendMessage:function (message, msgClass) {
if (msgClass == undefined)
msgClass = "chatMessage";
@@ -187,16 +203,7 @@ var ChatBoxUI = Class.extend({
var from = message.getAttribute("from");
var text = message.childNodes[0].nodeValue;
var msgClass = "chatMessage";
if (from == "System")
msgClass = "systemMessage";
if (this.showTimestamps) {
var date = new Date(parseInt(message.getAttribute("date")));
var dateStr = this.monthNames[date.getMonth()] + " " + date.getDate() + " " + this.formatToTwoDigits(date.getHours()) + ":" + this.formatToTwoDigits(date.getMinutes()) + ":" + this.formatToTwoDigits(date.getSeconds());
this.appendMessage("<div class='timestamp'>[" + dateStr + "]</div> <b>" + from + ":</b> " + text, msgClass);
} else {
this.appendMessage("<b>" + from + ":</b> " + text, msgClass);
}
this.appendChatMessage(from, message.getAttribute("date"), text);
}
var users = root.getElementsByTagName("user");
@@ -239,10 +246,14 @@ var ChatBoxUI = Class.extend({
},
sendMessage:function (message) {
var that = this;
this.communication.sendChatMessage(this.name, message, function(xml) {
that.processMessages(xml, false);
}, this.chatErrorMap());
if (this.sendMessageFunc != null) {
this.sendMessageFunc(message);
} else {
var that = this;
this.communication.sendChatMessage(this.name, message, function(xml) {
that.processMessages(xml, false);
}, this.chatErrorMap());
}
},
chatMalfunction: function() {

View File

@@ -208,6 +208,20 @@ var GempLotrCommunication = Class.extend({
dataType:"xml"
});
},
sendGameMessage: function(message, callback, errorMap) {
$.ajax({
type:"POST",
url:this.url + "/game/" + getUrlParam("gameId")+"/chat",
cache:false,
async: false,
data:{
message: message,
participantId:getUrlParam("participantId") },
success:this.deliveryCheck(callback),
error:this.errorCheck(errorMap),
dataType:"xml"
});
},
getGameCardModifiers:function (cardId, callback, errorMap) {
$.ajax({
type:"GET",

View File

@@ -863,6 +863,21 @@ var GameAnimations = Class.extend({
});
},
chatMessage:function (element, animate) {
var that = this;
$("#main").queue(
function (next) {
var from = element.getAttribute("participantId");
var date = element.getAttribute("date");
var message = element.getAttribute("message");
if (that.game.chatBox != null)
that.game.chatBox.appendChatMessage(form, date, message);
next();
});
},
warning:function (element, animate) {
var that = this;
$("#main").queue(

View File

@@ -474,7 +474,11 @@ var GempLotrGameUI = Class.extend({
};
var chatRoomName = (this.replayMode ? null : ("Game" + getUrlParam("gameId")));
this.chatBox = new ChatBoxUI(chatRoomName, $("#chatBox"), this.communication.url, false, playerListener, false, true);
this.chatBox = new ChatBoxUI(chatRoomName, $("#chatBox"), this.communication.url, false, playerListener, false, true, false);
this.chatBox.sendMessageFunc =
function(message) {
this.comm.sendGameMessage(message, function() {}, this.gameErrorMap());
};
this.chatBox.chatUpdateInterval = 3000;
if (!this.spectatorMode && !this.replayMode) {
@@ -1053,6 +1057,8 @@ var GempLotrGameUI = Class.extend({
this.animations.cardActivated(gameEvent, animate);
} else if (eventType == "D") {
this.animations.processDecision(gameEvent, animate);
} else if (eventType == "CH") {
this.animations.chatMessage(gameEvent, animate);
}
},