MCPcopy Create free account
hub / github.com/SamNet-dev/snix / jsonProxyPatcher

Function jsonProxyPatcher

integrate/integrate.go:81–129  ·  view source on GitHub ↗
(path string)

Source from the content-addressed store, hash-verified

79}
80
81func jsonProxyPatcher(path string) func(string, uint16) error {
82 return func(origHost string, origPort uint16) error {
83 raw, err := os.ReadFile(path)
84 if err != nil {
85 return err
86 }
87 var doc map[string]any
88 if err := json.Unmarshal(raw, &doc); err != nil {
89 return fmt.Errorf("unparseable JSON: %w", err)
90 }
91
92 // Xray / v2ray outbounds live under .outbounds[].settings.vnext[] for
93 // VLESS/VMess, or .outbounds[].settings.servers[] for Trojan/Shadowsocks.
94 outbounds, ok := doc["outbounds"].([]any)
95 if !ok || len(outbounds) == 0 {
96 return errors.New("no outbounds array found")
97 }
98 patched := false
99 for _, ob := range outbounds {
100 obm, ok := ob.(map[string]any)
101 if !ok {
102 continue
103 }
104 settings, _ := obm["settings"].(map[string]any)
105 if settings == nil {
106 continue
107 }
108 if patchVNext(settings, origHost, origPort) || patchServers(settings, origHost, origPort) {
109 patched = true
110 }
111 }
112 if !patched {
113 return errors.New("no VLESS/VMess/Trojan outbound with an address field found")
114 }
115
116 // Backup using the same bytes we parsed — safer than re-reading
117 // (avoids a TOCTOU where the file changed between read and backup).
118 if err := os.WriteFile(path+".bak", raw, 0o644); err != nil {
119 return fmt.Errorf("backup: %w", err)
120 }
121
122 // Write new.
123 updated, err := json.MarshalIndent(doc, "", " ")
124 if err != nil {
125 return err
126 }
127 return os.WriteFile(path, updated, 0o644)
128 }
129}
130
131// patchVNext rewrites the first vnext[].address/port it finds. Returns true if changed.
132func patchVNext(settings map[string]any, origHost string, origPort uint16) bool {

Calls 2

patchVNextFunction · 0.85
patchServersFunction · 0.85