Skip to content

Commit

Permalink
Allow only one instance of the game to be open. Fixed Alt-Tabbing
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanpmartell committed Jul 31, 2024
1 parent fe603b7 commit b0c9672
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 27 deletions.
35 changes: 29 additions & 6 deletions LittleWarGameClient/GameForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using CefSharp;
using CefSharp.Handler;
using CefSharp.WinForms;
using CefSharp.DevTools.Debugger;

namespace LittleWarGameClient
{
Expand Down Expand Up @@ -42,6 +43,7 @@ internal static GameForm Instance

internal GameForm()
{
PreInitWeb();
InitializeComponent();
settings = new Settings();
audioMngr = new AudioManager(Text);
Expand All @@ -51,16 +53,20 @@ internal GameForm()
InitWebView();
}

private void InitWebView()
private void PreInitWeb()
{
webBrowser.JavascriptMessageReceived += ElementMessage.JSMessageReceived;
var path = Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);
var cefSettings = new CefSettings();
cefSettings.CefCommandLineArgs.Add("no-proxy-server", "1");
cefSettings.CefCommandLineArgs.Add("disable-plugins-discovery", "1");
cefSettings.CefCommandLineArgs.Add("disable-extensions", "1");
cefSettings.RootCachePath = Path.Join(path, "data");
Cef.Initialize(cefSettings);
}

private void InitWebView()
{
webBrowser.JavascriptMessageReceived += ElementMessage.JSMessageReceived;
webBrowser.KeyboardHandler = kbHandler;
webBrowser.RequestHandler = new RequestInterceptor();
webBrowser.DownloadHandler = new DownloadInterceptor();
Expand Down Expand Up @@ -205,8 +211,15 @@ private void webView_LoadingStateChanged(object sender, LoadingStateChangedEvent

internal void InvokeUI(Action a)
{
if (formInstance != null)
formInstance.BeginInvoke(new MethodInvoker(a));
if (formInstance != null && formInstance.InvokeRequired)
{
if (formInstance.IsHandleCreated)
formInstance.BeginInvoke(new MethodInvoker(a));
}
else
{
a.Invoke();
}
}

private void GameForm_Deactivate(object sender, EventArgs e)
Expand All @@ -221,12 +234,22 @@ private void GameForm_Activated(object sender, EventArgs e)
ResizeGameWindows();
if (!OverlayForm.Instance.IsDisposed)
OverlayForm.Instance.Visible = true;
SendKeys.Send("%{F16}"); //Alt-Tab fix for game
}

private void GameForm_FormClosing(object sender, FormClosingEventArgs e)
{
audioMngr.DestroySession();
Application.Exit();
switch (e.CloseReason)
{
case CloseReason.None:
e.Cancel = true;
break;
case CloseReason.UserClosing:
audioMngr.DestroySession();
webBrowser.Dispose();
Application.Exit();
break;
}
}

private void GameForm_Resize(object sender, EventArgs e)
Expand Down
5 changes: 2 additions & 3 deletions LittleWarGameClient/KeyboardHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,9 @@ private void FriendsHotkeyFunc(ChromiumWebBrowser sender)

public bool OnPreKeyEvent(IWebBrowser webView, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut)
{
if (OverlayForm.Instance.IsActivated)
{
if (OverlayForm.Instance.IsActivated)
return true;
}

var key = (Keys)windowsKeyCode;
if (type == KeyType.RawKeyDown)
{
Expand Down
2 changes: 1 addition & 1 deletion LittleWarGameClient/OverlayForm.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 24 additions & 7 deletions LittleWarGameClient/OverlayForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ internal static OverlayForm Instance
}
}

private bool IsGameFormLoaded = false;
private BDictionary<string, Notification> overlayMessages;
internal void AddOverlayMessage(string name, Notification notification)
{
Expand All @@ -43,6 +44,9 @@ internal OverlayForm()
overlayMessages = new BDictionary<string, Notification>();
IsActivated = false;
InitializeComponent();
if (Program.LWG_FONT != null)
Font = new Font(Program.LWG_FONT, 21.75F, FontStyle.Regular, GraphicsUnit.Point);

try
{
SteamClient.Init(480);
Expand All @@ -58,7 +62,7 @@ protected override void OnRender(D2DGraphics g)
for (int i = 0; i < overlayMessages.Count; i++)
{
var notification = overlayMessages[i].Value.message;
g.DrawText($" >{notification}", D2DColor.Yellow, Font, 0, (i+1)*30);
g.DrawText($" >{notification}", D2DColor.Yellow, Font, 0, (i + 1) * 30);
}
}

Expand All @@ -77,19 +81,18 @@ private void OnGameOverlayActivated(bool overlayActivated)
{
InvokeUI(() =>
{
TransparencyKey = Color.Fuchsia;
IsActivated = true;
KeyPreview = true;
Activate();
GameForm.Instance.Visible = false;
TransparencyKey = Color.Fuchsia;
});
}
else
{
InvokeUI(() =>
{
TransparencyKey = Color.Black;
IsActivated = false;
KeyPreview = false;
GameForm.Instance.Visible = true;
TransparencyKey = Color.Black;
});
}
}
Expand All @@ -114,7 +117,21 @@ internal void InvokeUI(Action a)

private void OverlayForm_Load(object sender, EventArgs e)
{
GameForm.Instance.ShowDialog();
if (!IsGameFormLoaded)
{
IsGameFormLoaded = true;
GameForm.Instance.Show();
}
}

private void OverlayForm_FormClosing(object sender, FormClosingEventArgs e)
{
switch (e.CloseReason)
{
case CloseReason.None:
e.Cancel = true;
break;
}
}
}
}
80 changes: 70 additions & 10 deletions LittleWarGameClient/Program.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,92 @@
using CefSharp;
using CefSharp.DevTools.Overlay;
using LittleWarGameClient.Properties;
using Loyc.Syntax;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing.Text;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;

