mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-03 00:33:49 +03:00
Merge branch 'main' into teste-locale2
This commit is contained in:
commit
fab15ccded
26
.github/workflows/build.yml
vendored
26
.github/workflows/build.yml
vendored
@ -1,8 +1,6 @@
|
|||||||
name: Build
|
name: Build
|
||||||
|
|
||||||
on:
|
on: [pull_request]
|
||||||
push:
|
|
||||||
branches: main
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@ -39,7 +37,6 @@ jobs:
|
|||||||
if: matrix.os == 'ubuntu-latest'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
run: yarn build:linux
|
run: yarn build:linux
|
||||||
env:
|
env:
|
||||||
MAIN_VITE_STEAMGRIDDB_API_KEY: ${{ secrets.STEAMGRIDDB_API_KEY }}
|
|
||||||
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
|
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
|
||||||
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
|
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@ -48,7 +45,6 @@ jobs:
|
|||||||
if: matrix.os == 'windows-latest'
|
if: matrix.os == 'windows-latest'
|
||||||
run: yarn build:win
|
run: yarn build:win
|
||||||
env:
|
env:
|
||||||
MAIN_VITE_STEAMGRIDDB_API_KEY: ${{ secrets.STEAMGRIDDB_API_KEY }}
|
|
||||||
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
|
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
|
||||||
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
|
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@ -58,7 +54,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: Build-${{ matrix.os }}
|
name: Build-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
dist/*.exe
|
dist/win-unpacked/**
|
||||||
dist/*.zip
|
dist/*.zip
|
||||||
dist/*.dmg
|
dist/*.dmg
|
||||||
dist/*.deb
|
dist/*.deb
|
||||||
@ -66,21 +62,3 @@ jobs:
|
|||||||
dist/*.tar.gz
|
dist/*.tar.gz
|
||||||
dist/*.yml
|
dist/*.yml
|
||||||
dist/*.blockmap
|
dist/*.blockmap
|
||||||
|
|
||||||
- name: Release
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
draft: true
|
|
||||||
files: |
|
|
||||||
dist/*.exe
|
|
||||||
dist/*.zip
|
|
||||||
dist/*.dmg
|
|
||||||
dist/*.AppImage
|
|
||||||
dist/*.snap
|
|
||||||
dist/*.deb
|
|
||||||
dist/*.rpm
|
|
||||||
dist/*.tar.gz
|
|
||||||
dist/*.yml
|
|
||||||
dist/*.blockmap
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
70
.github/workflows/release.yml
vendored
Normal file
70
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
name: Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [windows-latest, ubuntu-latest]
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Check out Git repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: 20.11.1
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: yarn
|
||||||
|
|
||||||
|
- name: Install Python
|
||||||
|
uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: 3.9
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: pip install -r requirements.txt
|
||||||
|
|
||||||
|
- name: Build with cx_Freeze
|
||||||
|
run: python torrent-client/setup.py build
|
||||||
|
|
||||||
|
- name: Build Linux
|
||||||
|
if: matrix.os == 'ubuntu-latest'
|
||||||
|
run: yarn build:linux
|
||||||
|
env:
|
||||||
|
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
|
||||||
|
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build Windows
|
||||||
|
if: matrix.os == 'windows-latest'
|
||||||
|
run: yarn build:win
|
||||||
|
env:
|
||||||
|
MAIN_VITE_ONLINEFIX_USERNAME: ${{ secrets.ONLINEFIX_USERNAME }}
|
||||||
|
MAIN_VITE_ONLINEFIX_PASSWORD: ${{ secrets.ONLINEFIX_PASSWORD }}
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
draft: true
|
||||||
|
files: |
|
||||||
|
dist/*.exe
|
||||||
|
dist/*.zip
|
||||||
|
dist/*.dmg
|
||||||
|
dist/*.AppImage
|
||||||
|
dist/*.snap
|
||||||
|
dist/*.deb
|
||||||
|
dist/*.rpm
|
||||||
|
dist/*.tar.gz
|
||||||
|
dist/*.yml
|
||||||
|
dist/*.blockmap
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
@ -1,2 +1 @@
|
|||||||
yarn lint
|
yarn format
|
||||||
yarn typecheck
|
|
||||||
|
@ -1 +1,2 @@
|
|||||||
yarn format
|
yarn lint
|
||||||
|
yarn typecheck
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
out
|
out
|
||||||
dist
|
dist
|
||||||
|
seeds
|
||||||
pnpm-lock.yaml
|
pnpm-lock.yaml
|
||||||
LICENSE.md
|
LICENSE.md
|
||||||
tsconfig.json
|
tsconfig.json
|
||||||
|
@ -119,7 +119,7 @@ yarn
|
|||||||
|
|
||||||
### Усталёўка Python 3.9
|
### Усталёўка Python 3.9
|
||||||
|
|
||||||
Упэўніцеся, што ў вас усталяваны Python 3.9 на вашым кампутары. Вы можаце загрузіць і ўсталяваць яго з [python.org](https://www.python.org/downloads/release/python-3919/).
|
Упэўніцеся, што ў вас усталяваны Python 3.9 на вашым кампутары. Вы можаце загрузіць і ўсталяваць яго з [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||||
|
|
||||||
### Усталёўка залежнасцяў Python
|
### Усталёўка залежнасцяў Python
|
||||||
|
|
||||||
|
@ -13,11 +13,11 @@
|
|||||||
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
|
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
|
||||||
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
|
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
|
||||||
|
|
||||||
|
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
|
||||||
|
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
|
||||||
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
|
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
|
||||||
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
|
|
||||||
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
|
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
|
||||||
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
|
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
|
||||||
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
|
|
||||||
|
|
||||||
![Hydra Catalogue](./docs/screenshot.png)
|
![Hydra Catalogue](./docs/screenshot.png)
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ yarn
|
|||||||
|
|
||||||
### Install Python 3.9
|
### Install Python 3.9
|
||||||
|
|
||||||
Ensure you have Python 3.9 installed on your machine. You can download and install it from [python.org](https://www.python.org/downloads/release/python-3919/).
|
Ensure you have Python 3.9 installed on your machine. You can download and install it from [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||||
|
|
||||||
### Install Python Dependencies
|
### Install Python Dependencies
|
||||||
|
|
||||||
|
185
README.pl.md
Normal file
185
README.pl.md
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
<br>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
|
||||||
|
|
||||||
|
<h1 align="center">Hydra Launcher</h1>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<strong>Hydra - to program uruchamiający gry z własnym wbudowanym klientem bittorrent i samodzielnie zarządzanym repackagerem..</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
|
||||||
|
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
|
||||||
|
|
||||||
|
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
|
||||||
|
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
|
||||||
|
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
|
||||||
|
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
|
||||||
|
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
|
||||||
|
|
||||||
|
![Hydra Catalogue](./docs/screenshot.png)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## Zawartość.
|
||||||
|
|
||||||
|
- [O nas](#o-nas)
|
||||||
|
- [Cechy.](#cechy)
|
||||||
|
- [Instalacja](#instalacja)
|
||||||
|
- [Dokonaj wpłaty](#dokonaj-wpłaty)
|
||||||
|
- [Dołącz do naszego kanału Telegram](#dołącz-do-naszego-kanału-telegram)
|
||||||
|
- [Rozwidlenie i sklonowanie repozytorium](#rozwidlenie-i-sklonowanie-repozytorium)
|
||||||
|
- [Jak możesz wnieść swój wkład](#jak-możesz-pomóc)
|
||||||
|
- [Struktura projektu](#struktura-projektu)
|
||||||
|
- [Utwórz kompilację z kodu źródłowego](#utwórz-kompilację-z-kodu-źródłowego)
|
||||||
|
- [Instalacja Node.js](#zainstaluj-nodejs)
|
||||||
|
- [Instalacja Yarn](#zainstaluj-yarn)
|
||||||
|
- [Instalacja Node zależności](#zainstaluj-zależności-node)
|
||||||
|
- [Instalacja Python 3.9](#zainstaluj-python-39)
|
||||||
|
- [Instalacja Python zależności](#zainstaluj-zależności-pythona)
|
||||||
|
- [Zmienne środowiskowe](#zmienne-środowiskowe)
|
||||||
|
- [Uruchomienie](#utwórz-kompilację-z-kodu-źródłowego)
|
||||||
|
- [Tworzenie kompilacji](#tworzenie-kompilacji)
|
||||||
|
- [Tworzenie klienta bittorrent](#zbuduj-klienta-bittorrent)
|
||||||
|
- [Tworzenie kompilacji aplikacji Electron](#tworzenie-aplikacji-electron)
|
||||||
|
- [Współtwórcy](#współtwórcy)
|
||||||
|
|
||||||
|
## O nas
|
||||||
|
|
||||||
|
**Hydra** - jest **programem uruchamiającym gry** z wbudowanym **klientem BitTorrent** i **samozarządzającym się repackagerem**.
|
||||||
|
<br>
|
||||||
|
Ten launcher jest napisany w TypeScript (Electron) i Pythonie, który współpracuje z systemem torrent przy użyciu libtorrent.
|
||||||
|
|
||||||
|
## Cechy
|
||||||
|
|
||||||
|
- Samodzielnie zarządzany repackager wśród wszystkich najbardziej zaufanych stron na [Megathread]("https://www.reddit.com/r/Piracy/wiki/megathread/").
|
||||||
|
- Własny wbudowany klient bittorrent
|
||||||
|
- Integracja funkcji How Long To Beat (HLTB) na stronie gry
|
||||||
|
- Personalizacja folderu pobierania
|
||||||
|
- Powiadomienia o aktualizacjach listy repacków
|
||||||
|
- Wsparcie dla systemów Windows i Linux
|
||||||
|
- Stała aktualizacja
|
||||||
|
- I nie tylko ...
|
||||||
|
|
||||||
|
## Instalacja
|
||||||
|
|
||||||
|
Aby zainstalować, wykonaj poniższe czynności:
|
||||||
|
|
||||||
|
1. Pobierz najnowszą wersję programu Hydra ze strony [Wydania](https://github.com/hydralauncher/hydra/releases/latest).
|
||||||
|
- Pobierz .exe tylko, jeśli chcesz zainstalować Hydrę w systemie Windows.
|
||||||
|
- Pobierz .deb lub .rpm lub .zip, jeśli chcesz zainstalować Hydrę w systemie Linux (zależy od dystrybucji systemu Linux).
|
||||||
|
2. Uruchom pobrany plik.
|
||||||
|
3. Ciesz się Hydrą!
|
||||||
|
|
||||||
|
## <a name="contributing"> Dokonaj wpłaty
|
||||||
|
|
||||||
|
### <a name="join-our-telegram"></a> Dołącz do naszego kanału Telegram
|
||||||
|
|
||||||
|
Skupiamy nasze dyskusje na naszym kanale [Telegram](https://t.me/hydralauncher).
|
||||||
|
|
||||||
|
1. Dołącz do naszego kanału
|
||||||
|
2. Przejdź do kanału ról i wybierz rolę Pracownik.
|
||||||
|
3. Wejdź na kanał dev, komunikuj się z nami i dziel się swoimi pomysłami.
|
||||||
|
|
||||||
|
### Rozwidlenie i sklonowanie repozytorium
|
||||||
|
|
||||||
|
1. Rozwidlenie repozytorium [(kliknij tutaj, aby rozwidlić teraz)](https://github.com/hydralauncher/hydra/fork)
|
||||||
|
2. Sklonuj swój rozwidlony kod `git clone https://github.com/your_username/hydra`.
|
||||||
|
3. Utwórz nowy brunch
|
||||||
|
4. Wypchnij swoje zatwierdzenia
|
||||||
|
5. Wyślij nowy Pull Request
|
||||||
|
|
||||||
|
### Jak możesz pomóc
|
||||||
|
|
||||||
|
- Tłumaczenie: Chcemy, aby Hydra była dostępna dla jak największej liczby osób. Zachęcamy do pomocy w tłumaczeniu na nowe języki lub aktualizowaniu i ulepszaniu tych, które są już dostępne na Hydrze.
|
||||||
|
- Kod: Hydra jest zbudowana przy użyciu Typescript, Electron i odrobiny Pythona. Jeśli chcesz wnieść swój wkład, dołącz do naszego kanału Telegram!
|
||||||
|
|
||||||
|
### Struktura projektu
|
||||||
|
|
||||||
|
- Klient torrent: Używamy libtorrent, biblioteki Pythona, do zarządzania pobieraniem torrentów.
|
||||||
|
- src/renderer: interfejs aplikacji
|
||||||
|
- src/main: cała logika jest tutaj.
|
||||||
|
|
||||||
|
## Utwórz kompilację z kodu źródłowego
|
||||||
|
|
||||||
|
### Zainstaluj Node.js
|
||||||
|
|
||||||
|
Upewnij się, że masz zainstalowany Node.js na swoim komputerze. Jeśli nie, pobierz i zainstaluj go ze strony [nodejs.org](https://nodejs.org/).
|
||||||
|
|
||||||
|
### Zainstaluj Yarn
|
||||||
|
|
||||||
|
Yarn to menedżer pakietów dla Node.js. Jeśli jeszcze nie zainstalowałeś Yarn, możesz to zrobić, postępując zgodnie z instrukcjami na stronie [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/).
|
||||||
|
|
||||||
|
### Zainstaluj zależności Node
|
||||||
|
|
||||||
|
Przejdź do katalogu projektu i zainstaluj zależności Node za pomocą Yarn:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd hydra
|
||||||
|
yarn
|
||||||
|
```
|
||||||
|
|
||||||
|
### Zainstaluj Python 3.9
|
||||||
|
|
||||||
|
Upewnij się, że masz zainstalowany Python 3.9 na swoim komputerze. Można go pobrać i zainstalować ze strony [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||||
|
|
||||||
|
### Zainstaluj zależności Pythona
|
||||||
|
|
||||||
|
Zainstaluj niezbędne zależności Pythona za pomocą pip:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Zmienne środowiskowe
|
||||||
|
|
||||||
|
Będziesz potrzebował klucza API SteamGridDB, aby uzyskać ikony gier podczas instalacji.
|
||||||
|
Jeśli chcesz użyć onlinefix jako repackagera, musisz dodać swoje dane uwierzytelniające do .env
|
||||||
|
|
||||||
|
Po jego uzyskaniu można skopiować plik lub zmienić jego nazwę `.env.example` na `.env` i umieść go na`STEAMGRIDDB_API_KEY`, `ONLINEFIX_USERNAME`, `ONLINEFIX_PASSWORD`.
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
Po skonfigurowaniu wszystkiego można uruchomić następujące polecenie, aby uruchomić zarówno proces Electron, jak i klienta bittorrent:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Tworzenie kompilacji
|
||||||
|
|
||||||
|
### Zbuduj klienta bittorrent
|
||||||
|
|
||||||
|
Zbuduj klienta bittorrent za pomocą tego poleceniaи:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python torrent-client/setup.py build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tworzenie aplikacji Electron
|
||||||
|
|
||||||
|
Zbuduj aplikację Electron za pomocą tego polecenia:
|
||||||
|
|
||||||
|
W systemie Windows:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn build:win
|
||||||
|
```
|
||||||
|
|
||||||
|
W systemie Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn build:linux
|
||||||
|
```
|
||||||
|
|
||||||
|
## Współtwórcy
|
||||||
|
|
||||||
|
<a href="https://github.com/hydralauncher/hydra/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=hydralauncher/hydra" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Hydra posiada licencję [MIT License](LICENSE).
|
@ -13,12 +13,11 @@
|
|||||||
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
|
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
|
||||||
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
|
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
|
||||||
|
|
||||||
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
|
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
|
||||||
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
|
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
|
||||||
|
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
|
||||||
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
|
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
|
||||||
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
|
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
|
||||||
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
|
|
||||||
|
|
||||||
![Hydra Catalogue](./docs/screenshot.png)
|
![Hydra Catalogue](./docs/screenshot.png)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -119,7 +118,7 @@ yarn
|
|||||||
|
|
||||||
### <a name="install-python-39"></a> Instale Python 3.9
|
### <a name="install-python-39"></a> Instale Python 3.9
|
||||||
|
|
||||||
Certifique-se de ter o Python 3.9 instalado em sua máquina. Você pode baixá-lo e instalá-lo em [python.org](https://www.python.org/downloads/release/python-3919/).
|
Certifique-se de ter o Python 3.9 instalado em sua máquina. Você pode baixá-lo e instalá-lo em [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||||
|
|
||||||
### <a name="install-python-dependencies"></a> Instale Python Dependencies
|
### <a name="install-python-dependencies"></a> Instale Python Dependencies
|
||||||
|
|
||||||
|
10
README.ru.md
10
README.ru.md
@ -13,11 +13,11 @@
|
|||||||
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
|
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
|
||||||
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
|
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
|
||||||
|
|
||||||
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
|
|
||||||
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
|
|
||||||
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
|
|
||||||
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
|
|
||||||
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
|
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
|
||||||
|
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
|
||||||
|
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
|
||||||
|
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
|
||||||
|
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./docs/screenshot.png)
|
![Hydra Catalogue](./docs/screenshot.png)
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ yarn
|
|||||||
|
|
||||||
### Установка Python 3.9
|
### Установка Python 3.9
|
||||||
|
|
||||||
Убедитесь, что у вас установлен Python 3.9 на вашем компьютере. Вы можете загрузить и установить его с [python.org](https://www.python.org/downloads/release/python-3919/).
|
Убедитесь, что у вас установлен Python 3.9 на вашем компьютере. Вы можете загрузить и установить его с [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||||
|
|
||||||
### Установка зависимостей Python
|
### Установка зависимостей Python
|
||||||
|
|
||||||
|
@ -13,11 +13,11 @@
|
|||||||
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
|
[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions)
|
||||||
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
|
[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases)
|
||||||
|
|
||||||
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
|
|
||||||
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
|
|
||||||
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
|
|
||||||
[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md)
|
|
||||||
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
|
[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md)
|
||||||
|
[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md)
|
||||||
|
[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md)
|
||||||
|
[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md)
|
||||||
|
[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./docs/screenshot.png)
|
![Hydra Catalogue](./docs/screenshot.png)
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ yarn
|
|||||||
|
|
||||||
### Встановіть Python 3.9
|
### Встановіть Python 3.9
|
||||||
|
|
||||||
Переконайтеся, що на вашому комп'ютері встановлено Python 3.9. Ви можете завантажити та встановити його з [python.org](https://www.python.org/downloads/release/python-3919/).
|
Переконайтеся, що на вашому комп'ютері встановлено Python 3.9. Ви можете завантажити та встановити його з [python.org](https://www.python.org/downloads/release/python-3913/).
|
||||||
|
|
||||||
### Встановіть Python залежності
|
### Встановіть Python залежності
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ extraResources:
|
|||||||
- hydra-download-manager
|
- hydra-download-manager
|
||||||
- hydra.db
|
- hydra.db
|
||||||
- fastlist.exe
|
- fastlist.exe
|
||||||
|
- seeds
|
||||||
files:
|
files:
|
||||||
- "!**/.vscode/*"
|
- "!**/.vscode/*"
|
||||||
- "!src/*"
|
- "!src/*"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydra",
|
"name": "hydra",
|
||||||
"version": "1.2.2",
|
"version": "1.2.3",
|
||||||
"description": "Hydra",
|
"description": "Hydra",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "Los Broxas",
|
"author": "Los Broxas",
|
||||||
|
1
seeds/steam-games.json
Normal file
1
seeds/steam-games.json
Normal file
File diff suppressed because one or more lines are too long
@ -18,21 +18,6 @@ export const repackers = [
|
|||||||
"onlinefix",
|
"onlinefix",
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export const months = [
|
|
||||||
"Jan",
|
|
||||||
"Feb",
|
|
||||||
"Mar",
|
|
||||||
"Apr",
|
|
||||||
"May",
|
|
||||||
"Jun",
|
|
||||||
"Jul",
|
|
||||||
"Aug",
|
|
||||||
"Sep",
|
|
||||||
"Oct",
|
|
||||||
"Nov",
|
|
||||||
"Dec",
|
|
||||||
];
|
|
||||||
|
|
||||||
export const defaultDownloadsPath = app.getPath("downloads");
|
export const defaultDownloadsPath = app.getPath("downloads");
|
||||||
|
|
||||||
export const databasePath = path.join(
|
export const databasePath = path.join(
|
||||||
@ -41,5 +26,6 @@ export const databasePath = path.join(
|
|||||||
"hydra.db"
|
"hydra.db"
|
||||||
);
|
);
|
||||||
|
|
||||||
export const INSTALLATION_ID_LENGTH = 6;
|
export const seedsPath = app.isPackaged
|
||||||
export const ACTIVATION_KEY_MULTIPLIER = 7;
|
? path.join(process.resourcesPath, "seeds")
|
||||||
|
: path.join(__dirname, "..", "..", "seeds");
|
||||||
|
@ -1,25 +1,21 @@
|
|||||||
import { DataSource } from "typeorm";
|
import { DataSource } from "typeorm";
|
||||||
import {
|
import { Game, GameShopCache, Repack, UserPreferences } from "@main/entity";
|
||||||
Game,
|
import type { BetterSqlite3ConnectionOptions } from "typeorm/driver/better-sqlite3/BetterSqlite3ConnectionOptions";
|
||||||
GameShopCache,
|
|
||||||
Repack,
|
|
||||||
UserPreferences,
|
|
||||||
SteamGame,
|
|
||||||
} from "@main/entity";
|
|
||||||
import type { SqliteConnectionOptions } from "typeorm/driver/sqlite/SqliteConnectionOptions";
|
|
||||||
|
|
||||||
import { databasePath } from "./constants";
|
import { databasePath } from "./constants";
|
||||||
import migrations from "./migrations";
|
import migrations from "./migrations";
|
||||||
|
|
||||||
export const createDataSource = (options: Partial<SqliteConnectionOptions>) =>
|
export const createDataSource = (
|
||||||
|
options: Partial<BetterSqlite3ConnectionOptions>
|
||||||
|
) =>
|
||||||
new DataSource({
|
new DataSource({
|
||||||
type: "better-sqlite3",
|
type: "better-sqlite3",
|
||||||
database: databasePath,
|
entities: [Game, Repack, UserPreferences, GameShopCache],
|
||||||
entities: [Game, Repack, UserPreferences, GameShopCache, SteamGame],
|
|
||||||
synchronize: true,
|
synchronize: true,
|
||||||
|
database: databasePath,
|
||||||
...options,
|
...options,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const dataSource = createDataSource({
|
export const dataSource = createDataSource({
|
||||||
migrations: migrations,
|
migrations,
|
||||||
});
|
});
|
||||||
|
@ -23,8 +23,8 @@ export class Game {
|
|||||||
@Column("text")
|
@Column("text")
|
||||||
title: string;
|
title: string;
|
||||||
|
|
||||||
@Column("text")
|
@Column("text", { nullable: true })
|
||||||
iconUrl: string;
|
iconUrl: string | null;
|
||||||
|
|
||||||
@Column("text", { nullable: true })
|
@Column("text", { nullable: true })
|
||||||
folderName: string | null;
|
folderName: string | null;
|
||||||
|
@ -2,4 +2,3 @@ export * from "./game.entity";
|
|||||||
export * from "./repack.entity";
|
export * from "./repack.entity";
|
||||||
export * from "./user-preferences.entity";
|
export * from "./user-preferences.entity";
|
||||||
export * from "./game-shop-cache.entity";
|
export * from "./game-shop-cache.entity";
|
||||||
export * from "./steam-game.entity";
|
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import { Column, Entity, PrimaryColumn } from "typeorm";
|
|
||||||
|
|
||||||
@Entity("steam_game")
|
|
||||||
export class SteamGame {
|
|
||||||
@PrimaryColumn()
|
|
||||||
id: number;
|
|
||||||
|
|
||||||
@Column()
|
|
||||||
name: string;
|
|
||||||
}
|
|
@ -1,9 +1,10 @@
|
|||||||
import { gameShopCacheRepository, steamGameRepository } from "@main/repository";
|
import { gameShopCacheRepository } from "@main/repository";
|
||||||
import { getSteamAppDetails } from "@main/services";
|
import { getSteamAppDetails } from "@main/services";
|
||||||
|
|
||||||
import type { ShopDetails, GameShop, SteamAppDetails } from "@types";
|
import type { ShopDetails, GameShop, SteamAppDetails } from "@types";
|
||||||
|
|
||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
|
import { stateManager } from "@main/state-manager";
|
||||||
|
|
||||||
const getLocalizedSteamAppDetails = (
|
const getLocalizedSteamAppDetails = (
|
||||||
objectID: string,
|
objectID: string,
|
||||||
@ -13,10 +14,11 @@ const getLocalizedSteamAppDetails = (
|
|||||||
return getSteamAppDetails(objectID, language);
|
return getSteamAppDetails(objectID, language);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all([
|
return getSteamAppDetails(objectID, language).then((localizedAppDetails) => {
|
||||||
steamGameRepository.findOne({ where: { id: Number(objectID) } }),
|
const steamGame = stateManager
|
||||||
getSteamAppDetails(objectID, language),
|
.getValue("steamGames")
|
||||||
]).then(([steamGame, localizedAppDetails]) => {
|
.find((game) => game.id === Number(objectID));
|
||||||
|
|
||||||
if (steamGame && localizedAppDetails) {
|
if (steamGame && localizedAppDetails) {
|
||||||
return {
|
return {
|
||||||
...localizedAppDetails,
|
...localizedAppDetails,
|
||||||
|
@ -3,8 +3,8 @@ import { gameRepository } from "@main/repository";
|
|||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
|
|
||||||
import type { GameShop } from "@types";
|
import type { GameShop } from "@types";
|
||||||
import { getFileBase64 } from "@main/helpers";
|
import { getFileBase64, getSteamAppAsset } from "@main/helpers";
|
||||||
import { getSteamGameIconUrl } from "@main/services";
|
import { stateManager } from "@main/state-manager";
|
||||||
|
|
||||||
const addGameToLibrary = async (
|
const addGameToLibrary = async (
|
||||||
_event: Electron.IpcMainInvokeEvent,
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
@ -27,17 +27,29 @@ const addGameToLibrary = async (
|
|||||||
)
|
)
|
||||||
.then(async ({ affected }) => {
|
.then(async ({ affected }) => {
|
||||||
if (!affected) {
|
if (!affected) {
|
||||||
const iconUrl = await getFileBase64(
|
const steamGame = stateManager
|
||||||
await getSteamGameIconUrl(objectID)
|
.getValue("steamGames")
|
||||||
);
|
.find((game) => game.id === Number(objectID));
|
||||||
|
|
||||||
await gameRepository.insert({
|
const iconUrl = steamGame?.clientIcon
|
||||||
title,
|
? getSteamAppAsset("icon", objectID, steamGame.clientIcon)
|
||||||
iconUrl,
|
: null;
|
||||||
objectID,
|
|
||||||
shop: gameShop,
|
await gameRepository
|
||||||
executablePath,
|
.insert({
|
||||||
});
|
title,
|
||||||
|
iconUrl,
|
||||||
|
objectID,
|
||||||
|
shop: gameShop,
|
||||||
|
executablePath,
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
if (iconUrl) {
|
||||||
|
getFileBase64(iconUrl).then((base64) =>
|
||||||
|
gameRepository.update({ objectID }, { iconUrl: base64 })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { getSteamGameIconUrl } from "@main/services";
|
|
||||||
import {
|
import {
|
||||||
gameRepository,
|
gameRepository,
|
||||||
repackRepository,
|
repackRepository,
|
||||||
@ -8,10 +7,11 @@ import {
|
|||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
|
|
||||||
import type { GameShop } from "@types";
|
import type { GameShop } from "@types";
|
||||||
import { getFileBase64 } from "@main/helpers";
|
import { getFileBase64, getSteamAppAsset } from "@main/helpers";
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
import { DownloadManager } from "@main/services";
|
import { DownloadManager } from "@main/services";
|
||||||
import { Downloader, GameStatus } from "@shared";
|
import { Downloader, GameStatus } from "@shared";
|
||||||
|
import { stateManager } from "@main/state-manager";
|
||||||
|
|
||||||
const startGameDownload = async (
|
const startGameDownload = async (
|
||||||
_event: Electron.IpcMainInvokeEvent,
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
@ -76,18 +76,34 @@ const startGameDownload = async (
|
|||||||
|
|
||||||
return game;
|
return game;
|
||||||
} else {
|
} else {
|
||||||
const iconUrl = await getFileBase64(await getSteamGameIconUrl(objectID));
|
const steamGame = stateManager
|
||||||
|
.getValue("steamGames")
|
||||||
|
.find((game) => game.id === Number(objectID));
|
||||||
|
|
||||||
const createdGame = await gameRepository.save({
|
const iconUrl = steamGame?.clientIcon
|
||||||
title,
|
? getSteamAppAsset("icon", objectID, steamGame.clientIcon)
|
||||||
iconUrl,
|
: null;
|
||||||
objectID,
|
|
||||||
downloader,
|
const createdGame = await gameRepository
|
||||||
shop: gameShop,
|
.save({
|
||||||
status: GameStatus.Downloading,
|
title,
|
||||||
downloadPath,
|
iconUrl,
|
||||||
repack: { id: repackId },
|
objectID,
|
||||||
});
|
downloader,
|
||||||
|
shop: gameShop,
|
||||||
|
status: GameStatus.Downloading,
|
||||||
|
downloadPath,
|
||||||
|
repack: { id: repackId },
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
if (iconUrl) {
|
||||||
|
getFileBase64(iconUrl).then((base64) =>
|
||||||
|
gameRepository.update({ objectID }, { iconUrl: base64 })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
DownloadManager.downloadGame(createdGame.id);
|
DownloadManager.downloadGame(createdGame.id);
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ import {
|
|||||||
gogFormatter,
|
gogFormatter,
|
||||||
onlinefixFormatter,
|
onlinefixFormatter,
|
||||||
} from "./formatters";
|
} from "./formatters";
|
||||||
import { months, repackers } from "../constants";
|
import { repackers } from "../constants";
|
||||||
|
|
||||||
export const pipe =
|
export const pipe =
|
||||||
<T>(...fns: ((arg: T) => any)[]) =>
|
<T>(...fns: ((arg: T) => any)[]) =>
|
||||||
@ -44,19 +44,6 @@ export const repackerFormatter: Record<
|
|||||||
onlinefix: onlinefixFormatter,
|
onlinefix: onlinefixFormatter,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const formatUploadDate = (str: string) => {
|
|
||||||
const date = new Date();
|
|
||||||
|
|
||||||
const [month, day, year] = str.split(" ");
|
|
||||||
|
|
||||||
date.setMonth(months.indexOf(month.replace(".", "")));
|
|
||||||
date.setDate(Number(day.substring(0, 2)));
|
|
||||||
date.setFullYear(Number("20" + year.replace("'", "")));
|
|
||||||
date.setHours(0, 0, 0, 0);
|
|
||||||
|
|
||||||
return date;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getSteamAppAsset = (
|
export const getSteamAppAsset = (
|
||||||
category: "library" | "hero" | "logo" | "icon",
|
category: "library" | "hero" | "logo" | "icon",
|
||||||
objectID: string,
|
objectID: string,
|
||||||
|
@ -19,7 +19,7 @@ autoUpdater.setFeedURL({
|
|||||||
const gotTheLock = app.requestSingleInstanceLock();
|
const gotTheLock = app.requestSingleInstanceLock();
|
||||||
if (!gotTheLock) app.quit();
|
if (!gotTheLock) app.quit();
|
||||||
|
|
||||||
app.disableHardwareAcceleration();
|
app.commandLine.appendSwitch("--no-sandbox");
|
||||||
|
|
||||||
i18n.init({
|
i18n.init({
|
||||||
resources,
|
resources,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { stateManager } from "./state-manager";
|
import { stateManager } from "./state-manager";
|
||||||
import { repackersOn1337x } from "./constants";
|
import { repackersOn1337x, seedsPath } from "./constants";
|
||||||
import {
|
import {
|
||||||
getNewGOGGames,
|
getNewGOGGames,
|
||||||
getNewRepacksFromUser,
|
getNewRepacksFromUser,
|
||||||
@ -11,7 +11,6 @@ import {
|
|||||||
import {
|
import {
|
||||||
gameRepository,
|
gameRepository,
|
||||||
repackRepository,
|
repackRepository,
|
||||||
steamGameRepository,
|
|
||||||
userPreferencesRepository,
|
userPreferencesRepository,
|
||||||
} from "./repository";
|
} from "./repository";
|
||||||
import { TorrentDownloader } from "./services";
|
import { TorrentDownloader } from "./services";
|
||||||
@ -20,7 +19,11 @@ import { Notification } from "electron";
|
|||||||
import { t } from "i18next";
|
import { t } from "i18next";
|
||||||
import { GameStatus } from "@shared";
|
import { GameStatus } from "@shared";
|
||||||
import { In } from "typeorm";
|
import { In } from "typeorm";
|
||||||
|
import fs from "node:fs";
|
||||||
|
import path from "node:path";
|
||||||
import { RealDebridClient } from "./services/real-debrid";
|
import { RealDebridClient } from "./services/real-debrid";
|
||||||
|
import { orderBy } from "lodash-es";
|
||||||
|
import { SteamGame } from "@types";
|
||||||
|
|
||||||
startProcessWatcher();
|
startProcessWatcher();
|
||||||
|
|
||||||
@ -69,21 +72,18 @@ const checkForNewRepacks = async (userPreferences: UserPreferences | null) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const loadState = async (userPreferences: UserPreferences | null) => {
|
const loadState = async (userPreferences: UserPreferences | null) => {
|
||||||
const [repacks, steamGames] = await Promise.all([
|
const repacks = await repackRepository.find({
|
||||||
repackRepository.find({
|
order: {
|
||||||
order: {
|
createdAt: "desc",
|
||||||
createdAt: "desc",
|
},
|
||||||
},
|
});
|
||||||
}),
|
|
||||||
steamGameRepository.find({
|
const steamGames = JSON.parse(
|
||||||
order: {
|
fs.readFileSync(path.join(seedsPath, "steam-games.json"), "utf-8")
|
||||||
name: "asc",
|
) as SteamGame[];
|
||||||
},
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
|
|
||||||
stateManager.setValue("repacks", repacks);
|
stateManager.setValue("repacks", repacks);
|
||||||
stateManager.setValue("steamGames", steamGames);
|
stateManager.setValue("steamGames", orderBy(steamGames, ["name"], "asc"));
|
||||||
|
|
||||||
import("./events");
|
import("./events");
|
||||||
|
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
import { dataSource } from "./data-source";
|
import { dataSource } from "./data-source";
|
||||||
import {
|
import { Game, GameShopCache, Repack, UserPreferences } from "@main/entity";
|
||||||
Game,
|
|
||||||
GameShopCache,
|
|
||||||
Repack,
|
|
||||||
UserPreferences,
|
|
||||||
SteamGame,
|
|
||||||
} from "@main/entity";
|
|
||||||
|
|
||||||
export const gameRepository = dataSource.getRepository(Game);
|
export const gameRepository = dataSource.getRepository(Game);
|
||||||
|
|
||||||
@ -15,5 +9,3 @@ export const userPreferencesRepository =
|
|||||||
dataSource.getRepository(UserPreferences);
|
dataSource.getRepository(UserPreferences);
|
||||||
|
|
||||||
export const gameShopCacheRepository = dataSource.getRepository(GameShopCache);
|
export const gameShopCacheRepository = dataSource.getRepository(GameShopCache);
|
||||||
|
|
||||||
export const steamGameRepository = dataSource.getRepository(SteamGame);
|
|
||||||
|
40
src/main/scripts/get-games-icon-hash.ts
Normal file
40
src/main/scripts/get-games-icon-hash.ts
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import path from "node:path";
|
||||||
|
import fs from "node:fs";
|
||||||
|
|
||||||
|
import { getSteamGameClientIcon, logger } from "@main/services";
|
||||||
|
import { chunk } from "lodash-es";
|
||||||
|
import { seedsPath } from "@main/constants";
|
||||||
|
|
||||||
|
import type { SteamGame } from "@types";
|
||||||
|
|
||||||
|
const steamGamesPath = path.join(seedsPath, "steam-games.json");
|
||||||
|
|
||||||
|
const steamGames = JSON.parse(
|
||||||
|
fs.readFileSync(steamGamesPath, "utf-8")
|
||||||
|
) as SteamGame[];
|
||||||
|
|
||||||
|
const chunks = chunk(steamGames, 1500);
|
||||||
|
|
||||||
|
for (const chunk of chunks) {
|
||||||
|
await Promise.all(
|
||||||
|
chunk.map(async (steamGame) => {
|
||||||
|
if (steamGame.clientIcon) return;
|
||||||
|
|
||||||
|
const index = steamGames.findIndex((game) => game.id === steamGame.id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const clientIcon = await getSteamGameClientIcon(String(steamGame.id));
|
||||||
|
|
||||||
|
steamGames[index].clientIcon = clientIcon;
|
||||||
|
|
||||||
|
logger.log("info", `Set ${steamGame.name} client icon`);
|
||||||
|
} catch (err) {
|
||||||
|
steamGames[index].clientIcon = null;
|
||||||
|
logger.log("info", `Could not set icon for ${steamGame.name}`);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
fs.writeFileSync(steamGamesPath, JSON.stringify(steamGames));
|
||||||
|
logger.log("info", "Updated steam games");
|
||||||
|
}
|
@ -1,13 +1,39 @@
|
|||||||
import { JSDOM } from "jsdom";
|
import { JSDOM } from "jsdom";
|
||||||
|
|
||||||
import { formatUploadDate } from "@main/helpers";
|
|
||||||
|
|
||||||
import { Repack } from "@main/entity";
|
import { Repack } from "@main/entity";
|
||||||
import { requestWebPage, savePage } from "./helpers";
|
import { requestWebPage, savePage } from "./helpers";
|
||||||
|
|
||||||
|
const months = [
|
||||||
|
"Jan",
|
||||||
|
"Feb",
|
||||||
|
"Mar",
|
||||||
|
"Apr",
|
||||||
|
"May",
|
||||||
|
"Jun",
|
||||||
|
"Jul",
|
||||||
|
"Aug",
|
||||||
|
"Sep",
|
||||||
|
"Oct",
|
||||||
|
"Nov",
|
||||||
|
"Dec",
|
||||||
|
];
|
||||||
|
|
||||||
export const request1337x = async (path: string) =>
|
export const request1337x = async (path: string) =>
|
||||||
requestWebPage(`https://1337xx.to${path}`);
|
requestWebPage(`https://1337xx.to${path}`);
|
||||||
|
|
||||||
|
const formatUploadDate = (str: string) => {
|
||||||
|
const date = new Date();
|
||||||
|
|
||||||
|
const [month, day, year] = str.split(" ");
|
||||||
|
|
||||||
|
date.setMonth(months.indexOf(month.replace(".", "")));
|
||||||
|
date.setDate(Number(day.substring(0, 2)));
|
||||||
|
date.setFullYear(Number("20" + year.replace("'", "")));
|
||||||
|
date.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
return date;
|
||||||
|
};
|
||||||
|
|
||||||
/* TODO: $a will often be null */
|
/* TODO: $a will often be null */
|
||||||
const getTorrentDetails = async (path: string) => {
|
const getTorrentDetails = async (path: string) => {
|
||||||
const response = await request1337x(path);
|
const response = await request1337x(path);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { getSteamAppAsset } from "@main/helpers";
|
|
||||||
|
|
||||||
export interface SteamGridResponse {
|
export interface SteamGridResponse {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
@ -59,16 +58,11 @@ export const getSteamGridGameById = async (
|
|||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSteamGameIconUrl = async (objectID: string) => {
|
export const getSteamGameClientIcon = async (objectID: string) => {
|
||||||
const {
|
const {
|
||||||
data: { id: steamGridGameId },
|
data: { id: steamGridGameId },
|
||||||
} = await getSteamGridData(objectID, "games", "steam");
|
} = await getSteamGridData(objectID, "games", "steam");
|
||||||
|
|
||||||
const steamGridGame = await getSteamGridGameById(steamGridGameId);
|
const steamGridGame = await getSteamGridGameById(steamGridGameId);
|
||||||
|
return steamGridGame.data.platforms.steam.metadata.clienticon;
|
||||||
return getSteamAppAsset(
|
|
||||||
"icon",
|
|
||||||
objectID,
|
|
||||||
steamGridGame.data.platforms.steam.metadata.clienticon
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
@ -4,8 +4,8 @@ import { app } from "electron";
|
|||||||
import { chunk } from "lodash-es";
|
import { chunk } from "lodash-es";
|
||||||
|
|
||||||
import { createDataSource } from "@main/data-source";
|
import { createDataSource } from "@main/data-source";
|
||||||
import { Repack, SteamGame } from "@main/entity";
|
import { Repack } from "@main/entity";
|
||||||
import { repackRepository, steamGameRepository } from "@main/repository";
|
import { repackRepository } from "@main/repository";
|
||||||
|
|
||||||
export const resolveDatabaseUpdates = async () => {
|
export const resolveDatabaseUpdates = async () => {
|
||||||
const updateDataSource = createDataSource({
|
const updateDataSource = createDataSource({
|
||||||
@ -16,12 +16,8 @@ export const resolveDatabaseUpdates = async () => {
|
|||||||
|
|
||||||
return updateDataSource.initialize().then(async () => {
|
return updateDataSource.initialize().then(async () => {
|
||||||
const updateRepackRepository = updateDataSource.getRepository(Repack);
|
const updateRepackRepository = updateDataSource.getRepository(Repack);
|
||||||
const updateSteamGameRepository = updateDataSource.getRepository(SteamGame);
|
|
||||||
|
|
||||||
const [updateRepacks, updateSteamGames] = await Promise.all([
|
const updateRepacks = await updateRepackRepository.find();
|
||||||
updateRepackRepository.find(),
|
|
||||||
updateSteamGameRepository.find(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
const updateRepacksChunks = chunk(updateRepacks, 800);
|
const updateRepacksChunks = chunk(updateRepacks, 800);
|
||||||
|
|
||||||
@ -33,16 +29,5 @@ export const resolveDatabaseUpdates = async () => {
|
|||||||
.orIgnore()
|
.orIgnore()
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
const steamGamesChunks = chunk(updateSteamGames, 800);
|
|
||||||
|
|
||||||
for (const chunk of steamGamesChunks) {
|
|
||||||
await steamGameRepository
|
|
||||||
.createQueryBuilder()
|
|
||||||
.insert()
|
|
||||||
.values(chunk)
|
|
||||||
.orIgnore()
|
|
||||||
.execute();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import type { Repack, SteamGame } from "@main/entity";
|
import type { Repack } from "@main/entity";
|
||||||
|
import type { SteamGame } from "@types";
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
repacks: Repack[];
|
repacks: Repack[];
|
||||||
|
@ -106,6 +106,8 @@ export const menuItemButtonLabel = style({
|
|||||||
export const gameIcon = style({
|
export const gameIcon = style({
|
||||||
width: "20px",
|
width: "20px",
|
||||||
height: "20px",
|
height: "20px",
|
||||||
|
minWidth: "20px",
|
||||||
|
minHeight: "20px",
|
||||||
borderRadius: "4px",
|
borderRadius: "4px",
|
||||||
backgroundSize: "cover",
|
backgroundSize: "cover",
|
||||||
});
|
});
|
||||||
|
@ -13,6 +13,8 @@ import * as styles from "./sidebar.css";
|
|||||||
import { GameStatus, GameStatusHelper } from "@shared";
|
import { GameStatus, GameStatusHelper } from "@shared";
|
||||||
import { buildGameDetailsPath } from "@renderer/helpers";
|
import { buildGameDetailsPath } from "@renderer/helpers";
|
||||||
|
|
||||||
|
import SteamLogo from "@renderer/assets/steam-logo.svg?react";
|
||||||
|
|
||||||
const SIDEBAR_MIN_WIDTH = 200;
|
const SIDEBAR_MIN_WIDTH = 200;
|
||||||
const SIDEBAR_INITIAL_WIDTH = 250;
|
const SIDEBAR_INITIAL_WIDTH = 250;
|
||||||
const SIDEBAR_MAX_WIDTH = 450;
|
const SIDEBAR_MAX_WIDTH = 450;
|
||||||
@ -191,11 +193,16 @@ export function Sidebar() {
|
|||||||
handleSidebarItemClick(buildGameDetailsPath(game))
|
handleSidebarItemClick(buildGameDetailsPath(game))
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<img
|
{game.iconUrl ? (
|
||||||
className={styles.gameIcon}
|
<img
|
||||||
src={game.iconUrl}
|
className={styles.gameIcon}
|
||||||
alt={game.title}
|
src={game.iconUrl}
|
||||||
/>
|
alt={game.title}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<SteamLogo className={styles.gameIcon} />
|
||||||
|
)}
|
||||||
|
|
||||||
<span className={styles.menuItemButtonLabel}>
|
<span className={styles.menuItemButtonLabel}>
|
||||||
{getGameTitle(game)}
|
{getGameTitle(game)}
|
||||||
</span>
|
</span>
|
||||||
|
@ -105,7 +105,7 @@ export function Downloads() {
|
|||||||
if (GameStatusHelper.isReady(game?.status)) {
|
if (GameStatusHelper.isReady(game?.status)) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p>{game?.repack.title}</p>
|
<p>{game?.repack?.title}</p>
|
||||||
<p>{t("completed")}</p>
|
<p>{t("completed")}</p>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -95,7 +95,7 @@ export interface Game extends Omit<CatalogueEntry, "cover"> {
|
|||||||
folderName: string;
|
folderName: string;
|
||||||
downloadPath: string | null;
|
downloadPath: string | null;
|
||||||
repacks: GameRepack[];
|
repacks: GameRepack[];
|
||||||
repack: GameRepack;
|
repack: GameRepack | null;
|
||||||
progress: number;
|
progress: number;
|
||||||
fileVerificationProgress: number;
|
fileVerificationProgress: number;
|
||||||
decompressionProgress: number;
|
decompressionProgress: number;
|
||||||
@ -137,3 +137,9 @@ export interface Steam250Game {
|
|||||||
title: string;
|
title: string;
|
||||||
objectID: string;
|
objectID: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SteamGame {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
clientIcon: string | null;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user