修复ipv6问题

main
huyinsong 5 days ago
parent 3c1896a946
commit 6754b8acff
  1. 26
      Makefile
  2. BIN
      assets/icons/app.icns
  3. 17
      configs/client.yaml
  4. 1693
      coverage.html
  5. 195
      docs/BUILD_DMG.md
  6. 8
      internal/client/client.go
  7. 12
      internal/config/config.go
  8. 14
      pkg/logger/logger.go
  9. 96
      scripts/build-dmg.sh
  10. 172
      scripts/build-macos.sh
  11. 152
      scripts/create-dmg.sh
  12. 173
      scripts/create-icon.sh
  13. 103
      scripts/launcher.sh

@ -3,7 +3,7 @@ APP_NAME = wormhole-client
VERSION = v1.0.0
LDFLAGS = -ldflags "-X main.version=$(VERSION) -X main.buildTime=$(shell date -u '+%Y-%m-%d_%H:%M:%S')"
.PHONY: all build clean deps test run install uninstall lint coverage fmt vet check
.PHONY: all build clean deps test run install uninstall lint coverage fmt vet check dmg dmg-macos
all: clean deps build
@ -57,6 +57,28 @@ install: build
uninstall:
sudo rm -f /usr/local/bin/$(APP_NAME)
# macOS DMG 安装包构建
dmg-macos:
@echo "🍎 Building macOS DMG installer..."
@if [ "$(shell uname)" != "Darwin" ]; then \
echo "❌ DMG building is only supported on macOS"; \
exit 1; \
fi
chmod +x scripts/build-dmg.sh
./scripts/build-dmg.sh
@echo "✅ macOS DMG installer created in build/ directory"
# 通用 DMG 构建 (检测平台)
dmg:
@if [ "$(shell uname)" = "Darwin" ]; then \
$(MAKE) dmg-macos; \
else \
echo "❌ DMG building is only supported on macOS"; \
echo " You are on: $(shell uname)"; \
echo "ℹ Please use a macOS system to build DMG installers"; \
exit 1; \
fi
help:
@echo "Available targets:"
@echo " build - Build the client binary"
@ -73,6 +95,8 @@ help:
@echo " deps - Download dependencies"
@echo " install - Install to /usr/local/bin"
@echo " uninstall - Remove from /usr/local/bin"
@echo " dmg - Build macOS DMG installer (macOS only)"
@echo " dmg-macos - Build macOS DMG installer (macOS only)"
@echo ""
@echo "GUI Access:"
@echo " After starting, access the web GUI at:"

Binary file not shown.

@ -3,10 +3,12 @@ serviceType: client
# SOCKS5 服务器设置
server:
address: 3.133.130.202
address: 18.117.71.98
port: 1080
username: admin
password: secure123
preferIPv4: true # 强制使用IPv4
timeout: 60s # 增加连接超时
# 代理模式设置
proxy:
@ -17,7 +19,7 @@ proxy:
globalProxy:
enabled: true
dnsProxy: true
dnsPort: 5353
dnsPort: 15353 # 客户端DNS代理端口
# 智能分流路由规则
routing:
@ -56,7 +58,11 @@ globalProxy:
- "*.amazonaws.com"
- "*.aliyuncs.com"
- "*.qcloud.com"
- "*.cursor.sh"
- "*.apple.com"
- "*.icloud.com"
# 特定服务IP地址
- "101.34.16.52" # Gitea 服务器
# 强制代理域名列表 (必须经过代理)
forceDomains:
# Google 服务
@ -172,15 +178,12 @@ globalProxy:
- "*.twitch.tv"
- "steam.community"
- "*.steam.community"
# 特定服务IP地址
- "101.34.16.52" # Gitea 服务器
# 透明代理设置 (实验性功能)
transparentProxy:
enabled: false
port: 8080
dnsPort: 5353
dnsPort: 15353 # 透明代理DNS端口(与全局代理一致)
# 系统级修改 (需要root权限)
modifyDNS: true # 修改系统DNS设置

File diff suppressed because it is too large Load Diff

