diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index b77e4df7f..ceb5c80d1 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -589,6 +589,7 @@ SET(common_headers ptimer.h queue.h races.h + raid.h random.h rdtsc.h rulesys.h diff --git a/common/eq_packet_structs.h b/common/eq_packet_structs.h index 2831f09f6..fc47f43e6 100644 --- a/common/eq_packet_structs.h +++ b/common/eq_packet_structs.h @@ -4164,7 +4164,6 @@ struct RaidGeneral_Struct { /*68*/ uint32 unknown1; /*72*/ char leader_name[64]; /*136*/ uint32 parameter; -/*200*/ char note[64]; }; struct RaidAddMember_Struct { @@ -4175,9 +4174,14 @@ struct RaidAddMember_Struct { /*139*/ uint8 flags[5]; //no idea if these are needed... }; +struct RaidNote_Struct { +/*000*/ RaidGeneral_Struct general; +/*140*/ char note[64]; +}; + struct RaidMOTD_Struct { -/*000*/ RaidGeneral_Struct general; // leader_name and action only used -/*136*/ char motd[0]; // max size is 1024, but reply is variable +/*000*/ RaidGeneral_Struct general; +/*140*/ char motd[1024]; }; struct RaidLeadershipUpdate_Struct { diff --git a/common/patches/rof.cpp b/common/patches/rof.cpp index 318c50f62..9665f11a7 100644 --- a/common/patches/rof.cpp +++ b/common/patches/rof.cpp @@ -34,6 +34,7 @@ #include "../rulesys.h" #include "../path_manager.h" #include "../races.h" +#include "../raid.h" #include #include @@ -2608,88 +2609,124 @@ namespace RoF ENCODE(OP_RaidJoin) { - EQApplicationPacket *inapp = *p; - unsigned char * __emu_buffer = inapp->pBuffer; - RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer; + EQApplicationPacket* inapp = *p; + *p = nullptr; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer; - auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); - structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer; + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); + structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer; - general->action = 8; - general->parameter = 1; - strn0cpy(general->leader_name, raid_create->leader_name, 64); - strn0cpy(general->player_name, raid_create->leader_name, 64); + general->action = raidCreate; + general->parameter = RaidCommandAcceptInvite; + strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name)); + strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name)); + + dest->FastQueuePacket(&outapp); - dest->FastQueuePacket(&outapp_create); safe_delete(inapp); + } ENCODE(OP_RaidUpdate) { - EQApplicationPacket *inapp = *p; + EQApplicationPacket* inapp = *p; *p = nullptr; - unsigned char * __emu_buffer = inapp->pBuffer; - RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer; - if (raid_gen->action == 0) // raid add has longer length than other raid updates + switch (raid_gen->action) { - RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer; + case raidAdd: + { + RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct)); - structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer; + structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer; - add_member->raidGen.action = in_add_member->raidGen.action; - add_member->raidGen.parameter = in_add_member->raidGen.parameter; - strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64); - strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64); - add_member->_class = in_add_member->_class; - add_member->level = in_add_member->level; - add_member->isGroupLeader = in_add_member->isGroupLeader; - add_member->flags[0] = in_add_member->flags[0]; - add_member->flags[1] = in_add_member->flags[1]; - add_member->flags[2] = in_add_member->flags[2]; - add_member->flags[3] = in_add_member->flags[3]; - add_member->flags[4] = in_add_member->flags[4]; - dest->FastQueuePacket(&outapp); - } - else if (raid_gen->action == 35) - { - RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer; - auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) + - strlen(inmotd->motd) + 1); - structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer; + OUT(raidGen.action); + OUT(raidGen.parameter); + OUT_str(raidGen.leader_name); + OUT_str(raidGen.player_name); + OUT(_class); + OUT(level); + OUT(isGroupLeader); + OUT(flags[0]); + OUT(flags[1]); + OUT(flags[2]); + OUT(flags[3]); + OUT(flags[4]); - outmotd->general.action = inmotd->general.action; - strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64); - strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1); dest->FastQueuePacket(&outapp); + break; } - else if (raid_gen->action == 14 || raid_gen->action == 30) + case raidSetMotd: { - RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer; - auto outapp = - new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); - structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer; + RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct)); + structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.player_name); + OUT_str(general.leader_name); + OUT_str(motd); - outlaa->action = inlaa->action; - strn0cpy(outlaa->player_name, inlaa->player_name, 64); - strn0cpy(outlaa->leader_name, inlaa->leader_name, 64); - memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct)); dest->FastQueuePacket(&outapp); + break; } - else + case raidSetLeaderAbilities: + case raidMakeLeader: { - RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer; + RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); + structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer; + + OUT(action); + OUT_str(player_name); + OUT_str(leader_name); + memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct)); + + dest->FastQueuePacket(&outapp); + break; + } + case raidSetNote: + { + auto emu = (RaidNote_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct)); + auto eq = (structs::RaidNote_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.leader_name); + OUT_str(general.player_name); + OUT_str(note); + + dest->FastQueuePacket(&outapp); + break; + } + case raidNoRaid: + { + dest->QueuePacket(inapp); + break; + } + default: + { + RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); - structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer; - strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64); - strn0cpy(raid_general->player_name, in_raid_general->player_name, 64); - raid_general->action = in_raid_general->action; - raid_general->parameter = in_raid_general->parameter; - dest->FastQueuePacket(&outapp); - } + structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer; + OUT(action); + OUT(parameter); + OUT_str(leader_name); + OUT_str(player_name); + + dest->FastQueuePacket(&outapp); + break; + } + } safe_delete(inapp); } @@ -4861,37 +4898,47 @@ namespace RoF { DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct); - // This is a switch on the RaidGeneral action - switch (*(uint32 *)__packet->pBuffer) { - case 35: { // raidMOTD - // we don't have a nice macro for this - structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer; - __eq_buffer->motd[1023] = '\0'; - size_t motd_size = strlen(__eq_buffer->motd) + 1; - __packet->size = sizeof(RaidMOTD_Struct) + motd_size; - __packet->pBuffer = new unsigned char[__packet->size]; - RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer; - structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer; - strn0cpy(emu->general.player_name, eq->general.player_name, 64); - strn0cpy(emu->motd, eq->motd, motd_size); - IN(general.action); - IN(general.parameter); - FINISH_DIRECT_DECODE(); - break; - } - case 36: { // raidPlayerNote unhandled - break; - } - default: { - DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct); - SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); - strn0cpy(emu->leader_name, eq->leader_name, 64); - strn0cpy(emu->player_name, eq->player_name, 64); - IN(action); - IN(parameter); - FINISH_DIRECT_DECODE(); - break; - } + RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer; + + switch (rgs->action) + { + case raidSetMotd: + { + SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(motd); + + FINISH_VAR_DECODE(); + break; + } + case raidSetNote: + { + SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(note); + + FINISH_VAR_DECODE(); + break; + } + default: + { + SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); + IN(action); + IN(parameter); + IN_str(leader_name); + IN_str(player_name); + + FINISH_DIRECT_DECODE(); + break; + } } } diff --git a/common/patches/rof2.cpp b/common/patches/rof2.cpp index 6aba46261..bf9c6a363 100644 --- a/common/patches/rof2.cpp +++ b/common/patches/rof2.cpp @@ -35,7 +35,7 @@ #include "../path_manager.h" #include "../classes.h" #include "../races.h" -#include "../../zone/raids.h" +#include "../raid.h" #include #include @@ -2678,100 +2678,124 @@ namespace RoF2 ENCODE(OP_RaidJoin) { - EQApplicationPacket *inapp = *p; - unsigned char * __emu_buffer = inapp->pBuffer; - RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer; + EQApplicationPacket* inapp = *p; + *p = nullptr; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer; - auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); - structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer; + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); + structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer; - general->action = 8; - general->parameter = 1; - strn0cpy(general->leader_name, raid_create->leader_name, 64); - strn0cpy(general->player_name, raid_create->leader_name, 64); + general->action = raidCreate; + general->parameter = RaidCommandAcceptInvite; + strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name)); + strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name)); + + dest->FastQueuePacket(&outapp); - dest->FastQueuePacket(&outapp_create); safe_delete(inapp); + } ENCODE(OP_RaidUpdate) { - EQApplicationPacket *inapp = *p; + EQApplicationPacket* inapp = *p; *p = nullptr; - unsigned char * __emu_buffer = inapp->pBuffer; - RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer; - if (raid_gen->action == 0) // raid add has longer length than other raid updates + switch (raid_gen->action) { - RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer; + case raidAdd: + { + RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct)); - structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer; + structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer; - add_member->raidGen.action = in_add_member->raidGen.action; - add_member->raidGen.parameter = in_add_member->raidGen.parameter; - strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64); - strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64); - add_member->_class = in_add_member->_class; - add_member->level = in_add_member->level; - add_member->isGroupLeader = in_add_member->isGroupLeader; - add_member->flags[0] = in_add_member->flags[0]; - add_member->flags[1] = in_add_member->flags[1]; - add_member->flags[2] = in_add_member->flags[2]; - add_member->flags[3] = in_add_member->flags[3]; - add_member->flags[4] = in_add_member->flags[4]; - dest->FastQueuePacket(&outapp); - } - else if (raid_gen->action == 35) - { - RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer; - auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) + - strlen(inmotd->motd) + 1); - structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer; + OUT(raidGen.action); + OUT(raidGen.parameter); + OUT_str(raidGen.leader_name); + OUT_str(raidGen.player_name); + OUT(_class); + OUT(level); + OUT(isGroupLeader); + OUT(flags[0]); + OUT(flags[1]); + OUT(flags[2]); + OUT(flags[3]); + OUT(flags[4]); - outmotd->general.action = inmotd->general.action; - strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64); - strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1); dest->FastQueuePacket(&outapp); + break; } - else if (raid_gen->action == 14 || raid_gen->action == 30) + case raidSetMotd: { - RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer; - auto outapp = - new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); - structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer; + RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct)); + structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.player_name); + OUT_str(general.leader_name); + OUT_str(motd); - outlaa->action = inlaa->action; - strn0cpy(outlaa->player_name, inlaa->player_name, 64); - strn0cpy(outlaa->leader_name, inlaa->leader_name, 64); - memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct)); dest->FastQueuePacket(&outapp); + break; } - else if (raid_gen->action == raidSetNote) + case raidSetLeaderAbilities: + case raidMakeLeader: { - auto in_note = (RaidGeneral_Struct*)__emu_buffer; - auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); - auto note = (RaidGeneral_Struct*)outapp->pBuffer; - note->action = raidSetNote; - strn0cpy(note->leader_name, in_note->leader_name, sizeof(note->leader_name)); - strn0cpy(note->player_name, in_note->player_name, sizeof(note->leader_name)); - strn0cpy(note->note, in_note->note, sizeof(note->note)); - dest->QueuePacket(outapp); - safe_delete(outapp); + RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); + structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer; + + OUT(action); + OUT_str(player_name); + OUT_str(leader_name); + memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct)); + + dest->FastQueuePacket(&outapp); + break; } - else + case raidSetNote: { - RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer; + auto emu = (RaidNote_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct)); + auto eq = (structs::RaidNote_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.leader_name); + OUT_str(general.player_name); + OUT_str(note); + + dest->FastQueuePacket(&outapp); + break; + } + case raidNoRaid: + { + dest->QueuePacket(inapp); + break; + } + default: + { + RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); - structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer; - strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64); - strn0cpy(raid_general->player_name, in_raid_general->player_name, 64); - raid_general->action = in_raid_general->action; - raid_general->parameter = in_raid_general->parameter; - dest->FastQueuePacket(&outapp); - } + structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer; + OUT(action); + OUT(parameter); + OUT_str(leader_name); + OUT_str(player_name); + + dest->FastQueuePacket(&outapp); + break; + } + } safe_delete(inapp); } @@ -5091,37 +5115,47 @@ namespace RoF2 { DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct); - // This is a switch on the RaidGeneral action - switch (*(uint32 *)__packet->pBuffer) { - case 35: { // raidMOTD - // we don't have a nice macro for this - structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer; - __eq_buffer->motd[1023] = '\0'; - size_t motd_size = strlen(__eq_buffer->motd) + 1; - __packet->size = sizeof(RaidMOTD_Struct) + motd_size; - __packet->pBuffer = new unsigned char[__packet->size]; - RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer; - structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer; - strn0cpy(emu->general.player_name, eq->general.player_name, 64); - strn0cpy(emu->motd, eq->motd, motd_size); - IN(general.action); - IN(general.parameter); - FINISH_DIRECT_DECODE(); - break; - } - case 36: { // raidPlayerNote unhandled - break; - } - default: { - DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct); - SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); - strn0cpy(emu->leader_name, eq->leader_name, 64); - strn0cpy(emu->player_name, eq->player_name, 64); - IN(action); - IN(parameter); - FINISH_DIRECT_DECODE(); - break; - } + RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer; + + switch (rgs->action) + { + case raidSetMotd: + { + SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(motd); + + FINISH_VAR_DECODE(); + break; + } + case raidSetNote: + { + SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(note); + + FINISH_VAR_DECODE(); + break; + } + default: + { + SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); + IN(action); + IN(parameter); + IN_str(leader_name); + IN_str(player_name); + + FINISH_DIRECT_DECODE(); + break; + } } } diff --git a/common/patches/rof2_structs.h b/common/patches/rof2_structs.h index af9889f55..f1a9b111c 100644 --- a/common/patches/rof2_structs.h +++ b/common/patches/rof2_structs.h @@ -4198,9 +4198,14 @@ struct RaidAddMember_Struct { /*139*/ uint8 flags[5]; //no idea if these are needed... }; +struct RaidNote_Struct { +/*000*/ RaidGeneral_Struct general; +/*140*/ char note[64]; +}; + struct RaidMOTD_Struct { -/*000*/ RaidGeneral_Struct general; // leader_name and action only used -/*140*/ char motd[0]; // max size 1024, but reply is variable +/*000*/ RaidGeneral_Struct general; +/*140*/ char motd[1024]; }; struct RaidLeadershipUpdate_Struct { diff --git a/common/patches/rof_structs.h b/common/patches/rof_structs.h index ef2f8cc3e..c5ce0e702 100644 --- a/common/patches/rof_structs.h +++ b/common/patches/rof_structs.h @@ -4136,9 +4136,14 @@ struct RaidAddMember_Struct { /*139*/ uint8 flags[5]; //no idea if these are needed... }; +struct RaidNote_Struct { +/*000*/ RaidGeneral_Struct general; +/*140*/ char note[64]; +}; + struct RaidMOTD_Struct { /*000*/ RaidGeneral_Struct general; // leader_name and action only used -/*140*/ char motd[0]; // max size 1024, but reply is variable +/*140*/ char motd[1024]; // max size is 1024, but reply is variable }; struct RaidLeadershipUpdate_Struct { diff --git a/common/patches/sod.cpp b/common/patches/sod.cpp index 336cdff9b..43a07a9dc 100644 --- a/common/patches/sod.cpp +++ b/common/patches/sod.cpp @@ -34,6 +34,7 @@ #include "../rulesys.h" #include "../path_manager.h" #include "../races.h" +#include "../raid.h" #include #include @@ -1686,88 +1687,124 @@ namespace SoD ENCODE(OP_RaidJoin) { - EQApplicationPacket *inapp = *p; - unsigned char * __emu_buffer = inapp->pBuffer; - RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer; + EQApplicationPacket* inapp = *p; + *p = nullptr; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer; - auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); - structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer; + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); + structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer; - general->action = 8; - general->parameter = 1; - strn0cpy(general->leader_name, raid_create->leader_name, 64); - strn0cpy(general->player_name, raid_create->leader_name, 64); + general->action = raidCreate; + general->parameter = RaidCommandAcceptInvite; + strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name)); + strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name)); + + dest->FastQueuePacket(&outapp); - dest->FastQueuePacket(&outapp_create); safe_delete(inapp); + } ENCODE(OP_RaidUpdate) { - EQApplicationPacket *inapp = *p; + EQApplicationPacket* inapp = *p; *p = nullptr; - unsigned char * __emu_buffer = inapp->pBuffer; - RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer; - if (raid_gen->action == 0) // raid add has longer length than other raid updates + switch (raid_gen->action) { - RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer; + case raidAdd: + { + RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct)); - structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer; + structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer; - add_member->raidGen.action = in_add_member->raidGen.action; - add_member->raidGen.parameter = in_add_member->raidGen.parameter; - strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64); - strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64); - add_member->_class = in_add_member->_class; - add_member->level = in_add_member->level; - add_member->isGroupLeader = in_add_member->isGroupLeader; - add_member->flags[0] = in_add_member->flags[0]; - add_member->flags[1] = in_add_member->flags[1]; - add_member->flags[2] = in_add_member->flags[2]; - add_member->flags[3] = in_add_member->flags[3]; - add_member->flags[4] = in_add_member->flags[4]; - dest->FastQueuePacket(&outapp); - } - else if (raid_gen->action == 35) - { - RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer; - auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) + - strlen(inmotd->motd) + 1); - structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer; + OUT(raidGen.action); + OUT(raidGen.parameter); + OUT_str(raidGen.leader_name); + OUT_str(raidGen.player_name); + OUT(_class); + OUT(level); + OUT(isGroupLeader); + OUT(flags[0]); + OUT(flags[1]); + OUT(flags[2]); + OUT(flags[3]); + OUT(flags[4]); - outmotd->general.action = inmotd->general.action; - strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64); - strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1); dest->FastQueuePacket(&outapp); + break; } - else if (raid_gen->action == 14 || raid_gen->action == 30) + case raidSetMotd: { - RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer; - auto outapp = - new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); - structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer; + RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct)); + structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.player_name); + OUT_str(general.leader_name); + OUT_str(motd); - outlaa->action = inlaa->action; - strn0cpy(outlaa->player_name, inlaa->player_name, 64); - strn0cpy(outlaa->leader_name, inlaa->leader_name, 64); - memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct)); dest->FastQueuePacket(&outapp); + break; } - else + case raidSetLeaderAbilities: + case raidMakeLeader: { - RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer; + RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); + structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer; + + OUT(action); + OUT_str(player_name); + OUT_str(leader_name); + memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct)); + + dest->FastQueuePacket(&outapp); + break; + } + case raidSetNote: + { + auto emu = (RaidNote_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct)); + auto eq = (structs::RaidNote_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.leader_name); + OUT_str(general.player_name); + OUT_str(note); + + dest->FastQueuePacket(&outapp); + break; + } + case raidNoRaid: + { + dest->QueuePacket(inapp); + break; + } + default: + { + RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); - structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer; - strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64); - strn0cpy(raid_general->player_name, in_raid_general->player_name, 64); - raid_general->action = in_raid_general->action; - raid_general->parameter = in_raid_general->parameter; - dest->FastQueuePacket(&outapp); - } + structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer; + OUT(action); + OUT(parameter); + OUT_str(leader_name); + OUT_str(player_name); + + dest->FastQueuePacket(&outapp); + break; + } + } safe_delete(inapp); } @@ -3338,37 +3375,47 @@ namespace SoD { DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct); - // This is a switch on the RaidGeneral action - switch (*(uint32 *)__packet->pBuffer) { - case 35: { // raidMOTD - // we don't have a nice macro for this - structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer; - __eq_buffer->motd[1023] = '\0'; - size_t motd_size = strlen(__eq_buffer->motd) + 1; - __packet->size = sizeof(RaidMOTD_Struct) + motd_size; - __packet->pBuffer = new unsigned char[__packet->size]; - RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer; - structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer; - strn0cpy(emu->general.player_name, eq->general.player_name, 64); - strn0cpy(emu->motd, eq->motd, motd_size); - IN(general.action); - IN(general.parameter); - FINISH_DIRECT_DECODE(); - break; - } - case 36: { // raidPlayerNote unhandled - break; - } - default: { - DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct); - SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); - strn0cpy(emu->leader_name, eq->leader_name, 64); - strn0cpy(emu->player_name, eq->player_name, 64); - IN(action); - IN(parameter); - FINISH_DIRECT_DECODE(); - break; - } + RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer; + + switch (rgs->action) + { + case raidSetMotd: + { + SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(motd); + + FINISH_VAR_DECODE(); + break; + } + case raidSetNote: + { + SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(note); + + FINISH_VAR_DECODE(); + break; + } + default: + { + SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); + IN(action); + IN(parameter); + IN_str(leader_name); + IN_str(player_name); + + FINISH_DIRECT_DECODE(); + break; + } } } diff --git a/common/patches/sod_structs.h b/common/patches/sod_structs.h index 3c4d13f67..9d6e36e80 100644 --- a/common/patches/sod_structs.h +++ b/common/patches/sod_structs.h @@ -3592,9 +3592,14 @@ struct RaidAddMember_Struct { /*139*/ uint8 flags[5]; //no idea if these are needed... }; +struct RaidNote_Struct { +/*000*/ RaidGeneral_Struct general; +/*140*/ char note[64]; +}; + struct RaidMOTD_Struct { /*000*/ RaidGeneral_Struct general; // leader_name and action only used -/*140*/ char motd[0]; // max size 1024, but reply is variable +/*140*/ char motd[1024]; // max size is 1024, but reply is variable }; struct RaidLeadershipUpdate_Struct { diff --git a/common/patches/sof.cpp b/common/patches/sof.cpp index 17af33fc4..15384813e 100644 --- a/common/patches/sof.cpp +++ b/common/patches/sof.cpp @@ -33,6 +33,7 @@ #include "sof_structs.h" #include "../rulesys.h" #include "../path_manager.h" +#include "../raid.h" #include #include @@ -1356,88 +1357,124 @@ namespace SoF ENCODE(OP_RaidJoin) { - EQApplicationPacket *inapp = *p; - unsigned char * __emu_buffer = inapp->pBuffer; - RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer; + EQApplicationPacket* inapp = *p; + *p = nullptr; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer; - auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); - structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer; + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); + structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer; - general->action = 8; - general->parameter = 1; - strn0cpy(general->leader_name, raid_create->leader_name, 64); - strn0cpy(general->player_name, raid_create->leader_name, 64); + general->action = raidCreate; + general->parameter = RaidCommandAcceptInvite; + strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name)); + strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name)); + + dest->FastQueuePacket(&outapp); - dest->FastQueuePacket(&outapp_create); safe_delete(inapp); + } ENCODE(OP_RaidUpdate) { - EQApplicationPacket *inapp = *p; + EQApplicationPacket* inapp = *p; *p = nullptr; - unsigned char * __emu_buffer = inapp->pBuffer; - RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer; - if (raid_gen->action == 0) // raid add has longer length than other raid updates + switch (raid_gen->action) { - RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer; + case raidAdd: + { + RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct)); - structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer; + structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer; - add_member->raidGen.action = in_add_member->raidGen.action; - add_member->raidGen.parameter = in_add_member->raidGen.parameter; - strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64); - strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64); - add_member->_class = in_add_member->_class; - add_member->level = in_add_member->level; - add_member->isGroupLeader = in_add_member->isGroupLeader; - add_member->flags[0] = in_add_member->flags[0]; - add_member->flags[1] = in_add_member->flags[1]; - add_member->flags[2] = in_add_member->flags[2]; - add_member->flags[3] = in_add_member->flags[3]; - add_member->flags[4] = in_add_member->flags[4]; - dest->FastQueuePacket(&outapp); - } - else if (raid_gen->action == 35) - { - RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer; - auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) + - strlen(inmotd->motd) + 1); - structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer; + OUT(raidGen.action); + OUT(raidGen.parameter); + OUT_str(raidGen.leader_name); + OUT_str(raidGen.player_name); + OUT(_class); + OUT(level); + OUT(isGroupLeader); + OUT(flags[0]); + OUT(flags[1]); + OUT(flags[2]); + OUT(flags[3]); + OUT(flags[4]); - outmotd->general.action = inmotd->general.action; - strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64); - strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1); dest->FastQueuePacket(&outapp); + break; } - else if (raid_gen->action == 14 || raid_gen->action == 30) + case raidSetMotd: { - RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer; - auto outapp = - new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); - structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer; + RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct)); + structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.player_name); + OUT_str(general.leader_name); + OUT_str(motd); - outlaa->action = inlaa->action; - strn0cpy(outlaa->player_name, inlaa->player_name, 64); - strn0cpy(outlaa->leader_name, inlaa->leader_name, 64); - memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct)); dest->FastQueuePacket(&outapp); + break; } - else + case raidSetLeaderAbilities: + case raidMakeLeader: { - RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer; + RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); + structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer; + + OUT(action); + OUT_str(player_name); + OUT_str(leader_name); + memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct)); + + dest->FastQueuePacket(&outapp); + break; + } + case raidSetNote: + { + auto emu = (RaidNote_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct)); + auto eq = (structs::RaidNote_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.leader_name); + OUT_str(general.player_name); + OUT_str(note); + + dest->FastQueuePacket(&outapp); + break; + } + case raidNoRaid: + { + dest->QueuePacket(inapp); + break; + } + default: + { + RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); - structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer; - strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64); - strn0cpy(raid_general->player_name, in_raid_general->player_name, 64); - raid_general->action = in_raid_general->action; - raid_general->parameter = in_raid_general->parameter; - dest->FastQueuePacket(&outapp); - } + structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer; + OUT(action); + OUT(parameter); + OUT_str(leader_name); + OUT_str(player_name); + + dest->FastQueuePacket(&outapp); + break; + } + } safe_delete(inapp); } @@ -2743,37 +2780,47 @@ namespace SoF { DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct); - // This is a switch on the RaidGeneral action - switch (*(uint32 *)__packet->pBuffer) { - case 35: { // raidMOTD - // we don't have a nice macro for this - structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer; - __eq_buffer->motd[1023] = '\0'; - size_t motd_size = strlen(__eq_buffer->motd) + 1; - __packet->size = sizeof(RaidMOTD_Struct) + motd_size; - __packet->pBuffer = new unsigned char[__packet->size]; - RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer; - structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer; - strn0cpy(emu->general.player_name, eq->general.player_name, 64); - strn0cpy(emu->motd, eq->motd, motd_size); - IN(general.action); - IN(general.parameter); - FINISH_DIRECT_DECODE(); - break; - } - case 36: { // raidPlayerNote unhandled - break; - } - default: { - DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct); - SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); - strn0cpy(emu->leader_name, eq->leader_name, 64); - strn0cpy(emu->player_name, eq->player_name, 64); - IN(action); - IN(parameter); - FINISH_DIRECT_DECODE(); - break; - } + RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer; + + switch (rgs->action) + { + case raidSetMotd: + { + SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(motd); + + FINISH_VAR_DECODE(); + break; + } + case raidSetNote: + { + SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(note); + + FINISH_VAR_DECODE(); + break; + } + default: + { + SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); + IN(action); + IN(parameter); + IN_str(leader_name); + IN_str(player_name); + + FINISH_DIRECT_DECODE(); + break; + } } } diff --git a/common/patches/sof_structs.h b/common/patches/sof_structs.h index 70163ffc2..9f8d48eb1 100644 --- a/common/patches/sof_structs.h +++ b/common/patches/sof_structs.h @@ -3517,9 +3517,14 @@ struct RaidAddMember_Struct { /*139*/ uint8 flags[5]; //no idea if these are needed... }; +struct RaidNote_Struct { +/*000*/ RaidGeneral_Struct general; +/*140*/ char note[64]; +}; + struct RaidMOTD_Struct { /*000*/ RaidGeneral_Struct general; // leader_name and action only used -/*140*/ char motd[0]; // max size 1024, but reply is variable +/*140*/ char motd[1024]; // max size is 1024, but reply is variable }; struct RaidLeadershipUpdate_Struct { diff --git a/common/patches/ss_define.h b/common/patches/ss_define.h index 57bf6b1b4..cb52136e5 100644 --- a/common/patches/ss_define.h +++ b/common/patches/ss_define.h @@ -128,6 +128,15 @@ 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)); @@ -146,6 +155,9 @@ 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; diff --git a/common/patches/titanium.cpp b/common/patches/titanium.cpp index 7f7aa6326..6725f496a 100644 --- a/common/patches/titanium.cpp +++ b/common/patches/titanium.cpp @@ -33,6 +33,7 @@ #include "../item_instance.h" #include "titanium_structs.h" #include "../path_manager.h" +#include "../raid.h" #include @@ -1245,6 +1246,119 @@ namespace Titanium FINISH_ENCODE(); } + ENCODE(OP_MarkRaidNPC) + { + ENCODE_LENGTH_EXACT(MarkNPC_Struct); + SETUP_DIRECT_ENCODE(MarkNPC_Struct, MarkNPC_Struct); + + EQApplicationPacket* outapp = new EQApplicationPacket(OP_MarkNPC, sizeof(MarkNPC_Struct)); + MarkNPC_Struct* mnpcs = (MarkNPC_Struct*)outapp->pBuffer; + mnpcs->TargetID = emu->TargetID; + mnpcs->Number = emu->Number; + dest->QueuePacket(outapp); + safe_delete(outapp); + + FINISH_ENCODE(); + } + + ENCODE(OP_RaidUpdate) + { + EQApplicationPacket* inapp = *p; + *p = nullptr; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer; + + switch (raid_gen->action) + { + case raidAdd: + { + RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct)); + structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer; + + OUT(raidGen.action); + OUT(raidGen.parameter); + OUT_str(raidGen.leader_name); + OUT_str(raidGen.player_name); + OUT(_class); + OUT(level); + OUT(isGroupLeader); + + dest->FastQueuePacket(&outapp); + break; + + } + case raidSetMotd: + { + RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct)); + structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.player_name); + OUT_str(general.leader_name); + OUT_str(motd); + + dest->FastQueuePacket(&outapp); + break; + } + case raidSetLeaderAbilities: + case raidMakeLeader: + { + RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); + structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer; + + OUT(action); + OUT_str(player_name); + OUT_str(leader_name); + memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct)); + + dest->FastQueuePacket(&outapp); + break; + } + case raidSetNote: + { + auto emu = (RaidNote_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct)); + auto eq = (structs::RaidNote_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.leader_name); + OUT_str(general.player_name); + OUT_str(note); + + dest->FastQueuePacket(&outapp); + break; + } + case raidNoRaid: + { + dest->QueuePacket(inapp); + break; + } + default: + { + RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); + structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer; + + OUT(action); + OUT(parameter); + OUT_str(leader_name); + OUT_str(player_name); + + dest->FastQueuePacket(&outapp); + break; + } + } + safe_delete(inapp); + } + ENCODE(OP_ReadBook) { // no apparent slot translation needed @@ -2272,6 +2386,63 @@ namespace Titanium FINISH_DIRECT_DECODE(); } + DECODE(OP_RaidInvite) + { + DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct); + RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer; + + switch (rgs->action) + { + case raidSetMotd: + { + SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + + auto len = 0; + if (__packet->size < sizeof(structs::RaidMOTD_Struct)) { + len = __packet->size - sizeof(structs::RaidGeneral_Struct); + } + else { + len = sizeof(eq->motd); + } + + strn0cpy(emu->motd, eq->motd, len > 1024 ? 1024 : len); + emu->motd[len - 1] = '\0'; + + FINISH_VAR_DECODE(); + break; + } + case raidSetNote: + { + SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(note); + + FINISH_VAR_DECODE(); + break; + } + default: + { + SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); + IN(action); + IN(parameter); + IN_str(leader_name); + IN_str(player_name); + + FINISH_DIRECT_DECODE(); + break; + } + } + } + DECODE(OP_ReadBook) { // no apparent slot translation needed diff --git a/common/patches/titanium_ops.h b/common/patches/titanium_ops.h index c747233fd..c5c774a17 100644 --- a/common/patches/titanium_ops.h +++ b/common/patches/titanium_ops.h @@ -61,6 +61,8 @@ E(OP_OnLevelMessage) E(OP_PetBuffWindow) E(OP_PlayerProfile) E(OP_NewSpawn) +E(OP_MarkRaidNPC) +E(OP_RaidUpdate) E(OP_ReadBook) E(OP_RespondAA) E(OP_SendCharInfo) @@ -106,6 +108,7 @@ D(OP_LoadSpellSet) D(OP_LootItem) D(OP_MoveItem) D(OP_PetCommands) +D(OP_RaidInvite) D(OP_ReadBook) D(OP_SetServerFilter) D(OP_ShopPlayerSell) diff --git a/common/patches/titanium_structs.h b/common/patches/titanium_structs.h index 6093af656..15537013f 100644 --- a/common/patches/titanium_structs.h +++ b/common/patches/titanium_structs.h @@ -3017,23 +3017,39 @@ struct leadExpUpdateStruct { /*0028*/ uint32 unknown0028; }; - - struct RaidGeneral_Struct { -/*00*/ uint32 action; //=10 -/*04*/ char player_name[64]; //should both be the player's name -/*04*/ char leader_name[64]; +/*000*/ uint32 action; //=10 +/*004*/ char player_name[64]; //should both be the player's name +/*068*/ char leader_name[64]; /*132*/ uint32 parameter; }; -struct RaidAdd_Struct { -/*000*/ uint32 action; //=0 -/*004*/ char player_name[64]; //should both be the player's name -/*068*/ char leader_name[64]; -/*132*/ uint8 _class; -/*133*/ uint8 level; -/*134*/ uint8 has_group; -/*135*/ uint8 unknown135; //seems to be 0x42 or 0 +struct RaidAddMember_Struct { +/*000*/ RaidGeneral_Struct raidGen; +/*136*/ uint8 _class; +/*137*/ uint8 level; +/*138*/ uint8 isGroupLeader; +/*139*/ uint8 unknown139; //seems to be 0x42 or 0 +}; + +struct RaidNote_Struct { +/*000*/ RaidGeneral_Struct general; +/*136*/ char note[64]; +}; + +struct RaidMOTD_Struct { +/*000*/ RaidGeneral_Struct general; // leader_name and action only used +/*136*/ char motd[1024]; // max size is 1024, but reply is variable +}; + +struct RaidLeadershipUpdate_Struct { + /*000*/ uint32 action; + /*004*/ char player_name[64]; +// /*068*/ uint32 Unknown068; + /*072*/ char leader_name[64]; + /*136*/ GroupLeadershipAA_Struct group; //unneeded + /*200*/ RaidLeadershipAA_Struct raid; + /*264*/ char Unknown264[128]; }; struct RaidCreate_Struct { diff --git a/common/patches/uf.cpp b/common/patches/uf.cpp index b9197353e..a80c0eae9 100644 --- a/common/patches/uf.cpp +++ b/common/patches/uf.cpp @@ -35,6 +35,7 @@ #include "../path_manager.h" #include "../classes.h" #include "../races.h" +#include "../raid.h" #include #include @@ -1931,88 +1932,124 @@ namespace UF ENCODE(OP_RaidJoin) { - EQApplicationPacket *inapp = *p; - unsigned char * __emu_buffer = inapp->pBuffer; - RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer; + EQApplicationPacket* inapp = *p; + *p = nullptr; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer; - auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); - structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer; + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); + structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer; - general->action = 8; - general->parameter = 1; - strn0cpy(general->leader_name, raid_create->leader_name, 64); - strn0cpy(general->player_name, raid_create->leader_name, 64); + general->action = raidCreate; + general->parameter = RaidCommandAcceptInvite; + strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name)); + strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name)); + + dest->FastQueuePacket(&outapp); - dest->FastQueuePacket(&outapp_create); safe_delete(inapp); + } ENCODE(OP_RaidUpdate) { - EQApplicationPacket *inapp = *p; + EQApplicationPacket* inapp = *p; *p = nullptr; - unsigned char * __emu_buffer = inapp->pBuffer; - RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer; + unsigned char* __emu_buffer = inapp->pBuffer; + RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer; - if (raid_gen->action == 0) // raid add has longer length than other raid updates + switch (raid_gen->action) { - RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer; + case raidAdd: + { + RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct)); - structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer; + structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer; - add_member->raidGen.action = in_add_member->raidGen.action; - add_member->raidGen.parameter = in_add_member->raidGen.parameter; - strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64); - strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64); - add_member->_class = in_add_member->_class; - add_member->level = in_add_member->level; - add_member->isGroupLeader = in_add_member->isGroupLeader; - add_member->flags[0] = in_add_member->flags[0]; - add_member->flags[1] = in_add_member->flags[1]; - add_member->flags[2] = in_add_member->flags[2]; - add_member->flags[3] = in_add_member->flags[3]; - add_member->flags[4] = in_add_member->flags[4]; - dest->FastQueuePacket(&outapp); - } - else if (raid_gen->action == 35) - { - RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer; - auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) + - strlen(inmotd->motd) + 1); - structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer; + OUT(raidGen.action); + OUT(raidGen.parameter); + OUT_str(raidGen.leader_name); + OUT_str(raidGen.player_name); + OUT(_class); + OUT(level); + OUT(isGroupLeader); + OUT(flags[0]); + OUT(flags[1]); + OUT(flags[2]); + OUT(flags[3]); + OUT(flags[4]); - outmotd->general.action = inmotd->general.action; - strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64); - strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1); dest->FastQueuePacket(&outapp); + break; } - else if (raid_gen->action == 14 || raid_gen->action == 30) + case raidSetMotd: { - RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer; - auto outapp = - new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); - structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer; + RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct)); + structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.player_name); + OUT_str(general.leader_name); + OUT_str(motd); - outlaa->action = inlaa->action; - strn0cpy(outlaa->player_name, inlaa->player_name, 64); - strn0cpy(outlaa->leader_name, inlaa->leader_name, 64); - memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct)); dest->FastQueuePacket(&outapp); + break; } - else + case raidSetLeaderAbilities: + case raidMakeLeader: { - RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer; + RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct)); + structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer; + + OUT(action); + OUT_str(player_name); + OUT_str(leader_name); + memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct)); + + dest->FastQueuePacket(&outapp); + break; + } + case raidSetNote: + { + auto emu = (RaidNote_Struct*)__emu_buffer; + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct)); + auto eq = (structs::RaidNote_Struct*)outapp->pBuffer; + + OUT(general.action); + OUT_str(general.leader_name); + OUT_str(general.player_name); + OUT_str(note); + + dest->FastQueuePacket(&outapp); + break; + } + case raidNoRaid: + { + dest->QueuePacket(inapp); + break; + } + default: + { + RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer; auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct)); - structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer; - strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64); - strn0cpy(raid_general->player_name, in_raid_general->player_name, 64); - raid_general->action = in_raid_general->action; - raid_general->parameter = in_raid_general->parameter; - dest->FastQueuePacket(&outapp); - } + structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer; + OUT(action); + OUT(parameter); + OUT_str(leader_name); + OUT_str(player_name); + + dest->FastQueuePacket(&outapp); + break; + } + } safe_delete(inapp); } @@ -3637,39 +3674,48 @@ namespace UF { DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct); - // This is a switch on the RaidGeneral action - switch (*(uint32 *)__packet->pBuffer) { - case 35: { // raidMOTD - // we don't have a nice macro for this - structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer; - __eq_buffer->motd[1023] = '\0'; - size_t motd_size = strlen(__eq_buffer->motd) + 1; - __packet->size = sizeof(RaidMOTD_Struct) + motd_size; - __packet->pBuffer = new unsigned char[__packet->size]; - RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer; - structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer; - strn0cpy(emu->general.player_name, eq->general.player_name, 64); - strn0cpy(emu->motd, eq->motd, motd_size); - IN(general.action); - IN(general.parameter); - FINISH_DIRECT_DECODE(); - break; - } - case 36: { // raidPlayerNote unhandled - break; - } - default: { - DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct); - SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); - strn0cpy(emu->leader_name, eq->leader_name, 64); - strn0cpy(emu->player_name, eq->player_name, 64); - IN(action); - IN(parameter); - FINISH_DIRECT_DECODE(); - break; - } - } + RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer; + switch (rgs->action) + { + case raidSetMotd: + { + SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(motd); + + FINISH_VAR_DECODE(); + break; + } + case raidSetNote: + { + SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note); + + IN(general.action); + IN(general.parameter); + IN_str(general.leader_name); + IN_str(general.player_name); + IN_str(note); + + FINISH_VAR_DECODE(); + break; + } + default: + { + SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct); + IN(action); + IN(parameter); + IN_str(leader_name); + IN_str(player_name); + + FINISH_DIRECT_DECODE(); + break; + } + } } DECODE(OP_ReadBook) diff --git a/common/patches/uf_structs.h b/common/patches/uf_structs.h index e13f34d77..15c49ab26 100644 --- a/common/patches/uf_structs.h +++ b/common/patches/uf_structs.h @@ -3647,9 +3647,14 @@ struct RaidAddMember_Struct { /*139*/ uint8 flags[5]; //no idea if these are needed... }; +struct RaidNote_Struct { +/*000*/ RaidGeneral_Struct general; +/*140*/ char note[64]; +}; + struct RaidMOTD_Struct { -/*000*/ RaidGeneral_Struct general; // leader_name and action only used -/*140*/ char motd[0]; // max size 1024, but reply is variable +/*000*/ RaidGeneral_Struct general; +/*140*/ char motd[1024]; }; struct RaidLeadershipUpdate_Struct { diff --git a/common/raid.h b/common/raid.h new file mode 100644 index 000000000..605636fd4 --- /dev/null +++ b/common/raid.h @@ -0,0 +1,72 @@ +/* EQEMu: Everquest Server Emulator + Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org) + + 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 +*/ + +#ifndef RAID_H +#define RAID_H + +enum { //raid packet types: + raidAdd = 0, + raidRemove2 = 1, //parameter=0 + raidMemberNameChange = 2, + raidRemove1 = 3, //parameter=0xFFFFFFFF + raidNoLongerLeader = 4, + raidDisband = 5, + raidMembers = 6, //len 395+, details + members list + raidNoAssignLeadership = 7, + raidCreate = 8, //len 72 + raidUnknown = 9, // unused? + raidNoRaid = 10, //parameter=0 + raidChangeLootType = 11, + raidStringID = 12, + raidChangeGroupLeader = 13, //136 raid leader, new group leader, group_id? + raidSetLeaderAbilities = 14, //472 + raidSetLeaderData = 15, // 14,15 SoE names, not sure on difference, 14 packet has 0x100 bytes 15 0x214 in addition to raid general + raidChangeGroup = 16, //?? len 136 old leader, new leader, 0 (preceeded with a remove2) + raidLock = 17, //len 136 leader?, leader, 0 + raidUnlock = 18, //len 136 leader?, leader, 0 + raidRedStringID = 19, + raidSetLeader = 20, //len 388, contains 'details' struct without members; also used for "invite to raid" + raidMakeLeader = 30, + raidSetMotd = 35, + raidSetNote = 36, +}; + + +enum { //raid command types + RaidCommandInviteIntoExisting = 0, //in use + RaidCommandAcceptInvite = 1, //in use + RaidCommandInvite = 3, //in use + RaidCommandDisband = 5, //in use + RaidCommandMoveGroup = 6, //in use + RaidCommandRemoveGroupLeader = 7, + RaidCommandRaidLock = 8, //in use + RaidCommandRaidUnlock = 9, //in use + RaidCommandLootType = 20, //in use + RaidCommandAddLooter = 21, //in use + RaidCommandRemoveLooter = 22, //in use + RaidCommandMakeLeader = 30, + RaidCommandInviteFail = 31, //already in raid, waiting on invite from other raid, etc + RaidCommandLootType2 = 32, //in use + RaidCommandAddLooter2 = 33, //in use + RaidCommandRemoveLooter2 = 34, //in use + RaidCommandSetMotd = 35, + RaidCommandSetNote = 36, +}; + + +#endif diff --git a/common/servertalk.h b/common/servertalk.h index ce0427296..f27f2a46a 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -1077,7 +1077,7 @@ struct ServerRaidMessage_Struct { struct ServerRaidMOTD_Struct { uint32 rid; - char motd[0]; + char motd[1024]; }; struct ServerRaidNote_Struct { diff --git a/utils/patches/patch_Titanium.conf b/utils/patches/patch_Titanium.conf index e1f017c8a..d53063157 100644 --- a/utils/patches/patch_Titanium.conf +++ b/utils/patches/patch_Titanium.conf @@ -423,6 +423,8 @@ OP_CancelInvite=0x0000 OP_RaidJoin=0x1f21 # ShowEQ 10/27/05 OP_RaidInvite=0x5891 # ShowEQ 10/27/05 OP_RaidUpdate=0x1f21 # EQEmu 06/29/05 +OP_RaidDelegateAbility=0x56eb +OP_RaidClearNPCMarks=0x1794 OP_InspectBuffs=0x4FB6 diff --git a/utils/patches/patch_UF.conf b/utils/patches/patch_UF.conf index 75c4a1c5f..88e8ad654 100644 --- a/utils/patches/patch_UF.conf +++ b/utils/patches/patch_UF.conf @@ -534,6 +534,8 @@ OP_LFGResponse=0x0000 # OP_RaidInvite=0x60b5 # C OP_RaidUpdate=0x4d8b # C OP_RaidJoin=0x0000 # +OP_RaidDelegateAbility=0x0297 +OP_RaidClearNPCMarks=0x2af4 # Button-push commands OP_Taunt=0x30e2 # C diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 6ce650190..34937aa1d 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include "../common/global_define.h" #include "../common/eqemu_logsys.h" #include "../common/opcodemgr.h" +#include "../common/raid.h" + #include #include #include @@ -12578,8 +12580,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app) if (!raid) { break; } - - raid->SaveRaidNote(raid_command_packet->leader_name, raid_command_packet->note); + RaidNote_Struct* note = (RaidNote_Struct*)app->pBuffer; + raid->SaveRaidNote(raid_command_packet->leader_name, note->note); raid->SendRaidNotesToWorld(); break; } diff --git a/zone/raids.cpp b/zone/raids.cpp index 16a4a3f6c..42967abe9 100644 --- a/zone/raids.cpp +++ b/zone/raids.cpp @@ -20,6 +20,8 @@ #include "../common/events/player_event_logs.h" #include "../common/repositories/raid_details_repository.h" #include "../common/repositories/raid_members_repository.h" +#include "../common/raid.h" + #include "client.h" #include "entity.h" @@ -1547,21 +1549,22 @@ void Raid::SendRaidGroupRemove(const char *who, uint32 gid) void Raid::SendRaidMOTD(Client *c) { - if (!c || motd.empty()) { + if (!c || motd.empty() || c->IsBot()) { return; } - if (entity_list.GetBotByBotName(c->GetName())) { - return; - } + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidMOTD_Struct)); + auto data = (RaidMOTD_Struct*)outapp->pBuffer; - size_t size = motd.size() + 1; - auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidMOTD_Struct) + size); - auto rmotd = (RaidMOTD_Struct *)outapp->pBuffer; - rmotd->general.action = raidSetMotd; - strn0cpy(rmotd->general.player_name, c->GetName(), 64); - strn0cpy(rmotd->motd, motd.c_str(), size); - c->FastQueuePacket(&outapp); + data->general.action = raidSetMotd; + data->general.parameter = 0; + data->general.unknown1 = 0; + strn0cpy(data->general.leader_name, c->GetName(), sizeof(c->GetName())); + strn0cpy(data->general.player_name, GetLeaderName().c_str(), 64); + strn0cpy(data->motd, motd.c_str(), sizeof(data->motd)); + + c->QueuePacket(outapp); + safe_delete(outapp); } void Raid::SendRaidMOTD() @@ -1587,11 +1590,10 @@ void Raid::SendRaidMOTDToWorld() return; } - size_t size = motd.size() + 1; - auto pack = new ServerPacket(ServerOP_RaidMOTD, sizeof(ServerRaidMOTD_Struct) + size); + auto pack = new ServerPacket(ServerOP_RaidMOTD, sizeof(ServerRaidMOTD_Struct)); auto smotd = (ServerRaidMOTD_Struct *)pack->pBuffer; smotd->rid = GetID(); - strn0cpy(smotd->motd, motd.c_str(), size); + strn0cpy(smotd->motd, motd.c_str(), sizeof(smotd->motd)); worldserver.SendPacket(pack); safe_delete(pack); } @@ -1730,7 +1732,8 @@ bool Raid::LearnMembers() members[i].member = nullptr; strn0cpy(members[i].member_name, row[0], sizeof(members[i].member_name)); - strn0cpy(members[i].note, row[10], sizeof(members[i].note)); +// strn0cpy(members[i].note, row[10], sizeof(members[i].note)); + members[i].note = std::string(row[10]); uint32 group_id = Strings::ToUnsignedInt(row[1]); if (group_id >= MAX_RAID_GROUPS) { @@ -2275,7 +2278,7 @@ std::vector Raid::GetMembersWithNotes() { std::vector raid_members; for (const auto& m : members) { - if (strlen(m.note) != 0) { + if (!m.note.empty()) { raid_members.emplace_back(m); } } @@ -2288,12 +2291,17 @@ void Raid::SendRaidNotes() VerifyRaid(); for (const auto& c : GetMembersWithNotes()) { - auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct)); - auto note = (RaidGeneral_Struct*)outapp->pBuffer; - note->action = raidSetNote; - strn0cpy(note->leader_name, c.member_name, 64); - strn0cpy(note->player_name, GetLeaderName().c_str(), 64); - strn0cpy(note->note, c.note, 64); + + auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidNote_Struct)); + auto data = (RaidNote_Struct*)outapp->pBuffer; + + data->general.action = raidSetNote; + data->general.parameter = 0; + data->general.unknown1 = 0; + strn0cpy(data->general.leader_name, c.member_name, sizeof(c.member_name)); + strn0cpy(data->general.player_name, GetLeaderName().c_str(), GetLeaderName().length()); + strn0cpy(data->note, c.note.c_str(), sizeof(data->note)); + QueuePacket(outapp); safe_delete(outapp); } @@ -2552,7 +2560,7 @@ void Raid::UpdateXTargetType(XTargetType Type, Mob *m, const char *name) } if (name) { - strncpy(rm.member->XTargets[i].Name, name, 64); + strn0cpy(rm.member->XTargets[i].Name, name, 64); } rm.member->SendXTargetPacket(i, m); diff --git a/zone/raids.h b/zone/raids.h index 1c1dabc02..1c59a0184 100644 --- a/zone/raids.h +++ b/zone/raids.h @@ -27,55 +27,6 @@ class Client; class EQApplicationPacket; class Mob; -enum { //raid packet types: - raidAdd = 0, - raidRemove2 = 1, //parameter=0 - raidMemberNameChange = 2, - raidRemove1 = 3, //parameter=0xFFFFFFFF - raidNoLongerLeader = 4, - raidDisband = 5, - raidMembers = 6, //len 395+, details + members list - raidNoAssignLeadership = 7, - raidCreate = 8, //len 72 - raidUnknown = 9, // unused? - raidNoRaid = 10, //parameter=0 - raidChangeLootType = 11, - raidStringID = 12, - raidChangeGroupLeader = 13, //136 raid leader, new group leader, group_id? - raidSetLeaderAbilities = 14, //472 - raidSetLeaderData = 15, // 14,15 SoE names, not sure on difference, 14 packet has 0x100 bytes 15 0x214 in addition to raid general - raidChangeGroup = 16, //?? len 136 old leader, new leader, 0 (preceeded with a remove2) - raidLock = 17, //len 136 leader?, leader, 0 - raidUnlock = 18, //len 136 leader?, leader, 0 - raidRedStringID = 19, - raidSetLeader = 20, //len 388, contains 'details' struct without members; also used for "invite to raid" - raidMakeLeader = 30, - raidSetMotd = 35, - raidSetNote = 36, -}; - - -enum { //raid command types - RaidCommandInviteIntoExisting = 0, //in use - RaidCommandAcceptInvite = 1, //in use - RaidCommandInvite = 3, //in use - RaidCommandDisband = 5, //in use - RaidCommandMoveGroup = 6, //in use - RaidCommandRemoveGroupLeader = 7, - RaidCommandRaidLock = 8, //in use - RaidCommandRaidUnlock = 9, //in use - RaidCommandLootType = 20, //in use - RaidCommandAddLooter = 21, //in use - RaidCommandRemoveLooter = 22, //in use - RaidCommandMakeLeader = 30, - RaidCommandInviteFail = 31, //already in raid, waiting on invite from other raid, etc - RaidCommandLootType2 = 32, //in use - RaidCommandAddLooter2 = 33, //in use - RaidCommandRemoveLooter2 = 34, //in use - RaidCommandSetMotd = 35, - RaidCommandSetNote = 36, -}; - enum { FindNextMarkerSlot = 1, FindNextAssisterSlot = 2, @@ -129,7 +80,7 @@ struct RaidMember{ uint32 group_number; uint8 _class; uint8 level; - char note[64]; + std::string note; bool is_group_leader; bool is_raid_leader; bool is_looter;