Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
a1b008a
feat(next): add UI mockups and Stitch design prompt
YCC3741 Apr 16, 2026
a82f0e2
feat(next): scaffold Tauri v2 + Vue 3 TS project (P0 chunk 1)
YCC3741 Apr 16, 2026
425eb74
chore(next): add lint/format/test tooling (P0 step 0.4)
YCC3741 Apr 16, 2026
c8d6b43
ci(next): add smoke tests and GitHub Actions workflow (P0 steps 0.5-0.6)
YCC3741 Apr 16, 2026
ec02a34
ci: add commitlint for conventional commits on PRs to code (P0 step 0.7)
YCC3741 Apr 16, 2026
59e4e67
docs(next): add Traditional Chinese README and mark P0 complete (P0 s…
YCC3741 Apr 16, 2026
87578aa
feat(next): add core/wcdes DES/ECB/NoPadding module (P1)
YCC3741 Apr 16, 2026
f39f226
refactor(next): extract process_blocks helper in core/wcdes (SRP/DRY)
YCC3741 Apr 16, 2026
94a72c2
feat(next): add core/version comparison (P2 part 1/2)
YCC3741 Apr 16, 2026
ff1c231
feat(next): add core/parser modules (P2 part 2/2)
YCC3741 Apr 16, 2026
02b4caf
refactor(next): DRY capture_first across parsers (P2 polish)
YCC3741 Apr 16, 2026
0de45cb
feat(next): add services/beanfun skeleton + session_key (P3 chunk 1/5)
YCC3741 Apr 16, 2026
4443916
feat(next): add TW Regular login flow (P3 chunk 2/5)
YCC3741 Apr 16, 2026
9a642c2
refactor(next): align TW classify_outcome with WPF and extend coverag…
YCC3741 Apr 16, 2026
8729dbd
feat(next): add login_completed shared tail (P3 chunk 3.3.1)
YCC3741 Apr 16, 2026
e0aff15
feat(next): add HK Regular login flow (P3 chunk 3.3.2)
YCC3741 Apr 16, 2026
29f9028
feat(next): add TOTP login flow (P3 chunk 3.3.3)
YCC3741 Apr 16, 2026
4d47230
feat(next): add CheckIsRegisteDevice device-registration polling (P3 …
YCC3741 Apr 16, 2026
ec7df42
feat(next): add QR login init step (P3 chunk 3.4.1)
YCC3741 Apr 16, 2026
4d7b085
feat(next): add QR login poll step (P3 chunk 3.4.2)
YCC3741 Apr 16, 2026
ab1eb33
feat(next): add QR login finalize step (P3 chunk 3.4.3)
YCC3741 Apr 16, 2026
3921e0c
fix(next): align QR finalize with WPF LoginCompleted (P3 chunk 3.4 re…
YCC3741 Apr 17, 2026
b147571
feat(next): add logout flow (P3 chunk 3.5)
YCC3741 Apr 17, 2026
100eb8e
feat(next): add top-level login dispatcher (P3 chunk 3.5)
YCC3741 Apr 17, 2026
6834670
docs(next): correct chunk 3.5 inline docs to match implementation (P3…
YCC3741 Apr 17, 2026
3acf606
feat(next): add account read + JSON management endpoints (P4 chunk 4.1)
YCC3741 Apr 17, 2026
ffe4809
feat(next): add OTP retrieval flow (P4 chunk 4.2)
YCC3741 Apr 17, 2026
49d1a0e
feat(next): add advance-check verify flow (P4 chunk 4.3)
YCC3741 Apr 17, 2026
9d10b34
fix(next): align verify flow with WPF for HK region (P4 chunk 4.3 fix)
YCC3741 Apr 17, 2026
aed206d
feat(next): add WebForms account-management endpoints (P4 chunk 4.4)
YCC3741 Apr 17, 2026
3bd830c
feat(next): add DPAPI + entropy storage primitives (P5 chunk 5.1)
YCC3741 Apr 17, 2026
7afdd40
feat(next): add Users.dat JSON + DPAPI storage (P5 chunk 5.2)
YCC3741 Apr 17, 2026
85b13cd
feat(next): add AppSettings XML config store (P5 chunk 5.3)
YCC3741 Apr 17, 2026
469922c
fix(next): P5 review polish (F2 + F5 + F6)
YCC3741 Apr 17, 2026
0ce3d45
feat(next): add NRBF parser for legacy Users.dat (P6 chunk 6.1)
YCC3741 Apr 17, 2026
88aff85
feat(next): add legacy Users.dat migration (P6 chunk 6.2)
YCC3741 Apr 17, 2026
cdb374b
feat(next): add updater parser + proxy probe (P7 chunk 7.1)
YCC3741 Apr 17, 2026
a0a7663
feat(next): add updater GitHub fetch + channel selection (P7 chunk 7.2)
YCC3741 Apr 17, 2026
207919b
feat(next): add updater check_update composition (P7 chunk 7.3)
YCC3741 Apr 17, 2026
5631a41
feat(next): add game launcher primitives + Normal mode (P8 chunk 8.1)
YCC3741 Apr 17, 2026
fdada84
feat(next): add LocaleRemulator embed + SHA-256 release + runas launc…
YCC3741 Apr 17, 2026
c029174
fix(next): apply P8.2 review follow-ups (redact Debug, tighten releas…
YCC3741 Apr 17, 2026
75774ed
feat(next): add registry game_path + process find/kill (P9 chunk 9.1)
YCC3741 Apr 17, 2026
104dbb8
feat(next): add patcher kill + play_page close (P9 chunk 9.2)
YCC3741 Apr 17, 2026
a1c1607
feat(next): add auto-paste Win32 wrappers (P9 chunk 9.3)
YCC3741 Apr 17, 2026
ee71c29
feat(next): add Tauri command IPC infrastructure (P10 chunk 10.1)
YCC3741 Apr 17, 2026
57d5dc8
feat(next): add auth+account+otp commands (P10 chunk 10.2)
YCC3741 Apr 18, 2026
4ae1f49
chore(next): correct P10.2 Todo hash after stray amend
YCC3741 Apr 18, 2026
2f28041
feat(next): add launcher+storage+config+update+system commands (P10 c…
YCC3741 Apr 18, 2026
6770330
chore(next): backfill P10.3 Todo hash
YCC3741 Apr 18, 2026
8aeebaf
feat(next): add P11 frontend infra (i18n + Pinia + router + theme)
YCC3741 Apr 18, 2026
3e2bf22
chore(next): backfill P11 Todo hash
YCC3741 Apr 18, 2026
1e40051
fix(next): coerce JToken-style scalars in login JSON responses
YCC3741 Apr 18, 2026
7ef3085
chore(next): add login-flow diagnostic logging for success + failure …
YCC3741 Apr 18, 2026
756f595
fix(next): harden observability + P11/D4 live-test hotfixes
YCC3741 Apr 18, 2026
239b12c
feat(next): add P12.1 D1-D5 login flow views
YCC3741 Apr 18, 2026
57a34d7
chore(next): record P12.1 D1-D5 Todo progress
YCC3741 Apr 18, 2026
b0dcfc3
feat(next): add P12.1 D6-D10 login flow (TOTP + Wait + Verify) + i18n…
YCC3741 Apr 18, 2026
3465c84
chore(next): record P12.1 D6-D10 Todo progress
YCC3741 Apr 18, 2026
3f8c504
feat(next): add P12.2 account management views
YCC3741 Apr 19, 2026
db2e0f9
chore(next): record P12.2 Todo progress
YCC3741 Apr 19, 2026
a04774c
feat(next): add P12.3 game launch and unconnected game dialogs
YCC3741 Apr 19, 2026
193ff76
chore(next): record P12.3 Todo progress
YCC3741 Apr 19, 2026
cb52d40
feat(next): add P12.4 settings, about, and web browser shell
YCC3741 Apr 19, 2026
407b98d
chore(next): record P12.4 Todo progress
YCC3741 Apr 19, 2026
ca4062a
feat(next): add P12.5 tools dialogs and zh-CN fallback chain
YCC3741 Apr 19, 2026
d1498b7
chore(next): record P12.5 Todo progress
YCC3741 Apr 19, 2026
083ac3d
feat(next): add P12.4-followup-A login form parity buttons + useGameL…
YCC3741 Apr 20, 2026
ab056f8
feat(next): replace iframe placeholder with in-app browser window (P1…
YCC3741 Apr 20, 2026
97ff386
feat(next): in-app browser fixes, UI polish, tray, updater & manifest…
YCC3741 Apr 20, 2026
4f16906
refactor: flatten repo structure, rename to Beanfun, add CI workflows
YCC3741 Apr 20, 2026
a4d6754
Merge remote-tracking branch 'origin/code' into feat/beanfun-next-rew…
YCC3741 Apr 20, 2026
f2c2936
fix(ci): resolve all failing CI checks
YCC3741 Apr 20, 2026
4d0b9e3
fix(ci): add .gitattributes to enforce LF line endings
YCC3741 Apr 20, 2026
cbd679a
chore: remove commitlint, add architecture section to README
YCC3741 Apr 20, 2026
2981282
fix(ci): harden build-and-release workflow
YCC3741 Apr 20, 2026
14150b7
fix(security): redact sensitive data from logs and IPC surface
YCC3741 Apr 20, 2026
6b1237c
style: fix rustfmt formatting in error.rs
YCC3741 Apr 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 0 additions & 12 deletions .config/dotnet-tools.json

This file was deleted.

18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# EditorConfig (https://editorconfig.org) — Beanfun
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

# Rust / TOML follow Rust community convention.
[*.{rs,toml}]
indent_size = 4

# Markdown allows trailing whitespace (two-space line break).
[*.md]
trim_trailing_whitespace = false
10 changes: 10 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Force LF line endings for all text files, regardless of OS.
# Prevents CRLF issues in CI (rustfmt, prettier) on Windows runners.
* text=auto eol=lf

# Ensure these are always treated as binary (no line-ending conversion).
*.png binary
*.ico binary
*.dll binary
*.exe binary
*.xml binary
19 changes: 19 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 10

- package-ecosystem: cargo
directory: /src-tauri
schedule:
interval: weekly
open-pull-requests-limit: 10

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
open-pull-requests-limit: 5
146 changes: 78 additions & 68 deletions .github/workflows/build-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ on:
workflow_dispatch:
inputs:
release_name:
description: "Release Name (leave empty to auto-generate)"
description: 'Release Name (leave empty to auto-generate)'
required: false
default: ""
default: ''
release_type:
description: "Release type"
description: 'Release type'
required: true
default: "prerelease"
default: 'prerelease'
type: choice
options:
- prerelease
- release
version_increment:
description: "Version increment type"
description: 'Version increment type'
required: false
default: "patch"
default: 'patch'
type: choice
options:
- patch
Expand All @@ -30,47 +30,47 @@ env:

jobs:
build:
name: 'Build Beanfun.exe & Create Release'
runs-on: windows-latest
permissions:
contents: write

steps:
- name: Checkout Code
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup .NET 8
uses: actions/setup-dotnet@v5
- name: Setup Node.js
uses: actions/setup-node@v4
with:
dotnet-version: "8.0.x"
node-version: '22'
cache: npm
cache-dependency-path: package-lock.json

- name: Prepare Version & Inject AssemblyInfo
- name: Install Rust (stable)
uses: dtolnay/rust-toolchain@stable

- name: Cache Cargo
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri

- name: Install frontend dependencies
run: npm ci

- name: Prepare version
id: prep_version
shell: pwsh
run: |
$file = Get-ChildItem -Path . -Filter "AssemblyInfo.cs" -Recurse | Select-Object -First 1
if (-not $file) { Write-Error "AssemblyInfo.cs not found!"; exit 1 }

$content = Get-Content $file.FullName -Raw
if ($content -match 'AssemblyVersion\("(\d+)\.(\d+)(?:\.\d+)?\.\*"\)') {
$cargoToml = Get-Content src-tauri/Cargo.toml -Raw
if ($cargoToml -match 'version\s*=\s*"(\d+)\.(\d+)\.(\d+)"') {
$major = [int]$matches[1]
$minor = [int]$matches[2]
} else {
$major = 5
$minor = 8
}

git fetch --tags 2>$null
$tags = git tag -l "v$major.$minor.*.*" --sort=-v:refname

$patch = 0
$tagsArray = @($tags)
if ($tagsArray.Count -gt 0 -and $tagsArray[0]) {
$latestTag = $tagsArray[0]
if ($latestTag -match "^v\d+\.\d+\.(\d+)\.") {
$patch = [int]$matches[1]
}
$patch = [int]$matches[3]
} else {
Write-Error "Could not parse version from Cargo.toml"
exit 1
}

$releaseType = "${{ github.event.inputs.release_type }}"
Expand All @@ -82,44 +82,50 @@ jobs:
'minor' { $minor++; $patch=0 }
'patch' { $patch++ }
}
} else {
$patch++
} else {
$patch++
}

$utcNow = (Get-Date).ToUniversalTime()
$timestamp = $utcNow.ToString("yyMMddHHmm")
$buildDateTime = $utcNow.ToString("yyyy-MM-dd HH:mm:ss")

$baseDate = (Get-Date -Year 2000 -Month 1 -Day 1).ToUniversalTime()
$build = [math]::Floor(($utcNow - $baseDate).TotalDays)
$revision = [math]::Floor($utcNow.TimeOfDay.TotalSeconds / 2)

$infoVersion = "$major.$minor.$patch($timestamp)"
$tagName = "v$major.$minor.$patch.$timestamp"
$semVer = "$major.$minor.$patch"
$infoVersion = "$semVer($timestamp)"
$tagName = "v$semVer.$timestamp"

Write-Host "🚀 New Version: $infoVersion"

$content = $content -replace 'AssemblyVersion\(".*?"\)', "AssemblyVersion(`"$major.$minor.*`")"
if ($content -match 'AssemblyInformationalVersion') {
$content = $content -replace 'AssemblyInformationalVersion\(".*?"\)', "AssemblyInformationalVersion(`"$infoVersion`")"
} else {
$content += "`r`n[assembly: System.Reflection.AssemblyInformationalVersion(`"$infoVersion`")]"
}
if (-not $content.EndsWith("`n")) { $content += "`r`n" }
$content | Set-Content $file.FullName -NoNewline
Write-Host "Version: $infoVersion"

"tag_name=$tagName" >> $env:GITHUB_OUTPUT
"semantic_version=$semVer" >> $env:GITHUB_OUTPUT
"info_version=$infoVersion" >> $env:GITHUB_OUTPUT
"build_datetime=$buildDateTime" >> $env:GITHUB_OUTPUT
"build=$build" >> $env:GITHUB_OUTPUT
"revision=$revision" >> $env:GITHUB_OUTPUT

- name: Publish Application
run: dotnet publish Beanfun/Beanfun.csproj -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeNativeLibrariesForSelfExtract=true -p:IncludeAllContentForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=none -p:InformationalVersion="${{ steps.prep_version.outputs.info_version }}" -o publish
- name: Update version in Cargo.toml, tauri.conf.json, package.json
shell: pwsh
run: |
$semVer = "${{ steps.prep_version.outputs.semantic_version }}"

$cargo = Get-Content src-tauri/Cargo.toml -Raw -Encoding UTF8
$cargo = $cargo -replace '(?m)^version\s*=\s*"[\d.]+"', "version = `"$semVer`""
[System.IO.File]::WriteAllText("src-tauri/Cargo.toml", $cargo)

$tauri = Get-Content src-tauri/tauri.conf.json -Raw -Encoding UTF8
$tauri = $tauri -replace '"version"\s*:\s*"[\d.]+"', "`"version`": `"$semVer`""
[System.IO.File]::WriteAllText("src-tauri/tauri.conf.json", $tauri)

$pkg = Get-Content package.json -Raw -Encoding UTF8
$pkg = $pkg -replace '"version"\s*:\s*"[\d.]+"', "`"version`": `"$semVer`""
[System.IO.File]::WriteAllText("package.json", $pkg)

- name: Build Tauri application (standalone exe)
run: npm run tauri build -- --no-bundle

- name: Prepare Release Notes
- name: Rename exe to Beanfun.exe
shell: cmd
run: ren src-tauri\target\release\beanfun.exe Beanfun.exe

- name: Prepare release notes
id: prep_release
shell: pwsh
env:
Expand All @@ -132,16 +138,22 @@ jobs:
"exists=$($exists.ToString().ToLower())" >> $env:GITHUB_OUTPUT

if ($exists) {
Write-Host "⚠️ Tag $tag already exists. Skipping release creation."
Write-Host "Tag $tag already exists. Skipping release creation."
exit 0
}

$lastRelease = gh api repos/${{ github.repository }}/releases --paginate 2>$null | ConvertFrom-Json | Sort-Object created_at -Descending | Select-Object -First 1
$range = if ($lastRelease) { "$($lastRelease.tag_name)..HEAD" } else { "-n 30" }

$repoUrl = "${{ github.server_url }}/${{ github.repository }}"

$commits = git log $range --pretty=format:"- [%h]($repoUrl/commit/%H) %s - %an (%ad)" --date=short --no-merges
$lastRelease = gh api repos/${{ github.repository }}/releases --paginate 2>$null | ConvertFrom-Json | Sort-Object created_at -Descending | Select-Object -First 1

$logArgs = @('log', '--pretty=format:"- [%h](' + $repoUrl + '/commit/%H) %s - %an (%ad)"', '--date=short', '--no-merges')
if ($lastRelease) {
$logArgs += "$($lastRelease.tag_name)..HEAD"
} else {
$logArgs += '-n'
$logArgs += '30'
}
$commits = & git @logArgs

$commitCount = if ($commits) { ($commits -split "`n").Count } else { 0 }
$commitsText = if ($commits) { $commits -join "`n" } else { "No commits found" }
Expand All @@ -152,15 +164,15 @@ jobs:
$delimiter >> $env:GITHUB_OUTPUT
"commit_count=$commitCount" >> $env:GITHUB_OUTPUT

- name: Create Release
- name: Create GitHub Release
if: steps.prep_release.outputs.exists == 'false'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ steps.prep_version.outputs.tag_name }}
name: >
${{
github.event.inputs.release_name != ''
&& github.event.inputs.release_name
${{
github.event.inputs.release_name != ''
&& github.event.inputs.release_name
|| format('v{0}', steps.prep_version.outputs.semantic_version)
}}
body: |
Expand Down Expand Up @@ -191,21 +203,19 @@ jobs:
|------|-------|
| Full Build Version | ${{ steps.prep_version.outputs.info_version }} |
| Build Date/Time (UTC) | ${{ steps.prep_version.outputs.build_datetime }} |
| MS Build Revision | ${{ steps.prep_version.outputs.build }}.${{ steps.prep_version.outputs.revision }} |
| Source Commit | [View](${{ github.server_url }}/${{ github.repository }}/commit/${{ github.sha }}) |

</details>
files: publish/Beanfun.exe
files: src-tauri/target/release/Beanfun.exe
draft: false
prerelease: ${{ github.event.inputs.release_type == 'prerelease' }}

- name: Commit Version Change
- name: Commit version bump
if: steps.prep_release.outputs.exists == 'false'
shell: pwsh
run: |
$file = Get-ChildItem -Path . -Filter "AssemblyInfo.cs" -Recurse | Select-Object -First 1
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add $file.FullName
git add src-tauri/Cargo.toml src-tauri/tauri.conf.json package.json
git commit -m "Bump version to ${{ steps.prep_version.outputs.semantic_version }} for release ${{ steps.prep_version.outputs.tag_name }}"
git push
71 changes: 71 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Lint, Format & Test

on:
push:
branches: [code]
pull_request:
branches: [code]
workflow_dispatch:

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
frontend:
name: 'Frontend: ESLint / Prettier / TypeCheck / Vitest'
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: npm
cache-dependency-path: package-lock.json

- name: Install dependencies
run: npm ci

- name: ESLint
run: npm run lint

- name: Prettier check
run: npm run format:check

- name: Type check
run: npm run typecheck

- name: Unit tests (Vitest)
run: npm run test

rust:
name: 'Rust: fmt / Clippy / Test'
runs-on: windows-latest
defaults:
run:
working-directory: src-tauri
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Rust (stable)
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy

- name: Cache Cargo
uses: Swatinem/rust-cache@v2
with:
workspaces: src-tauri

- name: cargo fmt
run: cargo fmt --all -- --check

- name: cargo clippy
run: cargo clippy --all-targets -- -D warnings

- name: cargo test
run: cargo test
Loading
Loading