forked from mirrors/cursor-free-vip
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3dff87da9 | ||
|
|
861f258ce4 | ||
|
|
ab9202fe48 | ||
|
|
d60c46bac6 | ||
|
|
4757f9777a | ||
|
|
caecbd4c8d | ||
|
|
105b5d4517 | ||
|
|
f325690e32 | ||
|
|
3de2db74b2 | ||
|
|
6153041607 | ||
|
|
6eba95c055 | ||
|
|
21535104a6 | ||
|
|
b42b4b01b9 | ||
|
|
4b9c465dd5 | ||
|
|
b98059a476 | ||
|
|
56882f0663 | ||
|
|
0852472746 | ||
|
|
d867f5cfe9 | ||
|
|
e69e500e8d | ||
|
|
2f012b9dc5 | ||
|
|
d3c6bf227b | ||
|
|
f697b71755 | ||
|
|
5863891f4b | ||
|
|
7e0da4a0cb | ||
|
|
1cdb543ea9 | ||
|
|
5dad4f35a6 | ||
|
|
34a23a69a1 | ||
|
|
3cca2e3b17 | ||
|
|
ee287b91f2 | ||
|
|
96704e9f38 | ||
|
|
f541bc40b4 | ||
|
|
a730b145a1 | ||
|
|
9f81f94957 |
5
.SRCINFO
5
.SRCINFO
@@ -1,10 +1,11 @@
|
|||||||
pkgbase = cursor-free-vip-git
|
pkgbase = cursor-free-vip-git
|
||||||
pkgdesc = Reset Cursor AI MachineID & Auto Sign Up / In & Bypass Higher Token Limit
|
pkgdesc = Reset Cursor AI MachineID & Auto Sign Up / In & Bypass Higher Token Limit
|
||||||
pkgver = 1.9.03.2.g43a58db
|
pkgver = 1.9.04.10.g5863891
|
||||||
pkgrel = 1
|
pkgrel = 1
|
||||||
url = https://github.com/yeongpin/cursor-free-vip
|
url = https://github.com/yeongpin/cursor-free-vip
|
||||||
arch = x86_64
|
arch = x86_64
|
||||||
license = MIT
|
license = MIT
|
||||||
|
license = Attribution-NonCommercial-NoDerivatives 4.0 International
|
||||||
makedepends = git
|
makedepends = git
|
||||||
makedepends = python
|
makedepends = python
|
||||||
makedepends = pyinstaller
|
makedepends = pyinstaller
|
||||||
@@ -13,6 +14,8 @@ pkgbase = cursor-free-vip-git
|
|||||||
depends = cursor-bin
|
depends = cursor-bin
|
||||||
provides = cursor-free-vip
|
provides = cursor-free-vip
|
||||||
source = cursor-free-vip::git+https://github.com/yeongpin/cursor-free-vip.git
|
source = cursor-free-vip::git+https://github.com/yeongpin/cursor-free-vip.git
|
||||||
|
source = https://raw.githubusercontent.com/canmi21/openjlc/refs/heads/main/LICENSE
|
||||||
|
sha256sums = SKIP
|
||||||
sha256sums = SKIP
|
sha256sums = SKIP
|
||||||
|
|
||||||
pkgname = cursor-free-vip-git
|
pkgname = cursor-free-vip-git
|
||||||
|
|||||||
65
.github/workflows/build.yml
vendored
65
.github/workflows/build.yml
vendored
@@ -153,7 +153,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Build in ARM64 Docker container
|
- name: Build in ARM64 Docker container
|
||||||
run: |
|
run: |
|
||||||
docker run --rm --platform linux/arm64 -v ${{ github.workspace }}:/app -w /app arm64v8/python:3.9-slim bash -c "
|
docker run --rm --platform linux/arm64 -v ${{ github.workspace }}:/app -w /app arm64v8/python:3.10-slim bash -c "
|
||||||
apt-get update && apt-get install -y build-essential
|
apt-get update && apt-get install -y build-essential
|
||||||
pip install --upgrade pip
|
pip install --upgrade pip
|
||||||
pip install pyinstaller
|
pip install pyinstaller
|
||||||
@@ -211,6 +211,9 @@ jobs:
|
|||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-22.04
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Get version
|
- name: Get version
|
||||||
shell: bash
|
shell: bash
|
||||||
run: echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
|
run: echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV
|
||||||
@@ -220,18 +223,66 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
path: artifacts
|
path: artifacts
|
||||||
|
|
||||||
- name: Prepare release files
|
- name: Calculate SHA256 checksums
|
||||||
run: |
|
run: |
|
||||||
cd artifacts
|
mkdir -p checksums
|
||||||
echo "Contents of artifacts directory:"
|
for file in artifacts/CursorFreeVIP_${{ env.VERSION }}_windows.exe/CursorFreeVIP_${{ env.VERSION }}_windows.exe \
|
||||||
ls -la
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_arm64/CursorFreeVIP_${{ env.VERSION }}_mac_arm64 \
|
||||||
echo "Contents of subdirectories:"
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_linux_x64/CursorFreeVIP_${{ env.VERSION }}_linux_x64 \
|
||||||
ls -la */
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_linux_arm64/CursorFreeVIP_${{ env.VERSION }}_linux_arm64 \
|
||||||
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_intel/CursorFreeVIP_${{ env.VERSION }}_mac_intel
|
||||||
|
do
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
filename=$(basename $file)
|
||||||
|
sha256sum "$file" | cut -d ' ' -f 1 > checksums/${filename}.sha256
|
||||||
|
echo "${filename}: $(cat checksums/${filename}.sha256)" >> checksums/all_checksums.txt
|
||||||
|
else
|
||||||
|
echo "Warning: File $file not found"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
cat checksums/all_checksums.txt
|
||||||
|
|
||||||
|
- name: Extract release notes from CHANGELOG
|
||||||
|
run: |
|
||||||
|
version_pattern="## v${{ env.VERSION }}"
|
||||||
|
next_version_pattern="## v"
|
||||||
|
|
||||||
|
# Find the start line number of the current version
|
||||||
|
start_line=$(grep -n "$version_pattern" CHANGELOG.md | head -1 | cut -d: -f1)
|
||||||
|
|
||||||
|
if [ -z "$start_line" ]; then
|
||||||
|
echo "Error: Version ${{ env.VERSION }} not found in CHANGELOG.md"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Find the line number of the next version
|
||||||
|
next_version_line=$(tail -n +$((start_line + 1)) CHANGELOG.md | grep -n "$next_version_pattern" | head -1 | cut -d: -f1)
|
||||||
|
|
||||||
|
if [ -z "$next_version_line" ]; then
|
||||||
|
# If there's no next version, get to the end of the file
|
||||||
|
changelog_content=$(tail -n +$start_line CHANGELOG.md)
|
||||||
|
else
|
||||||
|
# Extract content between current version and next version
|
||||||
|
end_line=$((start_line + next_version_line - 1))
|
||||||
|
changelog_content=$(sed -n "${start_line},${end_line}p" CHANGELOG.md)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create release notes file
|
||||||
|
{
|
||||||
|
echo "$changelog_content"
|
||||||
|
echo ""
|
||||||
|
echo "## SHA256 Checksums"
|
||||||
|
cat checksums/all_checksums.txt
|
||||||
|
} > release_notes.md
|
||||||
|
|
||||||
|
# Display release notes for debugging
|
||||||
|
cat release_notes.md
|
||||||
|
|
||||||
- name: Create Release
|
- name: Create Release
|
||||||
uses: softprops/action-gh-release@v1
|
uses: softprops/action-gh-release@v1
|
||||||
with:
|
with:
|
||||||
tag_name: v${{ env.VERSION }}
|
tag_name: v${{ env.VERSION }}
|
||||||
|
body_path: release_notes.md
|
||||||
files: |
|
files: |
|
||||||
artifacts/CursorFreeVIP_${{ env.VERSION }}_windows.exe/CursorFreeVIP_${{ env.VERSION }}_windows.exe
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_windows.exe/CursorFreeVIP_${{ env.VERSION }}_windows.exe
|
||||||
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_arm64/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
artifacts/CursorFreeVIP_${{ env.VERSION }}_mac_arm64/CursorFreeVIP_${{ env.VERSION }}_mac_arm64
|
||||||
|
|||||||
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,5 +1,18 @@
|
|||||||
# Change Log
|
# Change Log
|
||||||
|
|
||||||
|
## v1.9.05
|
||||||
|
1. Refactor: Using match-case to refactor language mapping and menu selection logic, making the code clearer and more maintainable. | 使用 match-case 重构语言映射和菜单选择逻辑,使代码更清晰、可维护性更高。
|
||||||
|
2. Ci: Update the Python version in the ARM64 Docker build container to 3.10, making it more compatible and easier to migrate in the future. | 更新 ARM64 Docker 构建容器中的 Python 版本至 3.10,兼容性更强,方便未来迁移。
|
||||||
|
3. Fix: f-string backslash expression errors in multiple files | 修復多個文件中的 f-string 反斜杠表達式錯誤
|
||||||
|
4. Sync AUR new version 1.9.04 | 同步 AUR 新版本 1.9.04
|
||||||
|
5. Fix: missing license install on pkgbuild @michaeldavis246611119 mention here | 修復 pkgbuild 中缺少授權安裝 @michaeldavis246611119 提到這裡
|
||||||
|
6. Fix: readme table | 修復 readme 表格
|
||||||
|
7. Fix: google-chrome package name problem, add "google-chrome-stable" [Bug]: Chrome error | Arch | gnome | AUR chrome #242 [Discussion]: how to use the new feature, Register with Google Account #249 [Discussion]: Having issues using the script in Ubuntu #487 [Bug]: Can open chromium bin in linux #616 | 修復 google-chrome 包名稱問題,添加 "google-chrome-stable" [Bug]: Chrome error | Arch | gnome | AUR chrome #242 [Discussion]: how to use the new feature, Register with Google Account #249 [Discussion]: Having issues using the script in Ubuntu #487 [Bug]: Can open chromium bin in linux #616
|
||||||
|
8. Fix: exception error log | 修復異常錯誤日誌
|
||||||
|
9. Fix: github oauth error [Bug]: #564 | 修復 github oauth 錯誤 [Bug]: #564
|
||||||
|
10. Fix: ChromiumOptions.arguments type error: list object has no attribute 'get' | 修復 ChromiumOptions.arguments 類型錯誤:list 對象沒有屬性 'get'
|
||||||
|
11. Fix: Some Issues | 修復一些問題
|
||||||
|
|
||||||
## v1.9.04
|
## v1.9.04
|
||||||
1. Add: Opera GX Support | 添加 Opera GX 支持
|
1. Add: Opera GX Support | 添加 Opera GX 支持
|
||||||
2. Same as v1.9.03 | 與 v1.9.03 相同
|
2. Same as v1.9.03 | 與 v1.9.03 相同
|
||||||
|
|||||||
10
PKGBUILD
10
PKGBUILD
@@ -2,17 +2,17 @@
|
|||||||
# Contributor: Canmi (Canmi21)
|
# Contributor: Canmi (Canmi21)
|
||||||
|
|
||||||
pkgname=cursor-free-vip-git
|
pkgname=cursor-free-vip-git
|
||||||
pkgver=1.9.03.2.g43a58db
|
pkgver=1.9.04.10.g5863891
|
||||||
pkgrel=1
|
pkgrel=1
|
||||||
pkgdesc="Reset Cursor AI MachineID & Auto Sign Up / In & Bypass Higher Token Limit"
|
pkgdesc="Reset Cursor AI MachineID & Auto Sign Up / In & Bypass Higher Token Limit"
|
||||||
arch=('x86_64')
|
arch=('x86_64')
|
||||||
url="https://github.com/yeongpin/cursor-free-vip"
|
url="https://github.com/yeongpin/cursor-free-vip"
|
||||||
license=('MIT')
|
license=('MIT' 'Attribution-NonCommercial-NoDerivatives 4.0 International')
|
||||||
depends=('python' 'cursor-bin')
|
depends=('python' 'cursor-bin')
|
||||||
makedepends=('git' 'python' 'pyinstaller' 'uv')
|
makedepends=('git' 'python' 'pyinstaller' 'uv')
|
||||||
provides=('cursor-free-vip')
|
provides=('cursor-free-vip')
|
||||||
source=("cursor-free-vip::git+https://github.com/yeongpin/cursor-free-vip.git")
|
source=("cursor-free-vip::git+https://github.com/yeongpin/cursor-free-vip.git" "https://raw.githubusercontent.com/canmi21/openjlc/refs/heads/main/LICENSE")
|
||||||
sha256sums=('SKIP')
|
sha256sums=('SKIP' 'SKIP')
|
||||||
|
|
||||||
pkgver() {
|
pkgver() {
|
||||||
cd "$srcdir/cursor-free-vip"
|
cd "$srcdir/cursor-free-vip"
|
||||||
@@ -28,5 +28,7 @@ build() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
package() {
|
package() {
|
||||||
|
install -Dm644 "$srcdir/LICENSE" "$pkgdir/usr/share/licenses/$pkgname/mit_license"
|
||||||
|
install -Dm644 "$srcdir/cursor-free-vip/LICENSE.md" "$pkgdir/usr/share/licenses/$pkgname/attribution_non_commercial_no_derivatives_license"
|
||||||
install -Dm755 "$srcdir/cursor-free-vip/dist/cursor-free-vip" "$pkgdir/usr/bin/cursor-free-vip"
|
install -Dm755 "$srcdir/cursor-free-vip/dist/cursor-free-vip" "$pkgdir/usr/bin/cursor-free-vip"
|
||||||
}
|
}
|
||||||
22
README.md
22
README.md
@@ -7,10 +7,10 @@
|
|||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
|
|
||||||
[](https://github.com/yeongpin/cursor-free-vip/releases/latest)
|
[](https://github.com/yeongpin/cursor-free-vip/releases/latest)
|
||||||
[](https://creativecommons.org/licenses/by-nc-nd/4.0/)
|
[](https://creativecommons.org/licenses/by-nc-nd/4.0/)
|
||||||
[](https://github.com/yeongpin/cursor-free-vip/stargazers)
|
[](https://github.com/yeongpin/cursor-free-vip/stargazers)
|
||||||
[](https://github.com/yeongpin/cursor-free-vip/releases/latest)
|
[](https://github.com/yeongpin/cursor-free-vip/releases/latest)
|
||||||
<a href="https://buymeacoffee.com/yeongpin" target="_blank"><img alt="Buy Me a Coffee" src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-Support%20Me-FFDA33"></a>
|
<a href="https://buymeacoffee.com/yeongpin" target="_blank"><img alt="Buy Me a Coffee" src="https://img.shields.io/badge/Buy%20Me%20a%20Coffee-Support%20Me-FFDA33"></a>
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
@@ -40,10 +40,10 @@ Always clean your browser's cache and cookies. If possible, use a VPN to create
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
##### If you don't have browser, you can download it from
|
##### If you don't have browser, you can download it from
|
||||||
[Google Chrome](https://www.google.com/intl/en_pk/chrome/) or [Opera](https://www.opera.com/download) or [Edge](https://www.microsoft.com/en-us/edge) or [Firefox](https://www.mozilla.org/en-US/firefox/new/) or [Brave](https://www.brave.com/download/)
|
|
||||||
|
|
||||||
##### 如果沒有瀏覽器,可以從
|
##### 如果沒有瀏覽器,可以從这里下載
|
||||||
[Google Chrome](https://www.google.com/intl/en_pk/chrome/) 或 [Opera](https://www.opera.com/download) 或 [Edge](https://www.microsoft.com/en-us/edge) 或 [Firefox](https://www.mozilla.org/en-US/firefox/new/) 或 [Brave](https://www.brave.com/download/) 下載
|
|
||||||
|
[Google Chrome](https://www.google.com/intl/en_pk/chrome/) | [Opera](https://www.opera.com/download) | [Edge](https://www.microsoft.com/en-us/edge) | [Firefox](https://www.mozilla.org/en-US/firefox/new/) | [Brave](https://www.brave.com/download/)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -71,11 +71,11 @@ Always clean your browser's cache and cookies. If possible, use a VPN to create
|
|||||||
|
|
||||||
## 💻 System Support | 系統支持
|
## 💻 System Support | 系統支持
|
||||||
|
|
||||||
| Windows | x64 | ✅ | macOS | Intel | ✅ |
|
| Operating System | Architecture | Supported |
|
||||||
|:-------:|:-----:|:-:|:-----:|:-------------:|:-:|
|
|------------------|-------------------|-----------|
|
||||||
| Windows | x86 | ✅ | macOS | Apple Silicon | ✅ |
|
| Windows | x64, x86 | ✅ |
|
||||||
| Linux | x64 | ✅ | Linux | x86 | ✅ |
|
| macOS | Intel, Apple Silicon | ✅ |
|
||||||
| Linux | ARM64 | ✅ | Linux | ARM64 | ✅ |
|
| Linux | x64, x86, ARM64 | ✅ |
|
||||||
|
|
||||||
## 👀 How to use | 如何使用
|
## 👀 How to use | 如何使用
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ class CursorRegistration:
|
|||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.invalid_email') if self.translator else '无效的邮箱地址'}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('register.invalid_email') if self.translator else '无效的邮箱地址'}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
print(f"{Fore.CYAN}{EMOJI['MAIL']} {self.translator.get('register.email_address')}: {self.email_address}\n{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['MAIL']} {self.translator.get('register.email_address')}: {self.email_address}" + "\n" + f"{Style.RESET_ALL}")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -247,11 +247,11 @@ class CursorGoogleAccountDeleter(OAuthHandler):
|
|||||||
except:
|
except:
|
||||||
# Try direct JavaScript input as fallback
|
# Try direct JavaScript input as fallback
|
||||||
try:
|
try:
|
||||||
self.browser.run_js(f"""
|
self.browser.run_js(r"""
|
||||||
arguments[0].value = "Delete";
|
arguments[0].value = "Delete";
|
||||||
const event = new Event('input', {{ bubbles: true }});
|
const event = new Event('input', { bubbles: true });
|
||||||
arguments[0].dispatchEvent(event);
|
arguments[0].dispatchEvent(event);
|
||||||
const changeEvent = new Event('change', {{ bubbles: true }});
|
const changeEvent = new Event('change', { bubbles: true });
|
||||||
arguments[0].dispatchEvent(changeEvent);
|
arguments[0].dispatchEvent(changeEvent);
|
||||||
""", delete_input)
|
""", delete_input)
|
||||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('account_delete.typed_delete_js', fallback='Typed \"Delete\" using JavaScript')}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('account_delete.typed_delete_js', fallback='Typed \"Delete\" using JavaScript')}{Style.RESET_ALL}")
|
||||||
|
|||||||
284
main.py
284
main.py
@@ -110,18 +110,24 @@ class Translator:
|
|||||||
threadid = user32.GetWindowThreadProcessId(hwnd, 0)
|
threadid = user32.GetWindowThreadProcessId(hwnd, 0)
|
||||||
layout_id = user32.GetKeyboardLayout(threadid) & 0xFFFF
|
layout_id = user32.GetKeyboardLayout(threadid) & 0xFFFF
|
||||||
|
|
||||||
# Map language ID to our language codes
|
# Map language ID to our language codes using match-case
|
||||||
language_map = {
|
match layout_id:
|
||||||
0x0409: 'en', # English
|
case 0x0409:
|
||||||
0x0404: 'zh_tw', # Traditional Chinese
|
return 'en' # English
|
||||||
0x0804: 'zh_cn', # Simplified Chinese
|
case 0x0404:
|
||||||
0x0422: 'vi', # Vietnamese
|
return 'zh_tw' # Traditional Chinese
|
||||||
0x0419: 'ru', # Russian
|
case 0x0804:
|
||||||
0x0415: 'tr', # Turkish
|
return 'zh_cn' # Simplified Chinese
|
||||||
0x0402: 'bg', # Bulgarian
|
case 0x0422:
|
||||||
}
|
return 'vi' # Vietnamese
|
||||||
|
case 0x0419:
|
||||||
return language_map.get(layout_id, 'en')
|
return 'ru' # Russian
|
||||||
|
case 0x0415:
|
||||||
|
return 'tr' # Turkish
|
||||||
|
case 0x0402:
|
||||||
|
return 'bg' # Bulgarian
|
||||||
|
case _:
|
||||||
|
return 'en' # Default to English
|
||||||
except:
|
except:
|
||||||
return self._detect_unix_language()
|
return self._detect_unix_language()
|
||||||
|
|
||||||
@@ -136,53 +142,56 @@ class Translator:
|
|||||||
|
|
||||||
system_locale = system_locale.lower()
|
system_locale = system_locale.lower()
|
||||||
|
|
||||||
# Map locale to our language codes
|
# Map locale to our language codes using match-case
|
||||||
if system_locale.startswith('zh_tw') or system_locale.startswith('zh_hk'):
|
match system_locale:
|
||||||
return 'zh_tw'
|
case s if s.startswith('zh_tw') or s.startswith('zh_hk'):
|
||||||
elif system_locale.startswith('zh_cn'):
|
return 'zh_tw'
|
||||||
return 'zh_cn'
|
case s if s.startswith('zh_cn'):
|
||||||
elif system_locale.startswith('en'):
|
return 'zh_cn'
|
||||||
return 'en'
|
case s if s.startswith('en'):
|
||||||
elif system_locale.startswith('vi'):
|
return 'en'
|
||||||
return 'vi'
|
case s if s.startswith('vi'):
|
||||||
elif system_locale.startswith('nl'):
|
return 'vi'
|
||||||
return 'nl'
|
case s if s.startswith('nl'):
|
||||||
elif system_locale.startswith('de'):
|
return 'nl'
|
||||||
return 'de'
|
case s if s.startswith('de'):
|
||||||
elif system_locale.startswith('fr'):
|
return 'de'
|
||||||
return 'fr'
|
case s if s.startswith('fr'):
|
||||||
elif system_locale.startswith('pt'):
|
return 'fr'
|
||||||
return 'pt'
|
case s if s.startswith('pt'):
|
||||||
elif system_locale.startswith('ru'):
|
return 'pt'
|
||||||
return 'ru'
|
case s if s.startswith('ru'):
|
||||||
elif system_locale.startswith('tr'):
|
return 'ru'
|
||||||
return 'tr'
|
case s if s.startswith('tr'):
|
||||||
elif system_locale.startswith('bg'):
|
return 'tr'
|
||||||
return 'bg'
|
case s if s.startswith('bg'):
|
||||||
# Try to get language from LANG environment variable as fallback
|
return 'bg'
|
||||||
env_lang = os.getenv('LANG', '').lower()
|
case _:
|
||||||
if 'tw' in env_lang or 'hk' in env_lang:
|
# Try to get language from LANG environment variable as fallback
|
||||||
return 'zh_tw'
|
env_lang = os.getenv('LANG', '').lower()
|
||||||
elif 'cn' in env_lang:
|
match env_lang:
|
||||||
return 'zh_cn'
|
case s if 'tw' in s or 'hk' in s:
|
||||||
elif 'vi' in env_lang:
|
return 'zh_tw'
|
||||||
return 'vi'
|
case s if 'cn' in s:
|
||||||
elif 'nl' in env_lang:
|
return 'zh_cn'
|
||||||
return 'nl'
|
case s if 'vi' in s:
|
||||||
elif 'de' in env_lang:
|
return 'vi'
|
||||||
return 'de'
|
case s if 'nl' in s:
|
||||||
elif 'fr' in env_lang:
|
return 'nl'
|
||||||
return 'fr'
|
case s if 'de' in s:
|
||||||
elif 'pt' in env_lang:
|
return 'de'
|
||||||
return 'pt'
|
case s if 'fr' in s:
|
||||||
elif 'ru' in env_lang:
|
return 'fr'
|
||||||
return 'ru'
|
case s if 'pt' in s:
|
||||||
elif 'tr' in env_lang:
|
return 'pt'
|
||||||
return 'tr'
|
case s if 'ru' in s:
|
||||||
elif 'bg' in env_lang:
|
return 'ru'
|
||||||
return 'bg'
|
case s if 'tr' in s:
|
||||||
|
return 'tr'
|
||||||
return 'en'
|
case s if 'bg' in s:
|
||||||
|
return 'bg'
|
||||||
|
case _:
|
||||||
|
return 'en'
|
||||||
except:
|
except:
|
||||||
return 'en'
|
return 'en'
|
||||||
|
|
||||||
@@ -566,87 +575,88 @@ def main():
|
|||||||
choice_num = 17
|
choice_num = 17
|
||||||
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices=f'0-{choice_num}')}: {Style.RESET_ALL}")
|
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices=f'0-{choice_num}')}: {Style.RESET_ALL}")
|
||||||
|
|
||||||
if choice == "0":
|
match choice:
|
||||||
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.exit')}...{Style.RESET_ALL}")
|
case "0":
|
||||||
print(f"{Fore.CYAN}{'═' * 50}{Style.RESET_ALL}")
|
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.exit')}...{Style.RESET_ALL}")
|
||||||
return
|
print(f"{Fore.CYAN}{'═' * 50}{Style.RESET_ALL}")
|
||||||
elif choice == "1":
|
return
|
||||||
import reset_machine_manual
|
case "1":
|
||||||
reset_machine_manual.run(translator)
|
import reset_machine_manual
|
||||||
print_menu()
|
reset_machine_manual.run(translator)
|
||||||
elif choice == "2":
|
print_menu()
|
||||||
import cursor_register
|
case "2":
|
||||||
cursor_register.main(translator)
|
import cursor_register
|
||||||
print_menu()
|
cursor_register.main(translator)
|
||||||
elif choice == "3":
|
print_menu()
|
||||||
import cursor_register_google
|
case "3":
|
||||||
cursor_register_google.main(translator)
|
import cursor_register_google
|
||||||
print_menu()
|
cursor_register_google.main(translator)
|
||||||
elif choice == "4":
|
print_menu()
|
||||||
import cursor_register_github
|
case "4":
|
||||||
cursor_register_github.main(translator)
|
import cursor_register_github
|
||||||
print_menu()
|
cursor_register_github.main(translator)
|
||||||
elif choice == "5":
|
print_menu()
|
||||||
import cursor_register_manual
|
case "5":
|
||||||
cursor_register_manual.main(translator)
|
import cursor_register_manual
|
||||||
print_menu()
|
cursor_register_manual.main(translator)
|
||||||
elif choice == "6":
|
print_menu()
|
||||||
import github_cursor_register
|
case "6":
|
||||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.coming_soon')}{Style.RESET_ALL}")
|
import github_cursor_register
|
||||||
# github_cursor_register.main(translator)
|
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.coming_soon')}{Style.RESET_ALL}")
|
||||||
print_menu()
|
# github_cursor_register.main(translator)
|
||||||
elif choice == "7":
|
print_menu()
|
||||||
import quit_cursor
|
case "7":
|
||||||
quit_cursor.quit_cursor(translator)
|
import quit_cursor
|
||||||
print_menu()
|
quit_cursor.quit_cursor(translator)
|
||||||
elif choice == "8":
|
print_menu()
|
||||||
if select_language():
|
case "8":
|
||||||
|
if select_language():
|
||||||
|
print_menu()
|
||||||
|
continue
|
||||||
|
case "9":
|
||||||
|
import disable_auto_update
|
||||||
|
disable_auto_update.run(translator)
|
||||||
|
print_menu()
|
||||||
|
case "10":
|
||||||
|
import totally_reset_cursor
|
||||||
|
totally_reset_cursor.run(translator)
|
||||||
|
# print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.fixed_soon')}{Style.RESET_ALL}")
|
||||||
|
print_menu()
|
||||||
|
case "11":
|
||||||
|
import logo
|
||||||
|
print(logo.CURSOR_CONTRIBUTORS)
|
||||||
|
print_menu()
|
||||||
|
case "12":
|
||||||
|
from config import print_config
|
||||||
|
print_config(get_config(), translator)
|
||||||
|
print_menu()
|
||||||
|
case "13":
|
||||||
|
from oauth_auth import OAuthHandler
|
||||||
|
oauth = OAuthHandler(translator)
|
||||||
|
oauth._select_profile()
|
||||||
|
print_menu()
|
||||||
|
case "14":
|
||||||
|
import delete_cursor_google
|
||||||
|
delete_cursor_google.main(translator)
|
||||||
|
print_menu()
|
||||||
|
case "15":
|
||||||
|
import bypass_version
|
||||||
|
bypass_version.main(translator)
|
||||||
|
print_menu()
|
||||||
|
case "16":
|
||||||
|
import check_user_authorized
|
||||||
|
check_user_authorized.main(translator)
|
||||||
|
print_menu()
|
||||||
|
case "17":
|
||||||
|
import bypass_token_limit
|
||||||
|
bypass_token_limit.run(translator)
|
||||||
|
print_menu()
|
||||||
|
case _:
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
|
||||||
print_menu()
|
print_menu()
|
||||||
continue
|
|
||||||
elif choice == "9":
|
|
||||||
import disable_auto_update
|
|
||||||
disable_auto_update.run(translator)
|
|
||||||
print_menu()
|
|
||||||
elif choice == "10":
|
|
||||||
import totally_reset_cursor
|
|
||||||
totally_reset_cursor.run(translator)
|
|
||||||
# print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.fixed_soon')}{Style.RESET_ALL}")
|
|
||||||
print_menu()
|
|
||||||
elif choice == "11":
|
|
||||||
import logo
|
|
||||||
print(logo.CURSOR_CONTRIBUTORS)
|
|
||||||
print_menu()
|
|
||||||
elif choice == "12":
|
|
||||||
from config import print_config
|
|
||||||
print_config(get_config(), translator)
|
|
||||||
print_menu()
|
|
||||||
elif choice == "13":
|
|
||||||
from oauth_auth import OAuthHandler
|
|
||||||
oauth = OAuthHandler(translator)
|
|
||||||
oauth._select_profile()
|
|
||||||
print_menu()
|
|
||||||
elif choice == "14":
|
|
||||||
import delete_cursor_google
|
|
||||||
delete_cursor_google.main(translator)
|
|
||||||
print_menu()
|
|
||||||
elif choice == "15":
|
|
||||||
import bypass_version
|
|
||||||
bypass_version.main(translator)
|
|
||||||
print_menu()
|
|
||||||
elif choice == "16":
|
|
||||||
import check_user_authorized
|
|
||||||
check_user_authorized.main(translator)
|
|
||||||
print_menu()
|
|
||||||
elif choice == "17":
|
|
||||||
import bypass_token_limit
|
|
||||||
bypass_token_limit.run(translator)
|
|
||||||
print_menu()
|
|
||||||
else:
|
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
|
|
||||||
print_menu()
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.program_terminated')}{Style.RESET_ALL}")
|
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.program_terminated')}{Style.RESET_ALL}")
|
||||||
print(f"{Fore.CYAN}{'═' * 50}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{'═' * 50}{Style.RESET_ALL}")
|
||||||
return
|
return
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ class NewTempEmail:
|
|||||||
|
|
||||||
if sys.platform == "linux":
|
if sys.platform == "linux":
|
||||||
# Check if DISPLAY is set when not in headless mode
|
# Check if DISPLAY is set when not in headless mode
|
||||||
if not co.arguments.get("--headless=new") and not os.environ.get('DISPLAY'):
|
if "--headless=new" not in co.arguments and not os.environ.get('DISPLAY'):
|
||||||
print(f"{Fore.RED}❌ {self.translator.get('email.no_display_found') if self.translator else 'No display found. Make sure X server is running.'}{Style.RESET_ALL}")
|
print(f"{Fore.RED}❌ {self.translator.get('email.no_display_found') if self.translator else 'No display found. Make sure X server is running.'}{Style.RESET_ALL}")
|
||||||
print(f"{Fore.YELLOW}ℹ️ {self.translator.get('email.try_export_display') if self.translator else 'Try: export DISPLAY=:0'}{Style.RESET_ALL}")
|
print(f"{Fore.YELLOW}ℹ️ {self.translator.get('email.try_export_display') if self.translator else 'Try: export DISPLAY=:0'}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
# oauth_auth.py
|
||||||
import os
|
import os
|
||||||
from colorama import Fore, Style, init
|
from colorama import Fore, Style, init
|
||||||
import time
|
import time
|
||||||
@@ -30,7 +31,7 @@ class OAuthHandler:
|
|||||||
def __init__(self, translator=None, auth_type=None):
|
def __init__(self, translator=None, auth_type=None):
|
||||||
self.translator = translator
|
self.translator = translator
|
||||||
self.config = get_config(translator)
|
self.config = get_config(translator)
|
||||||
self.auth_type = auth_type # make sure the auth_type is not None
|
self.auth_type = auth_type
|
||||||
os.environ['BROWSER_HEADLESS'] = 'False'
|
os.environ['BROWSER_HEADLESS'] = 'False'
|
||||||
self.browser = None
|
self.browser = None
|
||||||
self.selected_profile = None
|
self.selected_profile = None
|
||||||
@@ -176,10 +177,15 @@ class OAuthHandler:
|
|||||||
browser_path = self._get_browser_path()
|
browser_path = self._get_browser_path()
|
||||||
|
|
||||||
if not browser_path:
|
if not browser_path:
|
||||||
raise Exception(f"{self.translator.get('oauth.no_compatible_browser_found') if self.translator else 'No compatible browser found. Please install Google Chrome or Chromium.'}\n{self.translator.get('oauth.supported_browsers', platform=platform_name)}\n" +
|
error_msg = (
|
||||||
"- Windows: Google Chrome, Chromium\n" +
|
f"{self.translator.get('oauth.no_compatible_browser_found') if self.translator else 'No compatible browser found. Please install Google Chrome or Chromium.'}" +
|
||||||
"- macOS: Google Chrome, Chromium\n" +
|
"\n" +
|
||||||
"- Linux: Google Chrome, Chromium, chromium-browser")
|
f"{self.translator.get('oauth.supported_browsers', platform=platform_name)}\n" +
|
||||||
|
"- Windows: Google Chrome, Chromium\n" +
|
||||||
|
"- macOS: Google Chrome, Chromium\n" +
|
||||||
|
"- Linux: Google Chrome, Chromium, google-chrome-stable"
|
||||||
|
)
|
||||||
|
raise Exception(error_msg)
|
||||||
|
|
||||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('oauth.found_browser_data_directory', path=user_data_dir) if self.translator else f'Found browser data directory: {user_data_dir}'}{Style.RESET_ALL}")
|
print(f"{Fore.CYAN}{EMOJI['INFO']} {self.translator.get('oauth.found_browser_data_directory', path=user_data_dir) if self.translator else f'Found browser data directory: {user_data_dir}'}{Style.RESET_ALL}")
|
||||||
|
|
||||||
@@ -239,7 +245,7 @@ class OAuthHandler:
|
|||||||
browser_processes = {
|
browser_processes = {
|
||||||
'chrome': {
|
'chrome': {
|
||||||
'win': ['chrome.exe', 'chromium.exe'],
|
'win': ['chrome.exe', 'chromium.exe'],
|
||||||
'linux': ['chrome', 'chromium', 'chromium-browser'],
|
'linux': ['chrome', 'chromium', 'chromium-browser', 'google-chrome-stable'],
|
||||||
'mac': ['Chrome', 'Chromium']
|
'mac': ['Chrome', 'Chromium']
|
||||||
},
|
},
|
||||||
'brave': {
|
'brave': {
|
||||||
@@ -423,7 +429,12 @@ class OAuthHandler:
|
|||||||
elif browser_type == 'firefox':
|
elif browser_type == 'firefox':
|
||||||
possible_paths = ['/usr/bin/firefox']
|
possible_paths = ['/usr/bin/firefox']
|
||||||
else: # 默认为 Chrome
|
else: # 默认为 Chrome
|
||||||
possible_paths = ['/usr/bin/google-chrome', '/usr/bin/google-chrome-stable', '/usr/bin/chromium', '/usr/bin/chromium-browser']
|
possible_paths = [
|
||||||
|
'/usr/bin/google-chrome-stable', # 优先检查 google-chrome-stable
|
||||||
|
'/usr/bin/google-chrome',
|
||||||
|
'/usr/bin/chromium',
|
||||||
|
'/usr/bin/chromium-browser'
|
||||||
|
]
|
||||||
|
|
||||||
# 检查每个可能的路径
|
# 检查每个可能的路径
|
||||||
for path in possible_paths:
|
for path in possible_paths:
|
||||||
@@ -431,7 +442,7 @@ class OAuthHandler:
|
|||||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('oauth.found_browser_at', path=path) if self.translator else f'Found browser at: {path}'}{Style.RESET_ALL}")
|
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('oauth.found_browser_at', path=path) if self.translator else f'Found browser at: {path}'}{Style.RESET_ALL}")
|
||||||
return path
|
return path
|
||||||
|
|
||||||
# 如果找不到指定浏览器,则尝试使用Chrome
|
# 如果找不到指定浏览器,则尝试使用 Chrome
|
||||||
if browser_type != 'chrome':
|
if browser_type != 'chrome':
|
||||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('oauth.browser_not_found_trying_chrome', browser=browser_type) if self.translator else f'Could not find {browser_type}, trying Chrome instead'}{Style.RESET_ALL}")
|
print(f"{Fore.YELLOW}{EMOJI['WARNING']} {self.translator.get('oauth.browser_not_found_trying_chrome', browser=browser_type) if self.translator else f'Could not find {browser_type}, trying Chrome instead'}{Style.RESET_ALL}")
|
||||||
return self._get_chrome_path()
|
return self._get_chrome_path()
|
||||||
@@ -442,29 +453,6 @@ class OAuthHandler:
|
|||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.error_finding_browser_path', error=str(e)) if self.translator else f'Error finding browser path: {e}'}{Style.RESET_ALL}")
|
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.error_finding_browser_path', error=str(e)) if self.translator else f'Error finding browser path: {e}'}{Style.RESET_ALL}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _get_chrome_path(self):
|
|
||||||
"""Fallback method to get Chrome path"""
|
|
||||||
try:
|
|
||||||
if os.name == 'nt': # Windows
|
|
||||||
possible_paths = [
|
|
||||||
os.path.join(os.environ.get('PROGRAMFILES', ''), 'Google', 'Chrome', 'Application', 'chrome.exe'),
|
|
||||||
os.path.join(os.environ.get('PROGRAMFILES(X86)', ''), 'Google', 'Chrome', 'Application', 'chrome.exe'),
|
|
||||||
os.path.join(os.environ.get('LOCALAPPDATA', ''), 'Google', 'Chrome', 'Application', 'chrome.exe')
|
|
||||||
]
|
|
||||||
elif sys.platform == 'darwin': # macOS
|
|
||||||
possible_paths = ['/Applications/Google Chrome.app/Contents/MacOS/Google Chrome']
|
|
||||||
else: # Linux
|
|
||||||
possible_paths = ['/usr/bin/google-chrome', '/usr/bin/google-chrome-stable', '/usr/bin/chromium', '/usr/bin/chromium-browser']
|
|
||||||
|
|
||||||
for path in possible_paths:
|
|
||||||
if os.path.exists(path):
|
|
||||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {self.translator.get('oauth.found_chrome_at', path=path) if self.translator else f'Found Chrome at: {path}'}{Style.RESET_ALL}")
|
|
||||||
return path
|
|
||||||
return None
|
|
||||||
except Exception as e:
|
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.error_finding_chrome_path', error=str(e)) if self.translator else f'Error finding Chrome path: {e}'}{Style.RESET_ALL}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _configure_browser_options(self, browser_path, user_data_dir, active_profile):
|
def _configure_browser_options(self, browser_path, user_data_dir, active_profile):
|
||||||
"""Configure browser options based on platform"""
|
"""Configure browser options based on platform"""
|
||||||
try:
|
try:
|
||||||
@@ -476,6 +464,7 @@ class OAuthHandler:
|
|||||||
co.set_argument('--no-first-run')
|
co.set_argument('--no-first-run')
|
||||||
co.set_argument('--no-default-browser-check')
|
co.set_argument('--no-default-browser-check')
|
||||||
co.set_argument('--disable-gpu')
|
co.set_argument('--disable-gpu')
|
||||||
|
co.set_argument('--remote-debugging-port=9222') # 明确指定调试端口
|
||||||
|
|
||||||
# Platform-specific options
|
# Platform-specific options
|
||||||
if sys.platform.startswith('linux'):
|
if sys.platform.startswith('linux'):
|
||||||
@@ -958,7 +947,8 @@ class OAuthHandler:
|
|||||||
value = cookie.get("value", "")
|
value = cookie.get("value", "")
|
||||||
token = get_token_from_cookie(value, self.translator)
|
token = get_token_from_cookie(value, self.translator)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {self.translator.get('oauth.token_extraction_error', error=str(e)) if self.translator else f'Token extraction error: {str(e)}'}{Style.RESET_ALL}")
|
error_message = f'Failed to extract auth info: {str(e)}' if not self.translator else self.translator.get('oauth.failed_to_extract_auth_info', error=str(e))
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {error_message}{Style.RESET_ALL}")
|
||||||
elif name == "cursor_email":
|
elif name == "cursor_email":
|
||||||
email = cookie.get("value")
|
email = cookie.get("value")
|
||||||
|
|
||||||
@@ -971,11 +961,13 @@ class OAuthHandler:
|
|||||||
missing.append("email")
|
missing.append("email")
|
||||||
if not token:
|
if not token:
|
||||||
missing.append("token")
|
missing.append("token")
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.missing_authentication_data', data=', '.join(missing)) if self.translator else f'Missing authentication data: {", ".join(missing)}'}{Style.RESET_ALL}")
|
error_message = f"Missing authentication data: {', '.join(missing)}" if not self.translator else self.translator.get('oauth.missing_authentication_data', data=', '.join(missing))
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {error_message}{Style.RESET_ALL}")
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.failed_to_extract_auth_info', error=str(e)) if self.translator else f'Failed to extract auth info: {str(e)}'}{Style.RESET_ALL}")
|
error_message = f'Failed to extract auth info: {str(e)}' if not self.translator else self.translator.get('oauth.failed_to_extract_auth_info', error=str(e))
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {error_message}{Style.RESET_ALL}")
|
||||||
return False, None
|
return False, None
|
||||||
|
|
||||||
def _delete_current_account(self):
|
def _delete_current_account(self):
|
||||||
@@ -1017,7 +1009,8 @@ class OAuthHandler:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"{Fore.RED}{EMOJI['ERROR']} {self.translator.get('oauth.failed_to_delete_account', error=str(e)) if self.translator else f'Failed to delete account: {str(e)}'}{Style.RESET_ALL}")
|
error_message = f'Failed to delete account: {str(e)}' if not self.translator else self.translator.get('oauth.failed_to_delete_account', error=str(e))
|
||||||
|
print(f"{Fore.RED}{EMOJI['ERROR']} {error_message}{Style.RESET_ALL}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def main(auth_type, translator=None):
|
def main(auth_type, translator=None):
|
||||||
|
|||||||
Reference in New Issue
Block a user