diff --git a/.editorconfig b/.editorconfig index 2261acb..26747b6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -90,8 +90,8 @@ dotnet_style_predefined_type_for_locals_parameters_members = true:warning dotnet_style_predefined_type_for_member_access = true:warning # Modifier preferences dotnet_style_require_accessibility_modifiers = always:warning -csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:warning -visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:warning +csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async:warning +visual_basic_preferred_modifier_order = Partial, Default, Private, Protected, Public, Friend, NotOverridable, Overridable, MustOverride, Overloads, Overrides, MustInherit, NotInheritable, Static, Shared, Shadows, ReadOnly, WriteOnly, Dim, Const, WithEvents, Widening, Narrowing, Custom, Async:warning dotnet_style_readonly_field = true:warning # Parentheses preferences dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:warning @@ -274,11 +274,11 @@ dotnet_naming_style.prefix_interface_with_i_style.required_prefix = I dotnet_naming_style.prefix_type_parameters_with_t_style.capitalization = pascal_case dotnet_naming_style.prefix_type_parameters_with_t_style.required_prefix = T # disallowed_style - Anything that has this style applied is marked as disallowed -dotnet_naming_style.disallowed_style.capitalization = pascal_case +dotnet_naming_style.disallowed_style.capitalization = pascal_case dotnet_naming_style.disallowed_style.required_prefix = ____RULE_VIOLATION____ dotnet_naming_style.disallowed_style.required_suffix = ____RULE_VIOLATION____ # internal_error_style - This style should never occur... if it does, it indicates a bug in file or in the parser using the file -dotnet_naming_style.internal_error_style.capitalization = pascal_case +dotnet_naming_style.internal_error_style.capitalization = pascal_case dotnet_naming_style.internal_error_style.required_prefix = ____INTERNAL_ERROR____ dotnet_naming_style.internal_error_style.required_suffix = ____INTERNAL_ERROR____ @@ -291,28 +291,28 @@ dotnet_naming_style.internal_error_style.required_suffix = ____INTERNAL_ERROR___ # All public/protected/protected_internal constant fields must be PascalCase # https://docs.microsoft.com/dotnet/standard/design-guidelines/field dotnet_naming_symbols.public_protected_constant_fields_group.applicable_accessibilities = public, protected, protected_internal -dotnet_naming_symbols.public_protected_constant_fields_group.required_modifiers = const -dotnet_naming_symbols.public_protected_constant_fields_group.applicable_kinds = field -dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.symbols = public_protected_constant_fields_group -dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.style = pascal_case_style -dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.severity = warning +dotnet_naming_symbols.public_protected_constant_fields_group.required_modifiers = const +dotnet_naming_symbols.public_protected_constant_fields_group.applicable_kinds = field +dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.symbols = public_protected_constant_fields_group +dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.style = pascal_case_style +dotnet_naming_rule.public_protected_constant_fields_must_be_pascal_case_rule.severity = warning # All public/protected/protected_internal static readonly fields must be PascalCase # https://docs.microsoft.com/dotnet/standard/design-guidelines/field dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_accessibilities = public, protected, protected_internal -dotnet_naming_symbols.public_protected_static_readonly_fields_group.required_modifiers = static, readonly -dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_kinds = field -dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.symbols = public_protected_static_readonly_fields_group -dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.style = pascal_case_style -dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.severity = warning +dotnet_naming_symbols.public_protected_static_readonly_fields_group.required_modifiers = static, readonly +dotnet_naming_symbols.public_protected_static_readonly_fields_group.applicable_kinds = field +dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.symbols = public_protected_static_readonly_fields_group +dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.style = pascal_case_style +dotnet_naming_rule.public_protected_static_readonly_fields_must_be_pascal_case_rule.severity = warning # No other public/protected/protected_internal fields are allowed # https://docs.microsoft.com/dotnet/standard/design-guidelines/field dotnet_naming_symbols.other_public_protected_fields_group.applicable_accessibilities = public, protected, protected_internal -dotnet_naming_symbols.other_public_protected_fields_group.applicable_kinds = field -dotnet_naming_rule.other_public_protected_fields_disallowed_rule.symbols = other_public_protected_fields_group -dotnet_naming_rule.other_public_protected_fields_disallowed_rule.style = disallowed_style -dotnet_naming_rule.other_public_protected_fields_disallowed_rule.severity = error +dotnet_naming_symbols.other_public_protected_fields_group.applicable_kinds = field +dotnet_naming_rule.other_public_protected_fields_disallowed_rule.symbols = other_public_protected_fields_group +dotnet_naming_rule.other_public_protected_fields_disallowed_rule.style = disallowed_style +dotnet_naming_rule.other_public_protected_fields_disallowed_rule.severity = error ########################################## # StyleCop Field Naming Rules @@ -324,52 +324,52 @@ dotnet_naming_rule.other_public_protected_fields_disallowed_rule.severity # All constant fields must be PascalCase # https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1303.md dotnet_naming_symbols.stylecop_constant_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private -dotnet_naming_symbols.stylecop_constant_fields_group.required_modifiers = const -dotnet_naming_symbols.stylecop_constant_fields_group.applicable_kinds = field -dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.symbols = stylecop_constant_fields_group -dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.style = pascal_case_style -dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.severity = warning +dotnet_naming_symbols.stylecop_constant_fields_group.required_modifiers = const +dotnet_naming_symbols.stylecop_constant_fields_group.applicable_kinds = field +dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.symbols = stylecop_constant_fields_group +dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.style = pascal_case_style +dotnet_naming_rule.stylecop_constant_fields_must_be_pascal_case_rule.severity = warning # All static readonly fields must be PascalCase # https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1311.md dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected, private -dotnet_naming_symbols.stylecop_static_readonly_fields_group.required_modifiers = static, readonly -dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_kinds = field -dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.symbols = stylecop_static_readonly_fields_group -dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.style = pascal_case_style -dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.severity = warning +dotnet_naming_symbols.stylecop_static_readonly_fields_group.required_modifiers = static, readonly +dotnet_naming_symbols.stylecop_static_readonly_fields_group.applicable_kinds = field +dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.symbols = stylecop_static_readonly_fields_group +dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.style = pascal_case_style +dotnet_naming_rule.stylecop_static_readonly_fields_must_be_pascal_case_rule.severity = warning # No non-private instance fields are allowed # https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1401.md dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_accessibilities = public, internal, protected_internal, protected, private_protected -dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_kinds = field -dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.symbols = stylecop_fields_must_be_private_group -dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.style = disallowed_style -dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.severity = error +dotnet_naming_symbols.stylecop_fields_must_be_private_group.applicable_kinds = field +dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.symbols = stylecop_fields_must_be_private_group +dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.style = disallowed_style +dotnet_naming_rule.stylecop_instance_fields_must_be_private_rule.severity = error # Private fields must be camelCase # https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1306.md dotnet_naming_symbols.stylecop_private_fields_group.applicable_accessibilities = private -dotnet_naming_symbols.stylecop_private_fields_group.applicable_kinds = field -dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.symbols = stylecop_private_fields_group -dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.style = camel_case_style -dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.severity = warning +dotnet_naming_symbols.stylecop_private_fields_group.applicable_kinds = field +dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.symbols = stylecop_private_fields_group +dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.style = camel_case_style +dotnet_naming_rule.stylecop_private_fields_must_be_camel_case_rule.severity = warning # Local variables must be camelCase # https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1312.md dotnet_naming_symbols.stylecop_local_fields_group.applicable_accessibilities = local -dotnet_naming_symbols.stylecop_local_fields_group.applicable_kinds = local -dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.symbols = stylecop_local_fields_group -dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.style = camel_case_style -dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.severity = silent +dotnet_naming_symbols.stylecop_local_fields_group.applicable_kinds = local +dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.symbols = stylecop_local_fields_group +dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.style = camel_case_style +dotnet_naming_rule.stylecop_local_fields_must_be_camel_case_rule.severity = silent # This rule should never fire. However, it's included for at least two purposes: # First, it helps to understand, reason about, and root-case certain types of issues, such as bugs in .editorconfig parsers. # Second, it helps to raise immediate awareness if a new field type is added (as occurred recently in C#). dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_accessibilities = * -dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_kinds = field -dotnet_naming_rule.sanity_check_uncovered_field_case_rule.symbols = sanity_check_uncovered_field_case_group -dotnet_naming_rule.sanity_check_uncovered_field_case_rule.style = internal_error_style +dotnet_naming_symbols.sanity_check_uncovered_field_case_group.applicable_kinds = field +dotnet_naming_rule.sanity_check_uncovered_field_case_rule.symbols = sanity_check_uncovered_field_case_group +dotnet_naming_rule.sanity_check_uncovered_field_case_rule.style = internal_error_style dotnet_naming_rule.sanity_check_uncovered_field_case_rule.severity = error @@ -389,30 +389,30 @@ dotnet_naming_rule.sanity_check_uncovered_field_case_rule.severity = error # - Constructors, Properties, Events, Methods # https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-type-members dotnet_naming_symbols.element_group.applicable_kinds = namespace, class, enum, struct, delegate, event, method, property -dotnet_naming_rule.element_rule.symbols = element_group -dotnet_naming_rule.element_rule.style = pascal_case_style -dotnet_naming_rule.element_rule.severity = warning +dotnet_naming_rule.element_rule.symbols = element_group +dotnet_naming_rule.element_rule.style = pascal_case_style +dotnet_naming_rule.element_rule.severity = warning # Interfaces use PascalCase and are prefixed with uppercase 'I' # https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces dotnet_naming_symbols.interface_group.applicable_kinds = interface -dotnet_naming_rule.interface_rule.symbols = interface_group -dotnet_naming_rule.interface_rule.style = prefix_interface_with_i_style -dotnet_naming_rule.interface_rule.severity = warning +dotnet_naming_rule.interface_rule.symbols = interface_group +dotnet_naming_rule.interface_rule.style = prefix_interface_with_i_style +dotnet_naming_rule.interface_rule.severity = warning # Generics Type Parameters use PascalCase and are prefixed with uppercase 'T' # https://docs.microsoft.com/dotnet/standard/design-guidelines/names-of-classes-structs-and-interfaces dotnet_naming_symbols.type_parameter_group.applicable_kinds = type_parameter -dotnet_naming_rule.type_parameter_rule.symbols = type_parameter_group -dotnet_naming_rule.type_parameter_rule.style = prefix_type_parameters_with_t_style -dotnet_naming_rule.type_parameter_rule.severity = warning +dotnet_naming_rule.type_parameter_rule.symbols = type_parameter_group +dotnet_naming_rule.type_parameter_rule.style = prefix_type_parameters_with_t_style +dotnet_naming_rule.type_parameter_rule.severity = warning # Function parameters use camelCase # https://docs.microsoft.com/dotnet/standard/design-guidelines/naming-parameters dotnet_naming_symbols.parameters_group.applicable_kinds = parameter -dotnet_naming_rule.parameters_rule.symbols = parameters_group -dotnet_naming_rule.parameters_rule.style = camel_case_style -dotnet_naming_rule.parameters_rule.severity = warning +dotnet_naming_rule.parameters_rule.symbols = parameters_group +dotnet_naming_rule.parameters_rule.style = camel_case_style +dotnet_naming_rule.parameters_rule.severity = warning ########################################## # License diff --git a/Benchmarks/BinaryConversionBenchmarks.cs b/Benchmarks/BinaryConversionBenchmarks.cs index ed55306..88603f4 100644 --- a/Benchmarks/BinaryConversionBenchmarks.cs +++ b/Benchmarks/BinaryConversionBenchmarks.cs @@ -1,10 +1,10 @@ -using System.Security.Cryptography; +namespace Benchmarks; + +using System.Security.Cryptography; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Jobs; using BenchmarkDotNet.Order; -namespace Benchmarks; - [SimpleJob(RuntimeMoniker.NativeAot70)] [SimpleJob(RuntimeMoniker.Net70)] [SimpleJob(RuntimeMoniker.Net60)] diff --git a/Benchmarks/Program.cs b/Benchmarks/Program.cs index 824e2d0..299cefe 100644 --- a/Benchmarks/Program.cs +++ b/Benchmarks/Program.cs @@ -1,7 +1,7 @@ -using System.Reflection; -using BenchmarkDotNet.Running; +namespace Benchmarks; -namespace Benchmarks; +using System.Reflection; +using BenchmarkDotNet.Running; internal class Program { diff --git a/Server/AuthSession.cs b/Server/AuthSession.cs index 7a7322f..eeb925d 100644 --- a/Server/AuthSession.cs +++ b/Server/AuthSession.cs @@ -1,35 +1,34 @@ -using System.Reflection; -using System.Text; +namespace Server; + +using System.Reflection; using MassTransit.Mediator; using Microsoft.Extensions.Logging; using NetCoreServer; -using Server.Packets; - -namespace Server; +using Packets; public class AuthSession : TcpSession { - private readonly IMediator _mediator; - private readonly ILogger _logger; + private readonly ILogger logger; + private readonly IMediator mediator; public AuthSession(TcpServer server, IMediator mediator, ILogger logger) : base(server) { - this._mediator = mediator; - this._logger = logger; + this.mediator = mediator; + this.logger = logger; } public override long Send(byte[] buffer) { - this._logger.LogInformation("Data being sent is: {Data}", BitConverter.ToString(buffer)); + this.logger.LogInformation("Data being sent is: {Data}", BitConverter.ToString(buffer)); return base.Send(buffer); } public void Send(IPacket packet) { var type = packet.GetType(); - this._logger.LogTrace("Packet of type {Type} is being serialized", type.Name); - var packetIdAttribute = type.GetCustomAttribute(); + this.logger.LogTrace("Packet of type {Type} is being serialized", type.Name); + var packetIdAttribute = type.GetCustomAttribute(); if (packetIdAttribute == null) { return; @@ -56,38 +55,38 @@ public class AuthSession : TcpSession buffer[2 + i] = bytesOfOpcode[i]; } - this._logger.LogTrace("Packet data being parsed is: {Data}", BitConverter.ToString(packetData.ToArray())); - this._logger.LogTrace("Packet being parsed is: {Data}", BitConverter.ToString(buffer.ToArray())); + this.logger.LogTrace("Packet data being parsed is: {Data}", BitConverter.ToString(packetData.ToArray())); + this.logger.LogTrace("Packet being parsed is: {Data}", BitConverter.ToString(buffer.ToArray())); this.Send(buffer); } protected override void OnReceived(byte[] buffer, long offset, long size) { - this._logger.LogDebug("Length: {Size} & offset: {Offset}", size, offset); + this.logger.LogDebug("Length: {Size} & offset: {Offset}", size, offset); Span decryptedBuffer = new byte[size]; // xor every value after the first 8 bytes - var dataBuffer = this.Decrypt(new ArraySegment(buffer, 8, (int)size - 8).ToArray()); + var dataBuffer = Decrypt(new ArraySegment(buffer, 8, (int)size - 8).ToArray()); - this._logger.LogDebug("Length {length}", BitConverter.ToUInt16(buffer, 0)); + this.logger.LogDebug("Length {length}", BitConverter.ToUInt16(buffer, 0)); var opCode = BitConverter.ToUInt16(buffer.ToArray(), 2); - this._logger.LogDebug("Packet Op Code: {OpCode}", opCode); - this._logger.LogDebug("Some Value: {RandomValue}" + buffer[4]); + this.logger.LogDebug("Packet Op Code: {OpCode}", opCode); + this.logger.LogDebug("Some Value: {RandomValue}", buffer[4]); var clientAliveTime = BitConverter.ToUInt16(buffer.ToArray(), 5); - this._logger.LogDebug("Client Alive time: {ClientAliveTime}", clientAliveTime); - this._logger.LogDebug("Might be a flag: {Flag}", buffer[7]); + this.logger.LogDebug("Client Alive time: {ClientAliveTime}", clientAliveTime); + this.logger.LogDebug("Might be a flag: {Flag}", buffer[7]); - this._logger.LogDebug("Full buffer: {Buffer}", BitConverter.ToString(dataBuffer.ToArray())); + this.logger.LogDebug("Full buffer: {Buffer}", BitConverter.ToString(dataBuffer.ToArray())); var rawPacket = new RawPacket((OperationCode)opCode, dataBuffer, clientAliveTime, buffer[7], buffer[4], this.Id, this); - Task.Run(() => this._mediator.Send(rawPacket)); - this._logger.LogInformation("Connection from: {@RemoteEndpoint}", this.Socket.RemoteEndPoint?.ToString()); + Task.Run(() => this.mediator.Send(rawPacket)); + this.logger.LogInformation("Connection from: {@RemoteEndpoint}", this.Socket.RemoteEndPoint?.ToString()); base.OnReceived(decryptedBuffer.ToArray(), offset, decryptedBuffer.Length); } - private byte[] Decrypt(byte[] buffer) + private static byte[] Decrypt(byte[] buffer) { for (var i = 0; i < buffer.Length; ++i) { diff --git a/Server/ChannelSession.cs b/Server/ChannelSession.cs index 8fbb53f..10ba237 100644 --- a/Server/ChannelSession.cs +++ b/Server/ChannelSession.cs @@ -1,47 +1,47 @@ -using System.Security.Cryptography; +namespace Server; + +using System.Security.Cryptography; using System.Text; using MassTransit.Mediator; using Microsoft.Extensions.Logging; using NetCoreServer; -namespace Server; - public class ChannelSession : TcpSession { - private readonly IMediator _mediator; - private readonly ILogger _logger; - private static readonly byte[] Key = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7 } .Reverse().ToArray(); - private static readonly byte[] IV = new byte[] + private static readonly byte[] Iv = new byte[] { 0xfe, 220, 0xba, 0x98, 0x76, 0x54, 50, 0x10, 15, 30, 0x2d, 60, 0x4b, 90, 0x69, 120 }.Reverse().ToArray(); - private readonly ICryptoTransform _encryptor; - private readonly ICryptoTransform _decryptor; + private readonly ICryptoTransform decryptor; + + private readonly ICryptoTransform encryptor; + private readonly ILogger logger; + private readonly IMediator mediator; public ChannelSession(TcpServer server, IMediator mediator, ILogger logger) : base(server) { - this._mediator = mediator; - this._logger = logger; + this.mediator = mediator; + this.logger = logger; var aes = Aes.Create(); aes.Key = Key; - aes.IV = IV; + aes.IV = Iv; aes.Padding = PaddingMode.None; aes.Mode = CipherMode.ECB; - this._decryptor = aes.CreateDecryptor(aes.Key, aes.IV); - this._encryptor = aes.CreateEncryptor(aes.Key, aes.IV); + this.decryptor = aes.CreateDecryptor(aes.Key, aes.IV); + this.encryptor = aes.CreateEncryptor(aes.Key, aes.IV); } protected override void OnReceived(byte[] buffer, long offset, long size) { try { - using (var ms = new MemoryStream(this.Decrypt(buffer))) - using (var cs = new CryptoStream(ms, this._decryptor, CryptoStreamMode.Read)) + using (var ms = new MemoryStream(Decrypt(buffer))) + using (var cs = new CryptoStream(ms, this.decryptor, CryptoStreamMode.Read)) { cs.Read(buffer); } @@ -50,12 +50,12 @@ public class ChannelSession : TcpSession } catch (CryptographicException ex) { - this._logger.LogError("An error has occured while decrypting: {ErrorMessage}", ex.Message); - this._logger.LogError("Default buffer message: {Message}", Encoding.ASCII.GetString(buffer)); + this.logger.LogError("An error has occured while decrypting: {ErrorMessage}", ex.Message); + this.logger.LogError("Default buffer message: {Message}", Encoding.ASCII.GetString(buffer)); } } - private byte[] Decrypt(byte[] buffer) + private static byte[] Decrypt(byte[] buffer) { for (var i = 0; i < buffer.Length; ++i) { diff --git a/Server/Consumers/PacketConsumer.cs b/Server/Consumers/PacketConsumer.cs index 4c8a9fa..c938cd3 100644 --- a/Server/Consumers/PacketConsumer.cs +++ b/Server/Consumers/PacketConsumer.cs @@ -1,18 +1,18 @@ -using MassTransit; -using Server.Packets; -using Server.Services; +namespace Server.Consumers; -namespace Server.Consumers; +using MassTransit; +using Packets; +using Services; public class PacketConsumer : IConsumer { - private readonly PacketDistributorService _distributorService; + private readonly PacketDistributorService distributorService; - public PacketConsumer(PacketDistributorService distributorService) => this._distributorService = distributorService; + public PacketConsumer(PacketDistributorService distributorService) => this.distributorService = distributorService; public Task Consume(ConsumeContext context) { - this._distributorService.AddPacket(context.Message); + this.distributorService.AddPacket(context.Message); return Task.CompletedTask; } } diff --git a/Server/DB/Documents/Account.cs b/Server/DB/Documents/Account.cs index f301c81..0eb5643 100644 --- a/Server/DB/Documents/Account.cs +++ b/Server/DB/Documents/Account.cs @@ -1,6 +1,6 @@ -using CouchDB.Driver.Types; +namespace Server.DB.Documents; -namespace Server.DB.Documents; +using CouchDB.Driver.Types; public class Account : CouchDocument { @@ -12,8 +12,8 @@ public class Account : CouchDocument this.PermissionLevel = permissionLevel; } - public string Username { get; private set; } - public string Password { get; private set; } - public string Email { get; private set; } - public byte PermissionLevel { get; private set; } + public string Username { get; set; } + public string Password { get; set; } + public string Email { get; set; } + public byte PermissionLevel { get; set; } } diff --git a/Server/DB/WonderkingContext.cs b/Server/DB/WonderkingContext.cs index 5d12a12..aae0df9 100644 --- a/Server/DB/WonderkingContext.cs +++ b/Server/DB/WonderkingContext.cs @@ -1,14 +1,14 @@ -using CouchDB.Driver; -using CouchDB.Driver.Options; -using Server.DB.Documents; +namespace Server.DB; -namespace Server.DB; +using CouchDB.Driver; +using CouchDB.Driver.Options; +using Documents; public class WonderkingContext : CouchContext { - public CouchDatabase Accounts { get; set; } - public WonderkingContext(CouchOptions options) : base(options) { } + + public CouchDatabase Accounts { get; } } diff --git a/Server/PacketHandlers/IPacketHandler.cs b/Server/PacketHandlers/IPacketHandler.cs index 66c195a..d5dbadf 100644 --- a/Server/PacketHandlers/IPacketHandler.cs +++ b/Server/PacketHandlers/IPacketHandler.cs @@ -1,9 +1,11 @@ -using NetCoreServer; -using Server.Packets; +namespace Server.PacketHandlers; -namespace Server.PacketHandlers; +using JetBrains.Annotations; +using NetCoreServer; +using Packets; public interface IPacketHandler where T : IPacket { + [UsedImplicitly] public Task HandleAsync(T packet, TcpSession session); } diff --git a/Server/PacketHandlers/LoginInfoHandler.cs b/Server/PacketHandlers/LoginInfoHandler.cs index f07fd8c..8478b86 100644 --- a/Server/PacketHandlers/LoginInfoHandler.cs +++ b/Server/PacketHandlers/LoginInfoHandler.cs @@ -1,49 +1,49 @@ -using Microsoft.Extensions.Configuration; +namespace Server.PacketHandlers; + +using DB; +using DB.Documents; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using NetCoreServer; -using Server.DB; -using Server.DB.Documents; -using Server.Packets.Incoming; -using Server.Packets.Outgoing; - -namespace Server.PacketHandlers; +using Packets.Incoming; +using Packets.Outgoing; public class LoginHandler : IPacketHandler { - private readonly ILogger _logger; - private readonly WonderkingContext _wonderkingContext; - private readonly IConfiguration _configuration; + private readonly IConfiguration configuration; + private readonly ILogger logger; + private readonly WonderkingContext wonderkingContext; public LoginHandler(ILogger logger, WonderkingContext wonderkingContext, IConfiguration configuration) { - this._logger = logger; - this._wonderkingContext = wonderkingContext; - this._configuration = configuration; + this.logger = logger; + this.wonderkingContext = wonderkingContext; + this.configuration = configuration; } public async Task HandleAsync(LoginInfoPacket packet, TcpSession session) { - this._logger.LogInformation("Login data: Username {Username} & Password {Password}", packet.Username, + this.logger.LogInformation("Login data: Username {Username} & Password {Password}", packet.Username, packet.Password); - var account = this._wonderkingContext.Accounts.FirstOrDefault(a => a.Username == packet.Username); + var account = this.wonderkingContext.Accounts.FirstOrDefault(a => a.Username == packet.Username); if (account == null) { - if (this._configuration.GetSection("Testing").GetValue("CreateAccountOnLogin")) + if (this.configuration.GetSection("Testing").GetValue("CreateAccountOnLogin")) { var result = - this._wonderkingContext.Accounts.AddAsync(new Account(packet.Username, packet.Password, "", 0)); + this.wonderkingContext.Accounts.AddAsync(new Account(packet.Username, packet.Password, "", 0)); await result; } else { // TODO: Send Message that account does not exist - this._logger.LogInformation("Requested account for user: {Username} does not exist", packet.Username); + this.logger.LogInformation("Requested account for user: {Username} does not exist", packet.Username); } } var loginResponsePacket = new LoginResponsePacket { - LoginResponseReason = LoginResponseReason.OK, + ResponseReason = LoginResponseReason.Ok, ChannelData = new[] { new ServerChannelData { ChannelId = 0, LoadPercentage = 75, ServerId = 0 } }, UnknownFlag = 1, IsGameMaster = true diff --git a/Server/Packets/Incoming/LoginInfoPacket.cs b/Server/Packets/Incoming/LoginInfoPacket.cs index a155f44..59a2f6a 100644 --- a/Server/Packets/Incoming/LoginInfoPacket.cs +++ b/Server/Packets/Incoming/LoginInfoPacket.cs @@ -1,13 +1,13 @@ -using System.Text; +namespace Server.Packets.Incoming; -namespace Server.Packets.Incoming; +using System.Text; [PacketId(OperationCode.LoginInfo)] public class LoginInfoPacket : IPacket { - public string Username; + public required string Username { get; set; } - public string Password; + public required string Password { get; set; } public void Deserialize(byte[] data) { diff --git a/Server/Packets/Outgoing/LoginResponsePacket.cs b/Server/Packets/Outgoing/LoginResponsePacket.cs index f8888a5..db1199a 100644 --- a/Server/Packets/Outgoing/LoginResponsePacket.cs +++ b/Server/Packets/Outgoing/LoginResponsePacket.cs @@ -3,19 +3,19 @@ [PacketId(OperationCode.LoginResponse)] public class LoginResponsePacket : IPacket { - public LoginResponseReason LoginResponseReason; - public byte UnknownFlag = 1; - public bool IsGameMaster; + public required LoginResponseReason ResponseReason { get; set; } + public required byte UnknownFlag { get; set; } = 1; + public required bool IsGameMaster { get; set; } - public ServerChannelData[] ChannelData; + public required ServerChannelData[] ChannelData { get; set; } public void Deserialize(byte[] data) { - this.LoginResponseReason = (LoginResponseReason)data[0]; + this.ResponseReason = (LoginResponseReason)data[0]; this.UnknownFlag = data[1]; this.IsGameMaster = BitConverter.ToBoolean(data, 2); var channelAmount = BitConverter.ToUInt16(data, 3); - var sizeOfServerChannelData = 5; + const int sizeOfServerChannelData = 5; this.ChannelData = Enumerable.Repeat(0, channelAmount).Select(i => new ServerChannelData { ServerId = BitConverter.ToUInt16(data, 5 + 0 + (i * sizeOfServerChannelData)), @@ -29,7 +29,7 @@ public class LoginResponsePacket : IPacket var sizeOfServerChannelData = 5; Span dataSpan = stackalloc byte[5 + (this.ChannelData.Length * sizeOfServerChannelData)]; dataSpan.Clear(); - dataSpan[0] = (byte)this.LoginResponseReason; + dataSpan[0] = (byte)this.ResponseReason; dataSpan[1] = this.UnknownFlag; dataSpan[2] = BitConverter.GetBytes(this.IsGameMaster)[0]; var bytesOfChannelAmount = BitConverter.GetBytes((ushort)this.ChannelData.Length); diff --git a/Server/Packets/Outgoing/LoginResponseReason.cs b/Server/Packets/Outgoing/LoginResponseReason.cs index f06b4ec..12963e3 100644 --- a/Server/Packets/Outgoing/LoginResponseReason.cs +++ b/Server/Packets/Outgoing/LoginResponseReason.cs @@ -2,7 +2,7 @@ public enum LoginResponseReason : byte { - OK, + Ok, AcountNotExist, WrongPassword, Error, @@ -11,8 +11,8 @@ public enum LoginResponseReason : byte PleaseSignUp, Suspended2, EmailVerify, - NotCBTUser, - ServerNotFoundOrDBProblem, + NotCbtUser, + ServerNotFoundOrDbProblem, LockedDuePayment, UserDeletedBigpoint, NoMoreTries diff --git a/Server/Packets/Outgoing/ServerChannelData.cs b/Server/Packets/Outgoing/ServerChannelData.cs index c6d1692..1d40818 100644 --- a/Server/Packets/Outgoing/ServerChannelData.cs +++ b/Server/Packets/Outgoing/ServerChannelData.cs @@ -2,7 +2,7 @@ public struct ServerChannelData { - public ushort ServerId; - public ushort ChannelId; - public byte LoadPercentage; + public ushort ServerId { get; set; } + public ushort ChannelId { get; set; } + public byte LoadPercentage { get; set; } } diff --git a/Server/Packets/PacketId.cs b/Server/Packets/PacketId.cs deleted file mode 100644 index 2dd4b9e..0000000 --- a/Server/Packets/PacketId.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Server.Packets; - -public class PacketId : Attribute -{ - public readonly OperationCode Code; - - public PacketId(OperationCode code) => this.Code = code; -} diff --git a/Server/Packets/PacketIdAttribute.cs b/Server/Packets/PacketIdAttribute.cs new file mode 100644 index 0000000..1ca4bd1 --- /dev/null +++ b/Server/Packets/PacketIdAttribute.cs @@ -0,0 +1,8 @@ +namespace Server.Packets; + +[AttributeUsage(AttributeTargets.Class, Inherited = false)] +public class PacketIdAttribute : Attribute +{ + public PacketIdAttribute(OperationCode code) => this.Code = code; + public OperationCode Code { get; } +} diff --git a/Server/Packets/RawPacket.cs b/Server/Packets/RawPacket.cs index 3beeed1..879d80e 100644 --- a/Server/Packets/RawPacket.cs +++ b/Server/Packets/RawPacket.cs @@ -1,19 +1,10 @@ -using MassTransit; +namespace Server.Packets; -namespace Server.Packets; +using MassTransit; [MessageUrn("packets")] public class RawPacket { - public readonly OperationCode OperationCode; - public byte[] MessageBody; - public readonly TimeSpan ClientAliveTime; - public readonly byte UnknownValue; - public readonly byte UnknownValue2; - public readonly Guid SessionId; - - public readonly AuthSession Session; - public RawPacket(OperationCode operationCode, byte[] messageBody, uint aliveTime, byte unknownValue2, byte unknownValue, Guid sessionId, AuthSession session) { @@ -31,4 +22,13 @@ public class RawPacket */ this.ClientAliveTime = TimeSpan.FromSeconds(5 * aliveTime); } + + public OperationCode OperationCode { get; } + public byte[] MessageBody { get; } + public TimeSpan ClientAliveTime { get; } + public byte UnknownValue { get; } + public byte UnknownValue2 { get; } + public Guid SessionId { get; } + + public AuthSession Session { get; } } diff --git a/Server/Program.cs b/Server/Program.cs index 048c816..5666de1 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -1,4 +1,5 @@ -using System.Net; +#pragma warning disable AV1500 +using System.Net; using System.Reflection; using CouchDB.Driver.DependencyInjection; using MassTransit; @@ -14,7 +15,7 @@ var configurationRoot = builder.Configuration.AddJsonFile("settings.json", false .AddEnvironmentVariables().Build(); builder.Services.AddLogging(); builder.Logging.AddFile("Logs/Server-{Date}.log", LogLevel.Debug); -builder.Logging.AddFile("Logs/Server-{Date}.json.log", isJson: true, minimumLevel: LogLevel.Debug); +builder.Logging.AddFile("Logs/Server-{Date}.json.log", LogLevel.Debug, isJson: true); builder.Services.AddCouchContext(cfg => { cfg.UseEndpoint(configurationRoot["DB:Endpoint"] ?? throw new InvalidOperationException()) @@ -27,8 +28,8 @@ builder.Services.AddHostedService(provider => provider.GetService() ?? throw new InvalidOperationException()); builder.Services.AddMassTransit(x => { - x.UsingInMemory((context, configurator) => { configurator.ConfigureEndpoints(context); }); - x.AddMediator(cfg => { cfg.AddConsumers(Assembly.GetExecutingAssembly()); }); + x.UsingInMemory((context, configurator) => configurator.ConfigureEndpoints(context)); + x.AddMediator(cfg => cfg.AddConsumers(Assembly.GetExecutingAssembly())); }); builder.Services.AddHostedService(provider => new WonderkingAuthServer(IPAddress.Any, 10001, provider.GetService>() ?? throw new InvalidOperationException(), @@ -36,3 +37,4 @@ builder.Services.AddHostedService(provider => new Wonderki using var host = builder.Build(); await host.RunAsync(); +#pragma warning restore AV1500 diff --git a/Server/Server.csproj b/Server/Server.csproj index 3ac59e2..ad6075d 100644 --- a/Server/Server.csproj +++ b/Server/Server.csproj @@ -19,10 +19,6 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/Server/Services/PacketDistributorService.cs b/Server/Services/PacketDistributorService.cs index b3dda7f..5b31d75 100644 --- a/Server/Services/PacketDistributorService.cs +++ b/Server/Services/PacketDistributorService.cs @@ -1,4 +1,6 @@ -using System.Collections.Concurrent; +namespace Server.Services; + +using System.Collections.Concurrent; using System.Reflection; using MassTransit.Internals; using Microsoft.Extensions.DependencyInjection; @@ -6,49 +8,51 @@ using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.VisualBasic.CompilerServices; using Newtonsoft.Json; -using Server.PacketHandlers; -using Server.Packets; - -namespace Server.Services; +using PacketHandlers; +using Packets; public class PacketDistributorService : IHostedService { - private readonly ConcurrentQueue _concurrentQueue; - private readonly ILogger _logger; - private readonly Dictionary _packetsTypes; - private readonly Dictionary _packetHandlers; - private readonly IServiceProvider _serviceProvider; + private readonly ConcurrentQueue concurrentQueue; + private readonly ILogger logger; + private readonly Dictionary packetHandlers; + private readonly Dictionary packetsTypes; + private readonly IServiceProvider serviceProvider; public PacketDistributorService(ILogger logger, IServiceProvider serviceProvider) { - this._concurrentQueue = new ConcurrentQueue(); - this._logger = logger; - this._serviceProvider = serviceProvider; - this._packetHandlers = new Dictionary(); - this._packetsTypes = new Dictionary(); + this.concurrentQueue = new ConcurrentQueue(); + this.logger = logger; + this.serviceProvider = serviceProvider; + this.packetHandlers = new Dictionary(); + this.packetsTypes = new Dictionary(); var executingAssembly = Assembly.GetExecutingAssembly(); - this._packetsTypes = this.GetPacketsWithId(executingAssembly); - this._packetHandlers = this.GetAllPacketHandlersWithId(executingAssembly); + this.packetsTypes = this.GetPacketsWithId(executingAssembly); + this.packetHandlers = this.GetAllPacketHandlersWithId(executingAssembly); } + public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask; + + public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; + private Dictionary GetPacketsWithId(Assembly executingAssembly) { var packetsWithId = executingAssembly.GetTypes().AsParallel() - .Where(type => type.GetCustomAttribute() != null && type.HasInterface(typeof(IPacket)) && + .Where(type => type.GetCustomAttribute() != null && type.HasInterface(typeof(IPacket)) && !type.IsInterface) - .ToDictionary(packet => packet.GetCustomAttribute()!.Code); + .ToDictionary(packet => packet.GetCustomAttribute()!.Code); if (packetsWithId is not { Count: 0 }) { packetsWithId.AsParallel().ForAll(packet => { - this._logger.LogTrace("Packet with ID: {PacketID} has been added as {PacketName}", packet.Key, + this.logger.LogTrace("Packet with ID: {PacketID} has been added as {PacketName}", packet.Key, packet.Value.FullName); }); return packetsWithId; } - this._logger.LogCritical("No Packets have been found"); + this.logger.LogCritical("No Packets have been found"); throw new IncompleteInitialization(); } @@ -59,38 +63,36 @@ public class PacketDistributorService : IHostedService .GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPacketHandler<>))).ToDictionary(type => type.GetInterfaces().First(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IPacketHandler<>)) - .GetGenericArguments()[0].GetCustomAttribute().Code); + .GetGenericArguments()[0].GetCustomAttribute().Code); if (packetHandlersWithId is not { Count: 0 }) { packetHandlersWithId.AsParallel().ForAll(packetHandler => { - this._logger.LogTrace("PacketHandler with ID: {PacketID} has been added as {PacketName}", + this.logger.LogTrace("PacketHandler with ID: {PacketID} has been added as {PacketName}", packetHandler.Key, packetHandler.Value.FullName); }); return packetHandlersWithId; } - this._logger.LogCritical("No PacketHandlers have been found"); + this.logger.LogCritical("No PacketHandlers have been found"); throw new IncompleteInitialization(); } - public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask; - public void AddPacket(RawPacket rawPacket) { - this._concurrentQueue.Enqueue(rawPacket); + this.concurrentQueue.Enqueue(rawPacket); Task.Run(() => this.DequeueRawPacketAsync()); - this._logger.LogInformation("Packet with ID: {MessageOperationCode} has been received", + this.logger.LogInformation("Packet with ID: {MessageOperationCode} has been received", rawPacket.OperationCode); } private async Task DequeueRawPacketAsync() { - if (this._concurrentQueue.TryDequeue(out var item)) + if (this.concurrentQueue.TryDequeue(out var item)) { - Task.Run(() => { this.InvokePacketHandler(item); }); + Task.Run(() => this.InvokePacketHandler(item)); } else { @@ -100,21 +102,19 @@ public class PacketDistributorService : IHostedService private void InvokePacketHandler(RawPacket? item) { - this._logger.LogTrace("[{TempId}] Packet with ID: {MessageOperationCode} is being dequeued", + this.logger.LogTrace("[{TempId}] Packet with ID: {MessageOperationCode} is being dequeued", item.Session.Id, item.OperationCode); - var packetType = this._packetsTypes[item.OperationCode]; + var packetType = this.packetsTypes[item.OperationCode]; var packet = (IPacket)Activator.CreateInstance(packetType)!; packet.Deserialize(item.MessageBody); var packetHandler = - ActivatorUtilities.GetServiceOrCreateInstance(this._serviceProvider, - this._packetHandlers[item.OperationCode]); + ActivatorUtilities.GetServiceOrCreateInstance(this.serviceProvider, + this.packetHandlers[item.OperationCode]); packetHandler.GetType().GetMethod("HandleAsync") ?.Invoke(packetHandler, new object[] { packet, item.Session }); - this._logger.LogDebug("Packet data {PacketData}", JsonConvert.SerializeObject(packet)); - this._logger.LogTrace("[{TempId}] Packet with ID: {MessageOperationCode} has finished", + this.logger.LogDebug("Packet data {PacketData}", JsonConvert.SerializeObject(packet)); + this.logger.LogTrace("[{TempId}] Packet with ID: {MessageOperationCode} has finished", item.Session.Id, item.OperationCode); } - - public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } diff --git a/Server/Services/WonderkingAuthServer.cs b/Server/Services/WonderkingAuthServer.cs index 80c2b59..510caf2 100644 --- a/Server/Services/WonderkingAuthServer.cs +++ b/Server/Services/WonderkingAuthServer.cs @@ -1,53 +1,24 @@ -using System.Net; +namespace Server.Services; + +using System.Net; using System.Net.Sockets; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using NetCoreServer; -namespace Server.Services; - public class WonderkingAuthServer : TcpServer, IHostedService { - private readonly ILogger _logger; - private readonly IServiceProvider _serviceProvider; + private readonly ILogger logger; + private readonly IServiceProvider serviceProvider; public WonderkingAuthServer(IPAddress address, int port, ILogger logger, IServiceProvider serviceProvider) : base(address, port) { - this._logger = logger; - this._serviceProvider = serviceProvider; + this.logger = logger; + this.serviceProvider = serviceProvider; } - protected override TcpSession CreateSession() => - ActivatorUtilities.CreateInstance(this._serviceProvider, this); - - protected override void OnStarting() - { - this._logger.LogInformation("Starting"); - base.OnStarting(); - } - - protected override void OnStarted() - { - this._logger.LogInformation("Started"); - base.OnStarted(); - } - - protected override void OnStopping() - { - this._logger.LogInformation("Stopping"); - base.OnStopping(); - } - - protected override void OnStopped() - { - this._logger.LogInformation("Stopped"); - base.OnStopped(); - } - - protected override void OnError(SocketError error) => this._logger.LogError("An error has occured {Error}", error); - public Task StartAsync(CancellationToken cancellationToken) { this.Start(); @@ -59,4 +30,33 @@ public class WonderkingAuthServer : TcpServer, IHostedService this.Stop(); return Task.CompletedTask; } + + protected override TcpSession CreateSession() => + ActivatorUtilities.CreateInstance(this.serviceProvider, this); + + protected override void OnStarting() + { + this.logger.LogInformation("Starting"); + base.OnStarting(); + } + + protected override void OnStarted() + { + this.logger.LogInformation("Started"); + base.OnStarted(); + } + + protected override void OnStopping() + { + this.logger.LogInformation("Stopping"); + base.OnStopping(); + } + + protected override void OnStopped() + { + this.logger.LogInformation("Stopped"); + base.OnStopped(); + } + + protected override void OnError(SocketError error) => this.logger.LogError("An error has occured {Error}", error); }