mirror of
https://github.com/yanue/V2rayU.git
synced 2025-06-27 05:30:09 +00:00
fix import vmess
This commit is contained in:
parent
3fa1f07e87
commit
bf86f1dfe3
19
README.md
19
README.md
@ -1,7 +1,7 @@
|
||||
# V2rayU
|
||||

|
||||
|
||||
V2rayU 是一款v2ray mac客户端,用于科学上网,使用swift4.2编写,基于v2ray项目,支持vmess,shadowsocks,socks5等服务协议(推荐搭建**v2ray服务**,可伪装成正常网站,防封锁), 支持二维码,剪贴板导入,手动配置,二维码分享等
|
||||
V2rayU 是一款v2ray mac客户端,用于科学上网,使用swift4.2编写,基于v2ray项目,支持vmess,shadowsocks,socks5等服务协议(推荐搭建**v2ray服务**,可伪装成正常网站,防封锁), 支持二维码,剪贴板导入,手动配置,二维码分享等, 项目地址: https://github.com/yanue/V2rayU
|
||||
|
||||
### 主要特性
|
||||
----
|
||||
@ -12,6 +12,7 @@ V2rayU 是一款v2ray mac客户端,用于科学上网,使用swift4.2编写,基
|
||||
- **分享二维码**: 支持v2ray及shadowsocks协议格式分享
|
||||
- **主动更新**: 支持主动更新到最新版
|
||||
- **全局模式**: 支持全局代理(有别于vpn,只是将代理信息更新到系统代理http,https,socks)
|
||||
- **支持4.0**: 支持手动切换到v2ray-core 4.0以上配置格式
|
||||
|
||||
### v2ray简介
|
||||
V2Ray 是 Project V 下的一个工具。Project V 包含一系列工具,帮助你打造专属的定制网络体系。而 V2Ray 属于最核心的一个。
|
||||
@ -45,9 +46,23 @@ v2ray模板: [https://github.com/KiriKira/vTemplate](https://github.com/KiriKira
|
||||
全局模式: 有别于vpn,只是将代理信息更新到系统代理http,https,socks,若需要真正全局模式, 推荐搭配使用Proxifier
|
||||
rules模式: 浏览器推荐搭配使用Proxy SwitchyOmega
|
||||
|
||||
### 相关文件
|
||||
v2ray-core文件: /Applications/V2rayU.app/Contents/Resources/v2ray-core
|
||||
v2ray-core启动: ~/Library/LaunchAgents/yanue.v2rayu.v2ray-core.plist
|
||||
v2ray-core日志: ~/Library/Logs/V2rayU.log
|
||||
当前启动服务配置: /Applications/V2rayU.app/Contents/Resources/config.json
|
||||
其他服务配置信息: ~/Library/Preferences/net.yanue.V2rayU.plist
|
||||
|
||||
如果启动无反应可以尝试从命令行手动启动,查看原因
|
||||
```
|
||||
cd /Applications/V2rayU.app/Contents/Resources/
|
||||
./v2ray-core/v2ray -config ./config.json
|
||||
```
|
||||
|
||||
### 软件使用问题
|
||||
1. 安装包显示文件已损坏的解决方案: sudo spctl --master-disable
|
||||
2. 有其他问题请提issue
|
||||
2. 如果启动后代理无效,请查看日志,入口: 菜单 -> Show logs...
|
||||
3. 有其他问题请提issue
|
||||
|
||||
### 感谢
|
||||
参考: ShadowsocksX-NG V2RayX
|
||||
|
@ -27,7 +27,7 @@
|
||||
<key>V2rayULauncher.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>14</integer>
|
||||
<integer>13</integer>
|
||||
</dict>
|
||||
<key>V2rayUTests.test.xcscheme</key>
|
||||
<dict>
|
||||
@ -37,28 +37,28 @@
|
||||
<key>V2rayUTests.testDecodeUrl.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false />
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>3</integer>
|
||||
</dict>
|
||||
<key>V2rayUTests.testDecodeVmess.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false />
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>4</integer>
|
||||
</dict>
|
||||
<key>V2rayUTests.testInbound.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false />
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
<key>V2rayUTests.testOutbound.xcscheme</key>
|
||||
<dict>
|
||||
<key>isShown</key>
|
||||
<false />
|
||||
<false/>
|
||||
<key>orderHint</key>
|
||||
<integer>12</integer>
|
||||
</dict>
|
||||
|
@ -2,54 +2,4 @@
|
||||
<Bucket
|
||||
type = "0"
|
||||
version = "2.0">
|
||||
<Breakpoints>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "V2rayUTests/V2rayUTests.swift"
|
||||
timestampString = "565078535.951556"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "32"
|
||||
endingLineNumber = "32"
|
||||
landmarkName = "testInbound()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "V2rayUTests/V2rayUTests.swift"
|
||||
timestampString = "565078535.951628"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "37"
|
||||
endingLineNumber = "37"
|
||||
landmarkName = "testInbound()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
<BreakpointProxy
|
||||
BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
|
||||
<BreakpointContent
|
||||
shouldBeEnabled = "Yes"
|
||||
ignoreCount = "0"
|
||||
continueAfterRunningActions = "No"
|
||||
filePath = "V2rayUTests/V2rayUTests.swift"
|
||||
timestampString = "565078535.951683"
|
||||
startingColumnNumber = "9223372036854775807"
|
||||
endingColumnNumber = "9223372036854775807"
|
||||
startingLineNumber = "27"
|
||||
endingLineNumber = "27"
|
||||
landmarkName = "testInbound()"
|
||||
landmarkType = "7">
|
||||
</BreakpointContent>
|
||||
</BreakpointProxy>
|
||||
</Breakpoints>
|
||||
</Bucket>
|
||||
|
@ -34,7 +34,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.9.9</string>
|
||||
<string>1.0.0</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
<string>public.app-category.utilities</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
|
@ -52,7 +52,6 @@ class ShareUri {
|
||||
}
|
||||
|
||||
if v2ray.serverProtocol == V2rayProtocolOutbound.shadowsocks.rawValue {
|
||||
print("share shadowsocks")
|
||||
self.genShadowsocksUri()
|
||||
return
|
||||
}
|
||||
@ -391,6 +390,7 @@ class VmessUri {
|
||||
let base64End = urlStr.firstIndex(of: "?")
|
||||
let encodedStr = String(urlStr[base64Begin..<(base64End ?? urlStr.endIndex)])
|
||||
guard let decodeStr = encodedStr.base64Decoded() else {
|
||||
self.error = "decode vmess error"
|
||||
return
|
||||
}
|
||||
|
||||
@ -433,7 +433,7 @@ class ShadowsockUri {
|
||||
// ss://bf-cfb:test@192.168.100.1:8888#remark
|
||||
func encode() -> String {
|
||||
let base64 = self.method + ":" + self.password + "@" + self.host + ":" + String(self.port)
|
||||
var ss = base64.base64Encoded()
|
||||
let ss = base64.base64Encoded()
|
||||
if ss != nil {
|
||||
return "ss://" + ss! + "#" + self.remark
|
||||
}
|
||||
@ -506,11 +506,12 @@ class ShadowsockUri {
|
||||
let encodedStr = String(urlStr[base64Begin..<(base64End ?? urlStr.endIndex)])
|
||||
|
||||
guard let data = Data(base64Encoded: self.padBase64(string: encodedStr)) else {
|
||||
self.error = "decode ss error"
|
||||
return (url.absoluteString, nil)
|
||||
}
|
||||
|
||||
guard let decoded = String(data: data, encoding: String.Encoding.utf8) else {
|
||||
print("decode error")
|
||||
self.error = "decode ss error"
|
||||
return (nil, nil)
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ extension String {
|
||||
Int.init($0) ?? 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//: ### Base64 encoding a string
|
||||
func base64Encoded() -> String? {
|
||||
if let data = self.data(using: .utf8) {
|
||||
@ -78,11 +78,16 @@ extension String {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
//: ### Base64 decoding a string
|
||||
func base64Decoded() -> String? {
|
||||
if let data = Data(base64Encoded: self) {
|
||||
return String(data: data, encoding: .utf8)
|
||||
if let _ = self.range(of: ":")?.lowerBound {
|
||||
return self
|
||||
}
|
||||
let base64String = self.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
|
||||
let padding = base64String.count + (base64String.count % 4 != 0 ? (4 - base64String.count % 4) : 0)
|
||||
if let decodedData = Data(base64Encoded: base64String.padding(toLength: padding, withPad: "=", startingAt: 0), options: NSData.Base64DecodingOptions(rawValue: 0)), let decodedString = NSString(data: decodedData, encoding: String.Encoding.utf8.rawValue) {
|
||||
return decodedString as String
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -397,13 +397,13 @@ class V2rayConfig: NSObject {
|
||||
switch self.streamNetwork {
|
||||
case V2rayStreamSettings.network.h2.rawValue:
|
||||
if self.streamH2.host.count > 0 {
|
||||
if self.streamH2.host[0].count == 0 {
|
||||
self.error = "missing streamSettings.httpSettings.host";
|
||||
return
|
||||
}
|
||||
// if self.streamH2.host[0].count == 0 {
|
||||
// self.error = "missing streamSettings.httpSettings.host";
|
||||
// return
|
||||
// }
|
||||
} else {
|
||||
self.error = "missing streamSettings.httpSettings.host";
|
||||
return
|
||||
// self.error = "missing streamSettings.httpSettings.host";
|
||||
// return
|
||||
}
|
||||
if self.streamH2.path.count == 0 {
|
||||
self.error = "missing streamSettings.httpSettings.path";
|
||||
|
@ -19,6 +19,14 @@ class V2rayUTests: XCTestCase {
|
||||
// override func tearDown() {
|
||||
// // Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
// }
|
||||
|
||||
func testImportVmess() {
|
||||
let url = "vmess://eyJhZGQiOiJhLnYycmF5LndvcmxkIiwiYWRkZGF0ZSI6bnVsbCwiYWlkIjoiNjQiLCJjb3VudHJ5IjpudWxsLCJkYXRhIjpudWxsLCJlcnJvcmNvdW50IjpudWxsLCJob3N0IjoiIiwiaWQiOiJjNzYwYTkzYi1iNjUyLTQ0YTAtOTdkOC0yNGI3YTg4OWM5MmMiLCJtX3N0YXRpb25fY25fbXMiOm51bGwsIm1fc3RhdGlvbl9jbl9zdGF0dXMiOm51bGwsIm1zIjpudWxsLCJuZXQiOiJoMiIsInBhdGgiOiIvZmdxIiwicG9ydCI6NDQzLCJwcyI6IlNTUlNIQVJFLkNPTSIsInN0YXR1cyI6bnVsbCwidGxzIjoidGxzIiwidHlwZSI6Im5vbmUiLCJ2IjoiMiJ9"
|
||||
let importUri = ImportUri()
|
||||
importUri.importVmessUri(uri: url)
|
||||
print("vmess1", importUri.error, importUri.json)
|
||||
}
|
||||
|
||||
|
||||
func testInbound() {
|
||||
var inbound = V2rayInbound()
|
||||
|
Loading…
x
Reference in New Issue
Block a user