package com.faforever.client.remote;
import com.faforever.client.game.Faction;
import com.faforever.client.game.GameType;
import com.faforever.client.game.NewGameInfo;
import com.faforever.client.i18n.I18n;
import com.faforever.client.net.ConnectionState;
import com.faforever.client.notification.Action;
import com.faforever.client.notification.NotificationService;
import com.faforever.client.notification.PersistentNotification;
import com.faforever.client.notification.Severity;
import com.faforever.client.rankedmatch.MatchmakerMessage;
import com.faforever.client.relay.GpgClientMessage;
import com.faforever.client.remote.domain.Avatar;
import com.faforever.client.remote.domain.GameAccess;
import com.faforever.client.remote.domain.GameInfoMessage;
import com.faforever.client.remote.domain.GameLaunchMessage;
import com.faforever.client.remote.domain.GameState;
import com.faforever.client.remote.domain.GameTypeMessage;
import com.faforever.client.remote.domain.LoginMessage;
import com.faforever.client.remote.domain.Player;
import com.faforever.client.remote.domain.PlayersMessage;
import com.faforever.client.remote.domain.RatingRange;
import com.faforever.client.remote.domain.ServerMessage;
import com.faforever.client.task.CompletableTask;
import com.faforever.client.task.TaskService;
import com.faforever.client.user.UserService;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Resource;
import java.lang.invoke.MethodHandles;
import java.net.InetSocketAddress;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.function.Consumer;
import static com.faforever.client.remote.domain.GameAccess.PASSWORD;
import static com.faforever.client.remote.domain.GameAccess.PUBLIC;
import static com.faforever.client.task.CompletableTask.Priority.HIGH;
import static java.util.Collections.singletonList;
public class MockFafServerAccessor implements FafServerAccessor {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private static final String USER_NAME = "MockUser";
private final Timer timer;
private final HashMap<Class<? extends ServerMessage>, Collection<Consumer<ServerMessage>>> messageListeners;
@Resource
UserService userService;
@Resource
TaskService taskService;
@Resource
NotificationService notificationService;
@Resource
I18n i18n;
private ObjectProperty<ConnectionState> connectionState;
public MockFafServerAccessor() {
timer = new Timer("LobbyServerAccessorTimer", true);
messageListeners = new HashMap<>();
connectionState = new SimpleObjectProperty<>();
}
@Override
@SuppressWarnings("unchecked")
public <T extends ServerMessage> void addOnMessageListener(Class<T> type, Consumer<T> listener) {
if (!messageListeners.containsKey(type)) {
messageListeners.put(type, new LinkedList<>());
}
messageListeners.get(type).add((Consumer<ServerMessage>) listener);
}
@Override
public <T extends ServerMessage> void removeOnMessageListener(Class<T> type, Consumer<T> listener) {
messageListeners.get(type).remove(listener);
}
@Override
public ReadOnlyObjectProperty<ConnectionState> connectionStateProperty() {
return connectionState;
}
@Override
public CompletionStage<LoginMessage> connectAndLogIn(String username, String password) {
return taskService.submitTask(new CompletableTask<LoginMessage>(HIGH) {
@Override
protected LoginMessage call() throws Exception {
updateTitle(i18n.get("login.progress.message"));
GameTypeMessage gameTypeMessage = new GameTypeMessage();
gameTypeMessage.setFullname("Forged Alliance Forever");
gameTypeMessage.setName("faf");
gameTypeMessage.setPublish(true);
gameTypeMessage.setDesc("Description");
messageListeners.getOrDefault(gameTypeMessage.getClass(), Collections.emptyList()).forEach(consumer -> consumer.accept(gameTypeMessage));
Player player = new Player();
player.setLogin(USER_NAME);
player.setClan("ABC");
player.setCountry("A1");
player.setGlobalRating(new float[]{1500, 220});
player.setLadderRating(new float[]{1500, 220});
player.setNumberOfGames(330);
PlayersMessage playersMessage = new PlayersMessage();
playersMessage.setPlayers(singletonList(player));
messageListeners.getOrDefault(playersMessage.getClass(), Collections.emptyList()).forEach(consumer -> consumer.accept(playersMessage));
timer.schedule(new TimerTask() {
@Override
public void run() {
UpdatedAchievementsMessage updatedAchievementsMessage = new UpdatedAchievementsMessage();
UpdatedAchievement updatedAchievement = new UpdatedAchievement();
updatedAchievement.setAchievementId("50260d04-90ff-45c8-816b-4ad8d7b97ecd");
updatedAchievement.setNewlyUnlocked(true);
updatedAchievementsMessage.setUpdatedAchievements(Arrays.asList(updatedAchievement));
messageListeners.getOrDefault(updatedAchievementsMessage.getClass(), Collections.emptyList()).forEach(consumer -> consumer.accept(updatedAchievementsMessage));
}
}, 7000);
timer.schedule(new TimerTask() {
@Override
public void run() {
MatchmakerMessage matchmakerServerMessage = new MatchmakerMessage();
matchmakerServerMessage.setQueues(singletonList(new MatchmakerMessage.MatchmakerQueue("ladder1v1", singletonList(new RatingRange(100, 200)), singletonList(new RatingRange(100, 200)))));
messageListeners.getOrDefault(matchmakerServerMessage.getClass(), Collections.emptyList()).forEach(consumer -> consumer.accept(matchmakerServerMessage));
}
}, 7000);
List<GameInfoMessage> gameInfoMessages = Arrays.asList(
createGameInfo(1, "Mock game 500 - 800", PUBLIC, "faf", "scmp_010", 3, 6, "Mock user"),
createGameInfo(2, "Mock game 500+", PUBLIC, "faf", "scmp_011", 3, 6, "Mock user"),
createGameInfo(3, "Mock game +500", PUBLIC, "faf", "scmp_012", 3, 6, "Mock user"),
createGameInfo(4, "Mock game <1000", PUBLIC, "faf", "scmp_013", 3, 6, "Mock user"),
createGameInfo(5, "Mock game >1000", PUBLIC, "faf", "scmp_014", 3, 6, "Mock user"),
createGameInfo(6, "Mock game ~600", PASSWORD, "faf", "scmp_015", 3, 6, "Mock user"),
createGameInfo(7, "Mock game 7", PASSWORD, "faf", "scmp_016", 3, 6, "Mock user")
);
gameInfoMessages.forEach(gameInfoMessage ->
messageListeners.getOrDefault(gameInfoMessage.getClass(), Collections.emptyList())
.forEach(consumer -> consumer.accept(gameInfoMessage)));
notificationService.addNotification(
new PersistentNotification(
"How about a long-running (7s) mock task?",
Severity.INFO,
Arrays.asList(
new Action("Execute", event ->
taskService.submitTask(new CompletableTask<Void>(HIGH) {
@Override
protected Void call() throws Exception {
updateTitle("Mock task");
Thread.sleep(2000);
for (int i = 0; i < 5; i++) {
updateProgress(i, 5);
Thread.sleep(1000);
}
return null;
}
})),
new Action("Nope")
)
)
);
LoginMessage sessionInfo = new LoginMessage();
sessionInfo.setId(123);
sessionInfo.setLogin(USER_NAME);
return sessionInfo;
}
}).getFuture();
}
@Override
public CompletionStage<GameLaunchMessage> requestHostGame(NewGameInfo newGameInfo, InetSocketAddress relayAddress, int externalPort) {
return taskService.submitTask(new CompletableTask<GameLaunchMessage>(HIGH) {
@Override
protected GameLaunchMessage call() throws Exception {
updateTitle(i18n.get("requestNewGameTask.title"));
GameLaunchMessage gameLaunchMessage = new GameLaunchMessage();
gameLaunchMessage.setArgs(Arrays.asList("/ratingcolor d8d8d8d8", "/numgames 1234"));
gameLaunchMessage.setMod("faf");
gameLaunchMessage.setUid(1234);
return gameLaunchMessage;
}
}).getFuture();
}
@Override
public CompletionStage<GameLaunchMessage> requestJoinGame(int gameId, String password, InetSocketAddress relayAddress, int externalPort) {
return taskService.submitTask(new CompletableTask<GameLaunchMessage>(HIGH) {
@Override
protected GameLaunchMessage call() throws Exception {
updateTitle(i18n.get("requestJoinGameTask.title"));
GameLaunchMessage gameLaunchMessage = new GameLaunchMessage();
gameLaunchMessage.setArgs(Arrays.asList("/ratingcolor d8d8d8d8", "/numgames 1234"));
gameLaunchMessage.setMod("faf");
gameLaunchMessage.setUid(1234);
return gameLaunchMessage;
}
}).getFuture();
}
@Override
public void disconnect() {
}
@Override
public void reconnect() {
}
@Override
public void addFriend(int playerId) {
}
@Override
public void addFoe(int playerId) {
}
@Override
public CompletionStage<GameLaunchMessage> startSearchRanked1v1(Faction faction, int gamePort, InetSocketAddress relayAddress) {
logger.debug("Searching 1v1 match with faction: {}", faction);
GameLaunchMessage gameLaunchMessage = new GameLaunchMessage();
gameLaunchMessage.setUid(123);
gameLaunchMessage.setMod(GameType.DEFAULT.getString());
return CompletableFuture.completedFuture(gameLaunchMessage);
}
@Override
public void stopSearchingRanked() {
logger.debug("Stopping searching 1v1 match");
}
@Override
public Long getSessionId() {
return null;
}
@Override
public void sendGpgMessage(GpgClientMessage message) {
}
@Override
public void initConnectivityTest(int port) {
}
@Override
public void removeFriend(int playerId) {
}
@Override
public void removeFoe(int playerId) {
}
@Override
public void selectAvatar(URL url) {
}
@Override
public List<Avatar> getAvailableAvatars() {
return null;
}
private GameInfoMessage createGameInfo(int uid, String title, GameAccess access, String featuredMod, String mapName, int numPlayers, int maxPlayers, String host) {
GameInfoMessage gameInfoMessage = new GameInfoMessage();
gameInfoMessage.setUid(uid);
gameInfoMessage.setTitle(title);
gameInfoMessage.setFeaturedMod(featuredMod);
gameInfoMessage.setMapname(mapName);
gameInfoMessage.setNumPlayers(numPlayers);
gameInfoMessage.setMaxPlayers(maxPlayers);
gameInfoMessage.setHost(host);
gameInfoMessage.setState(GameState.OPEN);
gameInfoMessage.setSimMods(Collections.emptyMap());
gameInfoMessage.setTeams(Collections.emptyMap());
gameInfoMessage.setFeaturedModVersions(Collections.emptyMap());
gameInfoMessage.setPasswordProtected(access == GameAccess.PASSWORD);
return gameInfoMessage;
}
}