dropinmodutil.js 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. exports.validateModsDir(modsdir)
  70. for(let f of files) {
  71. if(MOD_REGEX.exec(f.name) != null) {
  72. fs.moveSync(f.path, path.join(modsdir, f.name))
  73. }
  74. }
  75. }
  76. /**
  77. * Delete a drop-in mod from the file system.
  78. *
  79. * @param {string} modsDir The path to the mods directory.
  80. * @param {string} fullName The fullName of the discovered mod to delete.
  81. *
  82. * @returns {boolean} True if the mod was deleted, otherwise false.
  83. */
  84. exports.deleteDropinMod = function(modsDir, fullName){
  85. const res = shell.moveItemToTrash(path.join(modsDir, fullName))
  86. if(!res){
  87. shell.beep()
  88. }
  89. return res
  90. }
  91. /**
  92. * Toggle a discovered mod on or off. This is achieved by either
  93. * adding or disabling the .disabled extension to the local file.
  94. *
  95. * @param {string} modsDir The path to the mods directory.
  96. * @param {string} fullName The fullName of the discovered mod to toggle.
  97. * @param {boolean} enable Whether to toggle on or off the mod.
  98. *
  99. * @returns {Promise.<void>} A promise which resolves when the mod has
  100. * been toggled. If an IO error occurs the promise will be rejected.
  101. */
  102. exports.toggleDropinMod = function(modsDir, fullName, enable){
  103. return new Promise((resolve, reject) => {
  104. const oldPath = path.join(modsDir, fullName)
  105. const newPath = path.join(modsDir, enable ? fullName.substring(0, fullName.indexOf(DISABLED_EXT)) : fullName + DISABLED_EXT)
  106. fs.rename(oldPath, newPath, (err) => {
  107. if(err){
  108. reject(err)
  109. } else {
  110. resolve()
  111. }
  112. })
  113. })
  114. }
  115. /**
  116. * Check if a drop-in mod is enabled.
  117. *
  118. * @param {string} fullName The fullName of the discovered mod to toggle.
  119. * @returns {boolean} True if the mod is enabled, otherwise false.
  120. */
  121. exports.isDropinModEnabled = function(fullName){
  122. return !fullName.endsWith(DISABLED_EXT)
  123. }