package envoy.client.ui; import java.io.*; import java.time.Instant; import java.util.concurrent.TimeoutException; import java.util.logging.*; import javafx.application.Application; import javafx.scene.control.Alert; import javafx.scene.control.Alert.AlertType; import javafx.stage.Stage; import envoy.client.data.*; import envoy.client.event.EnvoyCloseEvent; import envoy.client.net.Client; import envoy.client.ui.SceneContext.SceneInfo; import envoy.client.ui.controller.LoginScene; import envoy.data.*; import envoy.data.User.UserStatus; import envoy.event.*; import envoy.exception.EnvoyException; import envoy.util.EnvoyLog; import dev.kske.eventbus.EventBus; /** * Handles application startup and shutdown. *
* Project: envoy-client
* File: Startup.java
* Created: 26.03.2020
*
* @author Kai S. K. Engelbart
* @author Maximilian Käfer
* @since Envoy Client v0.1-beta
*/
public final class Startup extends Application {
/**
* The version of this client. Used to verify compatibility with the server.
*
* @since Envoy Client v0.1-beta
*/
public static final String VERSION = "0.1-beta";
private static LocalDB localDB;
private static final Context context = Context.getInstance();
private static final Client client = context.getClient();
private static final ClientConfig config = ClientConfig.getInstance();
private static final Logger logger = EnvoyLog.getLogger(Startup.class);
/**
* Loads the configuration, initializes the client and the local database and
* delegates the rest of the startup process to {@link LoginScene}.
*
* @since Envoy Client v0.1-beta
*/
@Override
public void start(Stage stage) throws Exception {
try {
config.loadAll(Startup.class, "client.properties", getParameters().getRaw().toArray(new String[0]));
EnvoyLog.initialize(config);
} catch (final IllegalStateException e) {
new Alert(AlertType.ERROR, "Error loading configuration values:\n" + e);
logger.log(Level.SEVERE, "Error loading configuration values: ", e);
System.exit(1);
}
logger.log(Level.INFO, "Envoy starting...");
// Initialize the local database
try {
final var localDBDir = new File(config.getHomeDirectory(), config.getLocalDB().getPath());
logger.info("Initializing LocalDB at " + localDBDir);
localDB = new LocalDB(localDBDir);
} catch (IOException | EnvoyException e) {
logger.log(Level.SEVERE, "Could not initialize local database: ", e);
new Alert(AlertType.ERROR, "Could not initialize local database!\n" + e).showAndWait();
System.exit(1);
return;
}
// Prepare handshake
context.setLocalDB(localDB);
// Configure stage
stage.setTitle("Envoy");
stage.getIcons().add(IconUtil.loadIcon("envoy_logo"));
// Create scene context
final var sceneContext = new SceneContext(stage);
context.setSceneContext(sceneContext);
// Authenticate with token if present
if (localDB.getAuthToken() != null) {
logger.info("Attempting authentication with token...");
localDB.loadUserData();
if (!performHandshake(
LoginCredentials.loginWithToken(localDB.getUser().getName(), localDB.getAuthToken(), VERSION, localDB.getLastSync())))
sceneContext.load(SceneInfo.LOGIN_SCENE);
} else
// Load login scene
sceneContext.load(SceneInfo.LOGIN_SCENE);
}
/**
* Tries to perform a Handshake with the server.
*
* @param credentials the credentials to use for the handshake
* @return whether the handshake was successful or offline mode could be entered
* @since Envoy Client v0.2-beta
*/
public static boolean performHandshake(LoginCredentials credentials) {
final var cacheMap = new CacheMap();
cacheMap.put(Message.class, new Cache