chicken_dy/Assets/HCMiniSdk/Scripts/Server/HCServer.cs

410 lines
15 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
namespace HC
{
public class HCServer : HCSingleton<HCServer>
{
// #if !UNITY_EDITOR
// public const string BASE_URL = "https://sandc.gameztsvc.com/ztp";
//
// #else
// public const string BASE_URL = "https://tk.dgtverse.cn/ztp";
// #endif
public const string BASE_URL = "https://sandc.gameztsvc.com/ztp";
public const string URL_VERIFY_PURCHASE = "/game/report/iap";
public const string URL_LOGIN = "/game/user/login";
public const string URL_BIND = "/game/user/bind";
public const string URL_DELETE = "/game/user/delete";
public const string URL_MINI_APP_CONFIG = "/app/parameter";
public const string URL_MINI_APP_PAY = "/wechat/mini-app-pay";
public const string URL_ORDER_CREATE = "/order/create";
public const string URL_ORDER_QUERY = "/order/query";
public const string URL_ORDER_AWARDED = "/order/awarded";
public const string URL_CENSOR_TEXT = "/user/censor-text";
public const string URL_WX_DATA_DECRYPT = "/user/game-data-decrypt";
private const string XXTEA_KEY = "tkbff&(gBUjX#$s0710";
private const string secretKey = "tk~!@#$%^&*()_+0708";
public void WxDataDecrypt(string iv, string encryptedData, string signature, Action<int, string, MiniAppConfig> callback)
{
var req = new Dictionary<string, object>
{
["iv"] = iv,
["signature"] = signature,
["encrypted_data"] = encryptedData
};
Post(URL_WX_DATA_DECRYPT, req, callback);
}
public void AppConfig(Action<int, string, MiniAppConfig> callback)
{
var req = new Dictionary<string, object>();
int appType = 0;
#if WEBGL_WX
appType = 1;
#elif WEBGL_BYTEDANCE
appType = 2;
#endif
req["app_type"] = appType;
Post(URL_MINI_APP_CONFIG, req, callback);
}
public void MiniAppPay(string billNo, string productName, int amt, Action<int, string, MiniPayResult> callback)
{
Post(URL_MINI_APP_PAY, new Dictionary<string, object>()
{
["bill_no"] = billNo,
["product_name"] = productName,
["amt"] = amt,
}, callback);
}
public void CheckSensitiveWords(int type, string text, Action<int, string, CensorTextResult> callback)
{
Post(URL_CENSOR_TEXT, new Dictionary<string, object>()
{
["biz_type"] = type,
["text"] = text
}, callback);
}
/// <summary>
/// 支付下单接口
/// </summary>
/// <param name="productName">商品名称</param>
/// <param name="productId">商品id</param>
/// <param name="price">价格 (分)</param>
/// <param name="quantity">数量</param>
/// <param name="orderType">支付类型 1 = wechat</param>
/// <param name="currency">货币单位</param>
/// <param name="gameExtraParam"></param>
/// <param name="callback">回调</param>
public void OrderCreate(string productName, string productId, string price, int quantity, int orderType = 1, string currency = "CNY", string gameExtraParam = "", Action<int, string, OrderCreateResult> callback = null)
{
Post(URL_ORDER_CREATE, new Dictionary<string, object>
{
["product_name"] = productName,
["product_id"] = productId,
["price"] = price,
["quantity"] = quantity,
["order_type"] = orderType,
["currency"] = currency,
["game_extra_param"] = gameExtraParam,
}, callback);
}
/// <summary>
/// 订单查询
/// </summary>
/// <param name="orderNo">订单号</param>
/// <param name="callback">回调</param>
public void OrderQuery(string orderNo, Action<int, string, OrderQueryResult> callback = null)
{
Post(URL_ORDER_QUERY, new Dictionary<string, object>
{
["order_no"] = orderNo
}, callback);
}
/// <summary>
/// 订单奖励下发上报接口
/// </summary>
/// <param name="orderNo">订单号</param>
/// <param name="callback">回调</param>
public void OrderAwarded(string orderNo, Action<int, string, OrderQueryResult> callback = null)
{
Post(URL_ORDER_AWARDED, new Dictionary<string, object>
{
["order_no"] = orderNo
}, callback);
}
public void VerifyPurchase(Dictionary<string, object> args, Action<int, string, DataInfo> callback)
{
Post(URL_VERIFY_PURCHASE, args, callback);
}
public void Post<T>(string url, Dictionary<string, object> args, Action<int, string, T> callback,
Dictionary<string, string> headers = null) where T : new()
{
args ??= new Dictionary<string, object>();
headers ??= new Dictionary<string, string>();
AddBaseParameters(args);
EncryptionParameters(args);
var requestBody = ConvertDictionaryToJson(args);
HCDebugger.LogDebug("[server] url=> " + url);
HCDebugger.LogDebug("[server] requestBody=> " + requestBody);
var encryptBody = EncryptRequestBody(requestBody);
if (!string.IsNullOrEmpty(encryptBody))
{
headers["params"] = encryptBody;
headers["encrypt"] = true.ToString().ToLower();
requestBody = "";
}
HCRequestHandler.Instance.SendPostRequest(BASE_URL + url, requestBody, headers,
(code, res) =>
{
HCDebugger.LogDebug($"[server] resp ====> code : {code} res : {res}");
if (code == 0)
{
Response<T> resp = null;
var errorMsg = "";
try
{
res = DecryptResponseBody(res);
resp = JsonUtility.FromJson<Response<T>>(res);
}
catch (Exception e)
{
errorMsg = $"[server] Data conversion exception。{e.Message} {res}";
HCDebugger.LogError(errorMsg);
}
if (resp != null)
{
callback(resp.code, resp.msg, resp.data);
}
else
{
callback.Invoke(-1, errorMsg, new T());
}
}
else
{
callback.Invoke(code, res, new T());
}
HCDebugger.LogDebug("[server]" + "[res] " + res);
});
}
private static string EncryptRequestBody(string requestBody)
{
var encryptRequestBodyBytes = HCXXTEA.Encrypt(Encoding.UTF8.GetBytes(requestBody), Encoding.UTF8.GetBytes(XXTEA_KEY));
var encryptRequestBody = HCConvertUtils.BytesToHexString(encryptRequestBodyBytes, false);
HCDebugger.LogDebug($"[HCServer] [EncryptRequestBody] requestBody = {requestBody} encryptRequestBody = {encryptRequestBody}");
return encryptRequestBody;
}
private static string DecryptResponseBody(string responseBody)
{
var decryptResponseBodyBytes = HCXXTEA.Decrypt(HCConvertUtils.HexStringToBytes(responseBody), Encoding.UTF8.GetBytes(XXTEA_KEY));
var decryptResponseBody = Encoding.UTF8.GetString(decryptResponseBodyBytes);
HCDebugger.LogDebug($"[HCServer] [DecryptResponseBody] responseBody = {responseBody} decryptResponseBody = {decryptResponseBody}");
return decryptResponseBody;
}
private static string GetMD5Hash(string input)
{
using (var md5 = MD5.Create())
{
var inputBytes = Encoding.ASCII.GetBytes(input);
var hashBytes = md5.ComputeHash(inputBytes);
var builder = new StringBuilder();
foreach (var t in hashBytes)
{
builder.Append(t.ToString("x2")); // Convert byte to hexadecimal string
}
return builder.ToString();
}
}
private static void EncryptionParameters(Dictionary<string, object> args)
{
var signString =
$"{secretKey}platform={args["platform"]}packagename={args["package_name"]}channel={args["channel"]}appversion={args["app_version"]}appversioncode={args["app_version_code"]}language={args["language"]}ip={args["ip"]}ts={args["ts"]}";
var sign = GetMD5Hash(signString);
args["sign"] = sign;
}
private static void AddBaseParameters(IDictionary<string, object> args)
{
args.AddIfNotExists("unity_sdk_version", HCNativeInterface.SDKVersion);
args.AddIfNotExists("package_name", HCInfoUtils.GetBundleID());
args.AddIfNotExists("platform", HCInfoUtils.GetPlatform());
args.AddIfNotExists("channel", HCInfoUtils.GetChannel());
args.AddIfNotExists("device_type", HCInfoUtils.GetDeviceType());
args.AddIfNotExists("app_version", HCInfoUtils.GetAppVersion());
args.AddIfNotExists("app_version_code", HCInfoUtils.GetAppVersionCode());
args.AddIfNotExists("language", HCInfoUtils.GetLanguage());
args.AddIfNotExists("ip", "");
args.AddIfNotExists("device_id", HCTools.GetPlayerPrefsString(HCAccountManager.Instance.staticSaveKey_DeviceID));
args.AddIfNotExists("app_u8id", "");
args.AddIfNotExists("app_name", Application.productName);
args.AddIfNotExists("model", HCInfoUtils.GetModel());
args.AddIfNotExists("brand", HCInfoUtils.GetBrand());
args.AddIfNotExists("system_name", HCInfoUtils.GetSystemName());
args.AddIfNotExists("screen_size", "");
args.AddIfNotExists("network_type", "");
args.AddIfNotExists("ua", "");
args.AddIfNotExists("idfa", "");
args.AddIfNotExists("idfv", "");
args.AddIfNotExists("gaid", "");
args.AddIfNotExists("oaid", "");
args.AddIfNotExists("android_id", "");
args.AddIfNotExists("adid", "");
args.AddIfNotExists("fire_adid", "");
args.AddIfNotExists("ad_network", "");
args.AddIfNotExists("campaign", "");
args.AddIfNotExists("adgroup", "");
args.AddIfNotExists("creative", "");
args.AddIfNotExists("referrer", "");
args.AddIfNotExists("memory", "");
args.AddIfNotExists("memory_usage", "");
args.AddIfNotExists("country", "");
args.AddIfNotExists("user_id", HCTools.GetPlayerPrefsString(HCAccountManager.staticSaveKey_UserID));
args.AddIfNotExists("user_type", HCTools.GetPlayerPrefsInt(HCAccountManager.staticSaveKey_UserType));
args.AddIfNotExists("ss_distinct_id", HCTools.GetPlayerPrefsString(HCTools.SS_DISTINCT_ID));
args.AddIfNotExists("ss_account_id", HCTools.GetPlayerPrefsString(HCAccountManager.staticSaveKey_UserID));
args.AddIfNotExists("ts", "" + HCTimeTools.GetCurrentTimestamp());
foreach (var (key, value) in HCInfoUtils.GetBaseInfo())
{
args.AddIfNotExists(key, value);
}
}
public static string ConvertDictionaryToJson(Dictionary<string, object> dictionary)
{
StringBuilder jsonBuilder = new StringBuilder();
jsonBuilder.Append("{");
int count = 0;
foreach (KeyValuePair<string, object> kvp in dictionary)
{
string key = kvp.Key;
object value = kvp.Value;
jsonBuilder.AppendFormat("\"{0}\":", key);
if (value is int || value is float || value is bool)
{
jsonBuilder.Append(value.ToString().ToLower());
}
else if (value == null)
{
jsonBuilder.Append("\"\"");
}
else if (value is string)
{
jsonBuilder.AppendFormat("\"{0}\"", value);
}
else
{
// Handle other types or nested dictionaries recursively
Dictionary<string, object> nestedDictionary = value as Dictionary<string, object>;
if (nestedDictionary != null)
{
string nestedJson = ConvertDictionaryToJson(nestedDictionary);
jsonBuilder.Append(nestedJson);
}
}
count++;
if (count < dictionary.Count)
{
jsonBuilder.Append(",");
}
}
jsonBuilder.Append("}");
return jsonBuilder.ToString();
}
[Serializable]
public class Response<T>
{
public int code = -1;
public string msg;
public T data;
public int ts;
}
[Serializable]
public class DataInfo
{
public int illegal_order = -1;
}
[Serializable]
public class MiniAppConfig
{
public string content;
}
[Serializable]
public class MiniPayResult
{
public string order_no;
public int balance;
}
[Serializable]
public class CensorTextResult
{
public string has_sensitive;
public string content;
}
/// <summary>
/// 下单结果
/// </summary>
[Serializable]
public class OrderCreateResult
{
/// <summary>
/// 订单号
/// </summary>
public string order_no;
}
/// <summary>
/// 查询结果
/// </summary>
[Serializable]
public class OrderQueryResult
{
public const int PayStatusNotPaid = 0;
public const int PayStatusPaid = 1;
public const int PayStatusPaymentFailed = 2;
/// <summary>
/// 订单状态 0:未支付, 1:已支付2支付失败等其它原因
/// </summary>
public int pay_status;
public string transaction_id;
public string pay_success_time;
public string game_extra_param;
}
[Serializable]
public class OrderAwardedResult
{
}
}
}