From bcb2bd94af4d4437a799728673c596cc67a7e558 Mon Sep 17 00:00:00 2001 From: Wyvest Date: Thu, 25 Dec 2025 23:52:37 +0900 Subject: [PATCH] add rate limit check specifically for modrinth --- Cargo.lock | 197 +++++++++++++----- Cargo.toml | 3 +- apps/oneclient/frontend/src/bindings.gen.ts | 34 +-- .../frontend/src/components/DownloadMods.tsx | 2 +- packages/core/Cargo.toml | 1 + packages/core/src/utils/http.rs | 28 ++- packages/core/src/utils/minecraft.rs | 34 ++- 7 files changed, 228 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bd59fa95..e7d9f91c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1214,6 +1214,20 @@ dependencies = [ "syn 2.0.101", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "deflate64" version = "0.1.9" @@ -1685,6 +1699,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.5.0" @@ -1754,9 +1774,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1764,9 +1784,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" @@ -1792,9 +1812,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" @@ -1811,9 +1831,9 @@ dependencies = [ [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -1822,21 +1842,27 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -2018,9 +2044,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -2138,6 +2166,29 @@ dependencies = [ "system-deps", ] +[[package]] +name = "governor" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9efcab3c1958580ff1f25a2a41be1668f7603d849bb63af523b208a3cc1223b8" +dependencies = [ + "cfg-if", + "dashmap", + "futures-sink", + "futures-timer", + "futures-util", + "getrandom 0.3.2", + "hashbrown 0.16.1", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.9.1", + "smallvec", + "spinning_top", + "web-time", +] + [[package]] name = "group" version = "0.13.0" @@ -2243,7 +2294,18 @@ checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", ] [[package]] @@ -2689,10 +2751,11 @@ checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -3127,6 +3190,12 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "normpath" version = "1.3.0" @@ -3526,7 +3595,7 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oneclient_gui" -version = "0.2.0-alpha.2" +version = "1.0.0-alpha.1" dependencies = [ "anyhow", "chrono", @@ -3558,7 +3627,7 @@ dependencies = [ [[package]] name = "onelauncher_core" -version = "0.2.0-alpha.2" +version = "1.0.0-alpha.1" dependencies = [ "anyhow", "async-compression", @@ -3576,6 +3645,7 @@ dependencies = [ "dunce", "futures", "futures-lite", + "governor", "indicatif", "interpulse", "md-5", @@ -3620,7 +3690,7 @@ dependencies = [ [[package]] name = "onelauncher_entity" -version = "0.2.0-alpha.2" +version = "1.0.0-alpha.1" dependencies = [ "chrono", "interpulse", @@ -3636,7 +3706,7 @@ dependencies = [ [[package]] name = "onelauncher_gamemode" -version = "0.2.0-alpha.2" +version = "1.0.0-alpha.1" dependencies = [ "cc", "libc", @@ -3644,7 +3714,7 @@ dependencies = [ [[package]] name = "onelauncher_gui" -version = "0.2.0-alpha.2" +version = "1.0.0-alpha.1" dependencies = [ "anyhow", "chrono", @@ -3675,7 +3745,7 @@ dependencies = [ [[package]] name = "onelauncher_macro" -version = "0.2.0-alpha.2" +version = "1.0.0-alpha.1" dependencies = [ "proc-macro2", "quote", @@ -3684,7 +3754,7 @@ dependencies = [ [[package]] name = "onelauncher_migration" -version = "0.2.0-alpha.2" +version = "1.0.0-alpha.1" dependencies = [ "async-trait", "chrono", @@ -4335,6 +4405,21 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "quanta" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + [[package]] name = "quick-xml" version = "0.32.0" @@ -4532,6 +4617,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "raw-window-handle" version = "0.6.2" @@ -5553,6 +5647,15 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "spki" version = "0.7.3" @@ -7203,27 +7306,14 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.101", "wasm-bindgen-shared", ] @@ -7241,9 +7331,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7251,22 +7341,25 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn 2.0.101", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-streams" @@ -7361,6 +7454,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webkit2gtk" version = "2.0.1" diff --git a/Cargo.toml b/Cargo.toml index ac04216b..1631e3da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ homepage = "https://polyfrost.org/projects/onelauncher" license = "GPL-3.0-only" readme = "README.md" repository = "https://github.com/Polyfrost/OneLauncher" -version = "0.2.0-alpha.2" +version = "1.0.0-alpha.1" [workspace.dependencies] # workspace @@ -131,6 +131,7 @@ async-tempfile = { version = "=0.7.0" } tokio = { version = "1", features = [ "full" ] } tokio-stream = { version = "0.1", features = [ "fs" ] } tokio-util = { version = "0.7", features = [ "compat" ] } +governor = { version = "0.10.4" } # crypto digest = { version = "0.10" } diff --git a/apps/oneclient/frontend/src/bindings.gen.ts b/apps/oneclient/frontend/src/bindings.gen.ts index 7d3cc98e..72d720f8 100644 --- a/apps/oneclient/frontend/src/bindings.gen.ts +++ b/apps/oneclient/frontend/src/bindings.gen.ts @@ -301,20 +301,10 @@ export type VersionType = */ "old_beta" -const ARGS_MAP = { 'debug':'{"getType":[],"openDevTools":[],"getFamily":[],"getOsVersion":[],"getBuildTimestamp":[],"isInDev":[],"getLocale":[],"getPlatform":[],"getPackageVersion":[],"getArch":[],"getGitCommitHash":[]}', 'oneclient':'{"getVersions":[],"getBundlesFor":["cluster_id"],"getClustersGroupedByMajor":[]}', 'events':'{"message":["event"],"ingress":["event"],"process":["event"]}', 'core':'{"getRunningProcesses":[],"searchPackages":["provider","query"],"getMultiplePackages":["provider","slugs"],"isClusterRunning":["cluster_id"],"getPackage":["provider","slug"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"fetchMinecraftProfile":["uuid"],"getGameVersions":[],"readSettings":[],"getWorlds":["id"],"uploadSkinBytes":["access_token","skin_data","image_format","skin_variant"],"setDiscordRPCMessage":["message"],"open":["input"],"getGlobalProfile":[],"getUser":["uuid"],"getPackageBody":["provider","body"],"changeCape":["access_token","cape_uuid"],"removePackage":["cluster_id","package_hash"],"removeCape":["access_token"],"removeCluster":["id"],"getClusterById":["id"],"getLoadersForVersion":["mc_version"],"getUsers":[],"installModpack":["modpack","cluster_id"],"createCluster":["options"],"createSettingsProfile":["name"],"convertUsernameUUID":["username_uuid"],"changeSkin":["access_token","skin_url","skin_variant"],"getLogByName":["id","name"],"killProcess":["pid"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"getProfileOrDefault":["name"],"getRunningProcessesByClusterId":["cluster_id"],"openMsaLogin":[],"getScreenshots":["id"],"getUsersFromAuthor":["provider","author"],"removeUser":["uuid"],"launchCluster":["id","uuid"],"writeSettings":["setting"],"getClusters":[],"downloadExternalPackage":["package","cluster_id","force","skip_compatibility"],"setDefaultUser":["uuid"],"updateClusterById":["id","request"],"getLogs":["id"],"fetchLoggedInProfile":["access_token"],"getLinkedPackages":["cluster_id"],"getDefaultUser":["fallback"],"updateClusterProfile":["name","profile"]}', 'folders':'{"openCluster":["folder_name"],"fromCluster":["folder_name"]}' } -export type Router = { 'debug': { openDevTools: () => Promise, -isInDev: () => Promise, -getArch: () => Promise, -getFamily: () => Promise, -getLocale: () => Promise, -getType: () => Promise, -getPlatform: () => Promise, -getOsVersion: () => Promise, -getGitCommitHash: () => Promise, -getBuildTimestamp: () => Promise, -getPackageVersion: () => Promise }, -'folders': { fromCluster: (folderName: string) => Promise, -openCluster: (folderName: string) => Promise }, +const ARGS_MAP = { 'oneclient':'{"getVersions":[],"getClustersGroupedByMajor":[],"getBundlesFor":["cluster_id"]}', 'core':'{"createSettingsProfile":["name"],"getScreenshots":["id"],"getWorlds":["id"],"removeUser":["uuid"],"getDefaultUser":["fallback"],"isClusterRunning":["cluster_id"],"getMultiplePackages":["provider","slugs"],"getRunningProcesses":[],"getPackage":["provider","slug"],"installModpack":["modpack","cluster_id"],"getLogs":["id"],"getRunningProcessesByClusterId":["cluster_id"],"writeSettings":["setting"],"getUsersFromAuthor":["provider","author"],"fetchMinecraftProfile":["uuid"],"openMsaLogin":[],"removeCape":["access_token"],"getPackageBody":["provider","body"],"uploadSkinBytes":["access_token","skin_data","image_format","skin_variant"],"getLinkedPackages":["cluster_id"],"removePackage":["cluster_id","package_hash"],"getGameVersions":[],"updateClusterById":["id","request"],"getGlobalProfile":[],"createCluster":["options"],"getUsers":[],"removeCluster":["id"],"setDefaultUser":["uuid"],"launchCluster":["id","uuid"],"killProcess":["pid"],"getProfileOrDefault":["name"],"downloadPackage":["provider","package_id","version_id","cluster_id","skip_compatibility"],"changeCape":["access_token","cape_uuid"],"open":["input"],"convertUsernameUUID":["username_uuid"],"setDiscordRPCMessage":["message"],"updateClusterProfile":["name","profile"],"readSettings":[],"getClusters":[],"searchPackages":["provider","query"],"downloadExternalPackage":["package","cluster_id","force","skip_compatibility"],"getPackageVersions":["provider","slug","mc_version","loader","offset","limit"],"fetchLoggedInProfile":["access_token"],"getLogByName":["id","name"],"getClusterById":["id"],"getLoadersForVersion":["mc_version"],"getUser":["uuid"],"changeSkin":["access_token","skin_url","skin_variant"]}', 'folders':'{"fromCluster":["folder_name"],"openCluster":["folder_name"]}', 'events':'{"process":["event"],"ingress":["event"],"message":["event"]}', 'debug':'{"isInDev":[],"getBuildTimestamp":[],"getLocale":[],"openDevTools":[],"getPlatform":[],"getGitCommitHash":[],"getPackageVersion":[],"getFamily":[],"getOsVersion":[],"getArch":[],"getType":[]}' } +export type Router = { 'events': { ingress: (event: IngressPayload) => Promise, +message: (event: MessagePayload) => Promise, +process: (event: ProcessPayload) => Promise }, 'oneclient': { getClustersGroupedByMajor: () => Promise>, getBundlesFor: (clusterId: number) => Promise, getVersions: () => Promise }, @@ -366,9 +356,19 @@ removeCape: (accessToken: string) => Promise, convertUsernameUUID: (usernameUuid: string) => Promise, setDiscordRPCMessage: (message: string) => Promise, open: (input: string) => Promise }, -'events': { ingress: (event: IngressPayload) => Promise, -message: (event: MessagePayload) => Promise, -process: (event: ProcessPayload) => Promise } }; +'debug': { openDevTools: () => Promise, +isInDev: () => Promise, +getArch: () => Promise, +getFamily: () => Promise, +getLocale: () => Promise, +getType: () => Promise, +getPlatform: () => Promise, +getOsVersion: () => Promise, +getGitCommitHash: () => Promise, +getBuildTimestamp: () => Promise, +getPackageVersion: () => Promise }, +'folders': { fromCluster: (folderName: string) => Promise, +openCluster: (folderName: string) => Promise } }; export type { InferCommandOutput } diff --git a/apps/oneclient/frontend/src/components/DownloadMods.tsx b/apps/oneclient/frontend/src/components/DownloadMods.tsx index 8b24b1e8..c65739ac 100644 --- a/apps/oneclient/frontend/src/components/DownloadMods.tsx +++ b/apps/oneclient/frontend/src/components/DownloadMods.tsx @@ -123,7 +123,7 @@ function DownloadingMods({ mods, setOpen, nextPath }: { mods: ModDataArray; setO useEffect(() => { const downloadAll = async () => { if (useParallelModDownloading) - await downloadModsParallel(mods, 4, async (mod) => { + await downloadModsParallel(mods, 10, async (mod) => { setModName(mod.name); try { await download.mutateAsync(mod); diff --git a/packages/core/Cargo.toml b/packages/core/Cargo.toml index 996ecd0b..5b94fa37 100644 --- a/packages/core/Cargo.toml +++ b/packages/core/Cargo.toml @@ -59,6 +59,7 @@ sea-orm = { workspace = true } tokio = { workspace = true } tokio-util = { workspace = true } tokio-stream = { workspace = true } +governor = { workspace = true } futures = { workspace = true } futures-lite = { workspace = true } uuid = { workspace = true } diff --git a/packages/core/src/utils/http.rs b/packages/core/src/utils/http.rs index e38a5412..69f2579a 100644 --- a/packages/core/src/utils/http.rs +++ b/packages/core/src/utils/http.rs @@ -1,11 +1,13 @@ #![allow(clippy::implicit_hasher)] use std::collections::HashMap; +use std::num::NonZeroU32; use std::path::Path; use std::sync::{Arc, LazyLock, Mutex}; use bytes::Bytes; -use reqwest::{Method, RequestBuilder, StatusCode}; +use governor::{Quota, RateLimiter}; +use reqwest::{Method, RequestBuilder}; use serde::de::DeserializeOwned; use tokio::sync::Semaphore; use tokio_stream::StreamExt; @@ -49,6 +51,20 @@ pub(crate) static REQWEST_CLIENT: LazyLock = LazyLock::new(|| { .expect("failed to build reqwest client!") }); +pub(crate) static MODRINTH_RATE_LIMITER: LazyLock< + Arc< + RateLimiter< + governor::state::NotKeyed, + governor::state::InMemoryState, + governor::clock::DefaultClock, + >, + >, +> = LazyLock::new(|| { + Arc::new(RateLimiter::direct(Quota::per_minute( + NonZeroU32::new(300).unwrap(), + ))) +}); + pub(crate) static DOMAIN_SEMAPHORES: LazyLock>>> = LazyLock::new(|| Mutex::new(HashMap::new())); @@ -74,6 +90,11 @@ pub fn build_request(method: Method, url: &str) -> RequestBuilder { pub async fn send_request(request: reqwest::Request) -> LauncherResult { let domain_permit = if let Some(host) = request.url().host_str() { + if host.ends_with("modrinth.com") { + let start = std::time::Instant::now(); + MODRINTH_RATE_LIMITER.until_ready().await; + tracing::debug!("waited {:?} for modrinth rate limiter", start.elapsed()); + } let sem = get_domain_semaphore(host); Some(sem.acquire_owned().await.map_err(|e| anyhow::anyhow!(e))?) } else { @@ -130,6 +151,11 @@ pub async fn fetch_advanced( ) -> LauncherResult { let domain_permit = if let Ok(parsed_url) = reqwest::Url::parse(url) { if let Some(host) = parsed_url.host_str() { + if host.ends_with("modrinth.com") { + let start = std::time::Instant::now(); + MODRINTH_RATE_LIMITER.until_ready().await; + tracing::debug!("waited {:?} for modrinth rate limiter", start.elapsed()); + } let sem = get_domain_semaphore(host); Some(sem.acquire_owned().await.map_err(|e| anyhow::anyhow!(e))?) } else { diff --git a/packages/core/src/utils/minecraft.rs b/packages/core/src/utils/minecraft.rs index 7bfb27e1..3b02d48c 100644 --- a/packages/core/src/utils/minecraft.rs +++ b/packages/core/src/utils/minecraft.rs @@ -144,8 +144,18 @@ pub async fn fetch_player_profile(uuid: &str) -> LauncherResult( + let mut profile = http::fetch_json_advanced::( Method::GET, "https://api.minecraftservices.com/minecraft/profile", None, @@ -165,7 +175,23 @@ pub async fn fetch_logged_in_profile( None, None, ) - .await + .await?; + + for skin in &mut profile.skins { + skin.url = skin.url.replace( + "http://textures.minecraft.net", + "https://textures.minecraft.net", + ); + } + + for cape in &mut profile.capes { + cape.url = cape.url.replace( + "http://textures.minecraft.net", + "https://textures.minecraft.net", + ); + } + + Ok(profile) } pub async fn upload_skin_bytes(