load path from config, follow log file, working reopening
This commit is contained in:
parent
6f6894419a
commit
e1e2563ac2
@ -3,6 +3,8 @@
|
|||||||
#include <entt/entt.hpp>
|
#include <entt/entt.hpp>
|
||||||
#include <entt/fwd.hpp>
|
#include <entt/fwd.hpp>
|
||||||
|
|
||||||
|
#include <solanaceae/util/config_model.hpp>
|
||||||
|
|
||||||
#include "factorio_log_parser.hpp"
|
#include "factorio_log_parser.hpp"
|
||||||
#include "factorio.hpp"
|
#include "factorio.hpp"
|
||||||
|
|
||||||
@ -31,12 +33,13 @@ SOLANA_PLUGIN_EXPORT uint32_t solana_plugin_start(struct SolanaAPI* solana_api)
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
auto* conf = PLUG_RESOLVE_INSTANCE(ConfigModelI);
|
||||||
auto* cr = PLUG_RESOLVE_INSTANCE_VERSIONED(Contact3Registry, "1");
|
auto* cr = PLUG_RESOLVE_INSTANCE_VERSIONED(Contact3Registry, "1");
|
||||||
auto* rmm = PLUG_RESOLVE_INSTANCE(RegistryMessageModel);
|
auto* rmm = PLUG_RESOLVE_INSTANCE(RegistryMessageModel);
|
||||||
|
|
||||||
// static store, could be anywhere tho
|
// static store, could be anywhere tho
|
||||||
// construct with fetched dependencies
|
// 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);
|
g_f = std::make_unique<Factorio>(*cr, *rmm, *g_flp);
|
||||||
|
|
||||||
// register types
|
// register types
|
||||||
@ -57,9 +60,8 @@ SOLANA_PLUGIN_EXPORT void solana_plugin_stop(void) {
|
|||||||
g_flp.reset();
|
g_flp.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
SOLANA_PLUGIN_EXPORT float solana_plugin_tick(float) {
|
SOLANA_PLUGIN_EXPORT float solana_plugin_tick(float delta) {
|
||||||
//return g_rpbot->tick(delta);
|
return g_flp->tick(delta);
|
||||||
return 1000.f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // extern C
|
} // extern C
|
||||||
|
@ -29,34 +29,42 @@ bool Factorio::onEvent(const Message::Events::MessageConstruct& e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Factorio::onEvent(const FactorioLog::Events::Join& e) {
|
bool Factorio::onEvent(const FactorioLog::Events::Join& e) {
|
||||||
|
std::cout << "F: event join " << e.player_name << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Factorio::onEvent(const FactorioLog::Events::Leave& e) {
|
bool Factorio::onEvent(const FactorioLog::Events::Leave& e) {
|
||||||
|
std::cout << "F: event leave " << e.player_name << " " << e.reason << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Factorio::onEvent(const FactorioLog::Events::Chat& e) {
|
bool Factorio::onEvent(const FactorioLog::Events::Chat& e) {
|
||||||
|
std::cout << "F: event chat " << e.player_name << ": " << e.message << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Factorio::onEvent(const FactorioLog::Events::Died& e) {
|
bool Factorio::onEvent(const FactorioLog::Events::Died& e) {
|
||||||
|
std::cout << "F: event died " << e.player_name << ": " << e.reason << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Factorio::onEvent(const FactorioLog::Events::Evolution& e) {
|
bool Factorio::onEvent(const FactorioLog::Events::Evolution& e) {
|
||||||
|
std::cout << "F: event evolution " << e.evo << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Factorio::onEvent(const FactorioLog::Events::ResearchStarted& e) {
|
bool Factorio::onEvent(const FactorioLog::Events::ResearchStarted& e) {
|
||||||
|
std::cout << "F: event research started " << e.name << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Factorio::onEvent(const FactorioLog::Events::ResearchFinished& e) {
|
bool Factorio::onEvent(const FactorioLog::Events::ResearchFinished& e) {
|
||||||
|
std::cout << "F: event research finished " << e.name << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Factorio::onEvent(const FactorioLog::Events::ResearchCancelled& e) {
|
bool Factorio::onEvent(const FactorioLog::Events::ResearchCancelled& e) {
|
||||||
|
std::cout << "F: event research cancelled " << e.name << "\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,28 +1,74 @@
|
|||||||
#include "./factorio_log_parser.hpp"
|
#include "./factorio_log_parser.hpp"
|
||||||
|
|
||||||
|
#include <solanaceae/util/config_model.hpp>
|
||||||
|
|
||||||
#include "./log_parse.hpp"
|
#include "./log_parse.hpp"
|
||||||
|
|
||||||
FactorioLogParser::FactorioLogParser(void) :
|
FactorioLogParser::FactorioLogParser(ConfigModelI& conf) :
|
||||||
_fw("test.txt", [this](const auto& path, const auto event){ this->onFileEvent(path, event);})
|
_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) {
|
FactorioLogParser::~FactorioLogParser(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FactorioLogParser::onFileEvent(const std::string& path, const filewatch::Event change_type) {
|
float FactorioLogParser::tick(float) {
|
||||||
std::cout << "file even " << filewatch::event_to_string(change_type) << " on '" << path << "'\n";
|
std::lock_guard lg{_event_queue_mutex};
|
||||||
|
while (!_event_queue.empty()) {
|
||||||
// on create, close open log file and reopen and skip to end
|
dispatchRaw(_event_queue.front().event, _event_queue.front().params);
|
||||||
// on mod (?), read line, parse
|
_event_queue.pop();
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
void FactorioLogParser::dispatchRaw(std::string_view event, std::string_view params) {
|
||||||
|
@ -6,6 +6,12 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
struct ConfigModelI;
|
||||||
|
|
||||||
namespace FactorioLog::Events {
|
namespace FactorioLog::Events {
|
||||||
|
|
||||||
@ -77,16 +83,29 @@ struct FactorioLogParserEventI {
|
|||||||
using FactorioLogParserEventProviderI = EventProviderI<FactorioLogParserEventI>;
|
using FactorioLogParserEventProviderI = EventProviderI<FactorioLogParserEventI>;
|
||||||
|
|
||||||
class FactorioLogParser : public FactorioLogParserEventProviderI {
|
class FactorioLogParser : public FactorioLogParserEventProviderI {
|
||||||
|
std::string _log_file_path;
|
||||||
filewatch::FileWatch<std::string> _fw;
|
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:
|
public:
|
||||||
FactorioLogParser(void);
|
FactorioLogParser(ConfigModelI& conf);
|
||||||
virtual ~FactorioLogParser(void);
|
virtual ~FactorioLogParser(void);
|
||||||
|
|
||||||
|
float tick(float delta);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void onFileEvent(const std::string& path, const filewatch::Event change_type);
|
void onFileEvent(const std::string& path, const filewatch::Event change_type);
|
||||||
|
void resetLogFile(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void queueRaw(std::string_view event, std::string_view params);
|
||||||
void dispatchRaw(std::string_view event, std::string_view params);
|
void dispatchRaw(std::string_view event, std::string_view params);
|
||||||
|
|
||||||
void throwJoin(std::string_view params);
|
void throwJoin(std::string_view params);
|
||||||
|
Loading…
Reference in New Issue
Block a user