diff --git a/libreborn/include/libreborn/minecraft.h b/libreborn/include/libreborn/minecraft.h index d656c54..b3d08fe 100644 --- a/libreborn/include/libreborn/minecraft.h +++ b/libreborn/include/libreborn/minecraft.h @@ -92,6 +92,12 @@ static Minecraft_isLevelGenerated_t Minecraft_isLevelGenerated = (Minecraft_isLe typedef int32_t (*Minecraft_isCreativeMode_t)(unsigned char *minecraft); static Minecraft_isCreativeMode_t Minecraft_isCreativeMode = (Minecraft_isCreativeMode_t) 0x17270; +typedef void (*Minecraft_releaseMouse_t)(unsigned char *minecraft); +static Minecraft_releaseMouse_t Minecraft_releaseMouse = (Minecraft_releaseMouse_t) 0x15d30; + +typedef void (*Minecraft_grabMouse_t)(unsigned char *minecraft); +static Minecraft_grabMouse_t Minecraft_grabMouse = (Minecraft_grabMouse_t) 0x15d10; + static uint32_t Minecraft_screen_width_property_offset = 0x20; // int32_t static uint32_t Minecraft_server_side_network_handler_property_offset = 0x174; // ServerSideNetworkHandler * static uint32_t Minecraft_rak_net_instance_property_offset = 0x170; // RakNetInstance * @@ -103,6 +109,7 @@ static uint32_t Minecraft_options_property_offset = 0x3c; // Options static uint32_t Minecraft_hit_result_property_offset = 0xc38; // HitResult static uint32_t Minecraft_progress_property_offset = 0xc60; // int32_t static uint32_t Minecraft_command_server_property_offset = 0xcc0; // CommandServer * +static uint32_t Minecraft_screen_property_offset = 0xc10; // Screen * // CommandServer diff --git a/mods/src/chat/chat.cpp b/mods/src/chat/chat.cpp index e3e1e88..4832848 100644 --- a/mods/src/chat/chat.cpp +++ b/mods/src/chat/chat.cpp @@ -84,9 +84,16 @@ void chat_queue_message(char *message) { pthread_mutex_unlock(&queue_mutex); } // Empty Queue +unsigned int old_chat_counter = 0; void chat_send_messages(unsigned char *minecraft) { // Lock pthread_mutex_lock(&queue_mutex); + // If Message Was Submitted, No Other Chat Windows Are Open, And The Game Is Not Paused, Then Re-Lock Cursor + unsigned int new_chat_counter = chat_get_counter(); + if (old_chat_counter > new_chat_counter && new_chat_counter == 0 && (*(unsigned char **) (minecraft + Minecraft_screen_property_offset)) == NULL) { + (*Minecraft_grabMouse)(minecraft); + } + old_chat_counter = new_chat_counter; // Loop for (unsigned int i = 0; i < queue.size(); i++) { send_api_chat_command(minecraft, (char *) queue[i].c_str()); diff --git a/mods/src/chat/chat.h b/mods/src/chat/chat.h index 5b93199..caa5b3d 100644 --- a/mods/src/chat/chat.h +++ b/mods/src/chat/chat.h @@ -5,6 +5,8 @@ extern "C" { #endif void chat_open(); +unsigned int chat_get_counter(); + void chat_queue_message(char *message); void chat_send_messages(unsigned char *minecraft); diff --git a/mods/src/chat/ui.c b/mods/src/chat/ui.c index b220947..7fa1c4a 100644 --- a/mods/src/chat/ui.c +++ b/mods/src/chat/ui.c @@ -62,6 +62,13 @@ static char *run_command(char *command, int *return_code) { return output; } +// Count Chat Windows +static pthread_mutex_t chat_counter_lock = PTHREAD_MUTEX_INITIALIZER; +static unsigned int chat_counter = 0; +unsigned int chat_get_counter() { + return chat_counter; +} + // Chat Thread static void *chat_thread(__attribute__((unused)) void *nop) { // Prepare @@ -84,12 +91,21 @@ static void *chat_thread(__attribute__((unused)) void *nop) { // Free free(output); } + // Update Counter + pthread_mutex_lock(&chat_counter_lock); + chat_counter--; + pthread_mutex_unlock(&chat_counter_lock); // Return return NULL; } // Create Chat Thead void chat_open() { + // Update Counter + pthread_mutex_lock(&chat_counter_lock); + chat_counter++; + pthread_mutex_unlock(&chat_counter_lock); + // Start Thread pthread_t thread; pthread_create(&thread, NULL, chat_thread, NULL); } \ No newline at end of file diff --git a/mods/src/compat/compat.c b/mods/src/compat/compat.c index 7a5b7f3..33110b4 100644 --- a/mods/src/compat/compat.c +++ b/mods/src/compat/compat.c @@ -281,13 +281,14 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) { input_third_person(); handled = 1; } else if (event->key.keysym.sym == SDLK_t) { - // Release Mouse Immediately - SDL_WM_GrabInput(SDL_GRAB_OFF); - // Stop Tracking Mouse - glfw_key(glfw_window, GLFW_KEY_TAB, -1, GLFW_PRESS, -1); - glfw_key(glfw_window, GLFW_KEY_TAB, -1, GLFW_RELEASE, -1); - // Open Chat - chat_open(); + // Only When In-Game With No Other Chat Windows Open + if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON && chat_get_counter() == 0) { + // Release Mouse + input_set_mouse_grab_state(1); + // Open Chat + chat_open(); + } + // Mark Handled handled = 1; } } else if (event->type == SDL_MOUSEBUTTONDOWN || event->type == SDL_MOUSEBUTTONUP) { diff --git a/mods/src/input/input.c b/mods/src/input/input.c index fffc61d..6b995a4 100644 --- a/mods/src/input/input.c +++ b/mods/src/input/input.c @@ -26,6 +26,12 @@ void input_third_person() { third_person_toggle++; } +// Set mouse Grab State +static int mouse_grab_state = 0; +void input_set_mouse_grab_state(int state) { + mouse_grab_state = state; +} + // Handle Input Fixes static void Minecraft_tickInput_injection(unsigned char *minecraft) { // Call Original Method @@ -61,6 +67,16 @@ static void Minecraft_tickInput_injection(unsigned char *minecraft) { // Send Queued Chat Message chat_send_messages(minecraft); + + // Set Mouse Grab State + if (mouse_grab_state == -1) { + // Grab + (*Minecraft_grabMouse)(minecraft); + } else if (mouse_grab_state == 1) { + // Un-Grab + (*Minecraft_releaseMouse)(minecraft); + } + mouse_grab_state = 0; } #include diff --git a/mods/src/input/input.h b/mods/src/input/input.h index 9a29f37..32f0773 100644 --- a/mods/src/input/input.h +++ b/mods/src/input/input.h @@ -13,6 +13,8 @@ void input_third_person(); void input_set_is_left_click(int val); +void input_set_mouse_grab_state(int state); + void init_input_cpp(); #ifdef __cplusplus