Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 27 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build Unity WakaTime
name: Build Creative WakaTime

on:
pull_request:
Expand Down Expand Up @@ -72,8 +72,8 @@ jobs:
shell: msys2 {0}
run: |
echo "✅ Ninja build test completed!"
if [ -f "build/unity_wakatime.exe" ]; then
echo "📦 Executable created: $(stat -c%s build/unity_wakatime.exe) bytes"
if [ -f "build/creative_wakatime.exe" ]; then
echo "📦 Executable created: $(stat -c%s build/creative_wakatime.exe) bytes"
echo "🥷 Ninja build test passed - ready for production!"
else
echo "❌ Ninja build test failed!"
Expand Down Expand Up @@ -135,36 +135,49 @@ jobs:
- name: Build Production Release (Ninja)
shell: msys2 {0}
run: |
echo "🥷 Building Unity WakaTime with Ninja v${{ env.RELEASE_VERSION }}..."
echo "🥷 Building Creative WakaTime with Ninja v${{ env.RELEASE_VERSION }}..."
cmake --build build --config $BUILD_TYPE --parallel $(nproc)

- name: Verify Production Build
shell: msys2 {0}
run: |
if [ -f "build/unity_wakatime.exe" ]; then
if [ -f "build/creative_wakatime.exe" ]; then
echo "✅ Ninja production build successful!"
echo "📦 Final executable size: $(stat -c%s build/unity_wakatime.exe) bytes"
echo "📦 Final executable size: $(stat -c%s build/creative_wakatime.exe) bytes"
else
echo "❌ Ninja production build failed!"
exit 1
fi
- name: Create Release Package
shell: msys2 {0}
run: |
PACKAGE_NAME="Unity-Wakatime_v${{ env.RELEASE_VERSION }}"
PACKAGE_NAME="Creative-Wakatime_v${{ env.RELEASE_VERSION }}"
EXTENSION_NAME="creative-wakatime"
echo "📦 Creating release package: $PACKAGE_NAME"

mkdir -p "release-package/$PACKAGE_NAME"
cp build/unity_wakatime.exe "release-package/$PACKAGE_NAME/"
cp build/creative_wakatime.exe "release-package/$PACKAGE_NAME/"
cp build/logo_32.png "release-package/$PACKAGE_NAME/"

[ -f README.md ] && cp README.md "release-package/$PACKAGE_NAME/" || echo "README.md not found"
[ -f LICENSE ] && cp LICENSE "release-package/$PACKAGE_NAME/" || echo "LICENSE not found"

# Aseprite extension은 별도 설치 가능한 .aseprite-extension(zip)으로 패키징
if [ -d aseprite-extension ]; then
mkdir -p release-package/aseprite-extension-build
cp aseprite-extension/package.json release-package/aseprite-extension-build/
cp aseprite-extension/wakatime.lua release-package/aseprite-extension-build/
(cd release-package/aseprite-extension-build && 7z a "../${EXTENSION_NAME}.aseprite-extension" package.json wakatime.lua)
else
echo "aseprite-extension not found"
fi

