250 lines
10 KiB
C#
250 lines
10 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using RobotNet.MapManager.Data;
|
|
using RobotNet.MapManager.Services;
|
|
using RobotNet.MapShares;
|
|
using RobotNet.MapShares.Dtos;
|
|
using RobotNet.Shares;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
|
|
namespace RobotNet.MapManager.Controllers;
|
|
|
|
[Route("api/[controller]")]
|
|
[ApiController]
|
|
[Authorize]
|
|
public class MapExportController(MapEditorDbContext MapDb, MapEditorStorageRepository StorageRepo, IHttpClientFactory HttpClientFactory, LoggerController<MapExportController> Logger) : ControllerBase
|
|
{
|
|
private readonly byte[] Key = Encoding.UTF8.GetBytes("2512199802031998");
|
|
private readonly byte[] IV = Encoding.UTF8.GetBytes("2512199802031998");
|
|
|
|
[HttpGet]
|
|
[Route("encrypt/{Id}")]
|
|
public async Task<IActionResult> EncryptMap(Guid Id)
|
|
{
|
|
try
|
|
{
|
|
var map = await MapDb.Maps.FirstOrDefaultAsync(m => m.Id == Id);
|
|
if (map is null) return NotFound($"Map {Id} không tồn tại");
|
|
|
|
var (usingLocal, url) = StorageRepo.GetUrl("MapImages", $"{Id}");
|
|
byte[] imageData = await GetImageDataAsync(usingLocal, url);
|
|
|
|
var elementModels = MapDb.ElementModels.Where(n => n.MapId == Id);
|
|
List<ElementModelExportDto> ElementModelExport = [];
|
|
foreach (var elementModel in elementModels)
|
|
{
|
|
var getImageOpen = StorageRepo.GetUrl("ElementOpenModels", elementModel.Id.ToString());
|
|
byte[] imageElementModelOpenData = await GetImageDataAsync(getImageOpen.usingLocal, getImageOpen.url);
|
|
|
|
var getImageClose = StorageRepo.GetUrl("ElementCloseModels", elementModel.Id.ToString());
|
|
byte[] imageElementModelCloseData = await GetImageDataAsync(getImageClose.usingLocal, getImageClose.url);
|
|
|
|
ElementModelExport.Add(new ElementModelExportDto()
|
|
{
|
|
Id = elementModel.Id,
|
|
Height = elementModel.Height,
|
|
Width = elementModel.Width,
|
|
Image1Height = elementModel.Image1Height,
|
|
Image2Height = elementModel.Image2Height,
|
|
Image1Width = elementModel.Image1Width,
|
|
Image2Width = elementModel.Image2Width,
|
|
Name = elementModel.Name,
|
|
Content = elementModel.Content,
|
|
ImageOpenData = imageElementModelOpenData,
|
|
ImageCloseData = imageElementModelCloseData,
|
|
});
|
|
}
|
|
var nodes = MapDb.Nodes.Where(n => n.MapId == Id);
|
|
var edges = MapDb.Edges.Where(n => n.MapId == Id);
|
|
var zones = MapDb.Zones.Where(n => n.MapId == Id);
|
|
var actions = MapDb.Actions.Where(n => n.MapId == Id);
|
|
var elements = MapDb.Elements.Where(n => n.MapId == Id);
|
|
|
|
var mapDto = new MapExportDto()
|
|
{
|
|
Id = Id,
|
|
Name = map.Name,
|
|
Description = map.Description,
|
|
Info = new()
|
|
{
|
|
OriginX = map.OriginX,
|
|
OriginY = map.OriginY,
|
|
Resolution = map.Resolution,
|
|
ViewX = map.ViewX,
|
|
ViewY = map.ViewY,
|
|
ViewWidth = map.ViewWidth,
|
|
ViewHeight = map.ViewHeight,
|
|
VDA5050 = map.VDA5050,
|
|
},
|
|
Setting = new()
|
|
{
|
|
NodeNameAutoGenerate = map.NodeNameAutoGenerate,
|
|
NodeNameTemplate = map.NodeNameTemplateDefault,
|
|
NodeAllowedDeviationXy = map.EdgeAllowedDeviationXyDefault,
|
|
NodeAllowedDeviationTheta = map.EdgeAllowedDeviationThetaDefault,
|
|
|
|
EdgeStraightMaxSpeed = map.EdgeStraightMaxSpeedDefault,
|
|
EdgeCurveMaxSpeed = map.EdgeCurveMaxSpeedDefault,
|
|
EdgeMaxRotationSpeed = map.EdgeMaxRotationSpeedDefault,
|
|
EdgeMinLength = map.EdgeMinLengthDefault,
|
|
EdgeMaxHeight = map.EdgeMaxHeightDefault,
|
|
EdgeMinHeight = map.EdgeMinHeightDefault,
|
|
EdgeRotationAllowed = map.EdgeRotationAllowedDefault,
|
|
EdgeDirectionAllowed = map.EdgeDirectionAllowedDefault,
|
|
EdgeAllowedDeviationTheta = map.EdgeAllowedDeviationThetaDefault,
|
|
EdgeAllowedDeviationXy = map.EdgeAllowedDeviationXyDefault,
|
|
|
|
ZoneMinSquare = map.ZoneMinSquareDefault,
|
|
},
|
|
Data = new()
|
|
{
|
|
NodeCount = map.NodeCount,
|
|
Nodes = [.. nodes.Select(n => new NodeDto()
|
|
{
|
|
Id = n.Id,
|
|
Name = n.Name,
|
|
X = n.X,
|
|
Y = n.Y,
|
|
Theta = n.Theta,
|
|
AllowedDeviationXy = n.AllowedDeviationXy,
|
|
AllowedDeviationTheta = n.AllowedDeviationTheta,
|
|
Actions = n.Actions,
|
|
})],
|
|
Edges = [.. edges.Select(e => new EdgeDto()
|
|
{
|
|
ControlPoint1X = e.ControlPoint1X,
|
|
ControlPoint1Y = e.ControlPoint1Y,
|
|
ControlPoint2X = e.ControlPoint2X,
|
|
ControlPoint2Y = e.ControlPoint2Y,
|
|
TrajectoryDegree = e.TrajectoryDegree,
|
|
EndNodeId = e.EndNodeId,
|
|
StartNodeId = e.StartNodeId,
|
|
DirectionAllowed = e.DirectionAllowed,
|
|
RotationAllowed = e.RotationAllowed,
|
|
AllowedDeviationTheta = e.AllowedDeviationTheta,
|
|
AllowedDeviationXy = e.AllowedDeviationXy,
|
|
MaxHeight = e.MaxHeight,
|
|
MinHeight = e.MinHeight,
|
|
MaxSpeed = e.MaxSpeed,
|
|
MaxRotationSpeed = e.MaxRotationSpeed,
|
|
Actions = e.Actions,
|
|
})],
|
|
Zones = [.. zones.Select(z => new ZoneDto()
|
|
{
|
|
Type = z.Type,
|
|
X1 = z.X1,
|
|
Y1 = z.Y1,
|
|
X2 = z.X2,
|
|
Y2 = z.Y2,
|
|
X3 = z.X3,
|
|
Y3 = z.Y3,
|
|
X4 = z.X4,
|
|
Y4 = z.Y4,
|
|
})],
|
|
Actions = [.. actions.Select(a => new ActionDto()
|
|
{
|
|
Id = a.Id,
|
|
Name = a.Name,
|
|
Content = a.Content,
|
|
})],
|
|
ElementModels = [.. ElementModelExport],
|
|
Elements = [.. elements.Select(e => new ElementDto()
|
|
{
|
|
Name = e.Name,
|
|
IsOpen = e.IsOpen,
|
|
ModelId = e.ModelId,
|
|
NodeId = e.NodeId,
|
|
OffsetX = e.OffsetX,
|
|
OffsetY = e.OffsetY,
|
|
Content = e.Content,
|
|
})],
|
|
ImageData = imageData,
|
|
}
|
|
};
|
|
|
|
var jsonData = JsonSerializer.Serialize(mapDto, JsonOptionExtends.Write);
|
|
var data = EncryptDataAES(jsonData, Key, IV);
|
|
return File(data, "application/octet-stream", $"{map.Name}.map");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Warning($"EncryptMap: Hệ thống có lỗi xảy ra - {ex.Message}");
|
|
return NotFound("Hệ thống có lỗi xảy ra");
|
|
}
|
|
}
|
|
|
|
[HttpPost]
|
|
[Route("decrypt")]
|
|
public async Task<MessageResult<MapExportDto>> DecryptMap([FromForm(Name = "importmap")] IFormFile file)
|
|
{
|
|
try
|
|
{
|
|
if (file == null || file.Length == 0) return new(false, "File không hợp lệ");
|
|
if (!file.FileName.EndsWith(".map", StringComparison.OrdinalIgnoreCase)) return new(false, "Định dạng file không hợp lệ, yêu cầu file .map");
|
|
using var memoryStream = new MemoryStream();
|
|
await file.CopyToAsync(memoryStream);
|
|
byte[] fileBytes = memoryStream.ToArray();
|
|
|
|
var jsonData = DecryptDataAES(fileBytes, Key, IV);
|
|
var mapData = JsonSerializer.Deserialize<MapExportDto>(jsonData, JsonOptionExtends.Read);
|
|
if (mapData is null) return new(false, "Dữ liệu không hợp lệ");
|
|
else return new(true) { Data = mapData };
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Warning($"EncryptMap: Hệ thống có lỗi xảy ra - {ex.Message}");
|
|
return new(false, $"EncryptMap: Hệ thống có lỗi xảy ra - {ex.Message}");
|
|
}
|
|
}
|
|
|
|
private static byte[] EncryptDataAES(string data, byte[] key, byte[] iv)
|
|
{
|
|
using Aes aesAlg = Aes.Create();
|
|
aesAlg.Key = key;
|
|
aesAlg.IV = iv;
|
|
|
|
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
|
|
|
|
using MemoryStream msEncrypt = new();
|
|
using CryptoStream csEncrypt = new(msEncrypt, encryptor, CryptoStreamMode.Write);
|
|
using (StreamWriter swEncrypt = new(csEncrypt))
|
|
{
|
|
swEncrypt.Write(data);
|
|
}
|
|
return msEncrypt.ToArray();
|
|
}
|
|
|
|
private static string DecryptDataAES(byte[] data, byte[] key, byte[] iv)
|
|
{
|
|
using Aes aesAlg = Aes.Create();
|
|
aesAlg.Key = key;
|
|
aesAlg.IV = iv;
|
|
|
|
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
|
|
|
|
using MemoryStream msDecrypt = new(data);
|
|
using CryptoStream csDecrypt = new(msDecrypt, decryptor, CryptoStreamMode.Read);
|
|
using StreamReader srDecrypt = new(csDecrypt);
|
|
return srDecrypt.ReadToEnd();
|
|
}
|
|
|
|
public async Task<byte[]> GetImageDataAsync(bool usingLocal, string url)
|
|
{
|
|
if (!usingLocal)
|
|
{
|
|
var http = HttpClientFactory.CreateClient();
|
|
var response = await http.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
|
|
if (!response.IsSuccessStatusCode) return [];
|
|
return await response.Content.ReadAsByteArrayAsync();
|
|
}
|
|
else
|
|
{
|
|
if (System.IO.File.Exists(url)) return System.IO.File.ReadAllBytes(url);
|
|
return [];
|
|
}
|
|
}
|
|
}
|