From 4c48397d55f4afd8ab473a7db0e79523043fd573 Mon Sep 17 00:00:00 2001 From: Ansis Date: Wed, 16 Oct 2024 21:05:16 +0200 Subject: [PATCH] Remove WebView --- .../WebViewAudioSupportProvider.cs | 117 --- .../WebViewAudioSupportProvider.cs.meta | 3 - UltraStar Play/Assets/Common/Common.asmdef | 1 - .../Common/Graphics/SongMetaImageUtils.cs | 6 +- .../Graphics/YouTubeCoverImageProvider.cs | 110 --- .../YouTubeCoverImageProvider.cs.meta | 3 - .../Assets/Common/Model/Settings/Settings.cs | 5 - .../Common/Scene/CommonSceneObjects.prefab | 490 ------------- .../Common/Scene/CommonSceneObjectsBinder.cs | 1 - .../Assets/Common/SongPreviewControl.cs | 8 +- .../UploadWorkshopItemUiControl.cs | 9 +- .../UseSteamWorkshopItemsControl.cs | 19 - .../Assets/Common/Utils/WebViewUtils.cs | 160 +---- .../Video/SongVideoPlayer/SongVideoPlayer.cs | 3 - .../WebViewVideoSupportProvider.cs | 104 --- .../WebViewVideoSupportProvider.cs.meta | 3 - UltraStar Play/Assets/Common/WebView.meta | 8 - .../Common/WebView/BoolWebViewMessageDto.cs | 4 - .../WebView/BoolWebViewMessageDto.cs.meta | 3 - .../CanvasWebViewPrefab Variant.prefab | 166 ----- .../CanvasWebViewPrefab Variant.prefab.meta | 7 - .../Common/WebView/DefaultWebViewPage.html | 49 -- .../WebView/DefaultWebViewPage.html.meta | 3 - .../Common/WebView/NumberWebViewMessageDto.cs | 4 - .../WebView/NumberWebViewMessageDto.cs.meta | 3 - .../Assets/Common/WebView/WebViewManager.cs | 665 ------------------ .../Common/WebView/WebViewManager.cs.meta | 3 - .../Common/WebView/WebViewMessageDto.cs | 27 - .../Common/WebView/WebViewMessageDto.cs.meta | 3 - .../Common/WebView/WebViewMessageType.cs | 11 - .../Common/WebView/WebViewMessageType.cs.meta | 3 - .../WebViewRenderTexture.renderTexture | 39 - .../WebViewRenderTexture.renderTexture.meta | 8 - .../WebView/WebViewScriptFileSystemWatcher.cs | 53 -- .../WebViewScriptFileSystemWatcher.cs.meta | 3 - .../MediaFileFormatTests/WebViewTest.cs | 47 -- .../MediaFileFormatTests/WebViewTest.cs.meta | 3 - .../MediaFileFormatTests/WebViewTests.meta | 3 - .../WebViewTests/AudioOnly.txt | 9 - .../WebViewTests/AudioOnly.txt.meta | 7 - .../WebViewTests/AudioUrlAndExistingAudio.txt | 10 - .../AudioUrlAndExistingAudio.txt.meta | 7 - .../WebViewTests/AudioUrlAndMissingAudio.txt | 10 - .../AudioUrlAndMissingAudio.txt.meta | 7 - .../WebViewTests/AudioUrlOnly.txt | 9 - .../WebViewTests/AudioUrlOnly.txt.meta | 7 - .../WebViewTests/VideoUrlOnly.txt | 9 - .../WebViewTests/VideoUrlOnly.txt.meta | 7 - .../WebViewTests/WebsiteOnly.txt | 9 - .../WebViewTests/WebsiteOnly.txt.meta | 7 - .../MediaFileFormatTests/WebViewTests/ogg.ogg | Bin 50356 -> 0 bytes .../WebViewTests/ogg.ogg.meta | 23 - .../DevelopmentOptionsControl.cs | 20 +- UltraStar Play/Assets/Scenes/Scenes.asmdef | 1 - .../SongSelect/SongSelectSceneInputControl.cs | 4 - .../StreamingAssets/WebViewScripts.meta | 3 - .../StreamingAssets/WebViewScripts/README.md | 26 - .../WebViewScripts/README.md.meta | 3 - .../WebViewScripts/youtube.com.js | 102 --- .../WebViewScripts/youtube.com.js.meta | 3 - .../Core/Editor/Vuplex.WebView.Editor.asmdef | 19 - .../Editor/Vuplex.WebView.Editor.asmdef.meta | 7 - .../Vuplex.WebView.Plugins.Editor.asmdef | 19 - .../Vuplex.WebView.Plugins.Editor.asmdef.meta | 7 - .../Vuplex.WebView.Standalone.Editor.asmdef | 20 - ...plex.WebView.Standalone.Editor.asmdef.meta | 7 - ...x.WebView.Standalone.Windows.Editor.asmdef | 20 - ...View.Standalone.Windows.Editor.asmdef.meta | 7 - .../Vuplex/WebView/Vuplex.WebView.asmdef | 16 - .../Vuplex/WebView/Vuplex.WebView.asmdef.meta | 7 - .../VuplexWebViewDummy/CanvasWebViewPrefab.cs | 21 - .../CanvasWebViewPrefab.cs.meta | 3 - .../WebView/VuplexWebViewDummy/EventArgs.cs | 14 - .../VuplexWebViewDummy/EventArgs.cs.meta | 3 - .../WebView/VuplexWebViewDummy/IWebView.cs | 21 - .../VuplexWebViewDummy/IWebView.cs.meta | 3 - .../VuplexWebViewDummy/ProgressChangeType.cs | 13 - .../ProgressChangeType.cs.meta | 3 - .../ProgressChangedEventArgs.cs | 14 - .../ProgressChangedEventArgs.cs.meta | 3 - .../Vuplex/WebView/VuplexWebViewDummy/Web.cs | 18 - .../WebView/VuplexWebViewDummy/Web.cs.meta | 3 - .../playshared/Runtime/Songs/SongMetaUtils.cs | 1 + 83 files changed, 9 insertions(+), 2680 deletions(-) delete mode 100644 UltraStar Play/Assets/Common/Audio/SongAudioPlayer/WebViewAudioSupportProvider.cs delete mode 100644 UltraStar Play/Assets/Common/Audio/SongAudioPlayer/WebViewAudioSupportProvider.cs.meta delete mode 100644 UltraStar Play/Assets/Common/Graphics/YouTubeCoverImageProvider.cs delete mode 100644 UltraStar Play/Assets/Common/Graphics/YouTubeCoverImageProvider.cs.meta delete mode 100644 UltraStar Play/Assets/Common/Video/SongVideoPlayer/WebViewVideoSupportProvider.cs delete mode 100644 UltraStar Play/Assets/Common/Video/SongVideoPlayer/WebViewVideoSupportProvider.cs.meta delete mode 100644 UltraStar Play/Assets/Common/WebView.meta delete mode 100644 UltraStar Play/Assets/Common/WebView/BoolWebViewMessageDto.cs delete mode 100644 UltraStar Play/Assets/Common/WebView/BoolWebViewMessageDto.cs.meta delete mode 100644 UltraStar Play/Assets/Common/WebView/CanvasWebViewPrefab Variant.prefab delete mode 100644 UltraStar Play/Assets/Common/WebView/CanvasWebViewPrefab Variant.prefab.meta delete mode 100644 UltraStar Play/Assets/Common/WebView/DefaultWebViewPage.html delete mode 100644 UltraStar Play/Assets/Common/WebView/DefaultWebViewPage.html.meta delete mode 100644 UltraStar Play/Assets/Common/WebView/NumberWebViewMessageDto.cs delete mode 100644 UltraStar Play/Assets/Common/WebView/NumberWebViewMessageDto.cs.meta delete mode 100644 UltraStar Play/Assets/Common/WebView/WebViewManager.cs delete mode 100644 UltraStar Play/Assets/Common/WebView/WebViewManager.cs.meta delete mode 100644 UltraStar Play/Assets/Common/WebView/WebViewMessageDto.cs delete mode 100644 UltraStar Play/Assets/Common/WebView/WebViewMessageDto.cs.meta delete mode 100644 UltraStar Play/Assets/Common/WebView/WebViewMessageType.cs delete mode 100644 UltraStar Play/Assets/Common/WebView/WebViewMessageType.cs.meta delete mode 100644 UltraStar Play/Assets/Common/WebView/WebViewRenderTexture.renderTexture delete mode 100644 UltraStar Play/Assets/Common/WebView/WebViewRenderTexture.renderTexture.meta delete mode 100644 UltraStar Play/Assets/Common/WebView/WebViewScriptFileSystemWatcher.cs delete mode 100644 UltraStar Play/Assets/Common/WebView/WebViewScriptFileSystemWatcher.cs.meta delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTest.cs delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTest.cs.meta delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests.meta delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioOnly.txt delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioOnly.txt.meta delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndExistingAudio.txt delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndExistingAudio.txt.meta delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndMissingAudio.txt delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndMissingAudio.txt.meta delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlOnly.txt delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlOnly.txt.meta delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/VideoUrlOnly.txt delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/VideoUrlOnly.txt.meta delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/WebsiteOnly.txt delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/WebsiteOnly.txt.meta delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/ogg.ogg delete mode 100644 UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/ogg.ogg.meta delete mode 100644 UltraStar Play/Assets/StreamingAssets/WebViewScripts.meta delete mode 100644 UltraStar Play/Assets/StreamingAssets/WebViewScripts/README.md delete mode 100644 UltraStar Play/Assets/StreamingAssets/WebViewScripts/README.md.meta delete mode 100644 UltraStar Play/Assets/StreamingAssets/WebViewScripts/youtube.com.js delete mode 100644 UltraStar Play/Assets/StreamingAssets/WebViewScripts/youtube.com.js.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/Core/Editor/Vuplex.WebView.Editor.asmdef delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/Core/Editor/Vuplex.WebView.Editor.asmdef.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/Core/Plugins/Editor/Vuplex.WebView.Plugins.Editor.asmdef delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/Core/Plugins/Editor/Vuplex.WebView.Plugins.Editor.asmdef.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/Standalone/Editor/Vuplex.WebView.Standalone.Editor.asmdef delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/Standalone/Editor/Vuplex.WebView.Standalone.Editor.asmdef.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/Standalone/Windows/Editor/Vuplex.WebView.Standalone.Windows.Editor.asmdef delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/Standalone/Windows/Editor/Vuplex.WebView.Standalone.Windows.Editor.asmdef.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/Vuplex.WebView.asmdef delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/Vuplex.WebView.asmdef.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/CanvasWebViewPrefab.cs delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/CanvasWebViewPrefab.cs.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/EventArgs.cs delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/EventArgs.cs.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/IWebView.cs delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/IWebView.cs.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangeType.cs delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangeType.cs.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangedEventArgs.cs delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangedEventArgs.cs.meta delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/Web.cs delete mode 100644 UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/Web.cs.meta diff --git a/UltraStar Play/Assets/Common/Audio/SongAudioPlayer/WebViewAudioSupportProvider.cs b/UltraStar Play/Assets/Common/Audio/SongAudioPlayer/WebViewAudioSupportProvider.cs deleted file mode 100644 index c7ed5eaa2..000000000 --- a/UltraStar Play/Assets/Common/Audio/SongAudioPlayer/WebViewAudioSupportProvider.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using UniInject; -using UniRx; -using UnityEngine; - -public class WebViewAudioSupportProvider : AbstractAudioSupportProvider -{ - [Inject] - private WebViewManager webViewManager; - - public override IObservable LoadAsObservable(string audioUri, bool streamAudio, double startPositionInMillis) - { - bool success = webViewManager.LoadUrl(audioUri); - if (!success) - { - return ObservableUtils.LogExceptionThenThrow( - new SongAudioPlayerException($"Failed to load audio via WebView with URL {audioUri}")); - } - - // The WebView is loaded asynchronously. When the duration is available then the audio is loaded. - long startTime = TimeUtils.GetUnixTimeMilliseconds(); - long timeoutInMillis = 30000; - return Observable.Create(o => - { - StartCoroutine(CoroutineUtils.ExecuteWhenConditionIsTrue( - () => this == null - || DurationInMillis > 0 - || TimeUtils.IsDurationAboveThresholdInMillis(startTime, timeoutInMillis), - () => - { - if (this == null) - { - string errorMessage = $"Failed to load audio clip '{audioUri}': {nameof(WebViewAudioSupportProvider)} has been destroyed already."; - Debug.LogError(errorMessage); - throw new AudioSupportProviderException(errorMessage); - } - - if (TimeUtils.IsDurationAboveThresholdInMillis(startTime, timeoutInMillis)) - { - o.OnError(new AudioSupportProviderException("Loading audio using WebView timed out.")); - return; - } - - PositionInMillis = startPositionInMillis; - o.OnNext(new AudioLoadedEvent(audioUri)); - })); - - return Disposable.Empty; - }); - } - - public override bool IsSupported(string audioUri) - { - return WebViewUtils.CanHandleWebViewUrl(audioUri); - } - - public override void Unload() - { - webViewManager.StopPlayback(); - } - - public override void Play() - { - webViewManager.ResumePlayback(); - } - - public override void Pause() - { - webViewManager.PausePlayback(); - } - - public override void Stop() - { - webViewManager.StopPlayback(); - } - - public override bool IsPlaying - { - get => webViewManager.IsPlaying; - set - { - if (value) - { - Play(); - } - else - { - Pause(); - } - } - } - - public override double PlaybackSpeed - { - get => 1; - set => SetPlaybackSpeed(value, true); - } - - public override void SetPlaybackSpeed(double newValue, bool changeTempoButKeepPitch) - { - // Not supported - } - - public override double PositionInMillis - { - get => webViewManager.EstimatedPositionInMillis; - set => webViewManager.SetPositionInMillis(value); - } - - public override double DurationInMillis => webViewManager.DurationInMillis; - - public override double VolumeFactor - { - get => webViewManager.VolumeInPercent / 100.0; - set => webViewManager.VolumeInPercent = (int)(value * 100.0); - } -} diff --git a/UltraStar Play/Assets/Common/Audio/SongAudioPlayer/WebViewAudioSupportProvider.cs.meta b/UltraStar Play/Assets/Common/Audio/SongAudioPlayer/WebViewAudioSupportProvider.cs.meta deleted file mode 100644 index 5f7d57f45..000000000 --- a/UltraStar Play/Assets/Common/Audio/SongAudioPlayer/WebViewAudioSupportProvider.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 91d313ed911343d1a474159bfc826ff2 -timeCreated: 1715501643 \ No newline at end of file diff --git a/UltraStar Play/Assets/Common/Common.asmdef b/UltraStar Play/Assets/Common/Common.asmdef index f9f099cb8..6874df5c1 100644 --- a/UltraStar Play/Assets/Common/Common.asmdef +++ b/UltraStar Play/Assets/Common/Common.asmdef @@ -26,7 +26,6 @@ "playsharedui", "SpleeterSharp", "UnityStandaloneFileBrowser", - "Vuplex.WebView", "LiteNetLib", "com.whisper.unity", "FfmpegUnity", diff --git a/UltraStar Play/Assets/Common/Graphics/SongMetaImageUtils.cs b/UltraStar Play/Assets/Common/Graphics/SongMetaImageUtils.cs index 0a6b8d329..7680db012 100644 --- a/UltraStar Play/Assets/Common/Graphics/SongMetaImageUtils.cs +++ b/UltraStar Play/Assets/Common/Graphics/SongMetaImageUtils.cs @@ -7,8 +7,6 @@ public static class SongMetaImageUtils { - private static YouTubeCoverImageProvider youTubeCoverImageProvider = new(); - public static IObservable GetBackgroundOrCoverImageUri(SongMeta songMeta) { string uri = SongMetaUtils.GetBackgroundUri(songMeta); @@ -54,9 +52,7 @@ public static IObservable GetCoverOrBackgroundImageUri(SongMeta songMeta } // Try to find an image via mods - List songCoverImageProviders = ModManager.GetModObjects() - .Union(new List() { youTubeCoverImageProvider }) - .ToList(); + List songCoverImageProviders = ModManager.GetModObjects(); if (songCoverImageProviders.IsNullOrEmpty()) { return Observable.Return(""); diff --git a/UltraStar Play/Assets/Common/Graphics/YouTubeCoverImageProvider.cs b/UltraStar Play/Assets/Common/Graphics/YouTubeCoverImageProvider.cs deleted file mode 100644 index 437cfe681..000000000 --- a/UltraStar Play/Assets/Common/Graphics/YouTubeCoverImageProvider.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using UniRx; -using UnityEngine; - -public class YouTubeCoverImageProvider : ISongCoverImageProvider -{ - public IObservable GetCoverImageUri(SongMeta songMeta) - { - string webViewUri = SongMetaUtils.GetWebViewUrl(songMeta); - if (TryGetYouTubeUri(webViewUri, out Uri uri)) - { - return Observable.Return(GetCoverImageFromYouTube(uri)); - } - - return Observable.Empty(); - } - - private static string GetCoverImageFromYouTube(Uri uri) - { - // https://stackoverflow.com/questions/2068344/how-do-i-get-a-youtube-video-thumbnail-from-the-youtube-api - string videoId = GetYouTubeVideoId(uri); - if (videoId.IsNullOrEmpty()) - { - return ""; - } - return $"https://img.youtube.com/vi/{videoId}/hqdefault.jpg"; - } - - private static string GetYouTubeVideoId(Uri uri) - { - Dictionary queryParameters = ParseQueryString(uri); - if (queryParameters.TryGetValue("v", out string videoId)) - { - return videoId; - } - return ""; - } - - private static bool TryGetYouTubeUri(string resource, out Uri uri) - { - if (resource.IsNullOrEmpty() - || !WebRequestUtils.IsHttpOrHttpsUri(resource)) - { - uri = null; - return false; - } - - try - { - uri = new Uri(resource); - if (uri.Host.Contains("youtube")) - { - return true; - } - - uri = null; - return false; - } - catch (UriFormatException) - { - uri = null; - return false; - } - } - - /** - * Parse a URI query string. - * Workaround because System.Web.HttpUtility.ParseQueryString - * is not compiled into the project by Unity by default. - */ - public static Dictionary ParseQueryString(Uri uri) - { - string queryString = uri.Query; - - Dictionary parsedParameters = new Dictionary(); - if (queryString.IsNullOrEmpty()) - { - return parsedParameters; - } - - try - { - string[] queryParams = queryString.TrimStart('?').Split('&'); - foreach (string param in queryParams) - { - string[] keyValue = param.Split('='); - if (keyValue.Length == 2) - { - string key = Uri.UnescapeDataString(keyValue[0]); - string value = Uri.UnescapeDataString(keyValue[1]); - parsedParameters[key] = value; - } - else if (keyValue.Length == 1) - { - string key = Uri.UnescapeDataString(keyValue[0]); - parsedParameters[key] = null; - } - } - } - catch (Exception ex) - { - Debug.LogException(ex); - Debug.LogError($"Failed to parse query string of URI '{uri}': {ex.Message}"); - return parsedParameters; - } - - return parsedParameters; - } -} diff --git a/UltraStar Play/Assets/Common/Graphics/YouTubeCoverImageProvider.cs.meta b/UltraStar Play/Assets/Common/Graphics/YouTubeCoverImageProvider.cs.meta deleted file mode 100644 index fd726b2f9..000000000 --- a/UltraStar Play/Assets/Common/Graphics/YouTubeCoverImageProvider.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 46d703e04f2d422d812a0093363b916c -timeCreated: 1709987870 \ No newline at end of file diff --git a/UltraStar Play/Assets/Common/Model/Settings/Settings.cs b/UltraStar Play/Assets/Common/Model/Settings/Settings.cs index 04bba37a9..f63bcb0ce 100644 --- a/UltraStar Play/Assets/Common/Model/Settings/Settings.cs +++ b/UltraStar Play/Assets/Common/Model/Settings/Settings.cs @@ -147,11 +147,6 @@ public class Settings : ISettings public Dictionary> HttpApiPermissions { get; set; } = new(); public int CompanionClientMessageBufferTimeInMillis { get; set; } = 150; - // WebView settings - public List AcceptedWebViewHosts { get; set; } = new(); - public bool EnableWebView { get; set; } = true; - public string CustomUserAgent { get; set; } = ""; - // Other settings public PartyModeSettings PartyModeSettings { get; set; } = new(); public SongEditorSettings SongEditorSettings { get; set; } = new(); diff --git a/UltraStar Play/Assets/Common/Scene/CommonSceneObjects.prefab b/UltraStar Play/Assets/Common/Scene/CommonSceneObjects.prefab index bfbd17b4e..e300c81b7 100644 --- a/UltraStar Play/Assets/Common/Scene/CommonSceneObjects.prefab +++ b/UltraStar Play/Assets/Common/Scene/CommonSceneObjects.prefab @@ -964,7 +964,6 @@ Transform: - {fileID: 8210014063461271944} - {fileID: 3855433877842653761} - {fileID: 4351641984961804500} - - {fileID: 1396528235241154348} - {fileID: 7309157947487282350} - {fileID: 1155857935507181713} - {fileID: 3426646173330849412} @@ -1659,108 +1658,6 @@ MonoBehaviour: m_BlockingMask: serializedVersion: 2 m_Bits: 4294967295 ---- !u!1 &2109903415321387480 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 487775751351812396} - - component: {fileID: 519528370131799763} - - component: {fileID: 8178368657944125268} - - component: {fileID: 40393421652004942} - m_Layer: 9 - m_Name: WebViewCanvas - m_TagString: MelodyManiaOnly - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &487775751351812396 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2109903415321387480} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 0, y: 0, z: 0} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 7080564416713934777} - m_Father: {fileID: 1396528235241154348} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0, y: 0} ---- !u!223 &519528370131799763 -Canvas: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2109903415321387480} - m_Enabled: 1 - serializedVersion: 3 - m_RenderMode: 1 - m_Camera: {fileID: 2364365025742481650} - m_PlaneDistance: 100 - m_PixelPerfect: 0 - m_ReceivesEvents: 1 - m_OverrideSorting: 0 - m_OverridePixelPerfect: 0 - m_SortingBucketNormalizedSize: 0 - m_VertexColorAlwaysGammaSpace: 0 - m_AdditionalShaderChannelsFlag: 0 - m_UpdateRectTransformForStandalone: 0 - m_SortingLayerID: 0 - m_SortingOrder: 0 - m_TargetDisplay: 0 ---- !u!114 &8178368657944125268 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2109903415321387480} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} - m_Name: - m_EditorClassIdentifier: - m_UiScaleMode: 1 - m_ReferencePixelsPerUnit: 100 - m_ScaleFactor: 1 - m_ReferenceResolution: {x: 1920, y: 1080} - m_ScreenMatchMode: 0 - m_MatchWidthOrHeight: 0 - m_PhysicalUnit: 3 - m_FallbackScreenDPI: 96 - m_DefaultSpriteDPI: 96 - m_DynamicPixelsPerUnit: 1 - m_PresetInfoIsWorld: 0 ---- !u!114 &40393421652004942 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2109903415321387480} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreReversedGraphics: 1 - m_BlockingObjects: 0 - m_BlockingMask: - serializedVersion: 2 - m_Bits: 4294967295 --- !u!1 &2127652182009048729 GameObject: m_ObjectHideFlags: 0 @@ -7168,50 +7065,6 @@ VideoPlayer: m_WaitForFirstFrame: 1 m_FrameReadyEventEnabled: 0 m_VideoShaders: [] ---- !u!1 &3231274684231191156 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 7995986364530389882} - - component: {fileID: 3705748409921045012} - m_Layer: 0 - m_Name: WebViewScriptFileSystemWatcher - m_TagString: MelodyManiaOnly - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &7995986364530389882 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3231274684231191156} - serializedVersion: 2 - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1396528235241154348} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &3705748409921045012 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 3231274684231191156} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: f7dc3fe703c34dee838e8f0682097d70, type: 3} - m_Name: - m_EditorClassIdentifier: --- !u!1 &3312558049815969777 GameObject: m_ObjectHideFlags: 0 @@ -7703,89 +7556,6 @@ VideoPlayer: m_WaitForFirstFrame: 1 m_FrameReadyEventEnabled: 0 m_VideoShaders: [] ---- !u!1 &4674425732938775201 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 3568527301788257143} - - component: {fileID: 2674514932397205657} - - component: {fileID: 3656317211923003634} - m_Layer: 9 - m_Name: WebViewDisabledText - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &3568527301788257143 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4674425732938775201} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 7080564416713934777} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!222 &2674514932397205657 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4674425732938775201} - m_CullTransparentMesh: 1 ---- !u!114 &3656317211923003634 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4674425732938775201} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.1254902, g: 0.1254902, b: 0.1254902, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 64 - m_FontStyle: 0 - m_BestFit: 1 - m_MinSize: 3 - m_MaxSize: 64 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: 'The embedded browser has been disabled in the settings. - - - You can - toggle this overlay anytime by pressing F8 or Ctrl+B.' --- !u!1 &4760730431951538787 GameObject: m_ObjectHideFlags: 0 @@ -7876,134 +7646,6 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 45201bdb09f74cca9031b672cfb69c0c, type: 3} m_Name: m_EditorClassIdentifier: ---- !u!1 &4908938150708377613 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 5842408346874960166} - - component: {fileID: 2364365025742481650} - - component: {fileID: 3810538232154436742} - m_Layer: 0 - m_Name: WebViewCamera - m_TagString: MelodyManiaOnly - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &5842408346874960166 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4908938150708377613} - serializedVersion: 2 - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1396528235241154348} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!20 &2364365025742481650 -Camera: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4908938150708377613} - m_Enabled: 1 - serializedVersion: 2 - m_ClearFlags: 2 - m_BackGroundColor: {r: 0, g: 0, b: 0, a: 1} - m_projectionMatrixMode: 1 - m_GateFitMode: 2 - m_FOVAxisMode: 0 - m_Iso: 200 - m_ShutterSpeed: 0.005 - m_Aperture: 16 - m_FocusDistance: 10 - m_FocalLength: 50 - m_BladeCount: 5 - m_Curvature: {x: 2, y: 11} - m_BarrelClipping: 0.25 - m_Anamorphism: 0 - m_SensorSize: {x: 36, y: 24} - m_LensShift: {x: 0, y: 0} - m_NormalizedViewPortRect: - serializedVersion: 2 - x: 0 - y: 0 - width: 1 - height: 1 - near clip plane: 0.3 - far clip plane: 1000 - field of view: 60 - orthographic: 0 - orthographic size: 5 - m_Depth: 0 - m_CullingMask: - serializedVersion: 2 - m_Bits: 512 - m_RenderingPath: -1 - m_TargetTexture: {fileID: 8400000, guid: b7abf32de3eac1648b13bbe27ad196a8, type: 2} - m_TargetDisplay: 0 - m_TargetEye: 3 - m_HDR: 1 - m_AllowMSAA: 1 - m_AllowDynamicResolution: 0 - m_ForceIntoRT: 0 - m_OcclusionCulling: 0 - m_StereoConvergence: 10 - m_StereoSeparation: 0.022 ---- !u!114 &3810538232154436742 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4908938150708377613} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3} - m_Name: - m_EditorClassIdentifier: - m_RenderShadows: 0 - m_RequiresDepthTextureOption: 2 - m_RequiresOpaqueTextureOption: 2 - m_CameraType: 0 - m_Cameras: [] - m_RendererIndex: -1 - m_VolumeLayerMask: - serializedVersion: 2 - m_Bits: 1 - m_VolumeTrigger: {fileID: 0} - m_VolumeFrameworkUpdateModeOption: 2 - m_RenderPostProcessing: 0 - m_Antialiasing: 0 - m_AntialiasingQuality: 2 - m_StopNaN: 0 - m_Dithering: 0 - m_ClearDepth: 1 - m_AllowXRRendering: 1 - m_AllowHDROutput: 1 - m_UseScreenCoordOverride: 0 - m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0} - m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0} - m_RequiresDepthTexture: 0 - m_RequiresColorTexture: 0 - m_Version: 2 - m_TaaSettings: - quality: 3 - frameInfluence: 0.1 - jitterScale: 1 - mipBias: 0 - varianceClampScale: 0.9 - contrastAdaptiveSharpening: 0 --- !u!1 &5005797961523891926 GameObject: m_ObjectHideFlags: 0 @@ -8208,62 +7850,6 @@ MonoBehaviour: y: 0 width: 1 height: 1 ---- !u!1 &5673934055298899361 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1396528235241154348} - - component: {fileID: 8854215853695137417} - m_Layer: 0 - m_Name: WebViewManager - m_TagString: MelodyManiaOnly - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!4 &1396528235241154348 -Transform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5673934055298899361} - serializedVersion: 2 - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: -1920, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 7995986364530389882} - - {fileID: 5842408346874960166} - - {fileID: 487775751351812396} - m_Father: {fileID: 5483831765678408185} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!114 &8854215853695137417 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 5673934055298899361} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: c01bf111bd65446ab45a978e7a390215, type: 3} - m_Name: - m_EditorClassIdentifier: - webViewPrefabPrefab: {fileID: 3300069630544928059, guid: b8149ed42d0df794b8c7b96c0ca10689, - type: 3} - webViewCanvas: {fileID: 519528370131799763} - webViewCamera: {fileID: 2364365025742481650} - defaultWebViewHtml: {fileID: 4900000, guid: e3afca435ff14476bad0b2ad71017bc3, type: 3} - defaultRenderTexture: {fileID: 8400000, guid: b7abf32de3eac1648b13bbe27ad196a8, - type: 2} - volumeInPercent: 0 - isContentLoaded: 0 --- !u!1 &5675655531140774825 GameObject: m_ObjectHideFlags: 0 @@ -8771,82 +8357,6 @@ MonoBehaviour: steamAppId: 2394070 targetSteamId: 0 userSteamId: 0 ---- !u!1 &6306022575498970254 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 7080564416713934777} - - component: {fileID: 2603594510128697783} - - component: {fileID: 1059791845746085219} - m_Layer: 9 - m_Name: Background - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &7080564416713934777 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6306022575498970254} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 3568527301788257143} - m_Father: {fileID: 487775751351812396} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!222 &2603594510128697783 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6306022575498970254} - m_CullTransparentMesh: 1 ---- !u!114 &1059791845746085219 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 6306022575498970254} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 0} - m_Type: 0 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 --- !u!1 &6374073881040640669 GameObject: m_ObjectHideFlags: 0 diff --git a/UltraStar Play/Assets/Common/Scene/CommonSceneObjectsBinder.cs b/UltraStar Play/Assets/Common/Scene/CommonSceneObjectsBinder.cs index b6132fc3d..e8e61c134 100644 --- a/UltraStar Play/Assets/Common/Scene/CommonSceneObjectsBinder.cs +++ b/UltraStar Play/Assets/Common/Scene/CommonSceneObjectsBinder.cs @@ -43,7 +43,6 @@ public List GetBindings() bb.BindExistingInstance(DefaultFocusableNavigator.Instance); bb.BindExistingInstance(MicSampleRecorderManager.Instance); bb.BindExistingInstance(AchievementEventStream.Instance); - bb.BindExistingInstance(WebViewManager.Instance); bb.BindExistingInstance(SongMediaFileConversionManager.Instance); bb.BindExistingInstance(ModManager.Instance); bb.BindExistingInstance(RuntimeUiInspectionManager.Instance); diff --git a/UltraStar Play/Assets/Common/SongPreviewControl.cs b/UltraStar Play/Assets/Common/SongPreviewControl.cs index 2a37b64be..a1949016e 100644 --- a/UltraStar Play/Assets/Common/SongPreviewControl.cs +++ b/UltraStar Play/Assets/Common/SongPreviewControl.cs @@ -39,9 +39,6 @@ public class SongPreviewControl : MonoBehaviour, INeedInjection public ReactiveProperty VideoFadeIn { get; private set; } = new(); public ReactiveProperty BackgroundImageFadeIn { get; private set; } = new(); - // TODO: Inject the instance - private WebViewManager WebViewManager => WebViewManager.Instance; - protected virtual void Start() { if (GetFinalPreviewVolume() <= 0) @@ -81,10 +78,7 @@ protected virtual float UpdateVideoFadeIn() // The video has an additional delay to load. // As long as no frame is ready yet, the VideoPlayer.time is 0. - if (!songVideoPlayer.IsPartiallyLoaded - || (songVideoPlayer.PositionInMillis <= 0 - // WebView must be visible to see controls, even when audio is not ready yet. - && songVideoPlayer.CurrentVideoSupportProvider is not WebViewVideoSupportProvider)) + if (!songVideoPlayer.IsPartiallyLoaded || songVideoPlayer.PositionInMillis <= 0) { videoFadeInStartTimeInSeconds = Time.time; } diff --git a/UltraStar Play/Assets/Common/Steam/SteamWorkshop/UploadWorkshopItemUiControl.cs b/UltraStar Play/Assets/Common/Steam/SteamWorkshop/UploadWorkshopItemUiControl.cs index 0711b8f30..00a61c5c6 100644 --- a/UltraStar Play/Assets/Common/Steam/SteamWorkshop/UploadWorkshopItemUiControl.cs +++ b/UltraStar Play/Assets/Common/Steam/SteamWorkshop/UploadWorkshopItemUiControl.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using Steamworks.Ugc; @@ -16,14 +16,12 @@ public class UploadWorkshopItemUiControl : INeedInjection, IInjectionFinishedLis { PlayerProfileUtils.PlayerProfileImagesFolderName, ThemeFolderUtils.ThemeFolderName, - ModFolderUtils.ModsRootFolderName, - WebViewUtils.WebViewScriptsFolderName, + ModFolderUtils.ModsRootFolderName }; private static readonly string PlayerProfileImageTag = "PlayerProfileImage"; private static readonly string ThemeTag = "Theme"; private static readonly string ModTag = "Mod"; - private static readonly string WebViewScriptTag = "WebViewScript"; [Inject(UxmlName = R.UxmlNames.workshopItemChooser)] private DropdownField workshopItemChooser; @@ -199,8 +197,7 @@ private List GetTagsFromContentFolder(string folder) { { PlayerProfileUtils.PlayerProfileImagesFolderName, PlayerProfileImageTag }, { ThemeFolderUtils.ThemeFolderName, ThemeTag }, - { ModFolderUtils.ModsRootFolderName, ModTag }, - { WebViewUtils.WebViewScriptsFolderName, WebViewScriptTag }, + { ModFolderUtils.ModsRootFolderName, ModTag } }; foreach (string expectedSubfolder in expectedContentFolderSubfolders) { diff --git a/UltraStar Play/Assets/Common/Steam/SteamWorkshop/UseSteamWorkshopItemsControl.cs b/UltraStar Play/Assets/Common/Steam/SteamWorkshop/UseSteamWorkshopItemsControl.cs index e283607a5..9e99c02c7 100644 --- a/UltraStar Play/Assets/Common/Steam/SteamWorkshop/UseSteamWorkshopItemsControl.cs +++ b/UltraStar Play/Assets/Common/Steam/SteamWorkshop/UseSteamWorkshopItemsControl.cs @@ -18,7 +18,6 @@ public void UseWorkshopItems(List items) } Debug.Log($"Using content from {items.Count} Steam Workshop items: {items.Select(it => it.Title).JoinWith(", ")}"); - UseDownloadedWorkshopItemsForWebView(items); UseDownloadedWorkshopItemsForPlayerProfileImages(items); UseDownloadedWorkshopItemsForMods(items); UseDownloadedWorkshopItemsForThemes(items); @@ -78,24 +77,6 @@ private void UseDownloadedWorkshopItemsForPlayerProfileImages(List items) } } - private void UseDownloadedWorkshopItemsForWebView(List items) - { - try - { - WebViewUtils.AdditionalWebViewScriptsFolders = UnionWithSubfolderInWorkshopItems( - WebViewUtils.AdditionalWebViewScriptsFolders, - items, - WebViewUtils.WebViewScriptsFolderName); - Debug.Log($"Using Steam Workshop items for additional web view script folders: {WebViewUtils.AdditionalWebViewScriptsFolders.JoinWith(", ")}"); - WebViewManager.Instance.ReloadScripts(); - } - catch (Exception ex) - { - Debug.LogException(ex); - Debug.LogError($"Failed to make use of downloaded Workshop Items for WebView: {ex.Message}"); - } - } - private static List UnionWithSubfolderInWorkshopItems(List originalFolders, List items, string subfolderName) { return originalFolders diff --git a/UltraStar Play/Assets/Common/Utils/WebViewUtils.cs b/UltraStar Play/Assets/Common/Utils/WebViewUtils.cs index 61ddcb8e4..4e1fc19f1 100644 --- a/UltraStar Play/Assets/Common/Utils/WebViewUtils.cs +++ b/UltraStar Play/Assets/Common/Utils/WebViewUtils.cs @@ -1,163 +1,7 @@ using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using UnityEngine; +[Obsolete] public static class WebViewUtils { - public const string WebViewScriptsFolderName = "WebViewScripts"; - - [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] - private static void StaticInit() - { - ClearCache(); - } - private static bool hasScannedJavaScriptFiles; - private static readonly Dictionary hostToWebViewScript = new(); - private static readonly Dictionary hostToCachedWebViewScript = new(); - private static readonly Dictionary urlToCachedWebViewScript = new(); - - public static List AdditionalWebViewScriptsFolders { get; set; } = new(); - - public static bool CanHandleWebViewUrl(string url) - { - try - { - // Try to parse the URL to make sure it's valid. - string host = new Uri(url).Host; - } - catch (Exception e) - { - return false; - } - - if (!hasScannedJavaScriptFiles) - { - ScanJavaScriptFiles(); - } - - string webViewScript = GetWebViewScript(url); - return !webViewScript.IsNullOrEmpty(); - } - - public static string GetWebViewScript(string url) - { - // Try get cached template for the specific URL. - if (urlToCachedWebViewScript.TryGetValue(url, out CachedWebViewScript cachedWebViewScript)) - { - return cachedWebViewScript.Content; - } - - // Try get cached template for the host. - string urlHost = new Uri(url).Host; - if (!hostToCachedWebViewScript.TryGetValue(urlHost, out cachedWebViewScript)) - { - // Load and remember the template for the host. - cachedWebViewScript = LoadAndCacheWebViewScriptForHost(urlHost); - } - - if (cachedWebViewScript == null) - { - return ""; - } - - // Remember the template for the specific URL. - urlToCachedWebViewScript[url] = cachedWebViewScript; - - return cachedWebViewScript.Content; - } - - public static void ClearCache() - { - hostToWebViewScript.Clear(); - hostToCachedWebViewScript.Clear(); - urlToCachedWebViewScript.Clear(); - hasScannedJavaScriptFiles = false; - } - - private static CachedWebViewScript LoadAndCacheWebViewScriptForHost(string urlHost) - { - List> matches = hostToWebViewScript - .Where(entry => HostsMatch(entry.Key, urlHost)) - .ToList(); - if (matches.IsNullOrEmpty()) - { - return null; - } - - string filePath = matches.FirstOrDefault().Value; - string fileContent = File.ReadAllText(filePath); - - Debug.Log($"Found WebView script for host '{urlHost}' in file '{filePath}'"); - - CachedWebViewScript cachedWebViewScript = new(fileContent); - hostToCachedWebViewScript[urlHost] = cachedWebViewScript; - return cachedWebViewScript; - } - - private static bool HostsMatch(string a, string b) - { - string aWithoutWww = a.Replace("www.", ""); - string bWithoutWww = b.Replace("www.", ""); - return aWithoutWww.ToLowerInvariant() == bWithoutWww.ToLowerInvariant(); - } - - private static void ScanJavaScriptFiles() - { - if (hasScannedJavaScriptFiles) - { - return; - } - hasScannedJavaScriptFiles = true; - - List webViewScriptsFolders = GetWebViewScriptsFolders(); - - foreach (string scriptsFolder in webViewScriptsFolders) - { - if (!DirectoryUtils.Exists(scriptsFolder)) - { - continue; - } - Debug.Log($"Loading WebView scripts from folder '{scriptsFolder}'"); - string[] webViewScriptPaths = Directory.GetFiles(scriptsFolder, "*.js"); - Debug.Log($"Found {webViewScriptPaths.Length} WebView scripts in folder '{scriptsFolder}'"); - foreach (string webViewScriptPath in webViewScriptPaths) - { - string host = Path.GetFileNameWithoutExtension(webViewScriptPath); - hostToWebViewScript[host] = webViewScriptPath; - } - } - } - - public static List GetWebViewScriptsFolders() - { - return new List() - { - GetDefaultWebViewScriptsAbsolutePath(), - GetUserDefinedWebViewScriptsAbsolutePath(), - } - .Union(AdditionalWebViewScriptsFolders) - .ToList(); - } - - public static string GetDefaultWebViewScriptsAbsolutePath() - { - return ApplicationUtils.GetStreamingAssetsPath(WebViewScriptsFolderName); - } - - public static string GetUserDefinedWebViewScriptsAbsolutePath() - { - return ApplicationUtils.GetPersistentDataPath(WebViewScriptsFolderName); - } - - private class CachedWebViewScript - { - public string Content { get; private set; } - - public CachedWebViewScript(string content) - { - this.Content = content; - } - } + public static bool CanHandleWebViewUrl(string url) => false; } diff --git a/UltraStar Play/Assets/Common/Video/SongVideoPlayer/SongVideoPlayer.cs b/UltraStar Play/Assets/Common/Video/SongVideoPlayer/SongVideoPlayer.cs index bc8b87ee2..571586b37 100644 --- a/UltraStar Play/Assets/Common/Video/SongVideoPlayer/SongVideoPlayer.cs +++ b/UltraStar Play/Assets/Common/Video/SongVideoPlayer/SongVideoPlayer.cs @@ -34,9 +34,6 @@ static void StaticInit() private IVideoSupportProvider currentVideoSupportProvider; public IVideoSupportProvider CurrentVideoSupportProvider => currentVideoSupportProvider; - [Inject] - private WebViewManager webViewManager; - [Inject(UxmlName = R.UxmlNames.songVideoImage, Optional = true)] private VisualElement videoImageVisualElement; public VisualElement VideoImageVisualElement diff --git a/UltraStar Play/Assets/Common/Video/SongVideoPlayer/WebViewVideoSupportProvider.cs b/UltraStar Play/Assets/Common/Video/SongVideoPlayer/WebViewVideoSupportProvider.cs deleted file mode 100644 index c792b5b5d..000000000 --- a/UltraStar Play/Assets/Common/Video/SongVideoPlayer/WebViewVideoSupportProvider.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using UniInject; -using UniRx; -using UnityEngine; - -public class WebViewVideoSupportProvider : AbstractVideoSupportProvider -{ - [Inject] - private WebViewManager webViewManager; - - public override bool IsSupported(string videoUri, bool videoEqualsAudio) - { - return WebViewUtils.CanHandleWebViewUrl(videoUri); - } - - public override IObservable LoadAsObservable(string videoUri, double startPositionInMillis) - { - return Observable.Create(o => - { - StartCoroutine(CoroutineUtils.ExecuteWhenConditionIsTrue( - () => webViewManager.DurationInMillis > 0, - () => o.OnNext(new VideoLoadedEvent(videoUri)))); - return Disposable.Empty; - }); - } - - public override void Unload() - { - ResetWebViewRenderTexture(); - } - - public override void Play() - { - webViewManager.ResumePlayback(); - } - - public override void Pause() - { - webViewManager.PausePlayback(); - } - - public override void Stop() - { - webViewManager.StopPlayback(); - } - - public override bool IsPlaying - { - get => webViewManager.IsPlaying; - set - { - if (value) - { - webViewManager.ResumePlayback(); - } - else - { - webViewManager.PausePlayback(); - } - } - } - - public override bool IsLooping - { - get => false; - set { /* Not available */ } - } - - public override double PlaybackSpeed - { - get => 1; - set { /* Not available */ } - } - - public override double PositionInMillis - { - get => webViewManager.EstimatedPositionInMillis; - set => webViewManager.SetPositionInMillis(value); - } - - public override double DurationInMillis => webViewManager.DurationInMillis; - - public override void SetTargetTexture(RenderTexture renderTexture) - { - if (renderTexture != null) - { - SetWebViewRenderTextureToVideoRenderTexture(renderTexture); - } - else - { - ResetWebViewRenderTexture(); - } - } - - private void ResetWebViewRenderTexture() - { - webViewManager.ResetWebViewRenderTexture(); - } - - private void SetWebViewRenderTextureToVideoRenderTexture(RenderTexture renderTexture) - { - webViewManager.SetWebViewRenderTexture(renderTexture); - } -} diff --git a/UltraStar Play/Assets/Common/Video/SongVideoPlayer/WebViewVideoSupportProvider.cs.meta b/UltraStar Play/Assets/Common/Video/SongVideoPlayer/WebViewVideoSupportProvider.cs.meta deleted file mode 100644 index badcbd9f8..000000000 --- a/UltraStar Play/Assets/Common/Video/SongVideoPlayer/WebViewVideoSupportProvider.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2dc8272cf72d4efbb5aa41ff176fa2ad -timeCreated: 1715451934 \ No newline at end of file diff --git a/UltraStar Play/Assets/Common/WebView.meta b/UltraStar Play/Assets/Common/WebView.meta deleted file mode 100644 index 532b47ed1..000000000 --- a/UltraStar Play/Assets/Common/WebView.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ee4addedbf9530246b075874ed9f4e79 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/Common/WebView/BoolWebViewMessageDto.cs b/UltraStar Play/Assets/Common/WebView/BoolWebViewMessageDto.cs deleted file mode 100644 index aa622b9e3..000000000 --- a/UltraStar Play/Assets/Common/WebView/BoolWebViewMessageDto.cs +++ /dev/null @@ -1,4 +0,0 @@ -public class BoolWebViewMessageDto : WebViewMessageDto -{ - public bool value; -} diff --git a/UltraStar Play/Assets/Common/WebView/BoolWebViewMessageDto.cs.meta b/UltraStar Play/Assets/Common/WebView/BoolWebViewMessageDto.cs.meta deleted file mode 100644 index 2e8a59b4e..000000000 --- a/UltraStar Play/Assets/Common/WebView/BoolWebViewMessageDto.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: bec76f44286849a990e126149a967d4b -timeCreated: 1686425992 \ No newline at end of file diff --git a/UltraStar Play/Assets/Common/WebView/CanvasWebViewPrefab Variant.prefab b/UltraStar Play/Assets/Common/WebView/CanvasWebViewPrefab Variant.prefab deleted file mode 100644 index a71711ecb..000000000 --- a/UltraStar Play/Assets/Common/WebView/CanvasWebViewPrefab Variant.prefab +++ /dev/null @@ -1,166 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!1001 &3194267725575021595 -PrefabInstance: - m_ObjectHideFlags: 0 - serializedVersion: 2 - m_Modification: - serializedVersion: 3 - m_TransformParent: {fileID: 0} - m_Modifications: - - target: {fileID: 1255051872871948, guid: 3e10f3b6a733e441c8352020cff2f1f6, type: 3} - propertyPath: m_Layer - value: 9 - objectReference: {fileID: 0} - - target: {fileID: 1535822479614194, guid: 3e10f3b6a733e441c8352020cff2f1f6, type: 3} - propertyPath: m_Name - value: CanvasWebViewPrefab Variant - objectReference: {fileID: 0} - - target: {fileID: 1535822479614194, guid: 3e10f3b6a733e441c8352020cff2f1f6, type: 3} - propertyPath: m_Layer - value: 9 - objectReference: {fileID: 0} - - target: {fileID: 1589489459947714, guid: 3e10f3b6a733e441c8352020cff2f1f6, type: 3} - propertyPath: m_Layer - value: 9 - objectReference: {fileID: 0} - - target: {fileID: 114949863196309792, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: DragMode - value: 2 - objectReference: {fileID: 0} - - target: {fileID: 114949863196309792, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: ClickingEnabled - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 114949863196309792, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: HoveringEnabled - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 114949863196309792, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: KeyboardEnabled - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 114949863196309792, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: ScrollingEnabled - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 114949863196309792, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: LogConsoleMessages - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_Pivot.x - value: 0.5 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_Pivot.y - value: 0.5 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_RootOrder - value: -1 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_AnchorMax.x - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_AnchorMax.y - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_AnchorMin.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_AnchorMin.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_SizeDelta.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_SizeDelta.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_LocalPosition.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_LocalPosition.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_LocalPosition.z - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_LocalRotation.w - value: 1 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_LocalRotation.x - value: -0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_LocalRotation.y - value: -0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_LocalRotation.z - value: -0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_AnchoredPosition.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_AnchoredPosition.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_LocalEulerAnglesHint.x - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_LocalEulerAnglesHint.y - value: 0 - objectReference: {fileID: 0} - - target: {fileID: 224179541092979990, guid: 3e10f3b6a733e441c8352020cff2f1f6, - type: 3} - propertyPath: m_LocalEulerAnglesHint.z - value: 0 - objectReference: {fileID: 0} - m_RemovedComponents: [] - m_RemovedGameObjects: [] - m_AddedGameObjects: [] - m_AddedComponents: [] - m_SourcePrefab: {fileID: 100100000, guid: 3e10f3b6a733e441c8352020cff2f1f6, type: 3} diff --git a/UltraStar Play/Assets/Common/WebView/CanvasWebViewPrefab Variant.prefab.meta b/UltraStar Play/Assets/Common/WebView/CanvasWebViewPrefab Variant.prefab.meta deleted file mode 100644 index 190d8be19..000000000 --- a/UltraStar Play/Assets/Common/WebView/CanvasWebViewPrefab Variant.prefab.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: b8149ed42d0df794b8c7b96c0ca10689 -PrefabImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/Common/WebView/DefaultWebViewPage.html b/UltraStar Play/Assets/Common/WebView/DefaultWebViewPage.html deleted file mode 100644 index 62c32792c..000000000 --- a/UltraStar Play/Assets/Common/WebView/DefaultWebViewPage.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - Default WebView Page - - - - -

Embedded Browser Window

-
-

You can show / hide this window with F8 or Ctrl+B.

-

-

The embedded browser can be used to integrate external websites in the game.

-

For more information visit https://melodymania.org/how-to-embedded-browser

-
- - - \ No newline at end of file diff --git a/UltraStar Play/Assets/Common/WebView/DefaultWebViewPage.html.meta b/UltraStar Play/Assets/Common/WebView/DefaultWebViewPage.html.meta deleted file mode 100644 index 6eba58a65..000000000 --- a/UltraStar Play/Assets/Common/WebView/DefaultWebViewPage.html.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: e3afca435ff14476bad0b2ad71017bc3 -timeCreated: 1686427035 \ No newline at end of file diff --git a/UltraStar Play/Assets/Common/WebView/NumberWebViewMessageDto.cs b/UltraStar Play/Assets/Common/WebView/NumberWebViewMessageDto.cs deleted file mode 100644 index 5cbc9d59e..000000000 --- a/UltraStar Play/Assets/Common/WebView/NumberWebViewMessageDto.cs +++ /dev/null @@ -1,4 +0,0 @@ -public class NumberWebViewMessageDto : WebViewMessageDto -{ - public double value; -} diff --git a/UltraStar Play/Assets/Common/WebView/NumberWebViewMessageDto.cs.meta b/UltraStar Play/Assets/Common/WebView/NumberWebViewMessageDto.cs.meta deleted file mode 100644 index aaef1d868..000000000 --- a/UltraStar Play/Assets/Common/WebView/NumberWebViewMessageDto.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 62b85d714d36467986bfa14159078228 -timeCreated: 1686397183 \ No newline at end of file diff --git a/UltraStar Play/Assets/Common/WebView/WebViewManager.cs b/UltraStar Play/Assets/Common/WebView/WebViewManager.cs deleted file mode 100644 index f24ec09e6..000000000 --- a/UltraStar Play/Assets/Common/WebView/WebViewManager.cs +++ /dev/null @@ -1,665 +0,0 @@ -using System; -using PrimeInputActions; -using UniInject; -using UniRx; -using UnityEngine; -using UnityEngine.UIElements; -using Vuplex.WebView; - -public class WebViewManager : AbstractSingletonBehaviour, INeedInjection -{ - public static WebViewManager Instance => DontDestroyOnLoadManager.Instance.FindComponentOrThrow(); - - private static bool isWebConfigInitialized; - - [InjectedInInspector] - public CanvasWebViewPrefab webViewPrefabPrefab; - - [InjectedInInspector] - public Canvas webViewCanvas; - - [InjectedInInspector] - public Camera webViewCamera; - - [InjectedInInspector] - public TextAsset defaultWebViewHtml; - - [InjectedInInspector] - public RenderTexture defaultRenderTexture; - - [Inject] - private UIDocument uiDocument; - - [Inject] - private SceneNavigator sceneNavigator; - - [Inject] - private UiManager uiManager; - - [Inject] - private Settings settings; - - private IWebView webView; - public IWebView WebView => webView; // Public getter to allow modding - - private bool IsWebViewInitialized => webView != null; - private readonly Subject webViewInitializedEventStream = new(); - - private bool isPlaying; - public bool IsPlaying - { - get - { - if (!IsWebViewInitialized) - { - return false; - } - return isPlaying; - } - } - - private double durationInMillis; - public double DurationInMillis - { - get - { - if (!IsWebViewInitialized - || !isContentLoaded) - { - return 0; - } - return durationInMillis; - } - } - - - private long receivedPositionUpdatedTimeInMillis; - private double receivedPositionInMillis; - - private int estimatedPositionUpdatedFrameCount; - private long estimatedPositionUpdatedTimeInMillis; - private double estimatedPositionInMillis; - public double EstimatedPositionInMillis - { - get - { - if (!IsWebViewInitialized) - { - return 0; - } - - return estimatedPositionInMillis; - } - } - - public int volumeInPercent; - public int VolumeInPercent - { - get - { - if (!IsWebViewInitialized) - { - return 0; - } - return volumeInPercent; - } - set - { - volumeInPercent = value; - - if (!IsWebViewInitialized) - { - return; - } - - // The embedded browser does not consider AudioListener.volume. Thus, this must be considered here explicitly. - float jsVolume = AudioListener.volume * NumberUtils.PercentToFactor(volumeInPercent) * 100; - webView.ExecuteJavaScript($"setVolume({jsVolume})"); - } - } - - public bool isContentLoaded; - public bool IsContentLoaded - { - get - { - if (!IsWebViewInitialized) - { - return false; - } - return isContentLoaded; - } - } - - private string loadedUrl; - public string LoadedUrl => loadedUrl; // Public getter to allow modding - - private bool javaScriptCanLoadUrl; - - public bool IsWebViewCanvasControlEnabled => webViewCanvas.renderMode is RenderMode.ScreenSpaceOverlay; - - private CanvasWebViewPrefab webViewPrefabInstance; - - private bool hasShownControlsNotification; - - protected override object GetInstance() - { - return Instance; - } - - protected override void AwakeSingleton() - { - // Disable camera until WebView texture requested - webViewCamera.gameObject.SetActive(false); - } - - protected override void StartSingleton() - { - DirectoryUtils.CreateDirectory(WebViewUtils.GetDefaultWebViewScriptsAbsolutePath()); - - sceneNavigator.BeforeSceneChangeEventStream.Subscribe(_ => OnBeforeSceneChanged()); - sceneNavigator.SceneChangedEventStream.Subscribe(_ => OnSceneChanged()); - settings.ObserveEveryValueChanged(it => it.VolumePercent) - .Subscribe(_ => UpdateVolume()) - .AddTo(gameObject); - RegisterInputActions(); - - if (settings.EnableWebView) - { - InitializeWebViewConfig(); - InstantiateWebViewPrefab(); - } - } - - protected override void OnDestroySingleton() - { - base.OnDestroySingleton(); - if (webViewPrefabInstance != null) - { - webViewPrefabInstance.Initialized -= OnWebViewPrefabInstanceInitialized; - } - WebViewUtils.ClearCache(); - } - - private void InitializeWebViewConfig() - { - // Cannot change certain configuration after Chromium has been started - if (isWebConfigInitialized) - { - return; - } - isWebConfigInitialized = true; - - try - { - // By default browsers block web pages from autoplaying video or audio. - // Explicitly allow playback of video or audio without user interaction. - // This must be called early, e.g. in Awake. - Web.SetAutoplayEnabled(true); - - // Google only allows sign-in from selected browser. - // Thus, set the User-Agent header to a browser that is allowed by Google. - if (!settings.CustomUserAgent.IsNullOrEmpty()) - { - Web.SetUserAgent(settings.CustomUserAgent); - } - } - catch (Exception e) - { - Debug.LogException(e); - Debug.LogError($"Failed to instantiate WebView config: {e.Message}"); - } - } - - private void InstantiateWebViewPrefab() - { - if (webViewPrefabInstance != null) - { - Debug.LogWarning("Cannot instantiate WebView. WebView already instantiated."); - return; - } - - foreach (Transform child in webViewCanvas.transform) - { - Destroy(child.gameObject); - } - webViewPrefabInstance = Instantiate(webViewPrefabPrefab, webViewCanvas.transform); - webViewPrefabInstance.Initialized += OnWebViewPrefabInstanceInitialized; - } - - private void OnBeforeSceneChanged() - { - PausePlayback(); - } - - private void OnSceneChanged() - { - RegisterInputActions(); - } - - private void RegisterInputActions() - { - InputManager.GetInputAction(R.InputActions.usplay_toggleWebViewControl).PerformedAsObservable() - .Subscribe(_ => ToggleWebViewControl()) - .AddTo(gameObject); - - InputManager.GetInputAction(R.InputActions.usplay_back).PerformedAsObservable(200) - .Subscribe(_ => - { - if (IsWebViewCanvasControlEnabled) - { - ToggleWebViewControl(); - InputManager.GetInputAction(R.InputActions.usplay_back).CancelNotifyForThisFrame(); - } - }); - } - - private void ToggleWebViewControl() - { - if (IsWebViewCanvasControlEnabled) - { - webViewCanvas.renderMode = RenderMode.ScreenSpaceCamera; - SetWebViewInputEnabled(false); - SetUiToolkitInputEnabled(true); - } - else - { - webViewCanvas.renderMode = RenderMode.ScreenSpaceOverlay; - SetWebViewInputEnabled(true); - SetUiToolkitInputEnabled(false); - } - UpdateWebViewCameraActive(); - } - - private void SetWebViewInputEnabled(bool newValue) - { - if (webViewPrefabInstance == null) - { - return; - } - webViewPrefabInstance.HoveringEnabled = newValue; - webViewPrefabInstance.ClickingEnabled = newValue; - webViewPrefabInstance.ScrollingEnabled = newValue; - webViewPrefabInstance.KeyboardEnabled = newValue; - webViewPrefabInstance.CursorIconsEnabled = newValue; - } - - private void SetUiToolkitInputEnabled(bool newValue) - { - uiDocument.rootVisualElement.SetVisibleByDisplay(newValue); - } - - private void Update() - { - if (!IsWebViewInitialized) - { - return; - } - - UpdatePositionInMillisEstimate(); - SendPositionInMillisIfNeeded(); - } - - private void SendPositionInMillisIfNeeded() - { - long currentTimeInMillis = TimeUtils.GetUnixTimeMilliseconds(); - long timeInMillisSinceLastUpdate = currentTimeInMillis - receivedPositionUpdatedTimeInMillis; - if (timeInMillisSinceLastUpdate > 100) - { - webView.ExecuteJavaScript("sendPlaybackPositionInMillis()"); - } - } - - private void UpdatePositionInMillisEstimate() - { - if (!isPlaying - || !isContentLoaded - || estimatedPositionUpdatedFrameCount == Time.frameCount - || receivedPositionInMillis <= 0) - { - return; - } - - long currentTimeInMillis = TimeUtils.GetUnixTimeMilliseconds(); - long deltaTimeInMillis = currentTimeInMillis - estimatedPositionUpdatedTimeInMillis; - estimatedPositionInMillis += (int)deltaTimeInMillis; - estimatedPositionUpdatedTimeInMillis = currentTimeInMillis; - estimatedPositionUpdatedFrameCount = Time.frameCount; - } - - private void OnWebViewPrefabInstanceInitialized(object sender, EventArgs e) - { - webView = webViewPrefabInstance.WebView; - webViewPrefabInstance.WebView.MessageEmitted += OnWebViewMessageReceived; - webView.LoadProgressChanged += OnWebViewLoadProgressChanged; - - webView.LoadHtml(defaultWebViewHtml.text); - - webViewInitializedEventStream.OnNext(VoidEvent.instance); - } - - private void OnWebViewLoadProgressChanged(object sender, ProgressChangedEventArgs e) - { - if (e.Type is ProgressChangeType.Finished) - { - OnWebViewFinishedLoading(); - } - else if (e.Type is ProgressChangeType.Failed) - { - OnWebViewFailedLoading(); - } - } - - private void OnWebViewFinishedLoading() - { - Debug.Log("Finished loading of URL: " + loadedUrl); - isContentLoaded = true; - UpdateVolume(); - } - - private void UpdateVolume() - { - VolumeInPercent = VolumeInPercent; - } - - private void OnWebViewFailedLoading() - { - Debug.Log("Failed loading of URL: " + loadedUrl); - NotificationManager.CreateNotification(Translation.Get(R.Messages.common_error_failedToLoadWithName, - "name", loadedUrl)); - } - - private void OnWebViewMessageReceived(object sender, EventArgs e) - { - Log.Verbose(() => $"Received message from WebView: {e.Value}"); - string json = e.Value.Trim(); - if (!json.StartsWith("{") - || !json.EndsWith("}")) - { - return; - } - HandleWebViewMessage(json); - } - - private void HandleWebViewMessage(string json) - { - try - { - WebViewMessageDto webViewMessageDto = JsonConverter.FromJson(json); - if (webViewMessageDto == null) - { - Debug.LogError($"Failed to parse WebViewMessageDto: {json}"); - } - - if (WebViewMessageDto.TryParseType(webViewMessageDto.type, out WebViewMessageType webViewMessageType)) - { - switch (webViewMessageType) - { - case WebViewMessageType.PlaybackPositionInMillis: - { - NumberWebViewMessageDto numberWebViewMessageDto = JsonConverter.FromJson(json); - - long currentTimeInMillis = TimeUtils.GetUnixTimeMilliseconds(); - - // Log how far away from the actual time the estimate has become. - // double oldEstimatedPlaybackPositionInMillis = EstimatedPositionInMillis; - // double oldEstimatedPlaybackPositionInMillisOffset = numberWebViewMessageDto.value - - // oldEstimatedPlaybackPositionInMillis; - // Log.Verbose(() => $"Received new playback position. Old estimate offset: {oldEstimatedPlaybackPositionInMillisOffset}"); - - receivedPositionUpdatedTimeInMillis = currentTimeInMillis; - receivedPositionInMillis = numberWebViewMessageDto.value; - - estimatedPositionUpdatedFrameCount = Time.frameCount; - estimatedPositionUpdatedTimeInMillis = currentTimeInMillis; - estimatedPositionInMillis = receivedPositionInMillis; - break; - } - case WebViewMessageType.DurationInMillis: - { - NumberWebViewMessageDto numberWebViewMessageDto = JsonConverter.FromJson(json); - durationInMillis = numberWebViewMessageDto.value; - break; - } - case WebViewMessageType.Ready: - { - isContentLoaded = true; - break; - } - case WebViewMessageType.StartedOrResumed: - { - isPlaying = true; - break; - } - case WebViewMessageType.StoppedOrPaused: - { - isPlaying = false; - break; - } - case WebViewMessageType.CanLoadUrl: - { - BoolWebViewMessageDto boolWebViewMessageDto = JsonConverter.FromJson(json); - javaScriptCanLoadUrl = boolWebViewMessageDto.value; - break; - } - case WebViewMessageType.Volume: - { - NumberWebViewMessageDto numberWebViewMessageDto = JsonConverter.FromJson(json); - volumeInPercent = (int)numberWebViewMessageDto.value; - break; - } - } - } - } - catch (Exception e) - { - Debug.LogException(e); - Debug.LogError("Failed to parse WebViewMessageDto: " + json); - } - } - - public bool LoadUrl(string url) - { - if (settings == null - || !settings.EnableWebView) - { - Debug.LogWarning($"WebView cannot load URL because WebView is disabled in settings."); - return false; - } - - if (!WebViewUtils.CanHandleWebViewUrl(url)) - { - Debug.LogWarning($"Cannot handle URL: {url}"); - return false; - } - - string host = new Uri(url).Host; - string hostWithoutWww = host.TrimStart("www."); - string hostWithWww = $"www.{hostWithoutWww}"; - if (settings.AcceptedWebViewHosts.Contains(hostWithoutWww) - || settings.AcceptedWebViewHosts.Contains(hostWithWww)) - { - return DoLoadUrl(url); - } - Debug.LogWarning($"Asking to accept host before loading URI into WebView. host: '{host}', uri: '{url}'"); - - MessageDialogControl messageDialogControl = uiManager.CreateDialogControl(Translation.Get(R.Messages.webView_askToOpenWebsiteDialog_title)); - messageDialogControl.Message = Translation.Get(R.Messages.webView_askToOpenWebsiteDialog_message, - "host", host); - - messageDialogControl.AddInformationMessage($"You can open the embedded browser anytime by pressing F8 or Ctrl+B."); - - messageDialogControl.AddButton(Translation.Get(R.Messages.webView_askToOpenWebsiteDialog_confirm), _ => - { - messageDialogControl.CloseDialog(); - settings.AcceptedWebViewHosts.Add(host); - DoLoadUrl(url); - }); - messageDialogControl.AddButton(Translation.Get(R.Messages.action_cancel), - _ => messageDialogControl.CloseDialog()); - - return false; - } - - private bool DoLoadUrl(string url) - { - string webViewScript = WebViewUtils.GetWebViewScript(url); - if (webViewScript.IsNullOrEmpty()) - { - Debug.LogError($"Failed to load WebView script code for url: {url}"); - return false; - } - - if (isPlaying) - { - PausePlayback(); - } - - if (loadedUrl == url) - { - // Already loaded. - Debug.Log($"Reusing already loaded web page for URL {url}"); - SetPositionInMillis(0); - return true; - } - - bool isLoadingUrlOfSameHost; - try - { - isLoadingUrlOfSameHost = string.Equals(new Uri(loadedUrl).Host, new Uri(webView.Url).Host, StringComparison.InvariantCultureIgnoreCase); - } - catch - { - isLoadingUrlOfSameHost = false; - } - - if (!javaScriptCanLoadUrl) - { - isContentLoaded = false; - } - - loadedUrl = url; - RunWhenWebViewInitialized(() => - { - if (!hasShownControlsNotification) - { - hasShownControlsNotification = true; - NotificationManager.CreateNotification(Translation.Get(R.Messages.webView_info_controls)); - } - - if (isContentLoaded && isLoadingUrlOfSameHost && javaScriptCanLoadUrl) - { - Debug.Log("Loading new URL via JavaScript"); - webView.ExecuteJavaScript($"setVolume(0)"); - webView.ExecuteJavaScript($"loadUrl('{url}')"); - } - else - { - Debug.Log("Loading new URL into WebView"); - webView.PageLoadScripts.Clear(); - webView.PageLoadScripts.Add(webViewScript); - webView.LoadUrl(url); - } - }); - return true; - } - - private void UpdateWebViewCameraActive() - { - // Only render the WebView with the camera when it is visible to the user. - webViewCamera.gameObject.SetActive( - webViewCamera.targetTexture != null - || IsWebViewCanvasControlEnabled); - if (!webViewCamera.gameObject.activeSelf) - { - RenderTextureUtils.Clear(webViewCamera.targetTexture); - } - } - - public void ResumePlayback() - { - if (!IsWebViewInitialized) - { - return; - } - - isPlaying = true; - webView.ExecuteJavaScript("resumePlayback()"); - UpdateVolume(); - } - - public void SetPositionInMillis(double value) - { - if (!IsWebViewInitialized) - { - return; - } - webView.ExecuteJavaScript($"setPlaybackPositionInMillis({value})"); - receivedPositionInMillis = value; - estimatedPositionInMillis = value; - estimatedPositionUpdatedTimeInMillis = TimeUtils.GetUnixTimeMilliseconds(); - estimatedPositionUpdatedFrameCount = Time.frameCount; - } - - public void PausePlayback() - { - if (!IsWebViewInitialized) - { - return; - } - - isPlaying = false; - webView.ExecuteJavaScript("pausePlayback()"); - webView.ExecuteJavaScript("setVolume(0)"); - } - - public void StopPlayback() - { - if (!IsWebViewInitialized) - { - return; - } - - isPlaying = false; - webView.ExecuteJavaScript("stopPlayback()"); - } - - private void RunWhenWebViewInitialized(Action action) - { - if (IsWebViewInitialized) - { - action?.Invoke(); - } - else - { - IDisposable iDisposable = null; - iDisposable = webViewInitializedEventStream.Subscribe(_ => - { - action?.Invoke(); - iDisposable?.Dispose(); - }); - } - } - - public void ReloadScripts() - { - WebViewUtils.ClearCache(); - loadedUrl = null; - javaScriptCanLoadUrl = false; - Debug.Log("Reloaded WebView scripts by clearing cache."); - } - - public void SetWebViewRenderTexture(RenderTexture targetTexture) - { - if (webViewCamera.targetTexture != targetTexture) - { - webViewCamera.targetTexture = targetTexture; - UpdateWebViewCameraActive(); - } - } - - public void ResetWebViewRenderTexture() - { - SetWebViewRenderTexture(defaultRenderTexture); - } -} diff --git a/UltraStar Play/Assets/Common/WebView/WebViewManager.cs.meta b/UltraStar Play/Assets/Common/WebView/WebViewManager.cs.meta deleted file mode 100644 index a6207e979..000000000 --- a/UltraStar Play/Assets/Common/WebView/WebViewManager.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c01bf111bd65446ab45a978e7a390215 -timeCreated: 1686387913 \ No newline at end of file diff --git a/UltraStar Play/Assets/Common/WebView/WebViewMessageDto.cs b/UltraStar Play/Assets/Common/WebView/WebViewMessageDto.cs deleted file mode 100644 index d148eb8a3..000000000 --- a/UltraStar Play/Assets/Common/WebView/WebViewMessageDto.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; - -public class WebViewMessageDto -{ - public string type; - - public static bool TryParseType(string type, out WebViewMessageType webViewMessageType) - { - if (type.IsNullOrEmpty()) - { - webViewMessageType = WebViewMessageType.Unknown; - return false; - } - - foreach (WebViewMessageType typeEnum in EnumUtils.GetValuesAsList()) - { - if (string.Equals(type, typeEnum.ToString(), StringComparison.InvariantCultureIgnoreCase)) - { - webViewMessageType = typeEnum; - return true; - } - } - - webViewMessageType = WebViewMessageType.Unknown; - return false; - } -} diff --git a/UltraStar Play/Assets/Common/WebView/WebViewMessageDto.cs.meta b/UltraStar Play/Assets/Common/WebView/WebViewMessageDto.cs.meta deleted file mode 100644 index 9c198f968..000000000 --- a/UltraStar Play/Assets/Common/WebView/WebViewMessageDto.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 4c20765ae51a4b55815f84651c75812b -timeCreated: 1686390802 \ No newline at end of file diff --git a/UltraStar Play/Assets/Common/WebView/WebViewMessageType.cs b/UltraStar Play/Assets/Common/WebView/WebViewMessageType.cs deleted file mode 100644 index fb5b19b68..000000000 --- a/UltraStar Play/Assets/Common/WebView/WebViewMessageType.cs +++ /dev/null @@ -1,11 +0,0 @@ -public enum WebViewMessageType -{ - Unknown, - Ready, - StartedOrResumed, - StoppedOrPaused, - PlaybackPositionInMillis, - DurationInMillis, - Volume, - CanLoadUrl, -} diff --git a/UltraStar Play/Assets/Common/WebView/WebViewMessageType.cs.meta b/UltraStar Play/Assets/Common/WebView/WebViewMessageType.cs.meta deleted file mode 100644 index 438e3f90e..000000000 --- a/UltraStar Play/Assets/Common/WebView/WebViewMessageType.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 94d6cabf455a48d78cf3a11973a117e8 -timeCreated: 1686390817 \ No newline at end of file diff --git a/UltraStar Play/Assets/Common/WebView/WebViewRenderTexture.renderTexture b/UltraStar Play/Assets/Common/WebView/WebViewRenderTexture.renderTexture deleted file mode 100644 index f7b22b4a9..000000000 --- a/UltraStar Play/Assets/Common/WebView/WebViewRenderTexture.renderTexture +++ /dev/null @@ -1,39 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!84 &8400000 -RenderTexture: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: WebViewRenderTexture - m_ImageContentsHash: - serializedVersion: 2 - Hash: 00000000000000000000000000000000 - m_IsAlphaChannelOptional: 0 - serializedVersion: 6 - m_Width: 1920 - m_Height: 1080 - m_AntiAliasing: 1 - m_MipCount: -1 - m_DepthStencilFormat: 94 - m_ColorFormat: 8 - m_MipMap: 0 - m_GenerateMips: 1 - m_SRGB: 0 - m_UseDynamicScale: 0 - m_UseDynamicScaleExplicit: 0 - m_BindMS: 0 - m_EnableCompatibleFormat: 1 - m_EnableRandomWrite: 0 - m_TextureSettings: - serializedVersion: 2 - m_FilterMode: 1 - m_Aniso: 0 - m_MipBias: 0 - m_WrapU: 1 - m_WrapV: 1 - m_WrapW: 1 - m_Dimension: 2 - m_VolumeDepth: 1 - m_ShadowSamplingMode: 2 diff --git a/UltraStar Play/Assets/Common/WebView/WebViewRenderTexture.renderTexture.meta b/UltraStar Play/Assets/Common/WebView/WebViewRenderTexture.renderTexture.meta deleted file mode 100644 index 1704a6db8..000000000 --- a/UltraStar Play/Assets/Common/WebView/WebViewRenderTexture.renderTexture.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b7abf32de3eac1648b13bbe27ad196a8 -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 8400000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/Common/WebView/WebViewScriptFileSystemWatcher.cs b/UltraStar Play/Assets/Common/WebView/WebViewScriptFileSystemWatcher.cs deleted file mode 100644 index e18c66dda..000000000 --- a/UltraStar Play/Assets/Common/WebView/WebViewScriptFileSystemWatcher.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using UniInject; -using UniRx; -using UnityEngine; - -// Disable warning about fields that are never assigned, their values are injected. -#pragma warning disable CS0649 - -public class WebViewScriptFileSystemWatcher : AbstractSingletonBehaviour, INeedInjection -{ - public WebViewScriptFileSystemWatcher Instance => DontDestroyOnLoadManager.Instance.FindComponentOrThrow(); - - [Inject] - private WebViewManager webViewManager; - - private readonly List disposables = new(); - - protected override object GetInstance() - { - return Instance; - } - -#if UNITY_STANDALONE - protected override void StartSingleton() - { - foreach (string folder in WebViewUtils.GetWebViewScriptsFolders()) - { - if (!DirectoryUtils.Exists(folder)) - { - continue; - } - Debug.Log($"Watching WebView script files in {folder}"); - disposables.Add(FileSystemWatcherUtils.CreateFileSystemWatcher( - folder, - "*.js", - OnWebViewScriptChanged)); - } - } - - private void OnWebViewScriptChanged(object sender, FileSystemEventArgs e) - { - Debug.Log($"WebView script file changed: {e.FullPath}"); - MainThreadDispatcher.Send(_ => webViewManager.ReloadScripts(), null); - } -#endif - - private void OnDestroy() - { - disposables.ForEach(it => it.Dispose()); - } -} diff --git a/UltraStar Play/Assets/Common/WebView/WebViewScriptFileSystemWatcher.cs.meta b/UltraStar Play/Assets/Common/WebView/WebViewScriptFileSystemWatcher.cs.meta deleted file mode 100644 index 0ee434e74..000000000 --- a/UltraStar Play/Assets/Common/WebView/WebViewScriptFileSystemWatcher.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f7dc3fe703c34dee838e8f0682097d70 -timeCreated: 1686472963 \ No newline at end of file diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTest.cs b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTest.cs deleted file mode 100644 index 5de0c80d2..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTest.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using NUnit.Framework; -using UnityEngine.TestTools; - -[Ignore("No Vuplex.WebView present in the project")] -public class WebViewTest : AbstractMediaFileFormatTest -{ - private const long WebViewMaxWaitTimeInMillis = 30000; - private const double WebViewTargetDurationInMillis = 242561; - - private static string[] shouldUseLocalAudioFiles = new string[] - { - "WebViewTests/AudioUrlAndExistingAudio.txt", - }; - - private static string[] shouldUseWebViewFiles = new string[] - { - "WebViewTests/AudioUrlAndMissingAudio.txt", - "WebViewTests/AudioUrlOnly.txt", - "WebViewTests/AudioOnly.txt", - "WebViewTests/VideoUrlOnly.txt", - "WebViewTests/WebsiteOnly.txt", - }; - - protected override void ConfigureTestSettings(TestSettings settings) - { - settings.AcceptedWebViewHosts = new List() - { - "youtube.com", - }; - } - - [UnityTest] - public IEnumerator ShouldUseLocalAudioTest([ValueSource(nameof(shouldUseLocalAudioFiles))] string txtFilePath) - { - yield return SongAudioPlayerShouldLoadFile(txtFilePath); - Assert.IsFalse(songAudioPlayer.CurrentAudioSupportProvider is WebViewAudioSupportProvider); - } - - [UnityTest] - public IEnumerator ShouldUseWebView([ValueSource(nameof(shouldUseWebViewFiles))] string txtFilePath) - { - yield return SongAudioPlayerShouldLoadFile(txtFilePath, WebViewTargetDurationInMillis, WebViewMaxWaitTimeInMillis); - Assert.IsTrue(songAudioPlayer.CurrentAudioSupportProvider is WebViewAudioSupportProvider); - } -} diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTest.cs.meta b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTest.cs.meta deleted file mode 100644 index 1aed094da..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTest.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2768487a818f42eabf5d23d0bebc098c -timeCreated: 1697477844 \ No newline at end of file diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests.meta b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests.meta deleted file mode 100644 index 1a795e3a4..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: cd93bf9a931a4b7b8f72e337ffddf64d -timeCreated: 1697477674 \ No newline at end of file diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioOnly.txt b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioOnly.txt deleted file mode 100644 index c2fcc72fa..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioOnly.txt +++ /dev/null @@ -1,9 +0,0 @@ -#TITLE:TestTitle -#ARTIST:TestArtist -#MP3:https://www.youtube.com/watch?v=tEOZjZZmlAI -#BPM:200 -- 0 -: 4 3 9 Hel -: 8 3 9 lo -: 12 3 9 world! -E \ No newline at end of file diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioOnly.txt.meta b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioOnly.txt.meta deleted file mode 100644 index ab546c6c0..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioOnly.txt.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: afc03803f6ec85241a8384b22a1e887c -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndExistingAudio.txt b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndExistingAudio.txt deleted file mode 100644 index fbd816ec5..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndExistingAudio.txt +++ /dev/null @@ -1,10 +0,0 @@ -#TITLE:TestTitle -#ARTIST:TestArtist -#AUDIO:ogg.ogg -#AUDIOURL:https://www.youtube.com/watch?v=tEOZjZZmlAI -#BPM:200 -- 0 -: 4 3 9 Hel -: 8 3 9 lo -: 12 3 9 world! -E \ No newline at end of file diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndExistingAudio.txt.meta b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndExistingAudio.txt.meta deleted file mode 100644 index 5ffd352ae..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndExistingAudio.txt.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: ee5a2e4a439021541b4ec6ba266d13a1 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndMissingAudio.txt b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndMissingAudio.txt deleted file mode 100644 index 6ad1c8a26..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndMissingAudio.txt +++ /dev/null @@ -1,10 +0,0 @@ -#TITLE:TestTitle -#ARTIST:TestArtist -#AUDIO:missing-audio.ogg -#AUDIOURL:https://www.youtube.com/watch?v=tEOZjZZmlAI -#BPM:200 -- 0 -: 4 3 9 Hel -: 8 3 9 lo -: 12 3 9 world! -E \ No newline at end of file diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndMissingAudio.txt.meta b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndMissingAudio.txt.meta deleted file mode 100644 index 1044455d5..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlAndMissingAudio.txt.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 20b0714dcc9a7aa46ac75d63c45548ac -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlOnly.txt b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlOnly.txt deleted file mode 100644 index 0d32f03be..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlOnly.txt +++ /dev/null @@ -1,9 +0,0 @@ -#TITLE:TestTitle -#ARTIST:TestArtist -#AUDIOURL:https://www.youtube.com/watch?v=tEOZjZZmlAI -#BPM:200 -- 0 -: 4 3 9 Hel -: 8 3 9 lo -: 12 3 9 world! -E \ No newline at end of file diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlOnly.txt.meta b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlOnly.txt.meta deleted file mode 100644 index 84b7e1f57..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/AudioUrlOnly.txt.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 70d3f38ad61038e47b307afd93f646e7 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/VideoUrlOnly.txt b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/VideoUrlOnly.txt deleted file mode 100644 index 3e49d784b..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/VideoUrlOnly.txt +++ /dev/null @@ -1,9 +0,0 @@ -#TITLE:TestTitle -#ARTIST:TestArtist -#VIDEOURL:https://www.youtube.com/watch?v=tEOZjZZmlAI -#BPM:200 -- 0 -: 4 3 9 Hel -: 8 3 9 lo -: 12 3 9 world! -E \ No newline at end of file diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/VideoUrlOnly.txt.meta b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/VideoUrlOnly.txt.meta deleted file mode 100644 index 87b3cc817..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/VideoUrlOnly.txt.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 49d6d25fc2611c04592fa3d7c7921531 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/WebsiteOnly.txt b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/WebsiteOnly.txt deleted file mode 100644 index 674a09940..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/WebsiteOnly.txt +++ /dev/null @@ -1,9 +0,0 @@ -#TITLE:TestTitle -#ARTIST:TestArtist -#WEBSITE:https://www.youtube.com/watch?v=tEOZjZZmlAI -#BPM:200 -- 0 -: 4 3 9 Hel -: 8 3 9 lo -: 12 3 9 world! -E \ No newline at end of file diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/WebsiteOnly.txt.meta b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/WebsiteOnly.txt.meta deleted file mode 100644 index a9932acef..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/WebsiteOnly.txt.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: a2bb56b65c0d7c448a4c6116a08b1d90 -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/ogg.ogg b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/ogg.ogg deleted file mode 100644 index 6ba9a73aa366a6e7f2294cdc638821b07ae2929f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50356 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

9X!6}m&h!+gk|w}!l8$FB8M>bEHvi^!6W!s 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 O30(6%<&F|1K=wbKA`Ex{ diff --git a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/ogg.ogg.meta b/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/ogg.ogg.meta deleted file mode 100644 index 3c2f0880a..000000000 --- a/UltraStar Play/Assets/PlayModeTests/MediaFileFormatTests/WebViewTests/ogg.ogg.meta +++ /dev/null @@ -1,23 +0,0 @@ -fileFormatVersion: 2 -guid: 0c27004bbc903774eb5b0e114488c915 -AudioImporter: - externalObjects: {} - serializedVersion: 7 - defaultSettings: - serializedVersion: 2 - loadType: 0 - sampleRateSetting: 0 - sampleRateOverride: 44100 - compressionFormat: 1 - quality: 1 - conversionMode: 0 - preloadAudioData: 0 - platformSettingOverrides: {} - forceToMono: 0 - normalize: 1 - loadInBackground: 0 - ambisonic: 0 - 3D: 1 - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/Scenes/Options/DevelopmentOptions/DevelopmentOptionsControl.cs b/UltraStar Play/Assets/Scenes/Options/DevelopmentOptions/DevelopmentOptionsControl.cs index 1746002dd..b2f9513e3 100644 --- a/UltraStar Play/Assets/Scenes/Options/DevelopmentOptions/DevelopmentOptionsControl.cs +++ b/UltraStar Play/Assets/Scenes/Options/DevelopmentOptions/DevelopmentOptionsControl.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -264,14 +264,6 @@ protected override void Start() settings.EnableDynamicThemes = enableDynamicThemes; }); - FieldBindingUtils.Bind(enableWebViewToggle, - () => settings.EnableWebView, - newValue => settings.EnableWebView = newValue); - - FieldBindingUtils.Bind(webViewCustomUserAgentTextField, - () => settings.CustomUserAgent, - newValue => settings.CustomUserAgent = newValue); - FieldBindingUtils.Bind(songScanMaxBatchCountChooser, () => settings.SongScanMaxBatchCount, newValue => settings.SongScanMaxBatchCount = newValue); @@ -323,16 +315,6 @@ protected override void Start() openPersistentDataPathButton.HideByDisplay(); } - // Open WebView scripts path - if (PlatformUtils.IsStandalone) - { - openWebViewScriptsPathButton.RegisterCallbackButtonTriggered(_ => ApplicationUtils.OpenDirectory(WebViewUtils.GetDefaultWebViewScriptsAbsolutePath())); - } - else - { - openWebViewScriptsPathButton.HideByDisplay(); - } - // Message delay FieldBindingUtils.Bind(messageBufferTimeTextField, () => settings.CompanionClientMessageBufferTimeInMillis, diff --git a/UltraStar Play/Assets/Scenes/Scenes.asmdef b/UltraStar Play/Assets/Scenes/Scenes.asmdef index 9f52f1625..5f0dab14a 100644 --- a/UltraStar Play/Assets/Scenes/Scenes.asmdef +++ b/UltraStar Play/Assets/Scenes/Scenes.asmdef @@ -18,7 +18,6 @@ "playsharedui", "AndroidRuntimePermissions.Runtime", "UnityStandaloneFileBrowser", - "Vuplex.WebView", "LiteNetLib", "com.whisper.unity", "OneJS" diff --git a/UltraStar Play/Assets/Scenes/SongSelect/SongSelectSceneInputControl.cs b/UltraStar Play/Assets/Scenes/SongSelect/SongSelectSceneInputControl.cs index 406520d0c..62c3cca3f 100644 --- a/UltraStar Play/Assets/Scenes/SongSelect/SongSelectSceneInputControl.cs +++ b/UltraStar Play/Assets/Scenes/SongSelect/SongSelectSceneInputControl.cs @@ -42,9 +42,6 @@ public class SongSelectSceneInputControl : MonoBehaviour, INeedInjection [Inject] private PanelHelper panelHelper; - [Inject] - private WebViewManager webViewManager; - private readonly ReactiveProperty fuzzySearchText = new(""); public IObservable FuzzySearchText => fuzzySearchText; private float fuzzySearchLastInputTimeInSeconds; @@ -260,7 +257,6 @@ private void OnKeyboardTextInput(char newChar) if (newChar == (int)KeyCode.Escape || newChar == (int)KeyCode.Return || (newChar == (int)KeyCode.Backspace && fuzzySearchText.Value.IsNullOrEmpty()) - || webViewManager.IsWebViewCanvasControlEnabled || (newChar == (int)KeyCode.Space && fuzzySearchText.Value.IsNullOrEmpty())) { return; diff --git a/UltraStar Play/Assets/StreamingAssets/WebViewScripts.meta b/UltraStar Play/Assets/StreamingAssets/WebViewScripts.meta deleted file mode 100644 index 8b8e2bdf3..000000000 --- a/UltraStar Play/Assets/StreamingAssets/WebViewScripts.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2ffa1b6ad30045dbbf1a42beec1532f4 -timeCreated: 1686420111 \ No newline at end of file diff --git a/UltraStar Play/Assets/StreamingAssets/WebViewScripts/README.md b/UltraStar Play/Assets/StreamingAssets/WebViewScripts/README.md deleted file mode 100644 index 504972bad..000000000 --- a/UltraStar Play/Assets/StreamingAssets/WebViewScripts/README.md +++ /dev/null @@ -1,26 +0,0 @@ -The JavaScript files in this folder are for the embedded browser -to integrate third-party websites in the game. - -## File Name -- The file name must be the host of the URL that is handled by the script. - - Example: To handle a URL `https://my-video-platform.com/?v=SomeVideoId`, the script should be named `my-video-platform.com.js` -- After adding a script, the game will assume that the corresponding host is supported. - - Example: Adding a file `my-video-platform.com.js` will allow you to use the URL `https://my-video-platform.com/?v=SomeVideoId` (with or without `www.`) as #MP3 tag in song files. - -## Loading Order -- The scripts in this folder are loaded after the page is loaded. - -## Show Embedded Browser -- You can show / hide the embedded browser window by pressing `F8` or `Ctrl+B`. - -## Open URL -- The game will load a URL into the embedded browser when the song file should play its audio. -- A script can indicate that it is able to load a new URL on the same host by itself. - The game will then delegate loading a different URL to the script instead of navigating to a new URL. - -## Log Messages -- The `console.log` statements in the script are redirected to the game. -- You can see the log messages in the game by looking at the log file or by opening the in-game debug console that opens with `F7`. - -## Reloading Scripts -- A file system watcher is monitoring the scripts in this folder. If a script is changed, then the game will reload the script without requiring a restart. \ No newline at end of file diff --git a/UltraStar Play/Assets/StreamingAssets/WebViewScripts/README.md.meta b/UltraStar Play/Assets/StreamingAssets/WebViewScripts/README.md.meta deleted file mode 100644 index 31fd4ccd5..000000000 --- a/UltraStar Play/Assets/StreamingAssets/WebViewScripts/README.md.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 42da74cc6da343acbdff7f6112b9b29c -timeCreated: 1686471741 \ No newline at end of file diff --git a/UltraStar Play/Assets/StreamingAssets/WebViewScripts/youtube.com.js b/UltraStar Play/Assets/StreamingAssets/WebViewScripts/youtube.com.js deleted file mode 100644 index e78a4d700..000000000 --- a/UltraStar Play/Assets/StreamingAssets/WebViewScripts/youtube.com.js +++ /dev/null @@ -1,102 +0,0 @@ -function getPlayer() { - return document.getElementById('movie_player'); -} - -setInterval(() => checkPlayerState(), 1000); -postMessage({ type: 'CanLoadUrl', value: true }); - -var wasReady = false; -var lastPlayerState = 0; -function checkPlayerState() { - const currentPlayerState = getPlayer().getPlayerState(); - if (lastPlayerState !== currentPlayerState) { - lastPlayerState = currentPlayerState; - onPlayerStateChange(currentPlayerState); - } -} - -function onPlayerStateChange(newPlayerState) { - // console.log("onPlayerStateChange: " + newPlayerState); - - if (getPlayer().getVideoLoadedFraction() > 0 && !wasReady) { - wasReady = true; - postMessage({type: 'Ready', value: true}); - - const durationInMillis = getPlayer().getDuration() * 1000; - postMessage({type: 'DurationInMillis', value: durationInMillis}); - - // newPlayerState is - // -1 => not started - // 0 => finished - // 1 => playing - // 2 => paused - // 3 => buffering - // 5 => video positioned - if (newPlayerState.data === 1) { - postMessage({type: 'StartedOrResumed', value: true}); - } else { - postMessage({type: 'StoppedOrPaused', value: true}); - } - } -} - -function loadUrl(url) -{ - if (url.startsWith("{{")) { - console.log("url is not set. Using fallback value instead."); - url = fallbackUrl; - } - - if (url.startsWith("{{")) { - console.log("url is not set even after using fallback value. Aborting."); - return; - } - - const urlObject = new URL(url); - const videoId = urlObject.searchParams.get('v'); - - getPlayer().loadVideoById(videoId); -} - -function sendPlaybackPositionInMillis() { - const result = getPlayer().getCurrentTime() * 1000; - // console.log("sendPlaybackPositionInMillis: " + result); - postMessage({type: 'PlaybackPositionInMillis', value: result}); - return result; -} - -function setPlaybackPositionInMillis(positionInMillis) { - // console.log("setPlaybackPositionInMillis: " + positionInMillis); - getPlayer().seekTo(positionInMillis / 1000, true); -} - -function setVolume(volumeZeroToHundred) { - // console.log("setVolume: " + volumeZeroToHundred); - getPlayer().setVolume(volumeZeroToHundred); -} - -function resumePlayback() { - // console.log("resumePlayback"); - postMessage({type: 'StartedOrResumed', value: true}); - return getPlayer().playVideo(); -} - -function pausePlayback() { - // console.log("pausePlayback"); - postMessage({type: 'StoppedOrPaused', value: true}); - return getPlayer().pauseVideo(); -} - -function stopPlayback() { - // console.log("stopPlayback"); - postMessage({type: 'StoppedOrPaused', value: true}); - return getPlayer().stopVideo(); -} - -function postMessage(jsonObject) { - if (typeof vuplex === 'undefined' || !vuplex || !vuplex.postMessage) { - // console.log("postMessage: vuplex is not defined, ignoring message: " + JSON.stringify(jsonObject)); - return; - } - vuplex.postMessage(jsonObject); -} \ No newline at end of file diff --git a/UltraStar Play/Assets/StreamingAssets/WebViewScripts/youtube.com.js.meta b/UltraStar Play/Assets/StreamingAssets/WebViewScripts/youtube.com.js.meta deleted file mode 100644 index a6da579c5..000000000 --- a/UltraStar Play/Assets/StreamingAssets/WebViewScripts/youtube.com.js.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 1ead55afed1649558a3ee3da13d61747 -timeCreated: 1686420082 \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/Core/Editor/Vuplex.WebView.Editor.asmdef b/UltraStar Play/Assets/Vuplex/WebView/Core/Editor/Vuplex.WebView.Editor.asmdef deleted file mode 100644 index 426f73cbb..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/Core/Editor/Vuplex.WebView.Editor.asmdef +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "Vuplex.WebView.Editor", - "rootNamespace": "", - "references": [ - "GUID:75469ad4d38634e559750d17036d5f7c", - "GUID:93e7b0ac3fd94ca42bc5737c6200e6df" - ], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/Core/Editor/Vuplex.WebView.Editor.asmdef.meta b/UltraStar Play/Assets/Vuplex/WebView/Core/Editor/Vuplex.WebView.Editor.asmdef.meta deleted file mode 100644 index 8448fff79..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/Core/Editor/Vuplex.WebView.Editor.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 9c92aa7ad980b9c49b76e2d8df73af6f -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/Vuplex/WebView/Core/Plugins/Editor/Vuplex.WebView.Plugins.Editor.asmdef b/UltraStar Play/Assets/Vuplex/WebView/Core/Plugins/Editor/Vuplex.WebView.Plugins.Editor.asmdef deleted file mode 100644 index fa56fbb56..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/Core/Plugins/Editor/Vuplex.WebView.Plugins.Editor.asmdef +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "Vuplex.WebView.Plugins.Editor", - "rootNamespace": "", - "references": [ - "GUID:75469ad4d38634e559750d17036d5f7c", - "GUID:93e7b0ac3fd94ca42bc5737c6200e6df" - ], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/Core/Plugins/Editor/Vuplex.WebView.Plugins.Editor.asmdef.meta b/UltraStar Play/Assets/Vuplex/WebView/Core/Plugins/Editor/Vuplex.WebView.Plugins.Editor.asmdef.meta deleted file mode 100644 index bf92c6d19..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/Core/Plugins/Editor/Vuplex.WebView.Plugins.Editor.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 20f60ac9ba10eb44e8621f0928e89924 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/Vuplex/WebView/Standalone/Editor/Vuplex.WebView.Standalone.Editor.asmdef b/UltraStar Play/Assets/Vuplex/WebView/Standalone/Editor/Vuplex.WebView.Standalone.Editor.asmdef deleted file mode 100644 index 8631de7fe..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/Standalone/Editor/Vuplex.WebView.Standalone.Editor.asmdef +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "Vuplex.WebView.Standalone.Editor", - "rootNamespace": "", - "references": [ - "GUID:75469ad4d38634e559750d17036d5f7c", - "GUID:93e7b0ac3fd94ca42bc5737c6200e6df", - "GUID:9c92aa7ad980b9c49b76e2d8df73af6f" - ], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/Standalone/Editor/Vuplex.WebView.Standalone.Editor.asmdef.meta b/UltraStar Play/Assets/Vuplex/WebView/Standalone/Editor/Vuplex.WebView.Standalone.Editor.asmdef.meta deleted file mode 100644 index efc7c5102..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/Standalone/Editor/Vuplex.WebView.Standalone.Editor.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 04da61e7f8162bb4ebfe36948c998c9c -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/Vuplex/WebView/Standalone/Windows/Editor/Vuplex.WebView.Standalone.Windows.Editor.asmdef b/UltraStar Play/Assets/Vuplex/WebView/Standalone/Windows/Editor/Vuplex.WebView.Standalone.Windows.Editor.asmdef deleted file mode 100644 index 7147a7621..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/Standalone/Windows/Editor/Vuplex.WebView.Standalone.Windows.Editor.asmdef +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "Vuplex.WebView.Standalone.Windows.Editor", - "rootNamespace": "", - "references": [ - "GUID:75469ad4d38634e559750d17036d5f7c", - "GUID:93e7b0ac3fd94ca42bc5737c6200e6df", - "GUID:9c92aa7ad980b9c49b76e2d8df73af6f" - ], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/Standalone/Windows/Editor/Vuplex.WebView.Standalone.Windows.Editor.asmdef.meta b/UltraStar Play/Assets/Vuplex/WebView/Standalone/Windows/Editor/Vuplex.WebView.Standalone.Windows.Editor.asmdef.meta deleted file mode 100644 index 8eb8fa8d2..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/Standalone/Windows/Editor/Vuplex.WebView.Standalone.Windows.Editor.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 327b42399abd0f5498a8378425567f46 -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/Vuplex/WebView/Vuplex.WebView.asmdef b/UltraStar Play/Assets/Vuplex/WebView/Vuplex.WebView.asmdef deleted file mode 100644 index 8fe9ae81d..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/Vuplex.WebView.asmdef +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "Vuplex.WebView", - "rootNamespace": "", - "references": [ - "GUID:75469ad4d38634e559750d17036d5f7c" - ], - "includePlatforms": [], - "excludePlatforms": [], - "allowUnsafeCode": false, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": false, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/Vuplex.WebView.asmdef.meta b/UltraStar Play/Assets/Vuplex/WebView/Vuplex.WebView.asmdef.meta deleted file mode 100644 index f34744f7b..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/Vuplex.WebView.asmdef.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 93e7b0ac3fd94ca42bc5737c6200e6df -AssemblyDefinitionImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/CanvasWebViewPrefab.cs b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/CanvasWebViewPrefab.cs deleted file mode 100644 index e6df798cf..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/CanvasWebViewPrefab.cs +++ /dev/null @@ -1,21 +0,0 @@ -#if HAS_VUPLEX_WEBVIEW -#else - -using System; -using UnityEngine; - -namespace Vuplex.WebView -{ - public class CanvasWebViewPrefab : MonoBehaviour - { - public event EventHandler Initialized; - public bool HoveringEnabled { get; set; } - public bool ClickingEnabled { get; set; } - public bool ScrollingEnabled { get; set; } - public bool KeyboardEnabled { get; set; } - public bool CursorIconsEnabled { get; set; } - public IWebView WebView { get; set; } - } -} - -#endif diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/CanvasWebViewPrefab.cs.meta b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/CanvasWebViewPrefab.cs.meta deleted file mode 100644 index b89c1a93d..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/CanvasWebViewPrefab.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: b64500faec2247969c93a24ebc0df9cc -timeCreated: 1718551089 \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/EventArgs.cs b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/EventArgs.cs deleted file mode 100644 index 659fcd209..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/EventArgs.cs +++ /dev/null @@ -1,14 +0,0 @@ -#if HAS_VUPLEX_WEBVIEW -#else - -using System; - -namespace Vuplex.WebView -{ - public class EventArgs : EventArgs - { - public T Value { get; set; } - } -} - -#endif diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/EventArgs.cs.meta b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/EventArgs.cs.meta deleted file mode 100644 index b90243fa4..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/EventArgs.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: f2da63f13f194b8186d01d69706e80e0 -timeCreated: 1718551368 \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/IWebView.cs b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/IWebView.cs deleted file mode 100644 index d2f4ffe3e..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/IWebView.cs +++ /dev/null @@ -1,21 +0,0 @@ -#if HAS_VUPLEX_WEBVIEW -#else - -using System; -using System.Collections.Generic; - -namespace Vuplex.WebView -{ - public interface IWebView - { - void ExecuteJavaScript(string s); - event EventHandler> MessageEmitted; - event EventHandler LoadProgressChanged; - void LoadHtml(string text); - string Url { get; set; } - List PageLoadScripts { get; set; } - void LoadUrl(string url); - } -} - -#endif diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/IWebView.cs.meta b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/IWebView.cs.meta deleted file mode 100644 index 891afea5c..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/IWebView.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 251215508ba0484f9e5bc3b2a0f9858c -timeCreated: 1718551124 \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangeType.cs b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangeType.cs deleted file mode 100644 index fbfb2eaf6..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangeType.cs +++ /dev/null @@ -1,13 +0,0 @@ -#if HAS_VUPLEX_WEBVIEW -#else - -namespace Vuplex.WebView -{ - public enum ProgressChangeType - { - Finished, - Failed - } -} - -#endif diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangeType.cs.meta b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangeType.cs.meta deleted file mode 100644 index 9d360a5a4..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangeType.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 05f6cce95c1348ceb086a0528b8fb819 -timeCreated: 1718551340 \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangedEventArgs.cs b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangedEventArgs.cs deleted file mode 100644 index 94b7ec5f3..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangedEventArgs.cs +++ /dev/null @@ -1,14 +0,0 @@ -#if HAS_VUPLEX_WEBVIEW -#else - -using System; - -namespace Vuplex.WebView -{ - public class ProgressChangedEventArgs : EventArgs - { - public object Type { get; set; } - } -} - -#endif diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangedEventArgs.cs.meta b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangedEventArgs.cs.meta deleted file mode 100644 index 367d5a922..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/ProgressChangedEventArgs.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 87d81e11c0cb4e65a85eb5dad357d002 -timeCreated: 1718551323 \ No newline at end of file diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/Web.cs b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/Web.cs deleted file mode 100644 index b9dfc8e1f..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/Web.cs +++ /dev/null @@ -1,18 +0,0 @@ -#if HAS_VUPLEX_WEBVIEW -#else - -namespace Vuplex.WebView -{ - public static class Web - { - public static void SetAutoplayEnabled(bool b) - { - } - - public static void SetUserAgent(string s) - { - } - } -} - -#endif diff --git a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/Web.cs.meta b/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/Web.cs.meta deleted file mode 100644 index 31f7719b7..000000000 --- a/UltraStar Play/Assets/Vuplex/WebView/VuplexWebViewDummy/Web.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: d7f209fe5b254e58976def6b30339943 -timeCreated: 1718551141 \ No newline at end of file diff --git a/UltraStar Play/Packages/playshared/Runtime/Songs/SongMetaUtils.cs b/UltraStar Play/Packages/playshared/Runtime/Songs/SongMetaUtils.cs index f4d6dfeb8..f63ad0988 100644 --- a/UltraStar Play/Packages/playshared/Runtime/Songs/SongMetaUtils.cs +++ b/UltraStar Play/Packages/playshared/Runtime/Songs/SongMetaUtils.cs @@ -72,6 +72,7 @@ public static string GetInstrumentalAudioUri(SongMeta songMeta) return GetExistingResourceUriOrFirst(songMeta, songMeta.InstrumentalAudio, songMeta.InstrumentalAudioUrl); } + [Obsolete] public static string GetWebViewUrl(SongMeta songMeta) { return GetExistingResourceUriOrFirst(songMeta, songMeta.AudioUrl, songMeta.VideoUrl);