namespace LittleWarGameClient
{
internal static class Program
{
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

[DllImport("User32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumWindows(CallBackPtr lpEnumFunc, IntPtr lParam);

private delegate bool CallBackPtr(IntPtr hwnd, int lParam);

private static CallBackPtr callBackPtr = Callback;
private static List<WinStruct> _WinStructList = new List<WinStruct>();

internal static FontFamily? LWG_FONT;
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
string font_filename = "lwgFont.ttf";
if (!File.Exists(font_filename))
File.WriteAllBytes(font_filename, Resources.LcdSolidFont);
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddFontFile(font_filename);
LWG_FONT = pfc.Families[0];
Application.Run(OverlayForm.Instance);
bool createdNew = true;
using (Mutex mutex = new Mutex(true, "Global\\LittleWarGameClient", out createdNew))
{
if (createdNew)
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
string font_filename = "lwgFont.ttf";
if (!File.Exists(font_filename))
File.WriteAllBytes(font_filename, Resources.LcdSolidFont);
PrivateFontCollection pfc = new PrivateFontCollection();
pfc.AddFontFile(font_filename);
LWG_FONT = pfc.Families[0];
Application.Run(OverlayForm.Instance);
}
else
{
Process current = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName(current.ProcessName))
{
if (process.Id != current.Id)
{
var clientMainWindow = GetWindows(process.Handle).Where(window => window.WinTitle == "Littlewargame").First();
SetForegroundWindow(clientMainWindow.MainWindowHandle);
break;
}
}
}
}
}

private static bool Callback(IntPtr hWnd, int lparam)
{
StringBuilder sb = new StringBuilder(256);
int res = GetWindowText(hWnd, sb, 256);
_WinStructList.Add(new WinStruct { MainWindowHandle = hWnd, WinTitle = sb.ToString() });
return true;
}

private static List<WinStruct> GetWindows(IntPtr pHandle)
{
_WinStructList = new List<WinStruct>();
EnumWindows(callBackPtr, pHandle);
return _WinStructList;
}
}

internal struct WinStruct
{
internal string? WinTitle;
internal IntPtr MainWindowHandle;
}
}

0 comments on commit b0c9672

Please sign in to comment.