Skip to content

Commit 0b84dd7

Browse files
Various changed to make server easier to be split out for gui handling.
Various small additions to encounters in preparation of more elaborate encounter handling.
1 parent b03af28 commit 0b84dd7

File tree

9 files changed

+210
-79
lines changed

9 files changed

+210
-79
lines changed

src/common/Logging/Logger.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <filesystem>
1212
namespace fs = std::filesystem;
1313

14+
std::shared_ptr< Sapphire::buffer_sink_mt > Sapphire::Logger::m_bufferSink;
15+
1416

1517
void Sapphire::Logger::init( const std::string& logPath )
1618
{
@@ -27,7 +29,9 @@ void Sapphire::Logger::init( const std::string& logPath )
2729
auto stdout_sink = std::make_shared< spdlog::sinks::stdout_color_sink_mt >();
2830
auto daily_sink = std::make_shared< spdlog::sinks::daily_file_sink_mt >( logPath + ".log", 0, 0 );
2931

30-
std::vector< spdlog::sink_ptr > sinks { stdout_sink, daily_sink };
32+
m_bufferSink = std::make_shared< buffer_sink_mt >();
33+
34+
std::vector< spdlog::sink_ptr > sinks{ stdout_sink, daily_sink, m_bufferSink };
3135

3236
auto logger = std::make_shared< spdlog::async_logger >( "logger", sinks.begin(), sinks.end(),
3337
spdlog::thread_pool(), spdlog::async_overflow_policy::block );
@@ -47,6 +51,11 @@ void Sapphire::Logger::setLogLevel( uint8_t logLevel )
4751
spdlog::set_level( static_cast< spdlog::level::level_enum >( logLevel ) );
4852
}
4953

