diff --git a/buffer.h b/buffer.h new file mode 100644 index 000000000..652dcbb6a --- /dev/null +++ b/buffer.h @@ -0,0 +1,37 @@ +#ifndef BUFFER_H +#define BUFFER_H + +#include +#include + +inline void buffer_read_block(unsigned char*& p, void* dest, size_t size) { + std::memcpy(dest, p, size); + p += size; +} +template +inline T buffer_read(unsigned char*& p) { + T ret{}; + buffer_read_block(p, &ret, sizeof(T)); + return ret; +} + +inline void buffer_write_block(unsigned char*& p, const void* src, size_t size) { + std::memcpy(p, src, size); + p += size; +} +template +inline void buffer_write(unsigned char*& p, T value) { + buffer_write_block(p, &value,sizeof(T)); +} + +inline void vector_write_block(std::vector& buffer, const void* src, size_t size) { + const auto len = buffer.size(); + buffer.resize(len + size); + std::memcpy(&buffer[len], src, size); +} +template +inline void vector_write(std::vector& buffer, T value) { + vector_write_block(buffer, &value, sizeof(T)); +} + +#endif //BUFFER_H diff --git a/card.cpp b/card.cpp index 05ad398da..6c5111593 100644 --- a/card.cpp +++ b/card.cpp @@ -12,6 +12,7 @@ #include "group.h" #include "interpreter.h" #include "ocgapi.h" +#include "buffer.h" #include const std::unordered_map card::second_code = { @@ -176,17 +177,16 @@ card::card(duel* pd) { xyz_materials_previous_count_onfield = 0; current.controler = PLAYER_NONE; } -inline void update_cache(uint32& tdata, uint32& cache, int32*& p, uint32& query_flag, const uint32 flag) { +inline void update_cache(uint32& tdata, uint32& cache, byte*& p, uint32& query_flag, const uint32 flag) { if (tdata != cache) { cache = tdata; - *p = tdata; - ++p; + buffer_write(p, tdata); } else query_flag &= ~flag; } int32 card::get_infos(byte* buf, uint32 query_flag, int32 use_cache) { - int32* p = (int32*)buf; + byte* p = buf; std::pair atk_def(-10, -10); std::pair base_atk_def(-10, -10); if ((query_flag & QUERY_ATTACK) || (query_flag & QUERY_DEFENSE)) { @@ -196,15 +196,13 @@ int32 card::get_infos(byte* buf, uint32 query_flag, int32 use_cache) { base_atk_def = get_base_atk_def(); } //first 8 bytes: data length, query flag - p += 2; + p += 8; if (query_flag & QUERY_CODE) { - *p = data.code; - ++p; + buffer_write(p, data.code); } if (query_flag & QUERY_POSITION) { uint32 tdata = get_info_location(); - *p = tdata; - ++p; + buffer_write(p, tdata); if (q_cache.info_location != tdata) { q_cache.clear_cache(); q_cache.info_location = tdata; @@ -213,59 +211,54 @@ int32 card::get_infos(byte* buf, uint32 query_flag, int32 use_cache) { } if(!use_cache) { if (query_flag & QUERY_ALIAS) { - *p = get_code(); - q_cache.current_code = *p; - ++p; + uint32 tdata = get_code(); + buffer_write(p, tdata); + q_cache.current_code = tdata; } if (query_flag & QUERY_TYPE) { - *p = get_type(); - q_cache.type = *p; - ++p; + uint32 tdata = get_type(); + buffer_write(p, tdata); + q_cache.type = tdata; } if (query_flag & QUERY_LEVEL) { - *p = get_level(); - q_cache.level = *p; - ++p; + uint32 tdata = get_level(); + buffer_write(p, tdata); + q_cache.level = tdata; } if (query_flag & QUERY_RANK) { - *p = get_rank(); - q_cache.rank = *p; - ++p; + uint32 tdata = get_rank(); + buffer_write(p, tdata); + q_cache.rank = tdata; } if (query_flag & QUERY_ATTRIBUTE) { - *p = get_attribute(); - q_cache.attribute = *p; - ++p; + uint32 tdata = get_attribute(); + buffer_write(p, tdata); + q_cache.attribute = tdata; } if (query_flag & QUERY_RACE) { - *p = get_race(); - q_cache.race = *p; - ++p; + uint32 tdata = get_race(); + buffer_write(p, tdata); + q_cache.race = tdata; } if (query_flag & QUERY_ATTACK) { - *p = atk_def.first; + buffer_write(p, atk_def.first); q_cache.attack = atk_def.first; - ++p; } if (query_flag & QUERY_DEFENSE) { - *p = atk_def.second; + buffer_write(p, atk_def.second); q_cache.defense = atk_def.second; - ++p; } if (query_flag & QUERY_BASE_ATTACK) { - *p = base_atk_def.first; + buffer_write(p, base_atk_def.first); q_cache.base_attack = base_atk_def.first; - ++p; } if (query_flag & QUERY_BASE_DEFENSE) { - *p = base_atk_def.second; + buffer_write(p, base_atk_def.second); q_cache.base_defense = base_atk_def.second; - ++p; } if (query_flag & QUERY_REASON) { - *p = current.reason; + buffer_write(p, current.reason); q_cache.reason = current.reason; - ++p; } } else { @@ -296,8 +289,7 @@ int32 card::get_infos(byte* buf, uint32 query_flag, int32 use_cache) { if((query_flag & QUERY_ATTACK)) { if (atk_def.first != q_cache.attack) { q_cache.attack = atk_def.first; - *p = atk_def.first; - ++p; + buffer_write(p, atk_def.first); } else query_flag &= ~QUERY_ATTACK; @@ -305,8 +297,7 @@ int32 card::get_infos(byte* buf, uint32 query_flag, int32 use_cache) { if((query_flag & QUERY_DEFENSE)) { if (atk_def.second != q_cache.defense) { q_cache.defense = atk_def.second; - *p = atk_def.second; - ++p; + buffer_write(p, atk_def.second); } else query_flag &= ~QUERY_DEFENSE; @@ -314,8 +305,7 @@ int32 card::get_infos(byte* buf, uint32 query_flag, int32 use_cache) { if((query_flag & QUERY_BASE_ATTACK)) { if (base_atk_def.first != q_cache.base_attack) { q_cache.base_attack = base_atk_def.first; - *p = base_atk_def.first; - ++p; + buffer_write(p, base_atk_def.first); } else query_flag &= ~QUERY_BASE_ATTACK; @@ -323,8 +313,7 @@ int32 card::get_infos(byte* buf, uint32 query_flag, int32 use_cache) { if((query_flag & QUERY_BASE_DEFENSE)) { if (base_atk_def.second != q_cache.base_defense) { q_cache.base_defense = base_atk_def.second; - *p = base_atk_def.second; - ++p; + buffer_write(p, base_atk_def.second); } else query_flag &= ~QUERY_BASE_DEFENSE; @@ -335,73 +324,68 @@ int32 card::get_infos(byte* buf, uint32 query_flag, int32 use_cache) { } } if (query_flag & QUERY_REASON_CARD) { - *p = current.reason_card ? current.reason_card->get_info_location() : 0; - ++p; + uint32 tdata = current.reason_card ? current.reason_card->get_info_location() : 0; + buffer_write(p, tdata); } if(query_flag & QUERY_EQUIP_CARD) { if (equiping_target) { - *p = equiping_target->get_info_location(); - ++p; + uint32 tdata = equiping_target->get_info_location(); + buffer_write(p, tdata); } else query_flag &= ~QUERY_EQUIP_CARD; } if(query_flag & QUERY_TARGET_CARD) { - *p = (int32)effect_target_cards.size(); - ++p; + buffer_write(p, (int32_t)effect_target_cards.size()); for (auto& pcard : effect_target_cards) { - *p = pcard->get_info_location(); - ++p; + uint32 tdata = pcard->get_info_location(); + buffer_write(p, tdata); } } if(query_flag & QUERY_OVERLAY_CARD) { - *p = (int32)xyz_materials.size(); - ++p; + buffer_write(p, (int32_t)xyz_materials.size()); for (auto& xcard : xyz_materials) { - *p = xcard->data.code; - ++p; + buffer_write(p, xcard->data.code); } } if(query_flag & QUERY_COUNTERS) { - *p = (int32)counters.size(); - ++p; + buffer_write(p, (int32_t)counters.size()); for (const auto& cmit : counters) { - *p = cmit.first + ((cmit.second[0] + cmit.second[1]) << 16); - ++p; + int32 tdata = cmit.first + ((cmit.second[0] + cmit.second[1]) << 16); + buffer_write(p, tdata); } } if (query_flag & QUERY_OWNER) { - *p = owner; - ++p; + int32 tdata = owner; + buffer_write(p, tdata); } if(query_flag & QUERY_STATUS) { uint32 tdata = status & (STATUS_DISABLED | STATUS_FORBIDDEN | STATUS_PROC_COMPLETE); if(!use_cache || (tdata != q_cache.status)) { q_cache.status = tdata; - *p = tdata; - ++p; + buffer_write(p, tdata); } else query_flag &= ~QUERY_STATUS; } if(!use_cache) { if (query_flag & QUERY_LSCALE) { - *p = get_lscale(); - q_cache.lscale = *p; - ++p; + uint32 tdata = get_lscale(); + buffer_write(p, tdata); + q_cache.lscale = tdata; } if (query_flag & QUERY_RSCALE) { - *p = get_rscale(); - q_cache.rscale = *p; - ++p; + uint32 tdata = get_rscale(); + buffer_write(p, tdata); + q_cache.rscale = tdata; } if(query_flag & QUERY_LINK) { - *p = get_link(); - q_cache.link = *p; - ++p; - *p = get_link_marker(); - q_cache.link_marker = *p; - ++p; + uint32 tdata = get_link(); + buffer_write(p, tdata); + q_cache.link = tdata; + tdata = get_link_marker(); + buffer_write(p, tdata); + q_cache.link_marker = tdata; } } else { @@ -418,22 +402,18 @@ int32 card::get_infos(byte* buf, uint32 query_flag, int32 use_cache) { uint32 link_marker = get_link_marker(); if((link != q_cache.link) || (link_marker != q_cache.link_marker)) { q_cache.link = link; - *p = (int32)link; - ++p; + buffer_write(p, link); q_cache.link_marker = link_marker; - *p = (int32)link_marker; - ++p; + buffer_write(p, link_marker); } else query_flag &= ~QUERY_LINK; } } - int32* finalize = (int32*)buf; - *finalize = (byte*)p - buf; - ++finalize; - *finalize = query_flag; - ++finalize; - return (byte*)p - buf; + byte* finalize = buf; + buffer_write(finalize, p - buf); + buffer_write(finalize, query_flag); + return (int32)(p - buf); } uint32 card::get_info_location() { if(overlay_target) { diff --git a/duel.cpp b/duel.cpp index b2b91a5ee..2b967d072 100644 --- a/duel.cpp +++ b/duel.cpp @@ -13,14 +13,7 @@ #include "effect.h" #include "group.h" #include "ocgapi.h" - -inline void write_buffer_vector(std::vector& buffer, const void* data, int size) { - if (size > 0) { - const auto len = buffer.size(); - buffer.resize(len + size); - std::memcpy(&buffer[len], data, size); - } -} +#include "buffer.h" duel::duel() { lua = new interpreter(this); @@ -125,16 +118,16 @@ void duel::restore_assumes() { assumes.clear(); } void duel::write_buffer(const void* data, int size) { - write_buffer_vector(message_buffer, data, size); + vector_write_block(message_buffer, data, size); } void duel::write_buffer32(uint32 value) { - write_buffer(&value, sizeof(value)); + vector_write(message_buffer, value); } void duel::write_buffer16(uint16 value) { - write_buffer(&value, sizeof(value)); + vector_write(message_buffer, value); } void duel::write_buffer8(uint8 value) { - write_buffer(&value, sizeof(value)); + vector_write(message_buffer, value); } void duel::clear_buffer() { message_buffer.clear(); diff --git a/ocgapi.cpp b/ocgapi.cpp index 8a794ff4c..7295d8368 100644 --- a/ocgapi.cpp +++ b/ocgapi.cpp @@ -13,6 +13,7 @@ #include "effect.h" #include "field.h" #include "interpreter.h" +#include "buffer.h" #include static script_reader sreader = default_script_reader; @@ -206,7 +207,7 @@ extern "C" DECL_DLLEXPORT int32 query_card(intptr_t pduel, uint8 playerid, uint8 return pcard->get_infos(buf, query_flag, use_cache); } else { - *((int32*)buf) = LEN_EMPTY; + buffer_write(buf, LEN_EMPTY); return LEN_EMPTY; } } @@ -253,8 +254,7 @@ extern "C" DECL_DLLEXPORT int32 query_field_card(intptr_t pduel, uint8 playerid, int32 clen = pcard->get_infos(p, query_flag, use_cache); p += clen; } else { - *((int32*)p) = LEN_EMPTY; - p += LEN_EMPTY; + buffer_write(p, LEN_EMPTY); } } } @@ -264,8 +264,7 @@ extern "C" DECL_DLLEXPORT int32 query_field_card(intptr_t pduel, uint8 playerid, int32 clen = pcard->get_infos(p, query_flag, use_cache); p += clen; } else { - *((int32*)p) = LEN_EMPTY; - p += LEN_EMPTY; + buffer_write(p, LEN_EMPTY); } } } @@ -297,8 +296,7 @@ extern "C" DECL_DLLEXPORT int32 query_field_info(intptr_t pduel, byte* buf) { *p++ = ptduel->game_field->core.duel_rule; for(int playerid = 0; playerid < 2; ++playerid) { auto& player = ptduel->game_field->player[playerid]; - *((int*)p) = player.lp; - p += 4; + buffer_write(p, player.lp); for(auto& pcard : player.list_mzone) { if(pcard) { *p++ = 1; @@ -326,15 +324,12 @@ extern "C" DECL_DLLEXPORT int32 query_field_info(intptr_t pduel, byte* buf) { *p++ = (uint8)ptduel->game_field->core.current_chain.size(); for(const auto& ch : ptduel->game_field->core.current_chain) { effect* peffect = ch.triggering_effect; - *((int*)p) = peffect->get_handler()->data.code; - p += 4; - *((int*)p) = peffect->get_handler()->get_info_location(); - p += 4; + buffer_write(p, peffect->get_handler()->data.code); + buffer_write(p, peffect->get_handler()->get_info_location()); *p++ = ch.triggering_controler; *p++ = (uint8)ch.triggering_location; *p++ = ch.triggering_sequence; - *((int*)p) = peffect->description; - p += 4; + buffer_write(p, peffect->description); } return (int32)(p - buf); }