Skip to content

Commit

Permalink
auto-join rehosted games
Browse files Browse the repository at this point in the history
  • Loading branch information
Axle1975 committed Apr 12, 2021
1 parent 277e646 commit 22ee4ab
Show file tree
Hide file tree
Showing 21 changed files with 141 additions and 18 deletions.
3 changes: 3 additions & 0 deletions src/main/java/com/faforever/client/chat/ChatService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.collections.MapChangeListener;

import java.util.Set;
import java.util.concurrent.CompletableFuture;

public interface ChatService {
Expand All @@ -23,6 +24,8 @@ public interface ChatService {

ChatChannelUser getOrCreateChatUser(String username, String channel, boolean isModerator);

Set<String> getUserChannels(String username);

void addUsersListener(String channelName, MapChangeListener<String, ChatChannelUser> listener);

void addChatUsersByNameListener(MapChangeListener<String, ChatChannelUser> listener);
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/com/faforever/client/chat/MockChatService.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CompletableFuture;
Expand Down Expand Up @@ -106,6 +108,11 @@ public Channel getOrCreateChannel(String channelName) {
return channelUserListListeners.get(channelName);
}

@Override
public Set<String> getUserChannels(String username) {
return new HashSet<>();
}

@Override
public ChatChannelUser getOrCreateChatUser(String username, String channel, boolean isModerator) {
return null;
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/faforever/client/chat/PircBotXChatService.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
Expand Down Expand Up @@ -229,6 +231,16 @@ private ChatChannelUser getOrCreateChatUser(User user, String channelName) {
return getOrCreateChatUser(username, channelName, isModerator);
}

public Set<String> getUserChannels(String username) {
Set<String> channelNames = new HashSet<String>();
channels.forEach((channelName, channel) -> {
if (channel.getUser(username) != null) {
channelNames.add(channelName);
}
});
return channelNames;
}

private void onMotd(MotdEvent event) {
sendIdentify(event.getBot().getConfiguration());
}
Expand Down
55 changes: 51 additions & 4 deletions src/main/java/com/faforever/client/game/GameService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.faforever.client.game;

import com.faforever.client.chat.ChatService;
import com.faforever.client.config.ClientProperties;
import com.faforever.client.discord.DiscordRichPresenceService;
import com.faforever.client.fa.CloseGameEvent;
Expand All @@ -25,6 +26,7 @@
import com.faforever.client.patch.GameUpdater;
import com.faforever.client.player.Player;
import com.faforever.client.player.PlayerService;
import com.faforever.client.player.SocialStatus;
import com.faforever.client.preferences.NotificationsPrefs;
import com.faforever.client.preferences.PreferencesService;
import com.faforever.client.rankedmatch.MatchmakerInfoMessage;
Expand Down Expand Up @@ -146,6 +148,7 @@ public class GameService implements InitializingBean {
private final DiscordRichPresenceService discordRichPresenceService;
private final ReplayServer replayServer;
private final ReconnectTimerService reconnectTimerService;
private final ChatService chatService;

@VisibleForTesting
RatingMode ratingMode;
Expand Down Expand Up @@ -179,7 +182,9 @@ public GameService(ClientProperties clientProperties,
PlatformService platformService,
DiscordRichPresenceService discordRichPresenceService,
ReplayServer replayServer,
ReconnectTimerService reconnectTimerService) {
ReconnectTimerService reconnectTimerService,
ChatService chatService) {

this.fafService = fafService;
this.totalAnnihilationService = totalAnnihilationService;
this.mapService = mapService;
Expand All @@ -197,6 +202,7 @@ public GameService(ClientProperties clientProperties,
this.discordRichPresenceService = discordRichPresenceService;
this.replayServer = replayServer;
this.reconnectTimerService = reconnectTimerService;
this.chatService = chatService;

ircHostAndPort = String.format("%s:%d", clientProperties.getIrc().getHost(), 6667);//clientProperties.getIrc().getPort());
faWindowTitle = clientProperties.getForgedAlliance().getWindowTitle();
Expand Down Expand Up @@ -795,9 +801,11 @@ private void onGameInfo(GameInfoMessage gameInfoMessage) {
Optional<Player> currentPlayerOptional = playerService.getCurrentPlayer();

Game game = createOrUpdateGame(gameInfoMessage);
final boolean isGameCurrentGame = Objects.equals(currentGame.get(), game); // some control paths null out currentGame but we still need to remember this

if (GameStatus.ENDED == game.getStatus()) {
removeGame(gameInfoMessage);
if (!currentPlayerOptional.isPresent() || !Objects.equals(currentGame.get(), game)) {
if (!currentPlayerOptional.isPresent() || !isGameCurrentGame) {
return;
}
synchronized (currentGame) {
Expand All @@ -819,7 +827,7 @@ private void onGameInfo(GameInfoMessage gameInfoMessage) {
log.info("[onGameInfo] currentGame(game) because currentPlayerInGame && game.isOpen()");
currentGame.set(game);
}
} else if (Objects.equals(currentGame.get(), game) && !currentPlayerInGame) {
} else if (isGameCurrentGame && !currentPlayerInGame) {
synchronized (currentGame) {
log.info("[onGameInfo] currentGame(null) because !currentPlayerInGame");
currentGame.set(null);
Expand All @@ -835,6 +843,46 @@ private void onGameInfo(GameInfoMessage gameInfoMessage) {
platformService.focusWindow(faWindowTitle);
}
});

if (currentPlayerOptional.isPresent()) {
Player currentPlayer = currentPlayerOptional.get();
Player hostPlayer = playerService.getPlayerForUsername(game.getHost()).get();
Set<String> playerChannels = chatService.getUserChannels(hostPlayer.getUsername());
Set<String> currentPlayerChannels = chatService.getUserChannels(currentPlayer.getUsername());

if (
// auto-join if enabled in preferences
preferencesService.getPreferences().getAutoJoinEnabled() &&

// don't try to join own games ... and don't join a foe's game as a way to prevent griefing
hostPlayer.getSocialStatus() != SocialStatus.SELF && hostPlayer.getSocialStatus() != SocialStatus.FOE &&

// game is ripe for joining
(hostPlayer.getStatus() == PlayerStatus.HOSTING || hostPlayer.getStatus() == PlayerStatus.HOSTED) &&
(game.getStatus() == GameStatus.STAGING || game.getStatus() == GameStatus.BATTLEROOM) &&

// we don't want to auto-join if we're joined another game already
currentPlayer.getStatus() == PlayerStatus.IDLE &&
getCurrentGame() == null &&

// we don't want to rejoin the game we just left (NB getCurrentGame is nulled out on leaving a game. But isGameCurrentGame is initialised before that)
!isGameCurrentGame &&

// can't join until this information is available
game.getMapArchiveName() != null &&
game.getMapCrc() != null &&

// host can prevent auto joins by setting a password
!game.isPasswordProtected() &&

// only auto-join if host shares a common chat channel with us
chatService.getUserChannels(currentPlayer.getUsername()).stream().anyMatch(channel ->
channel.startsWith("#") && !chatService.isDefaultChannel(channel) && playerChannels.contains(channel))) {

log.info("auto-joining game: {}", game);
this.joinGame(game, null);
}
}
}

private Game createOrUpdateGame(GameInfoMessage gameInfoMessage) {
Expand Down Expand Up @@ -892,7 +940,6 @@ private double calcAverageRating(GameInfoMessage gameInfoMessage) {
}

private void updateFromGameInfo(GameInfoMessage gameInfoMessage, Game game) {

game.setId(gameInfoMessage.getUid());
game.setHost(gameInfoMessage.getHost());
game.setTitle(StringEscapeUtils.unescapeHtml4(gameInfoMessage.getTitle()));
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/faforever/client/map/MapService.java
Original file line number Diff line number Diff line change
Expand Up @@ -436,8 +436,9 @@ public boolean isOfficialMap(String mapName) {
return officialMaps.stream().anyMatch(name -> name.equalsIgnoreCase(mapName));
}

public boolean isOfficialArchive(Path archiveName) {
return officialMapArchives.stream().anyMatch(name -> name.equalsIgnoreCase(archiveName.toString()));
public boolean isOfficialArchive(Path archivePath) {
String archvieFileName = archivePath.getFileName().toString();
return officialMapArchives.stream().anyMatch(name -> name.equalsIgnoreCase(archvieFileName));
}

/**
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/faforever/client/preferences/Preferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class Preferences {
private final BooleanProperty proactiveResendEnabled;
private final BooleanProperty ircIntegrationEnabled;
private final BooleanProperty autoLaunchEnabled;
private final BooleanProperty autoJoinEnabled;
private final BooleanProperty requireUacEnabled;
// end TA options
private final ListProperty<String> ignoredNotifications;
Expand Down Expand Up @@ -89,6 +90,7 @@ public Preferences() {
proactiveResendEnabled = new SimpleBooleanProperty(false);
ircIntegrationEnabled = new SimpleBooleanProperty(false);
autoLaunchEnabled = new SimpleBooleanProperty(false);
autoJoinEnabled = new SimpleBooleanProperty(false);
requireUacEnabled = new SimpleBooleanProperty(false);
disallowJoinsViaDiscord = new SimpleBooleanProperty();
showGameDetailsSidePane = new SimpleBooleanProperty(false);
Expand Down Expand Up @@ -156,6 +158,10 @@ public BooleanProperty getAutoLaunchEnabledProperty() {
return autoLaunchEnabled;
}

public BooleanProperty getAutoJoinEnabledProperty() {
return autoJoinEnabled;
}

public BooleanProperty getRequireUacEnabledProperty() {
return requireUacEnabled;
}
Expand All @@ -176,6 +182,10 @@ public boolean getAutoLaunchEnabled() {
return autoLaunchEnabled.get();
}

public boolean getAutoJoinEnabled() {
return autoJoinEnabled.get();
}

public boolean getRequireUacEnabled() {
return requireUacEnabled.get();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public class SettingsController implements Controller<Node> {
public CheckBox proactiveResendToggle;
public CheckBox enableIrcIntegrationToggle;
public CheckBox enableAutoLaunchToggle;
public CheckBox enableAutoJoinToggle;
public CheckBox requireUacToggle;
public TableView<TotalAnnihilationPrefs> gameLocationTableView;
public TableColumn<TotalAnnihilationPrefs, String> gameLocationModTableColumn;
Expand Down Expand Up @@ -339,6 +340,7 @@ public void initialize() {
proactiveResendToggle.selectedProperty().bindBidirectional(preferences.getProactiveResendEnabledProperty());
enableIrcIntegrationToggle.selectedProperty().bindBidirectional(preferences.getIrcIntegrationEnabledProperty());
enableAutoLaunchToggle.selectedProperty().bindBidirectional(preferences.getAutoLaunchEnabledProperty());
enableAutoJoinToggle.selectedProperty().bindBidirectional(preferences.getAutoJoinEnabledProperty());
requireUacToggle.selectedProperty().bindBidirectional(preferences.getRequireUacEnabledProperty());
updateGameLocationTable();

Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -820,3 +820,5 @@ game.leave=Leave
game.start=Start
chat.currentGame=Your Hosted/Joined Game
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_cs.properties
Original file line number Diff line number Diff line change
Expand Up @@ -738,4 +738,6 @@ game.start.tooltip=Your friends want to play!\nClick to start TA
game.leave=Leave
game.start=Start
chat.currentGame=Your Hosted/Joined Game
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_de.properties
Original file line number Diff line number Diff line change
Expand Up @@ -815,4 +815,6 @@ game.start.tooltip = Ihre Freunde wollen spielen! Klicken Sie hier um TA zu star
game.leave = Verlassen
game.start = Starten
chat.currentGame = Ihr beigetretenes/gehostetes Spiel
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_es.properties
Original file line number Diff line number Diff line change
Expand Up @@ -690,4 +690,6 @@ game.start.tooltip=Tus amigos quieren jugar!\nHaga clic para empezar TA.
game.leave=Dejar
game.start=Lanzar
chat.currentGame=Crear/Conectar a una partida
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_fr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -814,4 +814,6 @@ game.start.tooltip=Your friends want to play!\nClick to start TA
game.leave=Leave
game.start=Start
chat.currentGame=Your Hosted/Joined Game
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_it.properties
Original file line number Diff line number Diff line change
Expand Up @@ -884,4 +884,6 @@ game.start.tooltip=I tuoi amici vogliono giocare!\nClicca per lanciare TA
game.leave=Abbandona
game.start=Inizia
chat.currentGame=La tua partita
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_iw.properties
Original file line number Diff line number Diff line change
Expand Up @@ -714,4 +714,6 @@ game.start.tooltip=Your friends want to play!\nClick to start TA
game.leave=Leave
game.start=Start
chat.currentGame=Your Hosted/Joined Game
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_nl.properties
Original file line number Diff line number Diff line change
Expand Up @@ -788,4 +788,6 @@ game.start.tooltip=Your friends want to play!\nClick to start TA
game.leave=Leave
game.start=Start
chat.currentGame=Your Hosted/Joined Game
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_pl.properties
Original file line number Diff line number Diff line change
Expand Up @@ -685,4 +685,6 @@ game.start.tooltip=Your friends want to play!\nClick to start TA
game.leave=Leave
game.start=Start
chat.currentGame=Your Hosted/Joined Game
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_ru.properties
Original file line number Diff line number Diff line change
Expand Up @@ -809,4 +809,6 @@ game.start.tooltip=Your friends want to play!\nClick to start TA
game.leave=Leave
game.start=Start
chat.currentGame=Your Hosted/Joined Game
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_tr.properties
Original file line number Diff line number Diff line change
Expand Up @@ -781,4 +781,6 @@ game.start.tooltip=Your friends want to play!\nClick to start TA
game.leave=Leave
game.start=Start
chat.currentGame=Your Hosted/Joined Game
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_uk.properties
Original file line number Diff line number Diff line change
Expand Up @@ -678,4 +678,6 @@ game.start.tooltip=Your friends want to play!\nClick to start TA
game.leave=Leave
game.start=Start
chat.currentGame=Your Hosted/Joined Game
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
4 changes: 3 additions & 1 deletion src/main/resources/i18n/messages_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -680,4 +680,6 @@ game.start.tooltip=Your friends want to play!\nClick to start TA
game.leave=Leave
game.start=Start
chat.currentGame=Your Hosted/Joined Game
game.create.install=Set Game Location
game.create.install=Set Game Location
settings.fa.enableAutoJoin=Auto-Join Rehosted Games
settings.fa.enableAutoJoin.description=Auto-join any game created by someone in the same chat channel as yourself. Of course this does not apply to the default chat channel #coreprime
Loading

0 comments on commit 22ee4ab

Please sign in to comment.