config.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // electron/utils/readConfig.js
  2. const fs = require('fs');
  3. const path = require('path');
  4. const { app } = require('electron');
  5. const defaultConfig = require('./config.default');
  6. const configPath = path.join(app.getPath("userData"),'config.default.json');
  7. // Smart Shooter 5 的历史默认安装目录。用户目录里的旧配置会盖掉代码默认值,
  8. // 只有仍停在这套出厂值时才自动切到 6;手动选过别的目录则保持不动。
  9. const LEGACY_SMARTSHOOTER5 = {
  10. controlType: "SmartShooter",
  11. controlPath: "C:\\Program Files\\Smart Shooter 5",
  12. }
  13. function sameValue(a, b) {
  14. return JSON.stringify(a) === JSON.stringify(b)
  15. }
  16. // 用户目录只保留和 utils 默认值不同的项
  17. function stripDefaults(overrides) {
  18. const next = { ...overrides }
  19. for (const key of Object.keys(next)) {
  20. if (Object.prototype.hasOwnProperty.call(defaultConfig, key) && sameValue(next[key], defaultConfig[key])) {
  21. delete next[key]
  22. }
  23. }
  24. return next
  25. }
  26. function overridesEqual(a, b) {
  27. const keys = new Set([...Object.keys(a || {}), ...Object.keys(b || {})])
  28. for (const key of keys) {
  29. if (!sameValue(a[key], b[key])) return false
  30. }
  31. return true
  32. }
  33. function readOverrides() {
  34. if (!fs.existsSync(configPath)) return {}
  35. const data = fs.readFileSync(configPath, 'utf8');
  36. const parsed = JSON.parse(data);
  37. if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {}
  38. return parsed
  39. }
  40. function writeOverrides(overrides) {
  41. fs.writeFileSync(configPath, JSON.stringify(overrides, null, 2), 'utf8');
  42. }
  43. function migrateLegacySmartShooter(overrides) {
  44. if (!overrides || overrides.smartShooter6Migrated) return { overrides, changed: false }
  45. const merged = { ...defaultConfig, ...overrides }
  46. const stillFactoryDefault = merged.controlType === LEGACY_SMARTSHOOTER5.controlType
  47. && merged.controlPath === LEGACY_SMARTSHOOTER5.controlPath
  48. const next = { ...overrides, smartShooter6Migrated: true }
  49. if (!stillFactoryDefault) return { overrides: next, changed: true }
  50. next.controlType = defaultConfig.controlType
  51. next.controlPath = defaultConfig.controlPath
  52. next.SmartShooterPath = overrides.SmartShooterPath || LEGACY_SMARTSHOOTER5.controlPath
  53. next.SmartShooter6Path = defaultConfig.SmartShooter6Path
  54. return { overrides: next, changed: true }
  55. }
  56. /**
  57. * 读取配置:utils 里的默认值打底,用户目录里只覆盖改过的项
  58. */
  59. function readConfigFile() {
  60. try {
  61. const overrides = readOverrides()
  62. const { overrides: migrated, changed } = migrateLegacySmartShooter(overrides)
  63. const stored = stripDefaults(migrated)
  64. if (changed || !overridesEqual(overrides, stored)) {
  65. writeOverrides(stored)
  66. }
  67. return {
  68. ...defaultConfig,
  69. ...stored,
  70. };
  71. } catch (error) {
  72. console.error('读取配置文件出错:', error);
  73. return null;
  74. }
  75. }
  76. /**
  77. * 一次写入多项调整。和默认值相同的项不写进用户目录
  78. */
  79. function updateConfigFile(partial) {
  80. try {
  81. const next = { ...readOverrides() }
  82. for (const [key, value] of Object.entries(partial)) {
  83. if (Object.prototype.hasOwnProperty.call(defaultConfig, key) && sameValue(value, defaultConfig[key])) {
  84. delete next[key]
  85. } else {
  86. next[key] = value
  87. }
  88. }
  89. writeOverrides(stripDefaults(next))
  90. console.log(`成功写入配置项: ${Object.keys(partial).join(', ')}`);
  91. } catch (error) {
  92. console.error('写入配置文件出错:', error);
  93. }
  94. }
  95. /**
  96. * 写入配置文件
  97. * @param {string} key - 要写入的配置项键名
  98. * @param {*} value - 要写入的配置项值
  99. */
  100. function writeConfigFile(key, value) {
  101. updateConfigFile({ [key]: value })
  102. }
  103. module.exports = {
  104. readConfigFile,
  105. writeConfigFile,
  106. updateConfigFile
  107. };