-
Notifications
You must be signed in to change notification settings - Fork 75
Shared modpacks routing #815
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- make the routes internal also
updated timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
created timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
|
||
maximum_users integer NOT NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's this field for?
|
||
CREATE TABLE shared_profiles_links ( | ||
id bigint PRIMARY KEY, -- id of the shared profile link (ignored in labrinth, for db use only) | ||
link varchar(48) NOT NULL UNIQUE, -- extension of the url that identifies this (ie profiles/afgxxczsewq) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just make it based on the ID? Like discord's invites, it could be like: https://modrinth/invite/AAdwaDWD
maximum_users integer NOT NULL, | ||
|
||
loader_id int NOT NULL REFERENCES loaders(id), | ||
loader_version varchar(255) NOT NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be better for these to not be columns and rather their own column with strings as the id. So it would be like a jsonb metadata column like `{ "game_version": "1.19.2", "loader_version": "47.1.2" } (same with game versions) as games and loader versions can be specific to Minecraft
#[derive(Clone, Debug, Serialize, Deserialize)] | ||
pub enum ClientProfileGame { | ||
Minecraft { | ||
game_id: GameId, | ||
game_name: String, | ||
game_version_id: LoaderFieldEnumValueId, | ||
game_version: String, | ||
}, | ||
Unknown { | ||
game_id: GameId, | ||
game_name: String, | ||
}, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need an enum here? Since we already have games dynamically in the database. Couldn't we just add a jsonb metadata field with game metadata (and then remove game_id and game_name fields
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatively we could build this in with the loader fields system... but I don't think it's the best idea bc stuff like loader versions aren't on labrinth
metadata jsonb NOT NULL DEFAULT '{}'::jsonb, | ||
|
||
game_id int NOT NULL REFERENCES games(id), | ||
game_version_id int NULL REFERENCES loader_field_enum_values(id) -- Minecraft java |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why does this exist if the game version is also in the metadata?
src/models/v3/client/profile.rs
Outdated
#[derive(Serialize, Deserialize, Clone)] | ||
pub struct ClientProfileShareLink { | ||
pub id: ClientProfileLinkId, // The url identifier, encoded as base62 | ||
pub url: String, // Includes the url identifier, intentionally redundant | ||
pub profile_id: ClientProfileId, | ||
pub created: DateTime<Utc>, | ||
pub expires: DateTime<Utc>, | ||
} | ||
|
||
impl From<database::models::client_profile_item::ClientProfileLink> for ClientProfileShareLink { | ||
fn from(link: database::models::client_profile_item::ClientProfileLink) -> Self { | ||
// Generate URL for easy access | ||
let profile_id: ClientProfileId = link.shared_profile_id.into(); | ||
let link_id: ClientProfileLinkId = link.id.into(); | ||
let url = format!( | ||
"{}/v3/client/profile/{}/accept/{}", | ||
dotenvy::var("SELF_ADDR").unwrap(), | ||
profile_id, | ||
link_id | ||
); | ||
|
||
Self { | ||
id: link_id, | ||
url, | ||
profile_id, | ||
created: link.created, | ||
expires: link.expires, | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The URL shouldn't be returned / parsed here. The frontend will generate it based on the link ID
src/models/v3/client/profile.rs
Outdated
/// Modrinth-associated versions | ||
pub versions: Vec<VersionId>, | ||
/// Overrides for this profile- only install paths are given, | ||
/// hashes are looked up in the CDN by the client | ||
pub override_install_paths: Vec<PathBuf>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this mean? IMO we shouldn't have the versions or any install info be returned here. It should be a separate route that is only called when the pack is being installed. And it can only be accessed once a user has accepted the invite.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Im not sure I agree- I think it could be useful to be able to see the stuff youre going to install on your computer before accepting, or what's 'in/on' the shared modpack, like in the frontend as a snippet of what you're getting in the pack.
All this displays is what the versions are and the 'names' of the overrides. do you think its not worth returning this?
// Delete a client profile | ||
pub async fn profile_delete( | ||
req: HttpRequest, | ||
info: web::Path<(String,)>, | ||
pool: web::Data<PgPool>, | ||
redis: web::Data<RedisPool>, | ||
session_queue: web::Data<AuthQueue>, | ||
) -> Result<HttpResponse, ApiError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should delete override files from the CDN as long as they are unused by other shared packs
version_id bigint NULL REFERENCES versions(id), -- for versions | ||
|
||
-- for cdn links to files we host directly | ||
file_hash varchar(255) NULL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should restructure this. Override files should be a separate table which this table refers too IMO. And then it should refer to this here (we could just re-use the files table TBH).
Like other API objects, this would allow us to have SHA1 and SHA512 hashes. Shared modpacks will also share files a ton (ex: if someone has the same exact config file between packs, we shouldn't haave to host it twice or have duplicate database entries)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think just using the files table would probably work well enough. It would also allow it so if someone did ever upload their mod to Modrinth, we could "re-link" it to the project dynamically and change it from an override to a Modrinth version ID. If that makes sense
"{id}/override", | ||
web::delete().to(client_profile_remove_overrides), | ||
) | ||
.route("{id}/share", web::get().to(profile_share)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO this route is kind of pointless. We should just return share links in the main profile body. When would you get a profile and not get its share links?
.route( | ||
"{id}/share/{url_identifier}", | ||
web::get().to(profile_link_get), | ||
) | ||
.route( | ||
"{id}/accept/{url_identifier}", | ||
web::post().to(accept_share_link), | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These routes are structured wrong. A share link would be like https://modrinth.com/share/aaJJJwwa. You won't know the profile ID. There should be a route to just get a profile from share link and accept a share link
NOTE: DO NOT MERGE until changes noted in the migrations file are reverted.
Fixes MOD-576
Notable deviations from spec:
modrinth://
link as we move from testing this with cloudflare to having the theseus implementation.