lt пре 5 дана
родитељ
комит
2aa5a25deb
1 измењених фајлова са 119 додато и 3 уклоњено
  1. 119 3
      RO_Server_Trunk-branch_0.1.39/roserver/game/model/role.go

+ 119 - 3
RO_Server_Trunk-branch_0.1.39/roserver/game/model/role.go

@@ -1,6 +1,9 @@
 package model
 
 import (
+	"crypto/md5"
+	"encoding/hex"
+	"encoding/json"
 	"errors"
 	"fmt"
 	"math"
@@ -11,6 +14,8 @@ import (
 	"rocommon/util"
 	"roserver/baseserver/model"
 	"roserver/serverproto"
+	"sort"
+	"strconv"
 	"strings"
 	"time"
 	"unicode/utf8"
@@ -3695,13 +3700,40 @@ func (this *Role) PayInfoGet(goodsType, goodsId, count int32, rushStage, rushRou
 			util.InfoF("uid=%v pc mode: shop:%v id:%v, count:%v, price:%v", this.GetUUid(), payOrderInfo.GoodsType, payOrderInfo.GoodsId, payOrderInfo.Count, payOrderInfo.Amount)
 			return
 		}
-		ordeinfo := OrderRequest{}
+		ordeinfo := OrderRequest{
+			GameArea:          "s1",
+			GameLevel:         "50",
+			GameOrderId:       "ORDER123456",
+			GameCurrency:      "CNY",
+			GamePrice:         "99.99",
+			GameRoleId:        "role_001",
+			GameRoleName:      "测试角色",
+			GameGuid:          12345,
+			NotifyId:          "-1",
+			Subject:           "至尊礼包",
+			GameAccessVersion: "2507",
+		}
+		extra := &Extras{
+			ServerId:  int(payOrderInfo.SId / 2),
+			Platform:  this.platform,
+			CpOrderId: strconv.FormatUint(payOrderInfo.CpOrderId, 10),
+		}
+		v, _ := json.Marshal(extra)
+		ordeinfo.ExtendsInfoData = string(v)
+
 		payOrderInfo.SdkOrderId = sdkOrderId
 		//保存订单信息到数据库
 		ackMsg.Amount = payOrderInfo.Amount
 		ackMsg.CpOrderId = payOrderInfo.CpOrderId
-		ackMsg.GoodsName = payOrderInfo.GoodsName
-		//ackMsg.GoodsName = service.GetServiceConfig().Node.PayCallBack
+		//ackMsg.GoodsName = payOrderInfo.GoodsName
+		info, err := GenerateGameSign(ordeinfo, "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCfYd3FqSaWqCpWLSktBSSgAelt0F6T+tO4C25YKR/6X/sPacDBbX662/0fW+H+YbXigHWFB/yangkhiZTpD/VmiOo5lISX6L0/m+13ti9b8jzTZcfVngfLsP+Ztbk81N1Jk0gWF4bndZxREJ3IxcEDHnIrwXgLGA2GJ89kdgudwIDAQAB")
+		if err != nil {
+			ackMsg.Error = int32(serverproto.ErrorCode_ERROR_PAY_NOT_OPEN)
+			this.ReplayGate(ackMsg, true)
+			util.ErrorF("uid=%v GenerateGameSign err:%v", this.GetUUid(), err)
+			return
+		}
+		ackMsg.GoodsName = info
 		ssSaveReqMsg := &serverproto.SSPayInfoSaveReq{
 			PayOrderInfo: payOrderInfo,
 			SaveNotify:   true,
@@ -3712,6 +3744,90 @@ func (this *Role) PayInfoGet(goodsType, goodsId, count int32, rushStage, rushRou
 	}
 }
 
+func GenerateGameSign(params interface{}, rsaPublicKey string) (string, error) {
+	// 1. 将结构体转换为 map
+	paramsMap, err := structToMap(params)
+	if err != nil {
+		return "", err
+	}
+
+	// 2. 过滤掉 game_sign 字段
+	delete(paramsMap, "game_sign")
+
+	// 3. 获取所有 key 并排序(字典序)
+	keys := make([]string, 0, len(paramsMap))
+	for k := range paramsMap {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+
+	// 4. 按顺序构建 QueryString
+	var queryParts []string
+	for _, k := range keys {
+		v := paramsMap[k]
+		// 跳过空值或零值(根据实际需求调整)
+		if v == "" || v == nil {
+			continue
+		}
+		// 将值转换为字符串
+		strValue := fmt.Sprintf("%v", v)
+		queryParts = append(queryParts, fmt.Sprintf("%s=%s", k, strValue))
+	}
+	queryString := strings.Join(queryParts, "&")
+
+	// 5. 在 QueryString 后面拼接 RSA 公钥
+	stringToSign := queryString + rsaPublicKey
+
+	// 6. 计算 MD5
+	hash := md5.Sum([]byte(stringToSign))
+	sign := hex.EncodeToString(hash[:])
+
+	return sign, nil
+}
+
+// structToMap 将结构体转换为 map[string]interface{}
+// 使用 json tag 作为 key
+func structToMap(obj interface{}) (map[string]interface{}, error) {
+	result := make(map[string]interface{})
+
+	v := reflect.ValueOf(obj)
+	t := reflect.TypeOf(obj)
+
+	// 如果是指针,获取其指向的值
+	if v.Kind() == reflect.Ptr {
+		v = v.Elem()
+		t = t.Elem()
+	}
+
+	// 确保是结构体类型
+	if v.Kind() != reflect.Struct {
+		return nil, fmt.Errorf("expected struct, got %v", v.Kind())
+	}
+
+	for i := 0; i < v.NumField(); i++ {
+		field := t.Field(i)
+		value := v.Field(i)
+
+		// 获取 json tag
+		jsonTag := field.Tag.Get("json")
+		if jsonTag == "" || jsonTag == "-" {
+			continue
+		}
+
+		// 处理 omitempty(去除后面的,omitempty)
+		jsonTag = strings.Split(jsonTag, ",")[0]
+
+		// 获取字段值
+		if value.Kind() == reflect.Ptr && value.IsNil() {
+			result[jsonTag] = nil
+		} else {
+			result[jsonTag] = value.Interface()
+		}
+	}
+
+	return result, nil
+}
+
 type OrderRequest struct {
 	// 訂單擴展數據,支持JSON或QueryString格式
 	ExtendsInfoData string `json:"extends_info_data"` // 最大128字符