Browse Source

Refactor timed message handling

pull/2421/head
Vladimir Olteanu 5 years ago committed by Anders Jenbo
parent
commit
f8d98560ae
  1. 9
      Source/multi.cpp
  2. 64
      Source/tmsg.cpp
  3. 20
      Source/tmsg.h

9
Source/multi.cpp

@ -303,12 +303,11 @@ void HandleAllPackets(int pnum, byte *pData, size_t nSize)
void ProcessTmsgs()
{
size_t cnt;
TPkt pkt;
uint8_t cnt;
std::unique_ptr<byte[]> msg;
while ((cnt = tmsg_get((byte *)&pkt)) != 0) {
HandleAllPackets(MyPlayerId, (byte *)&pkt, cnt);
}
while ((cnt = tmsg_get(&msg)) != 0)
HandleAllPackets(MyPlayerId, msg.get(), cnt);
}
void SendPlayerInfo(int pnum, _cmd_id cmd)

64
Source/tmsg.cpp

@ -3,67 +3,61 @@
*
* Implementation of functionality transmitting chat messages.
*/
#include <list>
#include "tmsg.h"
#include "diablo.h"
namespace devilution {
namespace {
TMsg *sgpTimedMsgHead;
struct TMsg {
uint32_t time;
std::unique_ptr<byte[]> body;
uint8_t len;
TMsg(uint32_t time, byte *data, uint8_t len)
: time(time)
, body(new byte[len])
, len(len)
{
memcpy(body.get(), data, len);
}
};
std::list<TMsg> TimedMsgList;
} // namespace
size_t tmsg_get(byte *pbMsg)
uint8_t tmsg_get(std::unique_ptr<byte[]> *msg)
{
TMsg *head;
if (sgpTimedMsgHead == nullptr)
if (TimedMsgList.empty())
return 0;
if ((int)(sgpTimedMsgHead->hdr.dwTime - SDL_GetTicks()) >= 0)
TMsg &head = TimedMsgList.front();
if ((int)(head.time - SDL_GetTicks()) >= 0)
return 0;
head = sgpTimedMsgHead;
sgpTimedMsgHead = head->hdr.pNext;
size_t len = head->hdr.bLen;
// BUGFIX: ignores dwMaxLen
memcpy(pbMsg, head->body, len);
std::free(head);
uint8_t len = head.len;
*msg = std::move(head.body);
TimedMsgList.pop_front();
return len;
}
void tmsg_add(byte *pbMsg, uint8_t bLen)
void tmsg_add(byte *msg, uint8_t len)
{
TMsg **tail;
TMsg *msg = static_cast<TMsg *>(std::malloc(bLen + sizeof(*msg)));
if (msg == nullptr)
app_fatal("Failed to allocate memory");
msg->hdr.pNext = nullptr;
msg->hdr.dwTime = SDL_GetTicks() + gnTickDelay * 10;
msg->hdr.bLen = bLen;
memcpy(msg->body, pbMsg, bLen);
for (tail = &sgpTimedMsgHead; *tail != nullptr; tail = &(*tail)->hdr.pNext) {
;
}
*tail = msg;
uint32_t time = SDL_GetTicks() + gnTickDelay * 10;
TimedMsgList.emplace_back(time, msg, len);
}
void tmsg_start()
{
assert(!sgpTimedMsgHead);
assert(TimedMsgList.empty());
}
void tmsg_cleanup()
{
TMsg *next;
while (sgpTimedMsgHead != nullptr) {
next = sgpTimedMsgHead->hdr.pNext;
std::free(sgpTimedMsgHead);
sgpTimedMsgHead = next;
}
TimedMsgList.clear();
}
} // namespace devilution

20
Source/tmsg.h

@ -6,28 +6,14 @@
#pragma once
#include <cstdint>
#include <memory>
#include "utils/stdcompat/cstddef.hpp"
namespace devilution {
#pragma pack(push, 1)
struct TMsgHdr {
struct TMsg *pNext;
int32_t dwTime;
uint8_t bLen;
};
struct TMsg {
TMsgHdr hdr;
// this is actually alignment padding, but the message body is appended to the struct
// so it's convenient to use byte-alignment and name it "body"
byte body[3];
};
#pragma pack(pop)
size_t tmsg_get(byte *pbMsg);
void tmsg_add(byte *pbMsg, uint8_t bLen);
uint8_t tmsg_get(std::unique_ptr<byte[]> *msg);
void tmsg_add(byte *msg, uint8_t bLen);
void tmsg_start();
void tmsg_cleanup();

Loading…
Cancel
Save