mirror of
https://github.com/modrinth/code.git
synced 2026-08-27 18:14:49 +00:00
feat: instances v2 (#6431)
* feat: base of instances v2 * feat: use old profiles with compat layer * prototype: instances v2 * fix: install_from using profile * fix: skins migration fix * fix: frontend still using profile path * fix: add update proj multiselect guard * fix: cargo fmt * fix: content missing fields * feat: break up app-lib/api/instance.rs * fix: check_content_updates mismatch * fix: updater modal cleanup w/new structure * feat: better update all handling * fix: remove preview_update_all * fix: feedback on bulk update + lint * fix: rem transitions * fix: change to jsonb * feat: app db backup after update * fix: lint * fix: sqlx prepare + use sqlx macros * fix: lint * fix: bugs * feat: defuck the installing process up * fix: bug of hell * fix: shear * fix: fmt * fix: install progress spacing + change mc/content/overrides to bytes * fix: lint * fix: prepr * fix: navtabs anim not working in app * fix: worlds.vue improvements + browse page fixes * feat: optimise queries + adapter fns * fix: lint * fix: lint * feat: shared modrinth-content-management crate (#6469) * feat: disable warnings setting * feat: add instances shortcuts (#6329) * Add modrinth://launch deep link to start a profile Support external profile launching via modrinth://launch/{profile_path} for integrations such as Stream Deck. * Change route to /launch/profile/{id} for future extensibility * fix: ensure profile path is url decoded * fix: URL-decode profile path from deep link * fix: use urlencoding crate for URL decoding * feat: implement app instance shortcuts * feat: change windows shortcut creation to use windows api instead * feat: implement creating a shortcut launching world/server * format * fmt * fix multiline inline tables * pnpm prepr * feat: move create shortcut to last item * refactor: split up shortcuts.rs for individual platforms * refactor: turn profile launch url into url type * use string literal and add safety comment * pt2 * refactor: rename anything that's profile into instance * update mac shortcut --------- Co-authored-by: DJCheesusReal <134006619+DJCheesusReal@users.noreply.github.com> --------- Co-authored-by: Truman Gao <106889354+tdgao@users.noreply.github.com> Co-authored-by: DJCheesusReal <134006619+DJCheesusReal@users.noreply.github.com>
This commit is contained in:
co-authored by
DJCheesusReal
Truman Gao
parent
ef4044534f
commit
734720e11e
@@ -0,0 +1,3 @@
|
||||
DROP TRIGGER IF EXISTS default_minecraft_capes_user_uuid_insert_check;
|
||||
DROP TRIGGER IF EXISTS default_minecraft_capes_user_uuid_update_check;
|
||||
DROP TRIGGER IF EXISTS default_minecraft_capes_user_uuid_update_cascade;
|
||||
@@ -0,0 +1,376 @@
|
||||
CREATE TABLE instances (
|
||||
id TEXT NOT NULL,
|
||||
path TEXT NOT NULL,
|
||||
applied_content_set_id TEXT NULL,
|
||||
|
||||
install_stage TEXT NOT NULL,
|
||||
launcher_feature_version TEXT NOT NULL,
|
||||
update_channel TEXT NOT NULL DEFAULT 'release',
|
||||
|
||||
name TEXT NOT NULL,
|
||||
icon_path TEXT NULL,
|
||||
|
||||
created INTEGER NOT NULL,
|
||||
modified INTEGER NOT NULL,
|
||||
last_played INTEGER NULL,
|
||||
|
||||
submitted_time_played INTEGER NOT NULL DEFAULT 0,
|
||||
recent_time_played INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE (path)
|
||||
);
|
||||
|
||||
CREATE INDEX instances_path ON instances(path);
|
||||
CREATE INDEX instances_applied_content_set_id
|
||||
ON instances(applied_content_set_id);
|
||||
|
||||
CREATE TABLE instance_links (
|
||||
instance_id TEXT NOT NULL,
|
||||
link_kind TEXT NOT NULL,
|
||||
|
||||
modrinth_project_id TEXT NULL,
|
||||
modrinth_version_id TEXT NULL,
|
||||
|
||||
server_project_id TEXT NULL,
|
||||
|
||||
content_project_id TEXT NULL,
|
||||
content_version_id TEXT NULL,
|
||||
|
||||
hosting_server_id TEXT NULL,
|
||||
hosting_instance_ids JSONB NULL,
|
||||
hosting_active_instance_id TEXT NULL,
|
||||
|
||||
shared_instance_id TEXT NULL,
|
||||
|
||||
PRIMARY KEY (instance_id),
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX instance_links_link_kind ON instance_links(link_kind);
|
||||
CREATE INDEX instance_links_modrinth_project_id
|
||||
ON instance_links(modrinth_project_id);
|
||||
CREATE INDEX instance_links_server_project_id
|
||||
ON instance_links(server_project_id);
|
||||
CREATE INDEX instance_links_hosting_server_id
|
||||
ON instance_links(hosting_server_id);
|
||||
CREATE INDEX instance_links_hosting_active_instance_id
|
||||
ON instance_links(hosting_active_instance_id);
|
||||
CREATE INDEX instance_links_shared_instance_id
|
||||
ON instance_links(shared_instance_id);
|
||||
|
||||
CREATE TABLE instance_groups (
|
||||
instance_id TEXT NOT NULL,
|
||||
group_name TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (instance_id, group_name),
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX instance_groups_group_name ON instance_groups(group_name);
|
||||
|
||||
CREATE TABLE instance_launch_overrides (
|
||||
instance_id TEXT NOT NULL,
|
||||
overrides JSONB NOT NULL,
|
||||
|
||||
PRIMARY KEY (instance_id),
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE instance_content_sets (
|
||||
id TEXT NOT NULL,
|
||||
instance_id TEXT NOT NULL,
|
||||
|
||||
name TEXT NOT NULL,
|
||||
source_kind TEXT NOT NULL,
|
||||
status TEXT NOT NULL,
|
||||
|
||||
game_version TEXT NOT NULL,
|
||||
protocol_version INTEGER NULL,
|
||||
loader TEXT NOT NULL,
|
||||
loader_version TEXT NULL,
|
||||
|
||||
created INTEGER NOT NULL,
|
||||
modified INTEGER NOT NULL,
|
||||
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX instance_content_sets_instance_id
|
||||
ON instance_content_sets(instance_id);
|
||||
|
||||
CREATE TABLE instance_content_set_remote_refs (
|
||||
content_set_id TEXT NOT NULL,
|
||||
ref_type TEXT NOT NULL,
|
||||
ref_id TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (content_set_id, ref_type),
|
||||
FOREIGN KEY (content_set_id)
|
||||
REFERENCES instance_content_sets(id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX instance_content_set_remote_refs_ref
|
||||
ON instance_content_set_remote_refs(ref_type, ref_id);
|
||||
|
||||
CREATE TABLE instance_content_set_sync_state (
|
||||
content_set_id TEXT NOT NULL,
|
||||
provider TEXT NOT NULL,
|
||||
|
||||
applied_update_id TEXT NULL,
|
||||
latest_available_update_id TEXT NULL,
|
||||
checked_at INTEGER NULL,
|
||||
status TEXT NOT NULL,
|
||||
|
||||
PRIMARY KEY (content_set_id),
|
||||
FOREIGN KEY (content_set_id)
|
||||
REFERENCES instance_content_sets(id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX instance_content_set_sync_state_provider
|
||||
ON instance_content_set_sync_state(provider);
|
||||
|
||||
CREATE INDEX instance_content_set_sync_state_latest_available_update_id
|
||||
ON instance_content_set_sync_state(latest_available_update_id);
|
||||
|
||||
CREATE TABLE instance_files (
|
||||
id TEXT NOT NULL,
|
||||
instance_id TEXT NOT NULL,
|
||||
|
||||
relative_path TEXT NOT NULL,
|
||||
file_name TEXT NOT NULL,
|
||||
enabled INTEGER NOT NULL,
|
||||
|
||||
sha1 TEXT NOT NULL,
|
||||
size INTEGER NOT NULL,
|
||||
missing INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
added_at INTEGER NOT NULL,
|
||||
modified_at INTEGER NOT NULL,
|
||||
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE (instance_id, relative_path),
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX instance_files_instance_id ON instance_files(instance_id);
|
||||
CREATE INDEX instance_files_sha1 ON instance_files(sha1);
|
||||
CREATE INDEX instance_files_missing ON instance_files(missing);
|
||||
|
||||
CREATE TABLE instance_content_entries (
|
||||
id TEXT NOT NULL,
|
||||
instance_id TEXT NOT NULL,
|
||||
content_set_id TEXT NOT NULL,
|
||||
file_id TEXT NULL,
|
||||
|
||||
project_type TEXT NOT NULL,
|
||||
project_id TEXT NULL,
|
||||
version_id TEXT NULL,
|
||||
|
||||
source_kind TEXT NOT NULL,
|
||||
server_requirement TEXT NOT NULL,
|
||||
client_requirement TEXT NOT NULL,
|
||||
enabled INTEGER NOT NULL DEFAULT 1,
|
||||
|
||||
added_at INTEGER NOT NULL,
|
||||
modified_at INTEGER NOT NULL,
|
||||
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (content_set_id)
|
||||
REFERENCES instance_content_sets(id)
|
||||
ON DELETE CASCADE,
|
||||
FOREIGN KEY (file_id) REFERENCES instance_files(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX instance_content_entries_instance_id
|
||||
ON instance_content_entries(instance_id);
|
||||
CREATE INDEX instance_content_entries_content_set_id
|
||||
ON instance_content_entries(content_set_id);
|
||||
CREATE INDEX instance_content_entries_file_id
|
||||
ON instance_content_entries(file_id);
|
||||
CREATE INDEX instance_content_entries_project_id
|
||||
ON instance_content_entries(project_id);
|
||||
CREATE INDEX instance_content_entries_version_id
|
||||
ON instance_content_entries(version_id);
|
||||
CREATE INDEX instance_content_entries_source_kind
|
||||
ON instance_content_entries(source_kind);
|
||||
|
||||
CREATE TABLE instance_content_update_checks (
|
||||
content_entry_id TEXT NOT NULL,
|
||||
|
||||
update_channel TEXT NOT NULL,
|
||||
update_version_id TEXT NULL,
|
||||
checked_at INTEGER NOT NULL,
|
||||
|
||||
PRIMARY KEY (content_entry_id),
|
||||
FOREIGN KEY (content_entry_id)
|
||||
REFERENCES instance_content_entries(id)
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX instance_content_update_checks_update_version_id
|
||||
ON instance_content_update_checks(update_version_id);
|
||||
|
||||
INSERT INTO instances (
|
||||
id,
|
||||
path,
|
||||
applied_content_set_id,
|
||||
install_stage,
|
||||
launcher_feature_version,
|
||||
update_channel,
|
||||
name,
|
||||
icon_path,
|
||||
created,
|
||||
modified,
|
||||
last_played,
|
||||
submitted_time_played,
|
||||
recent_time_played
|
||||
)
|
||||
SELECT
|
||||
'legacy:' || path,
|
||||
path,
|
||||
'legacy:' || path || ':default',
|
||||
install_stage,
|
||||
launcher_feature_version,
|
||||
preferred_update_channel,
|
||||
name,
|
||||
icon_path,
|
||||
created,
|
||||
modified,
|
||||
last_played,
|
||||
submitted_time_played,
|
||||
recent_time_played
|
||||
FROM profiles;
|
||||
|
||||
INSERT INTO instance_content_sets (
|
||||
id,
|
||||
instance_id,
|
||||
name,
|
||||
source_kind,
|
||||
status,
|
||||
game_version,
|
||||
protocol_version,
|
||||
loader,
|
||||
loader_version,
|
||||
created,
|
||||
modified
|
||||
)
|
||||
SELECT
|
||||
'legacy:' || path || ':default',
|
||||
'legacy:' || path,
|
||||
'Default',
|
||||
CASE
|
||||
WHEN linked_project_id IS NOT NULL
|
||||
AND linked_version_id IS NOT NULL
|
||||
AND linked_version_id != ''
|
||||
THEN 'modrinth_modpack'
|
||||
WHEN linked_project_id IS NOT NULL
|
||||
AND (linked_version_id IS NULL OR linked_version_id = '')
|
||||
THEN 'server_project'
|
||||
ELSE 'local'
|
||||
END,
|
||||
'available',
|
||||
game_version,
|
||||
protocol_version,
|
||||
mod_loader,
|
||||
mod_loader_version,
|
||||
created,
|
||||
modified
|
||||
FROM profiles;
|
||||
|
||||
INSERT INTO instance_links (
|
||||
instance_id,
|
||||
link_kind,
|
||||
modrinth_project_id,
|
||||
modrinth_version_id,
|
||||
server_project_id,
|
||||
content_project_id,
|
||||
content_version_id,
|
||||
hosting_server_id,
|
||||
hosting_instance_ids,
|
||||
hosting_active_instance_id,
|
||||
shared_instance_id
|
||||
)
|
||||
SELECT
|
||||
'legacy:' || path,
|
||||
CASE
|
||||
WHEN linked_project_id IS NULL
|
||||
THEN 'unmanaged'
|
||||
WHEN linked_version_id IS NULL OR linked_version_id = ''
|
||||
THEN 'server_project'
|
||||
ELSE 'modrinth_modpack'
|
||||
END,
|
||||
CASE
|
||||
WHEN linked_version_id IS NOT NULL AND linked_version_id != ''
|
||||
THEN linked_project_id
|
||||
ELSE NULL
|
||||
END,
|
||||
CASE
|
||||
WHEN linked_version_id IS NOT NULL AND linked_version_id != ''
|
||||
THEN linked_version_id
|
||||
ELSE NULL
|
||||
END,
|
||||
CASE
|
||||
WHEN linked_project_id IS NOT NULL
|
||||
AND (linked_version_id IS NULL OR linked_version_id = '')
|
||||
THEN linked_project_id
|
||||
ELSE NULL
|
||||
END,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
FROM profiles;
|
||||
|
||||
INSERT OR IGNORE INTO instance_groups (instance_id, group_name)
|
||||
SELECT
|
||||
'legacy:' || profiles.path,
|
||||
json_each.value
|
||||
FROM profiles, json_each(profiles.groups);
|
||||
|
||||
INSERT INTO instance_launch_overrides (
|
||||
instance_id,
|
||||
overrides
|
||||
)
|
||||
SELECT
|
||||
'legacy:' || path,
|
||||
jsonb(json_object(
|
||||
'java_path', override_java_path,
|
||||
'extra_launch_args', json(CASE
|
||||
WHEN json_type(override_extra_launch_args) = 'null' THEN 'null'
|
||||
ELSE json(override_extra_launch_args)
|
||||
END),
|
||||
'custom_env_vars', json(CASE
|
||||
WHEN json_type(override_custom_env_vars) = 'null' THEN 'null'
|
||||
ELSE json(override_custom_env_vars)
|
||||
END),
|
||||
'memory', json(CASE
|
||||
WHEN override_mc_memory_max IS NULL THEN 'null'
|
||||
ELSE json_object('maximum', override_mc_memory_max)
|
||||
END),
|
||||
'force_fullscreen', json(CASE
|
||||
WHEN override_mc_force_fullscreen IS NULL THEN 'null'
|
||||
WHEN override_mc_force_fullscreen = 0 THEN 'false'
|
||||
ELSE 'true'
|
||||
END),
|
||||
'game_resolution', json(CASE
|
||||
WHEN override_mc_game_resolution_x IS NULL
|
||||
OR override_mc_game_resolution_y IS NULL
|
||||
THEN 'null'
|
||||
ELSE json_array(
|
||||
override_mc_game_resolution_x,
|
||||
override_mc_game_resolution_y
|
||||
)
|
||||
END),
|
||||
'hooks', json_object(
|
||||
'pre_launch', COALESCE(override_hook_pre_launch, ''),
|
||||
'wrapper', COALESCE(override_hook_wrapper, ''),
|
||||
'post_exit', COALESCE(override_hook_post_exit, '')
|
||||
)
|
||||
))
|
||||
FROM profiles;
|
||||
@@ -0,0 +1,129 @@
|
||||
CREATE TEMP TABLE finish_instance_profile_migration_validation (
|
||||
error_count INTEGER NOT NULL CHECK (error_count = 0)
|
||||
);
|
||||
|
||||
INSERT INTO finish_instance_profile_migration_validation (error_count)
|
||||
SELECT COUNT(*)
|
||||
FROM profiles
|
||||
LEFT JOIN instances ON instances.path = profiles.path
|
||||
WHERE instances.id IS NULL;
|
||||
|
||||
INSERT INTO finish_instance_profile_migration_validation (error_count)
|
||||
SELECT COUNT(*)
|
||||
FROM instances
|
||||
LEFT JOIN instance_content_sets
|
||||
ON instance_content_sets.id = instances.applied_content_set_id
|
||||
AND instance_content_sets.instance_id = instances.id
|
||||
WHERE instances.applied_content_set_id IS NULL
|
||||
OR instance_content_sets.id IS NULL;
|
||||
|
||||
DROP TABLE finish_instance_profile_migration_validation;
|
||||
|
||||
DROP INDEX processes_profile_path;
|
||||
ALTER TABLE processes RENAME TO processes_old;
|
||||
|
||||
CREATE TABLE processes (
|
||||
pid INTEGER NOT NULL,
|
||||
start_time INTEGER NOT NULL,
|
||||
name TEXT NOT NULL,
|
||||
executable TEXT NOT NULL,
|
||||
instance_id TEXT NOT NULL,
|
||||
post_exit_command TEXT NULL,
|
||||
|
||||
UNIQUE (pid),
|
||||
PRIMARY KEY (pid),
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
INSERT INTO processes (
|
||||
pid,
|
||||
start_time,
|
||||
name,
|
||||
executable,
|
||||
instance_id,
|
||||
post_exit_command
|
||||
)
|
||||
SELECT
|
||||
processes_old.pid,
|
||||
processes_old.start_time,
|
||||
processes_old.name,
|
||||
processes_old.executable,
|
||||
instances.id,
|
||||
processes_old.post_exit_command
|
||||
FROM processes_old
|
||||
JOIN instances ON instances.path = processes_old.profile_path;
|
||||
|
||||
DROP TABLE processes_old;
|
||||
|
||||
CREATE INDEX processes_instance_id ON processes(instance_id);
|
||||
|
||||
DROP INDEX join_log_profile_path;
|
||||
ALTER TABLE join_log RENAME TO join_log_old;
|
||||
|
||||
CREATE TABLE join_log (
|
||||
instance_id TEXT NOT NULL,
|
||||
host TEXT NOT NULL,
|
||||
port INTEGER NOT NULL,
|
||||
join_time INTEGER NOT NULL,
|
||||
|
||||
PRIMARY KEY (instance_id, host, port),
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
INSERT INTO join_log (
|
||||
instance_id,
|
||||
host,
|
||||
port,
|
||||
join_time
|
||||
)
|
||||
SELECT
|
||||
instances.id,
|
||||
join_log_old.host,
|
||||
join_log_old.port,
|
||||
join_log_old.join_time
|
||||
FROM join_log_old
|
||||
JOIN instances ON instances.path = join_log_old.profile_path;
|
||||
|
||||
DROP TABLE join_log_old;
|
||||
|
||||
CREATE INDEX join_log_instance_id ON join_log(instance_id);
|
||||
|
||||
DROP INDEX attached_world_data_profile_path;
|
||||
ALTER TABLE attached_world_data RENAME TO attached_world_data_old;
|
||||
|
||||
CREATE TABLE attached_world_data (
|
||||
instance_id TEXT NOT NULL,
|
||||
world_type TEXT CHECK ( world_type in ('singleplayer', 'server') ) NOT NULL,
|
||||
world_id TEXT NOT NULL,
|
||||
display_status TEXT NOT NULL DEFAULT 'normal',
|
||||
project_id TEXT NULL,
|
||||
content_kind TEXT NULL,
|
||||
|
||||
PRIMARY KEY (instance_id, world_type, world_id),
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
INSERT INTO attached_world_data (
|
||||
instance_id,
|
||||
world_type,
|
||||
world_id,
|
||||
display_status,
|
||||
project_id,
|
||||
content_kind
|
||||
)
|
||||
SELECT
|
||||
instances.id,
|
||||
attached_world_data_old.world_type,
|
||||
attached_world_data_old.world_id,
|
||||
attached_world_data_old.display_status,
|
||||
attached_world_data_old.project_id,
|
||||
attached_world_data_old.content_kind
|
||||
FROM attached_world_data_old
|
||||
JOIN instances ON instances.path = attached_world_data_old.profile_path;
|
||||
|
||||
DROP TABLE attached_world_data_old;
|
||||
|
||||
CREATE INDEX attached_world_data_instance_id
|
||||
ON attached_world_data(instance_id);
|
||||
|
||||
DROP TABLE profiles;
|
||||
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE app_metadata (
|
||||
key TEXT NOT NULL,
|
||||
value TEXT NOT NULL,
|
||||
updated_at INTEGER NOT NULL DEFAULT (unixepoch()),
|
||||
|
||||
PRIMARY KEY (key)
|
||||
);
|
||||
@@ -0,0 +1,19 @@
|
||||
CREATE TABLE install_jobs (
|
||||
id TEXT NOT NULL PRIMARY KEY,
|
||||
instance_id TEXT NULL,
|
||||
kind TEXT NOT NULL,
|
||||
|
||||
status TEXT NOT NULL,
|
||||
state JSONB NOT NULL,
|
||||
|
||||
created INTEGER NOT NULL,
|
||||
modified INTEGER NOT NULL,
|
||||
finished INTEGER NULL,
|
||||
|
||||
dismissed INTEGER NOT NULL DEFAULT 0,
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE SET NULL
|
||||
);
|
||||
|
||||
CREATE INDEX install_jobs_instance_id ON install_jobs(instance_id);
|
||||
CREATE INDEX install_jobs_status ON install_jobs(status);
|
||||
CREATE INDEX install_jobs_finished ON install_jobs(finished);
|
||||
@@ -0,0 +1,21 @@
|
||||
ALTER TABLE instance_links ADD COLUMN imported_name TEXT NULL;
|
||||
ALTER TABLE instance_links ADD COLUMN imported_version_number TEXT NULL;
|
||||
ALTER TABLE instance_links ADD COLUMN imported_filename TEXT NULL;
|
||||
|
||||
UPDATE instance_links
|
||||
SET
|
||||
link_kind = 'imported_modpack',
|
||||
imported_name = (
|
||||
SELECT instances.name
|
||||
FROM instances
|
||||
WHERE instances.id = instance_links.instance_id
|
||||
)
|
||||
WHERE
|
||||
link_kind = 'unmanaged'
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM instance_content_entries
|
||||
WHERE
|
||||
instance_content_entries.instance_id = instance_links.instance_id
|
||||
AND instance_content_entries.source_kind = 'imported_modpack'
|
||||
);
|
||||
Reference in New Issue
Block a user