forked from xiaokangwang/AndroidLibV2ray
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathqrscan.go
124 lines (114 loc) · 2.82 KB
/
qrscan.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package libv2ray
import (
"fmt"
"io/ioutil"
"path/filepath"
"strings"
vlencoding "github.com/xiaokangwang/AndroidLibV2Ray/V2RayConfigureFileUtil/encoding"
"github.com/xiaokangwang/AndroidLibV2Ray/libV2RayAuxiliaryURL"
)
var CurrentScan *QRScanContext
type QRScanContext struct {
ec *vlencoding.Encoder
qd *vlencoding.QRDecoder
ScanReporter QRScanReport
vctx *V2RayContext
surpressFinish bool
legencyScanned bool
legencyScannedExt string
legencyScannedCtx []byte
}
func (qs *QRScanContext) OnNewScanResult(data string, allowdiscard bool) string {
if qs.qd == nil {
qs.qd = qs.ec.StartQRDecode()
qs.surpressFinish = false
}
//First try if it is a legacy schema
ok, ext, fb := libV2RayAuxiliaryURL.TryRender(data)
fmt.Println(qs.surpressFinish)
if ok && fb != nil {
//Decode ready
qs.legencyScanned = true
qs.legencyScannedExt = ext
qs.legencyScannedCtx = fb
if !qs.surpressFinish {
qs.surpressFinish = true
qs.ScanReporter.ReadyToFinish()
}
return "Legacy Scanned"
}
res := qs.ec.V2RayURLToByte(data)
if res == nil {
return "Unknown schema"
}
err := qs.qd.OnNewDataScanned(res)
if err != nil {
if strings.Contains(err.Error(), "inconsistent") && allowdiscard || true {
qs.qd = nil
qs.OnNewScanResult(data, allowdiscard)
} else {
return err.Error() + "\n[Tap to discard previous segment]"
}
}
if qs.qd.IsDecodeReady() && !qs.surpressFinish {
qs.surpressFinish = true
qs.ScanReporter.ReadyToFinish()
} else {
qs.ScanReporter.StatUpdate(qs.qd.PieceNeeded, qs.qd.PieceReceived)
}
return "Scanned"
}
func (qs *QRScanContext) Init() {
qs.ec = &vlencoding.Encoder{}
CurrentScan = qs
}
type QRScanReport interface {
ReadyToFinish()
StatUpdate(need, acquired int)
}
func (qs *QRScanContext) Finish(name string) bool {
//do we just scanned a legency schema
if qs.legencyScanned {
fdr := filepath.Dir(qs.vctx.GetConfigureFile())
err := ioutil.WriteFile(fmt.Sprintf("%v/%v%v", fdr, name, qs.legencyScannedExt), qs.legencyScannedCtx, 0600)
if err != nil {
fmt.Println(err)
return false
}
qs.legencyScanned = false
qs.Discard()
}
if !qs.qd.IsDecodeReady() {
fmt.Println("Called decoder when decode not ready")
return false
}
dec, err := qs.qd.Finish()
if err != nil {
fmt.Println(err)
return false
}
qs.qd = nil
suf, towrite, err := qs.ec.UnpackV2RayConfB(dec)
if err != nil {
fmt.Println(err)
return false
}
fdr := filepath.Dir(qs.vctx.GetConfigureFile())
err = ioutil.WriteFile(fmt.Sprintf("%v/%v%v", fdr, name, suf), towrite, 0600)
if err != nil {
fmt.Println(err)
return false
}
return true
}
func (qs *QRScanContext) Discard() {
qs.qd = nil
}
func (vc *V2RayContext) ScanQR() *QRScanContext {
if CurrentScan != nil {
return CurrentScan
}
ret := &QRScanContext{vctx: vc}
ret.Init()
return ret
}