Skip to content

Commit

Permalink
Merge pull request #591 from CnCNet/develop
Browse files Browse the repository at this point in the history
Release 2.11.2.0
  • Loading branch information
SadPencil authored Dec 6, 2024
2 parents e62a850 + b47495f commit 14cd841
Show file tree
Hide file tree
Showing 770 changed files with 76,398 additions and 13,344 deletions.
21 changes: 19 additions & 2 deletions ClientCore/ClientConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class ClientConfiguration
private const string SETTINGS = "Settings";
private const string LINKS = "Links";
private const string TRANSLATIONS = "Translations";
private const string USER_DEFAULTS = "UserDefaults";

private const string CLIENT_SETTINGS = "DTACnCNetClient.ini";
private const string GAME_OPTIONS = "GameOptions.ini";
Expand Down Expand Up @@ -193,7 +194,8 @@ public void RefreshSettings()

public int MaximumRenderHeight => clientDefinitionsIni.GetIntValue(SETTINGS, "MaximumRenderHeight", 800);

public string[] RecommendedResolutions => clientDefinitionsIni.GetStringValue(SETTINGS, "RecommendedResolutions", "1280x720,2560x1440,3840x2160").Split(',');
public string[] RecommendedResolutions => clientDefinitionsIni.GetStringValue(SETTINGS, "RecommendedResolutions",
$"{MinimumRenderWidth}x{MinimumRenderHeight},{MaximumRenderWidth}x{MaximumRenderHeight}").Split(',');

public string WindowTitle => clientDefinitionsIni.GetStringValue(SETTINGS, "WindowTitle", string.Empty)
.L10N("INI:ClientDefinitions:WindowTitle");
Expand Down Expand Up @@ -387,6 +389,11 @@ public IEnumerable<string> SupplementalMapFileExtensions
/// </summary>
public bool DisallowJoiningIncompatibleGames => clientDefinitionsIni.GetBooleanValue(SETTINGS, nameof(DisallowJoiningIncompatibleGames), false);

/// <summary>
/// Activates warnings for development builds of XNA Client
/// </summary>
public bool ShowDevelopmentBuildWarnings => clientDefinitionsIni.GetBooleanValue(SETTINGS, nameof(ShowDevelopmentBuildWarnings), true);

#endregion

#region Network definitions
Expand All @@ -405,6 +412,16 @@ public IEnumerable<string> SupplementalMapFileExtensions

#endregion

#region User default settings

public bool UserDefault_BorderlessWindowedClient => clientDefinitionsIni.GetBooleanValue(USER_DEFAULTS, "BorderlessWindowedClient", true);

public bool UserDefault_IntegerScaledClient => clientDefinitionsIni.GetBooleanValue(USER_DEFAULTS, "IntegerScaledClient", false);

public bool UserDefault_WriteInstallationPathToRegistry => clientDefinitionsIni.GetBooleanValue(USER_DEFAULTS, "WriteInstallationPathToRegistry", true);

#endregion

public List<string> GetIRCServers()
{
List<string> servers = [];
Expand All @@ -419,7 +436,7 @@ public List<string> GetIRCServers()
}

public bool DiscordIntegrationGloballyDisabled => string.IsNullOrWhiteSpace(DiscordAppId) || DisableDiscordIntegration;

public OSVersion GetOperatingSystemVersion()
{
#if NETFRAMEWORK
Expand Down
27 changes: 14 additions & 13 deletions ClientCore/CnCNet5/GameCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Reflection;
using Rampastring.Tools;
using SixLabors.ImageSharp;
using ClientCore.Extensions;

namespace ClientCore.CnCNet5
{
Expand Down Expand Up @@ -65,7 +66,7 @@ public void Initialize()
GameBroadcastChannel = "#cncnet-dta-games",
InternalName = "dta",
RegistryInstallPath = "HKCU\\Software\\TheDawnOfTheTiberiumAge",
UIName = "Dawn of the Tiberium Age",
UIName = "Dawn of the Tiberium Age".L10N("Client:Core:DawnoftheTiberiumAge"),
Texture = AssetLoader.TextureFromImage(dtaIcon)
},

Expand All @@ -76,7 +77,7 @@ public void Initialize()
GameBroadcastChannel = "#cncnet-ti-games",
InternalName = "ti",
RegistryInstallPath = "HKCU\\Software\\TwistedInsurrection",
UIName = "Twisted Insurrection",
UIName = "Twisted Insurrection".L10N("Client:Core:TwistedInsurrection"),
Texture = AssetLoader.TextureFromImage(tiIcon)
},

