244 lines
10 KiB
C++
244 lines
10 KiB
C++
// Copyright (C) 2007 EQ2EMulator Development Team, GPL v3+
|
|
|
|
#pragma once
|
|
|
|
#include <iostream>
|
|
#include <exception>
|
|
#include <vector>
|
|
#include <map>
|
|
#include <string>
|
|
#include <cstring>
|
|
#include <cstdio>
|
|
|
|
#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<int16, OpcodeManager*> 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<DataStruct*>::iterator itr2;
|
|
|
|
for (itr2 = packet->structs.begin(); itr2 != packet->structs.end(); itr2++) {
|
|
add(new DataStruct(*itr2));
|
|
}
|
|
std::vector<std::string>::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<DataStruct*>::iterator itr2;
|
|
name = packet->name;
|
|
|
|
for (itr2 = packet->structs.begin(); itr2 != packet->structs.end(); itr2++) {
|
|
add(new DataStruct(*itr2));
|
|
}
|
|
std::vector<std::string>::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<DataStruct*>* 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<DataStruct*> 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<DataStruct*>* 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<PacketStruct*> arrays; // Sub-packet arrays
|
|
std::vector<std::string> flags; // Packet flags
|
|
std::map<DataStruct*, void*> struct_data; // Data structure to memory mapping
|
|
std::map<int8, std::string> packed_data; // Packed data storage
|
|
std::map<std::string, DataStruct*> struct_map; // Name to data structure mapping
|
|
std::vector<DataStruct*> structs; // Main data structures
|
|
std::vector<DataStruct*> orig_structs; // Original structures for reAddAll
|
|
std::vector<PacketStruct*> orig_packets; // Original packets for reAddAll
|
|
}; |