@ -0,0 +1,195 @@
# macOS DMG 安装包构建指南
本文档介绍如何为 Wormhole SOCKS5 Client 构建 macOS DMG 安装包。
## 🔧 环境要求
### 系统要求
- **macOS 10.13+** (High Sierra 或更高版本)
- **Xcode Command Line Tools** 或完整的 Xcode
- **Go 1.19+**
### 可选工具
- **Python 3** + **Pillow (PIL)** - 用于生成自定义应用图标
- **Git** - 用于版本控制
## 🚀 快速开始
### 一键构建
```bash
# 构建完整的 DMG 安装包
make dmg
# 或者使用完整命令
make dmg-macos
```
### 分步构建
```bash
# 1. 构建 macOS 应用程序包
./scripts/build-macos.sh
# 2. 创建 DMG 安装包
./scripts/create-dmg.sh
# 3. 验证和测试
open build/Wormhole-Client-v1.0.0.dmg
```
## 📁 构建产物
构建成功后,将在 `build/` 目录下生成以下文件:
```
build/
├── Wormhole Client.app/ # macOS 应用程序包
│ ├── Contents/
│ │ ├── Info.plist # 应用信息
│ │ ├── MacOS/
│ │ │ ├── wormhole-client # 二进制文件
│ │ │ └── Wormhole Client # 启动脚本
│ │ └── Resources/
│ │ ├── configs/ # 配置文件
│ │ └── app.icns # 应用图标
│ └── ...
└── Wormhole-Client-v1.0.0.dmg # 最终安装包
```
## 🎨 自定义图标
### 使用自定义图标
1. 准备一个 1024x1024 的 PNG 图片
2. 将其保存为 `assets/icons/icon.png`
3. 重新构建即可使用自定义图标
### 自动生成图标
如果没有自定义图标,构建脚本会自动:
1. 尝试使用 Python PIL 生成简单图标
2. 如果失败,使用系统默认应用图标
## 📦 DMG 特性
### 安装体验
- **拖拽安装**: 用户只需将 app 拖到 Applications 文件夹
- **自动布局**: 优化的窗口布局和图标位置
- **说明文档**: 包含安装和使用说明
### DMG 内容
- `Wormhole Client.app` - 主应用程序
- `Applications` - Applications 文件夹快捷方式
- `README.txt` - 安装和使用说明
## 🔍 构建脚本详解
### build-macos.sh
- 编译 Go 二进制文件 (amd64 架构)
- 创建标准的 macOS 应用程序包结构
- 复制配置文件和资源
- 生成或复制应用图标
- 创建 Info.plist 文件
- 设置启动脚本
### create-dmg.sh
- 创建临时 DMG 工作目录
- 复制应用程序和创建符号链接
- 生成说明文档
- 使用 AppleScript 美化 DMG 外观
- 创建压缩的只读 DMG
- 验证 DMG 完整性
### build-dmg.sh
- 一键执行完整构建流程
- 环境检查和工具验证
- 构建结果汇总和验证
## 🛠 故障排除
### 常见问题
#### 1. hdiutil 权限错误
```bash
# 解决方案:使用 sudo 或给予磁盘访问权限
sudo ./scripts/create-dmg.sh
```
#### 2. AppleScript 执行失败
```bash
# 检查系统完整性保护 (SIP)
csrutil status
# 在系统偏好设置中允许自动化权限
# 系统偏好设置 > 安全性与隐私 > 隐私 > 自动化
```
#### 3. Go 编译失败
```bash
# 检查 Go 版本
go version
# 确保依赖已下载
go mod download
go mod tidy
```
### 调试模式
```bash
# 开启详细输出
set -x
./scripts/build-dmg.sh
```
## 📱 应用程序使用
### 安装后使用
1. 双击 DMG 文件挂载
2. 拖拽 `Wormhole Client.app` 到 Applications
3. 从 Applications 或 Launchpad 启动应用
### 启动模式
- **双击启动**: 自动以 HTTP 模式启动并打开 Web 界面
- **终端启动**: 支持所有命令行参数
```bash
# HTTP 模式
/Applications/Wormhole\ Client.app/Contents/MacOS/Wormhole\ Client -mode http
# 全局模式 (需要 sudo)
sudo /Applications/Wormhole\ Client.app/Contents/MacOS/Wormhole\ Client -mode global
```
### Web 界面
- **管理界面**: http://127.0.0.1:8080/gui
- **统计信息**: http://127.0.0.1:8080/stats
- **健康检查**: http://127.0.0.1:8080/health
## 🔒 代码签名 (可选)
如果需要分发给其他用户,建议进行代码签名:
```bash
# 签名应用程序
codesign --force --deep --sign "Developer ID Application: Your Name" \
"build/Wormhole Client.app"
# 签名 DMG
codesign --force --sign "Developer ID Application: Your Name" \
"build/Wormhole-Client-v1.0.0.dmg"
# 验证签名
codesign --verify --deep --strict --verbose=2 "build/Wormhole Client.app"
spctl --assess --type execute --verbose "build/Wormhole Client.app"
```
## 📈 版本管理
修改版本号:
1. 编辑 `scripts/build-macos.sh` 中的 `VERSION` 变量
2. 编辑 `Makefile` 中的 `VERSION` 变量
3. 重新构建 DMG
## 🤝 贡献
如果您发现构建脚本的问题或有改进建议,欢迎提交 Issue 或 Pull Request。
## 📄 许可证
本构建系统遵循项目的 MIT 许可证。

