| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905 | using System;using System.Collections.Generic;using System.IO;using System.Security.Cryptography;using System.Text;using UnityEngine;using UnityEngine.Networking;using simplejson;public class YouLoftServices : MonoBehaviour{     public static string URL_ROOT = "https://chinaapi.youloft.com";    /*       channelPay     */    /**     * 渠道下单接口,根据不同渠道需要的数据不同     * 返回的数据结构不同,前端需要根据情况解析     */    public static string ChannelpayOrder = "/api/Channelpay/Order";    /**     * 获取当前游戏,渠道的最新版本     * 返回结果无加密     */    public static string ChannelpayGetAppVersion = "/api/Channelpay/GetAppVersion";    /*    Config     */    /**     * 获取服务器配置     * appver:如果不需要根据版本判断可以串0     * lastver:每次全新获取传0     */    public static string ConfigSync = "/api/Config/Sync";    /*    Dedeem     */    /**     * 兑换码兑换接口     */    public static string DedeemConsume = "/api/Dedeem/Consume";    /*       user     */    /**     * 登录接口微信-游客     * 登录之后返回token,每次操作验证token     * 请求需要签名,返回数据无加密     */    public static string UserLogin = "/api/User/Login";    /**     * 获取(提交)存档到服务器     * 1.每次启动游戏优先获取存档     * 2.当有需要更新的存档时提交服务器     * 提交存档时服务器会默认覆盖以前的存档不会做其他判断     * 请求需要签名,返回数据有加密     */    public static string UserSync = "/api/User/Sync";    /**     * 获取(提交)存档到服务器     * 1.每次启动游戏优先获取存档     * 2.当有需要更新的存档时提交服务器     * 3.文件流不加入签名     * 4.返回字符串编码为ascii     * 提交存档时服务器会默认覆盖以前的存档不会做其他判断     * 请求需要签名,返回数据有加密     */    public static string UserSyncStream = "/api/User/SyncStream";    /**     * 心跳检测,判断当前客户端登陆是否有效     * 请求需要签名,返回数据无加密     */    public static string UserHeartbeat = "/api/User/Heartbeat";    /**     * 用户下订接口,下单成功之后返回支付链接     * -跳转支付页面     */    public static string UserOrder = "/api/User/Order";    /**     * 恢复购买,查看已完成的所有订单,以及消耗状态     * 请求需要签名,返回结果有加密     */    public static string UserResumepurchase = "/api/User/Resumepurchase";    /**     * 订单消耗     * 请求需要签名,返回结果有加密     */    public static string UserConsume = "/api/User/Consume";    /**     * 查询单个订单的状态     * 用来处理非消耗性商品,判断订单是否支付完成     * 返回结果有加密     */    public static string UserQueryOrder = "/api/User/QueryOrder";    /**     * 获取排行榜     * 用户信息     */    public static string UserLeaderboard = "/api/User/Leaderboard";    /**     * 提交用户分数     * 返回用户排行榜信息,返回结果无加密     */    public static string UserUploadScore = "/api/User/UploadScore";    /**     * 获取用户自己的排名     */    public static string UserGetUserRank = "/api/User/GetUserRank";    /**     * 提交反馈信息     */    public static string feedback = "/api/Feedback/Submit";    /**     * 获取活动及对应物品接口(带渠道),返回结果有加密     */    public static string getActivitiesWithChannel = "/api/Activity/GetActivitiesWithChannel";    /**     * 获取公告及补偿物品列表接口(带渠道),返回结果有加密     */    public static string gameAnoncementsWithChannel = "/api/Anoncement/GameAnoncementsWithChannel";    /**     * 带渠道的兑换     */    public static string RedeemConsume = "/api/Redeem/Consume";    public static string RedeemUserConsume = "/api/Redeem/UserConsume";    /**     * 上报付费,匹配点击记录,回调到广告方     */    public static string PayrecordSubmit = "/api/Payrecord/Submit";        #region 初始化    private static readonly YouLoftServices instance = null;    static YouLoftServices()    {        if (string.IsNullOrEmpty(apiUrl) || string.IsNullOrEmpty(gameId) || string.IsNullOrEmpty(gameKey))        {            Debug.LogError("没有配置YouLoftService配置");        }        else        {            Debug.Log("YouLoftService: " + string.Join("=", apiUrl, gameId, gameKey));            var go = new GameObject(nameof(YouLoftServices));            instance = go.AddComponent<YouLoftServices>();            DontDestroyOnLoad(go);        }    }    //初始化    public static void Init()    {    }    private static string apiUrl = "https://gameapi.pottingmob.com";    // private static string gameId = "80388d1f-8901-414c-b7f8-62d125e60200";    private static string gameId = PottingMobileContent.GameId;    private static string gameKey = PottingMobileContent.GameSecret;    // private static string gameKey = "12345678123456781234567812345678";    private static string tokenid = "";    private static string userid = "";    private static int GameServerArchiveversion { get; set; }    #endregion    /// <summary>    /// 服务器配置    /// </summary>    public static void ServerConfig(Action<int, string> callback)    {        var jsonData = new JSONObject        {            ["appVer"] = "0",            ["lastVer"] = 0,            ["nonce"] = UnityEngine.Random.Range(0, 100000000).ToString(),            ["timestamp"] = GetUnixTime(),            ["gameid"] = gameId        };        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(ConfigSync, jsonData, (i, s) =>        {            if (i == 1)            {                var jsn = JSON.Parse(s);                var data = DecryptDES(jsn["data"], gameKey.Substring(0, 8));                callback?.Invoke(1, data);            }            else callback?.Invoke(2, s);        });    }    /// <summary>    /// 兑换码    /// </summary>    public static void RedemptionCode(string code, Action<int, string> callback)    {        var jsonData = new JSONObject        {            ["redeemcode"] = code,            ["nonce"] = UnityEngine.Random.Range(0, 100000000).ToString(),            ["timestamp"] = GetUnixTime(),            ["gameid"] = gameId        };        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(DedeemConsume, jsonData, (i, s) =>        {            if (i == 1)            {                var jsn = JSON.Parse(s);                var data = DecryptDES(jsn["data"], gameKey.Substring(0, 8));                callback?.Invoke(1, data);            }            else callback?.Invoke(2, s);        });    }            public static void _redeemConsume(string code,string channel, Action<int, string> callback)    {        var jsonData = new JSONObject        {            ["redeemcode"] = code,            ["channel"] = channel,                        ["nonce"] = UnityEngine.Random.Range(0, 100000000).ToString(),            ["timestamp"] = GetUnixTime(),            ["gameid"] = gameId        };        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(RedeemConsume, jsonData, (i, s) =>        {            if (i == 1)            {                var jsn = JSON.Parse(s);                var data = DecryptDES(jsn["data"], gameKey.Substring(0, 8));                callback?.Invoke(1, data);            }            else callback?.Invoke(2, s);        });    }        public static void _redeemUserConsume(string code,string channel, Action<int, string> callback)    {        var jsonData = new JSONObject        {            ["redeemcode"] = code,            ["channel"] = channel,            ["clientid"] = userid,            ["nonce"] = UnityEngine.Random.Range(0, 100000000).ToString(),            ["timestamp"] = GetUnixTime(),            ["gameid"] = gameId                    };                var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(RedeemUserConsume, jsonData, (i, s) =>        {            if (i == 1)            {                var jsn = JSON.Parse(s);                var data = DecryptDES(jsn["data"], gameKey.Substring(0, 8));                callback?.Invoke(1, data);            }            else callback?.Invoke(2, s);        });    }    /// <summary>    ///服务器游戏版本    /// </summary>    public static void GameServerVersion(int channel, Action<int, string> callback)    {        var jsonData = new JSONObject        {            ["channel"] = channel,            ["nonce"] = UnityEngine.Random.Range(0, 100000000).ToString(),            ["timestamp"] = GetUnixTime(),            ["gameid"] = gameId        };        //0: 官方包 3: vivo 4: oppo 5: huawei 6: 4399 7: 应用包        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(ChannelpayGetAppVersion, jsonData, (i, s) =>        {            if (i == 1)            {                var jsn = JSON.Parse(s);                var data = DecryptDES(jsn["data"], gameKey.Substring(0, 8));                ShowLog("GameServerVersion:" + data);                callback?.Invoke(1, jsn);            }            else callback?.Invoke(2, s);        });    }    /// <summary>    /// 活动    /// </summary>    /// <param name="channel"></param>    /// <param name="language"></param>    /// <param name="callback"></param>    public static void ActivityBy(string channel,string language, Action<int, string> callback)    {        var jsonData = new JSONObject        {            ["channel"] = channel,            ["language"] = language,            ["nonce"] = UnityEngine.Random.Range(0, 100000000).ToString(),            ["timestamp"] = GetUnixTime(),            ["gameid"] = gameId        };        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(getActivitiesWithChannel, jsonData, (i, s) =>        {            if (i == 1)            {                var jsn = JSON.Parse(s);                var data = DecryptDES(jsn["data"], gameKey.Substring(0, 8));                callback?.Invoke(1, data);            }            else callback?.Invoke(2, s);        });    }    /// <summary>    /// 公告    /// </summary>    /// <param name="channel"></param>    /// <param name="version"></param>    /// <param name="language"></param>    /// <param name="callback"></param>    public static void AnnouncementBy(string channel, string version, string language, Action<int, string> callback)    {        var jsonData = new JSONObject        {            ["channel"] = channel,            ["version"] = version,            ["language"] = language,            ["nonce"] = UnityEngine.Random.Range(0, 100000000).ToString(),            ["timestamp"] = GetUnixTime(),            ["gameid"] = gameId        };        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(gameAnoncementsWithChannel, jsonData, (i, s) =>        {            var jsn = JSON.Parse(s);            var data = DecryptDES(jsn["data"], gameKey.Substring(0, 8));            callback?.Invoke(1, data);        });    }    // private static void MoniLogin()    // {    //     Login(new UserGraph    //     {    //         userID = SystemInfo.deviceUniqueIdentifier,    //         nickName = SystemInfo.deviceUniqueIdentifier,    //         platform = 0    //     }, (i, s) => { });    // }    /// <summary>    /// 登录    /// </summary>    public static void Login(string id, int type, string name, string icon, Action<int, string> callback)    {        var jsonData = new JSONObject        {            ["markid"] = id,            ["type"] = type,            ["name"] = name,            ["icon"] = icon,            ["nonce"] = UnityEngine.Random.Range(0, 100000000).ToString(),            ["timestamp"] = GetUnixTime(),            ["gameid"] = gameId        };        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(UserLogin, jsonData, (i, s) =>        {            if (i == 1)            {                var jsn = JSON.Parse(s);                var data = jsn["data"];                tokenid = data["tokenid"];                userid = data["userid"];                callback?.Invoke(1, userid);            }            else callback?.Invoke(2, s);        });    }    /// <summary>    /// 保存 or 提交存档    /// </summary>    public static void CommitArchive(string archiveStr, long archiveVersion, Action<int, string> callback)    {        ShowLog("CommitArchive_version = " + archiveVersion);        var jsonData = GetBaseJsonData();        jsonData["archive"] = archiveStr;        jsonData["archiveVersion"] = archiveVersion;        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(UserSync, jsonData, (i, s) =>        {            if (i == 1)            {                var jsn = JSON.Parse(s);                var archive = GetDecryptDESDecodeMsg(jsn["data"]);                var archiveJson = JSON.Parse(archive);                var archiveData = archiveJson["Archive"];                int.TryParse(archiveJson["Archiveversion"], out var version);                GameServerArchiveversion = version;                callback?.Invoke(1, archiveData);            }            else callback?.Invoke(2, s);        });    }    /// <summary>    /// 请求支付 (starUrl = resultData["data"] endUrl = resultData["returnAppLink"] orderid = resultData["orderid"])    /// </summary>    public static void RequestOrder(string goodsid,string activityid, Action<int, string, string, string> callback)    {        var jsonData = GetBaseJsonData();        jsonData["goodsid"] = goodsid;        jsonData["activityid"] = activityid;        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(UserOrder, jsonData, (i, s) =>        {            if (i == 1)            {                var resultData = JSON.Parse(s);                var starUrl = resultData["data"];                var endUrl = resultData["returnAppLink"];                var orderid = resultData["orderid"];                callback?.Invoke(1, starUrl, endUrl, orderid);            }            else callback?.Invoke(2, s, s, s);        });    }        public static void _channelPayOrder(int channel,string goodsid, Action<int, string> callback)    {        var jsonData = GetBaseJsonData();        jsonData["channel"] = channel;        jsonData["goodsid"] = goodsid;        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(ChannelpayOrder, jsonData, (i, s) =>        {            if (i == 1)            {                              callback?.Invoke(1, s);            }            else callback?.Invoke(2,s);        });    }        public static void _userQueryOrder(string goodsid, string orderId, Action<int, string> callback)    {        var jsonData = GetBaseJsonData();        jsonData["goodsid"] = goodsid;        jsonData["orderid"] = orderId;        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(UserQueryOrder, jsonData, (i, s) =>        {            if (i == 1)            {                callback?.Invoke(1, s);            }            else callback?.Invoke(2,s);        });    }        public static void _userHeartbeat(Action<int, string> callback)    {        var jsonData = GetBaseJsonData();        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(UserHeartbeat, jsonData, (i, s) =>        {            if (i == 1)            {                callback?.Invoke(1, s);            }            else callback?.Invoke(2,s);        });    }    /// <summary>    /// 消耗订单    /// </summary>    public static void ConsumeOrder(string goodsid, string orderid, Action<int, string> callback)    {        var jsonData = GetBaseJsonData();        jsonData["goodsid"] = goodsid;        jsonData["orderid"] = orderid;        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(UserConsume, jsonData, (i, s) =>        {            if (i == 1)            {                var resultData = JSON.Parse(s);                string orderData = GetDecryptDESDecodeMsg(resultData["data"]);                var orderJson = JSON.Parse(orderData);                var orderStatus = int.Parse(orderJson["Orderstatus"]); //0:not pay 1:pay 2:pay and use                ShowLog($"订单状态数据:{orderJson},{orderStatus}");                if (orderStatus == 2) callback?.Invoke(1, orderid);                else callback?.Invoke(2, "错误:订单状态=" + orderStatus.ToString());            }            else callback?.Invoke(2, s);        });    }    //查询订单    public static void ResumeOrder(Action<int, string>callback)    {        var jsonData = GetBaseJsonData();        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(UserResumepurchase, jsonData, (code, s) =>        {            if (code == 1)            {                var resultData = JSON.Parse(s);                string orderData = GetDecryptDESDecodeMsg(resultData["data"]);                var orderJson = JSON.Parse(orderData);                ShowLog("Resumepurchase data : " + orderJson);                // List<OrderInfo> orderList = new List<OrderInfo>();                // for (int i = 0; i < orderJson.Count; i++)                // {                //     var orderInfo = new OrderInfo();                //     orderInfo.orderID = orderJson[i]["Orderid"];                //     orderInfo.orderStatus = int.Parse(orderJson[i]["Orderstatus"]);                //     orderInfo.goodsID = orderJson[i]["Goodsid"];                //     orderInfo.goodsInfo = orderJson[i]["Goodsinfo"];                //     if (orderInfo.orderStatus == 1) orderList.Add(orderInfo);                //     else ShowLog("Resumepurchase orderStatus = " + orderInfo.orderStatus);                // }                callback?.Invoke(1, orderJson);            }            else callback?.Invoke(2, null);        });    }    public static void Feedback(string imsg, string contact, string savedata, string appVer, string deviceid,        string countrycode,        Action<int, string> callback)    {        var jsonData = new JSONObject();        jsonData["msg"] = imsg; //用户提交的信息        jsonData["contact"] = contact; //联系方式 邮箱 qq 电话,微信        jsonData["documentinfo"] = savedata; //存档        jsonData["appVer"] = appVer; //应用版本        jsonData["device"] = deviceid; //设备信息        jsonData["countryCode"] = countrycode; //国家代码        jsonData["nonce"] = UnityEngine.Random.Range(0, 100000000).ToString();        jsonData["timestamp"] = GetUnixTime();        jsonData["gameid"] = gameId;        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(feedback, jsonData, (i, s) => { callback?.Invoke(i == 1 ? 1 : 2, s); });    }    //上传分数    public static void UploadScore(string rankingid, int score, string info, System.Action<bool> callback = null)    {        var jsonData = GetBaseJsonData();        jsonData["rankingid"] = rankingid;        jsonData["score"] = score;        jsonData["info"] = info;        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(UserUploadScore, jsonData, (i, s) => { callback?.Invoke(i == 1); });    }            public static void _userGetUserRank(string rankingid,System.Action<int, string> callback)    {        var jsonData = GetBaseJsonData();        jsonData["rankingid"] = rankingid;        var signStr = GetSign(jsonData);        jsonData["sign"] = signStr;        PostJson(UserGetUserRank, jsonData, (i, s) =>        {            callback?.Invoke(i,s);        });    }    //获取排行榜链接    public static string GetLeaderboardLink(string rankId = "")    {        if (userid == null) return null;        return "https://chinaapi.youloft.com/ranking/index?" +               "gameid=" + gameId +               "&userid=" + userid +               "&rankid=" + rankId;    }    //服务基础数据    private static JSONObject GetBaseJsonData()    {        var jsonData = new JSONObject();        jsonData["userid"] = userid;        jsonData["token"] = tokenid;        jsonData["gameid"] = gameId;        jsonData["nonce"] = UnityEngine.Random.Range(0, 100000000).ToString();        jsonData["timestamp"] = GetUnixTime();        return jsonData;    }    private static string CheckError(UnityWebRequest request)    {        int code = 0;        string log = "";        if (request.error != null) code = -1;        if (code == 0 && request.downloadHandler.text != null)        {            var resultData = JSON.Parse(request.downloadHandler.text);            code = int.Parse(resultData["code"]);        }        switch (code)        {            case 200:            case 2000:            case 2100:            case 2200:                log = "";                break;            case -1:                log = request.error;                break;            case 4001:                log = "错误的随机数";                break;            case 4002:                log = "错误的时间";                break;            case 4003:                log = "错误的签名";                break;            case 4004:                log = "错误的游戏";                break;            case 4005:                log = "错误的授权";                break;            case 4006:                log = "错误的订单";                break;            case 4007:                log = "错误的标识";                break;            case 4008:                log = "用户登录异常";                break;            case 4009:                log = "服务器维护中";                break;            default:                log = "其他";                break;        }        if (!string.IsNullOrEmpty(log)) Debug.LogError($"CheckErrcode : code = {code}, Msg = {log}");        return log;    }    private static string GetSign(JSONObject jsonData)    {        List<string> keyList = new List<string>();        foreach (var pair in jsonData)        {            var value = pair.Value;            keyList.Add(value);        }        keyList.Add(gameKey);        return EncrpytParam(keyList);    }    #region 加密解密    /// <summary>    /// 对list ascii 排序,然后md5加密    /// </summary>    /// <param name="paramList"></param>    /// <returns></returns>    public static string EncrpytParam(List<string> paramList)    {        if (paramList == null)        {            throw new ArgumentNullException(nameof(paramList));        }        paramList.Sort((a, b) => { return string.CompareOrdinal(a, b); });        var tempStr = string.Join("&", paramList);        return MD5Hash(tempStr);    }    /// <summary>    /// md5加密,32位大写字母,不包含短横线    /// </summary>    /// <param name="input"></param>    /// <returns></returns>    public static string MD5Hash(string input)    {        using (var md5 = MD5.Create())        {            var result = md5.ComputeHash(Encoding.UTF8.GetBytes(input));            var strResult = BitConverter.ToString(result);            return strResult.Replace("-", "");        }    }    /// <summary>    /// 获取解密秘钥(登录)    /// </summary>    /// <returns></returns>    public static string GetDescryptKey()    {        var key = tokenid.Replace("-", "").Substring(0, 4) + gameKey.Substring(0, 4);        return key;    }    /// <summary>    /// DES解密字符串    /// </summary>    /// <param name="decryptString">待解密的字符串</param>    /// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>    /// <returns>解密成功返回解密后的字符串,失败返源串</returns>    public static string DecryptDES(string decryptString, string decryptKey)    {        try        {            byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);            byte[] rgbIV = { 0x12, 0x34, 0x56, 0x45, 0x31, 0x16, 0x78, 0x67 };            byte[] inputByteArray = Convert.FromBase64String(decryptString);            DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();            MemoryStream mStream = new MemoryStream();            CryptoStream cStream =                new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);            cStream.Write(inputByteArray, 0, inputByteArray.Length);            cStream.FlushFinalBlock();            return Encoding.UTF8.GetString(mStream.ToArray());        }        catch (Exception e)        {            Debug.LogError("DES解密字符串错误 : " + e);            return decryptString;        }    }    public static string GetGetDecryptDESWithoutToken(string decryptString)    {        return DecryptDES(decryptString, gameKey.Substring(0, 8));    }    public static string GetDecryptDESDecodeMsg(string decryptString)    {        string descyptKey = GetDescryptKey();        string dataStr = DecryptDES(decryptString, descyptKey);        return dataStr;    }    #endregion    #region http interface    private static void PostJson(string switcher, JSONObject jsonObject, Action<int, string> onCompleted)    {        var jsn = jsonObject.ToString();        ShowLog($"PostJson:Url={switcher},data={jsn}");        HttpPost(instance, switcher, Encoding.Default.GetBytes(jsn), request =>        {            var str = CheckError(request);            if (string.IsNullOrEmpty(str))            {                onCompleted?.Invoke(1, request.downloadHandler.text);            }            else onCompleted?.Invoke(2, str);        });    }    private static void HttpPost(MonoBehaviour holder, string switcher, byte[] body,        Action<UnityWebRequest> onCompleted,        int timeoutSeconds = -1)    {        holder.StartCoroutine(HttpPostHelper(holder, switcher, body, onCompleted, timeoutSeconds));    }    private static IEnumerator<UnityWebRequestAsyncOperation> HttpPostHelper(MonoBehaviour holder, string switcher,        byte[] body,        Action<UnityWebRequest> onCompleted, int timeoutSeconds)    {        using (UnityWebRequest request = new UnityWebRequest(apiUrl + switcher, "POST"))        {            request.uploadHandler = new UploadHandlerRaw(body);            request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");            request.downloadHandler = new DownloadHandlerBuffer();            if (timeoutSeconds > 0) request.timeout = timeoutSeconds;            yield return request.SendWebRequest();            onCompleted?.Invoke(request);        }    }    #endregion    public class OrderInfo    {        public string orderID;        public int orderStatus;        public string goodsID;        public string goodsInfo;    }    private static readonly DateTime _date = new DateTime(1970, 1, 1, 0, 0, 0, 0);    public static int GetUnixTime()    {        TimeSpan ts = DateTime.UtcNow - _date;        return Convert.ToInt32(ts.TotalSeconds);    }    public static string ShowLog(string msg)    {        Debug.Log(msg);        return msg;    }}public class UserGraph{    public string userID;    public int platform; //99:游客登录 0:自注册用户 1:微信登录 2:qq用户 3: vivo 4: oppo 5: huawei 6: 4399 7: 应用包    public string nickName;    public string imageUrl;}
 |