All functionality restored for 1.1.3

This commit is contained in:
Knaapchen 2022-10-14 15:36:02 +02:00
parent 35aabe59bf
commit ee2608a460
7 changed files with 103 additions and 237 deletions

View File

@ -24,10 +24,6 @@ namespace flyff {
// static_assert(sizeof(fugg::ModulePointer<void>) == sizeof(u32), "ModulePointer needs the same size as u32");
extern "C" {
// Translate
// extern void translate(u32, u32);
// extern void w2c_f167(fugg::String*, std::string*);
// show_message
// f2300_finalize_packet: Encrypts and constructs a packet for wire.
extern void w2c_f2303(u32);
// f2296_websocket_send: Sends a packet over the WebSocket connection.

View File

@ -103,15 +103,15 @@ struct __attribute__((packed)) Mover {
struct MoverMap {
struct __attribute__((packed)) Node {
Pointer<Node> next;
const Pointer<const Node> next;
unsigned int list_index;
unsigned long long hash;
Pointer<Mover> mover;
};
Pointer<uintptr_t> buckets;
const Pointer<const uintptr_t> buckets;
size_t capacity;
Pointer<Node> first;
const Pointer<const Node> first;
};
}; // namespace flyff

View File

@ -11,9 +11,10 @@ namespace raw {
static const uintptr_t& WORLD = 0x00036050;
static const uintptr_t& PLAYER = WORLD + 4;
static const uintptr_t& PLAYER_ID = 0x00035090;
static const uintptr_t& PLAYER_OBJECT_ID = 0x00035090;
// The messages that are limited to 5 that are show temporarily.
static const uintptr_t& MESSAGES_UI = 0x00036060;
static const uintptr_t& MOVER_MAP = 0x00033460;
extern "C" {
// get_mover
@ -36,9 +37,10 @@ static const auto& show_message = w2c_f340;
// 5. Post-run
Neuz::Neuz()
: movers(make_ref<MoverMap>(0x00032968)),
: movers(make_ref<MoverMap>(raw::MOVER_MAP)),
player(make_ref<Pointer<Mover>>(raw::PLAYER)),
messages_ui(make_ref<Pointer<uintptr_t>>(raw::MESSAGES_UI)) {}
messages_ui(make_ref<Pointer<uintptr_t>>(raw::MESSAGES_UI)),
player_object_id(make_ref<MoverID>(raw::PLAYER_OBJECT_ID)) {}
Neuz& Neuz::instance() {
static bool initialised = false;

View File

@ -7,6 +7,9 @@
#include "Mover.h"
namespace flyff {
const uint32_t PACKET_HEADER_HASH = 0x644ab000;
namespace raw {
static const auto& init = &Z_client_init;
@ -32,6 +35,7 @@ class Neuz {
MoverMap const& movers;
const Pointer<Mover>& player;
const MoverID& player_object_id;
// Execute the `main` function of the flyff-client.
int main() const;

View File

@ -77,27 +77,15 @@ class __attribute__((packed)) Pointer {
return *this;
}
T* operator->() {
T* operator->() const {
return as_outside();
}
T const* operator->() const {
return as_outside();
}
T& operator*() {
T& operator*() const {
return *as_outside();
}
T const& operator*() const {
return *as_outside();
}
explicit operator T*() {
return as_outside();
}
explicit operator T const*() {
explicit operator T*() const {
return as_outside();
}
@ -163,10 +151,15 @@ static_assert(sizeof(String) == sizeof(std::string),
template<typename T>
class __attribute__((packed)) Vector {
// const Pointer<T>& begin_;
// const Pointer<T>& end_;
// const Pointer<T>& capacity_;
Pointer<T> begin_;
Pointer<T> end_;
Pointer<T> capacity_;
Vector() : begin_(nullptr), end_(nullptr), capacity_(nullptr) { }
public:
typedef T* iterator;
typedef const T* const_iterator;

View File

@ -1048649,12 +1048649,26 @@ void w2c_f2303(u32 w2c_p0) {
FUNC_PROLOGUE;
u32 w2c_i0, w2c_i1, w2c_i2, w2c_i3;
u64 w2c_j1;
w2c_i0 = w2c_p0;
w2c_i0 = i32_load((&w2c_memory), (u64)(w2c_i0) + 4u);
w2c_l4 = w2c_i0;
const uintptr_t end = w2c_l4;
w2c_i1 = w2c_p0;
w2c_i1 = i32_load((&w2c_memory), (u64)(w2c_i1));
w2c_l2 = w2c_i1;
const uintptr_t begin = w2c_l2;
const size_t length = end - begin;
const unsigned char* data = &(&w2c_memory)->data[begin];
printf("Finalizing packet of length %zd: ", length);
for(int i = 0; i < length; i++) {
printf("%02X ", data[i]);
}
printf("\n");
w2c_i0 -= w2c_i1;
w2c_l7 = w2c_i0;
w2c_i0 = 9u;

View File

@ -33,8 +33,7 @@ void packet_push(std::vector<uint8_t>& packet, const T& value) {
}
void send_packet(const uint32_t& id, std::vector<uint8_t> payload) {
const uint32_t header_hash = 0x644ab400;
const uint32_t header = id ^ header_hash;
const uint32_t header = id < 0x400 ? id : id ^ flyff::PACKET_HEADER_HASH;
// Add header
packet_push(payload, header, std::begin(payload));
@ -106,12 +105,9 @@ void send_motion_packet(
MotionParam param3 = 0
) {
const int32_t motion_packet_id = 0x404;
auto& player_pointer = fugg::module_ref<uintptr_t>(0x0003546c);
if(player_pointer == 0)
return;
const auto& neuz = flyff::Neuz::instance();
auto& player = fugg::module_ref<flyff::Mover>(player_pointer);
if(!neuz.player) return;
std::vector<uint8_t> packet;
@ -121,17 +117,17 @@ void send_motion_packet(
if(param2 != 0) param_flags |= 4;
if(param3 != 0) param_flags |= 8;
packet_push<flyff::Vector3>(packet, player.position);
packet_push<flyff::Vector3>(packet, neuz.player->position);
packet_push<uint8_t>(packet, action);
packet_push<uint8_t>(packet, param_flags);
packet_push(packet, player.server_tick);
packet_push(packet, neuz.player->server_tick);
if(param0 != 0) packet_push<unsigned long long>(packet, param0);
if(param1 != 0) packet_push<unsigned long long>(packet, param1);
if(param2 != 0) packet_push<unsigned long long>(packet, param2);
if(param3 != 0) packet_push<unsigned long long>(packet, param3);
send_packet(0x404, packet);
send_packet(motion_packet_id, packet);
}
void set_target(const unsigned long long& id) {
@ -177,65 +173,28 @@ void write_chat_message(const std::string& message) {
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();
// BracketLeft
if(event->keyCode == 219 && is_running == false) {
const auto& player_pointer = fugg::module_ref<uintptr_t>(0x0003546c);
if(player_pointer == 0)
if(!neuz.player)
return;
const auto& player = fugg::module_ref<flyff::Mover>(player_pointer);
start_position = { player.position.x, player.position.y, player.position.z };
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;
// show_message("Bot started", { 0xFF, 0xFF, 0xFF });
// write_chat_message("Hi, how are you doing?");
// send_logout();
// show_message(get_text("ids_textclient_fly_noskill"), { 0xFF, 0xFF, 0xFF });
// set_target(778);
// interact_target(1);
// Some aibatt NW of Flaris
// set_target(0x069f7df5);
// interact_target(1);
// std::stringstream str;
// str << "Position: "
// << player.position.x << ", "
// << player.position.y << ", "
// << player.position.z;
// show_message(str.str(), { 0xFF, 0, 0xFF });
// std::stringstream str;
// str << "Sent_in_motion_packet: " << player.sent_in_motion_packet;
// show_message(str.str(), { 0xFF, 0, 0xFF });
// show_message(get_text("ids_ui_pk_confirm_title"), { 0x00, 0xFF, 0x00 });
// write_chat_message("Hahaha dikke vette moeders");
// move_to(6968.38, 100.011, 3328.86);
// send_motion_packet(0x404, 0x04, 535);
// send_motion_packet(0x404, 0x11, 1);
neuz.show_message("Bot started");
}
if(event->keyCode == 221) {
if(is_running == true) {
is_running = false;
// show_message("Bot stopped", { 0xFF, 0xFF, 0xFF });
neuz.show_message("Bot stopped");
} else {
const auto& player_pointer = fugg::module_ref<uintptr_t>(0x0003546c);
if(player_pointer == 0)
return;
if(!neuz.player) return;
// const auto& player = fugg::module_ref<flyff::Mover>(player_pointer);
@ -247,14 +206,9 @@ void on_keyup_hook(int event_type, const EmscriptenKeyboardEvent* event, void* u
}
flyff::Pointer<flyff::Mover> attack_next_target(flyff::Vector3 const& start_position) {
const auto& neuz = flyff::Neuz::instance();
auto& neuz = flyff::Neuz::instance();
const auto& player_pointer = fugg::module_ref<uintptr_t>(0x0003546c);
if(player_pointer == 0)
return nullptr;
auto& player = fugg::module_ref<flyff::Mover>(player_pointer);
const auto& player_object_id = fugg::module_ref<flyff::MoverID>(0x00034598);
if(!neuz.player) return nullptr;
float lowest_distance = std::numeric_limits<float>::max();
flyff::Pointer<flyff::Mover> closest = nullptr;
@ -271,12 +225,11 @@ flyff::Pointer<flyff::Mover> attack_next_target(flyff::Vector3 const& start_posi
auto squared = (dx * dx) + (dy * dy) + (dz * dz);
auto d = std::sqrt(squared);
if(mover->type == ObjectType::Mover &&
current->hash != player_object_id &&
current->hash != neuz.player_object_id &&
!mover->is_dead()) {
// If it's a monster that has me targetted
if(mover->last_attacked_target == player_object_id) {
if(mover->last_attacked_target == neuz.player_object_id) {
closest = mover;
closest_hash = current->hash;
@ -293,10 +246,10 @@ flyff::Pointer<flyff::Mover> attack_next_target(flyff::Vector3 const& start_posi
} while(current);
if(closest) {
player.selected_target = closest_hash;
player.move_toward_target = closest_hash;
player.attack_target = closest_hash;
player.follow_target = closest_hash;
neuz.player->selected_target = closest_hash;
neuz.player->move_toward_target = closest_hash;
neuz.player->attack_target = closest_hash;
neuz.player->follow_target = closest_hash;
set_target(closest_hash);
interact_target(1);
@ -308,12 +261,10 @@ flyff::Pointer<flyff::Mover> attack_next_target(flyff::Vector3 const& start_posi
}
const flyff::Mover* pickup_next_item() {
const auto& player_pointer = fugg::module_ref<uintptr_t>(0x0003546c);
if(player_pointer == 0)
return nullptr;
const auto& neuz = flyff::Neuz::instance();
auto& player = fugg::module_ref<flyff::Mover>(player_pointer);
const auto& player_object_id = fugg::module_ref<flyff::MoverID>(0x00034598);
if(!neuz.player) return nullptr;
auto& player = *neuz.player;
struct __attribute__((packed)) MoverHolder {
uintptr_t next;
@ -328,7 +279,7 @@ const flyff::Mover* pickup_next_item() {
uintptr_t first;
};
const auto& map = fugg::module_ref<MoverHolderMap>(0x00032968);
const auto& map = fugg::module_ref<MoverHolderMap>(0x00033460);
float lowest_distance = 999999.f;
uintptr_t closest = 0;
@ -389,7 +340,7 @@ bool is_in_moverlist(const void* ptr) {
uintptr_t first;
};
const auto& map = fugg::module_ref<MoverHolderMap>(0x00032968);
const auto& map = fugg::module_ref<MoverHolderMap>(0x00033460);
auto current = map.first;
do {
@ -415,155 +366,61 @@ void bot_tick() {
if(!neuz.player)
return;
neuz.show_message(neuz.player->name);
if(is_running) {
if(neuz.player->selected_target) {
const auto target = neuz.get_mover(neuz.player->selected_target);
std::cout << "Target: "
<< target->name << " "
<< "(" << target << ")"
<< " has "
<< target->move_toward_target << ", "
<< target->selected_target << ", "
<< target->attack_target << ", "
<< target->follow_target << ", "
// << target->
<< std::endl;
}
// if(player.selected_target != 0) {
// auto selected_target = neuz.get_mover(player.selected_target);
// std::cout << "Target: "
// << selected_target->name << " at "
// << selected_target->position.x << ", "
// << selected_target->position.y << ", "
// << selected_target->position.z << std::endl;
// } else {
// std::cout << "Got no target." << std::endl;
// }
// std::cout << get_text("ids_textclient_needsattackitem") << std::endl;
// const auto& neuz = flyff::Neuz::instance();
// auto first = neuz.movers.first;
// do {
// auto& mover = *first->mover;
// std::cout << mover.position << std::endl;
// first = first->next;
// } while(first);
// std::cout << neuz.movers.capacity << std::endl;
// std::cout << reinterpret_cast<void*>(player.if_not_null_needsattackitem) << std::endl;
// std::cout << "Some flags & 4 = " << ((player.movement_flags & 4) != 0) << std::endl;
// std::cout << player.prevents_pickup_emote() << std::endl;
// std::cout << player.pickup_things << std::endl;
std::cout << neuz.get_text("ids_textclient_party_changeitem") << std::endl;
// Party Distribute Item changed to %s.
// std::cout << get_text("ids_textclient_invalid_target_item") << std::endl;
// std::cout << get_text("ids_textclient_sbeve_notuseitem") << std::endl;
// std::cout << get_text("ids_textclient_lackspace") << std::endl;
// Cannot be done.
// You cannot use that item.
// Inventory is full. Please make room and try again.
// std::cout << get_text("ids_textclient_notdrop") << std::endl;
// You cannot drop a premium item on the ground.
// std::cout << get_text("ids_textclient_return_useitem") << std::endl;
// The item loses its potency 4 hours after being equipped if not returned to the inventory . Do you want to use the item?
// std::cout << get_text("ids_textclient_attentioncooltime") << std::endl;
// Please wait a while before using the item again.
// std::cout << get_text("ids_textclient_remove_error") << std::endl;
// That weapon is not possible to remove the element upgrading. Try again after checking.
// std::cout << get_text("ids_textclient_warningccls") << std::endl;
// Your stats will reset after you change your job. Do you want to change your job?
// if(is_running) {
// if(current_pickup_item != nullptr) {
// // std::cout << "Item's World = " << current_pickup_item->world << std::endl;
// // There is an item to pick up.
// if(is_in_moverlist(current_pickup_item)) {
// // Wait
// show_message("Waiting for pickup");
// } else {
// show_message("Picked up, waiting for ready");
if(current_pickup_item != nullptr) {
// std::cout << "Item's World = " << current_pickup_item->world << std::endl;
// There is an item to pick up.
if(is_in_moverlist(current_pickup_item)) {
// Wait
neuz.show_message("Waiting for pickup");
} else {
neuz.show_message("Picked up, waiting for ready");
// if((player.pickup_flags & 0x8ff) == 0 && player.current_animation == 0) {
// show_message("Picking up done.");
if((neuz.player->pickup_flags & 0x8ff) == 0 && neuz.player->current_animation == 0) {
neuz.show_message("Picking up done.");
// current_pickup_item = pickup_next_item();
// if(current_pickup_item != nullptr) {
// show_message("Picking up");
// }
// }
// // Maybe some confirmation...
// // send_motion_packet(0x01, *reinterpret_cast<const MotionParam*>(&player.rotation.y));
current_pickup_item = pickup_next_item();
if(current_pickup_item != nullptr) {
neuz.show_message("Picking up");
}
}
// Maybe some confirmation...
// send_motion_packet(0x01, *reinterpret_cast<const MotionParam*>(&player.rotation.y));
// }
// } else if(current_target == nullptr) {
// if(player.pickup_things != 1)
// return;
}
} else if(current_target == nullptr) {
if(neuz.player->pickup_things != 1)
return;
// current_pickup_item = nullptr;
// current_target = attack_next_target(start_position);
current_pickup_item = nullptr;
current_target = attack_next_target(start_position);
// if(current_target) {
// std::string str = "Attacking ";
// str.append(current_target->name);
if(current_target) {
std::string str = "Attacking ";
str.append(current_target->name);
// show_message(str, { 0xFF, 0xFF, 0xFF });
// } else {
// show_message("Unable to find target.", { 0xFF, 0x00, 0x00 });
// }
// } else if(current_target->is_dead()) {
// current_target = nullptr;
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) {
// show_message("Picking up");
// }
// }
// } else {
// // Reset current target is not running.
// current_target = nullptr;
// current_pickup_item = 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 = nullptr;
current_pickup_item = nullptr;
}
}
void before_main_loop() {
bot_tick();
// auto& client = fugg::Client::instance();
// const auto& test = translate("ids_textclient_cannot_dropmoney");
// const auto& test = translate("ids_textclient_skill_self");
// const auto& test = get_text("ids_textclient_notarget");
// const auto& test = get_text("ids_textclient_checkequip");
// const auto& test = get_text("ids_textclient_reapskill");
// const auto& test = get_text("ids_textclient_skillpoint_up");
// const auto& test = get_text("ids_textclient_skill_mate");
// const auto& test = get_text("IDS_PROPMOVER_TXT_000002");
// {
// const auto& test = get_text("ids_textclient_app_party");
// std::cout << test << std::endl;
// }
// {
// const auto& test = get_text("ids_ui_party_permanent");
// std::cout << test << std::endl;
// }
// show_message("HAHAH DIKKE VETTE ANUSSEN");
}
void after_main_loop() {