Import x-panel source
This commit is contained in:
28
util/common/err.go
Normal file
28
util/common/err.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"x-ui/logger"
|
||||
)
|
||||
|
||||
func NewErrorf(format string, a ...any) error {
|
||||
msg := fmt.Sprintf(format, a...)
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
func NewError(a ...any) error {
|
||||
msg := fmt.Sprintln(a...)
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
func Recover(msg string) any {
|
||||
panicErr := recover()
|
||||
if panicErr != nil {
|
||||
if msg != "" {
|
||||
logger.Error(msg, "panic:", panicErr)
|
||||
}
|
||||
}
|
||||
return panicErr
|
||||
}
|
||||
17
util/common/format.go
Normal file
17
util/common/format.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func FormatTraffic(trafficBytes int64) string {
|
||||
units := []string{"B", "KB", "MB", "GB", "TB", "PB"}
|
||||
unitIndex := 0
|
||||
size := float64(trafficBytes)
|
||||
|
||||
for size >= 1024 && unitIndex < len(units)-1 {
|
||||
size /= 1024
|
||||
unitIndex++
|
||||
}
|
||||
return fmt.Sprintf("%.2f%s", size, units[unitIndex])
|
||||
}
|
||||
30
util/common/multi_error.go
Normal file
30
util/common/multi_error.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type multiError []error
|
||||
|
||||
func (e multiError) Error() string {
|
||||
var r strings.Builder
|
||||
r.WriteString("multierr: ")
|
||||
for _, err := range e {
|
||||
r.WriteString(err.Error())
|
||||
r.WriteString(" | ")
|
||||
}
|
||||
return r.String()
|
||||
}
|
||||
|
||||
func Combine(maybeError ...error) error {
|
||||
var errs multiError
|
||||
for _, err := range maybeError {
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
}
|
||||
if len(errs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return errs
|
||||
}
|
||||
18
util/common/random.go
Normal file
18
util/common/random.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// RandomInt 返回一个 0 .. max-1 之间的随机整数(使用 crypto/rand)
|
||||
func RandomInt(max int) int {
|
||||
if max <= 0 {
|
||||
return 0
|
||||
}
|
||||
n, err := rand.Int(rand.Reader, big.NewInt(int64(max)))
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return int(n.Int64())
|
||||
}
|
||||
15
util/crypto/crypto.go
Normal file
15
util/crypto/crypto.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func HashPasswordAsBcrypt(password string) (string, error) {
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
return string(hash), err
|
||||
}
|
||||
|
||||
func CheckPasswordHash(hash, password string) bool {
|
||||
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||
return err == nil
|
||||
}
|
||||
24
util/json_util/json.go
Normal file
24
util/json_util/json.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package json_util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
)
|
||||
|
||||
type RawMessage []byte
|
||||
|
||||
// MarshalJSON: Customize json.RawMessage default behavior
|
||||
func (m RawMessage) MarshalJSON() ([]byte, error) {
|
||||
if len(m) == 0 {
|
||||
return []byte("null"), nil
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON: sets *m to a copy of data.
|
||||
func (m *RawMessage) UnmarshalJSON(data []byte) error {
|
||||
if m == nil {
|
||||
return errors.New("json.RawMessage: UnmarshalJSON on nil pointer")
|
||||
}
|
||||
*m = append((*m)[0:0], data...)
|
||||
return nil
|
||||
}
|
||||
46
util/random/random.go
Normal file
46
util/random/random.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package random
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
var (
|
||||
numSeq [10]rune
|
||||
lowerSeq [26]rune
|
||||
upperSeq [26]rune
|
||||
numLowerSeq [36]rune
|
||||
numUpperSeq [36]rune
|
||||
allSeq [62]rune
|
||||
)
|
||||
|
||||
func init() {
|
||||
for i := 0; i < 10; i++ {
|
||||
numSeq[i] = rune('0' + i)
|
||||
}
|
||||
for i := 0; i < 26; i++ {
|
||||
lowerSeq[i] = rune('a' + i)
|
||||
upperSeq[i] = rune('A' + i)
|
||||
}
|
||||
|
||||
copy(numLowerSeq[:], numSeq[:])
|
||||
copy(numLowerSeq[len(numSeq):], lowerSeq[:])
|
||||
|
||||
copy(numUpperSeq[:], numSeq[:])
|
||||
copy(numUpperSeq[len(numSeq):], upperSeq[:])
|
||||
|
||||
copy(allSeq[:], numSeq[:])
|
||||
copy(allSeq[len(numSeq):], lowerSeq[:])
|
||||
copy(allSeq[len(numSeq)+len(lowerSeq):], upperSeq[:])
|
||||
}
|
||||
|
||||
func Seq(n int) string {
|
||||
runes := make([]rune, n)
|
||||
for i := 0; i < n; i++ {
|
||||
runes[i] = allSeq[rand.Intn(len(allSeq))]
|
||||
}
|
||||
return string(runes)
|
||||
}
|
||||
|
||||
func Num(n int) int {
|
||||
return rand.Intn(n)
|
||||
}
|
||||
21
util/reflect_util/reflect.go
Normal file
21
util/reflect_util/reflect.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package reflect_util
|
||||
|
||||
import "reflect"
|
||||
|
||||
func GetFields(t reflect.Type) []reflect.StructField {
|
||||
num := t.NumField()
|
||||
fields := make([]reflect.StructField, 0, num)
|
||||
for i := 0; i < num; i++ {
|
||||
fields = append(fields, t.Field(i))
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func GetFieldValues(v reflect.Value) []reflect.Value {
|
||||
num := v.NumField()
|
||||
fields := make([]reflect.Value, 0, num)
|
||||
for i := 0; i < num; i++ {
|
||||
fields = append(fields, v.Field(i))
|
||||
}
|
||||
return fields
|
||||
}
|
||||
8
util/sys/psutil.go
Normal file
8
util/sys/psutil.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
_ "unsafe"
|
||||
)
|
||||
|
||||
//go:linkname HostProc github.com/shirou/gopsutil/v4/internal/common.HostProc
|
||||
func HostProc(combineWith ...string) string
|
||||
24
util/sys/sys_darwin.go
Normal file
24
util/sys/sys_darwin.go
Normal file
@@ -0,0 +1,24 @@
|
||||
//go:build darwin
|
||||
// +build darwin
|
||||
|
||||
package sys
|
||||
|
||||
import (
|
||||
"github.com/shirou/gopsutil/v4/net"
|
||||
)
|
||||
|
||||
func GetTCPCount() (int, error) {
|
||||
stats, err := net.Connections("tcp")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(stats), nil
|
||||
}
|
||||
|
||||
func GetUDPCount() (int, error) {
|
||||
stats, err := net.Connections("udp")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(stats), nil
|
||||
}
|
||||
81
util/sys/sys_linux.go
Normal file
81
util/sys/sys_linux.go
Normal file
@@ -0,0 +1,81 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package sys
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func getLinesNum(filename string) (int, error) {
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
sum := 0
|
||||
buf := make([]byte, 8192)
|
||||
for {
|
||||
n, err := file.Read(buf)
|
||||
|
||||
var buffPosition int
|
||||
for {
|
||||
i := bytes.IndexByte(buf[buffPosition:n], '\n')
|
||||
if i < 0 {
|
||||
break
|
||||
}
|
||||
buffPosition += i + 1
|
||||
sum++
|
||||
}
|
||||
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return sum, nil
|
||||
}
|
||||
|
||||
func GetTCPCount() (int, error) {
|
||||
root := HostProc()
|
||||
|
||||
tcp4, err := safeGetLinesNum(fmt.Sprintf("%v/net/tcp", root))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
tcp6, err := safeGetLinesNum(fmt.Sprintf("%v/net/tcp6", root))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return tcp4 + tcp6, nil
|
||||
}
|
||||
|
||||
func GetUDPCount() (int, error) {
|
||||
root := HostProc()
|
||||
|
||||
udp4, err := safeGetLinesNum(fmt.Sprintf("%v/net/udp", root))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
udp6, err := safeGetLinesNum(fmt.Sprintf("%v/net/udp6", root))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return udp4 + udp6, nil
|
||||
}
|
||||
|
||||
func safeGetLinesNum(path string) (int, error) {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
return 0, nil
|
||||
} else if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return getLinesNum(path)
|
||||
}
|
||||
30
util/sys/sys_windows.go
Normal file
30
util/sys/sys_windows.go
Normal file
@@ -0,0 +1,30 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package sys
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/shirou/gopsutil/v4/net"
|
||||
)
|
||||
|
||||
func GetConnectionCount(proto string) (int, error) {
|
||||
if proto != "tcp" && proto != "udp" {
|
||||
return 0, errors.New("invalid protocol")
|
||||
}
|
||||
|
||||
stats, err := net.Connections(proto)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return len(stats), nil
|
||||
}
|
||||
|
||||
func GetTCPCount() (int, error) {
|
||||
return GetConnectionCount("tcp")
|
||||
}
|
||||
|
||||
func GetUDPCount() (int, error) {
|
||||
return GetConnectionCount("udp")
|
||||
}
|
||||
Reference in New Issue
Block a user