feat: 增强踢人逻辑与BOSS脚本支持
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
优化踢人超时处理和僵尸连接清理,支持BOSS动作脚本并增加测试,修复事件匹配与战斗循环中的并发问题。
This commit is contained in:
@@ -1,106 +1,149 @@
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"blazing/common/data/share"
|
||||
"blazing/cool"
|
||||
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
config "blazing/modules/config/service"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
// Define the server handler
|
||||
type ServerHandler struct{}
|
||||
|
||||
// 实现踢人
|
||||
func (*ServerHandler) Kick(_ context.Context, userid uint32) error {
|
||||
|
||||
useid1, _ := share.ShareManager.GetUserOnline(userid)
|
||||
if useid1 == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
cl, ok := cool.GetClientOnly(useid1)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
cl.KickPerson(userid) //实现指定服务器踢人
|
||||
return nil
|
||||
}
|
||||
|
||||
// 注册logic服务器
|
||||
func (*ServerHandler) RegisterLogic(ctx context.Context, id, port uint32) error {
|
||||
fmt.Println("注册logic服务器", id, port)
|
||||
|
||||
//TODO 待修复滚动更新可能导致的玩家可以同时在旧服务器和新服务器同时在线的bug
|
||||
revClient, ok := jsonrpc.ExtractReverseClient[cool.ClientHandler](ctx)
|
||||
if !ok {
|
||||
return fmt.Errorf("no reverse client")
|
||||
}
|
||||
t := config.NewServerService().GetServerID((id))
|
||||
|
||||
aa, ok := cool.GetClient(t.OnlineID, t.Port)
|
||||
if ok && aa != nil { //如果已经存在且这个端口已经被存过
|
||||
aa.QuitSelf(0)
|
||||
}
|
||||
cool.AddClient(100000*id+port, &revClient)
|
||||
|
||||
//Refurh()
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func CServer() *jsonrpc.RPCServer {
|
||||
// create a new server instance
|
||||
rpcServer := jsonrpc.NewServer(jsonrpc.WithReverseClient[cool.ClientHandler](""))
|
||||
|
||||
rpcServer.Register("", &ServerHandler{})
|
||||
|
||||
return rpcServer
|
||||
|
||||
}
|
||||
|
||||
var closer jsonrpc.ClientCloser
|
||||
|
||||
func StartClient(id, port uint32, callback any) *struct {
|
||||
Kick func(uint32) error
|
||||
|
||||
RegisterLogic func(uint32, uint32) error
|
||||
} {
|
||||
//cool.Config.File.Domain = "127.0.0.1"
|
||||
var rpcaddr = "ws://" + cool.Config.File.Domain + gconv.String(cool.Config.Address) + "/rpc"
|
||||
|
||||
closer1, err := jsonrpc.NewMergeClient(context.Background(),
|
||||
rpcaddr, "", []interface{}{
|
||||
&RPCClient,
|
||||
}, nil, jsonrpc.WithClientHandler("", callback),
|
||||
jsonrpc.WithReconnFun(func() { RPCClient.RegisterLogic(id, port) }),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
|
||||
//if port != 0 { //注册logic
|
||||
defer RPCClient.RegisterLogic(id, port)
|
||||
|
||||
//}
|
||||
|
||||
closer = closer1
|
||||
|
||||
return &RPCClient
|
||||
}
|
||||
|
||||
// Setup RPCClient with reverse call handler
|
||||
var RPCClient struct {
|
||||
Kick func(uint32) error //踢人
|
||||
|
||||
RegisterLogic func(uint32, uint32) error
|
||||
|
||||
// UserLogin func(int32, int32) error //用户登录事件
|
||||
// UserLogout func(int32, int32) error //用户登出事件
|
||||
}
|
||||
package rpc
|
||||
|
||||
import (
|
||||
"blazing/common/data/share"
|
||||
"blazing/cool"
|
||||
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
config "blazing/modules/config/service"
|
||||
|
||||
"github.com/filecoin-project/go-jsonrpc"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
// Define the server handler
|
||||
type ServerHandler struct{}
|
||||
|
||||
const kickForwardTimeout = 3 * time.Second
|
||||
|
||||
// 实现踢人
|
||||
func (*ServerHandler) Kick(_ context.Context, userid uint32) error {
|
||||
useid1, err := share.ShareManager.GetUserOnline(userid)
|
||||
if err != nil || useid1 == 0 {
|
||||
// 请求到达时用户已离线,直接视为成功
|
||||
return nil
|
||||
}
|
||||
|
||||
cl, ok := cool.GetClientOnly(useid1)
|
||||
if !ok || cl == nil {
|
||||
// 目标服务器不在线,清理僵尸在线标记并视为成功
|
||||
_ = share.ShareManager.DeleteUserOnline(userid)
|
||||
cool.DeleteClientOnly(useid1)
|
||||
return nil
|
||||
}
|
||||
|
||||
resultCh := make(chan error, 1)
|
||||
go func() {
|
||||
resultCh <- cl.KickPerson(userid) // 实现指定服务器踢人
|
||||
}()
|
||||
|
||||
select {
|
||||
case callErr := <-resultCh:
|
||||
if callErr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 调用失败后兜底:用户若已离线/切服/目标服不在线都算成功
|
||||
useid2, err2 := share.ShareManager.GetUserOnline(userid)
|
||||
if err2 != nil || useid2 == 0 || useid2 != useid1 {
|
||||
return nil
|
||||
}
|
||||
if cl2, ok2 := cool.GetClientOnly(useid2); !ok2 || cl2 == nil {
|
||||
_ = share.ShareManager.DeleteUserOnline(userid)
|
||||
cool.DeleteClientOnly(useid2)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 仍在线则返回失败,不按成功处理
|
||||
return callErr
|
||||
case <-time.After(kickForwardTimeout):
|
||||
// 仅防止无限等待;超时不算成功
|
||||
useid2, err2 := share.ShareManager.GetUserOnline(userid)
|
||||
if err2 != nil || useid2 == 0 || useid2 != useid1 {
|
||||
return nil
|
||||
}
|
||||
if cl2, ok2 := cool.GetClientOnly(useid2); !ok2 || cl2 == nil {
|
||||
_ = share.ShareManager.DeleteUserOnline(userid)
|
||||
cool.DeleteClientOnly(useid2)
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("kick timeout, user still online: uid=%d server=%d", userid, useid2)
|
||||
}
|
||||
}
|
||||
|
||||
// 注册logic服务器
|
||||
func (*ServerHandler) RegisterLogic(ctx context.Context, id, port uint32) error {
|
||||
fmt.Println("注册logic服务器", id, port)
|
||||
|
||||
//TODO 待修复滚动更新可能导致的玩家可以同时在旧服务器和新服务器同时在线的bug
|
||||
revClient, ok := jsonrpc.ExtractReverseClient[cool.ClientHandler](ctx)
|
||||
if !ok {
|
||||
return fmt.Errorf("no reverse client")
|
||||
}
|
||||
t := config.NewServerService().GetServerID((id))
|
||||
|
||||
aa, ok := cool.GetClient(t.OnlineID, t.Port)
|
||||
if ok && aa != nil { //如果已经存在且这个端口已经被存过
|
||||
aa.QuitSelf(0)
|
||||
}
|
||||
cool.AddClient(100000*id+port, &revClient)
|
||||
|
||||
//Refurh()
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func CServer() *jsonrpc.RPCServer {
|
||||
// create a new server instance
|
||||
rpcServer := jsonrpc.NewServer(jsonrpc.WithReverseClient[cool.ClientHandler](""))
|
||||
|
||||
rpcServer.Register("", &ServerHandler{})
|
||||
|
||||
return rpcServer
|
||||
|
||||
}
|
||||
|
||||
var closer jsonrpc.ClientCloser
|
||||
|
||||
func StartClient(id, port uint32, callback any) *struct {
|
||||
Kick func(uint32) error
|
||||
|
||||
RegisterLogic func(uint32, uint32) error
|
||||
} {
|
||||
//cool.Config.File.Domain = "127.0.0.1"
|
||||
var rpcaddr = "ws://" + cool.Config.File.Domain + gconv.String(cool.Config.Address) + "/rpc"
|
||||
|
||||
closer1, err := jsonrpc.NewMergeClient(context.Background(),
|
||||
rpcaddr, "", []interface{}{
|
||||
&RPCClient,
|
||||
}, nil, jsonrpc.WithClientHandler("", callback),
|
||||
jsonrpc.WithReconnFun(func() { RPCClient.RegisterLogic(id, port) }),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
|
||||
//if port != 0 { //注册logic
|
||||
defer RPCClient.RegisterLogic(id, port)
|
||||
|
||||
//}
|
||||
|
||||
closer = closer1
|
||||
|
||||
return &RPCClient
|
||||
}
|
||||
|
||||
// Setup RPCClient with reverse call handler
|
||||
var RPCClient struct {
|
||||
Kick func(uint32) error //踢人
|
||||
|
||||
RegisterLogic func(uint32, uint32) error
|
||||
|
||||
// UserLogin func(int32, int32) error //用户登录事件
|
||||
// UserLogout func(int32, int32) error //用户登出事件
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user