DistributionFactory.ts 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import { Distribution, Server, Module, Type, Required as HeliosRequired } from 'helios-distribution-types'
  2. import { MavenComponents, MavenUtil } from 'common/util/MavenUtil'
  3. import { join } from 'path'
  4. import { LoggerUtil } from 'common/logging/loggerutil'
  5. const logger = LoggerUtil.getLogger('DistributionFactory')
  6. export class HeliosDistribution {
  7. private mainServerIndex!: number
  8. public readonly servers: HeliosServer[]
  9. constructor(
  10. public readonly rawDistribution: Distribution
  11. ) {
  12. this.resolveMainServerIndex()
  13. this.servers = this.rawDistribution.servers.map(s => new HeliosServer(s))
  14. }
  15. private resolveMainServerIndex(): void {
  16. if(this.rawDistribution.servers.length > 0) {
  17. for(let i=0; i<this.rawDistribution.servers.length; i++) {
  18. if(this.mainServerIndex == null) {
  19. if(this.rawDistribution.servers[i].mainServer) {
  20. this.mainServerIndex = i
  21. }
  22. } else {
  23. this.rawDistribution.servers[i].mainServer = false
  24. }
  25. }
  26. if(this.mainServerIndex == null) {
  27. this.mainServerIndex = 0
  28. this.rawDistribution.servers[this.mainServerIndex].mainServer = true
  29. }
  30. } else {
  31. logger.warn('Distribution has 0 configured servers. This doesnt seem right..')
  32. this.mainServerIndex = 0
  33. }
  34. }
  35. public getMainServer(): HeliosServer | null {
  36. return this.mainServerIndex < this.servers.length ? this.servers[this.mainServerIndex] : null
  37. }
  38. public getServerById(id: string): HeliosServer | null {
  39. return this.servers.find(s => s.rawServer.id === id) || null
  40. }
  41. }
  42. export class HeliosServer {
  43. public readonly modules: HeliosModule[]
  44. constructor(
  45. public readonly rawServer: Server
  46. ) {
  47. this.modules = rawServer.modules.map(m => new HeliosModule(m, rawServer.id))
  48. }
  49. }
  50. export class HeliosModule {
  51. public readonly subModules: HeliosModule[]
  52. private readonly mavenComponents: Readonly<MavenComponents>
  53. private readonly required: Readonly<Required<HeliosRequired>>
  54. private readonly localPath: string
  55. constructor(
  56. public readonly rawModule: Module,
  57. private readonly serverId: string
  58. ) {
  59. this.mavenComponents = this.resolveMavenComponents()
  60. this.required = this.resolveRequired()
  61. this.localPath = this.resolveLocalPath()
  62. if(this.rawModule.subModules != null) {
  63. this.subModules = this.rawModule.subModules.map(m => new HeliosModule(m, serverId))
  64. } else {
  65. this.subModules = []
  66. }
  67. }
  68. private resolveMavenComponents(): MavenComponents {
  69. // Files need not have a maven identifier if they provide a path.
  70. if(this.rawModule.type === Type.File && this.rawModule.artifact.path != null) {
  71. return null! as MavenComponents
  72. }
  73. // Version Manifests never provide a maven identifier.
  74. if(this.rawModule.type === Type.VersionManifest) {
  75. return null! as MavenComponents
  76. }
  77. const isMavenId = MavenUtil.isMavenIdentifier(this.rawModule.id)
  78. if(!isMavenId) {
  79. if(this.rawModule.type !== Type.File) {
  80. throw new Error(`Module ${this.rawModule.name} (${this.rawModule.id}) of type ${this.rawModule.type} must have a valid maven identifier!`)
  81. } else {
  82. throw new Error(`Module ${this.rawModule.name} (${this.rawModule.id}) of type ${this.rawModule.type} must either declare an artifact path or have a valid maven identifier!`)
  83. }
  84. }
  85. try {
  86. return MavenUtil.getMavenComponents(this.rawModule.id)
  87. } catch(err) {
  88. throw new Error(`Failed to resolve maven components for module ${this.rawModule.name} (${this.rawModule.id}) of type ${this.rawModule.type}. Reason: ${err.message}`)
  89. }
  90. }
  91. private resolveRequired(): Required<HeliosRequired> {
  92. if(this.rawModule.required == null) {
  93. return {
  94. value: true,
  95. def: true
  96. }
  97. } else {
  98. return {
  99. value: this.rawModule.required.value ?? true,
  100. def: this.rawModule.required.def ?? true
  101. }
  102. }
  103. }
  104. private resolveLocalPath(): string {
  105. // Version Manifests have a pre-determined path.
  106. if(this.rawModule.type === Type.VersionManifest) {
  107. return join('TODO_COMMON_DIR', 'versions', this.rawModule.id, `${this.rawModule.id}.json`)
  108. }
  109. const relativePath = this.rawModule.artifact.path ?? MavenUtil.mavenComponentsAsNormalizedPath(
  110. this.mavenComponents.group,
  111. this.mavenComponents.artifact,
  112. this.mavenComponents.version,
  113. this.mavenComponents.classifier,
  114. this.mavenComponents.extension
  115. )
  116. switch (this.rawModule.type) {
  117. case Type.Library:
  118. case Type.Forge:
  119. case Type.ForgeHosted:
  120. case Type.LiteLoader:
  121. return join('TODO_COMMON_DIR', 'libraries', relativePath)
  122. case Type.ForgeMod:
  123. case Type.LiteMod:
  124. return join('TODO_COMMON_DIR', 'modstore', relativePath)
  125. case Type.File:
  126. default:
  127. return join('TODO_INSTANCE_DIR', this.serverId, relativePath)
  128. }
  129. }
  130. public hasMavenComponents(): boolean {
  131. return this.mavenComponents != null
  132. }
  133. public getMavenComponents(): Readonly<MavenComponents> {
  134. return this.mavenComponents
  135. }
  136. public getRequired(): Readonly<Required<HeliosRequired>> {
  137. return this.required
  138. }
  139. public getPath(): string {
  140. return this.localPath
  141. }
  142. public getMavenIdentifier(): string {
  143. return MavenUtil.mavenComponentsToIdentifier(
  144. this.mavenComponents.group,
  145. this.mavenComponents.artifact,
  146. this.mavenComponents.version,
  147. this.mavenComponents.classifier,
  148. this.mavenComponents.extension
  149. )
  150. }
  151. public getExtensionlessMavenIdentifier(): string {
  152. return MavenUtil.mavenComponentsToExtensionlessIdentifier(
  153. this.mavenComponents.group,
  154. this.mavenComponents.artifact,
  155. this.mavenComponents.version,
  156. this.mavenComponents.classifier
  157. )
  158. }
  159. public getVersionlessMavenIdentifier(): string {
  160. return MavenUtil.mavenComponentsToVersionlessIdentifier(
  161. this.mavenComponents.group,
  162. this.mavenComponents.artifact
  163. )
  164. }
  165. public hasSubModules(): boolean {
  166. return this.subModules.length > 0
  167. }
  168. }