Expand All @@ -87,7 +88,7 @@ public void Initialize()
GameBroadcastChannel = "#cncnet-mo-games",
InternalName = "mo",
RegistryInstallPath = "HKCU\\Software\\MentalOmega",
UIName = "Mental Omega",
UIName = "Mental Omega".L10N("Client:Core:MentalOmega"),
Texture = AssetLoader.TextureFromImage(moIcon)
},

Expand All @@ -98,7 +99,7 @@ public void Initialize()
GameBroadcastChannel = "#redres-games",
InternalName = "rr",
RegistryInstallPath = "HKLM\\Software\\RedResurrection",
UIName = "YR Red-Resurrection",
UIName = "YR Red-Resurrection".L10N("Client:Core:YRRedResurrection"),
Texture = AssetLoader.TextureFromImage(rrIcon)
},

Expand All @@ -109,7 +110,7 @@ public void Initialize()
GameBroadcastChannel = "#rote-games",
InternalName = "re",
RegistryInstallPath = "HKLM\\Software\\RiseoftheEast",
UIName = "Rise of the East",
UIName = "Rise of the East".L10N("Client:Core:RiseoftheEast"),
Texture = AssetLoader.TextureFromImage(reIcon)
},

Expand All @@ -120,7 +121,7 @@ public void Initialize()
GameBroadcastChannel = "#cncreloaded-games",
InternalName = "cncr",
RegistryInstallPath = "HKCU\\Software\\CnCReloaded",
UIName = "C&C: Reloaded",
UIName = "C&C: Reloaded".L10N("Client:Core:CnCReloaded"),
Texture = AssetLoader.TextureFromImage(cncrIcon)
},

Expand All @@ -131,7 +132,7 @@ public void Initialize()
GameBroadcastChannel = "#cncnet-td-games",
InternalName = "td",
RegistryInstallPath = "HKLM\\Software\\Westwood\\Tiberian Dawn",
UIName = "Tiberian Dawn",
UIName = "Tiberian Dawn".L10N("Client:Core:TiberianDawn"),
Texture = AssetLoader.TextureFromImage(tdIcon),
Supported = false
},
Expand All @@ -143,7 +144,7 @@ public void Initialize()
GameBroadcastChannel = "#cncnet-ra-games",
InternalName = "ra",
RegistryInstallPath = "HKLM\\Software\\Westwood\\Red Alert",
UIName = "Red Alert",
UIName = "Red Alert".L10N("Client:Core:RedAlert"),
Texture = AssetLoader.TextureFromImage(raIcon),
Supported = false
},
Expand All @@ -155,7 +156,7 @@ public void Initialize()
GameBroadcastChannel = "#cncnet-d2k-games",
InternalName = "d2k",
RegistryInstallPath = "HKLM\\Software\\Westwood\\Dune 2000",
UIName = "Dune 2000",
UIName = "Dune 2000".L10N("Client:Core:Dune2000"),
Texture = AssetLoader.TextureFromImage(d2kIcon),
Supported = false
},
Expand All @@ -167,7 +168,7 @@ public void Initialize()
GameBroadcastChannel = "#cncnet-ts-games",
InternalName = "ts",
RegistryInstallPath = "HKLM\\Software\\Westwood\\Tiberian Sun",
UIName = "Tiberian Sun",
UIName = "Tiberian Sun".L10N("Client:Core:TiberianSun"),
Texture = AssetLoader.TextureFromImage(tsIcon)
},

Expand All @@ -178,7 +179,7 @@ public void Initialize()
GameBroadcastChannel = "#cncnet-yr-games",
InternalName = "yr",
RegistryInstallPath = "HKLM\\Software\\Westwood\\Yuri's Revenge",
UIName = "Yuri's Revenge",
UIName = "Yuri's Revenge".L10N("Client:Core:YurisRevenge"),
Texture = AssetLoader.TextureFromImage(yrIcon)
},

Expand All @@ -189,7 +190,7 @@ public void Initialize()
GameBroadcastChannel = "#cncnet-ss-games",
InternalName = "ss",
RegistryInstallPath = "HKLM\\Software\\Westwood\\Sole Survivor",
UIName = "Sole Survivor",
UIName = "Sole Survivor".L10N("Client:Core:SoleSurvivor"),
Texture = AssetLoader.TextureFromImage(ssIcon),
Supported = false
}
Expand All @@ -202,7 +203,7 @@ public void Initialize()
{
ChatChannel = "#cncnet",
InternalName = "cncnet",
UIName = "General CnCNet Chat",
UIName = "General CnCNet Chat".L10N("Client:Core:GeneralCnCNetChat"),
AlwaysEnabled = true,
Texture = AssetLoader.TextureFromImage(cncnetIcon)
}
Expand Down
94 changes: 94 additions & 0 deletions ClientCore/FileHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading.Tasks;

