mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-21 12:17:46 +00:00
add spdlog, remove boost is gone from common
This commit is contained in:
parent
28b5fd0714
commit
e357521ee6
21 changed files with 73 additions and 91 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
|||
[submodule "deps/asio"]
|
||||
path = deps/asio
|
||||
url = https://github.com/chriskohlhoff/asio.git
|
||||
[submodule "deps/spdlog"]
|
||||
path = deps/spdlog
|
||||
url = https://github.com/gabime/spdlog.git
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
if(UNIX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1z")
|
||||
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
|
||||
else()
|
||||
add_definitions(-D_WIN32_WINNT=0x601)
|
||||
|
|
1
deps/spdlog
vendored
Submodule
1
deps/spdlog
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 240a58fd6e8bfe8fa62dd3ea777d1909f6d89a72
|
|
@ -27,7 +27,6 @@ set_target_properties( common PROPERTIES
|
|||
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_CURRENT_SOURCE_DIR}/../../bin/"
|
||||
)
|
||||
|
||||
target_link_libraries( common PUBLIC ${Boost_LIBRARIES} )
|
||||
target_link_libraries( common PUBLIC xivdat )
|
||||
|
||||
target_link_libraries( common PUBLIC mysqlConnector )
|
||||
|
@ -45,8 +44,9 @@ endif()
|
|||
target_include_directories( common
|
||||
PUBLIC
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/asio/asio/include/"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/asio/asio/include/"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../../deps/spdlog/include/"
|
||||
PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/external/")
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ bool Core::ConfigMgr::loadConfig( const std::string& configName )
|
|||
std::ifstream configFile( localConfig.c_str() );
|
||||
configStream << configFile.rdbuf();
|
||||
|
||||
// parse the tree and we're fuckin done
|
||||
// parse the trxee and we're fuckin done
|
||||
//boost::property_tree::read_ini( configStream, m_propTree );
|
||||
|
||||
m_pInih = std::unique_ptr< INIReader >( new INIReader( localConfig ) );
|
||||
|
|
|
@ -1,18 +1,10 @@
|
|||
#include "Logger.h"
|
||||
|
||||
#include <boost/log/core.hpp>
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <boost/log/expressions.hpp>
|
||||
#include <boost/log/sinks/text_file_backend.hpp>
|
||||
#include <boost/log/utility/setup/file.hpp>
|
||||
#include <boost/log/utility/setup/common_attributes.hpp>
|
||||
#include <boost/log/sources/severity_logger.hpp>
|
||||
#include <boost/log/sources/record_ostream.hpp>
|
||||
#include <boost/log/sources/global_logger_storage.hpp>
|
||||
#include <boost/log/support/date_time.hpp>
|
||||
#include <boost/log/utility/manipulators/add_value.hpp>
|
||||
#include <boost/log/utility/setup/console.hpp>
|
||||
#include <iostream>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include <spdlog/sinks/daily_file_sink.h>
|
||||
|
||||
// #include <iostream>
|
||||
|
||||
namespace Core {
|
||||
|
||||
|
@ -35,56 +27,40 @@ void Logger::setLogPath( const std::string& logPath )
|
|||
void Logger::init()
|
||||
{
|
||||
|
||||
auto format = (
|
||||
boost::log::expressions::stream <<
|
||||
boost::log::expressions::format_date_time< boost::posix_time::ptime >(
|
||||
"TimeStamp", "[%H:%M:%S]" ) <<
|
||||
"[" << boost::log::trivial::severity << "] " <<
|
||||
boost::log::expressions::smessage
|
||||
);
|
||||
std::vector< spdlog::sink_ptr > sinks;
|
||||
|
||||
boost::log::add_file_log
|
||||
(
|
||||
boost::log::keywords::file_name =
|
||||
m_logFile + "%Y-%m-%d.log", /*< file name pattern >*/
|
||||
boost::log::keywords::rotation_size =
|
||||
10 * 1024 * 1024, /*< rotate files every 10 MiB... >*/
|
||||
boost::log::keywords::time_based_rotation = boost::log::sinks::file::rotation_at_time_point( 0, 0,
|
||||
0 ), /*< ...or at midnight >*/
|
||||
boost::log::keywords::open_mode = std::ios::app,
|
||||
boost::log::keywords::format = format,
|
||||
boost::log::keywords::auto_flush = true
|
||||
);
|
||||
sinks.push_back( std::make_shared< spdlog::sinks::stdout_color_sink_mt >() );
|
||||
sinks.push_back( std::make_shared< spdlog::sinks::daily_file_sink_mt >( m_logFile, 0, 0 ) );
|
||||
|
||||
boost::log::add_console_log( std::cout, boost::log::keywords::format = format );
|
||||
m_logger = std::make_shared< spdlog::logger >( "logger", std::begin( sinks ), std::end( sinks ) );
|
||||
|
||||
boost::log::add_common_attributes();
|
||||
//spdlog::set_pattern( "[%H:%M:%S] [%l] %v" );
|
||||
}
|
||||
|
||||
|
||||
void Logger::Log( LoggingSeverity logSev, const std::string& text )
|
||||
{
|
||||
BOOST_LOG_SEV( m_lg, ( boost::log::trivial::severity_level ) logSev ) << text;
|
||||
// BOOST_LOG_SEV( m_lg, ( boost::log::trivial::severity_level ) logSev ) << text;
|
||||
}
|
||||
|
||||
void Logger::error( const std::string& text )
|
||||
{
|
||||
BOOST_LOG_SEV( m_lg, boost::log::trivial::severity_level::error ) << text;
|
||||
m_logger->error( text );
|
||||
}
|
||||
|
||||
void Logger::info( const std::string& text )
|
||||
{
|
||||
BOOST_LOG_SEV( m_lg, boost::log::trivial::severity_level::info ) << text;
|
||||
m_logger->info( text );
|
||||
}
|
||||
|
||||
void Logger::debug( const std::string& text )
|
||||
{
|
||||
BOOST_LOG_SEV( m_lg, boost::log::trivial::severity_level::debug ) << text;
|
||||
m_logger->debug( text );
|
||||
}
|
||||
|
||||
void Logger::fatal( const std::string& text )
|
||||
{
|
||||
BOOST_LOG_SEV( m_lg, boost::log::trivial::severity_level::fatal ) << text;
|
||||
m_logger->critical( text );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#ifndef _LOGGER_H
|
||||
#define _LOGGER_H
|
||||
|
||||
#include <boost/log/trivial.hpp>
|
||||
// #include <boost/log/trivial.hpp>
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
|
@ -19,10 +21,10 @@ class Logger
|
|||
{
|
||||
|
||||
private:
|
||||
boost::log::sources::severity_logger_mt< boost::log::trivial::severity_level > m_lg;
|
||||
|
||||
std::string m_logFile;
|
||||
|
||||
std::shared_ptr< spdlog::logger > m_logger;
|
||||
|
||||
public:
|
||||
Logger();
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ foreach(_scriptDir ${children})
|
|||
if(MSVC)
|
||||
#target_link_libraries( "script_${_name}" ${Boost_LIBRARIES})
|
||||
set_target_properties( "script_${_name}" PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
LIBRARY_OUTPUT_DIRECTORY_DEBUG "${SCRIPT_LIB_DIR}"
|
||||
|
|
|
@ -8,7 +8,7 @@ file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
|||
add_executable(sapphire_api ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
||||
set_target_properties(sapphire_api PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../../../bin/"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _FORWARDS_H
|
||||
#define _FORWARDS_H
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace Core {
|
||||
|
||||
|
@ -19,20 +19,20 @@ class Session;
|
|||
|
||||
class ZonePosition;
|
||||
|
||||
typedef boost::shared_ptr< Zone > ZonePtr;
|
||||
typedef boost::shared_ptr< Item > ItemPtr;
|
||||
typedef boost::shared_ptr< ItemContainer > ItemContainerPtr;
|
||||
typedef boost::shared_ptr< Inventory > InventoryPtr;
|
||||
typedef boost::shared_ptr< Session > SessionPtr;
|
||||
typedef boost::shared_ptr< ZonePosition > ZonePositionPtr;
|
||||
typedef std::shared_ptr< Zone > ZonePtr;
|
||||
typedef std::shared_ptr< Item > ItemPtr;
|
||||
typedef std::shared_ptr< ItemContainer > ItemContainerPtr;
|
||||
typedef std::shared_ptr< Inventory > InventoryPtr;
|
||||
typedef std::shared_ptr< Session > SessionPtr;
|
||||
typedef std::shared_ptr< ZonePosition > ZonePositionPtr;
|
||||
|
||||
namespace StatusEffect {
|
||||
class StatusEffect;
|
||||
|
||||
class StatusEffectContainer;
|
||||
|
||||
typedef boost::shared_ptr< StatusEffect > StatusEffectPtr;
|
||||
typedef boost::shared_ptr< StatusEffectContainer > StatusEffectContainerPtr;
|
||||
typedef std::shared_ptr< StatusEffect > StatusEffectPtr;
|
||||
typedef std::shared_ptr< StatusEffectContainer > StatusEffectContainerPtr;
|
||||
}
|
||||
|
||||
namespace Entity {
|
||||
|
@ -42,15 +42,15 @@ class Player;
|
|||
|
||||
class BattleNpc;
|
||||
|
||||
typedef boost::shared_ptr< Chara > ActorPtr;
|
||||
typedef boost::shared_ptr< Player > PlayerPtr;
|
||||
typedef boost::shared_ptr< BattleNpc > BattleNpcPtr;
|
||||
typedef std::shared_ptr< Chara > ActorPtr;
|
||||
typedef std::shared_ptr< Player > PlayerPtr;
|
||||
typedef std::shared_ptr< BattleNpc > BattleNpcPtr;
|
||||
}
|
||||
|
||||
namespace Event {
|
||||
class EventHandler;
|
||||
|
||||
typedef boost::shared_ptr< EventHandler > EventPtr;
|
||||
typedef std::shared_ptr< EventHandler > EventPtr;
|
||||
}
|
||||
|
||||
namespace Action {
|
||||
|
@ -60,9 +60,9 @@ class ActionTeleport;
|
|||
|
||||
class EventAction;
|
||||
|
||||
typedef boost::shared_ptr< Action > ActionPtr;
|
||||
typedef boost::shared_ptr< ActionTeleport > ActionTeleportPtr;
|
||||
typedef boost::shared_ptr< EventAction > EventActionPtr;
|
||||
typedef std::shared_ptr< Action > ActionPtr;
|
||||
typedef std::shared_ptr< ActionTeleport > ActionTeleportPtr;
|
||||
typedef std::shared_ptr< EventAction > EventActionPtr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -79,18 +79,18 @@ class SessionConnection;
|
|||
|
||||
class ZoneConnection;
|
||||
|
||||
typedef boost::shared_ptr< Hive > HivePtr;
|
||||
typedef boost::shared_ptr< Acceptor > AcceptorPtr;
|
||||
typedef boost::shared_ptr< Connection > ConnectionPtr;
|
||||
typedef boost::shared_ptr< WorldConnection > WorldConnectionPtr;
|
||||
typedef boost::shared_ptr< ZoneConnection > ZoneConnectionPtr;
|
||||
typedef boost::shared_ptr< SessionConnection > SessionConnectionPtr;
|
||||
typedef std::shared_ptr< Hive > HivePtr;
|
||||
typedef std::shared_ptr< Acceptor > AcceptorPtr;
|
||||
typedef std::shared_ptr< Connection > ConnectionPtr;
|
||||
typedef std::shared_ptr< WorldConnection > WorldConnectionPtr;
|
||||
typedef std::shared_ptr< ZoneConnection > ZoneConnectionPtr;
|
||||
typedef std::shared_ptr< SessionConnection > SessionConnectionPtr;
|
||||
|
||||
namespace Packets {
|
||||
class GamePacket;
|
||||
|
||||
|
||||
typedef boost::shared_ptr< GamePacket > GamePacketPtr;
|
||||
typedef std::shared_ptr< GamePacket > GamePacketPtr;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@ Core::Data::ExdDataGenerated g_exdDataGen;
|
|||
Core::Network::SapphireAPI g_sapphireAPI;
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::property_tree;
|
||||
|
||||
using HttpServer = SimpleWeb::Server< SimpleWeb::HTTP >;
|
||||
using HttpClient = SimpleWeb::Client< SimpleWeb::HTTP >;
|
||||
|
@ -53,13 +52,13 @@ void default_resource_send( const HttpServer& server, const shared_ptr< HttpServ
|
|||
const shared_ptr< ifstream >& ifs );
|
||||
|
||||
|
||||
auto m_pConfig = boost::make_shared< Core::ConfigMgr >();
|
||||
auto m_pConfig = std::make_shared< Core::ConfigMgr >();
|
||||
HttpServer server;
|
||||
std::string configPath( "rest.ini" );
|
||||
|
||||
void reloadConfig()
|
||||
{
|
||||
m_pConfig = boost::make_shared< Core::ConfigMgr >();
|
||||
m_pConfig = std::make_shared< Core::ConfigMgr >();
|
||||
|
||||
if( !m_pConfig->loadConfig( configPath ) )
|
||||
throw "Error loading config ";
|
||||
|
@ -747,7 +746,7 @@ void defaultGet( shared_ptr< HttpServer::Response > response, shared_ptr< HttpSe
|
|||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
auto pLog = boost::shared_ptr< Core::Logger >( new Core::Logger() );
|
||||
auto pLog = std::shared_ptr< Core::Logger >( new Core::Logger() );
|
||||
g_fw.set< Core::Logger >( pLog );
|
||||
g_log.setLogPath( "log/SapphireAPI" );
|
||||
g_log.init();
|
||||
|
|
|
@ -23,7 +23,7 @@ file(GLOB SERVER_SOURCE_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
|||
add_executable( sapphire_zone ${SERVER_SOURCE_FILES} )
|
||||
|
||||
set_target_properties(sapphire_zone PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
ENABLE_EXPORTS ON
|
||||
|
|
|
@ -20,7 +20,7 @@ file(GLOB SERVER_SOURCE_FILES
|
|||
add_executable(discovery_parser ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
||||
set_target_properties(discovery_parser PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||
|
|
|
@ -14,7 +14,7 @@ file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
|||
add_executable(event_object_parser ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
||||
set_target_properties(event_object_parser PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||
|
|
|
@ -14,7 +14,7 @@ file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
|||
add_executable(exd_common_gen ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
||||
set_target_properties(exd_common_gen PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||
|
|
|
@ -8,16 +8,17 @@
|
|||
#include <iostream>
|
||||
#include <cctype>
|
||||
#include <set>
|
||||
#include <Exd/ExdData.h>
|
||||
#include <Exd/ExdDataGenerated.h>
|
||||
#include <Logging/Logger.h>
|
||||
#include <boost/range/algorithm/remove_if.hpp>
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
#include <fstream>
|
||||
|
||||
|
||||
Core::Logger g_log;
|
||||
Core::Data::ExdData g_exdData;
|
||||
Core::Data::ExdDataGenerated g_exdData;
|
||||
|
||||
|
||||
//const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" );
|
||||
|
@ -44,11 +45,11 @@ std::string generateEnum( const std::string& exd, int8_t nameIndex, const std::s
|
|||
{
|
||||
auto& fields = row.second;
|
||||
uint32_t id = row.first;
|
||||
auto test = boost::get< std::string >( &fields.at( nameIndex ) );
|
||||
auto test = std::get< std::string >( fields.at( nameIndex ) );
|
||||
if( !test )
|
||||
continue;
|
||||
auto str = *test;
|
||||
str.erase( boost::remove_if( str, boost::is_any_of( ",_-':!(){} \x02\x1f\x01\x03" ) ), str.end() );
|
||||
str.erase( std::remove_if( str.begin(), str.end(), std::is_any_of( ",_-':!(){} \x02\x1f\x01\x03" ) ) );
|
||||
if( str.empty() )
|
||||
continue;
|
||||
str[ 0 ] = std::toupper( str[ 0 ] );
|
||||
|
|
|
@ -14,7 +14,7 @@ file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
|||
add_executable(exd_struct_gen ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
||||
set_target_properties(exd_struct_gen PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||
|
|
|
@ -14,7 +14,7 @@ file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
|||
add_executable(exd_struct_test ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
||||
set_target_properties(exd_struct_test PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||
|
|
|
@ -14,7 +14,7 @@ file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
|||
add_executable(mob_parse ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
||||
set_target_properties(mob_parse PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||
|
|
|
@ -14,7 +14,7 @@ file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
|||
add_executable(pcb_reader2 ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
||||
set_target_properties(pcb_reader2 PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||
|
|
|
@ -20,7 +20,7 @@ file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*")
|
|||
add_executable(quest_parse ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES})
|
||||
|
||||
set_target_properties(quest_parse PROPERTIES
|
||||
CXX_STANDARD 14
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
CXX_EXTENSIONS ON
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../bin/"
|
||||
|
|
Loading…
Add table
Reference in a new issue