cleanup avatar
This commit is contained in:
parent
8a37a7b2da
commit
2afe43547d
4 changed files with 1002 additions and 1233 deletions
|
|
@ -1,5 +1,6 @@
|
|||
//! Database query modules.
|
||||
|
||||
pub mod avatar_common;
|
||||
pub mod avatars;
|
||||
pub mod channel_members;
|
||||
pub mod channels;
|
||||
|
|
|
|||
657
crates/chattyness-db/src/queries/avatar_common.rs
Normal file
657
crates/chattyness-db/src/queries/avatar_common.rs
Normal file
|
|
@ -0,0 +1,657 @@
|
|||
//! Common avatar query infrastructure.
|
||||
//!
|
||||
//! This module provides shared types and traits for server and realm avatars,
|
||||
//! eliminating duplication between `server_avatars.rs` and `realm_avatars.rs`.
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use sqlx::PgExecutor;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::models::{AvatarRenderData, EmotionState};
|
||||
use chattyness_error::AppError;
|
||||
|
||||
// =============================================================================
|
||||
// Avatar Slots - Array-based representation of avatar prop references
|
||||
// =============================================================================
|
||||
|
||||
/// Number of positions per layer (0-8).
|
||||
pub const LAYER_SIZE: usize = 9;
|
||||
|
||||
/// Number of emotion types.
|
||||
pub const EMOTION_COUNT: usize = 12;
|
||||
|
||||
/// Array-based representation of avatar prop slots.
|
||||
///
|
||||
/// This struct consolidates the 135 individual UUID fields into arrays,
|
||||
/// making the code more maintainable and enabling iteration.
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct AvatarSlots {
|
||||
/// Skin layer positions 0-8 (behind user, body/face).
|
||||
pub skin: [Option<Uuid>; LAYER_SIZE],
|
||||
/// Clothes layer positions 0-8 (with user, worn items).
|
||||
pub clothes: [Option<Uuid>; LAYER_SIZE],
|
||||
/// Accessories layer positions 0-8 (in front of user, held/attached items).
|
||||
pub accessories: [Option<Uuid>; LAYER_SIZE],
|
||||
/// Emotion layers: 12 emotions × 9 positions each.
|
||||
/// Index by EmotionState ordinal: neutral=0, happy=1, sad=2, etc.
|
||||
pub emotions: [[Option<Uuid>; LAYER_SIZE]; EMOTION_COUNT],
|
||||
}
|
||||
|
||||
impl AvatarSlots {
|
||||
/// Get the emotion layer for a specific emotion state.
|
||||
pub fn emotion_layer(&self, emotion: EmotionState) -> &[Option<Uuid>; LAYER_SIZE] {
|
||||
&self.emotions[emotion.as_index()]
|
||||
}
|
||||
|
||||
/// Collect all non-null prop UUIDs from all layers.
|
||||
pub fn collect_all_prop_ids(&self) -> Vec<Uuid> {
|
||||
let mut ids = Vec::new();
|
||||
|
||||
// Content layers
|
||||
for id in self.skin.iter().flatten() {
|
||||
ids.push(*id);
|
||||
}
|
||||
for id in self.clothes.iter().flatten() {
|
||||
ids.push(*id);
|
||||
}
|
||||
for id in self.accessories.iter().flatten() {
|
||||
ids.push(*id);
|
||||
}
|
||||
|
||||
// All emotion layers
|
||||
for emotion_layer in &self.emotions {
|
||||
for id in emotion_layer.iter().flatten() {
|
||||
ids.push(*id);
|
||||
}
|
||||
}
|
||||
|
||||
ids
|
||||
}
|
||||
|
||||
/// Collect prop UUIDs for content layers + specific emotion.
|
||||
pub fn collect_render_prop_ids(&self, emotion: EmotionState) -> Vec<Uuid> {
|
||||
let mut ids = Vec::new();
|
||||
|
||||
// Content layers
|
||||
for id in self.skin.iter().flatten() {
|
||||
ids.push(*id);
|
||||
}
|
||||
for id in self.clothes.iter().flatten() {
|
||||
ids.push(*id);
|
||||
}
|
||||
for id in self.accessories.iter().flatten() {
|
||||
ids.push(*id);
|
||||
}
|
||||
|
||||
// Specific emotion layer
|
||||
for id in self.emotion_layer(emotion).iter().flatten() {
|
||||
ids.push(*id);
|
||||
}
|
||||
|
||||
ids
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension trait for EmotionState to get array indices.
|
||||
pub trait EmotionIndex {
|
||||
fn as_index(&self) -> usize;
|
||||
fn from_index(index: usize) -> Option<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
|
||||
impl EmotionIndex for EmotionState {
|
||||
fn as_index(&self) -> usize {
|
||||
match self {
|
||||
EmotionState::Neutral => 0,
|
||||
EmotionState::Happy => 1,
|
||||
EmotionState::Sad => 2,
|
||||
EmotionState::Angry => 3,
|
||||
EmotionState::Surprised => 4,
|
||||
EmotionState::Thinking => 5,
|
||||
EmotionState::Laughing => 6,
|
||||
EmotionState::Crying => 7,
|
||||
EmotionState::Love => 8,
|
||||
EmotionState::Confused => 9,
|
||||
EmotionState::Sleeping => 10,
|
||||
EmotionState::Wink => 11,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_index(index: usize) -> Option<Self> {
|
||||
match index {
|
||||
0 => Some(EmotionState::Neutral),
|
||||
1 => Some(EmotionState::Happy),
|
||||
2 => Some(EmotionState::Sad),
|
||||
3 => Some(EmotionState::Angry),
|
||||
4 => Some(EmotionState::Surprised),
|
||||
5 => Some(EmotionState::Thinking),
|
||||
6 => Some(EmotionState::Laughing),
|
||||
7 => Some(EmotionState::Crying),
|
||||
8 => Some(EmotionState::Love),
|
||||
9 => Some(EmotionState::Confused),
|
||||
10 => Some(EmotionState::Sleeping),
|
||||
11 => Some(EmotionState::Wink),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Shared Row Types for Database Queries
|
||||
// =============================================================================
|
||||
|
||||
/// Row type for avatar with resolved asset paths.
|
||||
/// Used by both server and realm avatar queries.
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct AvatarWithPathsRow {
|
||||
pub id: Uuid,
|
||||
pub slug: Option<String>, // Server avatars have slug, realm might not in some queries
|
||||
pub name: String,
|
||||
pub description: Option<String>,
|
||||
// Skin layer paths
|
||||
pub skin_0: Option<String>,
|
||||
pub skin_1: Option<String>,
|
||||
pub skin_2: Option<String>,
|
||||
pub skin_3: Option<String>,
|
||||
pub skin_4: Option<String>,
|
||||
pub skin_5: Option<String>,
|
||||
pub skin_6: Option<String>,
|
||||
pub skin_7: Option<String>,
|
||||
pub skin_8: Option<String>,
|
||||
// Clothes layer paths
|
||||
pub clothes_0: Option<String>,
|
||||
pub clothes_1: Option<String>,
|
||||
pub clothes_2: Option<String>,
|
||||
pub clothes_3: Option<String>,
|
||||
pub clothes_4: Option<String>,
|
||||
pub clothes_5: Option<String>,
|
||||
pub clothes_6: Option<String>,
|
||||
pub clothes_7: Option<String>,
|
||||
pub clothes_8: Option<String>,
|
||||
// Accessories layer paths
|
||||
pub accessories_0: Option<String>,
|
||||
pub accessories_1: Option<String>,
|
||||
pub accessories_2: Option<String>,
|
||||
pub accessories_3: Option<String>,
|
||||
pub accessories_4: Option<String>,
|
||||
pub accessories_5: Option<String>,
|
||||
pub accessories_6: Option<String>,
|
||||
pub accessories_7: Option<String>,
|
||||
pub accessories_8: Option<String>,
|
||||
// Happy emotion layer paths (e1 - for store display)
|
||||
pub emotion_0: Option<String>,
|
||||
pub emotion_1: Option<String>,
|
||||
pub emotion_2: Option<String>,
|
||||
pub emotion_3: Option<String>,
|
||||
pub emotion_4: Option<String>,
|
||||
pub emotion_5: Option<String>,
|
||||
pub emotion_6: Option<String>,
|
||||
pub emotion_7: Option<String>,
|
||||
pub emotion_8: Option<String>,
|
||||
}
|
||||
|
||||
impl AvatarWithPathsRow {
|
||||
/// Extract skin layer as array.
|
||||
pub fn skin_layer(&self) -> [Option<String>; LAYER_SIZE] {
|
||||
[
|
||||
self.skin_0.clone(),
|
||||
self.skin_1.clone(),
|
||||
self.skin_2.clone(),
|
||||
self.skin_3.clone(),
|
||||
self.skin_4.clone(),
|
||||
self.skin_5.clone(),
|
||||
self.skin_6.clone(),
|
||||
self.skin_7.clone(),
|
||||
self.skin_8.clone(),
|
||||
]
|
||||
}
|
||||
|
||||
/// Extract clothes layer as array.
|
||||
pub fn clothes_layer(&self) -> [Option<String>; LAYER_SIZE] {
|
||||
[
|
||||
self.clothes_0.clone(),
|
||||
self.clothes_1.clone(),
|
||||
self.clothes_2.clone(),
|
||||
self.clothes_3.clone(),
|
||||
self.clothes_4.clone(),
|
||||
self.clothes_5.clone(),
|
||||
self.clothes_6.clone(),
|
||||
self.clothes_7.clone(),
|
||||
self.clothes_8.clone(),
|
||||
]
|
||||
}
|
||||
|
||||
/// Extract accessories layer as array.
|
||||
pub fn accessories_layer(&self) -> [Option<String>; LAYER_SIZE] {
|
||||
[
|
||||
self.accessories_0.clone(),
|
||||
self.accessories_1.clone(),
|
||||
self.accessories_2.clone(),
|
||||
self.accessories_3.clone(),
|
||||
self.accessories_4.clone(),
|
||||
self.accessories_5.clone(),
|
||||
self.accessories_6.clone(),
|
||||
self.accessories_7.clone(),
|
||||
self.accessories_8.clone(),
|
||||
]
|
||||
}
|
||||
|
||||
/// Extract emotion layer as array.
|
||||
pub fn emotion_layer(&self) -> [Option<String>; LAYER_SIZE] {
|
||||
[
|
||||
self.emotion_0.clone(),
|
||||
self.emotion_1.clone(),
|
||||
self.emotion_2.clone(),
|
||||
self.emotion_3.clone(),
|
||||
self.emotion_4.clone(),
|
||||
self.emotion_5.clone(),
|
||||
self.emotion_6.clone(),
|
||||
self.emotion_7.clone(),
|
||||
self.emotion_8.clone(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/// Row type for prop asset lookup.
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub struct PropAssetRow {
|
||||
pub id: Uuid,
|
||||
pub asset_path: String,
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Generic Query Helpers
|
||||
// =============================================================================
|
||||
|
||||
/// Build a prop UUID to asset path lookup map.
|
||||
pub async fn build_prop_map<'e>(
|
||||
executor: impl PgExecutor<'e>,
|
||||
prop_ids: &[Uuid],
|
||||
props_table: &str,
|
||||
) -> Result<HashMap<Uuid, String>, AppError> {
|
||||
if prop_ids.is_empty() {
|
||||
return Ok(HashMap::new());
|
||||
}
|
||||
|
||||
let query = format!(
|
||||
r#"
|
||||
SELECT id, asset_path
|
||||
FROM {}
|
||||
WHERE id = ANY($1)
|
||||
"#,
|
||||
props_table
|
||||
);
|
||||
|
||||
let rows = sqlx::query_as::<_, PropAssetRow>(&query)
|
||||
.bind(prop_ids)
|
||||
.fetch_all(executor)
|
||||
.await?;
|
||||
|
||||
Ok(rows.into_iter().map(|r| (r.id, r.asset_path)).collect())
|
||||
}
|
||||
|
||||
/// Resolve avatar slots to render data using a prop map.
|
||||
pub fn resolve_slots_to_render_data(
|
||||
avatar_id: Uuid,
|
||||
slots: &AvatarSlots,
|
||||
current_emotion: EmotionState,
|
||||
prop_map: &HashMap<Uuid, String>,
|
||||
) -> AvatarRenderData {
|
||||
let get_path = |id: Option<Uuid>| -> Option<String> {
|
||||
id.and_then(|id| prop_map.get(&id).cloned())
|
||||
};
|
||||
|
||||
let emotion_layer = slots.emotion_layer(current_emotion);
|
||||
|
||||
AvatarRenderData {
|
||||
avatar_id,
|
||||
current_emotion,
|
||||
skin_layer: [
|
||||
get_path(slots.skin[0]),
|
||||
get_path(slots.skin[1]),
|
||||
get_path(slots.skin[2]),
|
||||
get_path(slots.skin[3]),
|
||||
get_path(slots.skin[4]),
|
||||
get_path(slots.skin[5]),
|
||||
get_path(slots.skin[6]),
|
||||
get_path(slots.skin[7]),
|
||||
get_path(slots.skin[8]),
|
||||
],
|
||||
clothes_layer: [
|
||||
get_path(slots.clothes[0]),
|
||||
get_path(slots.clothes[1]),
|
||||
get_path(slots.clothes[2]),
|
||||
get_path(slots.clothes[3]),
|
||||
get_path(slots.clothes[4]),
|
||||
get_path(slots.clothes[5]),
|
||||
get_path(slots.clothes[6]),
|
||||
get_path(slots.clothes[7]),
|
||||
get_path(slots.clothes[8]),
|
||||
],
|
||||
accessories_layer: [
|
||||
get_path(slots.accessories[0]),
|
||||
get_path(slots.accessories[1]),
|
||||
get_path(slots.accessories[2]),
|
||||
get_path(slots.accessories[3]),
|
||||
get_path(slots.accessories[4]),
|
||||
get_path(slots.accessories[5]),
|
||||
get_path(slots.accessories[6]),
|
||||
get_path(slots.accessories[7]),
|
||||
get_path(slots.accessories[8]),
|
||||
],
|
||||
emotion_layer: [
|
||||
get_path(emotion_layer[0]),
|
||||
get_path(emotion_layer[1]),
|
||||
get_path(emotion_layer[2]),
|
||||
get_path(emotion_layer[3]),
|
||||
get_path(emotion_layer[4]),
|
||||
get_path(emotion_layer[5]),
|
||||
get_path(emotion_layer[6]),
|
||||
get_path(emotion_layer[7]),
|
||||
get_path(emotion_layer[8]),
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// SQL Generation Helpers
|
||||
// =============================================================================
|
||||
|
||||
/// Generate the SELECT clause for avatar paths query.
|
||||
/// Returns the column selections for joining props to get asset paths.
|
||||
pub fn avatar_paths_select_clause() -> &'static str {
|
||||
r#"
|
||||
a.id,
|
||||
a.name,
|
||||
a.description,
|
||||
-- Skin layer
|
||||
p_skin_0.asset_path AS skin_0,
|
||||
p_skin_1.asset_path AS skin_1,
|
||||
p_skin_2.asset_path AS skin_2,
|
||||
p_skin_3.asset_path AS skin_3,
|
||||
p_skin_4.asset_path AS skin_4,
|
||||
p_skin_5.asset_path AS skin_5,
|
||||
p_skin_6.asset_path AS skin_6,
|
||||
p_skin_7.asset_path AS skin_7,
|
||||
p_skin_8.asset_path AS skin_8,
|
||||
-- Clothes layer
|
||||
p_clothes_0.asset_path AS clothes_0,
|
||||
p_clothes_1.asset_path AS clothes_1,
|
||||
p_clothes_2.asset_path AS clothes_2,
|
||||
p_clothes_3.asset_path AS clothes_3,
|
||||
p_clothes_4.asset_path AS clothes_4,
|
||||
p_clothes_5.asset_path AS clothes_5,
|
||||
p_clothes_6.asset_path AS clothes_6,
|
||||
p_clothes_7.asset_path AS clothes_7,
|
||||
p_clothes_8.asset_path AS clothes_8,
|
||||
-- Accessories layer
|
||||
p_acc_0.asset_path AS accessories_0,
|
||||
p_acc_1.asset_path AS accessories_1,
|
||||
p_acc_2.asset_path AS accessories_2,
|
||||
p_acc_3.asset_path AS accessories_3,
|
||||
p_acc_4.asset_path AS accessories_4,
|
||||
p_acc_5.asset_path AS accessories_5,
|
||||
p_acc_6.asset_path AS accessories_6,
|
||||
p_acc_7.asset_path AS accessories_7,
|
||||
p_acc_8.asset_path AS accessories_8,
|
||||
-- Happy emotion layer (e1 - more inviting for store display)
|
||||
p_emo_0.asset_path AS emotion_0,
|
||||
p_emo_1.asset_path AS emotion_1,
|
||||
p_emo_2.asset_path AS emotion_2,
|
||||
p_emo_3.asset_path AS emotion_3,
|
||||
p_emo_4.asset_path AS emotion_4,
|
||||
p_emo_5.asset_path AS emotion_5,
|
||||
p_emo_6.asset_path AS emotion_6,
|
||||
p_emo_7.asset_path AS emotion_7,
|
||||
p_emo_8.asset_path AS emotion_8
|
||||
"#
|
||||
}
|
||||
|
||||
/// Generate the JOIN clause for avatar paths query.
|
||||
/// `props_table` should be "server.props" or "realm.props".
|
||||
pub fn avatar_paths_join_clause(props_table: &str) -> String {
|
||||
format!(
|
||||
r#"
|
||||
-- Skin layer joins
|
||||
LEFT JOIN {props} p_skin_0 ON a.l_skin_0 = p_skin_0.id
|
||||
LEFT JOIN {props} p_skin_1 ON a.l_skin_1 = p_skin_1.id
|
||||
LEFT JOIN {props} p_skin_2 ON a.l_skin_2 = p_skin_2.id
|
||||
LEFT JOIN {props} p_skin_3 ON a.l_skin_3 = p_skin_3.id
|
||||
LEFT JOIN {props} p_skin_4 ON a.l_skin_4 = p_skin_4.id
|
||||
LEFT JOIN {props} p_skin_5 ON a.l_skin_5 = p_skin_5.id
|
||||
LEFT JOIN {props} p_skin_6 ON a.l_skin_6 = p_skin_6.id
|
||||
LEFT JOIN {props} p_skin_7 ON a.l_skin_7 = p_skin_7.id
|
||||
LEFT JOIN {props} p_skin_8 ON a.l_skin_8 = p_skin_8.id
|
||||
-- Clothes layer joins
|
||||
LEFT JOIN {props} p_clothes_0 ON a.l_clothes_0 = p_clothes_0.id
|
||||
LEFT JOIN {props} p_clothes_1 ON a.l_clothes_1 = p_clothes_1.id
|
||||
LEFT JOIN {props} p_clothes_2 ON a.l_clothes_2 = p_clothes_2.id
|
||||
LEFT JOIN {props} p_clothes_3 ON a.l_clothes_3 = p_clothes_3.id
|
||||
LEFT JOIN {props} p_clothes_4 ON a.l_clothes_4 = p_clothes_4.id
|
||||
LEFT JOIN {props} p_clothes_5 ON a.l_clothes_5 = p_clothes_5.id
|
||||
LEFT JOIN {props} p_clothes_6 ON a.l_clothes_6 = p_clothes_6.id
|
||||
LEFT JOIN {props} p_clothes_7 ON a.l_clothes_7 = p_clothes_7.id
|
||||
LEFT JOIN {props} p_clothes_8 ON a.l_clothes_8 = p_clothes_8.id
|
||||
-- Accessories layer joins
|
||||
LEFT JOIN {props} p_acc_0 ON a.l_accessories_0 = p_acc_0.id
|
||||
LEFT JOIN {props} p_acc_1 ON a.l_accessories_1 = p_acc_1.id
|
||||
LEFT JOIN {props} p_acc_2 ON a.l_accessories_2 = p_acc_2.id
|
||||
LEFT JOIN {props} p_acc_3 ON a.l_accessories_3 = p_acc_3.id
|
||||
LEFT JOIN {props} p_acc_4 ON a.l_accessories_4 = p_acc_4.id
|
||||
LEFT JOIN {props} p_acc_5 ON a.l_accessories_5 = p_acc_5.id
|
||||
LEFT JOIN {props} p_acc_6 ON a.l_accessories_6 = p_acc_6.id
|
||||
LEFT JOIN {props} p_acc_7 ON a.l_accessories_7 = p_acc_7.id
|
||||
LEFT JOIN {props} p_acc_8 ON a.l_accessories_8 = p_acc_8.id
|
||||
-- Happy emotion layer joins (e1 - more inviting for store display)
|
||||
LEFT JOIN {props} p_emo_0 ON a.e_happy_0 = p_emo_0.id
|
||||
LEFT JOIN {props} p_emo_1 ON a.e_happy_1 = p_emo_1.id
|
||||
LEFT JOIN {props} p_emo_2 ON a.e_happy_2 = p_emo_2.id
|
||||
LEFT JOIN {props} p_emo_3 ON a.e_happy_3 = p_emo_3.id
|
||||
LEFT JOIN {props} p_emo_4 ON a.e_happy_4 = p_emo_4.id
|
||||
LEFT JOIN {props} p_emo_5 ON a.e_happy_5 = p_emo_5.id
|
||||
LEFT JOIN {props} p_emo_6 ON a.e_happy_6 = p_emo_6.id
|
||||
LEFT JOIN {props} p_emo_7 ON a.e_happy_7 = p_emo_7.id
|
||||
LEFT JOIN {props} p_emo_8 ON a.e_happy_8 = p_emo_8.id
|
||||
"#,
|
||||
props = props_table
|
||||
)
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Macros for Avatar Slot Extraction
|
||||
// =============================================================================
|
||||
|
||||
/// Extract AvatarSlots from an avatar struct with the standard field naming.
|
||||
/// Works with both ServerAvatar and RealmAvatar.
|
||||
#[macro_export]
|
||||
macro_rules! extract_avatar_slots {
|
||||
($avatar:expr) => {{
|
||||
use $crate::queries::avatar_common::AvatarSlots;
|
||||
|
||||
AvatarSlots {
|
||||
skin: [
|
||||
$avatar.l_skin_0,
|
||||
$avatar.l_skin_1,
|
||||
$avatar.l_skin_2,
|
||||
$avatar.l_skin_3,
|
||||
$avatar.l_skin_4,
|
||||
$avatar.l_skin_5,
|
||||
$avatar.l_skin_6,
|
||||
$avatar.l_skin_7,
|
||||
$avatar.l_skin_8,
|
||||
],
|
||||
clothes: [
|
||||
$avatar.l_clothes_0,
|
||||
$avatar.l_clothes_1,
|
||||
$avatar.l_clothes_2,
|
||||
$avatar.l_clothes_3,
|
||||
$avatar.l_clothes_4,
|
||||
$avatar.l_clothes_5,
|
||||
$avatar.l_clothes_6,
|
||||
$avatar.l_clothes_7,
|
||||
$avatar.l_clothes_8,
|
||||
],
|
||||
accessories: [
|
||||
$avatar.l_accessories_0,
|
||||
$avatar.l_accessories_1,
|
||||
$avatar.l_accessories_2,
|
||||
$avatar.l_accessories_3,
|
||||
$avatar.l_accessories_4,
|
||||
$avatar.l_accessories_5,
|
||||
$avatar.l_accessories_6,
|
||||
$avatar.l_accessories_7,
|
||||
$avatar.l_accessories_8,
|
||||
],
|
||||
emotions: [
|
||||
// Neutral (e0)
|
||||
[
|
||||
$avatar.e_neutral_0,
|
||||
$avatar.e_neutral_1,
|
||||
$avatar.e_neutral_2,
|
||||
$avatar.e_neutral_3,
|
||||
$avatar.e_neutral_4,
|
||||
$avatar.e_neutral_5,
|
||||
$avatar.e_neutral_6,
|
||||
$avatar.e_neutral_7,
|
||||
$avatar.e_neutral_8,
|
||||
],
|
||||
// Happy (e1)
|
||||
[
|
||||
$avatar.e_happy_0,
|
||||
$avatar.e_happy_1,
|
||||
$avatar.e_happy_2,
|
||||
$avatar.e_happy_3,
|
||||
$avatar.e_happy_4,
|
||||
$avatar.e_happy_5,
|
||||
$avatar.e_happy_6,
|
||||
$avatar.e_happy_7,
|
||||
$avatar.e_happy_8,
|
||||
],
|
||||
// Sad (e2)
|
||||
[
|
||||
$avatar.e_sad_0,
|
||||
$avatar.e_sad_1,
|
||||
$avatar.e_sad_2,
|
||||
$avatar.e_sad_3,
|
||||
$avatar.e_sad_4,
|
||||
$avatar.e_sad_5,
|
||||
$avatar.e_sad_6,
|
||||
$avatar.e_sad_7,
|
||||
$avatar.e_sad_8,
|
||||
],
|
||||
// Angry (e3)
|
||||
[
|
||||
$avatar.e_angry_0,
|
||||
$avatar.e_angry_1,
|
||||
$avatar.e_angry_2,
|
||||
$avatar.e_angry_3,
|
||||
$avatar.e_angry_4,
|
||||
$avatar.e_angry_5,
|
||||
$avatar.e_angry_6,
|
||||
$avatar.e_angry_7,
|
||||
$avatar.e_angry_8,
|
||||
],
|
||||
// Surprised (e4)
|
||||
[
|
||||
$avatar.e_surprised_0,
|
||||
$avatar.e_surprised_1,
|
||||
$avatar.e_surprised_2,
|
||||
$avatar.e_surprised_3,
|
||||
$avatar.e_surprised_4,
|
||||
$avatar.e_surprised_5,
|
||||
$avatar.e_surprised_6,
|
||||
$avatar.e_surprised_7,
|
||||
$avatar.e_surprised_8,
|
||||
],
|
||||
// Thinking (e5)
|
||||
[
|
||||
$avatar.e_thinking_0,
|
||||
$avatar.e_thinking_1,
|
||||
$avatar.e_thinking_2,
|
||||
$avatar.e_thinking_3,
|
||||
$avatar.e_thinking_4,
|
||||
$avatar.e_thinking_5,
|
||||
$avatar.e_thinking_6,
|
||||
$avatar.e_thinking_7,
|
||||
$avatar.e_thinking_8,
|
||||
],
|
||||
// Laughing (e6)
|
||||
[
|
||||
$avatar.e_laughing_0,
|
||||
$avatar.e_laughing_1,
|
||||
$avatar.e_laughing_2,
|
||||
$avatar.e_laughing_3,
|
||||
$avatar.e_laughing_4,
|
||||
$avatar.e_laughing_5,
|
||||
$avatar.e_laughing_6,
|
||||
$avatar.e_laughing_7,
|
||||
$avatar.e_laughing_8,
|
||||
],
|
||||
// Crying (e7)
|
||||
[
|
||||
$avatar.e_crying_0,
|
||||
$avatar.e_crying_1,
|
||||
$avatar.e_crying_2,
|
||||
$avatar.e_crying_3,
|
||||
$avatar.e_crying_4,
|
||||
$avatar.e_crying_5,
|
||||
$avatar.e_crying_6,
|
||||
$avatar.e_crying_7,
|
||||
$avatar.e_crying_8,
|
||||
],
|
||||
// Love (e8)
|
||||
[
|
||||
$avatar.e_love_0,
|
||||
$avatar.e_love_1,
|
||||
$avatar.e_love_2,
|
||||
$avatar.e_love_3,
|
||||
$avatar.e_love_4,
|
||||
$avatar.e_love_5,
|
||||
$avatar.e_love_6,
|
||||
$avatar.e_love_7,
|
||||
$avatar.e_love_8,
|
||||
],
|
||||
// Confused (e9)
|
||||
[
|
||||
$avatar.e_confused_0,
|
||||
$avatar.e_confused_1,
|
||||
$avatar.e_confused_2,
|
||||
$avatar.e_confused_3,
|
||||
$avatar.e_confused_4,
|
||||
$avatar.e_confused_5,
|
||||
$avatar.e_confused_6,
|
||||
$avatar.e_confused_7,
|
||||
$avatar.e_confused_8,
|
||||
],
|
||||
// Sleeping (e10)
|
||||
[
|
||||
$avatar.e_sleeping_0,
|
||||
$avatar.e_sleeping_1,
|
||||
$avatar.e_sleeping_2,
|
||||
$avatar.e_sleeping_3,
|
||||
$avatar.e_sleeping_4,
|
||||
$avatar.e_sleeping_5,
|
||||
$avatar.e_sleeping_6,
|
||||
$avatar.e_sleeping_7,
|
||||
$avatar.e_sleeping_8,
|
||||
],
|
||||
// Wink (e11)
|
||||
[
|
||||
$avatar.e_wink_0,
|
||||
$avatar.e_wink_1,
|
||||
$avatar.e_wink_2,
|
||||
$avatar.e_wink_3,
|
||||
$avatar.e_wink_4,
|
||||
$avatar.e_wink_5,
|
||||
$avatar.e_wink_6,
|
||||
$avatar.e_wink_7,
|
||||
$avatar.e_wink_8,
|
||||
],
|
||||
],
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
pub use extract_avatar_slots;
|
||||
|
|
@ -3,15 +3,22 @@
|
|||
//! Realm avatars are pre-configured avatar configurations specific to a realm.
|
||||
//! They reference realm.props directly (not inventory items).
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use chrono::{Duration, Utc};
|
||||
use sqlx::PgExecutor;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::models::{AvatarRenderData, EmotionState, RealmAvatar};
|
||||
use crate::extract_avatar_slots;
|
||||
use crate::models::{AvatarRenderData, EmotionState, RealmAvatar, RealmAvatarWithPaths};
|
||||
use crate::queries::avatar_common::{
|
||||
avatar_paths_join_clause, avatar_paths_select_clause, build_prop_map,
|
||||
resolve_slots_to_render_data,
|
||||
};
|
||||
use chattyness_error::AppError;
|
||||
|
||||
// =============================================================================
|
||||
// Basic Queries
|
||||
// =============================================================================
|
||||
|
||||
/// Get a realm avatar by slug within a realm.
|
||||
pub async fn get_realm_avatar_by_slug<'e>(
|
||||
executor: impl PgExecutor<'e>,
|
||||
|
|
@ -72,7 +79,9 @@ pub async fn list_public_realm_avatars<'e>(
|
|||
Ok(avatars)
|
||||
}
|
||||
|
||||
use crate::models::RealmAvatarWithPaths;
|
||||
// =============================================================================
|
||||
// Avatar with Paths Queries
|
||||
// =============================================================================
|
||||
|
||||
/// Row type for realm avatar with paths query.
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
|
|
@ -110,7 +119,7 @@ struct RealmAvatarWithPathsRow {
|
|||
accessories_6: Option<String>,
|
||||
accessories_7: Option<String>,
|
||||
accessories_8: Option<String>,
|
||||
// Happy emotion layer paths (e1 - more inviting for store display)
|
||||
// Happy emotion layer paths
|
||||
emotion_0: Option<String>,
|
||||
emotion_1: Option<String>,
|
||||
emotion_2: Option<String>,
|
||||
|
|
@ -153,104 +162,25 @@ impl From<RealmAvatarWithPathsRow> for RealmAvatarWithPaths {
|
|||
}
|
||||
|
||||
/// List all active public realm avatars with resolved asset paths.
|
||||
///
|
||||
/// Joins with the props table to resolve prop UUIDs to asset paths,
|
||||
/// suitable for client-side rendering without additional lookups.
|
||||
pub async fn list_public_realm_avatars_with_paths<'e>(
|
||||
executor: impl PgExecutor<'e>,
|
||||
realm_id: Uuid,
|
||||
) -> Result<Vec<RealmAvatarWithPaths>, AppError> {
|
||||
let rows = sqlx::query_as::<_, RealmAvatarWithPathsRow>(
|
||||
let join_clause = avatar_paths_join_clause("realm.props");
|
||||
let query = format!(
|
||||
r#"
|
||||
SELECT
|
||||
a.id,
|
||||
a.name,
|
||||
a.description,
|
||||
-- Skin layer
|
||||
p_skin_0.asset_path AS skin_0,
|
||||
p_skin_1.asset_path AS skin_1,
|
||||
p_skin_2.asset_path AS skin_2,
|
||||
p_skin_3.asset_path AS skin_3,
|
||||
p_skin_4.asset_path AS skin_4,
|
||||
p_skin_5.asset_path AS skin_5,
|
||||
p_skin_6.asset_path AS skin_6,
|
||||
p_skin_7.asset_path AS skin_7,
|
||||
p_skin_8.asset_path AS skin_8,
|
||||
-- Clothes layer
|
||||
p_clothes_0.asset_path AS clothes_0,
|
||||
p_clothes_1.asset_path AS clothes_1,
|
||||
p_clothes_2.asset_path AS clothes_2,
|
||||
p_clothes_3.asset_path AS clothes_3,
|
||||
p_clothes_4.asset_path AS clothes_4,
|
||||
p_clothes_5.asset_path AS clothes_5,
|
||||
p_clothes_6.asset_path AS clothes_6,
|
||||
p_clothes_7.asset_path AS clothes_7,
|
||||
p_clothes_8.asset_path AS clothes_8,
|
||||
-- Accessories layer
|
||||
p_acc_0.asset_path AS accessories_0,
|
||||
p_acc_1.asset_path AS accessories_1,
|
||||
p_acc_2.asset_path AS accessories_2,
|
||||
p_acc_3.asset_path AS accessories_3,
|
||||
p_acc_4.asset_path AS accessories_4,
|
||||
p_acc_5.asset_path AS accessories_5,
|
||||
p_acc_6.asset_path AS accessories_6,
|
||||
p_acc_7.asset_path AS accessories_7,
|
||||
p_acc_8.asset_path AS accessories_8,
|
||||
-- Happy emotion layer (e1 - more inviting for store display)
|
||||
p_emo_0.asset_path AS emotion_0,
|
||||
p_emo_1.asset_path AS emotion_1,
|
||||
p_emo_2.asset_path AS emotion_2,
|
||||
p_emo_3.asset_path AS emotion_3,
|
||||
p_emo_4.asset_path AS emotion_4,
|
||||
p_emo_5.asset_path AS emotion_5,
|
||||
p_emo_6.asset_path AS emotion_6,
|
||||
p_emo_7.asset_path AS emotion_7,
|
||||
p_emo_8.asset_path AS emotion_8
|
||||
{}
|
||||
FROM realm.avatars a
|
||||
-- Skin layer joins
|
||||
LEFT JOIN realm.props p_skin_0 ON a.l_skin_0 = p_skin_0.id
|
||||
LEFT JOIN realm.props p_skin_1 ON a.l_skin_1 = p_skin_1.id
|
||||
LEFT JOIN realm.props p_skin_2 ON a.l_skin_2 = p_skin_2.id
|
||||
LEFT JOIN realm.props p_skin_3 ON a.l_skin_3 = p_skin_3.id
|
||||
LEFT JOIN realm.props p_skin_4 ON a.l_skin_4 = p_skin_4.id
|
||||
LEFT JOIN realm.props p_skin_5 ON a.l_skin_5 = p_skin_5.id
|
||||
LEFT JOIN realm.props p_skin_6 ON a.l_skin_6 = p_skin_6.id
|
||||
LEFT JOIN realm.props p_skin_7 ON a.l_skin_7 = p_skin_7.id
|
||||
LEFT JOIN realm.props p_skin_8 ON a.l_skin_8 = p_skin_8.id
|
||||
-- Clothes layer joins
|
||||
LEFT JOIN realm.props p_clothes_0 ON a.l_clothes_0 = p_clothes_0.id
|
||||
LEFT JOIN realm.props p_clothes_1 ON a.l_clothes_1 = p_clothes_1.id
|
||||
LEFT JOIN realm.props p_clothes_2 ON a.l_clothes_2 = p_clothes_2.id
|
||||
LEFT JOIN realm.props p_clothes_3 ON a.l_clothes_3 = p_clothes_3.id
|
||||
LEFT JOIN realm.props p_clothes_4 ON a.l_clothes_4 = p_clothes_4.id
|
||||
LEFT JOIN realm.props p_clothes_5 ON a.l_clothes_5 = p_clothes_5.id
|
||||
LEFT JOIN realm.props p_clothes_6 ON a.l_clothes_6 = p_clothes_6.id
|
||||
LEFT JOIN realm.props p_clothes_7 ON a.l_clothes_7 = p_clothes_7.id
|
||||
LEFT JOIN realm.props p_clothes_8 ON a.l_clothes_8 = p_clothes_8.id
|
||||
-- Accessories layer joins
|
||||
LEFT JOIN realm.props p_acc_0 ON a.l_accessories_0 = p_acc_0.id
|
||||
LEFT JOIN realm.props p_acc_1 ON a.l_accessories_1 = p_acc_1.id
|
||||
LEFT JOIN realm.props p_acc_2 ON a.l_accessories_2 = p_acc_2.id
|
||||
LEFT JOIN realm.props p_acc_3 ON a.l_accessories_3 = p_acc_3.id
|
||||
LEFT JOIN realm.props p_acc_4 ON a.l_accessories_4 = p_acc_4.id
|
||||
LEFT JOIN realm.props p_acc_5 ON a.l_accessories_5 = p_acc_5.id
|
||||
LEFT JOIN realm.props p_acc_6 ON a.l_accessories_6 = p_acc_6.id
|
||||
LEFT JOIN realm.props p_acc_7 ON a.l_accessories_7 = p_acc_7.id
|
||||
LEFT JOIN realm.props p_acc_8 ON a.l_accessories_8 = p_acc_8.id
|
||||
-- Happy emotion layer joins (e1 - more inviting for store display)
|
||||
LEFT JOIN realm.props p_emo_0 ON a.e_happy_0 = p_emo_0.id
|
||||
LEFT JOIN realm.props p_emo_1 ON a.e_happy_1 = p_emo_1.id
|
||||
LEFT JOIN realm.props p_emo_2 ON a.e_happy_2 = p_emo_2.id
|
||||
LEFT JOIN realm.props p_emo_3 ON a.e_happy_3 = p_emo_3.id
|
||||
LEFT JOIN realm.props p_emo_4 ON a.e_happy_4 = p_emo_4.id
|
||||
LEFT JOIN realm.props p_emo_5 ON a.e_happy_5 = p_emo_5.id
|
||||
LEFT JOIN realm.props p_emo_6 ON a.e_happy_6 = p_emo_6.id
|
||||
LEFT JOIN realm.props p_emo_7 ON a.e_happy_7 = p_emo_7.id
|
||||
LEFT JOIN realm.props p_emo_8 ON a.e_happy_8 = p_emo_8.id
|
||||
{}
|
||||
WHERE a.realm_id = $1 AND a.is_active = true AND a.is_public = true
|
||||
ORDER BY a.name ASC
|
||||
"#,
|
||||
)
|
||||
avatar_paths_select_clause(),
|
||||
join_clause
|
||||
);
|
||||
|
||||
let rows = sqlx::query_as::<_, RealmAvatarWithPathsRow>(&query)
|
||||
.bind(realm_id)
|
||||
.fetch_all(executor)
|
||||
.await?;
|
||||
|
|
@ -258,130 +188,25 @@ pub async fn list_public_realm_avatars_with_paths<'e>(
|
|||
Ok(rows.into_iter().map(RealmAvatarWithPaths::from).collect())
|
||||
}
|
||||
|
||||
/// Row type for prop asset lookup.
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
struct PropAssetRow {
|
||||
id: Uuid,
|
||||
asset_path: String,
|
||||
}
|
||||
// =============================================================================
|
||||
// Render Data Resolution
|
||||
// =============================================================================
|
||||
|
||||
/// Resolve a realm avatar to render data.
|
||||
/// Joins the avatar's prop UUIDs with realm.props to get asset paths.
|
||||
pub async fn resolve_realm_avatar_to_render_data<'e>(
|
||||
executor: impl PgExecutor<'e>,
|
||||
avatar: &RealmAvatar,
|
||||
current_emotion: EmotionState,
|
||||
) -> Result<AvatarRenderData, AppError> {
|
||||
// Collect all non-null prop UUIDs
|
||||
let mut prop_ids: Vec<Uuid> = Vec::new();
|
||||
|
||||
// Content layers
|
||||
for id in [
|
||||
avatar.l_skin_0, avatar.l_skin_1, avatar.l_skin_2,
|
||||
avatar.l_skin_3, avatar.l_skin_4, avatar.l_skin_5,
|
||||
avatar.l_skin_6, avatar.l_skin_7, avatar.l_skin_8,
|
||||
avatar.l_clothes_0, avatar.l_clothes_1, avatar.l_clothes_2,
|
||||
avatar.l_clothes_3, avatar.l_clothes_4, avatar.l_clothes_5,
|
||||
avatar.l_clothes_6, avatar.l_clothes_7, avatar.l_clothes_8,
|
||||
avatar.l_accessories_0, avatar.l_accessories_1, avatar.l_accessories_2,
|
||||
avatar.l_accessories_3, avatar.l_accessories_4, avatar.l_accessories_5,
|
||||
avatar.l_accessories_6, avatar.l_accessories_7, avatar.l_accessories_8,
|
||||
].iter().flatten() {
|
||||
prop_ids.push(*id);
|
||||
let slots = extract_avatar_slots!(avatar);
|
||||
let prop_ids = slots.collect_render_prop_ids(current_emotion);
|
||||
let prop_map = build_prop_map(executor, &prop_ids, "realm.props").await?;
|
||||
Ok(resolve_slots_to_render_data(avatar.id, &slots, current_emotion, &prop_map))
|
||||
}
|
||||
|
||||
// Get emotion layer slots based on current emotion
|
||||
let emotion_slots: [Option<Uuid>; 9] = match current_emotion {
|
||||
EmotionState::Neutral => [avatar.e_neutral_0, avatar.e_neutral_1, avatar.e_neutral_2,
|
||||
avatar.e_neutral_3, avatar.e_neutral_4, avatar.e_neutral_5,
|
||||
avatar.e_neutral_6, avatar.e_neutral_7, avatar.e_neutral_8],
|
||||
EmotionState::Happy => [avatar.e_happy_0, avatar.e_happy_1, avatar.e_happy_2,
|
||||
avatar.e_happy_3, avatar.e_happy_4, avatar.e_happy_5,
|
||||
avatar.e_happy_6, avatar.e_happy_7, avatar.e_happy_8],
|
||||
EmotionState::Sad => [avatar.e_sad_0, avatar.e_sad_1, avatar.e_sad_2,
|
||||
avatar.e_sad_3, avatar.e_sad_4, avatar.e_sad_5,
|
||||
avatar.e_sad_6, avatar.e_sad_7, avatar.e_sad_8],
|
||||
EmotionState::Angry => [avatar.e_angry_0, avatar.e_angry_1, avatar.e_angry_2,
|
||||
avatar.e_angry_3, avatar.e_angry_4, avatar.e_angry_5,
|
||||
avatar.e_angry_6, avatar.e_angry_7, avatar.e_angry_8],
|
||||
EmotionState::Surprised => [avatar.e_surprised_0, avatar.e_surprised_1, avatar.e_surprised_2,
|
||||
avatar.e_surprised_3, avatar.e_surprised_4, avatar.e_surprised_5,
|
||||
avatar.e_surprised_6, avatar.e_surprised_7, avatar.e_surprised_8],
|
||||
EmotionState::Thinking => [avatar.e_thinking_0, avatar.e_thinking_1, avatar.e_thinking_2,
|
||||
avatar.e_thinking_3, avatar.e_thinking_4, avatar.e_thinking_5,
|
||||
avatar.e_thinking_6, avatar.e_thinking_7, avatar.e_thinking_8],
|
||||
EmotionState::Laughing => [avatar.e_laughing_0, avatar.e_laughing_1, avatar.e_laughing_2,
|
||||
avatar.e_laughing_3, avatar.e_laughing_4, avatar.e_laughing_5,
|
||||
avatar.e_laughing_6, avatar.e_laughing_7, avatar.e_laughing_8],
|
||||
EmotionState::Crying => [avatar.e_crying_0, avatar.e_crying_1, avatar.e_crying_2,
|
||||
avatar.e_crying_3, avatar.e_crying_4, avatar.e_crying_5,
|
||||
avatar.e_crying_6, avatar.e_crying_7, avatar.e_crying_8],
|
||||
EmotionState::Love => [avatar.e_love_0, avatar.e_love_1, avatar.e_love_2,
|
||||
avatar.e_love_3, avatar.e_love_4, avatar.e_love_5,
|
||||
avatar.e_love_6, avatar.e_love_7, avatar.e_love_8],
|
||||
EmotionState::Confused => [avatar.e_confused_0, avatar.e_confused_1, avatar.e_confused_2,
|
||||
avatar.e_confused_3, avatar.e_confused_4, avatar.e_confused_5,
|
||||
avatar.e_confused_6, avatar.e_confused_7, avatar.e_confused_8],
|
||||
EmotionState::Sleeping => [avatar.e_sleeping_0, avatar.e_sleeping_1, avatar.e_sleeping_2,
|
||||
avatar.e_sleeping_3, avatar.e_sleeping_4, avatar.e_sleeping_5,
|
||||
avatar.e_sleeping_6, avatar.e_sleeping_7, avatar.e_sleeping_8],
|
||||
EmotionState::Wink => [avatar.e_wink_0, avatar.e_wink_1, avatar.e_wink_2,
|
||||
avatar.e_wink_3, avatar.e_wink_4, avatar.e_wink_5,
|
||||
avatar.e_wink_6, avatar.e_wink_7, avatar.e_wink_8],
|
||||
};
|
||||
|
||||
for id in emotion_slots.iter().flatten() {
|
||||
prop_ids.push(*id);
|
||||
}
|
||||
|
||||
// Bulk lookup all prop asset paths from realm.props
|
||||
let prop_map: HashMap<Uuid, String> = if prop_ids.is_empty() {
|
||||
HashMap::new()
|
||||
} else {
|
||||
let rows = sqlx::query_as::<_, PropAssetRow>(
|
||||
r#"
|
||||
SELECT id, asset_path
|
||||
FROM realm.props
|
||||
WHERE id = ANY($1)
|
||||
"#,
|
||||
)
|
||||
.bind(&prop_ids)
|
||||
.fetch_all(executor)
|
||||
.await?;
|
||||
|
||||
rows.into_iter().map(|r| (r.id, r.asset_path)).collect()
|
||||
};
|
||||
|
||||
// Helper to look up path
|
||||
let get_path = |id: Option<Uuid>| -> Option<String> {
|
||||
id.and_then(|id| prop_map.get(&id).cloned())
|
||||
};
|
||||
|
||||
Ok(AvatarRenderData {
|
||||
avatar_id: avatar.id,
|
||||
current_emotion,
|
||||
skin_layer: [
|
||||
get_path(avatar.l_skin_0), get_path(avatar.l_skin_1), get_path(avatar.l_skin_2),
|
||||
get_path(avatar.l_skin_3), get_path(avatar.l_skin_4), get_path(avatar.l_skin_5),
|
||||
get_path(avatar.l_skin_6), get_path(avatar.l_skin_7), get_path(avatar.l_skin_8),
|
||||
],
|
||||
clothes_layer: [
|
||||
get_path(avatar.l_clothes_0), get_path(avatar.l_clothes_1), get_path(avatar.l_clothes_2),
|
||||
get_path(avatar.l_clothes_3), get_path(avatar.l_clothes_4), get_path(avatar.l_clothes_5),
|
||||
get_path(avatar.l_clothes_6), get_path(avatar.l_clothes_7), get_path(avatar.l_clothes_8),
|
||||
],
|
||||
accessories_layer: [
|
||||
get_path(avatar.l_accessories_0), get_path(avatar.l_accessories_1), get_path(avatar.l_accessories_2),
|
||||
get_path(avatar.l_accessories_3), get_path(avatar.l_accessories_4), get_path(avatar.l_accessories_5),
|
||||
get_path(avatar.l_accessories_6), get_path(avatar.l_accessories_7), get_path(avatar.l_accessories_8),
|
||||
],
|
||||
emotion_layer: [
|
||||
get_path(emotion_slots[0]), get_path(emotion_slots[1]), get_path(emotion_slots[2]),
|
||||
get_path(emotion_slots[3]), get_path(emotion_slots[4]), get_path(emotion_slots[5]),
|
||||
get_path(emotion_slots[6]), get_path(emotion_slots[7]), get_path(emotion_slots[8]),
|
||||
],
|
||||
})
|
||||
}
|
||||
// =============================================================================
|
||||
// Forced Avatar Management
|
||||
// =============================================================================
|
||||
|
||||
/// Apply a forced realm avatar to a user.
|
||||
pub async fn apply_forced_realm_avatar<'e>(
|
||||
|
|
@ -576,155 +401,65 @@ pub async fn create_realm_avatar<'e>(
|
|||
.bind(&req.thumbnail_path)
|
||||
.bind(created_by)
|
||||
// Skin layer
|
||||
.bind(req.l_skin_0)
|
||||
.bind(req.l_skin_1)
|
||||
.bind(req.l_skin_2)
|
||||
.bind(req.l_skin_3)
|
||||
.bind(req.l_skin_4)
|
||||
.bind(req.l_skin_5)
|
||||
.bind(req.l_skin_6)
|
||||
.bind(req.l_skin_7)
|
||||
.bind(req.l_skin_8)
|
||||
.bind(req.l_skin_0).bind(req.l_skin_1).bind(req.l_skin_2)
|
||||
.bind(req.l_skin_3).bind(req.l_skin_4).bind(req.l_skin_5)
|
||||
.bind(req.l_skin_6).bind(req.l_skin_7).bind(req.l_skin_8)
|
||||
// Clothes layer
|
||||
.bind(req.l_clothes_0)
|
||||
.bind(req.l_clothes_1)
|
||||
.bind(req.l_clothes_2)
|
||||
.bind(req.l_clothes_3)
|
||||
.bind(req.l_clothes_4)
|
||||
.bind(req.l_clothes_5)
|
||||
.bind(req.l_clothes_6)
|
||||
.bind(req.l_clothes_7)
|
||||
.bind(req.l_clothes_8)
|
||||
.bind(req.l_clothes_0).bind(req.l_clothes_1).bind(req.l_clothes_2)
|
||||
.bind(req.l_clothes_3).bind(req.l_clothes_4).bind(req.l_clothes_5)
|
||||
.bind(req.l_clothes_6).bind(req.l_clothes_7).bind(req.l_clothes_8)
|
||||
// Accessories layer
|
||||
.bind(req.l_accessories_0)
|
||||
.bind(req.l_accessories_1)
|
||||
.bind(req.l_accessories_2)
|
||||
.bind(req.l_accessories_3)
|
||||
.bind(req.l_accessories_4)
|
||||
.bind(req.l_accessories_5)
|
||||
.bind(req.l_accessories_6)
|
||||
.bind(req.l_accessories_7)
|
||||
.bind(req.l_accessories_8)
|
||||
.bind(req.l_accessories_0).bind(req.l_accessories_1).bind(req.l_accessories_2)
|
||||
.bind(req.l_accessories_3).bind(req.l_accessories_4).bind(req.l_accessories_5)
|
||||
.bind(req.l_accessories_6).bind(req.l_accessories_7).bind(req.l_accessories_8)
|
||||
// Neutral emotion
|
||||
.bind(req.e_neutral_0)
|
||||
.bind(req.e_neutral_1)
|
||||
.bind(req.e_neutral_2)
|
||||
.bind(req.e_neutral_3)
|
||||
.bind(req.e_neutral_4)
|
||||
.bind(req.e_neutral_5)
|
||||
.bind(req.e_neutral_6)
|
||||
.bind(req.e_neutral_7)
|
||||
.bind(req.e_neutral_8)
|
||||
.bind(req.e_neutral_0).bind(req.e_neutral_1).bind(req.e_neutral_2)
|
||||
.bind(req.e_neutral_3).bind(req.e_neutral_4).bind(req.e_neutral_5)
|
||||
.bind(req.e_neutral_6).bind(req.e_neutral_7).bind(req.e_neutral_8)
|
||||
// Happy emotion
|
||||
.bind(req.e_happy_0)
|
||||
.bind(req.e_happy_1)
|
||||
.bind(req.e_happy_2)
|
||||
.bind(req.e_happy_3)
|
||||
.bind(req.e_happy_4)
|
||||
.bind(req.e_happy_5)
|
||||
.bind(req.e_happy_6)
|
||||
.bind(req.e_happy_7)
|
||||
.bind(req.e_happy_8)
|
||||
.bind(req.e_happy_0).bind(req.e_happy_1).bind(req.e_happy_2)
|
||||
.bind(req.e_happy_3).bind(req.e_happy_4).bind(req.e_happy_5)
|
||||
.bind(req.e_happy_6).bind(req.e_happy_7).bind(req.e_happy_8)
|
||||
// Sad emotion
|
||||
.bind(req.e_sad_0)
|
||||
.bind(req.e_sad_1)
|
||||
.bind(req.e_sad_2)
|
||||
.bind(req.e_sad_3)
|
||||
.bind(req.e_sad_4)
|
||||
.bind(req.e_sad_5)
|
||||
.bind(req.e_sad_6)
|
||||
.bind(req.e_sad_7)
|
||||
.bind(req.e_sad_8)
|
||||
.bind(req.e_sad_0).bind(req.e_sad_1).bind(req.e_sad_2)
|
||||
.bind(req.e_sad_3).bind(req.e_sad_4).bind(req.e_sad_5)
|
||||
.bind(req.e_sad_6).bind(req.e_sad_7).bind(req.e_sad_8)
|
||||
// Angry emotion
|
||||
.bind(req.e_angry_0)
|
||||
.bind(req.e_angry_1)
|
||||
.bind(req.e_angry_2)
|
||||
.bind(req.e_angry_3)
|
||||
.bind(req.e_angry_4)
|
||||
.bind(req.e_angry_5)
|
||||
.bind(req.e_angry_6)
|
||||
.bind(req.e_angry_7)
|
||||
.bind(req.e_angry_8)
|
||||
.bind(req.e_angry_0).bind(req.e_angry_1).bind(req.e_angry_2)
|
||||
.bind(req.e_angry_3).bind(req.e_angry_4).bind(req.e_angry_5)
|
||||
.bind(req.e_angry_6).bind(req.e_angry_7).bind(req.e_angry_8)
|
||||
// Surprised emotion
|
||||
.bind(req.e_surprised_0)
|
||||
.bind(req.e_surprised_1)
|
||||
.bind(req.e_surprised_2)
|
||||
.bind(req.e_surprised_3)
|
||||
.bind(req.e_surprised_4)
|
||||
.bind(req.e_surprised_5)
|
||||
.bind(req.e_surprised_6)
|
||||
.bind(req.e_surprised_7)
|
||||
.bind(req.e_surprised_8)
|
||||
.bind(req.e_surprised_0).bind(req.e_surprised_1).bind(req.e_surprised_2)
|
||||
.bind(req.e_surprised_3).bind(req.e_surprised_4).bind(req.e_surprised_5)
|
||||
.bind(req.e_surprised_6).bind(req.e_surprised_7).bind(req.e_surprised_8)
|
||||
// Thinking emotion
|
||||
.bind(req.e_thinking_0)
|
||||
.bind(req.e_thinking_1)
|
||||
.bind(req.e_thinking_2)
|
||||
.bind(req.e_thinking_3)
|
||||
.bind(req.e_thinking_4)
|
||||
.bind(req.e_thinking_5)
|
||||
.bind(req.e_thinking_6)
|
||||
.bind(req.e_thinking_7)
|
||||
.bind(req.e_thinking_8)
|
||||
.bind(req.e_thinking_0).bind(req.e_thinking_1).bind(req.e_thinking_2)
|
||||
.bind(req.e_thinking_3).bind(req.e_thinking_4).bind(req.e_thinking_5)
|
||||
.bind(req.e_thinking_6).bind(req.e_thinking_7).bind(req.e_thinking_8)
|
||||
// Laughing emotion
|
||||
.bind(req.e_laughing_0)
|
||||
.bind(req.e_laughing_1)
|
||||
.bind(req.e_laughing_2)
|
||||
.bind(req.e_laughing_3)
|
||||
.bind(req.e_laughing_4)
|
||||
.bind(req.e_laughing_5)
|
||||
.bind(req.e_laughing_6)
|
||||
.bind(req.e_laughing_7)
|
||||
.bind(req.e_laughing_8)
|
||||
.bind(req.e_laughing_0).bind(req.e_laughing_1).bind(req.e_laughing_2)
|
||||
.bind(req.e_laughing_3).bind(req.e_laughing_4).bind(req.e_laughing_5)
|
||||
.bind(req.e_laughing_6).bind(req.e_laughing_7).bind(req.e_laughing_8)
|
||||
// Crying emotion
|
||||
.bind(req.e_crying_0)
|
||||
.bind(req.e_crying_1)
|
||||
.bind(req.e_crying_2)
|
||||
.bind(req.e_crying_3)
|
||||
.bind(req.e_crying_4)
|
||||
.bind(req.e_crying_5)
|
||||
.bind(req.e_crying_6)
|
||||
.bind(req.e_crying_7)
|
||||
.bind(req.e_crying_8)
|
||||
.bind(req.e_crying_0).bind(req.e_crying_1).bind(req.e_crying_2)
|
||||
.bind(req.e_crying_3).bind(req.e_crying_4).bind(req.e_crying_5)
|
||||
.bind(req.e_crying_6).bind(req.e_crying_7).bind(req.e_crying_8)
|
||||
// Love emotion
|
||||
.bind(req.e_love_0)
|
||||
.bind(req.e_love_1)
|
||||
.bind(req.e_love_2)
|
||||
.bind(req.e_love_3)
|
||||
.bind(req.e_love_4)
|
||||
.bind(req.e_love_5)
|
||||
.bind(req.e_love_6)
|
||||
.bind(req.e_love_7)
|
||||
.bind(req.e_love_8)
|
||||
.bind(req.e_love_0).bind(req.e_love_1).bind(req.e_love_2)
|
||||
.bind(req.e_love_3).bind(req.e_love_4).bind(req.e_love_5)
|
||||
.bind(req.e_love_6).bind(req.e_love_7).bind(req.e_love_8)
|
||||
// Confused emotion
|
||||
.bind(req.e_confused_0)
|
||||
.bind(req.e_confused_1)
|
||||
.bind(req.e_confused_2)
|
||||
.bind(req.e_confused_3)
|
||||
.bind(req.e_confused_4)
|
||||
.bind(req.e_confused_5)
|
||||
.bind(req.e_confused_6)
|
||||
.bind(req.e_confused_7)
|
||||
.bind(req.e_confused_8)
|
||||
.bind(req.e_confused_0).bind(req.e_confused_1).bind(req.e_confused_2)
|
||||
.bind(req.e_confused_3).bind(req.e_confused_4).bind(req.e_confused_5)
|
||||
.bind(req.e_confused_6).bind(req.e_confused_7).bind(req.e_confused_8)
|
||||
// Sleeping emotion
|
||||
.bind(req.e_sleeping_0)
|
||||
.bind(req.e_sleeping_1)
|
||||
.bind(req.e_sleeping_2)
|
||||
.bind(req.e_sleeping_3)
|
||||
.bind(req.e_sleeping_4)
|
||||
.bind(req.e_sleeping_5)
|
||||
.bind(req.e_sleeping_6)
|
||||
.bind(req.e_sleeping_7)
|
||||
.bind(req.e_sleeping_8)
|
||||
.bind(req.e_sleeping_0).bind(req.e_sleeping_1).bind(req.e_sleeping_2)
|
||||
.bind(req.e_sleeping_3).bind(req.e_sleeping_4).bind(req.e_sleeping_5)
|
||||
.bind(req.e_sleeping_6).bind(req.e_sleeping_7).bind(req.e_sleeping_8)
|
||||
// Wink emotion
|
||||
.bind(req.e_wink_0)
|
||||
.bind(req.e_wink_1)
|
||||
.bind(req.e_wink_2)
|
||||
.bind(req.e_wink_3)
|
||||
.bind(req.e_wink_4)
|
||||
.bind(req.e_wink_5)
|
||||
.bind(req.e_wink_6)
|
||||
.bind(req.e_wink_7)
|
||||
.bind(req.e_wink_8)
|
||||
.bind(req.e_wink_0).bind(req.e_wink_1).bind(req.e_wink_2)
|
||||
.bind(req.e_wink_3).bind(req.e_wink_4).bind(req.e_wink_5)
|
||||
.bind(req.e_wink_6).bind(req.e_wink_7).bind(req.e_wink_8)
|
||||
.fetch_one(executor)
|
||||
.await?;
|
||||
|
||||
|
|
@ -745,141 +480,51 @@ pub async fn update_realm_avatar<'e>(
|
|||
is_public = COALESCE($4, is_public),
|
||||
is_active = COALESCE($5, is_active),
|
||||
thumbnail_path = COALESCE($6, thumbnail_path),
|
||||
l_skin_0 = COALESCE($7, l_skin_0),
|
||||
l_skin_1 = COALESCE($8, l_skin_1),
|
||||
l_skin_2 = COALESCE($9, l_skin_2),
|
||||
l_skin_3 = COALESCE($10, l_skin_3),
|
||||
l_skin_4 = COALESCE($11, l_skin_4),
|
||||
l_skin_5 = COALESCE($12, l_skin_5),
|
||||
l_skin_6 = COALESCE($13, l_skin_6),
|
||||
l_skin_7 = COALESCE($14, l_skin_7),
|
||||
l_skin_8 = COALESCE($15, l_skin_8),
|
||||
l_clothes_0 = COALESCE($16, l_clothes_0),
|
||||
l_clothes_1 = COALESCE($17, l_clothes_1),
|
||||
l_clothes_2 = COALESCE($18, l_clothes_2),
|
||||
l_clothes_3 = COALESCE($19, l_clothes_3),
|
||||
l_clothes_4 = COALESCE($20, l_clothes_4),
|
||||
l_clothes_5 = COALESCE($21, l_clothes_5),
|
||||
l_clothes_6 = COALESCE($22, l_clothes_6),
|
||||
l_clothes_7 = COALESCE($23, l_clothes_7),
|
||||
l_clothes_8 = COALESCE($24, l_clothes_8),
|
||||
l_accessories_0 = COALESCE($25, l_accessories_0),
|
||||
l_accessories_1 = COALESCE($26, l_accessories_1),
|
||||
l_accessories_2 = COALESCE($27, l_accessories_2),
|
||||
l_accessories_3 = COALESCE($28, l_accessories_3),
|
||||
l_accessories_4 = COALESCE($29, l_accessories_4),
|
||||
l_accessories_5 = COALESCE($30, l_accessories_5),
|
||||
l_accessories_6 = COALESCE($31, l_accessories_6),
|
||||
l_accessories_7 = COALESCE($32, l_accessories_7),
|
||||
l_accessories_8 = COALESCE($33, l_accessories_8),
|
||||
e_neutral_0 = COALESCE($34, e_neutral_0),
|
||||
e_neutral_1 = COALESCE($35, e_neutral_1),
|
||||
e_neutral_2 = COALESCE($36, e_neutral_2),
|
||||
e_neutral_3 = COALESCE($37, e_neutral_3),
|
||||
e_neutral_4 = COALESCE($38, e_neutral_4),
|
||||
e_neutral_5 = COALESCE($39, e_neutral_5),
|
||||
e_neutral_6 = COALESCE($40, e_neutral_6),
|
||||
e_neutral_7 = COALESCE($41, e_neutral_7),
|
||||
e_neutral_8 = COALESCE($42, e_neutral_8),
|
||||
e_happy_0 = COALESCE($43, e_happy_0),
|
||||
e_happy_1 = COALESCE($44, e_happy_1),
|
||||
e_happy_2 = COALESCE($45, e_happy_2),
|
||||
e_happy_3 = COALESCE($46, e_happy_3),
|
||||
e_happy_4 = COALESCE($47, e_happy_4),
|
||||
e_happy_5 = COALESCE($48, e_happy_5),
|
||||
e_happy_6 = COALESCE($49, e_happy_6),
|
||||
e_happy_7 = COALESCE($50, e_happy_7),
|
||||
e_happy_8 = COALESCE($51, e_happy_8),
|
||||
e_sad_0 = COALESCE($52, e_sad_0),
|
||||
e_sad_1 = COALESCE($53, e_sad_1),
|
||||
e_sad_2 = COALESCE($54, e_sad_2),
|
||||
e_sad_3 = COALESCE($55, e_sad_3),
|
||||
e_sad_4 = COALESCE($56, e_sad_4),
|
||||
e_sad_5 = COALESCE($57, e_sad_5),
|
||||
e_sad_6 = COALESCE($58, e_sad_6),
|
||||
e_sad_7 = COALESCE($59, e_sad_7),
|
||||
e_sad_8 = COALESCE($60, e_sad_8),
|
||||
e_angry_0 = COALESCE($61, e_angry_0),
|
||||
e_angry_1 = COALESCE($62, e_angry_1),
|
||||
e_angry_2 = COALESCE($63, e_angry_2),
|
||||
e_angry_3 = COALESCE($64, e_angry_3),
|
||||
e_angry_4 = COALESCE($65, e_angry_4),
|
||||
e_angry_5 = COALESCE($66, e_angry_5),
|
||||
e_angry_6 = COALESCE($67, e_angry_6),
|
||||
e_angry_7 = COALESCE($68, e_angry_7),
|
||||
e_angry_8 = COALESCE($69, e_angry_8),
|
||||
e_surprised_0 = COALESCE($70, e_surprised_0),
|
||||
e_surprised_1 = COALESCE($71, e_surprised_1),
|
||||
e_surprised_2 = COALESCE($72, e_surprised_2),
|
||||
e_surprised_3 = COALESCE($73, e_surprised_3),
|
||||
e_surprised_4 = COALESCE($74, e_surprised_4),
|
||||
e_surprised_5 = COALESCE($75, e_surprised_5),
|
||||
e_surprised_6 = COALESCE($76, e_surprised_6),
|
||||
e_surprised_7 = COALESCE($77, e_surprised_7),
|
||||
e_surprised_8 = COALESCE($78, e_surprised_8),
|
||||
e_thinking_0 = COALESCE($79, e_thinking_0),
|
||||
e_thinking_1 = COALESCE($80, e_thinking_1),
|
||||
e_thinking_2 = COALESCE($81, e_thinking_2),
|
||||
e_thinking_3 = COALESCE($82, e_thinking_3),
|
||||
e_thinking_4 = COALESCE($83, e_thinking_4),
|
||||
e_thinking_5 = COALESCE($84, e_thinking_5),
|
||||
e_thinking_6 = COALESCE($85, e_thinking_6),
|
||||
e_thinking_7 = COALESCE($86, e_thinking_7),
|
||||
e_thinking_8 = COALESCE($87, e_thinking_8),
|
||||
e_laughing_0 = COALESCE($88, e_laughing_0),
|
||||
e_laughing_1 = COALESCE($89, e_laughing_1),
|
||||
e_laughing_2 = COALESCE($90, e_laughing_2),
|
||||
e_laughing_3 = COALESCE($91, e_laughing_3),
|
||||
e_laughing_4 = COALESCE($92, e_laughing_4),
|
||||
e_laughing_5 = COALESCE($93, e_laughing_5),
|
||||
e_laughing_6 = COALESCE($94, e_laughing_6),
|
||||
e_laughing_7 = COALESCE($95, e_laughing_7),
|
||||
e_laughing_8 = COALESCE($96, e_laughing_8),
|
||||
e_crying_0 = COALESCE($97, e_crying_0),
|
||||
e_crying_1 = COALESCE($98, e_crying_1),
|
||||
e_crying_2 = COALESCE($99, e_crying_2),
|
||||
e_crying_3 = COALESCE($100, e_crying_3),
|
||||
e_crying_4 = COALESCE($101, e_crying_4),
|
||||
e_crying_5 = COALESCE($102, e_crying_5),
|
||||
e_crying_6 = COALESCE($103, e_crying_6),
|
||||
e_crying_7 = COALESCE($104, e_crying_7),
|
||||
e_crying_8 = COALESCE($105, e_crying_8),
|
||||
e_love_0 = COALESCE($106, e_love_0),
|
||||
e_love_1 = COALESCE($107, e_love_1),
|
||||
e_love_2 = COALESCE($108, e_love_2),
|
||||
e_love_3 = COALESCE($109, e_love_3),
|
||||
e_love_4 = COALESCE($110, e_love_4),
|
||||
e_love_5 = COALESCE($111, e_love_5),
|
||||
e_love_6 = COALESCE($112, e_love_6),
|
||||
e_love_7 = COALESCE($113, e_love_7),
|
||||
e_love_8 = COALESCE($114, e_love_8),
|
||||
e_confused_0 = COALESCE($115, e_confused_0),
|
||||
e_confused_1 = COALESCE($116, e_confused_1),
|
||||
e_confused_2 = COALESCE($117, e_confused_2),
|
||||
e_confused_3 = COALESCE($118, e_confused_3),
|
||||
e_confused_4 = COALESCE($119, e_confused_4),
|
||||
e_confused_5 = COALESCE($120, e_confused_5),
|
||||
e_confused_6 = COALESCE($121, e_confused_6),
|
||||
e_confused_7 = COALESCE($122, e_confused_7),
|
||||
e_confused_8 = COALESCE($123, e_confused_8),
|
||||
e_sleeping_0 = COALESCE($124, e_sleeping_0),
|
||||
e_sleeping_1 = COALESCE($125, e_sleeping_1),
|
||||
e_sleeping_2 = COALESCE($126, e_sleeping_2),
|
||||
e_sleeping_3 = COALESCE($127, e_sleeping_3),
|
||||
e_sleeping_4 = COALESCE($128, e_sleeping_4),
|
||||
e_sleeping_5 = COALESCE($129, e_sleeping_5),
|
||||
e_sleeping_6 = COALESCE($130, e_sleeping_6),
|
||||
e_sleeping_7 = COALESCE($131, e_sleeping_7),
|
||||
e_sleeping_8 = COALESCE($132, e_sleeping_8),
|
||||
e_wink_0 = COALESCE($133, e_wink_0),
|
||||
e_wink_1 = COALESCE($134, e_wink_1),
|
||||
e_wink_2 = COALESCE($135, e_wink_2),
|
||||
e_wink_3 = COALESCE($136, e_wink_3),
|
||||
e_wink_4 = COALESCE($137, e_wink_4),
|
||||
e_wink_5 = COALESCE($138, e_wink_5),
|
||||
e_wink_6 = COALESCE($139, e_wink_6),
|
||||
e_wink_7 = COALESCE($140, e_wink_7),
|
||||
e_wink_8 = COALESCE($141, e_wink_8),
|
||||
l_skin_0 = COALESCE($7, l_skin_0), l_skin_1 = COALESCE($8, l_skin_1), l_skin_2 = COALESCE($9, l_skin_2),
|
||||
l_skin_3 = COALESCE($10, l_skin_3), l_skin_4 = COALESCE($11, l_skin_4), l_skin_5 = COALESCE($12, l_skin_5),
|
||||
l_skin_6 = COALESCE($13, l_skin_6), l_skin_7 = COALESCE($14, l_skin_7), l_skin_8 = COALESCE($15, l_skin_8),
|
||||
l_clothes_0 = COALESCE($16, l_clothes_0), l_clothes_1 = COALESCE($17, l_clothes_1), l_clothes_2 = COALESCE($18, l_clothes_2),
|
||||
l_clothes_3 = COALESCE($19, l_clothes_3), l_clothes_4 = COALESCE($20, l_clothes_4), l_clothes_5 = COALESCE($21, l_clothes_5),
|
||||
l_clothes_6 = COALESCE($22, l_clothes_6), l_clothes_7 = COALESCE($23, l_clothes_7), l_clothes_8 = COALESCE($24, l_clothes_8),
|
||||
l_accessories_0 = COALESCE($25, l_accessories_0), l_accessories_1 = COALESCE($26, l_accessories_1), l_accessories_2 = COALESCE($27, l_accessories_2),
|
||||
l_accessories_3 = COALESCE($28, l_accessories_3), l_accessories_4 = COALESCE($29, l_accessories_4), l_accessories_5 = COALESCE($30, l_accessories_5),
|
||||
l_accessories_6 = COALESCE($31, l_accessories_6), l_accessories_7 = COALESCE($32, l_accessories_7), l_accessories_8 = COALESCE($33, l_accessories_8),
|
||||
e_neutral_0 = COALESCE($34, e_neutral_0), e_neutral_1 = COALESCE($35, e_neutral_1), e_neutral_2 = COALESCE($36, e_neutral_2),
|
||||
e_neutral_3 = COALESCE($37, e_neutral_3), e_neutral_4 = COALESCE($38, e_neutral_4), e_neutral_5 = COALESCE($39, e_neutral_5),
|
||||
e_neutral_6 = COALESCE($40, e_neutral_6), e_neutral_7 = COALESCE($41, e_neutral_7), e_neutral_8 = COALESCE($42, e_neutral_8),
|
||||
e_happy_0 = COALESCE($43, e_happy_0), e_happy_1 = COALESCE($44, e_happy_1), e_happy_2 = COALESCE($45, e_happy_2),
|
||||
e_happy_3 = COALESCE($46, e_happy_3), e_happy_4 = COALESCE($47, e_happy_4), e_happy_5 = COALESCE($48, e_happy_5),
|
||||
e_happy_6 = COALESCE($49, e_happy_6), e_happy_7 = COALESCE($50, e_happy_7), e_happy_8 = COALESCE($51, e_happy_8),
|
||||
e_sad_0 = COALESCE($52, e_sad_0), e_sad_1 = COALESCE($53, e_sad_1), e_sad_2 = COALESCE($54, e_sad_2),
|
||||
e_sad_3 = COALESCE($55, e_sad_3), e_sad_4 = COALESCE($56, e_sad_4), e_sad_5 = COALESCE($57, e_sad_5),
|
||||
e_sad_6 = COALESCE($58, e_sad_6), e_sad_7 = COALESCE($59, e_sad_7), e_sad_8 = COALESCE($60, e_sad_8),
|
||||
e_angry_0 = COALESCE($61, e_angry_0), e_angry_1 = COALESCE($62, e_angry_1), e_angry_2 = COALESCE($63, e_angry_2),
|
||||
e_angry_3 = COALESCE($64, e_angry_3), e_angry_4 = COALESCE($65, e_angry_4), e_angry_5 = COALESCE($66, e_angry_5),
|
||||
e_angry_6 = COALESCE($67, e_angry_6), e_angry_7 = COALESCE($68, e_angry_7), e_angry_8 = COALESCE($69, e_angry_8),
|
||||
e_surprised_0 = COALESCE($70, e_surprised_0), e_surprised_1 = COALESCE($71, e_surprised_1), e_surprised_2 = COALESCE($72, e_surprised_2),
|
||||
e_surprised_3 = COALESCE($73, e_surprised_3), e_surprised_4 = COALESCE($74, e_surprised_4), e_surprised_5 = COALESCE($75, e_surprised_5),
|
||||
e_surprised_6 = COALESCE($76, e_surprised_6), e_surprised_7 = COALESCE($77, e_surprised_7), e_surprised_8 = COALESCE($78, e_surprised_8),
|
||||
e_thinking_0 = COALESCE($79, e_thinking_0), e_thinking_1 = COALESCE($80, e_thinking_1), e_thinking_2 = COALESCE($81, e_thinking_2),
|
||||
e_thinking_3 = COALESCE($82, e_thinking_3), e_thinking_4 = COALESCE($83, e_thinking_4), e_thinking_5 = COALESCE($84, e_thinking_5),
|
||||
e_thinking_6 = COALESCE($85, e_thinking_6), e_thinking_7 = COALESCE($86, e_thinking_7), e_thinking_8 = COALESCE($87, e_thinking_8),
|
||||
e_laughing_0 = COALESCE($88, e_laughing_0), e_laughing_1 = COALESCE($89, e_laughing_1), e_laughing_2 = COALESCE($90, e_laughing_2),
|
||||
e_laughing_3 = COALESCE($91, e_laughing_3), e_laughing_4 = COALESCE($92, e_laughing_4), e_laughing_5 = COALESCE($93, e_laughing_5),
|
||||
e_laughing_6 = COALESCE($94, e_laughing_6), e_laughing_7 = COALESCE($95, e_laughing_7), e_laughing_8 = COALESCE($96, e_laughing_8),
|
||||
e_crying_0 = COALESCE($97, e_crying_0), e_crying_1 = COALESCE($98, e_crying_1), e_crying_2 = COALESCE($99, e_crying_2),
|
||||
e_crying_3 = COALESCE($100, e_crying_3), e_crying_4 = COALESCE($101, e_crying_4), e_crying_5 = COALESCE($102, e_crying_5),
|
||||
e_crying_6 = COALESCE($103, e_crying_6), e_crying_7 = COALESCE($104, e_crying_7), e_crying_8 = COALESCE($105, e_crying_8),
|
||||
e_love_0 = COALESCE($106, e_love_0), e_love_1 = COALESCE($107, e_love_1), e_love_2 = COALESCE($108, e_love_2),
|
||||
e_love_3 = COALESCE($109, e_love_3), e_love_4 = COALESCE($110, e_love_4), e_love_5 = COALESCE($111, e_love_5),
|
||||
e_love_6 = COALESCE($112, e_love_6), e_love_7 = COALESCE($113, e_love_7), e_love_8 = COALESCE($114, e_love_8),
|
||||
e_confused_0 = COALESCE($115, e_confused_0), e_confused_1 = COALESCE($116, e_confused_1), e_confused_2 = COALESCE($117, e_confused_2),
|
||||
e_confused_3 = COALESCE($118, e_confused_3), e_confused_4 = COALESCE($119, e_confused_4), e_confused_5 = COALESCE($120, e_confused_5),
|
||||
e_confused_6 = COALESCE($121, e_confused_6), e_confused_7 = COALESCE($122, e_confused_7), e_confused_8 = COALESCE($123, e_confused_8),
|
||||
e_sleeping_0 = COALESCE($124, e_sleeping_0), e_sleeping_1 = COALESCE($125, e_sleeping_1), e_sleeping_2 = COALESCE($126, e_sleeping_2),
|
||||
e_sleeping_3 = COALESCE($127, e_sleeping_3), e_sleeping_4 = COALESCE($128, e_sleeping_4), e_sleeping_5 = COALESCE($129, e_sleeping_5),
|
||||
e_sleeping_6 = COALESCE($130, e_sleeping_6), e_sleeping_7 = COALESCE($131, e_sleeping_7), e_sleeping_8 = COALESCE($132, e_sleeping_8),
|
||||
e_wink_0 = COALESCE($133, e_wink_0), e_wink_1 = COALESCE($134, e_wink_1), e_wink_2 = COALESCE($135, e_wink_2),
|
||||
e_wink_3 = COALESCE($136, e_wink_3), e_wink_4 = COALESCE($137, e_wink_4), e_wink_5 = COALESCE($138, e_wink_5),
|
||||
e_wink_6 = COALESCE($139, e_wink_6), e_wink_7 = COALESCE($140, e_wink_7), e_wink_8 = COALESCE($141, e_wink_8),
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING *
|
||||
|
|
@ -892,155 +537,65 @@ pub async fn update_realm_avatar<'e>(
|
|||
.bind(req.is_active)
|
||||
.bind(&req.thumbnail_path)
|
||||
// Skin layer
|
||||
.bind(req.l_skin_0)
|
||||
.bind(req.l_skin_1)
|
||||
.bind(req.l_skin_2)
|
||||
.bind(req.l_skin_3)
|
||||
.bind(req.l_skin_4)
|
||||
.bind(req.l_skin_5)
|
||||
.bind(req.l_skin_6)
|
||||
.bind(req.l_skin_7)
|
||||
.bind(req.l_skin_8)
|
||||
.bind(req.l_skin_0).bind(req.l_skin_1).bind(req.l_skin_2)
|
||||
.bind(req.l_skin_3).bind(req.l_skin_4).bind(req.l_skin_5)
|
||||
.bind(req.l_skin_6).bind(req.l_skin_7).bind(req.l_skin_8)
|
||||
// Clothes layer
|
||||
.bind(req.l_clothes_0)
|
||||
.bind(req.l_clothes_1)
|
||||
.bind(req.l_clothes_2)
|
||||
.bind(req.l_clothes_3)
|
||||
.bind(req.l_clothes_4)
|
||||
.bind(req.l_clothes_5)
|
||||
.bind(req.l_clothes_6)
|
||||
.bind(req.l_clothes_7)
|
||||
.bind(req.l_clothes_8)
|
||||
.bind(req.l_clothes_0).bind(req.l_clothes_1).bind(req.l_clothes_2)
|
||||
.bind(req.l_clothes_3).bind(req.l_clothes_4).bind(req.l_clothes_5)
|
||||
.bind(req.l_clothes_6).bind(req.l_clothes_7).bind(req.l_clothes_8)
|
||||
// Accessories layer
|
||||
.bind(req.l_accessories_0)
|
||||
.bind(req.l_accessories_1)
|
||||
.bind(req.l_accessories_2)
|
||||
.bind(req.l_accessories_3)
|
||||
.bind(req.l_accessories_4)
|
||||
.bind(req.l_accessories_5)
|
||||
.bind(req.l_accessories_6)
|
||||
.bind(req.l_accessories_7)
|
||||
.bind(req.l_accessories_8)
|
||||
.bind(req.l_accessories_0).bind(req.l_accessories_1).bind(req.l_accessories_2)
|
||||
.bind(req.l_accessories_3).bind(req.l_accessories_4).bind(req.l_accessories_5)
|
||||
.bind(req.l_accessories_6).bind(req.l_accessories_7).bind(req.l_accessories_8)
|
||||
// Neutral emotion
|
||||
.bind(req.e_neutral_0)
|
||||
.bind(req.e_neutral_1)
|
||||
.bind(req.e_neutral_2)
|
||||
.bind(req.e_neutral_3)
|
||||
.bind(req.e_neutral_4)
|
||||
.bind(req.e_neutral_5)
|
||||
.bind(req.e_neutral_6)
|
||||
.bind(req.e_neutral_7)
|
||||
.bind(req.e_neutral_8)
|
||||
.bind(req.e_neutral_0).bind(req.e_neutral_1).bind(req.e_neutral_2)
|
||||
.bind(req.e_neutral_3).bind(req.e_neutral_4).bind(req.e_neutral_5)
|
||||
.bind(req.e_neutral_6).bind(req.e_neutral_7).bind(req.e_neutral_8)
|
||||
// Happy emotion
|
||||
.bind(req.e_happy_0)
|
||||
.bind(req.e_happy_1)
|
||||
.bind(req.e_happy_2)
|
||||
.bind(req.e_happy_3)
|
||||
.bind(req.e_happy_4)
|
||||
.bind(req.e_happy_5)
|
||||
.bind(req.e_happy_6)
|
||||
.bind(req.e_happy_7)
|
||||
.bind(req.e_happy_8)
|
||||
.bind(req.e_happy_0).bind(req.e_happy_1).bind(req.e_happy_2)
|
||||
.bind(req.e_happy_3).bind(req.e_happy_4).bind(req.e_happy_5)
|
||||
.bind(req.e_happy_6).bind(req.e_happy_7).bind(req.e_happy_8)
|
||||
// Sad emotion
|
||||
.bind(req.e_sad_0)
|
||||
.bind(req.e_sad_1)
|
||||
.bind(req.e_sad_2)
|
||||
.bind(req.e_sad_3)
|
||||
.bind(req.e_sad_4)
|
||||
.bind(req.e_sad_5)
|
||||
.bind(req.e_sad_6)
|
||||
.bind(req.e_sad_7)
|
||||
.bind(req.e_sad_8)
|
||||
.bind(req.e_sad_0).bind(req.e_sad_1).bind(req.e_sad_2)
|
||||
.bind(req.e_sad_3).bind(req.e_sad_4).bind(req.e_sad_5)
|
||||
.bind(req.e_sad_6).bind(req.e_sad_7).bind(req.e_sad_8)
|
||||
// Angry emotion
|
||||
.bind(req.e_angry_0)
|
||||
.bind(req.e_angry_1)
|
||||
.bind(req.e_angry_2)
|
||||
.bind(req.e_angry_3)
|
||||
.bind(req.e_angry_4)
|
||||
.bind(req.e_angry_5)
|
||||
.bind(req.e_angry_6)
|
||||
.bind(req.e_angry_7)
|
||||
.bind(req.e_angry_8)
|
||||
.bind(req.e_angry_0).bind(req.e_angry_1).bind(req.e_angry_2)
|
||||
.bind(req.e_angry_3).bind(req.e_angry_4).bind(req.e_angry_5)
|
||||
.bind(req.e_angry_6).bind(req.e_angry_7).bind(req.e_angry_8)
|
||||
// Surprised emotion
|
||||
.bind(req.e_surprised_0)
|
||||
.bind(req.e_surprised_1)
|
||||
.bind(req.e_surprised_2)
|
||||
.bind(req.e_surprised_3)
|
||||
.bind(req.e_surprised_4)
|
||||
.bind(req.e_surprised_5)
|
||||
.bind(req.e_surprised_6)
|
||||
.bind(req.e_surprised_7)
|
||||
.bind(req.e_surprised_8)
|
||||
.bind(req.e_surprised_0).bind(req.e_surprised_1).bind(req.e_surprised_2)
|
||||
.bind(req.e_surprised_3).bind(req.e_surprised_4).bind(req.e_surprised_5)
|
||||
.bind(req.e_surprised_6).bind(req.e_surprised_7).bind(req.e_surprised_8)
|
||||
// Thinking emotion
|
||||
.bind(req.e_thinking_0)
|
||||
.bind(req.e_thinking_1)
|
||||
.bind(req.e_thinking_2)
|
||||
.bind(req.e_thinking_3)
|
||||
.bind(req.e_thinking_4)
|
||||
.bind(req.e_thinking_5)
|
||||
.bind(req.e_thinking_6)
|
||||
.bind(req.e_thinking_7)
|
||||
.bind(req.e_thinking_8)
|
||||
.bind(req.e_thinking_0).bind(req.e_thinking_1).bind(req.e_thinking_2)
|
||||
.bind(req.e_thinking_3).bind(req.e_thinking_4).bind(req.e_thinking_5)
|
||||
.bind(req.e_thinking_6).bind(req.e_thinking_7).bind(req.e_thinking_8)
|
||||
// Laughing emotion
|
||||
.bind(req.e_laughing_0)
|
||||
.bind(req.e_laughing_1)
|
||||
.bind(req.e_laughing_2)
|
||||
.bind(req.e_laughing_3)
|
||||
.bind(req.e_laughing_4)
|
||||
.bind(req.e_laughing_5)
|
||||
.bind(req.e_laughing_6)
|
||||
.bind(req.e_laughing_7)
|
||||
.bind(req.e_laughing_8)
|
||||
.bind(req.e_laughing_0).bind(req.e_laughing_1).bind(req.e_laughing_2)
|
||||
.bind(req.e_laughing_3).bind(req.e_laughing_4).bind(req.e_laughing_5)
|
||||
.bind(req.e_laughing_6).bind(req.e_laughing_7).bind(req.e_laughing_8)
|
||||
// Crying emotion
|
||||
.bind(req.e_crying_0)
|
||||
.bind(req.e_crying_1)
|
||||
.bind(req.e_crying_2)
|
||||
.bind(req.e_crying_3)
|
||||
.bind(req.e_crying_4)
|
||||
.bind(req.e_crying_5)
|
||||
.bind(req.e_crying_6)
|
||||
.bind(req.e_crying_7)
|
||||
.bind(req.e_crying_8)
|
||||
.bind(req.e_crying_0).bind(req.e_crying_1).bind(req.e_crying_2)
|
||||
.bind(req.e_crying_3).bind(req.e_crying_4).bind(req.e_crying_5)
|
||||
.bind(req.e_crying_6).bind(req.e_crying_7).bind(req.e_crying_8)
|
||||
// Love emotion
|
||||
.bind(req.e_love_0)
|
||||
.bind(req.e_love_1)
|
||||
.bind(req.e_love_2)
|
||||
.bind(req.e_love_3)
|
||||
.bind(req.e_love_4)
|
||||
.bind(req.e_love_5)
|
||||
.bind(req.e_love_6)
|
||||
.bind(req.e_love_7)
|
||||
.bind(req.e_love_8)
|
||||
.bind(req.e_love_0).bind(req.e_love_1).bind(req.e_love_2)
|
||||
.bind(req.e_love_3).bind(req.e_love_4).bind(req.e_love_5)
|
||||
.bind(req.e_love_6).bind(req.e_love_7).bind(req.e_love_8)
|
||||
// Confused emotion
|
||||
.bind(req.e_confused_0)
|
||||
.bind(req.e_confused_1)
|
||||
.bind(req.e_confused_2)
|
||||
.bind(req.e_confused_3)
|
||||
.bind(req.e_confused_4)
|
||||
.bind(req.e_confused_5)
|
||||
.bind(req.e_confused_6)
|
||||
.bind(req.e_confused_7)
|
||||
.bind(req.e_confused_8)
|
||||
.bind(req.e_confused_0).bind(req.e_confused_1).bind(req.e_confused_2)
|
||||
.bind(req.e_confused_3).bind(req.e_confused_4).bind(req.e_confused_5)
|
||||
.bind(req.e_confused_6).bind(req.e_confused_7).bind(req.e_confused_8)
|
||||
// Sleeping emotion
|
||||
.bind(req.e_sleeping_0)
|
||||
.bind(req.e_sleeping_1)
|
||||
.bind(req.e_sleeping_2)
|
||||
.bind(req.e_sleeping_3)
|
||||
.bind(req.e_sleeping_4)
|
||||
.bind(req.e_sleeping_5)
|
||||
.bind(req.e_sleeping_6)
|
||||
.bind(req.e_sleeping_7)
|
||||
.bind(req.e_sleeping_8)
|
||||
.bind(req.e_sleeping_0).bind(req.e_sleeping_1).bind(req.e_sleeping_2)
|
||||
.bind(req.e_sleeping_3).bind(req.e_sleeping_4).bind(req.e_sleeping_5)
|
||||
.bind(req.e_sleeping_6).bind(req.e_sleeping_7).bind(req.e_sleeping_8)
|
||||
// Wink emotion
|
||||
.bind(req.e_wink_0)
|
||||
.bind(req.e_wink_1)
|
||||
.bind(req.e_wink_2)
|
||||
.bind(req.e_wink_3)
|
||||
.bind(req.e_wink_4)
|
||||
.bind(req.e_wink_5)
|
||||
.bind(req.e_wink_6)
|
||||
.bind(req.e_wink_7)
|
||||
.bind(req.e_wink_8)
|
||||
.bind(req.e_wink_0).bind(req.e_wink_1).bind(req.e_wink_2)
|
||||
.bind(req.e_wink_3).bind(req.e_wink_4).bind(req.e_wink_5)
|
||||
.bind(req.e_wink_6).bind(req.e_wink_7).bind(req.e_wink_8)
|
||||
.fetch_one(executor)
|
||||
.await?;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,15 +3,22 @@
|
|||
//! Server avatars are pre-configured avatar configurations available globally
|
||||
//! across all realms. They reference server.props directly (not inventory items).
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use sqlx::PgExecutor;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::models::{AvatarRenderData, EmotionState, ServerAvatar};
|
||||
use crate::extract_avatar_slots;
|
||||
use crate::models::{AvatarRenderData, EmotionState, ServerAvatar, ServerAvatarWithPaths};
|
||||
use crate::queries::avatar_common::{
|
||||
avatar_paths_join_clause, avatar_paths_select_clause, build_prop_map,
|
||||
resolve_slots_to_render_data,
|
||||
};
|
||||
use chattyness_error::AppError;
|
||||
|
||||
// =============================================================================
|
||||
// Basic Queries
|
||||
// =============================================================================
|
||||
|
||||
/// Get a server avatar by slug.
|
||||
pub async fn get_server_avatar_by_slug<'e>(
|
||||
executor: impl PgExecutor<'e>,
|
||||
|
|
@ -68,9 +75,11 @@ pub async fn list_public_server_avatars<'e>(
|
|||
Ok(avatars)
|
||||
}
|
||||
|
||||
use crate::models::ServerAvatarWithPaths;
|
||||
// =============================================================================
|
||||
// Avatar with Paths Queries
|
||||
// =============================================================================
|
||||
|
||||
/// Row type for server avatar with paths query.
|
||||
/// Row type for server avatar with paths query (includes slug).
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
struct ServerAvatarWithPathsRow {
|
||||
id: Uuid,
|
||||
|
|
@ -107,7 +116,7 @@ struct ServerAvatarWithPathsRow {
|
|||
accessories_6: Option<String>,
|
||||
accessories_7: Option<String>,
|
||||
accessories_8: Option<String>,
|
||||
// Happy emotion layer paths (e1 - more inviting for store display)
|
||||
// Happy emotion layer paths
|
||||
emotion_0: Option<String>,
|
||||
emotion_1: Option<String>,
|
||||
emotion_2: Option<String>,
|
||||
|
|
@ -151,234 +160,51 @@ impl From<ServerAvatarWithPathsRow> for ServerAvatarWithPaths {
|
|||
}
|
||||
|
||||
/// List all active public server avatars with resolved asset paths.
|
||||
///
|
||||
/// Joins with the props table to resolve prop UUIDs to asset paths,
|
||||
/// suitable for client-side rendering without additional lookups.
|
||||
pub async fn list_public_server_avatars_with_paths<'e>(
|
||||
executor: impl PgExecutor<'e>,
|
||||
) -> Result<Vec<ServerAvatarWithPaths>, AppError> {
|
||||
let rows = sqlx::query_as::<_, ServerAvatarWithPathsRow>(
|
||||
let join_clause = avatar_paths_join_clause("server.props");
|
||||
let query = format!(
|
||||
r#"
|
||||
SELECT
|
||||
a.id,
|
||||
a.slug,
|
||||
a.name,
|
||||
a.description,
|
||||
-- Skin layer
|
||||
p_skin_0.asset_path AS skin_0,
|
||||
p_skin_1.asset_path AS skin_1,
|
||||
p_skin_2.asset_path AS skin_2,
|
||||
p_skin_3.asset_path AS skin_3,
|
||||
p_skin_4.asset_path AS skin_4,
|
||||
p_skin_5.asset_path AS skin_5,
|
||||
p_skin_6.asset_path AS skin_6,
|
||||
p_skin_7.asset_path AS skin_7,
|
||||
p_skin_8.asset_path AS skin_8,
|
||||
-- Clothes layer
|
||||
p_clothes_0.asset_path AS clothes_0,
|
||||
p_clothes_1.asset_path AS clothes_1,
|
||||
p_clothes_2.asset_path AS clothes_2,
|
||||
p_clothes_3.asset_path AS clothes_3,
|
||||
p_clothes_4.asset_path AS clothes_4,
|
||||
p_clothes_5.asset_path AS clothes_5,
|
||||
p_clothes_6.asset_path AS clothes_6,
|
||||
p_clothes_7.asset_path AS clothes_7,
|
||||
p_clothes_8.asset_path AS clothes_8,
|
||||
-- Accessories layer
|
||||
p_acc_0.asset_path AS accessories_0,
|
||||
p_acc_1.asset_path AS accessories_1,
|
||||
p_acc_2.asset_path AS accessories_2,
|
||||
p_acc_3.asset_path AS accessories_3,
|
||||
p_acc_4.asset_path AS accessories_4,
|
||||
p_acc_5.asset_path AS accessories_5,
|
||||
p_acc_6.asset_path AS accessories_6,
|
||||
p_acc_7.asset_path AS accessories_7,
|
||||
p_acc_8.asset_path AS accessories_8,
|
||||
-- Happy emotion layer (e1 - more inviting for store display)
|
||||
p_emo_0.asset_path AS emotion_0,
|
||||
p_emo_1.asset_path AS emotion_1,
|
||||
p_emo_2.asset_path AS emotion_2,
|
||||
p_emo_3.asset_path AS emotion_3,
|
||||
p_emo_4.asset_path AS emotion_4,
|
||||
p_emo_5.asset_path AS emotion_5,
|
||||
p_emo_6.asset_path AS emotion_6,
|
||||
p_emo_7.asset_path AS emotion_7,
|
||||
p_emo_8.asset_path AS emotion_8
|
||||
{}
|
||||
FROM server.avatars a
|
||||
-- Skin layer joins
|
||||
LEFT JOIN server.props p_skin_0 ON a.l_skin_0 = p_skin_0.id
|
||||
LEFT JOIN server.props p_skin_1 ON a.l_skin_1 = p_skin_1.id
|
||||
LEFT JOIN server.props p_skin_2 ON a.l_skin_2 = p_skin_2.id
|
||||
LEFT JOIN server.props p_skin_3 ON a.l_skin_3 = p_skin_3.id
|
||||
LEFT JOIN server.props p_skin_4 ON a.l_skin_4 = p_skin_4.id
|
||||
LEFT JOIN server.props p_skin_5 ON a.l_skin_5 = p_skin_5.id
|
||||
LEFT JOIN server.props p_skin_6 ON a.l_skin_6 = p_skin_6.id
|
||||
LEFT JOIN server.props p_skin_7 ON a.l_skin_7 = p_skin_7.id
|
||||
LEFT JOIN server.props p_skin_8 ON a.l_skin_8 = p_skin_8.id
|
||||
-- Clothes layer joins
|
||||
LEFT JOIN server.props p_clothes_0 ON a.l_clothes_0 = p_clothes_0.id
|
||||
LEFT JOIN server.props p_clothes_1 ON a.l_clothes_1 = p_clothes_1.id
|
||||
LEFT JOIN server.props p_clothes_2 ON a.l_clothes_2 = p_clothes_2.id
|
||||
LEFT JOIN server.props p_clothes_3 ON a.l_clothes_3 = p_clothes_3.id
|
||||
LEFT JOIN server.props p_clothes_4 ON a.l_clothes_4 = p_clothes_4.id
|
||||
LEFT JOIN server.props p_clothes_5 ON a.l_clothes_5 = p_clothes_5.id
|
||||
LEFT JOIN server.props p_clothes_6 ON a.l_clothes_6 = p_clothes_6.id
|
||||
LEFT JOIN server.props p_clothes_7 ON a.l_clothes_7 = p_clothes_7.id
|
||||
LEFT JOIN server.props p_clothes_8 ON a.l_clothes_8 = p_clothes_8.id
|
||||
-- Accessories layer joins
|
||||
LEFT JOIN server.props p_acc_0 ON a.l_accessories_0 = p_acc_0.id
|
||||
LEFT JOIN server.props p_acc_1 ON a.l_accessories_1 = p_acc_1.id
|
||||
LEFT JOIN server.props p_acc_2 ON a.l_accessories_2 = p_acc_2.id
|
||||
LEFT JOIN server.props p_acc_3 ON a.l_accessories_3 = p_acc_3.id
|
||||
LEFT JOIN server.props p_acc_4 ON a.l_accessories_4 = p_acc_4.id
|
||||
LEFT JOIN server.props p_acc_5 ON a.l_accessories_5 = p_acc_5.id
|
||||
LEFT JOIN server.props p_acc_6 ON a.l_accessories_6 = p_acc_6.id
|
||||
LEFT JOIN server.props p_acc_7 ON a.l_accessories_7 = p_acc_7.id
|
||||
LEFT JOIN server.props p_acc_8 ON a.l_accessories_8 = p_acc_8.id
|
||||
-- Happy emotion layer joins (e1 - more inviting for store display)
|
||||
LEFT JOIN server.props p_emo_0 ON a.e_happy_0 = p_emo_0.id
|
||||
LEFT JOIN server.props p_emo_1 ON a.e_happy_1 = p_emo_1.id
|
||||
LEFT JOIN server.props p_emo_2 ON a.e_happy_2 = p_emo_2.id
|
||||
LEFT JOIN server.props p_emo_3 ON a.e_happy_3 = p_emo_3.id
|
||||
LEFT JOIN server.props p_emo_4 ON a.e_happy_4 = p_emo_4.id
|
||||
LEFT JOIN server.props p_emo_5 ON a.e_happy_5 = p_emo_5.id
|
||||
LEFT JOIN server.props p_emo_6 ON a.e_happy_6 = p_emo_6.id
|
||||
LEFT JOIN server.props p_emo_7 ON a.e_happy_7 = p_emo_7.id
|
||||
LEFT JOIN server.props p_emo_8 ON a.e_happy_8 = p_emo_8.id
|
||||
{}
|
||||
WHERE a.is_active = true AND a.is_public = true
|
||||
ORDER BY a.name ASC
|
||||
"#,
|
||||
)
|
||||
avatar_paths_select_clause(),
|
||||
join_clause
|
||||
);
|
||||
|
||||
let rows = sqlx::query_as::<_, ServerAvatarWithPathsRow>(&query)
|
||||
.fetch_all(executor)
|
||||
.await?;
|
||||
|
||||
Ok(rows.into_iter().map(ServerAvatarWithPaths::from).collect())
|
||||
}
|
||||
|
||||
/// Row type for prop asset lookup.
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
struct PropAssetRow {
|
||||
id: Uuid,
|
||||
asset_path: String,
|
||||
}
|
||||
// =============================================================================
|
||||
// Render Data Resolution
|
||||
// =============================================================================
|
||||
|
||||
/// Resolve a server avatar to render data.
|
||||
/// Joins the avatar's prop UUIDs with server.props to get asset paths.
|
||||
pub async fn resolve_server_avatar_to_render_data<'e>(
|
||||
executor: impl PgExecutor<'e>,
|
||||
avatar: &ServerAvatar,
|
||||
current_emotion: EmotionState,
|
||||
) -> Result<AvatarRenderData, AppError> {
|
||||
// Collect all non-null prop UUIDs
|
||||
let mut prop_ids: Vec<Uuid> = Vec::new();
|
||||
|
||||
// Content layers
|
||||
for id in [
|
||||
avatar.l_skin_0, avatar.l_skin_1, avatar.l_skin_2,
|
||||
avatar.l_skin_3, avatar.l_skin_4, avatar.l_skin_5,
|
||||
avatar.l_skin_6, avatar.l_skin_7, avatar.l_skin_8,
|
||||
avatar.l_clothes_0, avatar.l_clothes_1, avatar.l_clothes_2,
|
||||
avatar.l_clothes_3, avatar.l_clothes_4, avatar.l_clothes_5,
|
||||
avatar.l_clothes_6, avatar.l_clothes_7, avatar.l_clothes_8,
|
||||
avatar.l_accessories_0, avatar.l_accessories_1, avatar.l_accessories_2,
|
||||
avatar.l_accessories_3, avatar.l_accessories_4, avatar.l_accessories_5,
|
||||
avatar.l_accessories_6, avatar.l_accessories_7, avatar.l_accessories_8,
|
||||
].iter().flatten() {
|
||||
prop_ids.push(*id);
|
||||
let slots = extract_avatar_slots!(avatar);
|
||||
let prop_ids = slots.collect_render_prop_ids(current_emotion);
|
||||
let prop_map = build_prop_map(executor, &prop_ids, "server.props").await?;
|
||||
Ok(resolve_slots_to_render_data(avatar.id, &slots, current_emotion, &prop_map))
|
||||
}
|
||||
|
||||
// Get emotion layer slots based on current emotion
|
||||
let emotion_slots: [Option<Uuid>; 9] = match current_emotion {
|
||||
EmotionState::Neutral => [avatar.e_neutral_0, avatar.e_neutral_1, avatar.e_neutral_2,
|
||||
avatar.e_neutral_3, avatar.e_neutral_4, avatar.e_neutral_5,
|
||||
avatar.e_neutral_6, avatar.e_neutral_7, avatar.e_neutral_8],
|
||||
EmotionState::Happy => [avatar.e_happy_0, avatar.e_happy_1, avatar.e_happy_2,
|
||||
avatar.e_happy_3, avatar.e_happy_4, avatar.e_happy_5,
|
||||
avatar.e_happy_6, avatar.e_happy_7, avatar.e_happy_8],
|
||||
EmotionState::Sad => [avatar.e_sad_0, avatar.e_sad_1, avatar.e_sad_2,
|
||||
avatar.e_sad_3, avatar.e_sad_4, avatar.e_sad_5,
|
||||
avatar.e_sad_6, avatar.e_sad_7, avatar.e_sad_8],
|
||||
EmotionState::Angry => [avatar.e_angry_0, avatar.e_angry_1, avatar.e_angry_2,
|
||||
avatar.e_angry_3, avatar.e_angry_4, avatar.e_angry_5,
|
||||
avatar.e_angry_6, avatar.e_angry_7, avatar.e_angry_8],
|
||||
EmotionState::Surprised => [avatar.e_surprised_0, avatar.e_surprised_1, avatar.e_surprised_2,
|
||||
avatar.e_surprised_3, avatar.e_surprised_4, avatar.e_surprised_5,
|
||||
avatar.e_surprised_6, avatar.e_surprised_7, avatar.e_surprised_8],
|
||||
EmotionState::Thinking => [avatar.e_thinking_0, avatar.e_thinking_1, avatar.e_thinking_2,
|
||||
avatar.e_thinking_3, avatar.e_thinking_4, avatar.e_thinking_5,
|
||||
avatar.e_thinking_6, avatar.e_thinking_7, avatar.e_thinking_8],
|
||||
EmotionState::Laughing => [avatar.e_laughing_0, avatar.e_laughing_1, avatar.e_laughing_2,
|
||||
avatar.e_laughing_3, avatar.e_laughing_4, avatar.e_laughing_5,
|
||||
avatar.e_laughing_6, avatar.e_laughing_7, avatar.e_laughing_8],
|
||||
EmotionState::Crying => [avatar.e_crying_0, avatar.e_crying_1, avatar.e_crying_2,
|
||||
avatar.e_crying_3, avatar.e_crying_4, avatar.e_crying_5,
|
||||
avatar.e_crying_6, avatar.e_crying_7, avatar.e_crying_8],
|
||||
EmotionState::Love => [avatar.e_love_0, avatar.e_love_1, avatar.e_love_2,
|
||||
avatar.e_love_3, avatar.e_love_4, avatar.e_love_5,
|
||||
avatar.e_love_6, avatar.e_love_7, avatar.e_love_8],
|
||||
EmotionState::Confused => [avatar.e_confused_0, avatar.e_confused_1, avatar.e_confused_2,
|
||||
avatar.e_confused_3, avatar.e_confused_4, avatar.e_confused_5,
|
||||
avatar.e_confused_6, avatar.e_confused_7, avatar.e_confused_8],
|
||||
EmotionState::Sleeping => [avatar.e_sleeping_0, avatar.e_sleeping_1, avatar.e_sleeping_2,
|
||||
avatar.e_sleeping_3, avatar.e_sleeping_4, avatar.e_sleeping_5,
|
||||
avatar.e_sleeping_6, avatar.e_sleeping_7, avatar.e_sleeping_8],
|
||||
EmotionState::Wink => [avatar.e_wink_0, avatar.e_wink_1, avatar.e_wink_2,
|
||||
avatar.e_wink_3, avatar.e_wink_4, avatar.e_wink_5,
|
||||
avatar.e_wink_6, avatar.e_wink_7, avatar.e_wink_8],
|
||||
};
|
||||
|
||||
for id in emotion_slots.iter().flatten() {
|
||||
prop_ids.push(*id);
|
||||
}
|
||||
|
||||
// Bulk lookup all prop asset paths
|
||||
let prop_map: HashMap<Uuid, String> = if prop_ids.is_empty() {
|
||||
HashMap::new()
|
||||
} else {
|
||||
let rows = sqlx::query_as::<_, PropAssetRow>(
|
||||
r#"
|
||||
SELECT id, asset_path
|
||||
FROM server.props
|
||||
WHERE id = ANY($1)
|
||||
"#,
|
||||
)
|
||||
.bind(&prop_ids)
|
||||
.fetch_all(executor)
|
||||
.await?;
|
||||
|
||||
rows.into_iter().map(|r| (r.id, r.asset_path)).collect()
|
||||
};
|
||||
|
||||
// Helper to look up path
|
||||
let get_path = |id: Option<Uuid>| -> Option<String> {
|
||||
id.and_then(|id| prop_map.get(&id).cloned())
|
||||
};
|
||||
|
||||
Ok(AvatarRenderData {
|
||||
avatar_id: avatar.id,
|
||||
current_emotion,
|
||||
skin_layer: [
|
||||
get_path(avatar.l_skin_0), get_path(avatar.l_skin_1), get_path(avatar.l_skin_2),
|
||||
get_path(avatar.l_skin_3), get_path(avatar.l_skin_4), get_path(avatar.l_skin_5),
|
||||
get_path(avatar.l_skin_6), get_path(avatar.l_skin_7), get_path(avatar.l_skin_8),
|
||||
],
|
||||
clothes_layer: [
|
||||
get_path(avatar.l_clothes_0), get_path(avatar.l_clothes_1), get_path(avatar.l_clothes_2),
|
||||
get_path(avatar.l_clothes_3), get_path(avatar.l_clothes_4), get_path(avatar.l_clothes_5),
|
||||
get_path(avatar.l_clothes_6), get_path(avatar.l_clothes_7), get_path(avatar.l_clothes_8),
|
||||
],
|
||||
accessories_layer: [
|
||||
get_path(avatar.l_accessories_0), get_path(avatar.l_accessories_1), get_path(avatar.l_accessories_2),
|
||||
get_path(avatar.l_accessories_3), get_path(avatar.l_accessories_4), get_path(avatar.l_accessories_5),
|
||||
get_path(avatar.l_accessories_6), get_path(avatar.l_accessories_7), get_path(avatar.l_accessories_8),
|
||||
],
|
||||
emotion_layer: [
|
||||
get_path(emotion_slots[0]), get_path(emotion_slots[1]), get_path(emotion_slots[2]),
|
||||
get_path(emotion_slots[3]), get_path(emotion_slots[4]), get_path(emotion_slots[5]),
|
||||
get_path(emotion_slots[6]), get_path(emotion_slots[7]), get_path(emotion_slots[8]),
|
||||
],
|
||||
})
|
||||
}
|
||||
// =============================================================================
|
||||
// Forced Avatar Management
|
||||
// =============================================================================
|
||||
|
||||
/// Apply a forced server avatar to a user.
|
||||
pub async fn apply_forced_server_avatar<'e>(
|
||||
|
|
@ -599,155 +425,65 @@ pub async fn create_server_avatar<'e>(
|
|||
.bind(&req.thumbnail_path)
|
||||
.bind(created_by)
|
||||
// Skin layer
|
||||
.bind(req.l_skin_0)
|
||||
.bind(req.l_skin_1)
|
||||
.bind(req.l_skin_2)
|
||||
.bind(req.l_skin_3)
|
||||
.bind(req.l_skin_4)
|
||||
.bind(req.l_skin_5)
|
||||
.bind(req.l_skin_6)
|
||||
.bind(req.l_skin_7)
|
||||
.bind(req.l_skin_8)
|
||||
.bind(req.l_skin_0).bind(req.l_skin_1).bind(req.l_skin_2)
|
||||
.bind(req.l_skin_3).bind(req.l_skin_4).bind(req.l_skin_5)
|
||||
.bind(req.l_skin_6).bind(req.l_skin_7).bind(req.l_skin_8)
|
||||
// Clothes layer
|
||||
.bind(req.l_clothes_0)
|
||||
.bind(req.l_clothes_1)
|
||||
.bind(req.l_clothes_2)
|
||||
.bind(req.l_clothes_3)
|
||||
.bind(req.l_clothes_4)
|
||||
.bind(req.l_clothes_5)
|
||||
.bind(req.l_clothes_6)
|
||||
.bind(req.l_clothes_7)
|
||||
.bind(req.l_clothes_8)
|
||||
.bind(req.l_clothes_0).bind(req.l_clothes_1).bind(req.l_clothes_2)
|
||||
.bind(req.l_clothes_3).bind(req.l_clothes_4).bind(req.l_clothes_5)
|
||||
.bind(req.l_clothes_6).bind(req.l_clothes_7).bind(req.l_clothes_8)
|
||||
// Accessories layer
|
||||
.bind(req.l_accessories_0)
|
||||
.bind(req.l_accessories_1)
|
||||
.bind(req.l_accessories_2)
|
||||
.bind(req.l_accessories_3)
|
||||
.bind(req.l_accessories_4)
|
||||
.bind(req.l_accessories_5)
|
||||
.bind(req.l_accessories_6)
|
||||
.bind(req.l_accessories_7)
|
||||
.bind(req.l_accessories_8)
|
||||
.bind(req.l_accessories_0).bind(req.l_accessories_1).bind(req.l_accessories_2)
|
||||
.bind(req.l_accessories_3).bind(req.l_accessories_4).bind(req.l_accessories_5)
|
||||
.bind(req.l_accessories_6).bind(req.l_accessories_7).bind(req.l_accessories_8)
|
||||
// Neutral emotion
|
||||
.bind(req.e_neutral_0)
|
||||
.bind(req.e_neutral_1)
|
||||
.bind(req.e_neutral_2)
|
||||
.bind(req.e_neutral_3)
|
||||
.bind(req.e_neutral_4)
|
||||
.bind(req.e_neutral_5)
|
||||
.bind(req.e_neutral_6)
|
||||
.bind(req.e_neutral_7)
|
||||
.bind(req.e_neutral_8)
|
||||
.bind(req.e_neutral_0).bind(req.e_neutral_1).bind(req.e_neutral_2)
|
||||
.bind(req.e_neutral_3).bind(req.e_neutral_4).bind(req.e_neutral_5)
|
||||
.bind(req.e_neutral_6).bind(req.e_neutral_7).bind(req.e_neutral_8)
|
||||
// Happy emotion
|
||||
.bind(req.e_happy_0)
|
||||
.bind(req.e_happy_1)
|
||||
.bind(req.e_happy_2)
|
||||
.bind(req.e_happy_3)
|
||||
.bind(req.e_happy_4)
|
||||
.bind(req.e_happy_5)
|
||||
.bind(req.e_happy_6)
|
||||
.bind(req.e_happy_7)
|
||||
.bind(req.e_happy_8)
|
||||
.bind(req.e_happy_0).bind(req.e_happy_1).bind(req.e_happy_2)
|
||||
.bind(req.e_happy_3).bind(req.e_happy_4).bind(req.e_happy_5)
|
||||
.bind(req.e_happy_6).bind(req.e_happy_7).bind(req.e_happy_8)
|
||||
// Sad emotion
|
||||
.bind(req.e_sad_0)
|
||||
.bind(req.e_sad_1)
|
||||
.bind(req.e_sad_2)
|
||||
.bind(req.e_sad_3)
|
||||
.bind(req.e_sad_4)
|
||||
.bind(req.e_sad_5)
|
||||
.bind(req.e_sad_6)
|
||||
.bind(req.e_sad_7)
|
||||
.bind(req.e_sad_8)
|
||||
.bind(req.e_sad_0).bind(req.e_sad_1).bind(req.e_sad_2)
|
||||
.bind(req.e_sad_3).bind(req.e_sad_4).bind(req.e_sad_5)
|
||||
.bind(req.e_sad_6).bind(req.e_sad_7).bind(req.e_sad_8)
|
||||
// Angry emotion
|
||||
.bind(req.e_angry_0)
|
||||
.bind(req.e_angry_1)
|
||||
.bind(req.e_angry_2)
|
||||
.bind(req.e_angry_3)
|
||||
.bind(req.e_angry_4)
|
||||
.bind(req.e_angry_5)
|
||||
.bind(req.e_angry_6)
|
||||
.bind(req.e_angry_7)
|
||||
.bind(req.e_angry_8)
|
||||
.bind(req.e_angry_0).bind(req.e_angry_1).bind(req.e_angry_2)
|
||||
.bind(req.e_angry_3).bind(req.e_angry_4).bind(req.e_angry_5)
|
||||
.bind(req.e_angry_6).bind(req.e_angry_7).bind(req.e_angry_8)
|
||||
// Surprised emotion
|
||||
.bind(req.e_surprised_0)
|
||||
.bind(req.e_surprised_1)
|
||||
.bind(req.e_surprised_2)
|
||||
.bind(req.e_surprised_3)
|
||||
.bind(req.e_surprised_4)
|
||||
.bind(req.e_surprised_5)
|
||||
.bind(req.e_surprised_6)
|
||||
.bind(req.e_surprised_7)
|
||||
.bind(req.e_surprised_8)
|
||||
.bind(req.e_surprised_0).bind(req.e_surprised_1).bind(req.e_surprised_2)
|
||||
.bind(req.e_surprised_3).bind(req.e_surprised_4).bind(req.e_surprised_5)
|
||||
.bind(req.e_surprised_6).bind(req.e_surprised_7).bind(req.e_surprised_8)
|
||||
// Thinking emotion
|
||||
.bind(req.e_thinking_0)
|
||||
.bind(req.e_thinking_1)
|
||||
.bind(req.e_thinking_2)
|
||||
.bind(req.e_thinking_3)
|
||||
.bind(req.e_thinking_4)
|
||||
.bind(req.e_thinking_5)
|
||||
.bind(req.e_thinking_6)
|
||||
.bind(req.e_thinking_7)
|
||||
.bind(req.e_thinking_8)
|
||||
.bind(req.e_thinking_0).bind(req.e_thinking_1).bind(req.e_thinking_2)
|
||||
.bind(req.e_thinking_3).bind(req.e_thinking_4).bind(req.e_thinking_5)
|
||||
.bind(req.e_thinking_6).bind(req.e_thinking_7).bind(req.e_thinking_8)
|
||||
// Laughing emotion
|
||||
.bind(req.e_laughing_0)
|
||||
.bind(req.e_laughing_1)
|
||||
.bind(req.e_laughing_2)
|
||||
.bind(req.e_laughing_3)
|
||||
.bind(req.e_laughing_4)
|
||||
.bind(req.e_laughing_5)
|
||||
.bind(req.e_laughing_6)
|
||||
.bind(req.e_laughing_7)
|
||||
.bind(req.e_laughing_8)
|
||||
.bind(req.e_laughing_0).bind(req.e_laughing_1).bind(req.e_laughing_2)
|
||||
.bind(req.e_laughing_3).bind(req.e_laughing_4).bind(req.e_laughing_5)
|
||||
.bind(req.e_laughing_6).bind(req.e_laughing_7).bind(req.e_laughing_8)
|
||||
// Crying emotion
|
||||
.bind(req.e_crying_0)
|
||||
.bind(req.e_crying_1)
|
||||
.bind(req.e_crying_2)
|
||||
.bind(req.e_crying_3)
|
||||
.bind(req.e_crying_4)
|
||||
.bind(req.e_crying_5)
|
||||
.bind(req.e_crying_6)
|
||||
.bind(req.e_crying_7)
|
||||
.bind(req.e_crying_8)
|
||||
.bind(req.e_crying_0).bind(req.e_crying_1).bind(req.e_crying_2)
|
||||
.bind(req.e_crying_3).bind(req.e_crying_4).bind(req.e_crying_5)
|
||||
.bind(req.e_crying_6).bind(req.e_crying_7).bind(req.e_crying_8)
|
||||
// Love emotion
|
||||
.bind(req.e_love_0)
|
||||
.bind(req.e_love_1)
|
||||
.bind(req.e_love_2)
|
||||
.bind(req.e_love_3)
|
||||
.bind(req.e_love_4)
|
||||
.bind(req.e_love_5)
|
||||
.bind(req.e_love_6)
|
||||
.bind(req.e_love_7)
|
||||
.bind(req.e_love_8)
|
||||
.bind(req.e_love_0).bind(req.e_love_1).bind(req.e_love_2)
|
||||
.bind(req.e_love_3).bind(req.e_love_4).bind(req.e_love_5)
|
||||
.bind(req.e_love_6).bind(req.e_love_7).bind(req.e_love_8)
|
||||
// Confused emotion
|
||||
.bind(req.e_confused_0)
|
||||
.bind(req.e_confused_1)
|
||||
.bind(req.e_confused_2)
|
||||
.bind(req.e_confused_3)
|
||||
.bind(req.e_confused_4)
|
||||
.bind(req.e_confused_5)
|
||||
.bind(req.e_confused_6)
|
||||
.bind(req.e_confused_7)
|
||||
.bind(req.e_confused_8)
|
||||
.bind(req.e_confused_0).bind(req.e_confused_1).bind(req.e_confused_2)
|
||||
.bind(req.e_confused_3).bind(req.e_confused_4).bind(req.e_confused_5)
|
||||
.bind(req.e_confused_6).bind(req.e_confused_7).bind(req.e_confused_8)
|
||||
// Sleeping emotion
|
||||
.bind(req.e_sleeping_0)
|
||||
.bind(req.e_sleeping_1)
|
||||
.bind(req.e_sleeping_2)
|
||||
.bind(req.e_sleeping_3)
|
||||
.bind(req.e_sleeping_4)
|
||||
.bind(req.e_sleeping_5)
|
||||
.bind(req.e_sleeping_6)
|
||||
.bind(req.e_sleeping_7)
|
||||
.bind(req.e_sleeping_8)
|
||||
.bind(req.e_sleeping_0).bind(req.e_sleeping_1).bind(req.e_sleeping_2)
|
||||
.bind(req.e_sleeping_3).bind(req.e_sleeping_4).bind(req.e_sleeping_5)
|
||||
.bind(req.e_sleeping_6).bind(req.e_sleeping_7).bind(req.e_sleeping_8)
|
||||
// Wink emotion
|
||||
.bind(req.e_wink_0)
|
||||
.bind(req.e_wink_1)
|
||||
.bind(req.e_wink_2)
|
||||
.bind(req.e_wink_3)
|
||||
.bind(req.e_wink_4)
|
||||
.bind(req.e_wink_5)
|
||||
.bind(req.e_wink_6)
|
||||
.bind(req.e_wink_7)
|
||||
.bind(req.e_wink_8)
|
||||
.bind(req.e_wink_0).bind(req.e_wink_1).bind(req.e_wink_2)
|
||||
.bind(req.e_wink_3).bind(req.e_wink_4).bind(req.e_wink_5)
|
||||
.bind(req.e_wink_6).bind(req.e_wink_7).bind(req.e_wink_8)
|
||||
.fetch_one(executor)
|
||||
.await?;
|
||||
|
||||
|
|
@ -768,141 +504,51 @@ pub async fn update_server_avatar<'e>(
|
|||
is_public = COALESCE($4, is_public),
|
||||
is_active = COALESCE($5, is_active),
|
||||
thumbnail_path = COALESCE($6, thumbnail_path),
|
||||
l_skin_0 = COALESCE($7, l_skin_0),
|
||||
l_skin_1 = COALESCE($8, l_skin_1),
|
||||
l_skin_2 = COALESCE($9, l_skin_2),
|
||||
l_skin_3 = COALESCE($10, l_skin_3),
|
||||
l_skin_4 = COALESCE($11, l_skin_4),
|
||||
l_skin_5 = COALESCE($12, l_skin_5),
|
||||
l_skin_6 = COALESCE($13, l_skin_6),
|
||||
l_skin_7 = COALESCE($14, l_skin_7),
|
||||
l_skin_8 = COALESCE($15, l_skin_8),
|
||||
l_clothes_0 = COALESCE($16, l_clothes_0),
|
||||
l_clothes_1 = COALESCE($17, l_clothes_1),
|
||||
l_clothes_2 = COALESCE($18, l_clothes_2),
|
||||
l_clothes_3 = COALESCE($19, l_clothes_3),
|
||||
l_clothes_4 = COALESCE($20, l_clothes_4),
|
||||
l_clothes_5 = COALESCE($21, l_clothes_5),
|
||||
l_clothes_6 = COALESCE($22, l_clothes_6),
|
||||
l_clothes_7 = COALESCE($23, l_clothes_7),
|
||||
l_clothes_8 = COALESCE($24, l_clothes_8),
|
||||
l_accessories_0 = COALESCE($25, l_accessories_0),
|
||||
l_accessories_1 = COALESCE($26, l_accessories_1),
|
||||
l_accessories_2 = COALESCE($27, l_accessories_2),
|
||||
l_accessories_3 = COALESCE($28, l_accessories_3),
|
||||
l_accessories_4 = COALESCE($29, l_accessories_4),
|
||||
l_accessories_5 = COALESCE($30, l_accessories_5),
|
||||
l_accessories_6 = COALESCE($31, l_accessories_6),
|
||||
l_accessories_7 = COALESCE($32, l_accessories_7),
|
||||
l_accessories_8 = COALESCE($33, l_accessories_8),
|
||||
e_neutral_0 = COALESCE($34, e_neutral_0),
|
||||
e_neutral_1 = COALESCE($35, e_neutral_1),
|
||||
e_neutral_2 = COALESCE($36, e_neutral_2),
|
||||
e_neutral_3 = COALESCE($37, e_neutral_3),
|
||||
e_neutral_4 = COALESCE($38, e_neutral_4),
|
||||
e_neutral_5 = COALESCE($39, e_neutral_5),
|
||||
e_neutral_6 = COALESCE($40, e_neutral_6),
|
||||
e_neutral_7 = COALESCE($41, e_neutral_7),
|
||||
e_neutral_8 = COALESCE($42, e_neutral_8),
|
||||
e_happy_0 = COALESCE($43, e_happy_0),
|
||||
e_happy_1 = COALESCE($44, e_happy_1),
|
||||
e_happy_2 = COALESCE($45, e_happy_2),
|
||||
e_happy_3 = COALESCE($46, e_happy_3),
|
||||
e_happy_4 = COALESCE($47, e_happy_4),
|
||||
e_happy_5 = COALESCE($48, e_happy_5),
|
||||
e_happy_6 = COALESCE($49, e_happy_6),
|
||||
e_happy_7 = COALESCE($50, e_happy_7),
|
||||
e_happy_8 = COALESCE($51, e_happy_8),
|
||||
e_sad_0 = COALESCE($52, e_sad_0),
|
||||
e_sad_1 = COALESCE($53, e_sad_1),
|
||||
e_sad_2 = COALESCE($54, e_sad_2),
|
||||
e_sad_3 = COALESCE($55, e_sad_3),
|
||||
e_sad_4 = COALESCE($56, e_sad_4),
|
||||
e_sad_5 = COALESCE($57, e_sad_5),
|
||||
e_sad_6 = COALESCE($58, e_sad_6),
|
||||
e_sad_7 = COALESCE($59, e_sad_7),
|
||||
e_sad_8 = COALESCE($60, e_sad_8),
|
||||
e_angry_0 = COALESCE($61, e_angry_0),
|
||||
e_angry_1 = COALESCE($62, e_angry_1),
|
||||
e_angry_2 = COALESCE($63, e_angry_2),
|
||||
e_angry_3 = COALESCE($64, e_angry_3),
|
||||
e_angry_4 = COALESCE($65, e_angry_4),
|
||||
e_angry_5 = COALESCE($66, e_angry_5),
|
||||
e_angry_6 = COALESCE($67, e_angry_6),
|
||||
e_angry_7 = COALESCE($68, e_angry_7),
|
||||
e_angry_8 = COALESCE($69, e_angry_8),
|
||||
e_surprised_0 = COALESCE($70, e_surprised_0),
|
||||
e_surprised_1 = COALESCE($71, e_surprised_1),
|
||||
e_surprised_2 = COALESCE($72, e_surprised_2),
|
||||
e_surprised_3 = COALESCE($73, e_surprised_3),
|
||||
e_surprised_4 = COALESCE($74, e_surprised_4),
|
||||
e_surprised_5 = COALESCE($75, e_surprised_5),
|
||||
e_surprised_6 = COALESCE($76, e_surprised_6),
|
||||
e_surprised_7 = COALESCE($77, e_surprised_7),
|
||||
e_surprised_8 = COALESCE($78, e_surprised_8),
|
||||
e_thinking_0 = COALESCE($79, e_thinking_0),
|
||||
e_thinking_1 = COALESCE($80, e_thinking_1),
|
||||
e_thinking_2 = COALESCE($81, e_thinking_2),
|
||||
e_thinking_3 = COALESCE($82, e_thinking_3),
|
||||
e_thinking_4 = COALESCE($83, e_thinking_4),
|
||||
e_thinking_5 = COALESCE($84, e_thinking_5),
|
||||
e_thinking_6 = COALESCE($85, e_thinking_6),
|
||||
e_thinking_7 = COALESCE($86, e_thinking_7),
|
||||
e_thinking_8 = COALESCE($87, e_thinking_8),
|
||||
e_laughing_0 = COALESCE($88, e_laughing_0),
|
||||
e_laughing_1 = COALESCE($89, e_laughing_1),
|
||||
e_laughing_2 = COALESCE($90, e_laughing_2),
|
||||
e_laughing_3 = COALESCE($91, e_laughing_3),
|
||||
e_laughing_4 = COALESCE($92, e_laughing_4),
|
||||
e_laughing_5 = COALESCE($93, e_laughing_5),
|
||||
e_laughing_6 = COALESCE($94, e_laughing_6),
|
||||
e_laughing_7 = COALESCE($95, e_laughing_7),
|
||||
e_laughing_8 = COALESCE($96, e_laughing_8),
|
||||
e_crying_0 = COALESCE($97, e_crying_0),
|
||||
e_crying_1 = COALESCE($98, e_crying_1),
|
||||
e_crying_2 = COALESCE($99, e_crying_2),
|
||||
e_crying_3 = COALESCE($100, e_crying_3),
|
||||
e_crying_4 = COALESCE($101, e_crying_4),
|
||||
e_crying_5 = COALESCE($102, e_crying_5),
|
||||
e_crying_6 = COALESCE($103, e_crying_6),
|
||||
e_crying_7 = COALESCE($104, e_crying_7),
|
||||
e_crying_8 = COALESCE($105, e_crying_8),
|
||||
e_love_0 = COALESCE($106, e_love_0),
|
||||
e_love_1 = COALESCE($107, e_love_1),
|
||||
e_love_2 = COALESCE($108, e_love_2),
|
||||
e_love_3 = COALESCE($109, e_love_3),
|
||||
e_love_4 = COALESCE($110, e_love_4),
|
||||
e_love_5 = COALESCE($111, e_love_5),
|
||||
e_love_6 = COALESCE($112, e_love_6),
|
||||
e_love_7 = COALESCE($113, e_love_7),
|
||||
e_love_8 = COALESCE($114, e_love_8),
|
||||
e_confused_0 = COALESCE($115, e_confused_0),
|
||||
e_confused_1 = COALESCE($116, e_confused_1),
|
||||
e_confused_2 = COALESCE($117, e_confused_2),
|
||||
e_confused_3 = COALESCE($118, e_confused_3),
|
||||
e_confused_4 = COALESCE($119, e_confused_4),
|
||||
e_confused_5 = COALESCE($120, e_confused_5),
|
||||
e_confused_6 = COALESCE($121, e_confused_6),
|
||||
e_confused_7 = COALESCE($122, e_confused_7),
|
||||
e_confused_8 = COALESCE($123, e_confused_8),
|
||||
e_sleeping_0 = COALESCE($124, e_sleeping_0),
|
||||
e_sleeping_1 = COALESCE($125, e_sleeping_1),
|
||||
e_sleeping_2 = COALESCE($126, e_sleeping_2),
|
||||
e_sleeping_3 = COALESCE($127, e_sleeping_3),
|
||||
e_sleeping_4 = COALESCE($128, e_sleeping_4),
|
||||
e_sleeping_5 = COALESCE($129, e_sleeping_5),
|
||||
e_sleeping_6 = COALESCE($130, e_sleeping_6),
|
||||
e_sleeping_7 = COALESCE($131, e_sleeping_7),
|
||||
e_sleeping_8 = COALESCE($132, e_sleeping_8),
|
||||
e_wink_0 = COALESCE($133, e_wink_0),
|
||||
e_wink_1 = COALESCE($134, e_wink_1),
|
||||
e_wink_2 = COALESCE($135, e_wink_2),
|
||||
e_wink_3 = COALESCE($136, e_wink_3),
|
||||
e_wink_4 = COALESCE($137, e_wink_4),
|
||||
e_wink_5 = COALESCE($138, e_wink_5),
|
||||
e_wink_6 = COALESCE($139, e_wink_6),
|
||||
e_wink_7 = COALESCE($140, e_wink_7),
|
||||
e_wink_8 = COALESCE($141, e_wink_8),
|
||||
l_skin_0 = COALESCE($7, l_skin_0), l_skin_1 = COALESCE($8, l_skin_1), l_skin_2 = COALESCE($9, l_skin_2),
|
||||
l_skin_3 = COALESCE($10, l_skin_3), l_skin_4 = COALESCE($11, l_skin_4), l_skin_5 = COALESCE($12, l_skin_5),
|
||||
l_skin_6 = COALESCE($13, l_skin_6), l_skin_7 = COALESCE($14, l_skin_7), l_skin_8 = COALESCE($15, l_skin_8),
|
||||
l_clothes_0 = COALESCE($16, l_clothes_0), l_clothes_1 = COALESCE($17, l_clothes_1), l_clothes_2 = COALESCE($18, l_clothes_2),
|
||||
l_clothes_3 = COALESCE($19, l_clothes_3), l_clothes_4 = COALESCE($20, l_clothes_4), l_clothes_5 = COALESCE($21, l_clothes_5),
|
||||
l_clothes_6 = COALESCE($22, l_clothes_6), l_clothes_7 = COALESCE($23, l_clothes_7), l_clothes_8 = COALESCE($24, l_clothes_8),
|
||||
l_accessories_0 = COALESCE($25, l_accessories_0), l_accessories_1 = COALESCE($26, l_accessories_1), l_accessories_2 = COALESCE($27, l_accessories_2),
|
||||
l_accessories_3 = COALESCE($28, l_accessories_3), l_accessories_4 = COALESCE($29, l_accessories_4), l_accessories_5 = COALESCE($30, l_accessories_5),
|
||||
l_accessories_6 = COALESCE($31, l_accessories_6), l_accessories_7 = COALESCE($32, l_accessories_7), l_accessories_8 = COALESCE($33, l_accessories_8),
|
||||
e_neutral_0 = COALESCE($34, e_neutral_0), e_neutral_1 = COALESCE($35, e_neutral_1), e_neutral_2 = COALESCE($36, e_neutral_2),
|
||||
e_neutral_3 = COALESCE($37, e_neutral_3), e_neutral_4 = COALESCE($38, e_neutral_4), e_neutral_5 = COALESCE($39, e_neutral_5),
|
||||
e_neutral_6 = COALESCE($40, e_neutral_6), e_neutral_7 = COALESCE($41, e_neutral_7), e_neutral_8 = COALESCE($42, e_neutral_8),
|
||||
e_happy_0 = COALESCE($43, e_happy_0), e_happy_1 = COALESCE($44, e_happy_1), e_happy_2 = COALESCE($45, e_happy_2),
|
||||
e_happy_3 = COALESCE($46, e_happy_3), e_happy_4 = COALESCE($47, e_happy_4), e_happy_5 = COALESCE($48, e_happy_5),
|
||||
e_happy_6 = COALESCE($49, e_happy_6), e_happy_7 = COALESCE($50, e_happy_7), e_happy_8 = COALESCE($51, e_happy_8),
|
||||
e_sad_0 = COALESCE($52, e_sad_0), e_sad_1 = COALESCE($53, e_sad_1), e_sad_2 = COALESCE($54, e_sad_2),
|
||||
e_sad_3 = COALESCE($55, e_sad_3), e_sad_4 = COALESCE($56, e_sad_4), e_sad_5 = COALESCE($57, e_sad_5),
|
||||
e_sad_6 = COALESCE($58, e_sad_6), e_sad_7 = COALESCE($59, e_sad_7), e_sad_8 = COALESCE($60, e_sad_8),
|
||||
e_angry_0 = COALESCE($61, e_angry_0), e_angry_1 = COALESCE($62, e_angry_1), e_angry_2 = COALESCE($63, e_angry_2),
|
||||
e_angry_3 = COALESCE($64, e_angry_3), e_angry_4 = COALESCE($65, e_angry_4), e_angry_5 = COALESCE($66, e_angry_5),
|
||||
e_angry_6 = COALESCE($67, e_angry_6), e_angry_7 = COALESCE($68, e_angry_7), e_angry_8 = COALESCE($69, e_angry_8),
|
||||
e_surprised_0 = COALESCE($70, e_surprised_0), e_surprised_1 = COALESCE($71, e_surprised_1), e_surprised_2 = COALESCE($72, e_surprised_2),
|
||||
e_surprised_3 = COALESCE($73, e_surprised_3), e_surprised_4 = COALESCE($74, e_surprised_4), e_surprised_5 = COALESCE($75, e_surprised_5),
|
||||
e_surprised_6 = COALESCE($76, e_surprised_6), e_surprised_7 = COALESCE($77, e_surprised_7), e_surprised_8 = COALESCE($78, e_surprised_8),
|
||||
e_thinking_0 = COALESCE($79, e_thinking_0), e_thinking_1 = COALESCE($80, e_thinking_1), e_thinking_2 = COALESCE($81, e_thinking_2),
|
||||
e_thinking_3 = COALESCE($82, e_thinking_3), e_thinking_4 = COALESCE($83, e_thinking_4), e_thinking_5 = COALESCE($84, e_thinking_5),
|
||||
e_thinking_6 = COALESCE($85, e_thinking_6), e_thinking_7 = COALESCE($86, e_thinking_7), e_thinking_8 = COALESCE($87, e_thinking_8),
|
||||
e_laughing_0 = COALESCE($88, e_laughing_0), e_laughing_1 = COALESCE($89, e_laughing_1), e_laughing_2 = COALESCE($90, e_laughing_2),
|
||||
e_laughing_3 = COALESCE($91, e_laughing_3), e_laughing_4 = COALESCE($92, e_laughing_4), e_laughing_5 = COALESCE($93, e_laughing_5),
|
||||
e_laughing_6 = COALESCE($94, e_laughing_6), e_laughing_7 = COALESCE($95, e_laughing_7), e_laughing_8 = COALESCE($96, e_laughing_8),
|
||||
e_crying_0 = COALESCE($97, e_crying_0), e_crying_1 = COALESCE($98, e_crying_1), e_crying_2 = COALESCE($99, e_crying_2),
|
||||
e_crying_3 = COALESCE($100, e_crying_3), e_crying_4 = COALESCE($101, e_crying_4), e_crying_5 = COALESCE($102, e_crying_5),
|
||||
e_crying_6 = COALESCE($103, e_crying_6), e_crying_7 = COALESCE($104, e_crying_7), e_crying_8 = COALESCE($105, e_crying_8),
|
||||
e_love_0 = COALESCE($106, e_love_0), e_love_1 = COALESCE($107, e_love_1), e_love_2 = COALESCE($108, e_love_2),
|
||||
e_love_3 = COALESCE($109, e_love_3), e_love_4 = COALESCE($110, e_love_4), e_love_5 = COALESCE($111, e_love_5),
|
||||
e_love_6 = COALESCE($112, e_love_6), e_love_7 = COALESCE($113, e_love_7), e_love_8 = COALESCE($114, e_love_8),
|
||||
e_confused_0 = COALESCE($115, e_confused_0), e_confused_1 = COALESCE($116, e_confused_1), e_confused_2 = COALESCE($117, e_confused_2),
|
||||
e_confused_3 = COALESCE($118, e_confused_3), e_confused_4 = COALESCE($119, e_confused_4), e_confused_5 = COALESCE($120, e_confused_5),
|
||||
e_confused_6 = COALESCE($121, e_confused_6), e_confused_7 = COALESCE($122, e_confused_7), e_confused_8 = COALESCE($123, e_confused_8),
|
||||
e_sleeping_0 = COALESCE($124, e_sleeping_0), e_sleeping_1 = COALESCE($125, e_sleeping_1), e_sleeping_2 = COALESCE($126, e_sleeping_2),
|
||||
e_sleeping_3 = COALESCE($127, e_sleeping_3), e_sleeping_4 = COALESCE($128, e_sleeping_4), e_sleeping_5 = COALESCE($129, e_sleeping_5),
|
||||
e_sleeping_6 = COALESCE($130, e_sleeping_6), e_sleeping_7 = COALESCE($131, e_sleeping_7), e_sleeping_8 = COALESCE($132, e_sleeping_8),
|
||||
e_wink_0 = COALESCE($133, e_wink_0), e_wink_1 = COALESCE($134, e_wink_1), e_wink_2 = COALESCE($135, e_wink_2),
|
||||
e_wink_3 = COALESCE($136, e_wink_3), e_wink_4 = COALESCE($137, e_wink_4), e_wink_5 = COALESCE($138, e_wink_5),
|
||||
e_wink_6 = COALESCE($139, e_wink_6), e_wink_7 = COALESCE($140, e_wink_7), e_wink_8 = COALESCE($141, e_wink_8),
|
||||
updated_at = now()
|
||||
WHERE id = $1
|
||||
RETURNING *
|
||||
|
|
@ -915,155 +561,65 @@ pub async fn update_server_avatar<'e>(
|
|||
.bind(req.is_active)
|
||||
.bind(&req.thumbnail_path)
|
||||
// Skin layer
|
||||
.bind(req.l_skin_0)
|
||||
.bind(req.l_skin_1)
|
||||
.bind(req.l_skin_2)
|
||||
.bind(req.l_skin_3)
|
||||
.bind(req.l_skin_4)
|
||||
.bind(req.l_skin_5)
|
||||
.bind(req.l_skin_6)
|
||||
.bind(req.l_skin_7)
|
||||
.bind(req.l_skin_8)
|
||||
.bind(req.l_skin_0).bind(req.l_skin_1).bind(req.l_skin_2)
|
||||
.bind(req.l_skin_3).bind(req.l_skin_4).bind(req.l_skin_5)
|
||||
.bind(req.l_skin_6).bind(req.l_skin_7).bind(req.l_skin_8)
|
||||
// Clothes layer
|
||||
.bind(req.l_clothes_0)
|
||||
.bind(req.l_clothes_1)
|
||||
.bind(req.l_clothes_2)
|
||||
.bind(req.l_clothes_3)
|
||||
.bind(req.l_clothes_4)
|
||||
.bind(req.l_clothes_5)
|
||||
.bind(req.l_clothes_6)
|
||||
.bind(req.l_clothes_7)
|
||||
.bind(req.l_clothes_8)
|
||||
.bind(req.l_clothes_0).bind(req.l_clothes_1).bind(req.l_clothes_2)
|
||||
.bind(req.l_clothes_3).bind(req.l_clothes_4).bind(req.l_clothes_5)
|
||||
.bind(req.l_clothes_6).bind(req.l_clothes_7).bind(req.l_clothes_8)
|
||||
// Accessories layer
|
||||
.bind(req.l_accessories_0)
|
||||
.bind(req.l_accessories_1)
|
||||
.bind(req.l_accessories_2)
|
||||
.bind(req.l_accessories_3)
|
||||
.bind(req.l_accessories_4)
|
||||
.bind(req.l_accessories_5)
|
||||
.bind(req.l_accessories_6)
|
||||
.bind(req.l_accessories_7)
|
||||
.bind(req.l_accessories_8)
|
||||
.bind(req.l_accessories_0).bind(req.l_accessories_1).bind(req.l_accessories_2)
|
||||
.bind(req.l_accessories_3).bind(req.l_accessories_4).bind(req.l_accessories_5)
|
||||
.bind(req.l_accessories_6).bind(req.l_accessories_7).bind(req.l_accessories_8)
|
||||
// Neutral emotion
|
||||
.bind(req.e_neutral_0)
|
||||
.bind(req.e_neutral_1)
|
||||
.bind(req.e_neutral_2)
|
||||
.bind(req.e_neutral_3)
|
||||
.bind(req.e_neutral_4)
|
||||
.bind(req.e_neutral_5)
|
||||
.bind(req.e_neutral_6)
|
||||
.bind(req.e_neutral_7)
|
||||
.bind(req.e_neutral_8)
|
||||
.bind(req.e_neutral_0).bind(req.e_neutral_1).bind(req.e_neutral_2)
|
||||
.bind(req.e_neutral_3).bind(req.e_neutral_4).bind(req.e_neutral_5)
|
||||
.bind(req.e_neutral_6).bind(req.e_neutral_7).bind(req.e_neutral_8)
|
||||
// Happy emotion
|
||||
.bind(req.e_happy_0)
|
||||
.bind(req.e_happy_1)
|
||||
.bind(req.e_happy_2)
|
||||
.bind(req.e_happy_3)
|
||||
.bind(req.e_happy_4)
|
||||
.bind(req.e_happy_5)
|
||||
.bind(req.e_happy_6)
|
||||
.bind(req.e_happy_7)
|
||||
.bind(req.e_happy_8)
|
||||
.bind(req.e_happy_0).bind(req.e_happy_1).bind(req.e_happy_2)
|
||||
.bind(req.e_happy_3).bind(req.e_happy_4).bind(req.e_happy_5)
|
||||
.bind(req.e_happy_6).bind(req.e_happy_7).bind(req.e_happy_8)
|
||||
// Sad emotion
|
||||
.bind(req.e_sad_0)
|
||||
.bind(req.e_sad_1)
|
||||
.bind(req.e_sad_2)
|
||||
.bind(req.e_sad_3)
|
||||
.bind(req.e_sad_4)
|
||||
.bind(req.e_sad_5)
|
||||
.bind(req.e_sad_6)
|
||||
.bind(req.e_sad_7)
|
||||
.bind(req.e_sad_8)
|
||||
.bind(req.e_sad_0).bind(req.e_sad_1).bind(req.e_sad_2)
|
||||
.bind(req.e_sad_3).bind(req.e_sad_4).bind(req.e_sad_5)
|
||||
.bind(req.e_sad_6).bind(req.e_sad_7).bind(req.e_sad_8)
|
||||
// Angry emotion
|
||||
.bind(req.e_angry_0)
|
||||
.bind(req.e_angry_1)
|
||||
.bind(req.e_angry_2)
|
||||
.bind(req.e_angry_3)
|
||||
.bind(req.e_angry_4)
|
||||
.bind(req.e_angry_5)
|
||||
.bind(req.e_angry_6)
|
||||
.bind(req.e_angry_7)
|
||||
.bind(req.e_angry_8)
|
||||
.bind(req.e_angry_0).bind(req.e_angry_1).bind(req.e_angry_2)
|
||||
.bind(req.e_angry_3).bind(req.e_angry_4).bind(req.e_angry_5)
|
||||
.bind(req.e_angry_6).bind(req.e_angry_7).bind(req.e_angry_8)
|
||||
// Surprised emotion
|
||||
.bind(req.e_surprised_0)
|
||||
.bind(req.e_surprised_1)
|
||||
.bind(req.e_surprised_2)
|
||||
.bind(req.e_surprised_3)
|
||||
.bind(req.e_surprised_4)
|
||||
.bind(req.e_surprised_5)
|
||||
.bind(req.e_surprised_6)
|
||||
.bind(req.e_surprised_7)
|
||||
.bind(req.e_surprised_8)
|
||||
.bind(req.e_surprised_0).bind(req.e_surprised_1).bind(req.e_surprised_2)
|
||||
.bind(req.e_surprised_3).bind(req.e_surprised_4).bind(req.e_surprised_5)
|
||||
.bind(req.e_surprised_6).bind(req.e_surprised_7).bind(req.e_surprised_8)
|
||||
// Thinking emotion
|
||||
.bind(req.e_thinking_0)
|
||||
.bind(req.e_thinking_1)
|
||||
.bind(req.e_thinking_2)
|
||||
.bind(req.e_thinking_3)
|
||||
.bind(req.e_thinking_4)
|
||||
.bind(req.e_thinking_5)
|
||||
.bind(req.e_thinking_6)
|
||||
.bind(req.e_thinking_7)
|
||||
.bind(req.e_thinking_8)
|
||||
.bind(req.e_thinking_0).bind(req.e_thinking_1).bind(req.e_thinking_2)
|
||||
.bind(req.e_thinking_3).bind(req.e_thinking_4).bind(req.e_thinking_5)
|
||||
.bind(req.e_thinking_6).bind(req.e_thinking_7).bind(req.e_thinking_8)
|
||||
// Laughing emotion
|
||||
.bind(req.e_laughing_0)
|
||||
.bind(req.e_laughing_1)
|
||||
.bind(req.e_laughing_2)
|
||||
.bind(req.e_laughing_3)
|
||||
.bind(req.e_laughing_4)
|
||||
.bind(req.e_laughing_5)
|
||||
.bind(req.e_laughing_6)
|
||||
.bind(req.e_laughing_7)
|
||||
.bind(req.e_laughing_8)
|
||||
.bind(req.e_laughing_0).bind(req.e_laughing_1).bind(req.e_laughing_2)
|
||||
.bind(req.e_laughing_3).bind(req.e_laughing_4).bind(req.e_laughing_5)
|
||||
.bind(req.e_laughing_6).bind(req.e_laughing_7).bind(req.e_laughing_8)
|
||||
// Crying emotion
|
||||
.bind(req.e_crying_0)
|
||||
.bind(req.e_crying_1)
|
||||
.bind(req.e_crying_2)
|
||||
.bind(req.e_crying_3)
|
||||
.bind(req.e_crying_4)
|
||||
.bind(req.e_crying_5)
|
||||
.bind(req.e_crying_6)
|
||||
.bind(req.e_crying_7)
|
||||
.bind(req.e_crying_8)
|
||||
.bind(req.e_crying_0).bind(req.e_crying_1).bind(req.e_crying_2)
|
||||
.bind(req.e_crying_3).bind(req.e_crying_4).bind(req.e_crying_5)
|
||||
.bind(req.e_crying_6).bind(req.e_crying_7).bind(req.e_crying_8)
|
||||
// Love emotion
|
||||
.bind(req.e_love_0)
|
||||
.bind(req.e_love_1)
|
||||
.bind(req.e_love_2)
|
||||
.bind(req.e_love_3)
|
||||
.bind(req.e_love_4)
|
||||
.bind(req.e_love_5)
|
||||
.bind(req.e_love_6)
|
||||
.bind(req.e_love_7)
|
||||
.bind(req.e_love_8)
|
||||
.bind(req.e_love_0).bind(req.e_love_1).bind(req.e_love_2)
|
||||
.bind(req.e_love_3).bind(req.e_love_4).bind(req.e_love_5)
|
||||
.bind(req.e_love_6).bind(req.e_love_7).bind(req.e_love_8)
|
||||
// Confused emotion
|
||||
.bind(req.e_confused_0)
|
||||
.bind(req.e_confused_1)
|
||||
.bind(req.e_confused_2)
|
||||
.bind(req.e_confused_3)
|
||||
.bind(req.e_confused_4)
|
||||
.bind(req.e_confused_5)
|
||||
.bind(req.e_confused_6)
|
||||
.bind(req.e_confused_7)
|
||||
.bind(req.e_confused_8)
|
||||
.bind(req.e_confused_0).bind(req.e_confused_1).bind(req.e_confused_2)
|
||||
.bind(req.e_confused_3).bind(req.e_confused_4).bind(req.e_confused_5)
|
||||
.bind(req.e_confused_6).bind(req.e_confused_7).bind(req.e_confused_8)
|
||||
// Sleeping emotion
|
||||
.bind(req.e_sleeping_0)
|
||||
.bind(req.e_sleeping_1)
|
||||
.bind(req.e_sleeping_2)
|
||||
.bind(req.e_sleeping_3)
|
||||
.bind(req.e_sleeping_4)
|
||||
.bind(req.e_sleeping_5)
|
||||
.bind(req.e_sleeping_6)
|
||||
.bind(req.e_sleeping_7)
|
||||
.bind(req.e_sleeping_8)
|
||||
.bind(req.e_sleeping_0).bind(req.e_sleeping_1).bind(req.e_sleeping_2)
|
||||
.bind(req.e_sleeping_3).bind(req.e_sleeping_4).bind(req.e_sleeping_5)
|
||||
.bind(req.e_sleeping_6).bind(req.e_sleeping_7).bind(req.e_sleeping_8)
|
||||
// Wink emotion
|
||||
.bind(req.e_wink_0)
|
||||
.bind(req.e_wink_1)
|
||||
.bind(req.e_wink_2)
|
||||
.bind(req.e_wink_3)
|
||||
.bind(req.e_wink_4)
|
||||
.bind(req.e_wink_5)
|
||||
.bind(req.e_wink_6)
|
||||
.bind(req.e_wink_7)
|
||||
.bind(req.e_wink_8)
|
||||
.bind(req.e_wink_0).bind(req.e_wink_1).bind(req.e_wink_2)
|
||||
.bind(req.e_wink_3).bind(req.e_wink_4).bind(req.e_wink_5)
|
||||
.bind(req.e_wink_6).bind(req.e_wink_7).bind(req.e_wink_8)
|
||||
.fetch_one(executor)
|
||||
.await?;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue