Skip to content

Instantly share code, notes, and snippets.

@gerardmarquina
Last active April 18, 2019 16:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gerardmarquina/777ff95f145425020f83f80e76d54c84 to your computer and use it in GitHub Desktop.
Save gerardmarquina/777ff95f145425020f83f80e76d54c84 to your computer and use it in GitHub Desktop.
Improved version of the previous dev diary bot.
{ program bot;
uses
Winapi.Windows, System.SysUtils, System.Variants, System.Classes,
System.StrUtils, System.Net.URLClient, System.Net.HttpClient,
System.Net.HttpClientComponent;
{$APPTYPE CONSOLE }
{ var
client: TNetHTTPClient;
lr, response: TStringStream;
//responsereader: TStreamReader;
responsestrings, newr: TStringList;
textline, textindex: integer;
i,x: integer;
new: string;
finished: boolean;
lasthashcode: integer;
source: TStringStream;
procedure ClearScreen;
var
stdout: THandle;
csbi: TConsoleScreenBufferInfo;
ConsoleSize: DWORD;
NumWritten: DWORD;
Origin: TCoord;
begin
stdout := GetStdHandle(STD_OUTPUT_HANDLE);
Win32Check(stdout<>INVALID_HANDLE_VALUE);
Win32Check(GetConsoleScreenBufferInfo(stdout, csbi));
ConsoleSize := csbi.dwSize.X * csbi.dwSize.Y;
Origin.X := 0;
Origin.Y := 0;
Win32Check(FillConsoleOutputCharacter(stdout, ' ', ConsoleSize, Origin,
NumWritten));
Win32Check(FillConsoleOutputAttribute(stdout, csbi.wAttributes, ConsoleSize, Origin,
NumWritten));
Win32Check(SetConsoleCursorPosition(stdout, Origin));
end;
begin
client := TNetHTTPClient.Create(nil);
response := TStringStream.Create;
client.ContentType := 'application/json';
if paramcount>0 then begin
writeln('Executing pdx eu4 dev diary forum scrapper every ' + paramstr(1) + ' seconds');
sleep(3000);
end
else
begin
writeln('Please supply the refresh parameter');
readln;
exit;
end;
while true do
begin
clearscreen;
writeln('Scraping pdx game forums for new dev diaries...');
client.Get('https://forum.paradoxplaza.com/forum/index.php?forums/europa-universalis-iv.731/', response);
writeln('Finished get request, analyzing...');
responsereader := TStreamReader.Create(response);
//writeln(responsereader.ReadToEnd);
response.Position := 0;
responsestrings := TStringList.Create;
responsestrings.LoadFromStream(response);
for textline := 0 to responsestrings.Count do begin
textindex := ansipos('Development Diary', responsestrings[textline]);
if textindex<>0 then break;
end;
writeln('Found dev diary at line '+textline.ToString + ' at pos '+textindex.ToString);
writeln('Extracting entry URI...');
i := ansipos('index.php?threads/', responsestrings[textline])-1;
i := responsestrings[textline].Length - i;
new := AnsiRightStr(responsestrings[textline], i);
i := ansipos('/preview', new);
new := AnsiLeftStr(new, i);
writeln('URI: ' + new);
writeln('Scraping forum entry... ' + 'https://forum.paradoxplaza.com/forum/'+new);
client.Get('https://forum.paradoxplaza.com/forum/'+new, response);
writeln('Finished get request, analyzing...');
responsestrings := TStringList.Create;
responsestrings.LoadFromStream(response);
for textline := 0 to responsestrings.Count-1 do begin
textindex := ansipos('<div class="messageContent">', responsestrings[textline]);
if textindex<>0 then break;
end;
writeln('Found dev diary main comment at line '+textline.ToString + ' at pos '+textindex.ToString);
write('Printing dev diary message:');
sleep(1000);
write('.');
sleep(1000);
write('.');
sleep(1000);
write('.');
sleep(1000);
clearscreen();
newr:= TStringList.Create;
x := 0;
i := 0;
finished := false;
if lr = response then writeln('Last dev diary already notified') else
begin
client.Post('https://discordapp.com/api/webhooks/568442748240265216/vXQ4OxXhqu1mZRWKw8y1rGUVK8HnRHm7vSD-YqAPYj_zwTdbIECdNPPHSmFQHEbV4Hi6', TStringStream.Create('{"content": "'+'New Dev Diary! : https://forum.paradoxplaza.com/forum/'+new+'" } {'), response, [TNameValuePair.Create(' Content - Type ',' application /
json ')]);
{ writeln(response.ReadString(response.Size));
while finished=false do
begin
if ansipos('<div class="messageTextEndMarker">',responsestrings[textline+x]) <> 0 then break;
newr.Add(responsestrings[textline+x]);
writeln(newr[x]);
inc(x);
end;
lr := response;
end;
sleep(1000*strtoint(paramstr(1)));
end;
end. }
program bot;
{$APPTYPE CONSOLE}
uses System.SysUtils, System.Classes, System.StrUtils, System.Net.URLClient,
System.Net.HTTPClient, System.Net.HttpClientComponent;
type
RProgramOptions = record
public
refresh_time: integer; //Refresh Time in seconds
bot_webhook: string; //Bot Webhook URL
pdx_forum_url: string; //PDX Forum Base URL
pdx_forum_subforum_url: string; //PDX Subforum URL
pdx_forum_new_dev_diary_key_text: string; //Key text to search for
msg: string;
loop: boolean; //Loop activated (true, false)
end;
PProgramOptions = ^RProgramOptions;
DoubleInteger = array[0..1] of integer;
procedure GetOptionsFromParamStr(options: PProgramOptions);
begin
if paramcount = 7 then
begin
try
with options^ do
begin
refresh_time := strtoint(paramstr(1));
bot_webhook := paramstr(2);
pdx_forum_url := paramstr(3);
pdx_forum_subforum_url := paramstr(4);
pdx_forum_new_dev_diary_key_text := paramstr(5);
msg := paramstr(6);
loop := strtobool(paramstr(7));
end;
except
raise Exception.Create('Incorrect parameter definitions');
end;
end
else
raise Exception.Create('Unexpected parameter count, please provide parameters in this order: "bot.exe integer_[refresh_time] str_[bot_webhook] str_[pdx_forum_url] str_[pdx_subforum_url] str_[pdx_forum_new_dev_diary_key_text] str_[msg] bool_[loop]"');
end;
function CheckForStringAndReturnPos(searchfor: string; searchin: TStringList): integer; //Return[0] = line, Return[1] = char pos
var
i: integer;
x: integer;
begin
for i := 0 to searchin.Count do
begin
x := ansipos(searchfor, searchin[i]);
result := i;
if x <> 0 then exit;
end;
end;
function ExtractURLPathFromString(sender: string): string;
var
i: integer;
begin
i := ansipos('index.php?threads/', sender);
i := sender.Length - i;
result := AnsiRightStr(sender, i);
i := ansipos('/preview', result);
result := AnsiLeftStr(result, i);
{writeln('Extracting entry URI...');
i := ansipos('index.php?threads/', responsestrings[textline])-1;
i := responsestrings[textline].Length - i;
new := AnsiRightStr(responsestrings[textline], i);
i := ansipos('/preview', new);
new := AnsiLeftStr(new, i);
writeln('URI: ' + new);}
end;
function CheckForNewDevDiary(options: PProgramOptions): string;
var
client: TNetHTTPClient;
response: TStringStream;
response_s: TStringList;
forum_entry_url_position: integer;
forum_entry_url_raw: string;
dev_diary_url: string;
forum_entry_url_line: integer;
i: integer;
begin
client := TNetHTTPClient.Create(nil);
client.ContentType := 'application/json';
client.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36';
response := TStringStream.Create;
response_s := TStringList.Create;
client.Get(options^.pdx_forum_subforum_url, response);
response_s.LoadFromStream(response);
//for i := 0 to response_s.Count-1 do writeln(response_s[i]); Print HTML test
forum_entry_url_position := CheckForStringAndReturnPos(options^.pdx_forum_new_dev_diary_key_text, response_s);
forum_entry_url_line := forum_entry_url_position;
forum_entry_url_raw := response_s[forum_entry_url_position];
dev_diary_url := ExtractURLPathFromString(forum_entry_url_raw);
response.Clear;
response_s.Clear;
result := dev_diary_url;
end;
procedure DiscordWebHookPost(threadurl: string; options: PProgramOptions);
var
client: TNetHTTPClient;
begin
client := TNetHTTPClient.Create(nil);
client.ContentType := 'application/json';
client.Post(options^.bot_webhook, TStringStream.Create('{"content": "'+options^.msg+options^.pdx_forum_url + threadurl+'"}'));
end;
var
options: RProgramOptions;
last_dev_diary_checked, new_dev_diary: string;
begin
GetOptionsFromParamStr(@options);
while true do
begin
new_dev_diary := CheckForNewDevDiary(@options);
if last_dev_diary_checked <> new_dev_diary then
begin
DiscordWebHookPost(new_dev_diary, @options);
last_dev_diary_checked := new_dev_diary;
end;
if options.loop = false then exit;
sleep(1000*options.refresh_time);
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment