Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Bunnysplit MQ for Linux #360

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 98 additions & 3 deletions BunnymodXT/Linux/interprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace Interprocess
{
mqd_t mq = static_cast<mqd_t>(-1);
mqd_t mq_bunnysplit = static_cast<mqd_t>(-1);

void Initialize()
{
Expand Down Expand Up @@ -62,13 +63,25 @@ namespace Interprocess

void WriteTime(const Time& time)
{
if (!CVars::bxt_interprocess_enable.GetBool())
return;

std::vector<char> buf(10);
buf[0] = static_cast<char>(buf.size());
buf[1] = static_cast<char>(MessageType::TIME);
AddTimeToBuffer(buf.data() + 2, time);

if (CVars::_bxt_bunnysplit_time_update_frequency.GetFloat() > 0.0f) {
auto ms = static_cast<long long>(1000 / CVars::_bxt_bunnysplit_time_update_frequency.GetFloat());
static auto last_time = std::chrono::steady_clock::now() - std::chrono::milliseconds(ms + 1);
auto now = std::chrono::steady_clock::now();
if (now >= last_time + std::chrono::milliseconds(ms)) {
WriteBunnySplit(buf);
last_time = now;
}
} else {
WriteBunnySplit(buf);
}

if (!CVars::bxt_interprocess_enable.GetBool())
return;

Write(buf);
}
Expand Down Expand Up @@ -110,21 +123,103 @@ namespace Interprocess

void WriteGameEnd(const Time& time)
{
std::vector<char> buf(11);
buf[0] = static_cast<char>(buf.size());
buf[1] = static_cast<char>(MessageType::EVENT);
buf[2] = static_cast<char>(EventType::GAMEEND);
AddTimeToBuffer(buf.data() + 3, time);

WriteBunnySplit(buf);
}

void WriteMapChange(const Time& time, const std::string& map)
{
int32_t size = static_cast<int32_t>(map.size());

std::vector<char> buf(15 + size);
buf[0] = static_cast<char>(buf.size());
buf[1] = static_cast<char>(MessageType::EVENT);
buf[2] = static_cast<char>(EventType::MAPCHANGE);
auto time_size = AddTimeToBuffer(buf.data() + 3, time);

std::memcpy(buf.data() + 3 + time_size, &size, sizeof(size));
std::memcpy(buf.data() + 3 + time_size + 4, map.data(), size);

WriteBunnySplit(buf);
}

void WriteTimerReset(const Time& time)
{
std::vector<char> buf(11);
buf[0] = static_cast<char>(buf.size());
buf[1] = static_cast<char>(MessageType::EVENT);
buf[2] = static_cast<char>(EventType::TIMER_RESET);
AddTimeToBuffer(buf.data() + 3, time);

WriteBunnySplit(buf);
}

void WriteTimerStart(const Time& time)
{
std::vector<char> buf(11);
buf[0] = static_cast<char>(buf.size());
buf[1] = static_cast<char>(MessageType::EVENT);
buf[2] = static_cast<char>(EventType::TIMER_START);
AddTimeToBuffer(buf.data() + 3, time);

WriteBunnySplit(buf);
}

void WriteBSALeapOfFaith(const Time& time)
{
std::vector<char> buf(11);
buf[0] = static_cast<char>(buf.size());
buf[1] = static_cast<char>(MessageType::EVENT);
buf[2] = static_cast<char>(EventType::BS_ALEAPOFFAITH);
AddTimeToBuffer(buf.data() + 3, time);

WriteBunnySplit(buf);
}

void InitBunnySplitPipe()
{
mq_bunnysplit = mq_open(
"/" BUNNYSPLIT_MQ_NAME,
O_WRONLY | O_CREAT | O_NONBLOCK,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
nullptr);

if (mq_bunnysplit == static_cast<mqd_t>(-1)) {
EngineDevWarning("Error opening the BunnySplit message queue: %s\n", strerror(errno));
EngineWarning("BunnySplit integration is not available.\n");
return;
}

EngineDevMsg("Opened the BunnySplit message queue.\n");
}

void ShutdownBunnySplitPipe()
{
if (mq_bunnysplit != static_cast<mqd_t>(-1)) {
mq_close(mq_bunnysplit);
mq_unlink("/" BUNNYSPLIT_MQ_NAME);
EngineDevMsg("Closed the BunnySplit message queue.\n");
}

mq_bunnysplit = static_cast<mqd_t>(-1);
}

void WriteBunnySplit(const std::vector<char>& data)
{
if (mq_bunnysplit == static_cast<mqd_t>(-1))
return;

if (mq_send(mq_bunnysplit, data.data(), data.size(), 0) == -1) {
// This shouldn't really happen.
// Perhaps the message queue was force-deleted or something.
EngineDevWarning("[mq_bunnysplit] mq_send failed with %d (%s).\n", errno, strerror(errno));
ShutdownBunnySplitPipe();
InitBunnySplitPipe();
}
}
}
2 changes: 2 additions & 0 deletions BunnymodXT/Linux/main_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ static __attribute__((constructor(1337))) void Construct()
_EngineDevWarning = PrintDevWarning;

Interprocess::Initialize();
Interprocess::InitBunnySplitPipe();

Hooks::AddToHookedModules(&HwDLL::GetInstance());
Hooks::AddToHookedModules(&ClientDLL::GetInstance());
Expand All @@ -111,4 +112,5 @@ static __attribute__((destructor(1337))) void Destruct()
fclose(logfile);

Interprocess::Shutdown();
Interprocess::ShutdownBunnySplitPipe();
}
5 changes: 3 additions & 2 deletions BunnymodXT/Windows/interprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,9 +188,10 @@ namespace Interprocess
AddTimeToBuffer(buf.data() + 2, time);

if (CVars::_bxt_bunnysplit_time_update_frequency.GetFloat() > 0.0f) {
static auto last_time = std::chrono::steady_clock::now() - std::chrono::milliseconds(static_cast<long long>(1000 / CVars::_bxt_bunnysplit_time_update_frequency.GetFloat()) + 1);
auto ms = static_cast<long long>(1000 / CVars::_bxt_bunnysplit_time_update_frequency.GetFloat());
static auto last_time = std::chrono::steady_clock::now() - std::chrono::milliseconds(ms + 1);
auto now = std::chrono::steady_clock::now();
if (now >= last_time + std::chrono::milliseconds(static_cast<long long>(1000 / CVars::_bxt_bunnysplit_time_update_frequency.GetFloat()))) {
if (now >= last_time + std::chrono::milliseconds(ms)) {
WriteBunnySplit(buf);
last_time = now;
}
Expand Down
6 changes: 6 additions & 0 deletions BunnymodXT/interprocess.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,10 @@ namespace Interprocess
void WriteTimerReset(const Time& time);
void WriteTimerStart(const Time& time);
void WriteBSALeapOfFaith(const Time& time);

#ifndef _WIN32
void InitBunnySplitPipe();
void ShutdownBunnySplitPipe();
void WriteBunnySplit(const std::vector<char>& data);
#endif
}
1 change: 1 addition & 0 deletions BunnymodXT/shared.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ enum class EventType : unsigned char {

#define MQ_NAME "BunnymodXT-TASView"
#define BUNNYSPLIT_PIPE_NAME "BunnymodXT-BunnySplit"
#define BUNNYSPLIT_MQ_NAME "BunnymodXT-BunnySplit"