Initial commit

This commit is contained in:
Hash Borgir
2024-04-16 21:45:38 -06:00
commit 3159020c38
533 changed files with 135446 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
#pragma once
#include <cstdint>
#include <fw/singleton.h>
#include <diablo2/d2win.h>
#include <string>
#include <vector>
#include <diablo2/structures/gfxdata.h>
// Define the structure to hold stat information
struct StatEntry {
std::wstring stat_display_string;
diablo2::ui_color_t colorStat, colorStatValue;
int x1, y1, x2, y2, is_item_stat, item_type_id, stat = 0; // x1,y1 stat_display_string | x2,y2 statValue
};
extern std::vector<StatEntry> globalStatsVector; // Declaration of the global variable
extern diablo2::structures::gfxdata g_gfxdata; // global gfxdata
extern int randStat;
extern int randStatRangeLow;
extern int randStatRangeHigh;
extern int randStatBool;
namespace diablo2 {
namespace structures {
struct unit;
}
}
namespace d2_tweaks {
namespace common {
struct packet_header;
enum packet_types_cs_t;
enum message_types_t;
}
namespace client {
namespace modules {
class client_module;
}
class client : public singleton<client> {
uint8_t m_module_id_counter;
uint8_t m_tick_handler_id_counter;
modules::client_module* m_modules[0xFF]{ nullptr }; //max 255 modules atm.
modules::client_module* m_tick_handlers[0xFF]{ nullptr }; //max 255 handlers
modules::client_module* m_packet_handlers[0xFF]{ nullptr }; //max 255 handlers because of one-byte packet header
modules::client_module* m_packet_cs_handlers[0xFF]{ nullptr }; //max 255 handlers because of one-byte packet header
public:
explicit client(token);
void init();
void register_module(modules::client_module* module);
void register_tick_handler(modules::client_module* module);
void register_packet_handler(common::message_types_t type, modules::client_module* module);
void register_packet_cs_handler(common::packet_types_cs_t packet, common::message_types_t type, modules::client_module* module);
static diablo2::structures::unit* get_client_unit(uint32_t type, uint32_t guid);
private:
//static void __fastcall game_loop_start();
static void __fastcall handle_standart_packet(common::packet_header* packet, size_t size);
static void __fastcall handle_cs_packet(common::packet_header* packet, size_t size);
static void __fastcall handle_packet(common::packet_header* packet, size_t size);
static void __fastcall game_tick();
static int32_t __stdcall draw_game_ui();
};
}
}

View File

