Files
bl/modules/config/service/server.go
昔念 174562b895 ```
feat(config): 重构配置结构并添加服务器列表支持

- 重命名PortBL字段为GameOnlineID,改进命名语义
- 添加ServerList结构体用于管理服务器配置
- 移除七牛云配置相关字段
- 更新ID生成器使用GameOnlineID参数

fix(server): 调整服务器启动参数和VIP逻辑

- 将启动参数从-port改为-id,统一参数命名
- 更新服务器启动逻辑,基于GameOnlineID获取服务器信息
- 为VIP服务器启用调试模式
- 优化端口可用性检查逻辑

refactor(model): 统一模型基类结构

- 将各模型中的*cool.Model嵌入改为Base基类
- 移除soul.go
2026-01-08 03:30:18 +08:00

202 lines
4.6 KiB
Go

package service
import (
"blazing/cool"
"blazing/modules/config/model"
"bufio"
"fmt"
"os"
"sort"
"github.com/gogf/gf/v2/database/gdb"
"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(),
},
}
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
cool.DBM(s.Model).
Cache(gdb.CacheOption{
// Duration: time.Hour,
Force: false,
}).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
}