using System; using System.IO; using System.Net; using System.Text; using System.Threading.Tasks; using UnityEngine; // Класс для сериализации в JSON [System.Serializable] public class ServerResponse { public string message; public string timestamp; } public class WebServer : MonoBehaviour { private HttpListener listener; private bool isRunning = true; async void Start() { SettingsManager.Initialize(); await StartWebServerAsync(); } async Task StartWebServerAsync() { listener = new HttpListener(); listener.Prefixes.Add("http://localhost:8080/"); //тест listener.Prefixes.Add("http://fishka:8080/"); // 4. ВСЕ сетевые интерфейсы (самый важный!) listener.Prefixes.Add("http://*:8080/"); listener.Start(); Debug.Log("Async Web сервер запущен"); while (isRunning) { try { var context = await listener.GetContextAsync(); _ = Task.Run(() => ProcessRequestAsync(context)); } catch (System.Exception e) { Debug.LogError($"Ошибка: {e.Message}"); } } } async Task ProcessRequestAsync(HttpListenerContext context) { try { string path = context.Request.Url.LocalPath; string method = context.Request.HttpMethod; Debug.Log($"Запрос: {method} {path}"); if (method == "GET" && path == "/") { await HandleGetSettingsAsync(context); } else if (method == "POST" && path == "/upd") { await HandlePostUpdateAsync(context); } else { SendHtmlResponse(context, "

404 Not Found

", 404); } } catch (Exception ex) { Debug.LogError($"Error processing request: {ex.Message}"); SendHtmlResponse(context, $"

Error: {ex.Message}

", 500); } } async Task HandleGetSettingsAsync(HttpListenerContext context) { await Task.Run(() => { try { Debug.Log("Starting SettingsToHtml..."); var stopwatch = System.Diagnostics.Stopwatch.StartNew(); var htmlTask = Task.Run(() => SettingsToHtml.GetSettingsString(SettingsManager.Container.Settings)); if (htmlTask.Wait(TimeSpan.FromSeconds(5))) { string htmlContent = htmlTask.Result; stopwatch.Stop(); Debug.Log($"GetSettingsString выполнился за {stopwatch.ElapsedMilliseconds}ms"); if (string.IsNullOrEmpty(htmlContent)) { htmlContent = "

Error: Method returned empty string

"; } SendHtmlResponse(context, htmlContent); } else { Debug.LogError("GetSettingsString TIMEOUT (5 seconds)!"); SendHtmlResponse(context, "

Error: Settings generation timeout

", 500); } } catch (Exception ex) { Debug.LogError($"Error in GetSettingsString: {ex.Message}"); SendHtmlResponse(context, $"

Error: {ex.Message}

", 500); } }); } async Task HandlePostUpdateAsync(HttpListenerContext context) { try { // Читаем тело POST-запроса string requestBody; using (var reader = new StreamReader(context.Request.InputStream, context.Request.ContentEncoding)) { requestBody = await reader.ReadToEndAsync(); } Debug.Log($"Получен POST запрос на /upd"); Debug.Log($"Тело запроса: {requestBody}"); // Здесь вы можете обработать данные формы // Обычно данные формы приходят в формате: key1=value1&key2=value2 // Вы можете их разобрать: var formData = System.Web.HttpUtility.ParseQueryString(requestBody); // Пример: если у вас есть поле "action" в форме string action = formData["action"]; string buttonValue = formData["submit"]; // для input type="submit" Debug.Log($"Action: {action}, Button value: {buttonValue}"); // Пример обработки разных кнопок: // Если у вас несколько кнопок с разными именами/значениями if (!string.IsNullOrEmpty(formData["save"])) { await HandleSaveAction(formData); } else if (!string.IsNullOrEmpty(formData["reset"])) { await HandleResetAction(formData); } // Отправляем ответ обратно string responseHtml = @" Обновлено

Данные успешно получены!

Сервер обработал ваш запрос.

Вернуться назад "; SendHtmlResponse(context, responseHtml); } catch (Exception ex) { Debug.LogError($"Error handling POST /upd: {ex.Message}"); SendHtmlResponse(context, $"

Error: {ex.Message}

", 500); } } async Task HandleSaveAction(System.Collections.Specialized.NameValueCollection formData) { // Здесь обрабатываем сохранение настроек Debug.Log("Обработка сохранения настроек..."); // Пример: получаем значения из формы и обновляем настройки foreach (string key in formData.AllKeys) { string value = formData[key]; Debug.Log($"Поле формы: {key} = {value}"); // TODO: Обновить SettingsManager.Container.Settings на основе данных формы } // TODO: Сохранить настройки // SettingsManager.Save(); await Task.CompletedTask; } async Task HandleResetAction(System.Collections.Specialized.NameValueCollection formData) { // Здесь обрабатываем сброс настроек Debug.Log("Обработка сброса настроек..."); // TODO: Сбросить настройки к значениям по умолчанию await Task.CompletedTask; } void SendHtmlResponse(HttpListenerContext context, string html, int statusCode = 200) { try { byte[] buffer = Encoding.UTF8.GetBytes(html); context.Response.StatusCode = statusCode; context.Response.ContentType = "text/html; charset=utf-8"; context.Response.ContentLength64 = buffer.Length; context.Response.OutputStream.Write(buffer, 0, buffer.Length); context.Response.OutputStream.Close(); } catch (Exception ex) { Debug.LogError($"Error sending response: {ex.Message}"); } } void OnDestroy() { isRunning = false; listener?.Stop(); listener?.Close(); } private void OnApplicationQuit() { isRunning = false; listener?.Stop(); listener?.Close(); } }