diff --git a/.github/workflows/build-channel.yml b/.github/workflows/build-channel.yml
index 0ab6d5d..e8171d0 100644
--- a/.github/workflows/build-channel.yml
+++ b/.github/workflows/build-channel.yml
@@ -56,10 +56,8 @@ jobs:
"Minecraft.Client\\Windows64\\Iggy\\lib\\iggy_w64.lib",
"Minecraft.Client\\Windows64\\Iggy\\gdraw\\gdraw_d3d11.h",
"Minecraft.Client\\Windows64\\Miles\\lib\\mss64.lib",
- "Minecraft.Client\\Windows64\\4JLibs\\libs\\4J_Input_r.lib",
- "Minecraft.Client\\Windows64\\4JLibs\\libs\\4J_Storage_r.lib",
- "Minecraft.Client\\Windows64\\4JLibs\\libs\\4J_Profile_r.lib",
- "Minecraft.Client\\Windows64\\4JLibs\\libs\\4J_Render_PC.lib",
+ "Minecraft.Client\\Platform_Libs\\Dev\\Input\\4J_Input.cpp",
+ "Minecraft.Client\\Platform_Libs\\Dev\\Profile\\4J_Profile.cpp",
"Minecraft.Client\\Durango\\Sound\\Minecraft.msscmp",
"Minecraft.Client\\Windows64\\Sentient\\SentientTelemetryCommon.h",
"Minecraft.Client\\Windows64\\Sentient\\MinecraftTelemetry.h",
@@ -326,9 +324,11 @@ jobs:
shell: pwsh
run: |
$required = @(
- "Minecraft.Client\\Windows64\\4JLibs\\libs\\4J_Storage.lib",
- "Minecraft.Client\\Windows64\\4JLibs\\libs\\4J_Profile_r.lib",
- "Minecraft.Client\\Windows64\\4JLibs\\libs\\4J_Render_PC.lib",
+ "Minecraft.Client\\Platform_Libs\\Dev\\Storage\\4J_Storage.cpp",
+ "Minecraft.Client\\Platform_Libs\\Dev\\Storage\\STO_SaveGame.cpp",
+ "Minecraft.Client\\Platform_Libs\\Dev\\Profile\\4J_Profile.cpp",
+ "Minecraft.Client\\Platform_Libs\\Dev\\Render\\4J_Render.cpp",
+ "Minecraft.Client\\Platform_Libs\\Dev\\Render\\libpng\\png.c",
"Minecraft.Client\\Windows64\\Iggy\\gdraw\\gdraw_d3d11.h",
"Minecraft.Client\\Windows64\\Sentient\\SentientTelemetryCommon.h",
"Minecraft.Client\\Windows64\\Sentient\\MinecraftTelemetry.h",
@@ -338,7 +338,7 @@ jobs:
$missing = @($required | Where-Object { -not (Test-Path $_) })
if ($missing.Count -gt 0) {
- Write-Error "Missing required Windows dedicated server libs:`n$($missing -join "`n")"
+ Write-Error "Missing required Windows dedicated server files:`n$($missing -join "`n")"
exit 1
}
diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp
index 8054f8b..c41739d 100644
--- a/Minecraft.Client/Extrax64Stubs.cpp
+++ b/Minecraft.Client/Extrax64Stubs.cpp
@@ -46,7 +46,7 @@
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
#ifdef _WINDOWS64
//C4JStorage StorageManager;
-C_4JProfile ProfileManager;
+//C_4JProfile ProfileManager;
#endif
#endif // __PS3__
CSentientManager SentientManager;
diff --git a/Minecraft.Client/Minecraft.Client.vcxproj b/Minecraft.Client/Minecraft.Client.vcxproj
index 123427a..54e3e23 100644
--- a/Minecraft.Client/Minecraft.Client.vcxproj
+++ b/Minecraft.Client/Minecraft.Client.vcxproj
@@ -29393,6 +29393,78 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CUstdafx.h
Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+
+
+ true
+ NotUsing
+ stdafx.h
+ Windows64\4JLibs\inc;%(AdditionalIncludeDirectories)
+ truetrue
@@ -36217,8 +36289,8 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CUtrue
truetrue
- false
- false
+ true
+ truetruetruetrue
@@ -36250,7 +36322,7 @@ xcopy /q /y /i /s /e $(ProjectDir)Durango\CU $(LayoutDir)Image\Loose\CUtrue
truetrue
- false
+ truetruetruetrue
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/4J_Input.cpp b/Minecraft.Client/Platform_Libs/Dev/Input/4J_Input.cpp
new file mode 100644
index 0000000..a8d480f
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/4J_Input.cpp
@@ -0,0 +1,178 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "stdafx.h"
+#include "4J_Input.h"
+#include "INP_Keyboard.h"
+#include "INP_Main.h"
+
+C_4JInput InputManager;
+CKeyboard InternalKeyboard;
+
+void C_4JInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC)
+{
+ InternalInputManager.Initialise(iInputStateC, ucMapC, ucActionC, ucMenuActionC);
+}
+
+void C_4JInput::Tick(void)
+{
+ InternalInputManager.Tick();
+}
+
+void C_4JInput::SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax)
+{
+ InternalInputManager.SetDeadzoneAndMovementRange(uiDeadzone, uiMovementRangeMax);
+}
+
+void C_4JInput::SetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction, unsigned int uiActionVal)
+{
+ InternalInputManager.SetGameJoypadMaps(ucMap, ucAction, uiActionVal);
+}
+
+unsigned int C_4JInput::GetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction)
+{
+ return InternalInputManager.GetGameJoypadMaps(ucMap, ucAction);
+}
+
+void C_4JInput::SetJoypadMapVal(int iPad, unsigned char ucMap)
+{
+ InternalInputManager.SetJoypadMapVal(iPad, ucMap);
+}
+
+unsigned char C_4JInput::GetJoypadMapVal(int iPad)
+{
+ return InternalInputManager.GetJoypadMapVal(iPad);
+}
+
+void C_4JInput::SetJoypadSensitivity(int iPad, float fSensitivity)
+{
+ InternalInputManager.SetJoypadSensitivity(iPad, fSensitivity);
+}
+
+unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat)
+{
+ return InternalInputManager.GetValue(iPad, ucAction, bRepeat);
+}
+
+bool C_4JInput::ButtonPressed(int iPad, unsigned char ucAction)
+{
+ return InternalInputManager.ButtonPressed(iPad, ucAction);
+}
+
+bool C_4JInput::ButtonReleased(int iPad, unsigned char ucAction)
+{
+ return InternalInputManager.ButtonReleased(iPad, ucAction);
+}
+
+bool C_4JInput::ButtonDown(int iPad, unsigned char ucAction)
+{
+ return InternalInputManager.ButtonDown(iPad, ucAction);
+}
+
+void C_4JInput::SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
+{
+ InternalInputManager.SetJoypadStickAxisMap(iPad, uiFrom, uiTo);
+}
+
+void C_4JInput::SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
+{
+ InternalInputManager.SetJoypadStickTriggerMap(iPad, uiFrom, uiTo);
+}
+
+void C_4JInput::SetKeyRepeatRate(float fRepeatDelaySecs, float fRepeatRateSecs)
+{
+ InternalInputManager.SetKeyRepeatRate(fRepeatDelaySecs, fRepeatRateSecs);
+}
+
+void C_4JInput::SetDebugSequence(const char *chSequenceA, int (*Func)(LPVOID), LPVOID lpParam)
+{
+ InternalInputManager.SetDebugSequence(chSequenceA, Func, lpParam);
+}
+
+FLOAT C_4JInput::GetIdleSeconds(int iPad)
+{
+ return InternalInputManager.GetIdleSeconds(iPad);
+}
+
+bool C_4JInput::IsPadConnected(int iPad)
+{
+ return InternalInputManager.IsPadConnected(iPad);
+}
+
+float C_4JInput::GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadStick_LX(iPad, bCheckMenuDisplay);
+}
+
+float C_4JInput::GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadStick_LY(iPad, bCheckMenuDisplay);
+}
+
+float C_4JInput::GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadStick_RX(iPad, bCheckMenuDisplay);
+}
+
+float C_4JInput::GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadStick_RY(iPad, bCheckMenuDisplay);
+}
+
+unsigned char C_4JInput::GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadLTrigger(iPad, bCheckMenuDisplay);
+}
+
+unsigned char C_4JInput::GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay)
+{
+ return InternalInputManager.GetJoypadRTrigger(iPad, bCheckMenuDisplay);
+}
+
+void C_4JInput::SetMenuDisplayed(int iPad, bool bVal)
+{
+ InternalInputManager.SetMenuDisplayed(iPad, bVal);
+}
+
+EKeyboardResult C_4JInput::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam,
+ C_4JInput::EKeyboardMode eMode)
+{
+ return InternalKeyboard.RequestKeyboard(Title, Text, dwPad, uiMaxChars, Func, lpParam, eMode);
+}
+
+void C_4JInput::GetText(uint16_t *UTF16String)
+{
+ InternalKeyboard.GetText(UTF16String);
+}
+
+bool C_4JInput::VerifyStrings(WCHAR **pwStringA, int iStringC, int (*Func)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID lpParam)
+{
+ return true;
+}
+
+void C_4JInput::CancelQueuedVerifyStrings(int (*Func)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID lpParam) {}
+
+void C_4JInput::CancelAllVerifyInProgress(void) {}
+
+// bool C_4JInput::InputDetected(DWORD dwUserIndex,WCHAR *pwchInput) {}
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/CMakeLists.txt b/Minecraft.Client/Platform_Libs/Dev/Input/CMakeLists.txt
new file mode 100644
index 0000000..1bd6aa9
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 3.25 FATAL_ERROR)
+
+project(4JLibs.Windows.Input LANGUAGES CXX)
+
+add_library(${PROJECT_NAME} STATIC
+ 4J_Input.cpp
+ INP_ForceFeedback.cpp
+ INP_Keyboard.cpp
+ INP_Main.cpp
+ INP_StringCheck.cpp
+ LinkedList.cpp
+ stdafx.cpp
+)
+
+target_include_directories(${PROJECT_NAME} PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+target_precompile_headers(${PROJECT_NAME} PRIVATE
+ stdafx.h
+)
+
+set_target_properties(${PROJECT_NAME} PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "4J_Input"
+)
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/INP_ForceFeedback.cpp b/Minecraft.Client/Platform_Libs/Dev/Input/INP_ForceFeedback.cpp
new file mode 100644
index 0000000..3341a30
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/INP_ForceFeedback.cpp
@@ -0,0 +1,135 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "stdafx.h"
+#include "INP_ForceFeedback.h"
+
+void CForceFeedback::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC)
+{
+ m_Effects = new FF_EFFECT[MAX_EFFECTS];
+ m_EffectC = 0;
+
+ LARGE_INTEGER qwTicksPerSec;
+ QueryPerformanceFrequency(&qwTicksPerSec);
+
+ m_TicksPerSecond = qwTicksPerSec.LowPart;
+ m_unkBool = 0;
+}
+
+void CForceFeedback::RumbleEnable(int iQuadrant, bool bRumbleEnabled) {}
+
+void CForceFeedback::CreateEffect(void)
+{
+ assert(m_EffectC < MAX_EFFECTS);
+
+ FF_EFFECT *pEffect = &m_Effects[m_EffectC];
+ pEffect->m_uiDurationMs = 5;
+ pEffect->m_uiMagnitude = 500;
+ pEffect->m_uiEffectType = 0;
+ pEffect->dword18 = 10;
+ pEffect->dword18 = 100;
+
+ m_EffectC++;
+}
+
+void CForceFeedback::AddEffectInstance(unsigned int uiEffect)
+{
+ FF_EFFECT_INSTANCE *pEffectInst = new FF_EFFECT_INSTANCE();
+ pEffectInst->m_Effect = &m_Effects[uiEffect];
+ pEffectInst->m_uiInst = 0;
+
+ m_EffectList.AddToTail(pEffectInst);
+}
+
+void CForceFeedback::SetEffectInstanceState(unsigned int uiEffectInstance, unsigned int uiState)
+{
+ int iCount = 0;
+ LinkedList::_LL_NODE *pNode;
+ for (pNode = m_EffectList.m_Head;; pNode = pNode->m_Next)
+ {
+ if ((iCount++) == uiEffectInstance)
+ break;
+ }
+ pNode->GetDataAs()->m_bIsActive = true;
+}
+
+void CForceFeedback::ProcessEventInstance(FF_EFFECT_INSTANCE *pEffectInst) {}
+
+void CForceFeedback::PauseEventInstance(FF_EFFECT_INSTANCE *pEffectInst) {}
+
+void CForceFeedback::AddRumble(unsigned int uiPad, WORD leftMotorSpeed, WORD rightMotorSpeed, float fSeconds)
+{
+ RUMBLE_EFFECT *pRumble = new RUMBLE_EFFECT();
+
+ LARGE_INTEGER qwCurrentTime;
+ QueryPerformanceCounter(&qwCurrentTime);
+
+ pRumble->m_TimeLeft = (m_TicksPerSecond * fSeconds) + qwCurrentTime.QuadPart;
+ pRumble->m_RumbleData.wLeftMotorSpeed = leftMotorSpeed;
+ pRumble->m_RumbleData.wRightMotorSpeed = rightMotorSpeed;
+ pRumble->m_Pad = uiPad;
+
+ m_RumbleList.AddToTail(pRumble);
+}
+
+void CForceFeedback::Tick(void)
+{
+ for (LinkedList::_LL_NODE *pEffectNode = m_EffectList.m_Head; pEffectNode; pEffectNode = pEffectNode->m_Next)
+ {
+ if (pEffectNode->GetDataAs()->m_bIsActive)
+ {
+ ProcessEventInstance(pEffectNode->GetDataAs());
+ }
+ }
+
+ LARGE_INTEGER qwCurrentTime;
+ QueryPerformanceCounter(&qwCurrentTime);
+
+ LinkedList::_LL_NODE *pRumbleNode = m_RumbleList.m_Head;
+ while (pRumbleNode)
+ {
+ if (pRumbleNode->GetDataAs()->m_TimeLeft <= qwCurrentTime.QuadPart)
+ {
+ RUMBLE_EFFECT *pRumble = pRumbleNode->GetDataAs();
+
+ pRumble->m_RumbleData.wLeftMotorSpeed = 0;
+ pRumble->m_RumbleData.wRightMotorSpeed = 0;
+
+ XInputSetState(pRumble->m_Pad, &pRumble->m_RumbleData);
+
+ m_RumbleList.RemoveNode(pRumbleNode);
+
+ LinkedList::_LL_NODE *pTemp = pRumbleNode;
+ pRumbleNode = pRumbleNode->m_Next;
+
+ delete pTemp->GetDataAs();
+ delete pTemp;
+ }
+ else
+ {
+ XInputSetState(pRumbleNode->GetDataAs()->m_Pad, &pRumbleNode->GetDataAs()->m_RumbleData);
+ pRumbleNode = pRumbleNode->m_Next;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/INP_ForceFeedback.h b/Minecraft.Client/Platform_Libs/Dev/Input/INP_ForceFeedback.h
new file mode 100644
index 0000000..df75a47
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/INP_ForceFeedback.h
@@ -0,0 +1,84 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "LinkedList.h"
+
+#define MAX_EFFECTS 10
+
+class CForceFeedback
+{
+public:
+ enum FF_PARAMS
+ {
+ FF_PARAMS_RAMP,
+ FF_PARAMS_PERIODIC
+ };
+
+ struct RUMBLE_EFFECT
+ {
+ DWORD m_Pad;
+ uint64_t m_TimeLeft;
+ XINPUT_VIBRATION m_RumbleData;
+ WORD unk;
+ };
+
+ struct FF_EFFECT
+ {
+ unsigned int m_uiEffectType;
+ unsigned int m_uiDurationMs;
+ BYTE gap8[4];
+ unsigned int m_uiMagnitude;
+ BYTE gap10[8];
+ DWORD dword18;
+ DWORD dword1C;
+ };
+
+ struct FF_EFFECT_INSTANCE
+ {
+ bool m_bIsActive;
+ unsigned int m_uiInst;
+ CForceFeedback::FF_EFFECT *m_Effect;
+ };
+
+ void Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC);
+ void RumbleEnable(int iQuadrant, bool bRumbleEnabled);
+ void CreateEffect(void);
+ void AddEffectInstance(unsigned int uiEffect);
+ void SetEffectInstanceState(unsigned int uiEffectInstance, unsigned int uiState);
+
+ void ProcessEventInstance(FF_EFFECT_INSTANCE *pEffectInst);
+ void PauseEventInstance(FF_EFFECT_INSTANCE *pEffectInst);
+
+ void AddRumble(unsigned int uiPad, WORD leftMotorSpeed, WORD rightMotorSpeed, float fSeconds);
+
+ void Tick(void);
+
+ LinkedList m_EffectList;
+ FF_EFFECT *m_Effects;
+ int m_EffectC;
+ LinkedList m_RumbleList;
+ float m_TicksPerSecond;
+ bool m_unkBool;
+};
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/INP_Keyboard.cpp b/Minecraft.Client/Platform_Libs/Dev/Input/INP_Keyboard.cpp
new file mode 100644
index 0000000..a15f13f
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/INP_Keyboard.cpp
@@ -0,0 +1,47 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "stdafx.h"
+#include "INP_Keyboard.h"
+
+void CKeyboard::Tick(void) {}
+
+EKeyboardResult CKeyboard::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam,
+ C_4JInput::EKeyboardMode eMode)
+{
+ ClearGlobalText();
+ SeedEditBox();
+ Func(lpParam, C_4JInput::EKeyboardMode_Numeric);
+
+ return EKeyboard_ResultAccept;
+}
+
+void CKeyboard::GetText(uint16_t *UTF16String)
+{
+ uint16_t *keyString = GetGlobalText();
+ for (unsigned int index = 0; keyString[index] && index < 0x200; index++)
+ {
+ UTF16String[index] = keyString[index];
+ }
+}
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/INP_Keyboard.h b/Minecraft.Client/Platform_Libs/Dev/Input/INP_Keyboard.h
new file mode 100644
index 0000000..f6e00de
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/INP_Keyboard.h
@@ -0,0 +1,50 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "4J_Input.h"
+
+void ClearGlobalText();
+uint16_t *GetGlobalText();
+void SeedEditBox();
+
+class CKeyboard
+{
+public:
+ enum EKeyboardProcessState
+ {
+ };
+
+ struct SKeyboardInfo
+ {
+ };
+
+ void Tick(void);
+
+ EKeyboardResult RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int (*Func)(LPVOID, const bool), LPVOID lpParam,
+ C_4JInput::EKeyboardMode eMode);
+ void GetText(uint16_t *UTF16String);
+
+ BYTE gap0[0x68];
+};
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/INP_Main.cpp b/Minecraft.Client/Platform_Libs/Dev/Input/INP_Main.cpp
new file mode 100644
index 0000000..a10a6f7
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/INP_Main.cpp
@@ -0,0 +1,763 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "stdafx.h"
+#include "INP_Main.h"
+
+CInput InternalInputManager;
+
+CInput::CInput()
+{
+ m_ForceFeedback = CForceFeedback();
+ m_Keyboard = CKeyboard();
+
+ m_uiSigninJoypadMask = 0;
+ for (int i = 0; i < 4; ++i)
+ m_bIsMenuDisplayed[i] = 0;
+
+ InitTime();
+
+ m_fRepeatDelaySecs = 0.5f;
+ m_fRepeatRateSecs = 0.8f;
+ m_sDebugSequenceName = 0;
+ m_uiDebugSequenceIndex = 0;
+ m_pDebugSequenceFn = 0;
+}
+
+void CInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC)
+{
+ assert(iInputStateC > 0);
+ assert(ucMapC > 0);
+ assert(ucActionC > 0);
+
+ ZeroMemory(m_Joypads, sizeof(m_Joypads));
+
+ m_ucInputStateC = iInputStateC;
+
+ m_iDeadzone = 0x2710;
+ m_iMovementRangeMax = 0x7FFF;
+
+ m_iEffectiveRange = m_iMovementRangeMax - m_iDeadzone;
+ m_iHalfRange = m_iEffectiveRange / 2;
+ m_fEffectiveRange = (float)m_iEffectiveRange;
+
+ for (int i = 0; i < MAX_JOYPADS; i++)
+ {
+ m_Joypads[i].m_pInputStates = new XINPUT_STATE[m_ucInputStateC];
+ m_Joypads[i].m_ucInputStateIndex = -1;
+ m_Joypads[i].m_pfLeftThumbXAxisMap = &m_Joypads[i].m_fNormalizedLeftThumbX;
+ m_Joypads[i].m_pfLeftThumbYAxisMap = &m_Joypads[i].m_fNormalizedLeftThumbY;
+ m_Joypads[i].m_pfRightThumbXAxisMap = &m_Joypads[i].m_fNormalizedRightThumbX;
+ m_Joypads[i].m_pfRightThumbYAxisMap = &m_Joypads[i].m_fNormalizedRightThumbY;
+ m_Joypads[i].m_pucLeftTriggerAxisMap = &m_Joypads[i].m_ucLeftTriggerState;
+ m_Joypads[i].m_pucRightTriggerAxisMap = &m_Joypads[i].m_ucRightTriggerState;
+ m_Joypads[i].m_fSensitivity = 1.0f;
+ }
+
+ m_JoypadMap = (unsigned int **)operator new[](ucMapC * sizeof(int *));
+ for (int i = 0; i < ucMapC; i++)
+ {
+ m_JoypadMap[i] = (unsigned int *)operator new[](ucActionC * sizeof(int));
+ }
+
+ m_ucJoypadMapC = ucMapC;
+ m_ucJoypadMapActionC = ucActionC;
+ m_ucMenuActionC = ucMenuActionC;
+ m_bJoypadMapArrayIsSetup = false;
+
+ m_ForceFeedback.Initialise(iInputStateC, ucMapC, ucActionC, ucMenuActionC);
+}
+
+void CInput::Tick(void)
+{
+ UpdateJoypads();
+ m_ForceFeedback.Tick();
+ m_Keyboard.Tick();
+}
+
+void CInput::SetJoypadValues(JOYPAD *pThisPad)
+{
+ XINPUT_GAMEPAD *pGamePad = &pThisPad->m_pInputStates[pThisPad->m_ucInputStateIndex].Gamepad;
+
+ if (pGamePad->bLeftTrigger > 0x7Fu)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LT;
+ }
+ if (pGamePad->bRightTrigger > 0x7Fu)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RT;
+ }
+
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RB;
+ }
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LB;
+ }
+
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_A) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_A;
+ }
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_B) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_B;
+ }
+
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_X) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_X;
+ }
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_Y) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_Y;
+ }
+
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_START) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_START;
+ }
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_BACK) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_BACK;
+ }
+
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_LEFT_THUMB) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RTHUMB;
+ }
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_RIGHT_THUMB) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LTHUMB;
+ }
+
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_DPAD_UP) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_UP;
+ }
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_DPAD_DOWN) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_DOWN;
+ }
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_DPAD_LEFT) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_LEFT;
+ }
+ if ((pGamePad->wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) != 0)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_DPAD_RIGHT;
+ }
+
+ if (pGamePad->sThumbLX > m_iHalfRange + m_iDeadzone)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_RIGHT;
+ }
+ if (pGamePad->sThumbLX < -m_iDeadzone - m_iHalfRange)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_LEFT;
+ }
+
+ if (pGamePad->sThumbRY < -m_iDeadzone - m_iHalfRange)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_DOWN;
+ }
+ if (pGamePad->sThumbRY > m_iHalfRange + m_iDeadzone)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_UP;
+ }
+ if (pGamePad->sThumbRX > m_iHalfRange + m_iDeadzone)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_RIGHT;
+ }
+ if (pGamePad->sThumbRX < -m_iDeadzone - m_iHalfRange)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_RSTICK_LEFT;
+ }
+
+ if (pGamePad->sThumbLY < -m_iDeadzone - m_iHalfRange)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_DOWN;
+ }
+ if (pGamePad->sThumbLY > m_iHalfRange + m_iDeadzone)
+ {
+ pThisPad->m_uiButtons |= _360_JOY_BUTTON_LSTICK_UP;
+ }
+
+ pThisPad->m_ucLeftTriggerState = pGamePad->bLeftTrigger;
+ pThisPad->m_ucRightTriggerState = pGamePad->bRightTrigger;
+
+ if (pGamePad->sThumbRX <= m_iDeadzone)
+ {
+ if (pGamePad->sThumbRX >= -m_iDeadzone)
+ pThisPad->m_iRightThumbX = 0;
+ else
+ pThisPad->m_iRightThumbX = m_iDeadzone + pGamePad->sThumbRX;
+ }
+ else
+ {
+ pThisPad->m_iRightThumbX = pGamePad->sThumbRX - m_iDeadzone;
+ }
+ if (pGamePad->sThumbRY <= m_iDeadzone)
+ {
+ if (pGamePad->sThumbRY >= -m_iDeadzone)
+ pThisPad->m_iRightThumbY = 0;
+ else
+ pThisPad->m_iRightThumbY = m_iDeadzone + pGamePad->sThumbRY;
+ }
+ else
+ {
+ pThisPad->m_iRightThumbY = pGamePad->sThumbRY - m_iDeadzone;
+ }
+ if (pGamePad->sThumbLX <= m_iDeadzone)
+ {
+ if (pGamePad->sThumbLX >= -m_iDeadzone)
+ pThisPad->m_iLeftThumbX = 0;
+ else
+ pThisPad->m_iLeftThumbX = m_iDeadzone + pGamePad->sThumbLX;
+ }
+ else
+ {
+ pThisPad->m_iLeftThumbX = pGamePad->sThumbLX - m_iDeadzone;
+ }
+ if (pGamePad->sThumbLY <= m_iDeadzone)
+ {
+ if (pGamePad->sThumbLY >= -m_iDeadzone)
+ pThisPad->m_iLeftThumbY = 0;
+ else
+ pThisPad->m_iLeftThumbY = m_iDeadzone + pGamePad->sThumbLY;
+ }
+ else
+ {
+ pThisPad->m_iLeftThumbY = pGamePad->sThumbLY - m_iDeadzone;
+ }
+
+ pThisPad->m_iNormalizedLeftThumbX = pThisPad->m_iLeftThumbX / m_iEffectiveRange;
+ pThisPad->m_iNormalizedLeftThumbY = pThisPad->m_iLeftThumbY / m_iEffectiveRange;
+ pThisPad->m_iNormalizedRightThumbX = pThisPad->m_iRightThumbX / m_iEffectiveRange;
+ pThisPad->m_iNormalizedRightThumbY = pThisPad->m_iRightThumbY / m_iEffectiveRange;
+
+ pThisPad->m_fNormalizedLeftThumbX = pThisPad->m_iLeftThumbX / m_fEffectiveRange;
+ pThisPad->m_fNormalizedLeftThumbY = pThisPad->m_iLeftThumbY / m_fEffectiveRange;
+ pThisPad->m_fNormalizedRightThumbX = pThisPad->m_iRightThumbX / m_fEffectiveRange;
+ pThisPad->m_fNormalizedRightThumbY = pThisPad->m_iRightThumbY / m_fEffectiveRange;
+}
+
+void CInput::SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax)
+{
+ m_iDeadzone = uiDeadzone;
+ m_iMovementRangeMax = uiMovementRangeMax;
+ m_iEffectiveRange = uiMovementRangeMax - uiDeadzone;
+ m_iHalfRange = m_iEffectiveRange / 2;
+}
+
+void CInput::SetJoypadSensitivity(int iPad, float fSensitivity)
+{
+ m_Joypads[iPad].m_fSensitivity = fSensitivity;
+}
+
+void CInput::SetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction, unsigned int uiActionVal)
+{
+ assert(ucMap < m_ucJoypadMapC);
+ assert(ucAction < m_ucJoypadMapActionC);
+
+ m_JoypadMap[ucMap][ucAction] = uiActionVal;
+}
+
+unsigned int CInput::GetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction)
+{
+ assert(ucMap < m_ucJoypadMapC);
+ assert(ucAction < m_ucJoypadMapActionC);
+
+ return m_JoypadMap[ucMap][ucAction];
+}
+
+void CInput::SetJoypadMapVal(int iPad, unsigned char ucMap)
+{
+ m_bJoypadMapArrayIsSetup = true;
+ m_Joypads[iPad].m_ucMappingValue = ucMap;
+}
+
+unsigned char CInput::GetJoypadMapVal(int iPad)
+{
+ return m_Joypads[iPad].m_ucMappingValue;
+}
+
+void CInput::SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
+{
+ float *pfTo = nullptr;
+
+ switch (uiTo)
+ {
+ case AXIS_MAP_LX:
+ pfTo = &m_Joypads[iPad].m_fNormalizedLeftThumbX;
+ break;
+ case AXIS_MAP_LY:
+ pfTo = &m_Joypads[iPad].m_fNormalizedLeftThumbY;
+ break;
+ case AXIS_MAP_RX:
+ pfTo = &m_Joypads[iPad].m_fNormalizedRightThumbX;
+ break;
+ case AXIS_MAP_RY:
+ pfTo = &m_Joypads[iPad].m_fNormalizedRightThumbY;
+ break;
+ }
+
+ switch (uiFrom)
+ {
+ case AXIS_MAP_LX:
+ m_Joypads[iPad].m_pfLeftThumbXAxisMap = pfTo;
+ break;
+ case AXIS_MAP_LY:
+ m_Joypads[iPad].m_pfLeftThumbYAxisMap = pfTo;
+ break;
+ case AXIS_MAP_RX:
+ m_Joypads[iPad].m_pfRightThumbXAxisMap = pfTo;
+ break;
+ case AXIS_MAP_RY:
+ m_Joypads[iPad].m_pfRightThumbYAxisMap = pfTo;
+ break;
+ }
+}
+
+void CInput::SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo)
+{
+ unsigned char *pucTo = nullptr;
+
+ switch (uiTo)
+ {
+ case TRIGGER_MAP_0:
+ pucTo = &m_Joypads[iPad].m_ucRightTriggerState;
+ break;
+ case TRIGGER_MAP_1:
+ pucTo = &m_Joypads[iPad].m_ucLeftTriggerState;
+ break;
+ }
+
+ switch (uiFrom)
+ {
+ case TRIGGER_MAP_0:
+ m_Joypads[iPad].m_pucRightTriggerAxisMap = pucTo;
+ break;
+ case TRIGGER_MAP_1:
+ m_Joypads[iPad].m_pucLeftTriggerAxisMap = pucTo;
+ break;
+ }
+}
+
+bool CInput::IsPadConnected(int iPad)
+{
+ return m_Joypads[iPad].m_bIsConnected;
+}
+
+void CInput::SetSigninJoypadMask(unsigned int mask)
+{
+ m_uiSigninJoypadMask = mask;
+}
+
+unsigned int CInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat)
+{
+ if (m_bIsMenuDisplayed[iPad] && ucAction > this->m_ucMenuActionC)
+ {
+ return 0;
+ }
+
+ unsigned char ucMap = this->m_Joypads[iPad].m_ucMappingValue;
+ unsigned int uiVal = this->m_JoypadMap[ucMap][ucAction] & this->m_Joypads[iPad].m_uiButtons;
+ if (!uiVal || !bRepeat)
+ {
+ return uiVal;
+ }
+
+ int iKeyVal = 0;
+ for (int iKey = this->m_JoypadMap[ucMap][ucAction]; (iKey & 1) == 0; iKey >>= 1)
+ {
+ iKeyVal++;
+ }
+
+ if (m_fRepeatDelaySecs <= m_Timers[iPad][iKeyVal].m_fTotalHoldTime || m_Timers[iPad][iKeyVal].m_bInitialPressHandled)
+ {
+ if (m_Timers[iPad][iKeyVal].m_fTotalHoldTime < m_fRepeatDelaySecs)
+ {
+ return 0;
+ }
+ else if (m_Timers[iPad][iKeyVal].m_fLastRepeatTime == 0.0f)
+ {
+ m_Timers[iPad][iKeyVal].m_fLastRepeatTime = m_fRepeatDelaySecs;
+ return uiVal;
+ }
+ else if ((m_Timers[iPad][iKeyVal].m_fTotalHoldTime - m_Timers[iPad][iKeyVal].m_fLastRepeatTime) <= m_fRepeatRateSecs)
+ {
+ return 0;
+ }
+ else
+ {
+ m_Timers[iPad][iKeyVal].m_fLastRepeatTime = m_Timers[iPad][iKeyVal].m_fLastRepeatTime + m_fRepeatRateSecs;
+ return uiVal;
+ }
+ }
+ else
+ {
+ m_Timers[iPad][iKeyVal].m_bInitialPressHandled = true;
+ return uiVal;
+ }
+}
+
+bool CInput::IsSet(int iPad, unsigned char ucAction)
+{
+ return (!m_bIsMenuDisplayed[iPad] || ucAction <= m_ucMenuActionC) &&
+ (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtons) != 0;
+}
+
+bool CInput::ButtonPressed(int iPad, unsigned char ucAction)
+{
+ if (ucAction == 255)
+ {
+ return m_Joypads[iPad].m_uiButtonsPressed != 0;
+ }
+
+ if (m_bIsMenuDisplayed[iPad] && ucAction > m_ucMenuActionC)
+ {
+ return 0;
+ }
+
+ return (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtonsPressed) != 0;
+}
+
+bool CInput::ButtonReleased(int iPad, unsigned char ucAction)
+{
+ return (!m_bIsMenuDisplayed[iPad] || ucAction <= m_ucMenuActionC) &&
+ (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtonsReleased) != 0;
+}
+
+bool CInput::ButtonDown(int iPad, unsigned char ucAction)
+{
+ if (ucAction == 255)
+ {
+ return m_Joypads[iPad].m_uiButtons != 0;
+ }
+
+ if (m_bIsMenuDisplayed[iPad] && ucAction > m_ucMenuActionC)
+ {
+ return 0;
+ }
+
+ return (m_JoypadMap[m_Joypads[iPad].m_ucMappingValue][ucAction] & m_Joypads[iPad].m_uiButtons) != 0;
+}
+
+float CInput::GetJoypadStick_Menu_LX(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_iNormalizedLeftThumbX;
+}
+
+float CInput::GetJoypadStick_Menu_LY(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_iNormalizedLeftThumbY;
+}
+
+float CInput::GetJoypadStick_Menu_RX(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_iNormalizedRightThumbX;
+}
+
+float CInput::GetJoypadStick_Menu_RY(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_iNormalizedRightThumbY;
+}
+
+unsigned char CInput::GetJoypadLTrigger_Menu(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_ucLeftTriggerState;
+}
+
+unsigned char CInput::GetJoypadRTrigger_Menu(unsigned char ucPad)
+{
+ return m_Joypads[ucPad].m_ucRightTriggerState;
+}
+
+float CInput::GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0.0f;
+ }
+
+ return *m_Joypads[iPad].m_pfLeftThumbXAxisMap * m_Joypads[iPad].m_fSensitivity;
+}
+
+float CInput::GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0.0f;
+ }
+
+ return *m_Joypads[iPad].m_pfLeftThumbYAxisMap * m_Joypads[iPad].m_fSensitivity;
+}
+
+float CInput::GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0.0f;
+ }
+
+ return *m_Joypads[iPad].m_pfRightThumbXAxisMap * m_Joypads[iPad].m_fSensitivity;
+}
+
+float CInput::GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0.0f;
+ }
+
+ return *m_Joypads[iPad].m_pfRightThumbYAxisMap * m_Joypads[iPad].m_fSensitivity;
+}
+
+unsigned char CInput::GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0;
+ }
+
+ return *m_Joypads[iPad].m_pucLeftTriggerAxisMap;
+}
+
+unsigned char CInput::GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay)
+{
+ if (bCheckMenuDisplay && m_bIsMenuDisplayed[iPad])
+ {
+ return 0;
+ }
+
+ return *m_Joypads[iPad].m_pucRightTriggerAxisMap;
+}
+
+void CInput::SetMenuDisplayed(int iPad, bool bVal)
+{
+ m_bIsMenuDisplayed[iPad] = bVal;
+}
+
+void CInput::SetKeyRepeatRate(float fRepeatDelaySecs, float fRepeatRateSecs)
+{
+ m_fRepeatDelaySecs = fRepeatDelaySecs;
+ m_fRepeatRateSecs = fRepeatRateSecs;
+}
+
+void CInput::SetDebugSequence(const char *chSequenceA, int (*Func)(LPVOID), LPVOID lpParam)
+{
+ int iLen = strlen(chSequenceA);
+
+ m_sDebugSequenceName = (char *)operator new[](iLen);
+ strcpy(m_sDebugSequenceName, chSequenceA);
+
+ m_pDebugSequenceFn = Func;
+ m_pDebugSequenceParam = lpParam;
+}
+
+FLOAT CInput::GetIdleSeconds(int iPad)
+{
+ LARGE_INTEGER qwDeltaTime;
+ QueryPerformanceCounter(&qwDeltaTime);
+
+ LARGE_INTEGER fElapsedTime = this->m_LastActivityTime[iPad];
+ uint64_t qwNewTime = qwDeltaTime.QuadPart - fElapsedTime.QuadPart;
+
+ return this->m_fTickToSeconds * (qwDeltaTime.LowPart - fElapsedTime.LowPart);
+}
+
+bool CInput::UpdateJoypads()
+{
+ assert(m_bJoypadMapArrayIsSetup);
+
+ for (int i = 0; i < MAX_JOYPADS; i++)
+ {
+ JOYPAD *pThisPad = &m_Joypads[i];
+
+ pThisPad->m_uiOldButtons = pThisPad->m_uiButtons;
+ pThisPad->m_uiButtons = 0;
+ pThisPad->m_iRightThumbY = 0;
+ pThisPad->m_iRightThumbX = 0;
+ pThisPad->m_iLeftThumbY = 0;
+ pThisPad->m_iLeftThumbX = 0;
+ pThisPad->m_ucLeftTriggerState = 0;
+ pThisPad->m_ucRightTriggerState = 0;
+ }
+
+ for (int i = 0; i < MAX_JOYPADS; i++)
+ {
+ if (!m_Joypads[i].m_bIsDisabled)
+ {
+ JOYPAD *pThisPad = &m_Joypads[i];
+
+ bool bOldIsConnected = pThisPad->m_bIsConnected;
+
+ pThisPad->m_ucInputStateIndex = pThisPad->m_ucInputStateIndex++;
+ if (pThisPad->m_ucInputStateIndex == m_ucInputStateC)
+ {
+ pThisPad->m_ucInputStateIndex = 0;
+ }
+
+ pThisPad->m_bIsConnected = XInputGetState(i, &pThisPad->m_pInputStates[pThisPad->m_ucInputStateIndex]) == 0;
+
+ bool bWasConnected = bOldIsConnected && !pThisPad->m_bIsConnected;
+ pThisPad->m_bWasConnected = bWasConnected;
+
+ bool bHasConnected = !bOldIsConnected && pThisPad->m_bIsConnected;
+ pThisPad->m_bHasConnected = bHasConnected;
+
+ if (pThisPad->m_bIsConnected)
+ {
+ SetJoypadValues(pThisPad);
+
+ pThisPad->m_uiButtonsPressed = ~pThisPad->m_uiOldButtons & pThisPad->m_uiButtons;
+ pThisPad->m_uiButtonsReleased = ~pThisPad->m_uiButtons & pThisPad->m_uiOldButtons;
+
+ for (int bit = 0; bit < 24; ++bit)
+ {
+ if ((pThisPad->m_uiButtonsPressed & (1 << bit)) != 0)
+ {
+ GetStartTime(i, bit);
+ }
+ else if ((pThisPad->m_uiButtons & (1 << bit)) != 0)
+ {
+ UpdateTime(i, bit);
+ }
+ }
+ }
+ else if (pThisPad->m_bWasConnected)
+ {
+ ClearJoypadValues(pThisPad);
+ }
+
+ if (m_pDebugSequenceFn && (pThisPad->m_uiButtonsPressed & (_360_JOY_BUTTON_A | _360_JOY_BUTTON_B | _360_JOY_BUTTON_X | _360_JOY_BUTTON_Y |
+ _360_JOY_BUTTON_RB | _360_JOY_BUTTON_LB)) != 0)
+ {
+ char chSeq;
+
+ if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_A) == _360_JOY_BUTTON_A)
+ {
+ chSeq = 'A';
+ }
+ else if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_B) == _360_JOY_BUTTON_B)
+ {
+ chSeq = 'B';
+ }
+ else if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_X) == _360_JOY_BUTTON_X)
+ {
+ chSeq = 'X';
+ }
+ else if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_Y) == _360_JOY_BUTTON_Y)
+ {
+ chSeq = 'Y';
+ }
+ else if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_LB) == _360_JOY_BUTTON_LB)
+ {
+ chSeq = 'L';
+ }
+ else if ((pThisPad->m_uiButtonsPressed & _360_JOY_BUTTON_RB) == _360_JOY_BUTTON_RB)
+ {
+ chSeq = 'R';
+ }
+
+ if (m_sDebugSequenceName[m_uiDebugSequenceIndex] == chSeq)
+ {
+ if (!m_sDebugSequenceName[m_uiDebugSequenceIndex++])
+ {
+ m_uiDebugSequenceIndex = 0;
+ (m_pDebugSequenceFn)(m_pDebugSequenceParam);
+ }
+ }
+ else
+ {
+ m_uiDebugSequenceIndex = 0;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void CInput::ClearJoypadValues(JOYPAD *pThisPad)
+{
+ pThisPad->m_uiButtonsPressed = 0;
+ pThisPad->m_uiButtonsReleased = 0;
+ pThisPad->m_uiButtons = 0;
+ pThisPad->m_ucLeftTriggerState = 0;
+ pThisPad->m_ucRightTriggerState = 0;
+ pThisPad->m_iRightThumbX = 0;
+ pThisPad->m_iRightThumbY = 0;
+ pThisPad->m_iLeftThumbX = 0;
+ pThisPad->m_iLeftThumbY = 0;
+ pThisPad->m_iNormalizedLeftThumbX = 0;
+ pThisPad->m_iNormalizedLeftThumbY = 0;
+ pThisPad->m_iNormalizedRightThumbX = 0;
+ pThisPad->m_iNormalizedRightThumbY = 0;
+ pThisPad->m_fNormalizedLeftThumbX = 0.0f;
+ pThisPad->m_fNormalizedLeftThumbY = 0.0f;
+ pThisPad->m_fNormalizedRightThumbX = 0.0f;
+ pThisPad->m_fNormalizedRightThumbY = 0.0f;
+}
+
+void CInput::InitTime(void)
+{
+ LARGE_INTEGER qwTicksPerSec;
+ QueryPerformanceFrequency(&qwTicksPerSec);
+
+ m_fTickToSeconds = 1.0 / (float)(int)qwTicksPerSec.LowPart;
+ for (int i = 0; i < MAX_JOYPADS; i++)
+ {
+ m_LastActivityTime[i].QuadPart = 0;
+ }
+}
+
+void CInput::GetStartTime(int iPad, int iKey)
+{
+ QueryPerformanceCounter(&m_Timers[iPad][iKey].m_qwStartTime);
+
+ m_Timers[iPad][iKey].m_qwTotalHoldTicks.QuadPart = 0;
+ m_Timers[iPad][iKey].m_fTotalHoldTime = 0;
+ m_Timers[iPad][iKey].m_fLastRepeatTime = 0;
+ m_Timers[iPad][iKey].m_bInitialPressHandled = false;
+
+ m_LastActivityTime[iPad].QuadPart = m_Timers[iPad][iKey].m_qwStartTime.QuadPart;
+}
+
+void CInput::UpdateTime(int iPad, int iKey)
+{
+ LARGE_INTEGER qwDeltaTime;
+ QueryPerformanceCounter(&qwDeltaTime);
+
+ uint64_t qwNewTime = qwDeltaTime.QuadPart - m_Timers[iPad][iKey].m_qwStartTime.QuadPart;
+ m_Timers[iPad][iKey].m_qwTotalHoldTicks.QuadPart += qwNewTime;
+
+ m_Timers[iPad][iKey].m_qwStartTime = qwDeltaTime;
+ m_Timers[iPad][iKey].m_fTotalHoldTime = m_Timers[iPad][iKey].m_fTotalHoldTime + (m_fTickToSeconds * qwNewTime);
+
+ m_LastActivityTime[iPad].QuadPart = m_Timers[iPad][iKey].m_qwStartTime.QuadPart;
+}
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/INP_Main.h b/Minecraft.Client/Platform_Libs/Dev/Input/INP_Main.h
new file mode 100644
index 0000000..63d24b9
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/INP_Main.h
@@ -0,0 +1,183 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "INP_ForceFeedback.h"
+#include "INP_Keyboard.h"
+
+#define MAX_JOYPADS 4
+
+class CInput
+{
+public:
+ struct JOYPAD
+ {
+ bool m_bIsDisabled;
+ bool m_bIsConnected;
+ bool m_bWasConnected;
+ bool m_bHasConnected;
+
+ unsigned int m_uiButtons;
+ unsigned int m_uiOldButtons;
+ int m_uiButtonsPressed;
+ int m_uiButtonsReleased;
+
+ int m_iRightThumbX;
+ int m_iRightThumbY;
+ int m_iLeftThumbX;
+ int m_iLeftThumbY;
+
+ DWORD m_iNormalizedRightThumbX;
+ DWORD m_iNormalizedRightThumbY;
+ DWORD m_iNormalizedLeftThumbX;
+ DWORD m_iNormalizedLeftThumbY;
+
+ float m_fNormalizedRightThumbX;
+ float m_fNormalizedRightThumbY;
+ float m_fNormalizedLeftThumbX;
+ float m_fNormalizedLeftThumbY;
+
+ unsigned char m_ucLeftTriggerState;
+ unsigned char m_ucRightTriggerState;
+
+ float *m_pfLeftThumbXAxisMap;
+ float *m_pfLeftThumbYAxisMap;
+ float *m_pfRightThumbXAxisMap;
+ float *m_pfRightThumbYAxisMap;
+
+ float m_fSensitivity;
+
+ BYTE *m_pucLeftTriggerAxisMap;
+ BYTE *m_pucRightTriggerAxisMap;
+
+ unsigned char m_ucMappingValue;
+ unsigned char m_ucInputStateIndex;
+ XINPUT_STATE *m_pInputStates;
+ };
+
+ struct JOYPADS
+ {
+ };
+
+ struct TimeInfo
+ {
+ LARGE_INTEGER m_qwStartTime;
+ LARGE_INTEGER m_qwTotalHoldTicks;
+ float m_fTotalHoldTime;
+ float m_fLastRepeatTime;
+ bool m_bInitialPressHandled;
+ };
+
+ CInput();
+
+ void Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC);
+ void Tick(void);
+
+ void SetJoypadValues(JOYPAD *pThisPad);
+ void SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax);
+ void SetJoypadSensitivity(int iPad, float fSensitivity);
+
+ void SetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction, unsigned int uiActionVal);
+ unsigned int GetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction);
+ void SetJoypadMapVal(int iPad, unsigned char ucMap);
+ unsigned char GetJoypadMapVal(int iPad);
+
+ void SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo);
+ void SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo);
+
+ bool IsPadConnected(int iPad);
+ void SetSigninJoypadMask(unsigned int mask);
+ unsigned int GetValue(int iPad, unsigned char ucAction, bool bRepeat = false);
+ bool IsSet(int iPad, unsigned char ucAction);
+
+ bool ButtonPressed(int iPad, unsigned char ucAction = 255); // toggled
+ bool ButtonReleased(int iPad, unsigned char ucAction); // toggled
+ bool ButtonDown(int iPad, unsigned char ucAction = 255); // button held down
+
+ float GetJoypadStick_Menu_LX(unsigned char ucPad);
+ float GetJoypadStick_Menu_LY(unsigned char ucPad);
+ float GetJoypadStick_Menu_RX(unsigned char ucPad);
+ float GetJoypadStick_Menu_RY(unsigned char ucPad);
+ unsigned char GetJoypadLTrigger_Menu(unsigned char ucPad);
+ unsigned char GetJoypadRTrigger_Menu(unsigned char ucPad);
+
+ float GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay = true);
+ float GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay = true);
+ float GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay = true);
+ float GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay = true);
+ unsigned char GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay = true);
+ unsigned char GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay = true);
+
+ void SetMenuDisplayed(int iPad, bool bVal);
+
+ void SetKeyRepeatRate(float fRepeatDelaySecs, float fRepeatRateSecs);
+ void SetDebugSequence(const char *chSequenceA, int (*Func)(LPVOID), LPVOID lpParam);
+ FLOAT GetIdleSeconds(int iPad);
+
+ bool UpdateJoypads(void);
+ void ClearJoypadValues(JOYPAD *pThisPad);
+
+ void InitTime(void);
+ void GetStartTime(int iPad, int iKey);
+ void UpdateTime(int iPad, int iKey);
+
+ BYTE gap0[16];
+
+ JOYPAD m_Joypads[MAX_JOYPADS];
+
+ int m_iDeadzone;
+ int m_iMovementRangeMax;
+ int m_iEffectiveRange;
+ int m_iHalfRange;
+ float m_fEffectiveRange;
+
+ unsigned char m_ucInputStateC;
+ unsigned char m_ucJoypadMapC;
+ unsigned char m_ucJoypadMapActionC;
+ unsigned char m_ucMenuActionC;
+
+ unsigned int **m_JoypadMap;
+
+ bool m_bJoypadMapArrayIsSetup;
+ unsigned int m_uiSigninJoypadMask;
+ bool m_bIsMenuDisplayed[MAX_JOYPADS];
+
+ CForceFeedback m_ForceFeedback;
+ CKeyboard m_Keyboard;
+
+ float m_fTickToSeconds;
+ float m_fRepeatDelaySecs;
+ float m_fRepeatRateSecs;
+
+ TimeInfo m_Timers[MAX_JOYPADS][24];
+ LARGE_INTEGER m_LastActivityTime[MAX_JOYPADS];
+
+ char *m_sDebugSequenceName;
+ unsigned int m_uiDebugSequenceIndex;
+ int (*m_pDebugSequenceFn)(void *);
+ LPVOID m_pDebugSequenceParam;
+};
+
+// Singleton
+extern CInput InternalInputManager;
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/INP_StringCheck.cpp b/Minecraft.Client/Platform_Libs/Dev/Input/INP_StringCheck.cpp
new file mode 100644
index 0000000..541aeb2
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/INP_StringCheck.cpp
@@ -0,0 +1,26 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "stdafx.h"
+#include "INP_StringCheck.h"
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/INP_StringCheck.h b/Minecraft.Client/Platform_Libs/Dev/Input/INP_StringCheck.h
new file mode 100644
index 0000000..604a3e9
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/INP_StringCheck.h
@@ -0,0 +1,24 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/Input.vcxproj b/Minecraft.Client/Platform_Libs/Dev/Input/Input.vcxproj
new file mode 100644
index 0000000..fb52e36
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/Input.vcxproj
@@ -0,0 +1,184 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 18.0
+ Win32Proj
+ {258f8cf7-6317-480d-b07d-52a6846adf67}
+ input
+ 10.0
+ Input
+
+
+
+ StaticLibrary
+ true
+ v145
+ Unicode
+
+
+ StaticLibrary
+ false
+ v145
+ true
+ Unicode
+
+
+ StaticLibrary
+ true
+ v110
+ Unicode
+
+
+ StaticLibrary
+ false
+ v145
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4J_$(ProjectName)_d
+
+
+ 4J_$(ProjectName)
+
+
+
+ Level3
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+ Use
+ pch.h
+
+
+
+
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+ Use
+ pch.h
+
+
+
+
+ true
+
+
+
+
+ Level3
+ true
+ _CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+ Use
+ stdafx.h
+ stdafx.h
+ true
+ MultiThreadedDebug
+ Default
+ true
+
+
+
+
+ true
+
+
+
+
+
+ Level3
+ true
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+ Use
+ stdafx.h
+ stdafx.h
+ true
+ MultiThreaded
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/Input.vcxproj.filters b/Minecraft.Client/Platform_Libs/Dev/Input/Input.vcxproj.filters
new file mode 100644
index 0000000..53711b9
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/Input.vcxproj.filters
@@ -0,0 +1,59 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/LinkedList.cpp b/Minecraft.Client/Platform_Libs/Dev/Input/LinkedList.cpp
new file mode 100644
index 0000000..f9f71b4
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/LinkedList.cpp
@@ -0,0 +1,127 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "stdafx.h"
+#include "LinkedList.h"
+
+LinkedList::LinkedList()
+{
+ this->m_NodeC = 0;
+ this->m_Head = nullptr;
+ this->m_Tail = nullptr;
+}
+
+void LinkedList::AddToHead(void *pvData)
+{
+ _LL_NODE *pNode = new _LL_NODE();
+ pNode->m_pvData = pvData;
+
+ if (!m_Tail)
+ {
+ m_Tail = pNode;
+ }
+
+ if (m_Head)
+ {
+ m_Head->m_Prev = pNode;
+ pNode->m_Next = m_Head;
+ }
+
+ m_Head = pNode;
+ m_NodeC++;
+}
+
+void LinkedList::AddToTail(void *pvData)
+{
+ _LL_NODE *pNode = new _LL_NODE();
+ pNode->m_pvData = pvData;
+
+ if (!m_Head)
+ {
+ m_Head = pNode;
+ }
+
+ if (m_Tail)
+ {
+ m_Tail->m_Next = pNode;
+ pNode->m_Prev = m_Tail;
+ }
+
+ pNode->m_Next = nullptr;
+ pNode->m_Prev = m_Tail;
+
+ m_Tail = pNode;
+ m_NodeC++;
+}
+
+void LinkedList::RemoveNode(_LL_NODE *pNodeToRemove)
+{
+ _LL_NODE *pCurrentNode;
+ for (pCurrentNode = m_Head; pCurrentNode != pNodeToRemove; pCurrentNode = pCurrentNode->m_Next)
+ {
+ ;
+ }
+
+ if (pCurrentNode == m_Head)
+ {
+ m_Head = m_Head->m_Next;
+ }
+ else
+ {
+ pCurrentNode->m_Prev->m_Next = pCurrentNode->m_Next;
+
+ if (pCurrentNode->m_Next)
+ {
+ pCurrentNode->m_Next->m_Prev = pCurrentNode->m_Prev;
+ }
+ }
+
+ m_NodeC--;
+}
+
+LinkedList::_LL_NODE *LinkedList::RemoveHeadNode()
+{
+ _LL_NODE *pHeadNode = m_Head;
+
+ if (m_NodeC > 0)
+ {
+ m_Head = m_Head->m_Next;
+ m_NodeC--;
+ }
+
+ return pHeadNode;
+}
+
+void LinkedList::ClearList()
+{
+ while (true)
+ {
+ _LL_NODE *pHeadNode = RemoveHeadNode();
+ if (!pHeadNode)
+ {
+ break;
+ }
+ delete pHeadNode;
+ }
+}
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/LinkedList.h b/Minecraft.Client/Platform_Libs/Dev/Input/LinkedList.h
new file mode 100644
index 0000000..1cfbf2e
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/LinkedList.h
@@ -0,0 +1,52 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+class LinkedList
+{
+public:
+ struct _LL_NODE
+ {
+ template
+ T *GetDataAs()
+ {
+ return (T *)m_pvData;
+ }
+
+ void *m_pvData;
+ _LL_NODE *m_Next;
+ _LL_NODE *m_Prev;
+ };
+
+ int m_NodeC;
+ _LL_NODE *m_Head;
+ _LL_NODE *m_Tail;
+
+ LinkedList();
+ void AddToHead(void *pvData);
+ void AddToTail(void *pvData);
+ void RemoveNode(_LL_NODE *pNodeToRemove);
+ _LL_NODE *RemoveHeadNode();
+ void ClearList();
+};
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/stdafx.cpp b/Minecraft.Client/Platform_Libs/Dev/Input/stdafx.cpp
new file mode 100644
index 0000000..af112cc
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/stdafx.cpp
@@ -0,0 +1,25 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "stdafx.h"
diff --git a/Minecraft.Client/Platform_Libs/Dev/Input/stdafx.h b/Minecraft.Client/Platform_Libs/Dev/Input/stdafx.h
new file mode 100644
index 0000000..7a41c49
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Input/stdafx.h
@@ -0,0 +1,34 @@
+#ifndef STDAFX_H
+#define STDAFX_H
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+#include
+#include
+#include
+
+#endif //STDAFX_H
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/4J_Profile.cpp b/Minecraft.Client/Platform_Libs/Dev/Profile/4J_Profile.cpp
new file mode 100644
index 0000000..a1d60e6
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/4J_Profile.cpp
@@ -0,0 +1,29 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "stdafx.h"
+#include "4J_Profile.h"
+
+C_4JProfile ProfileManager;
+
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/CMakeLists.txt b/Minecraft.Client/Platform_Libs/Dev/Profile/CMakeLists.txt
new file mode 100644
index 0000000..0c52582
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/CMakeLists.txt
@@ -0,0 +1,26 @@
+cmake_minimum_required(VERSION 3.25 FATAL_ERROR)
+
+project(4JLibs.Windows.Profile LANGUAGES CXX)
+
+add_library(${PROJECT_NAME} STATIC
+ 4J_Profile.cpp
+ PRO_AwardManager.cpp
+ PRO_Data.cpp
+ PRO_Main.cpp
+ PRO_RichPresence.cpp
+ PRO_Sys.cpp
+ stdafx.cpp
+)
+
+target_include_directories(${PROJECT_NAME} PRIVATE
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+target_precompile_headers(${PROJECT_NAME} PRIVATE
+ stdafx.h
+)
+
+set_target_properties(${PROJECT_NAME} PROPERTIES
+ PREFIX ""
+ OUTPUT_NAME "4J_Profile"
+)
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_AwardManager.cpp b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_AwardManager.cpp
new file mode 100644
index 0000000..3bf1bb5
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_AwardManager.cpp
@@ -0,0 +1,23 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_AwardManager.h b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_AwardManager.h
new file mode 100644
index 0000000..604a3e9
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_AwardManager.h
@@ -0,0 +1,24 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Data.cpp b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Data.cpp
new file mode 100644
index 0000000..3bf1bb5
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Data.cpp
@@ -0,0 +1,23 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Data.h b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Data.h
new file mode 100644
index 0000000..604a3e9
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Data.h
@@ -0,0 +1,24 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Main.cpp b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Main.cpp
new file mode 100644
index 0000000..3bf1bb5
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Main.cpp
@@ -0,0 +1,23 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Main.h b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Main.h
new file mode 100644
index 0000000..604a3e9
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Main.h
@@ -0,0 +1,24 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_RichPresence.cpp b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_RichPresence.cpp
new file mode 100644
index 0000000..3bf1bb5
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_RichPresence.cpp
@@ -0,0 +1,23 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_RichPresence.h b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_RichPresence.h
new file mode 100644
index 0000000..604a3e9
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_RichPresence.h
@@ -0,0 +1,24 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Sys.cpp b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Sys.cpp
new file mode 100644
index 0000000..3bf1bb5
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Sys.cpp
@@ -0,0 +1,23 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Sys.h b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Sys.h
new file mode 100644
index 0000000..604a3e9
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/PRO_Sys.h
@@ -0,0 +1,24 @@
+#pragma once
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/Profile.vcxproj b/Minecraft.Client/Platform_Libs/Dev/Profile/Profile.vcxproj
new file mode 100644
index 0000000..f30d72e
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/Profile.vcxproj
@@ -0,0 +1,185 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 18.0
+ Win32Proj
+ {d68297b9-ca86-4a8c-b81f-61811d7f96b8}
+ profile
+ 10.0
+ Profile
+
+
+
+ StaticLibrary
+ true
+ v145
+ Unicode
+
+
+ StaticLibrary
+ false
+ v145
+ true
+ Unicode
+
+
+ StaticLibrary
+ true
+ v110
+ Unicode
+
+
+ StaticLibrary
+ false
+ v145
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4J_$(ProjectName)
+
+
+ 4J_$(ProjectName)_d
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+ Use
+ pch.h
+
+
+
+
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+ Use
+ pch.h
+
+
+
+
+ true
+
+
+
+
+ Level3
+ true
+ _CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+ Use
+ stdafx.h
+ true
+ stdafx.h
+ MultiThreadedDebug
+ Default
+ true
+
+
+
+
+ true
+
+
+
+
+
+ Level3
+ true
+ true
+ true
+ _CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+ Use
+ stdafx.h
+ true
+ stdafx.h
+ MultiThreaded
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/Profile.vcxproj.filters b/Minecraft.Client/Platform_Libs/Dev/Profile/Profile.vcxproj.filters
new file mode 100644
index 0000000..ddd612f
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/Profile.vcxproj.filters
@@ -0,0 +1,62 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/stdafx.cpp b/Minecraft.Client/Platform_Libs/Dev/Profile/stdafx.cpp
new file mode 100644
index 0000000..af112cc
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/stdafx.cpp
@@ -0,0 +1,25 @@
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "stdafx.h"
diff --git a/Minecraft.Client/Platform_Libs/Dev/Profile/stdafx.h b/Minecraft.Client/Platform_Libs/Dev/Profile/stdafx.h
new file mode 100644
index 0000000..8cb5bc3
--- /dev/null
+++ b/Minecraft.Client/Platform_Libs/Dev/Profile/stdafx.h
@@ -0,0 +1,38 @@
+#ifndef PCH_H
+#define PCH_H
+/*
+MIT License
+
+Copyright (c) 2026 Patoke
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#define WIN32_LEAN_AND_MEAN
+#include
+
+#include
+#include
+#include
+
+typedef unsigned __int64 __uint64;
+
+#include "extraX64.h"
+
+#endif //PCH_H
diff --git a/Minecraft.Client/Platform_Libs/Dev/Storage/4J_Storage.cpp b/Minecraft.Client/Platform_Libs/Dev/Storage/4J_Storage.cpp
index 31ddc72..aca15cb 100644
--- a/Minecraft.Client/Platform_Libs/Dev/Storage/4J_Storage.cpp
+++ b/Minecraft.Client/Platform_Libs/Dev/Storage/4J_Storage.cpp
@@ -22,6 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
+#include "stdafx.h"
#include "4J_Storage.h"
#include "STO_Main.h"
diff --git a/Minecraft.Client/Platform_Libs/Dev/Storage/STO_DLC.cpp b/Minecraft.Client/Platform_Libs/Dev/Storage/STO_DLC.cpp
index 316547e..bc4e8d2 100644
--- a/Minecraft.Client/Platform_Libs/Dev/Storage/STO_DLC.cpp
+++ b/Minecraft.Client/Platform_Libs/Dev/Storage/STO_DLC.cpp
@@ -22,6 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
+#include "stdafx.h"
#include "STO_DLC.h"
#include "STO_Main.h"
diff --git a/Minecraft.Client/Platform_Libs/Dev/Storage/STO_Main.cpp b/Minecraft.Client/Platform_Libs/Dev/Storage/STO_Main.cpp
index 9e5645a..f461618 100644
--- a/Minecraft.Client/Platform_Libs/Dev/Storage/STO_Main.cpp
+++ b/Minecraft.Client/Platform_Libs/Dev/Storage/STO_Main.cpp
@@ -22,6 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
+#include "stdafx.h"
#include "STO_Main.h"
#include "4J_Storage.h"
diff --git a/Minecraft.Client/Platform_Libs/Dev/Storage/STO_SaveGame.cpp b/Minecraft.Client/Platform_Libs/Dev/Storage/STO_SaveGame.cpp
index ce6c68a..a9fe931 100644
--- a/Minecraft.Client/Platform_Libs/Dev/Storage/STO_SaveGame.cpp
+++ b/Minecraft.Client/Platform_Libs/Dev/Storage/STO_SaveGame.cpp
@@ -22,6 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
+#include "stdafx.h"
#include "STO_SaveGame.h"
#include
diff --git a/Minecraft.Server b/Minecraft.Server
index 797530e..aad5c68 160000
--- a/Minecraft.Server
+++ b/Minecraft.Server
@@ -1 +1 @@
-Subproject commit 797530e883fb12887dbc40ff7e0f39b16771b9bc
+Subproject commit aad5c68b7eac04586d13241ea18e9bf6f7170185