mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-04-14 11:35:50 +00:00
Merge d9f3a030f8 into 169b216d7e
This commit is contained in:
commit
1db8e85dd7
2 changed files with 75 additions and 0 deletions
|
|
@ -34,6 +34,8 @@ import (
|
|||
"github.com/shirou/gopsutil/v4/load"
|
||||
"github.com/shirou/gopsutil/v4/mem"
|
||||
"github.com/shirou/gopsutil/v4/net"
|
||||
"github.com/xtls/xray-core/app/router"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// ProcessState represents the current state of a system process.
|
||||
|
|
@ -1055,6 +1057,48 @@ func (s *ServerService) IsValidGeofileName(filename string) bool {
|
|||
return matched
|
||||
}
|
||||
|
||||
// NormalizeGeositeCountryCodes reads a geosite .dat file, uppercases all
|
||||
// country_code fields, and writes it back. This works around a case-sensitivity
|
||||
// mismatch in Xray-core: the router normalizes codes to uppercase before lookup,
|
||||
// but the find() function compares bytes case-sensitively. Some geosite.dat
|
||||
// providers (e.g. Loyalsoldier) store codes in lowercase, causing lookup failures.
|
||||
func NormalizeGeositeCountryCodes(path string) error {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read geosite file %s: %w", path, err)
|
||||
}
|
||||
|
||||
var list router.GeoSiteList
|
||||
if err := proto.Unmarshal(data, &list); err != nil {
|
||||
return fmt.Errorf("failed to parse geosite file %s: %w", path, err)
|
||||
}
|
||||
|
||||
changed := false
|
||||
for _, entry := range list.Entry {
|
||||
upper := strings.ToUpper(entry.CountryCode)
|
||||
if entry.CountryCode != upper {
|
||||
entry.CountryCode = upper
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
if !changed {
|
||||
return nil
|
||||
}
|
||||
|
||||
normalized, err := proto.Marshal(&list)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to serialize normalized geosite file %s: %w", path, err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(path, normalized, 0644); err != nil {
|
||||
return fmt.Errorf("failed to write normalized geosite file %s: %w", path, err)
|
||||
}
|
||||
|
||||
logger.Infof("Normalized country codes to uppercase in %s (%d entries)", path, len(list.Entry))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ServerService) UpdateGeofile(fileName string) error {
|
||||
type geofileEntry struct {
|
||||
URL string
|
||||
|
|
@ -1146,12 +1190,22 @@ func (s *ServerService) UpdateGeofile(fileName string) error {
|
|||
|
||||
var errorMessages []string
|
||||
|
||||
normalizeIfGeosite := func(destPath, name string) {
|
||||
if strings.Contains(name, "geosite") {
|
||||
if err := NormalizeGeositeCountryCodes(destPath); err != nil {
|
||||
logger.Warningf("Failed to normalize geosite country codes in %s: %v", name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if fileName == "" {
|
||||
// Download all geofiles
|
||||
for _, entry := range geofileAllowlist {
|
||||
destPath := filepath.Join(config.GetBinFolderPath(), entry.FileName)
|
||||
if err := downloadFile(entry.URL, destPath); err != nil {
|
||||
errorMessages = append(errorMessages, fmt.Sprintf("Error downloading Geofile '%s': %v", entry.FileName, err))
|
||||
} else {
|
||||
normalizeIfGeosite(destPath, entry.FileName)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1159,6 +1213,8 @@ func (s *ServerService) UpdateGeofile(fileName string) error {
|
|||
destPath := filepath.Join(config.GetBinFolderPath(), entry.FileName)
|
||||
if err := downloadFile(entry.URL, destPath); err != nil {
|
||||
errorMessages = append(errorMessages, fmt.Sprintf("Error downloading Geofile '%s': %v", entry.FileName, err))
|
||||
} else {
|
||||
normalizeIfGeosite(destPath, entry.FileName)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
19
web/web.go
19
web/web.go
|
|
@ -12,6 +12,7 @@ import (
|
|||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
|
@ -292,9 +293,27 @@ func (s *Server) initRouter() (*gin.Engine, error) {
|
|||
return engine, nil
|
||||
}
|
||||
|
||||
// normalizeExistingGeositeFiles normalizes country codes in all geosite .dat
|
||||
// files found in the bin directory so Xray-core can locate entries correctly.
|
||||
func normalizeExistingGeositeFiles() {
|
||||
binDir := config.GetBinFolderPath()
|
||||
matches, err := filepath.Glob(filepath.Join(binDir, "geosite*.dat"))
|
||||
if err != nil {
|
||||
logger.Warningf("Failed to glob geosite files: %v", err)
|
||||
return
|
||||
}
|
||||
for _, path := range matches {
|
||||
if err := service.NormalizeGeositeCountryCodes(path); err != nil {
|
||||
logger.Warningf("Failed to normalize geosite country codes in %s: %v", path, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// startTask schedules background jobs (Xray checks, traffic jobs, cron
|
||||
// jobs) which the panel relies on for periodic maintenance and monitoring.
|
||||
func (s *Server) startTask() {
|
||||
normalizeExistingGeositeFiles()
|
||||
|
||||
err := s.xrayService.RestartXray(true)
|
||||
if err != nil {
|
||||
logger.Warning("start xray failed:", err)
|
||||
|
|
|
|||
Loading…
Reference in a new issue