mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 03:22:00 -08:00
improved replays - can now skip forward 10 moves or let the client play through the moves
This commit is contained in:
parent
6d4c3aa8d9
commit
f5c3494723
12 changed files with 142 additions and 20 deletions
|
|
@ -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
|
||||||
|
|
@ -932,6 +959,17 @@ public class GamePanel extends javax.swing.JPanel {
|
||||||
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 |
BIN
Mage.Client/src/main/resources/buttons/control_right.png
Normal file
BIN
Mage.Client/src/main/resources/buttons/control_right.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 411 B |
BIN
Mage.Client/src/main/resources/buttons/control_stop.png
Normal file
BIN
Mage.Client/src/main/resources/buttons/control_stop.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 528 B |
BIN
Mage.Client/src/main/resources/buttons/control_stop_left.png
Normal file
BIN
Mage.Client/src/main/resources/buttons/control_stop_left.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 452 B |
BIN
Mage.Client/src/main/resources/buttons/control_stop_right.png
Normal file
BIN
Mage.Client/src/main/resources/buttons/control_stop_right.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 433 B |
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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(
|
||||||
|
|
|
||||||
|
|
@ -69,4 +69,9 @@ public class ReplayManager {
|
||||||
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue