com.azerion.bluestack 6.0.0-beta.0 → 6.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -16
- package/Editor/Android/AndroidDependencyParser.cs +5 -2
- package/Editor/BlueStackAssetPostProcessor.cs +5 -2
- package/Editor/BlueStackDependenciesSource.xml +1 -1
- package/Editor/BlueStackSettings.cs +8 -0
- package/Editor/BlueStackSettingsEditor.cs +70 -19
- package/Editor/BlueStackVersionExporter.cs +214 -0
- package/Editor/BlueStackVersionExporter.cs.meta +2 -0
- package/Editor/Prefabs/AdPrefabs/Banners/Banner.prefab +53 -17
- package/Editor/Prefabs/AdPrefabs/Banners/DynamicBanner.prefab +49 -12
- package/Editor/Prefabs/AdPrefabs/Banners/{BannerMask.prefab → DynamicLeaderboard.prefab} +178 -75
- package/Editor/Prefabs/AdPrefabs/Banners/{BannerMask.prefab.meta → DynamicLeaderboard.prefab.meta} +1 -1
- package/Editor/Prefabs/AdPrefabs/Banners/FullBanner.prefab +53 -17
- package/Editor/Prefabs/AdPrefabs/Banners/LargeBanner.prefab +53 -17
- package/Editor/Prefabs/AdPrefabs/Banners/Leaderboard.prefab +53 -17
- package/Editor/Prefabs/AdPrefabs/Banners/MediumRectangle.prefab +53 -17
- package/Editor/iOS/{BlueStackBuildPostProcess.cs → IOSBuildPostProcess.cs} +1 -1
- package/Example/Scripts/NativeAdManager.cs +11 -19
- package/Example/Scripts/SmallNativeAdManager.cs +11 -19
- package/Plugins/Android/bluestack-unity-android-bridge-600.aar +0 -0
- package/Plugins/Android/bluestack-unity-android-bridge-600.aar.meta +2 -0
- package/Plugins/iOS/BSUBanner.h +6 -4
- package/Plugins/iOS/BSUBanner.swift +23 -20
- package/Plugins/iOS/BSUInitializer.h +1 -1
- package/Plugins/iOS/BSUInitializer.swift +10 -3
- package/Plugins/iOS/BSUInterface.h +12 -13
- package/Plugins/iOS/BSUInterface.m +34 -64
- package/Plugins/iOS/BSUInterstitialAd.swift +12 -3
- package/Plugins/iOS/BSULogger.h +22 -0
- package/Plugins/iOS/{BSUSettings.h.meta → BSULogger.h.meta} +5 -5
- package/Plugins/iOS/BSULogger.swift +60 -0
- package/Plugins/iOS/{BSUSettings.swift.meta → BSULogger.swift.meta} +5 -5
- package/Plugins/iOS/BSUNativeAd.swift +5 -4
- package/Plugins/iOS/BSUPluginUtil.swift +3 -9
- package/Plugins/iOS/BSURequestOptions.h +13 -5
- package/Plugins/iOS/BSURequestOptions.swift +46 -42
- package/Plugins/iOS/BSURewardedAd.swift +11 -2
- package/Plugins/iOS/BSUTypes.h +0 -1
- package/Plugins/iOS/BSUTypes.swift +0 -1
- package/README.md +7 -6
- package/Runtime/API/Banner/AdMaskHandler.cs +3 -2
- package/Runtime/API/Banner/AdPlacementHandler.cs +4 -5
- package/Runtime/API/Banner/BannerAd.cs +64 -47
- package/Runtime/API/BlueStackAds.cs +14 -3
- package/Runtime/API/InterstitialAd.cs +5 -6
- package/Runtime/API/NativeAd/NativeAd.cs +9 -13
- package/Runtime/API/NativeAd/NativeAdInteractionHandler.cs +2 -5
- package/Runtime/API/NativeAd/NativeAdLoader.cs +2 -2
- package/Runtime/API/NativeAd/NativeAdObject.cs +7 -23
- package/Runtime/API/{Preference → RequestOptions}/Gender.cs +1 -1
- package/Runtime/API/{Preference → RequestOptions}/Location.cs +23 -19
- package/Runtime/API/RequestOptions/RequestOptions.cs +66 -0
- package/Runtime/API/RequestOptions.meta +8 -0
- package/Runtime/API/Rewarded/RewardedAd.cs +4 -5
- package/Runtime/Common/AdsMainThreadDispatcher.cs +1 -1
- package/Runtime/Common/BlueStackLogger.cs +126 -0
- package/Runtime/Common/BlueStackLogger.cs.meta +2 -0
- package/Runtime/Common/BlueStackSdkInfo.cs +10 -0
- package/Runtime/Common/BlueStackSdkInfo.cs.meta +2 -0
- package/Runtime/Common/NativeAd/NativeUtils.cs +2 -2
- package/Runtime/Internal/IBannerAdClient.cs +4 -4
- package/Runtime/Internal/IBlueStackClient.cs +3 -1
- package/Runtime/Internal/IClientsFactory.cs +0 -2
- package/Runtime/Internal/IInterstitialAdClient.cs +1 -1
- package/Runtime/Internal/IRewardedAdClient.cs +1 -1
- package/Runtime/Internal/NativeAd/INativeAdClient.cs +1 -1
- package/Runtime/Platforms/Android/BannerAdClient.cs +28 -15
- package/Runtime/Platforms/Android/BlueStackClient.cs +8 -0
- package/Runtime/Platforms/Android/ClientsFactory.cs +0 -11
- package/Runtime/Platforms/Android/InitializationStatusClient.cs +2 -1
- package/Runtime/Platforms/Android/InterstitialAdClient.cs +12 -4
- package/Runtime/Platforms/Android/NativeAdClient.cs +14 -12
- package/Runtime/Platforms/Android/RequestOptionsClient.cs +76 -0
- package/Runtime/Platforms/Android/RequestOptionsClient.cs.meta +2 -0
- package/Runtime/Platforms/Android/RewardedAdClient.cs +12 -5
- package/Runtime/Platforms/Unity/AdBehaviour.cs +0 -3
- package/Runtime/Platforms/Unity/AdvertisementManager.cs +4 -4
- package/Runtime/Platforms/Unity/BannerAdClient.cs +256 -282
- package/Runtime/Platforms/Unity/BaseAdClient.cs +3 -2
- package/Runtime/Platforms/Unity/BlueStackClient.cs +5 -0
- package/Runtime/Platforms/Unity/ClientsFactory.cs +0 -5
- package/Runtime/Platforms/Unity/InterstitialAdClient.cs +4 -3
- package/Runtime/Platforms/Unity/NativeAdClient.cs +3 -5
- package/Runtime/Platforms/Unity/RewardedAdClient.cs +4 -3
- package/Runtime/Platforms/Unity/RewardedTimer.cs +2 -1
- package/Runtime/Platforms/iOS/BannerAdClient.cs +34 -14
- package/Runtime/Platforms/iOS/BlueStackClient.cs +5 -0
- package/Runtime/Platforms/iOS/ClientsFactory.cs +0 -11
- package/Runtime/Platforms/iOS/Externs.cs +15 -31
- package/Runtime/Platforms/iOS/InterstitialAdClient.cs +21 -11
- package/Runtime/Platforms/iOS/NativeAdClient.cs +16 -3
- package/Runtime/Platforms/iOS/RequestOptionsClient.cs +40 -0
- package/Runtime/Platforms/iOS/RequestOptionsClient.cs.meta +2 -0
- package/Runtime/Platforms/iOS/RewardedAdClient.cs +21 -10
- package/Runtime/Platforms/iOS/Utils.cs +1 -9
- package/Runtime/Utilities/AndroidEntryChecker.cs +5 -4
- package/Runtime/Utilities/CoordinateConverter.cs +81 -61
- package/package.json +2 -2
- package/CLAUDE.md +0 -157
- package/Example/Scripts/AnchoredBannerExample.cs +0 -179
- package/Example/Scripts/AnchoredBannerExample.cs.meta +0 -2
- package/Example/Scripts/BannerAnchor.cs +0 -75
- package/Example/Scripts/BannerAnchor.cs.meta +0 -2
- package/Plugins/Android/bluestack-unity-android-bridge-6.0.1.aar +0 -0
- package/Plugins/Android/bluestack-unity-android-bridge-6.0.1.aar.meta +0 -2
- package/Plugins/iOS/BSUSettings.h +0 -18
- package/Plugins/iOS/BSUSettings.swift +0 -13
- package/Runtime/API/Preference/Preference.cs +0 -80
- package/Runtime/API/Preference.meta +0 -3
- package/Runtime/API/Settings.cs +0 -21
- package/Runtime/API/Settings.cs.meta +0 -3
- package/Runtime/Internal/IPreferenceClient.cs +0 -15
- package/Runtime/Internal/IPreferenceClient.cs.meta +0 -3
- package/Runtime/Platforms/Android/PreferenceClient.cs +0 -85
- package/Runtime/Platforms/Android/PreferenceClient.cs.meta +0 -3
- package/Runtime/Platforms/Unity/PreferenceClient.cs +0 -65
- package/Runtime/Platforms/Unity/PreferenceClient.cs.meta +0 -3
- package/Runtime/Platforms/iOS/PreferenceClient.cs +0 -69
- package/Runtime/Platforms/iOS/PreferenceClient.cs.meta +0 -3
- /package/Editor/iOS/{BlueStackBuildPostProcess.cs.meta → IOSBuildPostProcess.cs.meta} +0 -0
- /package/Runtime/API/{Preference → RequestOptions}/Gender.cs.meta +0 -0
- /package/Runtime/API/{Preference → RequestOptions}/Location.cs.meta +0 -0
- /package/Runtime/API/{Preference/Preference.cs.meta → RequestOptions/RequestOptions.cs.meta} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [6.0.0] - 2026-
|
|
3
|
+
## [6.0.0-beta.2] - 2026-06-10
|
|
4
4
|
|
|
5
5
|
### Native SDK upgrades
|
|
6
6
|
|
|
@@ -20,11 +20,15 @@
|
|
|
20
20
|
- `BlueStackAds.IsInitialized` property to check native-side readiness.
|
|
21
21
|
- `InterstitialAd.IsReady` and `RewardedAd.IsReady` properties.
|
|
22
22
|
- `BannerAd` anchor-based positioning — new constructor
|
|
23
|
-
`BannerAd(string placementId, Transform anchor, Camera camera = null)`. The banner
|
|
24
|
-
anchor's screen position automatically via the new `AdPlacementHandler` component.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
`BannerAd(string placementId, AdSize adSize, Transform anchor, Camera camera = null)`. The banner
|
|
24
|
+
follows the anchor's screen position automatically via the new `AdPlacementHandler` component.
|
|
25
|
+
The anchor's screen-space position is treated as the banner's **top-left corner** (matching
|
|
26
|
+
native iOS / Android frame placement).
|
|
27
|
+
- `BannerAd` custom screen-space position constructor — `BannerAd(string placementId, AdSize adSize, Vector2 position)`.
|
|
28
|
+
The `position` is the banner's **top-left corner** in Unity pixels (bottom-left origin).
|
|
29
|
+
- Optional `useSafeArea` parameter on `BannerAd(string, AdSize, AdPosition, bool useSafeArea = true)`
|
|
30
|
+
to opt out of safe-area insets for sticky Top/Bottom banners. Custom-positioned banners always
|
|
31
|
+
ignore the safe area.
|
|
28
32
|
- Banner masking — `BannerAd.SetMask(RectTransform, Camera)` / `BannerAd.RemoveMask()` clip the banner
|
|
29
33
|
to a UI region. The mask follows the `RectTransform` as it animates or resizes.
|
|
30
34
|
- `BannerAd.OnAdResized` event delivers a `PreferredBannerSize` (`Width`, `Height`) whenever the SDK
|
|
@@ -32,8 +36,7 @@
|
|
|
32
36
|
- `BannerAd.OnAdLoaded` payload changed to `PreferredBannerSize` carrying the SDK-preferred dimensions
|
|
33
37
|
(was `EventArgs`).
|
|
34
38
|
- `RewardedAd.OnAdRewardEarned` (renamed from `OnRewardEarned`) delivers a `RewardedItem`.
|
|
35
|
-
- `UpdateInterval` API
|
|
36
|
-
(0 = every frame).
|
|
39
|
+
- `UpdateInterval` and `ForceUpdate` API added to `AdMaskHandler` and `AdPlacementHandler`
|
|
37
40
|
|
|
38
41
|
### Changed
|
|
39
42
|
|
|
@@ -66,17 +69,31 @@
|
|
|
66
69
|
- `OnRewardedVideoAdClicked` → `OnAdClicked`
|
|
67
70
|
- `OnRewardedVideoAdClosed` → `OnAdDismissed`
|
|
68
71
|
- `OnUserRewardEarned` → `OnAdRewardEarned`
|
|
69
|
-
-
|
|
70
|
-
-
|
|
71
|
-
`
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
-
|
|
75
|
-
|
|
72
|
+
- To display banner ads, `BannerAd.Show()` must be called after the ad has been loaded.
|
|
73
|
+
- **Breaking** — `BannerAd` constructors now take `AdSize` as a mandatory second parameter, and
|
|
74
|
+
`BannerAd.Load` no longer takes one:
|
|
75
|
+
- Before: `new BannerAd(placementId, adPosition); bannerAd.Load(adSize);`
|
|
76
|
+
- After: `new BannerAd(placementId, adSize, adPosition); bannerAd.Load();`
|
|
77
|
+
- Applies to all three constructor shapes (`AdPosition`, `Vector2`, `Transform` anchor).
|
|
78
|
+
- `BannerAd.Load(AdSize)` and `BannerAd.Load(AdSize, Preference)` are replaced by parameterless
|
|
79
|
+
`Load()` and `Load(Preference)` — the ad size is now fixed for the lifetime of the `BannerAd`.
|
|
80
|
+
- **Breaking** — `Preference` class renamed to `RequestOptions` and made **immutable**.
|
|
81
|
+
- Mutable `Set*` builder methods are replaced by a single optional-named-args constructor:
|
|
82
|
+
`new RequestOptions(age: 25, gender: Gender.Male, location: ..., consentFlag: 1,
|
|
83
|
+
language: "en", keyword: "...", contentUrl: "...")`.
|
|
84
|
+
- A single `RequestOptions` instance is safe to reuse across multiple `Load(...)` calls.
|
|
85
|
+
- **Breaking** — `Location` made immutable:
|
|
86
|
+
- Constructor now `new Location(double latitude, double longitude, string provider = NONE_PROVIDER)`
|
|
87
|
+
instead of `new Location(provider)` + mutable `Latitude` / `Longitude` setters.
|
|
88
|
+
- `getProvider()` method replaced by a `Provider` get-only property.
|
|
76
89
|
|
|
77
90
|
### Removed
|
|
78
91
|
|
|
79
|
-
- **Breaking** — `Settings` parameter removed from `BlueStackAds.Initialize`.
|
|
92
|
+
- **Breaking** — `Settings` parameter removed from `BlueStackAds.Initialize`. Use `BlueStackAds.SetDebugMode(bool)` instead of
|
|
93
|
+
`new Settings(isDebugModeEnabled: ...)`.
|
|
94
|
+
- **Breaking** — `Preference.Destroy()` removed — the new immutable `RequestOptions` holds no
|
|
95
|
+
native resources on the Unity side; the native intermediate is constructed and released inside
|
|
96
|
+
each `Load(...)` call.
|
|
80
97
|
|
|
81
98
|
## [3.4.1] - 2026-02-27
|
|
82
99
|
|
|
@@ -48,12 +48,15 @@ namespace Azerion.BlueStack.Editor.Android
|
|
|
48
48
|
{
|
|
49
49
|
var aliasAttribute = androidPackageNode.Attributes?["alias"];
|
|
50
50
|
var specAttribute = androidPackageNode.Attributes?["spec"];
|
|
51
|
-
var versionAttribute = androidPackageNode.Attributes?["version"];
|
|
52
51
|
var alias = aliasAttribute != null ? aliasAttribute.Value : specAttribute?.Value;
|
|
53
52
|
var name = specAttribute?.Value;
|
|
54
|
-
var version = versionAttribute?.Value;
|
|
55
53
|
if (name == null)
|
|
56
54
|
continue;
|
|
55
|
+
// Extract "version" from the spec "group:artifact:version"
|
|
56
|
+
var lastColon = name.LastIndexOf(':');
|
|
57
|
+
var version = lastColon >= 0 && lastColon < name.Length - 1
|
|
58
|
+
? name.Substring(lastColon + 1)
|
|
59
|
+
: null;
|
|
57
60
|
bool active = activeNames != null && activeNames.Contains(name);
|
|
58
61
|
dependencies.Add(
|
|
59
62
|
new BlueStackDependency(alias, name, version, androidPackageNode, active)
|
|
@@ -7,8 +7,11 @@ namespace Azerion.BlueStack.Editor
|
|
|
7
7
|
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets,
|
|
8
8
|
string[] movedFromAssetPaths, bool didDomainReload)
|
|
9
9
|
{
|
|
10
|
-
//
|
|
11
|
-
//
|
|
10
|
+
// Required when updating the SDK: sync dependencies when the project loads in the Unity Editor.
|
|
11
|
+
// Only run on a domain reload (project load / script recompile / SDK update).
|
|
12
|
+
if (!didDomainReload)
|
|
13
|
+
return;
|
|
14
|
+
|
|
12
15
|
BlueStackSettingsEditor.Initialize();
|
|
13
16
|
}
|
|
14
17
|
}
|
|
@@ -8,6 +8,14 @@ namespace Azerion.BlueStack.Editor
|
|
|
8
8
|
private static BlueStackSettings instance;
|
|
9
9
|
private const string BlueStackSettingsFile = "BlueStackSettings";
|
|
10
10
|
|
|
11
|
+
[SerializeField]
|
|
12
|
+
private string version;
|
|
13
|
+
public string Version
|
|
14
|
+
{
|
|
15
|
+
get => Instance.version;
|
|
16
|
+
set => Instance.version = value;
|
|
17
|
+
}
|
|
18
|
+
|
|
11
19
|
[SerializeField]
|
|
12
20
|
private string admobAppIdAndroid;
|
|
13
21
|
public string AdmobAppIdAndroid
|
|
@@ -53,8 +53,6 @@ namespace Azerion.BlueStack.Editor
|
|
|
53
53
|
BlueStackSettingsFileExtension
|
|
54
54
|
);
|
|
55
55
|
AssetDatabase.CreateAsset(BlueStackSettings.Instance, assetPathWithExtension);
|
|
56
|
-
AssetDatabase.SaveAssets();
|
|
57
|
-
|
|
58
56
|
return true;
|
|
59
57
|
}
|
|
60
58
|
catch (Exception e)
|
|
@@ -72,35 +70,88 @@ namespace Azerion.BlueStack.Editor
|
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
// This is Required when updating the SDK.
|
|
76
|
-
// Initialize and Sync dependencies when project loaded in Unity Editor.
|
|
77
|
-
// This logic is now moved to OnPostprocessAllAssets of BlueStackAssetPostProcessor
|
|
78
|
-
// [InitializeOnLoadMethod]
|
|
79
|
-
// static void OnProjectLoadedInEditor()
|
|
80
|
-
// {
|
|
81
|
-
// Initialize();
|
|
82
|
-
// }
|
|
83
|
-
|
|
84
73
|
void OnEnable()
|
|
85
74
|
{
|
|
86
|
-
|
|
75
|
+
// Only refresh the in-memory lists for display.
|
|
76
|
+
// PackageNode is a live XmlNode and BlueStackDependency uses auto-properties, so Unity
|
|
77
|
+
// serializes none of this into the asset, the lists must be rebuilt from XML each load.
|
|
78
|
+
|
|
79
|
+
LoadDependenciesIntoMemory();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private static void LoadDependenciesIntoMemory()
|
|
83
|
+
{
|
|
84
|
+
if (!DoesBlueStackSettingsExist())
|
|
85
|
+
return;
|
|
86
|
+
|
|
87
|
+
BlueStackSettings.Instance.AndroidDependencies =
|
|
88
|
+
DependencyProvider.GetBlueStackDependencies(new AndroidDependencyParser());
|
|
89
|
+
BlueStackSettings.Instance.IOSDependencies =
|
|
90
|
+
DependencyProvider.GetBlueStackDependencies(new IOSDependencyParser());
|
|
87
91
|
}
|
|
88
92
|
|
|
93
|
+
private static bool _isInitializing;
|
|
94
|
+
|
|
95
|
+
// The XML sync + persist happens once on domain reload from BlueStackAssetPostProcessor.
|
|
89
96
|
public static void Initialize()
|
|
90
97
|
{
|
|
98
|
+
// re-entrancy guard
|
|
99
|
+
if (_isInitializing)
|
|
100
|
+
return;
|
|
101
|
+
|
|
91
102
|
if (!DoesBlueStackSettingsExist())
|
|
92
103
|
return;
|
|
93
104
|
|
|
94
|
-
|
|
95
|
-
|
|
105
|
+
_isInitializing = true;
|
|
106
|
+
try
|
|
107
|
+
{
|
|
108
|
+
DependencyProvider.SyncDependenciesXMLs();
|
|
109
|
+
|
|
110
|
+
var androidDependencies = DependencyProvider.GetBlueStackDependencies(new AndroidDependencyParser());
|
|
111
|
+
var iOSDependencies = DependencyProvider.GetBlueStackDependencies(new IOSDependencyParser());
|
|
112
|
+
|
|
113
|
+
var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssetPath(
|
|
114
|
+
"Packages/com.azerion.bluestack");
|
|
115
|
+
var version = packageInfo != null ? packageInfo.version : BlueStackSettings.Instance.Version;
|
|
96
116
|
|
|
97
|
-
|
|
117
|
+
// Only persist when something actually changed. Re-saving an unchanged asset
|
|
118
|
+
// re-triggers OnPostprocessAllAssets and causes an infinite import loop.
|
|
119
|
+
bool changed =
|
|
120
|
+
BlueStackSettings.Instance.Version != version
|
|
121
|
+
|| !DependenciesEqual(BlueStackSettings.Instance.AndroidDependencies, androidDependencies)
|
|
122
|
+
|| !DependenciesEqual(BlueStackSettings.Instance.IOSDependencies, iOSDependencies);
|
|
98
123
|
|
|
99
|
-
|
|
100
|
-
|
|
124
|
+
BlueStackSettings.Instance.AndroidDependencies = androidDependencies;
|
|
125
|
+
BlueStackSettings.Instance.IOSDependencies = iOSDependencies;
|
|
126
|
+
BlueStackSettings.Instance.Version = version;
|
|
127
|
+
|
|
128
|
+
if (changed)
|
|
129
|
+
{
|
|
130
|
+
EditorUtility.SetDirty(BlueStackSettings.Instance);
|
|
131
|
+
AssetDatabase.SaveAssets();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
finally
|
|
135
|
+
{
|
|
136
|
+
_isInitializing = false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
101
139
|
|
|
102
|
-
|
|
103
|
-
|
|
140
|
+
// Compares dependency lists by the fields that get persisted in the asset.
|
|
141
|
+
private static bool DependenciesEqual(
|
|
142
|
+
List<BlueStackDependency> a,
|
|
143
|
+
List<BlueStackDependency> b)
|
|
144
|
+
{
|
|
145
|
+
if (a == null || b == null)
|
|
146
|
+
return ReferenceEquals(a, b);
|
|
147
|
+
if (a.Count != b.Count)
|
|
148
|
+
return false;
|
|
149
|
+
for (int i = 0; i < a.Count; i++)
|
|
150
|
+
{
|
|
151
|
+
if (a[i].Name != b[i].Name || a[i].Active != b[i].Active)
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
return true;
|
|
104
155
|
}
|
|
105
156
|
|
|
106
157
|
public override void OnInspectorGUI()
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.IO;
|
|
3
|
+
using System.Text.RegularExpressions;
|
|
4
|
+
using UnityEditor;
|
|
5
|
+
using UnityEditor.Build;
|
|
6
|
+
using UnityEditor.Build.Reporting;
|
|
7
|
+
using UnityEditor.PackageManager;
|
|
8
|
+
using UnityEngine;
|
|
9
|
+
using PackageInfo = UnityEditor.PackageManager.PackageInfo;
|
|
10
|
+
|
|
11
|
+
namespace Azerion.BlueStack.Editor
|
|
12
|
+
{
|
|
13
|
+
/// <summary>
|
|
14
|
+
/// Keeps the package version declared in <c>package.json</c> mirrored into,
|
|
15
|
+
/// • <c>Runtime/Common/BlueStackSdkInfo.cs</c>
|
|
16
|
+
/// • <c>BlueStackDependenciesSource.xml</c>
|
|
17
|
+
/// </summary>
|
|
18
|
+
[InitializeOnLoad]
|
|
19
|
+
public static class BlueStackVersionExporter
|
|
20
|
+
{
|
|
21
|
+
internal const string DependenciesVersionPattern = "(<dependencies\\b[^>]*?\\bversion=\")([^\"]*)(\")";
|
|
22
|
+
|
|
23
|
+
private static string _packageJsonPath;
|
|
24
|
+
private static DateTime _lastStamp;
|
|
25
|
+
|
|
26
|
+
static BlueStackVersionExporter()
|
|
27
|
+
{
|
|
28
|
+
Export();
|
|
29
|
+
EditorApplication.update += PollForPackageJsonChange;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Cheap mtime check; only does real work when package.json actually changes on disk.
|
|
33
|
+
private static void PollForPackageJsonChange()
|
|
34
|
+
{
|
|
35
|
+
if (string.IsNullOrEmpty(_packageJsonPath) || !File.Exists(_packageJsonPath))
|
|
36
|
+
{
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var stamp = File.GetLastWriteTimeUtc(_packageJsonPath);
|
|
41
|
+
if (stamp == _lastStamp)
|
|
42
|
+
{
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
_lastStamp = stamp;
|
|
47
|
+
Debug.Log("[BSU sync] package.json changed -> regenerating version files");
|
|
48
|
+
Export();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
private static void Export()
|
|
52
|
+
{
|
|
53
|
+
var packageInfo = PackageInfo.FindForAssembly(typeof(BlueStackVersionExporter).Assembly);
|
|
54
|
+
if (packageInfo == null)
|
|
55
|
+
{
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Never write into a read-only install (registry / git / embedded-in-cache).
|
|
60
|
+
if (packageInfo.source != PackageSource.Local && packageInfo.source != PackageSource.Embedded)
|
|
61
|
+
{
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
_packageJsonPath = Path.Combine(packageInfo.resolvedPath, "package.json");
|
|
66
|
+
|
|
67
|
+
// Read the version straight from disk — independent of when the Package Manager re-resolves.
|
|
68
|
+
var version = ReadPackageJsonVersion(_packageJsonPath);
|
|
69
|
+
if (string.IsNullOrEmpty(version))
|
|
70
|
+
{
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Remember the current mtime so the poller doesn't re-fire on the next domain reload.
|
|
75
|
+
_lastStamp = File.GetLastWriteTimeUtc(_packageJsonPath);
|
|
76
|
+
|
|
77
|
+
var changed = SyncDependenciesVersion(packageInfo.resolvedPath, version);
|
|
78
|
+
changed |= SyncSdkInfo(packageInfo.resolvedPath, version);
|
|
79
|
+
|
|
80
|
+
if (changed)
|
|
81
|
+
{
|
|
82
|
+
AssetDatabase.Refresh();
|
|
83
|
+
Debug.Log($"[BSU sync] version files updated to {version}");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
internal static string ReadPackageJsonVersion(string packageJsonPath)
|
|
88
|
+
{
|
|
89
|
+
if (!File.Exists(packageJsonPath))
|
|
90
|
+
{
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
try
|
|
95
|
+
{
|
|
96
|
+
var manifest = JsonUtility.FromJson<PackageManifest>(File.ReadAllText(packageJsonPath));
|
|
97
|
+
return manifest != null ? manifest.version : null;
|
|
98
|
+
}
|
|
99
|
+
catch (Exception e)
|
|
100
|
+
{
|
|
101
|
+
Debug.LogWarning($"[BSU sync] Could not parse {packageJsonPath}: {e.Message}");
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Returns true if the file was rewritten.
|
|
107
|
+
private static bool SyncSdkInfo(string resolvedPath, string version)
|
|
108
|
+
{
|
|
109
|
+
var outputFile = Path.Combine(resolvedPath, "Runtime", "Common", "BlueStackSdkInfo.cs");
|
|
110
|
+
var content = BuildSdkInfoContent(version);
|
|
111
|
+
|
|
112
|
+
if (File.Exists(outputFile) && File.ReadAllText(outputFile) == content)
|
|
113
|
+
{
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
File.WriteAllText(outputFile, content);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Returns true if the file was rewritten. Touches ONLY the root <dependencies version="…">.
|
|
122
|
+
internal static bool SyncDependenciesVersion(string resolvedPath, string version)
|
|
123
|
+
{
|
|
124
|
+
var xmlFile = Path.Combine(resolvedPath, "Editor", "BlueStackDependenciesSource.xml");
|
|
125
|
+
if (!File.Exists(xmlFile))
|
|
126
|
+
{
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
var xml = File.ReadAllText(xmlFile);
|
|
131
|
+
var match = Regex.Match(xml, DependenciesVersionPattern);
|
|
132
|
+
if (!match.Success)
|
|
133
|
+
{
|
|
134
|
+
Debug.LogWarning(
|
|
135
|
+
$"[BSU sync] No <dependencies version=\"...\"> attribute found in {xmlFile}; skipping version sync.");
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (match.Groups[2].Value == version)
|
|
140
|
+
{
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
var updated = Regex.Replace(xml, DependenciesVersionPattern, "${1}" + version + "${3}");
|
|
145
|
+
File.WriteAllText(xmlFile, updated);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Explicit "\n" keeps output byte-identical across platforms so the write-if-changed check holds.
|
|
150
|
+
private static string BuildSdkInfoContent(string version)
|
|
151
|
+
{
|
|
152
|
+
return
|
|
153
|
+
"// <auto-generated>\n" +
|
|
154
|
+
"// Generated by BlueStackVersionExporter from package.json. Do not edit by hand.\n" +
|
|
155
|
+
"// </auto-generated>\n" +
|
|
156
|
+
"namespace Azerion.BlueStack.Common\n" +
|
|
157
|
+
"{\n" +
|
|
158
|
+
" public static class BlueStackSdkInfo\n" +
|
|
159
|
+
" {\n" +
|
|
160
|
+
" public const string Version = \"" + version + "\";\n" +
|
|
161
|
+
" }\n" +
|
|
162
|
+
"}\n";
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
[Serializable]
|
|
166
|
+
private class PackageManifest
|
|
167
|
+
{
|
|
168
|
+
public string version;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/// <summary>
|
|
173
|
+
/// Build time validation, check that the version number in <c>BlueStackSdkInfo</c> and
|
|
174
|
+
/// <c>BlueStackDependenciesSource.xml</c> matches <c>package.json</c>
|
|
175
|
+
/// </summary>
|
|
176
|
+
public class BlueStackVersionBuildGate : IPreprocessBuildWithReport
|
|
177
|
+
{
|
|
178
|
+
public int callbackOrder => 0;
|
|
179
|
+
|
|
180
|
+
public void OnPreprocessBuild(BuildReport report)
|
|
181
|
+
{
|
|
182
|
+
var packageInfo = PackageInfo.FindForAssembly(typeof(BlueStackVersionBuildGate).Assembly);
|
|
183
|
+
if (packageInfo == null)
|
|
184
|
+
{
|
|
185
|
+
throw new BuildFailedException("[BlueStack] PackageInfo not found in package.json");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
var version = BlueStackVersionExporter.ReadPackageJsonVersion(
|
|
189
|
+
Path.Combine(packageInfo.resolvedPath, "package.json"));
|
|
190
|
+
if (string.IsNullOrEmpty(version))
|
|
191
|
+
{
|
|
192
|
+
throw new BuildFailedException("[BlueStack] Unable to retrieve the version number from package.json");
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// The XML is consumed at build/resolve time and isn't compiled — safe to rewrite in a mutable install.
|
|
196
|
+
if (packageInfo.source == PackageSource.Local || packageInfo.source == PackageSource.Embedded)
|
|
197
|
+
{
|
|
198
|
+
BlueStackVersionExporter.SyncDependenciesVersion(packageInfo.resolvedPath, version);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
var sdkInfoPath = Path.Combine(packageInfo.resolvedPath, "Runtime", "Common", "BlueStackSdkInfo.cs");
|
|
202
|
+
var committed = File.Exists(sdkInfoPath)
|
|
203
|
+
? Regex.Match(File.ReadAllText(sdkInfoPath), "Version\\s*=\\s*\"([^\"]+)\"").Groups[1].Value
|
|
204
|
+
: null;
|
|
205
|
+
|
|
206
|
+
if (committed != version)
|
|
207
|
+
{
|
|
208
|
+
throw new BuildFailedException(
|
|
209
|
+
$"[BlueStack] BlueStackSdkInfo.Version ('{committed}') is out of sync with package.json ('{version}'). " +
|
|
210
|
+
"Open the project in the Unity Editor so the version is regenerated, then rebuild.");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
@@ -31,12 +31,12 @@ RectTransform:
|
|
|
31
31
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
32
32
|
m_ConstrainProportionsScale: 0
|
|
33
33
|
m_Children: []
|
|
34
|
-
m_Father: {fileID:
|
|
34
|
+
m_Father: {fileID: 9100000000000002}
|
|
35
35
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
36
|
-
m_AnchorMin: {x: 0
|
|
37
|
-
m_AnchorMax: {x:
|
|
38
|
-
m_AnchoredPosition: {x: 0, y:
|
|
39
|
-
m_SizeDelta: {x:
|
|
36
|
+
m_AnchorMin: {x: 0, y: 0}
|
|
37
|
+
m_AnchorMax: {x: 1, y: 1}
|
|
38
|
+
m_AnchoredPosition: {x: 0, y: 0}
|
|
39
|
+
m_SizeDelta: {x: 0, y: 0}
|
|
40
40
|
m_Pivot: {x: 0.5, y: 0.5}
|
|
41
41
|
--- !u!222 &222746751799034550
|
|
42
42
|
CanvasRenderer:
|
|
@@ -56,8 +56,8 @@ MonoBehaviour:
|
|
|
56
56
|
m_Enabled: 1
|
|
57
57
|
m_EditorHideFlags: 0
|
|
58
58
|
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
|
59
|
-
m_Name:
|
|
60
|
-
m_EditorClassIdentifier:
|
|
59
|
+
m_Name:
|
|
60
|
+
m_EditorClassIdentifier:
|
|
61
61
|
m_Material: {fileID: 0}
|
|
62
62
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
|
63
63
|
m_RaycastTarget: 1
|
|
@@ -86,8 +86,8 @@ MonoBehaviour:
|
|
|
86
86
|
m_Enabled: 1
|
|
87
87
|
m_EditorHideFlags: 0
|
|
88
88
|
m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3}
|
|
89
|
-
m_Name:
|
|
90
|
-
m_EditorClassIdentifier:
|
|
89
|
+
m_Name:
|
|
90
|
+
m_EditorClassIdentifier:
|
|
91
91
|
m_Navigation:
|
|
92
92
|
m_Mode: 3
|
|
93
93
|
m_WrapAround: 0
|
|
@@ -148,17 +148,17 @@ RectTransform:
|
|
|
148
148
|
m_GameObject: {fileID: 1922916089534430}
|
|
149
149
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
150
150
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
|
151
|
-
m_LocalScale: {x:
|
|
151
|
+
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
152
152
|
m_ConstrainProportionsScale: 0
|
|
153
153
|
m_Children:
|
|
154
|
-
- {fileID:
|
|
154
|
+
- {fileID: 9100000000000002}
|
|
155
155
|
m_Father: {fileID: 0}
|
|
156
156
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
157
157
|
m_AnchorMin: {x: 0, y: 0}
|
|
158
|
-
m_AnchorMax: {x:
|
|
158
|
+
m_AnchorMax: {x: 1, y: 1}
|
|
159
159
|
m_AnchoredPosition: {x: 0, y: 0}
|
|
160
160
|
m_SizeDelta: {x: 0, y: 0}
|
|
161
|
-
m_Pivot: {x: 0, y: 0}
|
|
161
|
+
m_Pivot: {x: 0.5, y: 0.5}
|
|
162
162
|
--- !u!223 &223151453590684250
|
|
163
163
|
Canvas:
|
|
164
164
|
m_ObjectHideFlags: 0
|
|
@@ -192,8 +192,8 @@ MonoBehaviour:
|
|
|
192
192
|
m_Enabled: 1
|
|
193
193
|
m_EditorHideFlags: 0
|
|
194
194
|
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
|
|
195
|
-
m_Name:
|
|
196
|
-
m_EditorClassIdentifier:
|
|
195
|
+
m_Name:
|
|
196
|
+
m_EditorClassIdentifier:
|
|
197
197
|
m_IgnoreReversedGraphics: 1
|
|
198
198
|
m_BlockingObjects: 0
|
|
199
199
|
m_BlockingMask:
|
|
@@ -209,8 +209,8 @@ MonoBehaviour:
|
|
|
209
209
|
m_Enabled: 1
|
|
210
210
|
m_EditorHideFlags: 0
|
|
211
211
|
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
|
|
212
|
-
m_Name:
|
|
213
|
-
m_EditorClassIdentifier:
|
|
212
|
+
m_Name:
|
|
213
|
+
m_EditorClassIdentifier:
|
|
214
214
|
m_UiScaleMode: 1
|
|
215
215
|
m_ReferencePixelsPerUnit: 100
|
|
216
216
|
m_ScaleFactor: 1
|
|
@@ -222,3 +222,39 @@ MonoBehaviour:
|
|
|
222
222
|
m_DefaultSpriteDPI: 96
|
|
223
223
|
m_DynamicPixelsPerUnit: 1
|
|
224
224
|
m_PresetInfoIsWorld: 0
|
|
225
|
+
--- !u!1 &9100000000000001
|
|
226
|
+
GameObject:
|
|
227
|
+
m_ObjectHideFlags: 0
|
|
228
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
229
|
+
m_PrefabInstance: {fileID: 0}
|
|
230
|
+
m_PrefabAsset: {fileID: 0}
|
|
231
|
+
serializedVersion: 6
|
|
232
|
+
m_Component:
|
|
233
|
+
- component: {fileID: 9100000000000002}
|
|
234
|
+
m_Layer: 5
|
|
235
|
+
m_Name: BannerContainer
|
|
236
|
+
m_TagString: Untagged
|
|
237
|
+
m_Icon: {fileID: 0}
|
|
238
|
+
m_NavMeshLayer: 0
|
|
239
|
+
m_StaticEditorFlags: 0
|
|
240
|
+
m_IsActive: 1
|
|
241
|
+
--- !u!224 &9100000000000002
|
|
242
|
+
RectTransform:
|
|
243
|
+
m_ObjectHideFlags: 0
|
|
244
|
+
m_CorrespondingSourceObject: {fileID: 0}
|
|
245
|
+
m_PrefabInstance: {fileID: 0}
|
|
246
|
+
m_PrefabAsset: {fileID: 0}
|
|
247
|
+
m_GameObject: {fileID: 9100000000000001}
|
|
248
|
+
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
249
|
+
m_LocalPosition: {x: 0, y: 0, z: 0}
|
|
250
|
+
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
251
|
+
m_ConstrainProportionsScale: 0
|
|
252
|
+
m_Children:
|
|
253
|
+
- {fileID: 224102598220924924}
|
|
254
|
+
m_Father: {fileID: 224975965904302652}
|
|
255
|
+
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
256
|
+
m_AnchorMin: {x: 0.5, y: 0}
|
|
257
|
+
m_AnchorMax: {x: 0.5, y: 0}
|
|
258
|
+
m_AnchoredPosition: {x: 0, y: 75}
|
|
259
|
+
m_SizeDelta: {x: 960, y: 150}
|
|
260
|
+
m_Pivot: {x: 0.5, y: 0.5}
|