_sega 0ba6c842b2 Настройки с сайта работают
След. шаг это авторизация
2026-01-28 12:41:28 +03:00

313 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
//Зависит от SettingsManager
[System.Serializable]
public class ServerResponse
{
public string message;
public string timestamp;
}
public class WebServer : MonoBehaviour
{
private HttpListener listener;
private bool isRunning = true;
private static byte[] css;
async void Start()
{
SettingsManager.Initialize();//надо будет убирать
LoadCss();
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 == "GET" && path == "/style.css")
{
await HandleCssRequestAsync(context);
}
else if (method == "POST" && path == "/upd")
{
await HandlePostUpdateAsync(context);
}
else
{
SendHtmlResponse(context, "<h1>404 Not Found</h1>", 404);
}
}
catch (Exception ex)
{
Debug.LogError($"Error processing request: {ex.Message}");
SendHtmlResponse(context, $"<h1>Error: {ex.Message}</h1>", 500);
}
}
async Task HandleGetSettingsAsync(HttpListenerContext context)
{
await Task.Run(() =>
{
try
{
Debug.Log("Starting SettingsToHtml...");
var stopwatch = System.Diagnostics.Stopwatch.StartNew();
var htmlTask = Task.Run(() =>
HtmlBuilder.GetSettingsPage(SettingsManager.Container.Settings));
//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 = "<h1>Error: Method returned empty string</h1>";
}
SendHtmlResponse(context, htmlContent);
}
else
{
Debug.LogError("GetSettingsString TIMEOUT (5 seconds)!");
SendHtmlResponse(context, "<h1>Error: Settings generation timeout</h1>", 500);
}
}
catch (Exception ex)
{
Debug.LogError($"Error in GetSettingsString: {ex.Message}");
SendHtmlResponse(context, $"<h1>Error: {ex.Message}</h1>", 500);
}
});
}
async Task HandleCssRequestAsync(HttpListenerContext context)
{
context.Response.ContentType = "text/css";
context.Response.ContentLength64 = css.Length;
await context.Response.OutputStream.WriteAsync(css, 0, css.Length);
context.Response.OutputStream.Close();
}
private static void LoadCss()
{
TextAsset cssAsset = Resources.Load<TextAsset>("style");
try
{
print(cssAsset.text);
}
catch (Exception)
{
throw;
}
if (cssAsset != null)
{
css= Encoding.UTF8.GetBytes(cssAsset.text);
Debug.Log("CSS OK");
}
else
{
Debug.LogWarning("CSS NOT OK");
css = new byte[0];
}
}
async Task HandlePostUpdateAsync(HttpListenerContext context)
{
try
{
Encoding encoding = Encoding.UTF8;
string contentType = context.Request.ContentType?.ToLower() ?? "";
if (contentType.Contains("charset="))
{
try
{
string charset = contentType.Split("charset=")[1].Trim().Split(';')[0];
encoding = Encoding.GetEncoding(charset);
Debug.Log($"Определена кодировка из Content-Type: {charset}");
}
catch
{
encoding = Encoding.UTF8;
Debug.Log($"Не удалось определить кодировку из Content-Type, используем UTF-8");
}
}
// Читаем тело POST-запроса
string requestBody;
using (var reader = new StreamReader(context.Request.InputStream, encoding))
{
requestBody = await reader.ReadToEndAsync();
}
var formDict = new Dictionary<string, string>();
try
{
var formData = System.Web.HttpUtility.ParseQueryString(requestBody, encoding);
Debug.Log("\n=== Данные через ParseQueryString ===");
foreach (string key in formData.AllKeys)
{
if (key != null)
{
string value = formData[key] ?? "";
formDict[key] = value;
Debug.Log($" {key} = {formDict[key]}");
if (key.Contains("%"))
{
string decodedKey = Uri.UnescapeDataString(key);
Debug.Log($"РУЧНОЙ ДЕКОД: {decodedKey}");
}
}
}
}
catch (Exception parseEx)
{
Debug.LogWarning($"ParseQueryString ошибка: {parseEx.Message}");
}
SettingsApplier.ApplySettings(formDict);
//SettingsManager.OnSettingsChanged?.Invoke();
UnityMainThreadDispatcher.Instance.Enqueue(() => SettingsManager.OnSettingsChanged?.Invoke());
UnityMainThreadDispatcher.Instance.Enqueue(() => GameManager.instance.AdminPanel.GetComponent<SettingsScreen>().RefreshViews());
// Отправляем ответ обратно
string responseHtml = @"
<html>
<head>
<meta charset='UTF-8'>
<title>Обновлено</title>
<style>
body { font-family: Arial, sans-serif; padding: 20px; }
.success { color: green; font-weight: bold; }
.info { margin: 20px 0; padding: 10px; background: #f0f0f0; }
</style>
</head>
<body>
<h1 class='success'>✓ Данные успешно получены!</h1>
<div class='info'>
<p>Сервер обработал ваш запрос.</p>
<p>Полученные данные:</p>
<ul>";
// Добавляем список полученных данных в ответ
foreach (var kvp in formDict)
{
responseHtml += $"<li><strong>{kvp.Key}</strong>: {kvp.Value}</li>";
}
responseHtml += @"
</ul>
</div>
<a href='/' style='display: inline-block; margin-top: 20px; padding: 10px 20px; background: #007bff; color: white; text-decoration: none; border-radius: 5px;'>
Вернуться к настройкам
</a>
<script>
// Через 5 секунд возвращаемся назад
setTimeout(function() {
window.location.href = '/';
}, 5000);
</script>
</body>
</html>";
SendHtmlResponse(context, responseHtml);
}
catch (Exception ex)
{
Debug.LogError($"Ошибка обработки POST /upd: {ex.Message}");
Debug.LogError($"StackTrace: {ex.StackTrace}");
SendHtmlResponse(context,
$"<html><head><meta charset='UTF-8'><title>Ошибка</title></head><body>" +
$"<h1 style='color:red;'>Ошибка: {ex.Message}</h1>" +
$"<pre>{ex.StackTrace}</pre>" +
$"<a href='/'>Вернуться назад</a></body></html>",
500);
}
}
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();
}
}