Record game histories. Compute user stats and show them in the user panel.

This commit is contained in:
Me Car 2016-01-20 12:47:58 +09:00
parent 9f3e2aa4c4
commit 550648ccbe
22 changed files with 866 additions and 60 deletions

View file

@ -38,6 +38,7 @@ import mage.game.events.Listener;
import mage.game.events.TableEvent;
import mage.game.events.TableEventSource;
import mage.game.match.Match;
import mage.game.result.ResultProtos.TableProto;
import mage.game.tournament.Tournament;
import mage.players.Player;
@ -61,24 +62,29 @@ public class Table implements Serializable {
private TableState state;
private Match match;
private Tournament tournament;
private TableRecorder recorder;
public interface TableRecorder {
void record(Table table);
};
protected TableEventSource tableEventSource = new TableEventSource();
public Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List<String> playerTypes, Tournament tournament) {
this(roomId, gameType, name, controllerName, validator, playerTypes);
public Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List<String> playerTypes, TableRecorder recorder, Tournament tournament) {
this(roomId, gameType, name, controllerName, validator, playerTypes, recorder);
this.tournament = tournament;
this.isTournament = true;
setState(TableState.WAITING);
}
public Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List<String> playerTypes, Match match) {
this(roomId, gameType, name, controllerName, validator, playerTypes);
public Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List<String> playerTypes, TableRecorder recorder, Match match) {
this(roomId, gameType, name, controllerName, validator, playerTypes, recorder);
this.match = match;
this.isTournament = false;
setState(TableState.WAITING);
}
protected Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List<String> playerTypes) {
protected Table(UUID roomId, String gameType, String name, String controllerName, DeckValidator validator, List<String> playerTypes, TableRecorder recorder) {
tableId = UUID.randomUUID();
this.roomId = roomId;
this.numSeats = playerTypes.size();
@ -88,6 +94,7 @@ public class Table implements Serializable {
this.createTime = new Date();
createSeats(playerTypes);
this.validator = validator;
this.recorder = recorder;
}
private void createSeats(List<String> playerTypes) {
@ -235,6 +242,9 @@ public class Table implements Serializable {
if (isTournament()) {
getTournament().setTournamentState(state.toString());
}
if (state == TableState.FINISHED) {
this.recorder.record(this);
}
}
public TableState getState() {
@ -296,5 +306,21 @@ public class Table implements Serializable {
return match.getEndTime();
}
}
public TableProto toProto() {
TableProto.Builder builder = TableProto.newBuilder();
if (this.isTournament()) {
builder.getTourneyBuilder().mergeFrom(this.getTournament().toProto());
} else {
builder.getMatchBuilder().mergeFrom(this.getMatch().toProto());
}
return builder.setGameType(this.getGameType())
.setName(this.getName())
.setGameType(this.getGameType())
.setDeckType(this.getDeckType())
.setControllerName(this.getControllerName())
.setStartTimeMs(this.getStartTime().getTime())
.setEndTimeMs(this.getEndTime().getTime())
.build();
}
}

View file

@ -39,6 +39,7 @@ import java.util.Date;
import java.util.List;
import java.util.UUID;
import mage.game.GameInfo;
import mage.game.result.ResultProtos.MatchProto;
/**
*
@ -111,4 +112,6 @@ public interface Match {
void setTableId(UUID tableId);
void setTournamentRound(int round);
MatchProto toProto();
}

View file

@ -41,6 +41,8 @@ import mage.game.events.Listener;
import mage.game.events.TableEvent;
import mage.game.events.TableEvent.EventType;
import mage.game.events.TableEventSource;
import mage.game.result.ResultProtos.MatchProto;
import mage.game.result.ResultProtos.MatchQuitStatus;
import mage.players.Player;
import mage.util.DateFormat;
import org.apache.log4j.Logger;
@ -488,4 +490,25 @@ public abstract class MatchImpl implements Match {
this.getGames().clear();
}
@Override
public MatchProto toProto() {
MatchProto.Builder builder = MatchProto.newBuilder()
.setName(this.getName())
.setGameType(this.getOptions().getGameType())
.setDeckType(this.getOptions().getDeckType())
.setGames(this.getNumGames())
.setDraws(this.getDraws());
for (MatchPlayer matchPlayer : this.getPlayers()) {
MatchQuitStatus status = !matchPlayer.hasQuit() ? MatchQuitStatus.NO_MATCH_QUIT :
matchPlayer.getPlayer().hasTimerTimeout() ? MatchQuitStatus.TIMER_TIMEOUT :
matchPlayer.getPlayer().hasIdleTimeout() ? MatchQuitStatus.IDLE_TIMEOUT :
MatchQuitStatus.QUIT;
builder.addPlayersBuilder()
.setName(matchPlayer.getName())
.setQuit(status)
.setWins(matchPlayer.getWins());
}
return builder.build();
}
}

View file

@ -38,6 +38,7 @@ import mage.game.draft.Draft;
import mage.game.events.Listener;
import mage.game.events.PlayerQueryEvent;
import mage.game.events.TableEvent;
import mage.game.result.ResultProtos.TourneyProto;
import mage.players.Player;
/**
@ -98,4 +99,6 @@ public interface Tournament {
void clearDraft();
Draft getDraft();
TourneyProto toProto();
}

View file

@ -51,6 +51,11 @@ import mage.game.events.TableEvent.EventType;
import mage.game.events.TableEventSource;
import mage.game.match.Match;
import mage.game.match.MatchPlayer;
import mage.game.result.ResultProtos.MatchPlayerProto;
import mage.game.result.ResultProtos.MatchProto;
import mage.game.result.ResultProtos.MatchQuitStatus;
import mage.game.result.ResultProtos.TourneyProto;
import mage.game.result.ResultProtos.TourneyRoundProto;
import mage.players.Player;
import org.apache.log4j.Logger;
@ -555,4 +560,51 @@ public abstract class TournamentImpl implements Tournament {
return draft;
}
@Override
public TourneyProto toProto() {
TourneyProto.Builder tourneyBuilder = TourneyProto.newBuilder()
.setBoosterInfo(this.getBoosterInfo());
for (TournamentPlayer player : players.values()) {
TournamentPlayer replacedPlayer = player.getReplacedTournamentPlayer();
if (replacedPlayer != null) {
player = replacedPlayer;
}
tourneyBuilder.addPlayersBuilder().mergeFrom(player.toProto());
}
for (Round round : rounds) {
TourneyRoundProto.Builder roundBuilder = tourneyBuilder.addRoundsBuilder()
.setRound(round.getRoundNumber());
for (TournamentPairing pair : round.getPairs()) {
Match match = pair.getMatch();
if (match != null && match.hasEnded()) {
MatchProto.Builder matchBuilder = roundBuilder.addMatchesBuilder()
.setName(match.getName())
.setGameType(match.getOptions().getGameType())
.setDeckType(match.getOptions().getDeckType())
.setGames(match.getNumGames())
.setDraws(match.getDraws())
.addPlayers(matchToProto(match, pair.getPlayer1()))
.addPlayers(matchToProto(match, pair.getPlayer2()));
}
}
for (TournamentPlayer tp : round.getPlayerByes()) {
roundBuilder.addByes(tp.getPlayer().getName());
}
}
return tourneyBuilder.build();
}
private MatchPlayerProto matchToProto(Match match, TournamentPlayer player) {
MatchPlayer matchPlayer = match.getPlayer(player.getPlayer().getId());
MatchQuitStatus quit = !matchPlayer.hasQuit() ? MatchQuitStatus.NO_MATCH_QUIT :
matchPlayer.getPlayer().hasIdleTimeout() ? MatchQuitStatus.IDLE_TIMEOUT :
matchPlayer.getPlayer().hasTimerTimeout() ? MatchQuitStatus.TIMER_TIMEOUT :
MatchQuitStatus.QUIT;
return MatchPlayerProto.newBuilder()
.setName(player.getPlayer().getName())
.setWins(matchPlayer.getWins())
.setQuit(quit)
.build();
}
}

View file

@ -31,6 +31,8 @@ package mage.game.tournament;
import java.util.Set;
import mage.cards.decks.Deck;
import mage.constants.TournamentPlayerState;
import mage.game.result.ResultProtos.TourneyPlayerProto;
import mage.game.result.ResultProtos.TourneyQuitStatus;
import mage.players.Player;
import mage.util.TournamentUtil;
@ -52,6 +54,8 @@ public class TournamentPlayer {
protected boolean quit = false;
protected boolean doneConstructing;
protected boolean joined = false;
protected TourneyQuitStatus quitStatus = TourneyQuitStatus.NO_TOURNEY_QUIT;
protected TournamentPlayer replacedTournamentPlayer;
public TournamentPlayer(Player player, String playerType) {
this.player = player;
@ -60,7 +64,6 @@ public class TournamentPlayer {
this.stateInfo = "";
this.disconnectInfo = "";
this.results = "";
}
public Player getPlayer() {
@ -185,12 +188,13 @@ public class TournamentPlayer {
return quit;
}
public void setQuit(String info) {
public void setQuit(String info, TourneyQuitStatus status) {
setEliminated();
this.setState(TournamentPlayerState.CANCELED);
this.setStateInfo(info);
this.quit = true;
this.doneConstructing = true;
this.quitStatus = status;
}
/**
@ -216,5 +220,23 @@ public class TournamentPlayer {
&& !this.getState().equals(TournamentPlayerState.ELIMINATED)
&& !this.getState().equals(TournamentPlayerState.FINISHED);
}
public TournamentPlayer getReplacedTournamentPlayer() {
return this.replacedTournamentPlayer;
}
public void setReplacedTournamentPlayer(TournamentPlayer player) {
this.replacedTournamentPlayer = player;
}
public TourneyPlayerProto toProto() {
return TourneyPlayerProto.newBuilder()
.setName(this.player.getName())
.setPlayerType(this.playerType)
.setStateInfo(this.stateInfo)
.setDisconnectInfo(this.disconnectInfo)
.setQuit(this.quitStatus)
.build();
}
}