echo "📋 Release package contents:"
ls -la "release-package/$PACKAGE_NAME/"
ls -lh release-package/*.aseprite-extension || true

echo "PACKAGE_NAME=$PACKAGE_NAME" >> $GITHUB_ENV
echo "EXTENSION_NAME=$EXTENSION_NAME" >> $GITHUB_ENV

- name: Create ZIP Archive
shell: msys2 {0}
Expand All @@ -180,12 +193,16 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: ${{ env.PACKAGE_NAME }}
path: release-package/${{ env.PACKAGE_NAME }}/
path: |
release-package/${{ env.PACKAGE_NAME }}/
release-package/${{ env.EXTENSION_NAME }}.aseprite-extension
retention-days: 90

- name: Upload ZIP to Release
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
files: release-package/${{ env.PACKAGE_NAME }}.zip
files: |
release-package/${{ env.PACKAGE_NAME }}.zip
release-package/${{ env.EXTENSION_NAME }}.aseprite-extension
29 changes: 15 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.23)
project(unity_wakatime)
project(creative_wakatime)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand All @@ -11,6 +11,7 @@ set(SOURCES
src/process_monitor.cpp
src/file_watcher.cpp
src/wakatime_client.cpp
src/inbox_bridge.cpp
src/tray_icon.cpp
src/windows_dark_mode.cpp
src/unity_focus_detector.cpp
Expand All @@ -21,15 +22,16 @@ set(HEADERS
include/process_monitor.h
include/file_watcher.h
include/wakatime_client.h
include/inbox_bridge.h
include/tray_icon.h
include/windows_dark_mode.h
include/unity_focus_detector.h
)

add_executable(unity_wakatime ${SOURCES} ${HEADERS})
add_executable(creative_wakatime ${SOURCES} ${HEADERS})

if(WIN32)
target_compile_definitions(unity_wakatime PRIVATE
target_compile_definitions(creative_wakatime PRIVATE
WINVER=0x0601
_WIN32_WINNT=0x0601
UNICODE=1
Expand All @@ -38,15 +40,15 @@ if(WIN32)
)

if(MINGW)
target_link_options(unity_wakatime PRIVATE
target_link_options(creative_wakatime PRIVATE
-static-libgcc
-static-libstdc++
-static
-mwindows
-Wl,--enable-stdcall-fixup
)

target_link_libraries(unity_wakatime
target_link_libraries(creative_wakatime
winhttp
shell32
psapi
Expand All @@ -58,7 +60,7 @@ if(WIN32)
)
else()
# MSVC용 설정
target_link_libraries(unity_wakatime
target_link_libraries(creative_wakatime
winhttp
shell32
psapi
Expand All @@ -74,23 +76,22 @@ if(WIN32)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
if(MSVC)
# MSVC: Windows 서브시스템 설정
set_property(TARGET unity_wakatime PROPERTY WIN32_EXECUTABLE TRUE)
target_link_options(unity_wakatime PRIVATE
set_property(TARGET creative_wakatime PROPERTY WIN32_EXECUTABLE TRUE)
target_link_options(creative_wakatime PRIVATE
/SUBSYSTEM:WINDOWS
/ENTRY:mainCRTStartup
)
elseif(MINGW)
# MinGW: 크기 최적화 (-Os), LTO, 미사용 섹션 제거 (Resident Set Size 최소화)
target_compile_options(unity_wakatime PRIVATE
# MinGW: 크기 최적화 (-Os), 미사용 섹션 제거 (Resident Set Size 최소화)
# GCC 16.1.0(MSYS2 MinGW)에서 LTO(-flto) 링크 중 내부 컴파일러 오류가 발생하므로 비활성화한다.
target_compile_options(creative_wakatime PRIVATE
-Os
-flto
-ffunction-sections
-fdata-sections
)
target_link_options(unity_wakatime PRIVATE
-Os # LTO 링크 단계 최적화도 크기 우선으로
target_link_options(creative_wakatime PRIVATE
-Os # 링크 단계도 크기 우선으로 최적화
-s # Strip symbols for smaller file size
-flto
-Wl,--gc-sections
)
endif()
Expand Down
77 changes: 65 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,110 @@
<div align="center">

## Unity - WakaTime
## Creative - WakaTime

[![License: MIT](https://img.shields.io/badge/License-MIT-skyblue.svg?style=for-the-badge&logo=github)](LICENSE)
![GitHub Repo stars](https://img.shields.io/github/stars/snow0406/Unity-Wakatime?style=for-the-badge&logo=github&color=%23ef8d9d)
![GitHub Repo stars](https://img.shields.io/github/stars/snow0406/creative-wakatime?style=for-the-badge&logo=github&color=%23ef8d9d)

🎯 Automatic Unity project detection and time tracking for WakaTime
🎯 Automatic time tracking for **Unity** and **Aseprite** via WakaTime

---

</div>

### 🚀 Features

- **Automatic Detection**: Finds Unity projects automatically
- **Real-time Monitoring**: Tracks file changes as you code
- **Unity**: Automatic project detection + real-time file change tracking
- **Aseprite**: Editing & saving activity tracking via a lightweight Lua extension
- **Version Support**: Detects Unity editor versions (e.g., "Unity 2022.3")
- **System Tray**: Runs quietly in background with right-click menu
- **Smart Notifications**: Shows project start/stop alerts
- **Separate dashboards**: Unity and Aseprite are reported as distinct editors on WakaTime

### 🔧 System Requirements

- **OS**: Windows
- **API key**: WakaTime API KEY (free at wakatime.com)
- **Aseprite** (optional): for sprite/pixel-art tracking

### 📦 Installation

1. Go to [Releases](https://github.com/Snow0406/Unity-Wakatime/releases)
2. Download the latest `Unity-Wakatime_vX.X.X.zip`
1. Go to [Releases](https://github.com/Snow0406/creative-wakatime/releases)
2. Download the latest `Creative-Wakatime_vX.X.X.zip`
3. Extract to your preferred location
4. Run `unity_wakatime.exe`
4. Run `creative_wakatime.exe`

### ⚙️ Setup

1. **Get WakaTime API Key**:
- Visit https://wakatime.com/api-key
- Copy your API key

2. **Configure Unity WakaTime**:
2. **Configure Creative WakaTime**:
- Right-click the system tray icon
- Click "🔑 Setup API Key"
- The WakaTime website will open automatically
- Copy your API key and click OK
- Wait for validation ✅
- The API key is stored at `%APPDATA%/creative-wakatime/wakatime_config.txt`

3. **Start Unity and Code!**
3. **Unity** — Start and Code!
- Open any Unity project
- The app will automatically detect and start tracking
- The app automatically detects and starts tracking

4. **Aseprite** — Install the extension (optional):
- Download `creative-wakatime.aseprite-extension` from the same release.
- Double-click it, or install it from Aseprite via
**Edit > Preferences > Extensions > Add Extension**.
- Restart Aseprite.
- The extension writes local event files to `%APPDATA%/creative-wakatime/events/`.
- Creative WakaTime watches that folder and forwards heartbeats.

### 🧩 How Aseprite tracking works

Aseprite cannot be hooked directly from C++, so a small Aseprite **Lua extension**
emits local JSON event files on edit/save. The tray app watches
`%APPDATA%/creative-wakatime/events/` (event-driven, no polling) and converts each
event into a WakaTime heartbeat, then deletes the file.

```
Unity -> ProcessMonitor / FileWatcher -> WakaTimeClient -> WakaTime API
Aseprite -> Lua extension -> events/*.json -> Inbox bridge -> WakaTimeClient -> WakaTime API
```

Aseprite events are intentionally optional. If the extension is not installed,
Creative WakaTime only watches an empty local inbox and no Aseprite heartbeat is
created.

#### Aseprite extension behavior

- **Edit activity** (`sitechange`): active sprite/layer/frame changes are reported
as `is_write=false` with a 2-minute per-file debounce.
- **Save activity** (`aftercommand` → `SaveFile`/`SaveFileAs`/`SaveFileCopyAs`):
reported immediately as `is_write=true`.
- Unsaved sprites without a file path are ignored.
- `project` is the parent folder name of the sprite file.
- The extension does not call the WakaTime API directly; it only writes local
`.json` event files for the tray app to consume.

#### Manual Aseprite extension install

If you are building from source instead of using the release asset, zip the
contents of `aseprite-extension/` so that `package.json` and `wakatime.lua` are at
the root of the archive, then rename the archive to
`creative-wakatime.aseprite-extension`.

You can also copy the folder manually:

```text
%APPDATA%/Aseprite/extensions/creative-wakatime/
```

The folder must contain both `package.json` and `wakatime.lua`.

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

---

Made with ♥ by hy
Made with ♥ by hy
14 changes: 14 additions & 0 deletions aseprite-extension/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "creative-wakatime",
"displayName": "Creative WakaTime",
"description": "Tracks Aseprite editing/saving activity for Creative WakaTime (WakaTime). Writes local event files consumed by the Creative WakaTime tray app.",
"version": "2.0.0",
"author": {
"name": "hy"
},
"contributes": {
"scripts": [
{ "path": "./wakatime.lua" }
]
}
}
Loading
Loading