commit 41e8cb2dafc12abe6e07e68fd4387d0a159ae38f Author: Matthew Welch Date: Wed Feb 3 17:47:45 2021 -0800 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d06df06 --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# Lazarus compiler-generated binaries (safe to delete) +*.exe +*.dll +*.so +*.dylib +*.lrs +*.res +*.compiled +*.dbg +*.ppu +*.o +*.or +*.a + +# Lazarus autogenerated files (duplicated info) +*.rst +*.rsj +*.lrt + +# Lazarus local files (user-specific info) +*.lps + +# Lazarus backups and unit output folders. +# These can be changed by user in Lazarus/project options. +backup/ +*.bak +lib/ + +# Application bundle for Mac OS +*.app/ + +!tar.exe \ No newline at end of file diff --git a/downloader.lpi b/downloader.lpi new file mode 100644 index 0000000..fdb2c61 --- /dev/null +++ b/downloader.lpi @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + <UseAppBundle Value="False"/> + <ResourceType Value="res"/> + </General> + <BuildModes Count="1"> + <Item1 Name="Default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <UseFileFilters Value="True"/> + </PublishOptions> + <RunParams> + <FormatVersion Value="2"/> + <Modes Count="0"/> + </RunParams> + <Units Count="1"> + <Unit0> + <Filename Value="downloader.pas"/> + <IsPartOfProject Value="True"/> + </Unit0> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="downloader"/> + </Target> + <SearchPaths> + <IncludeFiles Value="$(ProjOutDir)"/> + <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + </CompilerOptions> + <Debugging> + <Exceptions Count="3"> + <Item1> + <Name Value="EAbort"/> + </Item1> + <Item2> + <Name Value="ECodetoolError"/> + </Item2> + <Item3> + <Name Value="EFOpenError"/> + </Item3> + </Exceptions> + </Debugging> +</CONFIG> diff --git a/downloader.pas b/downloader.pas new file mode 100644 index 0000000..19c39c9 --- /dev/null +++ b/downloader.pas @@ -0,0 +1,136 @@ +program downloader; + +uses fphttpclient, base64, opensslsockets, fpjson, jsonparser, SysUtils, process, Classes; + +const + authString = '***REMOVED***'; + +var + gameId: Integer; + gameData: TJSONData; + client: TFPHTTPClient; + tarFile: String; + +function getGameData(var client: TFPHTTPClient; gameId: Integer; out gameData: TJSONData): Boolean; +const + url = 'https://rpi.narnian.us/games/get_game/'; + +var + jData: TJSONData; + +begin + writeln('start get game data'); + client.AllowRedirect := true; + try + jData := GetJSON(client.Get(url+IntToStr(gameId))); + gameData := jData; + getGameData := true; + Except + getGameData := false; + end; +end; + +function downloadGameTar(var client: TFPHTTPClient; gameId: Integer): String; +const + url = 'https://rpi.narnian.us/games/download/windows/'; + +var + tarFile: TFileStream; + tarFileName: String; + +begin + writeln('start download tar'); + client.AllowRedirect := true; + tarFileName := gameData.FindPath('title_sanitized').AsString+'.tar'; + tarFile := TFileStream.Create(tarFileName, fmCreate); + client.Get(url+IntToStr(gameId), tarFile); + tarFile.Free; + downloadGameTar := tarFileName; +end; + +procedure extractTar(fileName: String); +var + s: AnsiString; + +begin + writeln('start extract tar'); + RunCommand('tar.exe', ['-xf', fileName], s); +end; + +procedure copyFile(oldFile, newFile: AnsiString); +var + splitDir: TStringArray; + s: String; + newDir: String = ''; + source, dest: TFileStream; + +begin + splitDir := newFile.Split(['\', '/']); + for s in splitDir do + begin + if not (s = splitDir[Length(splitDir)-1]) then + begin + newDir := newDir + s + '/'; + CreateDir(newDir); + end; + end; + source := TFileStream.Create(oldFile, fmOpenRead); + dest := TFileStream.Create(newFile, fmCreate); + dest.CopyFrom(source, source.Size); + source.Free; + dest.Free; +end; + +procedure moveFile(oldFile, newFile: AnsiString); +begin + copyFile(oldFile, newFile); + DeleteFile(oldFile); +end; + +procedure proccessHashFiles; +var + files: TJSONData; + hash: String; + hashPaths: TJSONArray; + i, j: Integer; + +begin + writeln('start proccess hash files'); + files := gameData.FindPath('windows.files'); + for i := 0 to files.count-1 do + begin + hash := TJSONObject(files).Names[i]; + hashPaths := TJSONArray(files.FindPath(hash)); + for j := 0 to hashPaths.Count-1 do + begin + if j = hashPaths.Count-1 then + moveFile(hash, hashPaths.Strings[j]) + else + copyFile(hash, hashPaths.Strings[j]); + end; + end; +end; + +begin + if ParamCount > 0 then + begin + gameId := StrToInt(ParamStr(1)); + client := TFPHTTPClient.Create(nil); + client.AddHeader('Authorization', 'Basic '+base64.EncodeStringBase64(authString)); + if getGameData(client, gameId, gameData) then + begin + tarFile := downloadGameTar(client, gameId); + extractTar(tarFile); + proccessHashFiles; + end + else + begin + WriteLn('Invalid game id given'); + end; + end + else + begin + WriteLn('No game id was given'); + end; +end. + diff --git a/tar.exe b/tar.exe new file mode 100644 index 0000000..d528bd3 Binary files /dev/null and b/tar.exe differ