mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
The old Windows64 port had no real player identity — it used hardcoded fake XUIDs, so anyone could impersonate anyone. This replaces that with proper auth supporting Mojang, Ely.by, and offline accounts. MCAuth library (new, MCAuth/): Mojang auth via MSA device code flow (XBL, SISU, MC services), Ely.by via Yggdrasil with 2FA, offline UUID generation matching Java Edition (MD5 v3 from "OfflinePlayer:<name>"). Multi-account manager with background token refresh, per-slot sessions, and on-disk token persistence. Server-side session verification via Mojang/Ely.by hasJoined API. Skin fetching and PNG validation from texture servers. Network protocol (version bumped to 80): Three new packets (AuthScheme, AuthResponse, AuthResult) implement a server-driven auth handshake before login completes. Player identity migrated from 64-bit XUID to 128-bit GameUUID backed by two uint64 fields (hi/lo). readPlayerUID/writePlayerUID now serialize 16 bytes on the wire. Old and new clients cannot connect to each other — version mismatch is rejected at PreLogin. Save migration: Map data mappings auto-migrate from old format: the old 64-bit XUID is placed in hi, lo is set to 0 as a sentinel. On first access by the real player, the sentinel entry is upgraded in-place to the full 128-bit UUID. Format detection is by file size (2080, 2112, or 4160 bytes). Player .dat filenames inside saveData.ms change from decimal XUID to dashed UUID — old saves need manual entry renaming in the archive. UI: NativeUIRenderer: immediate-mode drawing system (quads, text, 9-slice panels, scrollbars, focus lists) for rendering auth screens without Flash/Scaleform. UIScene_MSAuth handles device code display, Ely.by credential input with 2FA, per-account skin head preview, and multi-account add/remove/switch. Server: online-mode and auth-provider (mojang/elyby) in server.properties. Whitelist and ban checks validate against the server-verified UUID. Incompatible auth scheme logs which provider the server expects vs what the client is using. Also fixes a pre-existing exploit where any client could send a DebugOptionsPacket to grant themselves CraftAnything and other debug privileges on any server — now requires OP status server-side.
347 lines
14 KiB
C++
347 lines
14 KiB
C++
#pragma once
|
|
#include <cstdint>
|
|
#include <vector>
|
|
#include <string>
|
|
|
|
|
|
// NativeUI — Direct D3D11 2D rendering for SWF-free UIScene subclasses.
|
|
//
|
|
// Renders rectangles, text, and widgets via raw D3D11 draw calls,
|
|
// completely independent of the Tesselator/RenderManager pipeline.
|
|
//
|
|
// Usage:
|
|
//
|
|
// void MyScene::render(S32 w, S32 h, C4JRender::eViewportType vp)
|
|
// {
|
|
// if (!m_hasTickedOnce) return;
|
|
// NativeUI::BeginFrame();
|
|
//
|
|
// NativeUI::DrawRect(0, 0, 1280, 720, 0xCC000000u);
|
|
// NativeUI::DrawShadowText(640, 300, L"Hello",
|
|
// 0xFFFFFFFFu, 22.0f, ALIGN_CENTER_X);
|
|
//
|
|
// NativeUI::EndFrame();
|
|
// }
|
|
//
|
|
// Coordinate space: 1280 x 720 virtual canvas (resolution-independent).
|
|
// Color format: 0xAARRGGBB (alpha 0xFF = opaque).
|
|
// Font size: Height in virtual pixels. Bitmap font is 8 units tall;
|
|
// system scales to match. Common sizes: 8, 12, 14, 16, 22.
|
|
|
|
|
|
namespace NativeUI
|
|
{
|
|
// ---- Alignment flags ------------------------------------------
|
|
enum : uint32_t
|
|
{
|
|
ALIGN_LEFT = 0x00u,
|
|
ALIGN_RIGHT = 0x01u,
|
|
ALIGN_CENTER_X = 0x02u,
|
|
ALIGN_CENTER_Y = 0x04u,
|
|
ALIGN_BOTTOM = 0x08u,
|
|
};
|
|
|
|
// ---- Lifecycle ------------------------------------------------
|
|
|
|
void BeginFrame();
|
|
void EndFrame();
|
|
void Shutdown();
|
|
|
|
// ---- Input helpers (Windows64) -----------------------------------
|
|
|
|
// Convert window mouse coords to 1280x720 virtual canvas.
|
|
// Returns false if the window handle is invalid or has zero size.
|
|
bool GetMouseVirtual(float& outX, float& outY);
|
|
|
|
// ---- Primitives -----------------------------------------------
|
|
|
|
// Filled axis-aligned rectangle.
|
|
void DrawRect(float x, float y, float w, float h, uint32_t color);
|
|
|
|
// Fullscreen rectangle that covers the entire backbuffer (ignores 16:9 viewport).
|
|
// Use for dim overlays, backgrounds, etc. that must reach into pillarbox/letterbox bands.
|
|
void DrawRectFullscreen(uint32_t color);
|
|
|
|
// Filled rectangle with rounded corners (radius in virtual pixels).
|
|
void DrawRoundedRect(float x, float y, float w, float h,
|
|
float radius, uint32_t color);
|
|
|
|
// Rounded border (outline only, no fill).
|
|
void DrawRoundedBorder(float x, float y, float w, float h,
|
|
float radius, float thickness, uint32_t color);
|
|
|
|
// Outlined rectangle (border only, no fill).
|
|
void DrawBorder(float x, float y, float w, float h,
|
|
float thickness, uint32_t color);
|
|
|
|
// Horizontal line.
|
|
void DrawLine(float x, float y, float length, float thickness,
|
|
uint32_t color);
|
|
|
|
// Vertical line.
|
|
void DrawLineV(float x, float y, float length, float thickness,
|
|
uint32_t color);
|
|
|
|
// Filled rectangle with gradient (top to bottom).
|
|
void DrawGradientRect(float x, float y, float w, float h,
|
|
uint32_t topColor, uint32_t bottomColor);
|
|
|
|
// Rounded rect with gradient (top to bottom).
|
|
void DrawGradientRoundedRect(float x, float y, float w, float h,
|
|
float radius,
|
|
uint32_t topColor, uint32_t bottomColor);
|
|
|
|
// Drop shadow behind a rectangle (semi-transparent, offset).
|
|
void DrawDropShadow(float x, float y, float w, float h,
|
|
float offset = 4.0f, float spread = 6.0f,
|
|
uint32_t color = 0x60000000u);
|
|
|
|
// Panel with rounded corners, drop shadow, and optional border.
|
|
void DrawPanel(float x, float y, float w, float h,
|
|
float radius = 8.0f,
|
|
uint32_t bgColor = 0xF0181818u,
|
|
uint32_t borderColor = 0xFF333333u,
|
|
float borderThick = 1.0f,
|
|
bool shadow = true);
|
|
|
|
// Horizontal divider line with optional fade at edges.
|
|
void DrawDivider(float x, float y, float w,
|
|
uint32_t color = 0xFF333333u,
|
|
float thickness = 1.0f);
|
|
|
|
// ---- Text -----------------------------------------------------
|
|
|
|
void DrawText(float x, float y, const wchar_t* text,
|
|
uint32_t color, float size = 14.0f,
|
|
uint32_t align = ALIGN_LEFT);
|
|
|
|
void DrawShadowText(float x, float y, const wchar_t* text,
|
|
uint32_t color, float size = 14.0f,
|
|
uint32_t align = ALIGN_LEFT);
|
|
|
|
float DrawTextWrapped(float x, float y, const wchar_t* text,
|
|
float maxWidth, uint32_t color,
|
|
float size = 14.0f, uint32_t align = ALIGN_LEFT);
|
|
|
|
void MeasureText(const wchar_t* text, float size,
|
|
float* outWidth, float* outHeight);
|
|
|
|
float LineHeight(float size);
|
|
|
|
// ---- Clipping -------------------------------------------------
|
|
|
|
void PushClipRect(float x, float y, float w, float h);
|
|
void PopClipRect();
|
|
|
|
// ---- Widgets --------------------------------------------------
|
|
|
|
void DrawButton(float x, float y, float w, float h,
|
|
const wchar_t* label, bool focused,
|
|
bool hovered = false, float labelSize = 16.0f);
|
|
|
|
// Text input box from gui/gui.png (y=46, 20px tall in atlas).
|
|
void DrawTextBox(float x, float y, float w, float h,
|
|
uint32_t tint = 0xFFFFFFFFu);
|
|
|
|
// Clickable link text with underline. Opens URL on activation.
|
|
void DrawLink(float x, float y, const wchar_t* text,
|
|
const char* url, bool focused, bool hovered = false,
|
|
float size = 14.0f, uint32_t align = ALIGN_LEFT,
|
|
float* outX = nullptr, float* outY = nullptr,
|
|
float* outW = nullptr, float* outH = nullptr);
|
|
|
|
void DrawProgressBar(float x, float y, float w, float h,
|
|
float progress,
|
|
uint32_t fillColor = 0xFF1A71D1u,
|
|
uint32_t trackColor = 0xFF333333u);
|
|
|
|
void DrawSpinner(float cx, float cy, float radius, int tick,
|
|
uint32_t color = 0xFFFFFFFFu);
|
|
|
|
void DrawCheckbox(float x, float y, float size,
|
|
bool checked, bool focused,
|
|
bool hovered = false);
|
|
|
|
void DrawSlider(float x, float y, float w, float h,
|
|
float value, bool focused,
|
|
bool hovered = false,
|
|
uint32_t fillColor = 0xFF1A71D1u,
|
|
uint32_t trackColor = 0xFF333333u);
|
|
|
|
void DrawTooltip(float x, float y, const wchar_t* text,
|
|
float size = 12.0f);
|
|
|
|
// Open a URL in the system default browser (Windows only, no-op elsewhere).
|
|
void OpenURL(const char* url);
|
|
|
|
// ---- Texture drawing ------------------------------------------
|
|
|
|
// Load a texture from the game's resource pack (e.g. L"/gui/container.png").
|
|
// Returns an internal texture ID for use with Draw calls.
|
|
// Textures are cached — calling this multiple times with the same path is cheap.
|
|
int LoadTexture(const wchar_t* path);
|
|
|
|
// Load a pre-registered texture by TEXTURE_NAME enum value.
|
|
// See Textures.h for the full list (TN_GUI_GUI, TN_TERRAIN, etc.).
|
|
int LoadTextureByName(int textureName);
|
|
|
|
// Load a PNG file and create a D3D11 texture directly (bypasses RenderManager).
|
|
// Decodes via WIC, creates DXGI_FORMAT_R8G8B8A8_UNORM texture.
|
|
// Use this for externally sourced PNGs (e.g. Mojang skins) where the
|
|
// RenderManager's pixel format assumptions may not match.
|
|
// Returns texture ID (for use with DrawTexture/DrawTextureUV), or -1 on failure.
|
|
// Caches by path. Must be called from the main/render thread.
|
|
int LoadTextureFromFileDirect(const char* filePath,
|
|
int* outWidth = nullptr, int* outHeight = nullptr);
|
|
|
|
// Load a texture from an arbitrary filesystem path relative to the EXE dir.
|
|
// e.g. "Common/Media/Graphics/PanelsAndTabs/Panel_MM.png"
|
|
// Returns texture ID, or -1 on failure. Caches by path.
|
|
// Also returns texture dimensions via optional out params.
|
|
int LoadTextureFromFile(const char* filePath,
|
|
int* outWidth = nullptr, int* outHeight = nullptr);
|
|
|
|
// 9-slice panel: draws a scalable panel from 9 texture pieces.
|
|
// basePath = folder + prefix, e.g. "Common/Media/Graphics/PanelsAndTabs/Panel"
|
|
// Auto-detects naming convention:
|
|
// Convention A: _TL, _TM, _TR, _ML, _MM, _MR, _BL, _BM, _BR
|
|
// Convention B: _Top_L, _Top_M, _Top_R, _Mid_L, _Mid_M, _Mid_R, _Bot_L, _Bot_M, _Bot_R
|
|
struct NineSlice
|
|
{
|
|
int tl, tm, tr; // texture IDs: top-left, top-mid, top-right
|
|
int ml, mm, mr; // mid-left, mid-mid, mid-right
|
|
int bl, bm, br; // bot-left, bot-mid, bot-right
|
|
int cornerW, cornerH; // corner piece dimensions
|
|
bool valid;
|
|
};
|
|
|
|
// Load a 9-slice panel set from disk. Caches internally.
|
|
// Supports both naming conventions (auto-detected).
|
|
NineSlice LoadNineSlice(const char* basePath);
|
|
|
|
// Draw a 9-slice panel scaled to any size.
|
|
void DrawNineSlice(float x, float y, float w, float h,
|
|
const NineSlice& ns, uint32_t tint = 0xFFFFFFFFu);
|
|
|
|
// 3-slice horizontal strip (tabs, bars).
|
|
// basePath e.g. "Common/Media/Graphics/PanelsAndTabs/Tab"
|
|
// Expects: {basePath}_Left.png, _Middle.png, _Right.png
|
|
struct ThreeSlice
|
|
{
|
|
int left, mid, right; // texture IDs
|
|
int capW, capH; // left/right cap dimensions
|
|
bool valid;
|
|
};
|
|
|
|
// Load a 3-slice strip from disk. Caches internally.
|
|
ThreeSlice LoadThreeSlice(const char* basePath);
|
|
|
|
// Draw a 3-slice strip scaled horizontally.
|
|
void DrawThreeSlice(float x, float y, float w, float h,
|
|
const ThreeSlice& ts, uint32_t tint = 0xFFFFFFFFu);
|
|
|
|
// Draw a texture filling the given rect. tint multiplies the texture color.
|
|
// Pass 0xFFFFFFFF for no tint. textureId comes from LoadTexture/LoadTextureByName.
|
|
void DrawTexture(float x, float y, float w, float h,
|
|
int textureId, uint32_t tint = 0xFFFFFFFFu);
|
|
|
|
// Draw a sub-region of a texture (UV rect in [0,1] space).
|
|
void DrawTextureUV(float x, float y, float w, float h,
|
|
int textureId,
|
|
float u0, float v0, float u1, float v1,
|
|
uint32_t tint = 0xFFFFFFFFu);
|
|
|
|
// Draw a texture clipped to rounded corners (uses scissor).
|
|
void DrawTextureRounded(float x, float y, float w, float h,
|
|
int textureId, float radius,
|
|
uint32_t tint = 0xFFFFFFFFu);
|
|
|
|
// Draw a texture scaled to fit (maintaining aspect ratio, centered).
|
|
// texW/texH = source texture dimensions in pixels.
|
|
void DrawTextureFit(float x, float y, float w, float h,
|
|
int textureId, int texW, int texH,
|
|
uint32_t tint = 0xFFFFFFFFu);
|
|
|
|
// ---- Focus list -----------------------------------------------
|
|
|
|
class FocusList
|
|
{
|
|
public:
|
|
struct Entry { int id; float x, y, w, h; };
|
|
|
|
void Clear() { m_entries.clear(); m_hoveredId = -1; }
|
|
void Add(int id, float x, float y, float w, float h);
|
|
int GetFocused() const;
|
|
int GetHovered() const { return m_hoveredId; }
|
|
bool IsFocused(int id) const { return GetFocused() == id; }
|
|
bool IsHovered(int id) const { return m_lastDevice == eDevice_Mouse && m_hoveredId == id; }
|
|
bool IsActive(int id) const { return IsFocused(id) || IsHovered(id); }
|
|
|
|
// For rendering: show highlight based on last-used input device.
|
|
// Gamepad last → show focus ring on focused element, ignore mouse hover.
|
|
// Mouse last → show hover highlight, suppress gamepad focus ring.
|
|
bool ShowFocus(int id) const
|
|
{
|
|
if (m_lastDevice == eDevice_Mouse)
|
|
return m_hoveredId >= 0 && m_hoveredId == id;
|
|
// Gamepad or no device: show gamepad focus, ignore hover
|
|
return IsFocused(id);
|
|
}
|
|
|
|
void MoveNext();
|
|
void MovePrev();
|
|
void SetFocus(int id);
|
|
bool HitTest(float mx, float my, int& outId) const;
|
|
bool UpdateHover(float mx, float my);
|
|
void ClearHover() { m_hoveredId = -1; }
|
|
int Count() const { return (int)m_entries.size(); }
|
|
|
|
|
|
// Mouse hover — call once per tick from tick().
|
|
// Updates hover state, plays hover sound. No click handling.
|
|
|
|
void TickMouse();
|
|
|
|
// True while the mouse was used for the last interaction.
|
|
bool IsMouseConsumed() const { return m_mouseConsumed; }
|
|
|
|
|
|
// Gamepad/keyboard — standard menu key handling.
|
|
// Handles UP/DOWN/LEFT/RIGHT (navigation with sound),
|
|
// OK (returns focused id with press sound),
|
|
// CANCEL (returns backId with back sound).
|
|
//
|
|
// backId = the control id to return when CANCEL is pressed.
|
|
//
|
|
// Returns: >=0 = activated element id (OK or CANCEL)
|
|
// -1 = navigation happened (focus moved, no activation)
|
|
// -2 = key not handled (scene should set handled=false)
|
|
|
|
static constexpr int RESULT_NAVIGATED = -1;
|
|
static constexpr int RESULT_UNHANDLED = -2;
|
|
|
|
// panelX/Y/W/H = scene panel bounds. Used to hit-test mouse clicks
|
|
// when UIController sends ACTION_MENU_OK from a left-click.
|
|
int HandleMenuKey(int key, int backId = 0,
|
|
float panelX = 0, float panelY = 0,
|
|
float panelW = 0, float panelH = 0);
|
|
|
|
// Input device tracking — same concept as Iggy's lastUsedDevice.
|
|
// When the gamepad navigates, mouse hover is suppressed.
|
|
// When the mouse moves, gamepad focus ring is suppressed.
|
|
enum ELastDevice { eDevice_None, eDevice_Gamepad, eDevice_Mouse };
|
|
ELastDevice GetLastDevice() const { return m_lastDevice; }
|
|
|
|
private:
|
|
std::vector<Entry> m_entries;
|
|
int m_focusIdx = 0;
|
|
int m_hoveredId = -1;
|
|
int m_lastHoveredId = -1; // hover id from previous tick
|
|
bool m_mouseConsumed = false; // true = click in progress, don't re-fire
|
|
ELastDevice m_lastDevice = eDevice_None;
|
|
float m_lastMouseX = -1.0f;
|
|
float m_lastMouseY = -1.0f;
|
|
};
|
|
|
|
} // namespace NativeUI
|