Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/main/java/com/faforever/client/preferences/VetoKey.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
package com.faforever.client.preferences;

import com.faforever.client.domain.api.MapPoolAssignment;

public record VetoKey(
int matchmakerQueueMapPoolId,
int mapPoolMapVersionId
) {}
) {

public static VetoKey of(MapPoolAssignment assignment) {
return new VetoKey(assignment.mapPool().mapPool().id(), assignment.id());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
import com.faforever.client.domain.api.MapPoolAssignment;
import com.faforever.client.domain.api.MapVersion;
import com.faforever.client.fx.ImageViewHelper;
import com.faforever.client.fx.NodeController;
import com.faforever.client.i18n.I18n;
import com.faforever.client.map.MapService;
import com.faforever.client.fx.NodeController;
import com.faforever.client.map.MapService.PreviewSize;
import com.faforever.client.map.generator.MapGeneratorService;
import com.faforever.client.preferences.MatchmakerPrefs;
Expand All @@ -25,13 +25,14 @@
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.function.Consumer;

/**
Expand Down Expand Up @@ -101,9 +102,10 @@ void setVetoModeEnabled(BooleanProperty vetoModeEnabled) {
public void bindVetoModeDependentProperties() {
vetoesBox.mouseTransparentProperty().bind(vetoModeEnabled.not());
vetoesBox.visibleProperty().bind(vetoModeEnabled.or(tokenCount.greaterThan(0)));
root.cursorProperty().bind(Bindings.when(
Bindings.createBooleanBinding(() -> isGeneratedMap.getValue() || vetoModeEnabled.get(), isGeneratedMap, vetoModeEnabled)
).then(Cursor.DEFAULT).otherwise(Cursor.HAND));
root.cursorProperty()
.bind(Bindings.when(
Bindings.createBooleanBinding(() -> isGeneratedMap.getValue() || vetoModeEnabled.get(), isGeneratedMap,
vetoModeEnabled)).then(Cursor.DEFAULT).otherwise(Cursor.HAND));
}

@Override
Expand All @@ -112,9 +114,9 @@ protected void onInitialize() {
isGeneratedMap = mapObservable.map(map -> mapGeneratorService.isGeneratedMap(map.displayName())).orElse(false);

thumbnailImageView.imageProperty()
.bind(assignment
.map(assignmentBean -> mapService.loadPreview(assignmentBean.mapVersion(), PreviewSize.SMALL))
.flatMap(imageViewHelper::createPlaceholderImageOnErrorObservable));
.bind(assignment.map(
assignmentBean -> mapService.loadPreview(assignmentBean.mapVersion(), PreviewSize.SMALL))
.flatMap(imageViewHelper::createPlaceholderImageOnErrorObservable));

nameLabel.textProperty().bind(mapObservable.map(map -> {
if (isGeneratedMap.getValue()) {
Expand All @@ -123,9 +125,7 @@ protected void onInitialize() {
return map.displayName();
}));

authorBox.visibleProperty()
.bind(mapObservable.map(
map -> (map.author() != null) || isGeneratedMap.getValue()));
authorBox.visibleProperty().bind(mapObservable.map(map -> (map.author() != null) || isGeneratedMap.getValue()));
authorBox.managedProperty().bind(authorBox.visibleProperty());

authorLabel.textProperty().bind(mapObservable.map(map -> {
Expand Down Expand Up @@ -165,27 +165,26 @@ protected void onInitialize() {
});

vetoButton.setOnAction(event -> {
if (assignment.getValue() == null) {
MapPoolAssignment value = assignment.getValue();
if (value == null) {
return;
}
int currentTokenCount = tokenCount.get();
int currentMaxPerMap = maxPerMap.get();
if ((isMaxPerMapDynamic.get() || currentTokenCount < currentMaxPerMap) && currentTokenCount < vetoTokensMax.get() && vetoTokensLeft.getValue() > 0) {
teamMatchmakingService.setTokensForMap(
new VetoKey(assignment.getValue().mapPool().mapPool().id(), assignment.getValue().id()),
currentTokenCount + 1);
teamMatchmakingService.setTokensForMap(VetoKey.of(value), currentTokenCount + 1);
}
event.consume();
});

minusButton.setOnAction(event -> {
if (assignment.getValue() == null) {
MapPoolAssignment value = assignment.getValue();
if (value == null) {
return;
}
int current = tokenCount.get();
if (current > 0) {
teamMatchmakingService.setTokensForMap(
new VetoKey(assignment.getValue().mapPool().mapPool().id(), assignment.getValue().id()), current - 1);
teamMatchmakingService.setTokensForMap(VetoKey.of(value), current - 1);
}
event.consume();
});
Expand Down Expand Up @@ -213,11 +212,12 @@ private void updateBannedState() {
}

private void updateVetoes() {
if (assignment.getValue() == null) {
MapPoolAssignment value = assignment.getValue();
if (value == null) {
tokenCount.set(0);
return;
}
VetoKey key = new VetoKey(assignment.getValue().mapPool().mapPool().id(), assignment.getValue().id());
VetoKey key = VetoKey.of(value);
int usedTokens = matchmakerPrefs.getAppliedVetoes().getOrDefault(key, 0);
tokenCount.set(usedTokens);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
import java.time.Instant;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
Expand Down Expand Up @@ -245,12 +246,6 @@ public void afterPropertiesSet() throws Exception {
}
});

matchmakerPrefs.getAppliedVetoes().subscribe(()->{
if (fafServerAccessor.getConnectionState() == ConnectionState.CONNECTED) {
sendVetoes();
}
});

party.ownerProperty().subscribe((oldValue, newValue) -> {
if (oldValue != null) {
chatService.leaveChannel("#" + oldValue.getUsername() + PARTY_CHANNEL_SUFFIX);
Expand All @@ -274,27 +269,37 @@ private void sendVetoes() {
fafServerAccessor.setPlayerVetoes(getVetoesAsList());
}

public void setTokensForMap(VetoKey vetoKey, Integer vetoTokensApplied) {
matchmakerPrefs.getAppliedVetoes().put(vetoKey, vetoTokensApplied);
public void setTokensForMap(VetoKey key, int vetoTokensApplied) {
Integer previousValue;
if (vetoTokensApplied == 0) {
previousValue = matchmakerPrefs.getAppliedVetoes().remove(key);
} else {
previousValue = matchmakerPrefs.getAppliedVetoes().put(key, vetoTokensApplied);
}

if ((previousValue == null && vetoTokensApplied > 0) || (previousValue != null && previousValue != vetoTokensApplied)) {
sendVetoes();
}
}

public void setAllVetoes(List<VetoData> vetoes) {
public void updateVetoes(List<VetoData> vetoes) {
Map<VetoKey, Integer> vetosMap = vetoes.stream()
.collect(Collectors.toMap(
vetoData -> new VetoKey(vetoData.getMatchmakerQueueMapPoolId(),
vetoData.getMapPoolMapVersionId()),
VetoData::getVetoTokensApplied));
matchmakerPrefs.getAppliedVetoes().clear();
vetoes.forEach(v -> matchmakerPrefs.getAppliedVetoes().put(
new VetoKey(v.getMatchmakerQueueMapPoolId(), v.getMapPoolMapVersionId()),
v.getVetoTokensApplied()
));
matchmakerPrefs.getAppliedVetoes().putAll(vetosMap);
}

private void onVetoesChanged(VetoesChangedInfo vetoesChangedInfo) {
setAllVetoes(vetoesChangedInfo.getVetoes());
updateVetoes(vetoesChangedInfo.getVetoes());

if (vetoesChangedInfo.getForced()) {
notificationService.addNotification(
new ImmediateNotification(i18n.get("teammatchmaking.vetoes.forced.title"),
i18n.get("teammatchmaking.vetoes.forced.message"),
Severity.INFO,
Collections.singletonList(new DismissAction(i18n))));
notificationService.addNotification(new ImmediateNotification(i18n.get("teammatchmaking.vetoes.forced.title"),
i18n.get("teammatchmaking.vetoes.forced.message"),
Severity.INFO, Collections.singletonList(
new DismissAction(i18n))));
}
}

Expand All @@ -303,10 +308,8 @@ private List<VetoData> getVetoesAsList() {
.entrySet()
.stream()
.filter(entry -> entry.getValue() > 0)
.map(entry -> new VetoData(
entry.getKey().mapPoolMapVersionId(),
entry.getValue(),
entry.getKey().matchmakerQueueMapPoolId()))
.map(entry -> new VetoData(entry.getKey().mapPoolMapVersionId(), entry.getValue(),
entry.getKey().matchmakerQueueMapPoolId()))
.collect(Collectors.toList());
}

Expand Down Expand Up @@ -435,8 +438,7 @@ private Mono<MatchmakerQueueInfo> getQueueFromApi(MatchmakerInfo.MatchmakerQueue
.collection()
.setFilter(qBuilder().string("technicalName")
.eq(matchmakerQueue.getName()));
return fafApiAccessor.getMany(navigator)
.next().map(matchmakerMapper::map)
return fafApiAccessor.getMany(navigator).next().map(matchmakerMapper::map)
.map(queue -> matchmakerMapper.update(matchmakerQueue, queue))
.doOnNext(queue -> queue.setSelected(
!matchmakerPrefs.getUnselectedQueueIds().contains(queue.getId())))
Expand Down Expand Up @@ -464,20 +466,21 @@ public CompletableFuture<Boolean> joinQueues() {

return featuredModService.updateFeaturedModToLatest(FAF.getTechnicalName(), false)
.thenCompose(aVoid -> validQueues.stream()
.map(this::joinQueue)
.reduce((future1, future2) -> future1.thenCombine(future2,
(result1, result2) -> result1 || result2))
.orElse(CompletableFuture.completedFuture(false)))
.map(this::joinQueue)
.reduce((future1, future2) -> future1.thenCombine(future2,
(result1, result2) -> result1 || result2))
.orElse(CompletableFuture.completedFuture(false)))
.exceptionally(throwable -> {
throwable = ConcurrentUtil.unwrapIfCompletionException(throwable);
log.error("Unable to join queues", throwable);
if (throwable instanceof NotifiableException notifiableException) {
notificationService.addErrorNotification(notifiableException);
} else {
notificationService.addImmediateErrorNotification(throwable, "teammatchmaking.couldNotStart");
}
return false;
});
throwable = ConcurrentUtil.unwrapIfCompletionException(throwable);
log.error("Unable to join queues", throwable);
if (throwable instanceof NotifiableException notifiableException) {
notificationService.addErrorNotification(notifiableException);
} else {
notificationService.addImmediateErrorNotification(throwable,
"teammatchmaking.couldNotStart");
}
return false;
});
}

public void leaveQueues() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -637,13 +637,14 @@ public void testSendVetoesOnConnection() {
@Test
public void testSendVetoesOnVetoesChange() {
connectionState.set(ConnectionState.CONNECTED);
when(fafServerAccessor.getConnectionState()).thenReturn(ConnectionState.CONNECTED);
// Clear invocations from connection state change
org.mockito.Mockito.clearInvocations(fafServerAccessor);

matchmakerPrefs.getAppliedVetoes().put(new VetoKey(1, 1), 1);
instance.setTokensForMap(new VetoKey(1, 1), 1);

verify(fafServerAccessor, times(1)).setPlayerVetoes(List.of(new VetoData(1, 1, 1)));

instance.setTokensForMap(new VetoKey(1, 1), 1);

verify(fafServerAccessor, times(1)).setPlayerVetoes(anyList());
verify(fafServerAccessor, times(1)).setPlayerVetoes(List.of(new VetoData(1, 1, 1)));
}

@Test
Expand Down