Skip to content

Commit

Permalink
load path from config, follow log file, working reopening
Browse files Browse the repository at this point in the history
  • Loading branch information
Green-Sky committed Jun 11, 2024
1 parent 6f68944 commit e1e2563
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 16 deletions.
10 changes: 6 additions & 4 deletions plugins/plugin_factorio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/factorio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

68 changes: 57 additions & 11 deletions src/factorio_log_parser.cpp
Original file line number Diff line number Diff line change
@@ -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
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;
}

std::string line;
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
}
}
}

const auto parse_res = log_parse_line(line);
if (parse_res.has_value()) {
dispatchRaw(parse_res.value().event, parse_res.value().params);
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) {
Expand Down
21 changes: 20 additions & 1 deletion src/factorio_log_parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

#include <string>
#include <string_view>
#include <mutex>
#include <queue>
#include <fstream>

// fwd
struct ConfigModelI;

namespace FactorioLog::Events {

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit e1e2563

Please sign in to comment.