mirror of
https://github.com/DaKerboul/perun.git
synced 2026-08-09 17:05:39 +02:00
log mission logs into separate files
This commit is contained in:
@@ -1,12 +1,18 @@
|
|||||||
# CMakeList.txt : CMake project for perun_dll, include source and define
|
# CMakeList.txt : CMake project for perun_dll, include source and define
|
||||||
# project specific logic here.
|
# project specific logic here.
|
||||||
#
|
#
|
||||||
cmake_minimum_required (VERSION 3.8)
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
|
||||||
project ("parent")
|
project ("parent")
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 19.12.25835)
|
||||||
|
set(CMAKE_CXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
|
||||||
|
set(CMAKE_CXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(lua-5.1.5)
|
add_subdirectory(lua-5.1.5)
|
||||||
add_subdirectory(perun)
|
add_subdirectory(perun)
|
||||||
|
add_subdirectory(experimental)
|
||||||
18
03_Perun_Lua_Wrapper/experimental/CMakeLists.txt
Normal file
18
03_Perun_Lua_Wrapper/experimental/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.17)
|
||||||
|
project(experimental)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
|
set (EXPERIMENTAL_SOURCES
|
||||||
|
"src/main.cpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(experimental ${EXPERIMENTAL_SOURCES})
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
lua-5.1.5
|
||||||
|
ws2_32
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories (pierog PUBLIC)
|
||||||
|
#set_target_properties(main PROPERTIES OUTPUT_NAME "perun")
|
||||||
@@ -28,7 +28,7 @@ set (LUA_RUNTIME_SOURCES
|
|||||||
"src/lua.h"
|
"src/lua.h"
|
||||||
"src/lualib.h"
|
"src/lualib.h"
|
||||||
"src/lzio.c" "src/lzio.h"
|
"src/lzio.c" "src/lzio.h"
|
||||||
)
|
../experimental/src/main.cpp)
|
||||||
|
|
||||||
|
|
||||||
add_library( lua-5.1.5 ${LUA_RUNTIME_SOURCES} )
|
add_library( lua-5.1.5 ${LUA_RUNTIME_SOURCES} )
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
cmake_minimum_required(VERSION 3.17)
|
cmake_minimum_required(VERSION 3.17)
|
||||||
project(perun)
|
project(pierog)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
|
||||||
set (PERUN_DLL_SOURCES
|
set (PIEROG_DLL_SOURCES
|
||||||
"src/library.h"
|
"src/library.h"
|
||||||
"src/library.cpp"
|
"src/library.cpp"
|
||||||
"src/Connection.h"
|
"src/Connection.h"
|
||||||
@@ -11,13 +11,12 @@ set (PERUN_DLL_SOURCES
|
|||||||
)
|
)
|
||||||
|
|
||||||
include (GenerateExportHeader)
|
include (GenerateExportHeader)
|
||||||
add_library(perun SHARED ${PERUN_DLL_SOURCES})
|
add_library(pierog SHARED ${PIEROG_DLL_SOURCES})
|
||||||
|
|
||||||
target_link_libraries(
|
target_link_libraries(
|
||||||
perun
|
pierog
|
||||||
lua-5.1.5
|
lua-5.1.5
|
||||||
ws2_32
|
ws2_32
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories (perun PUBLIC)
|
target_include_directories (pierog PUBLIC)
|
||||||
#set_target_properties(main PROPERTIES OUTPUT_NAME "perun")
|
|
||||||
@@ -1,30 +1,25 @@
|
|||||||
#include "Connection.h"
|
#include "Connection.h"
|
||||||
|
|
||||||
SocketWrapper::SocketWrapper(std::string name): outputFile(name, std::ofstream::app) {
|
#include <utility>
|
||||||
tcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
#include <filesystem>
|
||||||
|
|
||||||
|
SocketWrapper::SocketWrapper(std::string logPath,
|
||||||
|
std::string host,
|
||||||
|
const int port): path(std::move(logPath)), tcpHost(std::move(host)), tcpPort(port){
|
||||||
|
this->tcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||||
|
|
||||||
|
startNewRecording();
|
||||||
}
|
}
|
||||||
|
|
||||||
SocketWrapper::~SocketWrapper() {
|
SocketWrapper::~SocketWrapper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int SocketWrapper::getAndResetReconnected() {
|
|
||||||
int result = this->flagReconnected;
|
|
||||||
|
|
||||||
this->flagReconnected = 0;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SocketWrapper::getFlagConnected() {
|
|
||||||
return this->connectionState;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SocketWrapper::tcpConnect() {
|
void SocketWrapper::tcpConnect() {
|
||||||
// Create socket address object from TCP port and host
|
// Create socket address object from TCP port and host
|
||||||
SOCKADDR_IN socketAddress;
|
SOCKADDR_IN socketAddress;
|
||||||
socketAddress.sin_family = AF_INET;
|
socketAddress.sin_family = AF_INET;
|
||||||
socketAddress.sin_port = htons(u_short(this->tcpPort));
|
socketAddress.sin_port = htons(u_short(this->tcpPort));
|
||||||
socketAddress.sin_addr.s_addr = *((unsigned long*)gethostbyname(this->tcpHost->c_str())->h_addr);
|
socketAddress.sin_addr.s_addr = *((unsigned long*)gethostbyname(this->tcpHost.c_str())->h_addr);
|
||||||
|
|
||||||
if (connect(tcpSocket, (sockaddr*)&socketAddress, sizeof(SOCKADDR_IN)) == 0) {
|
if (connect(tcpSocket, (sockaddr*)&socketAddress, sizeof(SOCKADDR_IN)) == 0) {
|
||||||
this->connectionState = CONNECTED;
|
this->connectionState = CONNECTED;
|
||||||
@@ -32,33 +27,54 @@ void SocketWrapper::tcpConnect() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SocketWrapper::createConnection(std::string* host, const int* port) {
|
void SocketWrapper::startNewRecording() {
|
||||||
|
if(outputFile != nullptr && outputFile->is_open() && outputFile->good()) {
|
||||||
|
outputFile->flush();
|
||||||
|
outputFile->close();
|
||||||
|
delete outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const now = std::chrono::system_clock::now();
|
||||||
|
auto const gmt = std::chrono::locate_zone("Etc/GMT");
|
||||||
|
auto const filename = std::format("pierog.{:%FT_%H%M%S}.log", std::chrono::zoned_time{gmt, floor<std::chrono::milliseconds>(now)});
|
||||||
|
|
||||||
|
std::filesystem::path dir(this->path);
|
||||||
|
std::filesystem::path file(filename);
|
||||||
|
auto fullPath = (dir / file).string();
|
||||||
|
|
||||||
|
outputFile = new std::ofstream(fullPath, std::ofstream::app | std::ios::out);
|
||||||
|
|
||||||
|
// clean the network buffer if nothing was ever sent
|
||||||
|
if(sentCounter > 0) {
|
||||||
|
mutexLock.lock();
|
||||||
|
dataBuffer.clear();
|
||||||
|
sendQueue.clear();
|
||||||
|
mutexLock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SocketWrapper::createConnection() {
|
||||||
// TCP connection - ConnectTo
|
// TCP connection - ConnectTo
|
||||||
this->tcpHost = host;
|
|
||||||
this->tcpPort = *port;
|
|
||||||
|
|
||||||
tcpConnect();
|
tcpConnect();
|
||||||
|
|
||||||
// Create new thread
|
|
||||||
std::thread thread_object([this]() {
|
std::thread thread_object([this]() {
|
||||||
// TCP sending loop
|
|
||||||
bool nothingToSend = false;
|
bool nothingToSend = false;
|
||||||
while (true) {
|
while (shouldRun) {
|
||||||
if (connectionState == CONNECTED && mutexLock.try_lock()) {
|
if (connectionState == CONNECTED && mutexLock.try_lock()) {
|
||||||
if (sendQueue.empty()) {
|
if (sendQueue.empty()) {
|
||||||
nothingToSend = true;
|
nothingToSend = true;
|
||||||
} else {
|
} else {
|
||||||
// Payload in queue
|
// Payload in queue
|
||||||
auto payload = sendQueue.front();
|
auto payload = sendQueue.front();
|
||||||
|
|
||||||
outputFile.write(payload->c_str(), payload->length());
|
|
||||||
outputFile.flush();
|
|
||||||
int bytesSent = send(tcpSocket, payload->c_str(), payload->length(), 0);
|
int bytesSent = send(tcpSocket, payload->c_str(), payload->length(), 0);
|
||||||
|
|
||||||
if (bytesSent == payload->length()) {
|
if (bytesSent == payload->length()) {
|
||||||
// All payload was sent
|
// All payload was sent
|
||||||
sendQueue.pop_front();
|
sendQueue.pop_front();
|
||||||
delete payload;
|
delete payload;
|
||||||
|
sentCounter += bytesSent;
|
||||||
} else {
|
} else {
|
||||||
// Remaining paylad
|
// Remaining paylad
|
||||||
if (bytesSent > 0) {
|
if (bytesSent > 0) {
|
||||||
@@ -67,6 +83,7 @@ void SocketWrapper::createConnection(std::string* host, const int* port) {
|
|||||||
sendQueue.pop_front();
|
sendQueue.pop_front();
|
||||||
sendQueue.push_front(&shortened);
|
sendQueue.push_front(&shortened);
|
||||||
delete payload;
|
delete payload;
|
||||||
|
sentCounter += bytesSent;
|
||||||
} else {
|
} else {
|
||||||
// Payload was not sent - handle error
|
// Payload was not sent - handle error
|
||||||
switch (WSAGetLastError()) {
|
switch (WSAGetLastError()) {
|
||||||
@@ -110,16 +127,38 @@ void SocketWrapper::disconnect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SocketWrapper::enqueueForSending(std::string* payload) {
|
void SocketWrapper::enqueueForSending(std::string* payload) {
|
||||||
|
if(outputFile == nullptr) {
|
||||||
|
startNewRecording();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(outputFile != nullptr) {
|
||||||
|
outputFile->write(payload->c_str(), payload->length());
|
||||||
|
if(payload->length() > 50) {
|
||||||
|
outputFile->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mutexLock.try_lock()) {
|
if (mutexLock.try_lock()) {
|
||||||
while (!dataBuffer.empty()) {
|
while (!dataBuffer.empty()) {
|
||||||
// Shift buffer to queue
|
// Shift buffer to queue
|
||||||
sendQueue.push_back(dataBuffer.front());
|
sendQueue.push_back(dataBuffer.front());
|
||||||
dataBuffer.pop();
|
dataBuffer.pop_front();
|
||||||
}
|
}
|
||||||
sendQueue.push_back(payload);
|
sendQueue.push_back(payload);
|
||||||
mutexLock.unlock();
|
mutexLock.unlock();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dataBuffer.push(payload);
|
dataBuffer.push_back(payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SocketWrapper::getAndResetReconnected() {
|
||||||
|
int result = this->flagReconnected;
|
||||||
|
|
||||||
|
this->flagReconnected = 0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int SocketWrapper::getFlagConnected() {
|
||||||
|
return this->connectionState;
|
||||||
|
}
|
||||||
@@ -17,32 +17,36 @@ enum enumConnectionState {
|
|||||||
|
|
||||||
class SocketWrapper {
|
class SocketWrapper {
|
||||||
public:
|
public:
|
||||||
SocketWrapper(std::string name);
|
SocketWrapper(std::string logPath,
|
||||||
|
std::string host,
|
||||||
|
const int port);
|
||||||
|
|
||||||
~SocketWrapper();
|
~SocketWrapper();
|
||||||
|
|
||||||
void disconnect();
|
void disconnect();
|
||||||
void createConnection(std::string* host, const int* port);
|
void createConnection();
|
||||||
|
void startNewRecording();
|
||||||
void enqueueForSending(std::string* payload);
|
void enqueueForSending(std::string* payload);
|
||||||
|
|
||||||
int getAndResetReconnected();
|
int getAndResetReconnected();
|
||||||
int getFlagConnected();
|
int getFlagConnected();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// SocketWrapper(const SocketWrapper&);
|
|
||||||
// SocketWrapper& operator=(const SocketWrapper&);
|
|
||||||
|
|
||||||
SOCKET tcpSocket;
|
SOCKET tcpSocket;
|
||||||
std::string* tcpHost;
|
const std::string path;
|
||||||
int tcpPort;
|
const std::string tcpHost = "localhost";
|
||||||
|
const int tcpPort = 0;
|
||||||
|
|
||||||
int flagReconnected = 0;
|
int flagReconnected = 0;
|
||||||
volatile enumConnectionState connectionState = DISCONNECTED;
|
volatile enumConnectionState connectionState = DISCONNECTED;
|
||||||
|
std::atomic<long long> sentCounter;
|
||||||
|
std::atomic<boolean> shouldRun = true;
|
||||||
|
|
||||||
std::queue<std::string*> dataBuffer;
|
std::deque<std::string*> dataBuffer;
|
||||||
std::deque<std::string*> sendQueue;
|
std::deque<std::string*> sendQueue;
|
||||||
|
|
||||||
std::mutex mutexLock;
|
std::mutex mutexLock;
|
||||||
std::ofstream outputFile;
|
std::ofstream * outputFile = nullptr;
|
||||||
|
|
||||||
void reconnect();
|
void reconnect();
|
||||||
void tcpConnect();
|
void tcpConnect();
|
||||||
|
|||||||
@@ -1,7 +1,13 @@
|
|||||||
#include "library.h"
|
#include "library.h"
|
||||||
|
#include <format>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
static SocketWrapper * tcpConnection = nullptr;
|
static SocketWrapper * tcpConnection = nullptr;
|
||||||
|
|
||||||
|
static std::string *startingDelimiter = nullptr;
|
||||||
|
static std::string *endingDelimiter = nullptr;
|
||||||
|
static std::string lastObservedHash = std::string("");
|
||||||
|
|
||||||
/* this method exists for comments */
|
/* this method exists for comments */
|
||||||
static int valuesToReturn(int input) {
|
static int valuesToReturn(int input) {
|
||||||
return input;
|
return input;
|
||||||
@@ -10,13 +16,14 @@ static int valuesToReturn(int input) {
|
|||||||
static int appStartHook(lua_State* luaState) {
|
static int appStartHook(lua_State* luaState) {
|
||||||
// Starting the app - prepare
|
// Starting the app - prepare
|
||||||
if(tcpConnection == nullptr) {
|
if(tcpConnection == nullptr) {
|
||||||
auto nowMillis = std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
|
|
||||||
auto millis = nowMillis.time_since_epoch().count();
|
|
||||||
|
|
||||||
char buffer[50];
|
int i = 1;
|
||||||
sprintf_s(buffer, "c:/temp/perun.%llu.log", millis);
|
const std::string path = std::string(lua_tolstring(luaState, i++, 0));
|
||||||
|
const std::string host = std::string(lua_tolstring(luaState, i++, 0));
|
||||||
|
const int port = (int) lua_tointeger(luaState, i++);
|
||||||
|
|
||||||
tcpConnection = new SocketWrapper(std::string(buffer));
|
tcpConnection = new SocketWrapper(path, host, port);
|
||||||
|
tcpConnection->createConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
lua_pushinteger(luaState, 1); // First return value: confirmation that app was started
|
lua_pushinteger(luaState, 1); // First return value: confirmation that app was started
|
||||||
@@ -34,14 +41,20 @@ static int appEndHook(lua_State* luaState) {
|
|||||||
return valuesToReturn(0);
|
return valuesToReturn(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcpConnect(lua_State* luaState) {
|
static int setDelimiters(lua_State* luaState) {
|
||||||
// Connect to the TCP socket
|
startingDelimiter = new std::string(lua_tolstring(luaState, 1, 0));
|
||||||
|
endingDelimiter = new std::string(lua_tolstring(luaState, 2, 0));
|
||||||
|
|
||||||
if(tcpConnection != nullptr) {
|
return valuesToReturn(0);
|
||||||
auto *host = new std::string(lua_tolstring(luaState, 1, 0));
|
}
|
||||||
const int *port = new int(lua_tointeger(luaState, 2));
|
|
||||||
|
|
||||||
tcpConnection->createConnection(host, port);
|
static int markMissionStart(lua_State* luaState) {
|
||||||
|
|
||||||
|
std::string missionHash = std::string(lua_tolstring(luaState, 1, 0));
|
||||||
|
|
||||||
|
if(tcpConnection != nullptr && missionHash ==lastObservedHash) {
|
||||||
|
tcpConnection->startNewRecording();
|
||||||
|
lastObservedHash = missionHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
return valuesToReturn(0);
|
return valuesToReturn(0);
|
||||||
@@ -51,7 +64,13 @@ static int tcpSend(lua_State* luaState) {
|
|||||||
// Send frame over TCP socket
|
// Send frame over TCP socket
|
||||||
|
|
||||||
if(tcpConnection != nullptr) {
|
if(tcpConnection != nullptr) {
|
||||||
|
if(startingDelimiter != nullptr) {
|
||||||
|
tcpConnection->enqueueForSending(new std::string(*startingDelimiter));
|
||||||
|
}
|
||||||
tcpConnection->enqueueForSending(new std::string(lua_tolstring(luaState, 1, 0)));
|
tcpConnection->enqueueForSending(new std::string(lua_tolstring(luaState, 1, 0)));
|
||||||
|
if(endingDelimiter != nullptr) {
|
||||||
|
tcpConnection->enqueueForSending(new std::string(*endingDelimiter));
|
||||||
|
}
|
||||||
|
|
||||||
lua_pushinteger(luaState,
|
lua_pushinteger(luaState,
|
||||||
tcpConnection->getFlagConnected()); // First return value: information if there is TCP connection
|
tcpConnection->getFlagConnected()); // First return value: information if there is TCP connection
|
||||||
@@ -65,17 +84,18 @@ static int tcpSend(lua_State* luaState) {
|
|||||||
return valuesToReturn(2);
|
return valuesToReturn(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int __declspec(dllexport) luaopen_perun(lua_State * L) {
|
extern "C" int __declspec(dllexport) luaopen_pierog(lua_State * L) {
|
||||||
static const luaL_Reg Map[] = {
|
static const luaL_Reg Map[] = {
|
||||||
{"StartOfApp", appStartHook}, // Called at the begining of the session
|
{"StartOfApp", appStartHook}, // Called at the begining of the session
|
||||||
{"EndOfApp", appEndHook }, // Called at the end of the session out of LuaExportStop
|
{"EndOfApp", appEndHook }, // Called at the end of the session out of LuaExportStop
|
||||||
{"tcpSend", tcpSend}, // Called to send data from lua over TCP
|
{"tcpSend", tcpSend}, // Called to send data from lua over TCP
|
||||||
{"tcpConnect", tcpConnect}, // Create connection
|
{"delimiters", setDelimiters },
|
||||||
|
{"markMissionStart", markMissionStart },
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Register the list of functions for lua
|
// Register the list of functions for lua
|
||||||
luaL_register(L, "perun", Map);
|
luaL_register(L, "pierog", Map);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user