修正 1.4.10源码无法编译

This commit is contained in:
gdy666 2023-08-23 22:14:42 +08:00
parent dda03b2a87
commit ef9f820560
29 changed files with 789 additions and 1523 deletions

View File

@ -1,6 +1,8 @@
# Lucky(大吉)
## 注意源码公布到1.4.10版本后续暂无继续开源计划
## 如果您是第一次使用Lucky请务必先访问 https://lucky666.cn 并仔细阅读相关的文档以获得必要的信息和答案。在这些文档中您可以了解到Lucky的基本功能和特性掌握Lucky的使用方法以及解决常见的问题和疑惑。

View File

@ -6,19 +6,11 @@ import (
"fmt"
"log"
"net"
"os"
"runtime"
"strings"
"sync"
ddnsconf "github.com/gdy666/lucky/module/ddns/conf"
portforwardconf "github.com/gdy666/lucky/module/portforward/conf"
"github.com/gdy666/lucky/module/portforward/socketproxy"
reverseproxyconf "github.com/gdy666/lucky/module/reverseproxy/conf"
safeconf "github.com/gdy666/lucky/module/safe/conf"
sslconf "github.com/gdy666/lucky/module/sslcertficate/conf"
wolconf "github.com/gdy666/lucky/module/wol/conf"
"github.com/gdy666/lucky/socketproxy"
"github.com/gdy666/lucky/thirdlib/gdylib/fileutils"
"github.com/gdy666/lucky/thirdlib/gdylib/stringsp"
)
@ -62,27 +54,23 @@ type BaseConfigure struct {
AllowInternetaccess bool `json:"AllowInternetaccess"` //允许外网访问
//GlobalMaxConnections int64 `json:"GlobalMaxConnections"` //全局最大连接数
LogMaxSize int `json:"LogMaxSize"` //日志记录最大条数
HttpClientSecureVerify bool `json:"HttpClientSecureVerify"`
HttpClientTimeout int `json:"HttpClientTimeout"`
}
type ProgramConfigure struct {
BaseConfigure BaseConfigure `json:"BaseConfigure"`
WhiteListConfigure safeconf.WhiteListConfigure `json:"WhiteListConfigure"`
BlackListConfigure safeconf.BlackListConfigure `json:"BlackListConfigure"`
DDNSConfigure ddnsconf.DDNSConfigure `json:"DDNSConfigure"` //DDNS 参数设置
DDNSTaskList []ddnsconf.DDNSTask `json:"DDNSTaskList"` //DDNS任务列表
ReverseProxyRuleList []reverseproxyconf.ReverseProxyRule `json:"ReverseProxyRuleList"` //反向代理规则列表
SSLCertficateList []sslconf.SSLCertficate `json:"SSLCertficateList"` //SSL证书列表
PortForwardsRuleList []portforwardconf.PortForwardsRule `json:"PortForwardsRuleList"` //端口转发规则列表
PortForwardsConfigure portforwardconf.PortForwardsConfigure `json:"PortForwardsConfigure"` //端口转发设置
WOLDeviceList []wolconf.WOLDevice `json:"WOLDeviceList"` //网络唤醒设备列表
WOLServiceConfigure wolconf.WOLServiceConfigure `json:"WOLServiceConfigure"` //网络唤醒客户端设置
WhiteListConfigure WhiteListConfigure `json:"WhiteListConfigure"`
BlackListConfigure BlackListConfigure `json:"BlackListConfigure"`
DDNSConfigure DDNSConfigure `json:"DDNSConfigure"` //DDNS 参数设置
DDNSTaskList []DDNSTask `json:"DDNSTaskList"` //DDNS任务列表
ReverseProxyRuleList []ReverseProxyRule `json:"ReverseProxyRuleList"` //反向代理规则列表
SSLCertficateList []SSLCertficate `json:"SSLCertficateList"` //SSL证书列表
PortForwardsRuleList []PortForwardsRule `json:"PortForwardsRuleList"` //端口转发规则列表
PortForwardsConfigure PortForwardsConfigure `json:"PortForwardsConfigure"` //端口转发设置
WOLDeviceList []WOLDevice `json:"WOLDeviceList"` //网络唤醒设备列表
}
var ConfigureMutex sync.RWMutex
var Configure *ProgramConfigure
var programConfigureMutex sync.RWMutex
var programConfigure *ProgramConfigure
var configurePath string
// var readConfigureFileOnce sync.Once
@ -94,10 +82,10 @@ var configureFileSign int8 = -1
// }
func GetAuthAccount() map[string]string {
ConfigureMutex.RLock()
defer ConfigureMutex.RUnlock()
programConfigureMutex.RLock()
defer programConfigureMutex.RUnlock()
accountInfo := make(map[string]string)
accountInfo[Configure.BaseConfigure.AdminAccount] = Configure.BaseConfigure.AdminPassword
accountInfo[programConfigure.BaseConfigure.AdminAccount] = programConfigure.BaseConfigure.AdminPassword
return accountInfo
}
@ -110,27 +98,27 @@ func SetRunMode(mode string) {
}
func SetConfig(p *ProgramConfigure) error {
ConfigureMutex.Lock()
defer ConfigureMutex.Unlock()
Configure = p
programConfigureMutex.Lock()
defer programConfigureMutex.Unlock()
programConfigure = p
return Save()
}
func GetConfig() *ProgramConfigure {
ConfigureMutex.RLock()
defer ConfigureMutex.RUnlock()
conf := *Configure
programConfigureMutex.RLock()
defer programConfigureMutex.RUnlock()
conf := *programConfigure
return &conf
}
func GetConfigureBytes() []byte {
ConfigureMutex.RLock()
defer ConfigureMutex.RUnlock()
if Configure == nil {
programConfigureMutex.RLock()
defer programConfigureMutex.RUnlock()
if programConfigure == nil {
return []byte("{}")
}
//JSON.Pars
res, err := json.MarshalIndent(*Configure, "", "\t")
res, err := json.MarshalIndent(*programConfigure, "", "\t")
if err != nil {
return []byte("{}")
}
@ -138,17 +126,61 @@ func GetConfigureBytes() []byte {
}
func GetBaseConfigure() BaseConfigure {
ConfigureMutex.RLock()
defer ConfigureMutex.RUnlock()
baseConf := Configure.BaseConfigure
programConfigureMutex.RLock()
defer programConfigureMutex.RUnlock()
baseConf := programConfigure.BaseConfigure
return baseConf
}
func GetDDNSConfigure() DDNSConfigure {
programConfigureMutex.RLock()
defer programConfigureMutex.RUnlock()
conf := programConfigure.DDNSConfigure
return conf
}
func GetPortForwardsConfigure() PortForwardsConfigure {
programConfigureMutex.RLock()
defer programConfigureMutex.RUnlock()
conf := programConfigure.PortForwardsConfigure
return conf
}
func SetPortForwardsConfigure(conf *PortForwardsConfigure) error {
programConfigureMutex.Lock()
defer programConfigureMutex.Unlock()
if conf.PortForwardsLimit < 0 {
conf.PortForwardsLimit = 0
} else if conf.PortForwardsLimit > 1024 {
conf.PortForwardsLimit = 1024
}
if conf.TCPPortforwardMaxConnections < 0 {
conf.TCPPortforwardMaxConnections = 0
} else if conf.TCPPortforwardMaxConnections > 4096 {
conf.TCPPortforwardMaxConnections = 4096
}
if conf.UDPReadTargetDataMaxgoroutineCount < 0 {
conf.UDPReadTargetDataMaxgoroutineCount = 0
} else if conf.UDPReadTargetDataMaxgoroutineCount > 4096 {
conf.UDPReadTargetDataMaxgoroutineCount = 4096
}
programConfigure.PortForwardsConfigure = *conf
socketproxy.SetGlobalMaxPortForwardsCountLimit(conf.PortForwardsLimit)
socketproxy.SetGlobalTCPPortforwardMaxConnections(conf.TCPPortforwardMaxConnections)
socketproxy.SetGlobalUDPReadTargetDataMaxgoroutineCountLimit(conf.UDPReadTargetDataMaxgoroutineCount)
return Save()
}
// 保存基础配置
func SetBaseConfigure(conf *BaseConfigure) error {
ConfigureMutex.Lock()
defer ConfigureMutex.Unlock()
Configure.BaseConfigure = *conf
programConfigureMutex.Lock()
defer programConfigureMutex.Unlock()
programConfigure.BaseConfigure = *conf
//socketproxy.SetGlobalMaxConnections(conf.GlobalMaxConnections)
//socketproxy.SetGlobalMaxPortForwardsCount(conf.ProxyCountLimit)
@ -159,12 +191,30 @@ func SetBaseConfigure(conf *BaseConfigure) error {
conf.LogMaxSize = maxLogSize
}
if conf.HttpClientTimeout <= 0 {
conf.HttpClientTimeout = 1
} else if conf.HttpClientTimeout > 60 {
conf.HttpClientTimeout = 60
return Save()
}
func SetDDNSConfigure(conf *DDNSConfigure) error {
programConfigureMutex.Lock()
defer programConfigureMutex.Unlock()
if conf.Intervals < 30 {
conf.Intervals = 30
}
if conf.Intervals > 3600 {
conf.Intervals = 3600
}
if conf.FirstCheckDelay < 0 {
conf.FirstCheckDelay = 0
}
if conf.FirstCheckDelay > 3600 {
conf.FirstCheckDelay = 3600
}
programConfigure.DDNSConfigure = *conf
return Save()
}
@ -180,13 +230,6 @@ func Read(filePath string) (err error) {
return err
}
checkConfigue(pc)
Configure = pc
return nil
}
func checkConfigue(pc *ProgramConfigure) {
if pc.PortForwardsConfigure.PortForwardsLimit <= 0 {
pc.PortForwardsConfigure.PortForwardsLimit = socketproxy.DEFAULT_MAX_PORTFORWARDS_LIMIT
}
@ -216,43 +259,13 @@ func checkConfigue(pc *ProgramConfigure) {
pc.BaseConfigure.LogMaxSize = maxLogSize
}
if pc.BaseConfigure.HttpClientTimeout <= 0 {
pc.BaseConfigure.HttpClientTimeout = 20
} else if pc.BaseConfigure.HttpClientTimeout > 60 {
pc.BaseConfigure.HttpClientTimeout = 60
}
programConfigure = pc
if pc.WOLServiceConfigure.Client.Port <= 0 {
pc.WOLServiceConfigure.Client.Port = 9
}
if pc.WOLServiceConfigure.Client.Repeat <= 0 {
pc.WOLServiceConfigure.Client.Repeat = 5
}
if pc.WOLServiceConfigure.Client.DeviceName == "" {
hostname, _ := os.Hostname()
pc.WOLServiceConfigure.Client.DeviceName = hostname
}
if pc.WOLServiceConfigure.Client.PowerOffCMD == "" {
switch runtime.GOOS {
case "linux":
pc.WOLServiceConfigure.Client.PowerOffCMD = "poweroff"
case "windows":
pc.WOLServiceConfigure.Client.PowerOffCMD = "Shutdown /s /t 0"
default:
pc.WOLServiceConfigure.Client.PowerOffCMD = ""
}
}
if pc.WOLServiceConfigure.Server.Token == "" {
pc.WOLServiceConfigure.Server.Token = "666666"
}
return nil
}
func LoadDefault(adminWebListenPort int) {
Configure = loadDefaultConfigure(adminWebListenPort)
programConfigure = loadDefaultConfigure(adminWebListenPort)
}
func Save() (err error) {
@ -271,7 +284,7 @@ func Save() (err error) {
}()
err = saveProgramConfig(Configure, configurePath)
err = saveProgramConfig(programConfigure, configurePath)
return
}
@ -314,41 +327,39 @@ func loadDefaultConfigure(
AllowInternetaccess: false,
LogMaxSize: defaultLogSize}
whiteListConfigure := safeconf.WhiteListConfigure{BaseConfigure: safeconf.WhiteListBaseConfigure{ActivelifeDuration: 36, BasicAccount: defaultAdminAccount, BasicPassword: defaultAdminPassword}}
whiteListConfigure := WhiteListConfigure{BaseConfigure: WhiteListBaseConfigure{ActivelifeDuration: 36, BasicAccount: defaultAdminAccount, BasicPassword: defaultAdminPassword}}
var pc ProgramConfigure
pc.BaseConfigure = baseConfigure
pc.WhiteListConfigure = whiteListConfigure
checkConfigue(&pc)
if pc.PortForwardsConfigure.PortForwardsLimit <= 0 {
pc.PortForwardsConfigure.PortForwardsLimit = socketproxy.DEFAULT_MAX_PORTFORWARDS_LIMIT
}
socketproxy.SetGlobalMaxPortForwardsCountLimit(pc.PortForwardsConfigure.PortForwardsLimit)
// if pc.PortForwardsConfigure.PortForwardsLimit <= 0 {
// pc.PortForwardsConfigure.PortForwardsLimit = socketproxy.DEFAULT_MAX_PORTFORWARDS_LIMIT
// }
// socketproxy.SetGlobalMaxPortForwardsCountLimit(pc.PortForwardsConfigure.PortForwardsLimit)
if pc.PortForwardsConfigure.TCPPortforwardMaxConnections <= 0 {
pc.PortForwardsConfigure.TCPPortforwardMaxConnections = socketproxy.TCPUDP_DEFAULT_SINGLE_PROXY_MAX_CONNECTIONS
}
socketproxy.SetGlobalTCPPortforwardMaxConnections(pc.PortForwardsConfigure.TCPPortforwardMaxConnections)
// if pc.PortForwardsConfigure.TCPPortforwardMaxConnections <= 0 {
// pc.PortForwardsConfigure.TCPPortforwardMaxConnections = socketproxy.TCPUDP_DEFAULT_SINGLE_PROXY_MAX_CONNECTIONS
// }
// socketproxy.SetGlobalTCPPortforwardMaxConnections(pc.PortForwardsConfigure.TCPPortforwardMaxConnections)
if pc.PortForwardsConfigure.UDPReadTargetDataMaxgoroutineCount <= 0 {
pc.PortForwardsConfigure.UDPReadTargetDataMaxgoroutineCount = socketproxy.DEFAULT_GLOBAL_UDPReadTargetDataMaxgoroutineCount
}
// if pc.PortForwardsConfigure.UDPReadTargetDataMaxgoroutineCount <= 0 {
// pc.PortForwardsConfigure.UDPReadTargetDataMaxgoroutineCount = socketproxy.DEFAULT_GLOBAL_UDPReadTargetDataMaxgoroutineCount
// }
socketproxy.SetGlobalUDPReadTargetDataMaxgoroutineCountLimit(pc.PortForwardsConfigure.UDPReadTargetDataMaxgoroutineCount)
// socketproxy.SetGlobalUDPReadTargetDataMaxgoroutineCountLimit(pc.PortForwardsConfigure.UDPReadTargetDataMaxgoroutineCount)
if pc.BaseConfigure.AdminWebListenPort <= 0 {
pc.BaseConfigure.AdminWebListenPort = defaultAdminListenPort
}
// if pc.BaseConfigure.AdminWebListenPort <= 0 {
// pc.BaseConfigure.AdminWebListenPort = defaultAdminListenPort
// }
if pc.DDNSConfigure.Intervals < 30 {
pc.DDNSConfigure.Intervals = 30
}
// if pc.DDNSConfigure.Intervals < 30 {
// pc.DDNSConfigure.Intervals = 30
// }
// if pc.DDNSConfigure.FirstCheckDelay <= 0 {
// pc.DDNSConfigure.FirstCheckDelay = 0
// }
if pc.DDNSConfigure.FirstCheckDelay <= 0 {
pc.DDNSConfigure.FirstCheckDelay = 0
}
return &pc
}

19
go.mod
View File

@ -4,18 +4,16 @@ go 1.18
require (
github.com/buger/jsonparser v1.1.1
github.com/eclipse/paho.mqtt.golang v1.4.2
github.com/eclipse/paho.mqtt.golang v1.4.1
github.com/fatedier/golib v0.2.0
github.com/gin-contrib/gzip v0.0.6
github.com/gin-gonic/gin v1.8.1
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/gorilla/websocket v1.5.0
github.com/guonaihong/gout v0.3.1
github.com/kardianos/service v1.2.2
github.com/miekg/dns v1.1.50
github.com/shirou/gopsutil/v3 v3.22.9
github.com/sirupsen/logrus v1.9.0
golang.org/x/net v0.1.0
golang.org/x/net v0.0.0-20221004154528-8021a29435af
)
require (
@ -25,6 +23,7 @@ require (
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.11.1 // indirect
github.com/goccy/go-json v0.9.11 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect
@ -38,12 +37,12 @@ require (
github.com/tklauser/numcpus v0.5.0 // indirect
github.com/ugorji/go/codec v1.2.7 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/mod v0.6.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/text v0.4.0 // indirect
golang.org/x/tools v0.2.0 // indirect
golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
golang.org/x/sys v0.0.0-20221010170243-090e33056c14 // indirect
golang.org/x/text v0.3.8 // indirect
golang.org/x/tools v0.1.12 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

38
go.sum
View File

@ -4,8 +4,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eclipse/paho.mqtt.golang v1.4.2 h1:66wOzfUHSSI1zamx7jR6yMEI5EuHnT1G6rNA5PM12m4=
github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA=
github.com/eclipse/paho.mqtt.golang v1.4.1 h1:tUSpviiL5G3P9SZZJPC4ZULZJsxQKXxfENpMvdbAXAI=
github.com/eclipse/paho.mqtt.golang v1.4.1/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA=
github.com/fatedier/golib v0.2.0 h1:8BxiUcjleBlXBYlTNUllD8KZZHaFU/NP/vP0Yu1Fkpg=
github.com/fatedier/golib v0.2.0/go.mod h1:e2NPpBGUFsHDjXrfP1B5aK3S0+yUeVxgqfc3go3KNj0=
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
@ -38,15 +38,12 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/guonaihong/gout v0.3.1 h1:pj/44Jw0TTmcHF2RjMaCWhKPwCH98YuQejbN15Hts/o=
github.com/guonaihong/gout v0.3.1/go.mod h1:lhje0jRkh/gcIogrG22ENPITo9tylQa3kwD9eVxcDrk=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60=
github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
@ -112,11 +109,11 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2 h1:x8vtB3zMecnlqZIwJNUUpwYKYSqCz5jXbiyv0ZJJZeI=
golang.org/x/crypto v0.0.0-20221010152910-d6f0a8c073c2/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190228165749-92fc7df08ae7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -125,17 +122,16 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4=
golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc=
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -149,20 +145,20 @@ golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cIyEbeXLBhy5Ha4nevyc=
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

129
main.go
View File

@ -6,27 +6,19 @@ import (
"flag"
"log"
"os"
"sync"
"os/signal"
"syscall"
"time"
"github.com/gdy666/lucky/config"
"github.com/gdy666/lucky/module/ddns"
"github.com/gdy666/lucky/module/ddns/ddnsgo"
"github.com/gdy666/lucky/module/portforward"
"github.com/gdy666/lucky/module/portforward/socketproxy"
"github.com/gdy666/lucky/module/reverseproxy"
"github.com/gdy666/lucky/module/safe"
"github.com/gdy666/lucky/module/service"
ssl "github.com/gdy666/lucky/module/sslcertficate"
"github.com/gdy666/lucky/module/wol"
"github.com/gdy666/lucky/web"
kservice "github.com/kardianos/service"
"github.com/gdy666/lucky/ddns"
"github.com/gdy666/lucky/reverseproxy"
"github.com/gdy666/lucky/socketproxy"
)
var (
listenPort = flag.Int("p", 16601, "http Admin Web listen port ")
configureFileURL = flag.String("c", "", "configure file url")
disableService = flag.Bool("ds", false, "disable service mode ")
)
var (
@ -41,49 +33,10 @@ var runTime time.Time
func init() {
var cstZone = time.FixedZone("CST", 8*3600) // 东八
time.Local = cstZone
service.RegisterStartFunc(run)
}
func main() {
flag.Parse()
service.SetListenPort(*listenPort)
service.SetConfigureFile(*configureFileURL)
s, _ := service.GetService()
if s != nil && !*disableService {
status, _ := s.Status()
//fmt.Printf("status:%d\n", status)
if status != kservice.StatusUnknown {
log.Printf("以服务形式运行\n")
if status == kservice.StatusStopped {
log.Printf("调用启动lucky windows服务")
service.Start()
log.Printf("本窗口5秒后退出,lucky将以windows后台服务方式启动.")
<-time.After(time.Second * 5)
os.Exit(0)
}
s.Run()
os.Exit(0)
}
}
run()
var w sync.WaitGroup
w.Add(1)
w.Wait()
// err := service.UninstallService()
// if err != nil {
// fmt.Printf("%s\n", err.Error())
// }
//
}
func run() {
config.InitAppInfo(version, date)
err := config.Read(*configureFileURL)
@ -101,13 +54,15 @@ func run() {
gcf := config.GetConfig()
safe.Init()
ssl.Init()
config.BlackListInit()
config.WhiteListInit()
config.SSLCertficateListInit()
wol.Init(web.GetLogger())
socketproxy.SetSafeCheck(safe.SafeCheck)
//fmt.Printf("*gcf:%v\n", *gcf)
socketproxy.SetSafeCheck(config.SafeCheck)
//socketproxy.SetGlobalMaxConnections(gcf.BaseConfigure.GlobalMaxConnections)
//socketproxy.SetGlobalMaxProxyCount(gcf.BaseConfigure.ProxyCountLimit)
config.SetRunMode(runMode)
config.SetVersion(version)
log.Printf("RunMode:%s\n", runMode)
@ -117,24 +72,60 @@ func run() {
runTime = time.Now()
portforward.Init()
//LoadRuleFromConfigFile(gcf)
ddnsgo.DDNSTaskListConfigureCheck()
ddnsConf := ddnsgo.GetDDNSConfigure()
config.PortForwardsRuleListInit()
//config.DDNSTaskListTaskDetailsInit()
config.DDNSTaskListConfigureCheck()
ddnsConf := config.GetDDNSConfigure()
if ddnsConf.Enable {
go ddns.Run(time.Duration(ddnsConf.FirstCheckDelay)*time.Second, time.Duration(ddnsConf.Intervals)*time.Second)
}
reverseproxy.InitReverseProxyServer()
//main goroutine wait
// sigs := make(chan os.Signal, 1)
// exit := make(chan bool, 1)
// signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
// go func() {
// <-sigs
// exit <- true
// }()
// <-exit
//ddns.RunTimer(time.Second, time.Second*30)
//initProxyList()
//*****************
// time.Sleep(time.Microsecond * 50)
// cruuentPath, _ := fileutils.GetCurrentDirectory()
// panicFile := fmt.Sprintf("%s/relayport_panic.log", cruuentPath)
// fileutils.PanicRedirect(panicFile)
//*****************
//main goroutine wait
sigs := make(chan os.Signal, 1)
exit := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-sigs
exit <- true
}()
<-exit
}
// func LoadRuleFromConfigFile(pc *config.ProgramConfigure) {
// if pc == nil {
// return
// }
// for i := range pc.RelayRuleList {
// relayRule, err := rule.CreateRuleByConfigureAndOptions(
// pc.RelayRuleList[i].Name,
// pc.RelayRuleList[i].Configurestr,
// pc.RelayRuleList[i].Options)
// if err != nil {
// continue
// }
// relayRule.From = "configureFile" //规则来源
// relayRule.IsEnable = pc.RelayRuleList[i].Enable
// _, e := rule.AddRuleToGlobalRuleList(false, *relayRule)
// if e != nil {
// log.Printf("%s\n", e)
// }
// }
// }

View File

@ -14,7 +14,7 @@ const (
type VoiceAssistant struct {
DeviceType string //语言助手类型 (设备类型).
VAType string //语言助手类型 MIOT AliGenie DuerOS
Device *Device
Device *BlinkerDevice
topic string
}
@ -31,34 +31,42 @@ func (v *VoiceAssistant) GetSKey() string {
}
}
func (v *VoiceAssistant) PowerChangeReply(msgid, state string) {
if state == "true" {
func (v *VoiceAssistant) PowerChangeReply(msgid, st string) {
state := "off"
if st == "true" {
state = "on"
} else if state == "false" {
state = "off"
}
data := map[string]string{"pState": state, "messageId": msgid}
// if v.VAType == "MIOT" {
// if state == "on" {
// state = "true"
// } else {
// state = "false"
// }
// }
data := map[string]string{"pState": state}
v.Device.SendMessage("vAssistant", v.GetToDevice(), msgid, data)
}
func (v *VoiceAssistant) QueryDeviceState(msgid string) {
state := v.Device.GetState()
var stateStr = ""
if state {
stateStr = "on"
} else {
stateStr = "off"
}
data := map[string]string{"pState": stateStr, "messageId": msgid}
state := v.Device.state
// if v.VAType == "MIOT" {
// if state == "on" {
// state = "true"
// } else {
// state = "false"
// }
// }
data := map[string]string{"pState": state}
v.Device.SendMessage("vAssistant", v.GetToDevice(), msgid, data)
}
func (v *VoiceAssistant) GetToDevice() string {
if v.Device.DetailInfo.Broker == "blinker" {
return "ServerReceiver"
}
// if v.Device.DetailInfo.Broker == "blinker" {
// return "ServerReceiver"
// }
return v.topic
}

View File

@ -2,7 +2,7 @@ package blinker
import (
"compress/gzip"
"crypto/tls"
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
@ -10,25 +10,12 @@ import (
"net/http"
"strings"
"sync"
"sync/atomic"
"time"
"github.com/buger/jsonparser"
MQTT "github.com/eclipse/paho.mqtt.golang"
"github.com/gdy666/lucky/thirdlib/gdylib/httputils"
)
const (
Disconnected uint32 = iota
Connecting
Reconnecting
Connected
)
func init() {
}
const (
HOST = "https://iot.diandeng.tech"
API_AUTH = HOST + "/api/v1/user/device/diy/auth"
@ -36,30 +23,24 @@ const (
API_VOICE_ASSISTANT = HOST + "/api/v1/user/device/voice_assistant"
)
type Device struct {
linkState uint32
type BlinkerDevice struct {
authKey string
subTopic string
pubTopic string
exasubTopic string //aliyun特有
exapubTopic string //aliyun特有
client MQTT.Client
clientMu sync.Mutex
DetailInfo BlinkerDetailInfo
heartBeatChan chan uint8
hbmu sync.Mutex
preSendTime time.Time
//sendMsgChan chan message
extStroe sync.Map
powerChangeCallbackMap sync.Map
state bool
queryStateFunc func() bool
sendMsgChan chan message
//
state string
voiceAssistants map[string]*VoiceAssistant
httpClientSecureVerify bool
httpClientTimeout int
httpclient *http.Client
}
type message struct {
@ -69,54 +50,19 @@ type message struct {
Msg any
}
func CreateDevice(ak string, httpClientSecureVerify bool, httpClientTimeout int) *Device {
d := &Device{authKey: ak, httpClientSecureVerify: httpClientSecureVerify, httpClientTimeout: httpClientTimeout}
func CreateBlinkerDevice(ak string) *BlinkerDevice {
d := &BlinkerDevice{authKey: ak}
d.voiceAssistants = make(map[string]*VoiceAssistant)
d.httpclient, _ = httputils.CreateHttpClient(
"tcp",
"",
!httpClientSecureVerify,
"",
"",
"",
"",
time.Duration(httpClientTimeout)*time.Second)
d.state = "on"
return d
}
func (d *Device) GetState() bool {
if d.queryStateFunc != nil {
return d.queryStateFunc()
}
return d.state
}
func (d *Device) SetQueryStateFunc(f func() bool) {
d.queryStateFunc = f
}
func (d *Device) RegisterPowerChangeCallbackFunc(key string, cb func(string)) {
d.powerChangeCallbackMap.Store(key, cb)
}
func (d *Device) UnRegisterPowerChangeCallbackFunc(key string) {
d.powerChangeCallbackMap.Delete(key)
}
func (d *Device) AddVoiceAssistant(v *VoiceAssistant) {
func (d *BlinkerDevice) AddVoiceAssistant(v *VoiceAssistant) {
v.Device = d
d.voiceAssistants[v.VAType] = v
}
func (d *Device) StoreExtData(key any, val any) {
d.extStroe.Store(key, val)
}
func (d *Device) GetExtData(key any) (val any, ok bool) {
val, ok = d.extStroe.Load(key)
return
}
func (d *Device) SyncAssistants() error {
func (d *BlinkerDevice) SyncAssistants() error {
for _, v := range d.voiceAssistants {
skey := v.GetSKey()
dataMap := make(map[string]string)
@ -125,7 +71,7 @@ func (d *Device) SyncAssistants() error {
dataBytes, _ := json.Marshal(dataMap)
resp, err := d.httpclient.Post(API_VOICE_ASSISTANT, "application/json", strings.NewReader(string(dataBytes)))
resp, err := http.Post(API_VOICE_ASSISTANT, "application/json", strings.NewReader(string(dataBytes)))
if err != nil {
return err
}
@ -139,75 +85,46 @@ func (d *Device) SyncAssistants() error {
return nil
}
// func (d *Device) RunSenderMessageService() {
// for m := range d.sendMsgChan {
// t := time.Since(d.preSendTime) - time.Millisecond*1100
// if t < 0 {
// //log.Printf("太快,睡眠一下:%d\n", -t)
// <-time.After(-t)
// }
// d.sendMessage(m.TargetType, m.Device, m.MessageID, m.Msg)
// }
// }
func (d *Device) RunHeartBearTimer() {
ticker := time.NewTicker(time.Second * 599)
defer func() {
ticker.Stop()
}()
for {
select {
case _, ok := <-d.heartBeatChan:
{
if !ok {
return
}
d.heartBeat()
}
case <-ticker.C:
d.heartBeatChan <- uint8(1)
func (d *BlinkerDevice) RunSenderMessageService() {
for m := range d.sendMsgChan {
t := time.Since(d.preSendTime) - time.Millisecond*1100
if t < 0 {
//log.Printf("太快,睡眠一下:%d\n", -t)
<-time.After(-t)
}
d.sendMessage(m.TargetType, m.Device, m.MessageID, m.Msg)
}
}
func (d *Device) Init() error {
func (d *BlinkerDevice) RunHeartBearTimer() {
if !d.hbmu.TryLock() {
return
}
defer d.hbmu.Unlock()
log.Printf("开始心跳...\n")
d.heartBeatChan <- uint8(1)
for range d.heartBeatChan {
d.heartBeat()
<-time.After(time.Second * 599)
d.heartBeatChan <- uint8(1)
}
log.Printf("心跳中止...\n")
}
func (d *BlinkerDevice) Init() error {
apiurl := fmt.Sprintf("%s?authKey=%s", API_AUTH, d.authKey)
resp, err := d.httpclient.Get(apiurl)
resp, err := http.Get(apiurl)
if err != nil {
return fmt.Errorf("device init httpclient.Get err:%s", err.Error())
return fmt.Errorf("device init http.Get err:%s", err.Error())
}
var infoRes BlinkerInfoRes
//jsonparser.Get()
respBytes, err := GetBytesFromHttpResponse(resp)
err = GetAndParseJSONResponseFromHttpResponse(resp, &infoRes)
if err != nil {
return fmt.Errorf("GetBytesFromHttpResponse error:%s", err.Error())
return fmt.Errorf("parse DeviceInfo resp err:%s", err.Error())
}
messageRet, _ := jsonparser.GetInt(respBytes, "message")
if messageRet != 1000 {
detailStr, _ := jsonparser.GetString(respBytes, "detail")
return fmt.Errorf("%s", detailStr)
}
err = json.Unmarshal(respBytes, &infoRes)
if err != nil {
return fmt.Errorf("登录过程解析登录结果出错:\n%s\n%s", string(respBytes), err.Error())
}
// err = GetAndParseJSONResponseFromHttpResponse(resp, &infoRes)
// if err != nil {
// return fmt.Errorf("parse DeviceInfo resp err:%s", err.Error())
// }
d.DetailInfo = infoRes.Detail
err = d.SyncAssistants()
@ -237,30 +154,7 @@ func (d *Device) Init() error {
return nil
}
func (d *Device) closeMQTTClient() {
d.clientMu.Lock()
defer d.clientMu.Unlock()
if d.client == nil {
return
}
log.Printf("点灯科技 [%s]主动关闭连接", d.authKey)
d.client.Disconnect(0)
close(d.heartBeatChan)
//close(d.sendMsgChan)
d.client = nil
}
func (d *Device) OnLine() bool {
state := atomic.LoadUint32(&d.linkState)
return state == Connected
}
func (d *Device) IsDisconnected() bool {
state := atomic.LoadUint32(&d.linkState)
return state == Disconnected
}
func (d *Device) Login() error {
func (d *BlinkerDevice) Login() error {
opts := MQTT.NewClientOptions()
brokeyURL := fmt.Sprintf("%s:%s", d.DetailInfo.Host, d.DetailInfo.Port)
@ -270,71 +164,69 @@ func (d *Device) Login() error {
opts.SetClientID(d.DetailInfo.DeviceName)
opts.SetUsername(d.DetailInfo.IotID)
opts.SetPassword(d.DetailInfo.IotToken)
opts.SetConnectTimeout(time.Second * 2)
opts.SetKeepAlive(time.Second * 30)
opts.SetTLSConfig(&tls.Config{InsecureSkipVerify: !d.httpClientSecureVerify})
opts.SetAutoReconnect(true)
opts.ConnectRetryInterval = time.Second * 3
//opts.SetKeepAlive(time.Second * 3)
//opts.WillRetained = true
//choke := make(chan [2]string)
// opts.SetDefaultPublishHandler(func(client MQTT.Client, msg MQTT.Message) {
// //choke <- [2]string{msg.Topic(), string(msg.Payload())}
// msg.Payload()
// })
opts.SetOnConnectHandler(func(c MQTT.Client) {
atomic.StoreUint32(&d.linkState, Connected)
log.Printf("点灯物联 [%s]已连接\n", d.authKey)
d.clientMu.Lock()
defer d.clientMu.Unlock()
log.Printf("连接成功!")
d.client = c
c.Subscribe(d.subTopic, byte(0), d.ReceiveMessageHandler)
//c.Subscribe(d.exasubTopic, byte(0), d.ReceiveMessageHandler)
d.heartBeatChan = make(chan uint8, 1)
go d.RunHeartBearTimer()
//d.sendMsgChan = make(chan message, 8)
//go d.RunSenderMessageService()
d.sendMsgChan = make(chan message, 8)
go d.RunSenderMessageService()
})
//d.client.Disconnect()
opts.OnConnectionLost = func(c MQTT.Client, err error) {
log.Printf("连接丢失:%s\n", err.Error())
close(d.heartBeatChan)
close(d.sendMsgChan)
d.client = nil
}
opts.SetConnectionLostHandler(func(c MQTT.Client, err error) {
log.Printf("点灯物联 [%s]连接丢失:%s\n", d.authKey, err.Error())
atomic.StoreUint32(&d.linkState, Disconnected)
//d.closeMQTTClient()
//fmt.Printf("SetConnectionLostHandler\n")
})
//opts.
opts.SetReconnectingHandler(func(c MQTT.Client, opt *MQTT.ClientOptions) {
atomic.StoreUint32(&d.linkState, Reconnecting)
})
client := MQTT.NewClient(opts)
if token := client.Connect(); token.Wait() && token.Error() != nil {
return fmt.Errorf("连接出错:%s", token.Error())
}
<-time.After(time.Second * 60000)
return nil
}
func (d *Device) Stop() {
d.closeMQTTClient()
}
func (d *Device) heartBeat() error {
func (d *BlinkerDevice) heartBeat() error {
//hr := fmt.Sprintf("%s?deviceName=%s&key=%s&heartbeat=600", SERVER+HEARTBEAT_URL, d.DetailInfo.DeviceName, d.authKey)
hr := fmt.Sprintf("%s?deviceName=%s&key=%s&heartbeat=600", API_HEARTBEAT, d.DetailInfo.DeviceName, d.authKey)
resp, err := d.httpclient.Get(hr)
resp, err := http.Get(hr)
if err != nil {
return fmt.Errorf("device init httpclient.Get err:%s", err.Error())
return fmt.Errorf("device init http.Get err:%s", err.Error())
}
_, err = GetBytesFromHttpResponse(resp)
respBytes, err := GetBytesFromHttpResponse(resp)
if err != nil {
return err
}
//fmt.Printf("HearBeat:%s\n", string(respBytes))
fmt.Printf("HearBeat:%s\n", string(respBytes))
return nil
}
func (d *Device) ReceiveMessageHandler(c MQTT.Client, m MQTT.Message) {
func (d *BlinkerDevice) ReceiveMessageHandler(c MQTT.Client, m MQTT.Message) {
//log.Printf("接收到MQTT消息:\n[【%s】\n%s\n\n", m.Topic(), m.Payload())
log.Printf("接收到MQTT消息:【%s】%s\n", m.Topic(), m.Payload())
if m.Topic() != d.subTopic {
return
@ -362,9 +254,9 @@ func (d *Device) ReceiveMessageHandler(c MQTT.Client, m MQTT.Message) {
}
func (d *Device) voiceAssistantMessageHandler(from string, msg []byte) {
func (d *BlinkerDevice) voiceAssistantMessageHandler(from string, msg []byte) {
//fmt.Printf("from:%s msg:%s\n", from, string(msg))
fmt.Printf("from:%s msg:%s\n", from, string(msg))
va, ok := d.voiceAssistants[from]
if !ok {
@ -393,28 +285,14 @@ func (d *Device) voiceAssistantMessageHandler(from string, msg []byte) {
}
func (d *Device) powerChange(va *VoiceAssistant, msgId, state string) {
func (d *BlinkerDevice) powerChange(va *VoiceAssistant, msgId, state string) {
d.state = state
if va != nil {
va.PowerChangeReply(msgId, state)
}
if state == "true" || state == "on" {
d.state = true
} else {
d.state = false
}
go func() {
d.powerChangeCallbackMap.Range(func(key any, val any) bool {
cb := val.(func(string))
cb(state)
return true
})
}()
}
func (d *Device) ownAppMessagehandler(msg []byte) {
func (d *BlinkerDevice) ownAppMessagehandler(msg []byte) {
getValue, getKeyError := jsonparser.GetString(msg, "data", "get")
if getKeyError == nil {
switch getValue {
@ -425,7 +303,7 @@ func (d *Device) ownAppMessagehandler(msg []byte) {
case "countdown":
d.SendMessage("OwnApp", d.DetailInfo.UUID, "", map[string]any{"countdown": "false"}) //`{ "countdown": false }`
default:
//fmt.Printf(` "data", "get":Value:%s`, getValue)
fmt.Printf(` "data", "get":Value:%s`, getValue)
}
return
@ -447,37 +325,34 @@ type mess2assistant struct {
MessageID string `json:"-"` //`json:"messageId"`
}
func (d *Device) formatMess2assistant(targetType, toDevice, msgid string, data any) ([]byte, error) {
func (d *BlinkerDevice) formatMess2assistant(targetType, toDevice, msgid string, data any) ([]byte, error) {
m := mess2assistant{DeviceType: targetType, Data: data, FromDeivce: d.DetailInfo.DeviceName, ToDevice: toDevice, MessageID: msgid}
rawBytes, err := json.Marshal(m)
if err != nil {
return []byte{}, err
}
//str := base64.StdEncoding.EncodeToString(rawBytes)
//log.Printf("回复语音助手:%s\n", string(rawBytes))
str := base64.StdEncoding.EncodeToString(rawBytes)
log.Printf("回复语音助手:%s\n", string(rawBytes))
//fmt.Printf("base64:%s\n", str)
//return []byte(str), nil
return rawBytes, nil
return []byte(str), nil
//return rawBytes, nil
}
func (d *Device) formatMess2Device(targetType, toDevice string, data any) ([]byte, error) {
func (d *BlinkerDevice) formatMess2Device(targetType, toDevice string, data any) ([]byte, error) {
m := mess2device{DeviceType: targetType, Data: data, FromDeivce: d.DetailInfo.DeviceName, ToDevice: toDevice}
return json.Marshal(m)
}
func (d *Device) SendMessage(targetType, todevice, msgid string, msg any) {
//m := message{Device: todevice, Msg: msg, TargetType: targetType, MessageID: msgid}
//d.sendMsgChan <- m
d.sendMessage(targetType, todevice, msgid, msg)
func (d *BlinkerDevice) SendMessage(targetType, todevice, msgid string, msg any) {
m := message{Device: todevice, Msg: msg, TargetType: targetType, MessageID: msgid}
d.sendMsgChan <- m
}
func (d *Device) sendMessage(targetType, todevice, msgid string, msg any) error {
d.clientMu.Lock()
defer d.clientMu.Unlock()
func (d *BlinkerDevice) sendMessage(targetType, todevice, msgid string, msg any) error {
if d.client == nil {
return fmt.Errorf("d.Client == nil")
return fmt.Errorf("SendMessage error:client == nil")
}
var pubTopic string
var payload []byte
@ -499,10 +374,10 @@ func (d *Device) sendMessage(targetType, todevice, msgid string, msg any) error
}
}
// fmt.Printf("topic:%s\n", pubTopic)
fmt.Printf("topic:%s\n", pubTopic)
if token := d.client.Publish(pubTopic, 1, true, payload); token.Wait() && token.Error() != nil {
//fmt.Printf("Publish error:%s\n", token.Error())
if token := d.client.Publish(pubTopic, 0, false, payload); token.Wait() && token.Error() != nil {
fmt.Printf("Publish error:%s\n", token.Error())
return token.Error()
}
d.preSendTime = time.Now()
@ -553,8 +428,6 @@ func GetAndParseJSONResponseFromHttpResponse(resp *http.Response, result interfa
if err != nil {
return fmt.Errorf("GetBytesFromHttpResponse err:%s", err.Error())
}
// fmt.Printf("FUCK:\n%s\n", string(bytes))
if len(bytes) > 0 {
err = json.Unmarshal(bytes, &result)
if err != nil {

View File

@ -11,7 +11,6 @@ import (
// NetInterface 本机网络
type NetInterface struct {
NetInterfaceName string
HardwareAddr string
AddressList []string
}
@ -52,7 +51,6 @@ func GetNetInterface() (ipv4NetInterfaces []NetInterface, ipv6NetInterfaces []Ne
ipv4NetInterfaces,
NetInterface{
NetInterfaceName: allNetInterfaces[i].Name,
HardwareAddr: allNetInterfaces[i].HardwareAddr.String(),
AddressList: ipv4,
},
)
@ -196,58 +194,3 @@ func GetBroadcast(ip net.IP, mask net.IPMask) string {
}
return bcst.String()
}
// ----------------------------------------------------------------
// NetInterface 本机网络
type NetInterfaceInfo struct {
NetInterfaceName string
HardwareAddr string
AddressList []IPInfo
}
type IPInfo struct {
IP string
BroadcastIP string
}
// GetNetInterface 获得网卡地址
// 返回ipv4, ipv6地址
func GetIPv4NetInterfaceInfoList() (ipv4NetInterfaces []NetInterfaceInfo, err error) {
allNetInterfaces, err := net.Interfaces()
if err != nil {
return ipv4NetInterfaces, err
}
for i := 0; i < len(allNetInterfaces); i++ {
if (allNetInterfaces[i].Flags & net.FlagUp) != 0 {
addrs, _ := allNetInterfaces[i].Addrs()
ipv4 := []IPInfo{}
for _, address := range addrs {
if ipnet, ok := address.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() {
_, bits := ipnet.Mask.Size()
// 需匹配全局单播地址
//if bits == 128 && ipv6Unicast.Contains(ipnet.IP) {
if bits == 32 {
info := IPInfo{IP: ipnet.IP.String(), BroadcastIP: GetBroadcast(ipnet.IP, ipnet.Mask)}
ipv4 = append(ipv4, info)
}
}
}
if len(ipv4) > 0 {
ipv4NetInterfaces = append(
ipv4NetInterfaces,
NetInterfaceInfo{
NetInterfaceName: allNetInterfaces[i].Name,
HardwareAddr: allNetInterfaces[i].HardwareAddr.String(),
AddressList: ipv4,
},
)
}
}
}
return ipv4NetInterfaces, nil
}

View File

@ -1,11 +1,5 @@
package stringsp
import (
"bytes"
"crypto/des"
"errors"
)
func StrIsInList(str string, strList []string) bool {
checkMap := make(map[string]uint8)
for i := range strList {
@ -16,58 +10,3 @@ func StrIsInList(str string, strList []string) bool {
}
return false
}
func zeroPadding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{0}, padding)
return append(ciphertext, padtext...)
}
func zeroUnPadding(origData []byte) []byte {
return bytes.TrimFunc(origData,
func(r rune) bool {
return r == rune(0)
})
}
// DesEncrypt Des加密
func DesEncrypt(src, key []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
bs := block.BlockSize()
src = zeroPadding(src, bs)
if len(src)%bs != 0 {
return nil, errors.New("Need a multiple of the blocksize")
}
out := make([]byte, len(src))
dst := out
for len(src) > 0 {
block.Encrypt(dst, src[:bs])
src = src[bs:]
dst = dst[bs:]
}
return out, nil
}
// DesDecrypt Des解密
func DesDecrypt(src, key []byte) ([]byte, error) {
block, err := des.NewCipher(key)
if err != nil {
return nil, err
}
out := make([]byte, len(src))
dst := out
bs := block.BlockSize()
if len(src)%bs != 0 {
return nil, errors.New("crypto/cipher: input not full blocks")
}
for len(src) > 0 {
block.Decrypt(dst, src[:bs])
src = src[bs:]
dst = dst[bs:]
}
out = zeroUnPadding(out)
return out, nil
}

View File

@ -1,4 +1,4 @@
package gowol
package wol
////////////////////////////////////////////////////////////////////////////////

View File

@ -1,4 +1,4 @@
package gowol
package wol
import (
"fmt"

View File

@ -55,7 +55,6 @@ declare module '@vue/runtime-core' {
WhiteLists: typeof import('./src/components/WhiteLists.vue')['default']
WhiteListSet: typeof import('./src/components/WhiteListSet.vue')['default']
WOL: typeof import('./src/components/tools/WOL.vue')['default']
WOLServiceSet: typeof import('./src/components/tools/WOLServiceSet.vue')['default']
}
}

View File

@ -8,8 +8,8 @@
<title>Lucky</title>
<script type="module" crossorigin src="/assets/index.0c84c960.js"></script>
<link rel="stylesheet" href="/assets/index.abda1f8d.css">
<script type="module" crossorigin src="/assets/index.e5c8aec2.js"></script>
<link rel="stylesheet" href="/assets/index.f23c7bd8.css">
</head>
<body style="margin:0">
<div id="app"></div>

View File

@ -83,21 +83,21 @@
}
},
"node_modules/@babel/core": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz",
"integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==",
"version": "7.19.3",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz",
"integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.18.6",
"@babel/generator": "^7.19.6",
"@babel/generator": "^7.19.3",
"@babel/helper-compilation-targets": "^7.19.3",
"@babel/helper-module-transforms": "^7.19.6",
"@babel/helpers": "^7.19.4",
"@babel/parser": "^7.19.6",
"@babel/helper-module-transforms": "^7.19.0",
"@babel/helpers": "^7.19.0",
"@babel/parser": "^7.19.3",
"@babel/template": "^7.18.10",
"@babel/traverse": "^7.19.6",
"@babel/types": "^7.19.4",
"@babel/traverse": "^7.19.3",
"@babel/types": "^7.19.3",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@ -113,9 +113,9 @@
}
},
"node_modules/@babel/generator": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.6.tgz",
"integrity": "sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA==",
"version": "7.19.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz",
"integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==",
"dev": true,
"dependencies": {
"@babel/types": "^7.19.4",
@ -205,19 +205,19 @@
}
},
"node_modules/@babel/helper-module-transforms": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz",
"integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==",
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz",
"integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==",
"dev": true,
"dependencies": {
"@babel/helper-environment-visitor": "^7.18.9",
"@babel/helper-module-imports": "^7.18.6",
"@babel/helper-simple-access": "^7.19.4",
"@babel/helper-simple-access": "^7.18.6",
"@babel/helper-split-export-declaration": "^7.18.6",
"@babel/helper-validator-identifier": "^7.19.1",
"@babel/helper-validator-identifier": "^7.18.6",
"@babel/template": "^7.18.10",
"@babel/traverse": "^7.19.6",
"@babel/types": "^7.19.4"
"@babel/traverse": "^7.19.0",
"@babel/types": "^7.19.0"
},
"engines": {
"node": ">=6.9.0"
@ -303,9 +303,9 @@
}
},
"node_modules/@babel/parser": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.6.tgz",
"integrity": "sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==",
"version": "7.19.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz",
"integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA==",
"bin": {
"parser": "bin/babel-parser.js"
},
@ -328,18 +328,18 @@
}
},
"node_modules/@babel/traverse": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.6.tgz",
"integrity": "sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ==",
"version": "7.19.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz",
"integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.18.6",
"@babel/generator": "^7.19.6",
"@babel/generator": "^7.19.4",
"@babel/helper-environment-visitor": "^7.18.9",
"@babel/helper-function-name": "^7.19.0",
"@babel/helper-hoist-variables": "^7.18.6",
"@babel/helper-split-export-declaration": "^7.18.6",
"@babel/parser": "^7.19.6",
"@babel/parser": "^7.19.4",
"@babel/types": "^7.19.4",
"debug": "^4.1.0",
"globals": "^11.1.0"
@ -400,9 +400,9 @@
"integrity": "sha512-bO37brCPfteXQfFY0DyNDGB3+IMe4j150KFQcgJ5aBP295p9nBGeHEs/p0czrRbtlHq4Px/yoPXO/+dOCcF4uA=="
},
"node_modules/@floating-ui/dom": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.3.tgz",
"integrity": "sha512-6H1kwjkOZKabApNtXRiYHvMmYJToJ1DV7rQ3xc/WJpOABhQIOJJOdz2AOejj8X+gcybaFmBpisVTZxBZAM3V0w==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.2.tgz",
"integrity": "sha512-5X9WSvZ8/fjy3gDu8yx9HAA4KG1lazUN2P4/VnaXLxTO9Dz53HI1oYoh1OlhqFNlHgGDiwFX5WhFCc2ljbW3yA==",
"dependencies": {
"@floating-ui/core": "^1.0.1"
}
@ -484,9 +484,9 @@
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.17",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
"version": "0.3.16",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz",
"integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "3.1.0",
@ -750,9 +750,9 @@
}
},
"node_modules/@types/eslint": {
"version": "8.4.7",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.7.tgz",
"integrity": "sha512-ehM7cCt2RSFs42mb+lcmhFT9ouIlV92PuaeRGn8N8c98oMjG4Z5pJHA9b1QiCcuqnbPSHcyfiD3mlhqMaHsQIw==",
"version": "8.4.6",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz",
"integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==",
"dev": true,
"dependencies": {
"@types/estree": "*",
@ -851,9 +851,9 @@
"peer": true
},
"node_modules/@types/node": {
"version": "18.11.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.2.tgz",
"integrity": "sha512-BWN3M23gLO2jVG8g/XHIRFWiiV4/GckeFIqbU/C4V3xpoBBWSMk4OZomouN0wCkfQFPqgZikyLr7DOYDysIkkw==",
"version": "18.8.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.4.tgz",
"integrity": "sha512-WdlVphvfR/GJCLEMbNA8lJ0lhFNBj4SW3O+O5/cEGw9oYrv0al9zTwuQsq+myDUXgNx2jgBynoVgZ2MMJ6pbow==",
"dev": true
},
"node_modules/@types/normalize-package-data": {
@ -921,9 +921,9 @@
}
},
"node_modules/@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
"version": "0.0.15",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.15.tgz",
"integrity": "sha512-w7hEHXnPMEZ+4nGKl/KDRVpxkwYxYExuHOYXyzIzCDzEZ9ZCGMAewulr9IqJu2LR4N37fcnb1XVeuZ09qgOxhA=="
},
"node_modules/@types/webpack-env": {
"version": "1.18.0",
@ -1222,36 +1222,36 @@
}
},
"node_modules/@vue/compiler-core": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.41.tgz",
"integrity": "sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.40.tgz",
"integrity": "sha512-2Dc3Stk0J/VyQ4OUr2yEC53kU28614lZS+bnrCbFSAIftBJ40g/2yQzf4mPBiFuqguMB7hyHaujdgZAQ67kZYA==",
"dependencies": {
"@babel/parser": "^7.16.4",
"@vue/shared": "3.2.41",
"@vue/shared": "3.2.40",
"estree-walker": "^2.0.2",
"source-map": "^0.6.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.41.tgz",
"integrity": "sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.40.tgz",
"integrity": "sha512-OZCNyYVC2LQJy4H7h0o28rtk+4v+HMQygRTpmibGoG9wZyomQiS5otU7qo3Wlq5UfHDw2RFwxb9BJgKjVpjrQw==",
"dependencies": {
"@vue/compiler-core": "3.2.41",
"@vue/shared": "3.2.41"
"@vue/compiler-core": "3.2.40",
"@vue/shared": "3.2.40"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.41.tgz",
"integrity": "sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.40.tgz",
"integrity": "sha512-tzqwniIN1fu1PDHC3CpqY/dPCfN/RN1thpBC+g69kJcrl7mbGiHKNwbA6kJ3XKKy8R6JLKqcpVugqN4HkeBFFg==",
"dependencies": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.41",
"@vue/compiler-dom": "3.2.41",
"@vue/compiler-ssr": "3.2.41",
"@vue/reactivity-transform": "3.2.41",
"@vue/shared": "3.2.41",
"@vue/compiler-core": "3.2.40",
"@vue/compiler-dom": "3.2.40",
"@vue/compiler-ssr": "3.2.40",
"@vue/reactivity-transform": "3.2.40",
"@vue/shared": "3.2.40",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7",
"postcss": "^8.1.10",
@ -1267,12 +1267,12 @@
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.41.tgz",
"integrity": "sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.40.tgz",
"integrity": "sha512-80cQcgasKjrPPuKcxwuCx7feq+wC6oFl5YaKSee9pV3DNq+6fmCVwEEC3vvkf/E2aI76rIJSOYHsWSEIxK74oQ==",
"dependencies": {
"@vue/compiler-dom": "3.2.41",
"@vue/shared": "3.2.41"
"@vue/compiler-dom": "3.2.40",
"@vue/shared": "3.2.40"
}
},
"node_modules/@vue/component-compiler-utils": {
@ -1346,21 +1346,21 @@
"peer": true
},
"node_modules/@vue/reactivity": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.41.tgz",
"integrity": "sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.40.tgz",
"integrity": "sha512-N9qgGLlZmtUBMHF9xDT4EkD9RdXde1Xbveb+niWMXuHVWQP5BzgRmE3SFyUBBcyayG4y1lhoz+lphGRRxxK4RA==",
"dependencies": {
"@vue/shared": "3.2.41"
"@vue/shared": "3.2.40"
}
},
"node_modules/@vue/reactivity-transform": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.41.tgz",
"integrity": "sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.40.tgz",
"integrity": "sha512-HQUCVwEaacq6fGEsg2NUuGKIhUveMCjOk8jGHqLXPI2w6zFoPrlQhwWEaINTv5kkZDXKEnCijAp+4gNEHG03yw==",
"dependencies": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.41",
"@vue/shared": "3.2.41",
"@vue/compiler-core": "3.2.40",
"@vue/shared": "3.2.40",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7"
}
@ -1374,40 +1374,40 @@
}
},
"node_modules/@vue/runtime-core": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.41.tgz",
"integrity": "sha512-0LBBRwqnI0p4FgIkO9q2aJBBTKDSjzhnxrxHYengkAF6dMOjeAIZFDADAlcf2h3GDALWnblbeprYYpItiulSVQ==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.40.tgz",
"integrity": "sha512-U1+rWf0H8xK8aBUZhnrN97yoZfHbjgw/bGUzfgKPJl69/mXDuSg8CbdBYBn6VVQdR947vWneQBFzdhasyzMUKg==",
"dependencies": {
"@vue/reactivity": "3.2.41",
"@vue/shared": "3.2.41"
"@vue/reactivity": "3.2.40",
"@vue/shared": "3.2.40"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.41.tgz",
"integrity": "sha512-U7zYuR1NVIP8BL6jmOqmapRAHovEFp7CSw4pR2FacqewXNGqZaRfHoNLQsqQvVQ8yuZNZtxSZy0FFyC70YXPpA==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.40.tgz",
"integrity": "sha512-AO2HMQ+0s2+MCec8hXAhxMgWhFhOPJ/CyRXnmTJ6XIOnJFLrH5Iq3TNwvVcODGR295jy77I6dWPj+wvFoSYaww==",
"dependencies": {
"@vue/runtime-core": "3.2.41",
"@vue/shared": "3.2.41",
"@vue/runtime-core": "3.2.40",
"@vue/shared": "3.2.40",
"csstype": "^2.6.8"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.41.tgz",
"integrity": "sha512-7YHLkfJdTlsZTV0ae5sPwl9Gn/EGr2hrlbcS/8naXm2CDpnKUwC68i1wGlrYAfIgYWL7vUZwk2GkYLQH5CvFig==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.40.tgz",
"integrity": "sha512-gtUcpRwrXOJPJ4qyBpU3EyxQa4EkV8I4f8VrDePcGCPe4O/hd0BPS7v9OgjIQob6Ap8VDz9G+mGTKazE45/95w==",
"dependencies": {
"@vue/compiler-ssr": "3.2.41",
"@vue/shared": "3.2.41"
"@vue/compiler-ssr": "3.2.40",
"@vue/shared": "3.2.40"
},
"peerDependencies": {
"vue": "3.2.41"
"vue": "3.2.40"
}
},
"node_modules/@vue/shared": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.41.tgz",
"integrity": "sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw=="
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.40.tgz",
"integrity": "sha512-0PLQ6RUtZM0vO3teRfzGi4ltLUO5aO+kLgwh4Um3THSR03rpQWLTuRCkuO5A41ITzwdWeKdPHtSARuPkoo5pCQ=="
},
"node_modules/@vue/vue-loader-v15": {
"name": "vue-loader",
@ -1451,13 +1451,13 @@
"peer": true
},
"node_modules/@vueuse/core": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.3.1.tgz",
"integrity": "sha512-xriyD+v3D2ObH/UtnkEl+1sbcLBVHNaZaLi/rqoNEe/B92hggDEFQIGXoQUjdRzYOjASHSezf9uCDtmd7LeWyA==",
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.3.0.tgz",
"integrity": "sha512-64Rna8IQDWpdrJxgitDg7yv1yTp41ZmvV8zlLEylK4QQLWAhz1OFGZDPZ8bU4lwcGgbEJ2sGi2jrdNh4LttUSQ==",
"dependencies": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.3.1",
"@vueuse/shared": "9.3.1",
"@types/web-bluetooth": "^0.0.15",
"@vueuse/metadata": "9.3.0",
"@vueuse/shared": "9.3.0",
"vue-demi": "*"
},
"funding": {
@ -1490,17 +1490,17 @@
}
},
"node_modules/@vueuse/metadata": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.3.1.tgz",
"integrity": "sha512-G1BPhtx3OHaL/y4OZBofh6Xt02G1VA9PuOO8nac9sTKMkMqfyez5VfkF3D9GUjSRNO7cVWyH4rceeGXfr2wdMg==",
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.3.0.tgz",
"integrity": "sha512-GnnfjbzIPJIh9ngL9s9oGU1+Hx/h5/KFqTfJykzh/1xjaHkedV9g0MASpdmPZIP+ynNhKAcEfA6g5i8KXwtoMA==",
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/@vueuse/shared": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.3.1.tgz",
"integrity": "sha512-YFu3qcnVeu0S2L4XdQJtBpDcjz6xwqHZtTv/XRhu66/yge1XVhxskUcc7VZbX52xF9A34V6KCfwncP9YDqYFiw==",
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.3.0.tgz",
"integrity": "sha512-caGUWLY0DpPC6l31KxeUy6vPVNA0yKxx81jFYLoMpyP6cF84FG5Dkf69DfSUqL57wX8JcUkJDMnQaQIZPWFEQQ==",
"dependencies": {
"vue-demi": "*"
},
@ -2307,9 +2307,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001422",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001422.tgz",
"integrity": "sha512-hSesn02u1QacQHhaxl/kNMZwqVG35Sz/8DgvmgedxSH8z9UUpcDYSPYgsj3x5dQNRcNp6BwpSfQfVzYUTm+fog==",
"version": "1.0.30001418",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz",
"integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==",
"dev": true,
"funding": [
{
@ -3561,15 +3561,15 @@
"peer": true
},
"node_modules/electron-to-chromium": {
"version": "1.4.284",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
"integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==",
"version": "1.4.279",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.279.tgz",
"integrity": "sha512-xs7vEuSZ84+JsHSTFqqG0TE3i8EAivHomRQZhhcRvsmnjsh5C2KdhwNKf4ZRYtzq75wojpFyqb62m32Oam57wA==",
"dev": true
},
"node_modules/element-plus": {
"version": "2.2.18",
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.2.18.tgz",
"integrity": "sha512-2pK2zmVOwP14eFl3rGoR+3BWJwDyO+DZCvzjQ8L6qjUR+hVKwFhgxIcSkKJatbcHFw5Xui6UyN20jV+gQP7mLg==",
"version": "2.2.17",
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.2.17.tgz",
"integrity": "sha512-MGwMIE/q+FFD3kgS23x8HIe5043tmD1cTRwjhIX9o6fim1avFnUkrsfYRvybbz4CkyqSb185EheZS5AUPpXh2g==",
"dependencies": {
"@ctrl/tinycolor": "^3.4.1",
"@element-plus/icons-vue": "^2.0.6",
@ -5193,9 +5193,9 @@
}
},
"node_modules/is-core-module": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
"integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
"dev": true,
"dependencies": {
"has": "^1.0.3"
@ -6865,9 +6865,9 @@
}
},
"node_modules/postcss": {
"version": "8.4.18",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz",
"integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==",
"version": "8.4.17",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz",
"integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==",
"funding": [
{
"type": "opencollective",
@ -8180,13 +8180,10 @@
}
},
"node_modules/shell-quote": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz",
"integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz",
"integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==",
"dev": true
},
"node_modules/side-channel": {
"version": "1.0.4",
@ -8889,9 +8886,9 @@
}
},
"node_modules/ufo": {
"version": "0.8.6",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.8.6.tgz",
"integrity": "sha512-fk6CmUgwKCfX79EzcDQQpSCMxrHstvbLswFChHS0Vump+kFkw7nJBfTZoC1j0bOGoY9I7R3n2DGek5ajbcYnOw==",
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.8.5.tgz",
"integrity": "sha512-e4+UtA5IRO+ha6hYklwj6r7BjiGMxS0O+UaSg9HbaTefg4kMkzj4tXzEBajRR+wkxf+golgAWKzLbytCUDMJAA==",
"dev": true
},
"node_modules/unimport": {
@ -9187,15 +9184,15 @@
}
},
"node_modules/vue": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.41.tgz",
"integrity": "sha512-uuuvnrDXEeZ9VUPljgHkqB5IaVO8SxhPpqF2eWOukVrBnRBx2THPSGQBnVRt0GrIG1gvCmFXMGbd7FqcT1ixNQ==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.40.tgz",
"integrity": "sha512-1mGHulzUbl2Nk3pfvI5aXYYyJUs1nm4kyvuz38u4xlQkLUn1i2R7nDbI4TufECmY8v1qNBHYy62bCaM+3cHP2A==",
"dependencies": {
"@vue/compiler-dom": "3.2.41",
"@vue/compiler-sfc": "3.2.41",
"@vue/runtime-dom": "3.2.41",
"@vue/server-renderer": "3.2.41",
"@vue/shared": "3.2.41"
"@vue/compiler-dom": "3.2.40",
"@vue/compiler-sfc": "3.2.40",
"@vue/runtime-dom": "3.2.40",
"@vue/server-renderer": "3.2.40",
"@vue/shared": "3.2.40"
}
},
"node_modules/vue-clipboard3": {
@ -10077,21 +10074,21 @@
"dev": true
},
"@babel/core": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.6.tgz",
"integrity": "sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==",
"version": "7.19.3",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz",
"integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==",
"dev": true,
"requires": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.18.6",
"@babel/generator": "^7.19.6",
"@babel/generator": "^7.19.3",
"@babel/helper-compilation-targets": "^7.19.3",
"@babel/helper-module-transforms": "^7.19.6",
"@babel/helpers": "^7.19.4",
"@babel/parser": "^7.19.6",
"@babel/helper-module-transforms": "^7.19.0",
"@babel/helpers": "^7.19.0",
"@babel/parser": "^7.19.3",
"@babel/template": "^7.18.10",
"@babel/traverse": "^7.19.6",
"@babel/types": "^7.19.4",
"@babel/traverse": "^7.19.3",
"@babel/types": "^7.19.3",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@ -10100,9 +10097,9 @@
}
},
"@babel/generator": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.6.tgz",
"integrity": "sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA==",
"version": "7.19.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.5.tgz",
"integrity": "sha512-DxbNz9Lz4aMZ99qPpO1raTbcrI1ZeYh+9NR9qhfkQIbFtVEqotHojEBxHzmxhVONkGt6VyrqVQcgpefMy9pqcg==",
"dev": true,
"requires": {
"@babel/types": "^7.19.4",
@ -10170,19 +10167,19 @@
}
},
"@babel/helper-module-transforms": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.6.tgz",
"integrity": "sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==",
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz",
"integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==",
"dev": true,
"requires": {
"@babel/helper-environment-visitor": "^7.18.9",
"@babel/helper-module-imports": "^7.18.6",
"@babel/helper-simple-access": "^7.19.4",
"@babel/helper-simple-access": "^7.18.6",
"@babel/helper-split-export-declaration": "^7.18.6",
"@babel/helper-validator-identifier": "^7.19.1",
"@babel/helper-validator-identifier": "^7.18.6",
"@babel/template": "^7.18.10",
"@babel/traverse": "^7.19.6",
"@babel/types": "^7.19.4"
"@babel/traverse": "^7.19.0",
"@babel/types": "^7.19.0"
}
},
"@babel/helper-simple-access": {
@ -10244,9 +10241,9 @@
}
},
"@babel/parser": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.6.tgz",
"integrity": "sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA=="
"version": "7.19.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.4.tgz",
"integrity": "sha512-qpVT7gtuOLjWeDTKLkJ6sryqLliBaFpAtGeqw5cs5giLldvh+Ch0plqnUMKoVAUS6ZEueQQiZV+p5pxtPitEsA=="
},
"@babel/template": {
"version": "7.18.10",
@ -10260,18 +10257,18 @@
}
},
"@babel/traverse": {
"version": "7.19.6",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.6.tgz",
"integrity": "sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ==",
"version": "7.19.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.4.tgz",
"integrity": "sha512-w3K1i+V5u2aJUOXBFFC5pveFLmtq1s3qcdDNC2qRI6WPBQIDaKFqXxDEqDO/h1dQ3HjsZoZMyIy6jGLq0xtw+g==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.18.6",
"@babel/generator": "^7.19.6",
"@babel/generator": "^7.19.4",
"@babel/helper-environment-visitor": "^7.18.9",
"@babel/helper-function-name": "^7.19.0",
"@babel/helper-hoist-variables": "^7.18.6",
"@babel/helper-split-export-declaration": "^7.18.6",
"@babel/parser": "^7.19.6",
"@babel/parser": "^7.19.4",
"@babel/types": "^7.19.4",
"debug": "^4.1.0",
"globals": "^11.1.0"
@ -10312,9 +10309,9 @@
"integrity": "sha512-bO37brCPfteXQfFY0DyNDGB3+IMe4j150KFQcgJ5aBP295p9nBGeHEs/p0czrRbtlHq4Px/yoPXO/+dOCcF4uA=="
},
"@floating-ui/dom": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.3.tgz",
"integrity": "sha512-6H1kwjkOZKabApNtXRiYHvMmYJToJ1DV7rQ3xc/WJpOABhQIOJJOdz2AOejj8X+gcybaFmBpisVTZxBZAM3V0w==",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.0.2.tgz",
"integrity": "sha512-5X9WSvZ8/fjy3gDu8yx9HAA4KG1lazUN2P4/VnaXLxTO9Dz53HI1oYoh1OlhqFNlHgGDiwFX5WhFCc2ljbW3yA==",
"requires": {
"@floating-ui/core": "^1.0.1"
}
@ -10386,9 +10383,9 @@
"dev": true
},
"@jridgewell/trace-mapping": {
"version": "0.3.17",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
"version": "0.3.16",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.16.tgz",
"integrity": "sha512-LCQ+NeThyJ4k1W2d+vIKdxuSt9R3pQSZ4P92m7EakaYuXcVWbHuT5bjNcqLd4Rdgi6xYWYDvBJZJLZSLanjDcA==",
"dev": true,
"requires": {
"@jridgewell/resolve-uri": "3.1.0",
@ -10607,9 +10604,9 @@
}
},
"@types/eslint": {
"version": "8.4.7",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.7.tgz",
"integrity": "sha512-ehM7cCt2RSFs42mb+lcmhFT9ouIlV92PuaeRGn8N8c98oMjG4Z5pJHA9b1QiCcuqnbPSHcyfiD3mlhqMaHsQIw==",
"version": "8.4.6",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.6.tgz",
"integrity": "sha512-/fqTbjxyFUaYNO7VcW5g+4npmqVACz1bB7RTHYuLj+PRjw9hrCwrUXVQFpChUS0JsyEFvMZ7U/PfmvWgxJhI9g==",
"dev": true,
"requires": {
"@types/estree": "*",
@ -10708,9 +10705,9 @@
"peer": true
},
"@types/node": {
"version": "18.11.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.2.tgz",
"integrity": "sha512-BWN3M23gLO2jVG8g/XHIRFWiiV4/GckeFIqbU/C4V3xpoBBWSMk4OZomouN0wCkfQFPqgZikyLr7DOYDysIkkw==",
"version": "18.8.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.8.4.tgz",
"integrity": "sha512-WdlVphvfR/GJCLEMbNA8lJ0lhFNBj4SW3O+O5/cEGw9oYrv0al9zTwuQsq+myDUXgNx2jgBynoVgZ2MMJ6pbow==",
"dev": true
},
"@types/normalize-package-data": {
@ -10778,9 +10775,9 @@
}
},
"@types/web-bluetooth": {
"version": "0.0.16",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
"version": "0.0.15",
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.15.tgz",
"integrity": "sha512-w7hEHXnPMEZ+4nGKl/KDRVpxkwYxYExuHOYXyzIzCDzEZ9ZCGMAewulr9IqJu2LR4N37fcnb1XVeuZ09qgOxhA=="
},
"@types/webpack-env": {
"version": "1.18.0",
@ -10992,36 +10989,36 @@
}
},
"@vue/compiler-core": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.41.tgz",
"integrity": "sha512-oA4mH6SA78DT+96/nsi4p9DX97PHcNROxs51lYk7gb9Z4BPKQ3Mh+BLn6CQZBw857Iuhu28BfMSRHAlPvD4vlw==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.40.tgz",
"integrity": "sha512-2Dc3Stk0J/VyQ4OUr2yEC53kU28614lZS+bnrCbFSAIftBJ40g/2yQzf4mPBiFuqguMB7hyHaujdgZAQ67kZYA==",
"requires": {
"@babel/parser": "^7.16.4",
"@vue/shared": "3.2.41",
"@vue/shared": "3.2.40",
"estree-walker": "^2.0.2",
"source-map": "^0.6.1"
}
},
"@vue/compiler-dom": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.41.tgz",
"integrity": "sha512-xe5TbbIsonjENxJsYRbDJvthzqxLNk+tb3d/c47zgREDa/PCp6/Y4gC/skM4H6PIuX5DAxm7fFJdbjjUH2QTMw==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.2.40.tgz",
"integrity": "sha512-OZCNyYVC2LQJy4H7h0o28rtk+4v+HMQygRTpmibGoG9wZyomQiS5otU7qo3Wlq5UfHDw2RFwxb9BJgKjVpjrQw==",
"requires": {
"@vue/compiler-core": "3.2.41",
"@vue/shared": "3.2.41"
"@vue/compiler-core": "3.2.40",
"@vue/shared": "3.2.40"
}
},
"@vue/compiler-sfc": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.41.tgz",
"integrity": "sha512-+1P2m5kxOeaxVmJNXnBskAn3BenbTmbxBxWOtBq3mQTCokIreuMULFantBUclP0+KnzNCMOvcnKinqQZmiOF8w==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.2.40.tgz",
"integrity": "sha512-tzqwniIN1fu1PDHC3CpqY/dPCfN/RN1thpBC+g69kJcrl7mbGiHKNwbA6kJ3XKKy8R6JLKqcpVugqN4HkeBFFg==",
"requires": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.41",
"@vue/compiler-dom": "3.2.41",
"@vue/compiler-ssr": "3.2.41",
"@vue/reactivity-transform": "3.2.41",
"@vue/shared": "3.2.41",
"@vue/compiler-core": "3.2.40",
"@vue/compiler-dom": "3.2.40",
"@vue/compiler-ssr": "3.2.40",
"@vue/reactivity-transform": "3.2.40",
"@vue/shared": "3.2.40",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7",
"postcss": "^8.1.10",
@ -11039,12 +11036,12 @@
}
},
"@vue/compiler-ssr": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.41.tgz",
"integrity": "sha512-Y5wPiNIiaMz/sps8+DmhaKfDm1xgj6GrH99z4gq2LQenfVQcYXmHIOBcs5qPwl7jaW3SUQWjkAPKMfQemEQZwQ==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.2.40.tgz",
"integrity": "sha512-80cQcgasKjrPPuKcxwuCx7feq+wC6oFl5YaKSee9pV3DNq+6fmCVwEEC3vvkf/E2aI76rIJSOYHsWSEIxK74oQ==",
"requires": {
"@vue/compiler-dom": "3.2.41",
"@vue/shared": "3.2.41"
"@vue/compiler-dom": "3.2.40",
"@vue/shared": "3.2.40"
}
},
"@vue/component-compiler-utils": {
@ -11111,21 +11108,21 @@
}
},
"@vue/reactivity": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.41.tgz",
"integrity": "sha512-9JvCnlj8uc5xRiQGZ28MKGjuCoPhhTwcoAdv3o31+cfGgonwdPNuvqAXLhlzu4zwqavFEG5tvaoINQEfxz+l6g==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.2.40.tgz",
"integrity": "sha512-N9qgGLlZmtUBMHF9xDT4EkD9RdXde1Xbveb+niWMXuHVWQP5BzgRmE3SFyUBBcyayG4y1lhoz+lphGRRxxK4RA==",
"requires": {
"@vue/shared": "3.2.41"
"@vue/shared": "3.2.40"
}
},
"@vue/reactivity-transform": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.41.tgz",
"integrity": "sha512-mK5+BNMsL4hHi+IR3Ft/ho6Za+L3FA5j8WvreJ7XzHrqkPq8jtF/SMo7tuc9gHjLDwKZX1nP1JQOKo9IEAn54A==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/reactivity-transform/-/reactivity-transform-3.2.40.tgz",
"integrity": "sha512-HQUCVwEaacq6fGEsg2NUuGKIhUveMCjOk8jGHqLXPI2w6zFoPrlQhwWEaINTv5kkZDXKEnCijAp+4gNEHG03yw==",
"requires": {
"@babel/parser": "^7.16.4",
"@vue/compiler-core": "3.2.41",
"@vue/shared": "3.2.41",
"@vue/compiler-core": "3.2.40",
"@vue/shared": "3.2.40",
"estree-walker": "^2.0.2",
"magic-string": "^0.25.7"
},
@ -11141,37 +11138,37 @@
}
},
"@vue/runtime-core": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.41.tgz",
"integrity": "sha512-0LBBRwqnI0p4FgIkO9q2aJBBTKDSjzhnxrxHYengkAF6dMOjeAIZFDADAlcf2h3GDALWnblbeprYYpItiulSVQ==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.2.40.tgz",
"integrity": "sha512-U1+rWf0H8xK8aBUZhnrN97yoZfHbjgw/bGUzfgKPJl69/mXDuSg8CbdBYBn6VVQdR947vWneQBFzdhasyzMUKg==",
"requires": {
"@vue/reactivity": "3.2.41",
"@vue/shared": "3.2.41"
"@vue/reactivity": "3.2.40",
"@vue/shared": "3.2.40"
}
},
"@vue/runtime-dom": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.41.tgz",
"integrity": "sha512-U7zYuR1NVIP8BL6jmOqmapRAHovEFp7CSw4pR2FacqewXNGqZaRfHoNLQsqQvVQ8yuZNZtxSZy0FFyC70YXPpA==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.2.40.tgz",
"integrity": "sha512-AO2HMQ+0s2+MCec8hXAhxMgWhFhOPJ/CyRXnmTJ6XIOnJFLrH5Iq3TNwvVcODGR295jy77I6dWPj+wvFoSYaww==",
"requires": {
"@vue/runtime-core": "3.2.41",
"@vue/shared": "3.2.41",
"@vue/runtime-core": "3.2.40",
"@vue/shared": "3.2.40",
"csstype": "^2.6.8"
}
},
"@vue/server-renderer": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.41.tgz",
"integrity": "sha512-7YHLkfJdTlsZTV0ae5sPwl9Gn/EGr2hrlbcS/8naXm2CDpnKUwC68i1wGlrYAfIgYWL7vUZwk2GkYLQH5CvFig==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.2.40.tgz",
"integrity": "sha512-gtUcpRwrXOJPJ4qyBpU3EyxQa4EkV8I4f8VrDePcGCPe4O/hd0BPS7v9OgjIQob6Ap8VDz9G+mGTKazE45/95w==",
"requires": {
"@vue/compiler-ssr": "3.2.41",
"@vue/shared": "3.2.41"
"@vue/compiler-ssr": "3.2.40",
"@vue/shared": "3.2.40"
}
},
"@vue/shared": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.41.tgz",
"integrity": "sha512-W9mfWLHmJhkfAmV+7gDjcHeAWALQtgGT3JErxULl0oz6R6+3ug91I7IErs93eCFhPCZPHBs4QJS7YWEV7A3sxw=="
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.2.40.tgz",
"integrity": "sha512-0PLQ6RUtZM0vO3teRfzGi4ltLUO5aO+kLgwh4Um3THSR03rpQWLTuRCkuO5A41ITzwdWeKdPHtSARuPkoo5pCQ=="
},
"@vue/vue-loader-v15": {
"version": "npm:vue-loader@15.10.0",
@ -11204,13 +11201,13 @@
"peer": true
},
"@vueuse/core": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.3.1.tgz",
"integrity": "sha512-xriyD+v3D2ObH/UtnkEl+1sbcLBVHNaZaLi/rqoNEe/B92hggDEFQIGXoQUjdRzYOjASHSezf9uCDtmd7LeWyA==",
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-9.3.0.tgz",
"integrity": "sha512-64Rna8IQDWpdrJxgitDg7yv1yTp41ZmvV8zlLEylK4QQLWAhz1OFGZDPZ8bU4lwcGgbEJ2sGi2jrdNh4LttUSQ==",
"requires": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.3.1",
"@vueuse/shared": "9.3.1",
"@types/web-bluetooth": "^0.0.15",
"@vueuse/metadata": "9.3.0",
"@vueuse/shared": "9.3.0",
"vue-demi": "*"
},
"dependencies": {
@ -11223,14 +11220,14 @@
}
},
"@vueuse/metadata": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.3.1.tgz",
"integrity": "sha512-G1BPhtx3OHaL/y4OZBofh6Xt02G1VA9PuOO8nac9sTKMkMqfyez5VfkF3D9GUjSRNO7cVWyH4rceeGXfr2wdMg=="
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-9.3.0.tgz",
"integrity": "sha512-GnnfjbzIPJIh9ngL9s9oGU1+Hx/h5/KFqTfJykzh/1xjaHkedV9g0MASpdmPZIP+ynNhKAcEfA6g5i8KXwtoMA=="
},
"@vueuse/shared": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.3.1.tgz",
"integrity": "sha512-YFu3qcnVeu0S2L4XdQJtBpDcjz6xwqHZtTv/XRhu66/yge1XVhxskUcc7VZbX52xF9A34V6KCfwncP9YDqYFiw==",
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-9.3.0.tgz",
"integrity": "sha512-caGUWLY0DpPC6l31KxeUy6vPVNA0yKxx81jFYLoMpyP6cF84FG5Dkf69DfSUqL57wX8JcUkJDMnQaQIZPWFEQQ==",
"requires": {
"vue-demi": "*"
},
@ -11852,9 +11849,9 @@
}
},
"caniuse-lite": {
"version": "1.0.30001422",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001422.tgz",
"integrity": "sha512-hSesn02u1QacQHhaxl/kNMZwqVG35Sz/8DgvmgedxSH8z9UUpcDYSPYgsj3x5dQNRcNp6BwpSfQfVzYUTm+fog==",
"version": "1.0.30001418",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001418.tgz",
"integrity": "sha512-oIs7+JL3K9JRQ3jPZjlH6qyYDp+nBTCais7hjh0s+fuBwufc7uZ7hPYMXrDOJhV360KGMTcczMRObk0/iMqZRg==",
"dev": true
},
"case-sensitive-paths-webpack-plugin": {
@ -12787,15 +12784,15 @@
"peer": true
},
"electron-to-chromium": {
"version": "1.4.284",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
"integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==",
"version": "1.4.279",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.279.tgz",
"integrity": "sha512-xs7vEuSZ84+JsHSTFqqG0TE3i8EAivHomRQZhhcRvsmnjsh5C2KdhwNKf4ZRYtzq75wojpFyqb62m32Oam57wA==",
"dev": true
},
"element-plus": {
"version": "2.2.18",
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.2.18.tgz",
"integrity": "sha512-2pK2zmVOwP14eFl3rGoR+3BWJwDyO+DZCvzjQ8L6qjUR+hVKwFhgxIcSkKJatbcHFw5Xui6UyN20jV+gQP7mLg==",
"version": "2.2.17",
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.2.17.tgz",
"integrity": "sha512-MGwMIE/q+FFD3kgS23x8HIe5043tmD1cTRwjhIX9o6fim1avFnUkrsfYRvybbz4CkyqSb185EheZS5AUPpXh2g==",
"requires": {
"@ctrl/tinycolor": "^3.4.1",
"@element-plus/icons-vue": "^2.0.6",
@ -13941,9 +13938,9 @@
}
},
"is-core-module": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz",
"integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==",
"dev": true,
"requires": {
"has": "^1.0.3"
@ -15227,9 +15224,9 @@
}
},
"postcss": {
"version": "8.4.18",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz",
"integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==",
"version": "8.4.17",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.17.tgz",
"integrity": "sha512-UNxNOLQydcOFi41yHNMcKRZ39NeXlr8AxGuZJsdub8vIb12fHzcq37DTU/QtbI6WLxNg2gF9Z+8qtRwTj1UI1Q==",
"requires": {
"nanoid": "^3.3.4",
"picocolors": "^1.0.0",
@ -16158,9 +16155,9 @@
"dev": true
},
"shell-quote": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.4.tgz",
"integrity": "sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==",
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.3.tgz",
"integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==",
"dev": true
},
"side-channel": {
@ -16691,9 +16688,9 @@
"peer": true
},
"ufo": {
"version": "0.8.6",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.8.6.tgz",
"integrity": "sha512-fk6CmUgwKCfX79EzcDQQpSCMxrHstvbLswFChHS0Vump+kFkw7nJBfTZoC1j0bOGoY9I7R3n2DGek5ajbcYnOw==",
"version": "0.8.5",
"resolved": "https://registry.npmjs.org/ufo/-/ufo-0.8.5.tgz",
"integrity": "sha512-e4+UtA5IRO+ha6hYklwj6r7BjiGMxS0O+UaSg9HbaTefg4kMkzj4tXzEBajRR+wkxf+golgAWKzLbytCUDMJAA==",
"dev": true
},
"unimport": {
@ -16876,15 +16873,15 @@
}
},
"vue": {
"version": "3.2.41",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.41.tgz",
"integrity": "sha512-uuuvnrDXEeZ9VUPljgHkqB5IaVO8SxhPpqF2eWOukVrBnRBx2THPSGQBnVRt0GrIG1gvCmFXMGbd7FqcT1ixNQ==",
"version": "3.2.40",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.2.40.tgz",
"integrity": "sha512-1mGHulzUbl2Nk3pfvI5aXYYyJUs1nm4kyvuz38u4xlQkLUn1i2R7nDbI4TufECmY8v1qNBHYy62bCaM+3cHP2A==",
"requires": {
"@vue/compiler-dom": "3.2.41",
"@vue/compiler-sfc": "3.2.41",
"@vue/runtime-dom": "3.2.41",
"@vue/server-renderer": "3.2.41",
"@vue/shared": "3.2.41"
"@vue/compiler-dom": "3.2.40",
"@vue/compiler-sfc": "3.2.40",
"@vue/runtime-dom": "3.2.40",
"@vue/server-renderer": "3.2.40",
"@vue/shared": "3.2.40"
}
},
"vue-clipboard3": {

View File

@ -30,7 +30,6 @@
<PortForward v-if="global.currentPage.value=='#portforward'"></PortForward>
<PortForwardSet v-if="global.currentPage.value=='#portforwardset'"></PortForwardSet>
<WOL v-if="global.currentPage.value=='#wol'"></WOL>
<WOLServiceSet v-if="global.currentPage.value=='#wolserviceset'"></WOLServiceSet>
</el-main>
</el-container>

View File

@ -562,16 +562,6 @@ export function apiWOLDeviceWakeUp(key) {
})
}
export function apiWOLDeviceShutDown(key) {
return httpRequest({
url: '/api/wol/device/shutdown',
method: 'get',
headers:{'Authorization':GetToken()},
params:{_:new Date().valueOf(),key:key}
})
}
export function apiAlterWOLDevice(data) {
return httpRequest({
url: '/api/wol/device',
@ -580,43 +570,3 @@ export function apiAlterWOLDevice(data) {
data:data
})
}
export function apiGetWOLServiceConfigure() {
return httpRequest({
url: '/api/wol/service/configure',
method: 'get',
headers:{'Authorization':GetToken()},
params:{_:new Date().valueOf()}
})
}
export function apiAlterWOLServiceConfigure(data) {
return httpRequest({
url: '/api/wol/service/configure',
method: 'put',
headers:{'Authorization':GetToken()},
data:data,
params:{_:new Date().valueOf()}
})
}
export function apiGetIPv4Interface() {
return httpRequest({
url: 'api/wol/service/getipv4interface',
method: 'get',
headers:{'Authorization':GetToken()},
params:{_:new Date().valueOf()}
})
}
export function apiOptionsLuckyService(option) {
return httpRequest({
url: '/api/lucky/service',
method: 'put',
headers:{'Authorization':GetToken()},
params:{_:new Date().valueOf(),option:option}
})
}

View File

@ -3,7 +3,7 @@
.PageRadius {
height: 90vh;
width: 100%;
max-width: 1600px;
max-width: 1300px;
border: 1px solid var(--el-border-color);
border-radius: 0;
margin: 20px

View File

@ -65,19 +65,6 @@
</el-form-item>
</div>
<div class="AdminListenDivRadius">
<p>全局设置</p>
<el-form-item label="Http(s) 客户端 安全证书验证" id="adminListen">
<el-switch v-model="form.HttpClientSecureVerify" class="mb-1" inline-prompt
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" width="50px"
active-text="启用" inactive-text="禁用" />
</el-form-item>
<el-form-item label="HttpClient timeout(秒)" >
<el-input-number v-model="form.HttpClientTimeout" autocomplete="off" :min="1" :max="60" />
</el-form-item>
</div>
@ -202,8 +189,6 @@ const rawData = {
// GlobalMaxConnections: 1,
AllowInternetaccess: false,
LogMaxSize:1024,
HttpClientSecureVerify:false,
HttpClientTimeout:20,
}
const form = ref(rawData)

View File

@ -113,13 +113,11 @@
<template #title>网络唤醒设备列表</template>
</el-menu-item>
<el-menu-item index="#wolserviceset">
<el-menu-item index="#wolset">
<el-icon>
<setting />
</el-icon>
<template #title>唤醒/关机服务设置</template>
<template #title>网络唤醒设置</template>
</el-menu-item>
</el-sub-menu>

View File

@ -1033,10 +1033,6 @@ onMounted(() => {
})
onUnmounted(() => {
clearInterval(timerID)
})
</script>

View File

@ -154,6 +154,7 @@ const RequestAlterPortForwardConfigure = () => {
onMounted(() => {
queryPortForwardsConfigure()
})
</script>

View File

@ -7,49 +7,27 @@
<div class="itemradius" :style="{
borderRadius: 'base',
}">
}" v-for="device in deviceList" >
<el-descriptions :column="4" border>
<div v-for="device in deviceList">
<el-descriptions-item label="设备" label-class-name="deviceNamelabelClass"
class-name="deviceNamecontentClass">
<el-button size="small" v-show="true">
{{ device.DeviceName == '' ? '未命名设备' : device.DeviceName }}
</el-button>
<el-descriptions :column="4" border >
<el-descriptions-item label="设备操作">
<el-tooltip placement="bottom" effect="dark" :trigger-keys="[]" content="">
<template #content>
<span v-html="deviceOnlieDeviceToBrHtml(device)"></span>
唤醒<br />
</template>
<el-button size="small" v-show="true">
{{device.State}}
<el-button size="small" :icon="Bell" circle type="success" @click="wakeup(device)">
</el-button>
</el-tooltip>
</el-descriptions-item>
<el-descriptions-item label="操作" label-class-name="deviceOptlabelClass"
class-name="deviceOptcontentClass">
<el-button size="small" type="success" @click="wakeup(device)">
唤醒
</el-button>
<el-tooltip placement="bottom" effect="dark" :trigger-keys="[]" content="">
<template #content>
关机<br />
</template>
<el-button size="small" type="danger" @click="shutdown(device)"
:disabled="avalidShutDownButton(device.State)">
关机
<el-button size="small" :icon="SwitchButton" circle type="danger">
</el-button>
</el-tooltip>
&nbsp; &nbsp;
<el-divider direction="vertical" />
&nbsp; &nbsp;
<el-button size="small" type="primary" @click="showAlterDeviceDialog(device)">
@ -61,18 +39,25 @@
</el-button>
</el-descriptions-item>
<el-descriptions-item label="物理网卡地址" label-class-name="deviceMaclabelClass"
class-name="deviceMaccontentClass">
<el-descriptions-item label="设备名称" >
<el-button size="default" v-show="true">
{{ device.DeviceName == '' ? '未命名设备' : device.DeviceName }}
</el-button>
</el-descriptions-item>
<el-descriptions-item label="设备MAC">
<el-tooltip placement="bottom" effect="dark" :trigger-keys="[]" content="">
<template #content>
物理网卡地址<br />
<span v-html="StrArrayListToBrHtml(device.MacList)"></span>
<br />
魔法包地址<br />
<span v-html="StrArrayListToBrHtml(device.BroadcastIPs)"></span>
<br />
端口: {{device.Port}} <br />
</template>
<el-button size="small" v-show="true">
{{device.MacList.length==1?device.MacList[0]:device.MacList[0]+'...' }}
@ -80,37 +65,31 @@
</el-tooltip>
</el-descriptions-item>
<el-descriptions-item label="物联网平台" label-class-name="deviceIOTlabelClass"
class-name="deviceIOTcontentClass">
<el-descriptions-item label="魔法包广播地址">
<el-tooltip placement="bottom" effect="dark" :trigger-keys="[]" content="">
<template #content>
<span v-html="showIOT_DianDengInfo(device)"></span>
<span v-html="StrArrayListToBrHtml(device.BroadcastIPs)"></span>
</template>
<el-button size="small" v-show="device.IOT_DianDeng_Enable"
:type="showIOT_DianDengColor(device)">
点灯科技
<el-button size="small" v-show="true">
{{device.BroadcastIPs.length==1?device.BroadcastIPs[0]:device.BroadcastIPs[0]+'...' }}
</el-button>
</el-tooltip>
<el-tooltip placement="bottom" effect="dark" :trigger-keys="[]" content="">
<el-tooltip class="box-item" effect="dark" :trigger-keys="[]" content="">
<template #content>
<span v-html="showIOT_BemfaInfo(device)"></span>
端口<br />
</template>
<el-button size="small" v-show="device.IOT_Bemfa_Enable"
:type="showIOT_BemfaColor(device)">
巴法云
<el-button size="small" v-show="true">
{{device.Port}}
</el-button>
</el-tooltip>
</el-tooltip>
</el-descriptions-item>
</div>
</el-descriptions>
@ -128,7 +107,7 @@
</el-affix>
<el-dialog v-if="deviceDialogShow" v-model="deviceDialogShow" :title=deviceDialogTitle draggable
:show-close="true" :close-on-click-modal="false" width="400px">
:show-close="false" :close-on-click-modal="false" width="400px">
<el-form-item label="设备名称" label-width="120px">
<el-input v-model="deviceForm.DeviceName" autocomplete="off" />
</el-form-item>
@ -197,89 +176,6 @@
</el-form-item>
</el-tooltip>
<div class="divRadius">
<p>第三方物联网平台对接-仅支持语音助手控制</p>
<div class="divIOTRadius">
<el-form-item label="点灯科技" label-width="120px" v-if="true">
<el-switch v-model="deviceForm.IOT_DianDeng_Enable" inline-prompt width="50px" active-text="启用"
inactive-text="禁用" />
</el-form-item>
<div v-show="deviceForm.IOT_DianDeng_Enable">
<el-tooltip class="box-item" effect="dark" :trigger-keys="[]" content="">
<template #content>
留空表示不启用该平台对接功能<br />
<br />
点灯科技官网:https://www.diandeng.tech/home<br />
<br />
在手机APP端注册登录-设备管理菜单-右上方+号按钮-添加点灯独立设备-选择网络接入-复制保存-secrte-key到下方<br />
目前仅支持点灯-独立设备类型,在设备管理修改设备名,这里的设备名就是你以后用语音助手控制操作设备时的名称.<br />
<br />
以小爱同学为例,在米家APP右下角"我的"-"其它平台设备"-右上方"添加"-选择"点灯科技"登录同步后即可.<br />
需要确保点灯secrte-key填写正确,在点灯APP已经显示设备在线再在米家执行同步,每次修改完设备名都要重新同步.<br />
小度/天猫精灵自行参考文档:https://www.diandeng.tech/doc/voice-assistant <br />
<br />
多个设备可以设置同一个secrte-key,表示多个待唤醒设备与同一个点灯设备绑定,一次语音操作同时控制多个设备的开关.不建议这样做.<br />
建议一个待唤醒设备对应一个点灯设备<br />
<br />
由于点灯接口偶尔发生变化,又不提供相关文档,所以哪天突然不能使用了也很正常.<br />
</template>
<el-form-item label-width="120px" label="设备密钥">
<el-input v-model="deviceForm.IOT_DianDeng_AUTHKEY" placeholder="设备密钥" type="text"
wrap="off">
</el-input>
</el-form-item>
</el-tooltip>
</div>
</div>
<div class="divIOTRadius">
<el-form-item label="巴法云" label-width="120px" v-if="true">
<el-switch v-model="deviceForm.IOT_Bemfa_Enable" inline-prompt width="50px" active-text="启用"
inactive-text="禁用" />
</el-form-item>
<div v-show="deviceForm.IOT_Bemfa_Enable">
<el-tooltip class="box-item" effect="dark" :trigger-keys="[]" content="">
<template #content>
留空表示不启用该平台对接功能<br />
<br />
巴法云官网:https://cloud.bemfa.com/<br />
<br />
注册登录后,在控制台右上方可查看私钥.<br />
目前仅支持MQTT设备云,记得创建的是MQTT设备云主题,而不是TCP创客云主题.主题名要以001结尾表示插座类型.<br />
<br />
以小爱同学为例,在米家APP右下角"我的"-"其它平台设备"-右上方"添加"-选择"巴法"登录同步后即可.<br />
需要确保私钥和主题填写正确,在控制台已经显示订阅设备在线再在米家执行同步,主题更多设置的右上方可修改昵称(在米家等平台显示的名称),每次修改完设备名都要重新同步.<br />
<br />
多个设备可以设置同一个主题,表示多个待唤醒设备与同一个主题绑定,一次语音操作同时控制多个设备的开关.不建议这样做.<br />
建议一个待唤醒设备对应一个主题<br />
<br />
<br />
</template>
<el-form-item label-width="120px" label="私钥">
<el-input v-model="deviceForm.IOT_Bemfa_SecretKey" placeholder="设备密钥" type="text"
wrap="off">
</el-input>
</el-form-item>
</el-tooltip>
<el-form-item label-width="120px" label="主题">
<el-input v-model="deviceForm.IOT_Bemfa_Topic" placeholder="订阅主题" type="text" wrap="off">
</el-input>
</el-form-item>
</div>
</div>
</div>
@ -297,11 +193,11 @@
</template>
<script lang="ts" setup>
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { ref, onMounted, computed } from 'vue'
import { ElMessageBox } from 'element-plus'
import { MessageShow } from '../../utils/ui'
import { StrArrayListToBrHtml, StrArrayListToArea, StringToArrayList } from '../../utils/utils'
import { GetToken, apiGetWOLDeviceList, apiAddWOLDevice, apiDeleteWOLDevice, apiAlterWOLDevice, apiWOLDeviceWakeUp, apiWOLDeviceShutDown } from '../../apis/utils'
import { GetToken, apiGetWOLDeviceList, apiAddWOLDevice, apiDeleteWOLDevice, apiAlterWOLDevice,apiWOLDeviceWakeUp } from '../../apis/utils'
import {
SwitchButton,
@ -309,16 +205,6 @@ import {
Bell,
} from '@element-plus/icons-vue'
const cellclass = {
"min-width": "50px",
"word-break": "keep-all"
}
const CS = {
"min-width": "300px",
"word-break": "break-all"
}
const deviceDialogShow = ref(false)
const deviceDialogTitle = ref("")
const deviceDialogCommitButtonText = ref("")
@ -326,51 +212,6 @@ const deviceFormMacListArea = ref("")
const deviceFormBroadcastIPsArea = ref("")
const deviceFormActionType = ref("")
const showIOT_DianDengInfo = (device) => {
var res = ""
if (device.DianDengClientState == "未设置") {
res = "未设置"
return res
}
res += '设备密钥:' + device.IOT_DianDeng_AUTHKEY + '<br/>'
res += '服务器连接状态:' + device.DianDengClientState + ' <br/>'
if (device.DianDengClientState == "已连接") {
res += '支持小爱同学 小度 天猫精灵<br/>'
}
return res
}
const showIOT_BemfaInfo = (device) => {
var res = ""
if (device.BemfaClientState == "未设置") {
res = "未设置"
return res
}
res += '私钥:' + device.IOT_Bemfa_SecretKey + '<br/>'
res += '订阅主题:' + device.IOT_Bemfa_Topic + '<br/>'
res += '服务器连接状态:' + device.BemfaClientState + ' <br/>'
if (device.BemfaClientState == "已连接") {
res += '支持小爱同学 小度 天猫精灵 google语音 AmazonAlexa<br/>'
}
return res
}
const showIOT_DianDengColor = (device) => {
if (device.DianDengClientState == "已连接") {
return "success"
}
return "info"
}
const showIOT_BemfaColor = (device) => {
if (device.BemfaClientState == "已连接") {
return "success"
}
return "info"
}
const deviceList = ref([{
Key: "",
DeviceName: "",
@ -379,15 +220,6 @@ const deviceList = ref([{
Port: 9,
Relay: true,
Repeat: 5,
State: "",
OnlineMacList: [''],
IOT_DianDeng_Enable: false,
IOT_DianDeng_AUTHKEY: "",
DianDengClientState: "",
IOT_Bemfa_Enable: false,
IOT_Bemfa_SecretKey: "",
IOT_Bemfa_Topic: "",
BemFaClientState: "",
},])
const deviceForm = ref({
@ -398,31 +230,12 @@ const deviceForm = ref({
Port: 9,
Relay: true,
Repeat: 5,
IOT_DianDeng_Enable: false,
IOT_DianDeng_AUTHKEY: "",
IOT_Bemfa_SecretKey: "",
IOT_Bemfa_Topic: "",
IOT_Bemfa_Enable: false,
})
const deviceOnlieDeviceToBrHtml = (device) => {
if (device.OnlineMacList == undefined || device.OnlineMacList == null || device.OnlineMacList.length <= 0) {
return "没有设备在线"
}
const deleteDevice = (device)=>{
var resHtml = "在线设备列表:<br />"
for (let i in device.OnlineMacList) {
resHtml += device.OnlineMacList[i] + '<br />'
}
return resHtml
}
const deleteDevice = (device) => {
const deviceName = device.DeviceName == "" ? device.MacList[0] : device.DeviceName;
const deviceText = "[" + deviceName + "]"
const deviceName = device.DeviceName==""?device.MacList[0]:device.DeviceName;
const deviceText = "[" + deviceName +"]"
ElMessageBox.confirm(
'确认要删除待唤醒设备 ' + deviceText + "?",
@ -455,22 +268,7 @@ const deleteDevice = (device) => {
}
const wakeup = (device) => {
const deviceName = device.DeviceName == "" ? device.MacList[0] : device.DeviceName;
const deviceText = "[" + deviceName + "]"
ElMessageBox.confirm(
'确认要唤醒设备 ' + deviceText + "?",
'Warning',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
const wakeup = (device)=>{
apiWOLDeviceWakeUp(device.Key).then((res) => {
if (res.ret == 0) {
MessageShow("success", "唤醒指令已发送")
@ -482,54 +280,7 @@ const wakeup = (device) => {
console.log("唤醒指令发送失败,网络请求出错:" + error)
MessageShow("error", "唤醒指令发送失败,网络请求出错")
})
})
}
const shutdown = (device) => {
const deviceName = device.DeviceName == "" ? device.MacList[0] : device.DeviceName;
const deviceText = "[" + deviceName + "]"
ElMessageBox.confirm(
'确认要向设备 ' + deviceText + " 发送关机指令?",
'Warning',
{
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
apiWOLDeviceShutDown(device.Key).then((res) => {
if (res.ret == 0) {
MessageShow("success", "已向在线设备发送关机指令")
queryDeviceList();
return
}
MessageShow("error", res.msg)
}).catch((error) => {
console.log("关机指令发送失败,网络请求出错:" + error)
MessageShow("error", "关机指令发送失败,网络请求出错")
})
})
}
const avalidShutDownButton = (state: string) => {
let res = state.indexOf("在线");
console.log("show: " + res)
if (res >= 0) {
return false
}
return true
}
const addOreAlterDevice = () => {
@ -572,22 +323,16 @@ const addOreAlterDevice = () => {
}
}
const showAlterDeviceDialog = (device) => {
const showAlterDeviceDialog = (device)=>{
deviceDialogCommitButtonText.value = "修改"
deviceForm.value = {
Key: device.Key,
DeviceName: device.DeviceName,
MacList: device.MacList,
MacList:device.MacList,
BroadcastIPs: device.BroadcastIPs,
Port: device.Port,
Relay: device.Relay,
Repeat: device.Repeat,
IOT_DianDeng_Enable: device.IOT_DianDeng_Enable,
IOT_DianDeng_AUTHKEY: device.IOT_DianDeng_AUTHKEY,
IOT_Bemfa_SecretKey: device.IOT_Bemfa_SecretKey,
IOT_Bemfa_Topic: device.IOT_Bemfa_Topic,
IOT_Bemfa_Enable: device.IOT_Bemfa_Enable,
}
deviceFormActionType.value = "alter"
deviceFormMacListArea.value = StrArrayListToArea(device.MacList)
@ -605,11 +350,6 @@ const showAddDeviceDialog = () => {
Port: 9,
Relay: true,
Repeat: 5,
IOT_DianDeng_Enable: false,
IOT_DianDeng_AUTHKEY: "",
IOT_Bemfa_Enable: false,
IOT_Bemfa_SecretKey: "",
IOT_Bemfa_Topic: "",
}
deviceFormActionType.value = "add"
@ -642,80 +382,19 @@ onMounted(() => {
})
onUnmounted(() => {
clearInterval(timerID)
})
</script>
<style lang="scss">
<style scoped>
.itemradius {
border: 1px solid var(--el-border-color);
border-radius: 0;
margin-left: 3px;
margin-top: 3px;
margin-right: 3px;
margin-bottom: 5px;
min-width: 1200px;
border: 1px solid var(--el-border-color);
border-radius: 0;
margin-left: 3px;
margin-top: 3px;
margin-right: 3px;
margin-bottom: 5px;
min-width: 1200px;
}
.divRadius {
border: 2px solid var(--el-border-color);
border-radius: 10px;
margin-left: 3px;
margin-top: 15px;
margin-right: 3px;
margin-bottom: 15px;
width: 330px;
padding-top: 9px;
padding-left: 9px;
padding-right: 9px;
}
.divIOTRadius {
border: 2px solid var(--el-border-color);
border-radius: 10px;
margin-left: 3px;
margin-top: 15px;
margin-right: 3px;
margin-bottom: 15px;
width: 300px;
padding-top: 9px;
padding-left: 9px;
padding-right: 9px;
}
.deviceNamelabelClass {
width: 55px,
}
.deviceNamecontentClass {
width: 230px,
}
.deviceOptlabelClass {
width: 55px,
}
.deviceOptcontentClass {
width: 320px,
}
.deviceMaclabelClass {
width: 110px,
}
.deviceMaccontentClass {
width: 150px,
}
.deviceIOTlabelClass {
width: 90px,
}
.deviceIOTcontentClass {
width: 180px,
}
</style>

View File

@ -12,13 +12,10 @@ export function isIP(ip :string){
}
const MenuIndexList = ["#status",
"#log",
"#whitelistset","#whitelists","#blacklists",
"#set","#login","#about",
"#ddns","#ddnstasklist","#ddnsset",
"#reverseproxylist","#ssl",
"#portforward","#portforwardset",
"#wol","#wolserviceset"]
"#log","#whitelistset",
"#whitelists","#blacklists","#set",
"#login","#ddns","#ddnstasklist","#ddnsset",
"#about","#reverseproxylist","#ssl","#portforward","#portforwardset","#wol"]
export function PageExist(page:string) {
for(let i in MenuIndexList){

View File

@ -6,18 +6,17 @@ import (
"strconv"
"strings"
"github.com/gdy666/lucky/module/safe"
safeconf "github.com/gdy666/lucky/module/safe/conf"
"github.com/gdy666/lucky/config"
"github.com/gdy666/lucky/thirdlib/gdylib/ginutils"
"github.com/gin-gonic/gin"
)
func whitelistConfigure(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"ret": 0, "data": safe.GetWhiteListBaseConfigure()})
c.JSON(http.StatusOK, gin.H{"ret": 0, "data": config.GetWhiteListBaseConfigure()})
}
func alterWhitelistConfigure(c *gin.Context) {
var requestObj safeconf.WhiteListBaseConfigure
var requestObj config.WhiteListBaseConfigure
err := c.BindJSON(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "修改请求解析出错"})
@ -30,7 +29,7 @@ func alterWhitelistConfigure(c *gin.Context) {
return
}
err = safe.SetWhiteListBaseConfigure(requestObj.ActivelifeDuration, requestObj.URL, requestObj.BasicAccount, requestObj.BasicPassword)
err = config.SetWhiteListBaseConfigure(requestObj.ActivelifeDuration, requestObj.URL, requestObj.BasicAccount, requestObj.BasicPassword)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "保存白名单配置出错"})
@ -40,13 +39,13 @@ func alterWhitelistConfigure(c *gin.Context) {
}
func querywhitelist(c *gin.Context) {
resList := safe.GetWhiteList()
resList := config.GetWhiteList()
c.JSON(http.StatusOK, gin.H{"ret": 0, "data": resList})
}
func deleteblacklist(c *gin.Context) {
ip := c.Query("ip")
err := safe.BlackListDelete(ip)
err := config.BlackListDelete(ip)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "删除黑名单指定IP出错"})
return
@ -56,7 +55,7 @@ func deleteblacklist(c *gin.Context) {
func deletewhitelist(c *gin.Context) {
ip := c.Query("ip")
err := safe.WhiteListDelete(ip)
err := config.WhiteListDelete(ip)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "删除白名单指定IP出错"})
return
@ -69,7 +68,7 @@ func flushblacklist(c *gin.Context) {
activelifeDurationStr := c.Query("life")
life, _ := strconv.Atoi(activelifeDurationStr)
newTime, err := safe.BlackListAdd(ip, int32(life))
newTime, err := config.BlackListAdd(ip, int32(life))
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": fmt.Sprintf("刷新IP有效期出错:%s", err.Error())})
return
@ -82,7 +81,7 @@ func flushwhitelist(c *gin.Context) {
activelifeDurationStr := c.Query("life")
life, _ := strconv.Atoi(activelifeDurationStr)
newTime, err := safe.WhiteListAdd(ip, int32(life))
newTime, err := config.WhiteListAdd(ip, int32(life))
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": fmt.Sprintf("刷新IP有效期出错:%s", err.Error())})
return
@ -91,12 +90,12 @@ func flushwhitelist(c *gin.Context) {
}
func queryblacklist(c *gin.Context) {
resList := safe.GetBlackList()
resList := config.GetBlackList()
c.JSON(http.StatusOK, gin.H{"ret": 0, "data": resList})
}
func whitelistBasicAuth(c *gin.Context) {
bc := safe.GetWhiteListBaseConfigure()
bc := config.GetWhiteListBaseConfigure()
whilelistURL := c.Param("url")
if (c.Request.RequestURI == "/wl" && bc.URL != "") || whilelistURL != bc.URL {
c.AbortWithStatus(http.StatusNotFound)
@ -117,7 +116,7 @@ func whitelistBasicAuth(c *gin.Context) {
func whilelistAdd(c *gin.Context) {
lifeTime, err := safe.WhiteListAdd(c.ClientIP(), 0)
lifeTime, err := config.WhiteListAdd(c.ClientIP(), 0)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "记录白名单IP出错"})
return

View File

@ -5,16 +5,14 @@ import (
"net/http"
"strings"
ddnsconf "github.com/gdy666/lucky/module/ddns/conf"
"github.com/gdy666/lucky/module/ddns/ddnscore.go"
"github.com/gdy666/lucky/module/ddns/ddnsgo"
"github.com/gdy666/lucky/thirdlib/gdylib/dnsutils"
"github.com/gdy666/lucky/config"
"github.com/gdy666/lucky/ddnscore.go"
"github.com/gdy666/lucky/thirdlib/gdylib/service"
"github.com/gin-gonic/gin"
)
func addDDNS(c *gin.Context) {
var requestObj ddnsconf.DDNSTask
var requestObj config.DDNSTask
err := c.BindJSON(&requestObj)
if err != nil {
@ -22,7 +20,7 @@ func addDDNS(c *gin.Context) {
return
}
//fmt.Printf("addDDNS requestObj:%v\n", requestObj)
err = ddnsconf.CheckDDNSTaskAvalid(&requestObj)
err = config.CheckDDNSTaskAvalid(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": err.Error()})
return
@ -30,7 +28,7 @@ func addDDNS(c *gin.Context) {
dealRequestDDNSTask(&requestObj)
err = ddnsgo.DDNSTaskListAdd(&requestObj)
err = config.DDNSTaskListAdd(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "DDNS任务添加出错"})
return
@ -45,7 +43,7 @@ func addDDNS(c *gin.Context) {
func deleteDDNSTask(c *gin.Context) {
taskKey := c.Query("key")
err := ddnsgo.DDNSTaskListDelete(taskKey)
err := config.DDNSTaskListDelete(taskKey)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": fmt.Errorf("删除DDNS任务出错:%s", err.Error())})
return
@ -80,39 +78,34 @@ func enableddns(c *gin.Context) {
}
func ddnsconfigure(c *gin.Context) {
conf := ddnsgo.GetDDNSConfigure()
conf := config.GetDDNSConfigure()
c.JSON(http.StatusOK, gin.H{"ret": 0, "ddnsconfigure": conf})
}
func alterDDNSTask(c *gin.Context) {
taskKey := c.Query("key")
var requestObj ddnsconf.DDNSTask
var requestObj config.DDNSTask
err := c.BindJSON(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "请求解析出错"})
return
}
err = ddnsconf.CheckDDNSTaskAvalid(&requestObj)
err = config.CheckDDNSTaskAvalid(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": err.Error()})
return
}
dealRequestDDNSTask(&requestObj)
err = ddnsgo.UpdateTaskToDDNSTaskList(taskKey, requestObj)
err = config.UpdateTaskToDDNSTaskList(taskKey, requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": fmt.Sprintf("更新DDNS任务出错:%s", err.Error())})
return
}
//ddnscore.DDNSTaskInfoMapDelete(taskKey)
//ddnscore.syncDomains()
t := ddnscore.GetDDNSTaskInfoByKey(taskKey)
if t != nil {
t.SyncDomains()
}
ddnscore.DDNSTaskInfoMapDelete(taskKey)
if requestObj.Enable {
service.Message("ddns", "syncDDNSTask", taskKey)
@ -124,7 +117,7 @@ func alterDDNSTask(c *gin.Context) {
func ddnsTaskList(c *gin.Context) {
conf := ddnsgo.GetDDNSConfigure()
conf := config.GetDDNSConfigure()
if !conf.Enable {
c.JSON(http.StatusOK, gin.H{"ret": 6, "msg": "请先在设置页面启用DDNS动态域名服务"})
@ -137,7 +130,7 @@ func ddnsTaskList(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"ret": 0, "data": taskList})
}
func dealRequestDDNSTask(t *ddnsconf.DDNSTask) {
func dealRequestDDNSTask(t *config.DDNSTask) {
if t.DNS.Name == "callback" {
t.DNS.ID = ""
@ -146,7 +139,7 @@ func dealRequestDDNSTask(t *ddnsconf.DDNSTask) {
//requestObj.DNS.Callback.CallbackSuccessContent = strings.TrimSpace(requestObj.DNS.Callback.CallbackSuccessContent)
t.DNS.Callback.RequestBody = strings.TrimSpace(t.DNS.Callback.RequestBody)
} else {
t.DNS.Callback = ddnsconf.DNSCallback{}
t.DNS.Callback = config.DNSCallback{}
}
if !t.DNS.ResolverDoaminCheck && len(t.DNS.DNSServerList) > 0 {
@ -155,9 +148,9 @@ func dealRequestDDNSTask(t *ddnsconf.DDNSTask) {
if t.DNS.ResolverDoaminCheck && (len(t.DNS.DNSServerList) == 0 || (len(t.DNS.DNSServerList) == 1 && t.DNS.DNSServerList[0] == "")) {
if t.TaskType == "IPv6" {
t.DNS.DNSServerList = dnsutils.DefaultIPv6DNSServerList
t.DNS.DNSServerList = config.DefaultIPv6DNSServerList
} else {
t.DNS.DNSServerList = dnsutils.DefaultIPv4DNSServerList
t.DNS.DNSServerList = config.DefaultIPv4DNSServerList
}
}
@ -225,14 +218,14 @@ func dealRequestDDNSTask(t *ddnsconf.DDNSTask) {
}
func alterDDNSConfigure(c *gin.Context) {
var requestObj ddnsconf.DDNSConfigure
var requestObj config.DDNSConfigure
err := c.BindJSON(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "请求解析出错"})
return
}
preConfigure := ddnsgo.GetDDNSConfigure()
preConfigure := config.GetDDNSConfigure()
if preConfigure.Enable != requestObj.Enable {
@ -245,7 +238,7 @@ func alterDDNSConfigure(c *gin.Context) {
}
err = ddnsgo.SetDDNSConfigure(&requestObj)
err = config.SetDDNSConfigure(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 2, "msg": "保存配置过程发生错误,请检测相关启动配置"})
return

View File

@ -6,16 +6,14 @@ import (
"net/http"
"strconv"
"github.com/gdy666/lucky/module/portforward"
portforwardconf "github.com/gdy666/lucky/module/portforward/conf"
"github.com/gdy666/lucky/module/portforward/socketproxy"
"github.com/gdy666/lucky/module/weblog"
"github.com/gdy666/lucky/config"
"github.com/gdy666/lucky/socketproxy"
"github.com/gdy666/lucky/thirdlib/gdylib/stringsp"
"github.com/gin-gonic/gin"
)
type ruleInfo struct {
portforwardconf.PortForwardsRule
config.PortForwardsRule
ProxyList []proxyInfo
LastLogs []any
}
@ -27,7 +25,7 @@ type proxyInfo struct {
}
func PortForwardsRuleList(c *gin.Context) {
ruleRawList := portforward.GetPortForwardsRuleList()
ruleRawList := config.GetPortForwardsRuleList()
var ruleList []ruleInfo
@ -52,7 +50,7 @@ func PortForwardsRuleList(c *gin.Context) {
}
func PortForwardsRuleAdd(c *gin.Context) {
var newRule portforwardconf.PortForwardsRule
var newRule config.PortForwardsRule
err := c.Bind(&newRule)
if err != nil {
log.Printf("请求解析出错:%s", err.Error())
@ -67,24 +65,24 @@ func PortForwardsRuleAdd(c *gin.Context) {
return
}
if int64(portforward.GetPortForwardsGlobalProxyCount()+newRule.ProxyCount()) > socketproxy.GetGlobalMaxPortForwardsCountLimit() {
if int64(config.GetPortForwardsGlobalProxyCount()+newRule.ProxyCount()) > socketproxy.GetGlobalMaxPortForwardsCountLimit() {
c.JSON(http.StatusOK, gin.H{"ret": 3, "msg": "超出全局端口转发最大数量限制"})
return
}
err = portforward.PortForwardsRuleListAdd(&newRule)
err = config.PortForwardsRuleListAdd(&newRule)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 4, "msg": fmt.Sprintf("添加转发规则出错:%s", err.Error())})
return
}
portforward.StartAllSocketProxysByRuleKey(newRule.Key)
config.StartAllSocketProxysByRuleKey(newRule.Key)
c.JSON(http.StatusOK, gin.H{"ret": 0})
}
func PortForwardsRuleAlter(c *gin.Context) {
var alterRule portforwardconf.PortForwardsRule
var alterRule config.PortForwardsRule
err := c.Bind(&alterRule)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": fmt.Sprintf("请求解析出错:%s", err.Error())})
@ -97,21 +95,21 @@ func PortForwardsRuleAlter(c *gin.Context) {
return
}
if int64(portforward.GetPortForwardsGlobalProxyCountExcept(alterRule.Key)+alterRule.ProxyCount()) > socketproxy.GetGlobalMaxPortForwardsCountLimit() {
if int64(config.GetPortForwardsGlobalProxyCountExcept(alterRule.Key)+alterRule.ProxyCount()) > socketproxy.GetGlobalMaxPortForwardsCountLimit() {
c.JSON(http.StatusOK, gin.H{"ret": 3, "msg": "超出全局端口转发最大数量限制"})
return
}
portforward.StopAllSocketProxysByRuleKey(alterRule.Key)
config.StopAllSocketProxysByRuleKey(alterRule.Key)
err = portforward.UpdatePortForwardsRuleToPortForwardsRuleList(alterRule.Key, &alterRule)
err = config.UpdatePortForwardsRuleToPortForwardsRuleList(alterRule.Key, &alterRule)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 4, "msg": fmt.Sprintf("修改转发规则出错:%s", err.Error())})
return
}
if alterRule.Enable {
portforward.StartAllSocketProxysByRuleKey(alterRule.Key)
config.StartAllSocketProxysByRuleKey(alterRule.Key)
}
c.JSON(http.StatusOK, gin.H{"ret": 0})
@ -126,7 +124,7 @@ func PortForwardsRuleEnable(c *gin.Context) {
enable = true
}
err := portforward.EnablePortForwardsRuleByKey(key, enable)
err := config.EnablePortForwardsRuleByKey(key, enable)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": fmt.Sprintf("开关转发规则出错:%s", err.Error())})
return
@ -138,32 +136,32 @@ func PortForwardsRuleEnable(c *gin.Context) {
func PortForwardsRuleDelete(c *gin.Context) {
key := c.Query("key")
err := portforward.PortForwardsRuleListDelete(key)
err := config.PortForwardsRuleListDelete(key)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": fmt.Sprintf("删除转发规则出错:%s", err.Error())})
return
}
portforward.TidyPortforwardLogsCache()
config.TidyPortforwardLogsCache()
c.JSON(http.StatusOK, gin.H{"ret": 0})
}
func portforwardConfigure(c *gin.Context) {
conf := portforward.GetPortForwardsConfigure()
conf := config.GetPortForwardsConfigure()
c.JSON(http.StatusOK, gin.H{"ret": 0, "configure": conf})
}
func alterPortForwardConfigure(c *gin.Context) {
var requestObj portforwardconf.PortForwardsConfigure
var requestObj config.PortForwardsConfigure
err := c.BindJSON(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "请求解析出错"})
return
}
err = portforward.SetPortForwardsConfigure(&requestObj)
err = config.SetPortForwardsConfigure(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 2, "msg": "保存配置过程发生错误,请检测相关启动配置"})
return
@ -182,11 +180,11 @@ func getPortwardRuleLogs(c *gin.Context) {
page = 1
}
rule := portforward.GetPortForwardsRuleByKey(key)
rule := config.GetPortForwardsRuleByKey(key)
if rule == nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": fmt.Sprintf("找不到key:%s对应的规则", key)})
return
}
total, logList := rule.GetLogsBuffer().GetLogsByLimit(weblog.WebLogConvert, pageSize, page)
total, logList := rule.GetLogsBuffer().GetLogsByLimit(config.WebLogConvert, pageSize, page)
c.JSON(http.StatusOK, gin.H{"ret": 0, "total": total, "page": page, "pageSize": pageSize, "logs": logList})
}

View File

@ -7,8 +7,8 @@ import (
"strconv"
"strings"
"github.com/gdy666/lucky/module/reverseproxy"
reverseproxyconf "github.com/gdy666/lucky/module/reverseproxy/conf"
"github.com/gdy666/lucky/config"
"github.com/gdy666/lucky/reverseproxy"
"github.com/gdy666/lucky/thirdlib/gdylib/stringsp"
"github.com/gin-gonic/gin"
)
@ -20,7 +20,7 @@ func reverseProxys(c *gin.Context) {
}
func addReverseProxyRule(c *gin.Context) {
var requestObj reverseproxyconf.ReverseProxyRule
var requestObj config.ReverseProxyRule
err := c.BindJSON(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "请求解析出错"})
@ -33,7 +33,7 @@ func addReverseProxyRule(c *gin.Context) {
return
}
err = reverseproxy.ReverseProxyRuleListAdd(&requestObj)
err = config.ReverseProxyRuleListAdd(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 2, "msg": fmt.Sprintf("添加反向代理规则失败:%s", err.Error())})
@ -48,7 +48,7 @@ func addReverseProxyRule(c *gin.Context) {
}
func alterReverseProxyRule(c *gin.Context) {
var requestObj reverseproxyconf.ReverseProxyRule
var requestObj config.ReverseProxyRule
err := c.BindJSON(&requestObj)
if err != nil {
fmt.Printf("fff:%s\n", err.Error())
@ -62,7 +62,7 @@ func alterReverseProxyRule(c *gin.Context) {
return
}
err = reverseproxy.UpdateReverseProxyRulet(requestObj)
err = config.UpdateReverseProxyRulet(requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 2, "msg": fmt.Sprintf("修改反向代理规则失败:%s", err.Error())})
@ -75,7 +75,7 @@ func alterReverseProxyRule(c *gin.Context) {
reverseproxy.EnableRuleByKey(requestObj.RuleKey, true)
}
reverseproxy.TidyReverseProxyCache()
config.TidyReverseProxyCache()
c.JSON(http.StatusOK, gin.H{"ret": 0, "msg": ""})
}
@ -90,13 +90,13 @@ func deleteReverseProxyRule(c *gin.Context) {
return
}
err = reverseproxy.ReverseProxyRuleListDelete(ruleKey)
err = config.ReverseProxyRuleListDelete(ruleKey)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 3, "msg": fmt.Sprintf("删除反向代理规则出错:%s", err.Error())})
return
}
reverseproxy.TidyReverseProxyCache()
config.TidyReverseProxyCache()
c.JSON(http.StatusOK, gin.H{"ret": 0, "msg": ""})
}
@ -127,7 +127,7 @@ func enableReverseProxyRule(c *gin.Context) {
return
}
err := reverseproxy.EnableReverseProxySubRule(ruleKey, proxyKey, enable)
err := config.EnableReverseProxySubRule(ruleKey, proxyKey, enable)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": err.Error()})
return
@ -136,7 +136,7 @@ func enableReverseProxyRule(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"ret": 0, "msg": ""})
}
func checkReverseProxyRuleRequest(rule *reverseproxyconf.ReverseProxyRule) error {
func checkReverseProxyRuleRequest(rule *config.ReverseProxyRule) error {
// if len(rule.ProxyList) <= 0 {
// return fmt.Errorf("至少添加一条反向代理转发规则")
// }

View File

@ -5,13 +5,12 @@ import (
"log"
"net/http"
ssl "github.com/gdy666/lucky/module/sslcertficate"
sslconf "github.com/gdy666/lucky/module/sslcertficate/conf"
"github.com/gdy666/lucky/config"
"github.com/gin-gonic/gin"
)
func addSSL(c *gin.Context) {
var requestObj sslconf.SSLCertficate
var requestObj config.SSLCertficate
err := c.BindJSON(&requestObj)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": "请求解析出错"})
@ -26,7 +25,7 @@ func addSSL(c *gin.Context) {
}
//fmt.Printf("CertsInfo:%v\n", *requestObj.CertsInfo)
err = ssl.SSLCertficateListAdd(&requestObj)
err = config.SSLCertficateListAdd(&requestObj)
if err != nil {
log.Printf("config.SSLCertficateListAdd error:%s", err.Error())
c.JSON(http.StatusOK, gin.H{"ret": 2, "msg": fmt.Sprintf("添加SSL证书出错!:%s", err.Error())})
@ -42,11 +41,11 @@ type sslResInfo struct {
Remark string `json:"Remark"`
Enable bool `json:"Enable"`
AddTime string `json:"AddTime"`
CertsInfo *[]sslconf.CertInfo `json:"CertsInfo"`
CertsInfo *[]config.CertInfo `json:"CertsInfo"`
}
func getSSLCertficateList(c *gin.Context) {
rawList := ssl.GetSSLCertficateList()
rawList := config.GetSSLCertficateList()
var res []sslResInfo
for i := range rawList {
info := sslResInfo{
@ -75,11 +74,11 @@ func alterSSLCertficate(c *gin.Context) {
if value == "true" {
enable = true
}
err = ssl.SSLCertficateEnable(key, enable)
err = config.SSLCertficateEnable(key, enable)
}
case "remark":
{
err = ssl.SSLCertficateAlterRemark(key, value)
err = config.SSLCertficateAlterRemark(key, value)
}
default:
err = fmt.Errorf("不支持修改的字段:%s", field)
@ -94,7 +93,7 @@ func alterSSLCertficate(c *gin.Context) {
func deleteSSLCertficate(c *gin.Context) {
key := c.Query("key")
err := ssl.SSLCertficateListDelete(key)
err := config.SSLCertficateListDelete(key)
if err != nil {
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": err.Error()})
return

View File

@ -19,12 +19,9 @@ import (
"github.com/gin-contrib/gzip"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"github.com/gdy666/lucky/config"
"github.com/gdy666/lucky/module/portforward/socketproxy"
"github.com/gdy666/lucky/module/service"
ssl "github.com/gdy666/lucky/module/sslcertficate"
"github.com/gdy666/lucky/socketproxy"
"github.com/gdy666/lucky/thirdlib/gdylib/fileutils"
"github.com/gdy666/lucky/thirdlib/gdylib/ginutils"
"github.com/gdy666/lucky/thirdlib/gdylib/logsbuffer"
@ -34,8 +31,6 @@ import (
"github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/v3/mem"
"github.com/shirou/gopsutil/v3/process"
wolhttpapi "github.com/gdy666/lucky/module/wol/httpapi"
)
//go:embed adminviews/dist
@ -44,17 +39,12 @@ var stafs fs.FS
var loginErrorCount = int32(0)
var rebootOnce sync.Once
var logBuffer *logsbuffer.LogsBuffer
var logger *logrus.Logger
type LogItem struct {
Timestamp string `json:"timestamp"`
Content string `json:"log"`
}
func GetLogger() *logrus.Logger {
return logger
}
func logConvert(lg *logsbuffer.LogItem) any {
l := LogItem{Content: lg.Content, Timestamp: fmt.Sprintf("%d", lg.Timestamp)}
return l
@ -63,11 +53,8 @@ func logConvert(lg *logsbuffer.LogItem) any {
func init() {
stafs, _ = fs.Sub(staticFs, "adminviews/dist")
logBuffer = logsbuffer.Create(1024)
//logBuffer.SetLogItemConverFunc(logConvert)
log.SetOutput(io.MultiWriter(logBuffer, os.Stdout))
logger = logrus.New()
logger.SetOutput(logBuffer)
//logger.SetLevel(logrus.InfoLevel)
wolhttpapi.SetLogger(logger)
}
@ -147,13 +134,17 @@ func RunAdminWeb(conf *config.BaseConfigure) {
authorized.PUT("/api/ssl", alterSSLCertficate)
authorized.DELETE("/api/ssl", deleteSSLCertficate)
authorized.POST("/api/wol/device", addWOLDevice)
authorized.GET("/api/wol/device/wakeup", WOLDeviceWakeUp)
authorized.GET("/api/wol/devices", getWOLDeviceList)
authorized.PUT("/api/wol/device", alterWOLDevice)
authorized.DELETE("/api/wol/device", deleteWOLDevice)
authorized.GET("/api/info", info)
authorized.GET("/api/configure", configure)
authorized.POST("/api/configure", restoreConfigure)
authorized.POST("/api/getfilebase64", getFileBase64)
authorized.PUT("/api/lucky/service", optionService)
authorized.GET("/api/restoreconfigureconfirm", restoreConfigureConfirm)
r.PUT("/api/logout", logout)
}
@ -166,8 +157,6 @@ func RunAdminWeb(conf *config.BaseConfigure) {
//r.Use(func() *gin.Context {})
wolhttpapi.RegisterAPI(r, authorized)
go func() {
httpListen := fmt.Sprintf(":%d", conf.AdminWebListenPort)
log.Printf("AdminWeb(Http) listen on %s", httpListen)
@ -179,7 +168,7 @@ func RunAdminWeb(conf *config.BaseConfigure) {
}()
if conf.AdminWebListenTLS {
certlist := ssl.GetValidSSLCertficateList()
certlist := config.GetValidSSLCertficateList()
if len(certlist) <= 0 {
log.Printf("可用SSL证书列表为空,AdminWeb(Https) 监听服务中止运行")
return
@ -508,78 +497,3 @@ func isLocalIP(ipstr string) bool {
(ip4[0] == 169 && ip4[1] == 254) || // 169.254.0.0/16
(ip4[0] == 192 && ip4[1] == 168) // 192.168.0.0/16
}
func optionService(c *gin.Context) {
option := c.Query("option")
//fmt.Printf("当前option:%s\n", op)
//retStatus :=
switch option {
case "install": //安装服务
err := service.InstallService()
if err == nil {
c.JSON(http.StatusOK, gin.H{"ret": 0, "status": service.GetServiceState()})
go func() {
service.Start()
<-time.After(time.Second * 1)
os.Exit(0)
}()
return
}
msg := err.Error()
if strings.Contains(msg, "Access is denied") {
msg = "请以管理员身份运行lucky后再次安装"
}
c.JSON(http.StatusOK, gin.H{"ret": 2, "msg": fmt.Sprintf("安装Lucky Windows服务失败:%s", msg)})
case "unstall": //卸载服务
err := service.UninstallService()
if err == nil {
c.JSON(http.StatusOK, gin.H{"ret": 0, "status": service.GetServiceState()})
go func() {
<-time.After(time.Second * 2)
service.Stop()
}()
return
}
msg := err.Error()
if strings.Contains(msg, "Access is denied") {
msg = "请以管理员身份运行lucky后再次卸载"
}
c.JSON(http.StatusOK, gin.H{"ret": 3, "msg": fmt.Sprintf("卸载Lucky Windows服务失败:%s", msg)})
case "start": //启用
err := service.Start()
if err == nil {
c.JSON(http.StatusOK, gin.H{"ret": 0, "status": service.GetServiceState(), "msg": "启用服务成功,程序即将重启并已后台服务形式启动,请重新登录后台"})
go func() {
<-time.After(time.Second * 1)
os.Exit(0)
}()
return
}
c.JSON(http.StatusOK, gin.H{"ret": 5, "status": service.GetServiceState(), "msg": fmt.Sprintf("启用服务失败:%s", err.Error())})
case "stop":
go func() {
<-time.After(time.Second * 2)
service.Stop()
}()
c.JSON(http.StatusOK, gin.H{"ret": 0, "status": service.GetServiceState(), "msg": "2秒后停止lucky服务,成功后lucky会退出,后台无法登录"})
return
case "restart":
err := service.Restart()
if err == nil {
c.JSON(http.StatusOK, gin.H{"ret": 0, "status": service.GetServiceState(), "msg": "重启服务成功,lucky即将重启,请重新登录后台"})
go func() {
<-time.After(time.Second * 1)
os.Exit(0)
}()
return
}
c.JSON(http.StatusOK, gin.H{"ret": 5, "status": service.GetServiceState(), "msg": fmt.Sprintf("重启服务出错:%s", err.Error())})
default:
c.JSON(http.StatusOK, gin.H{"ret": 1, "msg": fmt.Sprintf("未知操作:%s,操作服务中止", option)})
return
}
}