mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-09 11:42:21 +03:00
Merge branch 'main' of https://github.com/fhilipecrash/hydra
This commit is contained in:
commit
2db68ccd18
5
.github/workflows/build.yml
vendored
5
.github/workflows/build.yml
vendored
@ -10,7 +10,7 @@ jobs:
|
|||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [windows-latest, ubuntu-latest]
|
os: [windows-latest]
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Check out Git repository
|
- name: Check out Git repository
|
||||||
@ -40,6 +40,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Publish
|
- name: Publish
|
||||||
run: yarn run publish
|
run: yarn run publish
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
STEAMGRIDDB_API_KEY: ${{ env.STEAMGRIDDB_API_KEY }}
|
||||||
|
|
||||||
- name: Create artifact
|
- name: Create artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
22
README.md
22
README.md
@ -1,5 +1,7 @@
|
|||||||
# Hydra
|
# Hydra
|
||||||
|
|
||||||
|
<a href="https://discord.gg/hydralauncher" target="_blank">![Discord](https://img.shields.io/discord/1220692017311645737?style=flat&logo=discord&label=Hydra&labelColor=%231c1c1c)</a>
|
||||||
|
|
||||||
Hydra is a game launcher with its own embedded bittorrent client and a self-managed repack scraper.
|
Hydra is a game launcher with its own embedded bittorrent client and a self-managed repack scraper.
|
||||||
The launcher is written in TypeScript (Electron) and Python, which handles the torrenting system by using [libtorrent](https://www.libtorrent.org/).
|
The launcher is written in TypeScript (Electron) and Python, which handles the torrenting system by using [libtorrent](https://www.libtorrent.org/).
|
||||||
|
|
||||||
@ -9,11 +11,11 @@ The launcher is written in TypeScript (Electron) and Python, which handles the t
|
|||||||
|
|
||||||
### Install Node.js
|
### Install Node.js
|
||||||
|
|
||||||
Ensure you have Node.js installed on your machine. If not, download and install it from [nodejs.org](nodejs.org).
|
Ensure you have Node.js installed on your machine. If not, download and install it from [nodejs.org](https://nodejs.org/).
|
||||||
|
|
||||||
### Install Yarn
|
### Install Yarn
|
||||||
|
|
||||||
Yarn is a package manager for Node.js. If you haven't installed Yarn yet, you can do so by following the instructions on [yarnpkg.com](yarnpkg.com).
|
Yarn is a package manager for Node.js. If you haven't installed Yarn yet, you can do so by following the instructions on [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/).
|
||||||
|
|
||||||
### Clone the Repository
|
### Clone the Repository
|
||||||
|
|
||||||
@ -32,7 +34,7 @@ yarn
|
|||||||
|
|
||||||
### Install Python 3.9
|
### Install Python 3.9
|
||||||
|
|
||||||
Ensure you have Python installed on your machine. You can download and install it from [python.org](python.org).
|
Ensure you have Python installed on your machine. You can download and install it from [python.org](https://www.python.org/downloads/release/python-3919/).
|
||||||
|
|
||||||
### Install Python Dependencies
|
### Install Python Dependencies
|
||||||
|
|
||||||
@ -49,7 +51,11 @@ Once you have it, you can paste the `.env.example` file and put it on `STEAMGRID
|
|||||||
|
|
||||||
## Running
|
## Running
|
||||||
|
|
||||||
Once you've installed all dependencies, you can build and run Hydra Download Manager. Here are the basic commands:
|
Once you've got all things set up, you can run the following command to start both the Electron process and the bittorrent client:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn start
|
||||||
|
```
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
@ -69,6 +75,14 @@ Build the Electron application by using this command:
|
|||||||
yarn make
|
yarn make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
<a href="https://github.com/hydralauncher/hydra/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=hydralauncher/hydra" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
Made with [contrib.rocks](https://contrib.rocks).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Hydra is licensed under the [MIT License](LICENSE).
|
Hydra is licensed under the [MIT License](LICENSE).
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import { formatName, getSteamAppAsset, repackerFormatter } from "@main/helpers";
|
import { formatName, repackerFormatter } from "@main/helpers";
|
||||||
import { getTrendingGames } from "@main/services";
|
import { getTrendingGames } from "@main/services";
|
||||||
import type { CatalogueCategory, CatalogueEntry, GameShop } from "@types";
|
import type { CatalogueCategory, CatalogueEntry } from "@types";
|
||||||
|
|
||||||
import { stateManager } from "@main/state-manager";
|
import { stateManager } from "@main/state-manager";
|
||||||
import { searchGames, searchRepacks } from "../helpers/search-games";
|
import { searchGames } from "../helpers/search-games";
|
||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
|
|
||||||
const repacks = stateManager.getValue("repacks");
|
const repacks = stateManager.getValue("repacks");
|
||||||
@ -12,7 +12,14 @@ const getCatalogue = async (
|
|||||||
_event: Electron.IpcMainInvokeEvent,
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
category: CatalogueCategory
|
category: CatalogueCategory
|
||||||
) => {
|
) => {
|
||||||
|
const trendingGames = await getTrendingGames();
|
||||||
|
|
||||||
|
let i = 0;
|
||||||
|
const results: CatalogueEntry[] = [];
|
||||||
|
|
||||||
const getStringForLookup = (index: number) => {
|
const getStringForLookup = (index: number) => {
|
||||||
|
if (category === "trending") return trendingGames[index];
|
||||||
|
|
||||||
const repack = repacks[index];
|
const repack = repacks[index];
|
||||||
const formatter =
|
const formatter =
|
||||||
repackerFormatter[repack.repacker as keyof typeof repackerFormatter];
|
repackerFormatter[repack.repacker as keyof typeof repackerFormatter];
|
||||||
@ -23,56 +30,10 @@ const getCatalogue = async (
|
|||||||
if (!repacks.length) return [];
|
if (!repacks.length) return [];
|
||||||
|
|
||||||
const resultSize = 12;
|
const resultSize = 12;
|
||||||
const requestSize = resultSize;
|
const requestSize = resultSize * 2;
|
||||||
|
|
||||||
if (category === "trending") {
|
|
||||||
return searchTrending(resultSize);
|
|
||||||
} else {
|
|
||||||
return searchRecentlyAdded(resultSize, requestSize, getStringForLookup);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const searchTrending = async (
|
|
||||||
resultSize: number
|
|
||||||
): Promise<CatalogueEntry[]> => {
|
|
||||||
const results: CatalogueEntry[] = [];
|
|
||||||
const trendingGames = await getTrendingGames();
|
|
||||||
for (
|
|
||||||
let i = 0;
|
|
||||||
i < trendingGames.length && results.length < resultSize;
|
|
||||||
i++
|
|
||||||
) {
|
|
||||||
if (!trendingGames[i]) continue;
|
|
||||||
|
|
||||||
const { title, objectID } = trendingGames[i];
|
|
||||||
const repacks = searchRepacks(title);
|
|
||||||
|
|
||||||
if (title && repacks.length) {
|
|
||||||
const catalogueEntry = {
|
|
||||||
objectID,
|
|
||||||
title,
|
|
||||||
shop: "steam" as GameShop,
|
|
||||||
cover: getSteamAppAsset("library", objectID),
|
|
||||||
};
|
|
||||||
repacks.sort(
|
|
||||||
(a, b) =>
|
|
||||||
new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime()
|
|
||||||
);
|
|
||||||
results.push({ ...catalogueEntry, repacks });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
};
|
|
||||||
|
|
||||||
const searchRecentlyAdded = async (
|
|
||||||
resultSize: number,
|
|
||||||
requestSize: number,
|
|
||||||
getStringForLookup: { (index: number): any; (arg0: any): any }
|
|
||||||
): Promise<CatalogueEntry[]> => {
|
|
||||||
let lookupRequest = [];
|
let lookupRequest = [];
|
||||||
const results: CatalogueEntry[] = [];
|
|
||||||
|
|
||||||
for (let i = 0; results.length < resultSize; i++) {
|
while (results.length < resultSize) {
|
||||||
const stringForLookup = getStringForLookup(i);
|
const stringForLookup = getStringForLookup(i);
|
||||||
|
|
||||||
if (!stringForLookup) {
|
if (!stringForLookup) {
|
||||||
@ -82,6 +43,8 @@ const searchRecentlyAdded = async (
|
|||||||
|
|
||||||
lookupRequest.push(searchGames(stringForLookup));
|
lookupRequest.push(searchGames(stringForLookup));
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
if (lookupRequest.length < requestSize) {
|
if (lookupRequest.length < requestSize) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,7 @@ export const getTrendingGames = async () => {
|
|||||||
const { document } = window;
|
const { document } = window;
|
||||||
|
|
||||||
return Array.from(document.querySelectorAll(".appline .title a")).map(
|
return Array.from(document.querySelectorAll(".appline .title a")).map(
|
||||||
($title: HTMLAnchorElement) => {
|
($title) => $title.textContent!
|
||||||
const steamGameUrld = $title.href;
|
|
||||||
if (!steamGameUrld) return null;
|
|
||||||
return {
|
|
||||||
title: $title.textContent,
|
|
||||||
objectID: steamGameUrld.split("/").pop(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user