├── .gitignore ├── Decompiler ├── build.gradle.kts └── src │ └── main │ └── java │ └── me │ └── f1nal │ └── trinity │ └── decompiler │ ├── code │ ├── ClassNameConstants.java │ ├── CodeConstants.java │ ├── ExceptionHandler.java │ ├── ExceptionTable.java │ ├── FullInstructionSequence.java │ ├── Instruction.java │ ├── InstructionSequence.java │ ├── JumpInstruction.java │ ├── SimpleInstructionSequence.java │ ├── SwitchInstruction.java │ ├── cfg │ │ ├── BasicBlock.java │ │ ├── ControlFlowGraph.java │ │ └── ExceptionRangeCFG.java │ └── interpreter │ │ └── InstructionImpact.java │ ├── main │ ├── AssertProcessor.java │ ├── CancellationManager.java │ ├── ClassReference14Processor.java │ ├── ClassWriter.java │ ├── ClassesProcessor.java │ ├── DecompilerContext.java │ ├── EnumProcessor.java │ ├── Fernflower.java │ ├── InitializerProcessor.java │ ├── collectors │ │ ├── BytecodeMappingTracer.java │ │ ├── BytecodeSourceMapper.java │ │ ├── CounterContainer.java │ │ ├── ImportCollector.java │ │ └── VarNamesCollector.java │ ├── decompiler │ │ ├── BaseDecompiler.java │ │ ├── ConsoleDecompiler.java │ │ └── PrintStreamLogger.java │ ├── extern │ │ ├── ClassFormatException.java │ │ ├── IBytecodeProvider.java │ │ ├── IFernflowerLogger.java │ │ ├── IFernflowerPreferences.java │ │ ├── IIdentifierRenamer.java │ │ └── IResultSaver.java │ └── rels │ │ ├── ClassWrapper.java │ │ ├── LambdaProcessor.java │ │ ├── MethodProcessorRunnable.java │ │ ├── MethodWrapper.java │ │ ├── NestedClassProcessor.java │ │ └── NestedMemberAccess.java │ ├── modules │ ├── code │ │ └── DeadCodeHelper.java │ ├── decompiler │ │ ├── ClasspathHelper.java │ │ ├── ClearStructHelper.java │ │ ├── ConcatenationHelper.java │ │ ├── DecHelper.java │ │ ├── DomHelper.java │ │ ├── ExitHelper.java │ │ ├── ExprProcessor.java │ │ ├── ExpressionStack.java │ │ ├── FinallyProcessor.java │ │ ├── IdeaNotNullHelper.java │ │ ├── IfHelper.java │ │ ├── InlineSingleBlockHelper.java │ │ ├── LabelHelper.java │ │ ├── LoopExtractHelper.java │ │ ├── MergeHelper.java │ │ ├── PPandMMHelper.java │ │ ├── PatternHelper.java │ │ ├── PrimitiveExpressionList.java │ │ ├── SecondaryFunctionsHelper.java │ │ ├── SequenceHelper.java │ │ ├── SimplifyExprentsHelper.java │ │ ├── StackVarsProcessor.java │ │ ├── StatEdge.java │ │ ├── StrongConnectivityHelper.java │ │ ├── SwitchHelper.java │ │ ├── decompose │ │ │ ├── DominatorEngine.java │ │ │ ├── DominatorTreeExceptionFilter.java │ │ │ ├── FastExtendedPostdominanceHelper.java │ │ │ ├── GenericDominatorEngine.java │ │ │ ├── IGraph.java │ │ │ └── IGraphNode.java │ │ ├── deobfuscator │ │ │ ├── ExceptionDeobfuscator.java │ │ │ └── IrreducibleCFGDeobfuscator.java │ │ ├── exps │ │ │ ├── AnnotationExprent.java │ │ │ ├── ArrayExprent.java │ │ │ ├── AssertExprent.java │ │ │ ├── AssignmentExprent.java │ │ │ ├── ConstExprent.java │ │ │ ├── ExitExprent.java │ │ │ ├── ExprUtil.java │ │ │ ├── Exprent.java │ │ │ ├── FieldExprent.java │ │ │ ├── FunctionExprent.java │ │ │ ├── IfExprent.java │ │ │ ├── InvocationExprent.java │ │ │ ├── MonitorExprent.java │ │ │ ├── NewExprent.java │ │ │ ├── SwitchExprent.java │ │ │ ├── TrinityBytecodeMarkerExprent.java │ │ │ └── VarExprent.java │ │ ├── sforms │ │ │ ├── DirectGraph.java │ │ │ ├── DirectNode.java │ │ │ ├── FlattenStatementsHelper.java │ │ │ ├── SSAConstructorSparseEx.java │ │ │ └── SSAUConstructorSparseEx.java │ │ ├── stats │ │ │ ├── BasicBlockStatement.java │ │ │ ├── CatchAllStatement.java │ │ │ ├── CatchStatement.java │ │ │ ├── DoStatement.java │ │ │ ├── DummyExitStatement.java │ │ │ ├── GeneralStatement.java │ │ │ ├── IfStatement.java │ │ │ ├── RootStatement.java │ │ │ ├── SequenceStatement.java │ │ │ ├── Statement.java │ │ │ ├── Statements.java │ │ │ ├── SwitchStatement.java │ │ │ └── SynchronizedStatement.java │ │ ├── typeann │ │ │ ├── TargetInfo.java │ │ │ ├── TypeAnnotation.java │ │ │ └── TypeAnnotationWriteHelper.java │ │ └── vars │ │ │ ├── CheckTypesResult.java │ │ │ ├── VarDefinitionHelper.java │ │ │ ├── VarProcessor.java │ │ │ ├── VarTypeProcessor.java │ │ │ ├── VarVersionEdge.java │ │ │ ├── VarVersionNode.java │ │ │ ├── VarVersionPair.java │ │ │ ├── VarVersionsGraph.java │ │ │ └── VarVersionsProcessor.java │ └── renamer │ │ ├── ClassWrapperNode.java │ │ ├── ConverterHelper.java │ │ ├── IdentifierConverter.java │ │ └── PoolInterceptor.java │ ├── output │ ├── IMemberDetails.java │ ├── OutputMember.java │ ├── OutputMemberVisitor.java │ ├── impl │ │ ├── BytecodeMarkerOutputMember.java │ │ ├── ClassOutputMember.java │ │ ├── CommentOutputMember.java │ │ ├── FieldDeclarationOutputMember.java │ │ ├── FieldOutputMember.java │ │ ├── KeywordOutputMember.java │ │ ├── KindOutputMember.java │ │ ├── MethodOutputMember.java │ │ ├── MethodStartEndOutputMember.java │ │ ├── NumberOutputMember.java │ │ ├── PackageOutputMember.java │ │ ├── StringOutputMember.java │ │ └── VariableOutputMember.java │ └── serialize │ │ └── OutputMemberSerializer.java │ ├── struct │ ├── ContextUnit.java │ ├── IDecompiledData.java │ ├── StructClass.java │ ├── StructContext.java │ ├── StructField.java │ ├── StructMember.java │ ├── StructMethod.java │ ├── StructRecordComponent.java │ ├── StructTypePathEntry.java │ ├── attr │ │ ├── StructAnnDefaultAttribute.java │ │ ├── StructAnnotationAttribute.java │ │ ├── StructAnnotationParameterAttribute.java │ │ ├── StructBootstrapMethodsAttribute.java │ │ ├── StructCodeAttribute.java │ │ ├── StructConstantValueAttribute.java │ │ ├── StructEnclosingMethodAttribute.java │ │ ├── StructExceptionsAttribute.java │ │ ├── StructGeneralAttribute.java │ │ ├── StructGenericSignatureAttribute.java │ │ ├── StructInnerClassesAttribute.java │ │ ├── StructLineNumberTableAttribute.java │ │ ├── StructLocalVariableTableAttribute.java │ │ ├── StructLocalVariableTypeTableAttribute.java │ │ ├── StructMethodParametersAttribute.java │ │ ├── StructModuleAttribute.java │ │ ├── StructPermittedSubclassesAttribute.java │ │ ├── StructRecordAttribute.java │ │ └── StructTypeAnnotationAttribute.java │ ├── consts │ │ ├── ConstantPool.java │ │ ├── LinkConstant.java │ │ ├── PooledConstant.java │ │ └── PrimitiveConstant.java │ ├── gen │ │ ├── DataPoint.java │ │ ├── FieldDescriptor.java │ │ ├── MethodDescriptor.java │ │ ├── NewClassNameBuilder.java │ │ ├── Type.java │ │ ├── VarType.java │ │ └── generics │ │ │ ├── GenericClassDescriptor.java │ │ │ ├── GenericFieldDescriptor.java │ │ │ ├── GenericMain.java │ │ │ ├── GenericMethodDescriptor.java │ │ │ └── GenericType.java │ ├── lazy │ │ └── LazyLoader.java │ └── match │ │ ├── IMatchable.java │ │ ├── MatchEngine.java │ │ └── MatchNode.java │ └── util │ ├── DataInputFullStream.java │ ├── FastFixedSetFactory.java │ ├── FastSparseSetFactory.java │ ├── InterpreterUtil.java │ ├── ListStack.java │ ├── SFormsFastMapDirect.java │ ├── TextBuffer.java │ ├── TextUtil.java │ └── VBStyleCollection.java ├── LICENSE ├── PLANNED.md ├── README.md ├── build.gradle.kts ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshots └── trinity.png ├── settings.gradle.kts └── src └── main ├── java └── me │ └── f1nal │ └── trinity │ ├── Main.java │ ├── Trinity.java │ ├── appdata │ ├── AppDataFile.java │ ├── AppDataManager.java │ ├── PreferencesFile.java │ ├── RecentDatabaseEntry.java │ ├── RecentDatabasesFile.java │ ├── StateFile.java │ ├── ThemeFileNew.java │ ├── gui │ │ └── GuiStateMemory.java │ ├── keybindings │ │ └── KeyBindingData.java │ └── shutdown │ │ └── ShutdownHook.java │ ├── database │ ├── ClassPath.java │ ├── Database.java │ ├── DatabaseLoader.java │ ├── IDatabaseSavable.java │ ├── compression │ │ ├── DatabaseCompressionType.java │ │ ├── DatabaseCompressionTypeGZIP.java │ │ ├── DatabaseCompressionTypeLZ4.java │ │ ├── DatabaseCompressionTypeLZMA2.java │ │ ├── DatabaseCompressionTypeManager.java │ │ └── DatabaseCompressionTypeRaw.java │ ├── converter │ │ └── ClassNodeConverter.java │ ├── datapool │ │ └── DataPool.java │ ├── inputs │ │ ├── AbstractProjectInputFile.java │ │ ├── ProjectInputFileFactory.java │ │ ├── UnreadClassBytes.java │ │ └── impl │ │ │ ├── ProjectInputClassFile.java │ │ │ └── ProjectInputJARFile.java │ ├── object │ │ ├── AbstractDatabaseObject.java │ │ ├── DatabaseClassDisplayName.java │ │ ├── DatabaseDecompiler.java │ │ ├── DatabaseFieldDisplayName.java │ │ ├── DatabaseMethodDisplayName.java │ │ ├── DatabasePackage.java │ │ └── DatabaseVariable.java │ ├── patches │ │ ├── AbstractDatabasePatch.java │ │ ├── DatabasePatchManager.java │ │ └── impl │ │ │ └── DatabasePatchMethodHierarchyNames.java │ └── semaphore │ │ ├── DatabaseLoaderRunnable.java │ │ ├── DatabaseSaveShutdownHook.java │ │ └── DatabaseSemaphore.java │ ├── decompiler │ ├── ClassDecompileTask.java │ ├── DecompiledClass.java │ ├── DecompiledMethod.java │ ├── Decompiler.java │ └── output │ │ ├── DecompilerComponentInitializer.java │ │ ├── DecompilerMemberReader.java │ │ ├── FontEnum.java │ │ ├── colors │ │ ├── ColoredImString.java │ │ ├── ColoredString.java │ │ ├── ColoredStringBuilder.java │ │ └── SupplierColoredString.java │ │ └── number │ │ ├── ConvertedFloatingPointNumberDisplayType.java │ │ ├── NumberDisplayType.java │ │ ├── NumberDisplayTypeBinary.java │ │ ├── NumberDisplayTypeChar.java │ │ ├── NumberDisplayTypeDecimal.java │ │ ├── NumberDisplayTypeEnum.java │ │ ├── NumberDisplayTypeHex.java │ │ └── NumberDisplayTypeOctal.java │ ├── events │ ├── EventClassModified.java │ ├── EventClassesLoaded.java │ ├── EventMemberRename.java │ ├── EventPackageStructureReload.java │ ├── EventRefreshDecompilerText.java │ └── api │ │ ├── EventManager.java │ │ └── IEventListener.java │ ├── execution │ ├── AccessFlags.java │ ├── ClassInput.java │ ├── ClassTarget.java │ ├── EntryPoint.java │ ├── Execution.java │ ├── FieldInput.java │ ├── Input.java │ ├── InputType.java │ ├── MemberDetails.java │ ├── MemberInput.java │ ├── MethodInput.java │ ├── access │ │ ├── AccessFlagsMaskProvider.java │ │ └── SimpleAccessFlagsMaskProvider.java │ ├── analysis │ │ └── CodeAnalysis.java │ ├── compile │ │ ├── ClassWriterTask.java │ │ ├── Console.java │ │ └── SafeClassWriter.java │ ├── exception │ │ ├── ClassNotPresentException.java │ │ ├── HandleNotPresentException.java │ │ ├── MethodNotPresentException.java │ │ └── MissingEntryPointException.java │ ├── hierarchy │ │ ├── ClassHierarchy.java │ │ ├── MethodHierarchy.java │ │ └── ObjectHierarchyLoadTask.java │ ├── labels │ │ ├── LabelTable.java │ │ └── MethodLabel.java │ ├── loading │ │ ├── AsynchronousLoad.java │ │ ├── ProgressiveLoadTask.java │ │ └── tasks │ │ │ ├── ClassInputReaderLoadTask.java │ │ │ └── DatabaseReadObjectsLoadTask.java │ ├── packages │ │ ├── ArchiveEntry.java │ │ ├── ArchiveEntryViewerType.java │ │ ├── Package.java │ │ ├── PackageHierarchy.java │ │ ├── ResourceArchiveEntry.java │ │ └── other │ │ │ └── ExtractArchiveEntryRunnable.java │ ├── patch │ │ ├── ClassPatchManager.java │ │ └── classes │ │ │ ├── ClassPatch.java │ │ │ └── impl │ │ │ ├── ClassPatchDoubleInterface.java │ │ │ ├── ClassPatchEnumFieldOrder.java │ │ │ └── ClassPatchNullAnnotation.java │ ├── var │ │ ├── ImmutableVariable.java │ │ ├── Variable.java │ │ └── VariableTable.java │ └── xref │ │ ├── AbstractXref.java │ │ ├── ClassXref.java │ │ ├── MemberXref.java │ │ ├── XrefAccessType.java │ │ ├── XrefKind.java │ │ ├── XrefMap.java │ │ └── where │ │ ├── XrefWhere.java │ │ ├── XrefWhereClass.java │ │ ├── XrefWhereField.java │ │ ├── XrefWhereMethod.java │ │ └── XrefWhereMethodInsn.java │ ├── gui │ ├── DisplayManager.java │ ├── backend │ │ ├── ImGuiApplication.java │ │ └── ImGuiWindow.java │ ├── components │ │ ├── AccessFlagsEditor.java │ │ ├── CheckboxComponent.java │ │ ├── ClassSelectComponent.java │ │ ├── ComponentId.java │ │ ├── DescribableEnumComboBox.java │ │ ├── FontAwesomeIcons.java │ │ ├── FontSettings.java │ │ ├── MemberSelectComponent.java │ │ ├── MemorableCheckboxComponent.java │ │ ├── MoveButtonEnum.java │ │ ├── NextButtonEnum.java │ │ ├── PackageSelectComponent.java │ │ ├── SearchBar.java │ │ ├── events │ │ │ ├── MouseClickEventHandler.java │ │ │ └── MouseClickType.java │ │ ├── filelist │ │ │ ├── FileListBoxComponent.java │ │ │ ├── ListedFile.java │ │ │ └── ListedFileFactory.java │ │ ├── filter │ │ │ ├── Filter.java │ │ │ ├── ListFilterComponent.java │ │ │ ├── SearchBarFilter.java │ │ │ └── kind │ │ │ │ ├── IKind.java │ │ │ │ ├── IKindType.java │ │ │ │ └── KindFilter.java │ │ ├── general │ │ │ ├── EnumComboBox.java │ │ │ ├── FileSelectorComponent.java │ │ │ ├── LabeledTextList.java │ │ │ ├── ListBoxComponent.java │ │ │ ├── TextFieldComponent.java │ │ │ └── table │ │ │ │ ├── ITableCellRenderer.java │ │ │ │ ├── IWhere.java │ │ │ │ ├── TableColumn.java │ │ │ │ ├── TableColumnRendererText.java │ │ │ │ ├── TableColumnRendererXrefWhere.java │ │ │ │ └── TableComponent.java │ │ ├── popup │ │ │ ├── MenuBarProgress.java │ │ │ ├── PopupItemBuilder.java │ │ │ ├── PopupMenu.java │ │ │ ├── PopupMenuBar.java │ │ │ ├── PopupMenuState.java │ │ │ └── items │ │ │ │ ├── PopupItem.java │ │ │ │ ├── PopupItemMenu.java │ │ │ │ ├── PopupItemMenuItem.java │ │ │ │ ├── PopupItemPredicate.java │ │ │ │ └── PopupItemSeparator.java │ │ ├── tabs │ │ │ ├── ListBoxTabsComponent.java │ │ │ └── TabFrame.java │ │ └── tree │ │ │ ├── GenericTreeNode.java │ │ │ ├── TreeComponent.java │ │ │ └── TreeNode.java │ ├── input │ │ ├── InputHandler.java │ │ ├── InputManager.java │ │ └── KeyCode.java │ ├── viewport │ │ ├── FontManager.java │ │ ├── MainMenuBar.java │ │ ├── NotificationRenderer.java │ │ ├── dnd │ │ │ └── DragAndDropHandler.java │ │ └── notifications │ │ │ ├── ICaption.java │ │ │ ├── Notification.java │ │ │ ├── NotificationType.java │ │ │ └── SimpleCaption.java │ └── windows │ │ ├── WindowManager.java │ │ ├── api │ │ ├── AbstractWindow.java │ │ ├── ClosableWindow.java │ │ ├── PopupWindow.java │ │ └── StaticWindow.java │ │ └── impl │ │ ├── AboutWindow.java │ │ ├── ClassPickerPopup.java │ │ ├── ExportJarWindow.java │ │ ├── LoadingDatabasePopup.java │ │ ├── PreferencesFrame.java │ │ ├── SavingDatabasePopup.java │ │ ├── assembler │ │ ├── AssemblerFrame.java │ │ ├── AssemblerInstructionDecoder.java │ │ ├── InstructionComponent.java │ │ ├── InstructionList.java │ │ ├── action │ │ │ ├── DeleteInstructionAction.java │ │ │ ├── DuplicateInstructionAction.java │ │ │ ├── EditInstructionAction.java │ │ │ ├── InsertInstructionAction.java │ │ │ └── InstructionAction.java │ │ ├── args │ │ │ ├── DetailsArgument.java │ │ │ ├── HandleArgument.java │ │ │ ├── InstructionOperand.java │ │ │ ├── InvokeDynamicArgument.java │ │ │ ├── LabelArgument.java │ │ │ ├── NumberArgument.java │ │ │ ├── StringArgument.java │ │ │ ├── TypeArgument.java │ │ │ └── VariableArgument.java │ │ ├── drag │ │ │ └── InstructionPosition.java │ │ ├── fields │ │ │ ├── InstructionField.java │ │ │ ├── LabelRefsField.java │ │ │ └── TextField.java │ │ ├── history │ │ │ ├── AssemblerHistory.java │ │ │ ├── AssemblerHistoryFrame.java │ │ │ ├── InstructionClearHistory.java │ │ │ ├── InstructionDeleteHistory.java │ │ │ ├── InstructionDragHistory.java │ │ │ ├── InstructionDuplicateHistory.java │ │ │ ├── InstructionInsertHistory.java │ │ │ └── InstructionSetHistory.java │ │ ├── line │ │ │ ├── AssemblerInstructionTable.java │ │ │ ├── Instruction2SourceMapping.java │ │ │ ├── InstructionDrag.java │ │ │ ├── InstructionReferenceArrow.java │ │ │ ├── MethodOpcodeSource.java │ │ │ └── SourceLineNumber.java │ │ └── popup │ │ │ ├── AssemblerBytecodeGoToIndexPopup.java │ │ │ └── edit │ │ │ ├── AssemblerEditInstructionPopup.java │ │ │ ├── EditField.java │ │ │ ├── EditFieldClass.java │ │ │ ├── EditFieldDescriptor.java │ │ │ ├── EditFieldInteger.java │ │ │ ├── EditFieldLabel.java │ │ │ ├── EditFieldString.java │ │ │ ├── EditFieldText.java │ │ │ ├── EditFieldVariable.java │ │ │ ├── EditingInstruction.java │ │ │ ├── InvalidEditInputException.java │ │ │ └── OpcodeClasses.java │ │ ├── classstructure │ │ ├── ClassStructure.java │ │ ├── ClassStructureWindow.java │ │ ├── StructureKind.java │ │ └── nodes │ │ │ ├── AbstractClassStructureNodeInput.java │ │ │ ├── ClassStructureNode.java │ │ │ ├── ClassStructureNodeClass.java │ │ │ ├── ClassStructureNodeField.java │ │ │ └── ClassStructureNodeMethod.java │ │ ├── constant │ │ ├── ConstantSearchFrame.java │ │ ├── ConstantViewCache.java │ │ ├── ConstantViewFrame.java │ │ └── search │ │ │ ├── ConstantSearchType.java │ │ │ ├── ConstantSearchTypeNull.java │ │ │ ├── ConstantSearchTypeNumber.java │ │ │ ├── ConstantSearchTypeString.java │ │ │ └── LdcConstantSearcher.java │ │ ├── cp │ │ ├── BrowserViewerNode.java │ │ ├── FileKind.java │ │ ├── IBrowserViewerNode.java │ │ ├── IRenameHandler.java │ │ ├── ProjectBrowserFrame.java │ │ ├── ProjectBrowserTreeNode.java │ │ ├── ProjectBrowserTreeNodeEntry.java │ │ ├── ProjectBrowserTreeNodePackage.java │ │ └── RenameHandler.java │ │ ├── entryviewer │ │ ├── ArchiveEntryViewerWindow.java │ │ └── impl │ │ │ ├── HexEditWindow.java │ │ │ ├── TextEditorWindow.java │ │ │ └── decompiler │ │ │ ├── DecompilerAutoScroll.java │ │ │ ├── DecompilerComponent.java │ │ │ ├── DecompilerComponentRenameState.java │ │ │ ├── DecompilerCoordinates.java │ │ │ ├── DecompilerCursor.java │ │ │ ├── DecompilerGhostTextRenderer.java │ │ │ ├── DecompilerHighlight.java │ │ │ ├── DecompilerLine.java │ │ │ ├── DecompilerLineText.java │ │ │ ├── DecompilerSelection.java │ │ │ └── DecompilerWindow.java │ │ ├── ldc │ │ ├── CstChooserPopup.java │ │ ├── CstType.java │ │ └── types │ │ │ └── CstTypeByte.java │ │ ├── project │ │ ├── create │ │ │ ├── AbstractProjectCreationTab.java │ │ │ ├── NewProjectFrame.java │ │ │ ├── misc │ │ │ │ ├── ClassPathViewerElement.java │ │ │ │ └── ClassPathViewerWindow.java │ │ │ └── tabs │ │ │ │ ├── ProjectCreationGeneral.java │ │ │ │ └── ProjectCreationInput.java │ │ └── settings │ │ │ ├── AbstractProjectSettingsTab.java │ │ │ ├── ProjectSettingsWindow.java │ │ │ └── tabs │ │ │ ├── ProjectSettingsGeneral.java │ │ │ └── ProjectSettingsStatistics.java │ │ ├── refactor │ │ └── GlobalRenameWindow.java │ │ ├── themes │ │ ├── ModifiedThemeState.java │ │ ├── ThemeEditorFrame.java │ │ └── ThemeNamePopup.java │ │ └── xref │ │ ├── SearchMaxDisplay.java │ │ ├── XrefView.java │ │ ├── XrefViewerFrame.java │ │ ├── builder │ │ ├── IXrefBuilderProvider.java │ │ ├── XrefBuilder.java │ │ ├── XrefBuilderClassRef.java │ │ ├── XrefBuilderMemberRef.java │ │ └── XrefBuilderMemberRefPattern.java │ │ └── search │ │ ├── XrefSearchFrame.java │ │ ├── XrefSearchType.java │ │ ├── XrefSearchTypeClass.java │ │ └── XrefSearchTypeMember.java │ ├── input │ └── JrtInput.java │ ├── keybindings │ ├── Bindable.java │ ├── KeyBindManager.java │ └── KeyBinding.java │ ├── logging │ └── Logging.java │ ├── refactor │ ├── RefactorManager.java │ └── globalrename │ │ ├── GlobalRenameType.java │ │ ├── api │ │ ├── GlobalRenameContext.java │ │ └── Rename.java │ │ └── impl │ │ ├── EnumFieldsGlobalRename.java │ │ ├── MixinGlobalRename.java │ │ └── fullrename │ │ ├── FullGlobalRename.java │ │ └── types │ │ ├── FullRenameClassMember.java │ │ ├── FullRenameMember.java │ │ └── impl │ │ ├── FullRenameClasses.java │ │ ├── FullRenameFields.java │ │ ├── FullRenameMethods.java │ │ └── FullRenamePackages.java │ ├── remap │ ├── DisplayName.java │ ├── IDisplayNameProvider.java │ ├── NameHeuristics.java │ ├── Remapper.java │ └── RenameType.java │ ├── theme │ ├── CodeColor.java │ ├── CodeColorScheme.java │ ├── ColorChangeListener.java │ ├── ImGuiColor.java │ ├── LabeledColor.java │ ├── Theme.java │ ├── ThemeColor.java │ ├── ThemeColorCategory.java │ └── ThemeManager.java │ └── util │ ├── AnnotationUtil.java │ ├── ByteUtil.java │ ├── ClassUtils.java │ ├── ColorUtil.java │ ├── DescriptorUtil.java │ ├── FileUtil.java │ ├── GuiUtil.java │ ├── IDescribable.java │ ├── INameable.java │ ├── InstructionUtil.java │ ├── NameUtil.java │ ├── PatternUtil.java │ ├── RandomUtil.java │ ├── SearchTermMatchable.java │ ├── SerializationUtil.java │ ├── Stopwatch.java │ ├── StringUtil.java │ ├── SystemUtil.java │ ├── TextFieldPatternMatchCallback.java │ ├── TimeUtil.java │ ├── TimedStopwatch.java │ ├── TypeUtil.java │ ├── UnsafeUtil.java │ ├── animation │ ├── Animation.java │ └── Easing.java │ ├── annotations │ └── AnnotationDescriptor.java │ ├── history │ ├── ChangeManager.java │ └── Changeable.java │ └── java │ ├── BiHashMap.java │ └── Callback.java └── resources ├── fonts ├── JetBrainsMonoNL-Regular.ttf ├── fa-solid-900.ttf ├── inter-regular.ttf └── zed-mono-regular.ttf ├── themes └── Gerry_Dark.theme └── wordlist /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | build/ 3 | !gradle/wrapper/gradle-wrapper.jar 4 | !**/src/main/**/build/ 5 | !**/src/test/**/build/ 6 | hs_err_** 7 | 8 | ### IntelliJ IDEA ### 9 | .idea/modules.xml 10 | .idea/jarRepositories.xml 11 | .idea/compiler.xml 12 | .idea/libraries/ 13 | *.iws 14 | *.iml 15 | *.ipr 16 | out/ 17 | !**/src/main/**/out/ 18 | !**/src/test/**/out/ 19 | 20 | ### Eclipse ### 21 | .apt_generated 22 | .classpath 23 | .factorypath 24 | .project 25 | .settings 26 | .springBeans 27 | .sts4-cache 28 | bin/ 29 | !**/src/main/**/bin/ 30 | !**/src/test/**/bin/ 31 | 32 | ### NetBeans ### 33 | /nbproject/private/ 34 | /nbbuild/ 35 | /dist/ 36 | /nbdist/ 37 | /.nb-gradle/ 38 | 39 | ### VS Code ### 40 | .vscode/ 41 | 42 | ### Mac OS ### 43 | .DS_Store 44 | /.idea/ -------------------------------------------------------------------------------- /Decompiler/build.gradle.kts: -------------------------------------------------------------------------------- 1 | plugins { 2 | id("java") 3 | } 4 | 5 | group = "me.f1nal" 6 | 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | testImplementation(platform("org.junit:junit-bom:5.9.1")) 13 | testImplementation("org.junit.jupiter:junit-jupiter") 14 | implementation("org.jetbrains:annotations:24.1.0") 15 | implementation("org.apache.commons:commons-lang3:3.14.0") 16 | rootProject.dependencies 17 | } 18 | 19 | tasks.test { 20 | useJUnitPlatform() 21 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/code/ClassNameConstants.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package me.f1nal.trinity.decompiler.code; 3 | 4 | public interface ClassNameConstants { 5 | String JAVA_LANG_STRING = "java/lang/String"; 6 | } 7 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/code/ExceptionHandler.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.code; 3 | 4 | import me.f1nal.trinity.decompiler.main.DecompilerContext; 5 | 6 | public class ExceptionHandler { 7 | public int from = 0; 8 | public int to = 0; 9 | public int handler = 0; 10 | 11 | public int from_instr = 0; 12 | public int to_instr = 0; 13 | public int handler_instr = 0; 14 | 15 | public String exceptionClass = null; 16 | 17 | public String toString() { 18 | String new_line_separator = DecompilerContext.getNewLineSeparator(); 19 | return "from: " + from + " to: " + to + " handler: " + handler + new_line_separator + 20 | "from_instr: " + from_instr + " to_instr: " + to_instr + " handler_instr: " + handler_instr + new_line_separator + 21 | "exceptionClass: " + exceptionClass + new_line_separator; 22 | } 23 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/code/ExceptionTable.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.code; 3 | 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | public class ExceptionTable { 8 | public static final ExceptionTable EMPTY = new ExceptionTable(Collections.emptyList()); 9 | 10 | private final List handlers; 11 | 12 | public ExceptionTable(List handlers) { 13 | this.handlers = handlers; 14 | } 15 | 16 | public List getHandlers() { 17 | return handlers; 18 | } 19 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/code/FullInstructionSequence.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.code; 3 | 4 | import me.f1nal.trinity.decompiler.util.VBStyleCollection; 5 | 6 | 7 | public class FullInstructionSequence extends InstructionSequence { 8 | 9 | // ***************************************************************************** 10 | // constructors 11 | // ***************************************************************************** 12 | 13 | public FullInstructionSequence(VBStyleCollection collinstr, ExceptionTable extable) { 14 | super(collinstr); 15 | this.exceptionTable = extable; 16 | 17 | // translate raw exception handlers to instr 18 | for (ExceptionHandler handler : extable.getHandlers()) { 19 | handler.from_instr = this.getPointerByAbsOffset(handler.from); 20 | handler.to_instr = this.getPointerByAbsOffset(handler.to); 21 | handler.handler_instr = this.getPointerByAbsOffset(handler.handler); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/code/JumpInstruction.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.code; 3 | 4 | public class JumpInstruction extends Instruction { 5 | public int destination; 6 | 7 | public JumpInstruction(int opcode, int group, boolean wide, int bytecodeVersion, int[] operands) { 8 | super(opcode, group, wide, bytecodeVersion, operands); 9 | } 10 | 11 | @Override 12 | public void initInstruction(InstructionSequence seq) { 13 | destination = seq.getPointerByRelOffset(this.operand(0)); 14 | } 15 | 16 | @Override 17 | public JumpInstruction clone() { 18 | JumpInstruction copy = (JumpInstruction)super.clone(); 19 | copy.destination = destination; 20 | return copy; 21 | } 22 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/code/SimpleInstructionSequence.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.code; 3 | 4 | import me.f1nal.trinity.decompiler.util.VBStyleCollection; 5 | 6 | public class SimpleInstructionSequence extends InstructionSequence { 7 | 8 | public SimpleInstructionSequence() { 9 | } 10 | 11 | public SimpleInstructionSequence(VBStyleCollection collinstr) { 12 | super(collinstr); 13 | } 14 | 15 | @Override 16 | public SimpleInstructionSequence clone() { 17 | SimpleInstructionSequence newseq = new SimpleInstructionSequence(collinstr.clone()); 18 | newseq.setPointer(this.getPointer()); 19 | 20 | return newseq; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/main/collectors/CounterContainer.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.main.collectors; 3 | 4 | public class CounterContainer { 5 | public static final int STATEMENT_COUNTER = 0; 6 | public static final int EXPRESSION_COUNTER = 1; 7 | public static final int VAR_COUNTER = 2; 8 | 9 | private final int[] values = new int[]{1, 1, 1}; 10 | 11 | public void setCounter(int counter, int value) { 12 | values[counter] = value; 13 | } 14 | 15 | public int getCounter(int counter) { 16 | return values[counter]; 17 | } 18 | 19 | public int getCounterAndIncrement(int counter) { 20 | return values[counter]++; 21 | } 22 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/main/collectors/VarNamesCollector.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.main.collectors; 3 | 4 | import java.util.Collection; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | public class VarNamesCollector { 9 | 10 | private final Set usedNames = new HashSet<>(); 11 | 12 | public VarNamesCollector() { } 13 | 14 | public VarNamesCollector(Collection setNames) { 15 | usedNames.addAll(setNames); 16 | } 17 | 18 | public void addName(String value) { 19 | usedNames.add(value); 20 | } 21 | 22 | public String getFreeName(int index) { 23 | return getFreeName("var" + index); 24 | } 25 | 26 | public String getFreeName(String proposition) { 27 | while (usedNames.contains(proposition)) { 28 | proposition += "x"; 29 | } 30 | usedNames.add(proposition); 31 | return proposition; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/main/extern/ClassFormatException.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.main.extern; 3 | 4 | public class ClassFormatException extends RuntimeException { 5 | public ClassFormatException(String message) { 6 | super(message); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/main/extern/IBytecodeProvider.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.main.extern; 3 | 4 | import java.io.IOException; 5 | 6 | public interface IBytecodeProvider { 7 | byte[] getBytecode(String externalPath, String internalPath) throws IOException; 8 | } 9 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/main/extern/IIdentifierRenamer.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.main.extern; 3 | 4 | public interface IIdentifierRenamer { 5 | 6 | enum Type {ELEMENT_CLASS, ELEMENT_FIELD, ELEMENT_METHOD} 7 | 8 | boolean toBeRenamed(Type elementType, String className, String element, String descriptor); 9 | 10 | String getNextClassName(String fullName, String shortName); 11 | 12 | String getNextFieldName(String className, String field, String descriptor); 13 | 14 | String getNextMethodName(String className, String method, String descriptor); 15 | } 16 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/main/extern/IResultSaver.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.main.extern; 3 | 4 | import java.util.jar.Manifest; 5 | 6 | public interface IResultSaver { 7 | void saveFolder(String path); 8 | 9 | void copyFile(String source, String path, String entryName); 10 | 11 | void saveClassFile(String path, String qualifiedName, String entryName, String content, int[] mapping); 12 | 13 | void createArchive(String path, String archiveName, Manifest manifest); 14 | 15 | void saveDirEntry(String path, String archiveName, String entryName); 16 | 17 | void copyEntry(String source, String path, String archiveName, String entry); 18 | 19 | void saveClassEntry(String path, String archiveName, String qualifiedName, String entryName, String content); 20 | 21 | void closeArchive(String path, String archiveName); 22 | } 23 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/decompiler/ClearStructHelper.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.decompiler; 3 | 4 | import me.f1nal.trinity.decompiler.modules.decompiler.stats.RootStatement; 5 | import me.f1nal.trinity.decompiler.modules.decompiler.stats.Statement; 6 | 7 | import java.util.LinkedList; 8 | 9 | 10 | public final class ClearStructHelper { 11 | 12 | public static void clearStatements(RootStatement root) { 13 | 14 | LinkedList stack = new LinkedList<>(); 15 | stack.add(root); 16 | 17 | while (!stack.isEmpty()) { 18 | 19 | Statement stat = stack.removeFirst(); 20 | 21 | stat.clearTempInformation(); 22 | 23 | stack.addAll(stat.getStats()); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/decompiler/ExpressionStack.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.decompiler; 3 | 4 | import me.f1nal.trinity.decompiler.util.ListStack; 5 | import me.f1nal.trinity.decompiler.modules.decompiler.exps.Exprent; 6 | 7 | public class ExpressionStack extends ListStack { 8 | public ExpressionStack() { } 9 | 10 | private ExpressionStack(int initialCapacity) { 11 | super(initialCapacity); 12 | } 13 | 14 | @Override 15 | public ExpressionStack copy() { 16 | ExpressionStack copy = new ExpressionStack(size()); 17 | for (Exprent expr : this) copy.push(expr.copy()); 18 | return copy; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/decompiler/PrimitiveExpressionList.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.decompiler; 3 | 4 | import me.f1nal.trinity.decompiler.modules.decompiler.exps.Exprent; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class PrimitiveExpressionList { 10 | private final List expressions = new ArrayList<>(); 11 | private final ExpressionStack stack; 12 | 13 | public PrimitiveExpressionList() { 14 | this(new ExpressionStack()); 15 | } 16 | 17 | private PrimitiveExpressionList(ExpressionStack stack) { 18 | this.stack = stack; 19 | } 20 | 21 | public PrimitiveExpressionList copy() { 22 | return new PrimitiveExpressionList(stack.copy()); 23 | } 24 | 25 | public List getExpressions() { 26 | return expressions; 27 | } 28 | 29 | public ExpressionStack getStack() { 30 | return stack; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/decompiler/decompose/IGraph.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.decompiler.decompose; 3 | 4 | import java.util.List; 5 | import java.util.Set; 6 | 7 | public interface IGraph { 8 | 9 | List getReversePostOrderList(); 10 | 11 | Set getRoots(); 12 | } 13 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/decompiler/decompose/IGraphNode.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.decompiler.decompose; 3 | 4 | import java.util.List; 5 | 6 | public interface IGraphNode { 7 | List getPredecessorNodes(); 8 | } 9 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/decompiler/exps/AssertExprent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 3 | */ 4 | package me.f1nal.trinity.decompiler.modules.decompiler.exps; 5 | 6 | import me.f1nal.trinity.decompiler.main.collectors.BytecodeMappingTracer; 7 | import me.f1nal.trinity.decompiler.util.TextBuffer; 8 | 9 | import java.util.List; 10 | 11 | public class AssertExprent extends Exprent { 12 | 13 | private final List parameters; 14 | 15 | public AssertExprent(List parameters) { 16 | super(EXPRENT_ASSERT); 17 | this.parameters = parameters; 18 | } 19 | 20 | @Override 21 | public TextBuffer toJava(int indent, BytecodeMappingTracer tracer) { 22 | TextBuffer buffer = new TextBuffer(); 23 | 24 | buffer.append("assert "); 25 | 26 | tracer.addMapping(bytecode); 27 | 28 | if (parameters.get(0) == null) { 29 | buffer.append("false"); 30 | } 31 | else { 32 | buffer.append(parameters.get(0).toJava(indent, tracer)); 33 | } 34 | 35 | if (parameters.size() > 1) { 36 | buffer.append(" : "); 37 | buffer.append(parameters.get(1).toJava(indent, tracer)); 38 | } 39 | 40 | return buffer; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/decompiler/stats/DummyExitStatement.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.decompiler.stats; 3 | 4 | import java.util.Collection; 5 | import java.util.HashSet; 6 | import java.util.Set; 7 | 8 | public class DummyExitStatement extends Statement { 9 | public Set bytecode = null; // offsets of bytecode instructions mapped to dummy exit 10 | 11 | public DummyExitStatement() { 12 | super(StatementType.DUMMY_EXIT); 13 | } 14 | 15 | public void addBytecodeOffsets(Collection bytecodeOffsets) { 16 | if (bytecodeOffsets != null && !bytecodeOffsets.isEmpty()) { 17 | if (bytecode == null) { 18 | bytecode = new HashSet<>(bytecodeOffsets); 19 | } 20 | else { 21 | bytecode.addAll(bytecodeOffsets); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/decompiler/stats/RootStatement.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.decompiler.stats; 3 | 4 | import me.f1nal.trinity.decompiler.main.collectors.BytecodeMappingTracer; 5 | import me.f1nal.trinity.decompiler.modules.decompiler.ExprProcessor; 6 | import me.f1nal.trinity.decompiler.util.TextBuffer; 7 | 8 | public class RootStatement extends Statement { 9 | private final DummyExitStatement dummyExit; 10 | 11 | public RootStatement(Statement head, DummyExitStatement dummyExit) { 12 | super(StatementType.ROOT); 13 | 14 | first = head; 15 | this.dummyExit = dummyExit; 16 | 17 | stats.addWithKey(first, first.id); 18 | first.setParent(this); 19 | } 20 | 21 | @Override 22 | public TextBuffer toJava(int indent, BytecodeMappingTracer tracer) { 23 | return ExprProcessor.listToJava(varDefinitions, indent, tracer).append(first.toJava(indent, tracer)); 24 | } 25 | 26 | public DummyExitStatement getDummyExit() { 27 | return dummyExit; 28 | } 29 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/decompiler/vars/VarVersionEdge.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.decompiler.vars; 3 | 4 | public class VarVersionEdge { // FIXME: can be removed? 5 | 6 | public static final int EDGE_GENERAL = 0; 7 | public static final int EDGE_PHANTOM = 1; 8 | 9 | public final int type; 10 | 11 | public final VarVersionNode source; 12 | 13 | public final VarVersionNode dest; 14 | 15 | private final int hashCode; 16 | 17 | public VarVersionEdge(int type, VarVersionNode source, VarVersionNode dest) { 18 | this.type = type; 19 | this.source = source; 20 | this.dest = dest; 21 | this.hashCode = source.hashCode() ^ dest.hashCode() + type; 22 | } 23 | 24 | @Override 25 | public boolean equals(Object o) { 26 | if (o == this) return true; 27 | if (!(o instanceof VarVersionEdge edge)) return false; 28 | 29 | return type == edge.type && source == edge.source && dest == edge.dest; 30 | } 31 | 32 | @Override 33 | public int hashCode() { 34 | return hashCode; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return source.toString() + " ->" + type + "-> " + dest.toString(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/decompiler/vars/VarVersionPair.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.decompiler.vars; 3 | 4 | import me.f1nal.trinity.decompiler.modules.decompiler.exps.VarExprent; 5 | 6 | public class VarVersionPair { 7 | 8 | public final int var; 9 | public final int version; 10 | 11 | private int hashCode = -1; 12 | 13 | public VarVersionPair(int var, int version) { 14 | this.var = var; 15 | this.version = version; 16 | } 17 | 18 | public VarVersionPair(Integer var, Integer version) { 19 | this.var = var; 20 | this.version = version; 21 | } 22 | 23 | public VarVersionPair(VarExprent var) { 24 | this.var = var.getIndex(); 25 | this.version = var.getVersion(); 26 | } 27 | 28 | @Override 29 | public boolean equals(Object o) { 30 | if (o == this) return true; 31 | if (!(o instanceof VarVersionPair paar)) return false; 32 | 33 | return var == paar.var && version == paar.version; 34 | } 35 | 36 | @Override 37 | public int hashCode() { 38 | if (hashCode == -1) { 39 | hashCode = this.var * 3 + this.version; 40 | } 41 | return hashCode; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "(" + var + "," + version + ")"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/renamer/ClassWrapperNode.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.renamer; 3 | 4 | import me.f1nal.trinity.decompiler.struct.StructClass; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class ClassWrapperNode { 10 | private final StructClass classStruct; 11 | private final List subclasses = new ArrayList<>(); 12 | 13 | public ClassWrapperNode(StructClass cl) { 14 | this.classStruct = cl; 15 | } 16 | 17 | public void addSubclass(ClassWrapperNode node) { 18 | subclasses.add(node); 19 | } 20 | 21 | public StructClass getClassStruct() { 22 | return classStruct; 23 | } 24 | 25 | public List getSubclasses() { 26 | return subclasses; 27 | } 28 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/modules/renamer/PoolInterceptor.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.modules.renamer; 3 | 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | public class PoolInterceptor { 8 | private final Map mapOldToNewNames = new HashMap<>(); 9 | private final Map mapNewToOldNames = new HashMap<>(); 10 | 11 | public void addName(String oldName, String newName) { 12 | mapOldToNewNames.put(oldName, newName); 13 | mapNewToOldNames.put(newName, oldName); 14 | } 15 | 16 | public String getName(String oldName) { 17 | return mapOldToNewNames.get(oldName); 18 | } 19 | 20 | public String getOldName(String newName) { 21 | return mapNewToOldNames.get(newName); 22 | } 23 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/output/IMemberDetails.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output; 2 | 3 | public interface IMemberDetails { 4 | String getOwner(); 5 | String getName(); 6 | String getDesc(); 7 | } 8 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/output/OutputMember.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output; 2 | 3 | import java.io.DataInput; 4 | import java.io.DataOutput; 5 | import java.io.IOException; 6 | 7 | public abstract class OutputMember { 8 | private int length; 9 | 10 | public OutputMember(int length) { 11 | this.length = length; 12 | } 13 | 14 | public final int getLength() { 15 | return length; 16 | } 17 | 18 | protected abstract void serializeImpl(DataOutput dataOutput) throws IOException; 19 | protected abstract void deserializeImpl(DataInput dataInput) throws IOException; 20 | 21 | public abstract void visit(OutputMemberVisitor visitor); 22 | 23 | public void serialize(DataOutput dataOutput) throws IOException { 24 | dataOutput.writeInt(this.length); 25 | serializeImpl(dataOutput); 26 | } 27 | 28 | public void deserialize(DataInput dataInput) throws IOException { 29 | deserializeImpl(dataInput); 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return getClass().getSimpleName(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/output/OutputMemberVisitor.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output; 2 | 3 | import me.f1nal.trinity.decompiler.output.impl.*; 4 | 5 | public interface OutputMemberVisitor { 6 | void visitBytecodeMarker(BytecodeMarkerOutputMember bytecodeMarker); 7 | void visitClass(ClassOutputMember member); 8 | void visitComment(CommentOutputMember comment); 9 | void visitNumber(NumberOutputMember constant); 10 | void visitFieldDeclaration(FieldDeclarationOutputMember fieldDeclaration); 11 | void visitField(FieldOutputMember field); 12 | void visitKeyword(KeywordOutputMember keyword); 13 | void visitMethod(MethodOutputMember method); 14 | void visitMethodStartEnd(MethodStartEndOutputMember methodStartEnd); 15 | void visitPackage(PackageOutputMember pkg); 16 | void visitString(StringOutputMember string); 17 | void visitVariable(VariableOutputMember variable); 18 | void visitKind(KindOutputMember kind); 19 | } 20 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/output/impl/CommentOutputMember.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.impl; 2 | 3 | import me.f1nal.trinity.decompiler.output.OutputMember; 4 | import me.f1nal.trinity.decompiler.output.OutputMemberVisitor; 5 | 6 | import java.io.DataInput; 7 | import java.io.DataOutput; 8 | import java.io.IOException; 9 | 10 | public class CommentOutputMember extends OutputMember { 11 | public CommentOutputMember(int length) { 12 | super(length); 13 | } 14 | 15 | @Override 16 | protected void serializeImpl(DataOutput dataOutput) throws IOException { 17 | } 18 | 19 | @Override 20 | protected void deserializeImpl(DataInput dataInput) throws IOException { 21 | } 22 | 23 | @Override 24 | public void visit(OutputMemberVisitor visitor) { 25 | visitor.visitComment(this); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/output/impl/KeywordOutputMember.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.impl; 2 | 3 | import me.f1nal.trinity.decompiler.output.OutputMember; 4 | import me.f1nal.trinity.decompiler.output.OutputMemberVisitor; 5 | 6 | import java.io.DataInput; 7 | import java.io.DataOutput; 8 | import java.io.IOException; 9 | 10 | public class KeywordOutputMember extends OutputMember { 11 | public KeywordOutputMember(int length) { 12 | super(length); 13 | } 14 | 15 | @Override 16 | protected void serializeImpl(DataOutput dataOutput) throws IOException { 17 | 18 | } 19 | 20 | @Override 21 | protected void deserializeImpl(DataInput dataInput) throws IOException { 22 | 23 | } 24 | 25 | @Override 26 | public void visit(OutputMemberVisitor visitor) { 27 | visitor.visitKeyword(this); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/output/impl/StringOutputMember.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.impl; 2 | 3 | import me.f1nal.trinity.decompiler.output.OutputMember; 4 | import me.f1nal.trinity.decompiler.output.OutputMemberVisitor; 5 | 6 | import java.io.DataInput; 7 | import java.io.DataOutput; 8 | import java.io.IOException; 9 | 10 | public class StringOutputMember extends OutputMember { 11 | private String data; 12 | 13 | public StringOutputMember(int length) { 14 | super(length); 15 | } 16 | 17 | public StringOutputMember(int length, String data) { 18 | super(length); 19 | this.data = data; 20 | } 21 | 22 | @Override 23 | protected void serializeImpl(DataOutput dataOutput) throws IOException { 24 | dataOutput.writeUTF(this.data); 25 | } 26 | 27 | @Override 28 | protected void deserializeImpl(DataInput dataInput) throws IOException { 29 | this.data = dataInput.readUTF(); 30 | } 31 | 32 | public String getData() { 33 | return data; 34 | } 35 | 36 | @Override 37 | public void visit(OutputMemberVisitor visitor) { 38 | visitor.visitString(this); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/output/impl/VariableOutputMember.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.impl; 2 | 3 | import me.f1nal.trinity.decompiler.output.OutputMember; 4 | import me.f1nal.trinity.decompiler.output.OutputMemberVisitor; 5 | 6 | import java.io.DataInput; 7 | import java.io.DataOutput; 8 | import java.io.IOException; 9 | 10 | public class VariableOutputMember extends OutputMember { 11 | private int var; 12 | private String type; 13 | 14 | public VariableOutputMember(int length) { 15 | super(length); 16 | } 17 | 18 | public VariableOutputMember(int length, int var, String type) { 19 | super(length); 20 | this.var = var; 21 | this.type = type; 22 | } 23 | 24 | @Override 25 | protected void serializeImpl(DataOutput dataOutput) throws IOException { 26 | dataOutput.writeInt(var); 27 | dataOutput.writeUTF(type); 28 | } 29 | 30 | @Override 31 | protected void deserializeImpl(DataInput dataInput) throws IOException { 32 | var = dataInput.readInt(); 33 | type = dataInput.readUTF(); 34 | } 35 | 36 | @Override 37 | public void visit(OutputMemberVisitor visitor) { 38 | visitor.visitVariable(this); 39 | } 40 | 41 | public int getVar() { 42 | return var; 43 | } 44 | 45 | public String getType() { 46 | return type; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/IDecompiledData.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct; 3 | 4 | public interface IDecompiledData { 5 | 6 | String getClassEntryName(StructClass cl, String entryname); 7 | 8 | String getClassContent(StructClass cl); 9 | } 10 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/attr/StructAnnDefaultAttribute.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.attr; 3 | 4 | import me.f1nal.trinity.decompiler.struct.consts.ConstantPool; 5 | import me.f1nal.trinity.decompiler.modules.decompiler.exps.Exprent; 6 | import me.f1nal.trinity.decompiler.util.DataInputFullStream; 7 | 8 | import java.io.IOException; 9 | 10 | public class StructAnnDefaultAttribute extends StructGeneralAttribute { 11 | 12 | private Exprent defaultValue; 13 | 14 | @Override 15 | public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { 16 | defaultValue = StructAnnotationAttribute.parseAnnotationElement(data, pool); 17 | } 18 | 19 | public Exprent getDefaultValue() { 20 | return defaultValue; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/attr/StructConstantValueAttribute.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.attr; 3 | 4 | import me.f1nal.trinity.decompiler.struct.consts.ConstantPool; 5 | import me.f1nal.trinity.decompiler.util.DataInputFullStream; 6 | 7 | import java.io.IOException; 8 | 9 | public class StructConstantValueAttribute extends StructGeneralAttribute { 10 | 11 | private int index; 12 | 13 | @Override 14 | public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { 15 | index = data.readUnsignedShort(); 16 | } 17 | 18 | public int getIndex() { 19 | return index; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/attr/StructExceptionsAttribute.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.attr; 3 | 4 | import me.f1nal.trinity.decompiler.struct.consts.ConstantPool; 5 | import me.f1nal.trinity.decompiler.util.DataInputFullStream; 6 | 7 | import java.io.IOException; 8 | import java.util.ArrayList; 9 | import java.util.Collections; 10 | import java.util.List; 11 | 12 | public class StructExceptionsAttribute extends StructGeneralAttribute { 13 | 14 | private List throwsExceptions; 15 | 16 | @Override 17 | public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { 18 | int len = data.readUnsignedShort(); 19 | if (len > 0) { 20 | throwsExceptions = new ArrayList<>(len); 21 | for (int i = 0; i < len; i++) { 22 | throwsExceptions.add(data.readUnsignedShort()); 23 | } 24 | } 25 | else { 26 | throwsExceptions = Collections.emptyList(); 27 | } 28 | } 29 | 30 | public String getExcClassname(int index, ConstantPool pool) { 31 | return pool.getPrimitiveConstant(throwsExceptions.get(index)).getString(); 32 | } 33 | 34 | public List getThrowsExceptions() { 35 | return throwsExceptions; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/attr/StructGenericSignatureAttribute.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.attr; 3 | 4 | import me.f1nal.trinity.decompiler.struct.consts.ConstantPool; 5 | import me.f1nal.trinity.decompiler.util.DataInputFullStream; 6 | 7 | import java.io.IOException; 8 | 9 | public class StructGenericSignatureAttribute extends StructGeneralAttribute { 10 | 11 | private String signature; 12 | 13 | @Override 14 | public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { 15 | int index = data.readUnsignedShort(); 16 | signature = pool.getPrimitiveConstant(index).getString(); 17 | } 18 | 19 | public String getSignature() { 20 | return signature; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/attr/StructLocalVariableTypeTableAttribute.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.attr; 3 | 4 | import me.f1nal.trinity.decompiler.struct.consts.ConstantPool; 5 | import me.f1nal.trinity.decompiler.util.DataInputFullStream; 6 | 7 | import java.io.IOException; 8 | 9 | /* 10 | u2 local_variable_type_table_length; 11 | { u2 start_pc; 12 | u2 length; 13 | u2 name_index; 14 | u2 signature_index; 15 | u2 index; 16 | } local_variable_type_table[local_variable_type_table_length]; 17 | */ 18 | public class StructLocalVariableTypeTableAttribute extends StructGeneralAttribute { 19 | // store signature instead of descriptor 20 | private final StructLocalVariableTableAttribute backingAttribute = new StructLocalVariableTableAttribute(); 21 | 22 | @Override 23 | public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { 24 | backingAttribute.initContent(data, pool); 25 | } 26 | 27 | public void add(StructLocalVariableTypeTableAttribute attr) { 28 | backingAttribute.add(attr.backingAttribute); 29 | } 30 | 31 | public String getSignature(int index, int visibleOffset) { 32 | return backingAttribute.getDescriptor(index, visibleOffset); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/attr/StructPermittedSubclassesAttribute.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.attr; 3 | 4 | import me.f1nal.trinity.decompiler.struct.consts.ConstantPool; 5 | import me.f1nal.trinity.decompiler.util.DataInputFullStream; 6 | 7 | import java.io.IOException; 8 | import java.util.Arrays; 9 | import java.util.List; 10 | 11 | /* 12 | PermittedSubclasses_attribute { 13 | u2 attribute_name_index; 14 | u4 attribute_length; 15 | u2 number_of_classes; 16 | u2 classes[number_of_classes]; 17 | } 18 | */ 19 | public class StructPermittedSubclassesAttribute extends StructGeneralAttribute { 20 | List classes; 21 | 22 | @Override 23 | public void initContent(DataInputFullStream data, ConstantPool pool) throws IOException { 24 | int numberOfClasses = data.readUnsignedShort(); 25 | String[] classes = new String[numberOfClasses]; 26 | for (int i = 0; i < numberOfClasses; i++) { 27 | classes[i] = pool.getPrimitiveConstant(data.readUnsignedShort()).getString(); 28 | } 29 | this.classes = Arrays.asList(classes); 30 | } 31 | 32 | public List getClasses() { 33 | return classes; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/consts/PooledConstant.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.consts; 3 | 4 | import me.f1nal.trinity.decompiler.code.CodeConstants; 5 | 6 | public class PooledConstant implements CodeConstants { 7 | public final int type; 8 | 9 | public PooledConstant(int type) { 10 | this.type = type; 11 | } 12 | 13 | public void resolveConstant(ConstantPool pool) { } 14 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/gen/NewClassNameBuilder.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.gen; 3 | 4 | public interface NewClassNameBuilder { 5 | String buildNewClassname(String className); 6 | } 7 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/gen/Type.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. 2 | package me.f1nal.trinity.decompiler.struct.gen; 3 | 4 | import me.f1nal.trinity.decompiler.main.DecompilerContext; 5 | import me.f1nal.trinity.decompiler.modules.decompiler.ExprProcessor; 6 | 7 | import java.util.Arrays; 8 | import java.util.List; 9 | 10 | public interface Type { 11 | int getType(); 12 | 13 | int getArrayDim(); 14 | 15 | String getValue(); 16 | 17 | /** 18 | * Checks whether this Type can be annotated. Nested types can't be annotated when the right side of the currently considered types 19 | * contains a reference to a static class. 20 | */ 21 | default boolean isAnnotatable() { 22 | List nestedTypes = Arrays.asList(DecompilerContext.getImportCollector().getNestedName(getValue()).split("\\.")); 23 | if (nestedTypes.isEmpty()) return true; 24 | String curPath = getValue().substring(0, getValue().lastIndexOf('/') + 1) + nestedTypes.get(0) + '$'; 25 | return ExprProcessor.canWriteNestedTypeAnnotation(curPath, nestedTypes.subList(1, nestedTypes.size())); 26 | } 27 | } 28 | 29 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/gen/generics/GenericClassDescriptor.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.gen.generics; 3 | 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class GenericClassDescriptor { 8 | 9 | public GenericType superclass; 10 | 11 | public final List superinterfaces = new ArrayList<>(); 12 | 13 | public final List fparameters = new ArrayList<>(); 14 | 15 | public final List> fbounds = new ArrayList<>(); 16 | } 17 | -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/gen/generics/GenericFieldDescriptor.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.gen.generics; 3 | 4 | public class GenericFieldDescriptor { 5 | public final GenericType type; 6 | 7 | public GenericFieldDescriptor(GenericType type) { 8 | this.type = type; 9 | } 10 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/struct/match/IMatchable.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.struct.match; 3 | 4 | public interface IMatchable { 5 | enum MatchProperties { 6 | STATEMENT_TYPE, 7 | STATEMENT_RET, 8 | STATEMENT_STATSIZE, 9 | STATEMENT_EXPRSIZE, 10 | STATEMENT_POSITION, 11 | STATEMENT_IFTYPE, 12 | 13 | EXPRENT_TYPE, 14 | EXPRENT_RET, 15 | EXPRENT_POSITION, 16 | EXPRENT_FUNCTYPE, 17 | EXPRENT_EXITTYPE, 18 | EXPRENT_CONSTTYPE, 19 | EXPRENT_CONSTVALUE, 20 | EXPRENT_INVOCATION_CLASS, 21 | EXPRENT_INVOCATION_SIGNATURE, 22 | EXPRENT_INVOCATION_PARAMETER, 23 | EXPRENT_VAR_INDEX, 24 | EXPRENT_FIELD_NAME, 25 | } 26 | 27 | IMatchable findObject(MatchNode matchNode, int index); 28 | 29 | boolean match(MatchNode matchNode, MatchEngine engine); 30 | } -------------------------------------------------------------------------------- /Decompiler/src/main/java/me/f1nal/trinity/decompiler/util/DataInputFullStream.java: -------------------------------------------------------------------------------- 1 | // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. 2 | package me.f1nal.trinity.decompiler.util; 3 | 4 | import java.io.ByteArrayInputStream; 5 | import java.io.DataInputStream; 6 | import java.io.IOException; 7 | 8 | public class DataInputFullStream extends DataInputStream { 9 | public DataInputFullStream(byte[] bytes) { 10 | super(new ByteArrayInputStream(bytes)); 11 | } 12 | 13 | public byte[] read(int n) throws IOException { 14 | return InterpreterUtil.readBytes(this, n); 15 | } 16 | 17 | public void discard(int n) throws IOException { 18 | InterpreterUtil.discardBytes(this, n); 19 | } 20 | } -------------------------------------------------------------------------------- /PLANNED.md: -------------------------------------------------------------------------------- 1 | ## Planned features 2 | 3 | - Method/field/class editor & adder 4 | - Pattern analysis 5 | - Searching in text editor 6 | - Sorting in tables 7 | - Assembler operand overhaul 8 | - Fix new project & global rename with different font sizes -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firstfault/Trinity/b1e439457f1c90971993c0966234fd745df119c7/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Apr 06 11:36:43 AKDT 2024 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /screenshots/trinity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firstfault/Trinity/b1e439457f1c90971993c0966234fd745df119c7/screenshots/trinity.png -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | rootProject.name = "Trinity" 2 | include("Decompiler") 3 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/appdata/StateFile.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.appdata; 2 | 3 | public class StateFile extends AppDataFile { 4 | private String lastLaunchedVersion; 5 | /** 6 | * If we had a database loaded the last time Trinity was open. 7 | */ 8 | private boolean databaseLoaded; 9 | // private GuiStateMemory guiStateMemory; 10 | 11 | protected StateFile(AppDataManager manager) { 12 | super("state", manager); 13 | } 14 | 15 | // @Override 16 | // public void handleLoad() { 17 | // if (guiStateMemory == null) guiStateMemory = new GuiStateMemory(); 18 | // } 19 | 20 | public void setDatabaseLoaded(boolean databaseLoaded) { 21 | this.databaseLoaded = databaseLoaded; 22 | } 23 | 24 | public String getLastLaunchedVersion() { 25 | return lastLaunchedVersion; 26 | } 27 | 28 | public boolean isDatabaseLoaded() { 29 | return databaseLoaded; 30 | } 31 | 32 | public void setLastLaunchedVersion(String lastLaunchedVersion) { 33 | this.lastLaunchedVersion = lastLaunchedVersion; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/appdata/gui/GuiStateMemory.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.appdata.gui; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class GuiStateMemory { 7 | private final Map memorizedCheckboxes = new HashMap<>(); 8 | 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/appdata/keybindings/KeyBindingData.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.appdata.keybindings; 2 | 3 | public class KeyBindingData { 4 | private final int keyCode; 5 | private final String shortName; 6 | 7 | public KeyBindingData(int keyCode, String shortName) { 8 | this.keyCode = keyCode; 9 | this.shortName = shortName; 10 | } 11 | 12 | public int getKeyCode() { 13 | return keyCode; 14 | } 15 | 16 | public String getShortName() { 17 | return shortName; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/appdata/shutdown/ShutdownHook.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.appdata.shutdown; 2 | 3 | import me.f1nal.trinity.util.INameable; 4 | import org.jetbrains.annotations.NotNull; 5 | 6 | public class ShutdownHook implements Runnable, INameable { 7 | private final String name; 8 | private final Runnable runnable; 9 | private final Object lock = new Object(); 10 | private volatile boolean ran; 11 | 12 | public ShutdownHook(String name, @NotNull Runnable runnable) { 13 | this.name = name; 14 | this.runnable = runnable; 15 | } 16 | 17 | @Override 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public void run() { 23 | synchronized (this.lock) { 24 | if (this.ran) { 25 | return; 26 | } 27 | this.ran = true; 28 | } 29 | 30 | this.runnable.run(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/IDatabaseSavable.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database; 2 | 3 | import me.f1nal.trinity.Main; 4 | import me.f1nal.trinity.database.object.AbstractDatabaseObject; 5 | 6 | public interface IDatabaseSavable { 7 | T createDatabaseObject(); 8 | 9 | default void save() { 10 | Main.getTrinity().getDatabase().save(this); 11 | } 12 | 13 | default boolean isSaveRequired() { 14 | return true; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/compression/DatabaseCompressionType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.compression; 2 | 3 | import me.f1nal.trinity.util.IDescribable; 4 | import me.f1nal.trinity.util.INameable; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.OutputStream; 9 | 10 | public abstract class DatabaseCompressionType implements INameable, IDescribable { 11 | private final String name; 12 | private final String description; 13 | 14 | public DatabaseCompressionType(String name, String description) { 15 | this.name = name; 16 | this.description = description; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public String getDescription() { 24 | return description; 25 | } 26 | 27 | public abstract void compress(OutputStream stream, byte[] bytes) throws IOException; 28 | public abstract byte[] decompress(InputStream stream) throws IOException; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/compression/DatabaseCompressionTypeGZIP.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.compression; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | import java.util.zip.GZIPInputStream; 7 | import java.util.zip.GZIPOutputStream; 8 | 9 | public class DatabaseCompressionTypeGZIP extends DatabaseCompressionType { 10 | public DatabaseCompressionTypeGZIP() { 11 | super("GZIP", "Decently fast with good compression."); 12 | } 13 | 14 | @Override 15 | public void compress(OutputStream stream, byte[] bytes) throws IOException { 16 | GZIPOutputStream gzipOutputStream = new GZIPOutputStream(stream); 17 | gzipOutputStream.write(bytes); 18 | gzipOutputStream.close(); 19 | } 20 | 21 | @Override 22 | public byte[] decompress(InputStream stream) throws IOException { 23 | GZIPInputStream gzipInputStream = new GZIPInputStream(stream); 24 | byte[] bytes = gzipInputStream.readAllBytes(); 25 | gzipInputStream.close(); 26 | return bytes; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/compression/DatabaseCompressionTypeLZ4.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.compression; 2 | 3 | import net.jpountz.lz4.LZ4FrameInputStream; 4 | import net.jpountz.lz4.LZ4FrameOutputStream; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.OutputStream; 9 | 10 | public class DatabaseCompressionTypeLZ4 extends DatabaseCompressionType { 11 | public DatabaseCompressionTypeLZ4() { 12 | super("LZ4", "Very fast compression algorithm but bigger file size."); 13 | } 14 | 15 | @Override 16 | public void compress(OutputStream stream, byte[] bytes) throws IOException { 17 | LZ4FrameOutputStream xzOutputStream = new LZ4FrameOutputStream(stream); 18 | xzOutputStream.write(bytes); 19 | xzOutputStream.close(); 20 | } 21 | 22 | @Override 23 | public byte[] decompress(InputStream stream) throws IOException { 24 | LZ4FrameInputStream xzInputStream = new LZ4FrameInputStream(stream); 25 | byte[] bytes = xzInputStream.readAllBytes(); 26 | xzInputStream.close(); 27 | return bytes; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/compression/DatabaseCompressionTypeLZMA2.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.compression; 2 | 3 | import org.tukaani.xz.LZMA2Options; 4 | import org.tukaani.xz.XZInputStream; 5 | import org.tukaani.xz.XZOutputStream; 6 | 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.OutputStream; 10 | 11 | public class DatabaseCompressionTypeLZMA2 extends DatabaseCompressionType { 12 | public DatabaseCompressionTypeLZMA2() { 13 | super("LZMA2/XZ", "Very slow algorithm but very good compression."); 14 | } 15 | 16 | @Override 17 | public void compress(OutputStream stream, byte[] bytes) throws IOException { 18 | XZOutputStream xzOutputStream = new XZOutputStream(stream, new LZMA2Options(LZMA2Options.PRESET_MAX)); 19 | xzOutputStream.write(bytes); 20 | xzOutputStream.close(); 21 | } 22 | 23 | @Override 24 | public byte[] decompress(InputStream stream) throws IOException { 25 | XZInputStream xzInputStream = new XZInputStream(stream); 26 | byte[] bytes = xzInputStream.readAllBytes(); 27 | xzInputStream.close(); 28 | return bytes; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/compression/DatabaseCompressionTypeManager.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.compression; 2 | 3 | import java.util.List; 4 | 5 | public class DatabaseCompressionTypeManager { 6 | private static final List types = List.of( 7 | new DatabaseCompressionTypeLZ4(), 8 | new DatabaseCompressionTypeGZIP(), 9 | new DatabaseCompressionTypeLZMA2(), 10 | new DatabaseCompressionTypeRaw() 11 | ); 12 | 13 | public static DatabaseCompressionType getType(int index) { 14 | if (index < 0 || index >= types.size()) { 15 | return null; 16 | } 17 | return types.get(index); 18 | } 19 | 20 | public static List getTypes() { 21 | return types; 22 | } 23 | 24 | public static int getIndex(DatabaseCompressionType compressionType) { 25 | final int indexOf = types.indexOf(compressionType); 26 | if (indexOf == -1) throw new RuntimeException(); 27 | return indexOf; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/compression/DatabaseCompressionTypeRaw.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.compression; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.OutputStream; 6 | 7 | public class DatabaseCompressionTypeRaw extends DatabaseCompressionType { 8 | public DatabaseCompressionTypeRaw() { 9 | super("Raw", "No compression applied to the database file."); 10 | } 11 | 12 | @Override 13 | public void compress(OutputStream stream, byte[] bytes) throws IOException { 14 | stream.write(bytes); 15 | } 16 | 17 | @Override 18 | public byte[] decompress(InputStream stream) throws IOException { 19 | return stream.readAllBytes(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/inputs/AbstractProjectInputFile.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.inputs; 2 | 3 | import me.f1nal.trinity.database.ClassPath; 4 | import me.f1nal.trinity.gui.components.filelist.ListedFile; 5 | import me.f1nal.trinity.util.IDescribable; 6 | 7 | import java.io.File; 8 | 9 | public abstract class AbstractProjectInputFile extends ListedFile implements IDescribable { 10 | private final ClassPath classPath = new ClassPath(); 11 | 12 | public AbstractProjectInputFile(File file) { 13 | super(file); 14 | } 15 | 16 | public final ClassPath getClassPath() { 17 | return classPath; 18 | } 19 | 20 | public final void addInputs(ClassPath classPath) { 21 | classPath.addClassPath(classPath); 22 | } 23 | 24 | @Override 25 | public String getDescription() { 26 | return classPath.getClasses().size() + " classes, " + classPath.getResources().size() + " resources"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/inputs/UnreadClassBytes.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.inputs; 2 | 3 | /** 4 | * Bytes of a class that have not yet been processed into a {@link org.objectweb.asm.tree.ClassNode} 5 | */ 6 | public class UnreadClassBytes { 7 | private final String entryName; 8 | private final byte[] bytes; 9 | 10 | public UnreadClassBytes(String entryName, byte[] bytes) { 11 | this.entryName = entryName; 12 | this.bytes = bytes; 13 | } 14 | 15 | public String getEntryName() { 16 | return entryName; 17 | } 18 | 19 | public byte[] getBytes() { 20 | return bytes; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/inputs/impl/ProjectInputClassFile.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.inputs.impl; 2 | 3 | import me.f1nal.trinity.database.inputs.AbstractProjectInputFile; 4 | import me.f1nal.trinity.database.inputs.UnreadClassBytes; 5 | 6 | import java.io.File; 7 | 8 | public class ProjectInputClassFile extends AbstractProjectInputFile { 9 | public ProjectInputClassFile(File file, byte[] bytes) { 10 | super(file); 11 | 12 | this.getClassPath().addClass(new UnreadClassBytes(file.getName(), bytes)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/object/AbstractDatabaseObject.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.object; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | 5 | public abstract class AbstractDatabaseObject { 6 | /** 7 | * Loads this object back into Trinity. 8 | * 9 | * @return {@code true} if this object is still valid. 10 | */ 11 | public abstract boolean load(Trinity trinity); 12 | 13 | @Override 14 | public int hashCode() { 15 | return databaseHashCode(); 16 | } 17 | 18 | @Override 19 | public boolean equals(Object obj) { 20 | if (obj instanceof AbstractDatabaseObject) { 21 | return obj.hashCode() == this.hashCode(); 22 | } 23 | return super.equals(obj); 24 | } 25 | 26 | protected abstract int databaseHashCode(); 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/object/DatabaseDecompiler.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.object; 2 | 3 | import me.f1nal.trinity.Main; 4 | import me.f1nal.trinity.Trinity; 5 | import me.f1nal.trinity.execution.ClassInput; 6 | 7 | import java.util.Objects; 8 | 9 | public class DatabaseDecompiler extends AbstractDatabaseObject { 10 | private final String className; 11 | 12 | public DatabaseDecompiler(String className) { 13 | this.className = className; 14 | } 15 | 16 | @Override 17 | public boolean load(Trinity trinity) { 18 | ClassInput classInput = trinity.getExecution().getClassInput(this.className); 19 | if (classInput == null) { 20 | return false; 21 | } 22 | Main.getDisplayManager().openDecompilerView(classInput); 23 | return true; 24 | } 25 | 26 | @Override 27 | protected int databaseHashCode() { 28 | return Objects.hash("decompilerObj"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/object/DatabasePackage.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.object; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | import me.f1nal.trinity.execution.packages.Package; 5 | import me.f1nal.trinity.logging.Logging; 6 | 7 | import java.util.Objects; 8 | 9 | public class DatabasePackage extends AbstractDatabaseObject { 10 | private final String path; 11 | private final boolean open; 12 | 13 | public DatabasePackage(String path, boolean open) { 14 | this.path = path; 15 | this.open = open; 16 | } 17 | 18 | @Override 19 | public boolean load(Trinity trinity) { 20 | Package pkg = trinity.getExecution().getRootPackage().getPackageHierarchy().getPathToPackage().get(path); 21 | if (pkg == null) { 22 | Logging.warn("Cannot find package {} from database object.", path); 23 | return false; 24 | } 25 | pkg.setOpenForced(open); 26 | return true; 27 | } 28 | 29 | @Override 30 | protected int databaseHashCode() { 31 | return Objects.hash("package", path); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/patches/AbstractDatabasePatch.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.patches; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | 5 | public abstract class AbstractDatabasePatch { 6 | public abstract boolean isForVersion(int version); 7 | public abstract void apply(Trinity trinity); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/patches/DatabasePatchManager.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.patches; 2 | 3 | import me.f1nal.trinity.database.patches.impl.DatabasePatchMethodHierarchyNames; 4 | 5 | import java.util.List; 6 | 7 | public class DatabasePatchManager { 8 | private static final List PATCH_LIST = List.of( 9 | new DatabasePatchMethodHierarchyNames() 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/patches/impl/DatabasePatchMethodHierarchyNames.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.patches.impl; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | import me.f1nal.trinity.database.patches.AbstractDatabasePatch; 5 | 6 | public class DatabasePatchMethodHierarchyNames extends AbstractDatabasePatch { 7 | @Override 8 | public boolean isForVersion(int version) { 9 | return version == 1; 10 | } 11 | 12 | @Override 13 | public void apply(Trinity trinity) { 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/database/semaphore/DatabaseLoaderRunnable.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.database.semaphore; 2 | 3 | import java.io.File; 4 | 5 | public interface DatabaseLoaderRunnable { 6 | void run(File path) throws Throwable; 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/DecompiledMethod.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler; 2 | 3 | import me.f1nal.trinity.execution.MethodInput; 4 | import me.f1nal.trinity.gui.windows.impl.assembler.line.MethodOpcodeSource; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | public class DecompiledMethod { 10 | private final MethodInput methodInput; 11 | private final Map opcodeMap = new HashMap<>(); 12 | 13 | public DecompiledMethod(MethodInput methodInput) { 14 | this.methodInput = methodInput; 15 | } 16 | 17 | public Map getOpcodeMap() { 18 | return opcodeMap; 19 | } 20 | 21 | public MethodInput getMethodInput() { 22 | return methodInput; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/output/FontEnum.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output; 2 | 3 | import imgui.ImFont; 4 | import me.f1nal.trinity.util.INameable; 5 | 6 | import java.util.Arrays; 7 | import java.util.Objects; 8 | 9 | public enum FontEnum implements INameable { 10 | JETBRAINS_MONO("JetBrains Mono"), 11 | ZED_MONO("Zed Mono"), 12 | INTER("Inter"), 13 | ; 14 | 15 | private final String name; 16 | 17 | FontEnum(String name) { 18 | this.name = name; 19 | } 20 | 21 | @Override 22 | public String getName() { 23 | return this.name; 24 | } 25 | 26 | public static FontEnum getFont(String name) { 27 | return Objects.requireNonNull(Arrays.stream(values()).filter(value -> value.getName().equals(name)).findFirst().orElse(null), String.format("Font type '%s'", name)); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/output/colors/ColoredImString.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.colors; 2 | 3 | import imgui.type.ImString; 4 | 5 | public class ColoredImString extends SupplierColoredString { 6 | /** 7 | * Constructs a new {@link ColoredString} object with the specified text and color. 8 | * 9 | * @param text The textual content of the colored string. 10 | * @param color An integer representing the color associated with the text. 11 | */ 12 | public ColoredImString(ImString text, int color) { 13 | super(() -> text.get(), color); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/output/colors/SupplierColoredString.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.colors; 2 | 3 | import java.util.function.Supplier; 4 | 5 | public class SupplierColoredString extends ColoredString { 6 | private final Supplier text; 7 | 8 | /** 9 | * Constructs a new {@link ColoredString} object with the specified text and color. 10 | * 11 | * @param text The textual content of the colored string. 12 | * @param color An integer representing the color associated with the text. 13 | */ 14 | public SupplierColoredString(Supplier text, int color) { 15 | super(null, color); 16 | this.text = text; 17 | } 18 | 19 | @Override 20 | public String getText() { 21 | return text.get(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/output/number/ConvertedFloatingPointNumberDisplayType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.number; 2 | 3 | public abstract class ConvertedFloatingPointNumberDisplayType extends NumberDisplayType { 4 | @Override 5 | protected String getTextImpl(Number number) { 6 | if (number instanceof Float) { 7 | number = Float.floatToIntBits(number.floatValue()); 8 | } else if (number instanceof Double) { 9 | number = Double.doubleToLongBits(number.doubleValue()); 10 | } 11 | return getText(number); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/output/number/NumberDisplayType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.number; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | import me.f1nal.trinity.gui.windows.impl.constant.search.ConstantSearchType; 5 | import me.f1nal.trinity.gui.windows.impl.constant.search.ConstantSearchTypeNumber; 6 | 7 | public abstract class NumberDisplayType { 8 | public String getText(Number number) { 9 | return getTextImpl(number); 10 | } 11 | protected abstract String getTextImpl(Number number); 12 | public abstract String getLabel(); 13 | 14 | public ConstantSearchType getConstantSearchType(Trinity trinity, Number number) { 15 | if (number instanceof Float) { 16 | return new ConstantSearchTypeNumber.ConstantSearchTypeFloat(trinity, number.floatValue()); 17 | } 18 | if (number instanceof Double) { 19 | return new ConstantSearchTypeNumber.ConstantSearchTypeDouble(trinity, number.doubleValue()); 20 | } 21 | if (number instanceof Long) { 22 | return new ConstantSearchTypeNumber.ConstantSearchTypeLong(trinity, number.longValue()); 23 | } 24 | return new ConstantSearchTypeNumber.ConstantSearchTypeInteger(trinity, number.intValue()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/output/number/NumberDisplayTypeBinary.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.number; 2 | 3 | public class NumberDisplayTypeBinary extends ConvertedFloatingPointNumberDisplayType { 4 | @Override 5 | public String getTextImpl(Number number) { 6 | return "0b" + Long.toBinaryString(number.longValue()); 7 | } 8 | 9 | @Override 10 | public String getLabel() { 11 | return "Binary"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/output/number/NumberDisplayTypeDecimal.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.number; 2 | 3 | public class NumberDisplayTypeDecimal extends NumberDisplayType { 4 | @Override 5 | public String getTextImpl(Number number) { 6 | return Long.toString(number.longValue()); 7 | } 8 | 9 | @Override 10 | public String getLabel() { 11 | return "Decimal"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/output/number/NumberDisplayTypeEnum.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.number; 2 | 3 | import me.f1nal.trinity.util.INameable; 4 | 5 | public enum NumberDisplayTypeEnum implements INameable { 6 | DECIMAL("Decimal", new NumberDisplayTypeDecimal()), 7 | HEX("Hex", new NumberDisplayTypeHex()), 8 | OCTAL("Octal", new NumberDisplayTypeOctal()), 9 | BINARY("Binary", new NumberDisplayTypeBinary()), 10 | ASCII("ASCII", new NumberDisplayTypeChar()), 11 | ; 12 | private final String name; 13 | private final NumberDisplayType instance; 14 | 15 | NumberDisplayTypeEnum(String name, NumberDisplayType instance) { 16 | this.name = name; 17 | this.instance = instance; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public NumberDisplayType getInstance() { 26 | return instance; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/output/number/NumberDisplayTypeHex.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.number; 2 | 3 | public class NumberDisplayTypeHex extends NumberDisplayType { 4 | @Override 5 | public String getTextImpl(Number number) { 6 | String hexString; 7 | if (number instanceof Double) { 8 | hexString = Double.toHexString(number.doubleValue()); 9 | } else if (number instanceof Float) { 10 | hexString = Float.toHexString(number.floatValue()); 11 | } else { 12 | hexString = Long.toHexString(number.longValue()); 13 | } 14 | return "0x" + hexString.toUpperCase(); 15 | } 16 | 17 | @Override 18 | public String getLabel() { 19 | return "Hex"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/decompiler/output/number/NumberDisplayTypeOctal.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.decompiler.output.number; 2 | 3 | public class NumberDisplayTypeOctal extends ConvertedFloatingPointNumberDisplayType { 4 | @Override 5 | public String getTextImpl(Number number) { 6 | return "0" + Long.toOctalString(number.longValue()); 7 | } 8 | 9 | @Override 10 | public String getLabel() { 11 | return "Octal"; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/events/EventClassModified.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.events; 2 | 3 | import me.f1nal.trinity.execution.ClassInput; 4 | 5 | public class EventClassModified { 6 | private final ClassInput classInput; 7 | 8 | public EventClassModified(ClassInput classInput) { 9 | this.classInput = classInput; 10 | } 11 | 12 | public ClassInput getClassInput() { 13 | return classInput; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/events/EventClassesLoaded.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.events; 2 | 3 | public class EventClassesLoaded { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/events/EventMemberRename.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.events; 2 | 3 | import me.f1nal.trinity.execution.ClassTarget; 4 | 5 | public class EventMemberRename { 6 | private final ClassTarget target; 7 | 8 | public EventMemberRename(ClassTarget target) { 9 | this.target = target; 10 | } 11 | 12 | public ClassTarget getTarget() { 13 | return target; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/events/EventPackageStructureReload.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.events; 2 | 3 | public class EventPackageStructureReload { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/events/EventRefreshDecompilerText.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.events; 2 | 3 | import me.f1nal.trinity.decompiler.DecompiledClass; 4 | 5 | import java.util.function.Predicate; 6 | 7 | public class EventRefreshDecompilerText { 8 | private final Predicate predicate; 9 | 10 | public EventRefreshDecompilerText(Predicate predicate) { 11 | this.predicate = predicate; 12 | } 13 | 14 | public Predicate getPredicate() { 15 | return predicate; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/events/api/IEventListener.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.events.api; 2 | 3 | public interface IEventListener { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/FieldInput.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution; 2 | 3 | import me.f1nal.trinity.database.IDatabaseSavable; 4 | import me.f1nal.trinity.database.object.DatabaseFieldDisplayName; 5 | import me.f1nal.trinity.remap.Remapper; 6 | import org.objectweb.asm.tree.FieldNode; 7 | 8 | public class FieldInput extends MemberInput implements IDatabaseSavable { 9 | public FieldInput(FieldNode node, ClassInput owner) { 10 | super(node, owner, new MemberDetails(owner.getRealName(), node.name, node.desc)); 11 | } 12 | 13 | @Override 14 | public InputType getType() { 15 | return InputType.FIELD; 16 | } 17 | 18 | @Override 19 | public void setAccessFlagsMask(int accessFlagsMask) { 20 | getNode().access = accessFlagsMask; 21 | } 22 | 23 | @Override 24 | public int getAccessFlagsMask() { 25 | return getNode().access; 26 | } 27 | 28 | @Override 29 | public boolean isAccessFlagValid(AccessFlags.Flag flag) { 30 | return flag.isFieldFlag(); 31 | } 32 | 33 | @Override 34 | public void rename(Remapper remapper, String newName) { 35 | remapper.renameField(this, newName); 36 | } 37 | 38 | @Override 39 | public DatabaseFieldDisplayName createDatabaseObject() { 40 | return new DatabaseFieldDisplayName(this.getDetails(), this.getDisplayName()); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/InputType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution; 2 | 3 | public enum InputType { 4 | CLASS, 5 | METHOD, 6 | FIELD, 7 | PACKAGE 8 | ; 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/access/AccessFlagsMaskProvider.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.access; 2 | 3 | public interface AccessFlagsMaskProvider { 4 | void setAccessFlagsMask(int accessFlagsMask); 5 | int getAccessFlagsMask(); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/access/SimpleAccessFlagsMaskProvider.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.access; 2 | 3 | public class SimpleAccessFlagsMaskProvider implements AccessFlagsMaskProvider { 4 | private int accessFlags; 5 | 6 | public SimpleAccessFlagsMaskProvider(int accessFlags) { 7 | this.setAccessFlagsMask(accessFlags); 8 | } 9 | 10 | public SimpleAccessFlagsMaskProvider() { 11 | } 12 | 13 | @Override 14 | public void setAccessFlagsMask(int accessFlagsMask) { 15 | this.accessFlags = accessFlagsMask; 16 | } 17 | 18 | @Override 19 | public int getAccessFlagsMask() { 20 | return this.accessFlags; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/analysis/CodeAnalysis.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.analysis; 2 | 3 | public class CodeAnalysis { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/exception/ClassNotPresentException.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.exception; 2 | 3 | public final class ClassNotPresentException extends Exception { 4 | public ClassNotPresentException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/exception/HandleNotPresentException.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.exception; 2 | 3 | public class HandleNotPresentException extends Exception { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/exception/MethodNotPresentException.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.exception; 2 | 3 | public class MethodNotPresentException extends Exception { 4 | public MethodNotPresentException(String owner, String name, String desc) { 5 | super(owner + "." + name + desc); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/exception/MissingEntryPointException.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.exception; 2 | 3 | public class MissingEntryPointException extends Exception { 4 | public MissingEntryPointException() { 5 | } 6 | 7 | public MissingEntryPointException(String message) { 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/hierarchy/MethodHierarchy.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.hierarchy; 2 | 3 | import me.f1nal.trinity.execution.MethodInput; 4 | 5 | import java.util.ArrayList; 6 | import java.util.HashSet; 7 | import java.util.List; 8 | import java.util.Set; 9 | 10 | public final class MethodHierarchy { 11 | /** 12 | * Methods linked to this hierarchy. 13 | */ 14 | private final Set linkedMethods = new HashSet<>(); 15 | 16 | public Set getLinkedMethods() { 17 | return linkedMethods; 18 | } 19 | 20 | public void linkMethod(MethodInput methodInput) { 21 | if (methodInput.getMethodHierarchy() != null) { 22 | methodInput.getMethodHierarchy().mergeInto(this); 23 | return; 24 | } 25 | this.updateMethodHierarchy(methodInput); 26 | } 27 | 28 | private void updateMethodHierarchy(MethodInput methodInput) { 29 | this.linkedMethods.add(methodInput); 30 | methodInput.setMethodHierarchy(this); 31 | } 32 | 33 | private void mergeInto(MethodHierarchy methodHierarchy) { 34 | for (MethodInput linkedMethod : methodHierarchy.getLinkedMethods()) { 35 | this.updateMethodHierarchy(linkedMethod); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/labels/LabelTable.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.labels; 2 | 3 | import com.google.common.collect.BiMap; 4 | import com.google.common.collect.HashBiMap; 5 | import me.f1nal.trinity.execution.MethodInput; 6 | import org.objectweb.asm.Label; 7 | 8 | import java.util.Set; 9 | 10 | public class LabelTable { 11 | private final MethodInput methodInput; 12 | private final BiMap labelMap = HashBiMap.create(); 13 | 14 | public LabelTable(MethodInput methodInput) { 15 | this.methodInput = methodInput; 16 | } 17 | 18 | public MethodInput getMethodInput() { 19 | return methodInput; 20 | } 21 | 22 | public MethodLabel getLabel(Label label) { 23 | int size = labelMap.size(); 24 | return labelMap.computeIfAbsent(label, i -> new MethodLabel(this, "L".concat(String.valueOf(size)))); 25 | } 26 | 27 | public MethodLabel getLabel(String name) { 28 | for (MethodLabel label : labelMap.values()) { 29 | if (label.getName().equals(name)) { 30 | return label; 31 | } 32 | } 33 | return null; 34 | } 35 | 36 | public Set getLabels() { 37 | return labelMap.values(); 38 | } 39 | 40 | public Label getOriginal(MethodLabel label) { 41 | return labelMap.inverse().get(label); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/labels/MethodLabel.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.labels; 2 | 3 | import imgui.type.ImString; 4 | import org.objectweb.asm.Label; 5 | 6 | public class MethodLabel { 7 | private final LabelTable table; 8 | private final ImString name; 9 | 10 | public MethodLabel(LabelTable table, String name) { 11 | this.table = table; 12 | this.name = new ImString(name, 32); 13 | } 14 | 15 | public LabelTable getTable() { 16 | return table; 17 | } 18 | 19 | public String getName() { 20 | return name.get(); 21 | } 22 | 23 | public ImString getNameProperty() { 24 | return name; 25 | } 26 | 27 | public Label findOriginal() { 28 | return table.getOriginal(this); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/loading/tasks/DatabaseReadObjectsLoadTask.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.loading.tasks; 2 | 3 | import me.f1nal.trinity.database.Database; 4 | import me.f1nal.trinity.database.object.AbstractDatabaseObject; 5 | import me.f1nal.trinity.execution.loading.ProgressiveLoadTask; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class DatabaseReadObjectsLoadTask extends ProgressiveLoadTask { 11 | public DatabaseReadObjectsLoadTask() { 12 | super("Reading Objects"); 13 | } 14 | 15 | @Override 16 | public void runImpl() { 17 | Database database = getTrinity().getDatabase(); 18 | 19 | startWork(database.getObjects().size()); 20 | List invalid = new ArrayList<>(); 21 | database.getObjects().forEach(obj -> { 22 | if (!obj.load(getTrinity())) invalid.add(obj); 23 | finishedWork(); 24 | }); 25 | invalid.forEach(database.getObjects()::remove); 26 | database.setLoaded(getTrinity()); 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/packages/PackageHierarchy.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.packages; 2 | 3 | import me.f1nal.trinity.database.Database; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | public class PackageHierarchy { 9 | private final Package root; 10 | private final Database database; 11 | private final Map pathToPackage = new HashMap<>(); 12 | 13 | public PackageHierarchy(Package root, Database database) { 14 | this.root = root; 15 | this.database = database; 16 | } 17 | 18 | public Map getPathToPackage() { 19 | return pathToPackage; 20 | } 21 | 22 | public Database getDatabase() { 23 | return database; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/patch/ClassPatchManager.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.patch; 2 | 3 | import me.f1nal.trinity.execution.patch.classes.ClassPatch; 4 | import me.f1nal.trinity.execution.patch.classes.impl.ClassPatchDoubleInterface; 5 | import me.f1nal.trinity.execution.patch.classes.impl.ClassPatchEnumFieldOrder; 6 | import me.f1nal.trinity.execution.patch.classes.impl.ClassPatchNullAnnotation; 7 | 8 | import java.util.List; 9 | 10 | public class ClassPatchManager { 11 | private static final List classPatchList = List.of( 12 | new ClassPatchEnumFieldOrder(), 13 | new ClassPatchNullAnnotation(), 14 | new ClassPatchDoubleInterface() 15 | ); 16 | 17 | public static List getClassPatchList() { 18 | return classPatchList; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/patch/classes/ClassPatch.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.patch.classes; 2 | 3 | import org.objectweb.asm.tree.ClassNode; 4 | 5 | /** 6 | * Patches for fixing obfuscated classes before decompilation. 7 | */ 8 | public abstract class ClassPatch { 9 | public abstract void patch(ClassNode classNode); 10 | public abstract boolean isEnabled(ClassNode classNode); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/patch/classes/impl/ClassPatchDoubleInterface.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.patch.classes.impl; 2 | 3 | import me.f1nal.trinity.execution.patch.classes.ClassPatch; 4 | import org.objectweb.asm.tree.ClassNode; 5 | 6 | import java.util.*; 7 | 8 | public class ClassPatchDoubleInterface extends ClassPatch { 9 | @Override 10 | public void patch(ClassNode classNode) { 11 | Set interfaces = new LinkedHashSet<>(classNode.interfaces); 12 | classNode.interfaces.clear(); 13 | classNode.interfaces.addAll(interfaces); 14 | } 15 | 16 | @Override 17 | public boolean isEnabled(ClassNode classNode) { 18 | return classNode.interfaces != null && classNode.interfaces.size() > 1; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/patch/classes/impl/ClassPatchEnumFieldOrder.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.patch.classes.impl; 2 | 3 | import me.f1nal.trinity.Main; 4 | import me.f1nal.trinity.execution.patch.classes.ClassPatch; 5 | import org.objectweb.asm.Opcodes; 6 | import org.objectweb.asm.tree.ClassNode; 7 | import org.objectweb.asm.tree.FieldNode; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | /** 13 | * Fixes enum fields being out of order. 14 | */ 15 | public class ClassPatchEnumFieldOrder extends ClassPatch { 16 | @Override 17 | public void patch(ClassNode classNode) { 18 | List enumFields = new ArrayList<>(); 19 | List normalFields = new ArrayList<>(); 20 | 21 | for (FieldNode field : classNode.fields) { 22 | if ((field.access & Opcodes.ACC_ENUM) != 0) { 23 | enumFields.add(field); 24 | continue; 25 | } 26 | 27 | normalFields.add(field); 28 | } 29 | 30 | classNode.fields.clear(); 31 | classNode.fields.addAll(enumFields); 32 | classNode.fields.addAll(normalFields); 33 | } 34 | 35 | @Override 36 | public boolean isEnabled(ClassNode classNode) { 37 | return (classNode.access & Opcodes.ACC_ENUM) != 0 && !Main.getPreferences().isDecompilerEnumClass(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/var/ImmutableVariable.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.var; 2 | 3 | public class ImmutableVariable extends Variable { 4 | public ImmutableVariable(VariableTable table, String name) { 5 | super(table, name); 6 | } 7 | 8 | @Override 9 | public boolean isEditable() { 10 | return false; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/xref/AbstractXref.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.xref; 2 | 3 | import me.f1nal.trinity.execution.xref.where.XrefWhere; 4 | import me.f1nal.trinity.gui.components.filter.kind.IKind; 5 | import me.f1nal.trinity.gui.components.general.table.IWhere; 6 | import me.f1nal.trinity.util.SearchTermMatchable; 7 | 8 | public abstract class AbstractXref implements SearchTermMatchable, IKind, IWhere { 9 | private final XrefWhere where; 10 | private final XrefKind kind; 11 | 12 | protected AbstractXref(XrefWhere where, XrefKind kind) { 13 | this.where = where; 14 | this.kind = kind; 15 | } 16 | 17 | public abstract XrefAccessType getAccess(); 18 | public abstract String getInvocation(); 19 | @Override 20 | public final XrefWhere getWhere() { 21 | return where; 22 | } 23 | @Override 24 | public final XrefKind getKind() { 25 | return kind; 26 | } 27 | public final String getAccessText() { 28 | return getAccess().getText(); 29 | } 30 | 31 | @Override 32 | public boolean matches(String searchTerm) { 33 | String lowerCase = searchTerm.toLowerCase(); 34 | return getWhere().getText().toLowerCase().contains(lowerCase) || getInvocation().toLowerCase().contains(lowerCase); 35 | } 36 | } 37 | 38 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/xref/XrefAccessType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.xref; 2 | 3 | public enum XrefAccessType { 4 | READ("R"), 5 | WRITE("W"), 6 | EXECUTE("X"), 7 | ; 8 | 9 | private final String text; 10 | 11 | XrefAccessType(String text) { 12 | this.text = text; 13 | } 14 | 15 | public String getText() { 16 | return text; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/xref/XrefKind.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.xref; 2 | 3 | import me.f1nal.trinity.gui.components.filter.kind.IKindType; 4 | import me.f1nal.trinity.theme.CodeColorScheme; 5 | 6 | import java.util.function.Supplier; 7 | 8 | public enum XrefKind implements IKindType { 9 | TYPE("Type", () -> CodeColorScheme.XREF_TYPE), 10 | INVOKE("Invoke", () -> CodeColorScheme.XREF_INVOKE), 11 | FIELD("Field", () -> CodeColorScheme.XREF_FIELD), 12 | INHERIT("Inherit", () -> CodeColorScheme.XREF_INHERIT), 13 | RETURN("Return", () -> CodeColorScheme.XREF_RETURN), 14 | PARAMETER("Parameter", () -> CodeColorScheme.XREF_PARAMETER), 15 | ANNOTATION("Annotation", () -> CodeColorScheme.XREF_ANNOTATION), 16 | EXCEPTION("Exception", () -> CodeColorScheme.XREF_EXCEPTION), 17 | LITERAL("Literal", () -> CodeColorScheme.XREF_LITERAL), 18 | ; 19 | 20 | private final String name; 21 | private final Supplier color; 22 | 23 | XrefKind(String name, Supplier color) { 24 | this.name = name; 25 | this.color = color; 26 | } 27 | 28 | @Override 29 | public int getColor() { 30 | return color.get(); 31 | } 32 | 33 | @Override 34 | public String getName() { 35 | return this.name; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/xref/where/XrefWhereClass.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.xref.where; 2 | 3 | import me.f1nal.trinity.Main; 4 | import me.f1nal.trinity.execution.ClassInput; 5 | import me.f1nal.trinity.gui.components.popup.PopupItemBuilder; 6 | 7 | public class XrefWhereClass extends XrefWhere { 8 | private final ClassInput classInput; 9 | 10 | public XrefWhereClass(ClassInput classInput) { 11 | super("Class"); 12 | this.classInput = classInput; 13 | } 14 | 15 | public ClassInput getClassInput() { 16 | return classInput; 17 | } 18 | 19 | @Override 20 | public PopupItemBuilder menuItem() { 21 | return PopupItemBuilder.create().menuItem("Go to class", this::followInDecompiler); 22 | } 23 | 24 | @Override 25 | public String getText() { 26 | return this.classInput.getDisplayName().getName(); 27 | } 28 | 29 | @Override 30 | public void followInDecompiler() { 31 | Main.getDisplayManager().openDecompilerView(this.classInput); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/xref/where/XrefWhereField.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.xref.where; 2 | 3 | import me.f1nal.trinity.Main; 4 | import me.f1nal.trinity.execution.FieldInput; 5 | import me.f1nal.trinity.gui.components.popup.PopupItemBuilder; 6 | 7 | public class XrefWhereField extends XrefWhere { 8 | private final FieldInput fieldInput; 9 | 10 | public XrefWhereField(FieldInput fieldInput) { 11 | super("Field"); 12 | this.fieldInput = fieldInput; 13 | } 14 | 15 | @Override 16 | public PopupItemBuilder menuItem() { 17 | return PopupItemBuilder.create().menuItem("Go to field", this::followInDecompiler); 18 | } 19 | 20 | @Override 21 | public String getText() { 22 | return this.fieldInput.getOwningClass().getDisplaySimpleName() + "." + this.fieldInput.getDisplayName().getName(); 23 | } 24 | 25 | @Override 26 | public void followInDecompiler() { 27 | Main.getDisplayManager().openDecompilerView(this.fieldInput); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/xref/where/XrefWhereMethod.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.xref.where; 2 | 3 | import me.f1nal.trinity.Main; 4 | import me.f1nal.trinity.execution.MethodInput; 5 | import me.f1nal.trinity.gui.components.popup.PopupItemBuilder; 6 | 7 | public class XrefWhereMethod extends XrefWhere { 8 | private final MethodInput methodInput; 9 | 10 | public XrefWhereMethod(MethodInput methodInput) { 11 | super("Method"); 12 | this.methodInput = methodInput; 13 | } 14 | 15 | @Override 16 | public PopupItemBuilder menuItem() { 17 | return PopupItemBuilder.create().menuItem("Go to method", this::followInDecompiler); 18 | } 19 | 20 | @Override 21 | public String getText() { 22 | return methodInput.getOwningClass().getDisplaySimpleName() + "." + methodInput.getDisplayName().getName(); 23 | } 24 | 25 | @Override 26 | public void followInDecompiler() { 27 | Main.getDisplayManager().openDecompilerView(this.methodInput); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/execution/xref/where/XrefWhereMethodInsn.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.execution.xref.where; 2 | 3 | import me.f1nal.trinity.execution.MethodInput; 4 | import org.objectweb.asm.tree.AbstractInsnNode; 5 | 6 | public class XrefWhereMethodInsn extends XrefWhereMethod { 7 | private final AbstractInsnNode insnNode; 8 | 9 | public XrefWhereMethodInsn(MethodInput methodInput, AbstractInsnNode insnNode) { 10 | super(methodInput); 11 | this.insnNode = insnNode; 12 | } 13 | 14 | public AbstractInsnNode getInsnNode() { 15 | return insnNode; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/backend/ImGuiApplication.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.backend; 2 | 3 | import imgui.app.Configuration; 4 | 5 | public abstract class ImGuiApplication extends ImGuiWindow { 6 | /** 7 | * Method called before window creation. Could be used to provide basic window information, like title name etc. 8 | * 9 | * @param config configuration object with basic window information 10 | */ 11 | protected void configure(final Configuration config) { 12 | } 13 | 14 | /** 15 | * Method called once, before application run loop. 16 | */ 17 | protected void preRun() { 18 | } 19 | 20 | /** 21 | * Method called once, after application run loop. 22 | */ 23 | protected void postRun() { 24 | } 25 | 26 | /** 27 | * Entry point of any ImGui application. Use it to start the application loop. 28 | * 29 | * @param app application instance to run 30 | */ 31 | public static void launch(final ImGuiApplication app) { 32 | initialize(app); 33 | app.preRun(); 34 | app.run(); 35 | app.postRun(); 36 | app.dispose(); 37 | } 38 | 39 | private static void initialize(final ImGuiApplication app) { 40 | final Configuration config = new Configuration(); 41 | app.configure(config); 42 | app.init(config); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/CheckboxComponent.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components; 2 | 3 | import imgui.ImGui; 4 | import imgui.type.ImBoolean; 5 | 6 | import java.awt.font.ImageGraphicAttribute; 7 | 8 | public class CheckboxComponent { 9 | private final String id = ComponentId.getId(this.getClass()); 10 | protected final ImBoolean state = new ImBoolean(); 11 | private String label; 12 | 13 | public CheckboxComponent(String label) { 14 | this(label, false); 15 | } 16 | 17 | public CheckboxComponent(String label, boolean defaultValue) { 18 | this.label = label; 19 | this.state.set(defaultValue); 20 | } 21 | 22 | public void draw() { 23 | boolean checked = this.isChecked(); 24 | ImGui.checkbox(this.label + "###" + this.id, state); 25 | if (this.isChecked() != checked) { 26 | this.setChecked(this.isChecked()); 27 | } 28 | } 29 | 30 | public String getLabel() { 31 | return label; 32 | } 33 | 34 | public void setLabel(String label) { 35 | this.label = label; 36 | } 37 | 38 | public boolean isChecked() { 39 | return state.get(); 40 | } 41 | 42 | public void setChecked(boolean checked) { 43 | state.set(checked); 44 | } 45 | 46 | public void toggleChecked() { 47 | this.setChecked(!this.isChecked()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/ComponentId.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class ComponentId { 7 | private static Map, Integer> idMap = new HashMap<>(); 8 | private static int dockspaceId = 666; 9 | 10 | public static int getNextDockspaceId() { 11 | return dockspaceId++; 12 | } 13 | 14 | public static String getId(Class clazz) { 15 | int id = idMap.getOrDefault(clazz, 0); 16 | idMap.put(clazz, id + 1); 17 | return clazz.getName() + id; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/DescribableEnumComboBox.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components; 2 | 3 | import imgui.ImGui; 4 | import me.f1nal.trinity.gui.components.general.EnumComboBox; 5 | import me.f1nal.trinity.util.GuiUtil; 6 | import me.f1nal.trinity.util.IDescribable; 7 | import me.f1nal.trinity.util.INameable; 8 | 9 | import java.util.List; 10 | 11 | public class DescribableEnumComboBox extends EnumComboBox { 12 | public DescribableEnumComboBox(String label, T[] type, T selection) { 13 | super(label, type, selection); 14 | } 15 | 16 | public DescribableEnumComboBox(String label, T[] type) { 17 | super(label, type); 18 | } 19 | 20 | @Override 21 | public T draw() { 22 | this.drawLabel(); 23 | T selected = this.getSelected(); 24 | if (ImGui.beginCombo("###" + this.id, selected.getName())) { 25 | for (T type : this.getTypes()) { 26 | if (ImGui.selectable(type.getName(), selected == type)) { 27 | this.getSelection().set(List.of(this.getTypes()).indexOf(type)); 28 | } 29 | GuiUtil.tooltip(type.getDescription()); 30 | } 31 | ImGui.endCombo(); 32 | } 33 | return selected; 34 | } 35 | 36 | public T getSelected() { 37 | return this.getTypes()[this.getSelection().get()]; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/MemberSelectComponent.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components; 2 | 3 | import imgui.ImGui; 4 | import imgui.type.ImString; 5 | import me.f1nal.trinity.execution.MemberDetails; 6 | 7 | public class MemberSelectComponent { 8 | private final ClassSelectComponent classSelectComponent; 9 | private final ImString name = new ImString(256); 10 | private final ImString descriptor = new ImString(256); 11 | private final String id = ComponentId.getId(this.getClass()); 12 | 13 | public MemberSelectComponent(ClassSelectComponent classSelectComponent) { 14 | this.classSelectComponent = classSelectComponent; 15 | } 16 | 17 | public MemberDetails draw() { 18 | classSelectComponent.draw(); 19 | ImGui.inputTextWithHint("Name###Name" + id, "toString", name); 20 | ImGui.inputTextWithHint("Descriptor###Desc" + id, "()Ljava/lang/String", descriptor); 21 | return new MemberDetails(classSelectComponent.getClassName(), name.get(), descriptor.get()); 22 | } 23 | 24 | public ClassSelectComponent getClassSelectComponent() { 25 | return classSelectComponent; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/MemorableCheckboxComponent.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components; 2 | 3 | import imgui.ImGui; 4 | import imgui.type.ImBoolean; 5 | import me.f1nal.trinity.Main; 6 | 7 | import java.util.Map; 8 | 9 | public class MemorableCheckboxComponent extends CheckboxComponent { 10 | private final String identifier; 11 | 12 | public MemorableCheckboxComponent(String identifier, String label, boolean defaultValue) { 13 | super(label, defaultValue); 14 | this.identifier = identifier; 15 | 16 | Boolean memorized = getMemorizedCheckboxes().get(identifier); 17 | if (memorized != null) { 18 | this.setChecked(memorized); 19 | } 20 | } 21 | 22 | private static Map getMemorizedCheckboxes() { 23 | return Main.getPreferences().getMemorizedCheckboxes(); 24 | } 25 | 26 | @Override 27 | public void draw() { 28 | super.draw(); 29 | } 30 | 31 | @Override 32 | public void setChecked(boolean checked) { 33 | super.setChecked(checked); 34 | getMemorizedCheckboxes().put(this.identifier, checked); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/PackageSelectComponent.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components; 2 | 3 | import imgui.ImGui; 4 | import imgui.type.ImString; 5 | 6 | public class PackageSelectComponent { 7 | private final ImString packageText = new ImString(0x200); 8 | private final String componentId = ComponentId.getId(this.getClass()); 9 | 10 | public PackageSelectComponent(String defaultPath) { 11 | this.packageText.set(defaultPath); 12 | } 13 | 14 | public void draw() { 15 | ImGui.inputTextWithHint("###" + this.componentId, "com/example/package/", this.packageText); 16 | } 17 | 18 | public String getPackagePath() { 19 | String packageText = this.packageText.get(); 20 | packageText = packageText.replace('\\', '/'); 21 | while (packageText.contains("//")) packageText = packageText.replace("//", "/"); 22 | if (!packageText.endsWith("/")) packageText += "/"; 23 | return packageText; 24 | } 25 | 26 | public String getClassInPackage(String className) { 27 | return this.getPackagePath().concat(className); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/SearchBar.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components; 2 | 3 | import imgui.ImGui; 4 | import imgui.flag.ImGuiInputTextFlags; 5 | import imgui.type.ImString; 6 | 7 | public class SearchBar { 8 | private final ImString searchText; 9 | private final String id = ComponentId.getId(getClass()); 10 | public int inputTextFlags = ImGuiInputTextFlags.None; 11 | 12 | public SearchBar(int length) { 13 | this.searchText = new ImString(length); 14 | } 15 | 16 | public SearchBar() { 17 | this(256); 18 | } 19 | 20 | public String drawAndGet() { 21 | draw(); 22 | return this.searchText.get(); 23 | } 24 | 25 | public boolean draw() { 26 | return ImGui.inputText("Search###" + id, searchText, inputTextFlags); 27 | } 28 | 29 | public String getText() { 30 | return getSearchText().get(); 31 | } 32 | 33 | public ImString getSearchText() { 34 | return searchText; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/events/MouseClickEventHandler.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.events; 2 | 3 | public interface MouseClickEventHandler { 4 | void handleClick(MouseClickType clickType); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/events/MouseClickType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.events; 2 | 3 | public enum MouseClickType { 4 | LEFT_CLICK, 5 | RIGHT_CLICK, 6 | ; 7 | } -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/filelist/ListedFile.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.filelist; 2 | 3 | import me.f1nal.trinity.util.IDescribable; 4 | import me.f1nal.trinity.util.INameable; 5 | 6 | import java.io.File; 7 | 8 | public class ListedFile implements INameable, IDescribable { 9 | private final File file; 10 | private final String name; 11 | private final String path; 12 | 13 | protected ListedFile(File file) { 14 | this.file = file; 15 | this.name = file.getName(); 16 | this.path = file.getAbsolutePath(); 17 | } 18 | 19 | public File getFile() { 20 | return file; 21 | } 22 | 23 | @Override 24 | public String getName() { 25 | return this.name; 26 | } 27 | 28 | @Override 29 | public String getDescription() { 30 | return this.path; 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/filelist/ListedFileFactory.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.filelist; 2 | 3 | import org.jetbrains.annotations.Nullable; 4 | 5 | import java.io.File; 6 | 7 | public interface ListedFileFactory { 8 | @Nullable T create(File file); 9 | void view(T file); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/filter/Filter.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.filter; 2 | 3 | import java.util.Collection; 4 | import java.util.function.Predicate; 5 | 6 | public abstract class Filter { 7 | /** 8 | * Initializes this filter. 9 | */ 10 | public abstract void initialize(Collection collection); 11 | 12 | public abstract Predicate filter(); 13 | 14 | /** 15 | * Draws widgets related to this filter. 16 | * @return If the state was modified and a list refresh is needed, {@code true} needs to be returned. 17 | */ 18 | public abstract boolean draw(); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/filter/SearchBarFilter.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.filter; 2 | 3 | import imgui.ImGui; 4 | import me.f1nal.trinity.gui.components.SearchBar; 5 | import me.f1nal.trinity.util.SearchTermMatchable; 6 | 7 | import java.util.Collection; 8 | import java.util.function.Predicate; 9 | 10 | public class SearchBarFilter extends Filter { 11 | private final SearchBar searchBar; 12 | 13 | public SearchBarFilter(SearchBar searchBar) { 14 | this.searchBar = searchBar; 15 | } 16 | 17 | public SearchBarFilter() { 18 | this(new SearchBar()); 19 | } 20 | 21 | public SearchBar getSearchBar() { 22 | return searchBar; 23 | } 24 | 25 | @Override 26 | public void initialize(Collection collection) { 27 | } 28 | 29 | @Override 30 | public Predicate filter() { 31 | final String search = searchBar.getSearchText().get(); 32 | return search.isEmpty() ? (text) -> true : (text) -> text.matches(search); 33 | } 34 | 35 | @Override 36 | public boolean draw() { 37 | return searchBar.draw(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/filter/kind/IKind.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.filter.kind; 2 | 3 | public interface IKind { 4 | IKindType getKind(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/filter/kind/IKindType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.filter.kind; 2 | 3 | import me.f1nal.trinity.util.INameable; 4 | 5 | public interface IKindType extends INameable { 6 | int getColor(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/general/LabeledTextList.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.general; 2 | 3 | import imgui.ImGui; 4 | import me.f1nal.trinity.gui.components.ComponentId; 5 | import me.f1nal.trinity.util.SystemUtil; 6 | 7 | import java.util.LinkedHashMap; 8 | import java.util.Map; 9 | 10 | public class LabeledTextList { 11 | private final Map map; 12 | private final boolean copyButton; 13 | private final String id = ComponentId.getId(this.getClass()); 14 | 15 | public LabeledTextList(boolean copyButton) { 16 | this.copyButton = copyButton; 17 | this.map = new LinkedHashMap<>(); 18 | } 19 | 20 | public boolean isCopyButton() { 21 | return copyButton; 22 | } 23 | 24 | public void add(String key, String value) { 25 | this.map.put(key, value); 26 | } 27 | 28 | public void draw() { 29 | var ref = new Object() { 30 | int index = 0; 31 | }; 32 | map.forEach((key, value) -> { 33 | ImGui.textDisabled(key); 34 | ImGui.sameLine(); 35 | ImGui.text(value); 36 | 37 | if (isCopyButton()) { 38 | ImGui.sameLine(); 39 | if (ImGui.smallButton("Copy###" + id + "Cpy" + ++ref.index)) { 40 | SystemUtil.copyToClipboard(value); 41 | } 42 | } 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/general/TextFieldComponent.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.general; 2 | 3 | import imgui.ImGui; 4 | import imgui.callback.ImGuiInputTextCallback; 5 | import imgui.flag.ImGuiInputTextFlags; 6 | import imgui.type.ImString; 7 | import me.f1nal.trinity.gui.components.ComponentId; 8 | 9 | public class TextFieldComponent { 10 | private final ImString text; 11 | private final String id = ComponentId.getId(getClass()); 12 | private final String label; 13 | private ImGuiInputTextCallback callback; 14 | 15 | public TextFieldComponent(String label, ImString text) { 16 | this.text = text; 17 | this.label = label; 18 | } 19 | 20 | public void setCallback(ImGuiInputTextCallback callback) { 21 | this.callback = callback; 22 | } 23 | 24 | public boolean draw() { 25 | ImGui.text(this.label); 26 | return ImGui.inputText("###" + id, this.text, callback != null ? ImGuiInputTextFlags.CallbackCharFilter : ImGuiInputTextFlags.None, this.callback); 27 | } 28 | 29 | public String getText() { 30 | return text.get(); 31 | } 32 | 33 | public void setText(String text) { 34 | this.text.set(text); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/general/table/ITableCellRenderer.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.general.table; 2 | 3 | public interface ITableCellRenderer { 4 | void render(TableColumn column, T element); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/general/table/IWhere.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.general.table; 2 | 3 | import me.f1nal.trinity.execution.xref.where.XrefWhere; 4 | 5 | public interface IWhere { 6 | XrefWhere getWhere(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/general/table/TableColumn.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.general.table; 2 | 3 | import imgui.flag.ImGuiTableColumnFlags; 4 | import me.f1nal.trinity.util.ByteUtil; 5 | 6 | import java.util.function.Function; 7 | 8 | public class TableColumn { 9 | private final String header; 10 | private int flags = ImGuiTableColumnFlags.None; 11 | private final ITableCellRenderer renderer; 12 | 13 | public TableColumn(String header, Function text) { 14 | this(header, new TableColumnRendererText<>(text)); 15 | } 16 | 17 | public TableColumn(String header, ITableCellRenderer renderer) { 18 | this.header = header; 19 | this.renderer = renderer; 20 | } 21 | 22 | public TableColumn setResizable(boolean resizable) { 23 | this.flags = ByteUtil.setBitflag(this.flags, ImGuiTableColumnFlags.NoResize, !resizable); 24 | return this; 25 | } 26 | 27 | public boolean isResizable() { 28 | return ByteUtil.getBitflag(this.flags, ImGuiTableColumnFlags.NoResize); 29 | } 30 | 31 | public String getHeader() { 32 | return header; 33 | } 34 | 35 | public int getFlags() { 36 | return flags; 37 | } 38 | 39 | public void draw(T element) { 40 | this.renderer.render(this, element); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/general/table/TableColumnRendererText.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.general.table; 2 | 3 | import imgui.ImGui; 4 | 5 | import java.util.function.Function; 6 | 7 | public class TableColumnRendererText implements ITableCellRenderer { 8 | private final Function function; 9 | 10 | public TableColumnRendererText(Function function) { 11 | this.function = function; 12 | } 13 | 14 | @Override 15 | public void render(TableColumn column, T element) { 16 | ImGui.text(function.apply(element)); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/general/table/TableColumnRendererXrefWhere.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.general.table; 2 | 3 | import me.f1nal.trinity.Main; 4 | import me.f1nal.trinity.gui.components.filter.kind.IKind; 5 | 6 | public class TableColumnRendererXrefWhere implements ITableCellRenderer { 7 | @Override 8 | public void render(TableColumn column, T element) { 9 | element.getWhere().draw(element.getKind(), Main.getDisplayManager().getPopupMenu(), Main.getTrinity()); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/popup/MenuBarProgress.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.popup; 2 | 3 | public class MenuBarProgress { 4 | private final String routineName; 5 | private final String taskName; 6 | private int progress; 7 | 8 | public MenuBarProgress(String routineName, String taskName, int progress) { 9 | this.routineName = routineName; 10 | this.taskName = taskName; 11 | this.progress = progress; 12 | } 13 | 14 | public String getRoutineName() { 15 | return routineName; 16 | } 17 | 18 | public String getTaskName() { 19 | return taskName; 20 | } 21 | 22 | public int getProgress() { 23 | return progress; 24 | } 25 | 26 | public void setProgress(int progress) { 27 | this.progress = progress; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/popup/PopupMenuState.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.popup; 2 | 3 | public class PopupMenuState { 4 | public boolean canSeparate; 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/popup/items/PopupItem.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.popup.items; 2 | 3 | import me.f1nal.trinity.gui.components.popup.PopupMenuState; 4 | 5 | public abstract class PopupItem { 6 | public abstract void draw(PopupMenuState state); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/popup/items/PopupItemMenu.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.popup.items; 2 | 3 | import imgui.ImGui; 4 | import me.f1nal.trinity.gui.components.popup.PopupMenuState; 5 | 6 | import java.util.List; 7 | 8 | public class PopupItemMenu extends PopupItem { 9 | private final String label; 10 | private final List popupItems; 11 | 12 | public PopupItemMenu(String label, List popupItems) { 13 | this.label = label; 14 | this.popupItems = popupItems; 15 | } 16 | 17 | @Override 18 | public void draw(PopupMenuState state) { 19 | if (ImGui.beginMenu(this.label)) { 20 | PopupMenuState newState = new PopupMenuState(); 21 | popupItems.forEach(popupItem -> popupItem.draw(newState)); 22 | ImGui.endMenu(); 23 | } 24 | state.canSeparate = true; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/popup/items/PopupItemMenuItem.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.popup.items; 2 | 3 | import imgui.ImGui; 4 | import me.f1nal.trinity.gui.components.popup.PopupMenuState; 5 | 6 | public class PopupItemMenuItem extends PopupItem { 7 | private final String label; 8 | private final String shortcut; 9 | private final boolean selected; 10 | private final Runnable event; 11 | 12 | public PopupItemMenuItem(String label, String shortcut, boolean selected, Runnable event) { 13 | this.label = label; 14 | this.shortcut = shortcut; 15 | this.selected = selected; 16 | this.event = event; 17 | } 18 | 19 | public String getLabel() { 20 | return label; 21 | } 22 | 23 | public String getShortcut() { 24 | return shortcut; 25 | } 26 | 27 | public boolean isSelected() { 28 | return selected; 29 | } 30 | 31 | @Override 32 | public void draw(PopupMenuState state) { 33 | if (ImGui.menuItem(this.label, this.shortcut, this.selected)) { 34 | event.run(); 35 | } 36 | state.canSeparate = true; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/popup/items/PopupItemPredicate.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.popup.items; 2 | 3 | import me.f1nal.trinity.gui.components.popup.PopupMenuState; 4 | import me.f1nal.trinity.util.GuiUtil; 5 | 6 | import java.util.List; 7 | import java.util.function.BooleanSupplier; 8 | 9 | public class PopupItemPredicate extends PopupItem { 10 | private final BooleanSupplier predicate; 11 | private final List items; 12 | private final boolean disabled; 13 | 14 | public PopupItemPredicate(BooleanSupplier predicate, List items, boolean disabled) { 15 | this.predicate = predicate; 16 | this.items = items; 17 | this.disabled = disabled; 18 | } 19 | 20 | @Override 21 | public void draw(PopupMenuState state) { 22 | boolean enabled = predicate.getAsBoolean(); 23 | 24 | if (this.disabled) { 25 | GuiUtil.disabledWidget(enabled, () -> drawItems(state)); 26 | return; 27 | } 28 | 29 | if (enabled) { 30 | this.drawItems(state); 31 | } 32 | } 33 | 34 | private void drawItems(PopupMenuState state) { 35 | items.forEach(popupItem -> popupItem.draw(state)); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/popup/items/PopupItemSeparator.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.popup.items; 2 | 3 | import imgui.ImGui; 4 | import me.f1nal.trinity.gui.components.popup.PopupMenuState; 5 | 6 | public class PopupItemSeparator extends PopupItem { 7 | @Override 8 | public void draw(PopupMenuState state) { 9 | if (!state.canSeparate) { 10 | return; 11 | } 12 | ImGui.separator(); 13 | state.canSeparate = true; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/tabs/ListBoxTabsComponent.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.tabs; 2 | 3 | import me.f1nal.trinity.gui.components.general.ListBoxComponent; 4 | 5 | import java.util.List; 6 | 7 | public class ListBoxTabsComponent extends ListBoxComponent { 8 | public ListBoxTabsComponent(List elementList, T selection) { 9 | super(elementList, selection); 10 | } 11 | 12 | public ListBoxTabsComponent(List elementList) { 13 | super(elementList); 14 | } 15 | 16 | @Override 17 | public void draw(float sizeX, float sizeY) { 18 | super.draw(sizeX, sizeY); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/tabs/TabFrame.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.tabs; 2 | 3 | import me.f1nal.trinity.util.INameable; 4 | 5 | public interface TabFrame extends INameable { 6 | void drawTabContent(); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/tree/GenericTreeNode.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.tree; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class GenericTreeNode> { 7 | private final List children; 8 | 9 | public GenericTreeNode() { 10 | this.children = new ArrayList<>(); 11 | } 12 | 13 | public boolean isLeaf() { 14 | return this.children.isEmpty(); 15 | } 16 | 17 | public void addChild(T treeNode) { 18 | this.children.add(treeNode); 19 | } 20 | 21 | public List getChildren() { 22 | return children; 23 | } 24 | 25 | private void addChildrenRecursively(GenericTreeNode child, List> list) { 26 | list.add(child); 27 | for (GenericTreeNode c : child.getChildren()) { 28 | this.addChildrenRecursively(c, list); 29 | } 30 | } 31 | 32 | public List getAllChildren() { 33 | List list = new ArrayList<>(); 34 | //noinspection unchecked 35 | this.addChildrenRecursively(this, (List>) list); 36 | return list; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/tree/TreeComponent.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.tree; 2 | 3 | public class TreeComponent { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/components/tree/TreeNode.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.components.tree; 2 | 3 | public class TreeNode extends GenericTreeNode { 4 | public TreeNode() { 5 | super(); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/input/InputHandler.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.input; 2 | 3 | public class InputHandler { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/input/InputManager.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.input; 2 | 3 | import imgui.ImGui; 4 | 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public class InputManager { 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/input/KeyCode.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.input; 2 | 3 | public enum KeyCode { 4 | W, 5 | 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/viewport/notifications/ICaption.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.viewport.notifications; 2 | 3 | public interface ICaption { 4 | String getCaption(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/viewport/notifications/NotificationType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.viewport.notifications; 2 | 3 | import me.f1nal.trinity.gui.components.FontAwesomeIcons; 4 | import me.f1nal.trinity.theme.CodeColorScheme; 5 | 6 | import java.util.function.Supplier; 7 | 8 | public class NotificationType { 9 | private final String icon; 10 | private final Supplier color; 11 | 12 | public NotificationType(String icon, Supplier color) { 13 | this.icon = icon; 14 | this.color = color; 15 | } 16 | 17 | public String getIcon() { 18 | return icon; 19 | } 20 | 21 | public int getColor() { 22 | return color.get(); 23 | } 24 | 25 | public static final NotificationType ERROR = new NotificationType(FontAwesomeIcons.Times, () -> CodeColorScheme.NOTIFY_ERROR); 26 | public static final NotificationType WARNING = new NotificationType(FontAwesomeIcons.ExclamationTriangle, () -> CodeColorScheme.NOTIFY_WARN); 27 | public static final NotificationType INFO = new NotificationType(FontAwesomeIcons.Info, () -> CodeColorScheme.NOTIFY_INFORMATION); 28 | public static final NotificationType SUCCESS = new NotificationType(FontAwesomeIcons.Check, () -> CodeColorScheme.NOTIFY_SUCCESS); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/viewport/notifications/SimpleCaption.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.viewport.notifications; 2 | 3 | public class SimpleCaption implements ICaption { 4 | private final String caption; 5 | 6 | public SimpleCaption(String caption) { 7 | this.caption = caption; 8 | } 9 | 10 | @Override 11 | public String getCaption() { 12 | return caption; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/AboutWindow.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl; 2 | 3 | import imgui.ImGui; 4 | import imgui.flag.ImGuiWindowFlags; 5 | import me.f1nal.trinity.Main; 6 | import me.f1nal.trinity.Trinity; 7 | import me.f1nal.trinity.gui.components.FontAwesomeIcons; 8 | import me.f1nal.trinity.gui.windows.api.StaticWindow; 9 | import me.f1nal.trinity.util.GuiUtil; 10 | import me.f1nal.trinity.util.SystemUtil; 11 | 12 | import java.awt.*; 13 | 14 | public class AboutWindow extends StaticWindow { 15 | public AboutWindow(Trinity trinity) { 16 | super("About Trinity", 370, 100, trinity); 17 | this.windowFlags |= ImGuiWindowFlags.AlwaysAutoResize; 18 | } 19 | 20 | @Override 21 | protected void renderFrame() { 22 | ImGui.textWrapped(String.format("Software reverse engineering suite for Java applications developed by %s.\nYou are running version %s.", "final", Main.VERSION)); 23 | if (ImGui.button(FontAwesomeIcons.Link + " GitHub Page")) { 24 | SystemUtil.browseURL("https://github.com/firstfault/Trinity"); 25 | } 26 | GuiUtil.tooltip("Clicking will open a URL with your default browser"); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/LoadingDatabasePopup.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl; 2 | 3 | import imgui.ImGui; 4 | import me.f1nal.trinity.Main; 5 | import me.f1nal.trinity.Trinity; 6 | import me.f1nal.trinity.database.DatabaseLoader; 7 | import me.f1nal.trinity.gui.windows.api.PopupWindow; 8 | import me.f1nal.trinity.gui.windows.impl.project.create.NewProjectFrame; 9 | 10 | import java.io.File; 11 | 12 | public class LoadingDatabasePopup extends PopupWindow { 13 | private final File path; 14 | 15 | public LoadingDatabasePopup(Trinity trinity, File path) { 16 | super("Loading Database...", trinity); 17 | this.path = path; 18 | closeOnEscape = false; 19 | } 20 | 21 | @Override 22 | protected void renderFrame() { 23 | ImGui.text("Please wait while the last program database is being loaded."); 24 | if (DatabaseLoader.load.get(this.path).isDone()) { 25 | boolean status = DatabaseLoader.load.getStatus(); 26 | close(); 27 | if (!status) { 28 | Main.getWindowManager().addStaticWindow(NewProjectFrame.class); 29 | } 30 | DatabaseLoader.load.clear(); 31 | Main.getAppDataManager().getState().setDatabaseLoaded(true); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/SavingDatabasePopup.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl; 2 | 3 | import imgui.ImGui; 4 | import me.f1nal.trinity.Trinity; 5 | import me.f1nal.trinity.database.DatabaseLoader; 6 | import me.f1nal.trinity.gui.windows.api.PopupWindow; 7 | 8 | import java.util.function.Consumer; 9 | 10 | public class SavingDatabasePopup extends PopupWindow { 11 | private final Consumer callback; 12 | 13 | public SavingDatabasePopup(Trinity trinity, Consumer callback) { 14 | super("Saving Database...", trinity); 15 | this.callback = callback; 16 | closeOnEscape = false; 17 | } 18 | 19 | @Override 20 | protected void renderFrame() { 21 | ImGui.text("Please wait while the program database is being saved.\nExiting forcefully may result in corruption."); 22 | 23 | if (DatabaseLoader.save.get(trinity.getDatabase().getPath()).isDone()) { 24 | close(); 25 | callback.accept(DatabaseLoader.save.getStatus()); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/action/DeleteInstructionAction.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.action; 2 | 3 | import me.f1nal.trinity.gui.windows.impl.assembler.AssemblerFrame; 4 | import me.f1nal.trinity.gui.windows.impl.assembler.InstructionComponent; 5 | import org.lwjgl.glfw.GLFW; 6 | 7 | public final class DeleteInstructionAction implements InstructionAction { 8 | @Override 9 | public void execute(AssemblerFrame assemblerFrame, InstructionComponent instructionComponent) { 10 | assemblerFrame.deleteInstruction(instructionComponent); 11 | } 12 | 13 | @Override 14 | public String getName() { 15 | return "Delete"; 16 | } 17 | 18 | @Override 19 | public int getKey() { 20 | return GLFW.GLFW_KEY_DELETE; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/action/DuplicateInstructionAction.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.action; 2 | 3 | import me.f1nal.trinity.gui.windows.impl.assembler.AssemblerFrame; 4 | import me.f1nal.trinity.gui.windows.impl.assembler.InstructionComponent; 5 | import org.lwjgl.glfw.GLFW; 6 | 7 | public final class DuplicateInstructionAction implements InstructionAction { 8 | @Override 9 | public void execute(AssemblerFrame assemblerFrame, InstructionComponent instructionComponent) { 10 | assemblerFrame.duplicateInstruction(instructionComponent); 11 | } 12 | 13 | @Override 14 | public String getName() { 15 | return "Duplicate"; 16 | } 17 | 18 | @Override 19 | public int getKey() { 20 | return GLFW.GLFW_KEY_D; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/action/EditInstructionAction.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.action; 2 | 3 | import me.f1nal.trinity.gui.windows.impl.assembler.AssemblerFrame; 4 | import me.f1nal.trinity.gui.windows.impl.assembler.InstructionComponent; 5 | import org.lwjgl.glfw.GLFW; 6 | 7 | public final class EditInstructionAction implements InstructionAction { 8 | @Override 9 | public void execute(AssemblerFrame assemblerFrame, InstructionComponent instructionComponent) { 10 | assemblerFrame.openEditDialog(assemblerFrame.getInstructions().indexOf(instructionComponent)); 11 | } 12 | 13 | @Override 14 | public String getName() { 15 | return "Edit"; 16 | } 17 | 18 | @Override 19 | public int getKey() { 20 | return GLFW.GLFW_KEY_E; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/action/InsertInstructionAction.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.action; 2 | 3 | import me.f1nal.trinity.gui.windows.impl.assembler.AssemblerFrame; 4 | import me.f1nal.trinity.gui.windows.impl.assembler.InstructionComponent; 5 | import org.lwjgl.glfw.GLFW; 6 | 7 | public final class InsertInstructionAction implements InstructionAction { 8 | @Override 9 | public void execute(AssemblerFrame assemblerFrame, InstructionComponent instructionComponent) { 10 | assemblerFrame.openInsertDialog(assemblerFrame.getInstructions().indexOf(instructionComponent)); 11 | } 12 | 13 | @Override 14 | public String getName() { 15 | return "Insert"; 16 | } 17 | 18 | @Override 19 | public int getKey() { 20 | return GLFW.GLFW_KEY_I; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/action/InstructionAction.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.action; 2 | 3 | import me.f1nal.trinity.gui.windows.impl.assembler.AssemblerFrame; 4 | import me.f1nal.trinity.gui.windows.impl.assembler.InstructionComponent; 5 | import org.lwjgl.glfw.GLFW; 6 | 7 | import java.util.Objects; 8 | 9 | public interface InstructionAction { 10 | void execute(AssemblerFrame assemblerFrame, InstructionComponent instructionComponent); 11 | String getName(); 12 | int getKey(); 13 | 14 | default String getKeyName() { 15 | return Objects.requireNonNullElse(GLFW.glfwGetKeyName(getKey(), 0), "").toUpperCase(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/args/DetailsArgument.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.args; 2 | 3 | import me.f1nal.trinity.execution.MemberDetails; 4 | 5 | public class DetailsArgument extends InstructionOperand { 6 | private MemberDetails details; 7 | private final boolean method; 8 | 9 | public DetailsArgument(MemberDetails details, boolean method) { 10 | this.details = details; 11 | this.method = method; 12 | 13 | this.getDetailsText().addAll(details.asText(method)); 14 | } 15 | 16 | public MemberDetails getDetails() { 17 | return details; 18 | } 19 | 20 | @Override 21 | public InstructionOperand copy() { 22 | return new DetailsArgument(this.details, this.method); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/args/HandleArgument.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.args; 2 | 3 | import me.f1nal.trinity.decompiler.output.colors.ColoredString; 4 | import me.f1nal.trinity.execution.MemberDetails; 5 | import me.f1nal.trinity.theme.CodeColorScheme; 6 | import org.objectweb.asm.Handle; 7 | import org.objectweb.asm.Opcodes; 8 | 9 | public class HandleArgument extends InstructionOperand { 10 | private final Handle handle; 11 | 12 | public HandleArgument(Handle handle) { 13 | this.handle = handle; 14 | getDetailsText().add(new ColoredString("h_" + this.getTag(handle.getTag()).toLowerCase(), CodeColorScheme.KEYWORD)); 15 | getDetailsText().addAll(new MemberDetails(handle.getOwner(), handle.getName(), handle.getDesc()).asText(handle.getTag() >= Opcodes.H_INVOKEVIRTUAL)); 16 | } 17 | 18 | private final static String[] TAGS = {"GETFIELD", "GETSTATIC", "PUTFIELD", "PUTSTATIC", "INVOKEVIRTUAL", "INVOKESTATIC", "INVOKESPECIAL", "NEWINVOKESPECIAL", "INVOKEINTERFACE",}; 19 | 20 | private String getTag(int tag) { 21 | return TAGS[tag - Opcodes.H_GETFIELD]; 22 | } 23 | 24 | @Override 25 | public InstructionOperand copy() { 26 | return new HandleArgument(this.handle); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/args/InstructionOperand.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.args; 2 | 3 | import imgui.ImVec4; 4 | import me.f1nal.trinity.decompiler.output.colors.ColoredString; 5 | import me.f1nal.trinity.gui.windows.impl.assembler.fields.InstructionField; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public abstract class InstructionOperand { 11 | /** 12 | * Instruction details shown in the list of all instructions. 13 | */ 14 | private final List detailsText = new ArrayList<>(); 15 | private final List fields = new ArrayList<>(); 16 | private ImVec4 bounds; 17 | 18 | public void setBounds(ImVec4 bounds) { 19 | this.bounds = bounds; 20 | } 21 | 22 | public ImVec4 getBounds() { 23 | return bounds; 24 | } 25 | 26 | public List getDetailsText() { 27 | return detailsText; 28 | } 29 | 30 | public List getFields() { 31 | return fields; 32 | } 33 | 34 | public abstract InstructionOperand copy(); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/args/InvokeDynamicArgument.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.args; 2 | 3 | import me.f1nal.trinity.decompiler.output.colors.ColoredString; 4 | import me.f1nal.trinity.theme.CodeColorScheme; 5 | 6 | public class InvokeDynamicArgument extends InstructionOperand { 7 | private final String name, desc; 8 | public InvokeDynamicArgument(String name, String desc) { 9 | this.name = name; 10 | this.desc = desc; 11 | getDetailsText().add(new ColoredString(name, CodeColorScheme.METHOD_REF)); 12 | getDetailsText().add(new ColoredString("#", CodeColorScheme.DISABLED)); 13 | getDetailsText().add(new ColoredString(desc, CodeColorScheme.METHOD_REF)); 14 | } 15 | 16 | @Override 17 | public InstructionOperand copy() { 18 | return new InvokeDynamicArgument(this.name, this.desc); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/args/StringArgument.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.args; 2 | 3 | import me.f1nal.trinity.decompiler.output.colors.ColoredString; 4 | import me.f1nal.trinity.theme.CodeColorScheme; 5 | 6 | public class StringArgument extends InstructionOperand { 7 | private final String string; 8 | 9 | public StringArgument(String string) { 10 | this.string = string; 11 | this.getDetailsText().add(new ColoredString(String.format("\"%s\"", string), CodeColorScheme.STRING)); 12 | } 13 | 14 | public String getString() { 15 | return string; 16 | } 17 | 18 | @Override 19 | public InstructionOperand copy() { 20 | return new StringArgument(string); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/args/TypeArgument.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.args; 2 | 3 | import me.f1nal.trinity.decompiler.output.colors.ColoredString; 4 | import me.f1nal.trinity.theme.CodeColorScheme; 5 | 6 | public class TypeArgument extends InstructionOperand { 7 | private final String className; 8 | 9 | public TypeArgument(String className) { 10 | this.className = className; 11 | getDetailsText().add(new ColoredString(className, CodeColorScheme.CLASS_REF)); 12 | } 13 | 14 | @Override 15 | public InstructionOperand copy() { 16 | return new TypeArgument(this.className); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/args/VariableArgument.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.args; 2 | 3 | import me.f1nal.trinity.decompiler.output.colors.ColoredImString; 4 | import me.f1nal.trinity.execution.var.Variable; 5 | import me.f1nal.trinity.gui.windows.impl.assembler.fields.TextField; 6 | import me.f1nal.trinity.theme.CodeColorScheme; 7 | 8 | public class VariableArgument extends InstructionOperand { 9 | private final Variable variable; 10 | 11 | public VariableArgument(Variable variable) { 12 | this.variable = variable; 13 | 14 | this.getDetailsText().add(new ColoredImString(variable.getNameProperty(), CodeColorScheme.VAR_REF)); 15 | if (variable.isEditable()) { 16 | this.getFields().add(new TextField("Variable Name", variable.getNameProperty())); 17 | } 18 | } 19 | 20 | public Variable getVariable() { 21 | return variable; 22 | } 23 | 24 | @Override 25 | public InstructionOperand copy() { 26 | return new VariableArgument(this.variable); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/drag/InstructionPosition.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.drag; 2 | 3 | import me.f1nal.trinity.gui.windows.impl.assembler.InstructionComponent; 4 | import me.f1nal.trinity.gui.windows.impl.assembler.InstructionList; 5 | 6 | public class InstructionPosition { 7 | private final InstructionList list; 8 | private final InstructionComponent component; 9 | private final int index; 10 | 11 | public InstructionPosition(InstructionList list, InstructionComponent component, int index) { 12 | this.list = list; 13 | this.component = component; 14 | this.index = index; 15 | } 16 | 17 | public int getIndex() { 18 | return index; 19 | } 20 | 21 | public InstructionComponent getComponent() { 22 | return component; 23 | } 24 | 25 | public InstructionList getList() { 26 | return list; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/fields/InstructionField.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.fields; 2 | 3 | public abstract class InstructionField { 4 | public abstract void draw(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/fields/TextField.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.fields; 2 | 3 | import imgui.ImGui; 4 | import imgui.type.ImString; 5 | import me.f1nal.trinity.gui.components.ComponentId; 6 | 7 | public class TextField extends InstructionField { 8 | private final String label; 9 | private final ImString text; 10 | private final String id = ComponentId.getId(this.getClass()); 11 | 12 | public TextField(String label, ImString text) { 13 | this.label = label; 14 | this.text = text; 15 | } 16 | public String getLabel() { 17 | return label; 18 | } 19 | 20 | public ImString getText() { 21 | return text; 22 | } 23 | 24 | @Override 25 | public void draw() { 26 | ImGui.inputText(this.getLabel() + "###" + this.id, this.getText()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/line/InstructionDrag.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.line; 2 | 3 | import imgui.ImGui; 4 | import imgui.ImVec2; 5 | import me.f1nal.trinity.gui.windows.impl.assembler.InstructionComponent; 6 | 7 | public class InstructionDrag { 8 | private final InstructionComponent component; 9 | private ImVec2 mousePos; 10 | private final int index; 11 | 12 | public InstructionDrag(InstructionComponent component, ImVec2 mousePos, int index) { 13 | this.component = component; 14 | this.mousePos = mousePos; 15 | this.index = index; 16 | } 17 | 18 | public InstructionComponent getComponent() { 19 | return component; 20 | } 21 | 22 | public ImVec2 getMousePos() { 23 | return mousePos; 24 | } 25 | 26 | public int getIndex() { 27 | return index; 28 | } 29 | 30 | public void resetMousePos() { 31 | this.mousePos = ImGui.getMousePos(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/line/MethodOpcodeSource.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.line; 2 | 3 | import org.objectweb.asm.tree.AbstractInsnNode; 4 | 5 | import java.util.List; 6 | 7 | public class MethodOpcodeSource { 8 | private final List componentLinkedInstructions; 9 | private final int opcode; 10 | 11 | public MethodOpcodeSource(List componentLinkedInstructions, int opcode) { 12 | this.componentLinkedInstructions = componentLinkedInstructions; 13 | this.opcode = opcode; 14 | } 15 | 16 | public List getComponentLinkedInstructions() { 17 | return componentLinkedInstructions; 18 | } 19 | 20 | public int getOpcode() { 21 | return opcode; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/line/SourceLineNumber.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.line; 2 | 3 | import java.util.Objects; 4 | 5 | public class SourceLineNumber { 6 | private final int lineNumber; 7 | 8 | public SourceLineNumber(int lineNumber) { 9 | this.lineNumber = lineNumber; 10 | } 11 | 12 | public int getLineNumber() { 13 | return lineNumber; 14 | } 15 | 16 | @Override 17 | public boolean equals(Object o) { 18 | if (this == o) return true; 19 | if (o == null || getClass() != o.getClass()) return false; 20 | SourceLineNumber that = (SourceLineNumber) o; 21 | return lineNumber == that.lineNumber; 22 | } 23 | 24 | @Override 25 | public int hashCode() { 26 | return Objects.hash(lineNumber); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/popup/edit/EditFieldClass.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.popup.edit; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | import me.f1nal.trinity.gui.components.ClassSelectComponent; 5 | 6 | import java.util.function.Consumer; 7 | import java.util.function.Supplier; 8 | 9 | public final class EditFieldClass extends EditField { 10 | private final ClassSelectComponent classSelectComponent; 11 | 12 | public EditFieldClass(Trinity trinity, String editFieldName, Supplier getter, Consumer setter) { 13 | super(getter, setter); 14 | this.classSelectComponent = new ClassSelectComponent(trinity, editFieldName, target -> target.getInput() != null); 15 | } 16 | 17 | @Override 18 | public void draw() { 19 | if(this.classSelectComponent.draw()) { 20 | set(classSelectComponent.getClassName()); 21 | } 22 | } 23 | 24 | @Override 25 | public void updateField() { 26 | this.classSelectComponent.setClassName(get()); 27 | } 28 | 29 | @Override 30 | public boolean isValidInput() { 31 | final var className = classSelectComponent.getClassName(); 32 | return className != null && !className.isEmpty(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/popup/edit/EditFieldDescriptor.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.popup.edit; 2 | 3 | import java.util.function.Consumer; 4 | import java.util.function.Supplier; 5 | 6 | public class EditFieldDescriptor extends EditFieldString { 7 | EditFieldDescriptor(Supplier getter, Consumer setter) { 8 | super(256, "Descriptor", "java.lang.Object (Internal Type)", getter, setter); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/popup/edit/EditFieldInteger.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.popup.edit; 2 | 3 | import imgui.ImGui; 4 | import imgui.type.ImInt; 5 | 6 | import java.util.function.Consumer; 7 | import java.util.function.Supplier; 8 | 9 | public class EditFieldInteger extends EditField { 10 | private final String label; 11 | private final int dataType; 12 | private final ImInt value = new ImInt(); 13 | 14 | public EditFieldInteger(String label, Supplier getter, Consumer setter, int dataType) { 15 | super(getter, setter); 16 | this.label = label; 17 | this.dataType = dataType; 18 | } 19 | 20 | @Override 21 | public void draw() { 22 | if (ImGui.inputScalar(this.label, this.dataType, value, 1, 3)) { 23 | this.set(this.value.get()); 24 | } 25 | } 26 | 27 | @Override 28 | public void updateField() { 29 | value.set(this.get()); 30 | } 31 | 32 | @Override 33 | public boolean isValidInput() { 34 | return true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/popup/edit/EditFieldString.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.popup.edit; 2 | 3 | import java.util.function.Consumer; 4 | import java.util.function.Supplier; 5 | 6 | public class EditFieldString extends EditFieldText { 7 | EditFieldString(int length, String label, String hint, Supplier getter, Consumer setter) { 8 | super(length, label, hint, getter, setter); 9 | } 10 | 11 | @Override 12 | protected String parse(String input) { 13 | return input; 14 | } 15 | 16 | @Override 17 | public void updateField() { 18 | text.set(get()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/assembler/popup/edit/InvalidEditInputException.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.assembler.popup.edit; 2 | 3 | public class InvalidEditInputException extends Throwable { 4 | } 5 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/classstructure/ClassStructure.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.classstructure; 2 | 3 | import me.f1nal.trinity.execution.ClassInput; 4 | import me.f1nal.trinity.gui.windows.impl.classstructure.nodes.ClassStructureNodeClass; 5 | import me.f1nal.trinity.gui.windows.impl.classstructure.nodes.ClassStructureNodeField; 6 | import me.f1nal.trinity.gui.windows.impl.classstructure.nodes.ClassStructureNodeMethod; 7 | 8 | import java.util.Objects; 9 | 10 | public class ClassStructure { 11 | private final ClassInput classInput; 12 | private final ClassStructureNodeClass rootNode; 13 | 14 | public ClassStructure(ClassInput classInput) { 15 | this.classInput = Objects.requireNonNull(classInput, "Cannot initialize structure with a null class"); 16 | this.rootNode = new ClassStructureNodeClass(classInput); 17 | this.rootNode.getBrowserViewerNode().setDefaultOpen(true); 18 | 19 | classInput.getFieldMap().values().stream().map(ClassStructureNodeField::new).forEach(this.rootNode::addChild); 20 | classInput.getMethodMap().values().stream().map(ClassStructureNodeMethod::new).forEach(this.rootNode::addChild); 21 | } 22 | 23 | public ClassInput getClassInput() { 24 | return classInput; 25 | } 26 | 27 | public ClassStructureNodeClass getRootNode() { 28 | return rootNode; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/classstructure/StructureKind.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.classstructure; 2 | 3 | import me.f1nal.trinity.gui.components.filter.kind.IKindType; 4 | import me.f1nal.trinity.theme.CodeColorScheme; 5 | 6 | import java.util.function.Supplier; 7 | 8 | public enum StructureKind implements IKindType { 9 | CLASSES("Class", () -> CodeColorScheme.CLASS_REF), 10 | FIELD("Field", () -> CodeColorScheme.FIELD_REF), 11 | METHOD("Method", () -> CodeColorScheme.METHOD_REF), 12 | ; 13 | 14 | private final String name; 15 | private final Supplier color; 16 | 17 | StructureKind(String name, Supplier color) { 18 | this.name = name; 19 | this.color = color; 20 | } 21 | 22 | @Override 23 | public int getColor() { 24 | return color.get(); 25 | } 26 | 27 | @Override 28 | public String getName() { 29 | return this.name; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/classstructure/nodes/ClassStructureNodeField.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.classstructure.nodes; 2 | 3 | import me.f1nal.trinity.decompiler.output.colors.ColoredStringBuilder; 4 | import me.f1nal.trinity.execution.FieldInput; 5 | import me.f1nal.trinity.gui.components.FontAwesomeIcons; 6 | import me.f1nal.trinity.gui.windows.impl.classstructure.StructureKind; 7 | 8 | public class ClassStructureNodeField extends AbstractClassStructureNodeInput { 9 | public ClassStructureNodeField(FieldInput fieldInput) { 10 | super(FontAwesomeIcons.List, fieldInput); 11 | } 12 | 13 | @Override 14 | protected String getText() { 15 | return getInput().getDisplayName().getName(); 16 | } 17 | 18 | @Override 19 | public StructureKind getKind() { 20 | return StructureKind.FIELD; 21 | } 22 | 23 | @Override 24 | protected void appendType(ColoredStringBuilder text, String suffix) { 25 | appendReturnType(text, getInput().getDescriptor(), suffix); 26 | } 27 | 28 | @Override 29 | protected void appendParameters(ColoredStringBuilder text) { 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/constant/ConstantViewCache.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.constant; 2 | 3 | import me.f1nal.trinity.execution.xref.XrefKind; 4 | import me.f1nal.trinity.execution.xref.where.XrefWhere; 5 | import me.f1nal.trinity.gui.components.filter.kind.IKind; 6 | import me.f1nal.trinity.gui.components.general.table.IWhere; 7 | import me.f1nal.trinity.util.SearchTermMatchable; 8 | 9 | public class ConstantViewCache implements SearchTermMatchable, IWhere, IKind { 10 | private final String constant; 11 | private final XrefWhere where; 12 | private final XrefKind kind; 13 | 14 | public ConstantViewCache(String constant, XrefWhere where, XrefKind kind) { 15 | this.constant = constant; 16 | this.where = where; 17 | this.kind = kind; 18 | } 19 | 20 | public String getConstant() { 21 | return constant; 22 | } 23 | 24 | public XrefWhere getWhere() { 25 | return where; 26 | } 27 | 28 | @Override 29 | public XrefKind getKind() { 30 | return kind; 31 | } 32 | 33 | @Override 34 | public boolean matches(String searchTerm) { 35 | return this.getWhere().getText().contains(searchTerm); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/constant/search/ConstantSearchType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.constant.search; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | import me.f1nal.trinity.gui.windows.impl.constant.ConstantViewCache; 5 | import me.f1nal.trinity.util.INameable; 6 | 7 | import java.util.List; 8 | 9 | public abstract class ConstantSearchType implements INameable { 10 | private final String name; 11 | private final Trinity trinity; 12 | 13 | protected ConstantSearchType(String name, Trinity trinity) { 14 | this.name = name; 15 | this.trinity = trinity; 16 | } 17 | 18 | @Override 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public Trinity getTrinity() { 24 | return trinity; 25 | } 26 | 27 | public abstract boolean draw(); 28 | public abstract void populate(List list); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/cp/FileKind.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.cp; 2 | 3 | import me.f1nal.trinity.gui.components.filter.kind.IKindType; 4 | import me.f1nal.trinity.theme.CodeColorScheme; 5 | 6 | import java.util.function.Supplier; 7 | 8 | public enum FileKind implements IKindType { 9 | CLASSES("Classes", "Class", () -> CodeColorScheme.FILE_CLASS), 10 | ABSTRACT("Abstract", "Abstract Class", () -> CodeColorScheme.FILE_ABSTRACT), 11 | INTERFACES("Interface", "Interface", () -> CodeColorScheme.FILE_INTERFACE), 12 | ENUM("Enum", "Enum Class", () -> CodeColorScheme.FILE_ENUM), 13 | ANNOTATION("Annotation", "Annotation Class", () -> CodeColorScheme.FILE_ANNOTATION), 14 | RESOURCE("Resource", "Resource File", () -> CodeColorScheme.FILE_RESOURCE), 15 | ; 16 | 17 | private final String name; 18 | private final String fileType; 19 | private final Supplier color; 20 | 21 | FileKind(String name, String fileType, Supplier color) { 22 | this.name = name; 23 | this.fileType = fileType; 24 | this.color = color; 25 | } 26 | 27 | @Override 28 | public int getColor() { 29 | return color.get(); 30 | } 31 | 32 | @Override 33 | public String getName() { 34 | return this.name; 35 | } 36 | 37 | public String getFileType() { 38 | return fileType; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/cp/IBrowserViewerNode.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.cp; 2 | 3 | import me.f1nal.trinity.gui.components.filter.kind.IKind; 4 | import me.f1nal.trinity.util.SearchTermMatchable; 5 | 6 | public interface IBrowserViewerNode extends SearchTermMatchable, IKind { 7 | BrowserViewerNode getBrowserViewerNode(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/cp/IRenameHandler.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.cp; 2 | 3 | public interface IRenameHandler { 4 | RenameHandler getRenameHandler(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/cp/ProjectBrowserTreeNode.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.cp; 2 | 3 | import imgui.ImGui; 4 | import me.f1nal.trinity.Main; 5 | import me.f1nal.trinity.gui.components.popup.PopupItemBuilder; 6 | import me.f1nal.trinity.gui.components.tree.GenericTreeNode; 7 | import me.f1nal.trinity.util.GuiUtil; 8 | import me.f1nal.trinity.util.SystemUtil; 9 | 10 | public abstract class ProjectBrowserTreeNode extends GenericTreeNode> { 11 | protected final N node; 12 | 13 | protected ProjectBrowserTreeNode(N node) { 14 | this.node = node; 15 | } 16 | 17 | public N getNode() { 18 | return node; 19 | } 20 | 21 | public abstract void draw(ProjectBrowserFrame projectBrowserFrame); 22 | 23 | protected final void drawSize(String sizeText, long sizeInBytes) { 24 | ImGui.text(sizeText); 25 | GuiUtil.tooltip(sizeInBytes + "B"); 26 | if (ImGui.isItemClicked(1)) { 27 | Main.getDisplayManager().getPopupMenu().show(PopupItemBuilder.create().menuItem("Copy Size", () -> SystemUtil.copyToClipboard(String.valueOf(sizeInBytes)))); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/cp/ProjectBrowserTreeNodeEntry.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.cp; 2 | 3 | import imgui.ImGui; 4 | import imgui.flag.ImGuiTreeNodeFlags; 5 | import me.f1nal.trinity.execution.packages.ArchiveEntry; 6 | 7 | public class ProjectBrowserTreeNodeEntry extends ProjectBrowserTreeNode { 8 | public ProjectBrowserTreeNodeEntry(ArchiveEntry archiveEntry) { 9 | super(archiveEntry); 10 | } 11 | 12 | @Override 13 | public void draw(ProjectBrowserFrame projectBrowserFrame) { 14 | ImGui.tableNextRow(); 15 | ImGui.tableNextColumn(); 16 | 17 | ImGui.treeNodeEx("", ImGuiTreeNodeFlags.Leaf | ImGuiTreeNodeFlags.NoTreePushOnOpen | 18 | ImGuiTreeNodeFlags.SpanFullWidth); 19 | ImGui.sameLine(); 20 | node.getBrowserViewerNode().draw(); 21 | 22 | ImGui.tableNextColumn(); 23 | this.drawSize(node.getSize(), node.getSizeInBytes()); 24 | ImGui.tableNextColumn(); 25 | ImGui.textUnformatted(node.getArchiveEntryTypeName()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/cp/RenameHandler.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.cp; 2 | 3 | import me.f1nal.trinity.remap.Remapper; 4 | 5 | public interface RenameHandler { 6 | /** 7 | * Full name of this entry, to set the renaming field to when beginning rename. 8 | * @return The full name or {@code null} to automatically get the name. 9 | */ 10 | default String getFullName() { 11 | return null; 12 | } 13 | 14 | void rename(Remapper remapper, String newName); 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/entryviewer/impl/decompiler/DecompilerCoordinates.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.entryviewer.impl.decompiler; 2 | 3 | import java.util.Objects; 4 | 5 | public class DecompilerCoordinates { 6 | private final DecompilerLine line; 7 | private final int character; 8 | 9 | public DecompilerCoordinates(DecompilerLine line, int character) { 10 | this.line = line; 11 | this.character = character; 12 | } 13 | 14 | public DecompilerComponent getComponent() { 15 | return line.getComponentAtCharacter(this.getCharacter()); 16 | } 17 | 18 | public DecompilerLine getLine() { 19 | return line; 20 | } 21 | 22 | public int getCharacter() { 23 | return character; 24 | } 25 | 26 | @Override 27 | public boolean equals(Object o) { 28 | if (this == o) return true; 29 | if (o == null || getClass() != o.getClass()) return false; 30 | DecompilerCoordinates that = (DecompilerCoordinates) o; 31 | return character == that.character && Objects.equals(line, that.line); 32 | } 33 | 34 | @Override 35 | public int hashCode() { 36 | return Objects.hash(line, character); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/entryviewer/impl/decompiler/DecompilerHighlight.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.entryviewer.impl.decompiler; 2 | 3 | import imgui.ImColor; 4 | import me.f1nal.trinity.util.animation.Animation; 5 | import me.f1nal.trinity.util.animation.Easing; 6 | 7 | public class DecompilerHighlight { 8 | private final DecompilerComponent textComponent; 9 | private final Animation animation = new Animation(Easing.LINEAR, 1550L, 1.F); 10 | private boolean scrolled; 11 | 12 | public DecompilerHighlight(DecompilerComponent textComponent) { 13 | this.textComponent = textComponent; 14 | } 15 | 16 | public void setScrolled(boolean scrolled) { 17 | this.scrolled = scrolled; 18 | } 19 | 20 | public boolean isScrolled() { 21 | return scrolled; 22 | } 23 | 24 | public DecompilerComponent getTextComponent() { 25 | return textComponent; 26 | } 27 | 28 | public boolean isFinished() { 29 | return this.animation.isFinished(); 30 | } 31 | 32 | public int getColor() { 33 | animation.run(0.F); 34 | int white = (int) (150.F * animation.getValue()); 35 | return ImColor.rgba(white, white, white, (int) (120.F * animation.getValue())); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/entryviewer/impl/decompiler/DecompilerSelection.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.entryviewer.impl.decompiler; 2 | 3 | public class DecompilerSelection { 4 | private final DecompilerCoordinates start; 5 | private DecompilerCoordinates end; 6 | 7 | public DecompilerSelection(DecompilerCoordinates start, DecompilerCoordinates end) { 8 | this.start = start; 9 | this.end = end; 10 | } 11 | 12 | public DecompilerCoordinates getStart() { 13 | return start; 14 | } 15 | 16 | public DecompilerCoordinates getEnd() { 17 | return end; 18 | } 19 | 20 | public void setEnd(DecompilerCoordinates end) { 21 | this.end = end; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/ldc/types/CstTypeByte.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.ldc.types; 2 | 3 | import imgui.flag.ImGuiDataType; 4 | import me.f1nal.trinity.gui.windows.impl.assembler.popup.edit.EditFieldInteger; 5 | import me.f1nal.trinity.gui.windows.impl.ldc.CstType; 6 | 7 | public class CstTypeByte extends CstType { 8 | public CstTypeByte() { 9 | super("Byte"); 10 | this.addField(new EditFieldInteger("Value", () -> Integer.valueOf(getValue()), (val) -> { 11 | this.setValue(val.byteValue()); 12 | }, ImGuiDataType.S8)); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/project/create/AbstractProjectCreationTab.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.project.create; 2 | 3 | import me.f1nal.trinity.gui.components.tabs.TabFrame; 4 | import me.f1nal.trinity.util.IDescribable; 5 | 6 | public abstract class AbstractProjectCreationTab implements TabFrame, IDescribable { 7 | protected abstract boolean isInputValid(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/project/create/misc/ClassPathViewerElement.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.project.create.misc; 2 | 3 | import me.f1nal.trinity.util.ByteUtil; 4 | import me.f1nal.trinity.util.IDescribable; 5 | import me.f1nal.trinity.util.INameable; 6 | 7 | import java.util.function.BooleanSupplier; 8 | 9 | public class ClassPathViewerElement implements INameable, IDescribable { 10 | private final String name; 11 | private final String size; 12 | private final BooleanSupplier remove; 13 | 14 | public ClassPathViewerElement(String name, long size, BooleanSupplier remove) { 15 | this.name = name; 16 | this.size = ByteUtil.getHumanReadableByteCountSI(size); 17 | this.remove = remove; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return this.name; 23 | } 24 | 25 | @Override 26 | public String getDescription() { 27 | return this.size; 28 | } 29 | 30 | public boolean remove() { 31 | return remove.getAsBoolean(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/project/settings/AbstractProjectSettingsTab.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.project.settings; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | import me.f1nal.trinity.database.Database; 5 | import me.f1nal.trinity.gui.components.tabs.TabFrame; 6 | 7 | public abstract class AbstractProjectSettingsTab implements TabFrame { 8 | private final Trinity trinity; 9 | 10 | protected AbstractProjectSettingsTab(Trinity trinity) { 11 | this.trinity = trinity; 12 | } 13 | 14 | public final Trinity getTrinity() { 15 | return trinity; 16 | } 17 | 18 | public final Database getDatabase() { 19 | return trinity.getDatabase(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/themes/ModifiedThemeState.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.themes; 2 | 3 | import me.f1nal.trinity.theme.CodeColorScheme; 4 | import me.f1nal.trinity.theme.Theme; 5 | 6 | public class ModifiedThemeState { 7 | private final Theme theme; 8 | private final int[] originalColors; 9 | 10 | public ModifiedThemeState(Theme theme) { 11 | this.theme = theme; 12 | this.originalColors = new int[theme.getColors().size()]; 13 | for (int i = 0; i < this.originalColors.length; i++) { 14 | this.originalColors[i] = CodeColorScheme.getRgb(theme.getColors().get(i).getRgba()); 15 | } 16 | } 17 | 18 | public void revertTheme() { 19 | for (int i = 0; i < this.theme.getColors().size(); i++) { 20 | this.theme.getColors().get(i).setRgba(CodeColorScheme.toRgba(this.originalColors[i])); 21 | } 22 | } 23 | 24 | public Theme getTheme() { 25 | return theme; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/themes/ThemeNamePopup.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.themes; 2 | 3 | import imgui.ImGui; 4 | import imgui.type.ImString; 5 | import me.f1nal.trinity.Main; 6 | import me.f1nal.trinity.Trinity; 7 | import me.f1nal.trinity.gui.windows.api.PopupWindow; 8 | 9 | import java.util.function.Consumer; 10 | 11 | public class ThemeNamePopup extends PopupWindow { 12 | private final ImString string = new ImString("New Theme", 32); 13 | private final Consumer finish; 14 | 15 | public ThemeNamePopup(Trinity trinity, Consumer finish) { 16 | super("Create Theme", trinity); 17 | this.finish = finish; 18 | } 19 | 20 | @Override 21 | protected void renderFrame() { 22 | ImGui.inputText("Theme Name", this.string); 23 | boolean disabled = string.get().isEmpty() || Main.getThemeManager().getTheme(this.string.get()) != null; 24 | if (disabled) ImGui.beginDisabled(); 25 | if (ImGui.button("Done")) { 26 | this.finish.accept(this.string.get()); 27 | this.close(); 28 | } 29 | if (disabled) ImGui.endDisabled(); 30 | ImGui.sameLine(); 31 | if (ImGui.button("Close")) { 32 | this.close(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/xref/SearchMaxDisplay.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.xref; 2 | 3 | import me.f1nal.trinity.util.INameable; 4 | 5 | public enum SearchMaxDisplay implements INameable { 6 | MAX_100(100), 7 | MAX_200(200), 8 | MAX_500(500), 9 | MAX_1000(1000), 10 | MAX_2000(2000), 11 | MAX_2500(2500), 12 | ; 13 | 14 | private final int max; 15 | 16 | SearchMaxDisplay(int max) { 17 | this.max = max; 18 | } 19 | 20 | public int getMax() { 21 | return max; 22 | } 23 | 24 | @Override 25 | public String getName() { 26 | return String.valueOf(this.max); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/xref/XrefView.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.xref; 2 | 3 | import me.f1nal.trinity.execution.xref.AbstractXref; 4 | import me.f1nal.trinity.util.SearchTermMatchable; 5 | 6 | public class XrefView implements SearchTermMatchable { 7 | private final AbstractXref xref; 8 | private final String access; 9 | private final String invocation; 10 | private final String where; 11 | 12 | public XrefView(AbstractXref xref, String access, String invocation, String where) { 13 | this.xref = xref; 14 | this.access = access; 15 | this.invocation = invocation; 16 | this.where = where; 17 | } 18 | 19 | public AbstractXref getXref() { 20 | return xref; 21 | } 22 | 23 | public String getAccess() { 24 | return access; 25 | } 26 | 27 | public String getInvocation() { 28 | return invocation; 29 | } 30 | 31 | public String getWhere() { 32 | return where; 33 | } 34 | 35 | @Override 36 | public boolean matches(String searchTerm) { 37 | return invocation.toLowerCase().contains(searchTerm.toLowerCase()); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/xref/builder/IXrefBuilderProvider.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.xref.builder; 2 | 3 | import me.f1nal.trinity.Main; 4 | import me.f1nal.trinity.Trinity; 5 | import me.f1nal.trinity.execution.xref.XrefMap; 6 | import me.f1nal.trinity.gui.components.popup.PopupItemBuilder; 7 | import me.f1nal.trinity.gui.windows.impl.xref.XrefViewerFrame; 8 | 9 | public interface IXrefBuilderProvider { 10 | XrefBuilder createXrefBuilder(XrefMap xrefMap); 11 | default void addXrefViewerMenuItem(Trinity trinity, PopupItemBuilder builder) { 12 | builder.menuItem("View Xrefs", () -> { 13 | Main.getWindowManager().addClosableWindow(new XrefViewerFrame(this.createXrefBuilder(trinity.getExecution().getXrefMap()), trinity)); 14 | }); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/xref/builder/XrefBuilder.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.xref.builder; 2 | 3 | import me.f1nal.trinity.execution.xref.AbstractXref; 4 | import me.f1nal.trinity.execution.xref.XrefMap; 5 | 6 | import java.util.Collection; 7 | 8 | public abstract class XrefBuilder { 9 | private final XrefMap xrefMap; 10 | 11 | protected XrefBuilder(XrefMap xrefMap) { 12 | this.xrefMap = xrefMap; 13 | } 14 | 15 | public XrefMap getXrefMap() { 16 | return xrefMap; 17 | } 18 | 19 | public abstract String getTitle(); 20 | public abstract Collection createXrefs(); 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/xref/search/XrefSearchType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.xref.search; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | import me.f1nal.trinity.gui.windows.impl.xref.builder.XrefBuilder; 5 | import me.f1nal.trinity.util.INameable; 6 | 7 | public abstract class XrefSearchType implements INameable { 8 | private final String name; 9 | protected final Trinity trinity; 10 | 11 | protected XrefSearchType(String name, Trinity trinity) { 12 | this.name = name; 13 | this.trinity = trinity; 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return this.name; 19 | } 20 | 21 | /** 22 | * Draws this xref type. 23 | * @return {@code true} If we can search right now. 24 | */ 25 | public abstract boolean draw(); 26 | 27 | /** 28 | * Get a xref builder for this xref type. 29 | */ 30 | public abstract XrefBuilder search(); 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/gui/windows/impl/xref/search/XrefSearchTypeClass.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.gui.windows.impl.xref.search; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | import me.f1nal.trinity.gui.components.ClassSelectComponent; 5 | import me.f1nal.trinity.gui.windows.impl.xref.builder.XrefBuilder; 6 | import me.f1nal.trinity.gui.windows.impl.xref.builder.XrefBuilderClassRef; 7 | 8 | public class XrefSearchTypeClass extends XrefSearchType { 9 | private final ClassSelectComponent classSelectComponent = new ClassSelectComponent(trinity, "Class name", (target) -> true); 10 | 11 | protected XrefSearchTypeClass(Trinity trinity) { 12 | super("Class", trinity); 13 | } 14 | 15 | @Override 16 | public boolean draw() { 17 | classSelectComponent.draw(); 18 | return !this.classSelectComponent.getClassName().isEmpty(); 19 | } 20 | 21 | @Override 22 | public XrefBuilder search() { 23 | return new XrefBuilderClassRef(trinity.getExecution().getXrefMap(), this.classSelectComponent.getClassName()); 24 | } 25 | 26 | public ClassSelectComponent getClassSelectComponent() { 27 | return classSelectComponent; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/keybindings/Bindable.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.keybindings; 2 | 3 | import java.awt.event.KeyEvent; 4 | 5 | public class Bindable { 6 | private final String identifier; 7 | private final String displayName; 8 | private int keyCode; 9 | private String keyName; 10 | 11 | public Bindable(String identifier, String displayName) { 12 | this.identifier = identifier; 13 | this.displayName = displayName; 14 | 15 | this.bind(-1); 16 | } 17 | 18 | public void bind(int keyCode) { 19 | this.keyCode = keyCode; 20 | this.keyName = keyCode == -1 ? "None" : KeyEvent.getKeyText(keyCode); 21 | } 22 | 23 | public boolean isBound() { 24 | return keyCode != -1; 25 | } 26 | 27 | public int getKeyCode() { 28 | return keyCode; 29 | } 30 | 31 | public String getKeyName() { 32 | return keyName; 33 | } 34 | 35 | public String getIdentifier() { 36 | return identifier; 37 | } 38 | 39 | public String getDisplayName() { 40 | return displayName; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/keybindings/KeyBindManager.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.keybindings; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class KeyBindManager { 7 | private final List bindables = new ArrayList<>(); 8 | 9 | public final Bindable ASSEMBLER_INSERT = bindable("Assembler Insert", "assembler.insert"); 10 | 11 | private Bindable bindable(String name, String identifier) { 12 | Bindable bindable = new Bindable(identifier, name); 13 | bindables.add(bindable); 14 | return bindable; 15 | } 16 | 17 | public List getBindables() { 18 | return bindables; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/keybindings/KeyBinding.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.keybindings; 2 | 3 | public class KeyBinding { 4 | private final String shortName; 5 | private final int keyCode; 6 | 7 | public KeyBinding(String shortName, int keyCode) { 8 | this.shortName = shortName; 9 | this.keyCode = keyCode; 10 | } 11 | 12 | public String getShortName() { 13 | return shortName; 14 | } 15 | 16 | public int getKeyCode() { 17 | return keyCode; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/refactor/RefactorManager.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.refactor; 2 | 3 | import me.f1nal.trinity.Trinity; 4 | import me.f1nal.trinity.refactor.globalrename.GlobalRenameType; 5 | import me.f1nal.trinity.refactor.globalrename.impl.fullrename.FullGlobalRename; 6 | import me.f1nal.trinity.refactor.globalrename.impl.EnumFieldsGlobalRename; 7 | import me.f1nal.trinity.refactor.globalrename.impl.MixinGlobalRename; 8 | 9 | import java.util.List; 10 | 11 | public class RefactorManager { 12 | private final Trinity trinity; 13 | private final List globalRenameTypes = List.of(new FullGlobalRename(), new EnumFieldsGlobalRename(), new MixinGlobalRename()); 14 | 15 | public RefactorManager(Trinity trinity) { 16 | this.trinity = trinity; 17 | } 18 | 19 | public List getGlobalRenameTypes() { 20 | return globalRenameTypes; 21 | } 22 | 23 | public Trinity getTrinity() { 24 | return trinity; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/refactor/globalrename/GlobalRenameType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.refactor.globalrename; 2 | 3 | import me.f1nal.trinity.refactor.globalrename.api.GlobalRenameContext; 4 | import me.f1nal.trinity.util.IDescribable; 5 | import me.f1nal.trinity.util.INameable; 6 | 7 | public abstract class GlobalRenameType implements INameable, IDescribable { 8 | private final String name; 9 | private final String tooltipDescription; 10 | 11 | protected GlobalRenameType(String name, String tooltipDescription) { 12 | this.name = name; 13 | this.tooltipDescription = tooltipDescription; 14 | } 15 | 16 | @Override 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | @Override 22 | public String getDescription() { 23 | return tooltipDescription; 24 | } 25 | 26 | /** 27 | * Draw user inputs required for this global rename. 28 | */ 29 | public abstract void drawInputs(); 30 | public abstract void refactor(GlobalRenameContext context); 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/refactor/globalrename/api/GlobalRenameContext.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.refactor.globalrename.api; 2 | 3 | import me.f1nal.trinity.execution.Execution; 4 | import me.f1nal.trinity.remap.NameHeuristics; 5 | 6 | import java.util.List; 7 | 8 | public class GlobalRenameContext { 9 | private final Execution execution; 10 | private final List renames; 11 | private final NameHeuristics nameHeuristics; 12 | 13 | public GlobalRenameContext(Execution execution, List renames, NameHeuristics nameHeuristics) { 14 | this.execution = execution; 15 | this.renames = renames; 16 | this.nameHeuristics = nameHeuristics; 17 | } 18 | 19 | public Execution execution() { 20 | return execution; 21 | } 22 | 23 | public List renames() { 24 | return renames; 25 | } 26 | 27 | public NameHeuristics nameHeuristics() { 28 | return nameHeuristics; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/refactor/globalrename/api/Rename.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.refactor.globalrename.api; 2 | 3 | import me.f1nal.trinity.execution.Input; 4 | import me.f1nal.trinity.gui.windows.impl.cp.RenameHandler; 5 | import me.f1nal.trinity.remap.Remapper; 6 | 7 | public final class Rename { 8 | private final RenameHandler handler; 9 | private final String newName; 10 | 11 | public Rename(RenameHandler handler, String newName) { 12 | this.handler = handler; 13 | this.newName = newName; 14 | } 15 | 16 | public RenameHandler getHandler() { 17 | return handler; 18 | } 19 | 20 | public String getNewName() { 21 | return newName; 22 | } 23 | 24 | public void rename(Remapper remapper) { 25 | this.handler.rename(remapper, newName); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/refactor/globalrename/impl/fullrename/types/FullRenameMember.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.refactor.globalrename.impl.fullrename.types; 2 | 3 | import me.f1nal.trinity.gui.components.MemorableCheckboxComponent; 4 | import me.f1nal.trinity.refactor.globalrename.api.GlobalRenameContext; 5 | 6 | public abstract class FullRenameMember { 7 | private final String label, namePrefix; 8 | private final MemorableCheckboxComponent enabled; 9 | private int count; 10 | 11 | protected FullRenameMember(String label, String namePrefix) { 12 | this.label = label; 13 | this.namePrefix = namePrefix; 14 | this.enabled = new MemorableCheckboxComponent("fullRename" + label, label, true); 15 | } 16 | 17 | public abstract void refactor(GlobalRenameContext context); 18 | 19 | public final void prepare() { 20 | this.count = 0; 21 | } 22 | 23 | public final void draw() { 24 | this.enabled.draw(); 25 | } 26 | 27 | protected final String generateName() { 28 | return generateName(++this.count); 29 | } 30 | 31 | protected final String generateName(int count) { 32 | return this.namePrefix + count; 33 | } 34 | 35 | public final boolean isEnabled() { 36 | return enabled.isChecked(); 37 | } 38 | 39 | public final String getLabel() { 40 | return label; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/refactor/globalrename/impl/fullrename/types/impl/FullRenameClasses.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.refactor.globalrename.impl.fullrename.types.impl; 2 | 3 | import me.f1nal.trinity.execution.ClassInput; 4 | import me.f1nal.trinity.execution.InputType; 5 | import me.f1nal.trinity.refactor.globalrename.api.GlobalRenameContext; 6 | import me.f1nal.trinity.refactor.globalrename.api.Rename; 7 | import me.f1nal.trinity.refactor.globalrename.impl.fullrename.types.FullRenameMember; 8 | 9 | public class FullRenameClasses extends FullRenameMember { 10 | public FullRenameClasses() { 11 | super("Classes", "Class"); 12 | } 13 | 14 | @Override 15 | public void refactor(GlobalRenameContext context) { 16 | for (ClassInput classInput : context.execution().getClassList()) { 17 | if (context.nameHeuristics().isObfuscated(classInput.getDisplaySimpleName(), InputType.CLASS)) { 18 | context.renames().add(new Rename(classInput, classInput.getClassTarget().getPackage().getChildrenPath(generateName()))); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/refactor/globalrename/impl/fullrename/types/impl/FullRenameFields.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.refactor.globalrename.impl.fullrename.types.impl; 2 | 3 | import me.f1nal.trinity.execution.FieldInput; 4 | import me.f1nal.trinity.refactor.globalrename.api.GlobalRenameContext; 5 | import me.f1nal.trinity.refactor.globalrename.api.Rename; 6 | import me.f1nal.trinity.refactor.globalrename.impl.fullrename.types.FullRenameClassMember; 7 | 8 | public class FullRenameFields extends FullRenameClassMember { 9 | public FullRenameFields() { 10 | super("Fields", "field", FieldInput.class); 11 | } 12 | 13 | @Override 14 | protected void refactorMember(FieldInput member, GlobalRenameContext context) { 15 | if (context.nameHeuristics().isObfuscated(member.getDisplayName().getName(), member.getType())) { 16 | context.renames().add(new Rename(member, generateName())); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/refactor/globalrename/impl/fullrename/types/impl/FullRenameMethods.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.refactor.globalrename.impl.fullrename.types.impl; 2 | 3 | import me.f1nal.trinity.execution.MethodInput; 4 | import me.f1nal.trinity.refactor.globalrename.api.GlobalRenameContext; 5 | import me.f1nal.trinity.refactor.globalrename.api.Rename; 6 | import me.f1nal.trinity.refactor.globalrename.impl.fullrename.types.FullRenameClassMember; 7 | 8 | public class FullRenameMethods extends FullRenameClassMember { 9 | public FullRenameMethods() { 10 | super("Methods", "method", MethodInput.class); 11 | } 12 | 13 | @Override 14 | protected void refactorMember(MethodInput member, GlobalRenameContext context) { 15 | if (context.nameHeuristics().isObfuscated(member.getDisplayName().getName(), member.getType())) { 16 | context.renames().add(new Rename(member, generateName())); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/refactor/globalrename/impl/fullrename/types/impl/FullRenamePackages.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.refactor.globalrename.impl.fullrename.types.impl; 2 | 3 | import me.f1nal.trinity.execution.InputType; 4 | import me.f1nal.trinity.execution.packages.Package; 5 | import me.f1nal.trinity.refactor.globalrename.api.Rename; 6 | import me.f1nal.trinity.refactor.globalrename.api.GlobalRenameContext; 7 | import me.f1nal.trinity.refactor.globalrename.impl.fullrename.types.FullRenameMember; 8 | 9 | import java.util.List; 10 | 11 | public class FullRenamePackages extends FullRenameMember { 12 | public FullRenamePackages() { 13 | super("Packages", "pkg"); 14 | } 15 | 16 | @Override 17 | public void refactor(GlobalRenameContext context) { 18 | // FIXME: Doesn't rename B if A contains B and both are obfuscated. 19 | List packages = context.execution().getAllPackages(); 20 | for (Package pkg : packages) { 21 | if (pkg.isArchive() || !context.nameHeuristics().isObfuscated(pkg.getName(), InputType.PACKAGE)) { 22 | continue; 23 | } 24 | 25 | context.renames().add(new Rename(pkg::rename, generateName())); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/remap/DisplayName.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.remap; 2 | 3 | import java.util.Objects; 4 | 5 | public class DisplayName { 6 | private final String originalName; 7 | private String name; 8 | private RenameType type; 9 | 10 | public DisplayName(String name) { 11 | this.originalName = name; 12 | this.name = name; 13 | this.type = RenameType.NONE; 14 | } 15 | 16 | public String getOriginalName() { 17 | return originalName; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public void setName(String name, RenameType renameType) { 25 | if (name.equals(this.originalName)) { 26 | renameType = RenameType.NONE; 27 | } else if (renameType == null) { 28 | renameType = RenameType.MANUAL; 29 | } 30 | 31 | this.setNameFinally(name); 32 | this.setType(renameType); 33 | } 34 | 35 | protected void setNameFinally(String name) { 36 | this.name = name; 37 | } 38 | 39 | public void setName(String name) { 40 | this.setName(name, RenameType.MANUAL); 41 | } 42 | 43 | public RenameType getType() { 44 | return type; 45 | } 46 | 47 | public void setType(RenameType type) { 48 | this.type = Objects.requireNonNull(type, "Rename type cannot be null"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/remap/IDisplayNameProvider.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.remap; 2 | 3 | public interface IDisplayNameProvider { 4 | DisplayName getDisplayName(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/remap/RenameType.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.remap; 2 | 3 | public enum RenameType { 4 | /** 5 | * Original name, it is not renamed. 6 | */ 7 | NONE, 8 | /** 9 | * Rename issued by a human. 10 | */ 11 | MANUAL, 12 | /** 13 | * Rename issued with automatic tools. 14 | */ 15 | AUTOMATED; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/theme/ColorChangeListener.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.theme; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.METHOD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface ColorChangeListener { 11 | ThemeColorCategory category(); 12 | String label(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/theme/ImGuiColor.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.theme; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.FIELD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface ImGuiColor { 11 | int[] targets(); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/theme/LabeledColor.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.theme; 2 | 3 | import imgui.app.Color; 4 | 5 | import java.awt.*; 6 | import java.lang.annotation.ElementType; 7 | import java.lang.annotation.Retention; 8 | import java.lang.annotation.RetentionPolicy; 9 | import java.lang.annotation.Target; 10 | 11 | @Target(ElementType.FIELD) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface LabeledColor { 14 | ThemeColorCategory category(); 15 | String label(); 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/theme/ThemeColor.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.theme; 2 | 3 | import com.thoughtworks.xstream.annotations.XStreamOmitField; 4 | 5 | public class ThemeColor { 6 | private final String label; 7 | private final float[] rgba; 8 | @XStreamOmitField 9 | private final CodeColor codeColor; 10 | 11 | public ThemeColor(String label, int rgba, CodeColor codeColor) { 12 | this.label = label; 13 | 14 | this.rgba = CodeColorScheme.toRgba(rgba); 15 | this.codeColor = codeColor; 16 | } 17 | 18 | public String getLabel() { 19 | return label; 20 | } 21 | 22 | public float[] getRgba() { 23 | return rgba; 24 | } 25 | 26 | public void setRgba(float[] rgba) { 27 | System.arraycopy(rgba, 0, this.getRgba(), 0, rgba.length); 28 | } 29 | 30 | public CodeColor getCodeColor() { 31 | return codeColor; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/theme/ThemeColorCategory.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.theme; 2 | 3 | import me.f1nal.trinity.util.INameable; 4 | 5 | public enum ThemeColorCategory implements INameable { 6 | GENERAL("General"), 7 | FRAME("Frame"), 8 | CODE_EDITOR("Code Editor"), 9 | ASSEMBLER("Assembler"), 10 | XREF_KIND("Xref Kind"), 11 | FILE_KIND("File Kind"), 12 | ; 13 | 14 | private final String name; 15 | 16 | ThemeColorCategory(String name) { 17 | this.name = name; 18 | } 19 | 20 | @Override 21 | public String getName() { 22 | return this.name; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/AnnotationUtil.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import me.f1nal.trinity.util.annotations.AnnotationDescriptor; 4 | import org.objectweb.asm.tree.AnnotationNode; 5 | 6 | import java.util.List; 7 | 8 | public class AnnotationUtil { 9 | public static AnnotationDescriptor getAnnotation(List list, String typeName) { 10 | if (list != null) { 11 | typeName = "L" + typeName + ";"; 12 | 13 | for (AnnotationNode annotationNode : list) { 14 | if (annotationNode.desc.equals(typeName)) { 15 | AnnotationDescriptor annotationDescriptor = new AnnotationDescriptor(); 16 | 17 | if (annotationNode.values != null) for (int i = 0; i < annotationNode.values.size(); i+=2) { 18 | String name = (String) annotationNode.values.get(i); 19 | Object value = annotationNode.values.get(i + 1); 20 | 21 | annotationDescriptor.getValues().put(name, value); 22 | } 23 | 24 | return annotationDescriptor; 25 | } 26 | } 27 | } 28 | return null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/ClassUtils.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import org.objectweb.asm.Opcodes; 4 | import org.objectweb.asm.tree.ClassNode; 5 | import org.objectweb.asm.tree.MethodNode; 6 | 7 | public class ClassUtils { 8 | public static MethodNode findMethod(ClassNode classNode, String name, String desc, boolean isStatic) { 9 | for (MethodNode method : classNode.methods) { 10 | if (isStatic == ((method.access & Opcodes.ACC_STATIC) != 0)) { 11 | if (method.name.equals(name) && method.desc.equals(desc)) { 12 | return method; 13 | } 14 | } 15 | } 16 | return null; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/DescriptorUtil.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | public final class DescriptorUtil { 4 | 5 | public static boolean isMatchingParameters(String desc1, String desc2) { 6 | int indexOf1 = desc1.lastIndexOf(')'), indexOf2 = desc2.lastIndexOf(')'); 7 | if (indexOf1 != indexOf2 || indexOf1 == -1) { 8 | return false; 9 | } 10 | return desc1.substring(indexOf1).equals(desc2.substring(indexOf2)); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/FileUtil.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | public class FileUtil { 4 | public static String normalizeFileName(String fileName) { 5 | fileName = fileName.replace("\\", ""); 6 | fileName = fileName.replace("/", ""); 7 | fileName = fileName.replace(".", ""); 8 | return fileName; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/IDescribable.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | public interface IDescribable { 4 | String getDescription(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/INameable.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | public interface INameable { 4 | String getName(); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/PatternUtil.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | public class PatternUtil { 6 | public static final Pattern LETTERS_ONLY = Pattern.compile("[a-zA-Z]+"); 7 | public static final Pattern DATABASE_NAME = Pattern.compile("[a-zA-Z0-9 _+-]*"); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/RandomUtil.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import java.security.SecureRandom; 4 | import java.util.Random; 5 | 6 | public final class RandomUtil { 7 | private static final Random random = new SecureRandom(); 8 | 9 | /** 10 | * Generates a random long with all 64 bits included. 11 | * @return A randomly generated long. 12 | */ 13 | public static long getLong() { 14 | return getNumber(8); 15 | } 16 | 17 | public static int getInteger() { 18 | return random.nextInt(); 19 | } 20 | 21 | public static long getNumber(int length) { 22 | byte[] bytes = new byte[length]; 23 | random.nextBytes(bytes); 24 | return ByteUtil.getNumber(bytes, 0, length); 25 | } 26 | 27 | public static Random getRandom() { 28 | return random; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/SearchTermMatchable.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | public interface SearchTermMatchable { 8 | boolean matches(String searchTerm); 9 | 10 | static List match(String searchTerm, Collection list) { 11 | List copy = new ArrayList<>(list); 12 | copy.removeIf(matchable -> !searchTerm.isEmpty() && !matchable.matches(searchTerm)); 13 | return copy; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/SerializationUtil.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import com.thoughtworks.xstream.XStream; 4 | 5 | public class SerializationUtil { 6 | public static void addAlias(XStream stream, Class clazz, String alias) { 7 | stream.processAnnotations(clazz); 8 | stream.alias(alias, clazz); 9 | stream.allowTypes(new Class[]{clazz}); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/Stopwatch.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | public final class Stopwatch { 4 | private long millis; 5 | 6 | public Stopwatch() { 7 | this.reset(); 8 | } 9 | 10 | public Stopwatch(long millis) { 11 | this.millis = millis; 12 | } 13 | 14 | public long getDifference() { 15 | return System.currentTimeMillis() - millis; 16 | } 17 | 18 | public long getMillis() { 19 | return millis; 20 | } 21 | 22 | public boolean hasPassed(long time) { 23 | return System.currentTimeMillis() >= this.millis + time; 24 | } 25 | 26 | public void reset() { 27 | this.millis = System.currentTimeMillis(); 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/SystemUtil.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import me.f1nal.trinity.Main; 4 | import me.f1nal.trinity.logging.Logging; 5 | import org.lwjgl.glfw.GLFW; 6 | 7 | import java.awt.*; 8 | import java.net.URI; 9 | 10 | public class SystemUtil { 11 | public static void copyToClipboard(String text) { 12 | try { 13 | GLFW.glfwSetClipboardString(Main.getDisplayManager().getHandle(), text); 14 | } catch (Throwable ignored) { 15 | } 16 | } 17 | 18 | public static String getClipboard() { 19 | try { 20 | return GLFW.glfwGetClipboardString(Main.getDisplayManager().getHandle()); 21 | } catch (Throwable throwable) { 22 | return null; 23 | } 24 | } 25 | 26 | public static void browseURL(String url) { 27 | try { 28 | Desktop.getDesktop().browse(URI.create(url)); 29 | } catch (Throwable throwable) { 30 | Logging.warn("Failed to browse URL '{}': {}", url, throwable); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/TextFieldPatternMatchCallback.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import imgui.ImGuiInputTextCallbackData; 4 | import imgui.callback.ImGuiInputTextCallback; 5 | 6 | import java.util.regex.Pattern; 7 | 8 | public class TextFieldPatternMatchCallback extends ImGuiInputTextCallback { 9 | private final Pattern pattern; 10 | 11 | public TextFieldPatternMatchCallback(Pattern pattern) { 12 | this.pattern = pattern; 13 | } 14 | 15 | @Override 16 | public void accept(ImGuiInputTextCallbackData callbackData) { 17 | String string = String.valueOf((char) callbackData.getEventChar()); 18 | if (!pattern.matcher(string).matches()) { 19 | callbackData.setEventChar(0); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/TimeUtil.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import java.sql.Date; 4 | import java.text.DateFormat; 5 | import java.text.SimpleDateFormat; 6 | import java.time.Instant; 7 | 8 | public class TimeUtil { 9 | public static String getFormattedTime(long millis) { 10 | String pattern = "MM/dd/yyyy hh:mm a"; 11 | DateFormat df = new SimpleDateFormat(pattern); 12 | return df.format(Date.from(Instant.ofEpochMilli(millis))); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/TimedStopwatch.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | public class TimedStopwatch { 4 | private final Stopwatch stopwatch = new Stopwatch(); 5 | private long time; 6 | 7 | /** 8 | * Initializes a new {@link TimedStopwatch} object. 9 | * @param time Time until the stopwatch finishes. 10 | */ 11 | public TimedStopwatch(long time) { 12 | this.time = time; 13 | } 14 | 15 | /** 16 | * Resets the internal {@link Stopwatch} and sets a new time. 17 | * @param time Time until the stopwatch finishes. 18 | */ 19 | public void reset(long time) { 20 | this.stopwatch.reset(); 21 | this.time = time; 22 | } 23 | 24 | public long getTime() { 25 | return time; 26 | } 27 | 28 | public boolean isEnabled() { 29 | return time >= 0; 30 | } 31 | 32 | public boolean hasPassed() { 33 | return isEnabled() && stopwatch.hasPassed(this.time); 34 | } 35 | 36 | public long getPassed() { 37 | return stopwatch.getDifference(); 38 | } 39 | 40 | /** 41 | * @param timeAddition Time to add to check. 42 | */ 43 | public boolean hasPassed(long timeAddition) { 44 | return isEnabled() && stopwatch.hasPassed(this.time + timeAddition); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/TypeUtil.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import org.objectweb.asm.Type; 4 | 5 | public class TypeUtil { 6 | public static String getTypeDesc(String className) { 7 | return String.format("L%s;", className); 8 | } 9 | 10 | public static boolean isPrimitive(Type type) { 11 | int sort = type.getSort(); 12 | return sort > Type.VOID && sort < Type.ARRAY; 13 | } 14 | 15 | public static int getSizeInBytes(Type type) { 16 | switch (type.getSort()) { 17 | case Type.BOOLEAN: 18 | case Type.BYTE: 19 | return 1; 20 | case Type.SHORT: 21 | case Type.CHAR: 22 | return 2; 23 | case Type.INT: 24 | case Type.FLOAT: 25 | return 4; 26 | case Type.LONG: 27 | case Type.DOUBLE: 28 | return 8; 29 | default: 30 | throw new RuntimeException("Unknown type size: " + type.toString()); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/UnsafeUtil.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util; 2 | 3 | import sun.misc.Unsafe; 4 | 5 | import java.lang.reflect.Field; 6 | 7 | public class UnsafeUtil { 8 | private static final Unsafe unsafe; 9 | 10 | public static Unsafe getUnsafe() { 11 | return unsafe; 12 | } 13 | 14 | static { 15 | Field f; 16 | try { 17 | f = Unsafe.class.getDeclaredField("theUnsafe"); 18 | } catch (NoSuchFieldException exception) { 19 | throw new RuntimeException(exception); 20 | } 21 | f.setAccessible(true); 22 | try { 23 | unsafe = (Unsafe) f.get(null); 24 | } catch (IllegalAccessException exception) { 25 | throw new RuntimeException(exception); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/annotations/AnnotationDescriptor.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util.annotations; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | public class AnnotationDescriptor { 7 | private final Map values = new LinkedHashMap<>(); 8 | 9 | public Map getValues() { 10 | return values; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/history/ChangeManager.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util.history; 2 | 3 | import java.util.Stack; 4 | 5 | public class ChangeManager { 6 | private final Stack stack = new Stack<>(); 7 | 8 | public T getLast() { 9 | return stack.peek(); 10 | } 11 | 12 | public T removeLast() { 13 | return stack.pop(); 14 | } 15 | 16 | public void add(T change) { 17 | stack.push(change); 18 | } 19 | 20 | public Stack getStack() { 21 | return stack; 22 | } 23 | 24 | public void undo(T history) { 25 | history.undo(); 26 | stack.remove(history); 27 | } 28 | 29 | public boolean isEmpty() { 30 | return stack.isEmpty(); 31 | } 32 | 33 | // public void redo(T history) { 34 | // history.redo(); 35 | // history 36 | // } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/history/Changeable.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util.history; 2 | 3 | public interface Changeable { 4 | void undo(); 5 | void redo(); 6 | } 7 | -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/java/BiHashMap.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util.java; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Set; 6 | 7 | public class BiHashMap { 8 | private Map forwardMap = new HashMap<>(); 9 | private Map reverseMap = new HashMap<>(); 10 | 11 | public void put(K key, V value) { 12 | forwardMap.put(key, value); 13 | reverseMap.put(value, key); 14 | } 15 | 16 | public V getValue(K key) { 17 | return forwardMap.get(key); 18 | } 19 | 20 | public K getKey(V value) { 21 | return reverseMap.get(value); 22 | } 23 | 24 | public Set> entrySet() { 25 | return forwardMap.entrySet(); 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/me/f1nal/trinity/util/java/Callback.java: -------------------------------------------------------------------------------- 1 | package me.f1nal.trinity.util.java; 2 | 3 | public interface Callback { 4 | void call(T arg); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/fonts/JetBrainsMonoNL-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firstfault/Trinity/b1e439457f1c90971993c0966234fd745df119c7/src/main/resources/fonts/JetBrainsMonoNL-Regular.ttf -------------------------------------------------------------------------------- /src/main/resources/fonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firstfault/Trinity/b1e439457f1c90971993c0966234fd745df119c7/src/main/resources/fonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /src/main/resources/fonts/inter-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firstfault/Trinity/b1e439457f1c90971993c0966234fd745df119c7/src/main/resources/fonts/inter-regular.ttf -------------------------------------------------------------------------------- /src/main/resources/fonts/zed-mono-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/firstfault/Trinity/b1e439457f1c90971993c0966234fd745df119c7/src/main/resources/fonts/zed-mono-regular.ttf --------------------------------------------------------------------------------