You've already forked AstralRinth
forked from didirus/AstralRinth
Plugins (#758)
* plugins; datapacks * merge fixes/changes --------- Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
This commit is contained in:
@@ -1,44 +0,0 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT l.id id, l.loader loader, l.icon icon,\n ARRAY_AGG(DISTINCT pt.name) filter (where pt.name is not null) project_types,\n ARRAY_AGG(DISTINCT g.slug) filter (where g.slug is not null) games\n FROM loaders l \n LEFT OUTER JOIN loaders_project_types lpt ON joining_loader_id = l.id\n LEFT OUTER JOIN project_types pt ON lpt.joining_project_type_id = pt.id\n LEFT OUTER JOIN loaders_project_types_games lptg ON lptg.loader_id = lpt.joining_loader_id AND lptg.project_type_id = lpt.joining_project_type_id\n LEFT OUTER JOIN games g ON lptg.game_id = g.id\n GROUP BY l.id;\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "loader",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "icon",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "project_types",
|
||||
"type_info": "VarcharArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "games",
|
||||
"type_info": "VarcharArray"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "a796587302ae98d1af5f41696e401174fbeb9e8399bdcc78ffe8f80181b217a4"
|
||||
}
|
||||
50
.sqlx/query-cdb2f18f826097f0f17a1f7295d7c45eb1987b63c1a21666c6ca60c52217ba4d.json
generated
Normal file
50
.sqlx/query-cdb2f18f826097f0f17a1f7295d7c45eb1987b63c1a21666c6ca60c52217ba4d.json
generated
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT l.id id, l.loader loader, l.icon icon, l.metadata metadata,\n ARRAY_AGG(DISTINCT pt.name) filter (where pt.name is not null) project_types,\n ARRAY_AGG(DISTINCT g.slug) filter (where g.slug is not null) games\n FROM loaders l \n LEFT OUTER JOIN loaders_project_types lpt ON joining_loader_id = l.id\n LEFT OUTER JOIN project_types pt ON lpt.joining_project_type_id = pt.id\n LEFT OUTER JOIN loaders_project_types_games lptg ON lptg.loader_id = lpt.joining_loader_id AND lptg.project_type_id = lpt.joining_project_type_id\n LEFT OUTER JOIN games g ON lptg.game_id = g.id\n GROUP BY l.id;\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int4"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "loader",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "icon",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "metadata",
|
||||
"type_info": "Jsonb"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "project_types",
|
||||
"type_info": "VarcharArray"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "games",
|
||||
"type_info": "VarcharArray"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": []
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null
|
||||
]
|
||||
},
|
||||
"hash": "cdb2f18f826097f0f17a1f7295d7c45eb1987b63c1a21666c6ca60c52217ba4d"
|
||||
}
|
||||
46
migrations/20231115105022_plugins_datapacks_v3.sql
Normal file
46
migrations/20231115105022_plugins_datapacks_v3.sql
Normal file
@@ -0,0 +1,46 @@
|
||||
ALTER TABLE loaders ADD COLUMN metadata jsonb NOT NULL DEFAULT '{}'::jsonb;
|
||||
|
||||
-- Set 'platform' to 'true' for all plugin loaders
|
||||
-- From knossos v2
|
||||
-- pluginLoaders: ['bukkit', 'spigot', 'paper', 'purpur', 'sponge', 'folia'],
|
||||
-- pluginPlatformLoaders: ['bungeecord', 'waterfall', 'velocity'],
|
||||
-- allPluginLoaders: [
|
||||
-- 'bukkit',
|
||||
-- 'spigot',
|
||||
-- 'paper',
|
||||
-- 'purpur',
|
||||
-- 'sponge',
|
||||
-- 'bungeecord',
|
||||
-- 'waterfall',
|
||||
-- 'velocity',
|
||||
-- 'folia',
|
||||
-- ],
|
||||
-- dataPackLoaders: ['datapack'],
|
||||
-- modLoaders: ['forge', 'fabric', 'quilt', 'liteloader', 'modloader', 'rift', 'neoforge'],
|
||||
UPDATE loaders SET metadata = jsonb_set(metadata, '{platform}', 'false'::jsonb) WHERE loader in ('bukkit', 'spigot', 'paper', 'purpur', 'sponge', 'folia');
|
||||
UPDATE loaders SET metadata = jsonb_set(metadata, '{platform}', 'true'::jsonb) WHERE loader in ('bungeecord', 'waterfall', 'velocity');
|
||||
|
||||
INSERT INTO project_types (name) VALUES ('plugin');
|
||||
INSERT INTO project_types (name) VALUES ('datapack');
|
||||
|
||||
INSERT INTO loaders_project_types (joining_loader_id, joining_project_type_id)
|
||||
SELECT l.id, pt.id
|
||||
FROM loaders l
|
||||
CROSS JOIN project_types pt
|
||||
WHERE l.loader in ('datapack')
|
||||
AND pt.name = 'datapack';
|
||||
|
||||
INSERT INTO loaders_project_types (joining_loader_id, joining_project_type_id)
|
||||
SELECT l.id, pt.id
|
||||
FROM loaders l
|
||||
CROSS JOIN project_types pt
|
||||
WHERE l.loader in ('bukkit', 'spigot', 'paper', 'purpur', 'sponge', 'bungeecord', 'waterfall', 'velocity', 'folia')
|
||||
AND pt.name = 'plugin';
|
||||
|
||||
INSERT INTO loaders_project_types_games (loader_id, project_type_id, game_id)
|
||||
SELECT joining_loader_id, joining_project_type_id, g.id
|
||||
FROM loaders_project_types lpt
|
||||
INNER JOIN project_types pt ON pt.id = lpt.joining_project_type_id
|
||||
CROSS JOIN games g
|
||||
WHERE g.name = 'minecraft'
|
||||
AND pt.name in ('plugin', 'datapack');
|
||||
@@ -85,6 +85,7 @@ pub struct Loader {
|
||||
pub icon: String,
|
||||
pub supported_project_types: Vec<String>,
|
||||
pub supported_games: Vec<String>, // slugs
|
||||
pub metadata: serde_json::Value,
|
||||
}
|
||||
|
||||
impl Loader {
|
||||
@@ -136,7 +137,7 @@ impl Loader {
|
||||
|
||||
let result = sqlx::query!(
|
||||
"
|
||||
SELECT l.id id, l.loader loader, l.icon icon,
|
||||
SELECT l.id id, l.loader loader, l.icon icon, l.metadata metadata,
|
||||
ARRAY_AGG(DISTINCT pt.name) filter (where pt.name is not null) project_types,
|
||||
ARRAY_AGG(DISTINCT g.slug) filter (where g.slug is not null) games
|
||||
FROM loaders l
|
||||
@@ -161,7 +162,9 @@ impl Loader {
|
||||
.collect(),
|
||||
supported_games: x
|
||||
.games
|
||||
.unwrap_or_default()
|
||||
.unwrap_or_default(),
|
||||
metadata: x.metadata
|
||||
|
||||
}))
|
||||
})
|
||||
.try_collect::<Vec<_>>()
|
||||
|
||||
@@ -84,6 +84,7 @@ pub struct LoaderData {
|
||||
pub name: String,
|
||||
pub supported_project_types: Vec<String>,
|
||||
pub supported_games: Vec<String>,
|
||||
pub metadata: Value,
|
||||
}
|
||||
|
||||
pub async fn loader_list(
|
||||
@@ -98,6 +99,7 @@ pub async fn loader_list(
|
||||
name: x.loader,
|
||||
supported_project_types: x.supported_project_types,
|
||||
supported_games: x.supported_games,
|
||||
metadata: x.metadata,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
||||
@@ -3,8 +3,10 @@ use actix_web::{
|
||||
test::{self, TestRequest},
|
||||
};
|
||||
use async_trait::async_trait;
|
||||
use labrinth::database::models::loader_fields::LoaderFieldEnumValue;
|
||||
use labrinth::routes::v3::tags::GameData;
|
||||
use labrinth::{
|
||||
database::models::loader_fields::LoaderFieldEnumValue, routes::v3::tags::LoaderData,
|
||||
};
|
||||
|
||||
use crate::common::{
|
||||
api_common::{
|
||||
@@ -48,6 +50,12 @@ impl ApiTags for ApiV3 {
|
||||
}
|
||||
|
||||
impl ApiV3 {
|
||||
pub async fn get_loaders_deserialized(&self) -> Vec<LoaderData> {
|
||||
let resp = self.get_loaders().await;
|
||||
assert_eq!(resp.status(), 200);
|
||||
test::read_body_json(resp).await
|
||||
}
|
||||
|
||||
pub async fn get_loader_field_variants(&self, loader_field: &str) -> ServiceResponse {
|
||||
let req = TestRequest::get()
|
||||
.uri(&format!("/v3/loader_field?loader_field={}", loader_field))
|
||||
|
||||
@@ -25,6 +25,9 @@ INSERT INTO loaders_project_types (joining_loader_id, joining_project_type_id) V
|
||||
INSERT INTO loaders (id, loader) VALUES (6, 'forge');
|
||||
INSERT INTO loaders_project_types (joining_loader_id, joining_project_type_id) VALUES (6,1);
|
||||
|
||||
INSERT INTO loaders (id, loader, metadata) VALUES (7, 'bukkit', '{"platform":false}'::jsonb);
|
||||
INSERT INTO loaders (id, loader, metadata) VALUES (8, 'waterfall', '{"platform":true}'::jsonb);
|
||||
|
||||
-- Adds dummies to mrpack_loaders
|
||||
INSERT INTO loader_field_enum_values (enum_id, value) SELECT id, 'fabric' FROM loader_field_enums WHERE enum_name = 'mrpack_loaders';
|
||||
INSERT INTO loader_field_enum_values (enum_id, value) SELECT id, 'forge' FROM loader_field_enums WHERE enum_name = 'mrpack_loaders';
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use std::collections::HashSet;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use common::environment::with_test_environment_all;
|
||||
use common::{
|
||||
api_v3::ApiV3,
|
||||
environment::{with_test_environment, with_test_environment_all, TestEnvironment},
|
||||
};
|
||||
|
||||
use crate::common::api_common::ApiTags;
|
||||
|
||||
@@ -10,18 +13,8 @@ mod common;
|
||||
async fn get_tags() {
|
||||
with_test_environment_all(None, |test_env| async move {
|
||||
let api = &test_env.api;
|
||||
let loaders = api.get_loaders_deserialized_common().await;
|
||||
let categories = api.get_categories_deserialized_common().await;
|
||||
|
||||
let loader_names = loaders.into_iter().map(|x| x.name).collect::<HashSet<_>>();
|
||||
assert_eq!(
|
||||
loader_names,
|
||||
["fabric", "forge", "mrpack"]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
);
|
||||
|
||||
let category_names = categories
|
||||
.into_iter()
|
||||
.map(|x| x.name)
|
||||
@@ -44,3 +37,28 @@ async fn get_tags() {
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn get_tags_v3() {
|
||||
with_test_environment(None, |test_env: TestEnvironment<ApiV3>| async move {
|
||||
let api = &test_env.api;
|
||||
let loaders = api.get_loaders_deserialized().await;
|
||||
|
||||
let loader_metadata = loaders
|
||||
.into_iter()
|
||||
.map(|x| (x.name, x.metadata.get("platform").and_then(|x| x.as_bool())))
|
||||
.collect::<HashMap<_, _>>();
|
||||
let loader_names = loader_metadata.keys().cloned().collect::<HashSet<String>>();
|
||||
assert_eq!(
|
||||
loader_names,
|
||||
["fabric", "forge", "mrpack", "bukkit", "waterfall"]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
);
|
||||
assert_eq!(loader_metadata["fabric"], None);
|
||||
assert_eq!(loader_metadata["bukkit"], Some(false));
|
||||
assert_eq!(loader_metadata["waterfall"], Some(true));
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use itertools::Itertools;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
use crate::common::{
|
||||
@@ -12,33 +14,38 @@ async fn get_tags() {
|
||||
let game_versions = api.get_game_versions_deserialized().await;
|
||||
let loaders = api.get_loaders_deserialized().await;
|
||||
let side_types = api.get_side_types_deserialized().await;
|
||||
let categories = api.get_categories_deserialized().await;
|
||||
|
||||
// These tests match dummy data and will need to be updated if the dummy data changes;
|
||||
// These tests match dummy data and will need to be updated if the dummy data changes
|
||||
// Versions should be ordered by:
|
||||
// - ordering
|
||||
// - ordering ties settled by date added to database
|
||||
// - We also expect presentation of NEWEST to OLDEST
|
||||
// - All null orderings are treated as older than any non-null ordering
|
||||
// (for this test, the 1.20.1, etc, versions are all null ordering)
|
||||
let game_version_versions = game_versions
|
||||
.into_iter()
|
||||
.map(|x| x.version)
|
||||
.collect::<HashSet<_>>();
|
||||
.collect::<Vec<_>>();
|
||||
assert_eq!(
|
||||
game_version_versions,
|
||||
[
|
||||
"1.20.1",
|
||||
"1.20.2",
|
||||
"1.20.3",
|
||||
"1.20.4",
|
||||
"1.20.5",
|
||||
"Ordering_Negative1",
|
||||
"Ordering_Positive100"
|
||||
"Ordering_Positive100",
|
||||
"1.20.5",
|
||||
"1.20.4",
|
||||
"1.20.3",
|
||||
"1.20.2",
|
||||
"1.20.1"
|
||||
]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
.collect_vec()
|
||||
);
|
||||
|
||||
let loader_names = loaders.into_iter().map(|x| x.name).collect::<HashSet<_>>();
|
||||
assert_eq!(
|
||||
loader_names,
|
||||
["fabric", "forge", "mrpack"]
|
||||
["fabric", "forge", "mrpack", "bukkit", "waterfall"]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
@@ -52,26 +59,6 @@ async fn get_tags() {
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
);
|
||||
|
||||
let category_names = categories
|
||||
.into_iter()
|
||||
.map(|x| x.name)
|
||||
.collect::<HashSet<_>>();
|
||||
assert_eq!(
|
||||
category_names,
|
||||
[
|
||||
"combat",
|
||||
"economy",
|
||||
"food",
|
||||
"optimization",
|
||||
"decoration",
|
||||
"mobs",
|
||||
"magic"
|
||||
]
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
);
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user