purchases now persist in DLC menu!

This commit is contained in:
LazyByteDev
2026-03-04 01:25:17 -05:00
parent 4906bc901d
commit 28e106bbb9
4 changed files with 396 additions and 363 deletions

View File

@@ -15,6 +15,8 @@
// Windows64 DLC store stuff blahhhh - whisper // Windows64 DLC store stuff blahhhh - whisper
#ifdef _WINDOWS64 #ifdef _WINDOWS64
#include "Windows64_DLCOffers.h" #include "Windows64_DLCOffers.h"
#include "..\..\User.h"
#include "Windows64_Minecraft.h"
#include <unordered_map> #include <unordered_map>
static std::unordered_map<int,int> s_offerIndexToListPos; static std::unordered_map<int,int> s_offerIndexToListPos;
#endif #endif
@@ -166,10 +168,12 @@ void UIScene_DLCOffersMenu::handleInput(int iPad, int key, bool repeat, bool pre
int iIndex = getControlChildFocus(); int iIndex = getControlChildFocus();
if (iIndex >= 0 && iIndex < Windows64_DLCOffers::Get().GetOfferCount()) if (iIndex >= 0 && iIndex < Windows64_DLCOffers::Get().GetOfferCount())
{ {
Minecraft *pMinecraft = Minecraft::GetInstance();
Windows64_DLCOffers::Get().InstallOffer(iIndex, Windows64_DLCOffers::Get().InstallOffer(iIndex,
[](const wchar_t* id, bool ok, void*) { [](const wchar_t* id, bool ok, void*) {
wprintf(L"[DLC] Install %ls: %ls\n", id, ok ? L"OK" : L"FAILED"); wprintf(L"[DLC] Install %ls: %ls\n", id, ok ? L"OK" : L"FAILED");
}, nullptr); }, nullptr, pMinecraft->user->name.c_str());
} }
} }
#endif #endif
@@ -251,7 +255,7 @@ void UIScene_DLCOffersMenu::handlePress(F64 controlId, F64 childId)
Windows64_DLCOffers::Get().InstallOffer(iIndex, Windows64_DLCOffers::Get().InstallOffer(iIndex,
[](const wchar_t* id, bool ok, void*) { [](const wchar_t* id, bool ok, void*) {
wprintf(L"[DLC] Install %ls: %ls\n", id, ok ? L"OK" : L"FAILED"); wprintf(L"[DLC] Install %ls: %ls\n", id, ok ? L"OK" : L"FAILED");
}, nullptr); }, nullptr, Minecraft::GetInstance()->user->name.c_str());
} }
#else #else

View File

@@ -116,6 +116,8 @@ UIScene_MainMenu::UIScene_MainMenu(int iPad, void *initData, UILayer *parentLaye
// Fix for #45154 - Frontend: DLC: Content can only be downloaded from the frontend if you have not joined/exited multiplayer // Fix for #45154 - Frontend: DLC: Content can only be downloaded from the frontend if you have not joined/exited multiplayer
XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW);
#endif #endif
Minecraft::GetInstance()->user->name = convStringToWstring( ProfileManager.GetGamertag(ProfileManager.GetPrimaryPad()));
} }
UIScene_MainMenu::~UIScene_MainMenu() UIScene_MainMenu::~UIScene_MainMenu()

View File

