Skip to content

Commit 8c83527

Browse files
authored
Merge pull request #742 from CnCNet/develop
Release 2.12.4
2 parents 56f79a9 + 2373f7c commit 8c83527

12 files changed

Lines changed: 115 additions & 25 deletions

File tree

ClientCore/ClientConfiguration.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ public void RefreshSettings()
260260

261261
public string StatisticsLogFileName => clientDefinitionsIni.GetStringValue(SETTINGS, "StatisticsLogFileName", "DTA.LOG");
262262

263+
public string[] TrustedDomains => clientDefinitionsIni.GetStringValue(SETTINGS, "TrustedDomains", string.Empty).Split(',');
264+
265+
public string[] AlwaysTrustedDomains = {"cncnet.org", "gamesurge.net", "dronebl.org", "discord.com", "youtube.com", "youtu.be"};
266+
263267
public (string Name, string Path) GetThemeInfoFromIndex(int themeIndex) => clientDefinitionsIni.GetStringValue("Themes", themeIndex.ToString(), ",").Split(',').AsTuple2();
264268

265269
/// <summary>

ClientCore/FileHelper.cs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Threading.Tasks;
99

1010
using ClientCore.Extensions;
11+
using ClientCore.PlatformShim;
1112

1213
using Rampastring.Tools;
1314

@@ -91,17 +92,22 @@ public static void CreateHardLinkFromSource(string source, string destination, b
9192
}
9293
}
9394

94-
public static Encoding GetEncoding(string filename)
95+
public static Encoding GetEncoding(string filename, float minimalConfidence = 0.5f)
9596
{
96-
Encoding encoding = new UTF8Encoding(false);
97+
Encoding encoding = EncodingExt.UTF8NoBOM;
9798

9899
using (FileStream fs = File.OpenRead(filename))
99100
{
100101
Ude.CharsetDetector cdet = new Ude.CharsetDetector();
101102
cdet.Feed(fs);
102103
cdet.DataEnd();
103-
if (cdet.Charset != null)
104-
encoding = Encoding.GetEncoding(cdet.Charset);
104+
if (cdet.Charset != null && cdet.Confidence > minimalConfidence)
105+
{
106+
Encoding detectedEncoding = Encoding.GetEncoding(cdet.Charset);
107+
108+
if (detectedEncoding is not UTF8Encoding and not ASCIIEncoding)
109+
encoding = detectedEncoding;
110+
}
105111
}
106112

107113
return encoding;

ClientCore/PlatformShim/EncodingExt.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ static EncodingExt()
1616
/// ANSI doesn't mean a specific codepage, it means the default non-Unicode codepage which can be changed from Control Panel.
1717
/// </summary>
1818
public static Encoding ANSI { get; }
19+
20+
public static Encoding UTF8NoBOM { get; } = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false);
1921
}

