Unity IAP包位于何处?

时间:2017-01-01 15:29:07

标签: c# unity3d service import in-app-purchase

我目前正在开发一个编辑器脚本,可以简化我在我的游戏的免费增值和付费版本之间的转换。我想手动导入当我单击服务下的导入按钮时导入的.unitypackage文件 - >应用程序内购买。

我知道函数AssetDatabase.ImportAsset(path),但我首先需要包的路径。

提前致谢!

1 个答案:

答案 0 :(得分:1)

启用IAP并单击“导入”后,将发生以下情况:

1 .Unity将使用

生成随机文件名
FileUtil.GetUniqueTempPathInProject()

2 。完整路径将如下构建:

<ProjectName>Temp\FileUtil.GetUniqueTempPathInProject()

3 .Unity会将 .unitypackage 添加到该随机文件名的末尾。

现在,你有类似的东西:

<ProjectName>Temp\FileUtil.GetUniqueTempPathInProject()+".unitypackage";

4 .IAP包将被下载并存储到#3 的路径中。

它的外观图示:

enter image description here

5 。然后将文件复制到

<ProjectName>Temp\TarGZ

使用#2 生成的文件名保存。最后没有 .unitypackage ,例如#3

UnityEngine.Cloud.Purchasing

6 。之后,Unity会根据您提问中的AssetDatabase.ImportPackage 而不是 AssetDatabase.ImportAsset(path,false)导入它。

现在您可以看到Unity IAP软件包所在的位置,但您尝试执行的操作几乎没有问题

1 。对于要出现的IAP包,必须单击服务标签中的导入按钮。我相信你希望这是自动化的。

2 。文件名不是静态的,因此难以检索路径。从上图中可以看出,此文件夹中还有其他文件。我们不知道哪一个是 AIP 包。

3 。重新启动Unity时,将删除临时文件夹。因此下载的IAP包将丢失

获取Unity IAP软件包的最佳方法是直接从Unity服务器下载它,然后将其保存到您首选的位置。 下面的代码将下载IAP软件包并将其存储在:<ProjectName>/UnityEngine.Cloud.Purchasing.unitypackage 它还会导入它然后启用它。要使AIP正常运行,还必须启用 Analytics 。这段代码也会这样做。

我试图隐藏AIP url,以免它被滥用,Unity不会改变它。

如果您想将其重新制作成其他内容,则需要考虑的两个最重要的功能是downloadAndInstallAIP()deleteAndDisableAIP()

enter image description here

AIPDownloader 代码:

using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using UnityEditor;
using UnityEditor.Analytics;
using UnityEditor.Purchasing;
using UnityEngine;

[ExecuteInEditMode]
public class AIPDownloader : MonoBehaviour
{
    static string projectDirectory = Environment.CurrentDirectory;

    static string aipFileName = "UnityEngine.Cloud.Purchasing.unitypackage";
    static string etagName = "UnityEngine.Cloud.PurchasingETAG.text";

    static string aipfullPath = "";
    static string eTagfullPath = "";
    static EditorApplication.CallbackFunction doneEvent;


