@@ -45,6 +45,8 @@ object ConfigLoader {
4545 .weakKeys()
4646 .build<ClassLoader , TreeNode <List <String >>>()
4747
48+ private val PATCH_FILE_REGEX = " ([^.]+)\\ .patch\\ .([^.]+).*" .toRegex()
49+
4850 private val serverAdventure = try {
4951 Component .text()
5052 true
@@ -366,6 +368,55 @@ object ConfigLoader {
366368 }
367369 }
368370
371+ private fun sortPatches (paths : List <Path >): List <Path > {
372+ data class ResolvedPath (val path : Path ) {
373+ val key: String
374+ var requires: String?
375+
376+ init {
377+ val match = PATCH_FILE_REGEX .matchEntire(path.name)
378+ if (match != null ) {
379+ key = match.groupValues[1 ]
380+ requires = match.groupValues[2 ]
381+ } else {
382+ key = path.name.substringBefore(' .' )
383+ requires = null
384+ }
385+ }
386+ }
387+ val resolved = LinkedList (paths.map { ResolvedPath (it) })
388+ val dependencies = mutableMapOf<String , MutableList <ResolvedPath >>()
389+
390+ for (path in resolved) {
391+ val requires = path.requires
392+ if (requires != null ) {
393+ dependencies.getOrPut(requires) { mutableListOf () }.add(path)
394+ }
395+ }
396+
397+ val result = mutableListOf<Path >()
398+
399+ var lastSize = 0
400+ while (resolved.isNotEmpty()) {
401+ if (lastSize == resolved.size) {
402+ EsuCore .instance.warn(" Failed to resolve graph of patch file ${resolved.map { it.path }} , skipping." )
403+ break
404+ }
405+ lastSize = resolved.size
406+ val iterator = resolved.iterator()
407+ for (path in iterator) {
408+ if (path.requires != null ) continue
409+ dependencies[path.key]?.forEach { dep ->
410+ dep.requires = null
411+ }
412+ result.add(path.path)
413+ iterator.remove()
414+ }
415+ }
416+
417+ return result
418+ }
419+
369420 private fun getLangCache (classLoader : ClassLoader , path : String ): List <LangResource > {
370421 val tree = langCache.getIfPresent(classLoader) ? : let {
371422 val root = TreeNode <List <String >>()
0 commit comments