├── enigma-swing ├── .gitignore └── src │ ├── test │ └── resources │ │ ├── test_mappings │ │ ├── a │ │ │ ├── d.mapping │ │ │ └── b │ │ │ │ ├── c.mapping │ │ │ │ └── c │ │ │ │ ├── a.mapping │ │ │ │ └── b.mapping │ │ ├── b │ │ │ ├── f.mapping │ │ │ └── c │ │ │ │ └── g.mapping │ │ └── e.mapping │ │ └── tinylog.properties │ └── main │ ├── resources │ ├── icon.png │ ├── icons │ │ ├── chevron-up-black.svg │ │ ├── chevron-down-black.svg │ │ ├── chevron-down-white.svg │ │ ├── chevron-up-white.svg │ │ └── pending_status.svg │ └── stats.html │ └── java │ └── org │ └── quiltmc │ └── enigma │ └── gui │ ├── ConnectionState.java │ ├── util │ ├── LanguageChangeListener.java │ ├── ScaleChangeListener.java │ ├── ListUtil.java │ ├── SingleTreeSelectionModel.java │ ├── LanguageUtil.java │ └── History.java │ ├── config │ ├── theme │ │ ├── properties │ │ │ ├── composite │ │ │ │ └── Configurable.java │ │ │ ├── ConfigurableFlatLafThemeProperties.java │ │ │ ├── NonSystemLafThemeProperties.java │ │ │ ├── MetalThemeProperties.java │ │ │ ├── NoneThemeProperties.java │ │ │ ├── AbstractDarculaThemeProperties.java │ │ │ ├── NonConfigurableLafThemeProperties.java │ │ │ ├── DefaultThemeProperties.java │ │ │ ├── ConfigurableLafThemeProperties.java │ │ │ └── SystemThemeProperties.java │ │ └── look_and_feel │ │ │ ├── ConfigurableFlatDarkLaf.java │ │ │ ├── ConfigurableFlatLightLaf.java │ │ │ ├── TrackedSerializableColorGetter.java │ │ │ ├── SerializableColorGetter.java │ │ │ └── HexColorStringGetter.java │ ├── StatsSection.java │ ├── FeaturesSection.java │ ├── ConfigPaths.java │ ├── Decompiler.java │ ├── KeyBindConfig.java │ ├── NetConfig.java │ └── DevSection.java │ ├── BrowserCaret.java │ ├── event │ ├── ConvertingTextFieldListener.java │ └── EditorActionListener.java │ ├── ReadableToken.java │ ├── docker │ ├── AllClassesDocker.java │ ├── DeobfuscatedClassesDocker.java │ ├── ObfuscatedClassesDocker.java │ ├── InheritanceTreeDocker.java │ └── ImplementationsTreeDocker.java │ ├── network │ ├── IntegratedEnigmaServer.java │ └── IntegratedEnigmaClient.java │ ├── warning │ └── WarningType.java │ ├── search │ └── SearchEntry.java │ ├── node │ └── ClassSelectorPackageNode.java │ ├── renderer │ ├── MessageListCellRenderer.java │ ├── StructureOptionListCellRenderer.java │ ├── TokenListCellRenderer.java │ └── ImplementationsTreeCellRenderer.java │ ├── highlight │ └── SelectionHighlightPainter.java │ └── dialog │ └── ChangeDialog.java ├── enigma-cli ├── src │ ├── test │ │ ├── resources │ │ │ ├── drop_invalid_mappings │ │ │ │ ├── expected │ │ │ │ │ ├── EmptyMappings.mapping │ │ │ │ │ ├── DiscardInnerClass.mapping │ │ │ │ │ ├── MappingSave.mapping │ │ │ │ │ ├── Enums.mapping │ │ │ │ │ └── InvalidMappings.mapping │ │ │ │ └── input │ │ │ │ │ ├── DiscardInnerClass.mapping │ │ │ │ │ ├── EmptyMappings.mapping │ │ │ │ │ ├── MappingSave.mapping │ │ │ │ │ ├── Enums.mapping │ │ │ │ │ └── InvalidMappings.mapping │ │ │ ├── fillClassMappings │ │ │ │ ├── d.mapping │ │ │ │ ├── A_Anonymous.mapping │ │ │ │ ├── b.mapping │ │ │ │ ├── c.mapping │ │ │ │ ├── f.mapping │ │ │ │ └── e.mapping │ │ │ ├── packageAccess │ │ │ │ ├── wrongMappings │ │ │ │ │ ├── one │ │ │ │ │ │ └── One.mapping │ │ │ │ │ ├── two │ │ │ │ │ │ └── Two.mapping │ │ │ │ │ └── base │ │ │ │ │ │ └── Base.mapping │ │ │ │ └── correctMappings │ │ │ │ │ ├── base │ │ │ │ │ ├── One.mapping │ │ │ │ │ └── Base.mapping │ │ │ │ │ └── two │ │ │ │ │ └── Two.mapping │ │ │ ├── tinylog-test.properties │ │ │ ├── print_stats │ │ │ │ └── AwesomeClass.mapping │ │ │ └── mapSpecializedMethods │ │ │ │ └── a.mapping │ │ └── java │ │ │ └── org │ │ │ └── quiltmc │ │ │ └── enigma │ │ │ └── command │ │ │ ├── HelpCommandTest.java │ │ │ ├── PrintStatsCommandTest.java │ │ │ ├── CheckMappingsCommandTest.java │ │ │ └── CommandTest.java │ └── main │ │ └── java │ │ └── org │ │ └── quiltmc │ │ └── enigma │ │ └── command │ │ ├── ComposedArgument.java │ │ ├── HelpCommand.java │ │ ├── DeobfuscateCommand.java │ │ └── CommandsUtil.java └── build.gradle ├── enigma └── src │ ├── test │ ├── resources │ │ ├── formats │ │ │ ├── proguard_example_mapping.txt │ │ │ ├── srg_file_example_mapping.tsrg │ │ │ ├── invalid_mapping.garbage │ │ │ ├── enigma_file_example_mapping.mapping │ │ │ ├── enigma_directory_example_mapping │ │ │ │ └── TestClass.mapping │ │ │ ├── tiny_v2_example_mapping.tiny │ │ │ └── enigma_zip_example_mapping.zip │ │ ├── tinyV2InnerClasses │ │ │ └── org │ │ │ │ └── quiltmc │ │ │ │ ├── c.mapping │ │ │ │ └── enigma │ │ │ │ └── Dad.mapping │ │ ├── proguard-bridge-test.conf │ │ ├── proguard-test.conf │ │ ├── proguard-build.conf │ │ ├── proguard-decompiler-test.conf │ │ ├── proguard-similar_class_names-test.conf │ │ ├── proguard-enums-test.conf │ │ ├── comments │ │ │ └── test.mapping │ │ └── translation.mappings │ └── java │ │ └── org │ │ └── quiltmc │ │ └── enigma │ │ ├── input │ │ ├── packages │ │ │ ├── E.java │ │ │ ├── a │ │ │ │ ├── D.java │ │ │ │ └── b │ │ │ │ │ ├── C.java │ │ │ │ │ └── c │ │ │ │ │ ├── A.java │ │ │ │ │ └── B.java │ │ │ └── b │ │ │ │ ├── F.java │ │ │ │ └── c │ │ │ │ └── G.java │ │ ├── records │ │ │ ├── BasicRecord.java │ │ │ ├── BigRecord.java │ │ │ ├── Record2.java │ │ │ ├── NameMismatchRecord.java │ │ │ ├── ConstructorRecord.java │ │ │ └── Record.java │ │ ├── interface_union │ │ │ ├── DInterface.java │ │ │ ├── Union4Class.java │ │ │ ├── AInterface.java │ │ │ ├── BInterface.java │ │ │ ├── Union3Record.java │ │ │ ├── CClass.java │ │ │ ├── Union2Class.java │ │ │ └── Union1Class.java │ │ ├── interfaces │ │ │ ├── Root.java │ │ │ └── Inheritor.java │ │ ├── similar_class_names │ │ │ ├── Alpha.java │ │ │ ├── Caller.java │ │ │ └── Alphabet.java │ │ ├── inner_classes │ │ │ ├── D_Simple.java │ │ │ ├── F_ClassTree.java │ │ │ ├── A_Anonymous.java │ │ │ ├── B_AnonymousWithScopeArgs.java │ │ │ ├── C_ConstructorArgs.java │ │ │ ├── NestedLambdas.java │ │ │ └── E_AnonymousWithOuterAccess.java │ │ ├── package_access │ │ │ ├── Base.java │ │ │ ├── SamePackageChild.java │ │ │ └── sub │ │ │ │ └── OtherPackageChild.java │ │ ├── constructors │ │ │ ├── DefaultConstructable.java │ │ │ ├── SubSubClass.java │ │ │ ├── BaseClass.java │ │ │ ├── SubClass.java │ │ │ └── Caller.java │ │ ├── Keep.java │ │ ├── enums │ │ │ ├── TestEnum.java │ │ │ └── Color.java │ │ ├── translation │ │ │ ├── B_BaseClass.java │ │ │ ├── C_SubClass.java │ │ │ ├── A_Basic.java │ │ │ ├── F_ObjectMethods.java │ │ │ ├── D_AnonymousTesting.java │ │ │ ├── E_Bridges.java │ │ │ ├── G_OuterClass.java │ │ │ ├── I_Generics.java │ │ │ └── H_NamelessClass.java │ │ ├── decompiler │ │ │ └── TestVarargsDecompile.java │ │ ├── lone_class │ │ │ └── LoneClass.java │ │ ├── inheritance_tree │ │ │ ├── SubclassA.java │ │ │ ├── BaseClass.java │ │ │ ├── SubsubclassAA.java │ │ │ └── SubclassB.java │ │ ├── bridge │ │ │ ├── OtherClass.java │ │ │ ├── BaseClass.java │ │ │ └── SubClass.java │ │ ├── validation │ │ │ ├── SuperClass.java │ │ │ └── BaseClass.java │ │ └── lambdas │ │ │ └── Lambdas.java │ │ ├── translation │ │ └── mapping │ │ │ ├── TestTinyV2InnerClasses.java │ │ │ ├── TestV2Main.java │ │ │ └── TestComments.java │ │ ├── TestDeobfuscator.java │ │ └── TestEntryOrdering.java │ ├── main │ ├── resources │ │ ├── META-INF │ │ │ └── services │ │ │ │ └── org.quiltmc.enigma.api.EnigmaPlugin │ │ ├── tinylog.properties │ │ └── profile.json │ └── java │ │ └── org │ │ └── quiltmc │ │ └── enigma │ │ ├── api │ │ ├── source │ │ │ ├── SourceSettings.java │ │ │ ├── Source.java │ │ │ ├── Decompiler.java │ │ │ ├── TokenType.java │ │ │ ├── Decompilers.java │ │ │ └── Token.java │ │ ├── translation │ │ │ ├── mapping │ │ │ │ ├── ResolutionStrategy.java │ │ │ │ ├── serde │ │ │ │ │ ├── enigma │ │ │ │ │ │ └── EnigmaFormat.java │ │ │ │ │ ├── MappingsReader.java │ │ │ │ │ ├── MappingFileNameFormat.java │ │ │ │ │ ├── MappingParseException.java │ │ │ │ │ └── FileType.java │ │ │ │ ├── MappingPair.java │ │ │ │ ├── EntryMap.java │ │ │ │ ├── VoidEntryResolver.java │ │ │ │ └── tree │ │ │ │ │ ├── EntryTreeNode.java │ │ │ │ │ ├── EntryTreeUtil.java │ │ │ │ │ └── EntryTree.java │ │ │ ├── representation │ │ │ │ ├── entry │ │ │ │ │ └── DefEntry.java │ │ │ │ ├── ParameterAccessFlags.java │ │ │ │ └── ArgumentDescriptor.java │ │ │ ├── VoidTranslator.java │ │ │ ├── Translatable.java │ │ │ └── MappingTranslator.java │ │ ├── service │ │ │ ├── EnigmaServiceFactory.java │ │ │ ├── ObfuscationTestService.java │ │ │ ├── DecompilerService.java │ │ │ ├── EnigmaService.java │ │ │ ├── EnigmaServiceContext.java │ │ │ └── EnigmaServiceType.java │ │ ├── EnigmaPlugin.java │ │ ├── EnigmaPluginContext.java │ │ ├── analysis │ │ │ ├── tree │ │ │ │ ├── ReferenceTreeNode.java │ │ │ │ ├── AbstractMethodTreeNode.java │ │ │ │ └── AbstractClassTreeNode.java │ │ │ └── index │ │ │ │ └── jar │ │ │ │ ├── EnclosingMethodIndex.java │ │ │ │ ├── LibrariesJarIndex.java │ │ │ │ ├── MainJarIndex.java │ │ │ │ └── JarIndex.java │ │ ├── stats │ │ │ └── StatType.java │ │ ├── EnigmaServices.java │ │ ├── class_provider │ │ │ ├── ClasspathClassProvider.java │ │ │ ├── CombiningClassProvider.java │ │ │ └── CachingClassProvider.java │ │ ├── class_handle │ │ │ └── ClassHandleError.java │ │ └── event │ │ │ └── ClassHandleListener.java │ │ ├── impl │ │ ├── source │ │ │ ├── bytecode │ │ │ │ ├── BytecodeSourceIndex.java │ │ │ │ ├── BytecodeClassEntry.java │ │ │ │ └── BytecodeDecompiler.java │ │ │ ├── vineflower │ │ │ │ ├── VineflowerDecompiler.java │ │ │ │ ├── EnigmaFernflowerLogger.java │ │ │ │ └── EnigmaResultSaver.java │ │ │ └── procyon │ │ │ │ ├── transformer │ │ │ │ ├── InvalidIdentifierFix.java │ │ │ │ ├── DropImportAstTransform.java │ │ │ │ └── RemoveObjectCasts.java │ │ │ │ └── index │ │ │ │ └── SourceIndexVisitor.java │ │ ├── translation │ │ │ └── mapping │ │ │ │ └── serde │ │ │ │ ├── LfPrintWriter.java │ │ │ │ ├── RawEntryMapping.java │ │ │ │ └── MappingHelper.java │ │ ├── analysis │ │ │ ├── MethodNodeWithAction.java │ │ │ ├── Access.java │ │ │ └── ClassLoaderClassProvider.java │ │ └── bytecode │ │ │ └── translator │ │ │ ├── TranslationRecordComponentVisitor.java │ │ │ └── TranslationFieldVisitor.java │ │ └── util │ │ ├── Pair.java │ │ ├── AsmUtil.java │ │ ├── Os.java │ │ ├── validation │ │ ├── ParameterizedMessage.java │ │ ├── StandardValidation.java │ │ └── PrintNotifier.java │ │ └── EntryTreePrinter.java │ └── testFixtures │ ├── resources │ ├── META-INF │ │ └── services │ │ │ └── org.quiltmc.enigma.api.EnigmaPlugin │ └── profile.json │ └── java │ └── org │ └── quiltmc │ └── enigma │ └── TestUtil.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── .gitattributes ├── enigma-server ├── src │ ├── main │ │ └── java │ │ │ └── org │ │ │ └── quiltmc │ │ │ └── enigma │ │ │ └── network │ │ │ ├── packet │ │ │ ├── Packet.java │ │ │ ├── c2s │ │ │ │ ├── ConfirmChangeC2SPacket.java │ │ │ │ └── MessageC2SPacket.java │ │ │ └── s2c │ │ │ │ ├── MessageS2CPacket.java │ │ │ │ ├── KickS2CPacket.java │ │ │ │ ├── EntryChangeS2CPacket.java │ │ │ │ └── UserListS2CPacket.java │ │ │ ├── ServerPacketHandler.java │ │ │ └── ClientPacketHandler.java │ └── test │ │ └── java │ │ └── org │ │ └── quiltmc │ │ └── enigma │ │ └── network │ │ ├── TestEnigmaClient.java │ │ ├── ServerAddressTest.java │ │ └── DummyClientPacketHandler.java └── build.gradle ├── .gitignore ├── .github └── workflows │ ├── release.yml │ └── build.yml ├── .editorconfig ├── config └── checkstyle │ └── suppressions.xml ├── COPYING.md └── README.md /enigma-swing/.gitignore: -------------------------------------------------------------------------------- 1 | mappings/ 2 | -------------------------------------------------------------------------------- /enigma-swing/src/test/resources/test_mappings/a/d.mapping: -------------------------------------------------------------------------------- 1 | CLASS d a/D 2 | -------------------------------------------------------------------------------- /enigma-swing/src/test/resources/test_mappings/b/f.mapping: -------------------------------------------------------------------------------- 1 | CLASS f b/F 2 | -------------------------------------------------------------------------------- /enigma-swing/src/test/resources/test_mappings/a/b/c.mapping: -------------------------------------------------------------------------------- 1 | CLASS c a/b/C 2 | -------------------------------------------------------------------------------- /enigma-swing/src/test/resources/test_mappings/b/c/g.mapping: -------------------------------------------------------------------------------- 1 | CLASS g b/c/G 2 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/drop_invalid_mappings/expected/EmptyMappings.mapping: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /enigma-swing/src/test/resources/test_mappings/a/b/c/a.mapping: -------------------------------------------------------------------------------- 1 | CLASS a a/b/c/A 2 | -------------------------------------------------------------------------------- /enigma-swing/src/test/resources/test_mappings/a/b/c/b.mapping: -------------------------------------------------------------------------------- 1 | CLASS b a/b/c/B 2 | -------------------------------------------------------------------------------- /enigma/src/test/resources/formats/proguard_example_mapping.txt: -------------------------------------------------------------------------------- 1 | a -> TestClass: 2 | -------------------------------------------------------------------------------- /enigma/src/test/resources/formats/srg_file_example_mapping.tsrg: -------------------------------------------------------------------------------- 1 | a TestClass 2 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/fillClassMappings/d.mapping: -------------------------------------------------------------------------------- 1 | CLASS d 2 | CLASS a Inner 3 | -------------------------------------------------------------------------------- /enigma-swing/src/test/resources/test_mappings/e.mapping: -------------------------------------------------------------------------------- 1 | CLASS e E 2 | COMMENT a 3 | -------------------------------------------------------------------------------- /enigma/src/test/resources/formats/invalid_mapping.garbage: -------------------------------------------------------------------------------- 1 | hjgjghjkkghjggukuyyuiloyu 2 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/fillClassMappings/A_Anonymous.mapping: -------------------------------------------------------------------------------- 1 | CLASS a A_Anonymous 2 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/packageAccess/wrongMappings/one/One.mapping: -------------------------------------------------------------------------------- 1 | CLASS b one/One 2 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/packageAccess/wrongMappings/two/Two.mapping: -------------------------------------------------------------------------------- 1 | CLASS c two/Two 2 | -------------------------------------------------------------------------------- /enigma/src/test/resources/formats/enigma_file_example_mapping.mapping: -------------------------------------------------------------------------------- 1 | CLASS a TestClass 2 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/fillClassMappings/b.mapping: -------------------------------------------------------------------------------- 1 | CLASS b 2 | METHOD a foo (Ld;)V 3 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/packageAccess/correctMappings/base/One.mapping: -------------------------------------------------------------------------------- 1 | CLASS b base/One 2 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/packageAccess/correctMappings/two/Two.mapping: -------------------------------------------------------------------------------- 1 | CLASS c two/Two 2 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/packageAccess/wrongMappings/base/Base.mapping: -------------------------------------------------------------------------------- 1 | CLASS a base/Base 2 | -------------------------------------------------------------------------------- /enigma/src/test/resources/tinyV2InnerClasses/org/quiltmc/c.mapping: -------------------------------------------------------------------------------- 1 | CLASS c 2 | CLASS a Kid 3 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/fillClassMappings/c.mapping: -------------------------------------------------------------------------------- 1 | CLASS c 2 | CLASS a 3 | FIELD a a I 4 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/fillClassMappings/f.mapping: -------------------------------------------------------------------------------- 1 | CLASS f 2 | CLASS a 3 | CLASS a Level2 4 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/packageAccess/correctMappings/base/Base.mapping: -------------------------------------------------------------------------------- 1 | CLASS a base/Base 2 | -------------------------------------------------------------------------------- /enigma/src/test/resources/formats/enigma_directory_example_mapping/TestClass.mapping: -------------------------------------------------------------------------------- 1 | CLASS a TestClass 2 | -------------------------------------------------------------------------------- /enigma/src/test/resources/formats/tiny_v2_example_mapping.tiny: -------------------------------------------------------------------------------- 1 | tiny 2 0 intermediary named 2 | c a TestClass 3 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/fillClassMappings/e.mapping: -------------------------------------------------------------------------------- 1 | CLASS e 2 | METHOD a outerMethod ()Ljava/lang/String; 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrnitheMC/enigma/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include 'enigma' 2 | include 'enigma-swing' 3 | include 'enigma-server' 4 | include 'enigma-cli' 5 | -------------------------------------------------------------------------------- /enigma/src/main/resources/META-INF/services/org.quiltmc.enigma.api.EnigmaPlugin: -------------------------------------------------------------------------------- 1 | org.quiltmc.enigma.impl.plugin.BuiltinPlugin 2 | -------------------------------------------------------------------------------- /enigma-swing/src/main/resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrnitheMC/enigma/HEAD/enigma-swing/src/main/resources/icon.png -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/packages/E.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.packages; 2 | 3 | public class E { 4 | } 5 | -------------------------------------------------------------------------------- /enigma/src/testFixtures/resources/META-INF/services/org.quiltmc.enigma.api.EnigmaPlugin: -------------------------------------------------------------------------------- 1 | org.quiltmc.enigma.test.plugin.TestEnigmaPlugin 2 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/drop_invalid_mappings/expected/DiscardInnerClass.mapping: -------------------------------------------------------------------------------- 1 | CLASS f 2 | CLASS a 3 | CLASS a 4 | FIELD a q I 5 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/drop_invalid_mappings/expected/MappingSave.mapping: -------------------------------------------------------------------------------- 1 | CLASS c 2 | CLASS a 3 | METHOD (Lc;I)V 4 | ARG 2 x 5 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/packages/a/D.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.packages.a; 2 | 3 | public class D { 4 | } 5 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/packages/a/b/C.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.packages.a.b; 2 | 3 | public class C { 4 | } 5 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/packages/b/F.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.packages.b; 2 | 3 | public class F { 4 | } 5 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/packages/b/c/G.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.packages.b.c; 2 | 3 | public class G { 4 | } 5 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/packages/a/b/c/A.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.packages.a.b.c; 2 | 3 | public class A { 4 | } 5 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/packages/a/b/c/B.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.packages.a.b.c; 2 | 3 | public class B { 4 | } 5 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/records/BasicRecord.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.records; 2 | 3 | public record BasicRecord(int a) { 4 | } 5 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/drop_invalid_mappings/input/DiscardInnerClass.mapping: -------------------------------------------------------------------------------- 1 | CLASS f 2 | CLASS a 3 | CLASS a 4 | FIELD a q I 5 | CLASS a 6 | FIELD a I 7 | -------------------------------------------------------------------------------- /enigma/src/test/resources/formats/enigma_zip_example_mapping.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OrnitheMC/enigma/HEAD/enigma/src/test/resources/formats/enigma_zip_example_mapping.zip -------------------------------------------------------------------------------- /enigma/src/test/resources/tinyV2InnerClasses/org/quiltmc/enigma/Dad.mapping: -------------------------------------------------------------------------------- 1 | CLASS f org/quiltmc/enigma/Dad 2 | CLASS a One 3 | CLASS a Two 4 | CLASS a 5 | FIELD a value I 6 | -------------------------------------------------------------------------------- /enigma-cli/src/main/java/org/quiltmc/enigma/command/ComposedArgument.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.command; 2 | 3 | public record ComposedArgument(Argument argument, boolean optional) { 4 | } 5 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/drop_invalid_mappings/expected/Enums.mapping: -------------------------------------------------------------------------------- 1 | CLASS a Gaming 2 | FIELD a wawa I 3 | METHOD (Ljava/lang/String;II)V 4 | ARG 3 wawa 5 | METHOD a wawa ()I 6 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/interface_union/DInterface.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.interface_union; 2 | 3 | public interface DInterface { 4 | float factor(); 5 | } 6 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/interfaces/Root.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.interfaces; 2 | 3 | public interface Root { 4 | int a(); 5 | 6 | double b(double c); 7 | } 8 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/similar_class_names/Alpha.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.similar_class_names; 2 | 3 | public interface Alpha { 4 | char get(int n); 5 | } 6 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/ConnectionState.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui; 2 | 3 | public enum ConnectionState { 4 | NOT_CONNECTED, 5 | HOSTING, 6 | CONNECTED, 7 | } 8 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/util/LanguageChangeListener.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.util; 2 | 3 | public interface LanguageChangeListener { 4 | void retranslateUi(); 5 | } 6 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/records/BigRecord.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.records; 2 | 3 | public record BigRecord(double a, int b, long c, String d, float e, char f) { 4 | } 5 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/drop_invalid_mappings/input/EmptyMappings.mapping: -------------------------------------------------------------------------------- 1 | CLASS a 2 | FIELD a Ljava/lang/String; 3 | METHOD (Ljava/lang/String;)V 4 | ARG 1 5 | METHOD a ()Ljava/lang/String; 6 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/tinylog-test.properties: -------------------------------------------------------------------------------- 1 | writingthread = true 2 | 3 | writerConsole = console 4 | writerConsole.format = {date: HH:mm:ss.SSS} [{level}]: {message} 5 | writerConsole.level = debug 6 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/source/SourceSettings.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.source; 2 | 3 | public record SourceSettings(boolean removeImports, boolean removeVariableFinal) { 4 | } 5 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inner_classes/D_Simple.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inner_classes; 2 | 3 | public class D_Simple { 4 | class Inner { 5 | // nothing to do 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/package_access/Base.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.package_access; 2 | 3 | public class Base { 4 | protected int make() { 5 | return 42; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/constructors/DefaultConstructable.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.constructors; 2 | 3 | public class DefaultConstructable { 4 | // only default constructor 5 | } 6 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/drop_invalid_mappings/input/MappingSave.mapping: -------------------------------------------------------------------------------- 1 | CLASS c 2 | METHOD a ()V 3 | ARG 34 invalid 4 | ARG 23423 invalid 5 | CLASS a 6 | FIELD a I 7 | METHOD (Lc;I)V 8 | ARG 2 x 9 | -------------------------------------------------------------------------------- /enigma/src/test/resources/proguard-bridge-test.conf: -------------------------------------------------------------------------------- 1 | -repackageclasses 2 | -allowaccessmodification 3 | -dontoptimize 4 | -dontshrink 5 | -keepparameternames 6 | -keepattributes 7 | -keep class org.quiltmc.enigma.input.Keep 8 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/print_stats/AwesomeClass.mapping: -------------------------------------------------------------------------------- 1 | CLASS a AwesomeClass 2 | FIELD a gaming Ljava/lang/String; 3 | METHOD (Ljava/lang/String;)V 4 | ARG 1 gaming 5 | METHOD a getGaming ()Ljava/lang/String; 6 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/ResolutionStrategy.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping; 2 | 3 | public enum ResolutionStrategy { 4 | RESOLVE_ROOT, 5 | RESOLVE_CLOSEST 6 | } 7 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/properties/composite/Configurable.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.properties.composite; 2 | 3 | public interface Configurable { 4 | void configure(); 5 | } 6 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/similar_class_names/Caller.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.similar_class_names; 2 | 3 | public class Caller { 4 | public void call() { 5 | new Alphabet.Inner().get(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/mapSpecializedMethods/a.mapping: -------------------------------------------------------------------------------- 1 | CLASS a 2 | METHOD a foo (I)La; 3 | METHOD a foo (II)La; 4 | METHOD b bar (I)La; 5 | METHOD b baz (II)La; 6 | METHOD c baz (I)La; 7 | METHOD d foo ()La; 8 | METHOD e bar ()La; 9 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/service/EnigmaServiceFactory.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.service; 2 | 3 | public interface EnigmaServiceFactory { 4 | T create(EnigmaServiceContext ctx); 5 | } 6 | -------------------------------------------------------------------------------- /enigma/src/test/resources/proguard-test.conf: -------------------------------------------------------------------------------- 1 | -overloadaggressively 2 | -repackageclasses 3 | -allowaccessmodification 4 | -dontoptimize 5 | -dontshrink 6 | -keepparameternames 7 | -keepattributes 8 | -keep class org.quiltmc.enigma.input.Keep 9 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/Keep.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input; 2 | 3 | public class Keep { 4 | // a([Ljava/lang/String;)V 5 | public static void main(String... args) { 6 | System.out.println("Keep me!"); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/records/Record2.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.records; 2 | 3 | public record Record2(String a) { 4 | @Override 5 | public boolean equals(Object obj) { 6 | return obj == this; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/drop_invalid_mappings/input/Enums.mapping: -------------------------------------------------------------------------------- 1 | CLASS a Gaming 2 | FIELD a wawa I 3 | METHOD (Ljava/lang/String;II)V 4 | ARG 3 wawa 5 | METHOD a wawa ()I 6 | METHOD valueOf (Ljava/lang/String;)La; 7 | ARG 0 name 8 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/util/ScaleChangeListener.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.util; 2 | 3 | @FunctionalInterface 4 | public interface ScaleChangeListener { 5 | void onScaleChanged(float scale, float oldScale); 6 | } 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # 2 | # https://help.github.com/articles/dealing-with-line-endings/ 3 | # 4 | # Linux start script should use lf 5 | /gradlew text eol=lf 6 | 7 | # These are Windows script files and should use crlf 8 | *.bat text eol=crlf 9 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/interface_union/Union4Class.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.interface_union; 2 | 3 | public class Union4Class extends CClass implements DInterface { 4 | // DInterface.factor() implemented in CClass 5 | } 6 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/drop_invalid_mappings/expected/InvalidMappings.mapping: -------------------------------------------------------------------------------- 1 | CLASS a InvalidMappings 2 | FIELD a slayField Ljava/lang/String; 3 | METHOD (Ljava/lang/String;)V 4 | ARG 1 coolParameter 5 | METHOD a slayMethod ()Ljava/lang/String; 6 | -------------------------------------------------------------------------------- /enigma/src/test/resources/proguard-build.conf: -------------------------------------------------------------------------------- 1 | -dontoptimize 2 | -dontobfuscate 3 | -dontwarn 4 | -keep class org.quiltmc.enigma.Main { static void main(java.lang.String[]); } 5 | -keep class org.quiltmc.enigma.command.Main { static void main(java.lang.String[]); } 6 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/enums/TestEnum.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.enums; 2 | 3 | public enum TestEnum { 4 | One, 5 | Two, 6 | Three, 7 | Four, 8 | Five, 9 | Six, 10 | Seven, 11 | Eight, 12 | Nine, 13 | Ten; 14 | } 15 | -------------------------------------------------------------------------------- /enigma/src/test/resources/proguard-decompiler-test.conf: -------------------------------------------------------------------------------- 1 | -overloadaggressively 2 | -repackageclasses 3 | -allowaccessmodification 4 | -dontoptimize 5 | -dontshrink 6 | -keepparameternames 7 | -keepattributes 8 | -applymapping mappings-decompiler.txt 9 | -keep class org.quiltmc.enigma.input.Keep 10 | -------------------------------------------------------------------------------- /enigma-swing/src/main/resources/icons/chevron-up-black.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/constructors/SubSubClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.constructors; 2 | 3 | // e extends d 4 | public class SubSubClass extends SubClass { 5 | // (I)V 6 | public SubSubClass(int i) { 7 | // c.(I)V 8 | super(i); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/interface_union/AInterface.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.interface_union; 2 | 3 | public interface AInterface { 4 | int methodA(); 5 | 6 | // BInterface -> Union1Class 7 | void methodFoo(); 8 | 9 | // -> Union3Record 10 | double baz(); 11 | } 12 | -------------------------------------------------------------------------------- /enigma/src/test/resources/proguard-similar_class_names-test.conf: -------------------------------------------------------------------------------- 1 | -repackageclasses 2 | -allowaccessmodification 3 | -dontoptimize 4 | -dontshrink 5 | -keepparameternames 6 | -keepattributes 7 | -keep class org.quiltmc.enigma.input.Keep 8 | -keep class org.quiltmc.enigma.input.similar_class_names.* 9 | 10 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /enigma-swing/src/main/resources/icons/chevron-down-black.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /enigma-swing/src/main/resources/icons/chevron-down-white.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /enigma-swing/src/main/resources/icons/chevron-up-white.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/source/bytecode/BytecodeSourceIndex.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.source.bytecode; 2 | 3 | import org.quiltmc.enigma.api.source.SourceIndex; 4 | 5 | class BytecodeSourceIndex extends SourceIndex { 6 | BytecodeSourceIndex() { 7 | super(false); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/translation/B_BaseClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.translation; 2 | 3 | public class B_BaseClass { 4 | public int f1; 5 | public char f2; 6 | 7 | public int m1() { 8 | return 5; 9 | } 10 | 11 | public int m2() { 12 | return 42; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /enigma-server/src/main/java/org/quiltmc/enigma/network/packet/Packet.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network.packet; 2 | 3 | import java.io.DataOutput; 4 | import java.io.IOException; 5 | 6 | public interface Packet { 7 | void write(DataOutput output) throws IOException; 8 | 9 | void handle(H handler); 10 | } 11 | -------------------------------------------------------------------------------- /enigma-cli/src/test/java/org/quiltmc/enigma/command/HelpCommandTest.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.command; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | public class HelpCommandTest { 6 | @Test 7 | void test() throws Exception { 8 | // for manually verifying output 9 | new HelpCommand().run(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/decompiler/TestVarargsDecompile.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.decompiler; 2 | 3 | import org.quiltmc.enigma.input.Keep; 4 | 5 | // b 6 | public class TestVarargsDecompile { 7 | // a()V 8 | public void useVarargs() { 9 | Keep.main("Lorem", "ipsum"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/interface_union/BInterface.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.interface_union; 2 | 3 | public interface BInterface { 4 | // AInterface -> Union1Class 5 | void methodFoo(); 6 | 7 | double methodB(); 8 | 9 | // CClass -> Union2Class 10 | boolean methodBar(); 11 | } 12 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/interfaces/Inheritor.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.interfaces; 2 | 3 | public class Inheritor implements Root { 4 | @Override 5 | public int a() { 6 | return 23; 7 | } 8 | 9 | @Override 10 | public double b(double c) { 11 | return c + 100d; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/source/Source.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.source; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.EntryRemapper; 4 | 5 | public interface Source { 6 | String asString(); 7 | 8 | Source withJavadocs(EntryRemapper remapper); 9 | 10 | SourceIndex index(); 11 | } 12 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/lone_class/LoneClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.lone_class; 2 | 3 | public class LoneClass { 4 | private String name; 5 | 6 | public LoneClass(String name) { 7 | this.name = name; 8 | } 9 | 10 | public String getName() { 11 | return this.name; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/representation/entry/DefEntry.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.representation.entry; 2 | 3 | import org.quiltmc.enigma.api.translation.representation.AccessFlags; 4 | 5 | public interface DefEntry

> extends Entry

{ 6 | AccessFlags getAccess(); 7 | } 8 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/package_access/SamePackageChild.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.package_access; 2 | 3 | public class SamePackageChild extends Base { 4 | class Inner { 5 | final int value; 6 | 7 | Inner() { 8 | this.value = SamePackageChild.this.make(); // no synthetic method 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/util/ListUtil.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.util; 2 | 3 | import java.util.List; 4 | 5 | public final class ListUtil { 6 | private ListUtil() { } 7 | 8 | public static > L prepend(T first, L list) { 9 | list.add(0, first); 10 | 11 | return list; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inner_classes/F_ClassTree.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inner_classes; 2 | 3 | public class F_ClassTree { 4 | public class Level1 { 5 | public int f1; 6 | 7 | public class Level2 { 8 | public int f2; 9 | 10 | public class Level3 { 11 | public int f3; 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inheritance_tree/SubclassA.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inheritance_tree; 2 | 3 | // b extends a 4 | public abstract class SubclassA extends BaseClass { 5 | // (Ljava/lang/String;)V 6 | protected SubclassA(String name) { 7 | // call to a.(Ljava/lang/String)V 8 | super(name); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/records/NameMismatchRecord.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.records; 2 | 3 | public record NameMismatchRecord(int i) { 4 | public int a() { 5 | return 103; 6 | } 7 | 8 | // obfuscates to b(), mismatching with the record component name 9 | @Override 10 | public int i() { 11 | return this.i; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/interface_union/Union3Record.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.interface_union; 2 | 3 | public record Union3Record(double baz) implements AInterface { 4 | @Override 5 | public int methodA() { 6 | return -1; 7 | } 8 | 9 | @Override 10 | public void methodFoo() { 11 | } 12 | 13 | // AInterface -> baz() 14 | } 15 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/similar_class_names/Alphabet.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.similar_class_names; 2 | 3 | public class Alphabet { 4 | public static class Inner { 5 | public Alpha get() { 6 | return new Alpha() { 7 | @Override 8 | public char get(int n) { 9 | return 0; 10 | } 11 | }; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/VoidTranslator.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation; 2 | 3 | public enum VoidTranslator implements Translator { 4 | INSTANCE; 5 | 6 | @Override 7 | public TranslateResult extendedTranslate(T translatable) { 8 | return TranslateResult.obfuscated(translatable); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/BrowserCaret.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui; 2 | 3 | import javax.swing.text.DefaultCaret; 4 | 5 | public class BrowserCaret extends DefaultCaret { 6 | @Override 7 | public boolean isSelectionVisible() { 8 | return true; 9 | } 10 | 11 | @Override 12 | public boolean isVisible() { 13 | return true; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/constructors/BaseClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.constructors; 2 | 3 | // a 4 | public class BaseClass { 5 | // ()V 6 | public BaseClass() { 7 | System.out.println("Default constructor"); 8 | } 9 | 10 | // (I)V 11 | public BaseClass(int i) { 12 | System.out.println("Int constructor " + i); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inner_classes/A_Anonymous.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inner_classes; 2 | 3 | @SuppressWarnings("Convert2Lambda") 4 | public class A_Anonymous { 5 | public void foo() { 6 | Runnable runnable = new Runnable() { 7 | @Override 8 | public void run() { 9 | // don't care 10 | } 11 | }; 12 | runnable.run(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inner_classes/B_AnonymousWithScopeArgs.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inner_classes; 2 | 3 | public class B_AnonymousWithScopeArgs { 4 | public static void foo(final D_Simple arg) { 5 | System.out.println(new Object() { 6 | @Override 7 | public String toString() { 8 | return arg.toString(); 9 | } 10 | }); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/translation/C_SubClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.translation; 2 | 3 | public class C_SubClass extends B_BaseClass { 4 | public char f2; // shadows B_BaseClass.f2 5 | public int f3; 6 | public int f4; 7 | 8 | @Override 9 | public int m1() { 10 | return 32; 11 | } 12 | 13 | public int m3() { 14 | return 7; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inner_classes/C_ConstructorArgs.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inner_classes; 2 | 3 | @SuppressWarnings("unused") 4 | public class C_ConstructorArgs { 5 | Inner i; 6 | 7 | public void foo() { 8 | this.i = new Inner(5); 9 | } 10 | 11 | class Inner { 12 | private int a; 13 | 14 | Inner(int a) { 15 | this.a = a; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /enigma/src/test/resources/proguard-enums-test.conf: -------------------------------------------------------------------------------- 1 | -overloadaggressively 2 | -repackageclasses 3 | -allowaccessmodification 4 | -dontoptimize 5 | -dontshrink 6 | -keepparameternames 7 | -keepattributes 8 | -keep class org.quiltmc.enigma.input.Keep 9 | -keepclassmembers enum org.quiltmc.enigma.input.enums.Color { 10 | public static **[] values(); 11 | public static ** valueOf(java.lang.String); 12 | } 13 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/interface_union/CClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.interface_union; 2 | 3 | import java.util.Random; 4 | 5 | public class CClass { 6 | // BInterface -> Union2Class 7 | public boolean methodBar() { 8 | return true; 9 | } 10 | 11 | // DInterface -> Union4Class 12 | public float factor() { 13 | return (float) new Random().nextGaussian(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/EnigmaPlugin.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api; 2 | 3 | /** 4 | * An enigma plugin represents a collection of {@link org.quiltmc.enigma.api.service.EnigmaService services} that perform different functions. 5 | */ 6 | public interface EnigmaPlugin { 7 | /** 8 | * Initializes the plugin, registering all services. 9 | */ 10 | void init(EnigmaPluginContext ctx); 11 | } 12 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/package_access/sub/OtherPackageChild.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.package_access.sub; 2 | 3 | import org.quiltmc.enigma.input.package_access.Base; 4 | 5 | public class OtherPackageChild extends Base { 6 | class Inner { 7 | final int value; 8 | 9 | Inner() { 10 | this.value = OtherPackageChild.this.make(); // synthetic method call 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/util/SingleTreeSelectionModel.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.util; 2 | 3 | import javax.swing.tree.DefaultTreeSelectionModel; 4 | import javax.swing.tree.TreeSelectionModel; 5 | 6 | public class SingleTreeSelectionModel extends DefaultTreeSelectionModel { 7 | public SingleTreeSelectionModel() { 8 | this.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /enigma-swing/src/main/resources/icons/pending_status.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/records/ConstructorRecord.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.records; 2 | 3 | public record ConstructorRecord(String a, String b, int c, double d) { 4 | private static final int gaming = 234; 5 | 6 | public ConstructorRecord(String a, String b, double d, int c) { 7 | this(a, b, c, d); 8 | } 9 | 10 | public ConstructorRecord(String b) { 11 | this("gaming", b, 1, 2.0); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/EnigmaPluginContext.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api; 2 | 3 | import org.quiltmc.enigma.api.service.EnigmaService; 4 | import org.quiltmc.enigma.api.service.EnigmaServiceFactory; 5 | import org.quiltmc.enigma.api.service.EnigmaServiceType; 6 | 7 | public interface EnigmaPluginContext { 8 | void registerService(EnigmaServiceType serviceType, EnigmaServiceFactory factory); 9 | } 10 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/source/Decompiler.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.source; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.EntryRemapper; 4 | 5 | import javax.annotation.Nullable; 6 | 7 | public interface Decompiler { 8 | default Source getUndocumentedSource(String className) { 9 | return this.getSource(className, null); 10 | } 11 | 12 | Source getSource(String className, @Nullable EntryRemapper remapper); 13 | } 14 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/translation/mapping/serde/LfPrintWriter.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.translation.mapping.serde; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.Writer; 5 | 6 | public class LfPrintWriter extends PrintWriter { 7 | public LfPrintWriter(Writer out) { 8 | super(out); 9 | } 10 | 11 | @Override 12 | public void println() { 13 | // https://stackoverflow.com/a/14749004 14 | this.write('\n'); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /enigma-cli/src/test/resources/drop_invalid_mappings/input/InvalidMappings.mapping: -------------------------------------------------------------------------------- 1 | CLASS a InvalidMappings 2 | FIELD a slayField Ljava/lang/String; 3 | FIELD b fakeField I 4 | METHOD (Ljava/lang/String;)V 5 | ARG 0 outOfBoundsParameter1 6 | ARG 1 coolParameter 7 | ARG 2 outOfBoundsParameter2 8 | ARG 3 outOfBoundsParameter3 9 | METHOD a slayMethod ()Ljava/lang/String; 10 | ARG 1 fakeParameter 11 | METHOD b fakeMethod ()V 12 | CLASS b NonExistentClass 13 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/translation/A_Basic.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.translation; 2 | 3 | public class A_Basic { 4 | public int one; 5 | public float two; 6 | public String three; 7 | 8 | public void m1() { 9 | } 10 | 11 | public int m2() { 12 | return 42; 13 | } 14 | 15 | public void m3(int a1) { 16 | } 17 | 18 | public int m4(int a1) { 19 | return 5; // chosen by fair die roll, guaranteed to be random 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/translation/F_ObjectMethods.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.translation; 2 | 3 | @SuppressWarnings("FinalizeCalledExplicitly") 4 | public class F_ObjectMethods { 5 | public void callEmAll() 6 | throws Throwable { 7 | clone(); 8 | equals(this); 9 | finalize(); 10 | getClass(); 11 | hashCode(); 12 | notify(); 13 | notifyAll(); 14 | toString(); 15 | wait(); 16 | wait(0); 17 | wait(0, 0); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inner_classes/NestedLambdas.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inner_classes; 2 | 3 | import java.util.function.Consumer; 4 | 5 | public class NestedLambdas { 6 | public static void main(String g) { 7 | gaming((s) -> gaming((w) -> { 8 | System.out.println(s); 9 | gaming(System.out::println); 10 | })); 11 | } 12 | 13 | public static void gaming(Consumer runnable) { 14 | runnable.accept("Gaming!"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/translation/D_AnonymousTesting.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.translation; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class D_AnonymousTesting { 7 | public List getObjs() { 8 | List objs = new ArrayList(); 9 | objs.add(new Object() { 10 | @Override 11 | public String toString() { 12 | return "Object!"; 13 | } 14 | }); 15 | return objs; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/util/Pair.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.util; 2 | 3 | import java.util.Objects; 4 | 5 | public record Pair(A a, B b) { 6 | @Override 7 | public int hashCode() { 8 | return this.a.hashCode() ^ this.b.hashCode(); 9 | } 10 | 11 | @Override 12 | public boolean equals(Object o) { 13 | return o instanceof Pair 14 | && Objects.equals(this.a, ((Pair) o).a) 15 | && Objects.equals(this.b, ((Pair) o).b); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/translation/E_Bridges.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.translation; 2 | 3 | import java.util.Iterator; 4 | 5 | public class E_Bridges implements Iterator { 6 | @Override 7 | public boolean hasNext() { 8 | return false; 9 | } 10 | 11 | @Override 12 | public String next() { 13 | // the compiler will generate a bridge for this method 14 | return "foo"; 15 | } 16 | 17 | @Override 18 | public void remove() { 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/analysis/tree/ReferenceTreeNode.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.analysis.tree; 2 | 3 | import org.quiltmc.enigma.api.analysis.EntryReference; 4 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 5 | 6 | public interface ReferenceTreeNode, C extends Entry> { 7 | /** 8 | * Returns the entry represented by this tree node. 9 | */ 10 | E getEntry(); 11 | 12 | EntryReference getReference(); 13 | } 14 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inheritance_tree/BaseClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inheritance_tree; 2 | 3 | // a 4 | public abstract class BaseClass { 5 | // a 6 | private String name; 7 | 8 | // (Ljava/lang/String;)V 9 | protected BaseClass(String name) { 10 | this.name = name; 11 | } 12 | 13 | // a()Ljava/lang/String; 14 | public String getName() { 15 | return this.name; 16 | } 17 | 18 | // a()V 19 | public abstract void doBaseThings(); 20 | } 21 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/enigma/EnigmaFormat.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping.serde.enigma; 2 | 3 | public class EnigmaFormat { 4 | public static final String COMMENT = "COMMENT"; 5 | public static final String CLASS = "CLASS"; 6 | public static final String FIELD = "FIELD"; 7 | public static final String METHOD = "METHOD"; 8 | public static final String PARAMETER = "ARG"; 9 | public static final String LOCAL_VARIABLE = "LOCAL"; 10 | } 11 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/translation/G_OuterClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.translation; 2 | 3 | public class G_OuterClass { 4 | public class A_InnerClass { 5 | public int f1; 6 | public String f2; 7 | 8 | public void m1() {} 9 | 10 | public class A_InnerInnerClass { 11 | public int f3; 12 | 13 | public void m2() {} 14 | } 15 | } 16 | 17 | public class B_NamelessClass { 18 | public class A_NamedInnerClass { 19 | public int f4; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/interface_union/Union2Class.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.interface_union; 2 | 3 | import java.util.Random; 4 | 5 | public class Union2Class extends CClass implements BInterface { 6 | @Override 7 | public void methodFoo() { 8 | } 9 | 10 | @Override 11 | public double methodB() { 12 | return 6.02e23; 13 | } 14 | 15 | // BInterface + CClass 16 | @Override 17 | public boolean methodBar() { 18 | return new Random().nextExponential() > 2.0; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle 2 | .gradle 3 | 4 | # Eclipse 5 | .checkstyle 6 | .classpath 7 | .metadata 8 | .settings 9 | .project 10 | *.launch 11 | 12 | # Intellij/Idea 13 | .factorypath 14 | .idea 15 | *.iml 16 | *.ipr 17 | *.iws 18 | 19 | # Build artifacts 20 | bin/ 21 | build/ 22 | jars/ 23 | out/ 24 | classes/ 25 | 26 | # Debug artifacts 27 | run 28 | *.log 29 | 30 | # Windows 31 | *.db 32 | $RECYCLE.BIN/ 33 | 34 | # Mac 35 | .DS_Store 36 | 37 | # enigma 38 | /1.7.2-intermediary.jar 39 | /enigma_profile.json 40 | /mappings/ 41 | -------------------------------------------------------------------------------- /enigma-server/src/main/java/org/quiltmc/enigma/network/ServerPacketHandler.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network; 2 | 3 | import org.quiltmc.enigma.network.packet.Packet; 4 | 5 | import java.net.Socket; 6 | 7 | public record ServerPacketHandler(Socket client, EnigmaServer server) { 8 | public boolean isClientApproved() { 9 | return this.server.isClientApproved(this.client); 10 | } 11 | 12 | public void sendPacket(Packet packet) { 13 | this.server.sendPacket(this.client, packet); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/event/ConvertingTextFieldListener.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.event; 2 | 3 | import org.quiltmc.enigma.gui.element.ConvertingTextField; 4 | 5 | public interface ConvertingTextFieldListener { 6 | default void onStartEditing(ConvertingTextField field) { 7 | } 8 | 9 | default boolean tryStopEditing(ConvertingTextField field, boolean abort) { 10 | return true; 11 | } 12 | 13 | default void onStopEditing(ConvertingTextField field, boolean abort) { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /enigma/src/main/resources/tinylog.properties: -------------------------------------------------------------------------------- 1 | writingthread = true 2 | 3 | writerConsole = console 4 | writerConsole.format = {date: HH:mm:ss.SSS} [{level}]: {message} 5 | writerConsole.level = info 6 | 7 | writerFile = rolling file 8 | writerFile.level = trace 9 | writerFile.format= {date: HH:mm:ss.SSS} [{level}]: {message} 10 | writerFile.file = build/logs/log_{date:yyyy-MM-dd}-{count}.log 11 | writerFile.latest = build/logs/latest.log 12 | writerFile.charset = UTF-8 13 | writerFile.policy = daily, startup 14 | writirFile.backups = 10 15 | -------------------------------------------------------------------------------- /enigma-swing/src/test/resources/tinylog.properties: -------------------------------------------------------------------------------- 1 | writingthread = true 2 | 3 | writerConsole = console 4 | writerConsole.format = {date: HH:mm:ss.SSS} [{level}]: {message} 5 | writerConsole.level = info 6 | 7 | writerFile = rolling file 8 | writerFile.level = trace 9 | writerFile.format= {date: HH:mm:ss.SSS} [{level}]: {message} 10 | writerFile.file = build/logs/log_{date:yyyy-MM-dd}-{count}.log 11 | writerFile.latest = build/logs/latest.log 12 | writerFile.charset = UTF-8 13 | writerFile.policy = daily, startup 14 | writirFile.backups = 10 15 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/enums/Color.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.enums; 2 | 3 | // this enum does not have its `values` or `valueOf` methods obfuscated. 4 | // (see proguard-enums-test.conf) 5 | public enum Color { 6 | RED(0xff0000), 7 | YELLOW(0xffff00), 8 | GREEN(0x00ff00), 9 | CYAN(0x00ffff), 10 | BLUE(0x0000ff), 11 | MAGENTA(0xff00ff); 12 | 13 | public final int rgb; 14 | 15 | Color(int rgb) { 16 | this.rgb = rgb; 17 | } 18 | 19 | public int getColor() { 20 | return this.rgb; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/translation/I_Generics.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.translation; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public class I_Generics { 7 | public List f1; 8 | public List f2; 9 | public Map f3; 10 | public B_Generic f5; 11 | public B_Generic f6; 12 | 13 | public class A_Type { 14 | } 15 | 16 | public class B_Generic { 17 | public T f4; 18 | 19 | public T m1() { 20 | return null; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: [workflow_dispatch] # Manual trigger 3 | jobs: 4 | build: 5 | runs-on: ubuntu-22.04 6 | container: 7 | image: eclipse-temurin:20-jdk 8 | options: --user root 9 | steps: 10 | - uses: actions/checkout@v3 11 | - run: ./gradlew checkstyleMain build publish --stacktrace 12 | env: 13 | MAVEN_URL: ${{ secrets.NEW_MAVEN_URL }} 14 | MAVEN_USERNAME: ${{ secrets.NEW_MAVEN_USERNAME }} 15 | MAVEN_PASSWORD: ${{ secrets.NEW_MAVEN_PASSWORD }} 16 | -------------------------------------------------------------------------------- /enigma/src/main/resources/profile.json: -------------------------------------------------------------------------------- 1 | { 2 | "services": { 3 | "jar_indexer": [ 4 | { 5 | "id": "enigma:enum_initializer_indexer" 6 | }, 7 | { 8 | "id": "enigma:specialized_bridge_method_indexer" 9 | }, 10 | { 11 | "id": "enigma:record_component_indexer" 12 | } 13 | ], 14 | "name_proposal": [ 15 | { 16 | "id": "enigma:enum_name_proposer" 17 | }, 18 | { 19 | "id": "enigma:specialized_method_name_proposer" 20 | }, 21 | { 22 | "id": "enigma:record_component_proposer" 23 | } 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/records/Record.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.records; 2 | 3 | public record Record(String a, int b, double c) { 4 | // non canonical 5 | public Record(String a) { 6 | this(a, 0, 0.0); 7 | } 8 | 9 | // non canonical 10 | public Record(String a, double c, int b) { 11 | this(a, b, c); 12 | } 13 | 14 | // canonical with abnormal bytecode 15 | public Record(String a, int b, double c) { 16 | this.a = a; 17 | this.b = b; 18 | this.c = c; 19 | 20 | System.out.println("grind"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/ReadableToken.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui; 2 | 3 | public class ReadableToken { 4 | public final int line; 5 | public final int startColumn; 6 | public final int endColumn; 7 | 8 | public ReadableToken(int line, int startColumn, int endColumn) { 9 | this.line = line; 10 | this.startColumn = startColumn; 11 | this.endColumn = endColumn; 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "line " + this.line + " columns " + this.startColumn + "-" + this.endColumn; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/look_and_feel/ConfigurableFlatDarkLaf.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.look_and_feel; 2 | 3 | import com.formdev.flatlaf.FlatDarkLaf; 4 | import org.quiltmc.enigma.gui.config.theme.properties.composite.LookAndFeelProperties; 5 | 6 | public class ConfigurableFlatDarkLaf extends ConfigurableFlatLaf { 7 | public static final String NAME = "Configurable " + FlatDarkLaf.NAME; 8 | 9 | public ConfigurableFlatDarkLaf(LookAndFeelProperties.Colors colors) { 10 | super(NAME, colors, Base.DARK); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | tab_width = 4 8 | trim_trailing_whitespace = true 9 | 10 | [*.gradle] 11 | indent_style = tab 12 | 13 | [*.java] 14 | indent_style = tab 15 | ij_java_names_count_to_use_import_on_demand = 99 16 | 17 | [*.tiny] 18 | indent_style = tab 19 | 20 | [*.json] 21 | indent_style = tab 22 | 23 | [*.{mapping,mappings}] 24 | indent_style = tab 25 | 26 | [*.toml] 27 | indent_style = tab 28 | tab_width = 2 29 | 30 | [.editorconfig] 31 | indent_style = space 32 | indent_size = 4 33 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/look_and_feel/ConfigurableFlatLightLaf.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.look_and_feel; 2 | 3 | import com.formdev.flatlaf.FlatLightLaf; 4 | import org.quiltmc.enigma.gui.config.theme.properties.composite.LookAndFeelProperties; 5 | 6 | public class ConfigurableFlatLightLaf extends ConfigurableFlatLaf { 7 | public static final String NAME = "Configurable " + FlatLightLaf.NAME; 8 | 9 | public ConfigurableFlatLightLaf(LookAndFeelProperties.Colors colors) { 10 | super(NAME, colors, Base.LIGHT); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /config/checkstyle/suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /enigma-cli/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'application' 3 | id 'checkstyle' 4 | alias(libs.plugins.shadow) 5 | } 6 | 7 | dependencies { 8 | shadow(implementation project(':enigma')) 9 | testImplementation(testFixtures(project(':enigma'))) 10 | } 11 | 12 | application { 13 | mainClass = 'org.quiltmc.enigma.command.Main' 14 | jar.manifest.attributes 'Main-Class': mainClass 15 | } 16 | 17 | publishing { 18 | publications { 19 | "$project.name"(MavenPublication) { 20 | groupId project.group 21 | artifactId project.name 22 | version project.version 23 | from components.java 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/util/AsmUtil.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.util; 2 | 3 | import org.objectweb.asm.ClassReader; 4 | import org.objectweb.asm.ClassWriter; 5 | import org.objectweb.asm.tree.ClassNode; 6 | 7 | public class AsmUtil { 8 | public static byte[] nodeToBytes(ClassNode node) { 9 | ClassWriter w = new ClassWriter(0); 10 | node.accept(w); 11 | return w.toByteArray(); 12 | } 13 | 14 | public static ClassNode bytesToNode(byte[] bytes) { 15 | ClassReader r = new ClassReader(bytes); 16 | ClassNode node = new ClassNode(); 17 | r.accept(node, 0); 18 | return node; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/translation/H_NamelessClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.translation; 2 | 3 | public class H_NamelessClass { 4 | public class A_InnerClass { 5 | public int f1; 6 | public String f2; 7 | 8 | public void m1() {} 9 | 10 | public class A_InnerInnerClass { 11 | public int f3; 12 | 13 | public void m2() {} 14 | } 15 | } 16 | 17 | public class B_NamelessClass { 18 | public class A_NamedInnerClass { 19 | public int f4; 20 | 21 | public class A_AnotherInnerClass {} 22 | 23 | public class B_YetAnotherInnerClass {} 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/look_and_feel/TrackedSerializableColorGetter.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.look_and_feel; 2 | 3 | import org.quiltmc.config.api.values.TrackedValue; 4 | import org.quiltmc.enigma.gui.config.theme.properties.composite.LookAndFeelProperties; 5 | import org.quiltmc.enigma.gui.config.theme.properties.ThemeProperties; 6 | 7 | import java.util.function.Function; 8 | 9 | @FunctionalInterface 10 | public interface TrackedSerializableColorGetter extends Function 11 | > { } 12 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/constructors/SubClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.constructors; 2 | 3 | // d extends a 4 | public class SubClass extends BaseClass { 5 | // ()V 6 | public SubClass() { 7 | // a.()V 8 | } 9 | 10 | // (I)V 11 | public SubClass(int num) { 12 | // ()V 13 | this(); 14 | System.out.println("SubClass " + num); 15 | } 16 | 17 | // (II)V 18 | public SubClass(int a, int b) { 19 | // (I)V 20 | this(a + b); 21 | } 22 | 23 | // (III)V 24 | public SubClass(int a, int b, int c) { 25 | // a.()V 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/docker/AllClassesDocker.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.docker; 2 | 3 | import org.quiltmc.enigma.gui.ClassSelector; 4 | import org.quiltmc.enigma.gui.Gui; 5 | 6 | public class AllClassesDocker extends ClassesDocker { 7 | public AllClassesDocker(Gui gui) { 8 | super(gui, new ClassSelector(gui, ClassSelector.DEOBF_CLASS_COMPARATOR)); 9 | } 10 | 11 | @Override 12 | public String getId() { 13 | return "all_classes"; 14 | } 15 | 16 | @Override 17 | public Location getPreferredButtonLocation() { 18 | return new Location(Side.LEFT, VerticalLocation.TOP); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/bridge/OtherClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.bridge; 2 | 3 | import java.util.function.Function; 4 | import java.util.function.Supplier; 5 | 6 | // b 7 | public class OtherClass implements Supplier, Function { 8 | // a()Ljava/lang/Integer; 9 | // bridge get()Ljava/lang/Object; 10 | @Override 11 | public Integer get() { 12 | return -1; 13 | } 14 | 15 | // a(Ljava/lang/String;)Ljava/lang/Integer; 16 | // bridge apply(Ljava/lang/Object;)Ljava/lang/Object; 17 | @Override 18 | public Integer apply(String s) { 19 | return s.hashCode(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inner_classes/E_AnonymousWithOuterAccess.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inner_classes; 2 | 3 | public class E_AnonymousWithOuterAccess { 4 | // reproduction of error case documented at: 5 | // https://bitbucket.org/cuchaz/enigma/issue/61/stackoverflowerror-when-deobfuscating 6 | 7 | public Object makeInner() { 8 | this.outerMethod(); 9 | return new Object() { 10 | @Override 11 | public String toString() { 12 | return E_AnonymousWithOuterAccess.this.outerMethod(); 13 | } 14 | }; 15 | } 16 | 17 | private String outerMethod() { 18 | return "foo"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /enigma/src/test/resources/comments/test.mapping: -------------------------------------------------------------------------------- 1 | CLASS net/minecraft/class_1158 net/minecraft/util/math/Quaternion 2 | COMMENT it circel 3 | COMMENT next line 4 | FIELD field_21493 IDENTITY Lnet/minecraft/class_1158; 5 | COMMENT moar comment thing 6 | COMMENT near field 7 | METHOD foo bar (FFFF)V 8 | COMMENT method comment 9 | COMMENT second line 10 | COMMENT third line 11 | ARG 1 b 12 | COMMENT arg comment 13 | CLASS old new 14 | COMMENT inner comment 15 | FIELD field_19263 iterator Lnet/minecraft/class_3980; 16 | METHOD tryAdvance (Ljava/util/function/Consumer;)Z 17 | ARG 1 consumer 18 | COMMENT very inner comment -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/stats/StatType.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.stats; 2 | 3 | import org.quiltmc.enigma.util.I18n; 4 | 5 | public enum StatType { 6 | CLASSES("type.classes"), 7 | METHODS("type.methods"), 8 | FIELDS("type.fields"), 9 | PARAMETERS("type.parameters"); 10 | 11 | private final String translationKey; 12 | 13 | StatType(String translationKey) { 14 | this.translationKey = translationKey; 15 | } 16 | 17 | public String getTranslationKey() { 18 | return this.translationKey; 19 | } 20 | 21 | public String getName() { 22 | return I18n.translate(this.getTranslationKey()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/representation/ParameterAccessFlags.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.representation; 2 | 3 | import org.objectweb.asm.Opcodes; 4 | 5 | public class ParameterAccessFlags { 6 | public static final ParameterAccessFlags DEFAULT = new ParameterAccessFlags(0); 7 | 8 | private int flags; 9 | 10 | public ParameterAccessFlags(int flags) { 11 | this.flags = flags; 12 | } 13 | 14 | public boolean isSynthetic() { 15 | return (this.flags & Opcodes.ACC_SYNTHETIC) != 0; 16 | } 17 | 18 | public boolean isFinal() { 19 | return (this.flags & Opcodes.ACC_FINAL) != 0; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/network/IntegratedEnigmaServer.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.network; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.EntryRemapper; 4 | import org.quiltmc.enigma.network.EnigmaServer; 5 | 6 | import javax.swing.SwingUtilities; 7 | 8 | public class IntegratedEnigmaServer extends EnigmaServer { 9 | public IntegratedEnigmaServer(byte[] jarChecksum, char[] password, EntryRemapper mappings, int port) { 10 | super(jarChecksum, password, mappings, port); 11 | } 12 | 13 | @Override 14 | protected void runOnThread(Runnable task) { 15 | SwingUtilities.invokeLater(task); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /enigma-cli/src/test/java/org/quiltmc/enigma/command/PrintStatsCommandTest.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.command; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.quiltmc.enigma.TestUtil; 5 | 6 | import java.nio.file.Path; 7 | 8 | import static org.quiltmc.enigma.TestUtil.getResource; 9 | 10 | public class PrintStatsCommandTest { 11 | private static final Path JAR = TestUtil.obfJar("lone_class"); 12 | private static final Path MAPPINGS = getResource("/print_stats"); 13 | 14 | @Test 15 | public void test() throws Exception { 16 | // just here to manually verify output 17 | PrintStatsCommand.run(JAR, MAPPINGS, null, null); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/docker/DeobfuscatedClassesDocker.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.docker; 2 | 3 | import org.quiltmc.enigma.gui.ClassSelector; 4 | import org.quiltmc.enigma.gui.Gui; 5 | 6 | public class DeobfuscatedClassesDocker extends ClassesDocker { 7 | public DeobfuscatedClassesDocker(Gui gui) { 8 | super(gui, new ClassSelector(gui, ClassSelector.DEOBF_CLASS_COMPARATOR)); 9 | } 10 | 11 | @Override 12 | public String getId() { 13 | return "deobfuscated_classes"; 14 | } 15 | 16 | @Override 17 | public Location getPreferredButtonLocation() { 18 | return new Location(Side.LEFT, VerticalLocation.BOTTOM); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /enigma/src/testFixtures/resources/profile.json: -------------------------------------------------------------------------------- 1 | { 2 | "services": { 3 | "jar_indexer": [ 4 | { 5 | "id": "enigma:enum_initializer_indexer" 6 | }, 7 | { 8 | "id": "enigma:specialized_bridge_method_indexer" 9 | }, 10 | { 11 | "id": "enigma:record_component_indexer" 12 | } 13 | ], 14 | "name_proposal": [ 15 | { 16 | "id": "enigma:enum_name_proposer" 17 | }, 18 | { 19 | "id": "enigma:specialized_method_name_proposer" 20 | }, 21 | { 22 | "id": "test:parameters" 23 | }, 24 | { 25 | "id": "test:strings" 26 | }, 27 | { 28 | "id": "enigma:record_component_proposer" 29 | } 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inheritance_tree/SubsubclassAA.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inheritance_tree; 2 | 3 | // d extends b 4 | public class SubsubclassAA extends SubclassA { 5 | protected SubsubclassAA() { 6 | // call to b.(Ljava/lang/String;)V 7 | super("AA"); 8 | } 9 | 10 | @Override 11 | // a()Ljava/lang/String; 12 | public String getName() { 13 | // call to b.a()Ljava/lang/String; 14 | return "subsub" + super.getName(); 15 | } 16 | 17 | @Override 18 | // a()V 19 | public void doBaseThings() { 20 | // call to d.a()Ljava/lang/String; 21 | System.out.println("Base things by " + this.getName()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/analysis/MethodNodeWithAction.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.analysis; 2 | 3 | import org.objectweb.asm.tree.MethodNode; 4 | 5 | import java.util.function.Consumer; 6 | 7 | public class MethodNodeWithAction extends MethodNode { 8 | private final Consumer action; 9 | 10 | public MethodNodeWithAction(int api, int access, String name, String descriptor, String signature, String[] exceptions, Consumer action) { 11 | super(api, access, name, descriptor, signature, exceptions); 12 | this.action = action; 13 | } 14 | 15 | @Override 16 | public void visitEnd() { 17 | this.action.accept(this); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/network/IntegratedEnigmaClient.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.network; 2 | 3 | import org.quiltmc.enigma.network.ClientPacketHandler; 4 | import org.quiltmc.enigma.network.EnigmaClient; 5 | 6 | import javax.swing.SwingUtilities; 7 | 8 | public class IntegratedEnigmaClient extends EnigmaClient { 9 | public static boolean LOG_PACKETS = false; 10 | 11 | public IntegratedEnigmaClient(ClientPacketHandler handler, String ip, int port) { 12 | super(handler, ip, port); 13 | this.logPackets = LOG_PACKETS; 14 | } 15 | 16 | @Override 17 | protected void runOnThread(Runnable task) { 18 | SwingUtilities.invokeLater(task); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/service/ObfuscationTestService.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.service; 2 | 3 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 4 | 5 | /** 6 | * An obfuscation test service allows a plugin to override the deobfuscation status of an entry. 7 | *
8 | * Obfuscation test services are not active by default, and need to be specified in the {@link org.quiltmc.enigma.api.EnigmaProfile profile}. 9 | */ 10 | public interface ObfuscationTestService extends EnigmaService { 11 | EnigmaServiceType TYPE = EnigmaServiceType.create("obfuscation_test"); 12 | 13 | boolean testDeobfuscated(Entry entry); 14 | } 15 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/interface_union/Union1Class.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.interface_union; 2 | 3 | import java.util.Random; 4 | 5 | public class Union1Class implements AInterface, BInterface { 6 | @Override 7 | public int methodA() { 8 | return 32767; 9 | } 10 | 11 | // AInterface + BInterface 12 | @Override 13 | public void methodFoo() { 14 | System.out.println("foo"); 15 | } 16 | 17 | @Override 18 | public double baz() { 19 | return 200; 20 | } 21 | 22 | @Override 23 | public double methodB() { 24 | return new Random().nextGaussian(); 25 | } 26 | 27 | @Override 28 | public boolean methodBar() { 29 | return false; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/warning/WarningType.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.warning; 2 | 3 | import org.quiltmc.enigma.util.I18n; 4 | 5 | public enum WarningType { 6 | STATIC_FINAL_FIELD("warning.static_final_field"), 7 | CLASS("warning.class"), 8 | FIELD("warning.field"), 9 | ATOMIC_FIELD("warning.atomic_field"), 10 | METHOD("warning.method"), 11 | ARGUMENT("warning.argument"), 12 | UNKNOWN("warning.unknown"); 13 | 14 | private final String warningMessage; 15 | 16 | WarningType(String translatableText) { 17 | this.warningMessage = I18n.translate(translatableText); 18 | } 19 | 20 | public String getMessage() { 21 | return this.warningMessage; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/util/LanguageUtil.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public final class LanguageUtil { 7 | private static final List listeners = new ArrayList<>(); 8 | 9 | public LanguageUtil() { 10 | } 11 | 12 | public static void addListener(LanguageChangeListener listener) { 13 | listeners.add(listener); 14 | } 15 | 16 | public static void removeListener(LanguageChangeListener listener) { 17 | listeners.remove(listener); 18 | } 19 | 20 | public static void dispatchLanguageChange() { 21 | listeners.forEach(LanguageChangeListener::retranslateUi); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /COPYING.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2022 The Quilt Project. 2 | All rights reserved. This program and the accompanying materials 3 | are made available under the terms of the GNU Lesser General Public 4 | License v3.0 which accompanies this distribution, and is available at 5 | http://www.gnu.org/licenses/lgpl.html 6 | 7 | Original work by Jeff Martin: 8 | Copyright (c) 2015 Jeff Martin. 9 | All rights reserved. This program and the accompanying materials 10 | are made available under the terms of the GNU Lesser General Public 11 | License v3.0 which accompanies this distribution, and is available at 12 | http://www.gnu.org/licenses/lgpl.html 13 | 14 | To see the modifications that have been made, please see [changes.md](CHANGES.md). 15 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/StatsSection.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config; 2 | 3 | import org.quiltmc.config.api.ReflectiveConfig; 4 | import org.quiltmc.config.api.annotations.SerializedNameConvention; 5 | import org.quiltmc.config.api.metadata.NamingSchemes; 6 | import org.quiltmc.config.api.values.TrackedValue; 7 | 8 | @SerializedNameConvention(NamingSchemes.SNAKE_CASE) 9 | public class StatsSection extends ReflectiveConfig.Section { 10 | public final TrackedValue lastSelectedDir = this.value(""); 11 | public final TrackedValue lastTopLevelPackage = this.value(""); 12 | public final TrackedValue shouldIncludeSyntheticParameters = this.value(false); 13 | } 14 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/search/SearchEntry.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.search; 2 | 3 | import java.util.List; 4 | 5 | public interface SearchEntry { 6 | List getSearchableNames(); 7 | 8 | /** 9 | * Returns a type that uniquely identifies this search entry across possible changes. 10 | * This is used for tracking the amount of times this entry has been selected. 11 | * 12 | * @return a unique identifier for this search entry 13 | */ 14 | String getIdentifier(); 15 | 16 | /** 17 | * Returns the priority of the type of this entry. Entries with higher 18 | * priorities show up higher in the result list. Should be greater than zero. 19 | */ 20 | int getTypePriority(); 21 | } 22 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/MappingsReader.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping.serde; 2 | 3 | import org.quiltmc.enigma.api.ProgressListener; 4 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 5 | import org.quiltmc.enigma.api.translation.mapping.tree.EntryTree; 6 | 7 | import java.io.IOException; 8 | import java.nio.file.Path; 9 | 10 | public interface MappingsReader { 11 | EntryTree read(Path path, ProgressListener progress) throws MappingParseException, IOException; 12 | 13 | default EntryTree read(Path path) throws MappingParseException, IOException { 14 | return this.read(path, ProgressListener.createEmpty()); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/inheritance_tree/SubclassB.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.inheritance_tree; 2 | 3 | // c extends a 4 | public class SubclassB extends BaseClass { 5 | // a 6 | private int numThings; 7 | 8 | // ()V 9 | protected SubclassB() { 10 | // a.(Ljava/lang/String;)V 11 | super("B"); 12 | 13 | // access to a 14 | this.numThings = 4; 15 | } 16 | 17 | @Override 18 | // a()V 19 | public void doBaseThings() { 20 | // call to a.a()Ljava/lang/String; 21 | System.out.println("Base things by B! " + this.getName()); 22 | } 23 | 24 | // b()V 25 | public void doBThings() { 26 | // access to a 27 | System.out.println("" + this.numThings + " B things!"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/validation/SuperClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.validation; 2 | 3 | // b 4 | public class SuperClass { 5 | // a 6 | private static final String FIELD_A = "Hello"; 7 | // b 8 | public static final String FIELD_B = "World"; 9 | // a 10 | private final int fieldA = 0; 11 | // b 12 | private int fieldB; 13 | // b 14 | public boolean fieldC; 15 | 16 | // c()V 17 | public static void methodA() { 18 | } 19 | 20 | // a()Z 21 | public boolean methodB() { 22 | return false; 23 | } 24 | 25 | // a(I)V 26 | public void methodB(int i) { 27 | } 28 | 29 | // a()V 30 | private void methodC() { 31 | } 32 | 33 | // b()I 34 | public int methodD() { 35 | return 0; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/FeaturesSection.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config; 2 | 3 | import org.quiltmc.config.api.ReflectiveConfig; 4 | import org.quiltmc.config.api.annotations.Comment; 5 | import org.quiltmc.config.api.annotations.SerializedNameConvention; 6 | import org.quiltmc.config.api.metadata.NamingSchemes; 7 | import org.quiltmc.config.api.values.TrackedValue; 8 | 9 | @SerializedNameConvention(NamingSchemes.SNAKE_CASE) 10 | public class FeaturesSection extends ReflectiveConfig.Section { 11 | @Comment("Enables statistic icons in the class tree. This has a major performance impact on JAR files with lots of classes.") 12 | public final TrackedValue enableClassTreeStatIcons = this.value(true); 13 | } 14 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/EnigmaServices.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api; 2 | 3 | import com.google.common.collect.ImmutableListMultimap; 4 | import org.quiltmc.enigma.api.service.EnigmaService; 5 | import org.quiltmc.enigma.api.service.EnigmaServiceType; 6 | 7 | import java.util.List; 8 | 9 | public final class EnigmaServices { 10 | private final ImmutableListMultimap, EnigmaService> services; 11 | 12 | EnigmaServices(ImmutableListMultimap, EnigmaService> services) { 13 | this.services = services; 14 | } 15 | 16 | @SuppressWarnings("unchecked") 17 | public List get(EnigmaServiceType type) { 18 | return (List) this.services.get(type); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/event/EditorActionListener.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.event; 2 | 3 | import org.quiltmc.enigma.api.analysis.EntryReference; 4 | import org.quiltmc.enigma.api.class_handle.ClassHandle; 5 | import org.quiltmc.enigma.gui.panel.EditorPanel; 6 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 7 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 8 | 9 | public interface EditorActionListener { 10 | default void onCursorReferenceChanged(EditorPanel editor, EntryReference, Entry> ref) { 11 | } 12 | 13 | default void onClassHandleChanged(EditorPanel editor, ClassEntry old, ClassHandle ch) { 14 | } 15 | 16 | default void onTitleChanged(EditorPanel editor, String title) { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /enigma-server/src/main/java/org/quiltmc/enigma/network/ClientPacketHandler.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.EntryChange; 4 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 5 | import org.quiltmc.enigma.api.translation.mapping.tree.EntryTree; 6 | import org.quiltmc.enigma.network.packet.Packet; 7 | 8 | import java.util.List; 9 | 10 | public interface ClientPacketHandler { 11 | void openMappings(EntryTree mappings); 12 | 13 | boolean applyChangeFromServer(EntryChange change); 14 | 15 | void disconnectIfConnected(String reason); 16 | 17 | void sendPacket(Packet packet); 18 | 19 | void addMessage(ServerMessage message); 20 | 21 | void updateUserList(List users); 22 | } 23 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/representation/ArgumentDescriptor.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.representation; 2 | 3 | import java.util.function.UnaryOperator; 4 | 5 | public class ArgumentDescriptor extends TypeDescriptor { 6 | private ParameterAccessFlags access; 7 | 8 | public ArgumentDescriptor(String desc, ParameterAccessFlags access) { 9 | super(desc); 10 | this.access = access; 11 | } 12 | 13 | public ParameterAccessFlags getAccess() { 14 | return this.access; 15 | } 16 | 17 | public void setAccess(ParameterAccessFlags access) { 18 | this.access = access; 19 | } 20 | 21 | public ArgumentDescriptor remap(UnaryOperator remapper) { 22 | return new ArgumentDescriptor(super.remap(remapper).desc, this.getAccess()); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/MappingPair.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping; 2 | 3 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 4 | 5 | import javax.annotation.Nullable; 6 | 7 | public class MappingPair, M> { 8 | private final E entry; 9 | private M mapping; 10 | 11 | public MappingPair(E entry, @Nullable M mapping) { 12 | this.entry = entry; 13 | this.mapping = mapping; 14 | } 15 | 16 | public MappingPair(E entry) { 17 | this(entry, null); 18 | } 19 | 20 | public E getEntry() { 21 | return this.entry; 22 | } 23 | 24 | @Nullable 25 | public M getMapping() { 26 | return this.mapping; 27 | } 28 | 29 | public void setMapping(M mapping) { 30 | this.mapping = mapping; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /enigma-server/src/test/java/org/quiltmc/enigma/network/TestEnigmaClient.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network; 2 | 3 | import org.quiltmc.enigma.network.packet.Packet; 4 | 5 | import java.util.concurrent.CountDownLatch; 6 | 7 | public class TestEnigmaClient extends EnigmaClient { 8 | CountDownLatch packetSentLatch = new CountDownLatch(1); 9 | 10 | public TestEnigmaClient(ClientPacketHandler handler, String ip, int port) { 11 | super(handler, ip, port); 12 | this.logPackets = true; 13 | } 14 | 15 | @Override 16 | protected void runOnThread(Runnable task) { 17 | task.run(); 18 | } 19 | 20 | @Override 21 | public void sendPacket(Packet packet) { 22 | super.sendPacket(packet); 23 | if (this.packetSentLatch != null) { 24 | this.packetSentLatch.countDown(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/analysis/tree/AbstractMethodTreeNode.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.analysis.tree; 2 | 3 | import org.quiltmc.enigma.api.translation.Translator; 4 | import org.quiltmc.enigma.api.translation.representation.entry.MethodEntry; 5 | 6 | import javax.swing.tree.DefaultMutableTreeNode; 7 | 8 | public abstract class AbstractMethodTreeNode extends DefaultMutableTreeNode { 9 | protected final Translator translator; 10 | protected final MethodEntry entry; 11 | 12 | protected AbstractMethodTreeNode(Translator translator, MethodEntry entry) { 13 | this.translator = translator; 14 | this.entry = entry; 15 | } 16 | 17 | /** 18 | * Returns the method entry represented by this tree node. 19 | */ 20 | public MethodEntry getMethodEntry() { 21 | return this.entry; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/util/Os.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.util; 2 | 3 | import java.util.Locale; 4 | 5 | public enum Os { 6 | LINUX, 7 | MAC, 8 | SOLARIS, 9 | WINDOWS, 10 | OTHER; 11 | 12 | private static Os os = null; 13 | 14 | public static Os getOs() { 15 | if (os == null) { 16 | String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT); 17 | if (osName.contains("mac") || osName.contains("darwin")) { 18 | os = MAC; 19 | } else if (osName.contains("win")) { 20 | os = WINDOWS; 21 | } else if (osName.contains("nix") || osName.contains("nux") 22 | || osName.contains("aix")) { 23 | os = LINUX; 24 | } else if (osName.contains("sunos")) { 25 | os = SOLARIS; 26 | } else { 27 | os = OTHER; 28 | } 29 | } 30 | 31 | return os; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/MappingFileNameFormat.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping.serde; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | /** 6 | * Defines a strategy for naming files in directory-based mapping formats. 7 | */ 8 | public enum MappingFileNameFormat { 9 | /** 10 | * Names files based on the mappings' obfuscated names. 11 | * Example: if a class is mapped from {@code a} to {@code GreatClass}, its file will be named {@code GreatClass}. 12 | */ 13 | @SerializedName("by_obf") 14 | BY_OBF, 15 | /** 16 | * Names files based on the mappings' deobfuscated names. 17 | * Example: if a class is mapped from {@code a} to {@code GreatClass}, its file will be named {@code a}. 18 | */ 19 | @SerializedName("by_deobf") 20 | BY_DEOBF 21 | } 22 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/EntryMap.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.tree.EntryTreeNode; 4 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 5 | 6 | import javax.annotation.Nullable; 7 | import java.util.stream.Stream; 8 | 9 | public interface EntryMap { 10 | void insert(Entry entry, T value); 11 | 12 | default void insert(EntryTreeNode node) { 13 | this.insert(node.getEntry(), node.getValue()); 14 | } 15 | 16 | @Nullable 17 | T remove(Entry entry); 18 | 19 | @Nullable 20 | T get(Entry entry); 21 | 22 | default boolean contains(Entry entry) { 23 | return this.get(entry) != null; 24 | } 25 | 26 | Stream> getAllEntries(); 27 | 28 | boolean isEmpty(); 29 | } 30 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: [push, pull_request] 3 | jobs: 4 | build: 5 | strategy: 6 | matrix: 7 | java: [17-jdk, 20-jdk] 8 | runs-on: ubuntu-22.04 9 | container: 10 | image: eclipse-temurin:${{ matrix.java }} 11 | options: --user root 12 | steps: 13 | - uses: actions/checkout@v3 14 | - run: ./gradlew checkstyleMain build --stacktrace --warning-mode fail 15 | - name: Publish Snapshot 16 | if: ${{ matrix.java == '17-jdk' && github.repository_owner == 'QuiltMC' && contains(github.ref_name, 'develop') }} 17 | run: ./gradlew publish --stacktrace 18 | env: 19 | SNAPSHOTS_URL: ${{ secrets.SNAPSHOTS_URL }} 20 | SNAPSHOTS_USERNAME: ${{ secrets.SNAPSHOTS_USERNAME }} 21 | SNAPSHOTS_PASSWORD: ${{ secrets.SNAPSHOTS_PASSWORD }} 22 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/validation/BaseClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.validation; 2 | 3 | // a 4 | public class BaseClass extends SuperClass { 5 | // c 6 | private static final String FIELD_A = "fieldA"; 7 | // a 8 | public static final String FIELD_B = "fieldB"; 9 | // a 10 | private final int fieldA = -1; 11 | // b 12 | private int fieldB; 13 | // a 14 | public boolean fieldC; 15 | 16 | // a()V 17 | public static void methodA() { 18 | } 19 | 20 | // b()V 21 | public void methodE() { 22 | } 23 | 24 | // a(I)I 25 | public int methodE(int i) { 26 | return i; 27 | } 28 | 29 | // d()V 30 | private void methodC() { 31 | } 32 | 33 | // a()I 34 | public int methodF() { 35 | return 1; 36 | } 37 | 38 | // a(II)I 39 | public int methodG(int a, int b) { 40 | return a + b; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/service/DecompilerService.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.service; 2 | 3 | import org.quiltmc.enigma.api.class_provider.ClassProvider; 4 | import org.quiltmc.enigma.api.source.Decompiler; 5 | import org.quiltmc.enigma.api.source.SourceSettings; 6 | 7 | /** 8 | * Decompiler services provide implementations of {@link Decompiler} in order to convert bytecode into human-readable source code. 9 | *
10 | * Decompiler services are active by default, and as such do not need to be specified in the {@link org.quiltmc.enigma.api.EnigmaProfile profile}. 11 | */ 12 | public interface DecompilerService extends EnigmaService { 13 | EnigmaServiceType TYPE = EnigmaServiceType.create("decompiler", true); 14 | 15 | Decompiler create(ClassProvider classProvider, SourceSettings settings); 16 | } 17 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/Translatable.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.EntryMap; 4 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 5 | import org.quiltmc.enigma.api.translation.mapping.EntryResolver; 6 | 7 | import javax.annotation.Nullable; 8 | 9 | public interface Translatable { 10 | TranslateResult extendedTranslate(Translator translator, EntryResolver resolver, EntryMap mappings); 11 | 12 | @Nullable 13 | default Translatable translate(Translator translator, EntryResolver resolver, EntryMap mappings) { 14 | TranslateResult res = this.extendedTranslate(translator, resolver, mappings); 15 | return res == null ? null : res.getValue(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /enigma-server/src/main/java/org/quiltmc/enigma/network/packet/c2s/ConfirmChangeC2SPacket.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network.packet.c2s; 2 | 3 | import org.quiltmc.enigma.network.ServerPacketHandler; 4 | import org.quiltmc.enigma.network.packet.Packet; 5 | 6 | import java.io.DataInput; 7 | import java.io.DataOutput; 8 | import java.io.IOException; 9 | 10 | public record ConfirmChangeC2SPacket(int syncId) implements Packet { 11 | public ConfirmChangeC2SPacket(DataInput input) throws IOException { 12 | this(input.readUnsignedShort()); 13 | } 14 | 15 | @Override 16 | public void write(DataOutput output) throws IOException { 17 | output.writeShort(this.syncId); 18 | } 19 | 20 | @Override 21 | public void handle(ServerPacketHandler handler) { 22 | handler.server().confirmChange(handler.client(), this.syncId); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/node/ClassSelectorPackageNode.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.node; 2 | 3 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 4 | 5 | import javax.swing.tree.TreeNode; 6 | import java.util.Comparator; 7 | 8 | public class ClassSelectorPackageNode extends SortedMutableTreeNode { 9 | private final String packageName; 10 | 11 | public ClassSelectorPackageNode(Comparator comparator, String packageName) { 12 | super(comparator); 13 | 14 | this.packageName = packageName != null ? packageName : "(none)"; 15 | } 16 | 17 | public String getPackageName() { 18 | return this.packageName; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return !this.packageName.equals("(none)") ? ClassEntry.getNameInPackage(this.packageName) : "(none)"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /enigma-server/src/main/java/org/quiltmc/enigma/network/packet/s2c/MessageS2CPacket.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network.packet.s2c; 2 | 3 | import org.quiltmc.enigma.network.ClientPacketHandler; 4 | import org.quiltmc.enigma.network.ServerMessage; 5 | import org.quiltmc.enigma.network.packet.Packet; 6 | 7 | import java.io.DataInput; 8 | import java.io.DataOutput; 9 | import java.io.IOException; 10 | 11 | public record MessageS2CPacket(ServerMessage message) implements Packet { 12 | public MessageS2CPacket(DataInput input) throws IOException { 13 | this(ServerMessage.read(input)); 14 | } 15 | 16 | @Override 17 | public void write(DataOutput output) throws IOException { 18 | this.message.write(output); 19 | } 20 | 21 | @Override 22 | public void handle(ClientPacketHandler handler) { 23 | handler.addMessage(this.message); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/renderer/MessageListCellRenderer.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.renderer; 2 | 3 | import org.quiltmc.enigma.network.ServerMessage; 4 | 5 | import java.awt.Component; 6 | import javax.swing.DefaultListCellRenderer; 7 | import javax.swing.JList; 8 | 9 | // For now, just render the translated text. 10 | // TODO: Icons or something later? 11 | public class MessageListCellRenderer extends DefaultListCellRenderer { 12 | @Override 13 | public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 14 | super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 15 | ServerMessage message = (ServerMessage) value; 16 | if (message != null) { 17 | this.setText(message.translate()); 18 | } 19 | 20 | return this; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/renderer/StructureOptionListCellRenderer.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.renderer; 2 | 3 | import org.quiltmc.enigma.api.analysis.tree.StructureTreeOptions; 4 | import org.quiltmc.enigma.util.I18n; 5 | 6 | import java.awt.Component; 7 | import javax.swing.DefaultListCellRenderer; 8 | import javax.swing.JList; 9 | 10 | public class StructureOptionListCellRenderer extends DefaultListCellRenderer { 11 | @Override 12 | public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 13 | Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 14 | 15 | if (value instanceof StructureTreeOptions.Option option) { 16 | this.setText(I18n.translate(option.getTranslationKey())); 17 | } 18 | 19 | return c; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/properties/ConfigurableFlatLafThemeProperties.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.properties; 2 | 3 | import org.quiltmc.config.api.Config; 4 | import org.quiltmc.enigma.gui.config.theme.properties.composite.LookAndFeelProperties; 5 | import org.quiltmc.enigma.gui.config.theme.properties.composite.SyntaxPaneProperties; 6 | 7 | import java.util.List; 8 | 9 | public abstract class ConfigurableFlatLafThemeProperties extends ConfigurableLafThemeProperties { 10 | protected ConfigurableFlatLafThemeProperties( 11 | SyntaxPaneProperties syntaxPaneColors, 12 | LookAndFeelProperties lookAndFeelColors, 13 | List creators 14 | ) { 15 | super(syntaxPaneColors, lookAndFeelColors, creators); 16 | } 17 | 18 | @Override 19 | public final boolean onlyScaleFonts() { 20 | return true; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /enigma-server/src/main/java/org/quiltmc/enigma/network/packet/s2c/KickS2CPacket.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network.packet.s2c; 2 | 3 | import org.quiltmc.enigma.network.ClientPacketHandler; 4 | import org.quiltmc.enigma.network.packet.Packet; 5 | import org.quiltmc.enigma.network.packet.PacketHelper; 6 | 7 | import java.io.DataInput; 8 | import java.io.DataOutput; 9 | import java.io.IOException; 10 | 11 | public record KickS2CPacket(String reason) implements Packet { 12 | public KickS2CPacket(DataInput input) throws IOException { 13 | this(PacketHelper.readString(input)); 14 | } 15 | 16 | @Override 17 | public void write(DataOutput output) throws IOException { 18 | PacketHelper.writeString(output, this.reason); 19 | } 20 | 21 | @Override 22 | public void handle(ClientPacketHandler handler) { 23 | handler.disconnectIfConnected(this.reason); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/look_and_feel/SerializableColorGetter.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.look_and_feel; 2 | 3 | import org.quiltmc.config.api.values.TrackedValue; 4 | import org.quiltmc.enigma.gui.config.theme.properties.composite.LookAndFeelProperties; 5 | import org.quiltmc.enigma.gui.config.theme.properties.ThemeProperties; 6 | 7 | import java.util.function.Function; 8 | 9 | @FunctionalInterface 10 | public interface SerializableColorGetter extends Function { 11 | static SerializableColorGetter of(TrackedSerializableColorGetter getter) { 12 | return of(getter.andThen(TrackedValue::value)); 13 | } 14 | 15 | static SerializableColorGetter of(Function getter) { 16 | return getter::apply; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /enigma-server/build.gradle: -------------------------------------------------------------------------------- 1 | import quilt.internal.task.ProGuardExecTask 2 | 3 | plugins { 4 | id 'application' 5 | id 'checkstyle' 6 | alias(libs.plugins.shadow) 7 | } 8 | 9 | dependencies { 10 | shadow(implementation project(':enigma')) 11 | implementation libs.jopt 12 | 13 | testImplementation testFixtures(project(':enigma')) 14 | } 15 | 16 | application { 17 | mainClass = 'org.quiltmc.enigma.network.DedicatedEnigmaServer' 18 | jar.manifest.attributes 'Main-Class': mainClass 19 | } 20 | 21 | tasks.named('test') { 22 | inputs.files( 23 | project(':enigma').tasks 24 | .withType(ProGuardExecTask) 25 | .named('completeTestObf') 26 | .get().outJar 27 | ) 28 | } 29 | 30 | publishing { 31 | publications { 32 | "$project.name"(MavenPublication) { 33 | groupId project.group 34 | artifactId project.name 35 | version project.version 36 | from components.java 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/service/EnigmaService.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.service; 2 | 3 | /** 4 | * An enigma service is a component that provides a specific feature or piece of functionality to enigma. 5 | */ 6 | public interface EnigmaService { 7 | /** 8 | * The ID of this service. This should satisfy a few criteria: 9 | *
    10 | *
  • Be namespaced, with the plugin name and service name separated by a colon. The {@code enigma} namespace is reserved for builtin plugins.
  • 11 | *
  • Be all lowercase, with words separated by underscores. Slashes are allowed only after the namespace.
  • 12 | *
  • Be constant and unique: it should never change.
  • 13 | *
14 | *

Examples: {@code enigma:cfr}, {@code enigma:enum_proposers/name}, {@code your_plugin:custom_indexer}

15 | * 16 | * @return the constant ID 17 | */ 18 | String getId(); 19 | } 20 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/properties/NonSystemLafThemeProperties.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.properties; 2 | 3 | import org.quiltmc.config.api.Config; 4 | import org.quiltmc.enigma.gui.config.theme.properties.composite.SyntaxPaneProperties; 5 | 6 | import javax.swing.LookAndFeel; 7 | import javax.swing.UIManager; 8 | import javax.swing.UnsupportedLookAndFeelException; 9 | import java.util.List; 10 | 11 | public abstract class NonSystemLafThemeProperties extends ThemeProperties { 12 | protected NonSystemLafThemeProperties( 13 | SyntaxPaneProperties syntaxPaneColors, 14 | List creators 15 | ) { 16 | super(syntaxPaneColors, creators); 17 | } 18 | 19 | @Override 20 | public final void setGlobalLaf() throws UnsupportedLookAndFeelException { 21 | UIManager.setLookAndFeel(this.getLaf()); 22 | } 23 | 24 | protected abstract LookAndFeel getLaf(); 25 | } 26 | -------------------------------------------------------------------------------- /enigma-cli/src/test/java/org/quiltmc/enigma/command/CheckMappingsCommandTest.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.command; 2 | 3 | import org.quiltmc.enigma.TestUtil; 4 | import org.junit.jupiter.api.Assertions; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.nio.file.Path; 8 | 9 | public class CheckMappingsCommandTest extends CommandTest { 10 | private static final Path JAR = TestUtil.obfJar("package_access"); 11 | private static final Path WRONG_MAPPINGS = getResource("/packageAccess/wrongMappings"); 12 | private static final Path CORRECT_MAPPINGS = getResource("/packageAccess/correctMappings"); 13 | 14 | @Test 15 | public void testWrong() { 16 | Assertions.assertThrows(IllegalStateException.class, () -> 17 | CheckMappingsCommand.run(JAR, WRONG_MAPPINGS) 18 | ); 19 | } 20 | 21 | @Test 22 | public void testRight() { 23 | Assertions.assertDoesNotThrow(() -> CheckMappingsCommand.run(JAR, CORRECT_MAPPINGS)); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/VoidEntryResolver.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping; 2 | 3 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 4 | import org.quiltmc.enigma.api.translation.representation.entry.MethodEntry; 5 | 6 | import java.util.Collection; 7 | import java.util.Collections; 8 | import java.util.Set; 9 | 10 | public enum VoidEntryResolver implements EntryResolver { 11 | INSTANCE; 12 | 13 | @Override 14 | public > Collection resolveEntry(E entry, ResolutionStrategy strategy) { 15 | return Collections.singleton(entry); 16 | } 17 | 18 | @Override 19 | public Set> resolveEquivalentEntries(Entry entry) { 20 | return Collections.singleton(entry); 21 | } 22 | 23 | @Override 24 | public Set resolveEquivalentMethods(MethodEntry methodEntry) { 25 | return Collections.singleton(methodEntry); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/source/TokenType.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.source; 2 | 3 | /** 4 | * A token type dictates different types of mapping that an entry can have. 5 | */ 6 | public enum TokenType { 7 | /** 8 | * Tokens which have no mapping whatsoever. 9 | */ 10 | OBFUSCATED, 11 | /** 12 | * Tokens whose names have been read from a file or manually written by a user. 13 | */ 14 | DEOBFUSCATED, 15 | /** 16 | * Tokens that have automatically proposed names based on bytecode. 17 | */ 18 | JAR_PROPOSED, 19 | /** 20 | * Tokens that have automatically proposed names based on other mappings. 21 | */ 22 | DYNAMIC_PROPOSED, 23 | NAME_WARNING, 24 | DEBUG; 25 | 26 | /** 27 | * Checks whether this token has a name proposed by a plugin. 28 | * @return whether this token is proposed 29 | */ 30 | public boolean isProposed() { 31 | return this == DYNAMIC_PROPOSED || this == JAR_PROPOSED; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /enigma-cli/src/test/java/org/quiltmc/enigma/command/CommandTest.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.command; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 4 | import org.quiltmc.enigma.api.translation.mapping.tree.EntryTree; 5 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 6 | 7 | import java.net.URISyntaxException; 8 | import java.nio.file.Path; 9 | 10 | public abstract class CommandTest { 11 | public static Path getResource(String name) { 12 | try { 13 | return Path.of(CommandTest.class.getResource(name).toURI()).toAbsolutePath(); 14 | } catch (URISyntaxException e) { 15 | throw new RuntimeException(e); 16 | } 17 | } 18 | 19 | protected static String getName(EntryTree mappings, Entry entry) { 20 | if (!mappings.contains(entry)) { 21 | return null; 22 | } 23 | 24 | EntryMapping mapping = mappings.get(entry); 25 | return mapping != null ? mapping.targetName() : null; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/util/validation/ParameterizedMessage.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.util.validation; 2 | 3 | import java.io.File; 4 | 5 | /** 6 | * Represents a formatted message ready for display to the user. 7 | * @param message the message to display 8 | * @param params parameters to use when formatting the message text 9 | */ 10 | public record ParameterizedMessage(Message message, Object... params) { 11 | public static ParameterizedMessage openedProject(String jar, String mappings) { 12 | return new ParameterizedMessage(Message.OPENED_PROJECT, jar.substring(jar.lastIndexOf(File.separator)), mappings.substring(mappings.lastIndexOf(File.separator))); 13 | } 14 | 15 | public Message.Type getType() { 16 | return this.message.getType(); 17 | } 18 | 19 | public String getText() { 20 | return this.message.format(this.params); 21 | } 22 | 23 | public String getLongText() { 24 | return this.message.formatDetails(this.params); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/properties/MetalThemeProperties.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.properties; 2 | 3 | import org.quiltmc.config.api.Config; 4 | import org.quiltmc.enigma.gui.config.theme.properties.composite.SyntaxPaneProperties; 5 | 6 | import javax.swing.LookAndFeel; 7 | import javax.swing.plaf.metal.MetalLookAndFeel; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class MetalThemeProperties extends NonConfigurableLafThemeProperties { 12 | public MetalThemeProperties() { 13 | this(new SyntaxPaneProperties(), new ArrayList<>()); 14 | } 15 | 16 | protected MetalThemeProperties( 17 | SyntaxPaneProperties syntaxPaneColors, 18 | List creators 19 | ) { 20 | super(syntaxPaneColors, creators); 21 | } 22 | 23 | @Override 24 | public boolean onlyScaleFonts() { 25 | return false; 26 | } 27 | 28 | @Override 29 | protected LookAndFeel getLaf() { 30 | return new MetalLookAndFeel(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/util/validation/StandardValidation.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.util.validation; 2 | 3 | public class StandardValidation { 4 | public static boolean notBlank(ValidationContext vc, String value) { 5 | if (value.trim().isEmpty()) { 6 | vc.raise(Message.EMPTY_FIELD); 7 | return false; 8 | } 9 | 10 | return true; 11 | } 12 | 13 | public static boolean isInt(ValidationContext vc, String value) { 14 | if (!notBlank(vc, value)) return false; 15 | try { 16 | Integer.parseInt(value); 17 | return true; 18 | } catch (NumberFormatException e) { 19 | vc.raise(Message.NOT_INT); 20 | return false; 21 | } 22 | } 23 | 24 | public static boolean isIntInRange(ValidationContext vc, String value, int min, int max) { 25 | if (!isInt(vc, value)) return false; 26 | int intVal = Integer.parseInt(value); 27 | if (intVal < min || intVal > max) { 28 | vc.raise(Message.FIELD_OUT_OF_RANGE_INT, min, max); 29 | return false; 30 | } 31 | 32 | return true; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/MappingTranslator.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.EntryMap; 4 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 5 | import org.quiltmc.enigma.api.translation.mapping.EntryResolver; 6 | 7 | import javax.annotation.Nullable; 8 | 9 | public class MappingTranslator implements Translator { 10 | private final EntryMap mappings; 11 | private final EntryResolver resolver; 12 | 13 | public MappingTranslator(EntryMap mappings, EntryResolver resolver) { 14 | this.mappings = mappings; 15 | this.resolver = resolver; 16 | } 17 | 18 | @Nullable 19 | @SuppressWarnings("unchecked") 20 | @Override 21 | public TranslateResult extendedTranslate(T translatable) { 22 | if (translatable == null) { 23 | return null; 24 | } 25 | 26 | return (TranslateResult) translatable.extendedTranslate(this, this.resolver, this.mappings); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/analysis/Access.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.analysis; 2 | 3 | import org.quiltmc.enigma.api.translation.representation.AccessFlags; 4 | 5 | import java.lang.reflect.Modifier; 6 | 7 | public enum Access { 8 | PUBLIC, PROTECTED, PACKAGE, PRIVATE; 9 | 10 | public static Access get(AccessFlags flags) { 11 | return get(flags.getFlags()); 12 | } 13 | 14 | public static Access get(int modifiers) { 15 | boolean isPublic = Modifier.isPublic(modifiers); 16 | boolean isProtected = Modifier.isProtected(modifiers); 17 | boolean isPrivate = Modifier.isPrivate(modifiers); 18 | 19 | if (isPublic && !isProtected && !isPrivate) { 20 | return PUBLIC; 21 | } else if (!isPublic && isProtected && !isPrivate) { 22 | return PROTECTED; 23 | } else if (!isPublic && !isProtected && isPrivate) { 24 | return PRIVATE; 25 | } else if (!isPublic && !isProtected && !isPrivate) { 26 | return PACKAGE; 27 | } 28 | 29 | // assume public by default 30 | return PUBLIC; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/MappingParseException.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping.serde; 2 | 3 | import java.io.File; 4 | import java.nio.file.Path; 5 | 6 | public class MappingParseException extends Exception { 7 | private final int line; 8 | private final String message; 9 | private final Path filePath; 10 | 11 | public MappingParseException(File file, int line, String message) { 12 | this(file.toPath(), line, message); 13 | } 14 | 15 | public MappingParseException(Path filePath, int line, String message) { 16 | this.line = line; 17 | this.message = message; 18 | this.filePath = filePath; 19 | } 20 | 21 | public MappingParseException(Path filePath, int line, Throwable cause) { 22 | super(cause); 23 | this.line = line; 24 | this.message = cause.toString(); 25 | this.filePath = filePath; 26 | } 27 | 28 | @Override 29 | public String getMessage() { 30 | return "Line " + this.line + ": " + this.message + " in file " + this.filePath.toString(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/properties/NoneThemeProperties.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.properties; 2 | 3 | import org.quiltmc.config.api.Config; 4 | import org.quiltmc.enigma.gui.config.theme.properties.composite.SyntaxPaneProperties; 5 | 6 | import javax.swing.LookAndFeel; 7 | import javax.swing.UIManager; 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | public class NoneThemeProperties extends NonConfigurableLafThemeProperties { 12 | private static final LookAndFeel NONE_LAF = UIManager.getLookAndFeel(); 13 | 14 | public NoneThemeProperties() { 15 | this(new SyntaxPaneProperties(), new ArrayList<>()); 16 | } 17 | 18 | protected NoneThemeProperties( 19 | SyntaxPaneProperties syntaxPaneColors, 20 | List creators 21 | ) { 22 | super(syntaxPaneColors, creators); 23 | } 24 | 25 | @Override 26 | public boolean onlyScaleFonts() { 27 | return false; 28 | } 29 | 30 | @Override 31 | protected LookAndFeel getLaf() { 32 | return NONE_LAF; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /enigma/src/test/resources/translation.mappings: -------------------------------------------------------------------------------- 1 | CLASS a deobf/A_Basic 2 | FIELD a f1 I 3 | FIELD a f2 F 4 | FIELD a f3 Ljava/lang/String; 5 | METHOD a m1 ()V 6 | METHOD a m2 ()I 7 | METHOD a m3 (I)V 8 | METHOD a m4 (I)I 9 | CLASS b deobf/B_BaseClass 10 | FIELD a f1 I 11 | FIELD a f2 C 12 | METHOD a m1 ()I 13 | METHOD b m2 ()I 14 | CLASS c deobf/C_SubClass 15 | FIELD b f2 C 16 | FIELD b f3 I 17 | FIELD c f4 I 18 | METHOD a m1 ()I 19 | METHOD c m3 ()I 20 | CLASS g deobf/G_OuterClass 21 | CLASS g$a A_InnerClass 22 | CLASS g$a$a A_InnerInnerClass 23 | FIELD a f3 I 24 | METHOD a m2 ()V 25 | FIELD a f1 I 26 | FIELD a f2 Ljava/lang/String; 27 | METHOD a m1 ()V 28 | CLASS g$b 29 | CLASS g$b$a A_NamedInnerClass 30 | FIELD a f4 I 31 | CLASS h 32 | CLASS i deobf/I_Generics 33 | CLASS i$a A_Type 34 | CLASS i$b B_Generic 35 | FIELD a f4 Ljava/lang/Object; 36 | METHOD a m1 ()Ljava/lang/Object; 37 | FIELD a f1 Ljava/util/List; 38 | FIELD b f2 Ljava/util/List; 39 | FIELD a f3 Ljava/util/Map; 40 | FIELD a f5 Li$b; 41 | FIELD b f6 Li$b; 42 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/source/vineflower/VineflowerDecompiler.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.source.vineflower; 2 | 3 | import org.quiltmc.enigma.api.class_provider.ClassProvider; 4 | import org.quiltmc.enigma.api.source.Decompiler; 5 | import org.quiltmc.enigma.api.source.Source; 6 | import org.quiltmc.enigma.api.source.SourceSettings; 7 | import org.quiltmc.enigma.api.translation.mapping.EntryRemapper; 8 | 9 | import javax.annotation.Nullable; 10 | 11 | public class VineflowerDecompiler implements Decompiler { 12 | private final ClassProvider classProvider; 13 | private final SourceSettings sourceSettings; 14 | 15 | public VineflowerDecompiler(ClassProvider classProvider, SourceSettings sourceSettings) { 16 | this.classProvider = classProvider; 17 | this.sourceSettings = sourceSettings; 18 | } 19 | 20 | @Override 21 | public Source getSource(String className, @Nullable EntryRemapper remapper) { 22 | return new VineflowerSource(new EnigmaContextSource(this.classProvider, className), remapper, this.sourceSettings); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/constructors/Caller.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.constructors; 2 | 3 | // b 4 | public class Caller { 5 | // a()V 6 | public void callBaseDefault() { 7 | // a.()V 8 | System.out.println(new BaseClass()); 9 | } 10 | 11 | // b()V 12 | public void callBaseInt() { 13 | // a.(I)V 14 | System.out.println(new BaseClass(5)); 15 | } 16 | 17 | // c()V 18 | public void callSubDefault() { 19 | // d.()V 20 | System.out.println(new SubClass()); 21 | } 22 | 23 | // d()V 24 | public void callSubInt() { 25 | // d.(I)V 26 | System.out.println(new SubClass(6)); 27 | } 28 | 29 | // e()V 30 | public void callSubIntInt() { 31 | // d.(II)V 32 | System.out.println(new SubClass(4, 2)); 33 | } 34 | 35 | // f()V 36 | public void callSubSubInt() { 37 | // e.(I)V 38 | System.out.println(new SubSubClass(3)); 39 | } 40 | 41 | // g()V 42 | public void callDefaultConstructable() { 43 | // c.()V 44 | System.out.println(new DefaultConstructable()); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/lambdas/Lambdas.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.lambdas; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.function.Consumer; 6 | import java.util.function.Supplier; 7 | import java.util.stream.Stream; 8 | 9 | public class Lambdas { 10 | private List children = new ArrayList<>(); 11 | 12 | public Stream stream() { 13 | return Stream.concat(Stream.of(this), this.children.stream().flatMap(Lambdas::stream)); 14 | } 15 | 16 | public Stream crazyStream() { 17 | return get(() -> Stream.concat(Stream.of(this), this.children.stream().flatMap(Lambdas::crazyStream))); 18 | } 19 | 20 | public static Stream get(Supplier> provider) { 21 | return provider.get(); 22 | } 23 | 24 | public static void foo() { 25 | consume(s -> consume(s1 -> { 26 | System.out.println(s); 27 | consume(System.out::println); 28 | })); 29 | } 30 | 31 | public static void consume(Consumer consumer) { 32 | consumer.accept("Foo"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/class_provider/ClasspathClassProvider.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.class_provider; 2 | 3 | import org.objectweb.asm.ClassReader; 4 | import org.objectweb.asm.tree.ClassNode; 5 | 6 | import javax.annotation.Nullable; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.util.Collection; 10 | import java.util.Collections; 11 | 12 | /** 13 | * Provides classes by loading them from the classpath. 14 | */ 15 | public class ClasspathClassProvider implements ClassProvider { 16 | @Nullable 17 | @Override 18 | public ClassNode get(String name) { 19 | try (InputStream in = ClasspathClassProvider.class.getResourceAsStream("/" + name + ".class")) { 20 | if (in == null) { 21 | return null; 22 | } 23 | 24 | ClassNode node = new ClassNode(); 25 | new ClassReader(in).accept(node, 0); 26 | return node; 27 | } catch (IOException e) { 28 | return null; 29 | } 30 | } 31 | 32 | @Override 33 | public Collection getClassNames() { 34 | return Collections.emptyList(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/properties/AbstractDarculaThemeProperties.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.properties; 2 | 3 | import org.quiltmc.config.api.Config; 4 | import org.quiltmc.enigma.gui.config.theme.look_and_feel.ConfigurableFlatDarkLaf; 5 | import org.quiltmc.enigma.gui.config.theme.look_and_feel.ConfigurableFlatLaf; 6 | import org.quiltmc.enigma.gui.config.theme.properties.composite.LookAndFeelProperties; 7 | import org.quiltmc.enigma.gui.config.theme.properties.composite.SyntaxPaneProperties; 8 | 9 | import java.util.List; 10 | 11 | public abstract class AbstractDarculaThemeProperties extends ConfigurableFlatLafThemeProperties { 12 | protected AbstractDarculaThemeProperties( 13 | SyntaxPaneProperties syntaxPaneColors, LookAndFeelProperties lookAndFeelColors, 14 | List creators 15 | ) { 16 | super(syntaxPaneColors, lookAndFeelColors, creators); 17 | } 18 | 19 | @Override 20 | protected ConfigurableFlatLaf.Constructor getLafConstructor() { 21 | return ConfigurableFlatDarkLaf::new; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/docker/ObfuscatedClassesDocker.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.docker; 2 | 3 | import org.quiltmc.enigma.gui.ClassSelector; 4 | import org.quiltmc.enigma.gui.Gui; 5 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 6 | 7 | import java.util.Comparator; 8 | 9 | public class ObfuscatedClassesDocker extends ClassesDocker { 10 | private static final Comparator obfuscatedClassComparator = (a, b) -> { 11 | String aName = a.getFullName(); 12 | String bName = b.getFullName(); 13 | if (aName.length() != bName.length()) { 14 | return aName.length() - bName.length(); 15 | } 16 | 17 | return aName.compareTo(bName); 18 | }; 19 | 20 | public ObfuscatedClassesDocker(Gui gui) { 21 | super(gui, new ClassSelector(gui, obfuscatedClassComparator)); 22 | } 23 | 24 | @Override 25 | public String getId() { 26 | return "obfuscated_classes"; 27 | } 28 | 29 | @Override 30 | public Location getPreferredButtonLocation() { 31 | return new Location(Side.LEFT, VerticalLocation.TOP); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/class_handle/ClassHandleError.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.class_handle; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.PrintStream; 5 | import javax.annotation.Nullable; 6 | 7 | public final class ClassHandleError { 8 | public final Type type; 9 | public final Throwable cause; 10 | 11 | private ClassHandleError(Type type, Throwable cause) { 12 | this.type = type; 13 | this.cause = cause; 14 | } 15 | 16 | @Nullable 17 | public String getStackTrace() { 18 | if (this.cause == null) return null; 19 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 20 | PrintStream ps = new PrintStream(os); 21 | this.cause.printStackTrace(ps); 22 | return os.toString(); 23 | } 24 | 25 | public static ClassHandleError decompile(Throwable cause) { 26 | return new ClassHandleError(Type.DECOMPILE, cause); 27 | } 28 | 29 | public static ClassHandleError remap(Throwable cause) { 30 | return new ClassHandleError(Type.REMAP, cause); 31 | } 32 | 33 | public enum Type { 34 | DECOMPILE, 35 | REMAP, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/translation/mapping/TestTinyV2InnerClasses.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.translation.mapping; 2 | 3 | import org.quiltmc.enigma.api.Enigma; 4 | import org.quiltmc.enigma.api.EnigmaProject; 5 | import org.quiltmc.enigma.api.ProgressListener; 6 | import org.quiltmc.enigma.TestUtil; 7 | import org.quiltmc.enigma.api.class_provider.ClasspathClassProvider; 8 | import org.quiltmc.enigma.api.translation.mapping.serde.enigma.EnigmaMappingsReader; 9 | import org.junit.jupiter.api.Test; 10 | 11 | import java.nio.file.Path; 12 | 13 | public final class TestTinyV2InnerClasses { 14 | public static final Path JAR = TestUtil.obfJar("inner_classes"); 15 | public static final Path MAPPINGS = TestUtil.getResource("/tinyV2InnerClasses/"); 16 | 17 | @Test 18 | public void testMappings() throws Exception { 19 | EnigmaProject project = Enigma.create().openJar(JAR, new ClasspathClassProvider(), ProgressListener.createEmpty()); 20 | project.setMappings(EnigmaMappingsReader.DIRECTORY.read(MAPPINGS, ProgressListener.createEmpty()), ProgressListener.createEmpty()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /enigma-cli/src/main/java/org/quiltmc/enigma/command/HelpCommand.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.command; 2 | 3 | import org.tinylog.Logger; 4 | 5 | import java.util.Collection; 6 | 7 | public class HelpCommand extends Command { 8 | protected HelpCommand() { 9 | super(); 10 | } 11 | 12 | @Override 13 | public void run(String... args) throws Exception { 14 | StringBuilder help = new StringBuilder(); 15 | Collection commands = Main.getCommands().values(); 16 | 17 | help.append("Supported commands:").append("\n"); 18 | for (Command command : commands) { 19 | help.append("- ").append(command.getName()).append("\n"); 20 | help.append("\t").append(command.getDescription()).append("\n"); 21 | } 22 | 23 | help.append("Run any command with no arguments in order to see all possible arguments for that command."); 24 | Logger.info(help.toString()); 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return "help"; 30 | } 31 | 32 | @Override 33 | public String getDescription() { 34 | return "Provides a list of commands, along with some short descriptions."; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/ConfigPaths.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config; 2 | 3 | import org.quiltmc.enigma.util.Os; 4 | 5 | import java.nio.file.Path; 6 | import java.nio.file.Paths; 7 | 8 | public class ConfigPaths { 9 | public static Path getConfigPathRoot() { 10 | switch (Os.getOs()) { 11 | case LINUX -> { 12 | String configHome = System.getenv("XDG_CONFIG_HOME"); 13 | if (configHome == null) { 14 | return getUserHomeUnix().resolve(".config"); 15 | } 16 | 17 | return Paths.get(configHome); 18 | } 19 | case MAC -> { 20 | return getUserHomeUnix().resolve("Library").resolve("Application Support"); 21 | } 22 | case WINDOWS -> { 23 | return Paths.get(System.getenv("LOCALAPPDATA")); 24 | } 25 | default -> { 26 | return Paths.get(System.getProperty("user.dir")); 27 | } 28 | } 29 | } 30 | 31 | private static Path getUserHomeUnix() { 32 | String userHome = System.getenv("HOME"); 33 | if (userHome == null) { 34 | userHome = System.getProperty("user.dir"); 35 | } 36 | 37 | return Paths.get(userHome); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/properties/NonConfigurableLafThemeProperties.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.properties; 2 | 3 | import org.quiltmc.config.api.Config; 4 | import org.quiltmc.config.api.annotations.Comment; 5 | import org.quiltmc.enigma.gui.config.theme.properties.composite.LookAndFeelProperties; 6 | import org.quiltmc.enigma.gui.config.theme.properties.composite.SyntaxPaneProperties; 7 | import org.quiltmc.enigma.gui.util.ListUtil; 8 | 9 | import java.util.List; 10 | 11 | public abstract class NonConfigurableLafThemeProperties extends NonSystemLafThemeProperties { 12 | public static void createComment(Config.Builder builder) { 13 | builder.metadata(Comment.TYPE, comment -> 14 | comment.add(LookAndFeelProperties.COLORS_KEY + " are not configurable for this theme") 15 | ); 16 | } 17 | 18 | protected NonConfigurableLafThemeProperties( 19 | SyntaxPaneProperties syntaxPaneColors, 20 | List creators 21 | ) { 22 | super(syntaxPaneColors, ListUtil.prepend(NonConfigurableLafThemeProperties::createComment, creators)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/translation/mapping/serde/RawEntryMapping.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.translation.mapping.serde; 2 | 3 | import org.quiltmc.enigma.api.source.TokenType; 4 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 5 | 6 | import javax.annotation.Nullable; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | /** 11 | * A builder class for creating an {@link EntryMapping}, used when reading mappings. 12 | */ 13 | public final class RawEntryMapping { 14 | private final String targetName; 15 | private final List javadocs = new ArrayList<>(); 16 | 17 | public RawEntryMapping(@Nullable String targetName) { 18 | this.targetName = targetName != null && !targetName.equals("-") ? targetName : null; 19 | } 20 | 21 | public void addJavadocLine(String line) { 22 | this.javadocs.add(line); 23 | } 24 | 25 | public EntryMapping bake() { 26 | return new EntryMapping(this.targetName, this.javadocs.isEmpty() ? null : String.join("\n", this.javadocs), this.targetName == null ? TokenType.OBFUSCATED : TokenType.DEOBFUSCATED, null); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/Decompiler.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config; 2 | 3 | import org.quiltmc.enigma.gui.Gui; 4 | import org.quiltmc.enigma.gui.dialog.decompiler.VineflowerSettingsDialog; 5 | import org.quiltmc.enigma.api.service.DecompilerService; 6 | import org.quiltmc.enigma.api.source.Decompilers; 7 | 8 | import java.util.function.BiConsumer; 9 | import javax.swing.JDialog; 10 | 11 | public enum Decompiler { 12 | VINEFLOWER("Vineflower", Decompilers.VINEFLOWER, VineflowerSettingsDialog::new), 13 | CFR("CFR", Decompilers.CFR), 14 | PROCYON("Procyon", Decompilers.PROCYON), 15 | BYTECODE("Bytecode", Decompilers.BYTECODE); 16 | 17 | public final DecompilerService service; 18 | public final String name; 19 | public final BiConsumer settingsDialog; 20 | 21 | Decompiler(String name, DecompilerService service) { 22 | this(name, service, null); 23 | } 24 | 25 | Decompiler(String name, DecompilerService service, BiConsumer settingsDialog) { 26 | this.name = name; 27 | this.service = service; 28 | this.settingsDialog = settingsDialog; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/source/bytecode/BytecodeClassEntry.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.source.bytecode; 2 | 3 | import org.quiltmc.enigma.api.translation.TranslateResult; 4 | import org.quiltmc.enigma.api.translation.Translator; 5 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 6 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 7 | 8 | import javax.annotation.Nonnull; 9 | import javax.annotation.Nullable; 10 | 11 | class BytecodeClassEntry extends ClassEntry { 12 | BytecodeClassEntry(String className) { 13 | super(className); 14 | } 15 | 16 | BytecodeClassEntry(@Nullable ClassEntry parent, String className) { 17 | super(parent, className); 18 | } 19 | 20 | @Override 21 | public String getSourceRemapName() { 22 | return this.getFullName(); 23 | } 24 | 25 | @Override 26 | public TranslateResult extendedTranslate(Translator translator, @Nonnull EntryMapping mapping) { 27 | var result = super.extendedTranslate(translator, mapping); 28 | return result.map(e -> new BytecodeClassEntry(e.getParent(), e.getName())); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/renderer/TokenListCellRenderer.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.renderer; 2 | 3 | import org.quiltmc.enigma.gui.GuiController; 4 | import org.quiltmc.enigma.api.source.Token; 5 | 6 | import javax.swing.DefaultListCellRenderer; 7 | import javax.swing.JLabel; 8 | import javax.swing.JList; 9 | import javax.swing.ListCellRenderer; 10 | import java.awt.Component; 11 | 12 | public class TokenListCellRenderer implements ListCellRenderer { 13 | private final GuiController controller; 14 | private final DefaultListCellRenderer defaultRenderer; 15 | 16 | public TokenListCellRenderer(GuiController controller) { 17 | this.controller = controller; 18 | this.defaultRenderer = new DefaultListCellRenderer(); 19 | } 20 | 21 | @Override 22 | public Component getListCellRendererComponent(JList list, Token token, int index, boolean isSelected, boolean hasFocus) { 23 | JLabel label = (JLabel) this.defaultRenderer.getListCellRendererComponent(list, token, index, isSelected, hasFocus); 24 | label.setText(this.controller.getReadableToken(token).toString()); 25 | return label; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/KeyBindConfig.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config; 2 | 3 | import org.quiltmc.config.api.ReflectiveConfig; 4 | import org.quiltmc.config.api.annotations.SerializedNameConvention; 5 | import org.quiltmc.config.api.metadata.NamingSchemes; 6 | import org.quiltmc.config.api.values.TrackedValue; 7 | import org.quiltmc.config.api.values.ValueList; 8 | import org.quiltmc.config.api.values.ValueMap; 9 | import org.quiltmc.enigma.gui.config.keybind.KeyBind; 10 | 11 | @SerializedNameConvention(NamingSchemes.SNAKE_CASE) 12 | public final class KeyBindConfig extends ReflectiveConfig { 13 | public final TrackedValue>> keyCodes = this.map(ValueList.create("")).build(); 14 | 15 | public String[] getKeyCodes(KeyBind keyBind) { 16 | ValueList codes = this.keyCodes.value().get(keyBind.name()); 17 | return (codes == null || codes.isEmpty()) ? keyBind.serializeCombinations() : codes.toArray(String[]::new); 18 | } 19 | 20 | public void setBind(KeyBind keyBind) { 21 | this.keyCodes.value().put(keyBind.name(), ValueList.create("", keyBind.serializeCombinations())); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/event/ClassHandleListener.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.event; 2 | 3 | import org.quiltmc.enigma.api.class_handle.ClassHandle; 4 | import org.quiltmc.enigma.api.class_handle.ClassHandleError; 5 | import org.quiltmc.enigma.api.source.DecompiledClassSource; 6 | import org.quiltmc.enigma.api.source.Source; 7 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 8 | import org.quiltmc.enigma.util.Result; 9 | 10 | public interface ClassHandleListener { 11 | default void onDeobfRefChanged(ClassHandle h, ClassEntry deobfRef) { 12 | } 13 | 14 | default void onUncommentedSourceChanged(ClassHandle h, Result res) { 15 | } 16 | 17 | default void onDocsChanged(ClassHandle h, Result res) { 18 | } 19 | 20 | default void onMappedSourceChanged(ClassHandle h, Result res) { 21 | } 22 | 23 | default void onInvalidate(ClassHandle h, InvalidationType t) { 24 | } 25 | 26 | default void onDeleted(ClassHandle h) { 27 | } 28 | 29 | enum InvalidationType { 30 | FULL, 31 | JAVADOC, 32 | MAPPINGS, 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/look_and_feel/HexColorStringGetter.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.look_and_feel; 2 | 3 | import org.quiltmc.enigma.gui.config.theme.properties.composite.LookAndFeelProperties; 4 | import org.quiltmc.enigma.gui.config.theme.properties.ThemeProperties; 5 | 6 | import java.util.function.Function; 7 | 8 | @FunctionalInterface 9 | public interface HexColorStringGetter extends Function { 10 | static HexColorStringGetter of(TrackedSerializableColorGetter getter) { 11 | return of(SerializableColorGetter.of(getter)); 12 | } 13 | 14 | static HexColorStringGetter of(SerializableColorGetter getter) { 15 | return of(getter.andThen(HexColorStringGetter::colorPropertyValueOf)); 16 | } 17 | 18 | static HexColorStringGetter of(Function getter) { 19 | return getter::apply; 20 | } 21 | 22 | static String colorPropertyValueOf(ThemeProperties.SerializableColor color) { 23 | return prependHash(color.getRepresentation()); 24 | } 25 | 26 | static String prependHash(String hexColor) { 27 | return "#" + hexColor; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/analysis/index/jar/EnclosingMethodIndex.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.analysis.index.jar; 2 | 3 | import org.quiltmc.enigma.api.translation.representation.entry.ClassDefEntry; 4 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 5 | 6 | import javax.annotation.Nullable; 7 | import java.util.HashMap; 8 | import java.util.Map; 9 | 10 | public class EnclosingMethodIndex implements JarIndexer { 11 | private final Map enclosingMethodData = new HashMap<>(); 12 | 13 | @Override 14 | public void indexEnclosingMethod(ClassDefEntry classEntry, EnclosingMethodData enclosingMethodData) { 15 | this.enclosingMethodData.put(classEntry, enclosingMethodData); 16 | } 17 | 18 | @Nullable 19 | public EnclosingMethodData getEnclosingMethodData(ClassEntry entry) { 20 | return this.enclosingMethodData.get(entry); 21 | } 22 | 23 | public boolean hasEnclosingMethod(ClassEntry entry) { 24 | return this.getEnclosingMethodData(entry) != null; 25 | } 26 | 27 | @Override 28 | public String getTranslationKey() { 29 | return "progress.jar.indexing.process.enclosing_methods"; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /enigma-swing/src/main/resources/stats.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Stats 7 | 8 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /enigma-server/src/main/java/org/quiltmc/enigma/network/packet/c2s/MessageC2SPacket.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network.packet.c2s; 2 | 3 | import org.quiltmc.enigma.network.ServerMessage; 4 | import org.quiltmc.enigma.network.ServerPacketHandler; 5 | import org.quiltmc.enigma.network.packet.Packet; 6 | import org.quiltmc.enigma.network.packet.PacketHelper; 7 | 8 | import java.io.DataInput; 9 | import java.io.DataOutput; 10 | import java.io.IOException; 11 | 12 | public record MessageC2SPacket(String message) implements Packet { 13 | public MessageC2SPacket(DataInput input) throws IOException { 14 | this(PacketHelper.readString(input)); 15 | } 16 | 17 | @Override 18 | public void write(DataOutput output) throws IOException { 19 | PacketHelper.writeString(output, this.message); 20 | } 21 | 22 | @Override 23 | public void handle(ServerPacketHandler handler) { 24 | if (!handler.isClientApproved()) { 25 | return; 26 | } 27 | 28 | String trimmedMessage = this.message.trim(); 29 | if (!trimmedMessage.isEmpty()) { 30 | handler.server().sendMessage(ServerMessage.chat(handler.server().getUsername(handler.client()), trimmedMessage)); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/source/procyon/transformer/InvalidIdentifierFix.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.source.procyon.transformer; 2 | 3 | import com.strobel.decompiler.languages.java.ast.AstNode; 4 | import com.strobel.decompiler.languages.java.ast.DepthFirstAstVisitor; 5 | import com.strobel.decompiler.languages.java.ast.Identifier; 6 | import com.strobel.decompiler.languages.java.ast.transforms.IAstTransform; 7 | 8 | /** 9 | * Created by Thiakil on 13/07/2018. 10 | */ 11 | public class InvalidIdentifierFix implements IAstTransform { 12 | @Override 13 | public void run(AstNode compilationUnit) { 14 | compilationUnit.acceptVisitor(new Visitor(), null); 15 | } 16 | 17 | class Visitor extends DepthFirstAstVisitor { 18 | @Override 19 | public Void visitIdentifier(Identifier node, Void data) { 20 | super.visitIdentifier(node, data); 21 | if (node.getName().equals("do") || node.getName().equals("if")) { 22 | Identifier newIdentifier = Identifier.create(node.getName() + "_", node.getStartLocation()); 23 | newIdentifier.copyUserDataFrom(node); 24 | node.replaceWith(newIdentifier); 25 | } 26 | 27 | return null; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/tree/EntryTreeNode.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping.tree; 2 | 3 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 4 | 5 | import javax.annotation.Nullable; 6 | import java.util.ArrayList; 7 | import java.util.Collection; 8 | import java.util.List; 9 | 10 | public interface EntryTreeNode { 11 | @Nullable 12 | T getValue(); 13 | 14 | Entry getEntry(); 15 | 16 | boolean isEmpty(); 17 | 18 | Collection> getChildren(); 19 | 20 | Collection> getChildNodes(); 21 | 22 | default Collection> getNodesRecursively() { 23 | Collection> nodes = new ArrayList<>(); 24 | nodes.add(this); 25 | for (EntryTreeNode node : this.getChildNodes()) { 26 | nodes.addAll(node.getNodesRecursively()); 27 | } 28 | 29 | return nodes; 30 | } 31 | 32 | default List> getChildrenRecursively() { 33 | return this.getNodesRecursively().stream() 34 | .map(EntryTreeNode::getEntry) 35 | .toList(); 36 | } 37 | 38 | default boolean hasValue() { 39 | return this.getValue() != null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/highlight/SelectionHighlightPainter.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.highlight; 2 | 3 | import org.quiltmc.enigma.gui.config.Config; 4 | import org.quiltmc.enigma.gui.util.ScaleUtil; 5 | 6 | import java.awt.BasicStroke; 7 | import java.awt.Graphics; 8 | import java.awt.Graphics2D; 9 | import java.awt.Rectangle; 10 | import java.awt.Shape; 11 | import javax.swing.text.Highlighter; 12 | import javax.swing.text.JTextComponent; 13 | 14 | public class SelectionHighlightPainter implements Highlighter.HighlightPainter { 15 | public static final SelectionHighlightPainter INSTANCE = new SelectionHighlightPainter(); 16 | 17 | @Override 18 | public void paint(Graphics g, int start, int end, Shape shape, JTextComponent text) { 19 | // draw a thick border 20 | Graphics2D g2d = (Graphics2D) g; 21 | Rectangle bounds = BoxHighlightPainter.getBounds(text, start, end); 22 | g2d.setColor(Config.getCurrentSyntaxPaneColors().selectionHighlight.value()); 23 | g2d.setStroke(new BasicStroke(ScaleUtil.scale(2.0f))); 24 | 25 | int arcSize = ScaleUtil.scale(4); 26 | g2d.drawRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, arcSize, arcSize); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/analysis/tree/AbstractClassTreeNode.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.analysis.tree; 2 | 3 | import org.quiltmc.enigma.api.translation.TranslateResult; 4 | import org.quiltmc.enigma.api.translation.Translator; 5 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 6 | 7 | import javax.swing.tree.DefaultMutableTreeNode; 8 | 9 | public abstract class AbstractClassTreeNode extends DefaultMutableTreeNode { 10 | protected final Translator translator; 11 | protected final ClassEntry entry; 12 | 13 | protected AbstractClassTreeNode(Translator translator, ClassEntry entry) { 14 | this.translator = translator; 15 | this.entry = entry; 16 | } 17 | 18 | /** 19 | * Returns the class entry represented by this tree node. 20 | */ 21 | public ClassEntry getClassEntry() { 22 | return this.entry; 23 | } 24 | 25 | public String getClassName() { 26 | return this.entry.getFullName(); 27 | } 28 | 29 | @Override 30 | public String toString() { 31 | TranslateResult translated = this.translator.extendedTranslate(this.entry); 32 | return translated != null ? translated.getValue().toString() : "invalid class"; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/service/EnigmaServiceContext.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.service; 2 | 3 | import org.quiltmc.enigma.util.Either; 4 | 5 | import java.nio.file.Path; 6 | import java.util.List; 7 | import java.util.Optional; 8 | 9 | public interface EnigmaServiceContext { 10 | static EnigmaServiceContext empty() { 11 | return key -> Optional.empty(); 12 | } 13 | 14 | Optional>> getArgument(String key); 15 | 16 | default Optional getSingleArgument(String key) { 17 | return this.getArgument(key).flatMap(e -> e.left()); 18 | } 19 | 20 | default Optional> getMultipleArguments(String key) { 21 | return this.getArgument(key).flatMap(e -> e.right()); 22 | } 23 | 24 | /** 25 | * Resolves the path relative to the parent directory of the loaded {@link org.quiltmc.enigma.api.EnigmaProfile enigma profile}. 26 | * If there is no profile or the profile was not loaded from a file, the path is returned as-is. 27 | * @param path the path to resolve 28 | * @return the resolved path 29 | */ 30 | default Path getPath(String path) { 31 | return Path.of(path); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /enigma-server/src/main/java/org/quiltmc/enigma/network/packet/s2c/EntryChangeS2CPacket.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network.packet.s2c; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.EntryChange; 4 | import org.quiltmc.enigma.network.ClientPacketHandler; 5 | import org.quiltmc.enigma.network.packet.Packet; 6 | import org.quiltmc.enigma.network.packet.PacketHelper; 7 | import org.quiltmc.enigma.network.packet.c2s.ConfirmChangeC2SPacket; 8 | 9 | import java.io.DataInput; 10 | import java.io.DataOutput; 11 | import java.io.IOException; 12 | 13 | public record EntryChangeS2CPacket(int syncId, EntryChange change) implements Packet { 14 | public EntryChangeS2CPacket(DataInput input) throws IOException { 15 | this(input.readUnsignedShort(), PacketHelper.readEntryChange(input)); 16 | } 17 | 18 | @Override 19 | public void write(DataOutput output) throws IOException { 20 | output.writeShort(this.syncId); 21 | PacketHelper.writeEntryChange(output, this.change); 22 | } 23 | 24 | @Override 25 | public void handle(ClientPacketHandler handler) { 26 | if (handler.applyChangeFromServer(this.change)) { 27 | handler.sendPacket(new ConfirmChangeC2SPacket(this.syncId)); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/properties/DefaultThemeProperties.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.properties; 2 | 3 | import org.quiltmc.config.api.Config; 4 | import org.quiltmc.enigma.gui.config.theme.look_and_feel.ConfigurableFlatLaf; 5 | import org.quiltmc.enigma.gui.config.theme.look_and_feel.ConfigurableFlatLightLaf; 6 | import org.quiltmc.enigma.gui.config.theme.properties.composite.LookAndFeelProperties; 7 | import org.quiltmc.enigma.gui.config.theme.properties.composite.SyntaxPaneProperties; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class DefaultThemeProperties extends ConfigurableFlatLafThemeProperties { 13 | public DefaultThemeProperties() { 14 | this(new SyntaxPaneProperties(), new LookAndFeelProperties(), new ArrayList<>()); 15 | } 16 | 17 | protected DefaultThemeProperties( 18 | SyntaxPaneProperties syntaxPaneColors, LookAndFeelProperties lookAndFeelColors, 19 | List creators 20 | ) { 21 | super(syntaxPaneColors, lookAndFeelColors, creators); 22 | } 23 | 24 | @Override 25 | protected ConfigurableFlatLaf.Constructor getLafConstructor() { 26 | return ConfigurableFlatLightLaf::new; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/util/History.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.util; 2 | 3 | import com.google.common.collect.Queues; 4 | 5 | import java.util.Deque; 6 | 7 | public class History { 8 | private final Deque previous = Queues.newArrayDeque(); 9 | private final Deque next = Queues.newArrayDeque(); 10 | private T current; 11 | 12 | public History(T initial) { 13 | this.current = initial; 14 | } 15 | 16 | public T getCurrent() { 17 | return this.current; 18 | } 19 | 20 | public void push(T value) { 21 | this.previous.addLast(this.current); 22 | this.current = value; 23 | this.next.clear(); 24 | } 25 | 26 | public void replace(T value) { 27 | this.current = value; 28 | } 29 | 30 | public boolean canGoBack() { 31 | return !this.previous.isEmpty(); 32 | } 33 | 34 | public T goBack() { 35 | this.next.addFirst(this.current); 36 | this.current = this.previous.removeLast(); 37 | return this.current; 38 | } 39 | 40 | public boolean canGoForward() { 41 | return !this.next.isEmpty(); 42 | } 43 | 44 | public T goForward() { 45 | this.previous.addLast(this.current); 46 | this.current = this.next.removeFirst(); 47 | return this.current; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Enigma 2 | 3 | A tool for deobfuscation of Java bytecode. Forked from , which was forked from , originally created by [Jeff Martin](https://www.cuchazinteractive.com/). 4 | 5 | ## License 6 | 7 | Enigma is distributed under the [LGPL-3.0](LICENSE). 8 | 9 | Enigma includes the following open-source libraries: 10 | - [Vineflower](https://github.com/Vineflower/vineflower) (Apache-2.0) 11 | - [Procyon](https://github.com/mstrobel/procyon) (Apache-2.0) 12 | - A [modified version](https://github.com/fabricmc/cfr) of [CFR](https://github.com/leibnitz27/cfr) (MIT) 13 | - [Guava](https://github.com/google/guava) (Apache-2.0) 14 | - [SyntaxPane](https://github.com/Sciss/SyntaxPane) (Apache-2.0) 15 | - [FlatLaf](https://github.com/JFormDesigner/FlatLaf) (Apache-2.0) 16 | - [jopt-simple](https://github.com/jopt-simple/jopt-simple) (MIT) 17 | - [ASM](https://asm.ow2.io/) (BSD-3-Clause) 18 | 19 | ## Usage 20 | 21 | Pre-compiled jars can be found on the [Ornithe maven](https://maven.ornithemc.net/). 22 | 23 | ### Launching the GUI 24 | 25 | `java -jar enigma.jar` 26 | 27 | ### On the command line 28 | 29 | `java -cp enigma.jar org.quiltmc.enigma.command.Main` 30 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/source/procyon/transformer/DropImportAstTransform.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.source.procyon.transformer; 2 | 3 | import com.strobel.decompiler.languages.java.ast.AstNode; 4 | import com.strobel.decompiler.languages.java.ast.DepthFirstAstVisitor; 5 | import com.strobel.decompiler.languages.java.ast.ImportDeclaration; 6 | import com.strobel.decompiler.languages.java.ast.PackageDeclaration; 7 | import com.strobel.decompiler.languages.java.ast.transforms.IAstTransform; 8 | 9 | public final class DropImportAstTransform implements IAstTransform { 10 | public static final DropImportAstTransform INSTANCE = new DropImportAstTransform(); 11 | 12 | private DropImportAstTransform() { 13 | } 14 | 15 | @Override 16 | public void run(AstNode compilationUnit) { 17 | compilationUnit.acceptVisitor(new Visitor(), null); 18 | } 19 | 20 | static class Visitor extends DepthFirstAstVisitor { 21 | @Override 22 | public Void visitPackageDeclaration(PackageDeclaration node, Void data) { 23 | node.remove(); 24 | return null; 25 | } 26 | 27 | @Override 28 | public Void visitImportDeclaration(ImportDeclaration node, Void data) { 29 | node.remove(); 30 | return null; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/source/vineflower/EnigmaFernflowerLogger.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.source.vineflower; 2 | 3 | import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger; 4 | import org.tinylog.Logger; 5 | 6 | public class EnigmaFernflowerLogger extends IFernflowerLogger { 7 | private static final String MESSAGE_TEMPLATE = "[Vineflower] {}"; 8 | 9 | @Override 10 | public void writeMessage(String message, Severity severity) { 11 | if (accepts(severity)) { 12 | switch (severity) { 13 | case TRACE -> Logger.debug(MESSAGE_TEMPLATE, message); 14 | case INFO -> Logger.info(MESSAGE_TEMPLATE, message); 15 | case WARN -> Logger.warn(MESSAGE_TEMPLATE, message); 16 | case ERROR -> Logger.error(MESSAGE_TEMPLATE, message); 17 | } 18 | } 19 | } 20 | 21 | @Override 22 | public void writeMessage(String message, Severity severity, Throwable t) { 23 | if (accepts(severity)) { 24 | switch (severity) { 25 | case TRACE -> Logger.debug(t, MESSAGE_TEMPLATE, message); 26 | case INFO -> Logger.info(t, MESSAGE_TEMPLATE, message); 27 | case WARN -> Logger.warn(t, MESSAGE_TEMPLATE, message); 28 | case ERROR -> Logger.error(t, MESSAGE_TEMPLATE, message); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/util/validation/PrintNotifier.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.util.validation; 2 | 3 | import org.tinylog.Logger; 4 | 5 | import java.util.Arrays; 6 | 7 | /** 8 | * A simple notifier that prints messages to the console. 9 | */ 10 | public class PrintNotifier implements ValidationContext.Notifier { 11 | public static final PrintNotifier INSTANCE = new PrintNotifier(); 12 | 13 | @Override 14 | public void notify(ParameterizedMessage message) { 15 | formatMessage(message); 16 | } 17 | 18 | @Override 19 | public boolean verifyWarning(ParameterizedMessage message) { 20 | return true; 21 | } 22 | 23 | public static void formatMessage(ParameterizedMessage message) { 24 | String text = message.getText(); 25 | String longText = message.getLongText(); 26 | 27 | log(message.message().getType(), text); 28 | 29 | if (!longText.isEmpty()) { 30 | Arrays.stream(longText.split("\n")).forEach(s -> log(message.message().getType(), s)); 31 | } 32 | } 33 | 34 | private static void log(Message.Type level, String message, Object... args) { 35 | switch (level) { 36 | case WARNING -> Logger.warn(message, args); 37 | case ERROR -> Logger.error(message, args); 38 | default -> Logger.info(message, args); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/TestDeobfuscator.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma; 2 | 3 | import org.quiltmc.enigma.api.Enigma; 4 | import org.quiltmc.enigma.api.EnigmaProject; 5 | import org.quiltmc.enigma.api.ProgressListener; 6 | import org.quiltmc.enigma.api.class_provider.ClasspathClassProvider; 7 | import org.quiltmc.enigma.api.source.Decompiler; 8 | import org.quiltmc.enigma.api.source.Decompilers; 9 | import org.quiltmc.enigma.api.source.SourceSettings; 10 | import org.junit.jupiter.api.Test; 11 | 12 | import java.io.IOException; 13 | import java.nio.file.Path; 14 | 15 | public class TestDeobfuscator { 16 | private static final Path JAR = TestUtil.obfJar("lone_class"); 17 | 18 | private EnigmaProject openProject() throws IOException { 19 | Enigma enigma = Enigma.create(); 20 | return enigma.openJar(JAR, new ClasspathClassProvider(), ProgressListener.createEmpty()); 21 | } 22 | 23 | @Test 24 | public void loadJar() throws Exception { 25 | this.openProject(); 26 | } 27 | 28 | @Test 29 | public void decompileClass() throws Exception { 30 | EnigmaProject project = this.openProject(); 31 | Decompiler decompiler = Decompilers.CFR.create(project.getClassProvider(), new SourceSettings(false, false)); 32 | 33 | decompiler.getUndocumentedSource("a").asString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /enigma-server/src/main/java/org/quiltmc/enigma/network/packet/s2c/UserListS2CPacket.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network.packet.s2c; 2 | 3 | import org.quiltmc.enigma.network.ClientPacketHandler; 4 | import org.quiltmc.enigma.network.packet.Packet; 5 | import org.quiltmc.enigma.network.packet.PacketHelper; 6 | 7 | import java.io.DataInput; 8 | import java.io.DataOutput; 9 | import java.io.IOException; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class UserListS2CPacket implements Packet { 14 | private final List users; 15 | 16 | public UserListS2CPacket(List users) { 17 | this.users = users; 18 | } 19 | 20 | public UserListS2CPacket(DataInput input) throws IOException { 21 | int len = input.readUnsignedShort(); 22 | this.users = new ArrayList<>(len); 23 | for (int i = 0; i < len; i++) { 24 | this.users.add(PacketHelper.readString(input)); 25 | } 26 | } 27 | 28 | @Override 29 | public void write(DataOutput output) throws IOException { 30 | output.writeShort(this.users.size()); 31 | for (String user : this.users) { 32 | PacketHelper.writeString(output, user); 33 | } 34 | } 35 | 36 | @Override 37 | public void handle(ClientPacketHandler handler) { 38 | handler.updateUserList(this.users); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/docker/InheritanceTreeDocker.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.docker; 2 | 3 | import org.quiltmc.enigma.gui.Gui; 4 | import org.quiltmc.enigma.gui.renderer.InheritanceTreeCellRenderer; 5 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 6 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 7 | import org.quiltmc.enigma.api.translation.representation.entry.MethodEntry; 8 | 9 | import javax.annotation.Nullable; 10 | import javax.swing.tree.DefaultMutableTreeNode; 11 | 12 | public class InheritanceTreeDocker extends AbstractInheritanceTreeDocker { 13 | public InheritanceTreeDocker(Gui gui) { 14 | super(gui, new InheritanceTreeCellRenderer(gui), "docker.inheritance.inactive", "docker.inheritance.not_found"); 15 | } 16 | 17 | @Nullable 18 | @Override 19 | protected DefaultMutableTreeNode getNodeFor(Entry entry) { 20 | if (entry instanceof ClassEntry classEntry) { 21 | return this.gui.getController().getClassInheritance(classEntry); 22 | } else if (entry instanceof MethodEntry methodEntry) { 23 | return this.gui.getController().getMethodInheritance(methodEntry); 24 | } 25 | 26 | return null; 27 | } 28 | 29 | @Override 30 | public String getId() { 31 | return "inheritance"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/analysis/index/jar/LibrariesJarIndex.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.analysis.index.jar; 2 | 3 | import org.quiltmc.enigma.api.ProgressListener; 4 | import org.quiltmc.enigma.api.class_provider.ProjectClassProvider; 5 | import org.quiltmc.enigma.impl.analysis.index.AbstractJarIndex; 6 | 7 | public class LibrariesJarIndex extends AbstractJarIndex { 8 | public LibrariesJarIndex(JarIndexer... indexers) { 9 | super(indexers); 10 | } 11 | 12 | /** 13 | * Creates an empty index, configured to use all built-in indexers. 14 | * @return the newly created index 15 | */ 16 | public static JarIndex empty() { 17 | EntryIndex entryIndex = new EntryIndex(); 18 | ReferenceIndex referenceIndex = new ReferenceIndex(); 19 | InheritanceIndex inheritanceIndex = new InheritanceIndex(entryIndex); 20 | return new LibrariesJarIndex(entryIndex, inheritanceIndex, referenceIndex, new BridgeMethodIndex(entryIndex, inheritanceIndex, referenceIndex)); 21 | } 22 | 23 | @Override 24 | public String getTranslationKey() { 25 | return "progress.jar.indexing.libraries"; 26 | } 27 | 28 | @Override 29 | public void indexJar(ProjectClassProvider classProvider, ProgressListener progress) { 30 | this.indexJar(classProvider.getLibraryClassNames(), classProvider, progress); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/translation/mapping/TestV2Main.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.translation.mapping; 2 | 3 | import org.quiltmc.enigma.api.Enigma; 4 | import org.quiltmc.enigma.api.ProgressListener; 5 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 6 | import org.quiltmc.enigma.api.translation.mapping.MappingDelta; 7 | import org.quiltmc.enigma.api.translation.mapping.serde.MappingFileNameFormat; 8 | import org.quiltmc.enigma.api.translation.mapping.serde.MappingSaveParameters; 9 | import org.quiltmc.enigma.api.translation.mapping.serde.enigma.EnigmaMappingsReader; 10 | import org.quiltmc.enigma.api.translation.mapping.tree.EntryTree; 11 | 12 | import java.nio.file.Path; 13 | import java.nio.file.Paths; 14 | 15 | public final class TestV2Main { 16 | public static void main(String... args) throws Exception { 17 | Path path = TestTinyV2InnerClasses.MAPPINGS; 18 | 19 | MappingSaveParameters parameters = new MappingSaveParameters(MappingFileNameFormat.BY_DEOBF, false, "obf", "deobf"); 20 | 21 | EntryTree tree = EnigmaMappingsReader.DIRECTORY.read(path); 22 | Path file = Paths.get("currentYarn.tiny"); 23 | 24 | Enigma.create().getReadWriteService(file).get().write(tree, MappingDelta.added(tree), file, ProgressListener.createEmpty(), parameters); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /enigma-server/src/test/java/org/quiltmc/enigma/network/ServerAddressTest.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | import static org.junit.jupiter.api.Assertions.assertNull; 7 | 8 | public class ServerAddressTest { 9 | @Test 10 | public void validAddresses() { 11 | assertEquals(ServerAddress.of("127.0.0.1", 22), ServerAddress.from("127.0.0.1", 22)); 12 | assertEquals(ServerAddress.of("::1", 80), ServerAddress.from("[::1]:80", 22)); 13 | assertEquals(ServerAddress.of("dblsaiko.net", 22), ServerAddress.from("dblsaiko.net", 22)); 14 | assertEquals(ServerAddress.of("f00f:efee::127.0.0.1", 724), ServerAddress.from("[f00f:efee::127.0.0.1]:724", 22)); 15 | assertEquals(ServerAddress.of("aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:70", 22), ServerAddress.from("aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:aaaa:70", 22)); 16 | assertEquals(ServerAddress.of("::1", 22), ServerAddress.from("::1", 22)); 17 | assertEquals(ServerAddress.of("0", 22), ServerAddress.from("0", 22)); 18 | } 19 | 20 | @Test 21 | public void invalidAddresses() { 22 | assertNull(ServerAddress.from("127.0.0.1:-72", 22)); 23 | assertNull(ServerAddress.from("127.0.0.1:100000000", 22)); 24 | assertNull(ServerAddress.from("127.0.0.1:lmao", 22)); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/properties/ConfigurableLafThemeProperties.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.properties; 2 | 3 | import org.quiltmc.config.api.Config; 4 | import org.quiltmc.enigma.gui.config.theme.look_and_feel.ConfigurableFlatLaf; 5 | import org.quiltmc.enigma.gui.config.theme.properties.composite.LookAndFeelProperties; 6 | import org.quiltmc.enigma.gui.config.theme.properties.composite.SyntaxPaneProperties; 7 | import org.quiltmc.enigma.gui.util.ListUtil; 8 | 9 | import javax.swing.LookAndFeel; 10 | import java.util.List; 11 | 12 | public abstract class ConfigurableLafThemeProperties extends NonSystemLafThemeProperties { 13 | private final LookAndFeelProperties lookAndFeelProperties; 14 | 15 | protected ConfigurableLafThemeProperties( 16 | SyntaxPaneProperties syntaxPaneColors, 17 | LookAndFeelProperties lookAndFeelColors, 18 | List creators 19 | ) { 20 | super(syntaxPaneColors, ListUtil.prepend(lookAndFeelColors, creators)); 21 | this.lookAndFeelProperties = lookAndFeelColors; 22 | } 23 | 24 | @Override 25 | protected final LookAndFeel getLaf() { 26 | return this.getLafConstructor().construct(this.lookAndFeelProperties.colors); 27 | } 28 | 29 | protected abstract ConfigurableFlatLaf.Constructor getLafConstructor(); 30 | } 31 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/docker/ImplementationsTreeDocker.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.docker; 2 | 3 | import org.quiltmc.enigma.gui.Gui; 4 | import org.quiltmc.enigma.gui.renderer.ImplementationsTreeCellRenderer; 5 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 6 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 7 | import org.quiltmc.enigma.api.translation.representation.entry.MethodEntry; 8 | 9 | import javax.annotation.Nullable; 10 | import javax.swing.tree.DefaultMutableTreeNode; 11 | 12 | public class ImplementationsTreeDocker extends AbstractInheritanceTreeDocker { 13 | public ImplementationsTreeDocker(Gui gui) { 14 | super(gui, new ImplementationsTreeCellRenderer(gui), "docker.implementations.inactive", "docker.implementations.not_found"); 15 | } 16 | 17 | @Nullable 18 | @Override 19 | protected DefaultMutableTreeNode getNodeFor(Entry entry) { 20 | if (entry instanceof ClassEntry classEntry) { 21 | return this.gui.getController().getClassImplementations(classEntry); 22 | } else if (entry instanceof MethodEntry methodEntry) { 23 | return this.gui.getController().getMethodImplementations(methodEntry); 24 | } 25 | 26 | return null; 27 | } 28 | 29 | @Override 30 | public String getId() { 31 | return "implementations"; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/source/bytecode/BytecodeDecompiler.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.source.bytecode; 2 | 3 | import org.quiltmc.enigma.api.class_provider.ClassProvider; 4 | import org.quiltmc.enigma.api.source.Decompiler; 5 | import org.quiltmc.enigma.api.source.Source; 6 | import org.quiltmc.enigma.api.source.SourceSettings; 7 | import org.quiltmc.enigma.api.translation.mapping.EntryRemapper; 8 | import org.objectweb.asm.tree.ClassNode; 9 | 10 | import javax.annotation.Nullable; 11 | import java.util.Collection; 12 | import java.util.List; 13 | 14 | public class BytecodeDecompiler implements Decompiler { 15 | private final ClassProvider classProvider; 16 | 17 | public BytecodeDecompiler(ClassProvider classProvider, SourceSettings settings) { 18 | this.classProvider = classProvider; 19 | } 20 | 21 | @Override 22 | public Source getSource(String className, @Nullable EntryRemapper remapper) { 23 | String rootClassName = className.contains("$") ? className.substring(0, className.indexOf("$")) : className; 24 | Collection classes = this.classProvider.getClasses(rootClassName); 25 | List otherClassNodes = classes.stream().filter(s -> !rootClassName.equals(s)).map(this.classProvider::get).toList(); 26 | 27 | return new BytecodeSource(this.classProvider.get(className), otherClassNodes, remapper); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/NetConfig.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config; 2 | 3 | import org.quiltmc.config.api.ReflectiveConfig; 4 | import org.quiltmc.config.api.annotations.Comment; 5 | import org.quiltmc.config.api.annotations.SerializedNameConvention; 6 | import org.quiltmc.config.api.metadata.NamingSchemes; 7 | import org.quiltmc.config.api.values.TrackedValue; 8 | import org.quiltmc.enigma.network.EnigmaServer; 9 | 10 | @SerializedNameConvention(NamingSchemes.SNAKE_CASE) 11 | public final class NetConfig extends ReflectiveConfig { 12 | @Comment("Your username for multiplayer mapping. Defaults to the system username.") 13 | public final TrackedValue username = this.value(System.getProperty("user.name", "user")); 14 | public final TrackedValue password = this.value(""); 15 | public final TrackedValue remoteAddress = this.value(""); 16 | public final TrackedValue serverPassword = this.value(""); 17 | @Comment("The network port of this server. Interesting fact! The default was decided pretty much at random in the Fabric discord: https://discordapp.com/channels/507304429255393322/566418023372816394/700292322918793347 (server: https://fabricmc.net/discuss/). You can still blame 2xsaiko if it conflicts with anything.") 18 | public final TrackedValue serverPort = this.value(EnigmaServer.DEFAULT_PORT); 19 | } 20 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/source/procyon/index/SourceIndexVisitor.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.source.procyon.index; 2 | 3 | import com.strobel.assembler.metadata.TypeDefinition; 4 | import com.strobel.decompiler.languages.java.ast.AstNode; 5 | import com.strobel.decompiler.languages.java.ast.DepthFirstAstVisitor; 6 | import com.strobel.decompiler.languages.java.ast.Keys; 7 | import com.strobel.decompiler.languages.java.ast.TypeDeclaration; 8 | import org.quiltmc.enigma.api.source.SourceIndex; 9 | import org.quiltmc.enigma.impl.source.procyon.EntryParser; 10 | import org.quiltmc.enigma.api.translation.representation.entry.ClassDefEntry; 11 | 12 | public class SourceIndexVisitor extends DepthFirstAstVisitor { 13 | @Override 14 | public Void visitTypeDeclaration(TypeDeclaration node, SourceIndex index) { 15 | TypeDefinition def = node.getUserData(Keys.TYPE_DEFINITION); 16 | ClassDefEntry classEntry = EntryParser.parse(def); 17 | index.addDeclaration(TokenFactory.createToken(index, node.getNameToken()), classEntry); 18 | 19 | return node.acceptVisitor(new SourceIndexClassVisitor(classEntry), index); 20 | } 21 | 22 | @Override 23 | protected Void visitChildren(AstNode node, SourceIndex index) { 24 | for (final AstNode child : node.getChildren()) { 25 | child.acceptVisitor(this, index); 26 | } 27 | 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/TestEntryOrdering.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 6 | 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class TestEntryOrdering { 12 | @Test 13 | public void testClasses() { 14 | ClassEntry c01 = new ClassEntry("pkg/1665BFCF"); 15 | ClassEntry c02 = new ClassEntry("pkg/2BB46638"); 16 | ClassEntry c03 = new ClassEntry("pkg/2BB46638$AC5B2355"); 17 | ClassEntry c04 = new ClassEntry("pkg/6F88ECF"); 18 | ClassEntry c05 = new ClassEntry("pkg/6F88ECF$57C7176A"); 19 | ClassEntry c06 = new ClassEntry("pkg/FEE829A0"); 20 | ClassEntry c07 = new ClassEntry("pkg/FEE829A0$3A78ECBB"); 21 | ClassEntry c08 = new ClassEntry("pkg/294e9cee/77C137C5"); 22 | ClassEntry c09 = new ClassEntry("pkg/294e9cee/7daa64ce/158D6D20"); 23 | ClassEntry c10 = new ClassEntry("pkg/72e178af/225B1ACE"); 24 | ClassEntry c11 = new ClassEntry("pkg/aaf82493/80c8afa8/2760E349"); 25 | 26 | List classes = new ArrayList<>(List.of(c07, c06, c01, c10, c05, c09, c03, c11, c08, c04, c02)); 27 | 28 | Collections.sort(classes); 29 | Assertions.assertEquals(List.of(c01, c02, c03, c04, c05, c06, c07, c08, c09, c10, c11), classes); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /enigma/src/testFixtures/java/org/quiltmc/enigma/TestUtil.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma; 2 | 3 | import org.quiltmc.enigma.util.validation.ParameterizedMessage; 4 | import org.quiltmc.enigma.util.validation.ValidationContext; 5 | 6 | import java.net.URISyntaxException; 7 | import java.nio.file.Path; 8 | 9 | public final class TestUtil { 10 | private TestUtil() { 11 | } 12 | 13 | public static Path obfJar(String name) { 14 | return Path.of("").toAbsolutePath().getParent().resolve("enigma/build/test-obf/%s.jar".formatted(name)); 15 | } 16 | 17 | public static Path deobfJar(String name) { 18 | return Path.of("").toAbsolutePath().getParent().resolve("enigma/build/test-deobf/%s.jar".formatted(name)); 19 | } 20 | 21 | public static Path getResource(String name) { 22 | try { 23 | return Path.of(TestUtil.class.getResource(name).toURI()); 24 | } catch (URISyntaxException e) { 25 | throw new RuntimeException(e); 26 | } 27 | } 28 | 29 | public static ValidationContext newVC() { 30 | return new ValidationContext(notifier()); 31 | } 32 | 33 | private static ValidationContext.Notifier notifier() { 34 | return new ValidationContext.Notifier() { 35 | @Override 36 | public void notify(ParameterizedMessage message) { 37 | } 38 | 39 | @Override 40 | public boolean verifyWarning(ParameterizedMessage message) { 41 | return true; 42 | } 43 | }; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/serde/FileType.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping.serde; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * A file type. It can be either a single file with an extension, or a directory. 7 | * 8 | *

If a file type has multiple extensions, the default for saving will be the first one. 9 | */ 10 | public interface FileType { 11 | /** 12 | * Gets all possible extensions for this type of mapping file. 13 | * If {@link #isDirectory()} is {@code true}, this will return the types of mapping allowed inside the directory. 14 | * @return the file extension options 15 | */ 16 | List getExtensions(); 17 | 18 | /** 19 | * {@return whether this file type is a directory} 20 | */ 21 | boolean isDirectory(); 22 | 23 | record Directory(File file) implements FileType { 24 | @Override 25 | public List getExtensions() { 26 | return this.file.getExtensions(); 27 | } 28 | 29 | public boolean isDirectory() { 30 | return true; 31 | } 32 | } 33 | 34 | record File(List extensions) implements FileType { 35 | public File(String... extensions) { 36 | this(List.of(extensions)); 37 | } 38 | 39 | @Override 40 | public List getExtensions() { 41 | return this.extensions; 42 | } 43 | 44 | public boolean isDirectory() { 45 | return false; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/tree/EntryTreeUtil.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping.tree; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 4 | 5 | public class EntryTreeUtil { 6 | /** 7 | * Inserts all entries from both trees into a merged {@link HashEntryTree}, without performing any modifications on the original trees. 8 | * In the case of a conflict, the mappings from the right tree will overwrite the left tree. 9 | * @return the merged tree 10 | */ 11 | public static EntryTree merge(EntryTree leftTree, EntryTree rightTree) { 12 | EntryTree merged = new HashEntryTree<>(); 13 | 14 | rightTree.iterator().forEachRemaining(merged::insert); 15 | leftTree.iterator().forEachRemaining(node -> { 16 | if (merged.contains(node.getEntry())) { 17 | EntryMapping oldMapping = merged.get(node.getEntry()); 18 | EntryMapping newMapping = node.getValue(); 19 | 20 | if (oldMapping != null && newMapping != null) { 21 | EntryMapping mergedMapping = EntryMapping.merge(oldMapping, newMapping); 22 | merged.insert(node.getEntry(), mergedMapping); 23 | } else if (oldMapping == null && newMapping != null) { 24 | merged.insert(node); 25 | } 26 | } else { 27 | merged.insert(node); 28 | } 29 | }); 30 | 31 | return merged; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/theme/properties/SystemThemeProperties.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config.theme.properties; 2 | 3 | import org.quiltmc.config.api.Config; 4 | import org.quiltmc.enigma.gui.config.theme.properties.composite.SyntaxPaneProperties; 5 | import org.quiltmc.enigma.gui.util.ListUtil; 6 | 7 | import javax.swing.UIManager; 8 | import javax.swing.UnsupportedLookAndFeelException; 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class SystemThemeProperties extends ThemeProperties { 13 | public SystemThemeProperties() { 14 | this(new SyntaxPaneProperties(), new ArrayList<>()); 15 | } 16 | 17 | protected SystemThemeProperties( 18 | SyntaxPaneProperties syntaxPaneColors, 19 | List creators 20 | ) { 21 | super( 22 | syntaxPaneColors, 23 | // this is duplicated from NonConfigurableLafThemeProperties 24 | // because java doesn't support multi-inheritance 25 | ListUtil.prepend(NonConfigurableLafThemeProperties::createComment, creators) 26 | ); 27 | } 28 | 29 | @Override 30 | public void setGlobalLaf() throws 31 | UnsupportedLookAndFeelException, ClassNotFoundException, 32 | InstantiationException, IllegalAccessException { 33 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 34 | } 35 | 36 | @Override 37 | public boolean onlyScaleFonts() { 38 | return false; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /enigma-cli/src/main/java/org/quiltmc/enigma/command/DeobfuscateCommand.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.command; 2 | 3 | import org.quiltmc.enigma.api.EnigmaProject; 4 | import org.quiltmc.enigma.api.ProgressListener; 5 | 6 | import java.nio.file.Path; 7 | 8 | public class DeobfuscateCommand extends Command { 9 | public DeobfuscateCommand() { 10 | super(Argument.INPUT_JAR.required(), 11 | Argument.OUTPUT_JAR.required(), 12 | Argument.INPUT_MAPPINGS.optional() 13 | ); 14 | } 15 | 16 | @Override 17 | public void run(String... args) throws Exception { 18 | Path fileJarIn = getReadablePath(this.getArg(args, 0)); 19 | Path fileJarOut = getWritableFile(this.getArg(args, 1)).toPath(); 20 | Path fileMappings = getReadablePath(this.getArg(args, 2)); 21 | 22 | run(fileJarIn, fileJarOut, fileMappings); 23 | } 24 | 25 | @Override 26 | public String getName() { 27 | return "deobfuscate"; 28 | } 29 | 30 | @Override 31 | public String getDescription() { 32 | return "Remaps all names in the jar according to the provided mappings."; 33 | } 34 | 35 | public static void run(Path fileJarIn, Path fileJarOut, Path fileMappings) throws Exception { 36 | EnigmaProject project = openProject(fileJarIn, fileMappings); 37 | 38 | ProgressListener progress = new ConsoleProgressListener(); 39 | 40 | EnigmaProject.JarExport jar = project.exportRemappedJar(progress); 41 | jar.write(fileJarOut, progress); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/service/EnigmaServiceType.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.service; 2 | 3 | public record EnigmaServiceType( 4 | String key, 5 | boolean activeByDefault 6 | ) { 7 | public static EnigmaServiceType create(String key, boolean activeByDefault) { 8 | return new EnigmaServiceType<>(key, activeByDefault); 9 | } 10 | 11 | public static EnigmaServiceType create(String key) { 12 | return new EnigmaServiceType<>(key, false); 13 | } 14 | 15 | /** 16 | * The unique key of this service type. 17 | */ 18 | @Override 19 | public String key() { 20 | return this.key; 21 | } 22 | 23 | /** 24 | * Whether this service type is active by default. 25 | * If {@code true}, this service type will be active without being explicitly enabled in the profile. 26 | */ 27 | @Override 28 | public boolean activeByDefault() { 29 | return this.activeByDefault; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return this.key; 35 | } 36 | 37 | @Override 38 | public int hashCode() { 39 | return this.key.hashCode(); 40 | } 41 | 42 | @Override 43 | public boolean equals(Object obj) { 44 | if (obj == this) return true; 45 | 46 | if (obj instanceof EnigmaServiceType serviceType) { 47 | return serviceType.key.equals(this.key); 48 | } 49 | 50 | return false; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/renderer/ImplementationsTreeCellRenderer.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.renderer; 2 | 3 | import org.quiltmc.enigma.api.analysis.tree.ClassImplementationsTreeNode; 4 | import org.quiltmc.enigma.api.analysis.tree.MethodImplementationsTreeNode; 5 | import org.quiltmc.enigma.gui.Gui; 6 | import org.quiltmc.enigma.gui.config.Config; 7 | import org.quiltmc.enigma.gui.util.GuiUtil; 8 | 9 | import javax.swing.JTree; 10 | import javax.swing.tree.DefaultTreeCellRenderer; 11 | import java.awt.Component; 12 | 13 | public class ImplementationsTreeCellRenderer extends DefaultTreeCellRenderer { 14 | private final Gui gui; 15 | 16 | public ImplementationsTreeCellRenderer(Gui gui) { 17 | this.gui = gui; 18 | } 19 | 20 | @Override 21 | public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { 22 | Component c = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); 23 | 24 | this.setForeground(Config.getCurrentSyntaxPaneColors().text.value()); 25 | 26 | if (value instanceof ClassImplementationsTreeNode node) { 27 | this.setIcon(GuiUtil.getClassIcon(this.gui, node.getClassEntry())); 28 | } else if (value instanceof MethodImplementationsTreeNode node) { 29 | this.setIcon(GuiUtil.getMethodIcon(node.getMethodEntry())); 30 | } 31 | 32 | return c; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/source/Decompilers.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.source; 2 | 3 | import org.quiltmc.enigma.api.class_provider.ClassProvider; 4 | import org.quiltmc.enigma.api.service.DecompilerService; 5 | import org.quiltmc.enigma.impl.source.bytecode.BytecodeDecompiler; 6 | import org.quiltmc.enigma.impl.source.cfr.CfrDecompiler; 7 | import org.quiltmc.enigma.impl.source.procyon.ProcyonDecompiler; 8 | import org.quiltmc.enigma.impl.source.vineflower.VineflowerDecompiler; 9 | 10 | import java.util.function.BiFunction; 11 | 12 | public class Decompilers { 13 | public static final DecompilerService VINEFLOWER = create("enigma:vineflower", VineflowerDecompiler::new); 14 | public static final DecompilerService PROCYON = create("enigma:procyon", ProcyonDecompiler::new); 15 | public static final DecompilerService CFR = create("enigma:cfr", CfrDecompiler::new); 16 | public static final DecompilerService BYTECODE = create("enigma:bytecode", BytecodeDecompiler::new); 17 | 18 | private static DecompilerService create(String id, BiFunction factory) { 19 | return new DecompilerService() { 20 | @Override 21 | public Decompiler create(ClassProvider classProvider, SourceSettings settings) { 22 | return factory.apply(classProvider, settings); 23 | } 24 | 25 | @Override 26 | public String getId() { 27 | return id; 28 | } 29 | }; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/source/procyon/transformer/RemoveObjectCasts.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.source.procyon.transformer; 2 | 3 | import com.strobel.assembler.metadata.BuiltinTypes; 4 | import com.strobel.decompiler.DecompilerContext; 5 | import com.strobel.decompiler.languages.java.ast.AstNode; 6 | import com.strobel.decompiler.languages.java.ast.CastExpression; 7 | import com.strobel.decompiler.languages.java.ast.ContextTrackingVisitor; 8 | import com.strobel.decompiler.languages.java.ast.transforms.IAstTransform; 9 | 10 | /** 11 | * Created by Thiakil on 11/07/2018. 12 | */ 13 | public class RemoveObjectCasts implements IAstTransform { 14 | private final DecompilerContext _context; 15 | 16 | public RemoveObjectCasts(DecompilerContext context) { 17 | this._context = context; 18 | } 19 | 20 | @Override 21 | public void run(AstNode compilationUnit) { 22 | compilationUnit.acceptVisitor(new Visitor(this._context), null); 23 | } 24 | 25 | private static final class Visitor extends ContextTrackingVisitor { 26 | private Visitor(DecompilerContext context) { 27 | super(context); 28 | } 29 | 30 | @Override 31 | public Void visitCastExpression(CastExpression node, Void data) { 32 | if (node.getType().toTypeReference().equals(BuiltinTypes.Object)) { 33 | node.replaceWith(node.getExpression()); 34 | } 35 | 36 | return super.visitCastExpression(node, data); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/source/vineflower/EnigmaResultSaver.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.source.vineflower; 2 | 3 | import org.quiltmc.enigma.api.source.SourceIndex; 4 | import org.jetbrains.java.decompiler.main.extern.IResultSaver; 5 | 6 | import java.util.jar.Manifest; 7 | 8 | public class EnigmaResultSaver implements IResultSaver { 9 | private final SourceIndex index; 10 | 11 | public EnigmaResultSaver(SourceIndex index) { 12 | this.index = index; 13 | } 14 | 15 | @Override 16 | public void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping) { 17 | this.index.setSource(content); 18 | } 19 | 20 | @Override 21 | public void saveFolder(String path) { 22 | } 23 | 24 | @Override 25 | public void copyFile(String source, String path, String entryName) { 26 | } 27 | 28 | @Override 29 | public void createArchive(String path, String archiveName, Manifest manifest) { 30 | } 31 | 32 | @Override 33 | public void saveDirEntry(String path, String archiveName, String entryName) { 34 | } 35 | 36 | @Override 37 | public void copyEntry(String source, String path, String archiveName, String entry) { 38 | } 39 | 40 | @Override 41 | public void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content) { 42 | } 43 | 44 | @Override 45 | public void closeArchive(String path, String archiveName) { 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/translation/mapping/tree/EntryTree.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.translation.mapping.tree; 2 | 3 | import org.quiltmc.enigma.api.translation.Translatable; 4 | import org.quiltmc.enigma.api.translation.TranslateResult; 5 | import org.quiltmc.enigma.api.translation.Translator; 6 | import org.quiltmc.enigma.api.translation.mapping.EntryMap; 7 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 8 | import org.quiltmc.enigma.api.translation.mapping.EntryResolver; 9 | import org.quiltmc.enigma.api.translation.representation.entry.Entry; 10 | 11 | import java.util.Collection; 12 | import java.util.stream.Stream; 13 | import javax.annotation.Nullable; 14 | 15 | public interface EntryTree extends EntryMap, Iterable>, Translatable { 16 | Collection> getChildren(Entry entry); 17 | 18 | Collection> getSiblings(Entry entry); 19 | 20 | @Nullable 21 | EntryTreeNode findNode(Entry entry); 22 | 23 | Stream> getRootNodes(); 24 | 25 | @Override 26 | default TranslateResult> extendedTranslate(Translator translator, EntryResolver resolver, EntryMap mappings) { 27 | return TranslateResult.ungrouped(this.translate(translator, resolver, mappings)); 28 | } 29 | 30 | @Override 31 | EntryTree translate(Translator translator, EntryResolver resolver, EntryMap mappings); 32 | } 33 | -------------------------------------------------------------------------------- /enigma-cli/src/main/java/org/quiltmc/enigma/command/CommandsUtil.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.command; 2 | 3 | import org.quiltmc.enigma.api.Enigma; 4 | import org.quiltmc.enigma.api.service.ReadWriteService; 5 | import org.quiltmc.enigma.api.translation.mapping.serde.MappingsReader; 6 | import org.quiltmc.enigma.api.translation.mapping.serde.MappingsWriter; 7 | 8 | import java.nio.file.Path; 9 | 10 | public class CommandsUtil { 11 | public static ReadWriteService getReadWriteService(Enigma enigma, Path file) { 12 | var service = enigma.getReadWriteService(file); 13 | if (service.isEmpty()) { 14 | throw new UnsupportedOperationException("No reader/writer found for file \"" + file + "\""); 15 | } 16 | 17 | return service.get(); 18 | } 19 | 20 | public static MappingsReader getReader(Enigma enigma, Path file) { 21 | ReadWriteService service = getReadWriteService(enigma, file); 22 | 23 | if (!service.supportsReading()) { 24 | throw new UnsupportedOperationException("Read/write service for file \"" + file + "\" does not support reading!"); 25 | } 26 | 27 | return service; 28 | } 29 | 30 | public static MappingsWriter getWriter(Enigma enigma, Path file) { 31 | ReadWriteService service = getReadWriteService(enigma, file); 32 | 33 | if (!service.supportsWriting()) { 34 | throw new UnsupportedOperationException("Read/write service for file \"" + file + "\" does not support writing!"); 35 | } 36 | 37 | return service; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/class_provider/CombiningClassProvider.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.class_provider; 2 | 3 | import org.objectweb.asm.tree.ClassNode; 4 | 5 | import javax.annotation.Nullable; 6 | import java.util.ArrayList; 7 | import java.util.Arrays; 8 | import java.util.Collection; 9 | import java.util.List; 10 | 11 | /** 12 | * Combines a list of {@link ClassProvider}s into one, calling each one in a row 13 | * until one can provide the class. 14 | */ 15 | public class CombiningClassProvider implements ClassProvider { 16 | private final ClassProvider[] classProviders; 17 | 18 | public CombiningClassProvider(ClassProvider... classProviders) { 19 | this.classProviders = classProviders; 20 | } 21 | 22 | @Override 23 | @Nullable 24 | public ClassNode get(String name) { 25 | for (ClassProvider cp : this.classProviders) { 26 | ClassNode node = cp.get(name); 27 | 28 | if (node != null) { 29 | return node; 30 | } 31 | } 32 | 33 | return null; 34 | } 35 | 36 | @Override 37 | public Collection getClassNames() { 38 | return Arrays.stream(this.classProviders).flatMap(c -> c.getClassNames().stream()).toList(); 39 | } 40 | 41 | @Override 42 | public List getClasses(String className) { 43 | List classes = new ArrayList<>(); 44 | for (ClassProvider cp : this.classProviders) { 45 | classes.addAll(cp.getClasses(className)); 46 | } 47 | 48 | return classes; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /enigma-server/src/test/java/org/quiltmc/enigma/network/DummyClientPacketHandler.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.network; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.EntryChange; 4 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 5 | import org.quiltmc.enigma.api.translation.mapping.tree.EntryTree; 6 | import org.quiltmc.enigma.network.packet.Packet; 7 | 8 | import java.util.List; 9 | import java.util.concurrent.CountDownLatch; 10 | 11 | public class DummyClientPacketHandler implements ClientPacketHandler { 12 | TestEnigmaClient client; 13 | CountDownLatch disconnectFromServerLatch = new CountDownLatch(1); 14 | 15 | @Override 16 | public void openMappings(EntryTree mappings) { 17 | } 18 | 19 | @Override 20 | public boolean applyChangeFromServer(EntryChange change) { 21 | return true; 22 | } 23 | 24 | @Override 25 | public void disconnectIfConnected(String reason) { 26 | if (this.client != null) { 27 | this.client.disconnect(); 28 | } 29 | 30 | if (this.disconnectFromServerLatch != null) { 31 | this.disconnectFromServerLatch.countDown(); 32 | } 33 | } 34 | 35 | @Override 36 | public void sendPacket(Packet packet) { 37 | if (this.client != null) { 38 | this.client.sendPacket(packet); 39 | } 40 | } 41 | 42 | @Override 43 | public void addMessage(ServerMessage message) { 44 | } 45 | 46 | @Override 47 | public void updateUserList(List users) { 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/bridge/BaseClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.bridge; 2 | 3 | // a 4 | public class BaseClass { 5 | // a 6 | private int x; 7 | // b 8 | private int y; 9 | // c 10 | private int z; 11 | 12 | // (III)V 13 | public BaseClass(int x, int y, int z) { 14 | this.x = x; 15 | this.y = y; 16 | this.z = z; 17 | } 18 | 19 | // a()I 20 | public int getX() { 21 | return this.x; 22 | } 23 | 24 | // b()I 25 | public int getY() { 26 | return this.y; 27 | } 28 | 29 | // c()I 30 | public int getZ() { 31 | return this.z; 32 | } 33 | 34 | // d()La; 35 | public BaseClass foo() { 36 | System.out.println("foo"); 37 | return this; 38 | } 39 | 40 | // a(I)La; 41 | public BaseClass foo(int x) { 42 | return new BaseClass(x, 0, 0); 43 | } 44 | 45 | // a(II)La; 46 | public BaseClass foo(int x, int y) { 47 | return this.bar(1); 48 | } 49 | 50 | // e()La; 51 | public BaseClass bar() { 52 | return new BaseClass(0, 0, 0); 53 | } 54 | 55 | // b(I)La; 56 | public BaseClass bar(int x) { 57 | return this.baz(1, x); 58 | } 59 | 60 | // c(I)La; 61 | public BaseClass baz(int xz) { 62 | return new BaseClass(xz, 0, xz); 63 | } 64 | 65 | public BaseClass whee(long xyz, int q, int w) { 66 | return new BaseClass((int) xyz, (int) xyz, (int) xyz); 67 | } 68 | 69 | // b(II)La; 70 | public BaseClass baz(int xz, int y) { 71 | if (y == 0) { 72 | return this; 73 | } 74 | 75 | return new BaseClass(this.getX(), y, xz); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/config/DevSection.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.config; 2 | 3 | import org.quiltmc.config.api.ReflectiveConfig; 4 | import org.quiltmc.config.api.annotations.Processor; 5 | import org.quiltmc.config.api.annotations.SerializedNameConvention; 6 | import org.quiltmc.config.api.metadata.NamingSchemes; 7 | import org.quiltmc.config.api.values.TrackedValue; 8 | import org.quiltmc.enigma.api.source.DecompiledClassSource; 9 | import org.quiltmc.enigma.gui.network.IntegratedEnigmaClient; 10 | 11 | @SerializedNameConvention(NamingSchemes.SNAKE_CASE) 12 | public class DevSection extends ReflectiveConfig.Section { 13 | public transient boolean anyEnabled = false; 14 | 15 | public final TrackedValue showMappingSourcePlugin = this.value(false); 16 | 17 | @Processor("processDebugTokenHighlights") 18 | public final TrackedValue debugTokenHighlights = this.value(false); 19 | 20 | @Processor("processLogClientPackets") 21 | public final TrackedValue logClientPackets = this.value(false); 22 | 23 | @SuppressWarnings("unused") 24 | public void processDebugTokenHighlights(TrackedValue.Builder builder) { 25 | builder.callback(trackedValue -> DecompiledClassSource.DEBUG_TOKEN_HIGHLIGHTS = trackedValue.value()); 26 | } 27 | 28 | @SuppressWarnings("unused") 29 | public void processLogClientPackets(TrackedValue.Builder builder) { 30 | builder.callback(trackedValue -> IntegratedEnigmaClient.LOG_PACKETS = trackedValue.value()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/analysis/ClassLoaderClassProvider.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.analysis; 2 | 3 | import org.objectweb.asm.tree.ClassNode; 4 | import org.quiltmc.enigma.api.class_provider.ClassProvider; 5 | import org.quiltmc.enigma.util.AsmUtil; 6 | 7 | import javax.annotation.Nullable; 8 | import java.io.IOException; 9 | import java.util.Collection; 10 | import java.util.List; 11 | 12 | /** 13 | * Note: currently unfinished. Only indexes record and object. 14 | */ 15 | public class ClassLoaderClassProvider implements ClassProvider { 16 | private final ClassLoader loader; 17 | 18 | public ClassLoaderClassProvider(ClassLoader loader) { 19 | this.loader = loader; 20 | } 21 | 22 | @Nullable 23 | @Override 24 | @SuppressWarnings("ConstantConditions") 25 | public ClassNode get(String name) { 26 | try { 27 | Class clazz = this.loader.loadClass(name); 28 | String className = clazz.getName(); 29 | int i = className.lastIndexOf('.'); 30 | String resourceName = className.substring(i != -1 ? i + 1 : 0) + ".class"; 31 | 32 | try (var resource = clazz.getResourceAsStream(resourceName)) { 33 | return AsmUtil.bytesToNode(resource.readAllBytes()); 34 | } catch (IOException ignored) { 35 | // ignored 36 | } 37 | } catch (ClassNotFoundException ignored) { 38 | // ignored 39 | } 40 | 41 | return null; 42 | } 43 | 44 | @Override 45 | public Collection getClassNames() { 46 | return List.of("java.lang.Object", "java.lang.Record"); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/bytecode/translator/TranslationRecordComponentVisitor.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.bytecode.translator; 2 | 3 | import org.quiltmc.enigma.api.translation.Translator; 4 | import org.quiltmc.enigma.api.translation.representation.TypeDescriptor; 5 | import org.objectweb.asm.AnnotationVisitor; 6 | import org.objectweb.asm.RecordComponentVisitor; 7 | import org.objectweb.asm.TypePath; 8 | 9 | public class TranslationRecordComponentVisitor extends RecordComponentVisitor { 10 | private final Translator translator; 11 | 12 | public TranslationRecordComponentVisitor(Translator translator, int api, RecordComponentVisitor rcv) { 13 | super(api, rcv); 14 | this.translator = translator; 15 | } 16 | 17 | @Override 18 | public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 19 | TypeDescriptor typeDesc = this.translator.translate(new TypeDescriptor(desc)); 20 | AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible); 21 | return new TranslationAnnotationVisitor(this.translator, typeDesc.getTypeEntry(), this.api, av); 22 | } 23 | 24 | @Override 25 | public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { 26 | TypeDescriptor typeDesc = this.translator.translate(new TypeDescriptor(desc)); 27 | AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible); 28 | return new TranslationAnnotationVisitor(this.translator, typeDesc.getTypeEntry(), this.api, av); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/class_provider/CachingClassProvider.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.class_provider; 2 | 3 | import com.google.common.cache.Cache; 4 | import com.google.common.cache.CacheBuilder; 5 | import org.objectweb.asm.tree.ClassNode; 6 | 7 | import javax.annotation.Nullable; 8 | import java.util.Collection; 9 | import java.util.Optional; 10 | import java.util.concurrent.ExecutionException; 11 | import java.util.concurrent.TimeUnit; 12 | 13 | /** 14 | * Wraps a ClassProvider to provide caching and synchronization. 15 | */ 16 | public class CachingClassProvider implements ClassProvider { 17 | private final ClassProvider classProvider; 18 | private final Cache> cache = CacheBuilder.newBuilder() 19 | .maximumSize(128) 20 | .expireAfterAccess(1, TimeUnit.MINUTES) 21 | .concurrencyLevel(1) 22 | .build(); 23 | 24 | public CachingClassProvider(ClassProvider classProvider) { 25 | this.classProvider = classProvider; 26 | } 27 | 28 | @Override 29 | @Nullable 30 | public ClassNode get(String name) { 31 | try { 32 | return this.cache.get(name, () -> Optional.ofNullable(this.classProvider.get(name))).orElse(null); 33 | } catch (ExecutionException e) { 34 | throw new RuntimeException(e); 35 | } 36 | } 37 | 38 | @Override 39 | public Collection getClassNames() { 40 | return this.classProvider.getClassNames(); 41 | } 42 | 43 | @Override 44 | public Collection getClasses(String className) { 45 | return this.classProvider.getClasses(className); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/translation/mapping/TestComments.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.translation.mapping; 2 | 3 | import org.quiltmc.enigma.TestUtil; 4 | import org.quiltmc.enigma.api.Enigma; 5 | import org.quiltmc.enigma.api.ProgressListener; 6 | import org.quiltmc.enigma.api.translation.mapping.EntryMapping; 7 | import org.quiltmc.enigma.api.translation.mapping.MappingDelta; 8 | import org.quiltmc.enigma.api.translation.mapping.serde.MappingFileNameFormat; 9 | import org.quiltmc.enigma.api.translation.mapping.serde.MappingParseException; 10 | import org.quiltmc.enigma.api.translation.mapping.serde.MappingSaveParameters; 11 | import org.quiltmc.enigma.api.translation.mapping.serde.enigma.EnigmaMappingsReader; 12 | import org.quiltmc.enigma.api.translation.mapping.tree.EntryTree; 13 | import org.junit.jupiter.api.Test; 14 | 15 | import java.io.IOException; 16 | import java.nio.file.Path; 17 | 18 | public class TestComments { 19 | private static final Path DIRECTORY = TestUtil.getResource("/comments/"); 20 | 21 | @Test 22 | public void testParseAndWrite() throws IOException, MappingParseException { 23 | MappingSaveParameters params = new MappingSaveParameters(MappingFileNameFormat.BY_DEOBF, false, "intermediary", "named"); 24 | EntryTree mappings = EnigmaMappingsReader.DIRECTORY.read( 25 | DIRECTORY); 26 | 27 | Path file = DIRECTORY.resolve("convertedtiny.tiny"); 28 | 29 | Enigma.create().getReadWriteService(file).get().write(mappings, MappingDelta.added(mappings), file, ProgressListener.createEmpty(), params); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/translation/mapping/serde/MappingHelper.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.translation.mapping.serde; 2 | 3 | public final class MappingHelper { 4 | private static final String TO_ESCAPE = "\\\n\r\0\t"; 5 | private static final String ESCAPED = "\\nr0t"; 6 | 7 | public static String escape(String raw) { 8 | StringBuilder builder = new StringBuilder(raw.length() + 1); 9 | for (int i = 0; i < raw.length(); i++) { 10 | final char c = raw.charAt(i); 11 | final int r = TO_ESCAPE.indexOf(c); 12 | if (r < 0) { 13 | builder.append(c); 14 | } else { 15 | builder.append('\\').append(ESCAPED.charAt(r)); 16 | } 17 | } 18 | 19 | return builder.toString(); 20 | } 21 | 22 | public static String unescape(String str) { 23 | int pos = str.indexOf('\\'); 24 | if (pos < 0) return str; 25 | 26 | StringBuilder ret = new StringBuilder(str.length() - 1); 27 | int start = 0; 28 | 29 | do { 30 | ret.append(str, start, pos); 31 | pos++; 32 | int type; 33 | 34 | if (pos >= str.length()) { 35 | throw new RuntimeException("incomplete escape sequence at the end"); 36 | } else if ((type = ESCAPED.indexOf(str.charAt(pos))) < 0) { 37 | throw new RuntimeException("invalid escape character: \\" + str.charAt(pos)); 38 | } else { 39 | ret.append(TO_ESCAPE.charAt(type)); 40 | } 41 | 42 | start = pos + 1; 43 | } while ((pos = str.indexOf('\\', start)) >= 0); 44 | 45 | ret.append(str, start, str.length()); 46 | 47 | return ret.toString(); 48 | } 49 | 50 | private MappingHelper() { 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /enigma-swing/src/main/java/org/quiltmc/enigma/gui/dialog/ChangeDialog.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.gui.dialog; 2 | 3 | import org.quiltmc.enigma.gui.config.keybind.KeyBinds; 4 | import org.quiltmc.enigma.gui.util.GuiUtil; 5 | import org.quiltmc.enigma.util.I18n; 6 | 7 | import java.awt.BorderLayout; 8 | import java.awt.Dialog; 9 | import java.awt.Window; 10 | import javax.swing.JButton; 11 | import javax.swing.JDialog; 12 | import javax.swing.JLabel; 13 | import javax.swing.JPanel; 14 | 15 | public class ChangeDialog { 16 | public static void show(Window parent) { 17 | // init frame 18 | JDialog frame = new JDialog(parent, I18n.translate("menu.view.change.title"), Dialog.DEFAULT_MODALITY_TYPE); 19 | JPanel textPanel = new JPanel(); 20 | JPanel buttonPanel = new JPanel(); 21 | frame.setLayout(new BorderLayout()); 22 | frame.add(BorderLayout.NORTH, textPanel); 23 | frame.add(BorderLayout.SOUTH, buttonPanel); 24 | 25 | // show text 26 | JLabel text = new JLabel((I18n.translate("menu.view.change.summary"))); 27 | text.setHorizontalAlignment(JLabel.CENTER); 28 | textPanel.add(text); 29 | 30 | // show ok button 31 | JButton okButton = new JButton(I18n.translate("prompt.ok")); 32 | buttonPanel.add(okButton); 33 | okButton.addActionListener(event -> frame.dispose()); 34 | okButton.addKeyListener(GuiUtil.onKeyPress(e -> { 35 | if (KeyBinds.EXIT.matches(e)) { 36 | frame.dispose(); 37 | } 38 | })); 39 | 40 | // show the frame 41 | frame.pack(); 42 | frame.setResizable(false); 43 | frame.setLocationRelativeTo(parent); 44 | frame.setVisible(true); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/analysis/index/jar/MainJarIndex.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.analysis.index.jar; 2 | 3 | import org.quiltmc.enigma.api.ProgressListener; 4 | import org.quiltmc.enigma.api.class_provider.ProjectClassProvider; 5 | import org.quiltmc.enigma.impl.analysis.index.AbstractJarIndex; 6 | 7 | public class MainJarIndex extends AbstractJarIndex { 8 | public MainJarIndex(JarIndexer... indexers) { 9 | super(indexers); 10 | } 11 | 12 | /** 13 | * Creates an empty index, configured to use all built-in indexers. 14 | * @return the newly created index 15 | */ 16 | public static JarIndex empty() { 17 | EntryIndex entryIndex = new EntryIndex(); 18 | InheritanceIndex inheritanceIndex = new InheritanceIndex(entryIndex); 19 | ReferenceIndex referenceIndex = new ReferenceIndex(); 20 | BridgeMethodIndex bridgeMethodIndex = new BridgeMethodIndex(entryIndex, inheritanceIndex, referenceIndex); 21 | PackageVisibilityIndex packageVisibilityIndex = new PackageVisibilityIndex(); 22 | EnclosingMethodIndex enclosingMethodIndex = new EnclosingMethodIndex(); 23 | LambdaIndex lambdaIndex = new LambdaIndex(); 24 | return new MainJarIndex(entryIndex, inheritanceIndex, referenceIndex, bridgeMethodIndex, packageVisibilityIndex, enclosingMethodIndex, lambdaIndex); 25 | } 26 | 27 | @Override 28 | public String getTranslationKey() { 29 | return "progress.jar.indexing.jar"; 30 | } 31 | 32 | @Override 33 | public void indexJar(ProjectClassProvider classProvider, ProgressListener progress) { 34 | this.indexJar(classProvider.getMainClassNames(), classProvider, progress); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/analysis/index/jar/JarIndex.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.analysis.index.jar; 2 | 3 | import com.google.common.collect.ListMultimap; 4 | import org.quiltmc.enigma.api.ProgressListener; 5 | import org.quiltmc.enigma.api.class_provider.ProjectClassProvider; 6 | import org.quiltmc.enigma.api.translation.mapping.EntryResolver; 7 | import org.quiltmc.enigma.api.translation.representation.entry.ClassEntry; 8 | import org.quiltmc.enigma.api.translation.representation.entry.ParentedEntry; 9 | 10 | public interface JarIndex extends JarIndexer { 11 | /** 12 | * Gets the index associated with the provided class. 13 | * @param clazz the class of the index desired - for example, {@code PackageIndex.class} 14 | * @return the index 15 | */ 16 | T getIndex(Class clazz); 17 | 18 | /** 19 | * Runs every configured indexer over the provided jar. 20 | * @param classProvider a class provider containing all classes in the jar and libraries 21 | * @param progress a progress listener to track index completion 22 | */ 23 | void indexJar(ProjectClassProvider classProvider, ProgressListener progress); 24 | 25 | /** 26 | * {@return an entry resolver with this index's contents as context} 27 | */ 28 | EntryResolver getEntryResolver(); 29 | 30 | /** 31 | * {@return a map of all entries, keyed by their class} 32 | */ 33 | ListMultimap> getChildrenByClass(); 34 | 35 | /** 36 | * @param internalName 37 | * {@return whether this class is included in this index} 38 | */ 39 | boolean isIndexed(String internalName); 40 | } 41 | -------------------------------------------------------------------------------- /enigma/src/test/java/org/quiltmc/enigma/input/bridge/SubClass.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.input.bridge; 2 | 3 | // c extends a 4 | public class SubClass extends BaseClass { 5 | // (III)V 6 | public SubClass(int x, int y, int z) { 7 | super(x, y, z); 8 | } 9 | 10 | // f()Lc; 11 | // bridge d()La; 12 | public SubClass foo() { 13 | System.out.println("bar"); 14 | return this; 15 | } 16 | 17 | // d(I)Lc; 18 | // bridge a(I)La; 19 | public SubClass foo(int x) { 20 | return null; 21 | } 22 | 23 | // c(II)Lc; 24 | // bridge a(II)La; 25 | public SubClass foo(int x, int y) { 26 | return this.baz(y); 27 | } 28 | 29 | // g()Lc; 30 | // bridge e()La; 31 | public SubClass bar() { 32 | return new SubClass(this.getX(), -1, 0); 33 | } 34 | 35 | // e(I)Lc; 36 | // bridge b(I)La; 37 | public SubClass bar(int x) { 38 | return this.baz(-1, x); 39 | } 40 | 41 | // f(I)Lc; 42 | // bridge c(I)La; 43 | public SubClass baz(int xz) { 44 | return new SubClass(xz, this.getY(), this.getZ() + xz); 45 | } 46 | 47 | // d(II)Lc; 48 | // bridge b(II)La; 49 | public SubClass baz(int xz, int y) { 50 | if (y == 0) { 51 | return this; 52 | } 53 | 54 | return new SubClass(this.getX() - xz, this.getY() * y, this.getZ() + xz); 55 | } 56 | 57 | // c$a extends c 58 | public static class InnerSubClass extends SubClass { 59 | // (III)V 60 | public InnerSubClass(int x, int y, int z) { 61 | super(x, y, z); 62 | } 63 | 64 | // bridge d()La; 65 | // bridge a(I)La; 66 | // bridge a(II)La; 67 | // bridge e()La; 68 | // bridge b(I)La; 69 | // bridge c(I)La; 70 | // bridge b(II)La; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/util/EntryTreePrinter.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.util; 2 | 3 | import org.quiltmc.enigma.api.translation.mapping.tree.EntryTree; 4 | import org.quiltmc.enigma.api.translation.mapping.tree.EntryTreeNode; 5 | 6 | import java.io.PrintWriter; 7 | 8 | public final class EntryTreePrinter { 9 | private final PrintWriter output; 10 | 11 | public EntryTreePrinter(PrintWriter output) { 12 | this.output = output; 13 | } 14 | 15 | public static void print(PrintWriter output, EntryTree tree) { 16 | var printer = new EntryTreePrinter(output); 17 | printer.print(tree); 18 | } 19 | 20 | public void print(EntryTree tree) { 21 | this.output.println(tree); 22 | this.output.flush(); 23 | 24 | var iterator = tree.getRootNodes().iterator(); 25 | while (iterator.hasNext()) { 26 | var node = iterator.next(); 27 | this.printNode(node, iterator.hasNext(), ""); 28 | } 29 | } 30 | 31 | private void printNode(EntryTreeNode node, boolean hasNext, String indent) { 32 | this.output.print(indent); 33 | 34 | this.output.print(hasNext ? "├── " : "└── "); 35 | this.output.print(node.getEntry()); 36 | 37 | if (node.hasValue()) { 38 | this.output.print(" -> "); 39 | this.output.println(node.getValue()); 40 | } else { 41 | this.output.println(); 42 | } 43 | 44 | this.output.flush(); 45 | 46 | var iterator = node.getChildNodes().iterator(); 47 | while (iterator.hasNext()) { 48 | var child = iterator.next(); 49 | var childIndent = indent + (hasNext ? "│ " : " "); 50 | 51 | this.printNode(child, iterator.hasNext(), childIndent); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/impl/bytecode/translator/TranslationFieldVisitor.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.impl.bytecode.translator; 2 | 3 | import org.quiltmc.enigma.api.translation.Translator; 4 | import org.quiltmc.enigma.api.translation.representation.TypeDescriptor; 5 | import org.quiltmc.enigma.api.translation.representation.entry.FieldDefEntry; 6 | import org.objectweb.asm.AnnotationVisitor; 7 | import org.objectweb.asm.FieldVisitor; 8 | import org.objectweb.asm.TypePath; 9 | 10 | public class TranslationFieldVisitor extends FieldVisitor { 11 | private final FieldDefEntry fieldEntry; 12 | private final Translator translator; 13 | 14 | public TranslationFieldVisitor(Translator translator, FieldDefEntry fieldEntry, int api, FieldVisitor fv) { 15 | super(api, fv); 16 | this.translator = translator; 17 | this.fieldEntry = fieldEntry; 18 | } 19 | 20 | @Override 21 | public AnnotationVisitor visitAnnotation(String desc, boolean visible) { 22 | TypeDescriptor typeDesc = this.translator.translate(new TypeDescriptor(desc)); 23 | AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible); 24 | return new TranslationAnnotationVisitor(this.translator, typeDesc.getTypeEntry(), this.api, av); 25 | } 26 | 27 | @Override 28 | public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { 29 | TypeDescriptor typeDesc = this.translator.translate(new TypeDescriptor(desc)); 30 | AnnotationVisitor av = super.visitAnnotation(typeDesc.toString(), visible); 31 | return new TranslationAnnotationVisitor(this.translator, typeDesc.getTypeEntry(), this.api, av); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /enigma/src/main/java/org/quiltmc/enigma/api/source/Token.java: -------------------------------------------------------------------------------- 1 | package org.quiltmc.enigma.api.source; 2 | 3 | public class Token implements Comparable { 4 | public int start; 5 | public int end; 6 | public String text; 7 | 8 | public Token(int start, int end, String text) { 9 | this.start = start; 10 | this.end = end; 11 | this.text = text; 12 | } 13 | 14 | public int length() { 15 | return this.end - this.start; 16 | } 17 | 18 | public int getRenameOffset(String to) { 19 | return to.length() - this.length(); 20 | } 21 | 22 | public void rename(StringBuilder source, String to) { 23 | int oldEnd = this.end; 24 | this.text = to; 25 | this.end = this.start + to.length(); 26 | 27 | source.replace(this.start, oldEnd, to); 28 | } 29 | 30 | public Token move(int offset) { 31 | Token token = new Token(this.start + offset, this.end + offset, null); 32 | token.text = this.text; 33 | return token; 34 | } 35 | 36 | public boolean contains(int pos) { 37 | return pos >= this.start && pos <= this.end; 38 | } 39 | 40 | @Override 41 | public int compareTo(Token other) { 42 | return this.start - other.start; 43 | } 44 | 45 | @Override 46 | public boolean equals(Object other) { 47 | return other instanceof Token token && this.equals(token); 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | return this.start * 37 + this.end; 53 | } 54 | 55 | public boolean equals(Token other) { 56 | return this.start == other.start && this.end == other.end && this.text.equals(other.text); 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return String.format("[%d,%d]", this.start, this.end); 62 | } 63 | } 64 | --------------------------------------------------------------------------------