@@ -4,6 +4,8 @@
#include <winhttp.h> #include <winhttp.h>
#pragma comment(lib, "winhttp.lib") #pragma comment(lib, "winhttp.lib")
#include <shlobj.h> #include <shlobj.h>
#include "../Windows64_Minecraft.h"
#include "../User.h"
static bool ParseUrl(const wchar_t* url, static bool ParseUrl(const wchar_t* url,
std::wstring& host, INTERNET_PORT& port, std::wstring& host, INTERNET_PORT& port,
@@ -212,7 +214,7 @@ bool Windows64_DLCOffers::FetchImageFromUrl(const wchar_t* url, PBYTE* ppData, D
void Windows64_DLCOffers::InstallOffer(int iIndex, void Windows64_DLCOffers::InstallOffer(int iIndex,
W64_INSTALL_CALLBACK pfnCallback, W64_INSTALL_CALLBACK pfnCallback,
void* pUserData) void* pUserData, wstring username)
{ {
if (iIndex < 0 || iIndex >= (int)m_offers.size()) return; if (iIndex < 0 || iIndex >= (int)m_offers.size()) return;
@@ -221,6 +223,7 @@ void Windows64_DLCOffers::InstallOffer(int iIndex,
ctx->offerIndex = iIndex; ctx->offerIndex = iIndex;
ctx->pfnCallback = pfnCallback; ctx->pfnCallback = pfnCallback;
ctx->pUserData = pUserData; ctx->pUserData = pUserData;
ctx->username = username;
HANDLE hThread = CreateThread(nullptr, 0, InstallThreadProc, ctx, 0, nullptr); HANDLE hThread = CreateThread(nullptr, 0, InstallThreadProc, ctx, 0, nullptr);
if (hThread) CloseHandle(hThread); if (hThread) CloseHandle(hThread);
@@ -272,17 +275,37 @@ DWORD WINAPI Windows64_DLCOffers::InstallThreadProc(LPVOID lpParam)
if (bSuccess) if (bSuccess)
{ {
// Mark the offer as owned.
Windows64_DLCOffers::Get().SetPurchased(ctx->offerIndex); Windows64_DLCOffers::Get().SetPurchased(ctx->offerIndex);
// Must be set BEFORE m_iLastInstalled is updated so the game thread always
Windows64_DLCOffers::Get().SetPendingLoadPath(ctx->offerIndex, wszFilePath); Windows64_DLCOffers::Get().SetPendingLoadPath(ctx->offerIndex, wszFilePath);
InterlockedExchange(&Windows64_DLCOffers::Get().m_iLastInstalled, (LONG)ctx->offerIndex);
InterlockedExchange(&Windows64_DLCOffers::Get().m_iLastInstalled,
(LONG)ctx->offerIndex);
printf("[DLC] Installed '%ls' -> %ls\n", // notify server so purchase persists across sessions
ctx->offer.wszProductID, wszFilePath); wchar_t wszPath[256];
_snwprintf_s(wszPath, _countof(wszPath), _TRUNCATE,
L"/purchase/%ls?user=%ls",
ctx->offer.wszProductID, ctx->username.c_str());
HINTERNET hSession = WinHttpOpen(L"W64DLC/1.0", WINHTTP_ACCESS_TYPE_NO_PROXY, nullptr, nullptr, 0);
if (hSession)
{
HINTERNET hConn = WinHttpConnect(hSession, L"127.0.0.1", 3000, 0);
if (hConn)
{
HINTERNET hReq = WinHttpOpenRequest(hConn, L"POST", wszPath, nullptr,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
if (hReq)
{
WinHttpSendRequest(hReq, WINHTTP_NO_ADDITIONAL_HEADERS, 0,
WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
WinHttpReceiveResponse(hReq, nullptr);
WinHttpCloseHandle(hReq);
}
WinHttpCloseHandle(hConn);
}
WinHttpCloseHandle(hSession);
}
} }
else else
{ {
@@ -308,7 +331,10 @@ void Windows64_DLCOffers::FetchFromServer()
HINTERNET hConnect = WinHttpConnect(hSession, L"localhost", 3000, 0); HINTERNET hConnect = WinHttpConnect(hSession, L"localhost", 3000, 0);
if (!hConnect) { WinHttpCloseHandle(hSession); return; } if (!hConnect) { WinHttpCloseHandle(hSession); return; }
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", L"/dlc", wchar_t wszDlcPath[128];
_snwprintf_s(wszDlcPath, _countof(wszDlcPath), _TRUNCATE, L"/dlc?user=%ls", Minecraft::GetInstance()->user->name.c_str());
HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", wszDlcPath,
NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
if (!hRequest) if (!hRequest)
{ {

View File

@@ -67,7 +67,7 @@ public:
void InstallOffer(int iIndex, void InstallOffer(int iIndex,
W64_INSTALL_CALLBACK pfnCallback = nullptr, W64_INSTALL_CALLBACK pfnCallback = nullptr,
void* pUserData = nullptr); void* pUserData = nullptr, wstring username = L"");
static bool FetchImageFromUrl(const wchar_t* url, PBYTE* ppData, DWORD* pdwSize); static bool FetchImageFromUrl(const wchar_t* url, PBYTE* ppData, DWORD* pdwSize);
static bool FetchBytesFromUrl(const wchar_t* url, PBYTE* ppData, DWORD* pdwSize); static bool FetchBytesFromUrl(const wchar_t* url, PBYTE* ppData, DWORD* pdwSize);
@@ -95,6 +95,7 @@ private:
int offerIndex; int offerIndex;
W64_INSTALL_CALLBACK pfnCallback; W64_INSTALL_CALLBACK pfnCallback;
void* pUserData; void* pUserData;
wstring username;
}; };
static DWORD WINAPI InstallThreadProc(LPVOID lpParam); static DWORD WINAPI InstallThreadProc(LPVOID lpParam);