Files
novatask/internal/svc/game_action.go
2025-04-28 19:26:17 +08:00

128 lines
3.7 KiB
Go

package svc
import (
"bytes"
"context"
"database/sql"
"encoding/json"
"fmt"
"github.com/spf13/cast"
"github.com/zeromicro/go-zero/core/logx"
"io"
"math"
"net/http"
"nova_task/internal/model"
"nova_task/internal/pkg/encrypt/md5"
"strconv"
"strings"
"time"
)
// GetGameServerAddress 获取游戏服地址
func (s *ServiceContext) GetGameServerAddress(ctx context.Context, roleID int64) (string, map[string]any, error) {
agentIDServerID := math.Floor(float64(roleID)/100000000) / 100000
splitStr := cast.ToString(agentIDServerID)
splitParts := []string{"0", "0"}
if parts := strings.Split(splitStr, "."); len(parts) == 2 {
splitParts = parts
}
serverInfo := map[string]any{}
originalAgentID, _ := strconv.ParseInt(splitParts[0], 10, 64)
originalServerID, _ := strconv.ParseInt(splitParts[1], 10, 64)
serverInfo["original_agent_id"] = originalAgentID
serverInfo["original_server_id"] = originalServerID
agentId, serverServerId, err := s.MergeServerModel.FinalServer(ctx, originalAgentID, originalServerID)
if err != nil {
return "", serverInfo, err
}
serverInfo["agent_id"] = agentId
serverInfo["server_id"] = serverServerId
gs, err := s.ServersModel.GetGameServer(ctx, agentId, serverServerId)
if err != nil {
return "", serverInfo, err
}
serverInfo["web_port"] = gs.WebPort
serverInfo["server_ip"] = gs.ServerIP
serverInfo["public_server_ip"] = gs.PublicServerIP
return fmt.Sprintf("http://%s:%d", gs.PublicServerIP, gs.WebPort), serverInfo, nil
}
func (s *ServiceContext) GameAction(ctx context.Context, roleId int64, action string, args map[string]any) (any, error) {
//return map[string]any{
// "data": 1,
// "ret": 1,
//}, nil
addr, serverInfo, err := s.GetGameServerAddress(ctx, roleId)
if err != nil {
return nil, err
}
now := time.Now().Unix()
request := map[string]any{
"nova_time": now,
"nova_token": md5.Md5str(fmt.Sprintf("%d%s", now, s.Config.NovaToken)),
"nova_action": action,
"role_id": roleId,
}
for k, v := range args {
if _, ok := request[k]; ok {
continue
}
request[k] = v
}
data, _ := json.Marshal(request)
httpReq, err := http.NewRequest(http.MethodPost, addr, bytes.NewReader(data))
if err != nil {
return nil, err
}
httpReq.Header.Set("Content-Type", "application/json")
httpReq.Header.Set("Accept", "application/json")
httpResp, err := http.DefaultClient.Do(httpReq)
if err != nil {
s.ErrLog(ctx, action, addr, serverInfo, request, nil)
return nil, err
}
respData, _ := io.ReadAll(httpResp.Body)
resp := map[string]any{}
if err := json.Unmarshal(respData, &resp); err != nil {
s.ErrLog(ctx, action, addr, serverInfo, request, string(respData))
return nil, err
}
if cast.ToInt64(resp["ret"]) != 1 {
s.ErrLog(ctx, action, addr, serverInfo, request, resp)
return resp, fmt.Errorf("game action msg= %s, data=%v", cast.ToString(resp["msg"]), cast.ToString(resp["data"]))
}
s.ErrLog(ctx, action, addr, serverInfo, request, resp)
return resp, nil
}
func (s *ServiceContext) ErrLog(ctx context.Context, action, url string, serverInfo, req, resp any) {
var marshal = func(v any) string {
if v == nil {
return ""
}
if vv, ok := v.(string); ok {
return vv
}
data, _ := json.Marshal(v)
return string(data)
}
_, err := s.RequestServerLogModel.Insert(ctx, &model.NhRequestServerLog{
Action: action,
Url: url,
ServerInfo: marshal(serverInfo),
ReqData: marshal(req),
ResData: marshal(resp),
CreateTime: sql.NullTime{Valid: true, Time: time.Now()},
})
if err != nil {
logx.Errorw("insert request server log error", logx.Field("err", err), logx.Field("action", action), logx.Field("url", url), logx.Field("server_info", serverInfo), logx.Field("req", req), logx.Field("resp", resp))
}
}