    [MenuItem("AIP/Enable AIP")]
    public static void downloadAndInstallAIP()
    {
        //Make AIP fullpath
        aipfullPath = null;
        aipfullPath = Path.Combine(projectDirectory, aipFileName);

        //Make AIP Etag fullpath
        eTagfullPath = null;
        eTagfullPath = Path.Combine(projectDirectory, etagName);

        /*If the AIP File already exist at <ProjectName>/UnityEngine.Cloud.Purchasing.unitypackage, 
         * there is no need to re-download it.
         Re-import the package
         */

        if (File.Exists(aipfullPath))
        {
            Debug.Log("AIP Package already exist. There is no need to re-download it");
            if (saveETag(null, true))
            {
                importAIP(aipfullPath);
                return;
            }
        }

        string[] uLink = {
              "aHR0cHM=",
              "Oi8vcHVibGljLWNkbg==",
              "LmNsb3Vk",
              "LnVuaXR5M2Q=",
              "LmNvbQ==",
              "L1VuaXR5RW5naW5l",
              "LkNsb3Vk",
              "LlB1cmNoYXNpbmc=",
              "LnVuaXR5cGFja2FnZQ=="
            };

        prepare(uLink);

        try
        {
            ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);

            WebClient client = new WebClient();

            client.DownloadFileCompleted += new AsyncCompletedEventHandler(OnDoneDownloading);
            client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(OnDownloadProgressChanged);
            client.DownloadFileAsync(new Uri(calc(uLink)), aipfullPath);
        }
        catch (Exception e)
        {
            Debug.LogError("Error: " + e.Message);
        }
    }

    [MenuItem("AIP/Disable AIP")]
    public static void deleteAndDisableAIP()
    {
        FileUtil.DeleteFileOrDirectory("Assets/Plugins/UnityPurchasing");

        //Disable AIP
        PurchasingSettings.enabled = false;

        //Disable Analytics
        AnalyticsSettings.enabled = false;
    }


    private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
    {
        return true;
    }

    public bool isAIPEnabled()
    {
        return PurchasingSettings.enabled;
    }

    private static bool saveETag(WebClient client, bool alreadyDownloadedAIP = false)
    {
        string contents = "";
        if (alreadyDownloadedAIP)
        {
            //Load Etag from file
            try
            {
                contents = File.ReadAllText(eTagfullPath);
                return _saveEtag(contents, alreadyDownloadedAIP);
            }
            catch (Exception e)
            {
                Debug.LogWarning("File does not exist!: " + e.Message);
            }
            return false; //Failed
        }
        else
        {
            //Load Etag from downloaded WebClient
            contents = client.ResponseHeaders.Get("ETag");
            return _saveEtag(contents, alreadyDownloadedAIP);
        }
    }

    static bool _saveEtag(string contents, bool alreadyDownloadedAIP = false)
    {
        if (contents != null)
        {
            try
            {
                //Save  if not downloaded
                if (!alreadyDownloadedAIP)
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(eTagfullPath));
                    File.WriteAllText(eTagfullPath, contents);
                }

                //Save to the etag to AIP directory
                Directory.CreateDirectory(Path.GetDirectoryName("Assets/Plugins/UnityPurchasing/ETag"));
                File.WriteAllText("Assets/Plugins/UnityPurchasing/ETag", contents);
                return true;//Success
            }
            catch (Exception e)
            {
                Debug.LogWarning("Failed to write to file: " + e.Message);
                return false; //Failed
            }
        }
        else
        {
            return false; //Failed
        }
    }

    public static void OnDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        Debug.Log("Downloading: " + e.ProgressPercentage);
    }

    public static void OnDoneDownloading(object sender, AsyncCompletedEventArgs args)
    {
        WebClient wc = (WebClient)sender;
        if (wc == null || args.Error != null)
        {
            Debug.Log("Failed to Download AIP!");
            return;
        }
        Debug.Log("In Download Thread. Done Downloading");

        saveETag(wc, false);

        doneEvent = null;
        doneEvent = new EditorApplication.CallbackFunction(AfterDownLoading);

        //Add doneEvent function to call back!
        EditorApplication.update = (EditorApplication.CallbackFunction)Delegate.Combine(EditorApplication.update, doneEvent);
    }

    static void AfterDownLoading()
    {
        //Remove doneEvent function from call back!
        EditorApplication.update = (EditorApplication.CallbackFunction)Delegate.Remove(EditorApplication.update, doneEvent);
        Debug.Log("Back to Main Thread. Done Downloading!");

        importAIP(aipfullPath);
    }

    //Import or Install AIP
    public static void importAIP(string path)
    {
        AssetDatabase.ImportPackage(path, false);
        Debug.Log("Done Importing AIP package");

        //Enable Analytics
        AnalyticsSettings.enabled = true;

        //Enable AIP
        PurchasingSettings.enabled = true;
    }


    private static void prepare(string[] uLink)
    {
        for (int i = 5; i < uLink.Length; i++)
        {
            byte[] textAsBytes = System.Convert.FromBase64String(uLink[i]);
            uLink[i] = Encoding.UTF8.GetString(textAsBytes);
        }

        for (int i = 0; i < uLink.Length; i++)
        {
            byte[] textAsBytes = System.Convert.FromBase64String(uLink[i]);
            uLink[i] = Encoding.UTF8.GetString(textAsBytes);

            if (i == 4)
            {
                break;
            }
        }
    }

    private static string calc(string[] uLink)
    {
        return string.Join("", uLink);
    }
}