Draft Cubes rework (better cube from deck, dynamic data, better errors processing, actual MTGO Vintage Cube) (#13705)

- GUI, table: added dynamic data support for Cube Types (no more depends on server's config names, part of #12050);
- server: replace multiple MTGO Vintage Cubes by single cube, updated to April 2025 (part of #12050);
- server: fixed table freeze on starting error (related to #11285);
- GUI, table: added better support of Cube From Deck (client/server side errors, additional info about loaded cards, etc);
This commit is contained in:
Oleg Agafonov 2025-05-31 20:15:31 +04:00 committed by GitHub
parent 2034b3fe59
commit 3d45a24959
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 755 additions and 61 deletions

View file

@ -140,6 +140,9 @@
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCube"/>
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
<draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ModernCube2017"/>
<draftCube name="MTGO Vintage Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGOVintageCube"/>
<!-- outdated cubes - will be removed on next releases -->
<!--
<draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2013"/>
<draftCube name="MTGO Vintage Cube 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2014"/>
<draftCube name="MTGO Vintage Cube 2015" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2015"/>
@ -158,6 +161,7 @@
<draftCube name="MTGO Vintage Cube July 2021" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJuly2021"/>
<draftCube name="MTGO Vintage Cube February 2022" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeFebruary2022"/>
<draftCube name="MTGO Vintage Cube October 2023" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeOctober2023"/>
-->
<draftCube name="SCG Con Cube 2018 December" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ScgConCube2018December"/>
<draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/>
<draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGCube"/>

View file

@ -134,6 +134,9 @@
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegendaryCube"/>
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
<draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.ModernCube2017"/>
<draftCube name="MTGO Vintage Cube" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.MTGOVintageCube"/>
<!-- outdated cubes - will be removed on next releases -->
<!--
<draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCube2013"/>
<draftCube name="MTGO Vintage Cube 2014" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCube2014"/>
<draftCube name="MTGO Vintage Cube 2015" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCube2015"/>
@ -152,6 +155,7 @@
<draftCube name="MTGO Vintage Cube July 2021" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeJuly2021"/>
<draftCube name="MTGO Vintage Cube February 2022" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeFebruary2022"/>
<draftCube name="MTGO Vintage Cube October 2023" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.VintageCubeOctober2023"/>
-->
<draftCube name="SCG Con Cube 2018 December" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.ScgConCube2018December"/>
<draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/>
<draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft-${project.version}.jar" className="mage.tournament.cubes.MTGCube"/>

View file

@ -998,7 +998,7 @@ public class MageServerImpl implements MageServer {
public void handleException(Exception ex) throws MageException {
if (ex.getMessage() != null && !ex.getMessage().equals("No message")) {
throw new MageException("Server error: " + ex.getMessage());
throw new MageException(ex.getMessage());
}
if (ex instanceof ConcurrentModificationException) {

View file

@ -1,4 +1,3 @@
package mage.server.draft;
import mage.cards.decks.Deck;
@ -11,8 +10,7 @@ import java.util.Map;
import java.util.Set;
/**
*
* @author LevelX2
* @author LevelX2, JayDi85
*/
public enum CubeFactory {
@ -22,13 +20,12 @@ public enum CubeFactory {
private final Map<String, Class> draftCubes = new LinkedHashMap<>();
public DraftCube createDraftCube(String draftCubeName) {
DraftCube draftCube;
try {
Constructor<?> con = draftCubes.get(draftCubeName).getConstructor();
draftCube = (DraftCube)con.newInstance();
draftCube = (DraftCube) con.newInstance();
} catch (Exception ex) {
logger.fatal("CubeFactory error", ex);
return null;
@ -43,7 +40,7 @@ public enum CubeFactory {
DraftCube draftCube;
try {
Constructor<?> con = draftCubes.get(draftCubeName).getConstructor(Deck.class);
draftCube = (DraftCube)con.newInstance(cubeFromDeck);
draftCube = (DraftCube) con.newInstance(cubeFromDeck);
} catch (Exception ex) {
logger.fatal("CubeFactory error", ex);
return null;
@ -57,10 +54,24 @@ public enum CubeFactory {
return draftCubes.keySet();
}
public void addDraftCube(String name, Class draftCube) {
if (draftCube != null) {
this.draftCubes.put(name, draftCube);
public void addDraftCube(String configName, Class configCubeClass) {
// store cubes by auto-generated names, not from config
if (configCubeClass == null) {
return;
}
}
DraftCube draftCube = null;
try {
Constructor<?> con = configCubeClass.getConstructor();
draftCube = (DraftCube) con.newInstance();
if (this.draftCubes.containsKey(draftCube.getName())) {
throw new IllegalArgumentException("already exists " + draftCube.getName());
}
} catch (Exception e) {
logger.error("Can't create draft cube named by " + configName, e);
return;
}
this.draftCubes.put(draftCube.getName(), configCubeClass);
}
}

View file

@ -1,5 +1,3 @@
package mage.server.tournament;
import mage.cards.Sets;
@ -15,7 +13,6 @@ import java.lang.reflect.Constructor;
import java.util.*;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public enum TournamentFactory {
@ -27,7 +24,6 @@ public enum TournamentFactory {
private final List<TournamentTypeView> tournamentTypeViews = new ArrayList<>();
public Tournament createTournament(String tournamentType, TournamentOptions options) {
Tournament tournament;
@ -37,8 +33,8 @@ public enum TournamentFactory {
// transfer set information, create short info string for included sets
tournament.setTournamentType(tournamentTypes.get(tournamentType));
if (tournament.getTournamentType().isLimited()) {
Map<String,Integer> setInfo = new LinkedHashMap<>();
for (String setCode: options.getLimitedOptions().getSetCodes()) {
Map<String, Integer> setInfo = new LinkedHashMap<>();
for (String setCode : options.getLimitedOptions().getSetCodes()) {
tournament.getSets().add(Sets.findSet(setCode));
int count = setInfo.getOrDefault(setCode, 0);
setInfo.put(setCode, count + 1);
@ -52,25 +48,31 @@ public enum TournamentFactory {
} else {
draftCube = CubeFactory.instance.createDraftCube(tournament.getOptions().getLimitedOptions().getDraftCubeName());
}
tournament.getOptions().getLimitedOptions().setDraftCube(draftCube);
tournament.setBoosterInfo(tournament.getOptions().getLimitedOptions().getDraftCubeName());
String boosterInfo = "";
if (draftCube != null) {
// make sure all loaded (will raise error on empty cards list)
draftCube.validateData();
tournament.getOptions().getLimitedOptions().setDraftCube(draftCube);
boosterInfo = draftCube.getName();
}
tournament.setBoosterInfo(boosterInfo);
} else if (tournament.getTournamentType().isRandom()) {
StringBuilder rv = new StringBuilder( "Chaos Draft using sets: ");
for (Map.Entry<String, Integer> entry: setInfo.entrySet()){
StringBuilder rv = new StringBuilder("Chaos Draft using sets: ");
for (Map.Entry<String, Integer> entry : setInfo.entrySet()) {
rv.append(entry.getKey());
rv.append(';');
}
tournament.setBoosterInfo(rv.toString());
} else if (tournament.getTournamentType().isReshuffled()) {
StringBuilder rv = new StringBuilder( "Chaos Reshuffled Draft using sets: ");
for (Map.Entry<String, Integer> entry: setInfo.entrySet()){
StringBuilder rv = new StringBuilder("Chaos Reshuffled Draft using sets: ");
for (Map.Entry<String, Integer> entry : setInfo.entrySet()) {
rv.append(entry.getKey());
rv.append(';');
}
tournament.setBoosterInfo(rv.toString());
} else {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String,Integer> entry:setInfo.entrySet()) {
for (Map.Entry<String, Integer> entry : setInfo.entrySet()) {
sb.append(entry.getValue().toString()).append('x').append(entry.getKey()).append(' ');
}
tournament.setBoosterInfo(sb.toString());
@ -78,12 +80,9 @@ public enum TournamentFactory {
} else {
tournament.setBoosterInfo("");
}
} catch (Exception ex) {
logger.fatal("TournamentFactory error ", ex);
return null;
} catch (Exception e) {
throw new IllegalStateException("Can't create new tourney: " + e, e);
}
logger.debug("Tournament created: " + tournamentType + ' ' + tournament.getId());
return tournament;
}

View file

@ -105,6 +105,9 @@
<draftCube name="MTGO Legendary Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCube"/>
<draftCube name="MTGO Legendary Cube April 2016" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.LegendaryCubeApril2016"/>
<draftCube name="MTGO Modern Cube 2017" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ModernCube2017"/>
<draftCube name="MTGO Vintage Cube" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGOVintageCube"/>
<!-- outdated cubes - will be removed on next releases -->
<!--
<draftCube name="MTGO Vintage Cube 2013" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2013"/>
<draftCube name="MTGO Vintage Cube 2014" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2014"/>
<draftCube name="MTGO Vintage Cube 2015" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCube2015"/>
@ -119,6 +122,7 @@
<draftCube name="MTGO Vintage Cube December 2019" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeDecember2019"/>
<draftCube name="MTGO Vintage Cube April 2020" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeApril2020"/>
<draftCube name="MTGO Vintage Cube July 2020" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.VintageCubeJuly2020"/>
-->
<draftCube name="SCG Con Cube 2018 December" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.ScgConCube2018December"/>
<draftCube name="The Peasant's Toolbox" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.PeasantsToolboxCube"/>
<draftCube name="www.MTGCube.com" jar="mage-tournament-booster-draft.jar" className="mage.tournament.cubes.MTGCube"/>