DXMainClient/DXGUI/Generic/MainMenu.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,7 @@ private void CheckRequiredFiles()
438438
if (absentFiles.Count > 0)
439439
{
440440
string description = string.Empty;
441-
if (ClientConfiguration.Instance.ClientGameType == ClientType.YR)
441+
if (ClientConfiguration.Instance.ClientGameType == ClientType.Ares)
442442
{
443443
description = ("You are missing Yuri's Revenge files that are required\n" +
444444
"to play this mod! Yuri's Revenge mods are not standalone,\n" +

DXMainClient/DXGUI/Multiplayer/ChatListBox.cs

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
using System;
66
using ClientCore;
77
using ClientCore.Extensions;
8+
using ClientGUI;
9+
using System.Linq;
10+
using Rampastring.Tools;
811

912
namespace DTAClient.DXGUI.Multiplayer
1013
{
@@ -24,11 +27,53 @@ private void ChatListBox_DoubleLeftClick(object sender, EventArgs e)
2427
if (SelectedIndex < 0 || SelectedIndex >= Items.Count)
2528
return;
2629

27-
var link = Items[SelectedIndex].Text?.GetLink();
30+
// Get the clicked link
31+
string link = Items[SelectedIndex].Text?.GetLink();
2832
if (link == null)
2933
return;
3034

31-
ProcessLauncher.StartShellProcess(link);
35+
// Determine if the link is trusted
36+
bool isTrusted = false;
37+
try
38+
{
39+
string domain = new Uri(link).Host;
40+
var trustedDomains = ClientConfiguration.Instance.TrustedDomains.Concat(ClientConfiguration.Instance.AlwaysTrustedDomains);
41+
isTrusted = trustedDomains.Contains(domain, StringComparer.InvariantCultureIgnoreCase)
42+
|| trustedDomains.Any(trustedDomain => domain.EndsWith("." + trustedDomain, StringComparison.InvariantCultureIgnoreCase));
43+
}
44+
catch (Exception ex)
45+
{
46+
isTrusted = false;
47+
Logger.Log($"Error in parsing the URL \"{link}\": {ex.ToString()}");
48+
}
49+
50+
if (isTrusted)
51+
{
52+
ProcessLink(link);
53+
return;
54+
}
55+
56+
// Show the warning if the link is not trusted
57+
var msgBox = new XNAMessageBox(WindowManager,
58+
"Open Link Confirmation".L10N("Client:Main:OpenLinkConfirmationTitle"),
59+
"""
60+
You're about to open a link shared in chat.
61+
62+
Please note that this link hasn't been verified,
63+
and CnCNet is not responsible for its content.
64+
65+
Would you like to open the following link in your browser?
66+
""".L10N("Client:Main:OpenLinkConfirmationText")
67+
+ Environment.NewLine + Environment.NewLine + link,
68+
XNAMessageBoxButtons.YesNo);
69+
msgBox.YesClickedAction = (msgBox) => ProcessLink(link);
70+
msgBox.Show();
71+
}
72+
73+
private void ProcessLink(string link)
74+
{
75+
if (link != null)
76+
ProcessLauncher.StartShellProcess(link);
3277
}
3378

3479
public void AddMessage(string message)
@@ -49,7 +94,7 @@ public void AddMessage(ChatMessage message)
4994
Selectable = true,
5095
Tag = message
5196
};
52-
97+
5398
if (message.SenderName == null)
5499
{
55100
listBoxItem.Text = Renderer.GetSafeString(string.Format("[{0}] {1}",
@@ -61,7 +106,7 @@ public void AddMessage(ChatMessage message)
61106
listBoxItem.Text = Renderer.GetSafeString(string.Format("[{0}] {1}: {2}",
62107
message.DateTime.ToShortTimeString(), message.SenderName, message.Message), FontIndex);
63108
}
64-
109+
65110
AddItem(listBoxItem);
66111

67112
if (LastIndex >= Items.Count - 2)

DXMainClient/DXGUI/Multiplayer/GameLobby/MapCodeHelper.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Text;
5+
46
using ClientCore;
7+
using ClientCore.PlatformShim;
8+
59
using DTAClient.Domain.Multiplayer;
10+
611
using Rampastring.Tools;
712

813
namespace DTAClient.DXGUI.Multiplayer.GameLobby
@@ -17,14 +22,20 @@ public static class MapCodeHelper
1722
/// <param name="gameMode">Currently selected gamemode, if set.</param>
1823
public static void ApplyMapCode(IniFile mapIni, string customIniPath, GameMode gameMode)
1924
{
20-
IniFile associatedIni = new IniFile(SafePath.CombineFilePath(ProgramConstants.GamePath, customIniPath));
25+
string associatedIniPath = SafePath.CombineFilePath(ProgramConstants.GamePath, customIniPath);
26+
Encoding associatedIniEncoding = ClientConfiguration.Instance.ClientGameType == ClientCore.Enums.ClientType.TS ? FileHelper.GetEncoding(associatedIniPath) : EncodingExt.UTF8NoBOM;
27+
IniFile associatedIni = new IniFile(associatedIniPath, associatedIniEncoding);
2128
string extraIniName = null;
2229
if (gameMode != null)
2330
extraIniName = associatedIni.GetStringValue("GameModeIncludes", gameMode.Name, null);
2431
associatedIni.EraseSectionKeys("GameModeIncludes");
2532
ApplyMapCode(mapIni, associatedIni);
2633
if (!String.IsNullOrEmpty(extraIniName))
27-
ApplyMapCode(mapIni, new IniFile(SafePath.CombineFilePath(ProgramConstants.GamePath, extraIniName)));
34+
{
35+
string extraIniPath = SafePath.CombineFilePath(ProgramConstants.GamePath, extraIniName);
36+
Encoding extraIniEncoding = ClientConfiguration.Instance.ClientGameType == ClientCore.Enums.ClientType.TS ? FileHelper.GetEncoding(extraIniPath) : EncodingExt.UTF8NoBOM;
37+
ApplyMapCode(mapIni, new IniFile(extraIniPath, extraIniEncoding));
38+
}
2839
}
2940

3041
/// <summary>

DXMainClient/DXMainClient.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
<Prefer32Bit Condition="'$(Engine)' == 'WindowsXNA' And '$(TargetFrameworkIdentifier)' == '.NETFramework'">true</Prefer32Bit>
77
<UseAppHost>false</UseAppHost>
88
<SelfContained>false</SelfContained>
9-
<Description>CnCNet Main Client Library</Description>
9+
<Description>CnCNet Main Client</Description>
10+
<AssemblyTitle>CnCNet Client</AssemblyTitle>
1011
<RootNamespace>DTAClient</RootNamespace>
1112
<ApplicationIcon>clienticon.ico</ApplicationIcon>
1213
<ApplicationHighDpiMode Condition="'$(Engine)' == 'UniversalGL' OR '$(Engine)' == 'WindowsGL'">SystemAware</ApplicationHighDpiMode>

DXMainClient/Domain/Multiplayer/Map.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using static System.Collections.Specialized.BitVector32;
1717
using System.Diagnostics;
1818
using System.Text;
19+
using ClientCore.PlatformShim;
1920

2021
namespace DTAClient.Domain.Multiplayer
2122
{
@@ -712,15 +713,15 @@ public Texture2D LoadPreviewTexture()
712713

713714
public IniFile GetMapIni()
714715
{
715-
Encoding encoding = FileHelper.GetEncoding(CompleteFilePath);
716+
Encoding mapIniEncoding = ClientConfiguration.Instance.ClientGameType == ClientCore.Enums.ClientType.TS ? FileHelper.GetEncoding(CompleteFilePath) : EncodingExt.UTF8NoBOM;
716717

717-
var mapIni = new IniFile(CompleteFilePath, encoding);
718+
var mapIni = new IniFile(CompleteFilePath, mapIniEncoding);
718719

719720
if (!string.IsNullOrEmpty(ExtraININame))
720721
{
721722
string extraIniPath = SafePath.CombineFilePath(ProgramConstants.GamePath, "INI", "Map Code", ExtraININame);
722-
encoding = ClientConfiguration.Instance.ClientGameType == ClientCore.Enums.ClientType.TS ? FileHelper.GetEncoding(extraIniPath) : new UTF8Encoding(false);
723-
var extraIni = new IniFile(extraIniPath, encoding);
723+
Encoding extraIniEncoding = ClientConfiguration.Instance.ClientGameType == ClientCore.Enums.ClientType.TS ? FileHelper.GetEncoding(extraIniPath) : EncodingExt.UTF8NoBOM;
724+
var extraIni = new IniFile(extraIniPath, extraIniEncoding);
724725
IniFile.ConsolidateIniFiles(mapIni, extraIni);
725726
}
726727

Docs/INISystem.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,3 +505,19 @@ Children of [XNAWindow](https://github.com/CnCNet/xna-cncnet-client/blob/develop
505505
RandomBackgroundTextures= ; comma-separated list of strings,
506506
; paths of files to use randomly as BackgroundTexture
507507
```
508+
509+
# Global Config Files
510+
511+
## [ClientDefinition](https://github.com/CnCNet/xna-cncnet-client/blob/develop/ClientCore/ClientConfiguration.cs)
512+
> [!NOTE]
513+
> _TODO work in progress_
514+
515+
The `ClientDefinitions.ini` file defines the client's global settings, including the game type, recommended resolutions and the executable file used to launch the game.
516+
517+
In `ClientDefinitions.ini`:
518+
```ini
519+
[Settings]
520+
TrustedDomains= ; comma-separated list of strings,
521+
; domain names to match links and prevent the message box from appearing before they open by default browser
522+
; example: cncnet.org,github.com,moddb.com
523+
```

Docs/Migration-INI.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ Location=12,189
904904
905905
## Appendix
906906
907-
For completion's sake, below are additional steps required for a complete migration (beyond INI changes) to client version [2.11.0.0][client] from pre-2.11.0.0.
907+
For completion's sake, below are additional steps required for a complete migration (beyond INI changes) to client version [2.11.0.0][client_2.11] from pre-2.11.0.0.
908908

909909
### Update client binary files
910910

0 commit comments

Comments
 (0)