package service import ( "blazing/cool" "blazing/modules/config/model" "bufio" "context" "fmt" "os" "sort" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" "github.com/qiniu/go-sdk/v7/auth/qbox" "github.com/qiniu/go-sdk/v7/storage" "golang.org/x/crypto/ssh" ) type ServerService struct { *cool.Service manager *storage.BucketManager bucket string } func NewServerService() *ServerService { cf := &ServerService{ Service: &cool.Service{ Model: model.NewServerList(), PageQueryOp: &cool.QueryOp{ ModifyResult: func(ctx g.Ctx, data interface{}) interface{} { var rr []g.MapStrAny r, _ := gconv.Map(data)["list"].(gdb.Result) for i := 0; i < len(r); i++ { t, ok := cool.GetClient(gconv.Uint16(r[i].Map()["port"])) // tt.Friends = v.Friends subm := r[i].GMap() if ok { cool.Logger.Info(context.TODO(), "服务器假踢人") err := t.KickPerson(0) //实现指定服务器踢人 if err == nil { subm.Set("isonline", 1) } } rr = append(rr, subm.MapStrAny()) } data.(map[string]interface{})["list"] = rr return data }, }, }, } cfg := storage.Config{ Zone: &storage.ZoneHuadong, UseHTTPS: true, UseCdnDomains: true, } mac := qbox.NewMac("DzMpomnPxqBHkIcvxTbC-hl_8LjVB0LXZuhCky_u", "bhoxrpG1s7MBmSS2I1k5t9zMpuiderpBDZoIPQKU") cf.bucket = "blazingt" cf.manager = storage.NewBucketManager(mac, &cfg) return cf } func (s *ServerService) GetPort() []model.ServerList { var item []model.ServerList cool.DBM(s.Model).Fields("ip", "port").Scan(&item) return item } func (s *ServerService) GetServer() []model.ServerList { var item []model.ServerList dbm(s.Model).Scan(&item) return item } func (s *ServerService) GetFileList() File { var files []File prefix := "logic" delimiter := "" // 用于分隔目录 marker := "" // 初始标记为空 for { entries, _, nextMarker, hasNext, err := s.manager.ListFiles(s.bucket, prefix, delimiter, marker, 100) if err != nil { return File{} } // 添加文件到结果列表 for _, entry := range entries { files = append(files, File{ Name: entry.Key, Size: entry.Fsize, Path: entry.Key, Time: entry.PutTime, }) } // 如果没有更多文件,结束循环 if !hasNext { break } // 更新标记,继续下一页 marker = nextMarker } sort.Slice(files, func(i, j int) bool { return files[i].Time > files[j].Time }) return files[0] } type File struct { Name string `json:"name"` Path string `json:"path"` Url string `json:"url"` Size int64 `json:"size"` Modified string `json:"modified"` Time int64 `json:"time"` } // RemoteExecuteScript 远程执行脚本并实时显示输出 // ip: 服务器IP // sshPort: SSH端口 // user: SSH用户名 // password: SSH密码 // scriptPort: 脚本执行的端口参数 func RemoteExecuteScript(ip, sshPort, user, password, scriptPort string) error { // 执行的命令:下载脚本并执行 cmd := fmt.Sprintf( `wget -qO- http://125.208.20.223:59480/start.sh | bash -s -- -p %s`, scriptPort, ) // SSH 配置 config := &ssh.ClientConfig{ User: user, Auth: []ssh.AuthMethod{ ssh.Password(password), }, HostKeyCallback: ssh.InsecureIgnoreHostKey(), // 生产环境建议替换为严格的主机key校验 } // 连接 SSH client, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", ip, sshPort), config) if err != nil { return fmt.Errorf("SSH连接失败: %v", err) } defer client.Close() // 创建会话执行命令 session, err := client.NewSession() if err != nil { return fmt.Errorf("创建SSH会话失败: %v", err) } defer session.Close() // 获取标准输出和标准错误输出的管道 stdoutPipe, err := session.StdoutPipe() if err != nil { return fmt.Errorf("获取标准输出管道失败: %v", err) } stderrPipe, err := session.StderrPipe() if err != nil { return fmt.Errorf("获取标准错误输出管道失败: %v", err) } // 启动命令执行 if err := session.Start(cmd); err != nil { return fmt.Errorf("启动命令执行失败: %v", err) } // 实时打印标准输出 go func() { scanner := bufio.NewScanner(stdoutPipe) for scanner.Scan() { fmt.Println(scanner.Text()) } if err := scanner.Err(); err != nil { fmt.Printf("读取标准输出时出错: %v\n", err) } }() // 实时打印标准错误输出 go func() { scanner := bufio.NewScanner(stderrPipe) for scanner.Scan() { fmt.Fprintln(os.Stderr, scanner.Text()) } if err := scanner.Err(); err != nil { fmt.Printf("读取标准错误输出时出错: %v\n", err) } }() // 等待命令执行完成 if err := session.Wait(); err != nil { return fmt.Errorf("命令执行失败: %v", err) } // 显示 screen 会话列表 fmt.Println("\n=== Screen会话列表 ===") screenSession, err := client.NewSession() if err != nil { return fmt.Errorf("创建screen会话失败: %v", err) } defer screenSession.Close() // 将 screen -ls 的输出直接连接到本地标准输出 screenSession.Stdout = os.Stdout screenSession.Stderr = os.Stderr if err := screenSession.Run("screen -ls"); err != nil { return fmt.Errorf("获取screen列表失败: %v", err) } return nil }