improved replays - can now skip forward 10 moves or let the client play through the moves

This commit is contained in:
BetaSteward 2011-09-05 22:12:36 -04:00
parent 6d4c3aa8d9
commit f5c3494723
12 changed files with 142 additions and 20 deletions

View file

@ -60,6 +60,8 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.*;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
import mage.client.components.MageComponents; import mage.client.components.MageComponents;
@ -79,6 +81,7 @@ public class GamePanel extends javax.swing.JPanel {
private UUID gameId; private UUID gameId;
private UUID playerId; private UUID playerId;
private Session session; private Session session;
private ReplayTask replayTask;
private CombatDialog combat; private CombatDialog combat;
private PickNumberDialog pickNumber; private PickNumberDialog pickNumber;
private JLayeredPane jLayeredPane; private JLayeredPane jLayeredPane;
@ -572,8 +575,10 @@ public class GamePanel extends javax.swing.JPanel {
stack = new mage.client.cards.Cards(); stack = new mage.client.cards.Cards();
pnlReplay = new javax.swing.JPanel(); pnlReplay = new javax.swing.JPanel();
btnStopReplay = new javax.swing.JButton(); btnStopReplay = new javax.swing.JButton();
btnPreviousPlay = new javax.swing.JButton();
btnNextPlay = new javax.swing.JButton(); btnNextPlay = new javax.swing.JButton();
btnPlay = new javax.swing.JButton();
btnSkipForward = new javax.swing.JButton();
btnPreviousPlay = new javax.swing.JButton();
pnlBattlefield = new javax.swing.JPanel(); pnlBattlefield = new javax.swing.JPanel();
hand = new mage.client.cards.Cards(true); hand = new mage.client.cards.Cards(true);
gameChatPanel = new mage.client.chat.ChatPanel(); gameChatPanel = new mage.client.chat.ChatPanel();
@ -664,44 +669,63 @@ public class GamePanel extends javax.swing.JPanel {
stack.setPreferredSize(new java.awt.Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight + 25)); stack.setPreferredSize(new java.awt.Dimension(Config.dimensions.frameWidth, Config.dimensions.frameHeight + 25));
btnStopReplay.setText("Stop"); btnStopReplay.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/control_stop.png"))); // NOI18N
btnStopReplay.addActionListener(new java.awt.event.ActionListener() { btnStopReplay.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
btnStopReplayActionPerformed(evt); btnStopReplayActionPerformed(evt);
} }
}); });
btnPreviousPlay.setText("Previous"); btnNextPlay.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/control_stop_right.png"))); // NOI18N
btnPreviousPlay.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnPreviousPlayActionPerformed(evt);
}
});
btnNextPlay.setText("Next");
btnNextPlay.addActionListener(new java.awt.event.ActionListener() { btnNextPlay.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) { public void actionPerformed(java.awt.event.ActionEvent evt) {
btnNextPlayActionPerformed(evt); btnNextPlayActionPerformed(evt);
} }
}); });
btnPlay.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/control_right.png"))); // NOI18N
btnPlay.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnPlayActionPerformed(evt);
}
});
btnSkipForward.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/control_double_stop_right.png"))); // NOI18N
btnSkipForward.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnSkipForwardActionPerformed(evt);
}
});
btnPreviousPlay.setIcon(new javax.swing.ImageIcon(getClass().getResource("/buttons/control_stop_left.png"))); // NOI18N
btnPreviousPlay.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnPreviousPlayActionPerformed(evt);
}
});
javax.swing.GroupLayout pnlReplayLayout = new javax.swing.GroupLayout(pnlReplay); javax.swing.GroupLayout pnlReplayLayout = new javax.swing.GroupLayout(pnlReplay);
pnlReplay.setLayout(pnlReplayLayout); pnlReplay.setLayout(pnlReplayLayout);
pnlReplayLayout.setHorizontalGroup( pnlReplayLayout.setHorizontalGroup(
pnlReplayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) pnlReplayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnlReplayLayout.createSequentialGroup() .addGroup(pnlReplayLayout.createSequentialGroup()
.addComponent(btnStopReplay) .addComponent(btnPreviousPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnPreviousPlay) .addComponent(btnPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(btnStopReplay, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnNextPlay)) .addComponent(btnNextPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(btnSkipForward, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE))
); );
pnlReplayLayout.setVerticalGroup( pnlReplayLayout.setVerticalGroup(
pnlReplayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) pnlReplayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnlReplayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(btnSkipForward, 0, 0, Short.MAX_VALUE)
.addComponent(btnStopReplay) .addComponent(btnNextPlay, 0, 0, Short.MAX_VALUE)
.addComponent(btnPreviousPlay) .addComponent(btnStopReplay, 0, 0, Short.MAX_VALUE)
.addComponent(btnNextPlay)) .addComponent(btnPlay, 0, 0, Short.MAX_VALUE)
.addComponent(btnPreviousPlay, javax.swing.GroupLayout.PREFERRED_SIZE, 31, Short.MAX_VALUE)
); );
javax.swing.GroupLayout pnlGameInfoLayout = new javax.swing.GroupLayout(pnlGameInfo); javax.swing.GroupLayout pnlGameInfoLayout = new javax.swing.GroupLayout(pnlGameInfo);
@ -919,7 +943,10 @@ public class GamePanel extends javax.swing.JPanel {
}//GEN-LAST:event_btnStopWatchingActionPerformed }//GEN-LAST:event_btnStopWatchingActionPerformed
private void btnStopReplayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStopReplayActionPerformed private void btnStopReplayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnStopReplayActionPerformed
if (modalQuestion("Are you sure you want to stop replay?", "Stop replay") == JOptionPane.YES_OPTION) { if (replayTask != null && !replayTask.isDone()) {
replayTask.cancel(true);
}
else if (modalQuestion("Are you sure you want to stop replay?", "Stop replay") == JOptionPane.YES_OPTION) {
session.stopReplay(gameId); session.stopReplay(gameId);
} }
}//GEN-LAST:event_btnStopReplayActionPerformed }//GEN-LAST:event_btnStopReplayActionPerformed
@ -931,7 +958,18 @@ public class GamePanel extends javax.swing.JPanel {
private void btnPreviousPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPreviousPlayActionPerformed private void btnPreviousPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPreviousPlayActionPerformed
session.previousPlay(gameId); session.previousPlay(gameId);
}//GEN-LAST:event_btnPreviousPlayActionPerformed }//GEN-LAST:event_btnPreviousPlayActionPerformed
private void btnPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPlayActionPerformed
if (replayTask == null || replayTask.isDone()) {
replayTask = new ReplayTask(session, gameId);
replayTask.execute();
}
}//GEN-LAST:event_btnPlayActionPerformed
private void btnSkipForwardActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSkipForwardActionPerformed
session.skipForward(gameId, 10);
}//GEN-LAST:event_btnSkipForwardActionPerformed
private Dimension getHandCardDimension() { private Dimension getHandCardDimension() {
Preferences pref = MageFrame.getPreferences(); Preferences pref = MageFrame.getPreferences();
String useBigCards = pref.get(PreferencesDialog.KEY_HAND_USE_BIG_CARDS, "false"); String useBigCards = pref.get(PreferencesDialog.KEY_HAND_USE_BIG_CARDS, "false");
@ -966,6 +1004,7 @@ public class GamePanel extends javax.swing.JPanel {
setOpaque(false); setOpaque(false);
jPanel.setOpaque(false); jPanel.setOpaque(false);
jScrollPane1.setOpaque(false); jScrollPane1.setOpaque(false);
pnlReplay.setOpaque(false);
jPanel.setBorder(emptyBorder); jPanel.setBorder(emptyBorder);
jScrollPane1.setBorder(emptyBorder); jScrollPane1.setBorder(emptyBorder);
@ -1000,7 +1039,9 @@ public class GamePanel extends javax.swing.JPanel {
private javax.swing.JButton btnConcede; private javax.swing.JButton btnConcede;
private javax.swing.JButton btnSwitchHands; private javax.swing.JButton btnSwitchHands;
private javax.swing.JButton btnNextPlay; private javax.swing.JButton btnNextPlay;
private javax.swing.JButton btnPlay;
private javax.swing.JButton btnPreviousPlay; private javax.swing.JButton btnPreviousPlay;
private javax.swing.JButton btnSkipForward;
private javax.swing.JButton btnStopReplay; private javax.swing.JButton btnStopReplay;
private javax.swing.JButton btnStopWatching; private javax.swing.JButton btnStopWatching;
private mage.client.chat.ChatPanel gameChatPanel; private mage.client.chat.ChatPanel gameChatPanel;
@ -1045,3 +1086,37 @@ public class GamePanel extends javax.swing.JPanel {
private JButton prevStep; private JButton prevStep;
private JLabel endButtonTip; private JLabel endButtonTip;
} }
class ReplayTask extends SwingWorker<Void, Collection<MatchView>> {
private Session session;
private UUID gameId;
private final static Logger logger = Logger.getLogger(ReplayTask.class);
ReplayTask(Session session, UUID gameId) {
this.session = session;
this.gameId = gameId;
}
@Override
protected Void doInBackground() throws Exception {
while (!isCancelled()) {
session.nextPlay(gameId);
Thread.sleep(1000);
}
return null;
}
@Override
protected void done() {
try {
get();
} catch (InterruptedException ex) {
logger.fatal("Update Matches Task error", ex);
} catch (ExecutionException ex) {
logger.fatal("Update Matches Task error", ex);
} catch (CancellationException ex) {}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

View file

@ -113,6 +113,7 @@ public interface MageServer {
public void stopReplay(UUID gameId, String sessionId) throws MageException; public void stopReplay(UUID gameId, String sessionId) throws MageException;
public void nextPlay(UUID gameId, String sessionId) throws MageException; public void nextPlay(UUID gameId, String sessionId) throws MageException;
public void previousPlay(UUID gameId, String sessionId) throws MageException; public void previousPlay(UUID gameId, String sessionId) throws MageException;
public void skipForward(UUID gameId, String sessionId, int moves) throws MageException;
//test methods //test methods
public void cheat(UUID gameId, String sessionId, UUID playerId, DeckCardLists deckList) throws MageException; public void cheat(UUID gameId, String sessionId, UUID playerId, DeckCardLists deckList) throws MageException;

View file

@ -843,7 +843,21 @@ public class Session {
return false; return false;
} }
public boolean cheat(UUID gameId, UUID playerId, DeckCardLists deckList) { public boolean skipForward(UUID gameId, int moves) {
try {
if (isConnected()) {
server.skipForward(gameId, sessionId, moves);
return true;
}
} catch (MageException ex) {
handleMageException(ex);
} catch (Throwable t) {
handleThrowable(t);
}
return false;
}
public boolean cheat(UUID gameId, UUID playerId, DeckCardLists deckList) {
try { try {
if (isConnected()) { if (isConnected()) {
server.cheat(gameId, sessionId, playerId, deckList); server.cheat(gameId, sessionId, playerId, deckList);

View file

@ -858,6 +858,26 @@ public class MageServerImpl implements MageServer {
} }
@Override @Override
public void skipForward(final UUID gameId, final String sessionId, final int moves) throws MageException {
if (SessionManager.getInstance().isValidSession(sessionId)) {
try {
callExecutor.execute(
new Runnable() {
@Override
public void run() {
UUID userId = SessionManager.getInstance().getSession(sessionId).getUserId();
ReplayManager.getInstance().skipForward(gameId, userId, moves);
}
}
);
}
catch (Exception ex) {
handleException(ex);
}
}
}
@Override
public ServerState getServerState() throws MageException { public ServerState getServerState() throws MageException {
try { try {
return new ServerState( return new ServerState(

View file

@ -68,5 +68,10 @@ public class ReplayManager {
public void previousPlay(UUID gameId, UUID userId) { public void previousPlay(UUID gameId, UUID userId) {
replaySessions.get(gameId.toString() + userId.toString()).previous(); replaySessions.get(gameId.toString() + userId.toString()).previous();
} }
public void skipForward(UUID gameId, UUID userId, int moves) {
replaySessions.get(gameId.toString() + userId.toString()).next(moves);
}
} }

View file

@ -68,7 +68,14 @@ public class ReplaySession implements GameCallback {
updateGame(replay.next(), replay.getGame()); updateGame(replay.next(), replay.getGame());
} }
public synchronized void previous() { public synchronized void next(int moves) {
for (int i = 0; i < moves; i++) {
replay.next();
}
updateGame(replay.next(), replay.getGame());
}
public synchronized void previous() {
updateGame(replay.previous(), replay.getGame()); updateGame(replay.previous(), replay.getGame());
} }