antp wrote: 2025-10-11 11:12:39
Hi,
I didn't really follow how all this subject evolved in the last weeks, what can I say to users who ask what to do?
I suppose that the current system still relies on cURL then, seeing that the script here above seems to require ExternalCurlHandler.
Where is the last version of that one? Maybe I should include it officially in AMC then...
Hello Antoine,
Thanks to the efforts and great work of MrObama2022 and Garada we now have a 100% functional script again.
Yes, it needs cURL to work, it's the only way to get around Filmaffinity's protection.
Currently to work I think it would need ExternalCurlHandler.pas, StringUtils7552.pas and StringUtils1.pas
Now the script allows to use both advanced and normal search, it is selected with the AdvancedSearch option.
To minimize the number of requests to FilmAffinity that can generate a block, the results are displayed paginated using the "find more" button to load the following pages in case there is more than one.
Garada implemented options in ExternalCurlHandler.pas in case some users use versions lower than W10, Linux or do not want to use VBS. They can be changed by editing ExternalCurlHandler.pas
About include it officially in AMC, if you're concerned about whether filmaffinity might take some action against AMC for bypassing its protection. In my opinion, the AMC block is a collateral damage. Surely the main target of their firewall are the AI bots that are obtaining information from FilmAffinity for free for their own benefit, in addition to the fact that the AI bots surely generate thousands and thousands of requests every day with the monetary cost in traffic for filmaffinity.
I don't think they care about a small group of private users using a free program for their personal use, if this were the case they could have blocked it much sooner. In addition, I'm sure that like me, most of AMC users are also Filmaffinity users and visit the page, generating money with the banners. But of course it is your decision.
The code of last version of ExternalCurlHandler.pas is this (there are not link to download a file, only the code on Garada post
viewtopic.php?p=92950#p92950)
Code: Select all
unit ExternalCurlHandler;
uses StringUtils7552;
const
UseVBS = True; // Use Visual Basic Script to hide curl windows, disable if you do not want to or cannot use VBS (p.e. Linux)
tmpDir = ''; // (optional) if you want get your scripts directory clean, set here your tmp working dir, example C:\Users\YOURWINDOWSUSER\AppData\Local\Temp\
delayBetweenRequest = 2001;
curlPath = 'curl.exe'; // if you use Windows 7 or 8 download curl.exe for Windows (it's free) and set here the right path
vbsScript = 'ExternalCurlHandler.vbs';
curlOutput = 'curlOutput.html';
curlUserAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36';
TimeOut = 10000; // Time to wait for response in ms
var
InstallerPath: string;
function GetPage5Advanced(address: string; referer: string; cookies: string; content: string; headers: string): string;
var
cnt: integer;
fileContent: TStringList;
curlOutputResult: string;
sCommand: string;
wh,wm,ws,wms: Word;
IP: string;
begin
Result := '';
// Create VBS file if not exists
if setupScript then
begin
// Delete temporal files
if fileExists(InstallerPath + curlOutput) then
DeleteFile(InstallerPath + curlOutput);
curlOutputResult := curlOutput + '.result';
if fileExists(InstallerPath + curlOutputResult) then
DeleteFile(InstallerPath + curlOutputResult);
// Random IP
DecodeTime(Now, wh, wm, ws, wms);
IP := IntToStr(wms mod 255) + '.' + IntToStr(ws) + '.' + IntToStr(wm) + '.' + IntToStr(wh);
// CURL parameters:
// Create info file with return codes and possible errors, it's created after page is downloaded
sCommand := '-w "%output{' + InstallerPath + curlOutputResult + '}%{url}\nExitCode: %{exitcode}\nErrorMsg: %{errormsg}\nResponseCode: %{http_code}"';
// Download page and save to file
sCommand := sCommand + ' -L --output "' + InstallerPath + curlOutput + '" --url "' + address + '" ' + '-H "Accept: text/html, */*" -H "Accept-Language: it" -H "DNT: 1" -H "Priority: u=0, i" -H "Sec-Ch-Ua: \"Not)A;Brand\";v=\"8\", \"Chromium\";v=\"138\", \"Google Chrome\";v=\"138\"" -H "Sec-Ch-Ua-Mobile: ?0" -H "Sec-Ch-Ua-Platform: \"Windows\"" -H "Sec-Fetch-Dest: Document" -H "Sec-Fetch-Mode: Navigate" -H "Sec-Fetch-Site: None" -H "Sec-Fetch-User: ?1" -H "Upgrade-Insecure-Requests: 1" -H "X-Forwarded-For: ' + IP + '" -H "User-Agent: ' + curlUserAgent + '"';
//test slow connection, don't uncomment
//sCommand := '--limit-rate 1 ' + sCommand;
Sleep(delayBetweenRequest);
if UseVBS then
begin
// Launch CURL. Change " for #1 as VBS uses " for parameters. The VBS script undone the changes.
Launch('wscript.exe', '"' +InstallerPath + vbsScript + '" "' + curlPath + '" ' + StringReplace(sCommand, '"', #1));
end
else
Launch(curlPath, sCommand);
// Wait for end info file or timeout
cnt := 0;
while (not FileExists(InstallerPath + curlOutputResult)) and (cnt < TimeOut div 50) do
begin
cnt := cnt + 1;
Sleep(50);
end;
// if info file exists
if (fileExists(InstallerPath + curlOutputResult)) then
begin
fileContent := TStringList.Create;
try
// Read and delete info file
fileContent.LoadFromFile(InstallerPath + curlOutputResult);
DeleteFile(InstallerPath + curlOutputResult);
// if return error
if TextBetween(fileContent.Text, 'ErrorMsg: ', #13) <> '' then
ShowError('Error downloading page.' + #13 + fileContent.Text)
else if (fileExists(InstallerPath + curlOutput)) then // if downloaded page exits
begin
// Read and delete downloaded page
fileContent.LoadFromFile(InstallerPath + curlOutput);
DeleteFile(InstallerPath + curlOutput);
// Return page
Result := fileContent.Text;
//if Pos('</html>', Result) < 1 then
// ShowError('TRIM!!!');
end
else // no error, no download, no timeout...
ShowError('The page did not download');
finally
fileContent.Free;
end;
end
else // if not: timeout
ShowError('Internal Timeout!!');
end
else
begin
Sleep(delayBetweenRequest);
Result := GetPage5(address, referer, cookies, content, headers);
end;
end;
function setupScript: boolean;
var
ScriptContent: TStringList;
begin
Result := False;
// initialize working path
if (tmpDir <> '') then
InstallerPath := tmpDir
else
InstallerPath := dirScripts;
InstallerPath := IncludeTrailingPathDelimiter(InstallerPath);
// Create a generic VBS script that
// open a command with parameters in hidden window
if UseVBS then
if (not FileExists(InstallerPath + vbsScript)) then
begin
ScriptContent := TStringList.Create;
ScriptContent.Add('Dim Args()');
ScriptContent.Add('ReDim Args(WScript.Arguments.Count - 1)');
ScriptContent.Add('Args(0) = """" & WScript.Arguments(0) & """"');
ScriptContent.Add('For i = 1 To WScript.Arguments.Count - 1');
ScriptContent.Add(' Args(i) = Replace(WScript.Arguments(i), chr(1), chr(34))');
ScriptContent.Add('Next');
ScriptContent.Add('CreateObject("Wscript.Shell").Run Join(Args), 0, False');
ScriptContent.SaveToFile(InstallerPath + vbsScript);
ScriptContent.Free;
end;
Result := true;
end;
begin
end.
The link of last version of FilmAffinity (ES).ifs is this
https://mega.nz/file/sBkiAQTJ#xujzighhS ... vBcNYXzkFI
If you finally decide to officially include it in AMC as an official version I think it would be good to change filename and some lines of the INFO in the script, especially if you want the previous one to be overwritten using UPDATE_SCRIPTS.ifs
1- The filename from
FilmAffinity V2 (ES).ifs to
FilmAffinity (ES).ifs
2- The line
Title=FilmAffinity Unofficial v2 (ES) to
Title=FilmAffinity (ES)
3- The line
Version=5.0 unofficial to maybe
Version=5.0
4- Add to line
Comments=adaptation for compatibility with 4.2 version. Added Extras capture. Changed Charset ISO-> utf8 - new searh page structure something like this
Added cURL compatibility, need ExternalCurlHandler.pas to let people also need to have ExternalCurlHandler.pas
5- And finally add to line
Authors=aviloria (aviloria@yahoo.com) modded by: rodpedja (rodpedja@gmail.com), kreti (bisoft@hotmail.com), MrK, gilistico, juliojs, Albher, Arturo, jacqlittle, AgustinG, Fulvio53s03, MrObama2022 the name
Garada. He didn't put his name and has done a great job and he deserves it

. Of course if he is agree to include it!!