feat: create window client app

This commit is contained in:
k0t9i
2023-01-28 14:54:49 +04:00
parent 1d77bceeff
commit 42d594bbbb
43 changed files with 1142 additions and 98 deletions

View File

@@ -0,0 +1,27 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Client.Domain.Entities;
using Client.Domain.Factories;
using Client.Infrastructure.Parsers.Converters;
namespace Client.Infrastructure.Factories
{
public class EntityFactory<T> : EntityFactoryInterface<T> where T : EntityInterface
{
public T? Create(string data)
{
return JsonConvert.DeserializeObject<T>(data, settings);
}
public void Update(T entity, string data)
{
JsonConvert.PopulateObject(data, entity, settings);
}
private JsonSerializerSettings settings = new JsonSerializerSettings { Converters = { new BooleanConverter() } };
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Client.Domain.Entities;
using Client.Domain.Enums;
using Client.Domain.Factories;
using Client.Domain.Service;
namespace Client.Infrastructure.Factories
{
public class EntityHandlerFactory : EntityHandlerFactoryInterface
{
private readonly IServiceProvider serviceProvider;
public HandlerInterface GetHandler(MessageTypeEnum type)
{
HandlerInterface? result = null;
switch (type)
{
case MessageTypeEnum.Hero:
result = (HandlerInterface?)serviceProvider.GetService(typeof(EntityHandler<Hero>));
break;
case MessageTypeEnum.Drop:
result = (HandlerInterface?)serviceProvider.GetService(typeof(EntityHandler<Drop>));
break;
}
if (result == null)
{
throw new ArgumentException("Handler not found " + type.ToString());
}
return result;
}
public EntityHandlerFactory(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
}
}

View File

@@ -0,0 +1,33 @@
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Client.Infrastructure.Parsers.Converters
{
public class BooleanConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(bool);
}
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
var value = reader.Value;
if (value == null)
{
return null;
}
return value?.ToString()?.Trim('0') != "";
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
writer.WriteRawValue(value == null ? null : (string)value);
}
}
}

View File

@@ -0,0 +1,30 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
namespace Client.Infrastructure.Parsers.Converters
{
public class RawConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
{
return null;
}
var raw = JRaw.Create(reader);
return raw.ToString();
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
writer.WriteRawValue(value == null ? null : (string)value);
}
}
}

View File

@@ -0,0 +1,65 @@
using Newtonsoft.Json;
using Client.Domain.Enums;
namespace Client.Infrastructure.Parsers
{
public class JsonMessageParser : Domain.Parsers.MessageParserInterface
{
public Domain.DTO.Message Parse(string message)
{
try
{
var obj = JsonConvert.DeserializeObject<Objects.Message>(message);
if (obj == null)
{
throw new Domain.Exception.ParserException();
}
return new Domain.DTO.Message(GetType(obj.Type), GetOperation(obj.Operation), obj.Content ?? "");
}
catch(JsonException)
{
throw new Domain.Exception.ParserException();
}
}
private MessageTypeEnum GetType(string? type)
{
switch (type)
{
case "hero":
return MessageTypeEnum.Hero;
case "drop":
return MessageTypeEnum.Drop;
case "npc":
return MessageTypeEnum.NPC;
case "player":
return MessageTypeEnum.Player;
case "skill":
return MessageTypeEnum.Skill;
case "item":
return MessageTypeEnum.Item;
case "abnormalEffect":
return MessageTypeEnum.AbnormalEffect;
case "chat":
return MessageTypeEnum.Chat;
}
return MessageTypeEnum.None;
}
private MessageOperationEnum GetOperation(string? type)
{
switch (type)
{
case "create":
return MessageOperationEnum.Create;
case "update":
return MessageOperationEnum.Update;
case "delete":
return MessageOperationEnum.Delete;
}
return MessageOperationEnum.None;
}
}
}

View File

@@ -0,0 +1,21 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Client.Infrastructure.Parsers.Converters;
namespace Client.Infrastructure.Parsers.Objects
{
internal class Message
{
[JsonProperty]
public string? Type { get; private set; }
[JsonProperty]
public string? Operation { get; private set; }
[JsonProperty]
[JsonConverter(typeof(RawConverter))]
public string? Content { get; private set; }
}
}

View File

@@ -0,0 +1,109 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Client.Domain.Transports.TransportInterface;
namespace Client.Infrastructure.Transports
{
public class NamedPipeTransport : Domain.Transports.TransportInterface, IDisposable
{
public event DelegateMessage? Message;
public async Task ConnectAsync()
{
if (!IsConnected())
{
Disconnect();
connectionPipe = new NamedPipeClientStream(this.pipeName);
await connectionPipe.ConnectAsync();
connectionPipe.ReadMode = PipeTransmissionMode.Message;
Debug.WriteLine("Connected to connection pipe");
byte[] buffer = new byte[16384 * 2];
int read = connectionPipe.Read(buffer, 0, buffer.Length);
string pipeName = Encoding.Unicode.GetString(buffer).TrimEnd('\0');
if (pipeName == "")
{
return;
}
Debug.WriteLine("Received connection pipe name " + pipeName);
mainPipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
await mainPipe.ConnectAsync();
mainPipe.ReadMode = PipeTransmissionMode.Message;
Debug.WriteLine("Connected to main pipe\n");
}
}
public async Task StartReceiveAsync()
{
while (IsConnected())
{
byte[] buffer = new byte[16384 * 2];
int readBytes = await mainPipe!.ReadAsync(buffer, 0, buffer.Length);
if (readBytes != 0)
{
string text = Encoding.Unicode.GetString(buffer).TrimEnd('\0');
Message?.Invoke(text);
}
}
}
public async Task SendAsync(string data)
{
if (IsConnected())
{
var buffer = Encoding.Unicode.GetBytes(data);
await mainPipe!.WriteAsync(buffer, 0, buffer.Length);
}
}
public bool IsConnected()
{
return connectionPipe != null && connectionPipe.IsConnected && mainPipe != null && mainPipe.IsConnected;
}
public void Dispose()
{
Disconnect();
}
public NamedPipeTransport(string pipeName)
{
this.pipeName = pipeName;
}
private void Disconnect()
{
if (mainPipe != null)
{
Debug.WriteLine("Disconnected from main pipe");
mainPipe.Close();
mainPipe.Dispose();
mainPipe = null;
}
if (connectionPipe != null)
{
Debug.WriteLine("Disconnected from connection pipe");
connectionPipe.Close();
connectionPipe.Dispose();
connectionPipe = null;
}
}
private string pipeName;
private NamedPipeClientStream? connectionPipe;
private NamedPipeClientStream? mainPipe;
}
}