// Copyright (C) 2007 EQ2EMulator Development Team, GPL v3+ #pragma once #include #include #include #include #include #include #include #include "data_struct.hpp" #include "../log.hpp" #include "../debug.hpp" #include "../data_buffer.hpp" #include "../config_reader.hpp" #include "../misc_functions.hpp" #include "../opcodes/opcode_manager.hpp" #ifdef WORLD #include "../../WorldServer/Items/Items.h" #include "../../WorldServer/Player.h" #include "../../WorldServer/World.h" class Item; class Player; #endif extern ConfigReader configReader; extern std::map EQOpcodeManager; class PacketStruct : public DataBuffer { public: // Default constructor - initializes empty packet structure PacketStruct() { parent = 0; opcode = OP_Unknown; opcode_type = std::string(""); } // Copy constructor from existing packet with sub-packet flag PacketStruct(PacketStruct* packet, bool sub) { std::vector::iterator itr2; for (itr2 = packet->structs.begin(); itr2 != packet->structs.end(); itr2++) { add(new DataStruct(*itr2)); } std::vector::iterator itr; for (itr = packet->flags.begin(); itr != packet->flags.end(); itr++) { AddFlag((*itr).c_str()); } sub_packet = sub; opcode = packet->opcode; version = packet->version; opcode_type = packet->opcode_type; name = packet->name; sub_packet_size = 0; parent = 0; } // Copy constructor with client version specification PacketStruct(PacketStruct* packet, int16 in_client_version) { parent = packet->parent; client_version = in_client_version; std::vector::iterator itr2; name = packet->name; for (itr2 = packet->structs.begin(); itr2 != packet->structs.end(); itr2++) { add(new DataStruct(*itr2)); } std::vector::iterator itr; for (itr = packet->flags.begin(); itr != packet->flags.end(); itr++) { AddFlag((*itr).c_str()); } sub_packet = false; opcode = packet->opcode; version = packet->version; opcode_type = packet->opcode_type; sub_packet_size = 1; addPacketArrays(packet); } // Destructor - cleans up all allocated data structures and arrays ~PacketStruct() { deleteDataStructs(&structs); deleteDataStructs(&orig_structs); deletePacketArrays(this); struct_map.clear(); struct_data.clear(); flags.clear(); } // Core packet management functions void add(DataStruct* data); void add(PacketStruct* packet_struct); void remove(DataStruct* data); void remove(const char* name); DataStruct* findStruct(const char* name, int32 index); DataStruct* findStruct(const char* name, int32 index1, int32 index2); // String manipulation functions void setSmallStringByName(const char* name, const char* text, int32 index = 0); void setMediumStringByName(const char* name, const char* text, int32 index = 0); void setLargeStringByName(const char* name, const char* text, int32 index = 0); void setSmallString(DataStruct* data_struct, const char* text, int32 index = 0); void setMediumString(DataStruct* data_struct, const char* text, int32 index = 0); void setLargeString(DataStruct* data_struct, const char* text, int32 index = 0); // Color manipulation functions void setColorByName(const char* name, int8 red, int8 green, int8 blue, int32 index = 0); void setColorByName(const char* name, EQ2_Color* data, int32 index = 0); void setColorByName(const char* name, EQ2_Color data, int32 index = 0); void setColor(DataStruct* data, int8 red, int8 green, int8 blue, int32 index = 0); void setColor(DataStruct* data_struct, EQ2_Color data, int32 index = 0); // Equipment manipulation functions void setEquipmentByName(const char* name, EQ2_EquipmentItem data, int32 index = 0); void setEquipmentByName(const char* name, EQ2_EquipmentItem* data, int32 size); void setEquipmentByName(const char* name, int32 type, int8 c_red, int8 c_blue, int8 c_green, int8 h_red, int8 h_blue, int8 h_green, int32 index = 0); void setEquipmentByName(DataStruct* data_struct, EQ2_EquipmentItem data, int32 index = 0); void setEquipment(DataStruct* data, int16 type, int8 c_red, int8 c_blue, int8 c_green, int8 h_red, int8 h_blue, int8 h_green, int32 index); // Array management functions void reAddAll(int32 length); void renameSubstructArray(const char* substruct, int32 index); int32 GetArraySize(DataStruct* data_struct, int32 index); int32 GetArraySize(const char* name, int32 index); int32 GetArraySizeByName(const char* name, int32 index); void UpdateArrayByArrayLength(DataStruct* data_struct, int32 index, int32 size); void UpdateArrayByArrayLengthName(const char* name, int32 index, int32 size); // Packet structure utility functions void setAddToPacketByName(const char* name, bool new_val, int32 index = 0); void setArrayAddToPacketByName(const char* name, bool new_val, int32 index1 = 0, int32 index2 = 0); void setAddTypePacketByName(const char* name, int8 new_val, int32 index = 0); // Type checking functions bool IsStringValueType(std::string in_name, int32 index); bool IsColorValueType(std::string in_name, int32 index); // Variable state functions bool GetVariableIsSet(const char* name); bool GetVariableIsNotSet(const char* name); // Flag management functions bool CheckFlagExists(const char* name); void AddFlag(const char* name); // Serialization functions void serializePacket(bool clear = true); std::string* serializeString(); EQ2Packet* serialize(); EQ2Packet* serializeCountPacket(int16 version, int8 offset = 0, uchar* orig_packet = 0, uchar* xor_packet = 0); void AddSerializedData(DataStruct* data, int32 index = 0, std::string* datastring = 0); // Data loading functions bool LoadPacketData(uchar* data, int32 data_len, bool create_color = false); bool StructLoadData(DataStruct* data_struct, void* data, int32 len, bool useType2 = false, bool create_color = false); void LoadFromPacketStruct(PacketStruct* packet, char* substruct_name = 0); // Opcode management functions bool SetOpcode(const char* new_opcode); int16 GetOpcodeValue(int16 client_version); const char* GetOpcodeType(); void SetOpcodeType(const char* opcodeType); // Utility accessor functions std::vector* getStructs() { return &structs; } int32 GetVersion() { return version; } void SetVersion(int32 in_version) { version = in_version; } EmuOpcode GetOpcode() { return opcode; } const char* GetName() { return name.c_str(); } void SetName(const char* in_name) { name = std::string(in_name); } bool LoadedSuccessfully() { return loadedSuccessfully; } bool IsSubPacket() { return sub_packet; } void IsSubPacket(bool new_val) { sub_packet = new_val; } int32 GetSubPacketSize() { return sub_packet_size; } void SetSubPacketSize(int32 new_size) { sub_packet_size = new_size; } int32 GetTotalPacketSize(); // Advanced functions PacketStruct* GetPacketStructByName(const char* name); void* GetStructPointer(DataStruct* data_struct, bool erase = false); std::vector GetDataStructs(); void PrintPacket(); #ifdef WORLD // World server specific functions void setItem(DataStruct* ds, Item* item, Player* player, int32 index, sint8 offset = 0, bool loot_item = false, bool make_empty_item_packet = false, bool inspect = false); void setItemByName(const char* name, Item* item, Player* player, int32 index = 0, sint8 offset = 0, bool loot_item = false, bool make_empty_item_packet = false, bool inspect = false); void setItemArrayDataByName(const char* name, Item* item, Player* player, int32 index1 = 0, int32 index2 = 0, sint8 offset = 0, bool loot_item = false, bool make_empty_item_packet = false, bool inspect = false); void ResetData(); #endif // Include data getter/setter template functions #include "packet_struct_data.hpp" private: // Memory management functions void deleteDataStructs(std::vector* data_structs); void deletePacketArrays(PacketStruct* packet); void addPacketArrays(PacketStruct* packet); // Core data setting functions void setDataType(DataStruct* data_struct, char data, int32 index); void setDataType(DataStruct* data_struct, int8 data, int32 index); void setDataType(DataStruct* data_struct, int16 data, int32 index); void setDataType(DataStruct* data_struct, int32 data, int32 index); void setDataType(DataStruct* data_struct, int64 data, int32 index); void setDataType(DataStruct* data_struct, sint8 data, int32 index); void setDataType(DataStruct* data_struct, sint16 data, int32 index); void setDataType(DataStruct* data_struct, sint32 data, int32 index); void setDataType(DataStruct* data_struct, sint64 data, int32 index); void setDataType(DataStruct* data_struct, float data, int32 index); void setDataType(DataStruct* data_struct, double data, int32 index); void setData(DataStruct* data_struct, EQ2_8BitString* input_string, int32 index, bool use_second_type = false); void setData(DataStruct* data_struct, EQ2_16BitString* input_string, int32 index, bool use_second_type = false); void setData(DataStruct* data_struct, EQ2_32BitString* input_string, int32 index, bool use_second_type = false); // Member variables PacketStruct* parent; // Parent packet structure for sub-packets int32 sub_packet_size; // Size of sub-packet array std::string opcode_type; // String representation of opcode type bool sub_packet; // Whether this is a sub-packet bool loadedSuccessfully; // Whether data loaded successfully std::string name; // Name of this packet structure EmuOpcode opcode; // Opcode enumeration value int16 version; // Packet structure version int16 client_version; // Client version for compatibility std::vector arrays; // Sub-packet arrays std::vector flags; // Packet flags std::map struct_data; // Data structure to memory mapping std::map packed_data; // Packed data storage std::map struct_map; // Name to data structure mapping std::vector structs; // Main data structures std::vector orig_structs; // Original structures for reAddAll std::vector orig_packets; // Original packets for reAddAll };