gg.easy.airship 0.1.2106 → 0.1.2107
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/AuthenticationForUnity/Runtime/Browser/AndroidBrowser.cs +85 -0
- package/AuthenticationForUnity/Runtime/Browser/AndroidBrowser.cs.meta +3 -0
- package/Editor/Accessories/Clothing/PlatformGearBundleManifestEditor.cs +11 -12
- package/Editor/BuildMenu.cs +42 -0
- package/Editor/GameConfig/GameConfigEditor.cs +12 -0
- package/Editor/Packages/AirshipPackagesWindow.cs +36 -18
- package/Editor/Publish/API/DeploymentDto.cs +3 -0
- package/Editor/Publish/Deploy.cs +43 -40
- package/Runtime/Code/Auth/AuthManager.cs +2 -0
- package/Runtime/Code/Bootstrap/BundleDownloader.cs +8 -2
- package/Runtime/Code/Bootstrap/SignalHandler.cs +2 -0
- package/Runtime/Code/Bundles/AirshipPlatform.cs +1 -12
- package/Runtime/Code/Bundles/SystemRoot.cs +45 -5
- package/Runtime/Code/CoreUI/Loading/LoadingQuitButton.cs +7 -0
- package/Runtime/Code/GameConfig/GameConfig.cs +2 -0
- package/Runtime/Code/Luau/AirshipComponent.cs +16 -3
- package/Runtime/Code/Luau/ReflectionList.cs +1 -1
- package/Runtime/Code/Misc/CanvasDistanceCondition.cs +2 -0
- package/Runtime/Code/Platform/Shared/AirshipInventoryServiceDto.cs +0 -2
- package/Runtime/Code/Player/Character/Animation/CharacterAnimationHelper.cs +8 -8
- package/Runtime/Code/Player/OcclusionCam.cs +7 -5
- package/Runtime/Code/TSCodeGen/TypeGenerator.cs +1 -0
- package/Runtime/Plugins/Android/libLuauPlugin.so +0 -0
- package/Runtime/Plugins/Android/libLuauPlugin.so.meta +61 -0
- package/Runtime/Plugins/Android.meta +8 -0
- package/Runtime/Plugins/Linux/libLuauPlugin.so +0 -0
- package/Runtime/Plugins/Linux/libLuauPlugin.so.meta +21 -40
- package/Runtime/Plugins/Mac/LuauPlugin.bundle/Contents/MacOS/LuauPlugin +0 -0
- package/Runtime/Plugins/Windows/x64/LuauPlugin.dll +0 -0
- package/Runtime/Plugins/Windows/x64/LuauPlugin.dll.meta +64 -1
- package/Runtime/Plugins/Windows/x64/LuauPlugin.pdb +0 -0
- package/Runtime/Plugins/iOS/LuauPluginIos.a +0 -0
- package/Runtime/Plugins/iOS/LuauPluginIos.a.meta +27 -39
- package/Runtime/Scenes/Login.unity +371 -315
- package/ThirdParty/AppleAuth/Editor/ProjectCapabilityManagerExtension.cs +58 -46
- package/ThirdParty/NativeGallery/Editor/NGPostProcessBuild.cs +7 -1
- package/URP/AirshipURPAssetBaked.asset +2 -2
- package/URP/Shaders/AirshipCharacterAlpha.shader +2 -3
- package/package.json +1 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
using System;
|
|
2
|
+
using System.Net;
|
|
3
|
+
using System.Threading;
|
|
4
|
+
using System.Threading.Tasks;
|
|
5
|
+
using UnityEngine;
|
|
6
|
+
|
|
7
|
+
namespace Cdm.Authentication.Browser {
|
|
8
|
+
/// <summary>
|
|
9
|
+
/// OAuth 2.0 verification browser that runs a local server and waits for a call with
|
|
10
|
+
/// the authorization verification code.
|
|
11
|
+
/// </summary>
|
|
12
|
+
public class AndroidBrowser : IBrowser {
|
|
13
|
+
private string _prefix;
|
|
14
|
+
|
|
15
|
+
public AndroidBrowser(string prefix) {
|
|
16
|
+
_prefix = prefix;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private TaskCompletionSource<BrowserResult> _taskCompletionSource;
|
|
20
|
+
|
|
21
|
+
/// <summary>
|
|
22
|
+
/// Gets or sets the close page response. This HTML response is shown to the user after redirection is done.
|
|
23
|
+
/// </summary>
|
|
24
|
+
public string closePageResponse { get; set; } =
|
|
25
|
+
"<html><body><b>DONE!</b><br>(You can close this tab/window now)</body></html>";
|
|
26
|
+
|
|
27
|
+
public async Task<BrowserResult> StartAsync(string loginUrl, string redirectUrl, CancellationToken cancellationToken = default) {
|
|
28
|
+
_taskCompletionSource = new TaskCompletionSource<BrowserResult>();
|
|
29
|
+
|
|
30
|
+
cancellationToken.Register(() => {
|
|
31
|
+
_taskCompletionSource?.TrySetCanceled();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
using var httpListener = new HttpListener();
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
var prefix = _prefix;
|
|
38
|
+
prefix = AddForwardSlashIfNecessary(prefix);
|
|
39
|
+
httpListener.Prefixes.Add(prefix);
|
|
40
|
+
if (httpListener.IsListening) {
|
|
41
|
+
httpListener.Stop();
|
|
42
|
+
}
|
|
43
|
+
httpListener.Start();
|
|
44
|
+
httpListener.BeginGetContext(IncomingHttpRequest, httpListener);
|
|
45
|
+
|
|
46
|
+
Application.OpenURL(loginUrl);
|
|
47
|
+
|
|
48
|
+
return await _taskCompletionSource.Task;
|
|
49
|
+
} finally {
|
|
50
|
+
httpListener.Stop();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private void IncomingHttpRequest(IAsyncResult result) {
|
|
55
|
+
var httpListener = (HttpListener)result.AsyncState;
|
|
56
|
+
var httpContext = httpListener.EndGetContext(result);
|
|
57
|
+
var httpRequest = httpContext.Request;
|
|
58
|
+
|
|
59
|
+
// Build a response to send an "ok" back to the browser for the user to see.
|
|
60
|
+
var httpResponse = httpContext.Response;
|
|
61
|
+
var buffer = System.Text.Encoding.UTF8.GetBytes(closePageResponse);
|
|
62
|
+
|
|
63
|
+
// Send the output to the client browser.
|
|
64
|
+
httpResponse.ContentLength64 = buffer.Length;
|
|
65
|
+
var output = httpResponse.OutputStream;
|
|
66
|
+
output.Write(buffer, 0, buffer.Length);
|
|
67
|
+
output.Close();
|
|
68
|
+
|
|
69
|
+
_taskCompletionSource.SetResult(new BrowserResult(BrowserStatus.Success, httpRequest.Url.ToString()));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/// <summary>
|
|
73
|
+
/// Prefixes must end in a forward slash ("/")
|
|
74
|
+
/// </summary>
|
|
75
|
+
/// <see href="https://learn.microsoft.com/en-us/dotnet/api/system.net.httplistener?view=net-7.0#remarks" />
|
|
76
|
+
private string AddForwardSlashIfNecessary(string url) {
|
|
77
|
+
string forwardSlash = "/";
|
|
78
|
+
if (!url.EndsWith(forwardSlash)) {
|
|
79
|
+
url += forwardSlash;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return url;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -109,22 +109,21 @@ namespace Editor.Accessories.Clothing {
|
|
|
109
109
|
(string category, string subcategory) = GetGearCategory(gear);
|
|
110
110
|
|
|
111
111
|
// Create a new class id
|
|
112
|
-
var
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
}));
|
|
112
|
+
var data = JsonUtility.ToJson(new GearCreateRequest() {
|
|
113
|
+
name = gear.name,
|
|
114
|
+
imageId = "64351892-40d4-409b-ab3a-501818213b50",
|
|
115
|
+
description = "Clothing",
|
|
116
|
+
airAssets = new string[] { },
|
|
117
|
+
category = category,
|
|
118
|
+
subcategory = subcategory,
|
|
119
|
+
});
|
|
120
|
+
var req = UnityWebRequest.Post($"{AirshipPlatformUrl.contentService}/gear/resource-id/{easyOrgId}", data, "application/json");
|
|
123
121
|
req.SetRequestHeader("Authorization", "Bearer " + InternalHttpManager.editorAuthToken);
|
|
124
122
|
req.SetRequestHeader("x-airship-ignore-rate-limit", "true");
|
|
125
123
|
await req.SendWebRequest();
|
|
126
124
|
if (req.result != UnityWebRequest.Result.Success) {
|
|
127
|
-
Debug.
|
|
125
|
+
Debug.Log("Post request: " + data);
|
|
126
|
+
Debug.LogError("Failed to create gear class: " + req.downloadHandler.text);
|
|
128
127
|
return;
|
|
129
128
|
}
|
|
130
129
|
Debug.Log("Create classId response: " + req.downloadHandler.text);
|
package/Editor/BuildMenu.cs
CHANGED
|
@@ -218,6 +218,38 @@ namespace Editor {
|
|
|
218
218
|
#endif
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
public static void BuildAndroidClient(bool development) {
|
|
222
|
+
OnBuild();
|
|
223
|
+
CreateAssetBundles.ResetScenes();
|
|
224
|
+
|
|
225
|
+
PlayerSettings.SplashScreen.show = false;
|
|
226
|
+
PlayerSettings.SetScriptingBackend(NamedBuildTarget.Android, ScriptingImplementation.IL2CPP);
|
|
227
|
+
var options = new BuildPlayerOptions();
|
|
228
|
+
options.scenes = scenes;
|
|
229
|
+
options.locationPathName = $"build/client_android/{ClientExecutableName}.apk";
|
|
230
|
+
options.target = BuildTarget.Android;
|
|
231
|
+
if (development == true) {
|
|
232
|
+
options.options = BuildOptions.Development;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
var report = BuildPipeline.BuildPlayer(options);
|
|
236
|
+
var summary = report.summary;
|
|
237
|
+
switch (summary.result) {
|
|
238
|
+
case BuildResult.Succeeded:
|
|
239
|
+
Debug.Log($"Build Android succeeded with size: {FormatBytes(summary)}");
|
|
240
|
+
EditorUtility.RevealInFinder(report.summary.outputPath);
|
|
241
|
+
break;
|
|
242
|
+
case BuildResult.Failed:
|
|
243
|
+
Debug.LogError("Build Android failed");
|
|
244
|
+
break;
|
|
245
|
+
default:
|
|
246
|
+
Debug.LogError("Build Android unexpected result:" + summary.result);
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
CreateAssetBundles.AddAllGameBundleScenes();
|
|
251
|
+
}
|
|
252
|
+
|
|
221
253
|
#if AIRSHIP_PLAYER
|
|
222
254
|
[MenuItem("Airship/Create Binary/Client/iOS", priority = 80)]
|
|
223
255
|
public static void BuildIOSClientMenuItem() {
|
|
@@ -228,6 +260,16 @@ namespace Editor {
|
|
|
228
260
|
public static void BuildIOSDevelopmentClientMenuItem() {
|
|
229
261
|
BuildIOSClient(true);
|
|
230
262
|
}
|
|
263
|
+
|
|
264
|
+
[MenuItem("Airship/Create Binary/Client/Android", priority = 80)]
|
|
265
|
+
public static void BuildAndroidClientMenuItem() {
|
|
266
|
+
BuildAndroidClient(false);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
[MenuItem("Airship/Create Binary/Client/Android (Development)", priority = 80)]
|
|
270
|
+
public static void BuildAndroidDevelopmentClientMenuItem() {
|
|
271
|
+
BuildAndroidClient(true);
|
|
272
|
+
}
|
|
231
273
|
#endif
|
|
232
274
|
|
|
233
275
|
public static void BuildWindowsClientStaging() {
|
|
@@ -17,6 +17,8 @@ public class GameConfigEditor : UnityEditor.Editor {
|
|
|
17
17
|
private Action<UpdateSelectedGame> updateSelectedGame;
|
|
18
18
|
private Action requestRefresh;
|
|
19
19
|
|
|
20
|
+
private SerializedProperty supportsMobile;
|
|
21
|
+
|
|
20
22
|
Rect buttonRect;
|
|
21
23
|
public override void OnInspectorGUI() {
|
|
22
24
|
serializedObject.Update();
|
|
@@ -41,6 +43,14 @@ public class GameConfigEditor : UnityEditor.Editor {
|
|
|
41
43
|
}
|
|
42
44
|
GUILayout.EndHorizontal();
|
|
43
45
|
|
|
46
|
+
GUILayout.Space(20);
|
|
47
|
+
EditorGUILayout.LabelField("Platforms", EditorStyles.boldLabel);
|
|
48
|
+
EditorGUI.BeginDisabledGroup(true);
|
|
49
|
+
EditorGUILayout.Toggle(new GUIContent("Desktop"), true);
|
|
50
|
+
EditorGUI.EndDisabledGroup();
|
|
51
|
+
EditorGUILayout.PropertyField(this.supportsMobile, new GUIContent("Mobile"));
|
|
52
|
+
GUILayout.Space(20);
|
|
53
|
+
|
|
44
54
|
foreach (var field in typeof(GameConfig).GetFields()) {
|
|
45
55
|
if (field.Name is "gameId" or "gameLayers" || Attribute.IsDefined(field, typeof(HideInInspector))) continue; // Rendered above
|
|
46
56
|
|
|
@@ -95,6 +105,8 @@ public class GameConfigEditor : UnityEditor.Editor {
|
|
|
95
105
|
markPublishTargetPinged = false;
|
|
96
106
|
publishTargetPinged = true;
|
|
97
107
|
}
|
|
108
|
+
|
|
109
|
+
this.supportsMobile = serializedObject.FindProperty("supportsMobile");
|
|
98
110
|
|
|
99
111
|
updateSelectedGame += (update) => {
|
|
100
112
|
var gameId = update.gameId;
|
|
@@ -373,27 +373,24 @@ namespace Editor.Packages {
|
|
|
373
373
|
break;
|
|
374
374
|
}
|
|
375
375
|
|
|
376
|
-
var didVerify = AirshipPackagesWindow.VerifyBuildModules();
|
|
376
|
+
var didVerify = AirshipPackagesWindow.VerifyBuildModules(true);
|
|
377
377
|
if (!didVerify) {
|
|
378
378
|
Debug.LogErrorFormat("Missing build modules. Install missing modules in Unity Hub and restart Unity to publish package ({0}).", packageDoc.id);
|
|
379
379
|
yield break;
|
|
380
380
|
}
|
|
381
381
|
|
|
382
|
-
// Sort the current platform first to speed up build time
|
|
383
382
|
List<AirshipPlatform> platforms = new() {
|
|
384
|
-
|
|
383
|
+
AirshipPlatform.iOS,
|
|
385
384
|
AirshipPlatform.Mac,
|
|
386
385
|
AirshipPlatform.Windows,
|
|
386
|
+
AirshipPlatform.Android,
|
|
387
387
|
};
|
|
388
|
-
//
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
// platforms.Add(platform);
|
|
395
|
-
// }
|
|
396
|
-
// platforms.Remove(AirshipPlatform.Linux);
|
|
388
|
+
// Uncomment to just build iOS
|
|
389
|
+
if (isCoreMaterials) {
|
|
390
|
+
platforms.Clear();
|
|
391
|
+
// platforms.Add(AirshipPlatform.iOS);
|
|
392
|
+
platforms.Add(AirshipPlatform.Android);
|
|
393
|
+
}
|
|
397
394
|
|
|
398
395
|
if (!CreateAssetBundles.PrePublishChecks()) {
|
|
399
396
|
yield break;
|
|
@@ -435,7 +432,11 @@ namespace Editor.Packages {
|
|
|
435
432
|
buildParams.UseCache = this.publishOptionUseCache;
|
|
436
433
|
Debug.Log("Building package " + packageDoc.id + " with cache: " + this.publishOptionUseCache);
|
|
437
434
|
if (isCoreMaterials) {
|
|
438
|
-
|
|
435
|
+
if (platform is AirshipPlatform.iOS or AirshipPlatform.Android) {
|
|
436
|
+
buildParams.BundleCompression = BuildCompression.LZ4;
|
|
437
|
+
} else {
|
|
438
|
+
buildParams.BundleCompression = BuildCompression.Uncompressed;
|
|
439
|
+
}
|
|
439
440
|
} else {
|
|
440
441
|
buildParams.BundleCompression = BuildCompression.LZ4;
|
|
441
442
|
}
|
|
@@ -466,6 +467,10 @@ namespace Editor.Packages {
|
|
|
466
467
|
}
|
|
467
468
|
}
|
|
468
469
|
|
|
470
|
+
if (isCoreMaterials) {
|
|
471
|
+
yield break;
|
|
472
|
+
}
|
|
473
|
+
|
|
469
474
|
var importsFolder = Path.Join("Assets", "AirshipPackages");
|
|
470
475
|
var sourceAssetsFolder = Path.Join(importsFolder, packageDoc.id);
|
|
471
476
|
var typesFolder = Path.Join(Path.Join("Assets", "AirshipPackages", "Types~"), packageDoc.id);
|
|
@@ -590,8 +595,11 @@ namespace Editor.Packages {
|
|
|
590
595
|
|
|
591
596
|
// UploadSingleGameFile(urls.iOS_client_resources, $"{AirshipPlatform.iOS}/{orgScope}/{packageIdOnly}_client/resources", packageDoc),
|
|
592
597
|
// UploadSingleGameFile(urls.iOS_client_scenes, $"{AirshipPlatform.iOS}/{orgScope}/{packageIdOnly}_client/scenes", packageDoc),
|
|
593
|
-
|
|
594
|
-
|
|
598
|
+
UploadSingleGameFile(urls.iOS_shared_resources, $"{AirshipPlatform.iOS}/{orgScope}/{packageIdOnly}_shared/resources", packageDoc),
|
|
599
|
+
UploadSingleGameFile(urls.iOS_shared_scenes, $"{AirshipPlatform.iOS}/{orgScope}/{packageIdOnly}_shared/scenes", packageDoc),
|
|
600
|
+
|
|
601
|
+
UploadSingleGameFile(urls.Android_shared_resources, $"{AirshipPlatform.Android}/{orgScope}/{packageIdOnly}_shared/resources", packageDoc),
|
|
602
|
+
UploadSingleGameFile(urls.Android_shared_scenes, $"{AirshipPlatform.Android}/{orgScope}/{packageIdOnly}_shared/scenes", packageDoc),
|
|
595
603
|
});
|
|
596
604
|
}
|
|
597
605
|
|
|
@@ -659,7 +667,8 @@ namespace Editor.Packages {
|
|
|
659
667
|
// "Linux_shared_resources",
|
|
660
668
|
"Mac_shared_resources",
|
|
661
669
|
"Windows_shared_resources",
|
|
662
|
-
|
|
670
|
+
"iOS_shared_resources",
|
|
671
|
+
"Android_shared_resources",
|
|
663
672
|
|
|
664
673
|
// "Linux_shared_scenes",
|
|
665
674
|
// "Mac_shared_scenes",
|
|
@@ -690,7 +699,7 @@ namespace Editor.Packages {
|
|
|
690
699
|
Repaint();
|
|
691
700
|
}
|
|
692
701
|
|
|
693
|
-
public static bool VerifyBuildModules() {
|
|
702
|
+
public static bool VerifyBuildModules(bool mobileSupport) {
|
|
694
703
|
// var linux64 = ModuleUtil.IsModuleInstalled(BuildTarget.StandaloneLinux64);
|
|
695
704
|
// if (!linux64) {
|
|
696
705
|
// Debug.LogError("Linux Build Support (<b>Mono</b>) module not found.");
|
|
@@ -706,11 +715,20 @@ namespace Editor.Packages {
|
|
|
706
715
|
Debug.LogError("Windows Build Support (<b>Mono</b>) module not found.");
|
|
707
716
|
}
|
|
708
717
|
|
|
718
|
+
if (!mobileSupport) {
|
|
719
|
+
return mac && windows;
|
|
720
|
+
}
|
|
721
|
+
|
|
709
722
|
var iOS = ModuleUtil.IsModuleInstalled(BuildTarget.iOS);
|
|
710
723
|
if (!iOS) {
|
|
711
724
|
Debug.LogError("iOS Build Support module not found.");
|
|
712
725
|
}
|
|
713
|
-
|
|
726
|
+
|
|
727
|
+
var android = ModuleUtil.IsModuleInstalled(BuildTarget.Android);
|
|
728
|
+
if (!iOS) {
|
|
729
|
+
Debug.LogError("Android Build Support module not found.");
|
|
730
|
+
}
|
|
731
|
+
return mac && windows && iOS && android;
|
|
714
732
|
}
|
|
715
733
|
|
|
716
734
|
private static IEnumerator UploadSingleGameFile(string url, string filePath, AirshipPackageDocument packageDoc, bool absoluteFilePath = false) {
|
|
@@ -40,6 +40,9 @@ public class DeploymentUrls {
|
|
|
40
40
|
public string iOS_client_scenes;
|
|
41
41
|
public string iOS_shared_scenes;
|
|
42
42
|
|
|
43
|
+
public string Android_shared_resources;
|
|
44
|
+
public string Android_shared_scenes;
|
|
45
|
+
|
|
43
46
|
public string gameConfig;
|
|
44
47
|
public string source;
|
|
45
48
|
public string code;
|
package/Editor/Publish/Deploy.cs
CHANGED
|
@@ -35,31 +35,27 @@ public class Deploy {
|
|
|
35
35
|
private static GameDto activeDeployTarget;
|
|
36
36
|
public const ulong MAX_UPLOAD_KB = 500_000;
|
|
37
37
|
|
|
38
|
-
public static void
|
|
38
|
+
public static void PublishGame()
|
|
39
39
|
{
|
|
40
40
|
// Make sure we generate and write all `NetworkPrefabCollection`s before we
|
|
41
41
|
// build the game.
|
|
42
42
|
// NetworkPrefabManager.WriteAllCollections();
|
|
43
43
|
// Sort the current platform first to speed up build time
|
|
44
|
-
List<AirshipPlatform> platforms = new()
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
AirshipPlatform.
|
|
48
|
-
AirshipPlatform.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// foreach (var platform in AirshipPlatformUtil.livePlatforms) {
|
|
60
|
-
// if (platform == currentPlatform) continue;
|
|
61
|
-
// platforms.Add(platform);
|
|
62
|
-
// }
|
|
44
|
+
List<AirshipPlatform> platforms = new();
|
|
45
|
+
var gameConfig = GameConfig.Load();
|
|
46
|
+
if (gameConfig.supportsMobile) {
|
|
47
|
+
platforms.Add(AirshipPlatform.iOS);
|
|
48
|
+
platforms.Add(AirshipPlatform.Android);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// We want to end up on our editor machine's platform
|
|
52
|
+
#if UNITY_EDITOR_OSX
|
|
53
|
+
platforms.Add(AirshipPlatform.Windows);
|
|
54
|
+
platforms.Add(AirshipPlatform.Mac);
|
|
55
|
+
#else
|
|
56
|
+
platforms.Add(AirshipPlatform.Mac);
|
|
57
|
+
platforms.Add(AirshipPlatform.Windows);
|
|
58
|
+
#endif
|
|
63
59
|
EditorCoroutines.Execute((BuildAndDeploy(platforms.ToArray(), false)));
|
|
64
60
|
}
|
|
65
61
|
|
|
@@ -86,19 +82,21 @@ public class Deploy {
|
|
|
86
82
|
yield break;
|
|
87
83
|
}
|
|
88
84
|
|
|
85
|
+
var gameConfig = AssetDatabase.LoadAssetAtPath<GameConfig>("Assets/GameConfig.asset");
|
|
86
|
+
if (gameConfig == null) {
|
|
87
|
+
Debug.LogError("Missing GameConfig.");
|
|
88
|
+
yield break;
|
|
89
|
+
}
|
|
90
|
+
|
|
89
91
|
if (!skipBuild) {
|
|
90
|
-
var didVerify = AirshipPackagesWindow.VerifyBuildModules();
|
|
92
|
+
var didVerify = AirshipPackagesWindow.VerifyBuildModules(gameConfig.supportsMobile);
|
|
91
93
|
if (!didVerify) {
|
|
92
94
|
Debug.LogErrorFormat("Missing build modules. Install missing modules in Unity Hub and restart Unity to publish game.");
|
|
93
95
|
yield break;
|
|
94
96
|
}
|
|
95
97
|
}
|
|
96
98
|
|
|
97
|
-
|
|
98
|
-
if (gameConfig == null) {
|
|
99
|
-
Debug.LogError("Missing GameConfig.");
|
|
100
|
-
yield break;
|
|
101
|
-
}
|
|
99
|
+
|
|
102
100
|
|
|
103
101
|
var confirmedSaveState = EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo();
|
|
104
102
|
if (!confirmedSaveState || SceneManager.GetActiveScene().isDirty) { // User clicked "cancel"
|
|
@@ -300,8 +298,11 @@ public class Deploy {
|
|
|
300
298
|
|
|
301
299
|
// UploadSingleGameFile(urls.iOS_client_resources, $"{AirshipPlatform.iOS}/client/resources", AirshipPlatform.iOS),
|
|
302
300
|
// UploadSingleGameFile(urls.iOS_client_scenes, $"{AirshipPlatform.iOS}/client/scenes", AirshipPlatform.iOS),
|
|
303
|
-
|
|
304
|
-
|
|
301
|
+
UploadSingleGameFile(urls.iOS_shared_resources, $"{AirshipPlatform.iOS}/shared/resources", AirshipPlatform.iOS),
|
|
302
|
+
UploadSingleGameFile(urls.iOS_shared_scenes, $"{AirshipPlatform.iOS}/shared/scenes", AirshipPlatform.iOS),
|
|
303
|
+
|
|
304
|
+
UploadSingleGameFile(urls.Android_shared_resources, $"{AirshipPlatform.Android}/shared/resources", AirshipPlatform.Android),
|
|
305
|
+
UploadSingleGameFile(urls.Android_shared_scenes, $"{AirshipPlatform.Android}/shared/scenes", AirshipPlatform.Android),
|
|
305
306
|
});
|
|
306
307
|
}
|
|
307
308
|
|
|
@@ -381,6 +382,18 @@ public class Deploy {
|
|
|
381
382
|
|
|
382
383
|
// Complete deployment
|
|
383
384
|
{
|
|
385
|
+
List<string> uploadedFileIds = new();
|
|
386
|
+
uploadedFileIds.Add("Mac_shared_resources");
|
|
387
|
+
uploadedFileIds.Add("Mac_shared_scenes");
|
|
388
|
+
uploadedFileIds.Add("Windows_shared_resources");
|
|
389
|
+
uploadedFileIds.Add("Windows_shared_scenes");
|
|
390
|
+
if (gameConfig.supportsMobile) {
|
|
391
|
+
uploadedFileIds.Add("iOS_shared_resources");
|
|
392
|
+
uploadedFileIds.Add("iOS_shared_scenes");
|
|
393
|
+
uploadedFileIds.Add("Android_shared_resources");
|
|
394
|
+
uploadedFileIds.Add("Android_shared_scenes");
|
|
395
|
+
}
|
|
396
|
+
|
|
384
397
|
int attemptNum = 0;
|
|
385
398
|
while (attemptNum < 5) {
|
|
386
399
|
// Debug.Log("Complete. GameId: " + gameConfig.gameId + ", assetVersionId: " + deploymentDto.version.assetVersionNumber);
|
|
@@ -389,17 +402,7 @@ public class Deploy {
|
|
|
389
402
|
new CompleteGameDeploymentDto() {
|
|
390
403
|
gameId = gameConfig.gameId,
|
|
391
404
|
gameVersionId = deploymentDto.version.gameVersionId,
|
|
392
|
-
uploadedFileIds =
|
|
393
|
-
// "Linux_shared_resources",
|
|
394
|
-
"Mac_shared_resources",
|
|
395
|
-
"Windows_shared_resources",
|
|
396
|
-
// "iOS_shared_resources",
|
|
397
|
-
|
|
398
|
-
// "Linux_shared_scenes",
|
|
399
|
-
"Mac_shared_scenes",
|
|
400
|
-
"Windows_shared_scenes",
|
|
401
|
-
// "iOS_shared_scenes",
|
|
402
|
-
},
|
|
405
|
+
uploadedFileIds = uploadedFileIds.ToArray(),
|
|
403
406
|
}), "application/json");
|
|
404
407
|
req.SetRequestHeader("Authorization", "Bearer " + devKey);
|
|
405
408
|
yield return req.SendWebRequest();
|
|
@@ -617,7 +620,7 @@ public class Deploy {
|
|
|
617
620
|
|
|
618
621
|
switch (option) {
|
|
619
622
|
case 0: // Publish
|
|
620
|
-
Deploy.
|
|
623
|
+
Deploy.PublishGame();
|
|
621
624
|
break;
|
|
622
625
|
case 1: // Cancel
|
|
623
626
|
break;
|
|
@@ -121,6 +121,8 @@ public class AuthManager {
|
|
|
121
121
|
crossPlatformBrowser.platformBrowsers.Add(RuntimePlatform.OSXEditor, standaloneBrowser);
|
|
122
122
|
crossPlatformBrowser.platformBrowsers.Add(RuntimePlatform.OSXPlayer, standaloneBrowser);
|
|
123
123
|
crossPlatformBrowser.platformBrowsers.Add(RuntimePlatform.IPhonePlayer, new ASWebAuthenticationSessionBrowser());
|
|
124
|
+
// crossPlatformBrowser.platformBrowsers.Add(RuntimePlatform.Android, new DeepLinkBrowser());
|
|
125
|
+
crossPlatformBrowser.platformBrowsers.Add(RuntimePlatform.Android, new AndroidBrowser("http://*:8080"));
|
|
124
126
|
|
|
125
127
|
using var authenticationSession = new AuthenticationSession(auth, crossPlatformBrowser);
|
|
126
128
|
|
|
@@ -92,9 +92,15 @@ public class BundleDownloader : Singleton<BundleDownloader> {
|
|
|
92
92
|
|
|
93
93
|
long totalBytes = 0;
|
|
94
94
|
foreach (var request in preRequests) {
|
|
95
|
+
if (request.webRequest.result != UnityWebRequest.Result.Success) continue;
|
|
96
|
+
|
|
95
97
|
var contentLength = request.webRequest.GetResponseHeader("content-length");
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
try {
|
|
99
|
+
var bytes = long.Parse(contentLength);
|
|
100
|
+
totalBytes += bytes;
|
|
101
|
+
} catch (Exception e) {
|
|
102
|
+
Debug.LogError("Failed to parse content-length header: " + e);
|
|
103
|
+
}
|
|
98
104
|
}
|
|
99
105
|
|
|
100
106
|
if (loadingScreen) {
|
|
@@ -16,21 +16,10 @@ namespace Code.Bootstrap {
|
|
|
16
16
|
public class AirshipPlatformUtil {
|
|
17
17
|
public static AirshipPlatform[] livePlatforms = new[]
|
|
18
18
|
{
|
|
19
|
-
// AirshipPlatform.iOS,
|
|
20
|
-
AirshipPlatform.Mac,
|
|
21
|
-
AirshipPlatform.Windows,
|
|
22
|
-
AirshipPlatform.Linux
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
/// <summary>
|
|
26
|
-
/// Just another list that includes mobile.
|
|
27
|
-
/// You probably shouldn't use this -- instead use livePlatforms.
|
|
28
|
-
/// </summary>
|
|
29
|
-
public static AirshipPlatform[] betaPlatforms = new[] {
|
|
30
19
|
AirshipPlatform.iOS,
|
|
31
20
|
AirshipPlatform.Mac,
|
|
32
21
|
AirshipPlatform.Windows,
|
|
33
|
-
AirshipPlatform.Linux
|
|
22
|
+
AirshipPlatform.Linux
|
|
34
23
|
};
|
|
35
24
|
|
|
36
25
|
public static string GetStringName(AirshipPlatform platform) {
|
|
@@ -14,6 +14,7 @@ using Mirror;
|
|
|
14
14
|
using UnityEditor;
|
|
15
15
|
#endif
|
|
16
16
|
using UnityEngine;
|
|
17
|
+
using UnityEngine.Networking;
|
|
17
18
|
using UnityEngine.Serialization;
|
|
18
19
|
using Application = UnityEngine.Application;
|
|
19
20
|
using Debug = UnityEngine.Debug;
|
|
@@ -87,14 +88,35 @@ public class SystemRoot : Singleton<SystemRoot> {
|
|
|
87
88
|
platform = AirshipPlatform.Windows;
|
|
88
89
|
}
|
|
89
90
|
var path = Path.Join(Application.streamingAssetsPath, "ShippedBundles", $"CoreMaterials_{platform}/@easy/corematerials_shared/resources");
|
|
91
|
+
#if UNITY_ANDROID
|
|
92
|
+
Debug.Log($"Loading CoreMaterials (Android)... ({path})");
|
|
93
|
+
var st = Stopwatch.StartNew();
|
|
94
|
+
using var req = UnityWebRequestAssetBundle.GetAssetBundle(path);
|
|
95
|
+
await req.SendWebRequest();
|
|
96
|
+
if (req.result != UnityWebRequest.Result.Success) {
|
|
97
|
+
Debug.LogError($"Failed to load core materials bundle: {req.error}");
|
|
98
|
+
} else {
|
|
99
|
+
Debug.Log("Getting asset bundle from request");
|
|
100
|
+
var bundle = DownloadHandlerAssetBundle.GetContent(req);
|
|
101
|
+
if (bundle == null) {
|
|
102
|
+
|
|
103
|
+
}
|
|
104
|
+
this.coreMaterialsAssetBundle = bundle;
|
|
105
|
+
Debug.Log($"Loaded CoreMaterials bundle in {st.ElapsedMilliseconds} ms.");
|
|
106
|
+
}
|
|
107
|
+
#else
|
|
90
108
|
if (File.Exists(path)) {
|
|
109
|
+
Debug.Log($"Loading CoreMaterials... ({path})");
|
|
91
110
|
var st = Stopwatch.StartNew();
|
|
92
111
|
var ao = AssetBundle.LoadFromFileAsync(path);
|
|
93
112
|
this.extraBundleLoadRequests.Add(ao);
|
|
94
113
|
await ao;
|
|
95
114
|
this.coreMaterialsAssetBundle = ao.assetBundle;
|
|
96
115
|
Debug.Log($"Loaded CoreMaterials bundle in {st.ElapsedMilliseconds} ms.");
|
|
116
|
+
} else {
|
|
117
|
+
Debug.LogWarning($"CoreMaterials path not found ({path})");
|
|
97
118
|
}
|
|
119
|
+
#endif
|
|
98
120
|
}
|
|
99
121
|
}
|
|
100
122
|
|
|
@@ -294,33 +316,51 @@ public class SystemRoot : Singleton<SystemRoot> {
|
|
|
294
316
|
#endif
|
|
295
317
|
|
|
296
318
|
yield return this.WaitAll(loadLists[0].ToArray());
|
|
297
|
-
|
|
319
|
+
|
|
298
320
|
foreach (var ao in this.extraBundleLoadRequests) {
|
|
299
321
|
if (!ao.isDone) {
|
|
322
|
+
Debug.Log("Waiting for shipped asset bundles to load...");
|
|
300
323
|
yield return ao;
|
|
301
324
|
}
|
|
302
325
|
}
|
|
303
326
|
|
|
304
327
|
// Shader Variant Collections
|
|
305
328
|
if (!preWarmedCoreShaders && RunCore.IsClient()) {
|
|
329
|
+
// #if !UNITY_IOS && !UNITY_ANDROID
|
|
306
330
|
preWarmedCoreShaders = true;
|
|
307
|
-
while (!this.coreMaterialsAssetBundle) {
|
|
308
|
-
yield return null;
|
|
309
|
-
}
|
|
310
331
|
string[] collections = new[] {
|
|
311
332
|
"MainMenu",
|
|
312
333
|
// "RacingGame",
|
|
334
|
+
"BWShaderVariants 1 (Raven)",
|
|
313
335
|
};
|
|
314
336
|
foreach (var collectionName in collections) {
|
|
315
337
|
var path = $"Assets/AirshipPackages/@Easy/CoreMaterials/ShaderVariantCollections/{collectionName}.shadervariants".ToLower();
|
|
338
|
+
Debug.Log("Loading shader variant: " + collectionName);
|
|
339
|
+
if (this.coreMaterialsAssetBundle == null) {
|
|
340
|
+
Debug.LogWarning("coreMaterialsAssetBundle is null");
|
|
341
|
+
}
|
|
316
342
|
var shaderVariants = this.coreMaterialsAssetBundle.LoadAssetAsync<ShaderVariantCollection>(path);
|
|
343
|
+
Debug.Log($"Loading shader from path: {path}");
|
|
317
344
|
yield return shaderVariants;
|
|
318
345
|
if (shaderVariants != null) {
|
|
319
346
|
var st = Stopwatch.StartNew();
|
|
320
|
-
|
|
347
|
+
var col = shaderVariants.asset as ShaderVariantCollection;
|
|
348
|
+
if (col == null) {
|
|
349
|
+
Debug.LogWarning("Unable to warmup missing shader variant collection: " + collectionName);
|
|
350
|
+
continue;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
int variantCounter = 0;
|
|
354
|
+
int step = 1;
|
|
355
|
+
while (!col.WarmUpProgressively(step)) {
|
|
356
|
+
variantCounter += step;
|
|
357
|
+
Debug.Log($"Prewarm in progress ({collectionName}): {variantCounter}");
|
|
358
|
+
yield return null;
|
|
359
|
+
}
|
|
321
360
|
Debug.Log("Prewarmed " + collectionName + " in " + st.ElapsedMilliseconds + "ms");
|
|
322
361
|
}
|
|
323
362
|
}
|
|
363
|
+
// #endif
|
|
324
364
|
}
|
|
325
365
|
} else {
|
|
326
366
|
if (NetworkClient.isConnected) {
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
+
using System;
|
|
1
2
|
using UnityEngine;
|
|
2
3
|
|
|
3
4
|
public class LoadingQuitButton : MonoBehaviour {
|
|
4
5
|
public Transform visuals;
|
|
5
6
|
|
|
7
|
+
private void Awake() {
|
|
8
|
+
#if UNITY_IOS || UNITY_ANDROID
|
|
9
|
+
this.gameObject.SetActive(false);
|
|
10
|
+
#endif
|
|
11
|
+
}
|
|
12
|
+
|
|
6
13
|
public void Button_OnClick() {
|
|
7
14
|
Application.Quit();
|
|
8
15
|
}
|