private void OnDataReceived(IAsyncResult async) { HttpSocketState state = (HttpSocketState)async.AsyncState; if (state == null || state.Socket == null) { return; } try { int received = state.Socket.EndReceive(async); if (received == 0) { return; } HttpRequest request; using (var ms = new MemoryStream(state.Buffer, 0, received)) request = HttpHelper.GetRequest(ms); Logger.Info("Data received: " + Encoding.UTF8.GetString(state.Buffer, 0, received).Replace('\n', ' ').Replace('\r', ' ')); using (var ms = new MemoryStream(state.Buffer)) { if (request.Url.EndsWith("news.txt")) { HttpHelper.WriteResponse(ms, HttpResponceBuilder.File("Resources/Files/Russiandow_news.txt", Encoding.Unicode)); goto END; } if (request.Url.StartsWith("/motd/motd")) { HttpHelper.WriteResponse(ms, HttpResponceBuilder.File("Resources/Files/Russiandow_news.txt", Encoding.Unicode)); goto END; } if (request.Url.StartsWith("/motd/vercheck")) { //HttpHelper.WriteResponse(ms, HttpResponceBuilder.Text(@"\newver\1\newvername\1.4\dlurl\http://127.0.0.1/NewPatchHere.exe")); HttpHelper.WriteResponse(ms, HttpResponceBuilder.Text(@"\newver\0")); goto END; } if (request.Url.EndsWith("LobbyRooms.lua")) { HttpHelper.WriteResponse(ms, HttpResponceBuilder.File("Resources/Files/LobbyRooms.lua", Encoding.ASCII)); goto END; } if (request.Url.EndsWith("AutomatchDefaultsSS.lua") || request.Url.EndsWith("AutomatchDefaultsDXP2Fixed.lua")) { HttpHelper.WriteResponse(ms, HttpResponceBuilder.File("Resources/Files/AutomatchDefaults.lua", Encoding.ASCII)); goto END; } if (request.Url.EndsWith("homepage.php.htm")) { if (StatsResponce == null || (DateTime.Now - _lastStatsUpdate).TotalMinutes > 5) { StatsResponce = BuildTop10StatsResponce(); } HttpHelper.WriteResponse(ms, StatsResponce); goto END; } if (request.Url.StartsWith("/all")) { HttpHelper.WriteResponse(ms, BuildAllStatsResponce()); goto END; } HttpHelper.WriteResponse(ms, HttpResponceBuilder.NotFound()); END: // Завершение отправки var length = (int)ms.Position; ms.Position = 0; state.Socket.Send(state.Buffer, 0, length, SocketFlags.None); state.Dispose(); } } catch (ObjectDisposedException) { if (state != null) { state.Dispose(); } state = null; return; } catch (SocketException e) { switch (e.SocketErrorCode) { case SocketError.ConnectionReset: case SocketError.Disconnecting: case SocketError.NotConnected: case SocketError.TimedOut: if (state != null) { state.Dispose(); } state = null; return; default: Logger.Error(e, $"Error receiving data. SocketErrorCode: {e.SocketErrorCode}"); if (state != null) { state.Dispose(); } state = null; return; } } catch (Exception e) { Logger.Error(e, $"Error receiving data"); } // and we wait for more data... CONTINUE : WaitForData(ref state); }
/// <summary> /// Обработка HTTP запроса от игры на порт 80. /// Обрабатывает новостное сообщение, наличие патча, запрос страницы статистики, настройки автоматча и список имен комнат чата. /// </summary> void OnHttpReceived(TcpPortHandler handler, TcpClientNode node, byte[] buffer, int count) { try { var str = buffer.ToUtf8(count); LogTrace("HTTP CLIENT HASH " + node.GetHashCode()); LogTrace("HTTP " + str); HttpRequest request; using (var ms = new MemoryStream(buffer, 0, count, false, true)) request = HttpHelper.GetRequest(ms); using (var ms = new MemoryStream()) { // Запрос страницы статистики по кнопке из игры if (request.Url.StartsWith("/SS_StatsPage", StringComparison.OrdinalIgnoreCase)) { HttpHelper.WriteResponse(ms, HttpResponceBuilder.DowstatsRedirect()); goto END; } // Запрос текста новостей if (request.Url.EndsWith("news.txt", StringComparison.OrdinalIgnoreCase)) { LogForUser($"News requested"); // Фикс для рускоязычных if (request.Url.EndsWith("Russiandow_news.txt", StringComparison.OrdinalIgnoreCase)) { HttpHelper.WriteResponse(ms, HttpResponceBuilder.Text(GameSpyHttpDataConstants.RusNews, Encoding.Unicode)); } else { HttpHelper.WriteResponse(ms, HttpResponceBuilder.Text(GameSpyHttpDataConstants.EnNews, Encoding.Unicode)); } goto END; } // Отправка сообщения дня. Вроде нигде не отображается if (request.Url.StartsWith("/motd/motd", StringComparison.OrdinalIgnoreCase)) { HttpHelper.WriteResponse(ms, HttpResponceBuilder.Text(GameSpyHttpDataConstants.RusNews, Encoding.Unicode)); goto END; } // Проверка на существование патча. Можно прокидывать свои патчи для игры if (request.Url.StartsWith("/motd/vercheck", StringComparison.OrdinalIgnoreCase)) { LogForUser($"Vercheck requested"); // Пример отправки ссылки на скачивания патча //HttpHelper.WriteResponse(ms, HttpResponceBuilder.Text(@"\newver\1\newvername\1.4\dlurl\http://127.0.0.1/NewPatchHere.exe")); // Отправка инфы о том, что патча сейчас нет HttpHelper.WriteResponse(ms, HttpResponceBuilder.Text(@"\newver\0", Encoding.UTF8)); goto END; } // Запрос списка комнат с именами для отображения в интерфейсе if (request.Url.EndsWith("LobbyRooms.lua", StringComparison.OrdinalIgnoreCase)) { LogForUser($"LobbyRooms requested"); HttpHelper.WriteResponse(ms, HttpResponceBuilder.Text(GameSpyHttpDataConstants.RoomPairs, Encoding.ASCII)); goto END; } // Запрос дефолных настроек автоматча if (request.Url.EndsWith("AutomatchDefaultsSS.lua", StringComparison.OrdinalIgnoreCase) || request.Url.EndsWith("AutomatchDefaultsDXP2Fixed.lua", StringComparison.OrdinalIgnoreCase)) { LogForUser($"AutomatchDefaults requested"); //HttpHelper.WriteResponse(ms, HttpResponceBuilder.TextFileBytes(CoreContext.MasterServer.AutomatchDefaultsBytes)); HttpHelper.WriteResponse(ms, HttpResponceBuilder.Text(GameSpyHttpDataConstants.AutomatchDefaults, Encoding.ASCII)); goto END; } /*if (request.Url.EndsWith("homepage.php.htm", StringComparison.OrdinalIgnoreCase)) * { * if (StatsResponce == null || (DateTime.Now - _lastStatsUpdate).TotalMinutes > 5) * StatsResponce = BuildTop10StatsResponce(); * * HttpHelper.WriteResponse(ms, StatsResponce); * goto END; * }*/ // Если дошли сюда - отправляет NotFound HttpHelper.WriteResponse(ms, HttpResponceBuilder.NotFound()); END: LogTrace("HTTP WANT TO SEND " + node.GetHashCode() + " " + ms.Length); handler.Send(node, ms.ToArray()); handler.KillClient(node); } } catch (InvalidDataException ex) { //Log(ex); } }