diff --git a/src/com/sheepit/client/Option.java b/src/com/sheepit/client/Option.java new file mode 100644 index 0000000..5bc5bd9 --- /dev/null +++ b/src/com/sheepit/client/Option.java @@ -0,0 +1,19 @@ +package com.sheepit.client; + +import lombok.AllArgsConstructor; +import lombok.Data; +import org.jetbrains.annotations.NotNull; + +@Data +@AllArgsConstructor +public class Option { + private T value; + private boolean isLaunchCommand; + private String launchFlag; + + public Option(T value, @NotNull String launchFlag) { + this.value = value; + this.launchFlag = launchFlag; + this.isLaunchCommand = false; + } +} diff --git a/src/com/sheepit/client/SettingsLoader.java b/src/com/sheepit/client/SettingsLoader.java index 1ab0f52..c592bf1 100644 --- a/src/com/sheepit/client/SettingsLoader.java +++ b/src/com/sheepit/client/SettingsLoader.java @@ -29,40 +29,105 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.attribute.PosixFilePermission; import java.util.HashSet; +import java.util.List; import java.util.Properties; import java.util.Set; import com.sheepit.client.Configuration.ComputeType; import com.sheepit.client.hardware.gpu.GPU; import com.sheepit.client.hardware.gpu.GPUDevice; -import com.sheepit.client.standalone.GuiSwing; import com.sheepit.client.standalone.GuiText; import com.sheepit.client.standalone.GuiTextOneLine; import lombok.Data; @Data public class SettingsLoader { + + private enum PropertyNames { + + PRIORITY("priority"), + CACHE_DIR("cache-dir"), + COMPUTE_METHOD("compute-method"), + GPU("compute-gpu"), + RENDERBUCKET_SIZE("renderbucket-size"), + CORES("cores"), + CORES_BACKWARDS_COMPAT("cpu-cores"), + RAM("ram"), + RENDER_TIME("rendertime"), + LOGIN("login"), + PASSWORD("password"), + PROXY("proxy"), + HOSTNAME("hostname"), + AUTO_SIGNIN("auto-signin"), + USE_SYSTRAY("use-systray"), + HEADLESS("headless"), + UI("ui"), + THEME("theme"); + + String propertyName; + + PropertyNames(String prop) { + this.propertyName = prop; + } + + @Override + public String toString() { + return propertyName; + } + + } + + public static final String ARG_SERVER = "-server"; + public static final String ARG_LOGIN = "-login"; + public static final String ARG_PASSWORD = "-password"; + public static final String ARG_CACHE_DIR = "-cache-dir"; + public static final String ARG_SHARED_ZIP = "-shared-zip"; + public static final String ARG_GPU = "-gpu"; + public static final String ARG_NO_GPU = "--no-gpu"; + public static final String ARG_COMPUTE_METHOD = "-compute-method"; + public static final String ARG_CORES = "-cores"; + public static final String ARG_MEMORY = "-memory"; + public static final String ARG_RENDERTIME = "-rendertime"; + public static final String ARG_VERBOSE = "--verbose"; + public static final String ARG_REQUEST_TIME = "-request-time"; + public static final String ARG_SHUTDOWN = "-shutdown"; + public static final String ARG_SHUTDOWN_MODE = "-shutdown-mode"; + public static final String ARG_PROXY = "-proxy"; + public static final String ARG_EXTRAS = "-extras"; + public static final String ARG_UI = "-ui"; + public static final String ARG_CONFIG = "-config"; + public static final String ARG_VERSION = "--version"; + public static final String ARG_SHOW_GPU = "--show-gpu"; + public static final String ARG_NO_SYSTRAY = "--no-systray"; + public static final String ARG_PRIORITY = "-priority"; + public static final String ARG_TITLE = "-title"; + public static final String ARG_THEME = "-theme"; + public static final String ARG_RENDERBUCKET_SIZE = "-renderbucket-size"; + public static final String ARG_HOSTNAME = "-hostname"; + public static final String ARG_HEADLESS = "--headless"; + + private String path; - private String login; + private Option login; - private String password; + private Option password; - private String proxy; - private String hostname; - private String computeMethod; - private String gpu; - private String renderbucketSize; - private String cores; - private String ram; - private String renderTime; - private String cacheDir; - private String autoSignIn; - private String useSysTray; - private String headless; - private String ui; - private String theme; - private int priority; + private Option proxy; + private Option hostname; + private Option computeMethod; + private Option gpu; + private Option renderbucketSize; + private Option cores; + private Option ram; + private Option renderTime; + private Option cacheDir; + private Option autoSignIn; + private Option useSysTray; + private Option headless; + private Option ui; + private Option theme; + private Option priority; public SettingsLoader(String path_) { if (path_ == null) { @@ -73,53 +138,74 @@ public class SettingsLoader { } } - public SettingsLoader(String path_, String login_, String password_, String proxy_, String hostname_, ComputeType computeMethod_, GPUDevice gpu_, - int renderbucketSize_, int cores_, long maxRam_, int maxRenderTime_, String cacheDir_, boolean autoSignIn_, boolean useSysTray_, boolean isHeadless, String ui_, - String theme_, int priority_) { + public void setSettings(String path_, String login_, String password_, String proxy_, String hostname_, + ComputeType computeMethod_, GPUDevice gpu_, Integer renderbucketSize_, Integer cores_, Long maxRam_, + Integer maxRenderTime_, String cacheDir_, Boolean autoSignIn_, Boolean useSysTray_, Boolean isHeadless, + String ui_, String theme_, Integer priority_) { if (path_ == null) { path = getDefaultFilePath(); } else { path = path_; } - login = login_; - password = password_; - proxy = proxy_; - hostname = hostname_; - cacheDir = cacheDir_; - autoSignIn = String.valueOf(autoSignIn_); - useSysTray = String.valueOf(useSysTray_); - headless = String.valueOf(isHeadless); - ui = ui_; - priority = priority_; - theme = theme_; + login = setValue(login_, login, ARG_LOGIN); + password = setValue(password_, password, ARG_PASSWORD); + proxy = setValue(proxy_, proxy, ARG_PROXY); + hostname = setValue(hostname_, hostname, ARG_HOSTNAME); + cacheDir = setValue(cacheDir_, cacheDir, ARG_CACHE_DIR); + autoSignIn = setValue(autoSignIn_.toString(), autoSignIn, ""); + useSysTray = setValue(useSysTray_.toString(), useSysTray, ARG_NO_SYSTRAY); + headless = setValue(isHeadless.toString(), headless, ARG_HEADLESS); + ui = setValue(ui_, ui, ARG_UI); + priority = setValue(priority_, priority, ARG_PRIORITY); + theme = setValue(theme_, theme, ARG_THEME); + + renderbucketSize = setValue(renderbucketSize_.toString(), renderbucketSize, ARG_RENDERBUCKET_SIZE); if (cores_ > 0) { - cores = String.valueOf(cores_); + cores = setValue(cores_.toString(), cores, ARG_CORES); } if (maxRam_ > 0) { - ram = String.valueOf(maxRam_) + "k"; + ram = setValue(maxRam_+ "k", ram, ARG_MEMORY); } if (maxRenderTime_ > 0) { - renderTime = String.valueOf(maxRenderTime_); + renderTime = setValue(maxRenderTime_.toString(), renderTime, ARG_RENDERTIME); } if (computeMethod_ != null) { try { - computeMethod = computeMethod_.name(); + computeMethod = setValue(computeMethod_.name(), computeMethod, ARG_COMPUTE_METHOD); } catch (IllegalArgumentException e) { } } if (gpu_ != null) { - gpu = gpu_.getId(); + gpu = setValue(gpu_.getId(), gpu, ARG_GPU); } - if (renderbucketSize_ >= GPU.MIN_RENDERBUCKET_SIZE) { - renderbucketSize = String.valueOf(renderbucketSize_); + if (renderbucketSize_ != null && renderbucketSize_ >= GPU.MIN_RENDERBUCKET_SIZE) { + renderbucketSize = setValue(renderbucketSize_.toString(), renderbucketSize, ARG_RENDERBUCKET_SIZE); } } + /** + * sets an option to a given value. If the option being passed on is null it will be created with the given value and returned. + * @param value The value to be set + * @param option The {@link Option} object that the value is going to be stored in. Can be null + * @param launchFlag A flag indicating whether the option was set via a launch argument or not + * @param The type of the value stored within the option + * @return The {@link Option} object that has been passed on as a parameter with the value being set, or a newly created object if option was null + */ + private Option setValue(T value, Option option, String launchFlag) { + if (option == null && value != null) { + option = new Option<>(value, launchFlag); + } + else if (value != null){ + option.setValue(value); + } + return option; + } + public static String getDefaultFilePath() { return System.getProperty("user.home") + File.separator + ".sheepit.conf"; } @@ -128,77 +214,80 @@ public class SettingsLoader { return path; } - public void saveFile() { + /** + * Takes the list of launch parameters and marks every config setting corresponding to one of the set values as launch command, ensuring that they wont overwrite + * the one in the config file + * @param argsList a list of the launch arguments + */ + public void markLaunchSettings(List argsList) { + Option options[] = { login, password, proxy, hostname, computeMethod, gpu, renderbucketSize, cores, ram, renderTime, cacheDir, autoSignIn, + useSysTray, headless, ui, theme, priority }; + + for (Option option : options) { + if (option != null && argsList.contains(option.getLaunchFlag())) { + option.setLaunchCommand(true); + } + } + } + + /** + * Selects the right setting to store to the config file between the value currently set in the config file and the option the client is working with + * currently, depending on whether the setting was set via launch argument or not + * @param saveTo the properties object representing the config file that is going to be written + * @param configFileProperties the properties object containing the current config file values + * @param property an enum representing the name of the setting + * @param option the option containing the currently used value + */ + private void setProperty(Properties saveTo, Properties configFileProperties, PropertyNames property, Option option) { + if (option != null) { + if (option.isLaunchCommand()) { + String configValue = configFileProperties.getProperty(property.propertyName); + if (configValue != null) { + saveTo.setProperty(property.propertyName, configValue); + } + } + else { + saveTo.setProperty(property.propertyName, option.getValue()); + } + } + } + + @SuppressWarnings("PointlessBooleanExpression") public void saveFile() { + + Properties configFileProp = new Properties(); + if (new File(path).exists()) { + InputStream input = null; + try { + input = new FileInputStream(path); + configFileProp.load(input); + } catch (IOException e) { + e.printStackTrace(); + } + } + Properties prop = new Properties(); OutputStream output = null; try { output = new FileOutputStream(path); - prop.setProperty("priority", new Integer(priority).toString()); - - if (cacheDir != null) { - prop.setProperty("cache-dir", cacheDir); - } - - if (computeMethod != null) { - prop.setProperty("compute-method", computeMethod); - } - - if (gpu != null) { - prop.setProperty("compute-gpu", gpu); - } - - if (renderbucketSize != null) { - prop.setProperty("renderbucket-size", renderbucketSize); - } - - if (cores != null) { - prop.setProperty("cores", cores); - } - - if (ram != null) { - prop.setProperty("ram", ram); - } - - if (renderTime != null) { - prop.setProperty("rendertime", renderTime); - } - - if (login != null) { - prop.setProperty("login", login); - } - - if (password != null) { - prop.setProperty("password", password); - } - - if (proxy != null) { - prop.setProperty("proxy", proxy); - } - - if (hostname != null) { - prop.setProperty("hostname", hostname); - } - - if (autoSignIn != null) { - prop.setProperty("auto-signin", autoSignIn); - } - - if (useSysTray != null) { - prop.setProperty("use-systray", useSysTray); - } - - if (headless != null) { - prop.setProperty("headless", headless); - } - - if (ui != null) { - prop.setProperty("ui", ui); - } - - if (theme != null) { - prop.setProperty("theme", theme); - } + setProperty(prop, configFileProp, PropertyNames.PRIORITY, + new Option<>(priority != null ? priority.getValue().toString() : null, priority.isLaunchCommand(), ARG_PRIORITY)); + setProperty(prop, configFileProp, PropertyNames.CACHE_DIR, cacheDir); + setProperty(prop, configFileProp, PropertyNames.COMPUTE_METHOD, computeMethod); + setProperty(prop, configFileProp, PropertyNames.GPU, gpu); + setProperty(prop, configFileProp, PropertyNames.RENDERBUCKET_SIZE, renderbucketSize); + setProperty(prop, configFileProp, PropertyNames.CORES, cores); + setProperty(prop, configFileProp, PropertyNames.RAM, ram); + setProperty(prop, configFileProp, PropertyNames.RENDER_TIME, renderTime); + setProperty(prop, configFileProp, PropertyNames.LOGIN, login); + setProperty(prop, configFileProp, PropertyNames.PASSWORD, password); + setProperty(prop, configFileProp, PropertyNames.PROXY, proxy); + setProperty(prop, configFileProp, PropertyNames.HOSTNAME, hostname); + setProperty(prop, configFileProp, PropertyNames.AUTO_SIGNIN, autoSignIn); + setProperty(prop, configFileProp, PropertyNames.USE_SYSTRAY, useSysTray); + setProperty(prop, configFileProp, PropertyNames.HEADLESS, headless); + setProperty(prop, configFileProp, PropertyNames.UI, ui); + setProperty(prop, configFileProp, PropertyNames.THEME, theme); prop.store(output, null); } catch (IOException io) { @@ -231,10 +320,31 @@ public class SettingsLoader { } } + /** + * Initializes or sets an option object to the corresponding value from the config file + * @param config the properties loaded from the config file + * @param property the name of the property + * @param option the option to store the property value + * @param launchFlag the launch argument corresponding to the respective option + */ + private Option loadConfigOption(Properties config, PropertyNames property, Option option, String launchFlag) { + String configValue; + if (config.containsKey(property.propertyName)) { + configValue = config.getProperty(property.propertyName); + if (option == null && configValue != null) { + option = new Option<>(configValue, launchFlag); + } + else if (configValue != null){ + option.setValue(configValue); + } + } + return option; + } - public void loadFile() throws Exception { + public void loadFile(boolean initialize) throws Exception { - initWithDefaults(); + if (initialize) + initWithDefaults(); if (new File(path).exists() == false) { return; @@ -246,76 +356,48 @@ public class SettingsLoader { input = new FileInputStream(path); prop.load(input); - if (prop.containsKey("cache-dir")) { - this.cacheDir = prop.getProperty("cache-dir"); - } + cacheDir = loadConfigOption(prop, PropertyNames.CACHE_DIR, cacheDir, ARG_CACHE_DIR); - if (prop.containsKey("compute-method")) { - this.computeMethod = prop.getProperty("compute-method"); - } + computeMethod = loadConfigOption(prop, PropertyNames.COMPUTE_METHOD, computeMethod, ARG_COMPUTE_METHOD); - if (prop.containsKey("compute-gpu")) { - this.gpu = prop.getProperty("compute-gpu"); - } + gpu = loadConfigOption(prop, PropertyNames.GPU, gpu, ARG_GPU); - if (prop.containsKey("renderbucket-size")) { - this.renderbucketSize = prop.getProperty("renderbucket-size"); - } + renderbucketSize = loadConfigOption(prop, PropertyNames.RENDERBUCKET_SIZE, renderbucketSize, ARG_RENDERBUCKET_SIZE); - if (prop.containsKey("cpu-cores")) { // backward compatibility - this.cores = prop.getProperty("cpu-cores"); - } + cores = loadConfigOption(prop, PropertyNames.CORES_BACKWARDS_COMPAT, cores, ARG_CORES); - if (prop.containsKey("cores")) { - this.cores = prop.getProperty("cores"); - } + cores = loadConfigOption(prop, PropertyNames.CORES, cores, ARG_CORES); - if (prop.containsKey("ram")) { - this.ram = prop.getProperty("ram"); - } + ram = loadConfigOption(prop, PropertyNames.RAM, ram, ARG_MEMORY); - if (prop.containsKey("rendertime")) { - this.renderTime = prop.getProperty("rendertime"); - } + renderTime = loadConfigOption(prop, PropertyNames.RENDER_TIME, renderTime, ARG_RENDERTIME); - if (prop.containsKey("login")) { - this.login = prop.getProperty("login"); - } + login = loadConfigOption(prop, PropertyNames.LOGIN, login, ARG_LOGIN); - if (prop.containsKey("password")) { - this.password = prop.getProperty("password"); - } + password = loadConfigOption(prop, PropertyNames.PASSWORD, password, ARG_PASSWORD); - if (prop.containsKey("proxy")) { - this.proxy = prop.getProperty("proxy"); - } + proxy = loadConfigOption(prop, PropertyNames.PROXY, proxy, ARG_PROXY); - if (prop.containsKey("hostname")) { - this.hostname = prop.getProperty("hostname"); - } + hostname = loadConfigOption(prop, PropertyNames.HOSTNAME, hostname, ARG_HOSTNAME); - if (prop.containsKey("auto-signin")) { - this.autoSignIn = prop.getProperty("auto-signin"); - } + autoSignIn = loadConfigOption(prop, PropertyNames.AUTO_SIGNIN, autoSignIn, ""); - if (prop.containsKey("use-systray")) { - this.useSysTray = prop.getProperty("use-systray"); - } + useSysTray = loadConfigOption(prop, PropertyNames.USE_SYSTRAY, useSysTray, ARG_NO_SYSTRAY); - if (prop.containsKey("headless")) { - this.headless = prop.getProperty("headless"); - } + headless = loadConfigOption(prop, PropertyNames.HEADLESS, headless, ARG_HEADLESS); - if (prop.containsKey("ui")) { - this.ui = prop.getProperty("ui"); - } + ui = loadConfigOption(prop, PropertyNames.UI, ui, ARG_UI); - if (prop.containsKey("theme")) { - this.theme = prop.getProperty("theme"); - } + theme = loadConfigOption(prop, PropertyNames.THEME, theme, ARG_THEME); - if (prop.containsKey("priority")) { - this.priority = Integer.parseInt(prop.getProperty("priority")); + if (prop.containsKey(PropertyNames.PRIORITY.propertyName)) { + int prio = Integer.parseInt(prop.getProperty(PropertyNames.PRIORITY.propertyName)); + if (priority == null) { + priority = new Option<>(prio, ARG_PRIORITY); + } + else { + priority.setValue(prio); + } } } catch (Exception e) { //We need the try-catch here to ensure that the input file will be closed though we'll deal with the exception in the calling method @@ -336,14 +418,16 @@ public class SettingsLoader { /** * Merge the Settings file with the Configuration. * The Configuration will have high priority. + * @param config the config file + * @param initialize whether to initialize all fields with default values, should only be true on first call */ - public void merge(Configuration config) { + public void merge(Configuration config, boolean initialize) { if (config == null) { System.out.println("SettingsLoader::merge config is null"); } try { - loadFile(); + loadFile(initialize); applyConfigFileValues(config); } catch (Exception e) { @@ -357,35 +441,35 @@ public class SettingsLoader { private void applyConfigFileValues(Configuration config) { if (config.getLogin().isEmpty() && login != null) { - config.setLogin(login); + config.setLogin(login.getValue()); } if (config.getPassword().isEmpty() && password != null) { - config.setPassword(password); + config.setPassword(password.getValue()); } if ((config.getProxy() == null || config.getProxy().isEmpty()) && proxy != null) { - config.setProxy(proxy); + config.setProxy(proxy.getValue()); } if ((config.getHostname() == null || config.getHostname().isEmpty() || config.getHostname().equals(config.getDefaultHostname())) && hostname != null) { - config.setHostname(hostname); + config.setHostname(hostname.getValue()); } - if (!config.isHeadless() && headless != null) { - config.setHeadless(Boolean.parseBoolean(headless)); + if (config.isHeadless() == false && headless != null) { + config.setHeadless(Boolean.parseBoolean(headless.getValue())); } if (config.getPriority() == 19) { // 19 is default value - config.setUsePriority(priority); + config.setUsePriority(priority.getValue()); } try { if (config.getComputeMethod() == null && computeMethod == null) { config.setComputeMethod(ComputeType.CPU); } else if ((config.getComputeMethod() == null && computeMethod != null) || (computeMethod != null && config.getComputeMethod() != ComputeType - .valueOf(computeMethod))) { + .valueOf(computeMethod.getValue()))) { if (config.getComputeMethod() == null) { - config.setComputeMethod(ComputeType.valueOf(computeMethod)); + config.setComputeMethod(ComputeType.valueOf(computeMethod.getValue())); } } @@ -395,7 +479,7 @@ public class SettingsLoader { computeMethod = null; } if (config.getGPUDevice() == null && gpu != null) { - GPUDevice device = GPU.getGPUDevice(gpu); + GPUDevice device = GPU.getGPUDevice(gpu.getValue()); if (device != null) { config.setGPUDevice(device); @@ -406,7 +490,7 @@ public class SettingsLoader { else { // If the configuration file does have any value if (renderbucketSize != null) { - config.getGPUDevice().setRenderbucketSize(Integer.valueOf(renderbucketSize)); + config.getGPUDevice().setRenderbucketSize(Integer.valueOf(renderbucketSize.getValue())); } else { // Don't do anything here as the GPU get's a default value when it's initialised @@ -429,7 +513,7 @@ public class SettingsLoader { config.getGPUDevice().setRenderbucketSize(config.getRenderbucketSize()); } else if (renderbucketSize != null) { - config.getGPUDevice().setRenderbucketSize(Integer.parseInt(renderbucketSize)); + config.getGPUDevice().setRenderbucketSize(Integer.parseInt(renderbucketSize.getValue())); } else { config.getGPUDevice().setRenderbucketSize(config.getGPUDevice().getRecommendedBucketSize()); @@ -437,28 +521,28 @@ public class SettingsLoader { } if (config.getNbCores() == -1 && cores != null) { - config.setNbCores(Integer.valueOf(cores)); + config.setNbCores(Integer.parseInt(cores.getValue())); } if (config.getMaxMemory() == -1 && ram != null) { - config.setMaxMemory(Utils.parseNumber(ram) / 1000); // internal ram value is in kB + config.setMaxMemory(Utils.parseNumber(ram.getValue()) / 1000); // internal ram value is in kB } if (config.getMaxRenderTime() == -1 && renderTime != null) { - config.setMaxRenderTime(Integer.valueOf(renderTime)); + config.setMaxRenderTime(Integer.parseInt(renderTime.getValue())); } if (config.isUserHasSpecifiedACacheDir() == false && cacheDir != null) { - config.setCacheDir(new File(cacheDir)); + config.setCacheDir(new File(cacheDir.getValue())); } if (config.getUIType() == null && ui != null) { - config.setUIType(ui); + config.setUIType(ui.getValue()); } if (config.getTheme() == null) { - if (this.theme != null && (this.theme.equals("dark") || this.theme.equals("light"))) { - config.setTheme(this.theme); + if (this.theme != null && (this.theme.getValue().equals("dark") || this.theme.getValue().equals("light"))) { + config.setTheme(this.theme.getValue()); } else { config.setTheme("light"); @@ -467,11 +551,13 @@ public class SettingsLoader { // if the user has invoked the app with --no-systray, then we just overwrite the existing configuration with (boolean)false. If no parameter has been // specified and the settings file contains use-systray=false, then deactivate as well. - if (!config.isUseSysTray() || (config.isUseSysTray() && useSysTray != null && useSysTray.equals("false"))) { + if (!config.isUseSysTray() || (config.isUseSysTray() && useSysTray != null && useSysTray.getValue().equals("false"))) { config.setUseSysTray(false); } - config.setAutoSignIn(Boolean.parseBoolean(autoSignIn)); + if (config.isAutoSignIn() == false && autoSignIn != null) { + config.setAutoSignIn(Boolean.parseBoolean(autoSignIn.getValue())); + } } private void initWithDefaults() { @@ -485,14 +571,14 @@ public class SettingsLoader { this.renderbucketSize = null; this.cacheDir = null; this.autoSignIn = null; - this.useSysTray = String.valueOf(defaultConfigValues.isUseSysTray()); - this.headless = String.valueOf(defaultConfigValues.isHeadless()); + this.useSysTray = new Option<>(String.valueOf(defaultConfigValues.isUseSysTray()), ARG_NO_SYSTRAY); + this.headless = new Option<>(String.valueOf(defaultConfigValues.isHeadless()), ARG_HEADLESS); this.ui = null; - this.priority = defaultConfigValues.getPriority(); // must be the same default as Configuration + this.priority = new Option<>(defaultConfigValues.getPriority(), ARG_PRIORITY); // must be the same default as Configuration this.ram = null; this.renderTime = null; this.theme = null; - this.cores = String.valueOf(defaultConfigValues.getNbCores()); + this.cores = new Option<>(String.valueOf(defaultConfigValues.getNbCores()), ARG_CORES); } diff --git a/src/com/sheepit/client/standalone/GuiSwing.java b/src/com/sheepit/client/standalone/GuiSwing.java index 5c3c65a..73c72e7 100644 --- a/src/com/sheepit/client/standalone/GuiSwing.java +++ b/src/com/sheepit/client/standalone/GuiSwing.java @@ -291,8 +291,8 @@ public class GuiSwing extends JFrame implements Gui { @Override public void successfulAuthenticationEvent(String publickey) { if (settingsLoader != null) { - if (publickey != null && activitySettings.getLaunchConfig().getLogin().equals(settingsLoader.getLogin())) { - settingsLoader.setPassword(publickey); + if (publickey != null && settingsLoader.getLogin().isLaunchCommand() == false) { + settingsLoader.getPassword().setValue(publickey); } settingsLoader.saveFile(); } diff --git a/src/com/sheepit/client/standalone/Worker.java b/src/com/sheepit/client/standalone/Worker.java index 26cf8d4..698b99f 100644 --- a/src/com/sheepit/client/standalone/Worker.java +++ b/src/com/sheepit/client/standalone/Worker.java @@ -34,6 +34,7 @@ import java.time.format.DateTimeParseException; import java.time.temporal.ChronoUnit; import java.util.Calendar; import java.util.LinkedList; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -55,62 +56,62 @@ import com.sheepit.client.network.Proxy; import com.sheepit.client.os.OS; public class Worker { - @Option(name = "-server", usage = "Render-farm server, default https://client.sheepit-renderfarm.com", metaVar = "URL", required = false) private String server = "https://client.sheepit-renderfarm.com"; + @Option(name = SettingsLoader.ARG_SERVER, usage = "Render-farm server, default https://client.sheepit-renderfarm.com", metaVar = "URL", required = false) private String server = "https://client.sheepit-renderfarm.com"; - @Option(name = "-login", usage = "User's login", metaVar = "LOGIN", required = false) private String login = ""; + @Option(name = SettingsLoader.ARG_LOGIN, usage = "User's login", metaVar = "LOGIN", required = false) private String login = ""; - @Option(name = "-password", usage = "User's password or public key (accessible under the Keys tab of the profile page)", metaVar = "PASSWORD", required = false) private String password = ""; + @Option(name = SettingsLoader.ARG_PASSWORD, usage = "User's password or public key (accessible under the Keys tab of the profile page)", metaVar = "PASSWORD", required = false) private String password = ""; - @Option(name = "-cache-dir", usage = "Cache/Working directory. Caution, everything in it not related to the render-farm will be removed", metaVar = "/tmp/cache", required = false) private String cache_dir = null; + @Option(name = SettingsLoader.ARG_CACHE_DIR, usage = "Cache/Working directory. Caution, everything in it not related to the render-farm will be removed", metaVar = "/tmp/cache", required = false) private String cache_dir = null; - @Option(name = "-shared-zip", usage = "Shared directory for downloaded binaries and scenes. Useful when running two or more clients in the same computer/network to download once and render many times. IMPORTANT: This option and value must be identical in ALL clients sharing the directory.", required = false) private String sharedDownloadsDir = null; + @Option(name = SettingsLoader.ARG_SHARED_ZIP, usage = "Shared directory for downloaded binaries and scenes. Useful when running two or more clients in the same computer/network to download once and render many times. IMPORTANT: This option and value must be identical in ALL clients sharing the directory.", required = false) private String sharedDownloadsDir = null; - @Option(name = "-gpu", usage = "Name of the GPU used for the render, for example CUDA_0 for Nvidia or OPENCL_0 for AMD/Intel card", metaVar = "CUDA_0", required = false) private String gpu_device = null; + @Option(name = SettingsLoader.ARG_GPU, usage = "Name of the GPU used for the render, for example CUDA_0 for Nvidia or OPENCL_0 for AMD/Intel card", metaVar = "CUDA_0", required = false) private String gpu_device = null; - @Option(name = "--no-gpu", usage = "Don't detect GPUs", required = false) private boolean no_gpu_detection = false; + @Option(name = SettingsLoader.ARG_NO_GPU, usage = "Don't detect GPUs", required = false) private boolean no_gpu_detection = false; - @Option(name = "-compute-method", usage = "CPU: only use cpu, GPU: only use gpu, CPU_GPU: can use cpu and gpu (not at the same time) if -gpu is not use it will not use the gpu", metaVar = "CPU", required = false) private String method = null; + @Option(name = SettingsLoader.ARG_COMPUTE_METHOD, usage = "CPU: only use cpu, GPU: only use gpu, CPU_GPU: can use cpu and gpu (not at the same time) if -gpu is not use it will not use the gpu", metaVar = "CPU", required = false) private String method = null; - @Option(name = "-cores", usage = "Number of cores/threads to use for the render. The minimum is two cores unless your system only has one", metaVar = "3", required = false) private int nb_cores = -1; + @Option(name = SettingsLoader.ARG_CORES, usage = "Number of cores/threads to use for the render. The minimum is two cores unless your system only has one", metaVar = "3", required = false) private int nb_cores = -1; - @Option(name = "-memory", usage = "Maximum memory allow to be used by renderer, number with unit (800M, 2G, ...)", required = false) private String max_ram = null; + @Option(name = SettingsLoader.ARG_MEMORY, usage = "Maximum memory allow to be used by renderer, number with unit (800M, 2G, ...)", required = false) private String max_ram = null; - @Option(name = "-rendertime", usage = "Maximum time allow for each frame (in minutes)", required = false) private int max_rendertime = -1; + @Option(name = SettingsLoader.ARG_RENDERTIME, usage = "Maximum time allow for each frame (in minutes)", required = false) private int max_rendertime = -1; - @Option(name = "--verbose", usage = "Display log", required = false) private boolean print_log = false; + @Option(name = SettingsLoader.ARG_VERBOSE, usage = "Display log", required = false) private boolean print_log = false; - @Option(name = "-request-time", usage = "H1:M1-H2:M2,H3:M3-H4:M4 Use the 24h format. For example to request job between 2am-8.30am and 5pm-11pm you should do --request-time 2:00-8:30,17:00-23:00 Caution, it's the requesting job time to get a project, not the working time", metaVar = "2:00-8:30,17:00-23:00", required = false) private String request_time = null; + @Option(name = SettingsLoader.ARG_REQUEST_TIME, usage = "H1:M1-H2:M2,H3:M3-H4:M4 Use the 24h format. For example to request job between 2am-8.30am and 5pm-11pm you should do --request-time 2:00-8:30,17:00-23:00 Caution, it's the requesting job time to get a project, not the working time", metaVar = "2:00-8:30,17:00-23:00", required = false) private String request_time = null; - @Option(name = "-shutdown", usage = "Specify when the client will close and the host computer will shut down in a proper way. The time argument can have two different formats: an absolute date and time in the format yyyy-mm-ddThh:mm:ss (24h format) or a relative time in the format +m where m is the number of minutes from now.", metaVar = "DATETIME or +N", required = false) private String shutdown = null; + @Option(name = SettingsLoader.ARG_SHUTDOWN, usage = "Specify when the client will close and the host computer will shut down in a proper way. The time argument can have two different formats: an absolute date and time in the format yyyy-mm-ddThh:mm:ss (24h format) or a relative time in the format +m where m is the number of minutes from now.", metaVar = "DATETIME or +N", required = false) private String shutdown = null; - @Option(name = "-shutdown-mode", usage = "Indicates if the shutdown process waits for the upload queue to finish (wait) or interrupt all the pending tasks immediately (hard). The default shutdown mode is wait.", metaVar = "MODE", required = false) private String shutdownMode = null; + @Option(name = SettingsLoader.ARG_SHUTDOWN_MODE, usage = "Indicates if the shutdown process waits for the upload queue to finish (wait) or interrupt all the pending tasks immediately (hard). The default shutdown mode is wait.", metaVar = "MODE", required = false) private String shutdownMode = null; - @Option(name = "-proxy", usage = "URL of the proxy", metaVar = "http://login:password@host:port", required = false) private String proxy = null; + @Option(name = SettingsLoader.ARG_PROXY, usage = "URL of the proxy", metaVar = "http://login:password@host:port", required = false) private String proxy = null; - @Option(name = "-extras", usage = "Extras data push on the authentication request", required = false) private String extras = null; + @Option(name = SettingsLoader.ARG_EXTRAS, usage = "Extras data push on the authentication request", required = false) private String extras = null; - @Option(name = "-ui", usage = "Specify the user interface to use, default '" + GuiSwing.type + "', available '" + GuiTextOneLine.type + "', '" + @Option(name = SettingsLoader.ARG_UI, usage = "Specify the user interface to use, default '" + GuiSwing.type + "', available '" + GuiTextOneLine.type + "', '" + GuiText.type + "', '" + GuiSwing.type + "' (graphical)", required = false) private String ui_type = null; - @Option(name = "-config", usage = "Specify the configuration file", required = false) private String config_file = null; + @Option(name = SettingsLoader.ARG_CONFIG, usage = "Specify the configuration file", required = false) private String config_file = null; - @Option(name = "--version", usage = "Display application version", required = false, handler = VersionParameterHandler.class) private VersionParameterHandler versionHandler; + @Option(name = SettingsLoader.ARG_VERSION, usage = "Display application version", required = false, handler = VersionParameterHandler.class) private VersionParameterHandler versionHandler; - @Option(name = "--show-gpu", usage = "Print available GPU devices and exit", required = false, handler = ListGpuParameterHandler.class) private ListGpuParameterHandler listGpuParameterHandler; + @Option(name = SettingsLoader.ARG_SHOW_GPU, usage = "Print available GPU devices and exit", required = false, handler = ListGpuParameterHandler.class) private ListGpuParameterHandler listGpuParameterHandler; - @Option(name = "--no-systray", usage = "Don't use SysTray", required = false) private boolean useSysTray = false; + @Option(name = SettingsLoader.ARG_NO_SYSTRAY, usage = "Don't use SysTray", required = false) private boolean useSysTray = false; - @Option(name = "-priority", usage = "Set render process priority (19 lowest to -19 highest)", required = false) private int priority = 19; + @Option(name = SettingsLoader.ARG_PRIORITY, usage = "Set render process priority (19 lowest to -19 highest)", required = false) private int priority = 19; - @Option(name = "-title", usage = "Custom title for the GUI Client", required = false) private String title = "SheepIt Render Farm"; + @Option(name = SettingsLoader.ARG_TITLE, usage = "Custom title for the GUI Client", required = false) private String title = "SheepIt Render Farm"; - @Option(name = "-theme", usage = "Specify the theme to use for the graphical client, default 'light', available 'light', 'dark'", required = false) private String theme = null; + @Option(name = SettingsLoader.ARG_THEME, usage = "Specify the theme to use for the graphical client, default 'light', available 'light', 'dark'", required = false) private String theme = null; - @Option(name = "-renderbucket-size", usage = "Set a custom GPU renderbucket size (32 for 32x32px, 64 for 64x64px, and so on). NVIDIA GPUs support a maximum renderbucket size of 512x512 pixel, while AMD GPUs support a maximum 2048x2048 pixel renderbucket size. Minimum renderbucket size is 32 pixels for all GPUs", required = false) private int renderbucketSize = -1; + @Option(name = SettingsLoader.ARG_RENDERBUCKET_SIZE, usage = "Set a custom GPU renderbucket size (32 for 32x32px, 64 for 64x64px, and so on). NVIDIA GPUs support a maximum renderbucket size of 512x512 pixel, while AMD GPUs support a maximum 2048x2048 pixel renderbucket size. Minimum renderbucket size is 32 pixels for all GPUs", required = false) private int renderbucketSize = -1; - @Option(name = "-hostname", usage = "Set a custom hostname name (name change will be lost when client is closed)", required = false) private String hostname = null; + @Option(name = SettingsLoader.ARG_HOSTNAME, usage = "Set a custom hostname name (name change will be lost when client is closed)", required = false) private String hostname = null; - @Option(name = "--headless", usage = "Mark your client manually as headless to block Eevee projects", required = false) private boolean headless = java.awt.GraphicsEnvironment.isHeadless(); + @Option(name = SettingsLoader.ARG_HEADLESS, usage = "Mark your client manually as headless to block Eevee projects", required = false) private boolean headless = java.awt.GraphicsEnvironment.isHeadless(); public static void main(String[] args) { if (OS.getOS() == null) { @@ -432,7 +433,12 @@ public class Worker { } SettingsLoader settingsLoader = new SettingsLoader(config_file); - settingsLoader.merge(config); + settingsLoader.merge(config, true); + + if (args.length > 0) { + settingsLoader.markLaunchSettings(List.of(args)); + } + Log.getInstance(config).debug("client version " + config.getJarVersion()); // Hostname change will overwrite the existing one (default or read from configuration file) but changes will be lost when the client closes @@ -480,7 +486,6 @@ public class Worker { } Client cli = new Client(gui, config, server); gui.setClient(cli); - ShutdownHook hook = new ShutdownHook(cli); hook.attachShutDownHook(); diff --git a/src/com/sheepit/client/standalone/swing/activity/Settings.java b/src/com/sheepit/client/standalone/swing/activity/Settings.java index 8adcbe1..78715d9 100644 --- a/src/com/sheepit/client/standalone/swing/activity/Settings.java +++ b/src/com/sheepit/client/standalone/swing/activity/Settings.java @@ -63,7 +63,6 @@ import com.formdev.flatlaf.FlatDarkLaf; import com.sheepit.client.Configuration; import com.sheepit.client.Configuration.ComputeType; -import com.sheepit.client.SettingsLoader; import com.sheepit.client.hardware.cpu.CPU; import com.sheepit.client.hardware.gpu.GPU; import com.sheepit.client.hardware.gpu.GPUDevice; @@ -75,9 +74,9 @@ import com.sheepit.client.os.OS; import com.sheepit.client.standalone.GuiSwing; import com.sheepit.client.standalone.swing.SwingTooltips; import com.sheepit.client.standalone.swing.components.CollapsibleJPanel; -import lombok.Getter; import org.jetbrains.annotations.NotNull; + public class Settings implements Activity { private static final String DUMMY_CACHE_DIR = "Auto detected"; @@ -115,8 +114,6 @@ public class Settings implements Activity { private boolean sessionStarted; //indicates whether the settings activity gets shown on launch or mid-session. // it should only be false when the settings activity gets shown right after launch - @Getter private Configuration launchConfig; //the config we launched with, combined out of launch arguments and config file settings - public Settings(GuiSwing parent_) { parent = parent_; cacheDir = null; @@ -127,7 +124,7 @@ public class Settings implements Activity { @Override public void show() { Configuration config = parent.getConfiguration(); - new SettingsLoader(config.getConfigFilePath()).merge(config); + parent.getSettingsLoader().merge(config, false); useSysTrayPrevState = config.isUseSysTray(); isHeadlessPrevState = config.isHeadless(); @@ -600,11 +597,6 @@ public class Settings implements Activity { haveAutoStarted = true; new SaveAction().actionPerformed(null); } - - //check so the launch config does not get overwritten if the user goes back to the settings activity mid-session - if(!sessionStarted) { - launchConfig = new Configuration(config); - } } public void resizeWindow() {} @@ -758,10 +750,6 @@ public class Settings implements Activity { return; } - if(config.isAutoSignIn() && launchConfig == null) { - launchConfig = new Configuration(config); - } - if (themeOptionsGroup.getSelection().getActionCommand() != null) config.setTheme(themeOptionsGroup.getSelection().getActionCommand()); @@ -792,7 +780,6 @@ public class Settings implements Activity { int renderbucket_size = -1; if (renderbucketSize != null) { renderbucket_size = (int) Math.pow(2, (renderbucketSize.getValue() + 5)); - System.out.println(config.getRenderbucketSize() + " calced: " + renderbucket_size); } config.setRenderbucketSize(renderbucket_size); @@ -862,16 +849,10 @@ public class Settings implements Activity { if (saveFile.isSelected()) { - //save config file values to seperate config for later comparison (only necessary for GuiSwing as the other uis dont save any configs) - Configuration configFileConfiguration = new Configuration(null, "", ""); - configFileConfiguration.setConfigFilePath(config.getConfigFilePath()); - parent.getSettingsLoader().merge(configFileConfiguration); - - mergeChanges(launchConfig, config, configFileConfiguration); -// parent.setSettingsLoader( -// new SettingsLoader(config.getConfigFilePath(), login.getText(), new String(password.getPassword()), proxyText, hostnameText, method, -// selected_gpu, renderbucket_size, cpu_cores, max_ram, max_rendertime, cachePath, autoSignIn.isSelected(), useSysTray.isSelected(), -// headlessCheckbox.isSelected(), GuiSwing.type, themeOptionsGroup.getSelection().getActionCommand(), config.getPriority())); + parent.getSettingsLoader() + .setSettings(config.getConfigFilePath(), login.getText(), new String(password.getPassword()), proxyText, hostnameText, method, + selected_gpu, renderbucket_size, cpu_cores, max_ram, max_rendertime, getCachePath(config), autoSignIn.isSelected(), useSysTray.isSelected(), + headlessCheckbox.isSelected(), GuiSwing.type, themeOptionsGroup.getSelection().getActionCommand(), config.getPriority()); // wait for successful authentication (to store the public key) // or do we already have one? @@ -917,87 +898,6 @@ public class Settings implements Activity { return method; } - private void mergeChanges(Configuration launchConfig, Configuration workingConfig, Configuration configFileConfiguration) { - - /* if the config value we are checking is different from the config file (e.g. because it got passed as a launch argument) we leave the settingsLoader as is - as to not overwrite it with the launch argument. However, if it was changed after launch we do save it - */ - if (saveSetting(launchConfig.getLogin(), configFileConfiguration.getLogin(), workingConfig.getLogin())) { - parent.getSettingsLoader().setLogin(workingConfig.getLogin()); - } - - if (saveSetting(launchConfig.getPassword(), configFileConfiguration.getPassword(), workingConfig.getPassword())) { - parent.getSettingsLoader().setPassword(workingConfig.getPassword()); - } - - if (saveSetting(launchConfig.getHostname(), configFileConfiguration.getHostname(), workingConfig.getHostname())) { - parent.getSettingsLoader().setHostname(workingConfig.getHostname()); - } - - if (saveSetting(launchConfig.getProxy(), configFileConfiguration.getProxy(), workingConfig.getProxy())) { - parent.getSettingsLoader().setProxy(workingConfig.getProxy()); - } - - if (saveSetting(launchConfig.getNbCores(), configFileConfiguration.getNbCores(), workingConfig.getNbCores())) { - parent.getSettingsLoader().setCores(String.valueOf(workingConfig.getNbCores())); - } - - if (saveSetting(launchConfig.getMaxMemory(), configFileConfiguration.getMaxMemory(), workingConfig.getMaxMemory())) { - parent.getSettingsLoader().setRam(String.valueOf(workingConfig.getMaxMemory())); - } - - if (saveSetting(launchConfig.getMaxRenderTime(), configFileConfiguration.getMaxRenderTime(), workingConfig.getMaxRenderTime())) { - parent.getSettingsLoader().setRenderTime(String.valueOf(workingConfig.getMaxRenderTime())); - } - - if (saveSetting(launchConfig.getGPUDevice(), configFileConfiguration.getGPUDevice(), workingConfig.getGPUDevice())) { - parent.getSettingsLoader().setGpu(workingConfig.getGPUDevice().getId()); //TODO presumably works - } - - if (saveSetting(launchConfig.getRenderbucketSize(), configFileConfiguration.getRenderbucketSize(), workingConfig.getRenderbucketSize())) { - parent.getSettingsLoader().setRenderbucketSize(String.valueOf(workingConfig.getRenderbucketSize())); - } - - if (saveSetting(getCachePath(launchConfig), getCachePath(configFileConfiguration), getCachePath(workingConfig))) { - parent.getSettingsLoader().setCacheDir(getCachePath(workingConfig)); - } - - //not changeable through launch arguments - if (saveSetting(launchConfig.isAutoSignIn(), configFileConfiguration.isAutoSignIn(), workingConfig.isAutoSignIn())) { - parent.getSettingsLoader().setAutoSignIn(String.valueOf(workingConfig.isAutoSignIn())); - } - - if (saveSetting(launchConfig.isUseSysTray(), configFileConfiguration.isUseSysTray(), workingConfig.isUseSysTray())) { - parent.getSettingsLoader().setUseSysTray(String.valueOf(workingConfig.isUseSysTray())); - } - - if (saveSetting(launchConfig.isHeadless(), configFileConfiguration.isHeadless(), workingConfig.isHeadless())) { - parent.getSettingsLoader().setHeadless(String.valueOf(workingConfig.isHeadless())); - } - - //not needed as the user has no way of modifying that setting after launch -// if (saveSetting(launchConfig.getUIType(), configFileConfiguration.getUIType(), workingConfig.getUIType())) { -// parent.getSettingsLoader().setUi(workingConfig.getUIType()); -// } - - if (saveSetting(launchConfig.getTheme(), configFileConfiguration.getTheme(), workingConfig.getTheme())) { - parent.getSettingsLoader().setTheme(workingConfig.getTheme()); - } - - if (saveSetting(launchConfig.getPriority(), configFileConfiguration.getPriority(), workingConfig.getPriority())) { - parent.getSettingsLoader().setPriority(workingConfig.getPriority()); - } - - - } - - private boolean saveSetting(T launchValue, T configFileValue, T workingValue) { - if (workingValue == null) { - return false; - } - return !workingValue.equals(configFileValue) && !workingValue.equals(launchValue); - } - private String getCachePath(Configuration config) { String cachePath = null; if (config.isUserHasSpecifiedACacheDir() && config.getCacheDirForSettings() != null) { diff --git a/src/com/sheepit/client/standalone/swing/activity/Working.java b/src/com/sheepit/client/standalone/swing/activity/Working.java index a4345f9..c87fecd 100644 --- a/src/com/sheepit/client/standalone/swing/activity/Working.java +++ b/src/com/sheepit/client/standalone/swing/activity/Working.java @@ -29,7 +29,6 @@ import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.awt.Image; import java.io.File; -import java.io.IOException; import java.text.DecimalFormat; import java.util.Date;