diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml new file mode 100644 index 0000000..c15d1f5 --- /dev/null +++ b/.github/workflows/cicd.yml @@ -0,0 +1,128 @@ +name: CI/CD with Lazarus IDE on multiple operating systems. + +permissions: + contents: write + +on: + push: + pull_request: + workflow_dispatch: + # Automatic cron build every 6 months to check if everything still works. + schedule: + - cron: "0 0 1 1/6 *" + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. + fail-fast: false + + # Set up an array to perform the following three build configurations. + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + include: + - os: windows-latest + LAZBUILD_WITH_PATH: c:/lazarus/lazbuild + RELEASE_ZIP_FILE: trackereditor_windows_amd64.zip + LAZ_OPT: + - os: ubuntu-latest + LAZBUILD_WITH_PATH: lazbuild + RELEASE_ZIP_FILE: trackereditor_linux_amd64.zip + LAZ_OPT: + - os: macos-latest + LAZBUILD_WITH_PATH: /Applications/Lazarus/lazbuild + RELEASE_ZIP_FILE: trackereditor_UNSIGNED_macOS_Intel_64.zip + LAZ_OPT: --widgetset=cocoa + + steps: + - uses: actions/checkout@v4 + + - name: show LAZBUILD_WITH_PATH (deprecated) + if: ${{ matrix.LAZBUILD_WITH_PATH }} + shell: bash + run: echo ${{ matrix.LAZBUILD_WITH_PATH }} + + - name: Install Lazarus IDE + run: | + if [ "$RUNNER_OS" == "Linux" ]; then + sudo apt install -y lazarus zip + elif [ "$RUNNER_OS" == "Windows" ]; then + choco install lazarus zip + # https://wiki.overbyte.eu/wiki/index.php/ICS_Download#Download_OpenSSL_Binaries + curl -L -O --output-dir enduser https://github.com/GerryFerdinandus/Renesas-RX-GCC/releases/latest/download/libssl-3-x64.dll + curl -L -O --output-dir enduser https://github.com/GerryFerdinandus/Renesas-RX-GCC/releases/latest/download/libcrypto-3-x64.dll + elif [ "$RUNNER_OS" == "macOS" ]; then + brew install --cask lazarus + else + echo "$RUNNER_OS not supported" + exit 1 + fi + shell: bash + + - name: Build Release version + # Build trackereditor project (Release mode) + run: ${{ matrix.LAZBUILD_WITH_PATH }} --build-mode=Release ${{ matrix.LAZ_OPT }} source/project/tracker_editor/trackereditor.lpi + shell: bash + + - name: Build Unit Test + # Build unit test project (Debug mode) + run: ${{ matrix.LAZBUILD_WITH_PATH }} --build-mode=Debug ${{ matrix.LAZ_OPT }} source/project/unit_test/tracker_editor_test.lpi + shell: bash + + - name: Run Unit Test on Windows + if: matrix.os == 'windows-latest' + # Also remove all the extra file created by test. + # We do not what it in the ZIP release files. + # Undo all changes made by testing. + run: | + set -e + enduser/test_trackereditor -a --format=plain + set +e + + # remove file created by unit test + rm -f enduser/console_log.txt + rm -f enduser/export_trackers.txt + git reset --hard + shell: bash + + - name: Create a zip file for Linux release. + if: matrix.os == 'ubuntu-latest' + run: zip -j ${{ matrix.RELEASE_ZIP_FILE }} enduser/*.txt enduser/trackereditor + shell: bash + + - name: Create a zip file for Windows release. + if: matrix.os == 'windows-latest' + run: | + zip -j ${{ matrix.RELEASE_ZIP_FILE }} enduser/*.txt enduser/trackereditor.exe enduser/*.dll + shell: bash + + - name: Create a zip file for macOS .app release. (unsigned macOS app) + if: matrix.os == 'macos-latest' + run: | + # copy everything into enduser/macos/app folder + # + # Move the executable to the application bundle + mv enduser/trackereditor enduser/macos/app/trackereditor.app/Contents/MacOS + # Move the trackers list to application bundle + mv enduser/add_trackers.txt enduser/macos/app/trackereditor.app/Contents/MacOS + mv enduser/remove_trackers.txt enduser/macos/app/trackereditor.app/Contents/MacOS + # move all the *.txt file + mv enduser/*.txt enduser/macos/app + # zip only the app folder with extra text file. + /usr/bin/ditto -c -k "enduser/macos/app" "${{ matrix.RELEASE_ZIP_FILE }}" + shell: bash + + - name: Upload Artifact + uses: actions/upload-artifact@v3 + with: + path: ${{ matrix.RELEASE_ZIP_FILE }} + if-no-files-found: error # 'warn'. error + + - name: Zip file release to end user + uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') + with: + files: | + *.zip diff --git a/.gitmodules b/.gitmodules index 71353b1..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "travis-lazarus"] - path = travis-lazarus - url = https://github.com/GerryFerdinandus/travis-lazarus.git diff --git a/enduser/libeay32.dll b/enduser/libeay32.dll deleted file mode 100644 index b66c6bb..0000000 Binary files a/enduser/libeay32.dll and /dev/null differ diff --git a/enduser/ssleay32.dll b/enduser/ssleay32.dll deleted file mode 100644 index 2ebf965..0000000 Binary files a/enduser/ssleay32.dll and /dev/null differ diff --git a/source/code/bencode.pas b/source/code/bencode.pas index 715a16a..27fcddc 100644 --- a/source/code/bencode.pas +++ b/source/code/bencode.pas @@ -106,6 +106,7 @@ constructor TBEncoded.Create(Stream: TStream); var X: char; begin + Result := ''; // loop until we come across it X := ' '; repeat diff --git a/source/code/main.pas b/source/code/main.pas index 1cb416a..c2e3347 100644 --- a/source/code/main.pas +++ b/source/code/main.pas @@ -100,7 +100,7 @@ TFormTrackerModify = class(TForm) procedure FormDestroy(Sender: TObject); //Drag and drop '*.torrent' files/directory or 'tracker.txt' - procedure FormDropFiles(Sender: TObject; const FileNames: array of UTF8String); + procedure FormDropFiles(Sender: TObject; const FileNames: array of utf8string); //At start of the program the form will be show/hide procedure FormShow(Sender: TObject); @@ -166,10 +166,10 @@ TFormTrackerModify = class(TForm) FLogFile, FTrackerFile: TextFile; FProcessTimeStart, FProcessTimeTotal: TDateTime; FControlerGridTorrentData: TControlerGridTorrentData; - function CheckForAnnounce(const TrackerURL: UTF8String): boolean; + function CheckForAnnounce(const TrackerURL: utf8string): boolean; procedure AppendTrackersToMemoNewTrackers(TrackerList: TStringList); procedure ShowUserErrorMessage(const ErrorText: string; const FormText: string = ''); - function TrackerWithURLAndAnnounce(const TrackerURL: UTF8String): boolean; + function TrackerWithURLAndAnnounce(const TrackerURL: utf8string): boolean; procedure UpdateTorrent; procedure ShowHourGlassCursor(HourGlass: boolean); procedure ViewUpdateBegin; @@ -182,13 +182,13 @@ TFormTrackerModify = class(TForm) procedure UpdateViewRemoveTracker; function ReloadAllTorrentAndRefreshView: boolean; function AddTorrentFileList(TorrentFileNameStringList: TStringList): boolean; - function ReadAddTrackerFileFromUser(const FileName: UTF8String): boolean; - function LoadTorrentViaDir(const Dir: UTF8String): boolean; - function DecodeTorrentFile(const FileName: UTF8String): boolean; + function ReadAddTrackerFileFromUser(const FileName: utf8string): boolean; + function LoadTorrentViaDir(const Dir: utf8string): boolean; + function DecodeTorrentFile(const FileName: utf8string): boolean; procedure UpdateTrackerInsideFileList; procedure UpdateTorrentTrackerList; procedure ShowTrackerInsideFileList; - function TestConnectionSSL: Boolean; + function TestConnectionSSL: boolean; procedure CheckedOnOffAllTrackers(Value: boolean); function CopyUserInputNewTrackersToList(Temporary_SkipAnnounceCheck: boolean = @@ -204,10 +204,10 @@ TFormTrackerModify = class(TForm) implementation -uses fphttpclient, LCLIntf, lazutf8, LazFileUtils, trackerlist_online; +uses fphttpclient, LCLIntf, lazutf8, LazFileUtils, trackerlist_online, LCLVersion; const - RECOMENDED_TRACKERS: array[0..2] of UTF8String = + RECOMENDED_TRACKERS: array[0..2] of utf8string = ( 'udp://tracker.coppersurfer.tk:6969/announce', 'udp://tracker.opentrackr.org:1337/announce', @@ -215,7 +215,8 @@ implementation ); //program name and version (http://semver.org/) - FORM_CAPTION = 'Bittorrent tracker editor (1.33.0.beta.6)'; + FORM_CAPTION = 'Bittorrent tracker editor (1.33.0.beta.6/LCL ' + + lcl_version + '/FPC ' + {$I %FPCVERSION%} + ')'; GROUPBOX_PRESENT_TRACKERS_CAPTION = 'Present trackers in all torrent files. Select the one that you want to keep. And added to all torrent files.'; @@ -471,7 +472,7 @@ procedure TFormTrackerModify.MenuItemOnlineCheckSubmitNewTrackonClick(Sender: TO procedure TFormTrackerModify.AppendTrackersToMemoNewTrackers(TrackerList: TStringList); var - tracker: UTF8String; + tracker: utf8string; begin //Append all the trackers to MemoNewTrackers MemoNewTrackers.Lines.BeginUpdate; @@ -521,7 +522,7 @@ procedure TFormTrackerModify.MenuItemOnlineCheckDownloadNewTrackonClick( end; end; -function TFormTrackerModify.CheckForAnnounce(const TrackerURL: UTF8String): boolean; +function TFormTrackerModify.CheckForAnnounce(const TrackerURL: utf8string): boolean; begin Result := (not FTrackerList.SkipAnnounceCheck) and (not WebTorrentTrackerURL(TrackerURL)) and (not FDragAndDropStartUp); @@ -547,7 +548,7 @@ procedure TFormTrackerModify.ShowUserErrorMessage(const ErrorText: string; end; function TFormTrackerModify.TrackerWithURLAndAnnounce( - const TrackerURL: UTF8String): boolean; + const TrackerURL: utf8string): boolean; begin //Validate the begin of the URL Result := ValidTrackerURL(TrackerURL); @@ -874,7 +875,7 @@ procedure TFormTrackerModify.UpdateTorrent; procedure TFormTrackerModify.SaveTrackerFinalListToFile; var - TrackerStr: UTF8String; + TrackerStr: utf8string; begin //Create the tracker text file. The old one will be overwritten AssignFile(FTrackerFile, FFolderForTrackerListLoadAndSave + FILE_NAME_EXPORT_TRACKERS); @@ -894,7 +895,7 @@ procedure TFormTrackerModify.SaveTrackerFinalListToFile; procedure TFormTrackerModify.ConsoleModeOrDragAndDropStartupMode; var - FileNameOrDirStr: UTF8String; + FileNameOrDirStr: utf8string; StringList: TStringList; MustExitWithErrorCode: boolean; begin @@ -1030,7 +1031,7 @@ procedure TFormTrackerModify.ConsoleModeOrDragAndDropStartupMode; procedure TFormTrackerModify.UpdateViewRemoveTracker; var - TrackerStr: UTF8String; + TrackerStr: utf8string; i: integer; begin { @@ -1083,7 +1084,7 @@ procedure TFormTrackerModify.UpdateViewRemoveTracker; -function TFormTrackerModify.DecodeTorrentFile(const FileName: UTF8String): boolean; +function TFormTrackerModify.DecodeTorrentFile(const FileName: utf8string): boolean; begin //Called when user add torrent files //False if something is wrong with decoding torrent. @@ -1097,7 +1098,7 @@ function TFormTrackerModify.DecodeTorrentFile(const FileName: UTF8String): boole procedure TFormTrackerModify.UpdateTorrentTrackerList; var - TrackerStr: UTF8String; + TrackerStr: utf8string; begin //Copy the trackers found in one torrent file to FTrackerList.TrackerFromInsideTorrentFilesList for TrackerStr in FDecodePresentTorrent.TrackerList do @@ -1131,7 +1132,7 @@ procedure TFormTrackerModify.CheckedOnOffAllTrackers(Value: boolean); function TFormTrackerModify.CopyUserInputNewTrackersToList( Temporary_SkipAnnounceCheck: boolean): boolean; var - TrackerStrLoop, TrackerStr, ErrorStr: UTF8String; + TrackerStrLoop, TrackerStr, ErrorStr: utf8string; begin { Called after 'update torrent' is selected. @@ -1256,7 +1257,7 @@ procedure TFormTrackerModify.LoadTrackersTextFileAddTrackers( procedure TFormTrackerModify.LoadTrackersTextFileRemoveTrackers; var - filename: UTF8String; + filename: utf8string; begin filename := FFolderForTrackerListLoadAndSave + FILE_NAME_REMOVE_TRACKERS; try @@ -1350,7 +1351,7 @@ procedure TFormTrackerModify.MenuHelpVisitNewTrackonClick(Sender: TObject); function TFormTrackerModify.ReadAddTrackerFileFromUser( - const FileName: UTF8String): boolean; + const FileName: utf8string): boolean; var TrackerFileList: TStringList; begin @@ -1436,7 +1437,7 @@ procedure TFormTrackerModify.MenuUpdateTorrentSortClick(Sender: TObject); -function TFormTrackerModify.LoadTorrentViaDir(const Dir: UTF8String): boolean; +function TFormTrackerModify.LoadTorrentViaDir(const Dir: utf8string): boolean; var TorrentFilesNameStringList: TStringList; begin @@ -1454,7 +1455,7 @@ function TFormTrackerModify.LoadTorrentViaDir(const Dir: UTF8String): boolean; procedure TFormTrackerModify.FormDropFiles(Sender: TObject; - const FileNames: array of UTF8String); + const FileNames: array of utf8string); var Count: integer; TorrentFileNameStringList, //for the torrent files @@ -1466,7 +1467,7 @@ procedure TFormTrackerModify.FormDropFiles(Sender: TObject; //ViewUpdateBegin must be called one time. Keep track of it. ViewUpdateBeginActiveOneTimeOnly: boolean; - FileNameOrDirStr: UTF8String; + FileNameOrDirStr: utf8string; begin //Drag and drop a folder or files? @@ -1598,7 +1599,7 @@ function TFormTrackerModify.AddTorrentFileList(TorrentFileNameStringList: //This called from 'add folder' or 'drag and drop' var Count: integer; - TorrentFileNameStr: UTF8String; + TorrentFileNameStr: utf8string; begin { Every torrent file must be decoded for the tracker list inside. This torrent tracker list is add to FTrackerList.TrackerFromInsideTorrentFilesList. @@ -1639,7 +1640,7 @@ function TFormTrackerModify.AddTorrentFileList(TorrentFileNameStringList: function TFormTrackerModify.ReloadAllTorrentAndRefreshView: boolean; var - TorrentFileStr: UTF8String; + TorrentFileStr: utf8string; begin { This is called after updating the torrent. @@ -1703,7 +1704,7 @@ procedure TFormTrackerModify.ViewUpdateBegin; procedure TFormTrackerModify.ViewUpdateOneTorrentFileDecoded; var RowIndex: integer; - TorrentFileNameStr, PrivateStr: UTF8String; + TorrentFileNameStr, PrivateStr: utf8string; DateTimeStr: string; begin //Called after loading torrent file. @@ -1821,7 +1822,7 @@ procedure TFormTrackerModify.ShowHourGlassCursor(HourGlass: boolean); end; -function TFormTrackerModify.TestConnectionSSL: Boolean; +function TFormTrackerModify.TestConnectionSSL: boolean; begin Result := ParamCount = 1; if Result then @@ -1832,7 +1833,8 @@ function TFormTrackerModify.TestConnectionSSL: Boolean; begin // Check if there is SLL connection try - TFPCustomHTTPClient.SimpleGet('https://raw.githubusercontent.com/gerryferdinandus/bittorrent-tracker-editor/master/.travis.yml'); + TFPCustomHTTPClient.SimpleGet( + 'https://raw.githubusercontent.com/gerryferdinandus/bittorrent-tracker-editor/master/README.md'); except //No SLL or no internet connection. System.ExitCode := 1; @@ -1840,4 +1842,5 @@ function TFormTrackerModify.TestConnectionSSL: Boolean; end; end; end; + end. diff --git a/source/code/ngosang_trackerslist.pas b/source/code/ngosang_trackerslist.pas index 21168b5..e900ba3 100644 --- a/source/code/ngosang_trackerslist.pas +++ b/source/code/ngosang_trackerslist.pas @@ -66,7 +66,7 @@ TngosangTrackerList = class implementation -uses fphttpclient, LazUTF8, torrent_miscellaneous; +uses opensslsockets, OpenSSL, fphttpclient, LazUTF8, torrent_miscellaneous; const URL: array [Tngosang_List] of string = @@ -104,6 +104,7 @@ constructor TngosangTrackerList.Create; var i: Tngosang_List; begin + //Create all the TStringList for i in Tngosang_List do begin @@ -125,4 +126,47 @@ destructor TngosangTrackerList.Destroy; inherited Destroy; end; +initialization + // FPC 3.2.2 is missing support for the latest openSSL 3, will be fix in the future release. + // Latest openssl.pas https://gitlab.com/freepascal.org/fpc/source/-/blob/main/packages/openssl/src/openssl.pas?ref_type=heads + // Copy this newer SSL detection into the older openssl code used by the present FPC 3.2.2 +{$IFDEF VER3_2} +{$IFDEF WINDOWS} + DLLSSLName3 := {$IFDEF WIN64}'libssl-3-x64.dll'{$ELSE}'libssl-3.dll'{$ENDIF}; + DLLUtilName2 := {$IFDEF WIN64}'libcrypto-3-x64.dll'{$ELSE}'libcrypto-3.dll'{$ENDIF}; +{$ELSE WINDOWS} +{$IFDEF DARWIN} + if High(OpenSSL.DLLVersions) >= 19 then + begin + // macOS version + // LibreSSL + OpenSSL.DLLVersions[1] := '.48'; + OpenSSL.DLLVersions[2] := '.47'; + OpenSSL.DLLVersions[3] := '.46'; + OpenSSL.DLLVersions[4] := '.45'; + OpenSSL.DLLVersions[5] := '.44'; + OpenSSL.DLLVersions[6] := '.43'; + OpenSSL.DLLVersions[7] := '.35'; + + // OpenSSL + OpenSSL.DLLVersions[8] := '.3'; + OpenSSL.DLLVersions[9] := '.1.1'; + OpenSSL.DLLVersions[10] := '.11'; + OpenSSL.DLLVersions[11] := '.10'; + OpenSSL.DLLVersions[12] := '.1.0.6'; + OpenSSL.DLLVersions[13] := '.1.0.5'; + OpenSSL.DLLVersions[14] := '.1.0.4'; + OpenSSL.DLLVersions[15] := '.1.0.3'; + OpenSSL.DLLVersions[16] := '.1.0.2'; + OpenSSL.DLLVersions[17] := '.1.0.1'; + OpenSSL.DLLVersions[18] := '.1.0.0'; + OpenSSL.DLLVersions[19] := '.0.9.8'; + end; +{$ElSE DARWIN} + // Unix/Linux version of FPC need openSSL 3 in the detection list + OpenSSL.DLLVersions[Length(OpenSSL.DLLVersions) - 1] := '.3'; +{$ENDIF DARWIN} +{$ENDIF WINDOWS} +{$ENDIF VER3_2} + end. diff --git a/source/project/tracker_editor/trackereditor.lpi b/source/project/tracker_editor/trackereditor.lpi index 11ee463..bc0e2ec 100644 --- a/source/project/tracker_editor/trackereditor.lpi +++ b/source/project/tracker_editor/trackereditor.lpi @@ -1,14 +1,14 @@ - + + - <ResourceType Value="res"/> <UseXPManifest Value="True"/> diff --git a/source/project/tracker_editor/trackereditor.res b/source/project/tracker_editor/trackereditor.res index f6e8499..5565379 100644 Binary files a/source/project/tracker_editor/trackereditor.res and b/source/project/tracker_editor/trackereditor.res differ diff --git a/source/project/unit_test/tracker_editor_test.lpi b/source/project/unit_test/tracker_editor_test.lpi index e0d0afb..ed4628d 100644 --- a/source/project/unit_test/tracker_editor_test.lpi +++ b/source/project/unit_test/tracker_editor_test.lpi @@ -1,11 +1,16 @@ <?xml version="1.0" encoding="UTF-8"?> <CONFIG> <ProjectOptions> - <Version Value="11"/> + <Version Value="12"/> <PathDelim Value="\"/> <General> + <Flags> + <MainUnitHasCreateFormStatements Value="False"/> + <MainUnitHasTitleStatement Value="False"/> + <MainUnitHasScaledStatement Value="False"/> + <CompatibilityMode Value="True"/> + </Flags> <SessionStorage Value="None"/> - <MainUnit Value="0"/> <Title Value="tracker_editor_test"/> <UseAppBundle Value="False"/> <ResourceType Value="res"/> @@ -44,7 +49,6 @@ <Linking> <Debugging> <DebugInfoType Value="dsDwarf2Set"/> - <UseHeaptrc Value="True"/> <TrashVariables Value="True"/> <UseValgrind Value="True"/> <UseExternalDbgSyms Value="True"/> @@ -83,6 +87,9 @@ <Version Value="2"/> </PublishOptions> <RunParams> + <local> + <CommandLineParams Value="-a --format=plain"/> + </local> <FormatVersion Value="2"/> <Modes Count="1"> <Mode0 Name="default"> @@ -149,7 +156,7 @@ <Linking> <Debugging> <DebugInfoType Value="dsDwarf3"/> - <UseHeaptrc Value="True"/> + <UseLineInfoUnit Value="False"/> </Debugging> </Linking> </CompilerOptions> diff --git a/travis-lazarus b/travis-lazarus deleted file mode 160000 index e5caece..0000000 --- a/travis-lazarus +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e5caece318f06832ff767e3824ee450bcb7b7512