diff --git a/LittleWarGameClient/AddOns.js b/LittleWarGameClient/AddOns.js index 6c610c8..c712927 100644 --- a/LittleWarGameClient/AddOns.js +++ b/LittleWarGameClient/AddOns.js @@ -29,6 +29,26 @@ ); }, + changeVolume: function (element, volumeLevel) { + window.chrome.webview.postMessage( + JSON.stringify({ + Id: element.id, + Value: volumeLevel.toString(), + Type: "VolumeChanging" + }) + ); + }, + + saveVolumeChange: function (element, volumeLevel) { + window.chrome.webview.postMessage( + JSON.stringify({ + Id: element.id, + Value: volumeLevel.toString(), + Type: "VolumeChanged" + }) + ); + }, + fakeClick: function (anchorObj) { if (anchorObj.click) { anchorObj.click() @@ -125,9 +145,11 @@ }; addons.init = { - function(mouseLock, clientVersion) { + function(clientVersion, mouseLock, volume) { + this.handleConnectionError(); this.addExitButton(); this.changeQuitButtonText(); + this.addVolumeSlider(volume); this.addClientVersion(clientVersion); this.replaceMouseLockCheckbox(mouseLock); var fullScreenButton = document.getElementById("optionsFullscreenButton"); @@ -139,12 +161,67 @@ addons.init = { this.jsInitComplete(); }, + handleConnectionError: function () { + var connectionErrorWindow = document.getElementById("NoConnectionWindow"); + if (connectionErrorWindow != null) { + this.addReconnect(connectionErrorWindow); + } + else { + var observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + for(var i = 0; i < mutation.addedNodes.length; i++) + { + var element = mutation.addedNodes[i]; + if (element.id == "NoConnectionWindow") + { + addons.init.addReconnect(element); + } + } + }); + }); + observer.observe(document.body, { + childList: true + }); + } + }, + + addReconnect: function (element) { + element.style = "position: absolute; top: 50px; width: 300px;" + var windowTitle = element.getElementsByTagName('h2')[0]; + windowTitle.style = "position: relative;"; + var reconnectButton = document.createElement("h1"); + reconnectButton.innerText = "Reconnect"; + reconnectButton.style = "position: relative; left: 30%; width: fit-content;"; + reconnectButton.onmouseover = function() { this.style.color='darkorange' }; + reconnectButton.onmouseout = function() { this.style.color='inherit' }; + reconnectButton.onclick = function() { location.reload(); }; + windowTitle.insertAdjacentElement('afterend', reconnectButton); + }, + + addVolumeSlider: function (volume) { + var globalVolumeId = "globalVolumeLabel"; + if (!document.getElementById(globalVolumeId)) { + var globalVolume = document.createElement("p"); + globalVolume.id = globalVolumeId; + globalVolume.innerText = "Master Volume"; + var globalVolumeDiv = document.createElement("div"); + globalVolumeDiv.id = "optionsMasterSoundButton"; + var globalVolumeAnchor = document.createElement("a"); + globalVolumeDiv.appendChild(globalVolumeAnchor); + globalVolume.appendChild(globalVolumeDiv); + document.getElementById("optionsChecklistDiv").prepend(globalVolume); + $(globalVolumeDiv).slider({ slide: (event, ui) => addons.changeVolume(globalVolumeDiv, ui.value / 100) }); + $(globalVolumeDiv).slider({ change: (event, ui) => addons.saveVolumeChange(globalVolumeDiv, ui.value / 100) }); + $(globalVolumeDiv).slider("value", volume * 100); + } + }, + addClientMadeBy: function () { var imprintLink = document.getElementById("imprintLink"); imprintLink.onclick = function () { var breakElement = document.createElement("br"); var divElement = document.createElement("div"); - divElement.innerHTML = "Windows client made by SunNoise
© 2024"; + divElement.innerHTML = "Windows client made by Ivan Martell
© 2024"; var imprint = document.getElementById("addScrollableSubDivTextArea2"); imprint.appendChild(breakElement); imprint.appendChild(divElement); diff --git a/LittleWarGameClient/AudioManager.cs b/LittleWarGameClient/AudioManager.cs index 66a9fbc..8b97186 100644 --- a/LittleWarGameClient/AudioManager.cs +++ b/LittleWarGameClient/AudioManager.cs @@ -14,13 +14,13 @@ internal class AudioManager : IAudioSessionEventsHandler { private MMDevice? mainDevice; private AudioSessionControl? currentSession; - private readonly Form form; + private readonly string formTitle; - public AudioManager(Form form) + public AudioManager(string formTitle) { - this.form = form; + this.formTitle = formTitle; var etor = new MMDeviceEnumerator(); - this.mainDevice = etor.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); + mainDevice = etor.GetDefaultAudioEndpoint(DataFlow.Render, Role.Multimedia); if (mainDevice != null) { var sessions = mainDevice.AudioSessionManager.Sessions; @@ -32,14 +32,20 @@ public AudioManager(Form form) mainDevice.AudioSessionManager.OnSessionCreated += AudioSessionManager_OnSessionCreated; } } + + internal void ChangeVolume(float value) + { + if (currentSession != null) + currentSession.SimpleAudioVolume.Volume = value; + } internal void DestroySession() { - var sess = this.currentSession; - this.currentSession = null; - this.UnregisterFromSession(sess); + var sess = currentSession; + currentSession = null; + UnregisterFromSession(sess); if (mainDevice != null) { - mainDevice.AudioSessionManager.OnSessionCreated -= this.AudioSessionManager_OnSessionCreated; + mainDevice.AudioSessionManager.OnSessionCreated -= AudioSessionManager_OnSessionCreated; mainDevice.Dispose(); } } @@ -77,10 +83,11 @@ private void ChangeTextAndIcon(AudioSessionControl session) if (!isSubProc) return; - session.DisplayName = form.Text; + + session.DisplayName = formTitle; session.IconPath = GetType().Assembly.Location; - this.currentSession = session; - this.currentSession.RegisterEventClient(this); + currentSession = session; + currentSession.RegisterEventClient(this); } private void AudioSessionManager_OnSessionCreated(object sender, IAudioSessionControl newSession) @@ -130,13 +137,13 @@ void IAudioSessionEventsHandler.OnStateChanged(AudioSessionState state) { if (state == AudioSessionState.AudioSessionStateExpired) { - this.ReleaseSessionDelayed(this.currentSession); + ReleaseSessionDelayed(currentSession); } } void IAudioSessionEventsHandler.OnSessionDisconnected(AudioSessionDisconnectReason disconnectReason) { - this.ReleaseSessionDelayed(this.currentSession); + ReleaseSessionDelayed(currentSession); } private void ReleaseSessionDelayed(AudioSessionControl? session) diff --git a/LittleWarGameClient/Form1.Designer.cs b/LittleWarGameClient/Form1.Designer.cs index 2d74696..893254e 100644 --- a/LittleWarGameClient/Form1.Designer.cs +++ b/LittleWarGameClient/Form1.Designer.cs @@ -54,6 +54,7 @@ private void InitializeComponent() webView.Size = new Size(1264, 681); webView.TabIndex = 0; webView.ZoomFactor = 1D; + webView.NavigationStarting += webView_NavigationStarting; webView.NavigationCompleted += webView_NavigationCompleted; webView.WebMessageReceived += webView_WebMessageReceived; // @@ -90,9 +91,9 @@ private void InitializeComponent() loadingText.BorderStyle = BorderStyle.None; loadingText.Font = new Font("LCD Solid", 48F, FontStyle.Regular, GraphicsUnit.Point); loadingText.ForeColor = Color.White; - loadingText.Location = new Point(432, 474); + loadingText.Location = new Point(390, 474); loadingText.Name = "loadingText"; - loadingText.Size = new Size(400, 64); + loadingText.Size = new Size(480, 64); loadingText.TabIndex = 3; loadingText.Text = "Loading"; loadingText.TextAlign = HorizontalAlignment.Center; @@ -103,10 +104,9 @@ private void InitializeComponent() mainImage.ErrorImage = null; mainImage.Image = Properties.Resources.soldier; mainImage.InitialImage = null; - mainImage.Location = new Point(432, 52); - mainImage.MaximumSize = new Size(400, 400); + mainImage.Location = new Point(582, 120); mainImage.Name = "mainImage"; - mainImage.Size = new Size(400, 400); + mainImage.Size = new Size(100, 100); mainImage.SizeMode = PictureBoxSizeMode.StretchImage; mainImage.TabIndex = 2; mainImage.TabStop = false; diff --git a/LittleWarGameClient/Form1.cs b/LittleWarGameClient/Form1.cs index 43ac05f..afde17c 100644 --- a/LittleWarGameClient/Form1.cs +++ b/LittleWarGameClient/Form1.cs @@ -29,7 +29,7 @@ public Form1() { InitializeComponent(); InitWebView(); - audioMngr = new AudioManager(this); + audioMngr = new AudioManager(this.Text); settings = new Settings(); this.Size = settings.GetWindowSize(); fullScreen = new Fullscreen(this, settings); @@ -41,7 +41,6 @@ public Form1() private async void InitWebView() { loadingPanel.SetDoubleBuffered(); - loadingPanel.Visible = true; var path = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath); CoreWebView2Environment env = await CoreWebView2Environment.CreateAsync(null, Path.Join(path, "data"), new CoreWebView2EnvironmentOptions()); await webView.EnsureCoreWebView2Async(env); @@ -56,7 +55,7 @@ private void webView_NavigationCompleted(object sender, Microsoft.Web.WebView2.C { var addOnJS = System.IO.File.ReadAllText("AddOns.js"); webView.CoreWebView2.ExecuteScriptAsync(addOnJS); - ElementMessage.CallJSFunc(webView, "init.function", $"{settings.GetMouseLock().ToString().ToLower()}, \"{vHandler.CurrentVersion}\""); + ElementMessage.CallJSFunc(webView, "init.function", $"\"{vHandler.CurrentVersion}\", {settings.GetMouseLock().ToString().ToLower()}, {settings.GetVolume()}"); kbHandler.InitHotkeyNames(settings); gameHasLoaded = true; ResizeGameWindows(); @@ -85,8 +84,25 @@ private void webView_WebMessageReceived(object sender, Microsoft.Web.WebView2.Co CaptureCursor(); break; case ButtonType.InitComplete: - this.Controls.Remove(loadingPanel); + loadingPanel.Visible = false; loadingTimer.Enabled = false; + loadingText.Text = "Reconnecting"; + break; + case ButtonType.VolumeChanging: + if (msg.Value != null) + { + var val = float.Parse(msg.Value); + audioMngr.ChangeVolume(val); + } + break; + case ButtonType.VolumeChanged: + if (msg.Value != null) + { + var val = float.Parse(msg.Value); + audioMngr.ChangeVolume(val); + settings.SetVolume(val); + settings.SaveAsync(); + } break; } } @@ -156,5 +172,11 @@ private void loadingTimer_Tick(object sender, EventArgs e) else loadingText.Visible = true; } + + private void webView_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e) + { + loadingPanel.Visible = true; + loadingTimer.Enabled = true; + } } } diff --git a/LittleWarGameClient/Settings.cs b/LittleWarGameClient/Settings.cs index 2cef485..6077d5c 100644 --- a/LittleWarGameClient/Settings.cs +++ b/LittleWarGameClient/Settings.cs @@ -16,6 +16,7 @@ internal class Settings private const bool defaultFullscreen = false; private const bool defaultMouseLock = false; private const int defaultUpdateInterval = 1; + private const double defaultVolume = 1.0; private readonly DateTime defaultUpdateLastChecked = DateTime.MinValue; private const Keys defaultOptionsMenu = Keys.F10; private const Keys defaultFriendsMenu = Keys.F9; @@ -45,6 +46,7 @@ private void Init() SetFriendsMenuHotkey(GetFriendsMenuHotkey()); SetChatHistoryMenuHotkey(GetChatHistoryMenuHotkey()); SetFullscreenHotkey(GetFullscreenHotkey()); + SetVolume(GetVolume()); SaveAsync(); } @@ -73,6 +75,10 @@ private Ini CreateDefaultIniFile() new Property("friendsMenu", defaultFriendsMenu.ToString()), new Property("chatHistoryMenu", defaultChatHistoryMenu.ToString()), new Property("fullscreen", defaultFullscreenHotkey.ToString()) + }, + new Section("Audio") + { + new Property("volume", defaultVolume) } }; return settings; @@ -187,6 +193,16 @@ public Keys GetFullscreenHotkey() { return helper.GetVariable("Hotkeys", "fullscreen", defaultFullscreenHotkey); } + + internal void SetVolume(double value) + { + helper.SetVariable("Audio", "volume", value); + } + + public double GetVolume() + { + return helper.GetVariable("Audio", "volume", defaultVolume); + } } internal class Hotkey : Attribute diff --git a/LittleWarGameClient/SettingsHelper.cs b/LittleWarGameClient/SettingsHelper.cs index 0768af1..05d0b39 100644 --- a/LittleWarGameClient/SettingsHelper.cs +++ b/LittleWarGameClient/SettingsHelper.cs @@ -51,6 +51,18 @@ internal int GetVariable(string sectionName, string propertyName, int defaultVal } } + internal double GetVariable(string sectionName, string propertyName, double defaultValue) + { + try + { + return settings[sectionName][propertyName]; + } + catch + { + return defaultValue; + } + } + internal DateTime GetVariable(string sectionName, string propertyName, DateTime defaultValue) { try @@ -113,6 +125,19 @@ internal void SetVariable(string sectionName, string propertyName, int value) } } + internal void SetVariable(string sectionName, string propertyName, double value) + { + Section section = EnsureSection(sectionName); + try + { + section[propertyName] = value; + } + catch + { + section.Add(new Property(propertyName, value)); + } + } + internal void SetVariable(string sectionName, string propertyName, Keys value) { Section section = EnsureSection(sectionName); diff --git a/LittleWarGameClient/WebMessage.cs b/LittleWarGameClient/WebMessage.cs index f1ba381..6b330f3 100644 --- a/LittleWarGameClient/WebMessage.cs +++ b/LittleWarGameClient/WebMessage.cs @@ -28,6 +28,10 @@ internal enum ButtonType [EnumMember(Value = "MouseLock")] MouseLock, [EnumMember(Value = "InitComplete")] - InitComplete + InitComplete, + [EnumMember(Value = "VolumeChanging")] + VolumeChanging, + [EnumMember(Value = "VolumeChanged")] + VolumeChanged } }