@@ -23,39 +23,63 @@ export class ProxyParser {
23
23
24
24
class ShadowsocksParser {
25
25
parse ( url ) {
26
- let parts = url . replace ( 'ss://' , '' ) . split ( '#' ) ;
27
- let mainPart = parts [ 0 ] ;
28
- let tag = parts [ 1 ] ;
29
- if ( tag . includes ( '%' ) ) {
30
- tag = decodeURIComponent ( tag ) ;
31
- }
32
-
33
- let [ base64 , serverPart ] = mainPart . split ( '@' ) ;
34
- let decodedParts = decodeBase64 ( base64 ) . split ( ':' ) ;
35
- let method = decodedParts [ 0 ] ;
36
- let password = decodedParts . slice ( 1 ) . join ( ':' ) ;
37
-
38
- // Match IPv6 address
39
- let match = serverPart . match ( / \[ ( [ ^ \] ] + ) \] : ( \d + ) / ) ;
40
- let server , server_port ;
41
-
42
- if ( match ) {
43
- server = match [ 1 ] ;
44
- server_port = match [ 2 ] ;
45
- } else {
46
- [ server , server_port ] = serverPart . split ( ':' ) ;
47
- }
48
-
49
- return {
50
- "tag" : tag ,
51
- "type" : 'shadowsocks' ,
52
- "server" : server ,
53
- "server_port" : parseInt ( server_port ) ,
54
- "method" : method ,
55
- "password" : password ,
56
- "network" : 'tcp' ,
57
- "tcp_fast_open" : false
58
- }
26
+ let parts = url . replace ( 'ss://' , '' ) . split ( '#' ) ;
27
+ let mainPart = parts [ 0 ] ;
28
+ let tag = parts [ 1 ] ;
29
+ if ( tag && tag . includes ( '%' ) ) {
30
+ tag = decodeURIComponent ( tag ) ;
31
+ }
32
+
33
+ // Try new format first
34
+ try {
35
+ let [ base64 , serverPart ] = mainPart . split ( '@' ) ;
36
+ // If no @ symbol found, try legacy format
37
+ if ( ! serverPart ) {
38
+ // Decode the entire mainPart for legacy format
39
+ let decodedLegacy = decodeBase64 ( mainPart ) ;
40
+ // Legacy format: method:password@server :port
41
+ let [ methodAndPass , serverInfo ] = decodedLegacy . split ( '@' ) ;
42
+ let [ method , password ] = methodAndPass . split ( ':' ) ;
43
+ let [ server , server_port ] = this . parseServer ( serverInfo ) ;
44
+
45
+ return this . createConfig ( tag , server , server_port , method , password ) ;
46
+ }
47
+
48
+ // Continue with new format parsing
49
+ let decodedParts = decodeBase64 ( base64 ) . split ( ':' ) ;
50
+ let method = decodedParts [ 0 ] ;
51
+ let password = decodedParts . slice ( 1 ) . join ( ':' ) ;
52
+ let [ server , server_port ] = this . parseServer ( serverPart ) ;
53
+
54
+ return this . createConfig ( tag , server , server_port , method , password ) ;
55
+ } catch ( e ) {
56
+ console . error ( 'Failed to parse shadowsocks URL:' , e ) ;
57
+ return null ;
58
+ }
59
+ }
60
+
61
+ // Helper method to parse server info
62
+ parseServer ( serverPart ) {
63
+ // Match IPv6 address
64
+ let match = serverPart . match ( / \[ ( [ ^ \] ] + ) \] : ( \d + ) / ) ;
65
+ if ( match ) {
66
+ return [ match [ 1 ] , match [ 2 ] ] ;
67
+ }
68
+ return serverPart . split ( ':' ) ;
69
+ }
70
+
71
+ // Helper method to create config object
72
+ createConfig ( tag , server , server_port , method , password ) {
73
+ return {
74
+ "tag" : tag || "Shadowsocks" ,
75
+ "type" : 'shadowsocks' ,
76
+ "server" : server ,
77
+ "server_port" : parseInt ( server_port ) ,
78
+ "method" : method ,
79
+ "password" : password ,
80
+ "network" : 'tcp' ,
81
+ "tcp_fast_open" : false
82
+ } ;
59
83
}
60
84
}
61
85
0 commit comments