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

410 lines
15 KiB
C#
Raw Permalink Normal View History

2024-03-07 12:12:48 +00:00
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
{
}
}
}