generated from osc/skins-template
test
Some checks failed
Generate Skin previews, OSK files and per skin documentation / Full CI/CD Pipeline (push) Failing after 1s
Some checks failed
Generate Skin previews, OSK files and per skin documentation / Full CI/CD Pipeline (push) Failing after 1s
This commit is contained in:
@@ -63,933 +63,46 @@ jobs:
|
|||||||
tags: true
|
tags: true
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Discover all skins
|
- name: Discover and Detect Skins
|
||||||
shell: bash
|
id: discover
|
||||||
run: |
|
uses: ${{ env.REGISTRY_URL}}/osc/reusable-actions/.gitea/workflows/actions/discover-skins@main
|
||||||
echo "Discovering all skins in $SKINS_DIR…"
|
with:
|
||||||
mapfile -t skins < <(
|
force_rebuild: ${{ github.event.inputs.force_rebuild }}
|
||||||
find "$SKINS_DIR" -mindepth 1 -maxdepth 1 -type d \
|
target_skins: ${{ github.event.inputs.target_skins }}
|
||||||
| sed 's|'"$SKINS_DIR"'/||'
|
|
||||||
)
|
- name: Pull Git LFS
|
||||||
{
|
uses: ${{ env.REGISTRY_URL}}/osc/reusable-actions/.gitea/workflows/actions/pull-lfs@main
|
||||||
echo 'ALL_SKINS_DIR<<EOF'
|
with:
|
||||||
for s in "${skins[@]}"; do
|
changed_skins_file: ${{ steps.discover.outputs.changed_skins_file }}
|
||||||
echo "$s"
|
|
||||||
done
|
- name: Prepare Assets
|
||||||
echo 'EOF'
|
id: prepare
|
||||||
} >> "$GITHUB_ENV"
|
uses: ${{ env.REGISTRY_URL}}/osc/reusable-actions/.gitea/workflows/actions/prepare-assets@main
|
||||||
echo "→ ALL_SKINS_DIR set (newline-delimited list)"
|
with:
|
||||||
|
all_skins: ${{ steps.discover.outputs.all_skins }}
|
||||||
- name: Detect Changed Skin Directories
|
|
||||||
shell: bash
|
- name: Create Tag
|
||||||
run: |
|
id: tag
|
||||||
echo "[Detect Changed Skin Directories Started]"
|
uses: ${{ env.REGISTRY_URL}}/osc/reusable-actions/.gitea/workflows/actions/create-tag@main
|
||||||
|
|
||||||
readarray -t all_skins <<< "$ALL_SKINS_DIR"
|
- name: Generate Previews (videos + screenshots + renames)
|
||||||
|
uses: ${{ env.REGISTRY_URL}}/osc/reusable-actions/.gitea/workflows/actions/generate-previews@main
|
||||||
force_rebuild="${{ github.event.inputs.force_rebuild }}"
|
with:
|
||||||
target_skins="${{ github.event.inputs.target_skins }}"
|
changed_skins_file: ${{ steps.discover.outputs.changed_skins_file }}
|
||||||
skins=()
|
|
||||||
deleted_skins=()
|
- name: Generate Mod Icons and Convert Images
|
||||||
|
uses: ${{ env.REGISTRY_URL}}/osc/reusable-actions/.gitea/workflows/actions/generate-icons@main
|
||||||
echo "→ Force rebuild flag: $force_rebuild"
|
with:
|
||||||
echo "→ Target skins input: $target_skins"
|
changed_skins_file: ${{ steps.discover.outputs.changed_skins_file }}
|
||||||
|
|
||||||
if [[ "$force_rebuild" == "true" ]]; then
|
- name: Generate Documentation
|
||||||
echo "→ Force rebuild is enabled. Using ALL_SKINS_DIR for full list…"
|
uses: ${{ env.REGISTRY_URL}}/osc/reusable-actions/.gitea/workflows/actions/generate-docs@main
|
||||||
skins=("${all_skins[@]}")
|
with:
|
||||||
echo " ✓ Found ${#skins[@]} skin directories (from ALL_SKINS_DIR)"
|
new_tag: ${{ steps.tag.outputs.new_tag }}
|
||||||
|
readme_path: ${{ env.README_PATH }}
|
||||||
elif [[ -n "$target_skins" ]]; then
|
doc_dir: ${{ env.DOC_DIR }}
|
||||||
echo "→ Target skins specified. Using target_skins input…"
|
|
||||||
IFS=',' read -r -a input_skins <<< "$target_skins"
|
- name: Commit and Push
|
||||||
for s in "${input_skins[@]}"; do
|
uses: ${{ env.REGISTRY_URL}}/osc/reusable-actions/.gitea/workflows/actions/git-commit-push@main
|
||||||
s="${s#"${s%%[![:space:]]*}"}"
|
with:
|
||||||
s="${s%"${s##*[![:space:]]}"}"
|
new_tag: ${{ steps.tag.outputs.new_tag }}
|
||||||
[[ -n "$s" ]] && skins+=("$s")
|
|
||||||
done
|
|
||||||
echo " ✓ Found ${#skins[@]} skin(s) from target_skins input"
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "→ No rebuild flags set. Finding latest git tag..."
|
|
||||||
latest_tag=$(git tag --sort=-creatordate | head -n 1 || true)
|
|
||||||
|
|
||||||
if [[ -n "$latest_tag" ]]; then
|
|
||||||
echo "→ Latest tag found: $latest_tag"
|
|
||||||
echo "→ Finding added/modified skins since $latest_tag…"
|
|
||||||
|
|
||||||
mapfile -t skins < <(
|
|
||||||
git diff --name-only -z --diff-filter=AM "$latest_tag" HEAD \
|
|
||||||
| while IFS= read -r -d '' file; do
|
|
||||||
[[ $file == Skins/* ]] && echo "${file#Skins/}" | cut -d/ -f1
|
|
||||||
done | sort -u
|
|
||||||
)
|
|
||||||
echo " ✓ Found ${#skins[@]} added/modified skins"
|
|
||||||
|
|
||||||
echo "→ Finding deleted skins since $latest_tag…"
|
|
||||||
mapfile -t deleted_skins < <(
|
|
||||||
git diff --name-only -z --diff-filter=D "$latest_tag" HEAD \
|
|
||||||
| while IFS= read -r -d '' file; do
|
|
||||||
[[ $file == Skins/* ]] && echo "${file#Skins/}" | cut -d/ -f1
|
|
||||||
done | sort -u
|
|
||||||
)
|
|
||||||
if [ "${#deleted_skins[@]}" -gt 0 ]; then
|
|
||||||
for d in "${deleted_skins[@]}"; do
|
|
||||||
echo "→ Skin '$d' was deleted"
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo " ✓ No skins deleted"
|
|
||||||
fi
|
|
||||||
|
|
||||||
else
|
|
||||||
echo "→ No tag found. Falling back to ALL_SKINS_DIR for full list…"
|
|
||||||
skins=("${all_skins[@]}")
|
|
||||||
echo " ✓ Found ${#skins[@]} skin directories (from ALL_SKINS_DIR)"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[Cleaning Skin Names]"
|
|
||||||
uniq_skins=()
|
|
||||||
for skin in "${skins[@]}"; do
|
|
||||||
skin="${skin#"${skin%%[![:space:]]*}"}"
|
|
||||||
skin="${skin%"${skin##*[![:space:]]}"}"
|
|
||||||
[[ -n "$skin" ]] && uniq_skins+=("$skin")
|
|
||||||
done
|
|
||||||
echo " ✓ ${#uniq_skins[@]} valid skin names after cleaning"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
if [ "${#uniq_skins[@]}" -eq 0 ]; then
|
|
||||||
echo "→ No added/modified skins detected."
|
|
||||||
echo "CHANGED_SKINS_FILE=" >> "$GITHUB_ENV"
|
|
||||||
else
|
|
||||||
echo "[Writing Changed Skins to File]"
|
|
||||||
changed_skins_file=$(mktemp)
|
|
||||||
printf "%s\n" "${uniq_skins[@]}" > "$changed_skins_file"
|
|
||||||
echo " ✓ Skins written to $changed_skins_file"
|
|
||||||
echo "CHANGED_SKINS_FILE=$changed_skins_file" >> "$GITHUB_ENV"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[Detect Changed Skin Directories Complete — ${#uniq_skins[@]} skins processed, ${#deleted_skins[@]} skins deleted]"
|
|
||||||
|
|
||||||
- name: Pull Git LFS objects for changed skins (and core assets)
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
if [ -z "${CHANGED_SKINS_FILE:-}" ] || [ ! -s "$CHANGED_SKINS_FILE" ]; then
|
|
||||||
echo "No skins changed. Skipping git pull lfs."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
includes="src/**,export/**,media/**"
|
|
||||||
|
|
||||||
skin_includes=$(
|
|
||||||
while IFS= read -r skin; do
|
|
||||||
esc=$(printf '%s' "$skin" \
|
|
||||||
| sed -e 's/\[/\\[/g' -e 's/\]/\\]/g')
|
|
||||||
printf 'Skins/%s/**\n' "$esc"
|
|
||||||
done < "$CHANGED_SKINS_FILE" \
|
|
||||||
| paste -sd ','
|
|
||||||
)
|
|
||||||
|
|
||||||
includes="$includes,$skin_includes"
|
|
||||||
|
|
||||||
echo "→ Pulling LFS objects for patterns: $includes"
|
|
||||||
git lfs pull --include="$includes"
|
|
||||||
|
|
||||||
- name: Extract Repository path
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "Extracting repository path..."
|
|
||||||
USER_REPOSITORY="${{ github.workspace }}"
|
|
||||||
USER_REPOSITORY="${USER_REPOSITORY#/workspace/}"
|
|
||||||
USER_REPOSITORY="${USER_REPOSITORY%/}"
|
|
||||||
echo "Repository path extracted: $USER_REPOSITORY"
|
|
||||||
echo "USER_REPOSITORY=$USER_REPOSITORY" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Set XDG_RUNTIME_DIR
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "Setting XDG_RUNTIME_DIR..."
|
|
||||||
mkdir -p /tmp/xdg_runtime_dir
|
|
||||||
chmod 0700 /tmp/xdg_runtime_dir
|
|
||||||
echo "XDG_RUNTIME_DIR=/tmp/xdg_runtime_dir" >> "$GITHUB_ENV"
|
|
||||||
echo "XDG_RUNTIME_DIR set."
|
|
||||||
|
|
||||||
- name: Create directories for assets
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "Creating base directories for assets..."
|
|
||||||
mkdir -p "$REPO_SCREENSHOT_DIR" "$REPO_MOD_ICONS_DIR" "$REPO_RANKING_PANEL_DIR" "$OSK_PATH" "$REPO_THUMBNAIL_DIR"
|
|
||||||
|
|
||||||
readarray -t skins <<< "$ALL_SKINS_DIR"
|
|
||||||
|
|
||||||
for skin in "${skins[@]}"; do
|
|
||||||
echo " → Creating subdirs for '$skin'…"
|
|
||||||
mkdir -p \
|
|
||||||
"$REPO_SCREENSHOT_DIR/$skin" \
|
|
||||||
"$REPO_MOD_ICONS_DIR/$skin" \
|
|
||||||
"$REPO_RANKING_PANEL_DIR/$skin" \
|
|
||||||
"$OSK_PATH/$skin" \
|
|
||||||
"$REPO_THUMBNAIL_DIR/$skin"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "All asset directories created for ${#skins[@]} skins."
|
|
||||||
|
|
||||||
- name: Create New Tag
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "Computing new tag..."
|
|
||||||
latest_tag=$(git describe --tags $(git rev-list --tags --max-count=1) 2>/dev/null || echo "")
|
|
||||||
if [ -z "$latest_tag" ]; then
|
|
||||||
new_tag="v1.0.0"
|
|
||||||
else
|
|
||||||
IFS='.' read -r major minor patch <<< "${latest_tag#v}"
|
|
||||||
minor=$((minor + 1))
|
|
||||||
patch=0
|
|
||||||
new_tag="v${major}.${minor}.${patch}"
|
|
||||||
fi
|
|
||||||
echo "new_tag=$new_tag" >> $GITHUB_ENV
|
|
||||||
echo "Computed new tag: $new_tag"
|
|
||||||
|
|
||||||
- name: Move Skin files to Danser Skins directory
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "Moving Skin files to Danser Skins directory..."
|
|
||||||
mkdir -p "$DANSER_SKINS_DIR"
|
|
||||||
mv "$SKINS_DIR"/* "$DANSER_SKINS_DIR"
|
|
||||||
echo "Skin files moved."
|
|
||||||
|
|
||||||
- name: Generate Danser videos and screenshots
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "[Danser Job Started]"
|
|
||||||
|
|
||||||
if [ -z "${CHANGED_SKINS_FILE:-}" ] || [ ! -s "$CHANGED_SKINS_FILE" ]; then
|
|
||||||
echo "No skins changed. Skipping generation."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
mapfile -t skins < "$CHANGED_SKINS_FILE"
|
|
||||||
[ "${#skins[@]}" -eq 0 ] && { echo "No skins to process. Exiting."; exit 0; }
|
|
||||||
|
|
||||||
SKIN_COUNT=${#skins[@]}
|
|
||||||
INDEX=1
|
|
||||||
|
|
||||||
for skin_path in "${skins[@]}"; do
|
|
||||||
[ -z "$skin_path" ] && continue
|
|
||||||
SKIN_DIR="$DANSER_SKINS_DIR/$skin_path"
|
|
||||||
[ ! -d "$SKIN_DIR" ] && { echo "Skipping missing skin: $skin_path"; continue; }
|
|
||||||
|
|
||||||
SKIN_NAME="$skin_path"
|
|
||||||
OUT_VIDEO_DIR="$REPO_SCREENSHOT_DIR/$SKIN_NAME"
|
|
||||||
OUT_PNG_DIR="$REPO_RANKING_PANEL_DIR/$SKIN_NAME"
|
|
||||||
OUT_THUMBNAIL_DIR="$REPO_THUMBNAIL_DIR/$SKIN_NAME"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[$INDEX/$SKIN_COUNT] Generating for skin: $SKIN_NAME"
|
|
||||||
|
|
||||||
LOGFILE="/tmp/danser_log_$INDEX.txt"
|
|
||||||
|
|
||||||
echo " → Generating video..."
|
|
||||||
if ! xvfb-run -a "$DANSER_DIR/danser-cli" \
|
|
||||||
-replay "$GAMEPLAY_REPLAY_PATH" -record -skip -start=300 -end=307 -noupdatecheck \
|
|
||||||
-out="$SKIN_NAME" -skin="$SKIN_NAME" -settings="skinhub" >"$LOGFILE" 2>&1; then
|
|
||||||
echo " ✖ Video failed for $SKIN_NAME"; cat "$LOGFILE"; INDEX=$((INDEX+1)); continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" ]; then
|
|
||||||
echo " → Trimming MP4 with ffmpeg..."
|
|
||||||
ffmpeg -hide_banner -loglevel error \
|
|
||||||
-ss 5 -t 6.5 \
|
|
||||||
-i "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" \
|
|
||||||
-c:v h264_nvenc -preset fast \
|
|
||||||
-c:a aac -b:a 128k \
|
|
||||||
"$DANSER_VIDEO_DIR/${SKIN_NAME}_trimmed.mp4"
|
|
||||||
|
|
||||||
if [ -f "$DANSER_VIDEO_DIR/${SKIN_NAME}_trimmed.mp4" ]; then
|
|
||||||
mv "$DANSER_VIDEO_DIR/${SKIN_NAME}_trimmed.mp4" "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4"
|
|
||||||
mkdir -p "$OUT_VIDEO_DIR"
|
|
||||||
mv "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" "$OUT_VIDEO_DIR/$SKIN_NAME.mp4"
|
|
||||||
echo " ✓ Trimmed MP4 moved to $OUT_VIDEO_DIR/"
|
|
||||||
else
|
|
||||||
echo " ✖ ffmpeg trimming failed for $SKIN_NAME"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo " ✖ No MP4 found for $SKIN_NAME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo " → Taking screenshot..."
|
|
||||||
if ! xvfb-run -a "$DANSER_DIR/danser-cli" \
|
|
||||||
-replay "$PANEL_REPLAY_PATH" -skip -settings="skinhub" -noupdatecheck -ss 28 \
|
|
||||||
-out="$SKIN_NAME" -skin="$SKIN_NAME" >>"$LOGFILE" 2>&1; then
|
|
||||||
echo " ✖ Screenshot failed for $SKIN_NAME"; cat "$LOGFILE"; INDEX=$((INDEX+1)); continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$DANSER_SCREENSHOT_DIR/$SKIN_NAME.png" ]; then
|
|
||||||
mkdir -p "$OUT_PNG_DIR"
|
|
||||||
mv "$DANSER_SCREENSHOT_DIR/$SKIN_NAME.png" "$OUT_PNG_DIR/$SKIN_NAME.png"
|
|
||||||
echo " ✓ PNG moved to $OUT_PNG_DIR/"
|
|
||||||
else
|
|
||||||
echo " ✖ No PNG found for $SKIN_NAME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo " → Taking thumbnail screenshot..."
|
|
||||||
if ! xvfb-run -a "$DANSER_DIR/danser-cli" \
|
|
||||||
-replay "$THUMBNAIL_REPLAY_PATH" -skip -settings="skinhub" -noupdatecheck -ss 1.3 \
|
|
||||||
-out="${SKIN_NAME}_thumb" -skin="$SKIN_NAME" >>"$LOGFILE" 2>&1; then
|
|
||||||
echo " ✖ Thumbnail screenshot failed for $SKIN_NAME"; cat "$LOGFILE"; INDEX=$((INDEX+1)); continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$DANSER_SCREENSHOT_DIR/${SKIN_NAME}_thumb.png" ]; then
|
|
||||||
mkdir -p "$OUT_THUMBNAIL_DIR"
|
|
||||||
mv "$DANSER_SCREENSHOT_DIR/${SKIN_NAME}_thumb.png" "$OUT_THUMBNAIL_DIR/$SKIN_NAME.png"
|
|
||||||
echo " ✓ Thumbnail PNG moved to $OUT_THUMBNAIL_DIR/"
|
|
||||||
else
|
|
||||||
echo " ✖ No thumbnail PNG found for $SKIN_NAME"
|
|
||||||
fi
|
|
||||||
|
|
||||||
INDEX=$((INDEX + 1))
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[Danser Job Finished — processed $SKIN_COUNT skins]"
|
|
||||||
|
|
||||||
- name: Rename Generated Assets Based on skin.ini
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "[Asset Renaming Job Started]"
|
|
||||||
|
|
||||||
if [ -z "${CHANGED_SKINS_FILE:-}" ] || [ ! -s "$CHANGED_SKINS_FILE" ]; then
|
|
||||||
echo "No skins changed. Skipping asset renaming."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
mapfile -t skins < "$CHANGED_SKINS_FILE"
|
|
||||||
[ "${#skins[@]}" -eq 0 ] && { echo "No skins to rename. Exiting."; exit 0; }
|
|
||||||
|
|
||||||
SKIN_COUNT=${#skins[@]}
|
|
||||||
INDEX=1
|
|
||||||
|
|
||||||
sanitize_filename() {
|
|
||||||
echo "$1" | \
|
|
||||||
tr -d '\000-\037' | \
|
|
||||||
sed -e 's#[\\/:\*\?"<>|]#-#g' | \
|
|
||||||
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
|
|
||||||
}
|
|
||||||
|
|
||||||
for skin_path in "${skins[@]}"; do
|
|
||||||
[ -z "$skin_path" ] && continue
|
|
||||||
SKIN_DIR_NAME="$skin_path"
|
|
||||||
SKIN_DIR="$DANSER_SKINS_DIR/$skin_path"
|
|
||||||
if [ ! -d "$SKIN_DIR" ]; then
|
|
||||||
echo "Skipping missing skin directory: $SKIN_DIR"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Processing skin $INDEX/$SKIN_COUNT: $SKIN_DIR_NAME"
|
|
||||||
|
|
||||||
skin_header="$SKIN_DIR_NAME"
|
|
||||||
ini_file=$(find "$SKIN_DIR" -maxdepth 1 -iname "skin.ini" | head -n1 || true)
|
|
||||||
if [ -f "$ini_file" ]; then
|
|
||||||
name_line=$(grep -i '^[[:space:]]*Name:' "$ini_file" | head -n1 || true)
|
|
||||||
if [ -n "$name_line" ]; then
|
|
||||||
val="${name_line#*:}"
|
|
||||||
val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
|
||||||
if [ -n "$val" ]; then
|
|
||||||
sanitized="$(sanitize_filename "$val")"
|
|
||||||
[ -n "$sanitized" ] && skin_header="$sanitized"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
VIDEO_DIR="$REPO_SCREENSHOT_DIR/$SKIN_DIR_NAME"
|
|
||||||
PNG_DIR="$REPO_RANKING_PANEL_DIR/$SKIN_DIR_NAME"
|
|
||||||
THUMBNAIL_DIR="$REPO_THUMBNAIL_DIR/$SKIN_DIR_NAME"
|
|
||||||
|
|
||||||
if [ -f "$VIDEO_DIR/$SKIN_DIR_NAME.mp4" ] && [ "$SKIN_DIR_NAME" != "$skin_header" ]; then
|
|
||||||
mv -f "$VIDEO_DIR/$SKIN_DIR_NAME.mp4" \
|
|
||||||
"$VIDEO_DIR/$skin_header.mp4" || true
|
|
||||||
echo " ✓ Renamed MP4 to $VIDEO_DIR/$skin_header.mp4"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$PNG_DIR/$SKIN_DIR_NAME.png" ] && [ "$SKIN_DIR_NAME" != "$skin_header" ]; then
|
|
||||||
mv -f "$PNG_DIR/$SKIN_DIR_NAME.png" \
|
|
||||||
"$PNG_DIR/$skin_header.png" || true
|
|
||||||
echo " ✓ Renamed PNG to $PNG_DIR/$skin_header.png"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -f "$THUMBNAIL_DIR/$SKIN_DIR_NAME.png" ] && [ "$SKIN_DIR_NAME" != "$skin_header" ]; then
|
|
||||||
mv -f "$THUMBNAIL_DIR/$SKIN_DIR_NAME.png" \
|
|
||||||
"$THUMBNAIL_DIR/$skin_header.png" || true
|
|
||||||
echo " ✓ Renamed thumbnail to $THUMBNAIL_DIR/$skin_header.png"
|
|
||||||
fi
|
|
||||||
|
|
||||||
INDEX=$((INDEX + 1))
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[Asset Renaming Complete — processed $SKIN_COUNT skins]"
|
|
||||||
|
|
||||||
- name: Generate Mod Icons (WEBP)
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "[Mod Icon Generation Job Started]"
|
|
||||||
|
|
||||||
if [ -z "${CHANGED_SKINS_FILE:-}" ] || [ ! -s "$CHANGED_SKINS_FILE" ]; then
|
|
||||||
echo "No skins changed. Skipping mod icon generation."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
mapfile -t skin_dirs < "$CHANGED_SKINS_FILE"
|
|
||||||
[ "${#skin_dirs[@]}" -eq 0 ] && { echo "No skins to process. Exiting."; exit 0; }
|
|
||||||
|
|
||||||
sanitize_filename() {
|
|
||||||
echo "$1" | \
|
|
||||||
tr -d '\000-\037' | \
|
|
||||||
sed -e 's#[\\/:\*\?"<>|]#-#g' | \
|
|
||||||
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
|
|
||||||
}
|
|
||||||
|
|
||||||
ICONS_JSON_FILE="${{ github.workspace }}/.gitea/workflows/icons.json"
|
|
||||||
group1_icons=$(jq -r '.group1 | join(" ")' "$ICONS_JSON_FILE")
|
|
||||||
group2_icons=$(jq -r '.group2 | join(" ")' "$ICONS_JSON_FILE")
|
|
||||||
group3_icons=$(jq -r '.group3 | join(" ")' "$ICONS_JSON_FILE")
|
|
||||||
|
|
||||||
BLANK_IMAGE="blank.png"
|
|
||||||
magick -size "160x160" xc:none "$BLANK_IMAGE"
|
|
||||||
|
|
||||||
SKIN_COUNT=${#skin_dirs[@]}
|
|
||||||
INDEX=1
|
|
||||||
|
|
||||||
for skin_path in "${skin_dirs[@]}"; do
|
|
||||||
SKIN_DIR="$DANSER_SKINS_DIR/$skin_path"
|
|
||||||
[ ! -d "$SKIN_DIR" ] && { echo "Skipping missing skin directory: $SKIN_DIR"; ((INDEX++)); continue; }
|
|
||||||
|
|
||||||
skin_header="$skin_path"
|
|
||||||
ini_file=$(find "$SKIN_DIR" -maxdepth 1 -iname "skin.ini" | head -n1 || true)
|
|
||||||
if [ -f "$ini_file" ]; then
|
|
||||||
name_line=$(grep -i '^[[:space:]]*Name:' "$ini_file" | head -n1 || true)
|
|
||||||
if [ -n "$name_line" ]; then
|
|
||||||
val="${name_line#*:}"
|
|
||||||
val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
|
||||||
if [ -n "$val" ]; then
|
|
||||||
sanitized="$(sanitize_filename "$val")"
|
|
||||||
[ -n "$sanitized" ] && skin_header="$sanitized"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[$INDEX/$SKIN_COUNT] Skin: $skin_header"
|
|
||||||
|
|
||||||
ICON_FOLDER="$SKIN_DIR"
|
|
||||||
OUTPUT_DIR="$REPO_MOD_ICONS_DIR/$skin_path"
|
|
||||||
mkdir -p "$OUTPUT_DIR"
|
|
||||||
OUTPUT="$OUTPUT_DIR/${skin_header}-mod-icons.webp"
|
|
||||||
|
|
||||||
row_images=()
|
|
||||||
row_index=1
|
|
||||||
|
|
||||||
for group_list in "$group1_icons" "$group2_icons" "$group3_icons"; do
|
|
||||||
montage_files=()
|
|
||||||
for icon in $group_list; do
|
|
||||||
file=""
|
|
||||||
if [ -f "${ICON_FOLDER}/selection-mod-${icon}@2x.png" ]; then
|
|
||||||
file="${ICON_FOLDER}/selection-mod-${icon}@2x.png"
|
|
||||||
elif [ -f "${ICON_FOLDER}/selection-mod-${icon}.png" ]; then
|
|
||||||
file="${ICON_FOLDER}/selection-mod-${icon}.png"
|
|
||||||
elif [ -f "${DEFAULT_SKIN_DIR}/selection-mod-${icon}@2x.png" ]; then
|
|
||||||
file="${DEFAULT_SKIN_DIR}/selection-mod-${icon}@2x.png"
|
|
||||||
fi
|
|
||||||
|
|
||||||
[ -n "$file" ] && montage_files+=("$file")
|
|
||||||
done
|
|
||||||
|
|
||||||
while [ "${#montage_files[@]}" -lt 7 ]; do
|
|
||||||
montage_files+=("$BLANK_IMAGE")
|
|
||||||
done
|
|
||||||
|
|
||||||
magick montage "${montage_files[@]}" \
|
|
||||||
-tile "7x1" -geometry "160x160+10+10" -background none \
|
|
||||||
"row_${row_index}.png"
|
|
||||||
row_images+=("row_${row_index}.png")
|
|
||||||
row_index=$((row_index + 1))
|
|
||||||
done
|
|
||||||
|
|
||||||
magick montage "${row_images[@]}" \
|
|
||||||
-tile "1x${#row_images[@]}" -geometry "+10+10" -background none \
|
|
||||||
"temp_combined.png"
|
|
||||||
|
|
||||||
magick "temp_combined.png" -define webp:lossless=true "$OUTPUT"
|
|
||||||
rm temp_combined.png row_*.png
|
|
||||||
|
|
||||||
echo " ✓ Mod Icons Generated at $OUTPUT"
|
|
||||||
INDEX=$((INDEX + 1))
|
|
||||||
done
|
|
||||||
|
|
||||||
rm "$BLANK_IMAGE"
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[Mod Icon Generation Finished — processed $SKIN_COUNT skins]"
|
|
||||||
|
|
||||||
- name: Convert PNGs to WEBPs
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "[Convert PNG → WEBP Started]"
|
|
||||||
|
|
||||||
if [ -z "${CHANGED_SKINS_FILE:-}" ] || [ ! -s "$CHANGED_SKINS_FILE" ]; then
|
|
||||||
echo "No skins changed. Skipping conversion."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
mapfile -t skins < "$CHANGED_SKINS_FILE"
|
|
||||||
[ "${#skins[@]}" -eq 0 ] && { echo "No skins to process. Exiting."; exit 0; }
|
|
||||||
|
|
||||||
convert_pngs_to_webp() {
|
|
||||||
local base_dir="$1"
|
|
||||||
local skin_path="$2"
|
|
||||||
local dir="$base_dir/$skin_path"
|
|
||||||
echo " → Processing: $dir"
|
|
||||||
[ ! -d "$dir" ] && { echo " ✖ Directory does not exist: $dir"; return; }
|
|
||||||
find "$dir" -type f -iname "*.png" | while read -r png; do
|
|
||||||
webp="${png%.png}.webp"
|
|
||||||
echo " ↳ Converting: $png → $webp"
|
|
||||||
magick "$png" -define webp:lossless=false -quality 90 "$webp" && rm -f "$png"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
for skin_path in "${skins[@]}"; do
|
|
||||||
[ -z "$skin_path" ] && continue
|
|
||||||
convert_pngs_to_webp "$REPO_RANKING_PANEL_DIR" "$skin_path"
|
|
||||||
convert_pngs_to_webp "$REPO_THUMBNAIL_DIR" "$skin_path"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "[Convert PNG → WEBP Finished]"
|
|
||||||
|
|
||||||
- name: Create OSK Files
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "[OSK Creation Job Started]"
|
|
||||||
|
|
||||||
if [ -z "${CHANGED_SKINS_FILE:-}" ] || [ ! -s "$CHANGED_SKINS_FILE" ]; then
|
|
||||||
echo "No skins changed. Skipping OSK creation."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
mapfile -t skin_dirs < "$CHANGED_SKINS_FILE"
|
|
||||||
[ "${#skin_dirs[@]}" -eq 0 ] && { echo "No skins to process. Exiting."; exit 0; }
|
|
||||||
|
|
||||||
sanitize_filename() {
|
|
||||||
echo "$1" | \
|
|
||||||
tr -d '\000-\037' | \
|
|
||||||
sed -e 's#[\\/:\*\?"<>|]#-#g' | \
|
|
||||||
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
|
|
||||||
}
|
|
||||||
|
|
||||||
FIXED_TIMESTAMP="2025-01-01 00:00:00"
|
|
||||||
SKIN_COUNT=${#skin_dirs[@]}
|
|
||||||
INDEX=1
|
|
||||||
|
|
||||||
for skin_path in "${skin_dirs[@]}"; do
|
|
||||||
SKIN_DIR="$DANSER_SKINS_DIR/$skin_path"
|
|
||||||
[ ! -d "$SKIN_DIR" ] && { echo "Skipping missing skin directory: $SKIN_DIR"; ((INDEX++)); continue; }
|
|
||||||
|
|
||||||
OUTPUT_DIR="$OSK_PATH/$skin_path"
|
|
||||||
mkdir -p "$OUTPUT_DIR"
|
|
||||||
|
|
||||||
skin_header="$skin_path"
|
|
||||||
ini_file=$(find "$SKIN_DIR" -maxdepth 1 -iname "skin.ini" | head -n1 || true)
|
|
||||||
if [ -f "$ini_file" ]; then
|
|
||||||
name_line=$(grep -i '^[[:space:]]*name:' "$ini_file" | head -n1 || true)
|
|
||||||
if [ -n "$name_line" ]; then
|
|
||||||
val="${name_line#*:}"
|
|
||||||
val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
|
||||||
if [ -n "$val" ]; then
|
|
||||||
sanitized="$(sanitize_filename "$val")"
|
|
||||||
[ -n "$sanitized" ] && skin_header="$sanitized"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[$INDEX/$SKIN_COUNT] Processing skin: $skin_header"
|
|
||||||
|
|
||||||
(cd "$SKIN_DIR" && find . -type f -exec touch -d "$FIXED_TIMESTAMP" {} +)
|
|
||||||
|
|
||||||
(cd "$SKIN_DIR" && find . -type f | sort | \
|
|
||||||
zip -rq -D -X -9 --compression-method deflate \
|
|
||||||
"$OUTPUT_DIR/${skin_header}.osk" -@)
|
|
||||||
|
|
||||||
echo " ✓ OSK file created at $OUTPUT_DIR/${skin_header}.osk"
|
|
||||||
INDEX=$((INDEX + 1))
|
|
||||||
done
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "[OSK Creation Job Finished — processed $SKIN_COUNT skins]"
|
|
||||||
|
|
||||||
- name: Generate README
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "Generating README index…"
|
|
||||||
|
|
||||||
sanitize_filename() {
|
|
||||||
echo "$1" | \
|
|
||||||
tr -d '\000-\037' | \
|
|
||||||
sed -e 's#[\\/:\*\?"<>|]#-#g' -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
|
|
||||||
}
|
|
||||||
|
|
||||||
url_encode_path() {
|
|
||||||
local IFS='/'
|
|
||||||
local parts=($1)
|
|
||||||
local encoded=""
|
|
||||||
for part in "${parts[@]}"; do
|
|
||||||
[ -n "$encoded" ] && encoded+="/"
|
|
||||||
encoded+=$(printf '%s' "$part" | jq -sRr @uri)
|
|
||||||
done
|
|
||||||
echo "$encoded"
|
|
||||||
}
|
|
||||||
|
|
||||||
SKINS_JSON_FILE="${{ github.workspace }}/.gitea/workflows/skins.json"
|
|
||||||
DESC_FILE=$(mktemp)
|
|
||||||
|
|
||||||
echo "---" > "$README_PATH"
|
|
||||||
echo "gitea: none" >> "$README_PATH"
|
|
||||||
echo "include_toc: true" >> "$README_PATH"
|
|
||||||
echo "---" >> "$README_PATH"
|
|
||||||
echo "" >> "$README_PATH"
|
|
||||||
echo "# Skins" >> "$README_PATH"
|
|
||||||
echo "" >> "$README_PATH"
|
|
||||||
echo "<!--" >> "$README_PATH"
|
|
||||||
echo "osuid: $OSU_ID" >> "$README_PATH"
|
|
||||||
echo "-->" >> "$README_PATH"
|
|
||||||
echo "" >> "$README_PATH"
|
|
||||||
echo "**Go back to [osc/skins]($REGISTRY_URL/osc/skins)**" >> "$README_PATH"
|
|
||||||
echo "" >> "$README_PATH"
|
|
||||||
echo "**Click on the Skin name to download it, or click on the thumbnail to see more about the skin, including a video preview, screenshots, and mod icons.**" >> "$README_PATH"
|
|
||||||
echo "" >> "$README_PATH"
|
|
||||||
|
|
||||||
jq -r '.descriptions | to_entries[] | "\(.key)=\(.value)"' "$SKINS_JSON_FILE" > "$DESC_FILE"
|
|
||||||
jq -r '.order[]?' "$SKINS_JSON_FILE" > order.txt
|
|
||||||
|
|
||||||
get_desc() {
|
|
||||||
grep -F -m1 -- "$1=" "$DESC_FILE" 2>/dev/null | cut -d '=' -f2- || true
|
|
||||||
}
|
|
||||||
|
|
||||||
declare -A ordered
|
|
||||||
while IFS= read -r skin; do
|
|
||||||
[ "$skin" = "default-skin" ] && continue
|
|
||||||
ordered["$skin"]=1
|
|
||||||
dir="$DANSER_SKINS_DIR/$skin"
|
|
||||||
[ ! -d "$dir" ] && continue
|
|
||||||
|
|
||||||
ini_file=$(find "$dir" -maxdepth 1 -iname "skin.ini" | head -n1 || true)
|
|
||||||
skin_header="$skin"
|
|
||||||
|
|
||||||
if [ -f "$ini_file" ]; then
|
|
||||||
name_line=$(grep -a -i -m1 'Name[[:space:]]*:' "$ini_file" || true)
|
|
||||||
if [ -n "$name_line" ]; then
|
|
||||||
val="${name_line#*:}"
|
|
||||||
val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
|
||||||
[ -n "$val" ] && skin_header=$(sanitize_filename "$val")
|
|
||||||
else
|
|
||||||
skin_header=$(sanitize_filename "$skin")
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
raw_path="$(printf "%s/%s" "$skin" "$skin_header" | sed 's/^ *//;s/ *$//')"
|
|
||||||
base_path=$(url_encode_path "$raw_path")
|
|
||||||
|
|
||||||
echo "## [$skin_header]($REGISTRY_URL/$USER_REPOSITORY/media/tag/$new_tag/export/${base_path}.osk)" >> "$README_PATH"
|
|
||||||
echo "" >> "$README_PATH"
|
|
||||||
|
|
||||||
desc=$(get_desc "$skin")
|
|
||||||
[ -n "$desc" ] && { echo "$desc" >> "$README_PATH"; echo "" >> "$README_PATH"; }
|
|
||||||
|
|
||||||
if [ -f "$ini_file" ]; then
|
|
||||||
author_line=$(grep -i '^[[:space:]]*Author:' "$ini_file" | head -n1 || true)
|
|
||||||
if [ -n "$author_line" ]; then
|
|
||||||
author=$(echo "$author_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
||||||
[ -n "$author" ] && { echo "**Author:** $author" >> "$README_PATH"; echo "" >> "$README_PATH"; }
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[](/docs/${base_path}.md)" >> "$README_PATH"
|
|
||||||
echo "" >> "$README_PATH"
|
|
||||||
done < order.txt
|
|
||||||
|
|
||||||
for dir in "$DANSER_SKINS_DIR"/*; do
|
|
||||||
[ -d "$dir" ] || continue
|
|
||||||
skin="$(basename "$dir")"
|
|
||||||
[ "$skin" = "default-skin" ] && continue
|
|
||||||
[[ -n "${ordered[$skin]}" ]] && continue
|
|
||||||
|
|
||||||
ini_file=$(find "$dir" -maxdepth 1 -iname "skin.ini" | head -n1 || true)
|
|
||||||
skin_header="$skin"
|
|
||||||
|
|
||||||
if [ -f "$ini_file" ]; then
|
|
||||||
name_line=$(grep -a -i -m1 'Name[[:space:]]*:' "$ini_file" || true)
|
|
||||||
if [ -n "$name_line" ]; then
|
|
||||||
val="${name_line#*:}"
|
|
||||||
val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
|
||||||
[ -n "$val" ] && skin_header=$(sanitize_filename "$val")
|
|
||||||
else
|
|
||||||
skin_header=$(sanitize_filename "$skin")
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
|
|
||||||
raw_path="$(printf "%s/%s" "$skin" "$skin_header" | sed 's/^ *//;s/ *$//')"
|
|
||||||
base_path=$(url_encode_path "$raw_path")
|
|
||||||
|
|
||||||
echo "## [$skin_header]($REGISTRY_URL/$USER_REPOSITORY/media/tag/$new_tag/export/${base_path}.osk)" >> "$README_PATH"
|
|
||||||
echo "" >> "$README_PATH"
|
|
||||||
|
|
||||||
if [ -f "$ini_file" ]; then
|
|
||||||
author_line=$(grep -i '^[[:space:]]*Author:' "$ini_file" | head -n1 || true)
|
|
||||||
if [ -n "$author_line" ]; then
|
|
||||||
author=$(echo "$author_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
||||||
[ -n "$author" ] && { echo "**Author:** $author" >> "$README_PATH"; echo "" >> "$README_PATH"; }
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "[](/docs/${base_path}.md)" >> "$README_PATH"
|
|
||||||
echo "" >> "$README_PATH"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "# Build History" >> "$README_PATH"
|
|
||||||
echo "" >> "$README_PATH"
|
|
||||||
echo "| Version | Date |" >> "$README_PATH"
|
|
||||||
echo "| ------- | ---- |" >> "$README_PATH"
|
|
||||||
|
|
||||||
current_commit_date=$(TZ="Europe/Zurich" date -d "$(git log -1 --format=%cI)" "+%d.%m.%Y %H:%M:%S")
|
|
||||||
echo "| [\`$new_tag (Current)\`]($REGISTRY_URL/$USER_REPOSITORY/src/tag/$new_tag/README.md) | $current_commit_date |" >> "$README_PATH"
|
|
||||||
|
|
||||||
old_tags=$(git tag --sort=-v:refname | grep -v "^$new_tag$" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' || true)
|
|
||||||
if [ -n "$old_tags" ]; then
|
|
||||||
echo "$old_tags" | while read -r tag; do
|
|
||||||
tag_date=$(git log -1 --format=%ci "$tag")
|
|
||||||
formatted_date=$(TZ="Europe/Zurich" date -d "$tag_date" "+%d.%m.%Y %H:%M:%S")
|
|
||||||
echo "| [\`$tag\`]($REGISTRY_URL/$USER_REPOSITORY/src/tag/$tag/README.md) | $formatted_date |" >> "$README_PATH"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "README index generated successfully."
|
|
||||||
|
|
||||||
- name: Generate Per-Skin Pages
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
echo "Generating detailed per-skin markdown pages…"
|
|
||||||
|
|
||||||
sanitize_filename() {
|
|
||||||
echo "$1" | \
|
|
||||||
tr -d '\000-\037' | \
|
|
||||||
sed -e 's#[\\/:\*\?"<>|]#-#g' | \
|
|
||||||
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
|
|
||||||
}
|
|
||||||
|
|
||||||
url_encode_path() {
|
|
||||||
local IFS='/'
|
|
||||||
local parts=($1)
|
|
||||||
local encoded=""
|
|
||||||
for part in "${parts[@]}"; do
|
|
||||||
[ -n "$encoded" ] && encoded+="/"
|
|
||||||
encoded+=$(printf '%s' "$part" | jq -sRr @uri)
|
|
||||||
done
|
|
||||||
echo "$encoded"
|
|
||||||
}
|
|
||||||
|
|
||||||
mkdir -p "$DOC_DIR"
|
|
||||||
|
|
||||||
for dir in "$DANSER_SKINS_DIR"/*; do
|
|
||||||
[ -d "$dir" ] || continue
|
|
||||||
|
|
||||||
skin=$(basename "$dir")
|
|
||||||
[ "$skin" = "default-skin" ] && continue
|
|
||||||
ini_file=$(find "$dir" -maxdepth 1 -iname "skin.ini" | head -n1 || true)
|
|
||||||
skin_header="$skin"
|
|
||||||
|
|
||||||
if [ -f "$ini_file" ]; then
|
|
||||||
line=$(grep -i '^[[:space:]]*Name:' "$ini_file" | head -n1 || true)
|
|
||||||
if [ -n "$line" ]; then
|
|
||||||
val="${line#*:}"
|
|
||||||
val="$(echo "$val" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
|
||||||
if [ -n "$val" ]; then
|
|
||||||
skin_header=$(sanitize_filename "$val")
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
raw_path="${skin}/${skin_header}"
|
|
||||||
base_path=$(url_encode_path "$raw_path")
|
|
||||||
osk_url="$REGISTRY_URL/$USER_REPOSITORY/media/tag/$new_tag/export/${base_path}.osk"
|
|
||||||
md_file_path="${DOC_DIR}/${raw_path}.md"
|
|
||||||
|
|
||||||
mkdir -p "$(dirname "$md_file_path")"
|
|
||||||
|
|
||||||
video_url="$REGISTRY_URL/$USER_REPOSITORY/media/tag/$new_tag/media/gameplay/${base_path}.mp4"
|
|
||||||
|
|
||||||
author=""
|
|
||||||
if [ -f "$ini_file" ]; then
|
|
||||||
author_line=$(grep -i '^[[:space:]]*Author:' "$ini_file" | head -n1 || true)
|
|
||||||
if [ -n "$author_line" ]; then
|
|
||||||
author=$(echo "$author_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
{
|
|
||||||
echo "# [$skin_header]($osk_url)"
|
|
||||||
echo ""
|
|
||||||
[ -n "$author" ] && echo "**Author:** $author"
|
|
||||||
[ -n "$author" ] && echo ""
|
|
||||||
|
|
||||||
echo "## Hitsounds"
|
|
||||||
echo "<video controls autoplay loop muted playsinline src=\"$video_url\" type=\"video/mp4\">"
|
|
||||||
echo "</video>"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "## Ranking Panel"
|
|
||||||
echo ""
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo "## Mod Icons"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
echo ""
|
|
||||||
echo "## Build History"
|
|
||||||
echo ""
|
|
||||||
echo "| Version | Date |"
|
|
||||||
echo "| ------- | ---- |"
|
|
||||||
|
|
||||||
current_commit_date=$(TZ="Europe/Zurich" date -d "$(git log -1 --format=%cI)" "+%d.%m.%Y %H:%M:%S")
|
|
||||||
echo "| [\`$new_tag (Current)\`]($REGISTRY_URL/$USER_REPOSITORY/src/tag/$new_tag/docs/${base_path}.md) | $current_commit_date |"
|
|
||||||
|
|
||||||
old_tags=$(git tag --sort=-v:refname | grep -v "^$new_tag$" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' || true)
|
|
||||||
if [ -n "$old_tags" ]; then
|
|
||||||
echo "$old_tags" | while read -r tag; do
|
|
||||||
raw_osk_path="export/${skin}/${skin_header}.osk"
|
|
||||||
if git ls-tree -r --name-only "$tag" | grep -Fx -- "$raw_osk_path" >/dev/null; then
|
|
||||||
tag_date=$(git log -1 --format=%ci "$tag")
|
|
||||||
formatted_date=$(TZ="Europe/Zurich" date -d "$tag_date" "+%d.%m.%Y %H:%M:%S")
|
|
||||||
echo "| [\`$tag\`]($REGISTRY_URL/$USER_REPOSITORY/src/tag/$tag/docs/${base_path}.md) | $formatted_date |"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
} > "$md_file_path"
|
|
||||||
|
|
||||||
echo " → Wrote $md_file_path"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "Per-skin markdown pages complete."
|
|
||||||
|
|
||||||
- name: Cleanup Extra Files
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
set -euo pipefail
|
|
||||||
echo "[Cleanup Extra Files Started]"
|
|
||||||
|
|
||||||
[ -f how-to-use.md ] && rm -f how-to-use.md
|
|
||||||
[ -f src/replay.osr ] && rm -f src/replay.osr
|
|
||||||
[ -d src/default-skin ] && rm -rf src/default-skin
|
|
||||||
|
|
||||||
readarray -t skins <<< "$ALL_SKINS_DIR"
|
|
||||||
|
|
||||||
sanitize_filename() {
|
|
||||||
echo "$1" | \
|
|
||||||
tr -d '\000-\037' | \
|
|
||||||
sed -e 's#[\\/:\*\?"<>|]#-#g' | \
|
|
||||||
sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
|
|
||||||
}
|
|
||||||
|
|
||||||
prune_dir() {
|
|
||||||
local root="$1"
|
|
||||||
local skin="$2"
|
|
||||||
local expected="$3"
|
|
||||||
|
|
||||||
for f in "$root"/*; do
|
|
||||||
[ -f "$f" ] || continue
|
|
||||||
name="$(basename "$f")"
|
|
||||||
if printf '%s\n' "${skins[@]}" | grep -Fxq -- "$name"; then
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
echo " → Removing unexpected root file: $f"
|
|
||||||
rm -f "$f"
|
|
||||||
done
|
|
||||||
|
|
||||||
dir="$root/$skin"
|
|
||||||
[ -d "$dir" ] || return
|
|
||||||
for f in "$dir"/*; do
|
|
||||||
[ -e "$f" ] || continue
|
|
||||||
if [[ "$(basename "$f")" != "$expected" ]]; then
|
|
||||||
echo " → Removing unexpected file: $f"
|
|
||||||
rm -f "$f"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
for root in "$REPO_SCREENSHOT_DIR" "$REPO_RANKING_PANEL_DIR" "$REPO_MOD_ICONS_DIR" "$REPO_THUMBNAIL_DIR" "$OSK_PATH" "$DOC_DIR"; do
|
|
||||||
[ -d "$root" ] || continue
|
|
||||||
for dir in "$root"/*; do
|
|
||||||
[ -d "$dir" ] || continue
|
|
||||||
name="$(basename "$dir")"
|
|
||||||
if ! printf '%s\n' "${skins[@]}" | grep -Fxq -- "$name"; then
|
|
||||||
echo " → Skin '$name' deleted—removing directory $dir"
|
|
||||||
rm -rf "$dir"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
for skin in "${skins[@]}"; do
|
|
||||||
header=$(sanitize_filename "$skin")
|
|
||||||
ini=$(find "$DANSER_SKINS_DIR/$skin" -maxdepth 1 -type f -iname "skin.ini" -print -quit || true)
|
|
||||||
if [[ -f "$ini" ]]; then
|
|
||||||
raw=$(grep -i '^[[:space:]]*Name:' "$ini" | head -n1 || true)
|
|
||||||
raw="${raw#*:}"
|
|
||||||
raw="$(echo "$raw" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')"
|
|
||||||
tmp_header=$(sanitize_filename "$raw")
|
|
||||||
[[ -n "$tmp_header" ]] && header="$tmp_header"
|
|
||||||
fi
|
|
||||||
|
|
||||||
prune_dir "$REPO_SCREENSHOT_DIR" "$skin" "$header.mp4"
|
|
||||||
prune_dir "$REPO_RANKING_PANEL_DIR" "$skin" "$header.webp"
|
|
||||||
prune_dir "$REPO_MOD_ICONS_DIR" "$skin" "$header-mod-icons.webp"
|
|
||||||
prune_dir "$REPO_THUMBNAIL_DIR" "$skin" "$header.webp"
|
|
||||||
prune_dir "$OSK_PATH" "$skin" "$header.osk"
|
|
||||||
prune_dir "$DOC_DIR" "$skin" "$header.md"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "[Cleanup Extra Files Complete]"
|
|
||||||
|
|
||||||
- name: Configure Git
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
git config user.name "${{ github.actor }}"
|
|
||||||
git config user.email "${{ github.actor }}@users.noreply.${{ github.server_url }}"
|
|
||||||
|
|
||||||
- name: Add and Commit changes
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
git config advice.addIgnoredFile false
|
|
||||||
|
|
||||||
for p in docs/ media/gameplay media/thumbnail media/panel media/icons export README.md how-to-use.md src; do
|
|
||||||
if [ -e "$p" ]; then
|
|
||||||
git add -A "$p"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
git commit -m "[ci skip] push back from pipeline" -q || echo "No changes to commit"
|
|
||||||
|
|
||||||
- name: Push changes and create tag
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
if [ "${GITHUB_REF}" = "refs/heads/main" ]; then
|
|
||||||
git push origin HEAD:main || echo "No changes to push"
|
|
||||||
git tag "$new_tag"
|
|
||||||
git push origin "$new_tag"
|
|
||||||
else
|
|
||||||
git push origin HEAD:"${GITHUB_REF_NAME}" || echo "No changes to push"
|
|
||||||
fi
|
|
||||||
|
|||||||
148
README.md
148
README.md
@@ -1,148 +0,0 @@
|
|||||||
---
|
|
||||||
gitea: none
|
|
||||||
include_toc: true
|
|
||||||
---
|
|
||||||
|
|
||||||
# Skins
|
|
||||||
|
|
||||||
<!--
|
|
||||||
osuid: 13792719
|
|
||||||
-->
|
|
||||||
|
|
||||||
**Go back to [osc/skins](https://git.sulejmani.xyz/osc/skins)**
|
|
||||||
|
|
||||||
**Click on the Skin name to download it, or click on the thumbnail to see more about the skin, including a video preview, screenshots, and mod icons.**
|
|
||||||
|
|
||||||
## [Barely still Jace (Arlind edit)](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.osk)
|
|
||||||
|
|
||||||
My main skin.
|
|
||||||
|
|
||||||
**Author:** Various people
|
|
||||||
|
|
||||||
[](/docs/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.md)
|
|
||||||
|
|
||||||
## [Jace Arlind edit](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Jace/Jace%20Arlind%20edit.osk)
|
|
||||||
|
|
||||||
My secondary skin, only really used for EZ.
|
|
||||||
|
|
||||||
**Author:** Various people
|
|
||||||
|
|
||||||
[](/docs/-%20Jace/Jace%20Arlind%20edit.md)
|
|
||||||
|
|
||||||
## [Jace Arlind edit (white)](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.osk)
|
|
||||||
|
|
||||||
Mock up Rafis' skin.
|
|
||||||
|
|
||||||
**Author:** Various people
|
|
||||||
|
|
||||||
[](/docs/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.md)
|
|
||||||
|
|
||||||
## [Varvalian Arlind edit](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Varvalian/Varvalian%20Arlind%20edit.osk)
|
|
||||||
|
|
||||||
My first real skin I created for myself.
|
|
||||||
|
|
||||||
**Author:** Garin, Gab, Varvalian
|
|
||||||
|
|
||||||
[](/docs/-%20Varvalian/Varvalian%20Arlind%20edit.md)
|
|
||||||
|
|
||||||
## [Barely still Jace (Oreru edit)](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.osk)
|
|
||||||
|
|
||||||
Barely still Jace, but every Audio file got replaced with Oreru.
|
|
||||||
|
|
||||||
**Author:** Various people
|
|
||||||
|
|
||||||
[](/docs/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.md)
|
|
||||||
|
|
||||||
## [Gunna skin by Arlind](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Gunna/Gunna%20skin%20by%20Arlind.osk)
|
|
||||||
|
|
||||||
My first skin made from scratch.
|
|
||||||
|
|
||||||
**Author:** arlind
|
|
||||||
|
|
||||||
[](/docs/-%20Gunna/Gunna%20skin%20by%20Arlind.md)
|
|
||||||
|
|
||||||
## [Minimal by Geroyuni](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.osk)
|
|
||||||
|
|
||||||
My first skin that wasn't completely ass.
|
|
||||||
|
|
||||||
**Author:** Geroyuni
|
|
||||||
|
|
||||||
[](/docs/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.md)
|
|
||||||
|
|
||||||
## [Konata - Rave Party V0.9.1](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/Konata/Konata%20-%20Rave%20Party%20V0.9.1.osk)
|
|
||||||
|
|
||||||
Play this with hitlightning enabled lol.
|
|
||||||
|
|
||||||
**Author:** Vext
|
|
||||||
|
|
||||||
[](/docs/Konata/Konata%20-%20Rave%20Party%20V0.9.1.md)
|
|
||||||
|
|
||||||
## [Ameliorate v1.5](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/Ameliorate%20v1.5/Ameliorate%20v1.5.osk)
|
|
||||||
|
|
||||||
This is only on here 'cause all my main skins use the hitsounds from here.
|
|
||||||
|
|
||||||
**Author:** Toy
|
|
||||||
|
|
||||||
[](/docs/Ameliorate%20v1.5/Ameliorate%20v1.5.md)
|
|
||||||
|
|
||||||
## [Skin 2](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/Skin%202/Skin%202.osk)
|
|
||||||
|
|
||||||
Either this or as244 are the first 2 skins me and my friend made on osuskinner.
|
|
||||||
|
|
||||||
**Author:** osuskinner.com / Various Artist
|
|
||||||
|
|
||||||
[](/docs/Skin%202/Skin%202.md)
|
|
||||||
|
|
||||||
## [as244](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/as244/as244.osk)
|
|
||||||
|
|
||||||
Either this or Skin 2 are the first 2 skins me and my friend made on osuskinner.
|
|
||||||
|
|
||||||
**Author:** osuskinner.com / Various Artist
|
|
||||||
|
|
||||||
[](/docs/as244/as244.md)
|
|
||||||
|
|
||||||
## [boop](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/boop/boop.osk)
|
|
||||||
|
|
||||||
Just boop, downloaded it for DT.
|
|
||||||
|
|
||||||
**Author:** ryuk
|
|
||||||
|
|
||||||
[](/docs/boop/boop.md)
|
|
||||||
|
|
||||||
## [Default](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/Default/Default.osk)
|
|
||||||
|
|
||||||
**Author:** Developers
|
|
||||||
|
|
||||||
[](/docs/Default/Default.md)
|
|
||||||
|
|
||||||
## [MonkoGlassTest](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/MonkoGlassTest/MonkoGlassTest.osk)
|
|
||||||
|
|
||||||
**Author:** Monko2k | Edited by rektygon
|
|
||||||
|
|
||||||
[](/docs/MonkoGlassTest/MonkoGlassTest.md)
|
|
||||||
|
|
||||||
## [azerinoxrektygon edit](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/azerinoxrektygon%20edit/azerinoxrektygon%20edit.osk)
|
|
||||||
|
|
||||||
**Author:** marcel7 (various artists)
|
|
||||||
|
|
||||||
[](/docs/azerinoxrektygon%20edit/azerinoxrektygon%20edit.md)
|
|
||||||
|
|
||||||
## [kik0](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/kik0/kik0.osk)
|
|
||||||
|
|
||||||
**Author:** kik0
|
|
||||||
|
|
||||||
[](/docs/kik0/kik0.md)
|
|
||||||
|
|
||||||
# Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/README.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/README.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/README.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/README.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/README.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/README.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/README.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/README.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/README.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Barely still Jace (Arlind edit)](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.osk)
|
|
||||||
|
|
||||||
**Author:** Various people
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/-%20Barely%20still%20Jace/Barely%20still%20Jace%20%28Arlind%20edit%29.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Barely still Jace (Oreru edit)](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.osk)
|
|
||||||
|
|
||||||
**Author:** Various people
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/-%20Barely%20still%20oreru/Barely%20still%20Jace%20%28Oreru%20edit%29.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Gunna skin by Arlind](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Gunna/Gunna%20skin%20by%20Arlind.osk)
|
|
||||||
|
|
||||||
**Author:** arlind
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/-%20Gunna/Gunna%20skin%20by%20Arlind.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/-%20Gunna/Gunna%20skin%20by%20Arlind.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/-%20Gunna/Gunna%20skin%20by%20Arlind.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/-%20Gunna/Gunna%20skin%20by%20Arlind.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/-%20Gunna/Gunna%20skin%20by%20Arlind.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/-%20Gunna/Gunna%20skin%20by%20Arlind.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/-%20Gunna/Gunna%20skin%20by%20Arlind.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/-%20Gunna/Gunna%20skin%20by%20Arlind.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/-%20Gunna/Gunna%20skin%20by%20Arlind.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/-%20Gunna/Gunna%20skin%20by%20Arlind.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Jace Arlind edit (white)](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.osk)
|
|
||||||
|
|
||||||
**Author:** Various people
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/-%20Jace%20White/Jace%20Arlind%20edit%20%28white%29.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Jace Arlind edit](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Jace/Jace%20Arlind%20edit.osk)
|
|
||||||
|
|
||||||
**Author:** Various people
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/-%20Jace/Jace%20Arlind%20edit.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/-%20Jace/Jace%20Arlind%20edit.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/-%20Jace/Jace%20Arlind%20edit.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/-%20Jace/Jace%20Arlind%20edit.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/-%20Jace/Jace%20Arlind%20edit.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/-%20Jace/Jace%20Arlind%20edit.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/-%20Jace/Jace%20Arlind%20edit.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/-%20Jace/Jace%20Arlind%20edit.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/-%20Jace/Jace%20Arlind%20edit.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/-%20Jace/Jace%20Arlind%20edit.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Varvalian Arlind edit](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/-%20Varvalian/Varvalian%20Arlind%20edit.osk)
|
|
||||||
|
|
||||||
**Author:** Garin, Gab, Varvalian
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/-%20Varvalian/Varvalian%20Arlind%20edit.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/-%20Varvalian/Varvalian%20Arlind%20edit.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/-%20Varvalian/Varvalian%20Arlind%20edit.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/-%20Varvalian/Varvalian%20Arlind%20edit.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/-%20Varvalian/Varvalian%20Arlind%20edit.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/-%20Varvalian/Varvalian%20Arlind%20edit.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/-%20Varvalian/Varvalian%20Arlind%20edit.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/-%20Varvalian/Varvalian%20Arlind%20edit.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/-%20Varvalian/Varvalian%20Arlind%20edit.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/-%20Varvalian/Varvalian%20Arlind%20edit.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Ameliorate v1.5](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/Ameliorate%20v1.5/Ameliorate%20v1.5.osk)
|
|
||||||
|
|
||||||
**Author:** Toy
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/Ameliorate%20v1.5/Ameliorate%20v1.5.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/Ameliorate%20v1.5/Ameliorate%20v1.5.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/Ameliorate%20v1.5/Ameliorate%20v1.5.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/Ameliorate%20v1.5/Ameliorate%20v1.5.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/Ameliorate%20v1.5/Ameliorate%20v1.5.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/Ameliorate%20v1.5/Ameliorate%20v1.5.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/Ameliorate%20v1.5/Ameliorate%20v1.5.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/Ameliorate%20v1.5/Ameliorate%20v1.5.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/Ameliorate%20v1.5/Ameliorate%20v1.5.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/Ameliorate%20v1.5/Ameliorate%20v1.5.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Default](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/Default/Default.osk)
|
|
||||||
|
|
||||||
**Author:** Developers
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/Default/Default.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/Default/Default.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/Default/Default.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/Default/Default.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/Default/Default.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/Default/Default.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/Default/Default.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/Default/Default.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/Default/Default.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/Default/Default.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Konata - Rave Party V0.9.1](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/Konata/Konata%20-%20Rave%20Party%20V0.9.1.osk)
|
|
||||||
|
|
||||||
**Author:** Vext
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/Konata/Konata%20-%20Rave%20Party%20V0.9.1.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/Konata/Konata%20-%20Rave%20Party%20V0.9.1.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/Konata/Konata%20-%20Rave%20Party%20V0.9.1.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/Konata/Konata%20-%20Rave%20Party%20V0.9.1.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/Konata/Konata%20-%20Rave%20Party%20V0.9.1.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/Konata/Konata%20-%20Rave%20Party%20V0.9.1.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/Konata/Konata%20-%20Rave%20Party%20V0.9.1.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/Konata/Konata%20-%20Rave%20Party%20V0.9.1.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/Konata/Konata%20-%20Rave%20Party%20V0.9.1.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/Konata/Konata%20-%20Rave%20Party%20V0.9.1.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Minimal by Geroyuni](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.osk)
|
|
||||||
|
|
||||||
**Author:** Geroyuni
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/Minimal_by_Geroyuni/Minimal%20by%20Geroyuni.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [MonkoGlassTest](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/MonkoGlassTest/MonkoGlassTest.osk)
|
|
||||||
|
|
||||||
**Author:** Monko2k | Edited by rektygon
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/MonkoGlassTest/MonkoGlassTest.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/MonkoGlassTest/MonkoGlassTest.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/MonkoGlassTest/MonkoGlassTest.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/MonkoGlassTest/MonkoGlassTest.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/MonkoGlassTest/MonkoGlassTest.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/MonkoGlassTest/MonkoGlassTest.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/MonkoGlassTest/MonkoGlassTest.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/MonkoGlassTest/MonkoGlassTest.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/MonkoGlassTest/MonkoGlassTest.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/MonkoGlassTest/MonkoGlassTest.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [Skin 2](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/Skin%202/Skin%202.osk)
|
|
||||||
|
|
||||||
**Author:** osuskinner.com / Various Artist
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/Skin%202/Skin%202.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/Skin%202/Skin%202.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/Skin%202/Skin%202.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/Skin%202/Skin%202.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/Skin%202/Skin%202.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/Skin%202/Skin%202.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/Skin%202/Skin%202.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/Skin%202/Skin%202.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/Skin%202/Skin%202.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/Skin%202/Skin%202.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [as244](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/as244/as244.osk)
|
|
||||||
|
|
||||||
**Author:** osuskinner.com / Various Artist
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/as244/as244.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/as244/as244.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/as244/as244.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/as244/as244.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/as244/as244.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/as244/as244.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/as244/as244.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/as244/as244.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/as244/as244.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/as244/as244.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [azerinoxrektygon edit](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/azerinoxrektygon%20edit/azerinoxrektygon%20edit.osk)
|
|
||||||
|
|
||||||
**Author:** marcel7 (various artists)
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/azerinoxrektygon%20edit/azerinoxrektygon%20edit.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/azerinoxrektygon%20edit/azerinoxrektygon%20edit.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/azerinoxrektygon%20edit/azerinoxrektygon%20edit.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/azerinoxrektygon%20edit/azerinoxrektygon%20edit.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/azerinoxrektygon%20edit/azerinoxrektygon%20edit.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/azerinoxrektygon%20edit/azerinoxrektygon%20edit.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/azerinoxrektygon%20edit/azerinoxrektygon%20edit.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/azerinoxrektygon%20edit/azerinoxrektygon%20edit.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/azerinoxrektygon%20edit/azerinoxrektygon%20edit.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/azerinoxrektygon%20edit/azerinoxrektygon%20edit.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [boop](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/boop/boop.osk)
|
|
||||||
|
|
||||||
**Author:** ryuk
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/boop/boop.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/boop/boop.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/boop/boop.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/boop/boop.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/boop/boop.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/boop/boop.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/boop/boop.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/boop/boop.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/boop/boop.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/boop/boop.md) | 13.08.2025 23:05:16 |
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
# [kik0](https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/export/kik0/kik0.osk)
|
|
||||||
|
|
||||||
**Author:** kik0
|
|
||||||
|
|
||||||
## Hitsounds
|
|
||||||
<video controls autoplay loop muted playsinline src="https://git.sulejmani.xyz/Arlind/skins/media/tag/v1.8.0/media/gameplay/kik0/kik0.mp4" type="video/mp4">
|
|
||||||
</video>
|
|
||||||
|
|
||||||
## Ranking Panel
|
|
||||||

|
|
||||||
|
|
||||||
## Mod Icons
|
|
||||||

|
|
||||||
|
|
||||||
## Build History
|
|
||||||
|
|
||||||
| Version | Date |
|
|
||||||
| ------- | ---- |
|
|
||||||
| [`v1.8.0 (Current)`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.8.0/docs/kik0/kik0.md) | 01.10.2025 14:15:43 |
|
|
||||||
| [`v1.7.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.7.0/docs/kik0/kik0.md) | 30.09.2025 23:00:23 |
|
|
||||||
| [`v1.6.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.6.0/docs/kik0/kik0.md) | 30.09.2025 22:51:45 |
|
|
||||||
| [`v1.5.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.5.0/docs/kik0/kik0.md) | 30.09.2025 22:44:37 |
|
|
||||||
| [`v1.4.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.4.0/docs/kik0/kik0.md) | 17.09.2025 00:18:30 |
|
|
||||||
| [`v1.3.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.3.0/docs/kik0/kik0.md) | 17.09.2025 00:15:48 |
|
|
||||||
| [`v1.2.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.2.0/docs/kik0/kik0.md) | 16.09.2025 23:56:09 |
|
|
||||||
| [`v1.1.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.1.0/docs/kik0/kik0.md) | 18.08.2025 02:22:37 |
|
|
||||||
| [`v1.0.0`](https://git.sulejmani.xyz/Arlind/skins/src/tag/v1.0.0/docs/kik0/kik0.md) | 13.08.2025 23:05:16 |
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
export/Default/Default.osk
LFS
BIN
export/Default/Default.osk
LFS
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
export/Skin 2/Skin 2.osk
LFS
BIN
export/Skin 2/Skin 2.osk
LFS
Binary file not shown.
BIN
export/as244/as244.osk
LFS
BIN
export/as244/as244.osk
LFS
Binary file not shown.
Binary file not shown.
BIN
export/boop/boop.osk
LFS
BIN
export/boop/boop.osk
LFS
Binary file not shown.
BIN
export/kik0/kik0.osk
LFS
BIN
export/kik0/kik0.osk
LFS
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
media/gameplay/Skin 2/Skin 2.mp4
LFS
BIN
media/gameplay/Skin 2/Skin 2.mp4
LFS
Binary file not shown.
BIN
media/gameplay/as244/as244.mp4
LFS
BIN
media/gameplay/as244/as244.mp4
LFS
Binary file not shown.
Binary file not shown.
BIN
media/gameplay/boop/boop.mp4
LFS
BIN
media/gameplay/boop/boop.mp4
LFS
Binary file not shown.
BIN
media/gameplay/kik0/kik0.mp4
LFS
BIN
media/gameplay/kik0/kik0.mp4
LFS
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
media/panel/Default/Default.webp
LFS
BIN
media/panel/Default/Default.webp
LFS
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
media/panel/Skin 2/Skin 2.webp
LFS
BIN
media/panel/Skin 2/Skin 2.webp
LFS
Binary file not shown.
BIN
media/panel/as244/as244.webp
LFS
BIN
media/panel/as244/as244.webp
LFS
Binary file not shown.
Binary file not shown.
BIN
media/panel/boop/boop.webp
LFS
BIN
media/panel/boop/boop.webp
LFS
Binary file not shown.
BIN
media/panel/kik0/kik0.webp
LFS
BIN
media/panel/kik0/kik0.webp
LFS
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
media/thumbnail/as244/as244.webp
LFS
BIN
media/thumbnail/as244/as244.webp
LFS
Binary file not shown.
Binary file not shown.
BIN
media/thumbnail/boop/boop.webp
LFS
BIN
media/thumbnail/boop/boop.webp
LFS
Binary file not shown.
BIN
media/thumbnail/kik0/kik0.webp
LFS
BIN
media/thumbnail/kik0/kik0.webp
LFS
Binary file not shown.
Reference in New Issue
Block a user