#!/bin/bash # Set up stock avatar: upload props, create avatar, set as server default. # # Usage: ./stock/avatar/setup.sh [--force|-f] [HOST] # # Options: # --force, -f Update existing props/avatar instead of failing on conflict # # HOST defaults to http://localhost:3001 (owner admin port) # # Prerequisites: # 1. Run the dev server: ./run-dev.sh -f # 2. Wait for it to finish building: ./run-dev.sh -s set -e # Parse arguments FORCE="" HOST="http://localhost:3001" for arg in "$@"; do case "$arg" in --force|-f) FORCE="?force=true" ;; http://*) HOST="$arg" ;; esac done SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" echo "==========================================" echo "Stock Avatar Setup" echo "==========================================" echo "Host: $HOST" echo "Source: $SCRIPT_DIR" echo "" # Check if server is running echo "Checking server health..." health_response=$(curl -s -o /dev/null -w "%{http_code}" "$HOST/api/admin/health" 2>/dev/null || echo "000") if [ "$health_response" != "200" ]; then echo "ERROR: Server is not responding at $HOST (HTTP $health_response)" echo "" echo "Make sure the server is running:" echo " ./run-dev.sh -f" echo " ./run-dev.sh -s # Check status" exit 1 fi echo "Server is healthy!" echo "" # ============================================================================= # Step 1: Upload Props # ============================================================================= echo "==========================================" echo "Step 1: Uploading Props" echo "==========================================" capitalize() { echo "$1" | sed 's/.*/\u&/' } get_tags() { local filename="$1" case "$filename" in face.svg) echo '["base", "face"]' ;; neutral.svg|smile.svg|sad.svg|angry.svg|surprised.svg|thinking.svg|laughing.svg|crying.svg|love.svg|confused.svg|sleeping.svg|wink.svg) echo '["face"]' ;; *) echo '["prop"]' ;; esac } get_positioning() { local filename="$1" case "$filename" in face.svg) echo "layer:skin" ;; neutral.svg|smile.svg|sad.svg|angry.svg|surprised.svg|thinking.svg|laughing.svg|crying.svg|love.svg|confused.svg|sleeping.svg|wink.svg) echo "layer:emote" ;; *) echo "none" ;; esac } upload_count=0 upload_fail=0 for file in "$SCRIPT_DIR"/*.svg; do if [ ! -f "$file" ]; then continue fi filename=$(basename "$file") name_without_ext="${filename%.svg}" display_name=$(capitalize "$name_without_ext") tags=$(get_tags "$filename") positioning=$(get_positioning "$filename") echo " $filename -> $display_name" positioning_type="${positioning%%:*}" positioning_value="${positioning#*:}" case "$positioning_type" in layer) positioning_json="\"default_layer\": \"$positioning_value\", \"default_position\": 4" ;; *) positioning_json="" ;; esac if [ -n "$positioning_json" ]; then metadata="{\"name\": \"$display_name\", \"tags\": $tags, $positioning_json}" else metadata="{\"name\": \"$display_name\", \"tags\": $tags}" fi response=$(curl -s -w "\n%{http_code}" -X POST "$HOST/api/admin/props$FORCE" \ -F "metadata=$metadata" \ -F "file=@$file") http_code=$(echo "$response" | tail -n1) if [ "$http_code" = "200" ] || [ "$http_code" = "201" ]; then echo " ✓ Uploaded" ((++upload_count)) else body=$(echo "$response" | sed '$d') echo " ✗ Failed (HTTP $http_code): $body" ((++upload_fail)) fi done echo "" echo "Props: $upload_count uploaded, $upload_fail failed" echo "" if [ "$upload_fail" -gt 0 ] && [ -z "$FORCE" ]; then echo "Some props failed. Use --force to update existing props." exit 1 fi # ============================================================================= # Step 2: Query Prop UUIDs # ============================================================================= echo "==========================================" echo "Step 2: Creating Avatar" echo "==========================================" # Query prop UUID by slug via API get_prop_id() { local slug="$1" curl -s "$HOST/api/admin/props/by-slug/$slug" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4 } echo "Querying prop UUIDs..." FACE_ID=$(get_prop_id "face") if [ -z "$FACE_ID" ]; then echo "ERROR: Face prop not found." exit 1 fi NEUTRAL_ID=$(get_prop_id "neutral") SMILE_ID=$(get_prop_id "smile") SAD_ID=$(get_prop_id "sad") ANGRY_ID=$(get_prop_id "angry") SURPRISED_ID=$(get_prop_id "surprised") THINKING_ID=$(get_prop_id "thinking") LAUGHING_ID=$(get_prop_id "laughing") CRYING_ID=$(get_prop_id "crying") LOVE_ID=$(get_prop_id "love") CONFUSED_ID=$(get_prop_id "confused") SLEEPING_ID=$(get_prop_id "sleeping") WINK_ID=$(get_prop_id "wink") # Validate all props exist missing="" [ -z "$NEUTRAL_ID" ] && missing="$missing neutral" [ -z "$SMILE_ID" ] && missing="$missing smile" [ -z "$SAD_ID" ] && missing="$missing sad" [ -z "$ANGRY_ID" ] && missing="$missing angry" [ -z "$SURPRISED_ID" ] && missing="$missing surprised" [ -z "$THINKING_ID" ] && missing="$missing thinking" [ -z "$LAUGHING_ID" ] && missing="$missing laughing" [ -z "$CRYING_ID" ] && missing="$missing crying" [ -z "$LOVE_ID" ] && missing="$missing love" [ -z "$CONFUSED_ID" ] && missing="$missing confused" [ -z "$SLEEPING_ID" ] && missing="$missing sleeping" [ -z "$WINK_ID" ] && missing="$missing wink" if [ -n "$missing" ]; then echo "ERROR: Missing props:$missing" exit 1 fi echo " ✓ All 13 props found" # ============================================================================= # Step 3: Create Avatar # ============================================================================= # Check if avatar already exists existing_avatar=$(curl -s "$HOST/api/admin/avatars/by-slug/stock-avatar" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4) if [ -n "$existing_avatar" ] && [ -z "$FORCE" ]; then echo "Stock avatar already exists: $existing_avatar" echo "Use --force to recreate." AVATAR_ID="$existing_avatar" else avatar_json=$(cat < /dev/null fi response=$(curl -s -w "\n%{http_code}" -X POST "$HOST/api/admin/avatars" \ -H "Content-Type: application/json" \ -d "$avatar_json") http_code=$(echo "$response" | tail -n1) body=$(echo "$response" | sed '$d') if [ "$http_code" = "200" ] || [ "$http_code" = "201" ]; then AVATAR_ID=$(echo "$body" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4) echo " ✓ Created avatar: $AVATAR_ID" else echo " ✗ Failed (HTTP $http_code): $body" exit 1 fi fi # ============================================================================= # Step 4: Set as Server Default # ============================================================================= echo "" echo "==========================================" echo "Step 3: Setting Server Defaults" echo "==========================================" response=$(curl -s -w "\n%{http_code}" -X PATCH "$HOST/api/admin/config/default-avatars" \ -H "Content-Type: application/json" \ -d "{ \"default_avatar_neutral_child\": \"$AVATAR_ID\", \"default_avatar_neutral_adult\": \"$AVATAR_ID\", \"default_avatar_male_child\": \"$AVATAR_ID\", \"default_avatar_male_adult\": \"$AVATAR_ID\", \"default_avatar_female_child\": \"$AVATAR_ID\", \"default_avatar_female_adult\": \"$AVATAR_ID\" }") http_code=$(echo "$response" | tail -n1) if [ "$http_code" = "200" ]; then echo " ✓ Set all 6 default avatar columns" else echo " ✗ Failed (HTTP $http_code)" exit 1 fi echo "" echo "==========================================" echo "Stock Avatar Setup Complete!" echo "==========================================" echo "Avatar ID: $AVATAR_ID" echo ""