move to monorepo dir

This commit is contained in:
Jai A
2024-10-16 14:11:42 -07:00
parent ff7975773e
commit e3a3379615
756 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
use crate::validate::{SupportedGameVersions, ValidationError, ValidationResult};
use std::io::Cursor;
use zip::ZipArchive;
pub struct DataPackValidator;
impl super::Validator for DataPackValidator {
fn get_file_extensions(&self) -> &[&str] {
&["zip"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["datapack"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("pack.mcmeta").is_err() {
return Ok(ValidationResult::Warning(
"No pack.mcmeta present for datapack file. Tip: Make sure pack.mcmeta is in the root directory of your datapack!",
));
}
Ok(ValidationResult::Pass)
}
}

View File

@@ -0,0 +1,34 @@
use crate::validate::{filter_out_packs, SupportedGameVersions, ValidationError, ValidationResult};
use std::io::Cursor;
use zip::ZipArchive;
pub struct FabricValidator;
impl super::Validator for FabricValidator {
fn get_file_extensions(&self) -> &[&str] {
&["jar"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["fabric"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("fabric.mod.json").is_err() {
return Ok(ValidationResult::Warning(
"No fabric.mod.json present for Fabric file.",
));
}
filter_out_packs(archive)?;
Ok(ValidationResult::Pass)
}
}

View File

@@ -0,0 +1,77 @@
use crate::validate::{filter_out_packs, SupportedGameVersions, ValidationError, ValidationResult};
use chrono::DateTime;
use std::io::Cursor;
use zip::ZipArchive;
pub struct ForgeValidator;
impl super::Validator for ForgeValidator {
fn get_file_extensions(&self) -> &[&str] {
&["jar", "zip"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["forge"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
// Time since release of 1.13, the first forge version which uses the new TOML system
SupportedGameVersions::PastDate(DateTime::from_timestamp(1540122067, 0).unwrap())
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("META-INF/mods.toml").is_err()
&& archive.by_name("META-INF/MANIFEST.MF").is_err()
&& !archive.file_names().any(|x| x.ends_with(".class"))
{
return Ok(ValidationResult::Warning(
"No mods.toml or valid class files present for Forge file.",
));
}
filter_out_packs(archive)?;
Ok(ValidationResult::Pass)
}
}
pub struct LegacyForgeValidator;
impl super::Validator for LegacyForgeValidator {
fn get_file_extensions(&self) -> &[&str] {
&["jar", "zip"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["forge"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
// Times between versions 1.5.2 to 1.12.2, which all use the legacy way of defining mods
SupportedGameVersions::Range(
DateTime::from_timestamp(0, 0).unwrap(),
DateTime::from_timestamp(1540122066, 0).unwrap(),
)
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("mcmod.info").is_err()
&& archive.by_name("META-INF/MANIFEST.MF").is_err()
&& !archive.file_names().any(|x| x.ends_with(".class"))
{
return Ok(ValidationResult::Warning(
"Forge mod file does not contain mcmod.info or valid class files!",
));
};
filter_out_packs(archive)?;
Ok(ValidationResult::Pass)
}
}

View File

@@ -0,0 +1,34 @@
use crate::validate::{filter_out_packs, SupportedGameVersions, ValidationError, ValidationResult};
use std::io::Cursor;
use zip::ZipArchive;
pub struct LiteLoaderValidator;
impl super::Validator for LiteLoaderValidator {
fn get_file_extensions(&self) -> &[&str] {
&["litemod", "jar"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["liteloader"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("litemod.json").is_err() {
return Ok(ValidationResult::Warning(
"No litemod.json present for LiteLoader file.",
));
}
filter_out_packs(archive)?;
Ok(ValidationResult::Pass)
}
}

View File

@@ -0,0 +1,266 @@
use crate::database::models::legacy_loader_fields::MinecraftGameVersion;
use crate::database::models::loader_fields::VersionField;
use crate::database::models::DatabaseError;
use crate::database::redis::RedisPool;
use crate::models::pack::PackFormat;
use crate::models::projects::{FileType, Loader};
use crate::validate::datapack::DataPackValidator;
use crate::validate::fabric::FabricValidator;
use crate::validate::forge::{ForgeValidator, LegacyForgeValidator};
use crate::validate::liteloader::LiteLoaderValidator;
use crate::validate::modpack::ModpackValidator;
use crate::validate::neoforge::NeoForgeValidator;
use crate::validate::plugin::*;
use crate::validate::quilt::QuiltValidator;
use crate::validate::resourcepack::{PackValidator, TexturePackValidator};
use crate::validate::rift::RiftValidator;
use crate::validate::shader::{CanvasShaderValidator, CoreShaderValidator, ShaderValidator};
use chrono::{DateTime, Utc};
use std::io::Cursor;
use thiserror::Error;
use zip::ZipArchive;
mod datapack;
mod fabric;
mod forge;
mod liteloader;
mod modpack;
mod neoforge;
pub mod plugin;
mod quilt;
mod resourcepack;
mod rift;
mod shader;
#[derive(Error, Debug)]
pub enum ValidationError {
#[error("Unable to read Zip Archive: {0}")]
Zip(#[from] zip::result::ZipError),
#[error("IO Error: {0}")]
Io(#[from] std::io::Error),
#[error("Error while validating JSON for uploaded file: {0}")]
SerDe(#[from] serde_json::Error),
#[error("Invalid Input: {0}")]
InvalidInput(std::borrow::Cow<'static, str>),
#[error("Error while managing threads")]
Blocking(#[from] actix_web::error::BlockingError),
#[error("Error while querying database")]
Database(#[from] DatabaseError),
}
#[derive(Eq, PartialEq, Debug)]
pub enum ValidationResult {
/// File should be marked as primary with pack file data
PassWithPackDataAndFiles {
format: PackFormat,
files: Vec<String>,
},
/// File should be marked as primary
Pass,
/// File should not be marked primary, the reason for which is inside the String
Warning(&'static str),
}
impl ValidationResult {
pub fn is_passed(&self) -> bool {
match self {
ValidationResult::PassWithPackDataAndFiles { .. } => true,
ValidationResult::Pass => true,
ValidationResult::Warning(_) => false,
}
}
}
pub enum SupportedGameVersions {
All,
PastDate(DateTime<Utc>),
Range(DateTime<Utc>, DateTime<Utc>),
#[allow(dead_code)]
Custom(Vec<MinecraftGameVersion>),
}
pub trait Validator: Sync {
fn get_file_extensions(&self) -> &[&str];
fn get_supported_loaders(&self) -> &[&str];
fn get_supported_game_versions(&self) -> SupportedGameVersions;
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError>;
}
static ALWAYS_ALLOWED_EXT: &[&str] = &["zip", "txt"];
static VALIDATORS: &[&dyn Validator] = &[
&ModpackValidator,
&FabricValidator,
&ForgeValidator,
&LegacyForgeValidator,
&QuiltValidator,
&LiteLoaderValidator,
&PackValidator,
&TexturePackValidator,
&PluginYmlValidator,
&BungeeCordValidator,
&VelocityValidator,
&SpongeValidator,
&CanvasShaderValidator,
&ShaderValidator,
&CoreShaderValidator,
&DataPackValidator,
&RiftValidator,
&NeoForgeValidator,
];
/// The return value is whether this file should be marked as primary or not, based on the analysis of the file
#[allow(clippy::too_many_arguments)]
pub async fn validate_file(
data: bytes::Bytes,
file_extension: String,
loaders: Vec<Loader>,
file_type: Option<FileType>,
version_fields: Vec<VersionField>,
transaction: &mut sqlx::Transaction<'_, sqlx::Postgres>,
redis: &RedisPool,
) -> Result<ValidationResult, ValidationError> {
let game_versions = version_fields
.into_iter()
.find_map(|v| MinecraftGameVersion::try_from_version_field(&v).ok())
.unwrap_or_default();
let all_game_versions =
MinecraftGameVersion::list(None, None, &mut *transaction, redis).await?;
validate_minecraft_file(
data,
file_extension,
loaders,
game_versions,
all_game_versions,
file_type,
)
.await
}
async fn validate_minecraft_file(
data: bytes::Bytes,
file_extension: String,
loaders: Vec<Loader>,
game_versions: Vec<MinecraftGameVersion>,
all_game_versions: Vec<MinecraftGameVersion>,
file_type: Option<FileType>,
) -> Result<ValidationResult, ValidationError> {
actix_web::web::block(move || {
let reader = Cursor::new(data);
let mut zip = ZipArchive::new(reader)?;
if let Some(file_type) = file_type {
match file_type {
FileType::RequiredResourcePack | FileType::OptionalResourcePack => {
return PackValidator.validate(&mut zip);
}
FileType::Unknown => {}
}
}
let mut visited = false;
let mut saved_result = None;
for validator in VALIDATORS {
if loaders
.iter()
.any(|x| validator.get_supported_loaders().contains(&&*x.0))
&& game_version_supported(
&game_versions,
&all_game_versions,
validator.get_supported_game_versions(),
)
{
if validator.get_file_extensions().contains(&&*file_extension) {
let result = validator.validate(&mut zip)?;
match result {
ValidationResult::PassWithPackDataAndFiles { .. } => {
saved_result = Some(result);
}
ValidationResult::Pass => {
if saved_result.is_none() {
saved_result = Some(result);
}
}
ValidationResult::Warning(_) => {
return Ok(result);
}
}
} else {
visited = true;
}
}
}
if let Some(result) = saved_result {
return Ok(result);
}
if visited {
if ALWAYS_ALLOWED_EXT.contains(&&*file_extension) {
Ok(ValidationResult::Warning(
"File extension is invalid for input file",
))
} else {
Err(ValidationError::InvalidInput(
format!("File extension {file_extension} is invalid for input file").into(),
))
}
} else {
Ok(ValidationResult::Pass)
}
})
.await?
}
// Write tests for this
fn game_version_supported(
game_versions: &[MinecraftGameVersion],
all_game_versions: &[MinecraftGameVersion],
supported_game_versions: SupportedGameVersions,
) -> bool {
match supported_game_versions {
SupportedGameVersions::All => true,
SupportedGameVersions::PastDate(date) => game_versions.iter().any(|x| {
all_game_versions
.iter()
.find(|y| y.version == x.version)
.map(|x| x.created > date)
.unwrap_or(false)
}),
SupportedGameVersions::Range(before, after) => game_versions.iter().any(|x| {
all_game_versions
.iter()
.find(|y| y.version == x.version)
.map(|x| x.created > before && x.created < after)
.unwrap_or(false)
}),
SupportedGameVersions::Custom(versions) => {
let version_ids = versions.iter().map(|gv| gv.id).collect::<Vec<_>>();
let game_version_ids: Vec<_> = game_versions.iter().map(|gv| gv.id).collect::<Vec<_>>();
version_ids.iter().any(|x| game_version_ids.contains(x))
}
}
}
pub fn filter_out_packs(
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if (archive.by_name("modlist.html").is_ok() && archive.by_name("manifest.json").is_ok())
|| archive
.file_names()
.any(|x| x.starts_with("mods/") && x.ends_with(".jar"))
|| archive
.file_names()
.any(|x| x.starts_with("override/mods/") && x.ends_with(".jar"))
{
return Ok(ValidationResult::Warning(
"Invalid modpack file. You must upload a valid .MRPACK file.",
));
}
Ok(ValidationResult::Pass)
}

View File

@@ -0,0 +1,101 @@
use crate::models::pack::{PackFileHash, PackFormat};
use crate::util::validate::validation_errors_to_string;
use crate::validate::{SupportedGameVersions, ValidationError, ValidationResult};
use std::io::{Cursor, Read};
use std::path::Component;
use validator::Validate;
use zip::ZipArchive;
pub struct ModpackValidator;
impl super::Validator for ModpackValidator {
fn get_file_extensions(&self) -> &[&str] {
&["mrpack"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["mrpack"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
let pack: PackFormat = {
let mut file = if let Ok(file) = archive.by_name("modrinth.index.json") {
file
} else {
return Ok(ValidationResult::Warning("Pack manifest is missing."));
};
let mut contents = String::new();
file.read_to_string(&mut contents)?;
serde_json::from_str(&contents)?
};
pack.validate().map_err(|err| {
ValidationError::InvalidInput(validation_errors_to_string(err, None).into())
})?;
if pack.game != "minecraft" {
return Err(ValidationError::InvalidInput(
format!("Game {0} does not exist!", pack.game).into(),
));
}
if pack.files.is_empty() && !archive.file_names().any(|x| x.starts_with("overrides/")) {
return Err(ValidationError::InvalidInput("Pack has no files!".into()));
}
for file in &pack.files {
if !file.hashes.contains_key(&PackFileHash::Sha1) {
return Err(ValidationError::InvalidInput(
"All pack files must provide a SHA1 hash!".into(),
));
}
if !file.hashes.contains_key(&PackFileHash::Sha512) {
return Err(ValidationError::InvalidInput(
"All pack files must provide a SHA512 hash!".into(),
));
}
let path = std::path::Path::new(&file.path)
.components()
.next()
.ok_or_else(|| ValidationError::InvalidInput("Invalid pack file path!".into()))?;
match path {
Component::CurDir | Component::Normal(_) => {}
_ => {
return Err(ValidationError::InvalidInput(
"Invalid pack file path!".into(),
))
}
};
}
Ok(ValidationResult::PassWithPackDataAndFiles {
format: pack,
files: archive
.file_names()
.filter(|x| {
(x.ends_with("jar") || x.ends_with("zip"))
&& (x.starts_with("overrides/mods")
|| x.starts_with("client-overrides/mods")
|| x.starts_with("server-overrides/mods")
|| x.starts_with("overrides/resourcepacks")
|| x.starts_with("server-overrides/resourcepacks")
|| x.starts_with("overrides/shaderpacks")
|| x.starts_with("client-overrides/shaderpacks"))
})
.flat_map(|x| x.rsplit('/').next().map(|x| x.to_string()))
.collect::<Vec<String>>(),
})
}
}

View File

@@ -0,0 +1,38 @@
use crate::validate::{filter_out_packs, SupportedGameVersions, ValidationError, ValidationResult};
use std::io::Cursor;
use zip::ZipArchive;
pub struct NeoForgeValidator;
impl super::Validator for NeoForgeValidator {
fn get_file_extensions(&self) -> &[&str] {
&["jar", "zip"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["neoforge"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("META-INF/mods.toml").is_err()
&& archive.by_name("META-INF/neoforge.mods.toml").is_err()
&& archive.by_name("META-INF/MANIFEST.MF").is_err()
&& !archive.file_names().any(|x| x.ends_with(".class"))
{
return Ok(ValidationResult::Warning(
"No neoforge.mods.toml, mods.toml, or valid class files present for NeoForge file.",
));
}
filter_out_packs(archive)?;
Ok(ValidationResult::Pass)
}
}

View File

@@ -0,0 +1,129 @@
use crate::validate::{SupportedGameVersions, ValidationError, ValidationResult};
use std::io::Cursor;
use zip::ZipArchive;
pub struct PluginYmlValidator;
impl super::Validator for PluginYmlValidator {
fn get_file_extensions(&self) -> &[&str] {
&["zip", "jar"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["bukkit", "spigot", "paper", "purpur", "folia"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if !archive
.file_names()
.any(|name| name == "plugin.yml" || name == "paper-plugin.yml")
{
return Ok(ValidationResult::Warning(
"No plugin.yml or paper-plugin.yml present for plugin file.",
));
};
Ok(ValidationResult::Pass)
}
}
pub struct BungeeCordValidator;
impl super::Validator for BungeeCordValidator {
fn get_file_extensions(&self) -> &[&str] {
&["zip", "jar"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["bungeecord", "waterfall"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if !archive
.file_names()
.any(|name| name == "plugin.yml" || name == "bungee.yml")
{
return Ok(ValidationResult::Warning(
"No plugin.yml or bungee.yml present for plugin file.",
));
};
Ok(ValidationResult::Pass)
}
}
pub struct VelocityValidator;
impl super::Validator for VelocityValidator {
fn get_file_extensions(&self) -> &[&str] {
&["zip", "jar"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["velocity"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("velocity-plugin.json").is_err() {
return Ok(ValidationResult::Warning(
"No velocity-plugin.json present for plugin file.",
));
}
Ok(ValidationResult::Pass)
}
}
pub struct SpongeValidator;
impl super::Validator for SpongeValidator {
fn get_file_extensions(&self) -> &[&str] {
&["zip", "jar"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["sponge"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if !archive.file_names().any(|name| {
name == "sponge_plugins.json"
|| name == "mcmod.info"
|| name == "META-INF/sponge_plugins.json"
}) {
return Ok(ValidationResult::Warning(
"No sponge_plugins.json or mcmod.info present for Sponge plugin.",
));
};
Ok(ValidationResult::Pass)
}
}

View File

@@ -0,0 +1,36 @@
use crate::validate::{filter_out_packs, SupportedGameVersions, ValidationError, ValidationResult};
use chrono::DateTime;
use std::io::Cursor;
use zip::ZipArchive;
pub struct QuiltValidator;
impl super::Validator for QuiltValidator {
fn get_file_extensions(&self) -> &[&str] {
&["jar", "zip"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["quilt"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::PastDate(DateTime::from_timestamp(1646070100, 0).unwrap())
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("quilt.mod.json").is_err() && archive.by_name("fabric.mod.json").is_err()
{
return Ok(ValidationResult::Warning(
"No quilt.mod.json present for Quilt file.",
));
}
filter_out_packs(archive)?;
Ok(ValidationResult::Pass)
}
}

View File

@@ -0,0 +1,67 @@
use crate::validate::{SupportedGameVersions, ValidationError, ValidationResult};
use chrono::DateTime;
use std::io::Cursor;
use zip::ZipArchive;
pub struct PackValidator;
impl super::Validator for PackValidator {
fn get_file_extensions(&self) -> &[&str] {
&["zip"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["minecraft"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
// Time since release of 13w24a which replaced texture packs with resource packs
SupportedGameVersions::PastDate(DateTime::from_timestamp(1371137542, 0).unwrap())
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("pack.mcmeta").is_err() {
return Ok(ValidationResult::Warning(
"No pack.mcmeta present for pack file. Tip: Make sure pack.mcmeta is in the root directory of your pack!",
));
}
Ok(ValidationResult::Pass)
}
}
pub struct TexturePackValidator;
impl super::Validator for TexturePackValidator {
fn get_file_extensions(&self) -> &[&str] {
&["zip"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["minecraft"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
// a1.2.2a to 13w23b
SupportedGameVersions::Range(
DateTime::from_timestamp(1289339999, 0).unwrap(),
DateTime::from_timestamp(1370651522, 0).unwrap(),
)
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("pack.txt").is_err() {
return Ok(ValidationResult::Warning(
"No pack.txt present for pack file.",
));
}
Ok(ValidationResult::Pass)
}
}

View File

@@ -0,0 +1,34 @@
use crate::validate::{filter_out_packs, SupportedGameVersions, ValidationError, ValidationResult};
use std::io::Cursor;
use zip::ZipArchive;
pub struct RiftValidator;
impl super::Validator for RiftValidator {
fn get_file_extensions(&self) -> &[&str] {
&["jar"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["rift"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("riftmod.json").is_err() {
return Ok(ValidationResult::Warning(
"No riftmod.json present for Rift file.",
));
}
filter_out_packs(archive)?;
Ok(ValidationResult::Pass)
}
}

View File

@@ -0,0 +1,105 @@
use crate::validate::{SupportedGameVersions, ValidationError, ValidationResult};
use std::io::Cursor;
use zip::ZipArchive;
pub struct ShaderValidator;
impl super::Validator for ShaderValidator {
fn get_file_extensions(&self) -> &[&str] {
&["zip"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["optifine", "iris"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if !archive.file_names().any(|x| x.starts_with("shaders/")) {
return Ok(ValidationResult::Warning(
"No shaders folder present for OptiFine/Iris shader.",
));
}
Ok(ValidationResult::Pass)
}
}
pub struct CanvasShaderValidator;
impl super::Validator for CanvasShaderValidator {
fn get_file_extensions(&self) -> &[&str] {
&["zip"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["canvas"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("pack.mcmeta").is_err() {
return Ok(ValidationResult::Warning(
"No pack.mcmeta present for pack file. Tip: Make sure pack.mcmeta is in the root directory of your pack!",
));
};
if !archive.file_names().any(|x| x.contains("/pipelines/")) {
return Ok(ValidationResult::Warning(
"No pipeline shaders folder present for canvas shaders.",
));
}
Ok(ValidationResult::Pass)
}
}
pub struct CoreShaderValidator;
impl super::Validator for CoreShaderValidator {
fn get_file_extensions(&self) -> &[&str] {
&["zip"]
}
fn get_supported_loaders(&self) -> &[&str] {
&["vanilla"]
}
fn get_supported_game_versions(&self) -> SupportedGameVersions {
SupportedGameVersions::All
}
fn validate(
&self,
archive: &mut ZipArchive<Cursor<bytes::Bytes>>,
) -> Result<ValidationResult, ValidationError> {
if archive.by_name("pack.mcmeta").is_err() {
return Ok(ValidationResult::Warning(
"No pack.mcmeta present for pack file. Tip: Make sure pack.mcmeta is in the root directory of your pack!",
));
};
if !archive
.file_names()
.any(|x| x.starts_with("assets/minecraft/shaders/"))
{
return Ok(ValidationResult::Warning(
"No shaders folder present for vanilla shaders.",
));
}
Ok(ValidationResult::Pass)
}
}