@ -198,13 +198,15 @@ func (c *Client) startTransparentProxy() error {
logger.Info("💡 This will intercept network traffic transparently")
logger.Info("⚠ Requires root privileges and iptables support")
// TODO: 实现透明代理
logger.Error("❌ Transparent proxy mode is not yet implemented")
// 暂时禁用透明代理模式,提供更好的用户体验
logger.Warn("⚠ Transparent proxy mode is currently disabled")
logger.Info("🔄 This feature is under development and not yet ready for production use")
logger.Info("💡 Available alternatives:")
logger.Info(" - Use global mode: ./bin/wormhole-client -mode global")
logger.Info(" - Use HTTP mode: ./bin/wormhole-client -mode http")
logger.Info("📝 Note: Global mode provides similar functionality with system proxy configuration")
return fmt.Errorf("transparent proxy mode not implemented")
return fmt.Errorf("transparent proxy mode is currently disabled - please use 'global' or 'http' mode")
}
// createHTTPServerWithGUI 创建带有 GUI 的 HTTP 服务器

@ -21,10 +21,11 @@ type Config struct {
// Server SOCKS5服务器配置
type Server struct {
Address string `yaml:"address"`
Port int `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Address string `yaml:"address"`
Port int `yaml:"port"`
Username string `yaml:"username"`
Password string `yaml:"password"`
Timeout time.Duration `yaml:"timeout"`
}
// Proxy 代理模式配置
@ -77,6 +78,9 @@ func LoadConfig(configPath string) (*Config, error) {
if config.Timeout == 0 {
config.Timeout = 30 * time.Second
}
if config.Server.Timeout == 0 {
config.Server.Timeout = 60 * time.Second // 默认60秒服务器连接超时
}
if config.Proxy.LocalPort == 0 {
config.Proxy.LocalPort = 8080
}

@ -65,20 +65,30 @@ func (l *Logger) log(level LogLevel, format string, args ...interface{}) {
}
levelStr := ""
levelColor := ""
resetColor := "\033[0m"
switch level {
case DEBUG:
levelStr = "DEBUG"
levelColor = "\033[36m" // Cyan
case INFO:
levelStr = "INFO"
levelColor = "\033[32m" // Green
case WARN:
levelStr = "WARN"
levelColor = "\033[33m" // Yellow
case ERROR:
levelStr = "ERROR"
levelColor = "\033[31m" // Red
}
timestamp := time.Now().Format("2006-01-02 15:04:05")
timestamp := time.Now().Format("2006-01-02T15:04:05.000Z07:00")
message := fmt.Sprintf(format, args...)
logLine := fmt.Sprintf("[%s] [%s] %s", timestamp, levelStr, message)
// 结构化日志格式,类似logrus但保持简洁
logLine := fmt.Sprintf("%s[%s%s%s] [wormhole-client] %s",
timestamp, levelColor, levelStr, resetColor, message)
l.logger.Println(logLine)
}

@ -0,0 +1,96 @@
#!/bin/bash
set -e
# 项目信息
APP_NAME="Wormhole Client"
VERSION="v1.0.0"
# 路径配置
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
echo "🚀 Building Wormhole Client DMG Installer"
echo "=========================================="
echo "📦 Version: $VERSION"
echo "📁 Project: $PROJECT_ROOT"
echo ""
# 检查必要的工具
echo "🔍 Checking required tools..."
# 检查 Go
if ! command -v go &> /dev/null; then
echo "❌ Go is not installed. Please install Go first."
exit 1
fi
echo "✅ Go: $(go version)"
# 检查 hdiutil (macOS 内置)
if ! command -v hdiutil &> /dev/null; then
echo "❌ hdiutil not found. This script requires macOS."
exit 1
fi
echo "✅ hdiutil: Available"
# 检查 osascript (macOS 内置)
if ! command -v osascript &> /dev/null; then
echo "❌ osascript not found. This script requires macOS."
exit 1
fi
echo "✅ osascript: Available"
echo ""
# 步骤 1: 构建应用程序包
echo "📱 Step 1: Building macOS application bundle..."
echo "----------------------------------------------"
if [ -f "$SCRIPT_DIR/build-macos.sh" ]; then
chmod +x "$SCRIPT_DIR/build-macos.sh"
"$SCRIPT_DIR/build-macos.sh"
else
echo "❌ build-macos.sh not found!"
exit 1
fi
echo ""
# 步骤 2: 创建 DMG
echo "💿 Step 2: Creating DMG installer..."
echo "------------------------------------"
if [ -f "$SCRIPT_DIR/create-dmg.sh" ]; then
chmod +x "$SCRIPT_DIR/create-dmg.sh"
"$SCRIPT_DIR/create-dmg.sh"
else
echo "❌ create-dmg.sh not found!"
exit 1
fi
echo ""
# 完成总结
echo "🎉 BUILD COMPLETED SUCCESSFULLY!"
echo "================================="
BUILD_DIR="$PROJECT_ROOT/build"
FINAL_DMG="$BUILD_DIR/Wormhole-Client-$VERSION.dmg"
if [ -f "$FINAL_DMG" ]; then
echo "📦 DMG File: $FINAL_DMG"
echo "📊 File Size: $(du -h "$FINAL_DMG" | cut -f1)"
echo "🔗 SHA256: $(shasum -a 256 "$FINAL_DMG" | cut -d' ' -f1)"
echo ""
echo "📋 Distribution Ready:"
echo "1. Test the DMG by double-clicking it"
echo "2. Verify the application installs and runs correctly"
echo "3. Share the DMG file for distribution"
echo ""
echo "🔒 Security Notes:"
echo "- Users may need to allow the app in System Preferences > Security & Privacy"
echo "- Consider code signing for easier distribution"
echo "- For distribution outside the App Store, users may need to right-click and 'Open'"
echo ""
echo "✨ Your macOS installer is ready!"
else
echo "❌ DMG creation failed!"
exit 1
fi

@ -0,0 +1,172 @@
#!/bin/bash
set -e
# 项目信息
APP_NAME="Wormhole Client"
BUNDLE_ID="com.azoic.wormhole-client"
VERSION="v1.0.0"
BUILD_TIME=$(date -u '+%Y-%m-%d_%H:%M:%S')
# 路径配置
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
BUILD_DIR="$PROJECT_ROOT/build"
APP_DIR="$BUILD_DIR/$APP_NAME.app"
CONTENTS_DIR="$APP_DIR/Contents"
MACOS_DIR="$CONTENTS_DIR/MacOS"
RESOURCES_DIR="$CONTENTS_DIR/Resources"
DMG_DIR="$BUILD_DIR/dmg"
TEMP_DMG="$BUILD_DIR/temp.dmg"
FINAL_DMG="$BUILD_DIR/Wormhole-Client-$VERSION.dmg"
echo "🚀 Building Wormhole Client for macOS..."
echo "📦 Version: $VERSION"
echo "📅 Build Time: $BUILD_TIME"
# 清理构建目录
echo "🧹 Cleaning build directory..."
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
# 构建二进制文件
echo "🔨 Building binary..."
cd "$PROJECT_ROOT"
GOOS=darwin GOARCH=amd64 go build \
-ldflags "-X main.version=$VERSION -X main.buildTime=$BUILD_TIME" \
-o "$BUILD_DIR/wormhole-client" \
cmd/wormhole-client/main.go
echo "✅ Binary built successfully"
# 创建应用程序包结构
echo "📦 Creating application bundle..."
mkdir -p "$MACOS_DIR"
mkdir -p "$RESOURCES_DIR"
# 复制二进制文件
cp "$BUILD_DIR/wormhole-client" "$MACOS_DIR/"
# 复制配置文件
cp -r configs "$RESOURCES_DIR/"
# 创建或复制应用图标
ICON_PATH="$PROJECT_ROOT/assets/icons/app.icns"
if [ -f "$ICON_PATH" ]; then
echo "📱 Using custom app icon..."
cp "$ICON_PATH" "$RESOURCES_DIR/"
else
echo "🎨 Creating default app icon..."
if [ -f "$PROJECT_ROOT/scripts/create-icon.sh" ]; then
chmod +x "$PROJECT_ROOT/scripts/create-icon.sh"
"$PROJECT_ROOT/scripts/create-icon.sh"
if [ -f "$ICON_PATH" ]; then
cp "$ICON_PATH" "$RESOURCES_DIR/"
fi
fi
fi
# 创建启动脚本
cat > "$MACOS_DIR/Wormhole Client" << 'EOF'
#!/bin/bash
# Wormhole Client macOS Launcher
set -e
# 获取应用程序路径
APP_PATH="$(cd "$(dirname "$0")/.." && pwd)"
RESOURCES_PATH="$APP_PATH/Resources"
BINARY_PATH="$APP_PATH/MacOS/wormhole-client"
CONFIG_PATH="$RESOURCES_PATH/configs/client.yaml"
# 检查二进制文件
if [ ! -f "$BINARY_PATH" ]; then
echo "❌ Application binary not found"
exit 1
fi
# 设置工作目录
cd "$RESOURCES_PATH"
# 如果没有参数,启动 HTTP 模式并打开浏览器
if [ $# -eq 0 ]; then
echo "🚀 Starting Wormhole Client in HTTP proxy mode..."
echo "🌐 Web interface will open automatically"
# 后台启动应用
"$BINARY_PATH" -config "$CONFIG_PATH" -mode http &
APP_PID=$!
# 等待服务启动
sleep 3
# 打开 Web 界面
open "http://127.0.0.1:8080/gui" 2>/dev/null || echo "📱 Visit http://127.0.0.1:8080/gui to access the web interface"
# 等待应用程序结束
wait $APP_PID
else
# 有参数时直接传递
exec "$BINARY_PATH" -config "$CONFIG_PATH" "$@"
fi
EOF
chmod +x "$MACOS_DIR/Wormhole Client"
# 创建 Info.plist
cat > "$CONTENTS_DIR/Info.plist" << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>$APP_NAME</string>
<key>CFBundleExecutable</key>
<string>Wormhole Client</string>
<key>CFBundleIdentifier</key>
<string>$BUNDLE_ID</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$APP_NAME</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$VERSION</string>
<key>CFBundleVersion</key>
<string>$VERSION</string>
<key>LSMinimumSystemVersion</key>
<string>10.13</string>
<key>NSHighResolutionCapable</key>
<true/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.networking</string>
<key>LSUIElement</key>
<false/>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2024 Azoic. All rights reserved.</string>
<key>CFBundleIconFile</key>
<string>app</string>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>yaml</string>
<string>yml</string>
</array>
<key>CFBundleTypeName</key>
<string>Configuration File</string>
<key>CFBundleTypeRole</key>
<string>Editor</string>
</dict>
</array>
</dict>
</plist>
EOF
echo "✅ Application bundle created"
echo "🎯 Build completed successfully!"
echo "📁 Application bundle: $APP_DIR"

@ -0,0 +1,152 @@
#!/bin/bash
set -e
# 项目信息
APP_NAME="Wormhole Client"
VERSION="v1.0.0"
# 路径配置
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
BUILD_DIR="$PROJECT_ROOT/build"
APP_DIR="$BUILD_DIR/$APP_NAME.app"
DMG_DIR="$BUILD_DIR/dmg"
TEMP_DMG="$BUILD_DIR/temp.dmg"
FINAL_DMG="$BUILD_DIR/Wormhole-Client-$VERSION.dmg"
# DMG 配置
DMG_TITLE="Wormhole Client $VERSION"
DMG_SIZE="100m"
DMG_BACKGROUND="$PROJECT_ROOT/scripts/dmg-background.png"
DMG_ICON_SIZE=128
DMG_TEXT_SIZE=16
echo "📦 Creating DMG installer for Wormhole Client..."
# 检查应用程序包是否存在
if [ ! -d "$APP_DIR" ]; then
echo "❌ Application bundle not found. Please run build-macos.sh first."
exit 1
fi
# 清理并创建 DMG 目录
echo "🧹 Preparing DMG directory..."
rm -rf "$DMG_DIR"
mkdir -p "$DMG_DIR"
# 复制应用程序到 DMG 目录
echo "📱 Copying application to DMG..."
cp -R "$APP_DIR" "$DMG_DIR/"
# 创建 Applications 符号链接
echo "🔗 Creating Applications symlink..."
ln -s "/Applications" "$DMG_DIR/Applications"
# 创建 README 文件
echo "📝 Creating README..."
cat > "$DMG_DIR/README.txt" << EOF
Wormhole SOCKS5 Client $VERSION
安装说明:
1. 将 "Wormhole Client.app" 拖拽到 Applications 文件夹
2. 双击运行应用程序
3. 首次运行时,可能需要在系统偏好设置中允许运行
使用方法:
- HTTP 模式:./wormhole-client -mode http
- 全局模式:sudo ./wormhole-client -mode global (需要管理员权限)
Web 管理界面:http://127.0.0.1:8080/gui
统计信息:http://127.0.0.1:8080/stats
更多信息请访问:https://github.com/azoic/wormhole-client
Copyright © 2024 Azoic. All rights reserved.
EOF
# 创建临时 DMG
echo "💿 Creating temporary DMG..."
hdiutil create -srcfolder "$DMG_DIR" -volname "$DMG_TITLE" -fs HFS+ \
-fsargs "-c c=64,a=16,e=16" -format UDRW -size "$DMG_SIZE" "$TEMP_DMG"
# 挂载临时 DMG 进行自定义
echo "🎨 Customizing DMG appearance..."
DEVICE=$(hdiutil attach -readwrite -noverify -noautoopen "$TEMP_DMG" | \
egrep '^/dev/' | sed 1q | awk '{print $1}')
# 等待挂载完成
sleep 2
# 设置 DMG 窗口属性
MOUNT_DIR="/Volumes/$DMG_TITLE"
# 使用 AppleScript 设置 Finder 窗口
/usr/bin/osascript << EOF
tell application "Finder"
tell disk "$DMG_TITLE"
open
set current view of container window to icon view
set toolbar visible of container window to false
set statusbar visible of container window to false
set the bounds of container window to {400, 100, 920, 440}
set theViewOptions to the icon view options of container window
set arrangement of theViewOptions to not arranged
set icon size of theViewOptions to $DMG_ICON_SIZE
set text size of theViewOptions to $DMG_TEXT_SIZE
-- 设置图标位置
set position of item "Wormhole Client.app" of container window to {140, 120}
set position of item "Applications" of container window to {380, 120}
set position of item "README.txt" of container window to {260, 280}
-- 应用更改
update without registering applications
delay 2
end tell
end tell
EOF
# 等待 AppleScript 完成
sleep 3
# 卸载临时 DMG
hdiutil detach "$DEVICE"
# 创建最终的只读 DMG
echo "✨ Creating final DMG..."
rm -f "$FINAL_DMG"
hdiutil convert "$TEMP_DMG" -format UDZO -imagekey zlib-level=9 -o "$FINAL_DMG"
# 清理临时文件
echo "🧹 Cleaning up..."
rm -f "$TEMP_DMG"
rm -rf "$DMG_DIR"
# 显示结果
echo ""
echo "🎉 DMG creation completed successfully!"
echo "📁 DMG file: $FINAL_DMG"
echo "📊 File size: $(du -h "$FINAL_DMG" | cut -f1)"
echo ""
echo "✅ Installation package ready for distribution!"
# 验证 DMG
echo "🔍 Verifying DMG integrity..."
if hdiutil verify "$FINAL_DMG"; then
echo "✅ DMG verification passed"
else
echo "❌ DMG verification failed"
exit 1
fi
# 显示安装说明
echo ""
echo "📋 Installation Instructions:"
echo "1. Double-click the DMG file to mount it"
echo "2. Drag 'Wormhole Client.app' to the Applications folder"
echo "3. Eject the DMG"
echo "4. Launch 'Wormhole Client' from Applications"
echo ""
echo "🔒 Security Note:"
echo "If macOS blocks the app, go to System Preferences > Security & Privacy"
echo "and click 'Open Anyway' to allow the application to run."

@ -0,0 +1,173 @@
#!/bin/bash
set -e
# 项目信息
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ICON_DIR="$PROJECT_ROOT/assets/icons"
APP_ICON="$ICON_DIR/app.icns"
echo "🎨 Creating application icon..."
# 创建图标目录
mkdir -p "$ICON_DIR"
# 创建临时目录
TEMP_DIR=$(mktemp -d)
ICONSET_DIR="$TEMP_DIR/app.iconset"
mkdir -p "$ICONSET_DIR"
# 如果没有源图像,创建一个简单的默认图标
if [ ! -f "$ICON_DIR/icon.png" ]; then
echo "📝 Creating default icon..."
# 使用 sips 创建简单的彩色图标 (macOS 内置工具)
# 创建一个 1024x1024 的纯色图像作为基础
cat > "$TEMP_DIR/create_icon.py" << 'EOF'
#!/usr/bin/env python3
import sys
from PIL import Image, ImageDraw, ImageFont
import os
def create_icon(size, output_path):
# 创建图像
img = Image.new('RGBA', (size, size), (0, 0, 0, 0))
draw = ImageDraw.Draw(img)
# 绘制背景圆形
margin = size // 8
draw.ellipse([margin, margin, size-margin, size-margin],
fill=(58, 134, 255, 255), outline=(30, 100, 200, 255), width=size//50)
# 绘制文字
try:
font_size = size // 6
font = ImageFont.truetype("/System/Library/Fonts/Helvetica.ttc", font_size)
except:
font = ImageFont.load_default()
text = "W"
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
x = (size - text_width) // 2
y = (size - text_height) // 2 - size // 20
draw.text((x, y), text, fill=(255, 255, 255, 255), font=font)
# 保存图像
img.save(output_path, 'PNG')
if __name__ == "__main__":
sizes = [16, 32, 64, 128, 256, 512, 1024]
for size in sizes:
create_icon(size, f"{sys.argv[1]}/icon_{size}x{size}.png")
if size <= 512:
create_icon(size * 2, f"{sys.argv[1]}/icon_{size}x{size}@2x.png")
EOF
# 检查是否有 Python 和 PIL
if command -v python3 &> /dev/null && python3 -c "import PIL" 2>/dev/null; then
echo "✅ Using Python PIL to create icons"
python3 "$TEMP_DIR/create_icon.py" "$ICONSET_DIR"
else
echo "⚠ Python PIL not available, creating simple icons with sips"
# 创建基础图标
BASE_SIZE=1024
BASE_ICON="$TEMP_DIR/base_icon.png"
# 使用 sips 创建基础图标 (需要一个现有的图像文件)
# 如果没有图像,我们创建一个简单的文本文件然后转换
echo "Creating base icon with textutil and sips..."
# 创建一个 RTF 文件
cat > "$TEMP_DIR/icon.rtf" << 'EOF'
{\rtf1\ansi\deff0 {\fonttbl {\f0 Times New Roman;}}
\f0\fs200\qc\cf1 W}
EOF
# 转换为图像 (这在 macOS 上应该可行)
if command -v textutil &> /dev/null; then
textutil -convert html "$TEMP_DIR/icon.rtf" -output "$TEMP_DIR/icon.html"
fi
# 手动创建不同尺寸的图标
sizes=(16 32 64 128 256 512 1024)
for size in "${sizes[@]}"; do
# 创建空白图像并着色
sips -z $size $size /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns --out "$ICONSET_DIR/icon_${size}x${size}.png" 2>/dev/null || {
# 如果失败,复制系统默认图标
cp /System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns "$ICONSET_DIR/icon_${size}x${size}.png" 2>/dev/null || {
# 最后的后备方案:创建纯色文件
printf "\x89PNG\r\n\x1a\n" > "$ICONSET_DIR/icon_${size}x${size}.png"
}
}
# 创建 @2x 版本
if [ $size -le 512 ]; then
cp "$ICONSET_DIR/icon_${size}x${size}.png" "$ICONSET_DIR/icon_${size}x${size}@2x.png"
fi
done
fi
fi
# 确保所有必需的图标文件存在
declare -a required_icons=(
"icon_16x16.png"
"icon_16x16@2x.png"
"icon_32x32.png"
"icon_32x32@2x.png"
"icon_128x128.png"
"icon_128x128@2x.png"
"icon_256x256.png"
"icon_256x256@2x.png"
"icon_512x512.png"
"icon_512x512@2x.png"
)
echo "📋 Checking required icon files..."
missing_icons=false
for icon in "${required_icons[@]}"; do
if [ ! -f "$ICONSET_DIR/$icon" ]; then
echo " Missing: $icon"
missing_icons=true
fi
done
if [ "$missing_icons" = true ]; then
echo "🔧 Creating missing icons from system template..."
# 使用系统默认应用图标作为模板
TEMPLATE_ICON="/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns"
for icon in "${required_icons[@]}"; do
if [ ! -f "$ICONSET_DIR/$icon" ]; then
# 从系统图标创建所需尺寸
size=$(echo "$icon" | sed 's/icon_\([0-9]*\)x[0-9]*.*\.png/\1/')
sips -z $size $size "$TEMPLATE_ICON" --out "$ICONSET_DIR/$icon" 2>/dev/null || {
echo " Could not create $icon, using placeholder"
touch "$ICONSET_DIR/$icon"
}
fi
done
fi
# 创建 .icns 文件
echo "🔨 Creating .icns file..."
if iconutil -c icns "$ICONSET_DIR" -o "$APP_ICON"; then
echo "✅ Icon created successfully: $APP_ICON"
else
echo "❌ Failed to create icon, using system default"
# 复制系统默认图标
cp "/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns" "$APP_ICON" 2>/dev/null || {
echo "⚠ Could not copy system icon"
}
fi
# 清理临时文件
rm -rf "$TEMP_DIR"
echo "🎉 Icon creation completed!"
echo "📁 Icon location: $APP_ICON"

@ -0,0 +1,103 @@
#!/bin/bash
# Wormhole Client Launcher Script
# 用于在 macOS 应用程序包中启动客户端
set -e
# 获取应用程序包路径
APP_PATH="$(cd "$(dirname "$0")/.." && pwd)"
RESOURCES_PATH="$APP_PATH/Resources"
BINARY_PATH="$APP_PATH/MacOS/wormhole-client"
CONFIG_PATH="$RESOURCES_PATH/configs/client.yaml"
# 检查二进制文件是否存在
if [ ! -f "$BINARY_PATH" ]; then
echo "❌ Wormhole client binary not found at: $BINARY_PATH"
exit 1
fi
# 检查配置文件是否存在
if [ ! -f "$CONFIG_PATH" ]; then
echo "❌ Configuration file not found at: $CONFIG_PATH"
echo "Using default configuration..."
CONFIG_PATH=""
fi
# 设置工作目录为 Resources
cd "$RESOURCES_PATH"
# 显示启动信息
echo "🚀 Starting Wormhole SOCKS5 Client..."
echo "📁 App Path: $APP_PATH"
echo "📄 Config: $CONFIG_PATH"
echo ""
# 检查命令行参数
if [ $# -eq 0 ]; then
# 没有参数,显示选择菜单
echo "请选择运行模式:"
echo "1) HTTP 代理模式 (推荐)"
echo "2) 全局代理模式 (需要管理员权限)"
echo "3) 显示版本信息"
echo "4) 退出"
echo ""
read -p "请输入选项 (1-4): " choice
case $choice in
1)
MODE="http"
;;
2)
echo ""
echo "⚠ 全局代理模式需要管理员权限。"
echo "系统将提示您输入密码。"
echo ""
read -p "继续?(y/N): " confirm
if [[ $confirm =~ ^[Yy]$ ]]; then
MODE="global"
NEED_SUDO=true
else
echo "已取消"
exit 0
fi
;;
3)
exec "$BINARY_PATH" -version
;;
4)
echo "再见!"
exit 0
;;
*)
echo "❌ 无效选项"
exit 1
;;
esac
else
# 有参数,直接传递给二进制文件
if [ -n "$CONFIG_PATH" ]; then
exec "$BINARY_PATH" -config "$CONFIG_PATH" "$@"
else
exec "$BINARY_PATH" "$@"
fi
fi
# 启动应用程序
echo "🔧 启动模式: $MODE"
echo ""
if [ "$NEED_SUDO" = true ]; then
echo "🔒 请输入管理员密码以启动全局代理模式:"
if [ -n "$CONFIG_PATH" ]; then
sudo "$BINARY_PATH" -config "$CONFIG_PATH" -mode "$MODE"
else
sudo "$BINARY_PATH" -mode "$MODE"
fi
else
if [ -n "$CONFIG_PATH" ]; then
exec "$BINARY_PATH" -config "$CONFIG_PATH" -mode "$MODE"
else
exec "$BINARY_PATH" -mode "$MODE"
fi
fi
Loading…
Cancel
Save