using ClientCore.Extensions;

using Rampastring.Tools;

namespace ClientCore
{
public class FileHelper
{

/// <summary>
/// Establishes a hard link between an existing file and a new file. This function is only supported on the NTFS file system, and only for files, not directories.
/// <br/>
/// https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createhardlinkw
/// </summary>
/// <param name="lpFileName">The name of the new file.</param>
/// <param name="lpExistingFileName">The name of the existing file.</param>
/// <param name="lpSecurityAttributes">Reserved; must be NULL.</param>
/// <returns>If the function succeeds, the return value is nonzero. If the function fails, the return value is zero (0).</returns>
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "CreateHardLinkW")]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[SupportedOSPlatform("windows")]
private static extern bool CreateHardLink(string lpFileName, string lpExistingFileName, IntPtr lpSecurityAttributes);

/// <summary>
/// The link function makes a new link to the existing file named by oldname, under the new name newname.
/// <br/>
/// https://www.gnu.org/software/libc/manual/html_node/Hard-Links.html
/// <param name="oldname"></param>
/// <param name="newname"></param>
/// <returns>This function returns a value of 0 if it is successful and -1 on failure.</returns>
[DllImport("libc", EntryPoint = "link", SetLastError = true)]
[SupportedOSPlatform("linux")]
[SupportedOSPlatform("osx")]
private static extern int link([MarshalAs(UnmanagedType.LPUTF8Str)] string oldname, [MarshalAs(UnmanagedType.LPUTF8Str)] string newname);

/// <summary>
/// Creates hard link to the source file or copy that file, if got an error.
/// </summary>
/// <param name="source"></param>
/// <param name="destination"></param>
/// <param name="fallback"></param>
/// <exception cref="IOException"></exception>
/// <exception cref="PlatformNotSupportedException"></exception>
public static void CreateHardLinkFromSource(string source, string destination, bool fallback = true)
{
if (fallback)
{
try
{
CreateHardLinkFromSource(source, destination, fallback: false);
}
catch (Exception ex)
{
Logger.Log($"Failed to create hard link at {destination}. Fallback to copy. {ex.Message}");
File.Copy(source, destination, true);
}

return;
}

if (File.Exists(destination))
{
FileInfo destinationFile = new(destination);
destinationFile.IsReadOnly = false;
destinationFile.Delete();
}

if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
if (!CreateHardLink(destination, source, IntPtr.Zero))
Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
if (link(source, destination) != 0)
throw new IOException(string.Format("Unable to create hard link at {0} with the following error code: {1}"
.L10N("Client:DTAConfig:CreateHardLinkFailed"), destination, Marshal.GetLastWin32Error()));
}
else
{
throw new PlatformNotSupportedException();
}
}
}
}
6 changes: 4 additions & 2 deletions ClientCore/Settings/UserINISettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ protected UserINISettings(IniFile iniFile)
Renderer = new StringSetting(iniFile, COMPATIBILITY, "Renderer", string.Empty);
WindowedMode = new BoolSetting(iniFile, VIDEO, WINDOWED_MODE_KEY, false);
BorderlessWindowedMode = new BoolSetting(iniFile, VIDEO, "NoWindowFrame", false);
BorderlessWindowedClient = new BoolSetting(iniFile, VIDEO, "BorderlessWindowedClient", true);
BorderlessWindowedClient = new BoolSetting(iniFile, VIDEO, "BorderlessWindowedClient", ClientConfiguration.Instance.UserDefault_BorderlessWindowedClient);
IntegerScaledClient = new BoolSetting(iniFile, VIDEO, "IntegerScaledClient", ClientConfiguration.Instance.UserDefault_IntegerScaledClient);
ClientFPS = new IntSetting(iniFile, VIDEO, "ClientFPS", 60);
DisplayToggleableExtraTextures = new BoolSetting(iniFile, VIDEO, "DisplayToggleableExtraTextures", true);

