Added - queue configurator now has competitive settings; Modified - spawning of queue goes through hall, so it can be updated immediately; Tournaments can be spectated if there is 'casual' in their names

This commit is contained in:
jakub.salavec
2025-06-13 14:08:58 +02:00
parent 7991dc713e
commit a7057ee042
5 changed files with 65 additions and 18 deletions

View File

@@ -13,6 +13,7 @@ import com.gempukku.lotro.game.LotroCardBlueprintLibrary;
import com.gempukku.lotro.game.Player;
import com.gempukku.lotro.game.SortAndFilterCards;
import com.gempukku.lotro.game.formats.LotroFormatLibrary;
import com.gempukku.lotro.hall.HallServer;
import com.gempukku.lotro.logic.vo.LotroDeck;
import com.gempukku.lotro.packs.ProductLibrary;
import com.gempukku.lotro.tournament.*;
@@ -51,6 +52,8 @@ public class TournamentRequestHandler extends LotroServerRequestHandler implemen
private final TableDraftDefinitions _tableDraftLibrary;
private final ProductLibrary _productLibrary;
private final HallServer _hallServer;
private static final Logger _log = LogManager.getLogger(TournamentRequestHandler.class);
public TournamentRequestHandler(Map<Type, Object> context) {
@@ -66,6 +69,8 @@ public class TournamentRequestHandler extends LotroServerRequestHandler implemen
_productLibrary = extractObject(context, ProductLibrary.class);
_deckRenderer = new DeckRenderer(_library, _formatLibrary, _sortAndFilterCards);
_hallServer = extractObject(context, HallServer.class);
}
@Override
@@ -130,6 +135,10 @@ public class TournamentRequestHandler extends LotroServerRequestHandler implemen
String playoff = getFormParameterSafely(postDecoder, "playoff");
String maxPlayersStr = getFormParameterSafely(postDecoder, "maxPlayers");
String competitiveStr = getFormParameterSafely(postDecoder, "competitive");
boolean competitive = Throw400IfNullOrNonBoolean("competitive", competitiveStr);
String sealedFormatCodeStr = getFormParameterSafely(postDecoder, "sealedFormatCode");
String soloDraftFormatCodeStr = getFormParameterSafely(postDecoder, "soloDraftFormatCode");
@@ -151,7 +160,11 @@ public class TournamentRequestHandler extends LotroServerRequestHandler implemen
var params = new TournamentParams();
String casual = "Casual ";
String casualPrefix = "Casual ";
String competitivePrefix = "Competitive ";
String prefix = competitive ? competitivePrefix : casualPrefix;
//TODO ready check, ready check time, startable early
if(type == Tournament.TournamentType.SEALED) {
var sealedParams = new SealedTournamentParams();
@@ -165,7 +178,7 @@ public class TournamentRequestHandler extends LotroServerRequestHandler implemen
Throw400IfValidationFails("sealedFormatCode", sealedFormatCodeStr,sealedFormat != null);
sealedParams.sealedFormatCode = sealedFormatCodeStr;
sealedParams.format = sealedFormat.GetFormat().getCode();
sealedParams.name = casual + sealedFormat.GetName();
sealedParams.name = prefix + sealedFormat.GetName().substring(3); // Strip the ordering number for sealed formats
params = sealedParams;
}
else if (type == Tournament.TournamentType.SOLODRAFT) {
@@ -181,10 +194,10 @@ public class TournamentRequestHandler extends LotroServerRequestHandler implemen
soloDraftParams.soloDraftFormatCode = soloDraftFormatCodeStr;
soloDraftParams.format = soloDraftFormat.getFormat();
switch (soloDraftFormatCodeStr) {
case "fotr_draft" -> soloDraftParams.name = casual + "FotR Solo Draft";
case "ttt_draft" -> soloDraftParams.name = casual + "TTT Solo Draft";
case "hobbit_random_draft" -> soloDraftParams.name = casual + "Hobbit Solo Draft";
default -> soloDraftParams.name = casual + soloDraftFormatCodeStr;
case "fotr_draft" -> soloDraftParams.name = prefix + "FotR Solo Draft";
case "ttt_draft" -> soloDraftParams.name = prefix + "TTT Solo Draft";
case "hobbit_random_draft" -> soloDraftParams.name = prefix + "Hobbit Solo Draft";
default -> soloDraftParams.name = prefix + soloDraftFormatCodeStr;
}
params = soloDraftParams;
}
@@ -200,7 +213,7 @@ public class TournamentRequestHandler extends LotroServerRequestHandler implemen
Throw400IfValidationFails("soloTableDraftFormatCode", soloTableDraftFormatCodeStr,tableDraftDefinition != null);
soloTableDraftParams.soloTableDraftFormatCode = soloTableDraftFormatCodeStr;
soloTableDraftParams.format = tableDraftDefinition.getFormat();
soloTableDraftParams.name = casual + tableDraftDefinition.getName();
soloTableDraftParams.name = prefix + tableDraftDefinition.getName();
params = soloTableDraftParams;
}
else if (type == Tournament.TournamentType.TABLE_DRAFT) {
@@ -216,7 +229,7 @@ public class TournamentRequestHandler extends LotroServerRequestHandler implemen
tableDraftParams.tableDraftFormatCode = tableDraftFormatCodeStr;
tableDraftParams.format = tableDraftDefinition.getFormat();
tableDraftParams.draftTimerType = DraftTimer.getTypeFromString(tableDraftTimer);
tableDraftParams.name = casual + tableDraftDefinition.getName();
tableDraftParams.name = prefix + tableDraftDefinition.getName();
params = tableDraftParams;
}
else {
@@ -251,7 +264,7 @@ public class TournamentRequestHandler extends LotroServerRequestHandler implemen
return;
}
if (_tournamentService.addPlayerMadeLimitedQueue(info, resourceOwner, false, -1)) {
if (_hallServer.addPlayerMadeLimitedQueue(info, resourceOwner, false, -1)) {
responseWriter.sendJsonOK();
} else {
Throw400IfValidationFails("Error", "Error", false, "Error while creating queue or joining");

View File

@@ -1445,7 +1445,7 @@ var GempLotrCommunication = Class.extend({
});
},
createTournament:function (type, maxPlayers, sealedFormatCode, soloDraftFormatCode, tableDraftFormatCode, tableDraftTimer,
playoff, deckbuildingDuration, callback, errorMap) {
playoff, deckbuildingDuration, competitive, callback, errorMap) {
$.ajax({
type:"POST",
url:this.url + "/tournament/create",
@@ -1459,6 +1459,7 @@ var GempLotrCommunication = Class.extend({
tableDraftTimer:tableDraftTimer,
playoff:playoff,
deckbuildingDuration:deckbuildingDuration,
competitive:competitive,
participantId:getUrlParam("participantId")
},
success:this.deliveryCheck(callback),

View File

@@ -209,6 +209,10 @@ var GempLotrHallUI = Class.extend({
$toggleAdvanced.off("click").on("click", function () {
advancedVisible = !advancedVisible;
$advanced.toggle(advancedVisible);
if (advancedVisible) {
// Scroll to bottom so that the new field can be seen
$("#limitedGameForm").get(0).scrollIntoView({ behavior: "smooth", block: "end" });
}
$(this).text(advancedVisible ? "Hide advanced settings" : "Show advanced settings");
});
@@ -255,6 +259,13 @@ var GempLotrHallUI = Class.extend({
.append($("<option>").val("SWISS").text("Swiss"))
.append($("<option>").val("SINGLE_ELIMINATION").text("Single elimination"));
// Competitive
const $competitiveLabel = $("<label>").attr("for", "competitiveSelect").text("Competitive:");
const $competitiveSelect = $("<select>")
.attr({ id: "competitiveSelect", name: "competitive" })
.append($("<option>").val("false").text("Games can be spectated"))
.append($("<option>").val("true").text("No spectate; hidden names in queue"));
// Deck-building duration
const $durationLabel = $("<label>").attr("for", "deckDuration").text("Deck-building duration (minutes, minimum 5):");
const $durationInput = $("<input>")
@@ -292,7 +303,9 @@ var GempLotrHallUI = Class.extend({
$("<div>").append($pairingLabel),
$("<div>").append($pairingSelect),
$("<div>").append($durationLabel),
$("<div>").append($durationInput)
$("<div>").append($durationInput),
$("<div>").append($competitiveLabel),
$("<div>").append($competitiveSelect)
);
// Add validating listeners
@@ -340,6 +353,9 @@ var GempLotrHallUI = Class.extend({
// Pairing
const playoff = $("#pairingType").val();
const competitive = $("#competitiveSelect").val();
// Deck building duration (number input)
const deckbuildingDuration = parseInt($("#deckDuration").val(), 10) || 15;
const maxPlayers = parseInt($("#numPlayers").val(), 10) || 4;
@@ -354,6 +370,7 @@ var GempLotrHallUI = Class.extend({
tableDraftTimer,
playoff,
deckbuildingDuration,
competitive,
function(json) {
// Success callback — handle your response here
console.log("Tournament created successfully:", json);

View File

@@ -21,10 +21,7 @@ import com.gempukku.lotro.logic.GameUtils;
import com.gempukku.lotro.logic.timing.GameResultListener;
import com.gempukku.lotro.logic.vo.LotroDeck;
import com.gempukku.lotro.service.AdminService;
import com.gempukku.lotro.tournament.Tournament;
import com.gempukku.lotro.tournament.TournamentCallback;
import com.gempukku.lotro.tournament.TournamentQueue;
import com.gempukku.lotro.tournament.TournamentService;
import com.gempukku.lotro.tournament.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -476,6 +473,21 @@ public class HallServer extends AbstractServer {
}
}
public boolean addPlayerMadeLimitedQueue(TournamentInfo info, Player player, boolean startableEarly, int readyCheckTimeSecs) throws SQLException, IOException {
_hallDataAccessLock.writeLock().lock();
try {
boolean success = _tournamentService.addPlayerMadeLimitedQueue(info, player, startableEarly, readyCheckTimeSecs);
if (success) {
hallChanged();
}
return success;
} finally {
_hallDataAccessLock.writeLock().unlock();
}
}
public void leaveQueue(String queueId, Player player) throws SQLException, IOException {
_hallDataAccessLock.writeLock().lock();
try {
@@ -916,9 +928,9 @@ public class HallServer extends AbstractServer {
private HallTournamentCallback(Tournament tournament) {
tournamentId = tournament.getTournamentId();
tournamentName = tournament.getTournamentName();
// Tournaments with no prizes and no entry are not competitive
// Tournaments with no prizes or with 'casual' in their names are not competitive
boolean casual = tournament.getInfo().Parameters().prizes == Tournament.PrizeType.NONE
&& tournament.getInfo().Parameters().cost == 0;
|| tournamentName.toLowerCase().contains("casual");
if (tournament.isWC()) {
gameSettings = new GameSettings(null, _formatLibrary.getFormat(tournament.getFormatCode()),

View File

@@ -283,7 +283,11 @@ public abstract class AbstractTournamentQueue implements TournamentQueue {
@Override
public String getPlayerList() {
return _playerList;
if (_tournamentQueueName.toLowerCase().contains("competitive")) {
return "Competitive, player count: " + _players.size();
} else {
return _playerList;
}
}
@Override