mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
* Update Raid Functions Updated various raid features for: Titanium - Raid window now functional, including with BOTS - Raid delegate assist/mark work - Raid notes work - Raid /rmark, /clearmarks work Underfoot - Raid window was already functional - Raid delegate assist/mark work - Raid notes work - Raid /rmark, /clearmarks work * Updates to resolve feedback * Slight update for overlooked case in encode for RaidUpdate for clients above Ti. * Updates to further address feedback. Only updated translators for Ti/RoF2. Once ok, I will update the others. * Update linux-build.sh * Final updates for other translators and the strncpy_s issue. * Fix for strn0cpy in raids.cpp, translators, and defines. Updated all in raids.cpp as well. * Reveted defines change. * Reverted accidental change --------- Co-authored-by: Akkadius <akkadius1@gmail.com>
182 lines
6.2 KiB
C++
182 lines
6.2 KiB
C++
/* EQEMu: Everquest Server Emulator
|
|
|
|
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
|
are required to give you total support for your newly bought product;
|
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#define ENCODE(x) void Strategy::Encode_##x(EQApplicationPacket **p, std::shared_ptr<EQStreamInterface> dest, bool ack_req)
|
|
#define DECODE(x) void Strategy::Decode_##x(EQApplicationPacket *__packet)
|
|
|
|
#define StructDist(in, f1, f2) (uint32(&in->f2)-uint32(&in->f1))
|
|
#define CopyBlock(to, field, from, field1, field2) \
|
|
memcpy((void *) &to->field, (const void *) from->field1, StructDist(from, field1, field2));
|
|
#define CopyLen(to, field, from, field1, len) \
|
|
memcpy((void *) &to->field, (const void *) from->field1, len);
|
|
|
|
|
|
/*
|
|
*
|
|
* for encoders
|
|
*
|
|
*/
|
|
//more complex operations and variable length packets
|
|
#define FASTQUEUE(packet) dest->FastQueuePacket(&packet, ack_req);
|
|
#define TAKE(packet_name) \
|
|
EQApplicationPacket *packet_name = *p; \
|
|
*p = nullptr;
|
|
|
|
//simple buffer-to-buffer movement for fixed length packets
|
|
//the eq packet is mapped into `eq`, the emu packet into `emu`
|
|
#define SETUP_DIRECT_ENCODE(emu_struct, eq_struct) \
|
|
SETUP_VAR_ENCODE(emu_struct); \
|
|
ALLOC_VAR_ENCODE(eq_struct, sizeof(eq_struct));
|
|
|
|
//like a direct encode, but for variable length packets (two stage)
|
|
#define SETUP_VAR_ENCODE(emu_struct) \
|
|
EQApplicationPacket *__packet = *p; \
|
|
*p = nullptr; \
|
|
unsigned char *__emu_buffer = __packet->pBuffer; \
|
|
emu_struct *emu = (emu_struct *) __emu_buffer; \
|
|
uint32 __i = 0; \
|
|
__i++; /* to shut up compiler */
|
|
|
|
#define ALLOC_VAR_ENCODE(eq_struct, len) \
|
|
__packet->pBuffer = new unsigned char[len]; \
|
|
__packet->size = len; \
|
|
memset(__packet->pBuffer, 0, len); \
|
|
eq_struct *eq = (eq_struct *) __packet->pBuffer; \
|
|
|
|
#define ALLOC_LEN_ENCODE(len) \
|
|
__packet->pBuffer = new unsigned char[len]; \
|
|
__packet->size = len; \
|
|
memset(__packet->pBuffer, 0, len); \
|
|
|
|
//a shorter assignment for direct mode
|
|
#undef OUT
|
|
#define OUT(x) eq->x = emu->x;
|
|
#define OUT_str(x) \
|
|
strncpy(eq->x, emu->x, sizeof(eq->x)); \
|
|
eq->x[sizeof(eq->x)-1] = '\0';
|
|
#define OUT_array(x, n) \
|
|
for(__i = 0; __i < n; __i++) \
|
|
eq->x[__i] = emu->x[__i];
|
|
|
|
//call before any premature returns in an encoder using SETUP_DIRECT_ENCODE
|
|
#define FAIL_ENCODE() \
|
|
delete[] __emu_buffer; \
|
|
delete __packet;
|
|
|
|
//call to finish an encoder using SETUP_DIRECT_ENCODE
|
|
#define FINISH_ENCODE() \
|
|
delete[] __emu_buffer; \
|
|
dest->FastQueuePacket(&__packet, ack_req);
|
|
|
|
//check length of packet before decoding. Call before setup.
|
|
#define ENCODE_LENGTH_EXACT(struct_) \
|
|
if((*p)->size != sizeof(struct_)) { \
|
|
LogNetcode("Wrong size on outbound [{}] (" #struct_ "): Got [{}], expected [{}]", opcodes->EmuToName((*p)->GetOpcode()), (*p)->size, sizeof(struct_)); \
|
|
delete *p; \
|
|
*p = nullptr; \
|
|
return; \
|
|
}
|
|
#define ENCODE_LENGTH_ATLEAST(struct_) \
|
|
if((*p)->size < sizeof(struct_)) { \
|
|
LogNetcode("Wrong size on outbound [{}] (" #struct_ "): Got [{}], expected at least [{}]", opcodes->EmuToName((*p)->GetOpcode()), (*p)->size, sizeof(struct_)); \
|
|
delete *p; \
|
|
*p = nullptr; \
|
|
return; \
|
|
}
|
|
|
|
//forward this opcode to another encoder
|
|
#define ENCODE_FORWARD(other_op) \
|
|
Encode_##other_op(p, dest, ack_req);
|
|
|
|
//destroy the packet, it is not sent to this client version
|
|
#define EAT_ENCODE(op) \
|
|
ENCODE(op) { \
|
|
delete *p; \
|
|
*p = nullptr; \
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*
|
|
* for decoders:
|
|
*
|
|
*/
|
|
|
|
//simple buffer-to-buffer movement for fixed length packets
|
|
//the eq packet is mapped into `eq`, the emu packet into `emu`
|
|
#define SETUP_DIRECT_DECODE(emu_struct, eq_struct) \
|
|
unsigned char *__eq_buffer = __packet->pBuffer; \
|
|
__packet->size = sizeof(emu_struct); \
|
|
__packet->pBuffer = new unsigned char[__packet->size]; \
|
|
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
|
eq_struct *eq = (eq_struct *) __eq_buffer;
|
|
|
|
#define SETUP_VAR_DECODE(emu_struct, eq_struct, var_field) \
|
|
unsigned char *__eq_buffer = __packet->pBuffer; \
|
|
eq_struct* in = (eq_struct*)__packet->pBuffer; \
|
|
auto size = strlen(in->var_field); \
|
|
__packet->size = sizeof(emu_struct) + size + 1; \
|
|
__packet->pBuffer = new unsigned char[__packet->size]; \
|
|
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
|
|
eq_struct *eq = (eq_struct *) __eq_buffer;
|
|
|
|
#define MEMSET_IN(emu_struct) \
|
|
memset(__packet->pBuffer, 0, sizeof(emu_struct));
|
|
|
|
//a shorter assignment for direct mode
|
|
#undef IN
|
|
#define IN(x) emu->x = eq->x;
|
|
#define IN_str(x) \
|
|
strncpy(emu->x, eq->x, sizeof(emu->x)); \
|
|
emu->x[sizeof(emu->x)-1] = '\0';
|
|
#define IN_array(x, n) \
|
|
for(__i = 0; __i < n; __i++) \
|
|
emu->x[__i] = eq->x[__i];
|
|
|
|
//call before any premature returns in an encoder using SETUP_DIRECT_DECODE
|
|
#define FAIL_DIRECT_DECODE() \
|
|
delete[] __eq_buffer; \
|
|
p->SetOpcode(OP_Unknown);
|
|
|
|
#define FINISH_VAR_DECODE() \
|
|
delete[] __eq_buffer;
|
|
|
|
//call to finish an encoder using SETUP_DIRECT_DECODE
|
|
#define FINISH_DIRECT_DECODE() \
|
|
delete[] __eq_buffer;
|
|
|
|
//check length of packet before decoding. Call before setup.
|
|
#define DECODE_LENGTH_EXACT(struct_) \
|
|
if(__packet->size != sizeof(struct_)) { \
|
|
LogNetcode("Wrong size on incoming [{}] (" #struct_ "): Got [{}], expected [{}]", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
|
|
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
|
return; \
|
|
}
|
|
#define DECODE_LENGTH_ATLEAST(struct_) \
|
|
if(__packet->size < sizeof(struct_)) { \
|
|
LogNetcode("Wrong size on incoming [{}] (" #struct_ "): Got [{}], expected at least [{}]", opcodes->EmuToName(__packet->GetOpcode()), __packet->size, sizeof(struct_)); \
|
|
__packet->SetOpcode(OP_Unknown); /* invalidate the packet */ \
|
|
return; \
|
|
}
|
|
|
|
//forward this opcode to another decoder
|
|
#define DECODE_FORWARD(other_op) \
|
|
Decode_##other_op(__packet);
|