diff --git a/flyff-api/CMakeLists.txt b/flyff-api/CMakeLists.txt index 7f859e4..3331df5 100644 --- a/flyff-api/CMakeLists.txt +++ b/flyff-api/CMakeLists.txt @@ -2,6 +2,7 @@ add_library ( flyff-api "src/flyff.cpp" "src/Neuz.cpp" + "src/Mover.cpp" "src/import.cpp" "src/api.cpp" "include/flyff.h" diff --git a/flyff-api/include/flyff.h b/flyff-api/include/flyff.h index 3898eae..6f6c76b 100644 --- a/flyff-api/include/flyff.h +++ b/flyff-api/include/flyff.h @@ -5,6 +5,7 @@ // #include "../src/api.h" #include "../src/Neuz.h" #include "../src/Mover.h" +#include "../src/skill.h" #include "../src/import.h" diff --git a/flyff-api/src/Mover.h b/flyff-api/src/Mover.h index 87002f3..3c3efb6 100644 --- a/flyff-api/src/Mover.h +++ b/flyff-api/src/Mover.h @@ -14,275 +14,346 @@ namespace flyff { -namespace raw { - extern "C" { + namespace raw { + extern "C" { // w2c_f410: CMover::GetHitPoint(PlayerObject* mover); extern u32 w2c_f411(u32); // w2c_f2454: CCooltimeMgr::CanUse(uint64_t* timers, ItemProperty* prop); extern u32 w2c_f2466(u32, u32); - } -}; - -struct __attribute__((packed)) Mover { - static constexpr uint32_t MAX_PARAM = 0x52; - - using Parameter = unsigned long; - - using ObjectStateFlags = Object::StateFlags; - using ObjectState = Object::State; - - struct __attribute__((packed)) Vtable { - union { - DEFINE_MEMBER(52, u32, get_level); - DEFINE_MEMBER(56, u32, get_gender); - - DEFINE_MEMBER(144, u32, get_max_origin_hp); - DEFINE_MEMBER(148, u32, get_max_origin_mp); - - const MinimumSize<220> __size; - }; + } }; + struct __attribute__((packed)) Mover { + static constexpr uint32_t MAX_PARAM = 0x52; - union { - DEFINE_MEMBER(0x0, const Pointer, vtable); + using Parameter = unsigned long; - DEFINE_MEMBER(0x18, Matrix4, world_matrix); - - DEFINE_MEMBER(152, Vector3, position); - DEFINE_MEMBER(164, Vector3, rotation); - - DEFINE_MEMBER(188, Pointer, property); - - DEFINE_MEMBER(216, bool, is_despawned); - DEFINE_MEMBER(352, MoverID, object_id); - - DEFINE_MEMBER(920, Parameter, adjustParam[MAX_PARAM]); - DEFINE_MEMBER(1248, Parameter, changeParam[MAX_PARAM]); - - DEFINE_MEMBER(2020, const String, name); - - DEFINE_MEMBER(1628, Vector3, move_target); - DEFINE_MEMBER(1688, unsigned long long, last_combat); - - DEFINE_MEMBER(1728, MoverID, move_toward_target); - DEFINE_MEMBER(1736, MoverID, last_attacked_target); - DEFINE_MEMBER(1744, MoverID, selected_target); - // The id of the target that it hit last. - DEFINE_MEMBER(1752, MoverID, attack_target); - DEFINE_MEMBER(1760, MoverID, follow_target); - // The id, only non-zero when the attack animation plays, of the target it is attacking. - DEFINE_MEMBER(1768, MoverID, current_attack_target); - DEFINE_MEMBER(1776, MoverID, platform_standing_on); - - DEFINE_MEMBER(1816, int, adj_param); - DEFINE_MEMBER(1820, uint32_t, server_tick); - - DEFINE_MEMBER(1840, int, hitpoints); - - DEFINE_MEMBER(1792, int, current_animation); - - DEFINE_MEMBER(204, ObjectType, type); - - DEFINE_MEMBER(216, uint32_t, existence_check); - - DEFINE_MEMBER(1804, uint32_t, object_state); - DEFINE_MEMBER(1808, uint32_t, object_state_flags); - - DEFINE_MEMBER(904, uint32_t, if_not_null_needsattackitem); - - DEFINE_MEMBER(192, uintptr_t, world); - - // Only works on players. - DEFINE_MEMBER(2472, uint32_t, level); - - DEFINE_MEMBER(860, Vector, inventory); - - - DEFINE_MEMBER(3324, uint64_t, last_food_time); - DEFINE_MEMBER(3348, uint64_t, last_refresher_time); - DEFINE_MEMBER(3356, uint64_t, last_vitaldrink_time); - - const MinimumSize<4096> __size; - }; - - bool can_use_item(const Pointer& property) { - return raw::w2c_f2466(kMemory.to_inside(&last_food_time), static_cast(property)); - } - - bool is_in_combat() const { - const unsigned long long& now = fugg::module_ref(0x00032880); - // 10 seconds - return now - last_combat < 10000000; - } - - Parameter get_param(uint32_t index, Parameter base) const { - Parameter changeParam = get_change_param(index); - if(changeParam != 0x7FFFFFFF) - return changeParam; - - Parameter adjustParam = get_adjust_param(index); - if(adjustParam) - return base + adjustParam; - else - return base; - } - - Parameter get_adjust_param(Parameter index) const { - // Find these values in CMover::Init - return adjustParam[index] ^ adj_param ^ 0x0554e725 + index * 0x41c64e6d; - } - - Parameter get_change_param(Parameter index) const { - return changeParam[index] ^ adj_param ^ index * 0x41c64e6d + 0xb5a52d1a; - } - - u32 get_hp() const { - return raw::w2c_f411(kMemory.to_inside(this)); - } - - u32 get_max_hp() const { static constexpr Parameter DST_HP_MAX = 0x2c; static constexpr Parameter DST_HP_MAX_RATE = 0x35; - float factor = 1.0f; - int result = get_param(DST_HP_MAX, get_max_origin_hp()); - int percent = get_param(DST_HP_MAX_RATE, 0); + using ObjectStateFlags = Object::StateFlags; + using ObjectState = Object::State; - factor += (float)percent / (float)100; - result = (int)(result * factor); + struct __attribute__((packed)) Vtable { + union { + DEFINE_MEMBER(52, u32, get_level); + DEFINE_MEMBER(56, u32, get_gender); - return result; - } + DEFINE_MEMBER(96, u32, get_active_hand_item_prop); - u32 get_hp_percent(int percent = 100) const { - int max = get_max_hp(); - if(max == 0) return 0; + DEFINE_MEMBER(144, u32, get_max_origin_hp); + DEFINE_MEMBER(148, u32, get_max_origin_mp); - return get_hp() * percent / max; - } + const MinimumSize<220> __size; + }; + }; - u32 get_max_origin_hp() const { - using Fn = FunctionPointer; - const auto& fn = fugg::function_ref(vtable->get_max_origin_hp); + struct __attribute__((packed)) Skill { + union { + DEFINE_MEMBER(0, uintptr_t, index); + DEFINE_MEMBER(4, uintptr_t, level); + }; + }; - return fn(kMemory.to_inside(this), 0, 0); - } + struct __attribute__((packed)) Buff { + static constexpr Parameter BUFF_ITEM = 0; + static constexpr Parameter BUFF_SKILL = 1; + + struct __attribute__((packed)) Vtable { + union { + DEFINE_MEMBER(28, uintptr_t, get_type); + DEFINE_MEMBER(32, uintptr_t, get_id); + }; + }; + + union { + DEFINE_MEMBER(0, Pointer, vtable); + + DEFINE_MEMBER(4, Pointer, property); + DEFINE_MEMBER(8, Parameter, param_id); + + DEFINE_MEMBER(16, uint64_t, time_instantiated); + DEFINE_MEMBER(24, uint64_t, time_total); + + DEFINE_MEMBER(32, int, level); + + DEFINE_MEMBER(36, bool, is_removed); + DEFINE_MEMBER(37, bool, is_sfx); + }; + + int get_type() const { + using Fn = FunctionPointer; + const auto &fn = fugg::function_ref(vtable->get_type); + + return fn(kMemory.to_inside(this)); + } + + int get_id() const { + using Fn = FunctionPointer; + const auto &fn = fugg::function_ref(vtable->get_id); + + return fn(kMemory.to_inside(this)); + } + + uint64_t get_time_remaining() const; + }; + + union { + DEFINE_MEMBER(0x0, const Pointer, vtable); + + DEFINE_MEMBER(0x18, Matrix4, world_matrix); + + DEFINE_MEMBER(152, Vector3, position); + DEFINE_MEMBER(164, Vector3, rotation); + + DEFINE_MEMBER(188, Pointer, property); + + DEFINE_MEMBER(212, int, property_id); + DEFINE_MEMBER(216, bool, is_despawned); + DEFINE_MEMBER(352, MoverID, object_id); + + DEFINE_MEMBER(920, Parameter, adjusted_parameters[MAX_PARAM]); + DEFINE_MEMBER(1248, Parameter, changed_parameters[MAX_PARAM]); + + DEFINE_MEMBER(1576, Vector>, buffs); + + DEFINE_MEMBER(2020, const String, name); + + DEFINE_MEMBER(1628, Vector3, move_target); + DEFINE_MEMBER(1688, unsigned long long, last_combat); + + DEFINE_MEMBER(1728, MoverID, move_toward_target); + DEFINE_MEMBER(1736, MoverID, last_attacked_target); + DEFINE_MEMBER(1744, MoverID, selected_target); + // The id of the target that it hit last. + DEFINE_MEMBER(1752, MoverID, attack_target); + DEFINE_MEMBER(1760, MoverID, follow_target); + // The id, only non-zero when the attack animation plays, of the target it is attacking. + DEFINE_MEMBER(1768, MoverID, current_attack_target); + DEFINE_MEMBER(1776, MoverID, platform_standing_on); + + DEFINE_MEMBER(1816, int, adj_param); + DEFINE_MEMBER(1820, uint32_t, server_tick); + + DEFINE_MEMBER(1840, int, hitpoints); + + DEFINE_MEMBER(1848, int, is_grounded); + + DEFINE_MEMBER(1792, int, current_animation); + + DEFINE_MEMBER(204, ObjectType, type); + + DEFINE_MEMBER(216, uint32_t, existence_check); + + DEFINE_MEMBER(1804, uint32_t, object_state); + DEFINE_MEMBER(1808, uint32_t, object_state_flags); + + DEFINE_MEMBER(904, uint32_t, if_not_null_needsattackitem); + + DEFINE_MEMBER(192, uintptr_t, world); + + DEFINE_MEMBER(860, Vector, inventory); - // int get_max_hp() const { - // return raw::w2c_f410(kMemory.to_inside(this)); - // } + DEFINE_MEMBER(3324, uint64_t, last_food_time); + DEFINE_MEMBER(3348, uint64_t, last_refresher_time); + DEFINE_MEMBER(3356, uint64_t, last_vitaldrink_time); - uint32_t get_state() const { - return object_state; - } + DEFINE_MEMBER(3424, Vector, skills); - uint32_t get_move_state() const { - return (object_state & ObjectState::MovementAll); - } + const MinimumSize<4096> size; + }; - uint32_t get_turn_state() const { - return (object_state & ObjectState::TurnAll); - } + uint32_t get_skill_level(uint32_t skill_index) const { + for (const auto &skill: skills) { + if (skill_index == skill.index) + return skill.level; + } - uint32_t get_look_state() const { - return (object_state & ObjectState::LookAll); - } + return 0; + } - uint32_t get_jump_state() const { - return (object_state & ObjectState::JumpAll); - } + bool can_use_item(const Pointer &property) { + return raw::w2c_f2466(kMemory.to_inside(&last_food_time), static_cast(property)); + } - uint32_t get_attack_state() const { - return (object_state & ObjectState::AtkAll); - } + bool is_in_combat() const; - uint32_t get_damage_state() const { - return (object_state & ObjectState::DmgAll); - } + Parameter get_param(uint32_t index, Parameter base) const { + Parameter changeParam = get_change_param(index); + if (changeParam != 0x7FFFFFFF) + return changeParam; - uint32_t get_action_state() const { - return (object_state & ObjectState::ActionAll); - } + Parameter adjustParam = get_adjust_param(index); + if (adjustParam) + return base + adjustParam; + else + return base; + } - bool is_fly() const { - return (object_state_flags & ObjectStateFlags::Fly) != 0; - } + Parameter get_adjust_param(Parameter index) const { + // Find these values in CMover::Init + return adjusted_parameters[index] ^ adj_param ^ 0x0554e725 + index * 0x41c64e6d; + } - bool is_dead() const { - return (object_state & ObjectState::DieAll) != 0; - } + Parameter get_change_param(Parameter index) const { + return changed_parameters[index] ^ adj_param ^ index * 0x41c64e6d + 0xb5a52d1a; + } - bool is_sit() const { - return (object_state_flags & ObjectStateFlags::Sit) != 0; - } - // Whether the movement state is running, not if the Mover - // is actually moving. See `is_moving()` - bool is_run() const { - return (object_state_flags & ObjectStateFlags::Walk) == 0; - } - // Whether the movement state is walking, not if the Mover - // is actually moving. See `is_moving()` - bool is_walk() const { - return (object_state_flags & ObjectStateFlags::Walk) != 0; - } - // Normal action - No other commands have any effect during this action. - bool is_action() const { - return (object_state & ObjectState::ActionAll) != 0; - } + u32 get_hp() const { + return raw::w2c_f411(kMemory.to_inside(this)); + } - bool is_moving() const { - return (get_move_state() == ObjectState::MoveForward || - get_move_state() == ObjectState::MoveBackward || - get_move_state() == ObjectState::Left || - get_move_state() == ObjectState::Right); - } + flyff::Pointer get_equipped_item(const flyff::Part &part) { + using Fn = FunctionPointer; + const auto &fn = fugg::function_ref(vtable->get_active_hand_item_prop); - bool is_jumping() const { - return (object_state & ObjectState::JumpAll) != 0; - } + const auto &ptr = fn(kMemory.to_inside(this), static_cast(part)); + return flyff::Pointer(ptr); + } - bool is_attacking() const { - return (object_state & ObjectState::AtkAll) != 0; - } + uint32_t get_max_hp() const { + float factor = 1.0f; + int result = get_param(DST_HP_MAX, get_max_origin_hp()); + int percent = get_param(DST_HP_MAX_RATE, 0); - bool is_damaged() const { - return (object_state & ObjectState::DmgAll) != 0; - } + factor += (float) percent / (float) 100; + result = static_cast(result) * factor; - bool is_turning() const { - return (object_state & ObjectState::TurnAll) != 0; - } + return result; + } - u32 get_level() { - const auto& fn = fugg::function_ref>(vtable->get_level); + uint32_t get_hp_percent(int percent = 100) const { + int max = get_max_hp(); + if (max == 0) return 0; - return fn(kMemory.to_inside(this)); - } + return get_hp() * percent / max; + } - // int32_t get_gender() { - // // The function itself works but I fear it returns wrong results. - // // Female player = 0 - // // Male player = 0 - // // Npc = 2 - // const auto& fn = fugg::function_ref>>(vtable->get_gender); + uint32_t get_max_origin_hp() const { + using Fn = FunctionPointer; + const auto &fn = fugg::function_ref(vtable->get_max_origin_hp); - // return fn(Pointer(this)); - // } -}; + return fn(kMemory.to_inside(this), 0, 0); + } -struct MoverMap { - struct __attribute__((packed)) Node { - const Pointer next; - unsigned int list_index; - unsigned long long hash; - Pointer mover; + + // int get_max_hp() const { + // return raw::w2c_f410(kMemory.to_inside(this)); + // } + + uint32_t get_state() const { + return object_state; + } + + uint32_t get_move_state() const { + return (object_state & ObjectState::MovementAll); + } + + uint32_t get_turn_state() const { + return (object_state & ObjectState::TurnAll); + } + + uint32_t get_look_state() const { + return (object_state & ObjectState::LookAll); + } + + uint32_t get_jump_state() const { + return (object_state & ObjectState::JumpAll); + } + + uint32_t get_attack_state() const { + return (object_state & ObjectState::AtkAll); + } + + uint32_t get_damage_state() const { + return (object_state & ObjectState::DmgAll); + } + + uint32_t get_action_state() const { + return (object_state & ObjectState::ActionAll); + } + + bool is_fly() const { + return (object_state_flags & ObjectStateFlags::Fly) != 0; + } + + bool is_dead() const { + return (object_state & ObjectState::DieAll) != 0; + } + + bool is_sit() const { + return (object_state_flags & ObjectStateFlags::Sit) != 0; + } + + // Whether the movement state is running, not if the Mover + // is actually moving. See `is_moving()` + bool is_run() const { + return (object_state_flags & ObjectStateFlags::Walk) == 0; + } + + // Whether the movement state is walking, not if the Mover + // is actually moving. See `is_moving()` + bool is_walk() const { + return (object_state_flags & ObjectStateFlags::Walk) != 0; + } + + // Normal action - No other commands have any effect during this action. + bool is_action() const { + return (object_state & ObjectState::ActionAll) != 0; + } + + bool is_moving() const { + return (get_move_state() == ObjectState::MoveForward || + get_move_state() == ObjectState::MoveBackward || + get_move_state() == ObjectState::Left || + get_move_state() == ObjectState::Right); + } + + bool is_jumping() const { + return (object_state & ObjectState::JumpAll) != 0; + } + + bool is_attacking() const { + return (object_state & ObjectState::AtkAll) != 0; + } + + bool is_damaged() const { + return (object_state & ObjectState::DmgAll) != 0; + } + + bool is_turning() const { + return (object_state & ObjectState::TurnAll) != 0; + } + + u32 get_level() { + const auto &fn = fugg::function_ref>(vtable->get_level); + + return fn(kMemory.to_inside(this)); + } + + // int32_t get_gender() { + // // The function itself works but I fear it returns wrong results. + // // Female player = 0 + // // Male player = 0 + // // Npc = 2 + // const auto& fn = fugg::function_ref>>(vtable->get_gender); + + // return fn(Pointer(this)); + // } }; - const Pointer buckets; - size_t capacity; - const Pointer first; -}; + struct MoverMap { + struct __attribute__((packed)) Node { + const Pointer next; + unsigned int list_index; + unsigned long long hash; + Pointer mover; + }; + + const Pointer buckets; + size_t capacity; + const Pointer first; + }; }; // namespace flyff \ No newline at end of file diff --git a/flyff-api/src/Neuz.cpp b/flyff-api/src/Neuz.cpp index 26b9468..8496919 100644 --- a/flyff-api/src/Neuz.cpp +++ b/flyff-api/src/Neuz.cpp @@ -6,17 +6,20 @@ // static_assert(offsetof(TestMover, name) == 0x7f4, "Mover.name needs to be at // 2020"); - namespace flyff { namespace raw { -static const uintptr_t& WORLD = 0x00035eb8; -static const uintptr_t& PLAYER = WORLD + 4; +static constexpr uintptr_t WORLD = 0x00035eb8; +static constexpr uintptr_t PLAYER = WORLD + 4; -static const uintptr_t& PLAYER_OBJECT_ID = 0x00034ef8; +static constexpr uintptr_t PLAYER_OBJECT_ID = 0x00034ef8; // The messages that are limited to 5 that are show temporarily. -static const uintptr_t& MESSAGES_UI = 0x00035ec8; -static const uintptr_t& ANNOUNCEMENTS_UI = 0x00034c94; -static const uintptr_t& MOVER_MAP = 0x000332c8; +static constexpr uintptr_t MESSAGES_UI = 0x00035ec8; +static constexpr uintptr_t ANNOUNCEMENTS_UI = 0x00034c94; +static constexpr uintptr_t MOVER_MAP = 0x000332c8; + +static constexpr uintptr_t CURRENT_TIME = 0x00032880; +static constexpr uintptr_t START_TIME = 0x000328c0; +static constexpr uintptr_t MAYBE_LOGIN_TIME = START_TIME + 8; extern "C" { // get_mover @@ -29,6 +32,8 @@ extern void w2c_f341(u32, u32, u32); extern void w2c_f607(u32, u32, u32); // can_attack_target extern u32 w2c_f515(u32, u32); +// CProject::GetSkillProp() +extern u32 w2c_f440(u32, u32); }; static const auto& get_mover = w2c_f208; @@ -36,6 +41,7 @@ static const auto& get_text = w2c_f167; static const auto& show_message = w2c_f341; static const auto& show_announcement = w2c_f607; static const auto& can_attack_target = w2c_f515; +static const auto& get_skill_prop = w2c_f440; }; // namespace raw // Emscripten runtime: @@ -50,7 +56,10 @@ Neuz::Neuz() player(make_ref>(raw::PLAYER)), messages_ui(make_ref>(raw::MESSAGES_UI)), announcements_ui(make_ref>(raw::ANNOUNCEMENTS_UI)), - player_object_id(make_ref(raw::PLAYER_OBJECT_ID)) {} + player_object_id(make_ref(raw::PLAYER_OBJECT_ID)), + current_time(make_ref(raw::CURRENT_TIME)), + start_time(make_ref(raw::START_TIME)), + maybe_login_time(make_ref(raw::MAYBE_LOGIN_TIME)) {} Neuz& Neuz::instance() { static bool initialised = false; @@ -126,9 +135,14 @@ void Neuz::show_announcement(const std::string& message, bool Neuz::is_valid_attack(const Pointer& attacker, const Pointer& defender) const { - auto result = - raw::can_attack_target(static_cast(attacker), static_cast(defender)); + auto result = raw::can_attack_target(static_cast(attacker), + static_cast(defender)); return result != 0; } + + +Pointer Neuz::get_skill_property(int id) const { + return Pointer(raw::get_skill_prop(id, 1)); +} } // namespace flyff \ No newline at end of file diff --git a/flyff-api/src/Neuz.h b/flyff-api/src/Neuz.h index 4834471..25d101c 100644 --- a/flyff-api/src/Neuz.h +++ b/flyff-api/src/Neuz.h @@ -4,6 +4,7 @@ #include +#include "skill.h" #include "Mover.h" namespace flyff { @@ -38,6 +39,10 @@ class Neuz { const Pointer& player; const MoverID& player_object_id; + const uint64_t& current_time; + const uint64_t& start_time; + const uint64_t& maybe_login_time; + // Execute the `main` function of the flyff-client. int main() const; @@ -53,6 +58,8 @@ class Neuz { bool is_valid_attack(const Pointer& attacker, const Pointer& defender) const; + Pointer get_skill_property(int id) const; + // Easy to implement: Just send a EmscriptenKeyboardEvent* to the registered // function. void send_keydown(); void send_keyup(); void send_keypress(); }; diff --git a/flyff-api/src/core.h b/flyff-api/src/core.h index 24ea1f1..e22d249 100644 --- a/flyff-api/src/core.h +++ b/flyff-api/src/core.h @@ -10,7 +10,7 @@ template using FunctionPointer = ReturnType(*)(Args...); -template +template class MinimumSize { unsigned char __padding[kSize]; }; @@ -26,95 +26,98 @@ class MinimumSize { namespace flyff { -class Memory { - wasm_rt_memory_t** memory; - - public: - explicit Memory(wasm_rt_memory_t** mem) : memory(mem) {} - - uintptr_t start() const { - return reinterpret_cast((*memory)->data); - } - - uintptr_t to_inside(const uintptr_t offset) { - return offset != NULL ? offset - start() : NULL; - } - - intptr_t to_inside(const void* offset) { - return to_inside(reinterpret_cast(offset)); - } - - uintptr_t to_outside(const uintptr_t offset) { - return offset != NULL ? reinterpret_cast(&(*memory)->data[offset]) : NULL; - } - - template - T* to_outside(const T* offset) { - return reinterpret_cast( - to_outside(reinterpret_cast(offset))); - } -}; - -static auto kMemory = Memory(&Z_clientZ_memory); - -class Table {}; - -static const auto& kTable = &Z_clientZ_table; - - -template -T& make_ref(uintptr_t address) { - return *reinterpret_cast(kMemory.to_outside(address)); -} - -template -class __attribute__((packed)) Pointer { - // Always located INSIDE the flyff module. - uintptr_t offset; - - T* as_outside() const { - return reinterpret_cast(kMemory.to_outside(offset)); - } - - Pointer() : offset(0) { } + class Memory { + wasm_rt_memory_t **memory; public: - explicit Pointer(void* ptr) : offset(ptr == nullptr ? 0 : kMemory.to_inside(reinterpret_cast(ptr))) { } - explicit Pointer(uintptr_t ptr) : offset(ptr) { } + explicit Memory(wasm_rt_memory_t **mem) : memory(mem) {} - Pointer(const Pointer& other) : offset(other.offset) { } - Pointer& operator=(Pointer other) { - offset = other.offset; - return *this; + uintptr_t start() const { + return reinterpret_cast((*memory)->data); + } + + uintptr_t to_inside(const uintptr_t offset) const { + return offset != NULL ? offset - start() : NULL; + } + + uintptr_t to_inside(const void *offset) const { + return to_inside(reinterpret_cast(offset)); + } + + uintptr_t to_outside(const uintptr_t offset) { + return offset != NULL ? reinterpret_cast(&(*memory)->data[offset]) : NULL; + } + + template + T *to_outside(const T *offset) { + return reinterpret_cast( + to_outside(reinterpret_cast(offset))); + } + }; + + static auto kMemory = Memory(&Z_clientZ_memory); + + class Table { + }; + + static const auto &kTable = &Z_clientZ_table; + + + template + T &make_ref(uintptr_t address) { + return *reinterpret_cast(kMemory.to_outside(address)); } - T* operator->() const { - return as_outside(); - } + template + class __attribute__((packed)) Pointer; - T& operator*() const { - return *as_outside(); - } + template + class __attribute__((packed)) Pointer { + // Always located INSIDE the flyff module. + uintptr_t offset; - explicit operator T*() const { - return as_outside(); - } + T *as_outside() const { + return reinterpret_cast(kMemory.to_outside(offset)); + } - explicit operator u32() const { - return offset; - } + Pointer() : offset(0) {} - explicit operator bool() const { - return offset != 0 ? as_outside() != nullptr : false; - } + public: + explicit Pointer(void const *ptr) : offset( + ptr == nullptr ? 0 : kMemory.to_inside(reinterpret_cast(ptr))) {} - bool operator==(Pointer const& rhs) const { return offset == rhs.offset; } + explicit Pointer(uintptr_t ptr) : offset(ptr) {} - friend std::ostream& operator<<(std::ostream& os, const Pointer& ptr) { - os << reinterpret_cast(ptr.offset); - return os; - } -}; + Pointer(const Pointer &other) : offset(other.offset) {} + + Pointer &operator=(Pointer other) { + offset = other.offset; + return *this; + } + + T *operator->() const { + return as_outside(); + } + + explicit operator T *() const { + return as_outside(); + } + + explicit operator u32() const { + return offset; + } + + explicit operator bool() const { + return offset != 0 && as_outside() != nullptr; + } + + bool operator==(Pointer const &rhs) const { return offset == rhs.offset; } + + friend std::ostream &operator<<(std::ostream &os, const Pointer &ptr) { + os << reinterpret_cast(ptr.offset); + return os; + } + }; // Allocates an unmanaged pointer inside the flyff module. // template @@ -122,81 +125,81 @@ class __attribute__((packed)) Pointer { // return Pointer(new T(std::forward(args)...)); // } -class __attribute__((packed)) String { - union { - DEFINE_MEMBER(0x0, char*, text); - DEFINE_MEMBER(0x4, size_t, length); - DEFINE_MEMBER(0x8, void*, capacity); + class __attribute__((packed)) String { + union { + DEFINE_MEMBER(0x0, char*, text); + DEFINE_MEMBER(0x4, size_t, length); + DEFINE_MEMBER(0x8, void*, capacity); - DEFINE_MEMBER(0x0, char, data[1]); - DEFINE_MEMBER(0xb, char, short_length); + DEFINE_MEMBER(0x0, char, data[1]); + DEFINE_MEMBER(0xb, char, short_length); - const MinimumSize<12> __size; - }; + const MinimumSize<12> __size; + }; - public: - // This has to be const until strings can allocate... - operator const std::string() const { - auto copy = *this; + public: + // This has to be const until strings can allocate... + operator const std::string() const { + auto copy = *this; - auto is_short = -1 < copy.short_length; - if (!is_short) { - copy.text = kMemory.to_outside(text); - // TODO: Probably offset capacity too. + auto is_short = -1 < copy.short_length; + if (!is_short) { + copy.text = kMemory.to_outside(text); + // TODO: Probably offset capacity too. + } + + return *reinterpret_cast(©); } - return *reinterpret_cast(©); - } + friend std::ostream &operator<<(std::ostream &os, const String &str) { + const std::string conv = str; + os << conv; + return os; + } + }; - friend std::ostream& operator<<(std::ostream& os, const String& str) { - const std::string conv = str; - os << conv; - return os; - } -}; + typedef unsigned long long MoverID; -typedef unsigned long long MoverID; + static_assert(sizeof(String) == sizeof(std::string), + "String needs to be the same size as std::string"); -static_assert(sizeof(String) == sizeof(std::string), - "String needs to be the same size as std::string"); + template + class __attribute__((packed)) Vector { + // const Pointer& begin_; + // const Pointer& end_; + // const Pointer& capacity_; + Pointer begin_; + Pointer end_; + Pointer capacity_; -template -class __attribute__((packed)) Vector { - // const Pointer& begin_; - // const Pointer& end_; - // const Pointer& capacity_; - Pointer begin_; - Pointer end_; - Pointer capacity_; + Vector() : begin_(nullptr), end_(nullptr), capacity_(nullptr) {} - Vector() : begin_(nullptr), end_(nullptr), capacity_(nullptr) { } + public: + typedef T *iterator; + typedef const T *const_iterator; - public: - typedef T* iterator; - typedef const T* const_iterator; + // This has to be const until strings can allocate... + T *begin() const { + return static_cast(begin_); + } - // This has to be const until strings can allocate... - T* begin() const { - return static_cast(begin_); - } + T *end() const { + return static_cast(end_); + } - T* end() const { - return static_cast(end_); - } + // friend std::ostream& operator<<(std::ostream& os, const String& str) { + // const std::string conv = str; + // os << conv; + // return os; + // } + }; - // friend std::ostream& operator<<(std::ostream& os, const String& str) { - // const std::string conv = str; - // os << conv; - // return os; - // } -}; - -static_assert(sizeof(Vector) == sizeof(std::vector), - "Vector needs to be the same size as std::vector"); + static_assert(sizeof(Vector) == sizeof(std::vector), + "Vector needs to be the same size as std::vector"); -class HashMap { - -}; + class HashMap { + + }; }; // namespace flyff \ No newline at end of file diff --git a/flyff-api/src/item.h b/flyff-api/src/item.h index 13b7dac..1443df4 100644 --- a/flyff-api/src/item.h +++ b/flyff-api/src/item.h @@ -1,66 +1,135 @@ #pragma once -#include "core.h" - #include +#include "core.h" + namespace flyff { -struct __attribute__((packed)) ItemProperty { - static constexpr uint32_t IK2_FOOD = 14; - static constexpr uint32_t IK3_QUEST = 43; - static constexpr uint32_t COOLDOWN_FOOD = 0x00; - static constexpr uint32_t COOLDOWN_REFRESHER = 0x03; - static constexpr uint32_t COOLDOWN_VITALDRINK = 0x04; + enum class Part : uint32_t { + // Excluded from equipment + Head = 0, + // Excluded from equipment + Hair = 1, + UpperBody = 2, + LowerBody = 3, + Hand = 4, + Foot = 5, + Helmet = 6, + Robe = 7, + Cloak = 8, + OffHand = 9, + MainHand = 10, + Shield = 11, + Mask = 12, + // Exclude from equipment - This is to go after #16, but it has to + // be converted, so I solved it this way. + RIDE = 13, + // Simultaneous output parts up to here + // If you want to increase the number above 16, you must tell xuzhu. + // Otherwise, it's an error. - static constexpr uint32_t RECOVERY_COOLDOWN_INDEX[] = { - 0x03, 0x04, 0x00, 0x00, 0x01 + CAP2 = 14, // Exclude from equipment + UPPER2 = 15, // Exclude from equipment + + // For parts that are not rendered on the actual screen, use 16 or more. + // earrings, rings, etc. + + LOWER2 = 16, + HAND2 = 17, + FOOT2 = 18, + // Installed up to here, but by installing this, other parts are invisible. + // (It's different from Exclusive.) + + // Necklace + NECKLACE1 = 19, + // Ring + RING1 = 20, + RING2 = 21, + // Earrings + EARRING1 = 22, + EARRING2 = 23, + // A space to wear props except necklaces, rings, and earrings + PROPERTY = 24, + // various bullet slots + BULLET = 25, + // Fashion item hat + HAT = 26, + // Fashion Outfits + CLOTH = 27, + // Fashion Gloves + GLOVE = 28, + // Fashion Boots + BOOTS = 29, + // Fashion Cloak + CLOAK2 = 30, }; - union { - DEFINE_MEMBER(0, const flyff::String, model); - DEFINE_MEMBER(12, const uint32_t, id); - - DEFINE_MEMBER(156, const flyff::String, name); - DEFINE_MEMBER(168, const flyff::String, icon); - DEFINE_MEMBER(180, const flyff::String, description); - - // Has to be bigger that 0 to be considered for cooldown. - DEFINE_MEMBER(112, const int32_t, cooldown_time); - - DEFINE_MEMBER(348, const uint32_t, item_kind2); - DEFINE_MEMBER(352, const uint32_t, item_kind3); - - const MinimumSize<456> __size; + enum class ItemKind2 : uint32_t { + Food = 14, + Quest = 25, }; - bool is_food() { - static const uint32_t RECOVERY_SUB_CATEGORY_START = 1400; + enum class ItemKind3 : uint32_t { + CheerStick = 202, + KnuckleHammer = 203, - if(item_kind2 == IK2_FOOD) { - const uint32_t cd = item_kind3 - RECOVERY_SUB_CATEGORY_START; - if(cd < 5) { - return RECOVERY_COOLDOWN_INDEX[cd] == COOLDOWN_FOOD; + Shield = 300, + }; + + + struct __attribute__((packed)) ItemProperty { + static constexpr uint32_t COOLDOWN_FOOD = 0x00; + static constexpr uint32_t COOLDOWN_REFRESHER = 0x03; + static constexpr uint32_t COOLDOWN_VITALDRINK = 0x04; + + static constexpr uint32_t RECOVERY_COOLDOWN_INDEX[] = {0x03, 0x04, 0x00, + 0x00, 0x01}; + + union { + DEFINE_MEMBER(0, const flyff::String, model); + DEFINE_MEMBER(12, const uint32_t, id); + + DEFINE_MEMBER(244, const uint32_t, required_level); + + DEFINE_MEMBER(156, const flyff::String, name); + DEFINE_MEMBER(168, const flyff::String, icon); + DEFINE_MEMBER(180, const flyff::String, description); + + // Has to be bigger that 0 to be considered for cooldown. + DEFINE_MEMBER(112, const int32_t, cooldown_time); + + DEFINE_MEMBER(348, const ItemKind2, item_kind2); + DEFINE_MEMBER(352, const ItemKind3, item_kind3); + + const MinimumSize<456> size; + }; + + bool is_food() const { + static const uint32_t RECOVERY_SUB_CATEGORY_START = 1400; + + if (item_kind2 == ItemKind2::Food) { + const uint32_t cd = static_cast(item_kind3) - RECOVERY_SUB_CATEGORY_START; + if (cd < 5) { + return RECOVERY_COOLDOWN_INDEX[cd] == COOLDOWN_FOOD; + } } + + return false; } - return false; - } - - bool is_quest() { - return item_kind3 == IK3_QUEST; - } -}; - -struct __attribute__((packed)) InventoryItem { - union { - DEFINE_MEMBER(36, Pointer, property); - - DEFINE_MEMBER(60, int32_t, index); - DEFINE_MEMBER(64, uint32_t, quantity); - - const MinimumSize<96> __size; + bool is_quest() const { return item_kind2 == ItemKind2::Quest; } + }; + + struct __attribute__((packed)) InventoryItem { + union { + DEFINE_MEMBER(36, Pointer, property); + + DEFINE_MEMBER(60, int32_t, index); + DEFINE_MEMBER(64, uint32_t, quantity); + + const MinimumSize<96> size; + }; }; -}; } // namespace flyff \ No newline at end of file diff --git a/flyff-client/src/client.c b/flyff-client/src/client.c index e417080..df50119 100644 --- a/flyff-client/src/client.c +++ b/flyff-client/src/client.c @@ -681,7 +681,7 @@ static void w2c_f436(u32, u32, u32); static u32 w2c_f437(u32); static void w2c_f438(u32); static void w2c_f439(u32, u32); -static u32 w2c_f440(u32, u32); +u32 w2c_f440(u32, u32); static void w2c_f441(u32, u64, u64, u64, u64); static void w2c_f442(u32, u32, u32, u32); static u32 w2c_f443(u32, u32, u32, u32, u32); @@ -122491,7 +122491,7 @@ static void w2c_f439(u32 w2c_p0, u32 w2c_p1) { FUNC_EPILOGUE; } -static u32 w2c_f440(u32 w2c_p0, u32 w2c_p1) { +u32 w2c_f440(u32 w2c_p0, u32 w2c_p1) { u32 w2c_l2 = 0, w2c_l3 = 0, w2c_l4 = 0, w2c_l5 = 0, w2c_l6 = 0, w2c_l7 = 0, w2c_l8 = 0; FUNC_PROLOGUE; u32 w2c_i0, w2c_i1, w2c_i2, w2c_i3; diff --git a/fugg-client/CMakeLists.txt b/fugg-client/CMakeLists.txt index 6738c72..35addd4 100644 --- a/fugg-client/CMakeLists.txt +++ b/fugg-client/CMakeLists.txt @@ -9,7 +9,7 @@ add_executable( "src/export/embind.cpp" "src/export/env.cpp" "src/export/platform.cpp" -) + src/Bot.cpp src/Bot.h src/Action.h) # Flyff is based on c++14 add_definitions(-std=c++14 -Os) diff --git a/fugg-client/src/client.cpp b/fugg-client/src/client.cpp index 8fd9b9f..5700dcc 100644 --- a/fugg-client/src/client.cpp +++ b/fugg-client/src/client.cpp @@ -5,32 +5,31 @@ #include #include -namespace fugg -{ +namespace fugg { } -constexpr const uint32_t hash_to_id(const uint32_t hashed) { +constexpr const uint32_t hash_to_id(const uint32_t hashed) { return hashed ^ flyff::PACKET_HEADER_HASH; } template -void packet_push(std::vector& packet, const T& value, std::vector::iterator offset) { +void packet_push(std::vector &packet, const T &value, std::vector::iterator offset) { union ToBytes { T value; - uint8_t bytes[sizeof(T)]; + uint8_t bytes[sizeof(T)]; }; - ToBytes ref = { value }; + ToBytes ref = {value}; packet.insert(offset, std::begin(ref.bytes), std::end(ref.bytes)); } template -void packet_push(std::vector& packet, const T& value) { +void packet_push(std::vector &packet, const T &value) { return packet_push(packet, value, std::end(packet)); } -void send_packet(const uint32_t& id, std::vector payload) { +void send_packet(const uint32_t &id, std::vector payload) { const uint32_t header = id < 0x400 ? id : id ^ flyff::PACKET_HEADER_HASH; // Add header packet_push(payload, header, std::begin(payload)); @@ -40,22 +39,22 @@ void send_packet(const uint32_t& id, std::vector payload) { uintptr_t end; uintptr_t capacity; }; - - auto raw_payload = reinterpret_cast(&payload); + + auto raw_payload = reinterpret_cast(&payload); // Copy the message into a new ptr - auto payload_ = std::unique_ptr(new Vector { - .begin = fugg::RuntimePointer(raw_payload->begin).as_raw(), - .end = fugg::RuntimePointer(raw_payload->end).as_raw(), - .capacity = fugg::RuntimePointer(raw_payload->capacity).as_raw() + auto payload_ = std::unique_ptr(new Vector{ + .begin = fugg::RuntimePointer(raw_payload->begin).as_raw(), + .end = fugg::RuntimePointer(raw_payload->end).as_raw(), + .capacity = fugg::RuntimePointer(raw_payload->capacity).as_raw() }); flyff::api::finalize_packet( - fugg::RuntimePointer(payload_.get()).as_raw() + fugg::RuntimePointer(payload_.get()).as_raw() ); flyff::api::websocket_send( - payload_->begin, - payload_->end - payload_->begin + payload_->begin, + payload_->end - payload_->begin ); } @@ -74,7 +73,7 @@ void send_logout() { #include -void move_item_in_inventory(const uint32_t& from_slot, const uint32_t& to_slot) { +void move_item_in_inventory(const uint32_t &from_slot, const uint32_t &to_slot) { std::vector packet; packet_push(packet, from_slot); @@ -83,7 +82,7 @@ void move_item_in_inventory(const uint32_t& from_slot, const uint32_t& to_slot) send_packet(0x2001, packet); } -void use_item_in_inventory(const uint32_t& slot) { +void use_item_in_inventory(const uint32_t &slot) { std::vector packet; packet_push(packet, slot); @@ -93,51 +92,60 @@ void use_item_in_inventory(const uint32_t& slot) { send_packet(0x410, packet); } -using MotionParam = unsigned long long; +struct MotionPacketParams { + unsigned long long param0 = 0; + unsigned long long param1 = 0; + unsigned long long param2 = 0; + unsigned long long param3 = 0; +}; void send_motion_packet( - const uint32_t& action, - MotionParam param0 = 0, - MotionParam param1 = 0, - MotionParam param2 = 0, - MotionParam param3 = 0 + const uint32_t &action, + MotionPacketParams params, + uint32_t server_tick_delta = 0 ) { const int32_t motion_packet_id = 0x404; - const auto& neuz = flyff::Neuz::instance(); + const auto &neuz = flyff::Neuz::instance(); - if(!neuz.player) return; + if (!neuz.player) return; std::vector packet; uint8_t param_flags = 0; - if(param0 != 0) param_flags |= 1; - if(param1 != 0) param_flags |= 2; - if(param2 != 0) param_flags |= 4; - if(param3 != 0) param_flags |= 8; + if (params.param0 != 0) param_flags |= 1; + if (params.param1 != 0) param_flags |= 2; + if (params.param2 != 0) param_flags |= 4; + if (params.param3 != 0) param_flags |= 8; packet_push(packet, neuz.player->position); packet_push(packet, action); packet_push(packet, param_flags); - packet_push(packet, neuz.player->server_tick); + packet_push(packet, neuz.player->server_tick + server_tick_delta); - if(param0 != 0) packet_push(packet, param0); - if(param1 != 0) packet_push(packet, param1); - if(param2 != 0) packet_push(packet, param2); - if(param3 != 0) packet_push(packet, param3); + if (params.param0 != 0) packet_push(packet, params.param0); + if (params.param1 != 0) packet_push(packet, params.param1); + if (params.param2 != 0) packet_push(packet, params.param2); + if (params.param3 != 0) packet_push(packet, params.param3); send_packet(motion_packet_id, packet); } -void set_target(const unsigned long long& id) { - send_motion_packet(0x04, id); +void set_target(const unsigned long long &id) { + send_motion_packet(0x04, {id}); } void clear_target() { - send_motion_packet(0x04); + send_motion_packet(0x04, {}); } -void interact_target(const unsigned long long& index) { - send_motion_packet(0x11, index); +void interact_target(const unsigned long long &index) { + send_motion_packet(0x11, {index}); +} + +void use_skill(unsigned long long id, uint32_t server_tick_delta = 0) { + static constexpr unsigned long long param1 = -1; + + send_motion_packet(0x5, {id, param1}, server_tick_delta); } // void move_to(const float& x, const float& y, const float& z) { @@ -151,14 +159,14 @@ void interact_target(const unsigned long long& index) { // ); // } -void write_chat_message(const std::string& message) { +void write_chat_message(const std::string &message) { // 00 94 4A 64 [0B 00 00 00] [48 65 6C 6C 6F 20 77 6F 72 6C 64] 00 00 00 00 00 00 00 00 std::vector packet; // Message length packet_push(packet, message.length()); // Write message - for(const auto& character : message) { + for (const auto &character: message) { packet_push(packet, character); } // Unknown 1 @@ -169,53 +177,223 @@ void write_chat_message(const std::string& message) { send_packet(0x2000, packet); } +flyff::Pointer find_skill_buff(const flyff::Pointer &mover, uint32_t skill_index) { + for (const auto &buff: mover->buffs) { + if (buff->get_type() == flyff::Mover::Buff::BUFF_SKILL) { + auto skill_property = reinterpret_cast( + static_cast(buff->property) + ); + + if (!buff->is_removed && skill_property->id == skill_index) + return buff; + } + } + + return flyff::Pointer(nullptr); +} + +template +std::vector check_rebuff(const flyff::Pointer &player, const uint32_t (&buffs_to_check)[size]) { + const auto &neuz = flyff::Neuz::instance(); + + auto result = std::vector(); + for (const auto &skill_index: buffs_to_check) { + const auto &buff = find_skill_buff(player, skill_index); + const auto &skill_property = neuz.get_skill_property(skill_index); + // If a buff is active + if (buff) { + auto player_skill_level = player->get_skill_level(skill_index); + // For some reason it's one off... + auto current_skill_level = buff->level + 1; + auto buff_property = reinterpret_cast( + static_cast(buff->property) + ); + + if (player_skill_level > current_skill_level) { + // Always apply a higher buff. + result.push_back(skill_index); + } else if (buff->get_time_remaining() < 30 * 1000 && player_skill_level >= current_skill_level) { + // Refresh the buff. + result.push_back(skill_index); + } + } else { + // Apply the buff. + result.push_back(skill_index); + } + } + + return result; +} + +flyff::Pointer find_first_equippable_item(const flyff::ItemKind3& item_kind) { + const auto &neuz = flyff::Neuz::instance(); + const auto &player = neuz.player; + + uint32_t highest_level = 0; + flyff::InventoryItem const *highest = nullptr; + for (const auto &item: player->inventory) { + const auto &prop = item.property; + + if (item.index < 168 && prop && prop->item_kind3 == item_kind && prop->required_level <= player->get_level() && + prop->required_level > highest_level) { + highest = &item; + highest_level = prop->required_level; + } + } + + return flyff::Pointer(highest); +} + + bool is_running = false; -flyff::Vector3 start_position = { 0 }; -void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent* event, void* user_data) { - const auto& neuz = flyff::Neuz::instance(); +flyff::Vector3 start_position = {0}; +// The object property index of the monster to grind. +int object_property_index = 0; + +void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent *event, void *user_data) { + const auto &neuz = flyff::Neuz::instance(); + + if (event->keyCode == 220) { + +// if (!main_hand || main_hand->item_kind3 != flyff::ItemProperty::CheerStick) { +// const auto &stick = find_first_equippable_item(flyff::ItemProperty::CheerStick); +// +// if (stick) { +// std::string str = "Found valid cheerstick: "; +// str.append(neuz.get_text(stick->property->name)); +// neuz.show_message(str, {0, 0xFF, 0}); +// +// use_item_in_inventory(stick->index); +// } +// } + // std::cout << reinterpret_cast(static_cast(main_hand)) << " Weapon is required level: " << main_hand->required_level << std::endl; + + // auto length = ((uintptr_t)player->buffs.end() - (uintptr_t)player->buffs.begin()) / 4; + // std::cout << length << " buffs!" << std::endl;; + // for(const auto& test : player->buffs) { + // std::cout << "Buff with type " << test->get_type() << " and id " << reinterpret_cast(test->get_id()) << std::endl; + + // if(test->get_type() == flyff::Mover::Buff::BUFF_SKILL) { + // auto skill_property = reinterpret_cast( + // static_cast(test->property) + // ); + + // std::cout << "BuffSkill " + // << neuz.get_text(skill_property->name) + // << " ReqLv. " << skill_property->required_level + // << " Lv." << skill_property->level + // << " Id: " << reinterpret_cast(skill_property->id) + // << " Remaining: " << (test->get_time_remaining() / 1000) + // << std::endl; + // } + // } + + // + // clear_target(); + // auto items = player->inventory.begin(); + // auto length = ((uintptr_t)player->inventory.end() - (uintptr_t)player->inventory.begin()) / 0x60; + + // static constexpr int max_inventory_size = 168; + // static constexpr int slot_weapon = max_inventory_size + 10; + + // int stick_index = -1; + // if(items[slot_weapon].index != -1 && + // items[slot_weapon].property && + // items[slot_weapon].property->item_kind3 == flyff::ItemProperty::CheerStick) { + // stick_index = slot_weapon; + // } else { + // for(auto i = 0; i < length; i++) { + // if(items[i].index != -1 && items[i].property) { + // // if(items[i].index < 168) InventoryItem + // // else Equipped + + // // std::cout << items[i].index << std::endl; + // std::cout << neuz.get_text(items[i].property->name) << " at " << items[i].index << ": " + // << "IK2=" << items[i].property->item_kind2 << ", " + // << "IK3=" << items[i].property->item_kind3 + // << std::endl; + + // if(items[i].property->item_kind3 == flyff::ItemProperty::CheerStick) { + // stick_index = i; + // break; + // } + // } + // } + + // if(stick_index != -1) { + // // Switch main_hand + // use_item_in_inventory(stick_index); + // } + // } + + // if(stick_index != -1) { + // // Use skill Heal + // use_skill(0x2c, 10); + // } else { + // neuz.show_message("Could not find a stick to heal myself.", { 0xFF, 0, 0 }); + // } + } // BracketLeft - if(event->keyCode == 219 && is_running == false) { - if(!neuz.player) + if (event->keyCode == 219 && !is_running) { + if (!neuz.player) return; - start_position = { neuz.player->position.x, neuz.player->position.y, neuz.player->position.z }; + if (neuz.player->selected_target == 0) { + neuz.show_message("No monster selected, unable to start bot.", {0xFF, 0, 0}); + return; + } + + auto target = neuz.get_mover(neuz.player->selected_target); + if (!target) { + neuz.show_message("No monster selected, unable to start bot.", {0xFF, 0xFF, 0}); + return; + } + + std::string str = "I'm only going to kill "; + str.append(neuz.get_text(target->name)); + str.append("get_level())); + str.append(">"); + neuz.show_message(str); + + object_property_index = target->property_id; + start_position = {neuz.player->position.x, neuz.player->position.y, neuz.player->position.z}; std::cout << "Start botting at " << start_position << std::endl; - is_running = true; + is_running = true; - neuz.show_message("Bot started"); - } + neuz.show_message("Bot started"); + } - if(event->keyCode == 221) { - if(is_running == true) { - is_running = false; + if (event->keyCode == 221) { + if (is_running) { + is_running = false; neuz.show_message("Bot stopped"); } else { - if(!neuz.player) return; + if (!neuz.player) return; - const auto& player = *neuz.player; - - neuz.show_announcement("Hello world!", { 0xFF, 0, 0 }); + neuz.show_announcement("Hello world!", {0xFF, 0, 0}); auto current = neuz.movers.first; do { - const auto& mover = current->mover; + const auto &mover = current->mover; - if(mover->type == ObjectType::Mover) { + if (mover->type == ObjectType::Mover) { // int level = mover->get_level(); - std::cout << neuz.get_text(mover->name) << " get_level() << ">): " + std::cout << neuz.get_text(mover->name) << " get_level() << ">): " << (mover->is_dead() ? "Dead" : "Not dead") << ", " << (mover->is_fly() ? "Flying" : "Not flying") << ", " << (mover->is_jumping() ? "Jumping" : "Not jumping") << ", " - << (mover->is_moving() ? "Moving" : "Not moving") + << (mover->is_moving() ? "Moving" : "Not moving") + << (mover->is_grounded ? "On ground" : "Flying") << std::endl; } current = current->next; - } while(current); + } while (current); // auto items = player.inventory.begin(); // auto length = ((uintptr_t)player.inventory.end() - (uintptr_t)player.inventory.begin()) / 0x60; @@ -238,11 +416,11 @@ void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent* event, void* u } } -flyff::MoverID attack_next_target(flyff::Vector3 const& start_position) { - auto& neuz = flyff::Neuz::instance(); +flyff::MoverID attack_next_target(flyff::Vector3 const &start_position) { + auto &neuz = flyff::Neuz::instance(); + + if (!neuz.player) return 0; - if(!neuz.player) return 0; - // Found in the code somewhere. static constexpr float max_distance = 144.; @@ -251,35 +429,34 @@ flyff::MoverID attack_next_target(flyff::Vector3 const& start_position) { auto current = neuz.movers.first; do { - const auto& mover = current->mover; + const auto &mover = current->mover; - auto dx = std::abs(mover->position.x - start_position.x); - auto dy = std::abs(mover->position.y - start_position.y); - auto dz = std::abs(mover->position.z - start_position.z); + auto dx = std::abs(mover->position.x - neuz.player->position.x); + auto dy = std::abs(mover->position.y - neuz.player->position.y); + auto dz = std::abs(mover->position.z - neuz.player->position.z); auto squared = (dx * dx) + (dy * dy) + (dz * dz); auto d = std::sqrt(squared); - if(mover->type == ObjectType::Mover && - current->hash != neuz.player_object_id && + if (mover->type == ObjectType::Mover && + current->hash != neuz.player_object_id && !mover->is_dead() && + // Only attack ground mobs. + mover->is_grounded && + // Only attack same mobs. + mover->property_id == object_property_index && d <= max_distance) { - // If it's a monster that has me targetted - if(mover->last_attacked_target == neuz.player_object_id) { - closest = mover; - std::cout << mover->name << " has attacked me, so I'm attacking" << std::endl; - break; - } else if(d < lowest_distance) { + if (d < lowest_distance) { closest = mover; lowest_distance = d; } } current = current->next; - } while(current); + } while (current); - if(closest) { + if (closest) { neuz.player->selected_target = closest->object_id; set_target(closest->object_id); @@ -287,70 +464,57 @@ flyff::MoverID attack_next_target(flyff::Vector3 const& start_position) { interact_target(1); return closest->object_id; - } + } return 0; } flyff::MoverID find_next_item() { - const auto& neuz = flyff::Neuz::instance(); + const auto &neuz = flyff::Neuz::instance(); - if(!neuz.player) return 0; - auto& player = *neuz.player; + if (!neuz.player) return 0; float lowest_distance = 32.f; auto closest = flyff::Pointer(nullptr); auto current = neuz.movers.first; do { - const auto& mover = current->mover; + const auto &mover = current->mover; - auto dx = std::abs(mover->position.x - player.position.x); - auto dz = std::abs(mover->position.z - player.position.z); + auto dx = std::abs(mover->position.x - neuz.player->position.x); + auto dz = std::abs(mover->position.z - neuz.player->position.z); auto squared = (dx * dx) + (dz * dz); auto d = std::sqrt(squared); - if(mover->world != 0 && + if (mover->world != 0 && !mover->is_despawned && mover->type == ObjectType::Item && d <= lowest_distance) { - - flyff::ItemProperty* prop = reinterpret_cast( - static_cast(mover->property) + + auto *prop = reinterpret_cast( + static_cast(mover->property) ); - if(prop->is_quest()) { - std::string str = "Skipping "; - str.append(neuz.get_text(prop->name)); - str.append(" because is quest item."); - - neuz.show_message(str); - } else { + if (!prop->is_quest()) { closest = mover; lowest_distance = d; - - std::string str = ""; - str.append(neuz.get_text(prop->name)); - str.append(" is close."); - - neuz.show_message(str); } } current = current->next; - } while(current); + } while (current); - if(closest) + if (closest) return closest->object_id; else return 0; } void interact(flyff::MoverID id) { - const auto& neuz = flyff::Neuz::instance(); + const auto &neuz = flyff::Neuz::instance(); - if(!neuz.player) + if (!neuz.player) return; neuz.player->selected_target = id; @@ -364,9 +528,9 @@ flyff::MoverID current_target = 0; flyff::MoverID current_pickup_item = 0; void bot_tick() { - const auto& neuz = flyff::Neuz::instance(); + const auto &neuz = flyff::Neuz::instance(); - if(!neuz.player) + if (!neuz.player) return; // std::cout << "Max Max HP: " @@ -379,78 +543,167 @@ void bot_tick() { // printf("%#010x\n", neuz.player->get_state()); - if(is_running) { - if(neuz.player->is_dead()) { + if (is_running) { + if (neuz.player->is_dead()) { neuz.show_message("Player is dead, stopping...", {0xFF, 0x00, 0x00}); is_running = false; return; } + const auto &player = neuz.player; + // if is_idle: // if item_target: // pickup_item() // elif attacK_target: // attack_target() - if(neuz.player->get_hp_percent() < 75) { + if (neuz.player->get_hp_percent() < 75) { // neuz.show_message("Fooding because HP is under 75%"); - const auto& player = neuz.player; + const auto &player = neuz.player; auto items = player->inventory.begin(); - auto length = ((uintptr_t)player->inventory.end() - (uintptr_t)player->inventory.begin()) / 0x60; + auto length = ((uintptr_t) player->inventory.end() - (uintptr_t) player->inventory.begin()) / 0x60; - for(auto i = 0; i < length; i++) { - if(items[i].index != -1 && + for (auto i = 0; i < length; i++) { + if (items[i].index != -1 && items[i].property && - items[i].property->is_food() && + items[i].property->is_food() && player->can_use_item(items[i].property)) { std::string str = "Eating "; str.append(neuz.get_text(items[i].property->name)); str.append(" because HP is below 75%"); neuz.show_message(str); - + use_item_in_inventory(i); break; } - } - } + } + } - if(neuz.player->get_move_state() == 1 && + if (neuz.player->get_move_state() == 1 && !neuz.player->is_attacking()) { + + + // Check buffs. + static constexpr uint32_t buffs_to_check[] = { + flyff::SkillIndex::HeapUp, + flyff::SkillIndex::Haste, + flyff::SkillIndex::Patience + }; + auto item = neuz.get_mover(current_pickup_item); auto monster = neuz.get_mover(current_target); - if(item && !item->is_despawned && neuz.player->move_toward_target == 0) { + const auto &main_hand = player->get_equipped_item(flyff::Part::MainHand); + const auto &off_hand = player->get_equipped_item(flyff::Part::Shield); + + auto buffs = check_rebuff(neuz.player, buffs_to_check); + if (!buffs.empty() && (!item || item->is_despawned) && (!monster || monster->is_dead())) { + const auto next_buff = buffs.back(); + if (!main_hand || main_hand->item_kind3 != flyff::ItemKind3::CheerStick) { + const auto &stick = find_first_equippable_item(flyff::ItemKind3::CheerStick); + + if (stick) { + buffs.pop_back(); + + use_item_in_inventory(stick->index); + use_skill(next_buff); + return; + } else { + neuz.show_message("Unable to find a stick", {0xFF, 0, 0}); + } + } else { + buffs.pop_back(); + use_skill(next_buff); + return; + } + } + + if (buffs.empty()) { + if (!main_hand || main_hand->item_kind3 != flyff::ItemKind3::KnuckleHammer) { + const auto &knuckle = find_first_equippable_item(flyff::ItemKind3::KnuckleHammer); + + if (knuckle) { + use_item_in_inventory(knuckle->index); + } else { + neuz.show_message("Unable to find a knuckle", {0xFF, 0, 0}); + } + } + + if (!off_hand || off_hand->item_kind3 != flyff::ItemKind3::Shield) { + const auto &shield = find_first_equippable_item(flyff::ItemKind3::Shield); + + if (shield) { + use_item_in_inventory(shield->index); + } else { + neuz.show_message("Unable to find a shield", {0xFF, 0, 0}); + } + } + } + + if (item && !item->is_despawned && neuz.player->move_toward_target == 0) { // Pickup interact(item->object_id); - } else if(monster && !monster->is_dead() && neuz.player->move_toward_target == 0) { + } else if (monster && !monster->is_dead() && neuz.player->move_toward_target == 0) { // Attack interact(monster->object_id); // neuz.player->attack_target = monster->object_id; - } else if((!item || item->is_despawned) && - (!monster || monster->is_dead())) { + } else if ((!item || item->is_despawned) && + (!monster || monster->is_dead())) { std::cout << "No item, no target. Searching..." << std::endl; + + // First check all mobs if they attacked me (aggro ones). + auto current = neuz.movers.first; + do { + const auto &mover = current->mover; + + if (mover->type == ObjectType::Mover && + current->hash != neuz.player_object_id && + !mover->is_dead() && + // If it's a monster that has me targetted... + mover->last_attacked_target == neuz.player_object_id && + // ...and is tracking me + mover->follow_target == neuz.player_object_id) { + + current_target = attack_next_target(start_position); + + monster = neuz.get_mover(current_target); + std::string str = "Attacking "; + str.append(monster->name); + str.append(" because it attacked me."); + + interact(monster->object_id); + + neuz.show_message(str); + return; + } + + current = current->next; + } while (current); + // No item target and no attack target current_pickup_item = find_next_item(); item = neuz.get_mover(current_pickup_item); - if(item) { - // flyff::ItemProperty* prop = (flyff::ItemProperty*)static_cast(current_pickup_item->property); + if (item) { + flyff::ItemProperty *prop = reinterpret_cast( + static_cast(item->property) + ); std::string str = "Picking up "; - std::cout << str << std::endl; - // str.append(prop->name); + str.append(neuz.get_text(prop->name)); interact(item->object_id); - + neuz.show_message(str); } else { current_target = attack_next_target(start_position); monster = neuz.get_mover(current_target); - if(monster) { + if (monster) { std::string str = "Attacking "; str.append(monster->name); @@ -458,7 +711,7 @@ void bot_tick() { interact(monster->object_id); // neuz.player->attack_target = monster->object_id; - + neuz.show_message(str); } else { neuz.show_message("Unable to find target."); @@ -466,39 +719,6 @@ void bot_tick() { } } } - - // static constexpr uint32_t PICKUP = flyff::Object::State::AtkAll | flyff::Object::State::Dead; - - // if((current_pickup_item != nullptr && - // !current_pickup_item->is_despawned) || - // (neuz.player->object_state & PICKUP) != 0) { - // // Wait - // std::cout << "ObjectSTate & Pickup = " << reinterpret_cast(neuz.player->object_state & PICKUP) << std::endl; - // } else if(current_target == nullptr) { - // current_pickup_item = pickup_next_item(); - // if(current_pickup_item != nullptr) { - // neuz.show_message("Picking up"); - // return; - // } - - // current_target = attack_next_target(start_position); - - // if(current_target) { - // std::string str = "Attacking "; - // str.append(current_target->name); - - // neuz.show_message(str); - // } else { - // neuz.show_message("Unable to find target."); - // } - // } else if(current_target->is_dead()) { - // current_target = nullptr; - - // current_pickup_item = pickup_next_item(); - // if(current_pickup_item != nullptr) { - // neuz.show_message("Picking up"); - // } - // } } else { // Reset current target is not running. current_target = 0; @@ -515,7 +735,7 @@ void after_main_loop() { // auto& music_properties = fugg::module_ref>(0x00034f7c); // auto& item_properties = fugg::module_ref>(0x00035194); - + // for(auto& item : item_properties) { // std::cout << item.some_string->c_str() << std::endl; // } @@ -579,10 +799,10 @@ void after_main_loop() { // } // auto test = reinterpret_cast*>(0x00035194); - - - - + + + + // std::cout << "Test is at " << reinterpret_cast(test->to_intptr_t()) << std::endl; diff --git a/fugg-client/src/export/al.cpp b/fugg-client/src/export/al.cpp index 3154b7e..00a1f5e 100644 --- a/fugg-client/src/export/al.cpp +++ b/fugg-client/src/export/al.cpp @@ -7,175 +7,177 @@ #include #include +#include #define TRACE_AL_CALLS 0 /* import: 'a' 'u' */ // "u": "_alSourcef", -WASM_IMPORT_IMPL(env, _alSourcef) = [](u32 a, u32 b, f32 c) { +WASM_IMPORT_IMPL(env, _alSourcef) = [](u32 source, u32 param, f32 value) { #if TRACE_AL_CALLS std::cout << "_alSourcef(" - << a << ", " - << b << ", " - << c - << ")" << std::endl; -#endif - - alSourcef(a, b, c); -}; -// "w": "_alSourcei", -WASM_IMPORT_IMPL(env, _alSourcei) = [](u32 a, u32 b, u32 c) { -#if TRACE_AL_CALLS - std::cout << "_alSourcei(" - << a << ", " - << b << ", " - << c - << ")" << std::endl; -#endif - - alSourcei(a, b, c); -}; -/* import: 'a' 'F' */ -/* _alSourceStop*/ -WASM_IMPORT_IMPL(env, _alSourceStop) = [](u32 a) { -#if TRACE_AL_CALLS - std::cout << "_alSourceStop(" - << a - << ")" << std::endl; -#endif - - alSourceStop(a); -}; -// "L": "_alGetSourcei", -WASM_IMPORT_IMPL(env, _alGetSourcei) = [](u32 a, u32 b, u32 c) { - const auto& value = fugg::ModulePointer { c }; - -#if TRACE_AL_CALLS - std::cout << "_alGetSourcei(" - << a << ", " - << b << ", " + << source << ", " + << param << ", " << value << ")" << std::endl; #endif - alGetSourcei(a, b, value); + alSourcef(source, static_cast(param), value); +}; +// "w": "_alSourcei", +WASM_IMPORT_IMPL(env, _alSourcei) = [](u32 source, u32 param, u32 value) { +#if TRACE_AL_CALLS + std::cout << "_alSourcei(" + << source << ", " + << param << ", " + << value + << ")" << std::endl; +#endif + + alSourcei(source, static_cast(param), static_cast(value)); +}; +/* import: 'a' 'F' */ +/* _alSourceStop*/ +WASM_IMPORT_IMPL(env, _alSourceStop) = [](u32 source) { +#if TRACE_AL_CALLS + std::cout << "_alSourceStop(" + << source + << ")" << std::endl; +#endif + + alSourceStop(source); +}; +// "L": "_alGetSourcei", +WASM_IMPORT_IMPL(env, _alGetSourcei) = [](u32 source, u32 param, u32 c) { + const auto &value = flyff::Pointer{c}; + +#if TRACE_AL_CALLS + std::cout << "_alGetSourcei(" + << source << ", " + << param << ", " + << value + << ")" << std::endl; +#endif + + alGetSourcei(source, static_cast(param), static_cast(value)); }; /* import: 'a' 'Q' */ // "Q": "_alDeleteSources" -WASM_IMPORT_IMPL(env, _alDeleteSources) = [](u32 a, u32 b) { - const auto& sources = fugg::ModulePointer { b }; +WASM_IMPORT_IMPL(env, _alDeleteSources) = [](u32 n, u32 b) { + const auto &sources = flyff::Pointer{b}; #if TRACE_AL_CALLS std::cout << "_alDeleteSources(" - << a << ", " + << n << ", " << sources << ")" << std::endl; #endif - alDeleteSources(a, sources); + alDeleteSources(static_cast(n), static_cast(sources)); }; /* _alSource3f */ -WASM_IMPORT_IMPL(env, _alSource3f) = [](u32 a, u32 b, f32 c, f32 d, f32 e) { +WASM_IMPORT_IMPL(env, _alSource3f) = [](u32 source, u32 param, f32 value1, f32 value2, f32 value3) { #if TRACE_AL_CALLS std::cout << "_alSource3f(" - << a << ", " - << b << ", " - << c << ", " - << d << ", " - << e + << source << ", " + << param << ", " + << value1 << ", " + << value2 << ", " + << value3 << ")" << std::endl; #endif - alSource3f(a, b, c, d, e); + alSource3f(source, static_cast(param), value1, value2, value3); }; /* import: 'a' 'bb' */ // "bb": "_alSourcePlay", -WASM_IMPORT_IMPL(env, _alSourcePlay) = [](u32 a) { +WASM_IMPORT_IMPL(env, _alSourcePlay) = [](u32 source) { #if TRACE_AL_CALLS std::cout << "_alSourcePlay(" - << a + << source << ")" << std::endl; #endif - alSourcePlay(a); + alSourcePlay(source); }; /* import: 'a' 'cb' */ // "cb": "_alListenerfv", -WASM_IMPORT_IMPL(env, _alListenerfv) = [](u32 a, u32 b) { - const auto& values = fugg::ModulePointer { b }; +WASM_IMPORT_IMPL(env, _alListenerfv) = [](u32 param, u32 b) { + const auto &values = flyff::Pointer{b}; #if TRACE_AL_CALLS std::cout << "_alListenerfv(" - << a << ", " + << param << ", " << values << ")" << std::endl; #endif - alListenerfv(a, values); + alListenerfv(static_cast(param), static_cast(values)); }; /* import: 'a' 'db' */ // "db": "_alListener3f", -WASM_IMPORT_IMPL(env, _alListener3f) = [](u32 a, f32 b, f32 c, f32 d) { +WASM_IMPORT_IMPL(env, _alListener3f) = [](u32 param, f32 value1, f32 value2, f32 value3) { #if TRACE_AL_CALLS std::cout << "_alListener3f(" - << a << ", " - << b << ", " - << c << ", " - << d + << param << ", " + << value1 << ", " + << value2 << ", " + << value3 << ")" << std::endl; #endif - alListener3f(a, b, c, d); + alListener3f(static_cast(param), value1, value2, value3); }; /* import: 'a' 'Sb' */ /* _alDeleteBuffers */ -WASM_IMPORT_IMPL(env, _alDeleteBuffers) = [](u32 a, u32 b) { - const auto& buffers = fugg::ModulePointer { b }; +WASM_IMPORT_IMPL(env, _alDeleteBuffers) = [](u32 n, u32 b) { + const auto &buffers = flyff::Pointer{b}; #if TRACE_AL_CALLS std::cout << "_alDeleteBuffers(" - << a << ", " + << n << ", " << buffers << ")" << std::endl; #endif - alDeleteBuffers(a, buffers); + alDeleteBuffers(static_cast(n), static_cast(buffers)); }; /* import: 'a' 'Tb' */ /* _alBufferData */ -WASM_IMPORT_IMPL(env, _alBufferData) = [](u32 a, u32 b, u32 c, u32 d, u32 e) { - const auto& data = fugg::ModulePointer { c }; +WASM_IMPORT_IMPL(env, _alBufferData) = [](u32 buffer, u32 format, u32 c, u32 size, u32 freq) { + const auto &data = flyff::Pointer{c}; #if TRACE_AL_CALLS std::cout << "_alBufferData(" - << a << ", " - << b << ", " + << buffer << ", " + << format << ", " << data << ", " - << d << ", " - << e + << size << ", " + << freq << ")" << std::endl; #endif - alBufferData(a, b, data, d, e); + alBufferData(buffer, static_cast(format), static_cast(data), static_cast(size), + static_cast(freq)); }; /* import: 'a' 'Ub' */ // "Ub": "_alGenBuffers", -WASM_IMPORT_IMPL(env, _alGenBuffers) = [](u32 a, u32 b) { - const auto& buffers = fugg::ModulePointer { b }; +WASM_IMPORT_IMPL(env, _alGenBuffers) = [](u32 n, u32 b) { + const auto &buffers = flyff::Pointer{b}; #if TRACE_AL_CALLS std::cout << "_alGenBuffers(" - << a << ", " + << n << ", " << buffers << ")" << std::endl; #endif - alGenBuffers(a, buffers); + alGenBuffers(static_cast(n), static_cast(buffers)); }; /* import: 'a' 'Vb' */ // "Vb": "_alGetEnumValue", WASM_IMPORT_IMPL(env, _alGetEnumValue) = [](u32 a) { - const auto& ename = fugg::ModulePointer { a }; + const auto &ename = flyff::Pointer{a}; #if TRACE_AL_CALLS std::cout << "_alGetEnumValue(" @@ -183,15 +185,13 @@ WASM_IMPORT_IMPL(env, _alGetEnumValue) = [](u32 a) { << ")" << std::endl; #endif - return static_cast( - alGetEnumValue(ename) - ); + return static_cast(alGetEnumValue(static_cast(ename))); }; /* import: 'a' 'Wb' */ // "Wb": "_alcCloseDevice", WASM_IMPORT_IMPL(env, _alcCloseDevice) = [](u32 a) { // ALCdevice is not data, but an index. - const auto& device = reinterpret_cast(a); + const auto &device = reinterpret_cast(a); #if TRACE_AL_CALLS std::cout << "_alcCloseDevice(" @@ -199,41 +199,39 @@ WASM_IMPORT_IMPL(env, _alcCloseDevice) = [](u32 a) { << ")" << std::endl; #endif - return static_cast( - alcCloseDevice(device) - ); + return static_cast(alcCloseDevice(device)); }; /* import: 'a' 'Yb' */ // "Yb": "_alGenSources", -WASM_IMPORT_IMPL(env, _alGenSources) = [](u32 a, u32 b) { - const auto& sources = fugg::ModulePointer { b }; +WASM_IMPORT_IMPL(env, _alGenSources) = [](u32 n, u32 b) { + const auto &sources = flyff::Pointer{b}; #if TRACE_AL_CALLS std::cout << "_alGenSources(" - << a << ", " + << n << ", " << sources << ")" << std::endl; #endif - alGenSources(a, sources); + alGenSources(static_cast(n), static_cast(sources)); }; /* import: 'a' 'Zb' */ // "Zb": "_alListenerf", -WASM_IMPORT_IMPL(env, _alListenerf) = [](u32 a, f32 b) { +WASM_IMPORT_IMPL(env, _alListenerf) = [](u32 param, f32 value) { #if TRACE_AL_CALLS std::cout << "_alListenerf(" - << a << ", " - << b + << param << ", " + << value << ")" << std::endl; #endif - alListenerf(a, b); + alListenerf(static_cast(param), value); }; /* import: 'a' '_b' */ // "_b": "_alcMakeContextCurrent", WASM_IMPORT_IMPL(env, _alcMakeContextCurrent) = [](u32 a) { // ALCcontext is not data, but an index. - const auto& context = reinterpret_cast(a); + const auto &context = reinterpret_cast(a); #if TRACE_AL_CALLS std::cout << "_alcMakeContextCurrent(" @@ -241,16 +239,14 @@ WASM_IMPORT_IMPL(env, _alcMakeContextCurrent) = [](u32 a) { << ")" << std::endl; #endif - return static_cast( - alcMakeContextCurrent(context) - ); + return static_cast(alcMakeContextCurrent(context)); }; /* import: 'a' '$b' */ /* _alcCreateContext */ WASM_IMPORT_IMPL(env, _alcCreateContext) = [](u32 a, u32 b) { // ALCdevice is not data, but an index. - const auto& device = reinterpret_cast(a); - const auto& attr_list = fugg::ModulePointer { b }; + const auto &device = reinterpret_cast(a); + const auto &attr_list = fugg::ModulePointer{b}; #if TRACE_AL_CALLS std::cout << "_alcCreateContext(" @@ -259,15 +255,13 @@ WASM_IMPORT_IMPL(env, _alcCreateContext) = [](u32 a, u32 b) { << ")" << std::endl; #endif - return reinterpret_cast( - alcCreateContext(device, attr_list) - ); + return reinterpret_cast(alcCreateContext(device, attr_list)); }; /* import: 'a' 'Xb' */ // "Xb": "_alcDestroyContext", WASM_IMPORT_IMPL(env, _alcDestroyContext) = [](u32 a) { // ALCcontext is not data, but an index. - const auto& context = reinterpret_cast(a); + const auto &context = reinterpret_cast(a); #if TRACE_AL_CALLS std::cout << "_alcDestroyContext(" @@ -280,7 +274,7 @@ WASM_IMPORT_IMPL(env, _alcDestroyContext) = [](u32 a) { /* import: 'a' 'ac' */ // "ac": "_alcOpenDevice", WASM_IMPORT_IMPL(env, _alcOpenDevice) = [](u32 a) { - const auto& devicename = fugg::ModulePointer { a }; + const auto &devicename = flyff::Pointer{a}; #if TRACE_AL_CALLS std::cout << "_alcOpenDevice(" @@ -288,7 +282,5 @@ WASM_IMPORT_IMPL(env, _alcOpenDevice) = [](u32 a) { << ")" << std::endl; #endif - return reinterpret_cast( - alcOpenDevice(devicename) - ); + return reinterpret_cast(alcOpenDevice(static_cast(devicename))); }; \ No newline at end of file