From c9c40f75322299bb020274ace6eb79e59718885b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Tue, 21 Dec 2021 17:22:02 +0100 Subject: [PATCH] feat: add name changer packet interceptor sample --- NosSmooth.sln | 37 +++++++++- Samples/InterceptNameChanger/DllMain.cs | 46 ++++++++++++ Samples/InterceptNameChanger/FodyWeavers.xml | 3 + .../InterceptNameChanger.csproj | 67 +++++++++++++++++ .../NameChangeInterceptor.cs | 73 +++++++++++++++++++ Samples/InterceptNameChanger/NameChanger.cs | 69 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 41 +++++++++++ 7 files changed, 335 insertions(+), 1 deletion(-) create mode 100644 Samples/InterceptNameChanger/DllMain.cs create mode 100644 Samples/InterceptNameChanger/FodyWeavers.xml create mode 100644 Samples/InterceptNameChanger/InterceptNameChanger.csproj create mode 100644 Samples/InterceptNameChanger/NameChangeInterceptor.cs create mode 100644 Samples/InterceptNameChanger/NameChanger.cs create mode 100644 Samples/InterceptNameChanger/Properties/AssemblyInfo.cs diff --git a/NosSmooth.sln b/NosSmooth.sln index 25d412e..593d5c1 100644 --- a/NosSmooth.sln +++ b/NosSmooth.sln @@ -36,6 +36,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".metadata", ".metadata", "{ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleChat", "Samples\SimpleChat\SimpleChat.csproj", "{4017A4F4-5E59-48AA-A7D0-A8518148933A}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tets", "Tets", "{C6A8760D-92CB-4307-88A7-36CCAEBA4AD1}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NosCore.Packets.Tests", "libs\NosCore.Packets\test\NosCore.Packets.Tests\NosCore.Packets.Tests.csproj", "{726188BA-F0EA-4ECA-ACF4-CCC066464FF0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InterceptNameChanger", "Samples\InterceptNameChanger\InterceptNameChanger.csproj", "{F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LowLevel", "LowLevel", "{9025731C-084E-4E82-8CD4-0F52D3AA1F54}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -164,6 +172,30 @@ Global {4017A4F4-5E59-48AA-A7D0-A8518148933A}.Release|x64.Build.0 = Release|Any CPU {4017A4F4-5E59-48AA-A7D0-A8518148933A}.Release|x86.ActiveCfg = Release|Any CPU {4017A4F4-5E59-48AA-A7D0-A8518148933A}.Release|x86.Build.0 = Release|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Debug|x64.ActiveCfg = Debug|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Debug|x64.Build.0 = Debug|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Debug|x86.ActiveCfg = Debug|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Debug|x86.Build.0 = Debug|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Release|Any CPU.Build.0 = Release|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Release|x64.ActiveCfg = Release|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Release|x64.Build.0 = Release|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Release|x86.ActiveCfg = Release|Any CPU + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0}.Release|x86.Build.0 = Release|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Debug|x64.ActiveCfg = Debug|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Debug|x64.Build.0 = Debug|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Debug|x86.ActiveCfg = Debug|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Debug|x86.Build.0 = Debug|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Release|Any CPU.Build.0 = Release|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Release|x64.ActiveCfg = Release|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Release|x64.Build.0 = Release|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Release|x86.ActiveCfg = Release|Any CPU + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -177,7 +209,10 @@ Global {63E97FF3-7E40-44DE-9E91-F5DEE79AF95F} = {6078AE6E-7CD0-48E4-84E0-EB164D8881DA} {27DF38DF-AC58-4039-A91C-824D829ECECD} = {01B5E872-271F-4D30-A1AA-AD48D81840C5} {945E9248-C150-4617-AB0F-1450561859E3} = {01B5E872-271F-4D30-A1AA-AD48D81840C5} - {4017A4F4-5E59-48AA-A7D0-A8518148933A} = {F20FE754-FDEA-4F3A-93D4-0750CB9EBB33} + {726188BA-F0EA-4ECA-ACF4-CCC066464FF0} = {C6A8760D-92CB-4307-88A7-36CCAEBA4AD1} + {9025731C-084E-4E82-8CD4-0F52D3AA1F54} = {F20FE754-FDEA-4F3A-93D4-0750CB9EBB33} + {F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A} = {9025731C-084E-4E82-8CD4-0F52D3AA1F54} + {4017A4F4-5E59-48AA-A7D0-A8518148933A} = {9025731C-084E-4E82-8CD4-0F52D3AA1F54} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C5F46653-4DEC-429B-8580-4ED18ED9B4CA} diff --git a/Samples/InterceptNameChanger/DllMain.cs b/Samples/InterceptNameChanger/DllMain.cs new file mode 100644 index 0000000..c01e6e1 --- /dev/null +++ b/Samples/InterceptNameChanger/DllMain.cs @@ -0,0 +1,46 @@ +// +// DllMain.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Runtime.InteropServices; +using System.Threading; + +namespace InterceptNameChanger +{ + /// + /// The main entrypoint class of the dll. + /// + public class DllMain + { + [DllImport("kernel32")] +#pragma warning disable SA1600 + public static extern bool AllocConsole(); +#pragma warning restore SA1600 + + /// + /// The main entrypoint method of the dll. + /// + /// The handle of the module. + [DllExport] + public static void Main(IntPtr handle) + { + AllocConsole(); + Console.WriteLine("Hello from InterceptNameChanger DllMain entry point."); + + new Thread(() => + { + try + { + new NameChanger().RunAsync().GetAwaiter().GetResult(); + } + catch (Exception e) + { + Console.WriteLine(e.ToString()); + } + }).Start(); + } + } +} \ No newline at end of file diff --git a/Samples/InterceptNameChanger/FodyWeavers.xml b/Samples/InterceptNameChanger/FodyWeavers.xml new file mode 100644 index 0000000..5029e70 --- /dev/null +++ b/Samples/InterceptNameChanger/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/Samples/InterceptNameChanger/InterceptNameChanger.csproj b/Samples/InterceptNameChanger/InterceptNameChanger.csproj new file mode 100644 index 0000000..6a226ab --- /dev/null +++ b/Samples/InterceptNameChanger/InterceptNameChanger.csproj @@ -0,0 +1,67 @@ + + + net48 + enable + enable + 10 + + + 89E4EE92-5848-4390-A6A7-34972FE923F5 + DllExport.dll + InterceptNameChanger + true + x86 + 7 + false + false + false + false + 30000 + 2 + 0 + 0 + 0 + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + 1.7.4 + false + 1 + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)packages\DllExport.1.7.4\gcache\$(DllExportMetaXBase)\$(DllExportNamespace)\$(DllExportMetaLibName) + False + False + + + + + + + \ No newline at end of file diff --git a/Samples/InterceptNameChanger/NameChangeInterceptor.cs b/Samples/InterceptNameChanger/NameChangeInterceptor.cs new file mode 100644 index 0000000..46419fe --- /dev/null +++ b/Samples/InterceptNameChanger/NameChangeInterceptor.cs @@ -0,0 +1,73 @@ +// +// NameChangeInterceptor.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Microsoft.Extensions.Logging; +using NosCore.Packets.Enumerations; +using NosCore.Packets.ServerPackets.Chats; +using NosSmooth.Core.Client; +using NosSmooth.LocalClient; + +namespace InterceptNameChanger +{ + /// + /// Intercepts the packets so name in c_info may be replaced. + /// + public class NameChangeInterceptor : IPacketInterceptor + { + private readonly INostaleClient _client; + private readonly ILogger _logger; + private string _name = "Intercept"; + + /// + /// Initializes a new instance of the class. + /// + /// The nostale client. + /// The logger. + public NameChangeInterceptor(INostaleClient client, ILogger logger) + { + _client = client; + _logger = logger; + } + + /// + public bool InterceptSend(ref string packet) + { + if (packet.StartsWith("say #")) + { + _name = packet.Substring(5).Replace(" ", "⠀"); // Mind the symbols! + _logger.LogInformation("Name changed to {Name}", _name); + _client.ReceivePacketAsync(new SayPacket() + { + Message = $"Name changed to {_name}, change map for it to take effect.", + Type = SayColorType.Red + }).GetAwaiter().GetResult(); + return false; + } + + return true; // Accept the packet + } + + /// + public bool InterceptReceive(ref string packet) + { + if (packet.StartsWith("c_info")) + { + var oldPart = packet.Substring(packet.IndexOf(' ', 7)); + var result = _client.ReceivePacketAsync($"c_info {_name} " + oldPart) + .GetAwaiter().GetResult(); // Change the name + + if (!result.IsSuccess) + { + _logger.LogError("Could not send the c_info packet: {Reason}", result.Error.Message); + return true; // Accept the packet so client is not confused + } + return false; // Reject the packet + } + + return true; // Accept the packet + } + } +} \ No newline at end of file diff --git a/Samples/InterceptNameChanger/NameChanger.cs b/Samples/InterceptNameChanger/NameChanger.cs new file mode 100644 index 0000000..caaf0fd --- /dev/null +++ b/Samples/InterceptNameChanger/NameChanger.cs @@ -0,0 +1,69 @@ +// +// NameChanger.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using NosCore.Packets.Enumerations; +using NosCore.Packets.ServerPackets.Chats; +using NosCore.Shared.Enumerations; +using NosSmooth.Core.Client; +using NosSmooth.Core.Packets; +using NosSmooth.LocalClient; +using NosSmooth.LocalClient.Extensions; + +namespace InterceptNameChanger +{ + /// + /// Main class of name changer. + /// + public class NameChanger + { + /// + /// Run the name changer. + /// + /// A task that may or may not have succeeded. + public async Task RunAsync() + { + var provider = new ServiceCollection() + .AddLocalClient() + + // .AddPacketResponder() + .AddLogging(b => + { + b.ClearProviders(); + b.AddConsole(); + b.SetMinimumLevel(LogLevel.Debug); + }) + .Configure(o => o.AllowIntercept = true) + .AddSingleton() + .BuildServiceProvider(); + + var dummy1 = provider.GetRequiredService().ServerSerializer; + var dummy2 = provider.GetRequiredService().ClientSerializer; + + var logger = provider.GetRequiredService>(); + logger.LogInformation("Hello world from NameChanger!"); + + var client = provider.GetRequiredService(); + + var sayResult = await client.ReceivePacketAsync(new SayPacket() + { + Message = "The name may be changed by typing #{NewName} into the chat.", + VisualType = VisualType.Map, + Type = SayColorType.Red, + VisualId = 1, + }); + + if (!sayResult.IsSuccess) + { + logger.LogError("Could not send say packet"); + } + + await client.RunAsync(); + } + } +} \ No newline at end of file diff --git a/Samples/InterceptNameChanger/Properties/AssemblyInfo.cs b/Samples/InterceptNameChanger/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..2501ebf --- /dev/null +++ b/Samples/InterceptNameChanger/Properties/AssemblyInfo.cs @@ -0,0 +1,41 @@ +// +// AssemblyInfo.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("InterceptNameChanger")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("InterceptNameChanger")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("F96F3AA0-131E-4B6B-AB21-BBE2DEBCEF3A")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file -- 2.48.1