54+
std::shared_ptr< Sapphire::buffer_sink_mt > Sapphire::Logger::getBufferSink()
55+
{
56+
return m_bufferSink;
57+
}
58+
5059
void Sapphire::Logger::error( const std::string& text )
5160
{
5261
spdlog::get( "logger" )->error( text );
@@ -76,4 +85,3 @@ void Sapphire::Logger::trace( const std::string& text )
7685
{
7786
spdlog::get( "logger" )->trace( text );
7887
}
79-

src/common/Logging/Logger.h

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,120 @@
11
#pragma once
22

33
#include <string>
4+
#include <vector>
45
#include <spdlog/fmt/fmt.h>
56

7+
#include "spdlog/sinks/base_sink.h"
8+
69
namespace Sapphire
710
{
11+
// Custom sink class
12+
// Simplified custom sink class that avoids formatter conflicts
13+
template< typename Mutex >
14+
class buffer_sink : public spdlog::sinks::base_sink< Mutex >
15+
{
16+
public:
17+
buffer_sink() = default;
18+
19+
std::vector< std::string > getMessages() const
20+
{
21+
std::lock_guard< Mutex > lock( this->mutex_ );
22+
return messages_;
23+
}
24+
25+
void clearMessages()
26+
{
27+
std::lock_guard< Mutex > lock( this->mutex_ );
28+
messages_.clear();
29+
}
30+
31+
size_t getMessageCount() const
32+
{
33+
std::lock_guard< Mutex > lock( this->mutex_ );
34+
return messages_.size();
35+
}
36+
37+
protected:
38+
void sink_it_( const spdlog::details::log_msg& msg ) override
39+
{
40+
// Simple approach: extract the raw message and add basic formatting
41+
std::string raw_message( msg.payload.data(), msg.payload.size() );
42+
43+
// Create a simple timestamp (you can improve this)
44+
auto time_t = std::chrono::system_clock::to_time_t( msg.time );
45+
auto tm = *std::localtime( &time_t );
46+
47+
// Format: [HH:MM:SS] [LEVEL] message
48+
char time_buf[32];
49+
std::strftime( time_buf, sizeof( time_buf ), "%H:%M:%S", &tm );
50+
51+
std::string level_str;
52+
switch( msg.level )
53+
{
54+
case spdlog::level::trace: level_str = "trace"; break;
55+
case spdlog::level::debug: level_str = "debug"; break;
56+
case spdlog::level::info: level_str = "info"; break;
57+
case spdlog::level::warn: level_str = "warn"; break;
58+
case spdlog::level::err: level_str = "error"; break;
59+
case spdlog::level::critical: level_str = "fatal"; break;
60+
default: level_str = "unknown"; break;
61+
}
62+
63+
std::string formatted_message = fmt::format( "[{}] [{}] {}", time_buf, level_str, raw_message );
64+
65+
messages_.push_back( std::move( formatted_message ) );
66+
67+
// Limit buffer size
68+
if( messages_.size() > max_messages_ )
69+
{
70+
messages_.erase( messages_.begin() );
71+
}
72+
}
73+
74+
void flush_() override
75+
{
76+
// Nothing to flush for this sink
77+
}
78+
79+
private:
80+
std::vector< std::string > messages_;
81+
static const size_t max_messages_ = 1000;
82+
};
83+
84+
using buffer_sink_mt = buffer_sink< std::mutex >;
85+
using buffer_sink_st = buffer_sink< spdlog::details::null_mutex >;
86+
87+
888

989
class Logger
1090
{
11-
1291
private:
1392
std::string m_logFile;
93+
static std::shared_ptr< buffer_sink_mt > m_bufferSink;
94+
1495
Logger() = default;
96+
1597
~Logger() = default;
1698

1799
public:
18-
19100
static void init( const std::string& logPath );
101+
20102
static void setLogLevel( uint8_t logLevel );
21103

104+
static std::shared_ptr< buffer_sink_mt > getBufferSink();
105+
22106
// todo: this is a minor increase in build time because of fmtlib, but much less than including spdlog directly
23107

24108
static void error( const std::string& text );
109+
25110
template< typename... Args >
26111
static void error( const std::string& text, const Args&... args )
27112
{
28113
error( fmt::format( text, args... ) );
29114
}
30115

31116
static void warn( const std::string& text );
117+
32118
template< typename... Args >
33119
static void warn( const std::string& text, const Args&... args )
34120
{
@@ -37,6 +123,7 @@ namespace Sapphire
37123

38124

39125
static void info( const std::string& text );
126+
40127
template< typename... Args >
41128
static void info( const std::string& text, const Args&... args )
42129
{
@@ -45,6 +132,7 @@ namespace Sapphire
45132

46133

47134
static void debug( const std::string& text );
135+
48136
template< typename... Args >
49137
static void debug( const std::string& text, const Args&... args )
50138
{
@@ -53,6 +141,7 @@ namespace Sapphire
53141

54142

55143
static void fatal( const std::string& text );
144+
56145
template< typename... Args >
57146
static void fatal( const std::string& text, const Args&... args )
58147
{
@@ -61,14 +150,11 @@ namespace Sapphire
61150

62151

63152
static void trace( const std::string& text );
153+
64154
template< typename... Args >
65155
static void trace( const std::string& text, const Args&... args )
66156
{
67157
trace( fmt::format( text, args... ) );
68158
}
69-
70-
71159
};
72-
73160
}
74-

src/common/Util/Util.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <sstream>
44
#include <iomanip>
55
#include <algorithm>
6+
#include <fstream>
67
#include <string>
78

89
using namespace Sapphire::Common;
@@ -147,6 +148,34 @@ void Util::valueToFlagByteIndexValue( uint32_t inVal, uint8_t& outVal, uint16_t&
147148
outVal = 1 << bitIndex;
148149
}
149150

151+
std::string Util::readFileToString( const std::string& filename )
152+
{
153+
// Open the file for reading
154+
std::ifstream file( filename );
155+
156+
// Check if the file was opened successfully
157+
if( !file )
158+
{
159+
throw std::runtime_error( "Failed to open file" );
160+
}
161+
162+
// Read the contents of the file into a string
163+
std::string fileContents( ( std::istreambuf_iterator< char >( file ) ),
164+
std::istreambuf_iterator< char >() );
165+
166+
// Close the file
167+
file.close();
168+
169+
// Remove all newlines from the file contents
170+
fileContents.erase( std::remove( fileContents.begin(), fileContents.end(), '\n' ), fileContents.end() );
171+
fileContents.erase( std::remove( fileContents.begin(), fileContents.end(), '\r' ), fileContents.end() );
172+
173+
174+
// Return the file contents as a string
175+
return fileContents;
176+
177+
}
178+
150179

151180
std::string Util::fmtUtcTime( const std::string& fmt )
152181
{

src/common/Util/Util.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ namespace Sapphire::Common::Util
4444
seed ^= hasher( v ) + 0x9e3779b9 + ( seed << 6 ) + ( seed >> 2 );
4545
}
4646

47+
std::string readFileToString( const std::string& filename );
48+
4749
}
4850

4951
#endif

src/world/Encounter/Encounter.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,23 @@
44

55
namespace Sapphire
66
{
7-
Encounter::Encounter( TerritoryPtr pInstance, std::shared_ptr< Event::Director > pDirector, const std::string& timelineName ) :
7+
Encounter::Encounter( TerritoryPtr pInstance, std::shared_ptr< Event::Director > pDirector,
8+
const std::string& timelineName ) :
89
m_pTeri( pInstance ),
910
m_pDirector( pDirector ),
10-
m_timelineName( timelineName ),
1111
m_status( EncounterStatus::UNINITIALIZED )
1212
{
13+
m_setup.timelineName = timelineName;
1314
}
1415

1516
void Encounter::init()
1617
{
17-
m_pTimeline = TimelinePack::createTimelinePack( m_timelineName );
18+
m_pTimeline = TimelinePack::createTimelinePack( m_setup.timelineName );
1819
m_pTimeline->setEncounter( shared_from_this() );
1920
m_status = EncounterStatus::IDLE;
2021
m_startTime = 0;
2122

22-
for( const auto& actor : m_actorSetupList )
23+
for( const auto& actor : m_setup.actorSetupList )
2324
{
2425
auto entry = m_pTeri->createBNpcFromLayoutId( actor.layoutId, actor.hp, actor.type );
2526
entry->init();
@@ -97,8 +98,13 @@ namespace Sapphire
9798
return m_pDirector;
9899
}
99100

100-
void Encounter::setInitialActorSetup( const std::vector<EncounterActor>& actorSetupList )
101+
void Encounter::setInitialActorSetup( const std::vector< EncounterActor >& actorSetupList )
101102
{
102-
m_actorSetupList = actorSetupList;
103+
m_setup.actorSetupList = actorSetupList;
104+
}
105+
106+
EncounterSetup& Encounter::getSetup()
107+
{
108+
return m_setup;
103109
}
104110
}

src/world/Encounter/Encounter.h

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ namespace Sapphire
2020
SUCCESS
2121
};
2222

23+
enum class EncounterShape
24+
{
25+
BOX,
26+
CYLINDER
27+
};
28+
2329
struct EncounterActor
2430
{
2531
uint32_t layoutId;
@@ -28,6 +34,18 @@ namespace Sapphire
2834
uint32_t flags;
2935
};
3036

37+
struct EncounterSetup
38+
{
39+
std::string timelineName;
40+
std::vector< EncounterActor > actorSetupList;
41+
EncounterShape encounterShape;
42+
// for BOX shape, this would be m_position = min, m_position2 = max
43+
// for CYLINDER m_position = center, m_position2.x radius, position2.y height
44+
Common::FFXIVARR_POSITION3 position;
45+
Common::FFXIVARR_POSITION3 position2;
46+
bool hasLockout{false};
47+
};
48+
3149
class Encounter : public std::enable_shared_from_this< Encounter >
3250
{
3351
public:
@@ -65,19 +83,21 @@ namespace Sapphire
6583

6684
void setInitialActorSetup( const std::vector< EncounterActor >& actorSetupList );
6785

86+
EncounterSetup& getSetup();
87+
6888
protected:
6989
uint64_t m_startTime{ 0 };
70-
std::string m_timelineName;
90+
7191
std::set< Entity::PlayerPtr > m_playerList;
7292
std::unordered_map< uint32_t, Entity::BNpcPtr > m_bnpcs;
73-
7493
EncounterStatus m_status{ EncounterStatus::IDLE };
75-
7694
Event::DirectorPtr m_pDirector;
7795
TerritoryPtr m_pTeri;
78-
79-
std::vector< EncounterActor > m_actorSetupList;
8096
std::shared_ptr< TimelinePack > m_pTimeline;
97+
98+
// encountersetup
99+
EncounterSetup m_setup;
100+
81101
};
82102

83103

0 commit comments

Comments
 (0)