1
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 35s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m9s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 54s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 2m0s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 51s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m44s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 57s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m49s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 1m11s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 55s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m31s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 1m14s
All checks were successful
Build Multi-Platform Binaries / build-frontend (push) Successful in 35s
Build Multi-Platform Binaries / build-binaries (amd64, darwin, server, false) (push) Successful in 1m9s
Build Multi-Platform Binaries / build-binaries (amd64, linux, client, true) (push) Successful in 54s
Build Multi-Platform Binaries / build-binaries (amd64, linux, server, true) (push) Successful in 2m0s
Build Multi-Platform Binaries / build-binaries (amd64, windows, client, true) (push) Successful in 51s
Build Multi-Platform Binaries / build-binaries (amd64, windows, server, true) (push) Successful in 1m44s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, client, true) (push) Successful in 57s
Build Multi-Platform Binaries / build-binaries (arm, 7, linux, server, true) (push) Successful in 1m49s
Build Multi-Platform Binaries / build-binaries (arm64, darwin, server, false) (push) Successful in 1m11s
Build Multi-Platform Binaries / build-binaries (arm64, linux, client, true) (push) Successful in 55s
Build Multi-Platform Binaries / build-binaries (arm64, linux, server, true) (push) Successful in 1m31s
Build Multi-Platform Binaries / build-binaries (arm64, windows, server, false) (push) Successful in 1m14s
This commit is contained in:
@@ -77,6 +77,7 @@ func main() {
|
|||||||
log.Fatalf("[Plugin] Register error: %v", err)
|
log.Fatalf("[Plugin] Register error: %v", err)
|
||||||
}
|
}
|
||||||
server.SetPluginRegistry(registry)
|
server.SetPluginRegistry(registry)
|
||||||
|
server.SetJSPluginStore(clientStore) // 设置 JS 插件存储,用于客户端重连时恢复插件
|
||||||
log.Printf("[Plugin] Registered %d plugins", len(builtin.GetServerPlugins()))
|
log.Printf("[Plugin] Registered %d plugins", len(builtin.GetServerPlugins()))
|
||||||
|
|
||||||
// 加载 JS 插件配置
|
// 加载 JS 插件配置
|
||||||
|
|||||||
@@ -139,7 +139,18 @@ func (h *StoreHandler) Install(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将插件信息保存到数据库
|
// 将插件保存到 JSPluginStore(用于客户端重连时恢复)
|
||||||
|
jsPlugin := &db.JSPlugin{
|
||||||
|
Name: req.PluginName,
|
||||||
|
Source: string(source),
|
||||||
|
Signature: string(signature),
|
||||||
|
AutoStart: true,
|
||||||
|
Enabled: true,
|
||||||
|
}
|
||||||
|
// 尝试保存,忽略错误(可能已存在)
|
||||||
|
h.app.GetJSPluginStore().SaveJSPlugin(jsPlugin)
|
||||||
|
|
||||||
|
// 将插件信息保存到客户端记录
|
||||||
dbClient, err := h.app.GetClientStore().GetClient(req.ClientID)
|
dbClient, err := h.app.GetClientStore().GetClient(req.ClientID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// 检查插件是否已存在
|
// 检查插件是否已存在
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ func generateClientID() string {
|
|||||||
// Server 隧道服务端
|
// Server 隧道服务端
|
||||||
type Server struct {
|
type Server struct {
|
||||||
clientStore db.ClientStore
|
clientStore db.ClientStore
|
||||||
|
jsPluginStore db.JSPluginStore // JS 插件存储
|
||||||
bindAddr string
|
bindAddr string
|
||||||
bindPort int
|
bindPort int
|
||||||
token string
|
token string
|
||||||
@@ -147,6 +148,11 @@ func (s *Server) SetPluginRegistry(registry *plugin.Registry) {
|
|||||||
s.pluginRegistry = registry
|
s.pluginRegistry = registry
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetJSPluginStore 设置 JS 插件存储
|
||||||
|
func (s *Server) SetJSPluginStore(store db.JSPluginStore) {
|
||||||
|
s.jsPluginStore = store
|
||||||
|
}
|
||||||
|
|
||||||
// LoadJSPlugins 加载 JS 插件配置
|
// LoadJSPlugins 加载 JS 插件配置
|
||||||
func (s *Server) LoadJSPlugins(plugins []JSPluginEntry) {
|
func (s *Server) LoadJSPlugins(plugins []JSPluginEntry) {
|
||||||
s.jsPlugins = plugins
|
s.jsPlugins = plugins
|
||||||
@@ -1112,6 +1118,10 @@ func (s *Server) handleClientPluginConn(cs *ClientSession, conn net.Conn, rule p
|
|||||||
|
|
||||||
// autoPushJSPlugins 自动推送 JS 插件到客户端
|
// autoPushJSPlugins 自动推送 JS 插件到客户端
|
||||||
func (s *Server) autoPushJSPlugins(cs *ClientSession) {
|
func (s *Server) autoPushJSPlugins(cs *ClientSession) {
|
||||||
|
// 记录已推送的插件,避免重复推送
|
||||||
|
pushedPlugins := make(map[string]bool)
|
||||||
|
|
||||||
|
// 1. 推送配置文件中的 JS 插件
|
||||||
for _, jp := range s.jsPlugins {
|
for _, jp := range s.jsPlugins {
|
||||||
if !s.shouldPushToClient(jp.AutoPush, cs.ID) {
|
if !s.shouldPushToClient(jp.AutoPush, cs.ID) {
|
||||||
continue
|
continue
|
||||||
@@ -1130,6 +1140,67 @@ func (s *Server) autoPushJSPlugins(cs *ClientSession) {
|
|||||||
|
|
||||||
if err := s.InstallJSPluginToClient(cs.ID, req); err != nil {
|
if err := s.InstallJSPluginToClient(cs.ID, req); err != nil {
|
||||||
log.Printf("[Server] Failed to push JS plugin %s: %v", jp.Name, err)
|
log.Printf("[Server] Failed to push JS plugin %s: %v", jp.Name, err)
|
||||||
|
} else {
|
||||||
|
pushedPlugins[jp.Name] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 推送客户端已安装的插件(从数据库)
|
||||||
|
s.pushClientInstalledPlugins(cs, pushedPlugins)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pushClientInstalledPlugins 推送客户端已安装的插件
|
||||||
|
func (s *Server) pushClientInstalledPlugins(cs *ClientSession, alreadyPushed map[string]bool) {
|
||||||
|
if s.jsPluginStore == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取客户端信息
|
||||||
|
client, err := s.clientStore.GetClient(cs.ID)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历客户端已安装的插件
|
||||||
|
for _, cp := range client.Plugins {
|
||||||
|
if !cp.Enabled {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 跳过已推送的
|
||||||
|
if alreadyPushed[cp.Name] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从 JSPluginStore 获取插件完整信息
|
||||||
|
jsPlugin, err := s.jsPluginStore.GetJSPlugin(cp.Name)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[Server] JS plugin %s not found in store: %v", cp.Name, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("[Server] Restoring installed plugin %s to client %s", cp.Name, cs.ID)
|
||||||
|
|
||||||
|
// 合并配置(客户端配置优先)
|
||||||
|
config := jsPlugin.Config
|
||||||
|
if config == nil {
|
||||||
|
config = make(map[string]string)
|
||||||
|
}
|
||||||
|
for k, v := range cp.Config {
|
||||||
|
config[k] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
req := router.JSPluginInstallRequest{
|
||||||
|
PluginName: cp.Name,
|
||||||
|
Source: jsPlugin.Source,
|
||||||
|
Signature: jsPlugin.Signature,
|
||||||
|
RuleName: cp.Name,
|
||||||
|
Config: config,
|
||||||
|
AutoStart: jsPlugin.AutoStart,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.InstallJSPluginToClient(cs.ID, req); err != nil {
|
||||||
|
log.Printf("[Server] Failed to restore plugin %s: %v", cp.Name, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user