/*
*
* Copyright (c) 2000-2009 by Rodney Kinney, Brent Easton
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License (LGPL) as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, copies are available
* at http://www.opensource.org.
*/
package VASSAL.chat;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import VASSAL.command.Command;
import VASSAL.command.CommandEncoder;
import VASSAL.configure.SoundConfigurer;
import VASSAL.i18n.Resources;
import VASSAL.preferences.Prefs;
import VASSAL.tools.SequenceEncoder;
/**
* Encodes commands that play sounds
* This class is used exclusively by the 'Send wake-up' server feature.
* Limit the number of wake-ups we will respond to in a row from the same player
* before querying if we want to ignore them in future.
* Wait at least 5 seconds before responding to a new wake-up.
*/
public class SoundEncoder implements CommandEncoder {
public static final String COMMAND_PREFIX = "PLAY\t"; //$NON-NLS-1$
private PlayerEncoder playerEncoder;
public SoundEncoder(PlayerEncoder p) {
playerEncoder = p;
}
public Command decode(String command) {
if (command.startsWith(COMMAND_PREFIX)) {
SequenceEncoder.Decoder sd = new SequenceEncoder.Decoder(command, '\t');
sd.nextToken();
final String soundKey = sd.nextToken();
final Player sender = playerEncoder.stringToPlayer(sd.nextToken("")); //$NON-NLS-1$
return new Cmd(soundKey, sender);
}
else {
return null;
}
}
public String encode(Command c) {
String s = null;
if (c instanceof Cmd) {
Cmd cmd = (Cmd) c;
SequenceEncoder se = new SequenceEncoder('\t');
se.append(cmd.soundKey);
se.append(playerEncoder.playerToString(cmd.getSender()));
s = COMMAND_PREFIX+se.getValue();
}
return s;
}
public static class Cmd extends Command {
private static final int TOO_MANY = 4;
public static final int TOO_SOON = 10 * 1000; // 10s
private static long lastTime = System.currentTimeMillis();
private static Player lastSender;
private static int sendCount;
private static ArrayList<Player> banned = new ArrayList<Player>();
private static boolean updating = false;
private String soundKey;
private Player sender;
public Cmd(String soundKey, Player player) {
this.soundKey = soundKey;
this.sender = player;
}
protected void executeCommand() {
/**
* Ignore if we don't want to hear from this player anymore, we are
* already processing a wake-up, or we have already processed a wake-up recently
*/
final long now = System.currentTimeMillis();
if (banned.contains(sender) || updating || (now - lastTime) < (TOO_SOON)) {
updating = false;
return;
}
updating = true;
lastTime = now;
final SoundConfigurer c = (SoundConfigurer) Prefs.getGlobalPrefs().getOption(soundKey);
if (c != null) {
c.play();
}
if (sender.equals(lastSender)) {
if (sendCount++ >= TOO_MANY) {
if (JOptionPane.YES_OPTION ==
JOptionPane.showConfirmDialog
(null,
Resources.getString("Chat.ignore_wakeups", sender.getName()), //$NON-NLS-1$
null,
JOptionPane.YES_NO_OPTION)) {
banned.add(sender);
}
else {
sendCount = 1;
}
}
}
else {
lastSender = sender;
sendCount = 1;
}
updating = false;
}
protected Command myUndoCommand() {
return null;
}
public Player getSender() {
return sender;
}
}
}