mirror of
https://github.com/fumiama/tienyik.git
synced 2026-06-04 23:10:26 +08:00
205 lines
4.9 KiB
Go
205 lines
4.9 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
"syscall"
|
|
"time"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
|
|
base14 "github.com/fumiama/go-base16384"
|
|
"github.com/fumiama/tienyik"
|
|
"github.com/fumiama/tienyik/api/auth"
|
|
"github.com/fumiama/tienyik/api/cdserv"
|
|
"github.com/fumiama/tienyik/api/desktop"
|
|
"github.com/fumiama/tienyik/hcli"
|
|
"github.com/fumiama/tienyik/internal/log"
|
|
"github.com/fumiama/tienyik/internal/textio"
|
|
)
|
|
|
|
type config struct {
|
|
UserAccount string `yaml:"UserAccount"`
|
|
PasswordB14 string `yaml:"PasswordB14"` // PasswordB14 is a little bit more secure
|
|
CheckIntervalSec int `yaml:"CheckIntervalSec"` // CheckIntervalSec default 60
|
|
GetDeviceCount int `yaml:"GetDeviceCount"` // GetDeviceCount default 20
|
|
}
|
|
|
|
func main() {
|
|
c := flag.String("c", "config.yaml", "load config file")
|
|
s := flag.String("s", "", "save config file template")
|
|
flag.Parse()
|
|
|
|
cfg := config{}
|
|
|
|
if *s != "" {
|
|
fmt.Print("UserAccount: ")
|
|
fmt.Scanln(&cfg.UserAccount)
|
|
pwd := ""
|
|
fmt.Print("Password: ")
|
|
textio.NoEchoScanln(&pwd)
|
|
cfg.PasswordB14 = base14.EncodeString(pwd)
|
|
cfg.CheckIntervalSec = 60
|
|
cfg.GetDeviceCount = 20
|
|
data, err := yaml.Marshal(&cfg)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
err = os.WriteFile(*s, data, 0644)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
return
|
|
}
|
|
|
|
f, err := os.Open(*c)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
err = yaml.NewDecoder(f).Decode(&cfg)
|
|
_ = f.Close()
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
if cfg.UserAccount == "" {
|
|
log.Fatalln("user account must be set")
|
|
}
|
|
if cfg.PasswordB14 == "" {
|
|
log.Fatalln("password must be set (in b14 format)")
|
|
}
|
|
if cfg.CheckIntervalSec <= 0 {
|
|
cfg.CheckIntervalSec = 60
|
|
}
|
|
if cfg.GetDeviceCount <= 0 {
|
|
cfg.GetDeviceCount = 20
|
|
}
|
|
|
|
RECONN:
|
|
cli := hcli.NewClient()
|
|
sd, err := cdserv.GetServData()
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
x, err := auth.GenChallengeData(nil, cli)
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
sd.SetClient(cli)
|
|
pwd := base14.DecodeString(cfg.PasswordB14)
|
|
rsp, err := auth.Login(nil, cli, &auth.RequestLogin{
|
|
UserAccount: cfg.UserAccount,
|
|
Password: tienyik.ChallengePassword(pwd, x.ChallengeCode),
|
|
SHA256Password: tienyik.ChallengeSHA256Password(pwd, x.ChallengeCode),
|
|
ChallengeID: x.ChallengeID,
|
|
DeviceCode: cli.Devicecode,
|
|
DeviceName: tienyik.DeviceNameEdge,
|
|
DeviceType: cli.Devicetype,
|
|
DeviceModel: tienyik.DeviceModelMacOS,
|
|
AppVersion: tienyik.AppVersion,
|
|
SysVersion: tienyik.DeviceModelMacOS,
|
|
ClientVersion: cli.Version,
|
|
})
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
rsp.SetClient(cli)
|
|
defer auth.Logout(nil, cli)
|
|
|
|
pd, err := desktop.PageDesktop(nil, cli, &desktop.RequestPageDesktop{
|
|
GetCnt: 20,
|
|
DesktopTypes: []string{"1", tienyik.ArchX86},
|
|
SortType: desktop.DefaultRequestPageDesktopSortType,
|
|
})
|
|
if err != nil {
|
|
log.Fatalln(err)
|
|
}
|
|
|
|
mp := make(map[string][2]string, len(pd.DesktopList)*4)
|
|
sb := strings.Builder{}
|
|
sb.WriteString("available desktops:")
|
|
for _, x := range pd.DesktopList {
|
|
if x.UseStatusText == "运行中" {
|
|
sb.WriteString(" |●")
|
|
} else {
|
|
sb.WriteString(" |○")
|
|
}
|
|
sb.WriteString("[")
|
|
sb.WriteString(x.ObjID)
|
|
sb.WriteString("]")
|
|
sb.WriteString(x.ObjName)
|
|
sb.WriteString("(")
|
|
sb.WriteString(x.OsName)
|
|
sb.WriteString(")|")
|
|
mp[x.ObjID] = [2]string{x.ObjName, x.OsType}
|
|
}
|
|
log.Infoln(&sb)
|
|
|
|
t := time.NewTicker(time.Second * time.Duration(cfg.CheckIntervalSec))
|
|
defer t.Stop()
|
|
|
|
mainStopCh := make(chan struct{})
|
|
mc := make(chan os.Signal, 4)
|
|
signal.Notify(mc, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM)
|
|
go func() {
|
|
for {
|
|
<-mc
|
|
close(mainStopCh)
|
|
}
|
|
}()
|
|
|
|
errcnt := 0
|
|
for {
|
|
if errcnt > 16 {
|
|
goto RECONN
|
|
}
|
|
select {
|
|
case <-t.C:
|
|
log.Infoln("start refreshing...")
|
|
|
|
reqs := make([]desktop.RequestState, len(pd.DesktopList))
|
|
for i, x := range pd.DesktopList {
|
|
reqs[i].ObjID = x.ObjID
|
|
reqs[i].ObjType = x.ObjType
|
|
}
|
|
s, err := desktop.State(nil, cli, reqs)
|
|
if err != nil {
|
|
log.Warnln("get state err:", err)
|
|
errcnt++
|
|
time.Sleep(time.Minute)
|
|
}
|
|
for _, x := range s {
|
|
log.Infof("%s [%s]%s status is %s", x.ObjID, mp[x.ObjID][0], x.DesktopState)
|
|
if x.DesktopState == "ACTIVE" {
|
|
continue
|
|
}
|
|
log.Infof("%s [%s]%s do refresh", x.ObjID, mp[x.ObjID][0])
|
|
_, err = desktop.Connect(nil, cli, &desktop.RequestConnect{
|
|
ObjID: x.ObjID,
|
|
ObjType: x.ObjType,
|
|
OsType: mp[x.ObjID][1],
|
|
DeviceID: int(cli.Devicetype),
|
|
DeviceCode: cli.Devicecode,
|
|
DeviceName: tienyik.DeviceNameEdge,
|
|
SysVersion: tienyik.DeviceModelMacOS,
|
|
AppVersion: tienyik.AppVersion,
|
|
HostName: tienyik.DeviceNameEdge,
|
|
HardwareFeatureCode: cli.Devicecode,
|
|
SpecifiedCertCategory: 1,
|
|
})
|
|
if err != nil {
|
|
log.Warnln("connect err:", err)
|
|
errcnt++
|
|
time.Sleep(time.Minute)
|
|
}
|
|
}
|
|
case <-mainStopCh:
|
|
log.Warnln("quit loop")
|
|
return
|
|
}
|
|
}
|
|
|
|
}
|