settings.java 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package au.pfip;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.io.OutputStream;
  5. import java.nio.file.Files;
  6. import java.nio.file.Path;
  7. import java.util.LinkedHashMap;
  8. import java.util.Map;
  9. import java.util.Properties;
  10. /**
  11. * Settings file (Java XML properties). The first of these that exists is used:
  12. * /etc/timekeeper.inf, ~/timekeeper.inf, ~/.config/timekeeper/timekeeper.inf,
  13. * ./timekeeper.inf. Run as root and keep the file in /etc: a settings file
  14. * the monitored user can edit defeats the monitoring.
  15. *
  16. * Changes: missing keys fall back to defaults (a missing key used to throw a
  17. * NullPointerException or silently disable the program), the settings file is
  18. * closed after reading, and the defaults written into a new file no longer
  19. * contain real user names or a network name.
  20. */
  21. public class settings {
  22. private static final Properties settings = new Properties();
  23. private static final Map<String, String> defaults = new LinkedHashMap<>();
  24. private static String settingsFile;
  25. static {
  26. defaults.put("TimekeeperActive", "true");
  27. defaults.put("LogFilePath", System.getProperty("user.home"));
  28. // Comma separated list of the accounts to watch, e.g. "alice,bob". Must be set.
  29. defaults.put("UsersToMonitor", "");
  30. // Name of a network where enforcement is switched off. Empty means none.
  31. defaults.put("ExemptNetwork", "");
  32. defaults.put("GamesURL", "https://overlord.pfip.au/e107_plugins/timekeeper/timekeeperClientServices/games.json");
  33. defaults.put("PlaytimeURL", "https://overlord.pfip.au/e107_plugins/timekeeper/timekeeperClientServices/timer.php");
  34. // How many checks in a row may fail to reach the server before the game is closed (1 = close at once).
  35. defaults.put("OfflineChecksBeforeKill", "5");
  36. defaults.put("GamesRefreshMinutes", "60");
  37. }
  38. public static boolean initialiseSettings()
  39. {
  40. try {
  41. String[] paths = {"/etc/timekeeper.inf", System.getProperty("user.home") + "/timekeeper.inf", System.getProperty("user.home") + "/.config/timekeeper/timekeeper.inf", System.getProperty("user.dir") + "/timekeeper.inf"};
  42. for (String candidate : paths) {
  43. System.out.println("Checking for settings at " + candidate);
  44. Path path = Path.of(candidate);
  45. if (Files.exists(path)) {
  46. System.out.println("Found settings at " + path);
  47. settingsFile = String.valueOf(path);
  48. try (InputStream in = Files.newInputStream(path)) {
  49. settings.loadFromXML(in);
  50. }
  51. return true;
  52. }
  53. }
  54. Path path = Path.of(paths[2]);
  55. settingsFile = paths[2];
  56. Files.createDirectories(path.getParent());
  57. createSettingsFile();
  58. System.out.println("Settings file created at " + settingsFile + ". Set UsersToMonitor in it.");
  59. return true;
  60. } catch (IOException e) {
  61. //noinspection CallToPrintStackTrace
  62. e.printStackTrace();
  63. return false;
  64. }
  65. }
  66. private static void createSettingsFile()
  67. {
  68. for (Map.Entry<String, String> entry : defaults.entrySet()) {
  69. addSetting(entry.getKey(), entry.getValue());
  70. }
  71. saveSettingsFile();
  72. }
  73. public static void saveSettingsFile()
  74. {
  75. try (OutputStream out = Files.newOutputStream(Path.of(settingsFile))) {
  76. settings.storeToXML(out, "Timekeeper configuration file.");
  77. } catch (IOException e) {
  78. throw new RuntimeException(e);
  79. }
  80. }
  81. public static void addSetting(String key, String val)
  82. {
  83. settings.setProperty(key, String.valueOf(val));
  84. }
  85. /**
  86. * A setting, or its default when the file doesn't have it. Never null.
  87. */
  88. public static String getSetting(String key)
  89. {
  90. String value = settings.getProperty(key);
  91. if (value == null) {
  92. value = defaults.get(key);
  93. }
  94. return value == null ? "" : value.trim();
  95. }
  96. public static int getInt(String key, int fallback)
  97. {
  98. try {
  99. return Integer.parseInt(getSetting(key));
  100. } catch (NumberFormatException e) {
  101. return fallback;
  102. }
  103. }
  104. /**
  105. * The folder the settings file lives in (also used for the games list cache).
  106. */
  107. public static Path getSettingsDirectory()
  108. {
  109. Path parent = (settingsFile == null) ? null : Path.of(settingsFile).toAbsolutePath().getParent();
  110. return parent != null ? parent : Path.of(System.getProperty("user.home"));
  111. }
  112. }