@@ -0,0 +1,23 @@
#pragma once
#include <d2tweaks/client/modules/client_module.h>
namespace d2_tweaks {
namespace ui {
namespace controls {
class label;
}
}
namespace client {
namespace modules {
class auto_gold_pickup final : public client_module {
public:
void init() override;
void init_early() override;
void handle_packet(common::packet_header* packet) override;
void tick() override;
};
}
}
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include <d2tweaks/client/modules/client_module.h>
namespace d2_tweaks {
namespace client {
namespace modules {
class auto_item_pickup final : public client_module {
public:
void init() override;
void init_early() override;
void handle_packet(common::packet_header* packet) override;
void tick() override;
};
}
}
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include <d2tweaks/client/modules/client_module.h>
//Inventory auto sort module client side
namespace d2_tweaks {
namespace client {
namespace modules {
class autosort final : public client_module {
public:
void init() override;
void init_early() override;
void handle_packet(common::packet_header* packet) override;
};
}
}
}

View File

@@ -0,0 +1,28 @@
#pragma once
#include <cstdint>
#define MODULE_INIT(module_name) static d2_tweaks::client::modules::module_name g_instance;
namespace d2_tweaks {
namespace common {
struct packet_header;
}
namespace client {
namespace modules {
class client_module {
public:
virtual ~client_module() = default;
client_module();
virtual void init() = 0;
virtual void init_early() = 0;
virtual void draw_ui();
virtual void tick();
virtual void handle_packet(common::packet_header* packet);
virtual void handle_cs_packet(common::packet_header* packet);
};
}
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include <d2tweaks/client/modules/client_module.h>
//Display damage client side
namespace d2_tweaks {
namespace client {
namespace modules {
class damage_display final : public client_module {
public:
void init() override;
void init_early() override;
void handle_packet(common::packet_header* packet) override;
void tick() override;
};
}
}
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include <d2tweaks/client/modules/client_module.h>
namespace d2_tweaks {
namespace client {
namespace modules {
class item_drop_message final : public client_module {
public:
void init() override;
void init_early() override;
void handle_packet(common::packet_header* packet) override;
static void GamePacketReceivedInterceptASM();
static void __fastcall GamePacketReceivedIntercept(uint8_t* packet, size_t size);
};
}
}
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include <d2tweaks/client/modules/client_module.h>
//Item moving between inventory pages (cube, inventory and stash) by ctrl+click client side
namespace d2_tweaks {
namespace client {
namespace modules {
class item_move final : public client_module {
public:
void init() override;
void init_early() override;
void handle_packet(common::packet_header* packet) override;
};
}
}
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include <d2tweaks/client/modules/client_module.h>
namespace d2_tweaks {
namespace client {
namespace modules {
class loot_filter final : public client_module {
public:
void init() override;
void init_early() override;
};
}
}
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include <diablo2/structures/item_data.h>
#include <cstring>
namespace d2_tweaks {
namespace client {
namespace modules {
struct loot_filter_settings {
size_t size; //struct size
bool alt_only;
bool show_gold;
bool show_runes;
bool show_gems;
bool quality_settings[static_cast<size_t>(diablo2::structures::item_quality_t::ITEM_QUALITY_COUNT)];
char reserved[1004];
static loot_filter_settings& get();
static void save(const char* name);
static void load(const char* name);
static void remove(const char* name);
private:
loot_filter_settings() : size(sizeof(loot_filter_settings)),
alt_only(false), show_gold(true), show_runes(true), show_gems(true), reserved{}
{
memset(quality_settings, 0x1, sizeof quality_settings);
}
};
}
}
}

View File

@@ -0,0 +1,67 @@
#pragma once
#include <fw/singleton.h>
#include <d2tweaks/ui/menu.h>
namespace diablo2 {
namespace structures {
struct unit;
enum class item_quality_t : unsigned;
}
}
namespace d2_tweaks {
namespace ui {
namespace controls {
class checkbox;
}
}
namespace client {
namespace modules {
class loot_filter_settings_menu final : public ui::menu, singleton<loot_filter_settings_menu> {
ui::controls::checkbox* m_altonly;
ui::controls::checkbox* m_show_gold;
ui::controls::checkbox* m_show_runes;
ui::controls::checkbox* m_show_gems;
void(__fastcall* m_draw_dropped_items_names_original)(void*, void*);
void(__fastcall* m_handle_dropped_items_original)(void*, void*);
public:
explicit loot_filter_settings_menu(token);
void reload_settings();
void draw() override;
private:
void register_misc_checkboxes();
void register_quality_checkboxes();
void update_alt_only(bool value);
void update_show_gold(bool value);
void update_show_runes(bool value);
void update_show_gems(bool value);
void update_quality_allowance(bool value, diablo2::structures::item_quality_t quality);
void register_quality_checkbox(const std::string& name, diablo2::structures::item_quality_t quality);
void setup_hooks();
void setup_alt_hook() const;
static bool is_gold(diablo2::structures::unit* item);
static bool is_rune(diablo2::structures::unit* item);
static bool is_gem(diablo2::structures::unit* item);
static bool __fastcall check_alt_item(diablo2::structures::unit* unit);
//draw labels over dropped items
static void __fastcall draw_dropped_items_names(diablo2::structures::unit* unit, void* edx);
//handle hovering over item and actual click
static void __fastcall handle_dropped_items(diablo2::structures::unit* unit, void* edx);
};
}
}
}

View File

@@ -0,0 +1,32 @@
#pragma once
#include <fw/singleton.h>
#include <d2tweaks/ui/menu.h>
namespace d2_tweaks {
namespace ui {
namespace controls {
class button;
}
}
}
namespace d2_tweaks {
namespace client {
namespace modules {
class loot_filter_settings_toggle_menu final : public ui::menu, singleton<loot_filter_settings_toggle_menu> {
ui::controls::button* m_toggle_filter_settings_btn;
menu* m_filter_settings_menu;
bool m_show;
public:
explicit loot_filter_settings_toggle_menu(token);
void toggle_filter_settings_click();
void draw() override;
bool key_event(uint32_t key, bool up) override;
};
}
}
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include <d2tweaks/client/modules/client_module.h>
//Client side patches that are too small to implement as separate modules
namespace d2_tweaks {
namespace client {
namespace modules {
class small_patches final : public client_module {
public:
void init() override;
void init_early() override;
};
}
}
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include <d2tweaks/client/modules/client_module.h>
//Test client side module
namespace d2_tweaks {
namespace client {
namespace modules {
class test final : public client_module {
public:
void init() override;
void init_early() override;
void handle_packet(common::packet_header* packet) override;
};
}
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include <cstdint>
#include <d2tweaks/client/modules/client_module.h>
namespace d2_tweaks {
namespace client {
namespace modules {
class trader_update final : public client_module {
public:
void init() override;
void init_early() override;
void handle_packet(common::packet_header* packet) override;
void handle_cs_packet(common::packet_header* packet) override;
void tick() override;
};
}
}
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include <cstdint>
#include <d2tweaks/client/modules/client_module.h>
namespace d2_tweaks {
namespace client {
namespace modules {
class transmute final : public client_module {
public:
void init() override;
void init_early() override;
void handle_packet(common::packet_header* packet) override;
void tick() override;
};
}
}
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include <string>
namespace d2_tweaks {
namespace common {
enum mpq_file_type_t;
class asset final {
std::string m_path;
void* m_asset;
mpq_file_type_t m_type;
public:
explicit asset(const std::string& path, void* asset, mpq_file_type_t type) : m_path(path), m_asset(asset), m_type(type) {}
const std::string& get_path() const {
return m_path;
}
void* get() const {
return m_asset;
}
mpq_file_type_t get_type() const {
return m_type;
}
void update(void* asset) {
m_asset = asset;
}
};
}
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include <fw/singleton.h>
#include <functional>
#include <string>
#include <unordered_map>
namespace d2_tweaks {
namespace common {
class asset;
enum mpq_file_type_t {
MPQ_FILE_TYPE_UNKNOWN = -1,
MPQ_FILE_TYPE_DC6 = 0,
MPQ_FILE_TYPE_DCC = 1,
MPQ_FILE_TYPE_COUNT
};
class asset_manager : public singleton<asset_manager> {
std::unordered_map<std::string, asset*> m_assets;
public:
explicit asset_manager(token);
void init();
asset* get_mpq_file(const std::string& path, mpq_file_type_t type);
private:
void* load_asset_data(const std::string& path, mpq_file_type_t type);
static int32_t __stdcall reload();
};
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include <fw/singleton.h>
namespace d2_tweaks {
namespace common {
struct packet_header;
class common : public singleton<common> {
public:
explicit common(token);
void init();
bool get_packet_size_cs(packet_header* packet, size_t& size);
bool get_packet_size_sc(packet_header* packet, size_t& size);
};
}
}

View File

@@ -0,0 +1,391 @@
#pragma once
#include <cstdint>
namespace d2_tweaks {
namespace common {
#pragma pack(push,1)
#define MAX_MSG_SIZE = 0x204
enum packet_types_cs_t {
PACKET_0x00,
PACKET_0x01,
PACKET_0x02,
PACKET_0x03,
PACKET_0x04,
PACKET_0x05,
PACKET_0x06,
PACKET_0x07,
PACKET_0x08,
PACKET_0x09,
PACKET_0x0A,
PACKET_0x0B,
PACKET_0x0C,
PACKET_0x0D,
PACKET_0x0E,
PACKET_0x0F,
PACKET_0x10,
PACKET_0x11,
PACKET_0x12,
PACKET_0x13,
PACKET_0x14,
PACKET_0x15,
PACKET_0x16,
PACKET_0x17,
PACKET_0x18,
PACKET_0x19,
PACKET_0x1A,
PACKET_0x1B,
PACKET_0x1C,
PACKET_0x1D,
PACKET_0x1E,
PACKET_0x1F,
PACKET_0x20,
PACKET_0x21,
PACKET_0x22,
PACKET_0x23,
PACKET_0x24,
PACKET_0x25,
PACKET_0x26,
PACKET_0x27,
PACKET_0x28,
PACKET_0x29,
PACKET_0x2A,
PACKET_0x2B,
PACKET_0x2C,
PACKET_0x2D,
PACKET_0x2E,
PACKET_0x2F,
PACKET_0x30,
PACKET_0x31,
PACKET_0x32,
PACKET_0x33,
PACKET_0x34,
PACKET_0x35,
PACKET_0x36,
PACKET_0x37,
PACKET_0x38,
PACKET_0x39,
PACKET_0x3A,
PACKET_0x3B,
PACKET_0x3C,
PACKET_0x3D,
PACKET_0x3E,
PACKET_0x3F,
PACKET_0x40,
PACKET_0x41,
PACKET_0x42,
PACKET_0x43,
PACKET_0x44,
PACKET_0x45,
PACKET_0x46,
PACKET_0x47,
PACKET_0x48,
PACKET_0x49,
PACKET_0x4A,
PACKET_0x4B,
PACKET_0x4C,
PACKET_0x4D,
PACKET_0x4E,
PACKET_0x4F,
PACKET_0x50,
PACKET_0x51,
PACKET_0x52,
PACKET_0x53,
PACKET_0x54,
PACKET_0x55,
PACKET_0x56,
PACKET_0x57,
PACKET_0x58,
PACKET_0x59,
PACKET_0x5A,
PACKET_0x5B,
PACKET_0x5C,
PACKET_0x5D,
PACKET_0x5E,
PACKET_0x5F,
PACKET_0x60,
PACKET_0x61,
PACKET_0x62,
PACKET_0x63,
PACKET_0x64,
PACKET_0x65,
PACKET_0x66,
PACKET_0x67,
PACKET_0x68,
PACKET_0x69,
PACKET_0x6A,
PACKET_0x6B,
PACKET_0x6C,
PACKET_0x6D,
PACKET_0x6E,
PACKET_0x6F,
PACKET_0x70,
PACKET_0x71,
PACKET_0x72,
PACKET_0x73,
PACKET_0x74,
PACKET_0x75,
PACKET_0x76,
PACKET_0x77,
PACKET_0x78,
PACKET_0x79,
PACKET_0x7A,
PACKET_0x7B,
PACKET_0x7C,
PACKET_0x7D,
PACKET_0x7E,
PACKET_0x7F,
PACKET_0x80,
PACKET_0x81,
PACKET_0x82,
PACKET_0x83,
PACKET_0x84,
PACKET_0x85,
PACKET_0x86,
PACKET_0x87,
PACKET_0x88,
PACKET_0x89,
PACKET_0x8A,
PACKET_0x8B,
PACKET_0x8C,
PACKET_0x8D,
PACKET_0x8E,
PACKET_0x8F,
PACKET_0x90,
PACKET_0x91,
PACKET_0x92,
PACKET_0x93,
PACKET_0x94,
PACKET_0x95,
PACKET_0x96,
PACKET_0x97,
PACKET_0x98,
PACKET_0x99,
PACKET_0x9A,
PACKET_0x9B,
PACKET_0x9C,
PACKET_0x9D,
PACKET_0x9E,
PACKET_0x9F,
PACKET_0xA0,
PACKET_0xA1,
PACKET_0xA2,
PACKET_0xA3,
PACKET_0xA4,
PACKET_0xA5,
PACKET_0xA6,
PACKET_0xA7,
PACKET_0xA8,
PACKET_0xA9,
PACKET_0xAA,
PACKET_0xAB,
PACKET_0xAC,
PACKET_0xAD,
PACKET_0xAE,
PACKET_0xAF,
PACKET_0xB0,
PACKET_0xB1,
PACKET_0xB2,
PACKET_0xB3,
PACKET_0xB4
};
enum message_types_t {
MESSAGE_TYPE_ITEM_MOVE = 1,
MESSAGE_TYPE_INVENTORY_SORT,
MESSAGE_TYPE_DAMAGE_INFO,
MESSAGE_TYPE_GOLD_PICKUP_INFO,
MESSAGE_TYPE_ITEM_PICKUP_INFO,
MESSAGE_TYPE_ITEM_DROPPED_INFO,
MESSAGE_TYPE_TRANSMUTE,
MESSAGE_TYPE_TRADER_UPDATE,
MESSAGE_TYPE_COUNT
};
enum damage_type_t : uint8_t {
DAMAGE_TYPE_PHYSICAL = 0,
DAMAGE_TYPE_COLD = 1,
DAMAGE_TYPE_FIRE = 2,
DAMAGE_TYPE_LIGHTNING = 3,
DAMAGE_TYPE_POISON = 4,
DAMAGE_TYPE_MAGIC = 5,
DAMAGE_TYPE_COUNT,
DAMAGE_TYPE_UNKNOWN = 0xFF
};
struct packet_header {
uint8_t d2_packet_type;
uint8_t message_type;
packet_header() : d2_packet_type(0xBB), message_type(0) {}
};
struct d2_entity_action_cs : packet_header {
uint32_t action;
uint32_t entity_id;
uint32_t complement;
d2_entity_action_cs() : action(0), entity_id(0), complement(0) {}
};
struct item_move_cs : packet_header {
uint32_t item_guid;
uint8_t target_page;
item_move_cs() : item_guid(0), target_page(0) {
message_type = MESSAGE_TYPE_ITEM_MOVE;
}
};
struct item_move_sc : packet_header {
uint32_t item_guid;
uint32_t tx;
uint32_t ty;
uint8_t target_page;
item_move_sc() : item_guid(0), tx(0), ty(0), target_page(0) {
message_type = MESSAGE_TYPE_ITEM_MOVE;
}
};
struct inventory_sort_cs : packet_header {
uint8_t page;
inventory_sort_cs() : page(0) {
message_type = MESSAGE_TYPE_INVENTORY_SORT;
}
};
struct inventory_sort_sc : packet_header {
uint8_t page;
uint8_t tx;
uint8_t ty;
uint32_t guid;
inventory_sort_sc() : page(0), tx(0), ty(0), guid(0) {
message_type = MESSAGE_TYPE_INVENTORY_SORT;
}
};
struct damage_info_cs : packet_header {
uint8_t state; //on or off
damage_info_cs() : state(0) {
message_type = MESSAGE_TYPE_DAMAGE_INFO;
}
};
struct damage_info_sc : packet_header {
uint8_t unit_type;
uint32_t guid;
damage_type_t damage_type;
uint32_t damage;
uint32_t currentHp; // New field for current hit points
uint32_t maxHp; // New field for maximum hit points
damage_info_sc() : unit_type(0), guid(0), damage_type(DAMAGE_TYPE_UNKNOWN), damage(0), currentHp(0), maxHp(0) {
message_type = MESSAGE_TYPE_DAMAGE_INFO;
}
};
struct gold_pickup_info_sc : packet_header {
uint32_t gold;
gold_pickup_info_sc() : gold(0) {
message_type = MESSAGE_TYPE_GOLD_PICKUP_INFO;
}
};
struct gold_pickup_info_cs : packet_header {
uint32_t item_guid;
gold_pickup_info_cs() : item_guid(0) {
message_type = MESSAGE_TYPE_GOLD_PICKUP_INFO;
}
};
struct item_pickup_info_cs : packet_header {
uint32_t item_guid;
item_pickup_info_cs() : item_guid(0) {
message_type = MESSAGE_TYPE_ITEM_PICKUP_INFO;
}
};
struct item_pickup_info_sc : packet_header {
bool inventory_full;
item_pickup_info_sc() : inventory_full(false) {
message_type = MESSAGE_TYPE_ITEM_PICKUP_INFO;
}
};
struct item_dropped_info_cs : packet_header {
uint16_t item_id;
uint8_t code[4];
item_dropped_info_cs() : item_id(0), code{ 0 } {
message_type = MESSAGE_TYPE_ITEM_DROPPED_INFO;
}
};
struct item_dropped_info_sc : packet_header {
uint32_t item;
uint8_t code[4];
uint8_t quality;
uint8_t showthis;
uint8_t namestr[130]; //130
uint8_t index_arr_itemtype;
uint8_t arr_itemtype_codestr_equivstr[20][5];
item_dropped_info_sc() : item(0), quality(0), showthis(0), index_arr_itemtype(0), code{ 0 }, arr_itemtype_codestr_equivstr{ 0 }, namestr{ 0 } {
message_type = MESSAGE_TYPE_ITEM_DROPPED_INFO;
}
};
struct transmute_info_sc : packet_header {
uint32_t item_guid;
uint32_t tx;
uint32_t ty;
uint8_t target_page;
uint8_t command;
transmute_info_sc() : item_guid(0), tx(0), ty(0), target_page(0), command(0) {
message_type = MESSAGE_TYPE_TRANSMUTE;
}
};
struct transmute_info_cs : packet_header {
uint32_t item_guid;
uint8_t target_page;
uint8_t command;
bool transmute_start_flag;
transmute_info_cs() : item_guid(0), target_page(0), command(0), transmute_start_flag(0) {
message_type = MESSAGE_TYPE_TRANSMUTE;
}
};
struct trader_update_cs : packet_header {
uint32_t npc_id;
uint32_t client_id;
uint8_t command;
bool is_gamble_menu_open;
trader_update_cs() : npc_id(0), client_id(0), command(0), is_gamble_menu_open(0) {
message_type = MESSAGE_TYPE_TRADER_UPDATE;
}
};
struct trader_update_sc : packet_header {
uint32_t npc_id;
uint32_t client_id;
uint8_t command;
bool is_gamble_menu_open;
trader_update_sc() : npc_id(0), client_id(0), command(0), is_gamble_menu_open(0) {
message_type = MESSAGE_TYPE_TRADER_UPDATE;
}
};
#pragma pack(pop)
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include <d2tweaks/server/modules/server_module.h>
namespace d2_tweaks {
namespace server {
class server;
namespace modules {
class auto_gold_pickup final : public server_module {
public:
void init() override;
void tick(diablo2::structures::game* game, diablo2::structures::unit* unit) override;
bool handle_packet(diablo2::structures::game* game, diablo2::structures::unit* player, common::packet_header* packet) override;
bool au_pickup_gold(diablo2::structures::game* game, diablo2::structures::unit* unit, diablo2::structures::unit* item);
};
}
}
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include <d2tweaks/server/modules/server_module.h>
namespace d2_tweaks {
namespace server {
class server;
namespace modules {
class auto_item_pickup final : public server_module {
public:
void init() override;
void tick(diablo2::structures::game* game, diablo2::structures::unit* unit) override;
bool handle_packet(diablo2::structures::game* game, diablo2::structures::unit* player, common::packet_header* packet) override;
bool au_pickup_item(diablo2::structures::game* game, diablo2::structures::unit* unit, uint32_t guid);
};
}
}
}

View File

@@ -0,0 +1,35 @@
#pragma once
#include <cstdint>
#include <d2tweaks/server/modules/server_module.h>
//Inventory auto sort module server side
namespace diablo2 {
namespace structures {
struct game;
struct inventory;
struct unit;
}
}
namespace d2_tweaks {
namespace server {
class server;
namespace modules {
class autosort final : public server_module {
public:
void init() override;
bool handle_packet(diablo2::structures::game* game, diablo2::structures::unit* player,
common::packet_header* packet) override;
private:
bool sort(diablo2::structures::game* game, diablo2::structures::unit* player, uint8_t page);
bool find_free_space(diablo2::structures::inventory* inv,
diablo2::structures::unit* item, int32_t inventoryIndex, char page, uint32_t& x, uint32_t& y, bool isCharmZone);
};
}
}
}

View File

@@ -0,0 +1,32 @@
#pragma once
#include <cstdint>
#include <d2tweaks/server/modules/server_module.h>
//Display damage server side
namespace diablo2 {
namespace structures {
struct inventory;
struct game;
struct unit;
}
}
namespace d2_tweaks {
namespace server {
class server;
namespace modules {
class damage_display final : public server_module {
public:
void init() override;
bool handle_packet(diablo2::structures::game* game, diablo2::structures::unit* player,
common::packet_header* packet) override;
void tick(diablo2::structures::game* game, diablo2::structures::unit* unit) override;
};
}
}
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <d2tweaks/server/modules/server_module.h>
namespace d2_tweaks {
namespace server {
class server;
namespace modules {
class identify_on_pickup final : public server_module {
public:
void init() override;
};
}
}
}

View File

@@ -0,0 +1,18 @@
#pragma once
#include <d2tweaks/server/modules/server_module.h>
namespace d2_tweaks {
namespace server {
class server;
namespace modules {
class item_drop_message final : public server_module {
public:
void init() override;
void tick(diablo2::structures::game* game, diablo2::structures::unit* unit) override;
bool handle_packet(diablo2::structures::game* game, diablo2::structures::unit* player, common::packet_header* packet) override;
};
}
}
}

View File

@@ -0,0 +1,34 @@
#pragma once
#include <cstdint>
#include <d2tweaks/server/modules/server_module.h>
//Item moving between inventory pages (cube, inventory and stash) by ctrl+click server side
namespace diablo2 {
namespace structures {
struct inventory;
struct game;
struct unit;
}
}
namespace d2_tweaks {
namespace server {
class server;
namespace modules {
class item_move final : public server_module {
public:
void init() override;
bool handle_packet(diablo2::structures::game* game, diablo2::structures::unit* player,
common::packet_header* packet) override;
private:
bool find_free_space(diablo2::structures::inventory* inv,
diablo2::structures::unit* item, int32_t inventoryIndex, char page, uint32_t& x, uint32_t& y);
};
}
}
}

View File

@@ -0,0 +1,38 @@
#pragma once
#include <stdint.h>
#define MODULE_INIT(module_name) static d2_tweaks::server::modules::module_name g_instance;
namespace diablo2 {
namespace structures {
struct game;
struct unit;
}
}
namespace d2_tweaks {
namespace common {
struct packet_header;
}
namespace server {
namespace modules {
class server_module {
public:
virtual ~server_module() = default;
server_module();
virtual void init() = 0;
/**
* \brief
* \param game
* \param player
* \param packet
* \return true - block further packet processing, false - pass packet to game
*/
virtual bool handle_packet(diablo2::structures::game* game, diablo2::structures::unit* player, common::packet_header* packet);
virtual void tick(diablo2::structures::game* game, diablo2::structures::unit* unit);
};
}
}
}

View File

@@ -0,0 +1,16 @@
#pragma once
#include <d2tweaks/server/modules/server_module.h>
namespace d2_tweaks {
namespace server {
class server;
namespace modules {
class test final : public server_module {
public:
void init() override;
};
}
}
}

View File

@@ -0,0 +1,32 @@
#pragma once
#include <cstdint>
#include <d2tweaks/server/modules/server_module.h>
namespace diablo2 {
namespace structures {
struct inventory;
struct game;
struct unit;
}
}
namespace d2_tweaks {
namespace server {
class server;
namespace modules {
class trader_update final : public server_module {
public:
void init() override;
void tick(diablo2::structures::game* game, diablo2::structures::unit* unit) override;
bool handle_packet(diablo2::structures::game* game, diablo2::structures::unit* player, common::packet_header* packet) override;
//private:
// bool find_free_space(diablo2::structures::inventory* inv, diablo2::structures::unit* item, int32_t inventoryIndex, char page, uint32_t& x, uint32_t& y);
// bool send_to_cube(diablo2::structures::game* game, diablo2::structures::unit* player, diablo2::structures::unit* item);
// bool move_item_to(diablo2::structures::game* game, diablo2::structures::unit* player, common::packet_header* packet);
};
}
}
}

View File

@@ -0,0 +1,32 @@
#pragma once
#include <cstdint>
#include <d2tweaks/server/modules/server_module.h>
namespace diablo2 {
namespace structures {
struct inventory;
struct game;
struct unit;
}
}
namespace d2_tweaks {
namespace server {
class server;
namespace modules {
class transmute final : public server_module {
public:
void init() override;
void tick(diablo2::structures::game* game, diablo2::structures::unit* unit) override;
bool handle_packet(diablo2::structures::game* game, diablo2::structures::unit* player, common::packet_header* packet) override;
private:
bool find_free_space(diablo2::structures::inventory* inv, diablo2::structures::unit* item, int32_t inventoryIndex, char page, uint32_t& x, uint32_t& y);
bool send_to_cube(diablo2::structures::game* game, diablo2::structures::unit* player, diablo2::structures::unit* item);
bool move_item_to(diablo2::structures::game* game, diablo2::structures::unit* player, common::packet_header* packet);
};
}
}
}

View File

@@ -0,0 +1,55 @@
#pragma once
#include <cstdint>
#include <fw/singleton.h>
#include <d2tweaks/common/protocol.h>
#include <functional>
namespace diablo2 {
namespace structures {
enum class unit_type_t;
struct game;
struct inventory;
struct unit;
struct net_client;
}
}
namespace d2_tweaks {
namespace common {
struct packet_header;
}
namespace server {
namespace modules {
class server_module;
}
class server : public singleton<server> {
uint8_t m_module_id_counter;
uint8_t m_tick_handler_id_counter;
modules::server_module* m_modules[0xFF]{ nullptr }; //max 255 modules atm.
modules::server_module* m_tick_handlers[0xFF]{ nullptr }; //max 255 modules atm.
modules::server_module* m_packet_handlers[0xFF]{ nullptr }; //max 255 handlers because of one-byte packet header
public:
explicit server(token);
void init();
void send_packet(diablo2::structures::net_client* client, common::packet_header* packet, size_t size);
bool handle_packet(diablo2::structures::game* game, diablo2::structures::unit* player, common::packet_header* packet);
void register_module(modules::server_module* module);
void register_tick_handler(modules::server_module* module);
void register_packet_handler(common::message_types_t type, modules::server_module* module);
diablo2::structures::unit* get_server_unit(diablo2::structures::game* game, uint32_t guid, diablo2::structures::unit_type_t type);
void iterate_server_units(diablo2::structures::game* game, diablo2::structures::unit_type_t type,
const std::function<bool(diablo2::structures::unit*)>& cb);
private:
static int32_t __fastcall net_tick(diablo2::structures::game* game, diablo2::structures::unit* unit, int32_t a3, int32_t a4);
};
}
}

View File

@@ -0,0 +1,91 @@
#pragma once
#include <d2tweaks/ui/controls/control.h>
#include <d2tweaks/ui/rect.h>
#include <cstdint>
#include <functional>
#include <pugixml.hpp>
namespace diablo2 {
namespace structures {
struct cell_file;
}
}
namespace d2_tweaks {
namespace common {
class asset;
}
namespace ui {
namespace controls {
class image;
class button final : public control {
rect m_rect;
image* m_image;
int32_t m_frame_down;
int32_t m_frame_up;
int32_t m_click_sound;
bool m_is_down;
int32_t m_current_frame;
uint32_t m_res_count;
std::wstring m_popup;
std::function<void()> m_on_click;
std::vector<respos> m_respos;
public:
button(menu* menu, const rect& rect, const std::function<void()>& onClick,
common::asset* image, int32_t frameDown, int32_t frameUp, int32_t clickSound = -1);
explicit button(menu* menu, const pugi::xml_node& node);
virtual ~button();
void set_x(int32_t value) override;
int32_t get_x() const override {
return m_rect.get_x();
}
void set_y(int32_t value) override;
int32_t get_y() const override {
return m_rect.get_y();
}
std::wstring popup() const {
return m_popup;
}
void set_popup(const std::wstring& popup) {
m_popup = popup;
}
void set_current_frame(int32_t value) {
m_current_frame = value;
}
int32_t get_current_frame() {
return m_current_frame;
}
std::function<void()> get_on_click() const {
return m_on_click;
}
void set_on_click(const std::function<void()>& on_click) {
m_on_click = on_click;
}
void draw() override;
void draw(int32_t offsetX, int32_t offsetY) override;
void left_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) override;
void right_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) override;
void key_event(int32_t offsetX, int32_t offsetY, uint32_t key, bool up, bool& block) override;
};
}
}
}

View File

@@ -0,0 +1,85 @@
#pragma once
#include <d2tweaks/ui/controls/control.h>
#include <pugixml.hpp>
#include <functional>
#include <d2tweaks/ui/rect.h>
namespace d2_tweaks {
namespace common {
class asset;
}
}
namespace d2_tweaks {
namespace ui {
namespace controls {
class image;
class label;
class checkbox : public control {
rect m_rect;
image* m_image;
label* m_label;
std::wstring m_popup;
int32_t m_frame_checked;
int32_t m_frame_unchecked;
int32_t m_click_sound;
bool m_is_down;
bool m_state;
std::function<void(bool)> m_on_click;
public:
explicit checkbox(menu* menu, const std::wstring& text, const rect& rect, const std::function<void()>& onClick,
common::asset* image, int32_t frameChecked, int32_t frameUnchecked, int32_t clickSound = -1);
explicit checkbox(menu* menu, const pugi::xml_node& node);
void set_x(int32_t value) override;
int32_t get_x() const override {
return m_rect.get_x();
}
void set_y(int32_t value) override;
int32_t get_y() const override {
return m_rect.get_y();
}
std::wstring popup() const {
return m_popup;
}
void set_popup(const std::wstring& popup) {
m_popup = popup;
}
std::function<void(bool)> get_on_click() const {
return m_on_click;
}
void set_on_click(const std::function<void(bool)>& on_click) {
m_on_click = on_click;
}
bool get_state() const {
return m_state;
}
void set_state(bool value) {
m_state = value;
}
void draw() override;
void draw(int32_t offsetX, int32_t offsetY) override;
void left_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) override;
void right_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) override;
void key_event(int32_t offsetX, int32_t offsetY, uint32_t key, bool up, bool& block) override;
};
}
}
}

View File

@@ -0,0 +1,120 @@
#pragma once
#include <string>
#include <cstdint>
namespace d2_tweaks {
namespace ui {
class menu;
namespace controls {
struct respos {
uint32_t res_x;
uint32_t res_y;
uint32_t pos_x;
uint32_t pos_y;
};
class control {
control* m_parent;
menu* m_menu;
std::string m_name;
bool m_enabled = false;
bool m_visible = false;
int32_t m_x;
int32_t m_y;
int32_t m_width;
int32_t m_height;
public:
control(menu* menu, int32_t x, int32_t y, int32_t w, int32_t h) : m_parent(nullptr),
m_menu(menu),
m_x(x), m_y(y),
m_width(w), m_height(h) {}
virtual ~control() = default;
control* get_parent() const {
return m_parent;
}
void set_parent(control* const parent) {
m_parent = parent;
}
menu* get_menu() const {
return m_menu;
}
void set_menu(menu* const menu) {
m_menu = menu;
}
std::string get_name() const {
return m_name;
}
void set_name(const std::string& name) {
m_name = name;
}
virtual bool get_enabled() const {
return m_enabled;
}
virtual void set_enabled(bool value) {
m_enabled = value;
}
virtual bool get_visible() const {
return m_visible;
}
virtual void set_visible(bool value) {
m_visible = value;
}
virtual int32_t get_x() const {
return m_x;
}
virtual void set_x(int32_t value) {
m_x = value;
}
virtual int32_t get_y() const {
return m_y;
}
virtual void set_y(int32_t value) {
m_y = value;
}
virtual int32_t get_width() const {
return m_width;
}
virtual void set_width(const int32_t width) {
m_width = width;
}
virtual int32_t get_height() const {
return m_height;
}
virtual void set_height(const int32_t height) {
m_height = height;
}
virtual void draw() = 0;
virtual void draw(int32_t offsetX, int32_t offsetY) = 0;
virtual void left_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) = 0;
virtual void right_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) = 0;
virtual void key_event(int32_t offsetX, int32_t offsetY, uint32_t key, bool up, bool& block) = 0;
};
}
}
}

View File

@@ -0,0 +1,31 @@
#pragma once
#include <d2tweaks/ui/controls/control.h>
#include <pugixml.hpp>
#include <vector>
namespace d2_tweaks {
namespace ui {
class menu;
namespace controls {
class group : public control {
std::vector<control*> m_controls;
public:
explicit group(menu* menu, int32_t x, int32_t y);
explicit group(menu* menu, const pugi::xml_node& node);
void draw() override;
void draw(int32_t offsetX, int32_t offsetY) override;
void left_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) override;
void right_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) override;
void key_event(int32_t offsetX, int32_t offsetY, uint32_t key, bool up, bool& block) override;
private:
void add_control(control* control);
};
}
}
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include <d2tweaks/ui/controls/control.h>
#include <diablo2/structures/gfxdata.h>
#include <pugixml.hpp>
#include <d2tweaks/ui/rect.h>
namespace d2_tweaks {
namespace common {
class asset;
}
namespace ui {
namespace controls {
class image : public control {
common::asset* m_image;
int32_t m_frame;
rect m_rect;
bool m_block_click;
diablo2::structures::gfxdata m_draw_info;
public:
explicit image(menu* menu, common::asset* image, int32_t x = 0, int32_t y = 0, int32_t frame = 0);
explicit image(menu* menu, const pugi::xml_node& node);
void set_frame(int32_t frame) {
m_frame = static_cast<uint32_t>(frame);
}
int32_t get_frame() const {
return static_cast<int32_t>(m_frame);
}
void draw() override;
void draw(int32_t offsetX, int32_t offsetY) override;
void left_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) override;
void right_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) override;
void key_event(int32_t offsetX, int32_t offsetY, uint32_t key, bool up, bool& block) override;
};
}
}
}

View File

@@ -0,0 +1,61 @@
#pragma once
#include <d2tweaks/ui/controls/control.h>
#include <vector>
#include <pugixml.hpp>
#include <diablo2/d2win.h>
namespace d2_tweaks {
namespace ui {
namespace controls {
class label : public control {
std::wstring m_text;
bool m_text_owned;
diablo2::ui_color_t m_color;
diablo2::ui_font_t m_font;
uint32_t m_res_count;
std::vector<respos> m_respos;
public:
explicit label(menu* menu, const std::wstring& text, int32_t x = 0, int32_t y = 0,
diablo2::ui_color_t color = diablo2::UI_COLOR_WHITE,
diablo2::ui_font_t font = diablo2::UI_FONT_16);
explicit label(menu* menu, const pugi::xml_node& node);
void set_text(const std::wstring& text) {
m_text = text;
}
const std::wstring& get_text() const {
return m_text;
}
diablo2::ui_color_t get_color() const {
return m_color;
}
void set_color(const diablo2::ui_color_t color) {
m_color = color;
}
diablo2::ui_font_t get_font() const {
return m_font;
}
void set_font(const diablo2::ui_font_t font) {
m_font = font;
}
void draw() override;
void draw(int32_t offsetX, int32_t offsetY) override;
void left_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) override;
void right_mouse(int32_t offsetX, int32_t offsetY, bool up, bool& block) override;
void key_event(int32_t offsetX, int32_t offsetY, uint32_t key, bool up, bool& block) override;
};
}
}
}

View File

@@ -0,0 +1,88 @@
#pragma once
#include <vector>
#include <string>
#include <unordered_map>
namespace d2_tweaks {
namespace ui {
namespace controls {
class control;
}
struct respos {
uint32_t res_x;
uint32_t res_y;
uint32_t pos_x;
uint32_t pos_y;
};
class menu {
bool m_enabled = false;
bool m_visible = false;
std::string m_name;
int32_t m_x;
int32_t m_y;
int32_t m_width;
int32_t m_height;
uint32_t m_res_count;
std::vector<controls::control*> m_controls;
std::unordered_map<std::string, controls::control*> m_named_controls;
std::vector<respos> m_respos;
public:
virtual ~menu() = default;
menu();
const std::vector<controls::control*>& get_controls() const {
return m_controls;
}
const std::string& get_name() const {
return m_name;
}
virtual bool get_enabled() const {
return m_enabled;
}
virtual void set_enabled(bool value) {
m_enabled = value;
}
virtual bool get_visible() const {
return m_visible;
}
virtual void set_visible(bool value) {
m_visible = value;
}
bool load_xml(const char* path);
template<typename TControl = controls::control>
TControl* get_control(const std::string& name) {
const auto it = m_named_controls.find(name);
if (it == m_named_controls.end())
return nullptr;
return static_cast<TControl*>(it->second);
}
virtual void add_control(controls::control* control);
//virtual controls::control* get_control(const std::string& name);
virtual void remove_control(controls::control* control);
virtual void draw();
virtual bool left_mouse(bool up);
virtual bool right_mouse(bool up);
virtual bool key_event(uint32_t key, bool up);
};
}
}

View File

@@ -0,0 +1,57 @@
#pragma once
#include <cstdint>
namespace d2_tweaks {
namespace ui {
//Special ui rectangle with starting point in the left bottom corner
class rect {
int32_t m_x, m_y, m_w, m_h;
public:
rect() : m_x(0), m_y(0), m_w(0), m_h(0) {}
rect(int32_t x, int32_t y, int32_t width, int32_t height) : m_x(x), m_y(y), m_w(width), m_h(height) {}
int32_t get_x() const {
return m_x;
}
void set_x(int32_t value) {
m_x = value;
}
int32_t get_y() const {
return m_y;
}
void set_y(int32_t value) {
m_y = value;
}
void set_width(int32_t value) {
m_w = value;
}
int32_t get_width() const {
return m_w;
}
void set_height(int32_t value) {
m_h = value;
}
int32_t get_height() const {
return m_h;
}
bool contains(int32_t x, int32_t y) const {
return x >= m_x && x < m_x + m_w &&
y > m_y - m_h && y <= m_y;
}
bool contains(int32_t x, int32_t y, int32_t offsetX, int32_t offsetY) const {
return x >= m_x + offsetX && x < m_x + offsetX + m_w &&
y > m_y + offsetY - m_h && y <= m_y + offsetY;
}
};
}
}

View File

@@ -0,0 +1,39 @@
#pragma once
#include <Windows.h>
#include <fw/singleton.h>
#include <vector>
#include <string>
namespace d2_tweaks {
namespace ui {
class menu;
class ui_manager final : public singleton<ui_manager> {
std::vector<menu*> m_menus;
bool m_was_down_before_left = false;
bool m_was_down_before_right = false;
bool m_mouse_state_left = false;
bool m_mouse_state_right = false;
public:
explicit ui_manager(token);
void add_menu(menu* m);
menu* get_menu(const std::string& name);
void remove_menu(menu* m);
void draw();
private:
static LRESULT __stdcall wnd_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
void process_inputs();
bool process_left_mouse(bool up);
bool process_right_mouse(bool up);
bool process_key_event(uint32_t key, bool up);
};
}
}