01-30-2024 11:55 AM
I've almost completed what I think is a pretty solid script to allow the user to download DLC (assetbundle) for my app using Oculus Platform. All goes well from entitlement checks, to retrieving prices, to checking already purchased items, to the purchase itself.
Starting the actual download however fails and returns this error:
Either the service couldn't be connected to, Horizon isn't installed, or you're running an incompatible of home/horizon
What's strange is that I can't find anything about this error. Literally zero results on google.
Solved! Go to Solution.
03-23-2024 12:55 PM
Thanks for replying, I fixed it but forgot that I reported this problem.
My approach around handling AssetIDs was wrong. They're susceptible to change and can't just be stored somewhere. I believe that this error happens when you try to download an AssetID that doesn't exist. Or it does exist but belongs to another app (hence why the specific 'horizon isn't installed' error is so rare).
Anyway, we got it fixed by always relying on GetList() at the start of the app. Here's a snippet of our approach:
void OnPurchasesRetrieved()
{
Debug.Log("Finished checking purchased DLC. Retrieving downloadable assets");
GetOculusAssetFileList();
}
public void GetOculusAssetFileList()
{
AssetFile.GetList().OnComplete((Message<AssetDetailsList> msg) =>
{
if (msg.IsError)
{
Debug.LogError("Error retrieving DLC information: " + msg.GetError().Message);
loadStatus.text = "Error retrieving DLC information";
return;
}
List<ulong> assetIds = new List<ulong>();
Dictionary<string, string> newSkuToFilepathMap = new Dictionary<string, string>();
FetchPurchasedProducts((purchasedSkus) =>
{
foreach (var assetDetail in msg.Data)
{
Debug.Log($"AssetID: {assetDetail.AssetId}, Filepath: {assetDetail.Filepath}");
if (!string.IsNullOrEmpty(assetDetail.Filepath))
{
var filepathParts = assetDetail.Filepath.Split('/');
var filename = filepathParts.LastOrDefault();
var sku = Path.GetFileNameWithoutExtension(filename);
if (thumbnailSKUs.Contains(sku))
{
newSkuToFilepathMap[sku] = assetDetail.Filepath;
bool isDownloaded = File.Exists(assetDetail.Filepath);
skuDownloadStatus[sku] = isDownloaded;
assetIds.Add(assetDetail.AssetId);
skuToAssetIdMap[sku] = assetDetail.AssetId;
skuPurchaseStatus[sku] = purchasedSkus.Contains(sku);
}
}
}
skuToFilepathMap = newSkuToFilepathMap;
dlcAssetIds = assetIds.ToArray();
});
});
}
private void FetchPurchasedProducts(Action<List<string>> onComplete)
{
IAP.GetViewerPurchases().OnComplete((Message<PurchaseList> msg) =>
{
if (msg.IsError)
{
Debug.LogError("Error checking purchased DLC: " + msg.GetError().Message);
onComplete(new List<string>());
return;
}
List<string> purchasedSkus = msg.Data.Select(p => p.Sku).ToList();
onComplete(purchasedSkus);
});
}
03-13-2024 06:09 PM
Hi there,
Any update on this? We're having the exact same problem.
03-23-2024 12:55 PM
Thanks for replying, I fixed it but forgot that I reported this problem.
My approach around handling AssetIDs was wrong. They're susceptible to change and can't just be stored somewhere. I believe that this error happens when you try to download an AssetID that doesn't exist. Or it does exist but belongs to another app (hence why the specific 'horizon isn't installed' error is so rare).
Anyway, we got it fixed by always relying on GetList() at the start of the app. Here's a snippet of our approach:
void OnPurchasesRetrieved()
{
Debug.Log("Finished checking purchased DLC. Retrieving downloadable assets");
GetOculusAssetFileList();
}
public void GetOculusAssetFileList()
{
AssetFile.GetList().OnComplete((Message<AssetDetailsList> msg) =>
{
if (msg.IsError)
{
Debug.LogError("Error retrieving DLC information: " + msg.GetError().Message);
loadStatus.text = "Error retrieving DLC information";
return;
}
List<ulong> assetIds = new List<ulong>();
Dictionary<string, string> newSkuToFilepathMap = new Dictionary<string, string>();
FetchPurchasedProducts((purchasedSkus) =>
{
foreach (var assetDetail in msg.Data)
{
Debug.Log($"AssetID: {assetDetail.AssetId}, Filepath: {assetDetail.Filepath}");
if (!string.IsNullOrEmpty(assetDetail.Filepath))
{
var filepathParts = assetDetail.Filepath.Split('/');
var filename = filepathParts.LastOrDefault();
var sku = Path.GetFileNameWithoutExtension(filename);
if (thumbnailSKUs.Contains(sku))
{
newSkuToFilepathMap[sku] = assetDetail.Filepath;
bool isDownloaded = File.Exists(assetDetail.Filepath);
skuDownloadStatus[sku] = isDownloaded;
assetIds.Add(assetDetail.AssetId);
skuToAssetIdMap[sku] = assetDetail.AssetId;
skuPurchaseStatus[sku] = purchasedSkus.Contains(sku);
}
}
}
skuToFilepathMap = newSkuToFilepathMap;
dlcAssetIds = assetIds.ToArray();
});
});
}
private void FetchPurchasedProducts(Action<List<string>> onComplete)
{
IAP.GetViewerPurchases().OnComplete((Message<PurchaseList> msg) =>
{
if (msg.IsError)
{
Debug.LogError("Error checking purchased DLC: " + msg.GetError().Message);
onComplete(new List<string>());
return;
}
List<string> purchasedSkus = msg.Data.Select(p => p.Sku).ToList();
onComplete(purchasedSkus);
});
}