Compare commits
No commits in common. "315a3927f33bae31ba5916a9ed8c666852e550cc" and "3a6f7e7d7d27866fca0c6476b3d5932d66ad0b9f" have entirely different histories.
315a3927f3
...
3a6f7e7d7d
|
@ -196,6 +196,3 @@
|
||||||
[submodule "third_party/boost/mysql"]
|
[submodule "third_party/boost/mysql"]
|
||||||
path = third_party/boost/mysql
|
path = third_party/boost/mysql
|
||||||
url = https://github.com/boostorg/mysql.git
|
url = https://github.com/boostorg/mysql.git
|
||||||
[submodule "third_party/spdlog"]
|
|
||||||
path = third_party/spdlog
|
|
||||||
url = https://github.com/gabime/spdlog
|
|
||||||
|
|
|
@ -2,6 +2,10 @@ add_library(base_base
|
||||||
assert.cpp
|
assert.cpp
|
||||||
backoff.cpp
|
backoff.cpp
|
||||||
html_escape.cpp
|
html_escape.cpp
|
||||||
|
|
||||||
|
# logging library
|
||||||
|
logger.cpp
|
||||||
|
stdout_sink.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
lobbyserver_target(base_base)
|
lobbyserver_target(base_base)
|
||||||
|
@ -9,7 +13,6 @@ lobbyserver_target(base_base)
|
||||||
target_link_libraries(base_base PUBLIC
|
target_link_libraries(base_base PUBLIC
|
||||||
# techinically not needed anymore but /shrug
|
# techinically not needed anymore but /shrug
|
||||||
base::impl
|
base::impl
|
||||||
spdlog::spdlog
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(base::base ALIAS base_base)
|
add_library(base::base ALIAS base_base)
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <spdlog/spdlog.h>
|
#include <base/logger.hpp>
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
|
|
||||||
|
static Logger gAssertLogger{MakeChannelId(MessageSource::Base, MessageComponentSource::Base_Assertions)};
|
||||||
|
|
||||||
[[noreturn]] void ExitMsg(const char* message) {
|
[[noreturn]] void ExitMsg(const char* message) {
|
||||||
spdlog::error("{}", message);
|
gAssertLogger.Fatal("{}", message);
|
||||||
std::exit(0xAF);
|
std::exit(0xAF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,172 @@
|
||||||
|
#include <base/assert.hpp>
|
||||||
|
#include <base/logger.hpp>
|
||||||
|
#include <base/types.hpp>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <deque>
|
||||||
|
#include <iostream>
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
namespace logger_detail {
|
||||||
|
|
||||||
|
static constexpr std::string_view SeverityToString(MessageSeverity sev) {
|
||||||
|
// This must match order of logger_detail::MessageSeverity.
|
||||||
|
const char* MessageSeverityStringTable[] = { "Debug", "Info", "Warn", "Error", "Fatal" };
|
||||||
|
return MessageSeverityStringTable[static_cast<std::size_t>(sev)];
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr static auto ChannelToString(ChannelId channelId) -> std::string_view {
|
||||||
|
MessageSource src;
|
||||||
|
MessageComponentSource comp;
|
||||||
|
|
||||||
|
ChannelIdToComponents(channelId, src, comp);
|
||||||
|
|
||||||
|
switch(src) {
|
||||||
|
case MessageSource::Main: {
|
||||||
|
switch(comp) {
|
||||||
|
case MessageComponentSource::Main_Global: return "Main::Global";
|
||||||
|
default: BASE_CHECK(false, "Invalid component source");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
case MessageSource::Base: {
|
||||||
|
switch(comp) {
|
||||||
|
case MessageComponentSource::Base_Assertions: return "Base::Assert";
|
||||||
|
default: BASE_CHECK(false, "Invalid component source");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
case MessageSource::Http: {
|
||||||
|
switch(comp) {
|
||||||
|
case MessageComponentSource::Http_Server: return "HTTP::Server";
|
||||||
|
case MessageComponentSource::Http_WebSocketClient: return "HTTP::WebSocketClient";
|
||||||
|
default: BASE_CHECK(false, "Invalid component source");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
case MessageSource::Server: {
|
||||||
|
switch(comp) {
|
||||||
|
case MessageComponentSource::Server_Server: return "LobbyServer2::Server";
|
||||||
|
default: BASE_CHECK(false, "Invalid component source");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
default: BASE_CHECK(false, "Invalid channel source {:04x}", static_cast<u16>(src));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LoggerThreadData {
|
||||||
|
// Logger thread stuff
|
||||||
|
std::thread loggerThread;
|
||||||
|
std::mutex logQueueMutex;
|
||||||
|
std::condition_variable logQueueCv;
|
||||||
|
std::deque<MessageData> logQueue;
|
||||||
|
|
||||||
|
bool logThreadShutdown = false;
|
||||||
|
|
||||||
|
// N.B: This is stored/cached here just because it really does
|
||||||
|
// *NOT* need to be in a hot path.
|
||||||
|
const std::chrono::time_zone* timeZone = std::chrono::current_zone();
|
||||||
|
|
||||||
|
bool ShouldUnblock() {
|
||||||
|
// Always unblock if the logger thread needs to be shut down.
|
||||||
|
if(logThreadShutdown)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return !logQueue.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushMessage(MessageData&& md) {
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lk(logQueueMutex);
|
||||||
|
logQueue.emplace_back(std::move(md));
|
||||||
|
}
|
||||||
|
logQueueCv.notify_one();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Unique<LoggerThreadData> threadData;
|
||||||
|
|
||||||
|
void LoggerGlobalState::LoggerThread() {
|
||||||
|
auto& self = The();
|
||||||
|
|
||||||
|
// Fancy thread names.
|
||||||
|
pthread_setname_np(pthread_self(), "LoggerThread");
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
std::unique_lock<std::mutex> lk(threadData->logQueueMutex);
|
||||||
|
if(threadData->logQueue.empty()) {
|
||||||
|
// Await for messages.
|
||||||
|
threadData->logQueueCv.wait(lk, []() { return threadData->ShouldUnblock(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush the logger queue until there are no more messages.
|
||||||
|
while(!threadData->logQueue.empty()) {
|
||||||
|
self.OutputMessage(threadData->logQueue.back());
|
||||||
|
threadData->logQueue.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shutdown if requested.
|
||||||
|
if(threadData->logThreadShutdown)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerGlobalState& LoggerGlobalState::The() {
|
||||||
|
static LoggerGlobalState storage;
|
||||||
|
return storage;
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerGlobalState::LoggerGlobalState() {
|
||||||
|
// Spawn the logger thread
|
||||||
|
threadData = std::make_unique<LoggerThreadData>();
|
||||||
|
threadData->loggerThread = std::thread(&LoggerGlobalState::LoggerThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggerGlobalState::~LoggerGlobalState() {
|
||||||
|
// Shut down the logger thread
|
||||||
|
threadData->logThreadShutdown = true;
|
||||||
|
threadData->logQueueCv.notify_all();
|
||||||
|
threadData->loggerThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoggerGlobalState::AttachSink(Sink& sink) {
|
||||||
|
sinks.push_back(&sink);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LoggerGlobalState::OutputMessage(const MessageData& data) {
|
||||||
|
// give up early if no sinks are attached
|
||||||
|
if(sinks.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(data.severity < logLevel)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto formattedLoggerMessage =
|
||||||
|
std::format("[{:%F %H:%M:%S}|{}|{}] {}", std::chrono::floor<std::chrono::milliseconds>(threadData->timeZone->to_local(data.time)),
|
||||||
|
SeverityToString(data.severity), ChannelToString(data.channelId), data.message);
|
||||||
|
|
||||||
|
for(auto sink : sinks)
|
||||||
|
sink->OutputMessage(formattedLoggerMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace logger_detail
|
||||||
|
|
||||||
|
Logger& Logger::Global() {
|
||||||
|
static Logger globalLogger;
|
||||||
|
return globalLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::VOut(MessageSeverity severity, std::string_view format, std::format_args args) {
|
||||||
|
logger_detail::MessageData data {
|
||||||
|
.time = std::chrono::system_clock::now(), .severity = severity, .channelId = channelId, .message = std::vformat(format, args)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Push data into logger thread.
|
||||||
|
logger_detail::threadData->PushMessage(std::move(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace base
|
|
@ -0,0 +1,212 @@
|
||||||
|
//! Logging utilities for the Support Library
|
||||||
|
//! Using Standard C++ <format>
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <format>
|
||||||
|
#include <base/types.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace base {
|
||||||
|
|
||||||
|
namespace logger_detail {
|
||||||
|
|
||||||
|
enum class MessageSeverity { Debug, Info, Warning, Error, Fatal };
|
||||||
|
|
||||||
|
/// A message source. In our tree, this is essentially defined as
|
||||||
|
/// each library the server's made up of.
|
||||||
|
enum class MessageSource : u16 { Main = 0x1000, Base, Http, Server };
|
||||||
|
|
||||||
|
/// A component source. This basically defines "what" part of a source
|
||||||
|
/// is creating the message. For instance, the HTTP library has multiple
|
||||||
|
/// components which can each log messages.
|
||||||
|
enum class MessageComponentSource : u16 {
|
||||||
|
// The "default" global logger channel
|
||||||
|
Main_Global = 0x1000,
|
||||||
|
|
||||||
|
Base_Assertions = 0x10,
|
||||||
|
|
||||||
|
Http_Server = 0x50,
|
||||||
|
Http_Router,
|
||||||
|
Http_WebSocketClient,
|
||||||
|
|
||||||
|
Server_Server = 0x60,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A channel ID. `enum class`es are used to avoid confusion with a normal u32,
|
||||||
|
/// and to also add addional interface type safety.
|
||||||
|
///
|
||||||
|
/// A channel ID looks something like:
|
||||||
|
/// ssssssss ssssssss cccccccc cccccccc
|
||||||
|
///
|
||||||
|
/// Where:
|
||||||
|
/// s: message source
|
||||||
|
/// c: message component source
|
||||||
|
enum class ChannelId : u32 {};
|
||||||
|
|
||||||
|
/// Create a channel ID from a source and component source.
|
||||||
|
constexpr static ChannelId MakeChannelId(MessageSource source, MessageComponentSource component) {
|
||||||
|
auto srcbits = std::bit_cast<u16>(source);
|
||||||
|
auto cmpbits = std::bit_cast<u16>(component);
|
||||||
|
|
||||||
|
return static_cast<ChannelId>((static_cast<u32>(srcbits) << 16 | cmpbits));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Splits a channel ID into its individual components.
|
||||||
|
constexpr static void ChannelIdToComponents(ChannelId id, MessageSource& src, MessageComponentSource& component) {
|
||||||
|
src = static_cast<MessageSource>((static_cast<u32>(id) & 0xffff0000) >> 16);
|
||||||
|
component = static_cast<MessageComponentSource>(static_cast<u32>(id) & 0x0000ffff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The default global channel ID.
|
||||||
|
constexpr static auto ChannelGlobal = MakeChannelId(MessageSource::Main, MessageComponentSource::Main_Global);
|
||||||
|
|
||||||
|
/// Message data. This is only used by logger sinks.
|
||||||
|
struct MessageData {
|
||||||
|
std::chrono::system_clock::time_point time;
|
||||||
|
MessageSeverity severity;
|
||||||
|
|
||||||
|
ChannelId channelId; // the channel ID.
|
||||||
|
|
||||||
|
std::string message; // DO NOT SET THIS, IT WILL BE OVERWRITTEN AND I WILL BE VERY SAD -lily
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A logger sink. Outputs messages to some device (a TTY), a file,
|
||||||
|
/// what have you. Basically a interface for the logger to spit stuff out.
|
||||||
|
///
|
||||||
|
/// # Notes
|
||||||
|
/// Sinks do not run on the main application thread. Instead, they run on a
|
||||||
|
/// single Support Library internal thread which the only purpose of is to
|
||||||
|
/// stream logger messages and output them, from a internally managed queue.
|
||||||
|
///
|
||||||
|
/// This is techinically a implementation detail, but for implementers of logger
|
||||||
|
/// sinks it's probably a good idea for them to know just in case.
|
||||||
|
///
|
||||||
|
/// Do note that you probably don't have to actually do any thread-safety magic
|
||||||
|
/// in your sink implementation, since it's only a single thread/etc...
|
||||||
|
struct Sink {
|
||||||
|
virtual void OutputMessage(std::string_view message) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Shared global state all loggers use.
|
||||||
|
struct LoggerGlobalState {
|
||||||
|
static LoggerGlobalState& The();
|
||||||
|
|
||||||
|
void AttachSink(Sink& sink);
|
||||||
|
|
||||||
|
void OutputMessage(const MessageData& data);
|
||||||
|
|
||||||
|
/// Get the current log level.
|
||||||
|
MessageSeverity GetLogLevel() const { return logLevel; }
|
||||||
|
|
||||||
|
/// Set the current log level.
|
||||||
|
void SetLogLevel(MessageSeverity newLogLevel) { logLevel = newLogLevel; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
LoggerGlobalState();
|
||||||
|
~LoggerGlobalState();
|
||||||
|
|
||||||
|
std::vector<Sink*> sinks;
|
||||||
|
MessageSeverity logLevel { MessageSeverity::Info };
|
||||||
|
|
||||||
|
static void LoggerThread();
|
||||||
|
};
|
||||||
|
|
||||||
|
inline auto& GlobalState() {
|
||||||
|
return LoggerGlobalState::The();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace logger_detail
|
||||||
|
|
||||||
|
using logger_detail::ChannelId;
|
||||||
|
using logger_detail::MessageComponentSource;
|
||||||
|
using logger_detail::MessageSource;
|
||||||
|
|
||||||
|
using logger_detail::MakeChannelId;
|
||||||
|
|
||||||
|
/// Attach a sink to all Support loggers; allowing it to output logger messages.
|
||||||
|
inline void AttachSink(logger_detail::Sink& sink) {
|
||||||
|
logger_detail::GlobalState().AttachSink(sink);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline logger_detail::MessageSeverity GetLogLevel() {
|
||||||
|
return logger_detail::GlobalState().GetLogLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void SetLogLevel(logger_detail::MessageSeverity newLevel) {
|
||||||
|
return logger_detail::GlobalState().SetLogLevel(newLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Logger {
|
||||||
|
using MessageSeverity = logger_detail::MessageSeverity;
|
||||||
|
using MessageData = logger_detail::MessageData;
|
||||||
|
using Sink = logger_detail::Sink;
|
||||||
|
|
||||||
|
/// Get the global instance of the logger.
|
||||||
|
static Logger& Global();
|
||||||
|
|
||||||
|
Logger() : Logger(logger_detail::ChannelGlobal) {}
|
||||||
|
|
||||||
|
constexpr explicit Logger(ChannelId channel) { this->channelId = channel; }
|
||||||
|
|
||||||
|
Logger(const Logger&) = delete;
|
||||||
|
Logger(Logger&&) = delete;
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
inline void Debug(std::string_view fmt, Args... args) {
|
||||||
|
VOut(MessageSeverity::Debug, fmt, std::make_format_args(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
inline void Info(std::string_view fmt, Args... args) {
|
||||||
|
VOut(MessageSeverity::Info, fmt, std::make_format_args(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
inline void Warning(std::string_view fmt, Args... args) {
|
||||||
|
VOut(MessageSeverity::Warning, fmt, std::make_format_args(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
inline void Error(std::string_view fmt, Args... args) {
|
||||||
|
VOut(MessageSeverity::Error, fmt, std::make_format_args(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
inline void Fatal(std::string_view fmt, Args... args) {
|
||||||
|
VOut(MessageSeverity::Fatal, fmt, std::make_format_args(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void VOut(MessageSeverity severity, std::string_view format, std::format_args args);
|
||||||
|
|
||||||
|
ChannelId channelId;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
constexpr void LogDebug(std::string_view format, Args... args) {
|
||||||
|
Logger::Global().Debug(format, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
constexpr void LogInfo(std::string_view format, Args... args) {
|
||||||
|
Logger::Global().Info(format, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
constexpr void LogWarning(std::string_view format, Args... args) {
|
||||||
|
Logger::Global().Warning(format, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
constexpr void LogError(std::string_view format, Args... args) {
|
||||||
|
Logger::Global().Error(format, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class... Args>
|
||||||
|
constexpr void LogFatal(std::string_view format, Args... args) {
|
||||||
|
Logger::Global().Fatal(format, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace base
|
|
@ -14,7 +14,6 @@ add_library(base_http
|
||||||
lobbyserver_target(base_http)
|
lobbyserver_target(base_http)
|
||||||
|
|
||||||
target_link_libraries(base_http PUBLIC
|
target_link_libraries(base_http PUBLIC
|
||||||
spdlog::spdlog
|
|
||||||
base::impl
|
base::impl
|
||||||
Boost::url
|
Boost::url
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <boost/beast/core/flat_buffer.hpp>
|
#include <boost/beast/core/flat_buffer.hpp>
|
||||||
#include <boost/beast/http/read.hpp>
|
#include <boost/beast/http/read.hpp>
|
||||||
|
@ -71,8 +71,7 @@ namespace base::http {
|
||||||
|
|
||||||
struct Server::Impl {
|
struct Server::Impl {
|
||||||
struct Session {
|
struct Session {
|
||||||
Session(Impl& impl, Server::StreamType&& stream)
|
Session(Impl& impl, Server::StreamType&& stream) : impl(impl), stream(std::move(stream)) {}
|
||||||
: impl(impl), stream(std::move(stream)) {}
|
|
||||||
|
|
||||||
void Close() {
|
void Close() {
|
||||||
if(stream.socket().is_open()) {
|
if(stream.socket().is_open()) {
|
||||||
|
@ -108,7 +107,7 @@ namespace base::http {
|
||||||
}
|
}
|
||||||
} catch(bsys::system_error& ec) {
|
} catch(bsys::system_error& ec) {
|
||||||
// if(ec.code() != beast::http::error::end_of_stream)
|
// if(ec.code() != beast::http::error::end_of_stream)
|
||||||
// spdlog::error("Error in http::BasicServer::DoSession(): {}", ec.what());
|
// logger.Error("Error in http::BasicServer::DoSession(): {}", ec.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: standalone close() function
|
// todo: standalone close() function
|
||||||
|
@ -181,8 +180,7 @@ namespace base::http {
|
||||||
using RouteVariant = std::variant<Server::RouteHandler, Server::WebSocketRouteHandler>;
|
using RouteVariant = std::variant<Server::RouteHandler, Server::WebSocketRouteHandler>;
|
||||||
|
|
||||||
template <class ProtocolEndpoint>
|
template <class ProtocolEndpoint>
|
||||||
Impl(asio::any_io_executor ioc, ProtocolEndpoint ep)
|
Impl(asio::any_io_executor ioc, ProtocolEndpoint ep) : exec(ioc), ep(ep), acceptor(ioc) {}
|
||||||
: exec(ioc), ep(ep), acceptor(ioc) {}
|
|
||||||
|
|
||||||
void On(beast::http::verb verb, std::string_view path, Server::RouteHandler handler) {
|
void On(beast::http::verb verb, std::string_view path, Server::RouteHandler handler) {
|
||||||
handlerStorage.emplace_back(handler);
|
handlerStorage.emplace_back(handler);
|
||||||
|
@ -194,7 +192,7 @@ namespace base::http {
|
||||||
|
|
||||||
if(errstr) {
|
if(errstr) {
|
||||||
// error inserting into tree
|
// error inserting into tree
|
||||||
spdlog::error("Error inserting route \"{}\" into tree: {}", path, errstr);
|
logger.Error("Error inserting route \"{}\" into tree: {}", path, errstr);
|
||||||
free(errstr);
|
free(errstr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -207,7 +205,7 @@ namespace base::http {
|
||||||
&errstr);
|
&errstr);
|
||||||
if(errstr) {
|
if(errstr) {
|
||||||
// error inserting into tree
|
// error inserting into tree
|
||||||
spdlog::error("Error inserting route \"{}\" into tree: {}", path, errstr);
|
logger.Error("Error inserting route \"{}\" into tree: {}", path, errstr);
|
||||||
free(errstr);
|
free(errstr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -218,7 +216,7 @@ namespace base::http {
|
||||||
char* errstr { nullptr };
|
char* errstr { nullptr };
|
||||||
tree.compile(&errstr);
|
tree.compile(&errstr);
|
||||||
if(errstr) {
|
if(errstr) {
|
||||||
spdlog::error("Error compiling route tree: {}", errstr);
|
logger.Error("Error compiling route tree: {}", errstr);
|
||||||
free(errstr);
|
free(errstr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -317,7 +315,7 @@ namespace base::http {
|
||||||
using reuse_port = asio::detail::socket_option::boolean<SOL_SOCKET, SO_REUSEPORT>;
|
using reuse_port = asio::detail::socket_option::boolean<SOL_SOCKET, SO_REUSEPORT>;
|
||||||
acceptor.set_option(reuse_port(true));
|
acceptor.set_option(reuse_port(true));
|
||||||
|
|
||||||
spdlog::info("Able to enable SO_NODELAY; doing so");
|
logger.Info("Able to enable SO_NODELAY; doing so");
|
||||||
acceptor.set_option(asio::ip::tcp::no_delay { true });
|
acceptor.set_option(asio::ip::tcp::no_delay { true });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,7 +332,7 @@ namespace base::http {
|
||||||
} catch(bsys::system_error& ec) {
|
} catch(bsys::system_error& ec) {
|
||||||
// Filter out "operation cancelled", because that's not really an error we need to know about.
|
// Filter out "operation cancelled", because that's not really an error we need to know about.
|
||||||
if(ec.code() != asio::error::operation_aborted)
|
if(ec.code() != asio::error::operation_aborted)
|
||||||
spdlog::error("Error in http::BasicServer::Listener(): {}", ec.what());
|
logger.Error("Error in http::BasicServer::Listener(): {}", ec.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
listening = false;
|
listening = false;
|
||||||
|
@ -374,6 +372,8 @@ namespace base::http {
|
||||||
bool listening { false };
|
bool listening { false };
|
||||||
|
|
||||||
asio::basic_socket_acceptor<GenericProtocol> acceptor;
|
asio::basic_socket_acceptor<GenericProtocol> acceptor;
|
||||||
|
|
||||||
|
Logger logger { MakeChannelId(MessageSource::Http, MessageComponentSource::Http_Server) };
|
||||||
};
|
};
|
||||||
|
|
||||||
Server::Server(asio::any_io_executor ioc, asio::ip::tcp::endpoint ep) {
|
Server::Server(asio::any_io_executor ioc, asio::ip::tcp::endpoint ep) {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <http/request.hpp>
|
#include <http/request.hpp>
|
||||||
#include <http/response.hpp>
|
#include <http/response.hpp>
|
||||||
#include <http/websocket_client.hpp>
|
#include <http/websocket_client.hpp>
|
||||||
|
#include <base/logger.hpp>
|
||||||
#include <base/types.hpp>
|
#include <base/types.hpp>
|
||||||
|
|
||||||
namespace base::http {
|
namespace base::http {
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include <http/websocket_client.hpp>
|
#include <http/websocket_client.hpp>
|
||||||
#include <http/proxy_address.hpp>
|
#include <http/proxy_address.hpp>
|
||||||
#include <base/assert.hpp>
|
#include <base/assert.hpp>
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
namespace base::http {
|
namespace base::http {
|
||||||
|
|
||||||
|
@ -84,7 +83,7 @@ namespace base::http {
|
||||||
asio::deferred);
|
asio::deferred);
|
||||||
}
|
}
|
||||||
} catch(bsys::error_code& ec) {
|
} catch(bsys::error_code& ec) {
|
||||||
spdlog::error("Error when closing (not fatal): {}", ec.what());
|
logger.Error("Error when closing (not fatal): {}", ec.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify the send task that it needs to stop
|
// notify the send task that it needs to stop
|
||||||
|
@ -139,7 +138,7 @@ namespace base::http {
|
||||||
self->sendQueue.shrink_to_fit();
|
self->sendQueue.shrink_to_fit();
|
||||||
}
|
}
|
||||||
} catch(bsys::system_error& ec) {
|
} catch(bsys::system_error& ec) {
|
||||||
// spdlog::error("failure in write end: {}", ec.what());
|
// logger.Error("failure in write end: {}", ec.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
co_await self->Close();
|
co_await self->Close();
|
||||||
|
@ -185,7 +184,7 @@ namespace base::http {
|
||||||
} catch(bsys::system_error& ec) {
|
} catch(bsys::system_error& ec) {
|
||||||
// TODO: this should be re-enabled but doesn't seem to limit properly
|
// TODO: this should be re-enabled but doesn't seem to limit properly
|
||||||
// if(ec.code() != beast::websocket::error::closed || ec.code() != asio::error::eof)
|
// if(ec.code() != beast::websocket::error::closed || ec.code() != asio::error::eof)
|
||||||
// spdlog::error("fail in read end {}", ec.what());
|
// logger.Error("fail in read end {}", ec.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
co_await self->Close();
|
co_await self->Close();
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <http/request.hpp>
|
#include <http/request.hpp>
|
||||||
#include <http/websocket_message.hpp>
|
#include <http/websocket_message.hpp>
|
||||||
#include <base/async_condition_variable.hpp>
|
#include <base/async_condition_variable.hpp>
|
||||||
|
#include <base/logger.hpp>
|
||||||
#include <base/types.hpp>
|
#include <base/types.hpp>
|
||||||
|
|
||||||
namespace base::http {
|
namespace base::http {
|
||||||
|
@ -69,6 +70,8 @@ namespace base::http {
|
||||||
|
|
||||||
Request upgrade;
|
Request upgrade;
|
||||||
|
|
||||||
|
Logger logger { MakeChannelId(MessageSource::Http, MessageComponentSource::Http_WebSocketClient) };
|
||||||
|
|
||||||
constexpr static u32 MAX_MESSAGES_IN_QUEUE = 256;
|
constexpr static u32 MAX_MESSAGES_IN_QUEUE = 256;
|
||||||
|
|
||||||
Awaitable<void> WriteEnd();
|
Awaitable<void> WriteEnd();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <base/assert.hpp>
|
#include <base/assert.hpp>
|
||||||
|
#include <base/logger.hpp>
|
||||||
#include <base/types.hpp>
|
#include <base/types.hpp>
|
||||||
|
|
||||||
namespace base::http {
|
namespace base::http {
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#include <boost/asio/read.hpp>
|
#include <boost/asio/read.hpp>
|
||||||
#include <boost/asio/write.hpp>
|
#include <boost/asio/write.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include "DirtySockServer.hpp"
|
#include "DirtySockServer.hpp"
|
||||||
|
|
||||||
constexpr static auto MAX_PAYLOAD_SIZE = 4 * (1024 * 1024);
|
constexpr static auto MAX_PAYLOAD_SIZE = 4 * (1024 * 1024);
|
||||||
|
@ -31,7 +30,7 @@ namespace ls {
|
||||||
|
|
||||||
// Sanity check. I don't expect game payloa
|
// Sanity check. I don't expect game payloa
|
||||||
if(header.payloadSize > MAX_PAYLOAD_SIZE) {
|
if(header.payloadSize > MAX_PAYLOAD_SIZE) {
|
||||||
logger->error("WOAH! Message size {} MB larger than {}MB..", (static_cast<float>(header.payloadSize) / 1024 / 1024), (static_cast<float>(MAX_PAYLOAD_SIZE) / 1024 / 1024));
|
base::LogError("WOAH! Message size {} MB larger than {}MB..", (static_cast<float>(header.payloadSize) / 1024 / 1024), (static_cast<float>(MAX_PAYLOAD_SIZE) / 1024 / 1024));
|
||||||
co_return nullptr;
|
co_return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ namespace ls {
|
||||||
co_return MessageFactory::CreateAndParseMessage(header, propertyBuffer);
|
co_return MessageFactory::CreateAndParseMessage(header, propertyBuffer);
|
||||||
} catch(bsys::system_error& ec) {
|
} catch(bsys::system_error& ec) {
|
||||||
if(ec.code() != asio::error::operation_aborted)
|
if(ec.code() != asio::error::operation_aborted)
|
||||||
logger->error("Error in DirtySockClient::WriteMessage(): {}", ec.what());
|
base::LogError("Error in DirtySockClient::WriteMessage(): {}", ec.what());
|
||||||
co_return nullptr;
|
co_return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +62,7 @@ namespace ls {
|
||||||
co_await asio::async_write(stream, asio::buffer(buf), asio::deferred);
|
co_await asio::async_write(stream, asio::buffer(buf), asio::deferred);
|
||||||
} catch(bsys::system_error& ec) {
|
} catch(bsys::system_error& ec) {
|
||||||
if(ec.code() != asio::error::operation_aborted)
|
if(ec.code() != asio::error::operation_aborted)
|
||||||
logger->error("Error in DirtySockClient::WriteMessage(): {}", ec.what());
|
base::LogError("Error in DirtySockClient::WriteMessage(): {}", ec.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,14 +76,14 @@ namespace ls {
|
||||||
co_await message->Process(shared_from_this());
|
co_await message->Process(shared_from_this());
|
||||||
} else {
|
} else {
|
||||||
// This will occur if parsing fails or etc.
|
// This will occur if parsing fails or etc.
|
||||||
logger->error("Error parsing message, closing connection");
|
base::LogError("Error parsing message, closing connection");
|
||||||
Close();
|
Close();
|
||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(bsys::system_error& ec) {
|
} catch(bsys::system_error& ec) {
|
||||||
if(ec.code() != asio::error::operation_aborted)
|
if(ec.code() != asio::error::operation_aborted)
|
||||||
logger->error("Error in DirtySockClient::Run(): {}", ec.what());
|
base::LogError("Error in DirtySockClient::Run(): {}", ec.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
#include <base/types.hpp>
|
#include <base/types.hpp>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <impl/asio_config.hpp>
|
#include <impl/asio_config.hpp>
|
||||||
|
@ -31,12 +29,11 @@ namespace ls {
|
||||||
// internal
|
// internal
|
||||||
base::Awaitable<MessagePtr> ReadMessage();
|
base::Awaitable<MessagePtr> ReadMessage();
|
||||||
|
|
||||||
|
|
||||||
base::Awaitable<void> Run();
|
base::Awaitable<void> Run();
|
||||||
|
|
||||||
Stream stream;
|
Stream stream;
|
||||||
base::Ref<DirtySockServer> server;
|
base::Ref<DirtySockServer> server;
|
||||||
|
|
||||||
base::Ref<spdlog::logger> logger = spdlog::get("ls_dsock_client");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ls
|
} // namespace ls
|
|
@ -1,7 +1,5 @@
|
||||||
#include "DirtySockServer.hpp"
|
#include "DirtySockServer.hpp"
|
||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
#include "DirtySockClient.hpp"
|
#include "DirtySockClient.hpp"
|
||||||
|
|
||||||
namespace ls {
|
namespace ls {
|
||||||
|
@ -11,7 +9,7 @@ namespace ls {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DirtySockServer::Start(const Protocol::endpoint& ep) {
|
void DirtySockServer::Start(const Protocol::endpoint& ep) {
|
||||||
asio::co_spawn(exec, Listener(ep), base::DefCoroCompletion("DirtySockServer listener"));
|
asio::co_spawn(exec, Listener(ep), base::DefCoroCompletion("EaServer listener"));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DirtySockServer::Listening() const {
|
bool DirtySockServer::Listening() const {
|
||||||
|
@ -34,7 +32,7 @@ namespace ls {
|
||||||
acceptor.bind(endpoint);
|
acceptor.bind(endpoint);
|
||||||
acceptor.listen(asio::socket_base::max_listen_connections);
|
acceptor.listen(asio::socket_base::max_listen_connections);
|
||||||
|
|
||||||
logger->info("DirtySockServer listening on {}:{}", endpoint.address().to_string(), endpoint.port());
|
logger.Info("DirtySockServer listening on {}:{}", endpoint.address().to_string(), endpoint.port());
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
auto socket = co_await acceptor.async_accept(asio::deferred);
|
auto socket = co_await acceptor.async_accept(asio::deferred);
|
||||||
|
@ -44,7 +42,7 @@ namespace ls {
|
||||||
}
|
}
|
||||||
} catch(bsys::system_error& ec) {
|
} catch(bsys::system_error& ec) {
|
||||||
if(ec.code() != asio::error::operation_aborted)
|
if(ec.code() != asio::error::operation_aborted)
|
||||||
logger->error("Error in DirtySockServer::Listener(): {}", ec.what());
|
logger.Error("Error in DirtySockServer::Listener(): {}", ec.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
co_return;
|
co_return;
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <base/fourcc.hpp>
|
#include <base/fourcc.hpp>
|
||||||
|
#include <base/logger.hpp>
|
||||||
#include <impl/asio_config.hpp>
|
#include <impl/asio_config.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
namespace ls {
|
namespace ls {
|
||||||
struct DirtySockClient;
|
struct DirtySockClient;
|
||||||
|
@ -39,8 +39,8 @@ namespace ls {
|
||||||
|
|
||||||
std::set<base::Ref<DirtySockClient>> clientSet;
|
std::set<base::Ref<DirtySockClient>> clientSet;
|
||||||
|
|
||||||
base::Ref<spdlog::logger> logger = spdlog::get("ls_dsock_server");
|
// i'm moving to spdlog fuck this
|
||||||
|
base::Logger logger { base::MakeChannelId(base::MessageSource::Server, base::MessageComponentSource::Server_Server) };
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ls
|
} // namespace ls
|
|
@ -1,6 +1,6 @@
|
||||||
#include "IMessage.hpp"
|
#include "IMessage.hpp"
|
||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
#include <base/logger.hpp>
|
||||||
#include <impl/asio_config.hpp>
|
#include <impl/asio_config.hpp>
|
||||||
|
|
||||||
// So debug message can just reply
|
// So debug message can just reply
|
||||||
|
@ -153,11 +153,11 @@ namespace ls {
|
||||||
base::Awaitable<void> Process(base::Ref<ls::DirtySockClient> client) override {
|
base::Awaitable<void> Process(base::Ref<ls::DirtySockClient> client) override {
|
||||||
auto* fccbytes = std::bit_cast<u8*>(&header.typeCode);
|
auto* fccbytes = std::bit_cast<u8*>(&header.typeCode);
|
||||||
|
|
||||||
spdlog::info("Debug Message FourCC lo: \"{:c}{:c}{:c}{:c}\"", fccbytes[0], fccbytes[1], fccbytes[2], fccbytes[3]);
|
base::LogInfo("Debug Message FourCC lo: \"{:c}{:c}{:c}{:c}\"", fccbytes[0], fccbytes[1], fccbytes[2], fccbytes[3]);
|
||||||
spdlog::info("Debug Message Properties:");
|
base::LogInfo("Debug Message Properties:");
|
||||||
|
|
||||||
for(auto [key, value] : properties)
|
for(auto [key, value] : properties)
|
||||||
spdlog::info("{}: {}", key, value);
|
base::LogInfo("{}: {}", key, value);
|
||||||
|
|
||||||
// :( but it works to just replay the message.
|
// :( but it works to just replay the message.
|
||||||
co_await client->WriteMessage(std::make_shared<DebugMessage>(*this));
|
co_await client->WriteMessage(std::make_shared<DebugMessage>(*this));
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
#include "Server.hpp"
|
#include "Server.hpp"
|
||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
#include "DirtySockServer.hpp"
|
#include "DirtySockServer.hpp"
|
||||||
#include "impl/asio_config.hpp"
|
#include "impl/asio_config.hpp"
|
||||||
|
|
||||||
|
@ -22,14 +20,12 @@ namespace ls {
|
||||||
|
|
||||||
if(!lobbyServer->Listening()) {
|
if(!lobbyServer->Listening()) {
|
||||||
// uh oh worm..
|
// uh oh worm..
|
||||||
logger->error("for some reason lobby server isnt listening..");
|
logger.Error("for some reason lobby server isnt listening..");
|
||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: http server? there's apparently some stuff we can have that uses it
|
// TODO: http server? there's apparently some stuff we can have that uses it
|
||||||
|
|
||||||
logger->info("SSX3LobbyServer started successfully!");
|
|
||||||
|
|
||||||
// wait to stop
|
// wait to stop
|
||||||
co_await stopCv.Wait([&]() { return stopping; });
|
co_await stopCv.Wait([&]() { return stopping; });
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include <impl/asio_config.hpp>
|
#include <impl/asio_config.hpp>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
#include "base/logger.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace ls {
|
namespace ls {
|
||||||
|
|
||||||
|
@ -34,7 +35,8 @@ namespace ls {
|
||||||
|
|
||||||
Config config;
|
Config config;
|
||||||
|
|
||||||
base::Ref<spdlog::logger> logger = spdlog::get("ls_server");
|
base::Logger logger { base::MakeChannelId(base::MessageSource::Server, base::MessageComponentSource::Server_Server) };
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ls
|
} // namespace ls
|
29
src/main.cpp
29
src/main.cpp
|
@ -1,15 +1,12 @@
|
||||||
#include <base/assert.hpp>
|
#include <base/assert.hpp>
|
||||||
|
#include <base/stdout_sink.hpp>
|
||||||
#include <base/types.hpp>
|
#include <base/types.hpp>
|
||||||
#include <boost/asio/signal_set.hpp>
|
#include <boost/asio/signal_set.hpp>
|
||||||
#include <boost/asio/thread_pool.hpp>
|
#include <boost/asio/thread_pool.hpp>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <toml++/toml.hpp>
|
#include <toml++/toml.hpp>
|
||||||
|
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
#include <spdlog/cfg/env.h>
|
|
||||||
|
|
||||||
#include "Server.hpp"
|
#include "Server.hpp"
|
||||||
#include "spdlog/sinks/stdout_color_sinks.h"
|
|
||||||
|
|
||||||
asio::io_context ioc(1);
|
asio::io_context ioc(1);
|
||||||
base::Unique<ls::Server> server;
|
base::Unique<ls::Server> server;
|
||||||
|
@ -21,10 +18,10 @@ base::Awaitable<void> CoWaitForSignal() {
|
||||||
try {
|
try {
|
||||||
co_await interruptSignal.async_wait(asio::deferred);
|
co_await interruptSignal.async_wait(asio::deferred);
|
||||||
} catch(bsys::system_error& ec) {
|
} catch(bsys::system_error& ec) {
|
||||||
spdlog::error("Error waiting for signal? {}", ec.what());
|
base::LogError("Error waiting for signal? {}", ec.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
spdlog::info("SIGINT/SIGTERM recieved, stopping server...");
|
base::LogInfo("SIGINT/SIGTERM recieved, stopping server...");
|
||||||
|
|
||||||
// After this the main coroutine will handle cleanly shutting down
|
// After this the main coroutine will handle cleanly shutting down
|
||||||
co_await server->Stop();
|
co_await server->Stop();
|
||||||
|
@ -38,13 +35,7 @@ base::Awaitable<void> CoMain(const ls::Server::Config& config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
base::LoggerAttachStdout();
|
||||||
// create spdlog loggers
|
|
||||||
spdlog::create<spdlog::sinks::stdout_color_sink_mt>("ls_server");
|
|
||||||
spdlog::create<spdlog::sinks::stdout_color_sink_mt>("ls_dsock_client");
|
|
||||||
spdlog::create<spdlog::sinks::stdout_color_sink_mt>("ls_dsock_server");
|
|
||||||
|
|
||||||
spdlog::cfg::load_env_levels();
|
|
||||||
|
|
||||||
auto config = ls::Server::Config {};
|
auto config = ls::Server::Config {};
|
||||||
|
|
||||||
|
@ -57,29 +48,29 @@ int main() {
|
||||||
auto buddy_port_ptr = table["lobbyserver"]["buddy_listen_port"].as_integer();
|
auto buddy_port_ptr = table["lobbyserver"]["buddy_listen_port"].as_integer();
|
||||||
|
|
||||||
if(!addr_ptr || !lobby_port_ptr || !buddy_port_ptr) {
|
if(!addr_ptr || !lobby_port_ptr || !buddy_port_ptr) {
|
||||||
spdlog::error("Invalid configuration file \"{}\".", CONFIG_FILE);
|
base::LogError("Invalid configuration file \"{}\".", CONFIG_FILE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lobby_port_ptr->get() > 65535) {
|
if(lobby_port_ptr->get() > 65535) {
|
||||||
spdlog::error("Invalid lobby listen port \"{}\", should be 65535 or less", lobby_port_ptr->get());
|
base::LogError("Invalid lobby listen port \"{}\", should be 65535 or less", lobby_port_ptr->get());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buddy_port_ptr->get() > 65535) {
|
if(buddy_port_ptr->get() > 65535) {
|
||||||
spdlog::error("Invalid buddy listen port \"{}\", should be 65535 or less", buddy_port_ptr->get());
|
base::LogError("Invalid buddy listen port \"{}\", should be 65535 or less", buddy_port_ptr->get());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.buddyListenEndpoint = { asio::ip::make_address(addr_ptr->get()), static_cast<u16>(buddy_port_ptr->get()) };
|
config.buddyListenEndpoint = { asio::ip::make_address(addr_ptr->get()), static_cast<u16>(buddy_port_ptr->get()) };
|
||||||
config.lobbyListenEndpoint = { asio::ip::make_address(addr_ptr->get()), static_cast<u16>(lobby_port_ptr->get()) };
|
config.lobbyListenEndpoint = { asio::ip::make_address(addr_ptr->get()), static_cast<u16>(lobby_port_ptr->get()) };
|
||||||
} else {
|
} else {
|
||||||
spdlog::error("Invalid configuration file \"{}\"", CONFIG_FILE);
|
base::LogError("Invalid configuration file \"{}\"", CONFIG_FILE);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch(toml::parse_error& err) {
|
} catch(toml::parse_error& err) {
|
||||||
spdlog::error("Error parsing configuration file \"{}\": {}", CONFIG_FILE, err.what());
|
base::LogError("Error parsing configuration file \"{}\": {}", CONFIG_FILE, err.what());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +92,7 @@ int main() {
|
||||||
BASE_CHECK(false, "Unhandled exception in server main loop: {}", e.what());
|
BASE_CHECK(false, "Unhandled exception in server main loop: {}", e.what());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
spdlog::info("Server returned, exiting process\n");
|
base::LogInfo("Server returned, exiting process\n");
|
||||||
// done
|
// done
|
||||||
ioc.stop();
|
ioc.stop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
#include <impl/asio_config.hpp>
|
#include <impl/asio_config.hpp>
|
||||||
#include <spdlog/spdlog.h>
|
|
||||||
|
|
||||||
|
#include "base/logger.hpp"
|
||||||
#include "../IMessage.hpp"
|
#include "../IMessage.hpp"
|
||||||
|
|
||||||
LS_MESSAGE(PingMessage, "~png") {
|
LS_MESSAGE(PingMessage, "~png") {
|
||||||
LS_MESSAGE_CTOR(PingMessage, "~png")
|
LS_MESSAGE_CTOR(PingMessage, "~png")
|
||||||
|
|
||||||
base::Awaitable<void> Process(base::Ref<ls::DirtySockClient> client) override {
|
base::Awaitable<void> Process(base::Ref<ls::DirtySockClient> client) override {
|
||||||
spdlog::info("Got ping message!");
|
base::LogInfo("Got ping message!");
|
||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,2 @@
|
||||||
add_subdirectory(boost)
|
add_subdirectory(boost)
|
||||||
add_subdirectory(tomlplusplus)
|
add_subdirectory(tomlplusplus)
|
||||||
|
|
||||||
set(SPDLOG_USE_STD_FORMAT ON)
|
|
||||||
add_subdirectory(spdlog)
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit ae525b75c31adaad130dd4501d37ff632ec5eade
|
|
Loading…
Reference in New Issue