All functionality restored for 1.1.3
This commit is contained in:
parent
35aabe59bf
commit
ee2608a460
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
Reference in New Issue