Initial commit
Some checks failed
CI/CD Pipeline / Full CI/CD Pipeline (push) Failing after 0s

This commit is contained in:
2025-06-08 13:25:19 +02:00
commit 4a5e0b0c91
641 changed files with 2617 additions and 0 deletions

15
.gitattributes vendored Normal file
View File

@@ -0,0 +1,15 @@
*.db filter=lfs diff=lfs merge=lfs -text
*.exe filter=lfs diff=lfs merge=lfs -text
*.gif filter=lfs diff=lfs merge=lfs -text
*.jpg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text
*.PNG filter=lfs diff=lfs merge=lfs -text
*.mp3 filter=lfs diff=lfs merge=lfs -text
*.ogg filter=lfs diff=lfs merge=lfs -text
*.osk filter=lfs diff=lfs merge=lfs -text
*.osr filter=lfs diff=lfs merge=lfs -text
*.osz filter=lfs diff=lfs merge=lfs -text
*.pack filter=lfs diff=lfs merge=lfs -text
*.pdn filter=lfs diff=lfs merge=lfs -text
*.wav filter=lfs diff=lfs merge=lfs -text
*.WAV filter=lfs diff=lfs merge=lfs -text

560
.gitea/workflows/ci.yml Normal file
View File

@@ -0,0 +1,560 @@
name: CI/CD Pipeline
on:
push:
branches:
- main
paths:
- '.gitea/workflows/ci.yml'
- 'Skins/**/*'
workflow_dispatch:
env:
DANSER_PATH: "/app/danser/danser-cli"
DANSER_DIR: "/app/danser"
DANSER_VIDEO_DIR: "/app/danser/videos"
DANSER_SCREENSHOT_DIR: "/app/danser/screenshots"
SKINS_DIR: "${{ github.workspace }}/Skins"
DANSER_SKINS_DIR: "/app/danser/skins"
DEFAULT_SKIN_DIR: "${{ github.workspace }}/src/default-skin"
REPO_SCREENSHOT_DIR: "${{ github.workspace }}/media/gameplay"
REPO_MOD_ICONS_DIR: "${{ github.workspace }}/media/icons"
REPO_RANKING_PANEL_DIR: "${{ github.workspace }}/media/panel"
SETTINGS_JSON_PATH: "/app/danser/settings/default.json"
README_PATH: "${{ github.workspace }}/README.md"
REPLAY_PATH: "${{ github.workspace }}/src/replay.osr"
OSK_PATH: "${{ github.workspace }}/export"
IMAGE_NAME: arlind/skins
REGISTRY_URL: "https://${{ vars.CONTAINER_REGISTRY }}"
OSU_ID: ${{ vars.OSUID }}
jobs:
generate_everything:
name: Full CI/CD Pipeline
runs-on: ubuntu-latest
container:
image: ${{ vars.CONTAINER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest
options: >-
--gpus all
--privileged
--security-opt seccomp=unconfined
--security-opt apparmor=unconfined
--cap-add=ALL
--env NVIDIA_DRIVER_CAPABILITIES=all
--env NVIDIA_VISIBLE_DEVICES=all
--user 0:0
steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
token: ${{ secrets.TOKEN }}
- name: Git LFS Pull
run: |
echo "Pulling Git LFS files..."
git lfs pull
echo "LFS files pulled."
- name: Extract Repository path
run: |
FULL_WORKSPACE_PATH="${{ github.workspace }}"
USER_REPOSITORY="${FULL_WORKSPACE_PATH#/workspace/}"
USER_REPOSITORY="${USER_REPOSITORY%/}"
echo "USER_REPOSITORY=$USER_REPOSITORY" >> $GITHUB_ENV
- name: Set XDG_RUNTIME_DIR
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
run: |
echo "Creating asset directories..."
mkdir -p "$REPO_SCREENSHOT_DIR"
mkdir -p "$REPO_MOD_ICONS_DIR"
mkdir -p "$REPO_RANKING_PANEL_DIR"
mkdir -p "$OSK_PATH"
echo "Asset directories created successfully."
- name: Create New Tag
run: |
echo "Computing new tag..."
git fetch --tags >/dev/null 2>&1
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
version=${latest_tag#v}
major=$(echo "$version" | cut -d. -f1)
minor=$(echo "$version" | cut -d. -f2)
patch=$(echo "$version" | cut -d. -f3)
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
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
run: |
echo "[Danser Job Started]"
SKIN_COUNT=$(find "$DANSER_SKINS_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l)
INDEX=1
for skin in "$DANSER_SKINS_DIR"/*/; do
if [ -d "$skin" ]; then
SKIN_NAME=$(basename "$skin")
echo ""
echo "[$INDEX/$SKIN_COUNT] Skin: $SKIN_NAME"
LOGFILE="/tmp/danser_log_$SKIN_NAME.txt"
FFMPEG_LOG="/tmp/ffmpeg_log_$SKIN_NAME.txt"
echo " → Generating video..."
if ! xvfb-run -a "$DANSER_DIR/danser-cli" -replay "$REPLAY_PATH" -record -skip -start=215 -end=230 -noupdatecheck -out="$SKIN_NAME" -skin "$SKIN_NAME" >"$LOGFILE" 2>&1; then
echo " ✖ Video generation failed for $SKIN_NAME. Log output:"
cat "$LOGFILE"
exit 1
fi
echo " → Taking screenshot..."
if ! xvfb-run -a "$DANSER_DIR/danser-cli" -replay "$REPLAY_PATH" -skip -noupdatecheck -ss 243 -out="$SKIN_NAME" -skin "$SKIN_NAME" >>"$LOGFILE" 2>&1; then
echo " ✖ Screenshot generation failed for $SKIN_NAME. Log output:"
cat "$LOGFILE"
exit 1
fi
if [ -f "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" ]; then
echo " → Converting to GIF..."
if ! ffmpeg -y -hwaccel cuda -ss 4 -t 10 -i "$DANSER_VIDEO_DIR/$SKIN_NAME.mp4" \
-filter_complex "[0:v] fps=24,scale=720:-1:flags=lanczos,palettegen [p]; \
[0:v] fps=24,scale=720:-1:flags=lanczos [x]; \
[x][p] paletteuse" \
-c:v gif "$DANSER_VIDEO_DIR/$SKIN_NAME.gif" >"$FFMPEG_LOG" 2>&1; then
echo " ✖ FFmpeg conversion failed for $SKIN_NAME. Log output:"
cat "$FFMPEG_LOG"
exit 1
fi
mv "$DANSER_VIDEO_DIR/$SKIN_NAME.gif" "$REPO_SCREENSHOT_DIR/$SKIN_NAME.gif"
fi
if [ -f "$DANSER_SCREENSHOT_DIR/$SKIN_NAME.png" ]; then
mv "$DANSER_SCREENSHOT_DIR/$SKIN_NAME.png" "$REPO_RANKING_PANEL_DIR/$SKIN_NAME.png"
fi
echo " ✓ Completed"
INDEX=$((INDEX + 1))
fi
done
echo ""
echo "[Danser Job Finished — $SKIN_COUNT skins processed]"
- name: Rename Generated Assets Based on skin.ini
run: |
echo "[Asset Renaming Started]"
INDEX=1
SKIN_COUNT=$(find "$DANSER_SKINS_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l)
for skin_path in "$DANSER_SKINS_DIR"/*/; do
if [ -d "$skin_path" ]; then
SKIN_NAME=$(basename "$skin_path")
echo ""
echo "[$INDEX/$SKIN_COUNT] Skin: $SKIN_NAME"
ini_file=$(find "$skin_path" -maxdepth 1 -iname "skin.ini" | head -n1)
skin_header="$SKIN_NAME"
if [ -f "$ini_file" ]; then
name_line=$(grep -i '^[[:space:]]*name:' "$ini_file" | head -n1)
if [ -n "$name_line" ]; then
new_name=$(echo "$name_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
[ -n "$new_name" ] && skin_header="$new_name"
fi
fi
original_gif="$REPO_SCREENSHOT_DIR/$SKIN_NAME.gif"
renamed_gif="$REPO_SCREENSHOT_DIR/$skin_header.gif"
if [ -f "$original_gif" ] && [ "$original_gif" != "$renamed_gif" ]; then
mv -f "$original_gif" "$renamed_gif"
echo " ✓ Renamed GIF"
else
echo " → No GIF to rename or already named correctly"
fi
original_png="$REPO_RANKING_PANEL_DIR/$SKIN_NAME.png"
renamed_png="$REPO_RANKING_PANEL_DIR/$skin_header.png"
if [ -f "$original_png" ] && [ "$original_png" != "$renamed_png" ]; then
mv -f "$original_png" "$renamed_png"
echo " ✓ Renamed PNG"
else
echo " → No PNG to rename or already named correctly"
fi
echo " ✓ Completed"
INDEX=$((INDEX + 1))
fi
done
echo ""
echo "[Asset Renaming Complete — $SKIN_COUNT skins processed]"
- name: Generate Mod Icons
run: |
echo "[Mod Icon Generation Started]"
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")
SKIN_COUNT=$(find "$DANSER_SKINS_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l)
INDEX=1
for skin_path in "$DANSER_SKINS_DIR"/*/; do
if [ -d "$skin_path" ]; then
SKIN_NAME=$(basename "$skin_path")
echo ""
echo "[$INDEX/$SKIN_COUNT] Skin: $SKIN_NAME"
ini_file=$(find "$skin_path" -maxdepth 1 -iname "skin.ini" | head -n1)
skin_header="$SKIN_NAME"
if [ -f "$ini_file" ]; then
name_line=$(grep -i '^[[:space:]]*name:' "$ini_file" | head -n1)
if [ -n "$name_line" ]; then
new_name=$(echo "$name_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
if [ -n "$new_name" ]; then
skin_header="$new_name"
fi
fi
fi
ICON_FOLDER="$skin_path"
OUTPUT="${REPO_MOD_ICONS_DIR}/${skin_header}-mod-icons.png"
TILE_SIZE=160
PADDING=10
MAX_ICONS=7
BLANK_IMAGE="blank.png"
magick -size "${TILE_SIZE}x${TILE_SIZE}" xc:none "$BLANK_IMAGE"
row_images=""
row_index=1
for group_list in "$group1_icons" "$group2_icons" "$group3_icons"; do
montage_files=""
count=0
for icon in $group_list; do
icon_path="${ICON_FOLDER}/selection-mod-${icon}@2x.png"
if [ -f "$icon_path" ]; then
montage_files="$montage_files \"$icon_path\""
count=$((count + 1))
elif [ -f "$DEFAULT_SKIN_DIR/selection-mod-${icon}@2x.png" ]; then
montage_files="$montage_files \"$DEFAULT_SKIN_DIR/selection-mod-${icon}@2x.png\""
count=$((count + 1))
fi
done
missing=$(( MAX_ICONS - count ))
if [ "$missing" -lt 0 ]; then
missing=0
fi
i=0
while [ "$i" -lt "$missing" ]; do
montage_files="$montage_files \"$BLANK_IMAGE\""
i=$((i + 1))
done
row_file="row_${row_index}.png"
eval "magick montage $montage_files -tile \"${MAX_ICONS}x1\" -geometry \"${TILE_SIZE}x${TILE_SIZE}+${PADDING}+${PADDING}\" -background none \"$row_file\""
row_images="$row_images \"$row_file\""
row_index=$((row_index + 1))
done
num_rows=0
for _ in $row_images; do
num_rows=$((num_rows + 1))
done
eval "magick montage $row_images -tile \"1x${num_rows}\" -geometry \"+${PADDING}+${PADDING}\" -background none \"$OUTPUT\""
rm "$BLANK_IMAGE"
rm row_*.png
echo " ✓ Completed"
INDEX=$((INDEX + 1))
fi
done
echo ""
echo "[Mod Icon Generation Finished — $SKIN_COUNT skins processed]"
- name: Create OSK files
run: |
echo "[OSK Creation Job Started]"
SKIN_COUNT=$(find "$DANSER_SKINS_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l)
INDEX=1
FIXED_TIMESTAMP="2025-01-01 00:00:00"
find "$DANSER_SKINS_DIR" -mindepth 1 -maxdepth 1 -type d | sort | while IFS= read -r skin; do
SKIN_FOLDER=$(basename "$skin")
echo ""
echo "[$INDEX/$SKIN_COUNT] Processing skin folder: $SKIN_FOLDER"
ini_file=$(find "$skin" -maxdepth 1 -iname "skin.ini" | head -n1)
if [ -f "$ini_file" ]; then
name_line=$(grep -i '^[[:space:]]*name:' "$ini_file" | head -n1)
if [ -n "$name_line" ]; then
new_name=$(echo "$name_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
if [ -n "$new_name" ]; then
SKIN_FOLDER="$new_name"
fi
fi
else
echo " → No skin.ini found, using folder name."
fi
osk_file="${OSK_PATH}/${SKIN_FOLDER}.osk"
if ! (cd "$skin" && find . -type f -exec touch -d "$FIXED_TIMESTAMP" {} +); then
echo " ✖ Failed to normalize timestamps in $skin"
exit 1
fi
if (
cd "$skin" && \
find . -type f | sort | zip -rq -D -X -9 --compression-method deflate "$osk_file" -@
); then
echo " ✓ OSK file created successfully."
else
echo " ✖ Failed to create OSK file: $osk_file"
exit 1
fi
INDEX=$((INDEX + 1))
done
echo ""
echo "[OSK Creation Job Finished — $SKIN_COUNT skins processed]"
- name: Generate README
run: |
echo "Starting README generation..."
SKINS_JSON_FILE="${{ github.workspace }}/.gitea/workflows/skins.json"
DESC_FILE=$(mktemp)
jq -r '.descriptions | to_entries[] | "\(.key)=\(.value)"' "$SKINS_JSON_FILE" > "$DESC_FILE"
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"
get_desc() {
key=$1
escaped_key=$(printf '%s\n' "$key" | sed 's/[\/&]/\\&/g')
grep "^${escaped_key}=" "$DESC_FILE" | cut -d '=' -f2-
}
ORDER_FILE=$(mktemp)
JSON_SKINS_TMP=$(mktemp)
SEEN_HEADERS_FILE=$(mktemp)
jq -r '.order[]' "$SKINS_JSON_FILE" > "$ORDER_FILE"
cp "$ORDER_FILE" "$JSON_SKINS_TMP"
while IFS= read -r skin; do
dir="$DANSER_SKINS_DIR/$skin"
if [ ! -d "$dir" ]; then
echo "Skipping missing skin directory: $skin"
continue
fi
ini_file=$(find "$dir" -maxdepth 1 -iname "skin.ini" | head -n 1)
skin_header="$skin"
if [ -f "$ini_file" ]; then
name_line=$(grep -i '^[[:space:]]*name:' "$ini_file" | head -n 1)
if [ -n "$name_line" ]; then
skin_header=$(echo "$name_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
fi
fi
if grep -Fxq "$skin_header" "$SEEN_HEADERS_FILE"; then
echo "Skipping duplicate skin header from JSON order: $skin_header"
continue
fi
echo "$skin_header" >> "$SEEN_HEADERS_FILE"
escaped_img=$(echo "$skin_header.gif" | sed 's/ /%20/g')
escaped_osk=$(echo "$skin_header.osk" | sed 's/ /%20/g')
echo "## [$skin_header]($REGISTRY_URL/$USER_REPOSITORY/media/tag/$new_tag/export/$escaped_osk)" >> "$README_PATH"
echo "" >> "$README_PATH"
skin_desc=$(get_desc "$skin")
if [ -n "$skin_desc" ]; then
echo "$skin_desc" >> "$README_PATH"
echo "" >> "$README_PATH"
fi
if [ -f "$ini_file" ]; then
author_line=$(grep -i '^[[:space:]]*Author:' "$ini_file" | head -n 1 || true)
if [ -n "$author_line" ]; then
author=$(echo "$author_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
if [ -n "$author" ]; then
echo "**Author:** $author" >> "$README_PATH"
echo "" >> "$README_PATH"
fi
fi
fi
echo "![$skin_header Gameplay](media/gameplay/$escaped_img)" >> "$README_PATH"
echo "" >> "$README_PATH"
if [ -f "media/panel/${skin_header}.png" ]; then
escaped_panel=$(echo "${skin_header}.png" | sed 's/ /%20/g')
echo "![$skin_header Ranking Panel](media/panel/$escaped_panel)" >> "$README_PATH"
echo "" >> "$README_PATH"
fi
mod_icon_file="${skin_header}-mod-icons.png"
if [ -f "media/icons/$mod_icon_file" ]; then
escaped_mod=$(echo "$mod_icon_file" | sed 's/ /%20/g')
echo "![$skin_header Mods](media/icons/$escaped_mod)" >> "$README_PATH"
echo "" >> "$README_PATH"
fi
done < "$ORDER_FILE"
find "$DANSER_SKINS_DIR" -mindepth 1 -maxdepth 1 -type d | while IFS= read -r dir; do
skin=$(basename "$dir")
ini_file=$(find "$dir" -maxdepth 1 -iname "skin.ini" | head -n 1)
skin_header="$skin"
if [ -f "$ini_file" ]; then
name_line=$(grep -i '^[[:space:]]*name:' "$ini_file" | head -n 1)
if [ -n "$name_line" ]; then
skin_header=$(echo "$name_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
fi
fi
if grep -Fxq "$skin_header" "$SEEN_HEADERS_FILE"; then
continue
fi
if grep -Fxq "$skin" "$JSON_SKINS_TMP"; then
continue
fi
echo "$skin_header" >> "$SEEN_HEADERS_FILE"
escaped_img=$(echo "$skin_header.gif" | sed 's/ /%20/g')
escaped_osk=$(echo "$skin_header.osk" | sed 's/ /%20/g')
echo "## [$skin_header]($REGISTRY_URL/$USER_REPOSITORY/media/tag/$new_tag/export/$escaped_osk)" >> "$README_PATH"
echo "" >> "$README_PATH"
if [ -f "$ini_file" ]; then
author_line=$(grep -i '^[[:space:]]*Author:' "$ini_file" | head -n 1 || true)
if [ -n "$author_line" ]; then
author=$(echo "$author_line" | cut -d ':' -f2- | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
if [ -n "$author" ]; then
echo "**Author:** $author" >> "$README_PATH"
echo "" >> "$README_PATH"
fi
fi
fi
echo "![$skin_header Gameplay](media/gameplay/$escaped_img)" >> "$README_PATH"
echo "" >> "$README_PATH"
if [ -f "media/panel/${skin_header}.png" ]; then
escaped_panel=$(echo "${skin_header}.png" | sed 's/ /%20/g')
echo "![$skin_header Ranking Panel](media/panel/$escaped_panel)" >> "$README_PATH"
echo "" >> "$README_PATH"
fi
mod_icon_file="${skin_header}-mod-icons.png"
if [ -f "media/icons/$mod_icon_file" ]; then
escaped_mod=$(echo "$mod_icon_file" | sed 's/ /%20/g')
echo "![$skin_header Mods](media/icons/$escaped_mod)" >> "$README_PATH"
echo "" >> "$README_PATH"
fi
done
rm "$DESC_FILE" "$ORDER_FILE" "$JSON_SKINS_TMP" "$SEEN_HEADERS_FILE"
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)\`](https://git.sulejmani.xyz/arlind/skins/src/tag/$new_tag/README.md) | $current_commit_date |" >> "$README_PATH"
git tag --sort=-v:refname | grep -v "^$new_tag$" | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | 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\`](https://git.sulejmani.xyz/arlind/skins/src/tag/$tag/README.md) | $formatted_date |" >> "$README_PATH"
done
echo "README generation completed."
- name: Configure Git
run: |
echo "Configuring git user and LFS..."
git config user.email "arlind@sulej.ch"
git config user.name "ci-bot"
git config lfs.https://${{ vars.CONTAINER_REGISTRY }}/arlind/skins.git/info/lfs.locksverify true
echo "Git configured."
- name: Add and Commit changes
run: |
git config advice.addIgnoredFile false
echo "Staging files for commit..."
git add README.md media/gameplay/* media/panel/* media/icons/* export/*
echo "Committing changes..."
git commit -m "[ci skip] push back from pipeline" -q || echo "No changes to commit"
echo "Commit step completed."
- name: Push changes and create tag
run: |
echo "Checking branch and pushing changes..."
if [ "${GITHUB_REF}" = "refs/heads/main" ]; then
echo "On main branch: pushing to origin main..."
git push origin HEAD:main || echo "No changes to push"
echo "Creating and pushing tag $new_tag..."
git tag "$new_tag"
git push origin "$new_tag"
else
echo "On branch ${GITHUB_REF_NAME}: pushing to origin ${GITHUB_REF_NAME}..."
git push origin HEAD:"${GITHUB_REF_NAME}" || echo "No changes to push"
fi
echo "Push step completed."

View File

@@ -0,0 +1,25 @@
{
"group1": [
"easy",
"nofail",
"halftime"
],
"group2": [
"hardrock",
"suddendeath",
"perfect",
"doubletime",
"nightcore",
"hidden",
"flashlight"
],
"group3": [
"relax",
"relax2",
"autoplay",
"target",
"spunout",
"cinema",
"scorev2"
]
}

View File

@@ -0,0 +1,10 @@
{
"order": [
"example1",
"example2"
],
"descriptions": {
"example1": "Description of example1",
"example2": "Description of example2"
}
}

0
.gitignore vendored Normal file
View File

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Arlind-dev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

15
hardlink-songs-folder.bat Normal file
View File

@@ -0,0 +1,15 @@
@echo off
net session >nul 2>&1
if %errorLevel% neq 0 (
echo Requesting admin privileges...
powershell -Command "Start-Process cmd -ArgumentList '/c \"%~f0\"' -Verb RunAs"
exit /b
)
echo Running robocopy sync as Administrator...
echo.
robocopy "E:\osu!\skins" "D:\git\skins\Skins" /MIR /COPYALL /SEC /B /XJ /DCOPY:T /J
echo Robocopy sync completed.
pause

6
rsync.sh Normal file
View File

@@ -0,0 +1,6 @@
#!/usr/bin/env bash
rsync -av --delete /mnt/e/osu\!/Skins/ /home/nixos/git/skins/Skins/
find ./Skins/ -type f ! -perm 644 -exec chmod 644 {} +
find ./Skins/ -type d ! -perm 755 -exec chmod 755 {} +

View File

@@ -0,0 +1,7 @@
All osu! graphic and other game assets are copyright ppy Pty Ltd.
You are granted permission to use the elements contained within this archive as a template for creating your own skins. You can modify these in any way you see fit. Please do not include the resources if you haven't modified them; the defaults will automatically be used in this case.
You are NOT permitted to use these graphics outside of skins and/or beatmaps. This includes using them on other websites, games, products etc.
If you would like to use the resources outside of the scope provided above, please contact me at pe@ppy.sh

View File

@@ -0,0 +1,27 @@
About this skin :
=======================
Template by Corne2Plum3 (https://osu.ppy.sh/users/15646039).
This is the just the default skin from the stable version (no target practice sprites sorry...), but 2021 version (from the 20210821 version to be exact). I tried to make the default skin but updated (the last I found was from 2014...), and complete (I added almost missing files) where skinners use it as a template to create their skin.
Most of the sprites and gameplay sounds are from ppy/osu-ressources (https://github.com/ppy/osu-resources). Sometimes I used an AI to generates the @2x versions of some files. For the sounds, I tried to pick them directly from the game, so sorry if it's not accurate...
Please don't kill me for making this, peppy!
A few notes :
=============
BACK BUTTON:
It's impossible to recreate the back button. In this skin, there is just 1 frame of the back button. Unlike the default, he's isn't animated, and doesn't change according to the game language.
COMBO SPRITES:
Same than score sprites.
SLIDERBALL:
It's IMPOSSIBLE to recreate exactly the default sliderball with skinning, because sliderb files disable sliderb-spec (overlay) and sliderb-nd (background). So you will see only sliderb files in game with this skin.
The only way to have the same sliderball than the default skin is deleting ALL slider ball files (sliderb, sliderb-spec and sliderb-nd).
SPINNER APPROACH CIRCLE:
With the default skin which uses new spinner, spinner-approachcircle is invisible. In the folder 'new spinner/visible approach circle' you have the default spinner-approachcircle if this file is needed.

BIN
src/default-skin/applause.wav LFS Normal file

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
src/default-skin/button-left.png LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/default-skin/button-right.png LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
src/default-skin/check-off.wav LFS Normal file

Binary file not shown.

BIN
src/default-skin/check-on.wav LFS Normal file

Binary file not shown.

BIN
src/default-skin/click-close.wav LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
src/default-skin/click-short.wav LFS Normal file

Binary file not shown.

BIN
src/default-skin/combobreak.wav LFS Normal file

Binary file not shown.

BIN
src/default-skin/comboburst.png LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
src/default-skin/count.wav LFS Normal file

Binary file not shown.

BIN
src/default-skin/count1.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/count1@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/count2.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/count2@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/count3.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/count3@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/cursor-smoke.png LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
src/default-skin/cursor.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/cursor@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/cursormiddle.png LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
src/default-skin/cursortrail.png LFS Normal file

Binary file not shown.

Binary file not shown.

BIN
src/default-skin/default-0.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-0@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-1.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-1@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-2.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-2@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-3.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-3@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-4.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-4@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-5.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-5@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-6.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-6@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-7.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-7@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-8.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-8@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-9.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/default-9@2x.png LFS Normal file

Binary file not shown.

BIN
src/default-skin/drum-hitclap.wav LFS Normal file

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
src/default-skin/failsound.mp3 LFS Normal file

Binary file not shown.

BIN
src/default-skin/followpoint.png LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/default-skin/fruit-apple.png LFS Normal file

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
src/default-skin/fruit-drop.png LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/default-skin/fruit-grapes.png LFS Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
src/default-skin/fruit-orange.png LFS Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More