Expand All @@ -86,7 +87,7 @@ protected UserINISettings(IniFile iniFile)
ChatColor = new IntSetting(iniFile, MULTIPLAYER, "ChatColor", -1);
LANChatColor = new IntSetting(iniFile, MULTIPLAYER, "LANChatColor", -1);
PingUnofficialCnCNetTunnels = new BoolSetting(iniFile, MULTIPLAYER, "PingCustomTunnels", true);
WritePathToRegistry = new BoolSetting(iniFile, OPTIONS, "WriteInstallationPathToRegistry", true);
WritePathToRegistry = new BoolSetting(iniFile, OPTIONS, "WriteInstallationPathToRegistry", ClientConfiguration.Instance.UserDefault_WriteInstallationPathToRegistry);
PlaySoundOnGameHosted = new BoolSetting(iniFile, MULTIPLAYER, "PlaySoundOnGameHosted", true);
SkipConnectDialog = new BoolSetting(iniFile, MULTIPLAYER, "SkipConnectDialog", false);
PersistentMode = new BoolSetting(iniFile, MULTIPLAYER, "PersistentMode", false);
Expand Down Expand Up @@ -151,6 +152,7 @@ protected UserINISettings(IniFile iniFile)
public IntSetting ClientResolutionX { get; set; }
public IntSetting ClientResolutionY { get; set; }
public BoolSetting BorderlessWindowedClient { get; private set; }
public BoolSetting IntegerScaledClient { get; private set; }
public IntSetting ClientFPS { get; private set; }
public BoolSetting DisplayToggleableExtraTextures { get; private set; }

Expand Down
22 changes: 22 additions & 0 deletions ClientGUI/XNAClientToggleButton.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using Microsoft.Xna.Framework.Graphics;
using Rampastring.Tools;
using Rampastring.XNAUI;
using Rampastring.XNAUI.XNAControls;

Expand Down Expand Up @@ -66,5 +67,26 @@ public void SetToolTipText(string text)
public XNAClientToggleButton(WindowManager windowManager) : base(windowManager)
{
}

protected override void ParseControlINIAttribute(IniFile iniFile, string key, string value)
{
switch (key)
{
case nameof(CheckedTexture):
CheckedTexture = AssetLoader.LoadTexture(value);
UpdateIdleTexture();
break;
case nameof(UncheckedTexture):
UncheckedTexture = AssetLoader.LoadTexture(value);
UpdateIdleTexture();
break;
case nameof(ToolTip):
SetToolTipText(value);
break;
default:
base.ParseControlINIAttribute(iniFile, key, value);
break;
}
}
}
}
2 changes: 1 addition & 1 deletion ClientUpdater/Updater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ internal static void UpdateUserAgent(HttpClient httpClient)
if (UpdaterVersion != "N/A")
httpClient.DefaultRequestHeaders.UserAgent.Add(new(nameof(Updater), UpdaterVersion));

httpClient.DefaultRequestHeaders.UserAgent.Add(new("Client", Assembly.GetEntryAssembly().GetName().Version.ToString()));
httpClient.DefaultRequestHeaders.UserAgent.Add(new("Client", GitVersionInformation.AssemblySemVer));
}

/// <summary>
Expand Down
12 changes: 10 additions & 2 deletions DTAConfig/DirectDrawWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,12 +163,20 @@ public bool IsCompatibleWithOS(OSVersion os)
/// </summary>
public void Apply()
{
string ddrawDllSourcePath = SafePath.CombineFilePath(ProgramConstants.GetBaseResourcePath(), ddrawDLLPath);
string ddrawDllTargetPath = SafePath.CombineFilePath(ProgramConstants.GamePath, "ddraw.dll");

if (!string.IsNullOrEmpty(ddrawDLLPath))
{
File.Copy(SafePath.CombineFilePath(ProgramConstants.GetBaseResourcePath(), ddrawDLLPath), SafePath.CombineFilePath(ProgramConstants.GamePath, "ddraw.dll"), true);
FileHelper.CreateHardLinkFromSource(ddrawDllSourcePath, ddrawDllTargetPath);
new FileInfo(ddrawDllSourcePath).IsReadOnly = true;
new FileInfo(ddrawDllTargetPath).IsReadOnly = true;
}
else
File.Delete(SafePath.CombineFilePath(ProgramConstants.GamePath, "ddraw.dll"));
{
new FileInfo(ddrawDllTargetPath).IsReadOnly = false;
File.Delete(ddrawDllTargetPath);
}


if (!string.IsNullOrEmpty(ConfigFileName) && !string.IsNullOrEmpty(resConfigFileName)
Expand Down
Loading

0 comments on commit 14cd841

Please sign in to comment.