diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..8c75eab --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,76 @@ +name: Publish FFTool + +on: + push: + tags: + - * + +env: + PROJECT_PROPERTIES: TheDialgaTeam.Pokemon3D.Server.prop + PROJECT_PUBLISH_ROOT: bin + DOTNET_VERSION: 7.0.x + RELEASE_TEMPLATE: RELEASE_TEMPLATE.md + +defaults: + run: + shell: pwsh + +jobs: + build: + name: Build and Publish + runs-on: windows-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Install dotnet + uses: actions/setup-dotnet@v3 + with: + dotnet-version: ${{ env.DOTNET_VERSION }} + + - name: Setup NuGet Credentials + run: | + dotnet nuget add source "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" --name "github/${{ github.repository_owner }}" --username "${{ github.actor }}" --password "${{ github.token }}" --store-password-in-clear-text + + - name: Get version number + id: get_version + run: | + $version = "${{ github.ref }}" -split "/" | Select-Object -Last 1 + Write-Output "::set-output name=version::$version" + + - name: Patch project properties + run: | + $version = "${{ steps.get_version.outputs.version }}" + $properties_file = Join-Path "${{ github.workspace }}" "${{ env.PROJECT_PROPERTIES }}" + ((Get-Content "$properties_file") -replace '^(\s*).+?<\/Version>(\s*)$', "`$1${version}`$2") | Set-Content "${properties_file}" + + - name: Build project + run: | + dotnet publish -c Release -r win-x64 + dotnet publish -c Release -r linux-x64 + dotnet publish -c Release -r osx-x64 + + - name: Compress Files + run: | + cd bin + 7z a -mx9 "win-x64.zip" "win-x64" + + 7z a "linux-x64.tar" "linux-x64" + 7z a -mx9 -sdel "linux-x64.tar.gz" "linux-x64.tar" + + 7z a "osx-x64.tar" "osx-x64" + 7z a -mx9 -sdel "osx-x64.tar.gz" "osx-x64.tar" + + - name: Deploy + uses: softprops/action-gh-release@v1 + with: + name: Pokemon 3D Server ${{ steps.get_version.outputs.version }} + body_path: ${{ github.workspace }}/${{ env.RELEASE_TEMPLATE }} + files: | + ${{ github.workspace }}/${{ env.PROJECT_PUBLISH_ROOT }}/*.zip + ${{ github.workspace }}/${{ env.PROJECT_PUBLISH_ROOT }}/*.tar.gz + draft: false + fail_on_unmatched_files: true \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/ICommand.cs b/TheDialgaTeam.Mediator.Abstractions/ICommand.cs deleted file mode 100644 index 9e44ca2..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/ICommand.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface ICommand : IRequest -{ -} - -public interface ICommand : IRequest -{ -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/ICommandHandler.cs b/TheDialgaTeam.Mediator.Abstractions/ICommandHandler.cs deleted file mode 100644 index 40ad66f..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/ICommandHandler.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface ICommandHandler : IRequestHandler where TRequest : ICommand -{ -} - -public interface ICommandHandler : IRequestHandler where TRequest : ICommand -{ -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/IEvent.cs b/TheDialgaTeam.Mediator.Abstractions/IEvent.cs deleted file mode 100644 index 16d9fdf..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/IEvent.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface IEvent : INotification -{ -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/IEventHandler.cs b/TheDialgaTeam.Mediator.Abstractions/IEventHandler.cs deleted file mode 100644 index 94d5dbb..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/IEventHandler.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface IEventHandler : INotificationHandler where TEvent : IEvent -{ -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/IMediator.cs b/TheDialgaTeam.Mediator.Abstractions/IMediator.cs deleted file mode 100644 index 9befb2b..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/IMediator.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface IMediator -{ - Task SendAsync(IRequest request, CancellationToken cancellationToken = default); - - Task SendAsync(IRequest request, CancellationToken cancellationToken = default); - - Task PublishAsync(INotification notification, CancellationToken cancellationToken = default); -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/INotification.cs b/TheDialgaTeam.Mediator.Abstractions/INotification.cs deleted file mode 100644 index cd0d488..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/INotification.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface INotification -{ -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/INotificationHandler.cs b/TheDialgaTeam.Mediator.Abstractions/INotificationHandler.cs deleted file mode 100644 index 91fa411..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/INotificationHandler.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface INotificationHandler -{ -} - -public interface INotificationHandler : INotificationHandler where TNotification : INotification -{ - Task HandleAsync(TNotification notification, CancellationToken cancellationToken); -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/IQuery.cs b/TheDialgaTeam.Mediator.Abstractions/IQuery.cs deleted file mode 100644 index 24e30bb..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/IQuery.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface IQuery : IRequest -{ -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/IQueryHandler.cs b/TheDialgaTeam.Mediator.Abstractions/IQueryHandler.cs deleted file mode 100644 index be15fc5..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/IQueryHandler.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface IQueryHandler : IRequestHandler where TRequest : IQuery -{ -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/IRequest.cs b/TheDialgaTeam.Mediator.Abstractions/IRequest.cs deleted file mode 100644 index 1459026..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/IRequest.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface IBaseRequest -{ -} - -public interface IRequest : IBaseRequest -{ -} - -public interface IRequest : IBaseRequest -{ -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/IRequestHandler.cs b/TheDialgaTeam.Mediator.Abstractions/IRequestHandler.cs deleted file mode 100644 index e8eab8e..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/IRequestHandler.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface IRequestHandler -{ -} - -public interface IRequestHandler : IRequestHandler where TRequest : IRequest -{ - Task HandleAsync(TRequest request, CancellationToken cancellationToken); -} - -public interface IRequestHandler : IRequestHandler where TRequest : IRequest -{ - Task HandleAsync(TRequest request, CancellationToken cancellationToken); -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/IRequestPipeline.cs b/TheDialgaTeam.Mediator.Abstractions/IRequestPipeline.cs deleted file mode 100644 index 225dd0e..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/IRequestPipeline.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface IRequestPipeline -{ -} - -public interface IRequestPipeline : IRequestPipeline where TRequest : IRequest -{ - Task HandleAsync(TRequest request, Func next, CancellationToken cancellationToken); -} - -public interface IRequestPipeline : IRequestPipeline where TRequest : IRequest -{ - Task HandleAsync(TRequest request, Func> next, CancellationToken cancellationToken); -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/IRequestPostProcessor.cs b/TheDialgaTeam.Mediator.Abstractions/IRequestPostProcessor.cs deleted file mode 100644 index 3ac01f7..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/IRequestPostProcessor.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface IRequestPostProcessor where TRequest : IBaseRequest -{ - Task Process(TRequest request, CancellationToken cancellationToken); -} - -public interface IRequestPostProcessor where TRequest : IBaseRequest -{ - Task Process(TRequest request, TResponse response, CancellationToken cancellationToken); -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/IRequestPreProcessor.cs b/TheDialgaTeam.Mediator.Abstractions/IRequestPreProcessor.cs deleted file mode 100644 index 813e438..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/IRequestPreProcessor.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace TheDialgaTeam.Mediator.Abstractions; - -public interface IRequestPreProcessor where TRequest : IBaseRequest -{ - Task Process(TRequest request, CancellationToken cancellationToken); -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.Abstractions/TheDialgaTeam.Mediator.Abstractions.csproj b/TheDialgaTeam.Mediator.Abstractions/TheDialgaTeam.Mediator.Abstractions.csproj deleted file mode 100644 index 6836c68..0000000 --- a/TheDialgaTeam.Mediator.Abstractions/TheDialgaTeam.Mediator.Abstractions.csproj +++ /dev/null @@ -1,9 +0,0 @@ - - - - net7.0 - enable - enable - - - diff --git a/TheDialgaTeam.Mediator.SourceGenerator/MediatorGenerator.cs b/TheDialgaTeam.Mediator.SourceGenerator/MediatorGenerator.cs deleted file mode 100644 index 09ba697..0000000 --- a/TheDialgaTeam.Mediator.SourceGenerator/MediatorGenerator.cs +++ /dev/null @@ -1,357 +0,0 @@ -using System.Collections.Immutable; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp.Syntax; - -namespace TheDialgaTeam.Mediator.SourceGenerator; - -[Generator] -public sealed class MediatorGenerator : IIncrementalGenerator -{ - public void Initialize(IncrementalGeneratorInitializationContext context) - { - var getMediatorInterfaces = context.CompilationProvider.Select((compilation, token) => compilation.SyntaxTrees - .SelectMany(tree => tree.GetRoot(token).DescendantNodes()) - .Where(node => node is ClassDeclarationSyntax or RecordDeclarationSyntax) - .Select(node => compilation.GetSemanticModel(node.SyntaxTree).GetDeclaredSymbol(node, token)) - .Where(symbol => symbol != null && ((ITypeSymbol) symbol).AllInterfaces.Any(typeSymbol => - typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Equals("global::TheDialgaTeam.Mediator.Abstractions.IBaseRequest") || - typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Equals("global::TheDialgaTeam.Mediator.Abstractions.INotification") || - typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Equals("global::TheDialgaTeam.Mediator.Abstractions.INotificationHandler"))) - .OfType() - .ToImmutableArray() - ); - - context.RegisterSourceOutput(getMediatorInterfaces, (productionContext, symbols) => - { - var sourceBuilder = new SourceBuilder(); - - sourceBuilder.WriteNamespace("TheDialgaTeam.Mediator.Extensions").WriteBlock(builder => - { - builder.WriteUsingNamespace( - "global::Microsoft.Extensions.DependencyInjection", - "global::Microsoft.Extensions.DependencyInjection.Extensions", - "global::TheDialgaTeam.Mediator.Abstractions", - "global::TheDialgaTeam.Mediator.Implementations", - "global::TheDialgaTeam.Mediator.Implementations.Pipelines"); - - builder.WriteLine("public static class ServiceCollectionExtensions").WriteBlock(classBuilder => - { - classBuilder.WriteLine("public static IServiceCollection AddMediator(this IServiceCollection collection)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("collection.TryAddSingleton();"); - methodBuilder.WriteLine("collection.TryAddSingleton(typeof(MediatorSender<>));"); - methodBuilder.WriteLine("collection.TryAddSingleton(typeof(MediatorSender<,>));"); - methodBuilder.WriteLine("collection.TryAddSingleton(typeof(MediatorPublisher<>));"); - - methodBuilder.WriteLine("collection.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IRequestPipeline<>), typeof(PreProcessorRequestPipeline<>)));"); - methodBuilder.WriteLine("collection.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IRequestPipeline<,>), typeof(PreProcessorRequestPipeline<,>)));"); - methodBuilder.WriteLine("collection.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IRequestPipeline<>), typeof(PostProcessorRequestPipeline<>)));"); - methodBuilder.WriteLine("collection.TryAddEnumerable(ServiceDescriptor.Singleton(typeof(IRequestPipeline<,>), typeof(PostProcessorRequestPipeline<,>)));"); - - methodBuilder.WriteLine("return collection;"); - }); - }); - }); - - sourceBuilder.WriteNamespace("TheDialgaTeam.Mediator.Abstractions").WriteBlock(builder => - { - builder.WriteUsingNamespace( - "global::System.Threading", - "global::System.Threading.Tasks", - "global::TheDialgaTeam.Mediator.Abstractions"); - - #region IMediatorSender - - builder.WriteLine("file interface IBaseMediatorSender").WriteBlock(); - - builder.WriteLine("file interface IMediatorSender : IBaseMediatorSender").WriteBlock(interfaceBuilder => - { - interfaceBuilder.WriteLine("Task SendAsync(IRequest request, CancellationToken cancellationToken);"); - }); - - builder.WriteLine("file interface IMediatorSender : IBaseMediatorSender").WriteBlock(interfaceBuilder => - { - interfaceBuilder.WriteLine("Task SendAsync(IRequest request, CancellationToken cancellationToken);"); - }); - - #endregion - - #region IMediatorPublisher - - builder.WriteLine("file interface IBaseMediatorPublisher").WriteBlock(); - - builder.WriteLine("file interface IMediatorPublisher : IBaseMediatorPublisher").WriteBlock(interfaceBuilder => - { - interfaceBuilder.WriteLine("Task PublishAsync(INotification notification, CancellationToken cancellationToken);"); - }); - - #endregion - - }); - - sourceBuilder.WriteNamespace("TheDialgaTeam.Mediator.Implementations").WriteBlock(builder => - { - builder.WriteUsingNamespace( - "global::Microsoft.Extensions.DependencyInjection", - "global::Microsoft.Extensions.DependencyInjection.Extensions", - "global::System.Collections.Concurrent", - "global::System.Runtime.CompilerServices", - "global::System.Threading", - "global::System.Threading.Tasks", - "global::TheDialgaTeam.Mediator.Abstractions"); - - #region Mediator - - builder.WriteLine("file sealed class Mediator : IMediator").WriteBlock(classBuilder => - { - classBuilder.WriteLine("private readonly IServiceProvider _serviceProvider;"); - classBuilder.WriteLine("private readonly ConcurrentDictionary _senders = new();"); - classBuilder.WriteLine("private readonly ConcurrentDictionary _publishers = new();"); - classBuilder.WriteLine("private readonly Dictionary _mediatorTypes = new();"); - - classBuilder.WriteEmptyLine(); - - classBuilder.WriteLine("public Mediator(IServiceProvider serviceProvider)").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_serviceProvider = serviceProvider;"); - - foreach (var symbol in symbols) - { - if (symbol.AllInterfaces.Any(namedTypeSymbol => namedTypeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Equals("global::TheDialgaTeam.Mediator.Abstractions.IBaseRequest"))) - { - var requestType = symbol.AllInterfaces.SingleOrDefault(typeSymbol => typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).StartsWith("global::TheDialgaTeam.Mediator.Abstractions.IRequest")); - - if (requestType is not null) - { - if (requestType.IsGenericType) - { - constructorBuilder.WriteLine($"_mediatorTypes.Add(typeof({symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}), typeof(MediatorSender<{symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}, {string.Join(", ", requestType.TypeArguments.Select(typeSymbol => typeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)))}>));"); - } - else - { - constructorBuilder.WriteLine($"_mediatorTypes.Add(typeof({symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}), typeof(MediatorSender<{symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>));"); - } - } - } - - if (symbol.AllInterfaces.Any(namedTypeSymbol => namedTypeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat).Equals("global::TheDialgaTeam.Mediator.Abstractions.INotification"))) - { - constructorBuilder.WriteLine($"_mediatorTypes.Add(typeof({symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}), typeof(MediatorPublisher<{symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)}>));"); - } - } - }); - - classBuilder.WriteLine("public Task SendAsync(IRequest request, CancellationToken cancellationToken = default)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("var handler = Unsafe.As(_senders.GetOrAdd(request.GetType(), static (type, args) => Unsafe.As(args._serviceProvider.GetRequiredService(args._mediatorTypes[type])), (_serviceProvider, _mediatorTypes)));"); - methodBuilder.WriteLine("return handler.SendAsync(request, cancellationToken);"); - }); - - classBuilder.WriteLine("public Task SendAsync(IRequest request, CancellationToken cancellationToken = default)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("var handler = Unsafe.As>(_senders.GetOrAdd(request.GetType(), static (type, args) => Unsafe.As(args._serviceProvider.GetRequiredService(args._mediatorTypes[type])), (_serviceProvider, _mediatorTypes)));"); - methodBuilder.WriteLine("return handler.SendAsync(request, cancellationToken);"); - }); - - classBuilder.WriteLine("public Task PublishAsync(INotification notification, CancellationToken cancellationToken = default)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("var handler = Unsafe.As(_publishers.GetOrAdd(notification.GetType(), static (type, args) => Unsafe.As(args._serviceProvider.GetRequiredService(args._mediatorTypes[type])), (_serviceProvider, _mediatorTypes)));"); - methodBuilder.WriteLine("return handler.PublishAsync(notification, cancellationToken);"); - }); - }); - - #endregion - - #region MediatorSender - - builder.WriteLine("file sealed class MediatorSender : IMediatorSender where TRequest : IRequest").WriteBlock(classBuilder => - { - classBuilder.WriteLine("private readonly IRequestHandler _handler;"); - classBuilder.WriteLine("private readonly IEnumerable> _pipelines;"); - classBuilder.WriteEmptyLine(); - - classBuilder.WriteLine("public MediatorSender(IRequestHandler handler) : this(handler, Array.Empty>())").WriteBlock(); - - classBuilder.WriteLine("public MediatorSender(IRequestHandler handler, IEnumerable> pipelines)").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_handler = handler;"); - constructorBuilder.WriteLine("_pipelines = pipelines;"); - }); - - classBuilder.WriteLine("public Task SendAsync(IRequest request, CancellationToken cancellationToken)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("return _pipelines.Reverse().Aggregate(() => _handler.HandleAsync((TRequest) request, cancellationToken), (next, pipeline) => () => pipeline.HandleAsync((TRequest) request, next, cancellationToken))();"); - }); - }); - - builder.WriteLine("file sealed class MediatorSender : IMediatorSender where TRequest : IRequest").WriteBlock(classBuilder => - { - classBuilder.WriteLine("private readonly IRequestHandler _handler;"); - classBuilder.WriteLine("private readonly IEnumerable> _pipelines;"); - classBuilder.WriteEmptyLine(); - - classBuilder.WriteLine("public MediatorSender(IRequestHandler handler) : this(handler, Array.Empty>())").WriteBlock(); - - classBuilder.WriteLine("public MediatorSender(IRequestHandler handler, IEnumerable> pipelines)").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_handler = handler;"); - constructorBuilder.WriteLine("_pipelines = pipelines;"); - }); - - classBuilder.WriteLine("public Task SendAsync(IRequest request, CancellationToken cancellationToken)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("return _pipelines.Reverse().Aggregate(() => _handler.HandleAsync((TRequest) request, cancellationToken), (next, pipeline) => () => pipeline.HandleAsync((TRequest) request, next, cancellationToken))();"); - }); - }); - - #endregion - - #region MediatorPublisher - - builder.WriteLine("file sealed class MediatorPublisher : IMediatorPublisher where TNotification : INotification").WriteBlock(classBuilder => - { - classBuilder.WriteLine("private readonly IEnumerable> _handlers;"); - classBuilder.WriteEmptyLine(); - - classBuilder.WriteLine("public MediatorPublisher() : this(Array.Empty>())").WriteBlock().WriteEmptyLine(); - - classBuilder.WriteLine("public MediatorPublisher(IEnumerable> handlers)").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_handlers = handlers;"); - }); - - classBuilder.WriteLine("public Task PublishAsync(INotification notification, CancellationToken cancellationToken)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("return Task.WhenAll(_handlers.Select(handler => handler.HandleAsync((TNotification) notification, cancellationToken)));"); - }); - }); - - #endregion - }); - - sourceBuilder.WriteNamespace("TheDialgaTeam.Mediator.Implementations.Pipelines").WriteBlock(builder => - { - builder.WriteUsingNamespace( - "global::System.Threading", - "global::System.Threading.Tasks", - "global::TheDialgaTeam.Mediator.Abstractions"); - - #region PreProcessorRequestPipeline - - builder.WriteLine("file sealed class PreProcessorRequestPipeline : IRequestPipeline where TRequest : IRequest").WriteBlock(classBuilder => - { - classBuilder.WriteLine("private readonly IEnumerable> _processors;"); - classBuilder.WriteEmptyLine(); - - classBuilder.WriteLine("public PreProcessorRequestPipeline()").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_processors = Array.Empty>();"); - }); - - classBuilder.WriteLine("public PreProcessorRequestPipeline(IEnumerable> processors)").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_processors = processors;"); - }); - - classBuilder.WriteLine("public async Task HandleAsync(TRequest request, Func next, CancellationToken cancellationToken)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("foreach (var processor in _processors)").WriteBlock(foreachBuilder => - { - foreachBuilder.WriteLine("await processor.Process(request, cancellationToken).ConfigureAwait(false);"); - }); - - methodBuilder.WriteLine("await next().ConfigureAwait(false);"); - }); - }); - - builder.WriteLine("file sealed class PreProcessorRequestPipeline : IRequestPipeline where TRequest : IRequest").WriteBlock(classBuilder => - { - classBuilder.WriteLine("private readonly IEnumerable> _processors;"); - classBuilder.WriteEmptyLine(); - - classBuilder.WriteLine("public PreProcessorRequestPipeline()").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_processors = Array.Empty>();"); - }); - - classBuilder.WriteLine("public PreProcessorRequestPipeline(IEnumerable> processors)").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_processors = processors;"); - }); - - classBuilder.WriteLine("public async Task HandleAsync(TRequest request, Func> next, CancellationToken cancellationToken)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("foreach (var processor in _processors)").WriteBlock(foreachBuilder => - { - foreachBuilder.WriteLine("await processor.Process(request, cancellationToken).ConfigureAwait(false);"); - }); - - methodBuilder.WriteLine("return await next().ConfigureAwait(false);"); - }); - }); - - #endregion - - #region PostProcessorRequestPipeline - - builder.WriteLine("file sealed class PostProcessorRequestPipeline : IRequestPipeline where TRequest : IRequest").WriteBlock(classBuilder => - { - classBuilder.WriteLine("private readonly IEnumerable> _processors;"); - classBuilder.WriteEmptyLine(); - - classBuilder.WriteLine("public PostProcessorRequestPipeline()").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_processors = Array.Empty>();"); - }); - - classBuilder.WriteLine("public PostProcessorRequestPipeline(IEnumerable> processors)").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_processors = processors;"); - }); - - classBuilder.WriteLine("public async Task HandleAsync(TRequest request, Func next, CancellationToken cancellationToken)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("await next().ConfigureAwait(false);"); - - methodBuilder.WriteLine("foreach (var processor in _processors)").WriteBlock(foreachBuilder => - { - foreachBuilder.WriteLine("await processor.Process(request, cancellationToken).ConfigureAwait(false);"); - }); - }); - }); - - builder.WriteLine("file sealed class PostProcessorRequestPipeline : IRequestPipeline where TRequest : IRequest").WriteBlock(classBuilder => - { - classBuilder.WriteLine("private readonly IEnumerable> _processors;"); - classBuilder.WriteEmptyLine(); - - classBuilder.WriteLine("public PostProcessorRequestPipeline()").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_processors = Array.Empty>();"); - }); - - classBuilder.WriteLine("public PostProcessorRequestPipeline(IEnumerable> processors)").WriteBlock(constructorBuilder => - { - constructorBuilder.WriteLine("_processors = processors;"); - }); - - classBuilder.WriteLine("public async Task HandleAsync(TRequest request, Func> next, CancellationToken cancellationToken)").WriteBlock(methodBuilder => - { - methodBuilder.WriteLine("var response = await next().ConfigureAwait(false);"); - - methodBuilder.WriteLine("foreach (var processor in _processors)").WriteBlock(foreachBuilder => - { - foreachBuilder.WriteLine("await processor.Process(request, response, cancellationToken).ConfigureAwait(false);"); - }); - - methodBuilder.WriteLine("return response;"); - }); - }); - - #endregion - }); - - productionContext.AddSource("Mediator.cs", sourceBuilder.ToString()); - }); - } -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.SourceGenerator/Properties/launchSettings.json b/TheDialgaTeam.Mediator.SourceGenerator/Properties/launchSettings.json deleted file mode 100644 index cbfefef..0000000 --- a/TheDialgaTeam.Mediator.SourceGenerator/Properties/launchSettings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "profiles": { - "Debug Generator": { - "commandName": "DebugRoslynComponent", - "targetProject": "..\\TheDialgaTeam.Pokemon3D.Server.Core\\TheDialgaTeam.Pokemon3D.Server.Core.csproj" - } - } -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.SourceGenerator/SourceBuilder.cs b/TheDialgaTeam.Mediator.SourceGenerator/SourceBuilder.cs deleted file mode 100644 index e0d6240..0000000 --- a/TheDialgaTeam.Mediator.SourceGenerator/SourceBuilder.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System.Reflection; -using System.Text; - -namespace TheDialgaTeam.Mediator.SourceGenerator; - -public sealed class SourceBuilder -{ - private readonly int _indentationAmount; - private readonly char[] _indentationCache; - - private readonly StringBuilder _stringBuilder = new(); - - private int _currentIndentation; - - public SourceBuilder(char indentationChar = ' ', int indentationAmount = 4) : this(indentationChar, indentationAmount, 0) - { - } - - private SourceBuilder(char indentationChar = ' ', int indentationAmount = 4, int currentIndentation = 0) - { - _indentationAmount = indentationAmount; - _indentationCache = new char[Math.Min(indentationAmount * 5, 1024 / sizeof(char))]; - _indentationCache.AsSpan().Fill(indentationChar); - _currentIndentation = currentIndentation; - } - - public SourceBuilder WriteLine(string source) - { - AddIndentation(); - _stringBuilder.AppendLine(source); - return this; - } - - public SourceBuilder WriteEmptyLine() - { - _stringBuilder.AppendLine(string.Empty); - return this; - } - - public SourceBuilder WriteUsingNamespace(params string[] namespaces) - { - foreach (var @namespace in namespaces) - { - WriteLine($"using {@namespace};"); - } - - WriteEmptyLine(); - - return this; - } - - public SourceBuilder WriteNamespace(string @namespace) - { - return WriteLine($"namespace {@namespace}"); - } - - public SourceBuilder WriteGeneratedCodeAttribute() - { - return WriteLine($"[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"{Assembly.GetExecutingAssembly().GetName().Name}\", \"{Assembly.GetExecutingAssembly().GetName().Version}\")]"); - } - - public SourceBuilder WriteOpenBlock() - { - AddIndentation(); - - _stringBuilder.AppendLine("{"); - _currentIndentation += _indentationAmount; - - return this; - } - - public SourceBuilder WriteCloseBlock() - { - _currentIndentation -= _indentationAmount; - - AddIndentation(); - _stringBuilder.AppendLine("}"); - - return this; - } - - public SourceBuilder WriteBlock(Action? action = null) - { - WriteOpenBlock(); - - var sourceBuilder = new SourceBuilder(_indentationCache[0], _indentationAmount, _currentIndentation); - action?.Invoke(sourceBuilder); - - var result = sourceBuilder.ToString(); - - if (!string.IsNullOrEmpty(result)) - { - _stringBuilder.AppendLine(result); - } - - WriteCloseBlock(); - - WriteEmptyLine(); - - return this; - } - - public override string ToString() - { - return _stringBuilder.ToString().TrimEnd(' ', '\r', '\n'); - } - - private void AddIndentation() - { - var indentationApplied = 0; - - do - { - var indentAmount = Math.Min(_currentIndentation - indentationApplied, _indentationCache.Length); - _stringBuilder.Append(_indentationCache, 0, indentAmount); - indentationApplied += indentAmount; - } while (_currentIndentation != indentationApplied); - } -} \ No newline at end of file diff --git a/TheDialgaTeam.Mediator.SourceGenerator/TheDialgaTeam.Mediator.SourceGenerator.csproj b/TheDialgaTeam.Mediator.SourceGenerator/TheDialgaTeam.Mediator.SourceGenerator.csproj deleted file mode 100644 index 0c108fc..0000000 --- a/TheDialgaTeam.Mediator.SourceGenerator/TheDialgaTeam.Mediator.SourceGenerator.csproj +++ /dev/null @@ -1,17 +0,0 @@ - - - - net7.0 - enable - enable - latest - true - true - - - - - - - - diff --git a/TheDialgaTeam.Pokemon3D.Server.Cli/Program.cs b/TheDialgaTeam.Pokemon3D.Server.Cli/Program.cs index 8affa0c..7fe1d9f 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Cli/Program.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Cli/Program.cs @@ -30,7 +30,7 @@ public static Task Main(string[] args) .RunConsoleAsync(options => options.SuppressStatusMessages = true); } - private static void OnCurrentDomainOnUnhandledException(object _, UnhandledExceptionEventArgs eventArgs) + private static void OnCurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs eventArgs) { if (!eventArgs.IsTerminating) return; diff --git a/TheDialgaTeam.Pokemon3D.Server.Cli/TheDialgaTeam.Pokemon3D.Server.Cli.csproj b/TheDialgaTeam.Pokemon3D.Server.Cli/TheDialgaTeam.Pokemon3D.Server.Cli.csproj index 4e36911..009af91 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Cli/TheDialgaTeam.Pokemon3D.Server.Cli.csproj +++ b/TheDialgaTeam.Pokemon3D.Server.Cli/TheDialgaTeam.Pokemon3D.Server.Cli.csproj @@ -1,22 +1,15 @@ + + Pokemon3D.Server.Cli Exe - net7.0 Icon.ico TheDialgaTeam.Pokemon3D.Server.Cli - 1.0.0 - Yong Jian Ming - The Dialga Team Pokemon3D.Server.Cli Pokemon 3D Server in console mode. - https://github.com/TheDialgaTeam/TheDialgaTeam.Pokemon3D.Server - https://github.com/TheDialgaTeam/TheDialgaTeam.Pokemon3D.Server - - enable - enable true false diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Extensions/ServiceCollectionExtensions.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Extensions/ServiceCollectionExtensions.cs index 0fec312..31be2ad 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Extensions/ServiceCollectionExtensions.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Extensions/ServiceCollectionExtensions.cs @@ -16,9 +16,9 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.Extensions.DependencyInjection; -using TheDialgaTeam.Mediator.Extensions; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Extensions; using TheDialgaTeam.Pokemon3D.Server.Core.Options.Extensions; +using TheDialgaTeam.Pokemon3D.Server.Core.Player.Extensions; namespace TheDialgaTeam.Pokemon3D.Server.Core.Extensions; @@ -32,6 +32,7 @@ public static IServiceCollection AddPokemonServer(this IServiceCollection collec collection.AddPokemonServerNetwork(); collection.AddPokemonServerOptions(); + collection.AddPokemonServerPlayer(); return collection; } diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/ConnectedEventArgs.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/Connected.cs similarity index 86% rename from TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/ConnectedEventArgs.cs rename to TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/Connected.cs index e77f036..f886509 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/ConnectedEventArgs.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/Connected.cs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using TheDialgaTeam.Mediator.Abstractions; +using Mediator; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces; namespace TheDialgaTeam.Pokemon3D.Server.Core.Network.Events; -public sealed record ConnectedEventArgs(IPokemonServerClient PokemonServerClient) : IEvent; \ No newline at end of file +public sealed record Connected(IPokemonServerClient PokemonServerClient) : INotification; \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/DisconnectedEventArgs.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/Disconnected.cs similarity index 86% rename from TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/DisconnectedEventArgs.cs rename to TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/Disconnected.cs index 0df38b0..25732ac 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/DisconnectedEventArgs.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/Disconnected.cs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using TheDialgaTeam.Mediator.Abstractions; +using Mediator; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces; namespace TheDialgaTeam.Pokemon3D.Server.Core.Network.Events; -public sealed record DisconnectedEventArgs(IPokemonServerClient PokemonServerClient) : IEvent; \ No newline at end of file +public sealed record Disconnected(IPokemonServerClient PokemonServerClient) : INotification; \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/NewPackageReceivedEventArgs.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/NewPacketReceived.cs similarity index 86% rename from TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/NewPackageReceivedEventArgs.cs rename to TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/NewPacketReceived.cs index aa4ce91..8a0bc4a 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/NewPackageReceivedEventArgs.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Events/NewPacketReceived.cs @@ -14,10 +14,10 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using TheDialgaTeam.Mediator.Abstractions; +using Mediator; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces.Packets; namespace TheDialgaTeam.Pokemon3D.Server.Core.Network.Events; -public sealed record NewPackageReceivedEventArgs(IPokemonServerClient Network, IPacket Packet) : IEvent; \ No newline at end of file +public sealed record NewPacketReceived(IPokemonServerClient Network, IPacket Packet) : INotification; \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Extensions/ServiceCollectionExtensions.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Extensions/ServiceCollectionExtensions.cs index 3ae48dc..ec0cb19 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Extensions/ServiceCollectionExtensions.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Extensions/ServiceCollectionExtensions.cs @@ -16,8 +16,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using TheDialgaTeam.Mediator.Abstractions; -using TheDialgaTeam.Pokemon3D.Server.Core.Network.Events; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Implementations; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces; @@ -30,10 +28,6 @@ public static IServiceCollection AddPokemonServerNetwork(this IServiceCollection collection.TryAddSingleton(); collection.TryAddSingleton(); collection.TryAddSingleton(); - - collection.TryAddSingleton(); - collection.AddSingleton>(provider => provider.GetRequiredService()); - collection.AddSingleton>(provider => provider.GetRequiredService()); return collection; } diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/NetworkContainer.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/NetworkContainer.cs new file mode 100644 index 0000000..faa4cda --- /dev/null +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/NetworkContainer.cs @@ -0,0 +1,86 @@ +// Pokemon 3D Server Client +// Copyright (C) 2023 Yong Jian Ming +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Mediator; +using TheDialgaTeam.Pokemon3D.Server.Core.Network.Events; +using TheDialgaTeam.Pokemon3D.Server.Core.Network.Implementations.Packets; +using TheDialgaTeam.Pokemon3D.Server.Core.Network.Implementations.Packets.Types; +using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces; +using TheDialgaTeam.Pokemon3D.Server.Core.Options.Interfaces; +using TheDialgaTeam.Pokemon3D.Server.Core.Player.Queries; + +namespace TheDialgaTeam.Pokemon3D.Server.Core.Network.Implementations; + +internal sealed class NetworkContainer : + INotificationHandler, + INotificationHandler, + INotificationHandler +{ + private readonly IMediator _mediator; + private readonly IPokemonServerOptions _options; + + private readonly List _tcpClientNetworks = new(); + private readonly object _clientLock = new(); + + public NetworkContainer(IMediator mediator, IPokemonServerOptions options) + { + _mediator = mediator; + _options = options; + } + + private void AddClient(IPokemonServerClient network) + { + lock (_clientLock) + { + _tcpClientNetworks.Add(network); + } + } + + private void RemoveClient(IPokemonServerClient network) + { + lock (_clientLock) + { + _tcpClientNetworks.Remove(network); + } + } + + public ValueTask Handle(Connected notification, CancellationToken cancellationToken) + { + AddClient(notification.PokemonServerClient); + return ValueTask.CompletedTask; + } + + public ValueTask Handle(Disconnected notification, CancellationToken cancellationToken) + { + notification.PokemonServerClient.Dispose(); + RemoveClient(notification.PokemonServerClient); + return ValueTask.CompletedTask; + } + + public async ValueTask Handle(NewPacketReceived notification, CancellationToken cancellationToken) + { + switch (notification.Packet.PacketType) + { + case PacketType.ServerDataRequest: + { + var playerCount = await _mediator.Send(new GetPlayerCount(), cancellationToken).ConfigureAwait(false); + var packet = new ServerInfoDataPacket(playerCount, _options.ServerOptions.MaxPlayers, _options.ServerOptions.ServerName, _options.ServerOptions.ServerDescription, Array.Empty()); + notification.Network.SendPackage(packet); + break; + } + } + } +} \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/Packets/Packet.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/Packets/Packet.cs index c7320bf..07aba7e 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/Packets/Packet.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/Packets/Packet.cs @@ -41,107 +41,115 @@ public static bool TryParse(ReadOnlySpan rawData, [MaybeNullWhen(false)] o var dataIndexes = Array.Empty(); var currentDataIndex = 0; - while (currentPackageIndex <= maxPackageIndex) + try { - var nextDataLength = rawData.IndexOf('|'); - - if (nextDataLength == -1) + while (currentPackageIndex <= maxPackageIndex) { - packet = null; - return false; - } - - var data = rawData[..nextDataLength]; + var nextDataLength = rawData.IndexOf('|'); - switch (currentPackageIndex) - { - // Protocol Version - case 0: + if (nextDataLength == -1) { - if (!data.SequenceEqual(ProtocolVersion.AsSpan())) - { - packet = null; - return false; - } - break; + packet = null; + return false; } - - // Package Type - case 1: + + var data = rawData[..nextDataLength]; + + switch (currentPackageIndex) { - if (!Enum.TryParse(data, out packageType)) + // Protocol Version + case 0: { - packet = null; - return false; + if (!data.SequenceEqual(ProtocolVersion.AsSpan())) + { + packet = null; + return false; + } + + break; } - break; - } - - // Origin - case 2: - { - if (!int.TryParse(data, out origin)) + + // Package Type + case 1: { - packet = null; - return false; + if (!Enum.TryParse(data, out packageType)) + { + packet = null; + return false; + } + + break; } - break; - } - - // Package Index Length - case 3: - { - if (!int.TryParse(data, out dataIndexLength)) + + // Origin + case 2: { - packet = null; - return false; - } + if (!int.TryParse(data, out origin)) + { + packet = null; + return false; + } - if (dataIndexLength == 0) break; + break; + } - maxPackageIndex += dataIndexLength; - dataIndexes = ArrayPool.Shared.Rent(dataIndexLength); - break; - } - - default: - { - if (!int.TryParse(data, out var dataIndex)) + // Package Index Length + case 3: { - packet = null; - return false; + if (!int.TryParse(data, out dataIndexLength)) + { + packet = null; + return false; + } + + if (dataIndexLength == 0) break; + + maxPackageIndex += dataIndexLength; + dataIndexes = ArrayPool.Shared.Rent(dataIndexLength); + break; } - dataIndexes[currentDataIndex++] = dataIndex; - break; + default: + { + if (!int.TryParse(data, out var dataIndex)) + { + packet = null; + return false; + } + + dataIndexes[currentDataIndex++] = dataIndex; + break; + } } + + currentPackageIndex++; + rawData = rawData[(nextDataLength + 1)..]; } - - currentPackageIndex++; - rawData = rawData[(nextDataLength + 1)..]; - } - - if (dataIndexLength > 0) - { - ArrayPool.Shared.Return(dataIndexes); - } - switch (packageType) - { - case PacketType.ServerDataRequest: + switch (packageType) { - packet = new ServerDataRequestPacket(); - return true; - } + case PacketType.ServerDataRequest: + { + packet = new ServerDataRequestPacket(); + return true; + } - default: + default: + { + packet = null; + return false; + } + } + } + finally + { + if (dataIndexLength > 0) { - packet = null; - return false; + ArrayPool.Shared.Return(dataIndexes); } } } - + public string ToRawPacket() { _stringBuilder ??= new StringBuilder(); @@ -156,7 +164,7 @@ public string ToRawPacket() var dataItems = GetDataItems(); _stringBuilder.Append(dataItems.Length); - + var count = 0; foreach (var dataItem in dataItems) @@ -166,7 +174,7 @@ public string ToRawPacket() count += dataItem.Length; } - + _stringBuilder.Append('|'); foreach (var dataItem in dataItems) diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/Packets/Types/GameDataPacket.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/Packets/Types/GameDataPacket.cs index 27744c7..078988c 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/Packets/Types/GameDataPacket.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/Packets/Types/GameDataPacket.cs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using TheDialgaTeam.Pokemon3D.Server.Core.Player; +using TheDialgaTeam.Pokemon3D.Server.Core.Player.Implementations; namespace TheDialgaTeam.Pokemon3D.Server.Core.Network.Implementations.Packets.Types; diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PlayerContainer.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PlayerContainer.cs deleted file mode 100644 index cd66a93..0000000 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PlayerContainer.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Pokemon 3D Server Client -// Copyright (C) 2023 Yong Jian Ming -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -using TheDialgaTeam.Mediator.Abstractions; -using TheDialgaTeam.Pokemon3D.Server.Core.Network.Events; -using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces; - -namespace TheDialgaTeam.Pokemon3D.Server.Core.Network.Implementations; - -internal sealed class PlayerContainer : IEventHandler, IEventHandler -{ - private readonly List _tcpClientNetworks = new(); - private readonly object _clientLock = new(); - - private void AddClient(IPokemonServerClient network) - { - lock (_clientLock) - { - _tcpClientNetworks.Add(network); - } - } - - private void RemoveClient(IPokemonServerClient network) - { - lock (_clientLock) - { - _tcpClientNetworks.Remove(network); - } - } - - public Task HandleAsync(ConnectedEventArgs e, CancellationToken cancellationToken) - { - AddClient(e.PokemonServerClient); - return Task.CompletedTask; - } - - public Task HandleAsync(DisconnectedEventArgs e, CancellationToken cancellationToken) - { - e.PokemonServerClient.Dispose(); - RemoveClient(e.PokemonServerClient); - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PokemonServerClient.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PokemonServerClient.cs index dacd476..9a8b1fd 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PokemonServerClient.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PokemonServerClient.cs @@ -17,8 +17,8 @@ using System.Net; using System.Net.Sockets; using System.Text; +using Mediator; using Microsoft.Extensions.Logging; -using TheDialgaTeam.Mediator.Abstractions; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Events; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Implementations.Packets; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces; @@ -85,11 +85,11 @@ public void SendPackage(IPacket packet) } } - public Task DisconnectAsync() + public ValueTask DisconnectAsync() { _tcpClient.Close(); PrintDisconnected(RemoteIpAddress); - return _mediator.PublishAsync(new DisconnectedEventArgs(this)); + return _mediator.Publish(new Disconnected(this)); } private async Task RunReadingTask() @@ -120,7 +120,7 @@ private async Task RunReadingTask() try { - await _mediator.PublishAsync(new NewPackageReceivedEventArgs(this, package)); + await _mediator.Publish(new NewPacketReceived(this, package)); } catch (Exception ex) { diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PokemonServerListener.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PokemonServerListener.cs index 02a3c89..0cca4bd 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PokemonServerListener.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Implementations/PokemonServerListener.cs @@ -16,9 +16,9 @@ using System.Net; using System.Net.Sockets; +using Mediator; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using TheDialgaTeam.Mediator.Abstractions; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Events; using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces; using TheDialgaTeam.Pokemon3D.Server.Core.Options.Interfaces; @@ -77,15 +77,14 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) PrintServerOfflineMode(); } - var localIpAddress = await NetworkUtility.GetLocalIpAddressAsync(stoppingToken).ConfigureAwait(false); - PrintServerPlayerCanJoinVia(string.Join(", ", localIpAddress.Where(address => address.AddressFamily == AddressFamily.InterNetwork).Select(address => address.ToString())), string.Join(", ", serverOptions.GameModes)); + PrintServerPlayerCanJoinVia(string.Join(", ", serverOptions.GameModes)); Task.Run(RunServerPortCheckingTask, stoppingToken).FireAndForget(); while (!stoppingToken.IsCancellationRequested) { var tcpClient = await _tcpListener.AcceptTcpClientAsync(stoppingToken).ConfigureAwait(false); - await _mediator.PublishAsync(new ConnectedEventArgs(_pokemonServerClientFactory.CreateTcpClientNetwork(tcpClient)), stoppingToken).ConfigureAwait(false); + await _mediator.Publish(new Connected(_pokemonServerClientFactory.CreateTcpClientNetwork(tcpClient)), stoppingToken).ConfigureAwait(false); } } catch (SocketException exception) @@ -145,8 +144,8 @@ private async Task RunServerPortCheckingTask() [LoggerMessage(Level = LogLevel.Information, Message = "[Server] Players with offline profile can join the server.")] private partial void PrintServerOfflineMode(); - [LoggerMessage(Level = LogLevel.Information, Message = "[Server] Players can join using the following addresses: {localIpAddress} (Local) with the following GameModes: {gameModes}.")] - private partial void PrintServerPlayerCanJoinVia(string localIpAddress, string gameModes); + [LoggerMessage(Level = LogLevel.Information, Message = "[Server] Players can join with the following GameModes: {gameModes}.")] + private partial void PrintServerPlayerCanJoinVia(string gameModes); [LoggerMessage(Level = LogLevel.Information, Message = "[Server] Checking port {port} is open...")] private partial void PrintRunningPortCheck(int port); diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Interfaces/IPokemonServerClient.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Interfaces/IPokemonServerClient.cs index 839b03a..dd057b9 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Network/Interfaces/IPokemonServerClient.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Network/Interfaces/IPokemonServerClient.cs @@ -25,5 +25,5 @@ public interface IPokemonServerClient : IDisposable void SendPackage(IPacket packet); - Task DisconnectAsync(); + ValueTask DisconnectAsync(); } \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Commands/CreateNewPlayer.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Commands/CreateNewPlayer.cs new file mode 100644 index 0000000..cd2e8c6 --- /dev/null +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Commands/CreateNewPlayer.cs @@ -0,0 +1,23 @@ +// Pokemon 3D Server Client +// Copyright (C) 2023 Yong Jian Ming +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Mediator; +using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces; +using TheDialgaTeam.Pokemon3D.Server.Core.Network.Interfaces.Packets; + +namespace TheDialgaTeam.Pokemon3D.Server.Core.Player.Commands; + +public sealed record CreateNewPlayer(IPokemonServerClient Client, IPacket Packet) : ICommand; \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Extensions/ServiceCollectionExtensions.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Extensions/ServiceCollectionExtensions.cs new file mode 100644 index 0000000..bdf02dc --- /dev/null +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Extensions/ServiceCollectionExtensions.cs @@ -0,0 +1,31 @@ +// Pokemon 3D Server Client +// Copyright (C) 2023 Yong Jian Ming +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; +using TheDialgaTeam.Pokemon3D.Server.Core.Player.Implementations; +using TheDialgaTeam.Pokemon3D.Server.Core.Player.Interfaces; + +namespace TheDialgaTeam.Pokemon3D.Server.Core.Player.Extensions; + +public static class ServiceCollectionExtensions +{ + public static IServiceCollection AddPokemonServerPlayer(this IServiceCollection collection) + { + collection.TryAddSingleton(); + return collection; + } +} \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Player/BusyType.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/BusyType.cs similarity index 89% rename from TheDialgaTeam.Pokemon3D.Server.Core/Player/BusyType.cs rename to TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/BusyType.cs index 6b757c5..6229737 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Player/BusyType.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/BusyType.cs @@ -14,9 +14,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -namespace TheDialgaTeam.Pokemon3D.Server.Core.Player; +namespace TheDialgaTeam.Pokemon3D.Server.Core.Player.Implementations; -public enum BusyType +internal enum BusyType { NotBusy = 0, Battling = 1, diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Player.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/Player.cs similarity index 95% rename from TheDialgaTeam.Pokemon3D.Server.Core/Player/Player.cs rename to TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/Player.cs index bdeaea3..284d317 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Player.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/Player.cs @@ -15,10 +15,11 @@ // along with this program. If not, see . using TheDialgaTeam.Pokemon3D.Server.Core.Network.Implementations.Packets.Types; +using TheDialgaTeam.Pokemon3D.Server.Core.Player.Interfaces; -namespace TheDialgaTeam.Pokemon3D.Server.Core.Player; +namespace TheDialgaTeam.Pokemon3D.Server.Core.Player.Implementations; -internal sealed class Player +internal sealed class Player : IPlayer { public int Id { get; } diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/PlayerContainer.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/PlayerContainer.cs new file mode 100644 index 0000000..07e2580 --- /dev/null +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/PlayerContainer.cs @@ -0,0 +1,52 @@ +// Pokemon 3D Server Client +// Copyright (C) 2023 Yong Jian Ming +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections.Concurrent; +using Mediator; +using TheDialgaTeam.Pokemon3D.Server.Core.Player.Commands; +using TheDialgaTeam.Pokemon3D.Server.Core.Player.Interfaces; +using TheDialgaTeam.Pokemon3D.Server.Core.Player.Queries; + +namespace TheDialgaTeam.Pokemon3D.Server.Core.Player.Implementations; + +internal sealed class PlayerContainer : + IQueryHandler, + ICommandHandler +{ + private readonly List _players = new(); + private readonly object _playerLock = new(); + + private int _nextRunningId; + private readonly ConcurrentQueue _runningIdQueue = new(); + + public ValueTask Handle(GetPlayerCount query, CancellationToken cancellationToken) + { + lock (_playerLock) + { + return ValueTask.FromResult(_players.Count); + } + } + + public ValueTask Handle(CreateNewPlayer command, CancellationToken cancellationToken) + { + throw new NotImplementedException(); + } + + private int GetNextRunningId() + { + return _runningIdQueue.TryDequeue(out var id) ? id : Interlocked.Increment(ref _nextRunningId); + } +} \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/PlayerFactory.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/PlayerFactory.cs new file mode 100644 index 0000000..7233f80 --- /dev/null +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/PlayerFactory.cs @@ -0,0 +1,35 @@ +// Pokemon 3D Server Client +// Copyright (C) 2023 Yong Jian Ming +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Microsoft.Extensions.DependencyInjection; +using TheDialgaTeam.Pokemon3D.Server.Core.Player.Interfaces; + +namespace TheDialgaTeam.Pokemon3D.Server.Core.Player.Implementations; + +internal sealed class PlayerFactory : IPlayerFactory +{ + private readonly IServiceProvider _serviceProvider; + + public PlayerFactory(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + } + + public IPlayer CreatePlayer(int id) + { + return ActivatorUtilities.CreateInstance(_serviceProvider, id); + } +} \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Position.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/Position.cs similarity index 92% rename from TheDialgaTeam.Pokemon3D.Server.Core/Player/Position.cs rename to TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/Position.cs index 1c0138c..23aeb73 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Position.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Implementations/Position.cs @@ -18,9 +18,9 @@ using System.Globalization; using TheDialgaTeam.Pokemon3D.Server.Core.Utilities; -namespace TheDialgaTeam.Pokemon3D.Server.Core.Player; +namespace TheDialgaTeam.Pokemon3D.Server.Core.Player.Implementations; -public readonly record struct Position(float X, float Y, float Z) +internal readonly record struct Position(float X, float Y, float Z) { private static readonly ConcurrentDictionary NumberFormatInfos = new(); diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Interfaces/IPlayer.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Interfaces/IPlayer.cs new file mode 100644 index 0000000..7f6d1b2 --- /dev/null +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Interfaces/IPlayer.cs @@ -0,0 +1,21 @@ +// Pokemon 3D Server Client +// Copyright (C) 2023 Yong Jian Ming +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace TheDialgaTeam.Pokemon3D.Server.Core.Player.Interfaces; + +public interface IPlayer +{ +} \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Interfaces/IPlayerFactory.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Interfaces/IPlayerFactory.cs new file mode 100644 index 0000000..d12613e --- /dev/null +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Interfaces/IPlayerFactory.cs @@ -0,0 +1,22 @@ +// Pokemon 3D Server Client +// Copyright (C) 2023 Yong Jian Ming +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace TheDialgaTeam.Pokemon3D.Server.Core.Player.Interfaces; + +public interface IPlayerFactory +{ + IPlayer CreatePlayer(int id); +} \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Player/Queries/GetPlayerCount.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Queries/GetPlayerCount.cs new file mode 100644 index 0000000..dfb433e --- /dev/null +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Player/Queries/GetPlayerCount.cs @@ -0,0 +1,21 @@ +// Pokemon 3D Server Client +// Copyright (C) 2023 Yong Jian Ming +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Mediator; + +namespace TheDialgaTeam.Pokemon3D.Server.Core.Player.Queries; + +public sealed record GetPlayerCount : IQuery; \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/TheDialgaTeam.Pokemon3D.Server.Core.csproj b/TheDialgaTeam.Pokemon3D.Server.Core/TheDialgaTeam.Pokemon3D.Server.Core.csproj index a7d4103..3473600 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/TheDialgaTeam.Pokemon3D.Server.Core.csproj +++ b/TheDialgaTeam.Pokemon3D.Server.Core/TheDialgaTeam.Pokemon3D.Server.Core.csproj @@ -1,30 +1,21 @@ - - net7.0 - enable - enable - - true - - + + $(NoWarn);SYSLIB1006 - - - - embedded + false - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + - - - - - diff --git a/TheDialgaTeam.Pokemon3D.Server.Core/Utilities/NetworkUtility.cs b/TheDialgaTeam.Pokemon3D.Server.Core/Utilities/NetworkUtility.cs index 2ea5d73..36f1899 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Core/Utilities/NetworkUtility.cs +++ b/TheDialgaTeam.Pokemon3D.Server.Core/Utilities/NetworkUtility.cs @@ -25,11 +25,6 @@ public static IPAddress[] GetLocalIpAddress() return Dns.GetHostAddresses(Dns.GetHostName()); } - public static async Task GetLocalIpAddressAsync(CancellationToken cancellationToken = default) - { - return await Dns.GetHostAddressesAsync(Dns.GetHostName(), cancellationToken).ConfigureAwait(false); - } - public static async Task GetPublicIpAddressAsync(HttpClient httpClient, CancellationToken cancellationToken = default) { var externalIpAddress = await httpClient.GetStringAsync("https://api.ipify.org", cancellationToken).ConfigureAwait(false); diff --git a/TheDialgaTeam.Pokemon3D.Server.Gui/TheDialgaTeam.Pokemon3D.Server.Gui.csproj b/TheDialgaTeam.Pokemon3D.Server.Gui/TheDialgaTeam.Pokemon3D.Server.Gui.csproj index b8951c3..c59aac8 100644 --- a/TheDialgaTeam.Pokemon3D.Server.Gui/TheDialgaTeam.Pokemon3D.Server.Gui.csproj +++ b/TheDialgaTeam.Pokemon3D.Server.Gui/TheDialgaTeam.Pokemon3D.Server.Gui.csproj @@ -1,20 +1,16 @@  + + + Pokemon3D.Server.Gui WinExe - net7.0 Assets\Icon.ico TheDialgaTeam.Pokemon3D.Server.Gui - 1.0.0 - Yong Jian Ming - The Dialga Team Pokemon3D.Server.Gui Pokemon 3D Server in graphical mode. - https://github.com/TheDialgaTeam/TheDialgaTeam.Pokemon3D.Server - https://github.com/TheDialgaTeam/TheDialgaTeam.Pokemon3D.Server - enable true app.manifest true @@ -34,14 +30,14 @@ - - - - - - + + + + + + - + diff --git a/TheDialgaTeam.Pokemon3D.Server.prop b/TheDialgaTeam.Pokemon3D.Server.prop new file mode 100644 index 0000000..13452f3 --- /dev/null +++ b/TheDialgaTeam.Pokemon3D.Server.prop @@ -0,0 +1,22 @@ + + + + net7.0 + + enable + enable + true + + 1.0.0 + Yong Jian Ming + The Dialga Team + https://github.com/TheDialgaTeam/TheDialgaTeam.Pokemon3D.Server + https://github.com/TheDialgaTeam/TheDialgaTeam.Pokemon3D.Server + git + + + + none + + + \ No newline at end of file diff --git a/TheDialgaTeam.Pokemon3D.Server.sln b/TheDialgaTeam.Pokemon3D.Server.sln index b16806b..27e759a 100644 --- a/TheDialgaTeam.Pokemon3D.Server.sln +++ b/TheDialgaTeam.Pokemon3D.Server.sln @@ -6,10 +6,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheDialgaTeam.Pokemon3D.Ser EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheDialgaTeam.Pokemon3D.Server.Gui", "TheDialgaTeam.Pokemon3D.Server.Gui\TheDialgaTeam.Pokemon3D.Server.Gui.csproj", "{D1E19B60-CF7B-42C6-9C7A-9BDE7D0A0361}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheDialgaTeam.Mediator.SourceGenerator", "TheDialgaTeam.Mediator.SourceGenerator\TheDialgaTeam.Mediator.SourceGenerator.csproj", "{AB423470-C39E-4F2E-A594-F8076FD17CB5}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TheDialgaTeam.Mediator.Abstractions", "TheDialgaTeam.Mediator.Abstractions\TheDialgaTeam.Mediator.Abstractions.csproj", "{79553E00-C401-4FE6-BD8C-1D3AAA9DC2BB}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -30,13 +26,5 @@ Global {D1E19B60-CF7B-42C6-9C7A-9BDE7D0A0361}.Release|Any CPU.ActiveCfg = Release|Any CPU {D1E19B60-CF7B-42C6-9C7A-9BDE7D0A0361}.Release|Any CPU.Build.0 = Release|Any CPU {D1E19B60-CF7B-42C6-9C7A-9BDE7D0A0361}.Release|Any CPU.Deploy.0 = Release|Any CPU - {AB423470-C39E-4F2E-A594-F8076FD17CB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AB423470-C39E-4F2E-A594-F8076FD17CB5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AB423470-C39E-4F2E-A594-F8076FD17CB5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AB423470-C39E-4F2E-A594-F8076FD17CB5}.Release|Any CPU.Build.0 = Release|Any CPU - {79553E00-C401-4FE6-BD8C-1D3AAA9DC2BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {79553E00-C401-4FE6-BD8C-1D3AAA9DC2BB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {79553E00-C401-4FE6-BD8C-1D3AAA9DC2BB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {79553E00-C401-4FE6-BD8C-1D3AAA9DC2BB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal