451 lines
16 KiB
C#
451 lines
16 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Web.Http;
|
|
using System.Linq;
|
|
using System.Net.Http;
|
|
using System.Net;
|
|
using System.IO;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.Drawing.Imaging;
|
|
using VNCServerList.Models;
|
|
using VNCServerList.Services;
|
|
|
|
namespace VNCServerList.Web.Controllers
|
|
{
|
|
[RoutePrefix("api/vncserver")]
|
|
public class VNCServerController : ApiController
|
|
{
|
|
private readonly DatabaseService _databaseService;
|
|
private readonly VNCService _vncService;
|
|
private readonly SettingsService _settingsService;
|
|
|
|
public VNCServerController()
|
|
{
|
|
_settingsService = new SettingsService();
|
|
_databaseService = new DatabaseService();
|
|
_vncService = new VNCService(_databaseService, _settingsService);
|
|
}
|
|
|
|
[HttpGet]
|
|
[Route("list")]
|
|
public IHttpActionResult GetServerList(string userName = null)
|
|
{
|
|
try
|
|
{
|
|
var servers = _databaseService.GetAllServers();
|
|
|
|
// 사용자 이름이 있으면 필터링
|
|
if (!string.IsNullOrEmpty(userName))
|
|
{
|
|
servers = servers.Where(s => s.User.Equals(userName, StringComparison.OrdinalIgnoreCase)).ToList();
|
|
}
|
|
|
|
// 사용자명으로 오름차순 정렬
|
|
var sortedServers = servers.OrderBy(s => s.User).ThenBy(s => s.IP).ToList();
|
|
return Ok(sortedServers);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpGet]
|
|
[Route("get/{user}/{ip}")]
|
|
public IHttpActionResult GetServer(string user, string ip)
|
|
{
|
|
try
|
|
{
|
|
var server = _databaseService.GetServerByUserAndIP(user, ip);
|
|
if (server == null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
return Ok(server);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpPost]
|
|
[Route("add")]
|
|
public IHttpActionResult AddServer([FromBody] VNCServer server)
|
|
{
|
|
try
|
|
{
|
|
if (server == null)
|
|
{
|
|
return BadRequest("서버 정보가 없습니다.");
|
|
}
|
|
|
|
// 아이콘이 Base64로 전송된 경우 처리
|
|
if (!string.IsNullOrEmpty(server.IconBase64))
|
|
{
|
|
try
|
|
{
|
|
var iconData = Convert.FromBase64String(server.IconBase64);
|
|
server.Icon = ResizeImage(iconData, 128, 128);
|
|
}
|
|
catch
|
|
{
|
|
return BadRequest("아이콘 데이터 형식이 올바르지 않습니다.");
|
|
}
|
|
}
|
|
|
|
bool success = _databaseService.AddServer(server);
|
|
if (success)
|
|
{
|
|
return Ok(new { Message = "서버가 성공적으로 추가되었습니다." });
|
|
}
|
|
else
|
|
{
|
|
return BadRequest("서버 추가에 실패했습니다.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpPut]
|
|
[Route("update/{originalUser}/{originalIp}")]
|
|
public IHttpActionResult UpdateServer(string originalUser, string originalIp, [FromBody] VNCServer server)
|
|
{
|
|
try
|
|
{
|
|
if (server == null)
|
|
{
|
|
return BadRequest("서버 정보가 없습니다.");
|
|
}
|
|
|
|
// 아이콘이 Base64로 전송된 경우 처리
|
|
if (!string.IsNullOrEmpty(server.IconBase64))
|
|
{
|
|
try
|
|
{
|
|
var iconData = Convert.FromBase64String(server.IconBase64);
|
|
server.Icon = ResizeImage(iconData, 128, 128);
|
|
}
|
|
catch
|
|
{
|
|
return BadRequest("아이콘 데이터 형식이 올바르지 않습니다.");
|
|
}
|
|
}
|
|
|
|
// 원본 사용자명과 IP로 서버를 찾아서 업데이트
|
|
bool success = _databaseService.UpdateServerByUserAndIP(originalUser, originalIp, server);
|
|
if (success)
|
|
{
|
|
return Ok(new { Message = "서버가 성공적으로 업데이트되었습니다." });
|
|
}
|
|
else
|
|
{
|
|
return NotFound();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpDelete]
|
|
[Route("delete/{user}/{ip}")]
|
|
public IHttpActionResult DeleteServer(string user, string ip)
|
|
{
|
|
try
|
|
{
|
|
bool success = _databaseService.DeleteServer(user, ip);
|
|
if (success)
|
|
{
|
|
return Ok(new { Message = "서버가 성공적으로 삭제되었습니다." });
|
|
}
|
|
else
|
|
{
|
|
return NotFound();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpPost]
|
|
[Route("connect/{user}/{ip}")]
|
|
public IHttpActionResult ConnectToServer(string user, string ip)
|
|
{
|
|
try
|
|
{
|
|
bool success = _vncService.ConnectToServer(user, ip);
|
|
if (success)
|
|
{
|
|
return Ok(new { Message = "VNC 연결이 시작되었습니다." });
|
|
}
|
|
else
|
|
{
|
|
return BadRequest("VNC 연결에 실패했습니다.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpGet]
|
|
[Route("vnc-status")]
|
|
public IHttpActionResult GetVNCStatus()
|
|
{
|
|
try
|
|
{
|
|
bool isInstalled = _vncService.IsVNCViewerInstalled();
|
|
string path = _vncService.GetVNCViewerPath();
|
|
|
|
return Ok(new
|
|
{
|
|
IsInstalled = isInstalled,
|
|
Path = path
|
|
});
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpPost]
|
|
[Route("set-vnc-path")]
|
|
public IHttpActionResult SetVNCPath([FromBody] VNCPathRequest data)
|
|
{
|
|
try
|
|
{
|
|
string path = data.Path;
|
|
if (string.IsNullOrEmpty(path))
|
|
{
|
|
return BadRequest("VNC Viewer 경로가 제공되지 않았습니다.");
|
|
}
|
|
|
|
_vncService.SetVNCViewerPath(path);
|
|
return Ok(new { Message = "VNC Viewer 경로가 설정되었습니다." });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpGet]
|
|
[Route("settings")]
|
|
public IHttpActionResult GetSettings()
|
|
{
|
|
try
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("=== 설정 조회 시작 ===");
|
|
|
|
var settings = _settingsService.GetSettings();
|
|
|
|
// 디버깅용 로그
|
|
System.Diagnostics.Debug.WriteLine($"조회된 설정: VNCViewerPath='{settings.VNCViewerPath}', WebServerPort={settings.WebServerPort}");
|
|
System.Diagnostics.Debug.WriteLine("=== 설정 조회 완료 ===");
|
|
|
|
return Ok(settings);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine($"설정 조회 오류: {ex.Message}");
|
|
System.Diagnostics.Debug.WriteLine($"스택 트레이스: {ex.StackTrace}");
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpPost]
|
|
[Route("settings")]
|
|
public IHttpActionResult UpdateSettings([FromBody] AppSettings settings)
|
|
{
|
|
try
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("=== 설정 저장 요청 시작 ===");
|
|
|
|
if (settings == null)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine("설정 객체가 null입니다.");
|
|
return BadRequest("설정 정보가 없습니다.");
|
|
}
|
|
|
|
// 디버깅용 로그
|
|
System.Diagnostics.Debug.WriteLine($"받은 설정 데이터: VNCViewerPath='{settings.VNCViewerPath}', WebServerPort={settings.WebServerPort}");
|
|
System.Diagnostics.Debug.WriteLine($"VNCViewerPath 타입: {settings.VNCViewerPath?.GetType()}");
|
|
System.Diagnostics.Debug.WriteLine($"WebServerPort 타입: {settings.WebServerPort.GetType()}");
|
|
|
|
_settingsService.SaveSettings(settings);
|
|
|
|
// 저장된 설정 확인
|
|
var savedSettings = _settingsService.GetSettings();
|
|
System.Diagnostics.Debug.WriteLine($"저장된 설정: VNCViewerPath='{savedSettings.VNCViewerPath}', WebServerPort={savedSettings.WebServerPort}");
|
|
System.Diagnostics.Debug.WriteLine("=== 설정 저장 완료 ===");
|
|
|
|
return Ok(new { Message = "설정이 저장되었습니다." });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
System.Diagnostics.Debug.WriteLine($"설정 저장 오류: {ex.Message}");
|
|
System.Diagnostics.Debug.WriteLine($"스택 트레이스: {ex.StackTrace}");
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpGet]
|
|
[Route("icon/{user}/{ip}")]
|
|
public HttpResponseMessage GetServerIcon(string user, string ip)
|
|
{
|
|
try
|
|
{
|
|
var server = _databaseService.GetServerByUserAndIP(user, ip);
|
|
if (server?.Icon == null || server.Icon.Length == 0)
|
|
{
|
|
return Request.CreateResponse(HttpStatusCode.NotFound);
|
|
}
|
|
|
|
var response = Request.CreateResponse(HttpStatusCode.OK);
|
|
response.Content = new ByteArrayContent(server.Icon);
|
|
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("image/png");
|
|
return response;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return Request.CreateResponse(HttpStatusCode.InternalServerError, ex.Message);
|
|
}
|
|
}
|
|
|
|
private byte[] ResizeImage(byte[] imageData, int maxWidth = 128, int maxHeight = 128)
|
|
{
|
|
using (var originalStream = new MemoryStream(imageData))
|
|
using (var originalImage = Image.FromStream(originalStream))
|
|
{
|
|
// 원본 이미지 크기
|
|
int originalWidth = originalImage.Width;
|
|
int originalHeight = originalImage.Height;
|
|
|
|
// 리사이즈가 필요한지 확인
|
|
if (originalWidth <= maxWidth && originalHeight <= maxHeight)
|
|
{
|
|
return imageData; // 리사이즈 불필요
|
|
}
|
|
|
|
// 새로운 크기 계산 (비율 유지)
|
|
double ratioX = (double)maxWidth / originalWidth;
|
|
double ratioY = (double)maxHeight / originalHeight;
|
|
double ratio = Math.Min(ratioX, ratioY);
|
|
|
|
int newWidth = (int)(originalWidth * ratio);
|
|
int newHeight = (int)(originalHeight * ratio);
|
|
|
|
// 새 이미지 생성
|
|
using (var resizedImage = new Bitmap(newWidth, newHeight))
|
|
using (var graphics = Graphics.FromImage(resizedImage))
|
|
{
|
|
// 고품질 리사이즈 설정
|
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
|
|
// 이미지 그리기
|
|
graphics.DrawImage(originalImage, 0, 0, newWidth, newHeight);
|
|
|
|
// PNG로 변환하여 반환
|
|
using (var outputStream = new MemoryStream())
|
|
{
|
|
resizedImage.Save(outputStream, ImageFormat.Png);
|
|
return outputStream.ToArray();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
[HttpPost]
|
|
[Route("icon/{user}/{ip}")]
|
|
public IHttpActionResult UploadServerIcon(string user, string ip)
|
|
{
|
|
try
|
|
{
|
|
var httpRequest = System.Web.HttpContext.Current.Request;
|
|
if (httpRequest.Files.Count == 0)
|
|
{
|
|
return BadRequest("업로드된 파일이 없습니다.");
|
|
}
|
|
|
|
var file = httpRequest.Files[0];
|
|
if (file.ContentLength > 1024 * 1024) // 1MB 제한
|
|
{
|
|
return BadRequest("파일 크기는 1MB를 초과할 수 없습니다.");
|
|
}
|
|
|
|
using (var memoryStream = new MemoryStream())
|
|
{
|
|
file.InputStream.CopyTo(memoryStream);
|
|
var originalIconData = memoryStream.ToArray();
|
|
|
|
// 이미지 리사이즈 (128x128로 제한)
|
|
var resizedIconData = ResizeImage(originalIconData, 128, 128);
|
|
|
|
var server = _databaseService.GetServerByUserAndIP(user, ip);
|
|
if (server == null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
server.Icon = resizedIconData;
|
|
bool success = _databaseService.UpdateServer(server);
|
|
|
|
if (success)
|
|
{
|
|
return Ok(new { Message = "아이콘이 성공적으로 업로드되었습니다." });
|
|
}
|
|
else
|
|
{
|
|
return BadRequest("아이콘 업로드에 실패했습니다.");
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
|
|
[HttpDelete]
|
|
[Route("icon/{user}/{ip}")]
|
|
public IHttpActionResult DeleteServerIcon(string user, string ip)
|
|
{
|
|
try
|
|
{
|
|
var server = _databaseService.GetServerByUserAndIP(user, ip);
|
|
if (server == null)
|
|
{
|
|
return NotFound();
|
|
}
|
|
|
|
server.Icon = null;
|
|
bool success = _databaseService.UpdateServer(server);
|
|
|
|
if (success)
|
|
{
|
|
return Ok(new { Message = "아이콘이 성공적으로 삭제되었습니다." });
|
|
}
|
|
else
|
|
{
|
|
return BadRequest("아이콘 삭제에 실패했습니다.");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
return InternalServerError(ex);
|
|
}
|
|
}
|
|
}
|
|
} |