Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 07/13/22 in all areas

  1. Remy Lebeau

    Best way to replace D11 distributed Indy with latest Git Indy?

    Yes, there are some Embarcadero technologies that use Indy internally, and so the installer has included Indy because of that. At one point, the techs were linked directly to the public version of Indy that shipped with the IDE, making it virtually impossible for users to update Indy without breaking those techs. But over the years, Embarcadero has updated their tech to use a private version of Indy instead (or their own libraries), so users can freely update the public version of Indy. But, there have been a few glitches in that process from time to time, causing unwanted linkages to the public Indy again. Nothing in recent years, that I recall, though.
  2. Remy Lebeau

    Best way to replace D11 distributed Indy with latest Git Indy?

    Essentially, yes - with caveats, depending on the IDE version (mostly old ones), which are documented in Indy's install instructions. I rename the pre-installed Indy folders and move the pre-installed Indy binaries to a separate folder (in case I ever need to restore them), and then I compile Indy in my own folder and install the binaries from there. That way, I can make changes to Indy and have them show up in projects/IDE. I install the IDE in the default installation path. Basically, yes. Some caveats similar to that are mentioned in Indy's install instructions, but only in relation to Embarcadero's own technologies that use Indy internally. Yup. And you have to make sure you clean up ONLY the ones that relate to Indy, and not to someone else who might have also used the "Id" prefix (albeit rare)... Cool.
  3. sfrazor

    Dynamic class member names

    This works fantastic! I couldn't leave my previous solution for the next programmer to untangle so I reverted in the repo and here is what I ended up with. Again constant strings are handled via a simple en/decode function (while I'm wishing can I wish for macro support?). The last of my "mandates" was obfuscate the class field names since they were the most revealing. But as a bonus This solution also takes care of sensitive procedure names. Unit tests still run! So it seems I didn't break anything at a glance. unit Unit4; {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) Fields([vcPublic])} interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, REST.Json, REST.Json.Types; type TPII = class public //Obfuscated Faaaa: string; Fbbbb: string; Fcccc: string; public //Human readable property FNAME: string read Faaaa write Faaaa; property FAddress: string read Fbbbb write Fbbbb; property FCity: string read Fcccc write Fcccc; end; type TForm4 = class(TForm) Memo1: TMemo; Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure MyPIIProcedure; //Could be sensative. Needs to be hidden as well... end; var Form4: TForm4; implementation {$R *.dfm} procedure TForm4.Button1Click(Sender: TObject); begin MyPIIProcedure; end; procedure TForm4.MyPIIProcedure; var MyPII: TPII; PIIJSON: string; begin MyPII:= TPII.Create; MyPII.FName:= 'John'; MyPII.FAddress:= 'Main Street'; MyPII.FCity:= 'New York'; PIIJSON := TJSON.ObjectToJsonString(MyPII, [joIndentCaseCamel]); Memo1.Lines.Add('////////////// JSON DATA //////////////'); Memo1.Lines.Add(PIIJSON); MyPII.Free; end; end. To top it off I wrote a small "scrubber" that does the search and replace as mentioned above in the .pas but did it like this: Used this to take care of the actual class names... created an include file with the known-name and an obfuscated equivalent. Wrote a small Delphi console app to do this. Works great in the CI/CD pipeline build. This took care of the remaining 60 or so edge cases hidden in the code. Added the scrubber to the pre-build command to parse out the .pas files needed. Before compile. The resulting binaries are petty darn clean! So thanks again to everyone that chimed in! All great ideas and led to the working solution. No more "plain text" identifiers.
  4. dummzeuch

    Format source with tabs

    Yes. I never even thought about using tabs because they usually are a pain in the lower back everywhere.
  5. Fr0sT.Brutal

    Format source with tabs

    Tabs for indenting are a pain so not surprise
  6. Artem's Classes/Components/Controls library (ACL) Library contains number of classes, components and visual controls for Delphi that used in AIMP. I have published the library because it was used in plugins that no longer supported by me. If anyone will be interested the library I will add more details and create index of all features and abilities of the library. My working Delphi is 11.0 Alexandria. The library may work on earlier versions of Delphi, but I haven't tested it. Link: https://github.com/ArtemIzmaylov/ACL
  7. You can compress the file before sending. Should give you the best result.
  8. These numbers are randomly distributed? When not, it might be more space efficient to store differences (after converting them to integers). If differences are small, you could use variable-length storing (7 bit data, 1 bit as indicator, that another byte is used). And finally a compression.
  9. If the values for each block don't use the full value range, you can store a base value and only the difference for the others. In other words: Instead of always subtract 30, find the min value of that block (Vmin), store that followed by the other values with the min value subtracted (V - VMin). Of course that would only help if Vmax - Vmin <= 65535.
  10. hsauro

    Interfaces - Time to face my ignorance.

    Most articles will explain the properties of interfaces but rarely why and when you’d use them. Someone pointed me to this article (search for interfaces) and it helped me a lot to understand why they can be useful. http://www.unigui.com/doc/online_help/user-interface.htm?fbclid=IwAR12Yq3agChFOoUvH4OE8K9gHApA6y-p6NdIHejeRKSxjEmmEMwOhpP0CNw
  11. Fr0sT.Brutal

    Dynamic class member names

    I still consider it the most easy and at the same time working solution. You still use human readable member names but with small non-disrupting addition. Before building a release, run regexp replace for all source files and that's all. No he doesn't. He wants both readable names and auto-JSON-ing which requires RTTI which leaves readable traces in binary. Hmm. How about using {$RTTI EXPLICIT PROPERTIES vcPublished} and then TObfuscatedClass = class private FSecretField: string; public // for use from code property SecretField: string read FSecretField write FSecretField; published // for JSON-ing property bwoirhoeri: string read FSecretField write FSecretField; end;
  12. Angus Robertson

    ICS Email and OAuth2

    In June 2022 Google stopped accepting traditional authentication methods for it's SMTP and POP3 email servers, instead requiring OAuth2, and I believe Microsoft is doing the same from October 2022. The main different with OAuth2 is the application does not store the account password so is unable to share it. Instead the user is directed to a sign-in web page from Google or Microsoft where the account details are entered and the application receives limited life tokens that are used instead of the password. For this to work, the developer needs an application account at Google or Microsoft to obtain a application client ID and secret, which need to saved securely and sent as part of the OAuth2 sign-in. In theory, Google and Microsoft need to approve applications using the account client details, and will give warnings during sign-in after a grace period. If sign-in works, the application receives an access token usually with a life of a few hours, and a refresh token that may be stored securely like a password and may have a life of several months and which may be used to obtain a new access token without a new sign-in. Note the refresh token may be cancelled at any time requiring a new sign-in. The refresh token may also be shared between different applications using the same client details and email account, for instance with servers where interaction is not possible. ICS added support for OAuth2 with version V8.65 in November 2020 to the TSslSmtpCli, TSslPop3Cli and TIcsMailQueue email components, by adding the TIcsRestEmail component to projects with some extra code, as illustrated in the samples OverbyteIcsMailQuTst, OverbyteIcsSslMailSnd and OverbyteIcsSslMailRcv. But the ICS server samples using email were not updated at the time, so have now been done for the forthcoming V8.70 release which is available from SVN and the overnight zip, OverbyteIcsSslMultiWebServ, OverbyteIcsDDWebService and OverbyteIcsSslMultiFtpServ. Since other developers may similarly need to add OAuth2 support for email applications, this is a quick guide. 1 - For the TSslSmtpCli, TSslPop3Cli or TIcsMailQueue component, add an onOATokenEvent handler. 2 - Drop a TIcsRestEmail component named IcsRestEmail and add onEmailNewTokenEvent and onEmailProgEvent handlers. The LoginTimeout property defines how long the component will wait for an interactive browser OAuth2 login, if necessary, defaulting to 30 seconds. If this happens the onEmailNewTokenEvent is called allowing the application to save the new refresh token to avoid further interaction. 3 - In the onOATokenEvent event, call the IcsRestEmail.GetNewToken method and set the handler properties Token, TokExpireDT and TokAccount, see any of the samples. 4 - Set the IcsRestEmail component properties RestEmailType, ClientId, ClientSecret, and RefrToken, there is a function IcsLoadRestEmailFromIni that does this from an INI file for the server samples (without encryption). 5 - Set SMTP AuthType to smtpAuthXOAuth2 or POP3 AuthType to popAuthXOAuth2 with the appropriate host. This causes onOATokenEvent to be called when an access token is needed. Angus
  13. aehimself

    TThreadedTimer

    In some occasions the inaccuracy of Delphi's TTimer cased serious headaches so I did some digging and found an old post on how to turn a thread into a much more accurate timer. While I analyzed the code to find out how it works I made some comments and also took the liberty to change it here and there... and wrapped the whole thing in a TComponent which easily can be installed in the IDE and dropped on almost anything. The TThreadedTimer's OnTimer event runs in the VCL thread so any UI element can be manipulated from there. It is also a drop-in replacement for TTimer, meaning you change your DFM and PAS and it should work exactly the same way. My version delays enabling the thread so it won't spin freely until it has an event handler, properly resets the timing sequence if the Timer is set to Disabled and then Enabled again and also - in theory - the OnTimer event will no longer fire during destruction. Being a Windows-only guy it relies on WinApi, but I guess it can be made cross-platform by using Delphi's own TEvent class... as it yields zero benefits I didn't care to look into it. As the original idea wasn't mine the right thing to do is to release this version under the do-whatever-you-want license. Feel free to use, point out possible issues or modify it to fit your needs. God bless open source 🙂 uThreadedTimer.7z
  14. Tntman

    Drone control from mobile

    Order amount: $ 2.49 this is how much i payed for ESP8862 ( shipping included ). I got it 2 years ago and it is still working fine.. When we talk about arduinos and stuff like that i am always getting cheapest possible components and i never had problems.. One of the reasons why i am getting cheapest possible components all the time is that i am using them just for testing purposes, playing around and learning... I think that u can make it like client-server app, send converted image ( text ) over socket and display it in ur app.. U can display it in normal image component
  15. Kryvich

    Delphi SQL Formatter

    I think 5 function calls or 5 assigments is not the best code style. Consider these variants: SQL.Add('SELECT EntCity, EntStageName' + sLineBreak + 'FROM Entertainers' + sLineBreak + 'WHERE 1=1' + sLineBreak + 'AND TEST=''TEST''' + sLineBreak + 'ORDER BY EntCity ASC, EntStageName ASC'); CommandText := 'SELECT EntCity, EntStageName' + sLineBreak + 'FROM Entertainers' + sLineBreak + 'WHERE 1=1' + sLineBreak + 'AND TEST=''TEST''' + sLineBreak + 'ORDER BY EntCity ASC, EntStageName ASC'; Optionally replace line breaks with spaces: SQL.Add('SELECT EntCity, EntStageName ' + 'FROM Entertainers ' + 'WHERE 1=1 ' + 'AND TEST=''TEST'' ' + 'ORDER BY EntCity ASC, EntStageName ASC');
×