dropinmodutil.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. const fs = require('fs-extra')
  2. const path = require('path')
  3. const { shell } = require('electron')
  4. // Group #1: File Name (without .disabled, if any)
  5. // Group #2: File Extension (jar, zip, or litemod)
  6. // Group #3: If it is disabled (if string 'disabled' is present)
  7. const MOD_REGEX = /^(.+(jar|zip|litemod))(?:\.(disabled))?$/
  8. const DISABLED_EXT = '.disabled'
  9. /**
  10. * Validate that the given mods directory exists. If not,
  11. * it is created.
  12. *
  13. * @param {string} modsDir The path to the mods directory.
  14. */
  15. exports.validateModsDir = function(modsDir) {
  16. fs.ensureDirSync(modsDir)
  17. }
  18. /**
  19. * Scan for drop-in mods in both the mods folder and version
  20. * safe mods folder.
  21. *
  22. * @param {string} modsDir The path to the mods directory.
  23. * @param {string} version The minecraft version of the server configuration.
  24. *
  25. * @returns {{fullName: string, name: string, ext: string, disabled: boolean}[]}
  26. * An array of objects storing metadata about each discovered mod.
  27. */
  28. exports.scanForDropinMods = function(modsDir, version) {
  29. const modsDiscovered = []
  30. if(fs.existsSync(modsDir)){
  31. let modCandidates = fs.readdirSync(modsDir)
  32. let verCandidates = []
  33. const versionDir = path.join(modsDir, version)
  34. if(fs.existsSync(versionDir)){
  35. verCandidates = fs.readdirSync(versionDir)
  36. }
  37. for(let file of modCandidates){
  38. const match = MOD_REGEX.exec(file)
  39. if(match != null){
  40. modsDiscovered.push({
  41. fullName: match[0],
  42. name: match[1],
  43. ext: match[2],
  44. disabled: match[3] != null
  45. })
  46. }
  47. }
  48. for(let file of verCandidates){
  49. const match = MOD_REGEX.exec(file)
  50. if(match != null){
  51. modsDiscovered.push({
  52. fullName: path.join(version, match[0]),
  53. name: match[1],
  54. ext: match[2],
  55. disabled: match[3] != null
  56. })
  57. }
  58. }
  59. }
  60. return modsDiscovered
  61. }
  62. /**
  63. * Add dropin mods.
  64. *
  65. * @param {FileList} files The files to add.
  66. * @param {string} modsDir The path to the mods directory.
  67. */
  68. exports.addDropinMods = function(files, modsdir) {
  69. for(let f of files) {
  70. if(MOD_REGEX.exec(f.name) != null) {
  71. fs.moveSync(f.path, path.join(modsdir, f.name))
  72. }
  73. }
  74. }
  75. /**
  76. * Delete a drop-in mod from the file system.
  77. *
  78. * @param {string} modsDir The path to the mods directory.
  79. * @param {string} fullName The fullName of the discovered mod to delete.
  80. *
  81. * @returns {boolean} True if the mod was deleted, otherwise false.
  82. */
  83. exports.deleteDropinMod = function(modsDir, fullName){
  84. const res = shell.moveItemToTrash(path.join(modsDir, fullName))
  85. if(!res){
  86. shell.beep()
  87. }
  88. return res
  89. }
  90. /**
  91. * Toggle a discovered mod on or off. This is achieved by either
  92. * adding or disabling the .disabled extension to the local file.
  93. *
  94. * @param {string} modsDir The path to the mods directory.
  95. * @param {string} fullName The fullName of the discovered mod to toggle.
  96. * @param {boolean} enable Whether to toggle on or off the mod.
  97. *
  98. * @returns {Promise.<void>} A promise which resolves when the mod has
  99. * been toggled. If an IO error occurs the promise will be rejected.
  100. */
  101. exports.toggleDropinMod = function(modsDir, fullName, enable){
  102. return new Promise((resolve, reject) => {
  103. const oldPath = path.join(modsDir, fullName)
  104. const newPath = path.join(modsDir, enable ? fullName.substring(0, fullName.indexOf(DISABLED_EXT)) : fullName + DISABLED_EXT)
  105. fs.rename(oldPath, newPath, (err) => {
  106. if(err){
  107. reject(err)
  108. } else {
  109. resolve()
  110. }
  111. })
  112. })
  113. }
  114. /**
  115. * Check if a drop-in mod is enabled.
  116. *
  117. * @param {string} fullName The fullName of the discovered mod to toggle.
  118. * @returns {boolean} True if the mod is enabled, otherwise false.
  119. */
  120. exports.isDropinModEnabled = function(fullName){
  121. return !fullName.endsWith(DISABLED_EXT)
  122. }