#![cfg(feature = "sprite")]
#![allow(unused_imports)]
#![allow(unused_variables)]
#![allow(unused_mut)]
#![allow(clippy::field_reassign_with_default)]
#![allow(clippy::bool_assert_comparison)]
use std::fs;
use std::path::Path;
use unity_asset_decode::sprite::{Sprite, SpriteProcessor};
use unity_asset_decode::texture::{Texture2D, TextureFormat};
use unity_asset_decode::unity_version::UnityVersion;
#[test]
fn test_sprite_image_extraction_unitypy_compat() {
println!("Testing sprite image extraction compatibility with UnityPy...");
let mut texture = Texture2D::default();
texture.name = "UI_Atlas".to_string();
texture.width = 256;
texture.height = 256;
texture.format = TextureFormat::RGBA32;
let mut texture_data = Vec::new();
for y in 0..256 {
for x in 0..256 {
let (r, g, b) = if x < 128 && y < 128 {
(255, 100, 100) } else if x >= 128 && y < 128 {
(100, 255, 100) } else if x < 128 && y >= 128 {
(100, 100, 255) } else {
(255, 255, 100) };
texture_data.extend_from_slice(&[r, g, b, 255]);
}
}
texture.image_data = texture_data;
let mut sprite = Sprite::default();
sprite.name = "UI_Button".to_string();
sprite.rect_x = 64.0;
sprite.rect_y = 192.0; sprite.rect_width = 64.0;
sprite.rect_height = 64.0;
sprite.pixels_to_units = 100.0;
println!(
" Testing sprite extraction from {}x{} atlas",
texture.width, texture.height
);
println!(
" Sprite: '{}' at ({}, {}) size {}x{}",
sprite.name, sprite.rect_x, sprite.rect_y, sprite.rect_width, sprite.rect_height
);
let sprite_processor = SpriteProcessor::new(UnityVersion::default());
match sprite_processor.extract_sprite_image(&sprite, &texture) {
Ok(sprite_image_data) => {
println!(
" ✓ Successfully extracted sprite image: {} bytes",
sprite_image_data.len()
);
assert!(!sprite_image_data.is_empty());
if sprite_image_data.len() >= 8 {
let png_header = &sprite_image_data[0..8];
let expected_png_header = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A];
assert_eq!(png_header, expected_png_header, "Should be valid PNG data");
}
println!(" ✓ Sprite extraction compatible with UnityPy");
}
Err(e) => {
panic!("Sprite extraction failed: {}", e);
}
}
}
#[test]
fn test_sprite_properties_unitypy_compat() {
println!("Testing sprite properties compatibility with UnityPy...");
let mut sprite = Sprite::default();
sprite.name = "PlayerIcon".to_string();
sprite.rect_x = 128.0;
sprite.rect_y = 64.0;
sprite.rect_width = 32.0;
sprite.rect_height = 48.0;
sprite.offset_x = 2.0;
sprite.offset_y = -1.5;
sprite.pivot_x = 0.5;
sprite.pivot_y = 0.0; sprite.pixels_to_units = 16.0; sprite.border_x = 4.0;
sprite.border_y = 4.0;
sprite.border_z = 4.0;
sprite.border_w = 4.0;
sprite.is_polygon = false;
println!(" Sprite Properties (UnityPy compatible):");
println!(" Name: {}", sprite.name);
println!(
" Rect: ({}, {}) {}x{}",
sprite.rect_x, sprite.rect_y, sprite.rect_width, sprite.rect_height
);
println!(" Offset: ({}, {})", sprite.offset_x, sprite.offset_y);
println!(" Pivot: ({}, {})", sprite.pivot_x, sprite.pivot_y);
println!(
" Border: L:{} B:{} R:{} T:{}",
sprite.border_x, sprite.border_y, sprite.border_z, sprite.border_w
);
println!(" PixelsToUnits: {}", sprite.pixels_to_units);
println!(" IsPolygon: {}", sprite.is_polygon);
assert_eq!(sprite.name, "PlayerIcon");
assert_eq!(sprite.rect_x, 128.0);
assert_eq!(sprite.rect_y, 64.0);
assert_eq!(sprite.rect_width, 32.0);
assert_eq!(sprite.rect_height, 48.0);
assert_eq!(sprite.offset_x, 2.0);
assert_eq!(sprite.offset_y, -1.5);
assert_eq!(sprite.pivot_x, 0.5);
assert_eq!(sprite.pivot_y, 0.0);
assert_eq!(sprite.pixels_to_units, 16.0);
assert_eq!(sprite.is_polygon, false);
println!(" ✓ All properties compatible with UnityPy");
}
#[test]
fn test_sprite_atlas_unitypy_compat() {
println!("Testing sprite atlas handling compatibility with UnityPy...");
let atlas_sprites = vec![
("Icon_Health", 0.0, 224.0, 32.0, 32.0),
("Icon_Mana", 32.0, 224.0, 32.0, 32.0),
("Icon_Stamina", 64.0, 224.0, 32.0, 32.0),
("Button_Play", 0.0, 192.0, 64.0, 32.0),
("Button_Pause", 64.0, 192.0, 64.0, 32.0),
];
let mut atlas_texture = Texture2D::default();
atlas_texture.name = "UI_Atlas_01".to_string();
atlas_texture.width = 256;
atlas_texture.height = 256;
atlas_texture.format = TextureFormat::RGBA32;
let mut texture_data = vec![128u8; 256 * 256 * 4]; atlas_texture.image_data = texture_data;
println!(
" Testing {} sprites from atlas '{}'",
atlas_sprites.len(),
atlas_texture.name
);
for (name, x, y, width, height) in atlas_sprites {
let mut sprite = Sprite::default();
sprite.name = name.to_string();
sprite.rect_x = x;
sprite.rect_y = y;
sprite.rect_width = width;
sprite.rect_height = height;
sprite.pixels_to_units = 100.0;
sprite.sprite_atlas_path_id = Some(12345);
sprite.render_data.texture_path_id = 67890;
println!(
" Testing sprite '{}' ({}x{} at {}, {})",
name, width, height, x, y
);
let sprite_processor = SpriteProcessor::new(UnityVersion::default());
match sprite_processor.extract_sprite_image(&sprite, &atlas_texture) {
Ok(sprite_image_data) => {
assert!(!sprite_image_data.is_empty());
println!(
" ✓ Extracted sprite image: {} bytes",
sprite_image_data.len()
);
}
Err(e) => {
panic!("Failed to extract sprite '{}': {}", name, e);
}
}
assert_eq!(sprite.name, name);
assert_eq!(sprite.render_data.texture_path_id, 67890);
println!(" ✓ Atlas sprite info correct");
}
println!(" ✓ All atlas sprites processed successfully (UnityPy compatible)");
}
#[test]
fn test_sprite_export_unitypy_compat() {
println!("Testing sprite export compatibility with UnityPy...");
let mut texture = Texture2D::default();
texture.name = "ExportTest".to_string();
texture.width = 64;
texture.height = 64;
texture.format = TextureFormat::RGBA32;
let mut texture_data = Vec::new();
for y in 0..64 {
for x in 0..64 {
let intensity = ((x + y) * 4) as u8;
texture_data.extend_from_slice(&[intensity, intensity / 2, 255 - intensity, 255]);
}
}
texture.image_data = texture_data;
let mut sprite = Sprite::default();
sprite.name = "ExportSprite".to_string();
sprite.rect_x = 0.0;
sprite.rect_y = 0.0;
sprite.rect_width = 64.0;
sprite.rect_height = 64.0;
std::fs::create_dir_all("target").ok();
let png_path = "target/unitypy_compat_sprite.png";
let sprite_processor = SpriteProcessor::new(UnityVersion::default());
match sprite_processor.extract_sprite_image(&sprite, &texture) {
Ok(png_data) => {
match fs::write(png_path, &png_data) {
Ok(()) => {
println!(" ✓ PNG export successful (like UnityPy's save method)");
assert!(Path::new(png_path).exists(), "PNG file should exist");
if let Ok(metadata) = fs::metadata(png_path) {
let file_size = metadata.len();
println!(" ✓ PNG file size: {} bytes", file_size);
assert!(file_size > 100, "PNG should have reasonable size");
}
fs::remove_file(png_path).ok();
}
Err(e) => {
panic!("Failed to write PNG file: {}", e);
}
}
}
Err(e) => {
panic!("PNG export failed: {}", e);
}
}
println!(" ✓ Sprite export fully compatible with UnityPy workflow");
}
#[test]
fn test_sprite_processor_version_compat() {
println!("Testing sprite processor version compatibility...");
let test_versions = vec![
"5.0.0f1",
"5.6.0f1",
"2017.1.0f1",
"2018.4.0f1",
"2019.4.0f1",
"2020.3.0f1",
"2021.3.0f1",
];
for version_str in test_versions {
let version = UnityVersion::parse_version(version_str).unwrap();
let processor = SpriteProcessor::new(version);
println!(" Testing version {}", version_str);
println!(" ✓ Processor created for version {}", version_str);
}
println!(" ✓ Sprite processor compatible with all Unity versions");
}