load path from config, follow log file, working reopening
Some checks failed
ContinuousIntegration / linux (push) Successful in 23s
ContinuousIntegration / macos (push) Has been cancelled
ContinuousIntegration / windows (push) Has been cancelled

This commit is contained in:
Green Sky 2024-06-11 12:02:53 +02:00
parent 6f6894419a
commit e1e2563ac2
No known key found for this signature in database
4 changed files with 94 additions and 19 deletions

View File

@ -3,6 +3,8 @@
#include <entt/entt.hpp>
#include <entt/fwd.hpp>
#include <solanaceae/util/config_model.hpp>
#include "factorio_log_parser.hpp"
#include "factorio.hpp"
@ -31,12 +33,13 @@ SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_start(struct SolanaAPI* solana_api)
}
try {
auto* conf = PLUG_RESOLVE_INSTANCE(ConfigModelI);
auto* cr = PLUG_RESOLVE_INSTANCE_VERSIONED(Contact3Registry, "1");
auto* rmm = PLUG_RESOLVE_INSTANCE(RegistryMessageModel);
// static store, could be anywhere tho
// construct with fetched dependencies
g_flp = std::make_unique<FactorioLogParser>();
g_flp = std::make_unique<FactorioLogParser>(*conf);
g_f = std::make_unique<Factorio>(*cr, *rmm, *g_flp);
// register types
@ -57,9 +60,8 @@ SOLANA_PLUGIN_EXPORT void solana_plugin_stop(void) {
g_flp.reset();
}
SOLANA_PLUGIN_EXPORT float solana_plugin_tick(float) {
//return g_rpbot->tick(delta);
return 1000.f;
SOLANA_PLUGIN_EXPORT float solana_plugin_tick(float delta) {
return g_flp->tick(delta);
}
} // extern C

View File

@ -29,34 +29,42 @@ bool Factorio::onEvent(const Message::Events::MessageConstruct& e) {
}
bool Factorio::onEvent(const FactorioLog::Events::Join& e) {
std::cout << "F: event join " << e.player_name << "\n";
return false;
}
bool Factorio::onEvent(const FactorioLog::Events::Leave& e) {
std::cout << "F: event leave " << e.player_name << " " << e.reason << "\n";
return false;
}
bool Factorio::onEvent(const FactorioLog::Events::Chat& e) {
std::cout << "F: event chat " << e.player_name << ": " << e.message << "\n";
return false;
}
bool Factorio::onEvent(const FactorioLog::Events::Died& e) {
std::cout << "F: event died " << e.player_name << ": " << e.reason << "\n";
return false;
}
bool Factorio::onEvent(const FactorioLog::Events::Evolution& e) {
std::cout << "F: event evolution " << e.evo << "\n";
return false;
}
bool Factorio::onEvent(const FactorioLog::Events::ResearchStarted& e) {
std::cout << "F: event research started " << e.name << "\n";
return false;
}
bool Factorio::onEvent(const FactorioLog::Events::ResearchFinished& e) {
std::cout << "F: event research finished " << e.name << "\n";
return false;
}
bool Factorio::onEvent(const FactorioLog::Events::ResearchCancelled& e) {
std::cout << "F: event research cancelled " << e.name << "\n";
return false;
}

View File

@ -1,28 +1,74 @@
#include "./factorio_log_parser.hpp"
#include <solanaceae/util/config_model.hpp>
#include "./log_parse.hpp"
FactorioLogParser::FactorioLogParser(void) :
_fw("test.txt", [this](const auto& path, const auto event){ this->onFileEvent(path, event);})
FactorioLogParser::FactorioLogParser(ConfigModelI& conf) :
_log_file_path(conf.get_string("FactorioLogParser", "log_file_path").value_or("factorio-current.log")),
_fw(_log_file_path, [this](const auto& path, const auto event){ this->onFileEvent(path, event);})
{
resetLogFile();
}
FactorioLogParser::~FactorioLogParser(void) {
}
void FactorioLogParser::onFileEvent(const std::string& path, const filewatch::Event change_type) {
std::cout << "file even " << filewatch::event_to_string(change_type) << " on '" << path << "'\n";
// on create, close open log file and reopen and skip to end
// on mod (?), read line, parse
std::string line;
const auto parse_res = log_parse_line(line);
if (parse_res.has_value()) {
dispatchRaw(parse_res.value().event, parse_res.value().params);
float FactorioLogParser::tick(float) {
std::lock_guard lg{_event_queue_mutex};
while (!_event_queue.empty()) {
dispatchRaw(_event_queue.front().event, _event_queue.front().params);
_event_queue.pop();
}
return 10.f;
}
void FactorioLogParser::onFileEvent(const std::string& path, const filewatch::Event change_type) {
// compare path?
if (change_type == filewatch::Event::added) {
// on create, close open log file and reopen and skip to end
resetLogFile();
} else if (change_type == filewatch::Event::modified) {
// on mod, read lines and parse
if (!_log_file.is_open()) {
std::cerr << "FLP: modified file not open!\n";
//resetLogFile();
} else {
std::string line;
while (std::getline(_log_file, line).good()) {
if (line.empty()) {
std::cerr << "FLP error: getline empty??\n";
continue;
}
const auto parse_res = log_parse_line(line);
if (parse_res.has_value()) {
queueRaw(parse_res.value().event, parse_res.value().params);
}
}
_log_file.clear(); // reset eof and fail bits
}
}
}
void FactorioLogParser::resetLogFile(void) {
std::cerr << "FLP: resetting log file\n";
if (_log_file.is_open()) {
_log_file.close();
_log_file.clear();
}
_log_file.open(_log_file_path, std::ios::in | std::ios::binary | std::ios::ate);
if (!_log_file.is_open()) {
std::cerr << "FLP error: failed opening file\n";
}
}
void FactorioLogParser::queueRaw(std::string_view event, std::string_view params) {
std::lock_guard lg{_event_queue_mutex};
_event_queue.push(EventEntry{static_cast<std::string>(event), static_cast<std::string>(params)});
//std::cerr << "enqued '" << event << "': '" << params << "'\n";
}
void FactorioLogParser::dispatchRaw(std::string_view event, std::string_view params) {

View File

@ -6,6 +6,12 @@
#include <string>
#include <string_view>
#include <mutex>
#include <queue>
#include <fstream>
// fwd
struct ConfigModelI;
namespace FactorioLog::Events {
@ -77,16 +83,29 @@ struct FactorioLogParserEventI {
using FactorioLogParserEventProviderI = EventProviderI<FactorioLogParserEventI>;
class FactorioLogParser : public FactorioLogParserEventProviderI {
std::string _log_file_path;
filewatch::FileWatch<std::string> _fw;
std::ifstream _log_file;
struct EventEntry {
std::string event;
std::string params;
};
std::queue<EventEntry> _event_queue;
std::mutex _event_queue_mutex;
public:
FactorioLogParser(void);
FactorioLogParser(ConfigModelI& conf);
virtual ~FactorioLogParser(void);
float tick(float delta);
protected:
void onFileEvent(const std::string& path, const filewatch::Event change_type);
void resetLogFile(void);
protected:
void queueRaw(std::string_view event, std::string_view params);
void dispatchRaw(std::string_view event, std::string_view params);
void throwJoin(std::string_view params);