Add
This commit is contained in:
+1
-2
@@ -12,7 +12,6 @@ endif()
|
||||
if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
message(FATAL_ERROR "Use a 64-bit generator/toolchain (x64).")
|
||||
endif()
|
||||
|
||||
set(CMAKE_CONFIGURATION_TYPES
|
||||
"Debug"
|
||||
"Release"
|
||||
@@ -21,7 +20,7 @@ set(CMAKE_CONFIGURATION_TYPES
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
function(configure_compiler_target target)
|
||||
# MSVC and compatible compilers (like Clang-cl)
|
||||
# MSVC and compatible compilers (like Clang-cl) !
|
||||
if (MSVC)
|
||||
target_compile_options(${target} PRIVATE
|
||||
$<$<AND:$<CONFIG:Debug>,$<COMPILE_LANGUAGE:C,CXX>>:/W3>
|
||||
|
||||
@@ -21,9 +21,11 @@ set(MINECRAFT_CLIENT_SOURCES
|
||||
$<$<STREQUAL:${PLATFORM_NAME},Windows64>:${MINECRAFT_CLIENT_WINDOWS}>
|
||||
$<$<STREQUAL:${PLATFORM_NAME},Xbox>:${MINECRAFT_CLIENT_XBOX360}>
|
||||
${SOURCES_COMMON}
|
||||
|
||||
"${CMAKE_SOURCE_DIR}/Minecraft.Client/Common/StringUtils.cpp"
|
||||
)
|
||||
|
||||
add_executable(Minecraft.Client ${MINECRAFT_CLIENT_SOURCES})
|
||||
add_executable(Minecraft.Client ${MINECRAFT_CLIENT_SOURCES} "Common/UI/UIScene_AchievementsMenu.cpp" "Common/UI/UIScene_AchievementsMenu.h" "Common/UI/UIControl_AchievementsList.cpp" "Common/UI/UIControl_AchievementsList.h" "Windows64/NetworkHelpers.h" "Windows64/NetworkHelpers.cpp")
|
||||
|
||||
# Only define executable on windows
|
||||
if(PLATFORM_NAME STREQUAL "Windows64")
|
||||
|
||||
@@ -1,13 +1,144 @@
|
||||
#include "stdafx.h"
|
||||
#include "ClientConstants.h"
|
||||
#include "Common/BuildVer.h"
|
||||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
#include <string>
|
||||
|
||||
const wstring ClientConstants::VERSION_STRING = wstring(L"Minecraft LCE ") + VER_FILEVERSION_STR_W;//+ SharedConstants::VERSION_STRING;
|
||||
const wstring ClientConstants::BRANCH_STRING = VER_BRANCHVERSION_STR_W;
|
||||
#pragma comment(lib, "wininet.lib")
|
||||
|
||||
// Default value for the toggle. If BuildVer defines VER_SHOW_VERSION_WATERMARK, use that.
|
||||
#ifdef VER_SHOW_VERSION_WATERMARK
|
||||
const bool ClientConstants::SHOW_VERSION_WATERMARK = (VER_SHOW_VERSION_WATERMARK != 0);
|
||||
#else
|
||||
const bool ClientConstants::SHOW_VERSION_WATERMARK = false;
|
||||
#endif
|
||||
extern char g_LCENToken[512];
|
||||
|
||||
const wchar_t* ClientConstants::LCEN_HOST = L"https://network-server-7kuc.onrender.com";
|
||||
|
||||
const std::wstring ClientConstants::VERSION_STRING =
|
||||
L"Minecraft: Legacy Network Beta Build 2026.06.14-128 [DO NOT DISTRIBUTE]";
|
||||
|
||||
static std::wstring g_cachedStatus = L"LCEN: Establishing a connection";
|
||||
static CRITICAL_SECTION g_statusLock;
|
||||
static bool g_threadStarted = false;
|
||||
static HANDLE g_threadHandle = nullptr;
|
||||
|
||||
DWORD WINAPI LCENStatusThread(LPVOID)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
std::wstring newStatus = L"LCE Network offline";
|
||||
|
||||
if (g_LCENToken[0] != '\0')
|
||||
{
|
||||
HINTERNET hNet = InternetOpenA("openLCE", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
|
||||
if (hNet)
|
||||
{
|
||||
char authHeader[600];
|
||||
_snprintf_s(authHeader, sizeof(authHeader), _TRUNCATE, "Authorization: Bearer %s", g_LCENToken);
|
||||
|
||||
HINTERNET hReq = InternetOpenUrlA(
|
||||
hNet,
|
||||
"https://network-server-7kuc.onrender.com/auth/validate",
|
||||
authHeader,
|
||||
(DWORD)strlen(authHeader),
|
||||
INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
|
||||
0
|
||||
);
|
||||
|
||||
if (hReq)
|
||||
{
|
||||
char buf[4096] = {};
|
||||
DWORD read = 0;
|
||||
InternetReadFile(hReq, buf, sizeof(buf) - 1, &read);
|
||||
|
||||
if (read > 0)
|
||||
{
|
||||
if (strstr(buf, "\"Account banned\""))
|
||||
{
|
||||
newStatus = L"LCEN could not connect: Banned user profile";
|
||||
}
|
||||
else if (strstr(buf, "\"reason\":\""))
|
||||
{
|
||||
const char* r = strstr(buf, "\"reason\":\"") + 10;
|
||||
const char* end = strchr(r, '"');
|
||||
|
||||
if (end)
|
||||
{
|
||||
char reason[128] = {};
|
||||
size_t len = min((size_t)(end - r), sizeof(reason) - 1);
|
||||
strncpy_s(reason, r, len);
|
||||
|
||||
wchar_t wReason[128] = {};
|
||||
MultiByteToWideChar(CP_UTF8, 0, reason, -1, wReason, 128);
|
||||
|
||||
newStatus = L"Banned dum dum: ";
|
||||
newStatus += wReason;
|
||||
}
|
||||
}
|
||||
else if (strstr(buf, "\"Invalid token\""))
|
||||
{
|
||||
newStatus = L"LCEN could not connect: Invalid Token";
|
||||
}
|
||||
else if (strstr(buf, "\"gamertag\":\""))
|
||||
{
|
||||
const char* g = strstr(buf, "\"gamertag\":\"") + 12;
|
||||
const char* end = strchr(g, '"');
|
||||
|
||||
if (end)
|
||||
{
|
||||
char gamertag[64] = {};
|
||||
size_t len = min((size_t)(end - g), sizeof(gamertag) - 1);
|
||||
strncpy_s(gamertag, g, len);
|
||||
|
||||
wchar_t wGamertag[64] = {};
|
||||
MultiByteToWideChar(CP_UTF8, 0, gamertag, -1, wGamertag, 64);
|
||||
|
||||
newStatus = L"[Connected] ";
|
||||
newStatus += wGamertag;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newStatus = L"LCE Network Authentication failed";
|
||||
}
|
||||
}
|
||||
|
||||
InternetCloseHandle(hReq);
|
||||
}
|
||||
|
||||
InternetCloseHandle(hNet);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newStatus = L"Not connected with LCEN servers";
|
||||
}
|
||||
|
||||
EnterCriticalSection(&g_statusLock);
|
||||
g_cachedStatus = newStatus;
|
||||
LeaveCriticalSection(&g_statusLock);
|
||||
|
||||
Sleep(2000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void InitLCENSystem()
|
||||
{
|
||||
if (g_threadStarted)
|
||||
return;
|
||||
|
||||
g_threadStarted = true;
|
||||
InitializeCriticalSection(&g_statusLock);
|
||||
|
||||
g_threadHandle = CreateThread(nullptr, 0, LCENStatusThread, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
std::wstring ClientConstants::GetLCENString()
|
||||
{
|
||||
InitLCENSystem();
|
||||
|
||||
EnterCriticalSection(&g_statusLock);
|
||||
std::wstring copy = g_cachedStatus;
|
||||
LeaveCriticalSection(&g_statusLock);
|
||||
|
||||
return copy;
|
||||
}
|
||||
@@ -13,10 +13,9 @@ class ClientConstants
|
||||
// INTERNAL DEVELOPMENT SETTINGS
|
||||
public:
|
||||
static const wstring VERSION_STRING;
|
||||
static const wstring BRANCH_STRING;
|
||||
|
||||
// Toggle to show/hide the version/branch watermark in the debug overlay
|
||||
static const bool SHOW_VERSION_WATERMARK;
|
||||
static const wstring LCEN_STRING;
|
||||
static const wchar_t* LCEN_HOST;
|
||||
static std::wstring GetLCENString();
|
||||
|
||||
static const bool DEADMAU5_CAMERA_CHEATS = false;
|
||||
};
|
||||
@@ -23,18 +23,18 @@ enum eAward
|
||||
eAward_DispenseWithThis,
|
||||
eAward_InToTheNether,
|
||||
|
||||
eAward_mine100Blocks,
|
||||
eAward_kill10Creepers,
|
||||
//eAward_mine100Blocks,
|
||||
//eAward_kill10Creepers,
|
||||
eAward_eatPorkChop,
|
||||
eAward_play100Days,
|
||||
eAward_arrowKillCreeper,
|
||||
eAward_socialPost,
|
||||
//eAward_socialPost,
|
||||
|
||||
#ifndef _XBOX
|
||||
// 4J Stu - Does not map to any Xbox achievements
|
||||
eAward_snipeSkeleton,
|
||||
eAward_diamonds,
|
||||
eAward_portal,
|
||||
//eAward_portal,
|
||||
eAward_ghast,
|
||||
eAward_blazeRod,
|
||||
eAward_potion,
|
||||
@@ -45,7 +45,7 @@ enum eAward
|
||||
eAward_bookcase,
|
||||
#endif
|
||||
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
|
||||
eAward_adventuringTime,
|
||||
eAward_repopulation,
|
||||
//eAward_porkChop,
|
||||
@@ -66,7 +66,6 @@ enum eAward
|
||||
eAward_ironMan,
|
||||
eAward_zombieDoctor,
|
||||
eAward_lionTamer,
|
||||
#endif
|
||||
|
||||
eAward_Max,
|
||||
};
|
||||
|
||||
@@ -849,6 +849,12 @@ void CMinecraftApp::InitGameSettings()
|
||||
SetDefaultOptions(pProfileSettings,i,false);
|
||||
|
||||
#endif
|
||||
Minecraft* minecraft = Minecraft::GetInstance();
|
||||
if (minecraft != nullptr && minecraft->stats[i] != nullptr)
|
||||
{
|
||||
minecraft->stats[i]->clear();
|
||||
minecraft->stats[i]->parse(GameSettingsA[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4645,6 +4651,15 @@ int CMinecraftApp::SignoutExitWorldThreadProc( void* lpParameter )
|
||||
case DisconnectPacket::eDisconnect_OutdatedClient:
|
||||
exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD;
|
||||
break;
|
||||
case DisconnectPacket::eDisconnect_LCENAuth:
|
||||
exitReasonStringId = IDS_CONNECTION_LOST_LCEN;
|
||||
break;
|
||||
case DisconnectPacket::eDisconnect_LCENBanned:
|
||||
exitReasonStringId = IDS_LCEN_BANNED;
|
||||
break;
|
||||
case DisconnectPacket::eDisconnect_LCENServiceUnavailable:
|
||||
exitReasonStringId = IDS_LCEN_NO_CONNECTION;
|
||||
break;
|
||||
default:
|
||||
exitReasonStringId = IDS_DISCONNECTED;
|
||||
}
|
||||
@@ -4705,6 +4720,16 @@ int CMinecraftApp::SignoutExitWorldThreadProc( void* lpParameter )
|
||||
break;
|
||||
case DisconnectPacket::eDisconnect_OutdatedClient:
|
||||
exitReasonStringId = IDS_DISCONNECTED_CLIENT_OLD;
|
||||
break;
|
||||
case DisconnectPacket::eDisconnect_LCENAuth:
|
||||
exitReasonStringId = IDS_CONNECTION_LOST_LCEN;
|
||||
break;
|
||||
case DisconnectPacket::eDisconnect_LCENBanned:
|
||||
exitReasonStringId = IDS_LCEN_BANNED;
|
||||
break;
|
||||
case DisconnectPacket::eDisconnect_LCENServiceUnavailable:
|
||||
exitReasonStringId = IDS_LCEN_NO_CONNECTION;
|
||||
break;
|
||||
default:
|
||||
exitReasonStringId = IDS_DISCONNECTED;
|
||||
}
|
||||
@@ -6527,7 +6552,7 @@ int CMinecraftApp::GetHTMLFontSize(EHTMLFontSize size)
|
||||
return s_iHTMLFontSizesA[size];
|
||||
}
|
||||
|
||||
wstring CMinecraftApp::FormatHTMLString(int iPad, const wstring &desc, int shadowColour /*= 0xFFFFFFFF*/)
|
||||
wstring CMinecraftApp::FormatHTMLString(int iPad, const wstring &desc, int shadowColour /*= 0xFFFFFFFF*/, bool override)
|
||||
{
|
||||
wstring text(desc);
|
||||
|
||||
@@ -6610,7 +6635,7 @@ wstring CMinecraftApp::FormatHTMLString(int iPad, const wstring &desc, int shado
|
||||
text = replaceAll(text, L"{*CONTROLLER_VK_A*}", GetVKReplacement(VK_PAD_A) );
|
||||
text = replaceAll(text, L"{*CONTROLLER_VK_B*}", GetVKReplacement(VK_PAD_B) );
|
||||
text = replaceAll(text, L"{*CONTROLLER_VK_X*}", GetVKReplacement(VK_PAD_X) );
|
||||
text = replaceAll(text, L"{*CONTROLLER_VK_Y*}", GetVKReplacement(VK_PAD_Y) );
|
||||
text = replaceAll(text, L"{*CONTROLLER_VK_Y*}", GetVKReplacement(VK_PAD_Y, override) );
|
||||
text = replaceAll(text, L"{*CONTROLLER_VK_LB*}", GetVKReplacement(VK_PAD_LSHOULDER) );
|
||||
text = replaceAll(text, L"{*CONTROLLER_VK_RB*}", GetVKReplacement(VK_PAD_RSHOULDER) );
|
||||
text = replaceAll(text, L"{*CONTROLLER_VK_LS*}", GetVKReplacement(VK_PAD_LTHUMB_UP) );
|
||||
@@ -6849,7 +6874,7 @@ wstring CMinecraftApp::GetActionReplacement(int iPad, unsigned char ucAction)
|
||||
#endif
|
||||
}
|
||||
|
||||
wstring CMinecraftApp::GetVKReplacement(unsigned int uiVKey)
|
||||
wstring CMinecraftApp::GetVKReplacement(unsigned int uiVKey, bool override)
|
||||
{
|
||||
#ifdef _XBOX
|
||||
switch(uiVKey)
|
||||
@@ -6967,7 +6992,7 @@ wstring CMinecraftApp::GetVKReplacement(unsigned int uiVKey)
|
||||
int size = 30;
|
||||
#elif defined _WIN64
|
||||
int size = 45;
|
||||
if(ui.getScreenHeight() < 1080) size = 30;
|
||||
if(ui.getScreenHeight() < 1080 || override == true) size = 30;
|
||||
#else
|
||||
int size = 45;
|
||||
#endif
|
||||
@@ -9800,6 +9825,48 @@ bool CMinecraftApp::IsLocalMultiplayerAvailable()
|
||||
|
||||
void CMinecraftApp::getLocale(vector<wstring> &vecWstrLocales)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
{
|
||||
int iPad = ProfileManager.GetPrimaryPad();
|
||||
if (iPad >= 0 && GameSettingsA[iPad] != nullptr &&
|
||||
GameSettingsA[iPad]->ucLanguage != MINECRAFT_LANGUAGE_DEFAULT)
|
||||
{
|
||||
DWORD lang = GameSettingsA[iPad]->ucLanguage;
|
||||
DWORD locale = GameSettingsA[iPad]->ucLocale;
|
||||
vector<eMCLang> locales;
|
||||
switch(lang)
|
||||
{
|
||||
case XC_LANGUAGE_GERMAN: locales.push_back(eMCLang_deDE); break;
|
||||
case XC_LANGUAGE_FRENCH: locales.push_back(eMCLang_frFR); break;
|
||||
case XC_LANGUAGE_ITALIAN: locales.push_back(eMCLang_itIT); break;
|
||||
case XC_LANGUAGE_JAPANESE: locales.push_back(eMCLang_jaJP); break;
|
||||
case XC_LANGUAGE_KOREAN: locales.push_back(eMCLang_koKR); break;
|
||||
case XC_LANGUAGE_POLISH: locales.push_back(eMCLang_plPL); break;
|
||||
case XC_LANGUAGE_RUSSIAN: locales.push_back(eMCLang_ruRU); break;
|
||||
case XC_LANGUAGE_DUTCH: locales.push_back(eMCLang_nlNL); break;
|
||||
case XC_LANGUAGE_DANISH: locales.push_back(eMCLang_daDA); break;
|
||||
case XC_LANGUAGE_FINISH: locales.push_back(eMCLang_fiFI); break;
|
||||
case XC_LANGUAGE_SWEDISH: locales.push_back(eMCLang_svSV); break;
|
||||
case XC_LANGUAGE_BNORWEGIAN: locales.push_back(eMCLang_nbNO); break;
|
||||
case XC_LANGUAGE_GREEK: locales.push_back(eMCLang_elGR); break;
|
||||
case XC_LANGUAGE_TCHINESE: locales.push_back(eMCLang_zhCHT); break;
|
||||
case XC_LANGUAGE_PORTUGUESE:
|
||||
if(locale == XC_LOCALE_BRAZIL) locales.push_back(eMCLang_ptBR);
|
||||
locales.push_back(eMCLang_ptPT);
|
||||
break;
|
||||
case XC_LANGUAGE_SPANISH:
|
||||
if(locale == XC_LOCALE_LATIN_AMERICA) locales.push_back(eMCLang_esMX);
|
||||
locales.push_back(eMCLang_esES);
|
||||
break;
|
||||
}
|
||||
locales.push_back(eMCLang_enUS);
|
||||
locales.push_back(eMCLang_null);
|
||||
for (auto &l : locales)
|
||||
vecWstrLocales.push_back(m_localeA[l]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
vector<eMCLang> locales;
|
||||
|
||||
DWORD dwSystemLanguage = XGetLanguage( );
|
||||
|
||||
@@ -97,7 +97,7 @@ public:
|
||||
*/
|
||||
static const int GAME_DEFINED_PROFILE_DATA_BYTES = 2*972; // per user
|
||||
#else
|
||||
static const int GAME_DEFINED_PROFILE_DATA_BYTES = 972; // per user
|
||||
static const int GAME_DEFINED_PROFILE_DATA_BYTES = 2*972; // per user
|
||||
#endif
|
||||
unsigned int uiGameDefinedDataChangedBitmask;
|
||||
|
||||
@@ -564,11 +564,11 @@ public:
|
||||
int GetHTMLColour(eMinecraftColour colour);
|
||||
int GetHTMLColor(eMinecraftColour colour) { return GetHTMLColour(colour); }
|
||||
int GetHTMLFontSize(EHTMLFontSize size);
|
||||
wstring FormatHTMLString(int iPad, const wstring& desc, int shadowColour = 0xFFFFFFFF);
|
||||
wstring FormatHTMLString(int iPad, const wstring& desc, int shadowColour = 0xFFFFFFFF, bool override = false);
|
||||
wstring EscapeHTMLString(const wstring &desc);
|
||||
wstring FormatChatMessage(const wstring& desc, bool applyStyling = true);
|
||||
wstring GetActionReplacement(int iPad, unsigned char ucAction);
|
||||
wstring GetVKReplacement(unsigned int uiVKey);
|
||||
wstring GetVKReplacement(unsigned int uiVKey, bool override = false);
|
||||
wstring GetIconReplacement(unsigned int uiIcon);
|
||||
|
||||
float getAppTime() { return m_Time.fAppTime; }
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -923,7 +923,9 @@ void CPlatformNetworkManagerStub::SearchForGames()
|
||||
strncpy_s(info->data.hostIP, sizeof(info->data.hostIP), ipBuf, _TRUNCATE);
|
||||
info->data.hostPort = port;
|
||||
info->sessionId = static_cast<uint64_t>(inet_addr(ipBuf)) | static_cast<uint64_t>(port) << 32;
|
||||
friendsSessions[0].push_back(info);
|
||||
if (info) {
|
||||
friendsSessions[0].push_back(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "StringUtils.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace UtilityGame
|
||||
{
|
||||
namespace StringUtils
|
||||
{
|
||||
std::string WideToUtf8(const std::wstring &value)
|
||||
{
|
||||
if (value.empty())
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
int charCount = WideCharToMultiByte(CP_UTF8, 0, value.c_str(), (int)value.length(), NULL, 0, NULL, NULL);
|
||||
if (charCount <= 0)
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::string utf8;
|
||||
utf8.resize(charCount);
|
||||
WideCharToMultiByte(CP_UTF8, 0, value.c_str(), (int)value.length(), &utf8[0], charCount, NULL, NULL);
|
||||
return utf8;
|
||||
}
|
||||
|
||||
std::wstring Utf8ToWide(const char *value)
|
||||
{
|
||||
if (value == NULL || value[0] == 0)
|
||||
{
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
int wideCount = MultiByteToWideChar(CP_UTF8, 0, value, -1, NULL, 0);
|
||||
if (wideCount <= 0)
|
||||
{
|
||||
// Fall back to the current ANSI code page so legacy non-UTF-8 inputs remain readable.
|
||||
wideCount = MultiByteToWideChar(CP_ACP, 0, value, -1, NULL, 0);
|
||||
if (wideCount <= 0)
|
||||
{
|
||||
return std::wstring();
|
||||
}
|
||||
|
||||
std::wstring wide;
|
||||
wide.resize(wideCount - 1);
|
||||
MultiByteToWideChar(CP_ACP, 0, value, -1, &wide[0], wideCount);
|
||||
return wide;
|
||||
}
|
||||
|
||||
std::wstring wide;
|
||||
wide.resize(wideCount - 1);
|
||||
MultiByteToWideChar(CP_UTF8, 0, value, -1, &wide[0], wideCount);
|
||||
return wide;
|
||||
}
|
||||
|
||||
std::wstring Utf8ToWide(const std::string &value)
|
||||
{
|
||||
return Utf8ToWide(value.c_str());
|
||||
}
|
||||
|
||||
std::string StripUtf8Bom(const std::string &value)
|
||||
{
|
||||
if (value.size() >= 3 &&
|
||||
(unsigned char)value[0] == 0xEF &&
|
||||
(unsigned char)value[1] == 0xBB &&
|
||||
(unsigned char)value[2] == 0xBF)
|
||||
{
|
||||
return value.substr(3);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string TrimAscii(const std::string &value)
|
||||
{
|
||||
size_t start = 0;
|
||||
while (start < value.length() && std::isspace((unsigned char)value[start]))
|
||||
{
|
||||
++start;
|
||||
}
|
||||
|
||||
size_t end = value.length();
|
||||
while (end > start && std::isspace((unsigned char)value[end - 1]))
|
||||
{
|
||||
--end;
|
||||
}
|
||||
|
||||
return value.substr(start, end - start);
|
||||
}
|
||||
|
||||
std::string ToLowerAscii(const std::string &value)
|
||||
{
|
||||
std::string lowered = value;
|
||||
for (size_t i = 0; i < lowered.length(); ++i)
|
||||
{
|
||||
lowered[i] = (char)std::tolower((unsigned char)lowered[i]);
|
||||
}
|
||||
return lowered;
|
||||
}
|
||||
|
||||
std::string JoinTokens(const std::vector<std::string> &tokens, size_t startIndex, const char *separator)
|
||||
{
|
||||
if (startIndex >= tokens.size())
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const auto joinSeparator = std::string((separator != nullptr) ? separator : " ");
|
||||
size_t totalLength = 0;
|
||||
for (size_t i = startIndex; i < tokens.size(); ++i)
|
||||
{
|
||||
totalLength += tokens[i].size();
|
||||
}
|
||||
|
||||
totalLength += (tokens.size() - startIndex - 1) * joinSeparator.size();
|
||||
std::string joined;
|
||||
joined.reserve(totalLength);
|
||||
for (size_t i = startIndex; i < tokens.size(); ++i)
|
||||
{
|
||||
if (!joined.empty())
|
||||
{
|
||||
joined += joinSeparator;
|
||||
}
|
||||
|
||||
joined += tokens[i];
|
||||
}
|
||||
|
||||
return joined;
|
||||
}
|
||||
|
||||
bool StartsWithIgnoreCase(const std::string &value, const std::string &prefix)
|
||||
{
|
||||
if (prefix.size() > value.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < prefix.size(); ++i)
|
||||
{
|
||||
unsigned char a = (unsigned char)value[i];
|
||||
unsigned char b = (unsigned char)prefix[i];
|
||||
if (std::tolower(a) != std::tolower(b))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TryParseUnsignedLongLong(const std::string &value, unsigned long long *outValue)
|
||||
{
|
||||
if (outValue == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string trimmed = TrimAscii(value);
|
||||
if (trimmed.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
char *end = nullptr;
|
||||
const unsigned long long parsed = _strtoui64(trimmed.c_str(), &end, 0);
|
||||
if (end == trimmed.c_str() || errno != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
while (*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n')
|
||||
{
|
||||
++end;
|
||||
}
|
||||
|
||||
if (*end != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*outValue = parsed;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetCurrentUtcTimestampIso8601()
|
||||
{
|
||||
SYSTEMTIME utc = {};
|
||||
GetSystemTime(&utc);
|
||||
|
||||
char created[64] = {};
|
||||
sprintf_s(
|
||||
created,
|
||||
sizeof(created),
|
||||
"%04u-%02u-%02uT%02u:%02u:%02uZ",
|
||||
(unsigned)utc.wYear,
|
||||
(unsigned)utc.wMonth,
|
||||
(unsigned)utc.wDay,
|
||||
(unsigned)utc.wHour,
|
||||
(unsigned)utc.wMinute,
|
||||
(unsigned)utc.wSecond);
|
||||
return created;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace UtilityGame
|
||||
{
|
||||
namespace StringUtils
|
||||
{
|
||||
std::string WideToUtf8(const std::wstring &value);
|
||||
std::wstring Utf8ToWide(const char *value);
|
||||
std::wstring Utf8ToWide(const std::string &value);
|
||||
std::string StripUtf8Bom(const std::string &value);
|
||||
|
||||
std::string TrimAscii(const std::string &value);
|
||||
std::string ToLowerAscii(const std::string &value);
|
||||
std::string JoinTokens(const std::vector<std::string> &tokens, size_t startIndex = 0, const char *separator = " ");
|
||||
bool StartsWithIgnoreCase(const std::string &value, const std::string &prefix);
|
||||
bool TryParseUnsignedLongLong(const std::string &value, unsigned long long *outValue);
|
||||
std::string GetCurrentUtcTimestampIso8601();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,12 +70,61 @@ void UIComponent_PressStartToPlay::handleReload()
|
||||
m_controlPressStartPanel.setVisible(showPressStart);
|
||||
}
|
||||
|
||||
void UIComponent_PressStartToPlay::ShowAchievementToast(string achievementName, string achievementDescription, string achT)
|
||||
{
|
||||
/*IggyStringUTF8 stringVal;
|
||||
stringVal.string = (char*)label.c_str();
|
||||
stringVal.length = static_cast<S32>(label.length());
|
||||
value[0].type = IGGY_DATATYPE_string_UTF8;
|
||||
value[0].string8 = stringVal;*/
|
||||
|
||||
IggyDataValue result;
|
||||
IggyDataValue value[3];
|
||||
|
||||
IggyStringUTF8 stringVal1;
|
||||
value[0].type = IGGY_DATATYPE_string_UTF8;
|
||||
stringVal1.string = (char*)achievementName.c_str();
|
||||
stringVal1.length = static_cast<S32>(achievementName.length());
|
||||
value[0].string8 = stringVal1;
|
||||
|
||||
IggyStringUTF8 stringVal2;
|
||||
stringVal2.string = (char*)achievementDescription.c_str();
|
||||
stringVal2.length = static_cast<S32>(achievementDescription.length());
|
||||
value[1].type = IGGY_DATATYPE_string_UTF8;
|
||||
value[1].string8 = stringVal2;
|
||||
|
||||
IggyStringUTF8 stringVal3;
|
||||
stringVal3.string = (char*)achT.c_str();
|
||||
stringVal3.length = static_cast<S32>(achT.length()+3);
|
||||
value[2].type = IGGY_DATATYPE_string_UTF8;
|
||||
value[2].string8 = stringVal3;
|
||||
|
||||
IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcShowAchToast, 3, value);
|
||||
|
||||
addTimer(1, 5000);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void UIComponent_PressStartToPlay::HideAchievementToast()
|
||||
{
|
||||
IggyDataValue result;
|
||||
IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcHideAchToast, 0, nullptr);
|
||||
|
||||
Minecraft::GetInstance()->achID = 0;
|
||||
}
|
||||
|
||||
void UIComponent_PressStartToPlay::handleTimerComplete(int id)
|
||||
{
|
||||
m_controlPressStartPanel.setVisible(false);
|
||||
for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i)
|
||||
{
|
||||
m_showingPressStart[i] = false;
|
||||
if (id == 1) {
|
||||
HideAchievementToast();
|
||||
killTimer(id);
|
||||
ui.toastOn = false;
|
||||
}
|
||||
}
|
||||
ui.ClearPressStart();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "UIScene.h"
|
||||
#include "UIControl_Label.h"
|
||||
|
||||
|
||||
class UIComponent_PressStartToPlay : public UIScene
|
||||
{
|
||||
@@ -15,7 +17,7 @@ private:
|
||||
protected:
|
||||
UIControl_Label m_labelTrialTimer, m_labelPressStart, m_playerDisplayName;
|
||||
UIControl m_controlSaveIcon, m_controlPressStartPanel;
|
||||
IggyName m_funcShowController;
|
||||
IggyName m_funcShowController, m_funcShowAchToast, m_funcHideAchToast;
|
||||
UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene)
|
||||
UI_MAP_ELEMENT(m_labelTrialTimer, "TrialTimer")
|
||||
UI_MAP_ELEMENT(m_controlSaveIcon, "SaveIcon")
|
||||
@@ -26,6 +28,8 @@ protected:
|
||||
UI_END_MAP_CHILD_ELEMENTS()
|
||||
|
||||
UI_MAP_NAME(m_funcShowController, L"ShowController");
|
||||
UI_MAP_NAME(m_funcShowAchToast, L"ShowAchievementToast");
|
||||
UI_MAP_NAME(m_funcHideAchToast, L"HideAchievementToast");
|
||||
UI_END_MAP_ELEMENTS_AND_NAMES()
|
||||
|
||||
public:
|
||||
@@ -47,6 +51,9 @@ public:
|
||||
// Returns true if lower scenes in this scenes layer, or in any layer below this scenes layers should be hidden
|
||||
virtual bool hidesLowerScenes() { return false; }
|
||||
|
||||
void ShowAchievementToast(string achievementName, string achievementDescription, string achT = "");
|
||||
void HideAchievementToast();
|
||||
|
||||
virtual void handleReload();
|
||||
virtual void handleTimerComplete(int id);
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
eTexturePackList,
|
||||
eBitmapIcon,
|
||||
eTouchControl,
|
||||
eAchievementList,
|
||||
};
|
||||
protected:
|
||||
eUIControlType m_eControlType;
|
||||
@@ -63,7 +64,7 @@ public:
|
||||
UIControl();
|
||||
|
||||
virtual bool setupControl(UIScene *scene, IggyValuePath *parent, const string &controlName);
|
||||
void UpdateControl();
|
||||
virtual void UpdateControl();
|
||||
void setHidden(bool bHidden) {m_bHidden=bHidden;}
|
||||
bool getHidden(void) {return m_bHidden;}
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
#include "UIControl_AchievementsList.h"
|
||||
#include "stdafx.h"
|
||||
#include "UI.h"
|
||||
#include "../../../Minecraft.World/JavaMath.h"
|
||||
|
||||
UIControl_AchievementsList::UIControl_AchievementsList()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UIControl_AchievementsList::init(int id)
|
||||
{
|
||||
m_id = id;
|
||||
|
||||
IggyDataValue result;
|
||||
IggyDataValue value[1];
|
||||
value[0].type = IGGY_DATATYPE_number;
|
||||
value[0].number = id;
|
||||
IggyResult out = IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, getIggyValuePath(), m_initFunc, 1, value);
|
||||
|
||||
//Hardcoded from SWF since it techinically won't ever change, and getting the x and y just doesnt work through the intended way
|
||||
m_x = 221;
|
||||
m_y = 204;
|
||||
}
|
||||
|
||||
void UIControl_AchievementsList::setCurrentSelection(int iSelection)
|
||||
{
|
||||
IggyDataValue result;
|
||||
IggyDataValue value[1];
|
||||
|
||||
value[0].type = IGGY_DATATYPE_number;
|
||||
value[0].number = iSelection;
|
||||
IggyResult out = IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, getIggyValuePath(), m_funcHighlightItem, 1, value);
|
||||
}
|
||||
|
||||
bool UIControl_AchievementsList::setupControl(UIScene* scene, IggyValuePath* parent, const string& controlName)
|
||||
{
|
||||
UIControl::setControlType(UIControl::eAchievementList);
|
||||
bool success = UIControl_Base::setupControl(scene, parent, controlName);
|
||||
|
||||
//Label specific initialisers
|
||||
m_funcAddNewItem = registerFastName(L"addNewItem");
|
||||
m_funcHighlightItem = registerFastName(L"HighlightItem");
|
||||
m_funcSetTouchFocus = registerFastName(L"SetTouchFocus");
|
||||
m_funcEnableButton = registerFastName(L"EnableButton");
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void UIControl_AchievementsList::UpdateControl()
|
||||
{
|
||||
F64 fwidth, fheight;
|
||||
IggyValueGetF64RS(getIggyValuePath(), m_nameWidth, nullptr, &fwidth);
|
||||
IggyValueGetF64RS(getIggyValuePath(), m_nameHeight, nullptr, &fheight);
|
||||
m_width = static_cast<S32>(Math::round(fwidth));
|
||||
m_height = static_cast<S32>(Math::round(fheight));
|
||||
}
|
||||
|
||||
void UIControl_AchievementsList::SetTouchFocus(S32 iX, S32 iY, bool bRepeat)
|
||||
{
|
||||
IggyDataValue result;
|
||||
IggyDataValue value[3];
|
||||
|
||||
value[0].type = IGGY_DATATYPE_number;
|
||||
value[0].number = iX;
|
||||
value[1].type = IGGY_DATATYPE_number;
|
||||
value[1].number = iY;
|
||||
value[2].type = IGGY_DATATYPE_boolean;
|
||||
value[2].boolval = bRepeat;
|
||||
|
||||
IggyResult out = IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, getIggyValuePath(), m_funcSetTouchFocus, 3, value);
|
||||
}
|
||||
|
||||
void UIControl_AchievementsList::addnewItem(int id, wstring textureName)
|
||||
{
|
||||
IggyDataValue result;
|
||||
IggyDataValue value[2];
|
||||
value[0].type = IGGY_DATATYPE_number;
|
||||
value[0].number = id;
|
||||
value[1].type = IGGY_DATATYPE_string_UTF16;
|
||||
IggyStringUTF16 stringVal;
|
||||
stringVal.string = (IggyUTF16*)textureName.c_str();
|
||||
stringVal.length = textureName.length();
|
||||
value[1].string16 = stringVal;
|
||||
IggyResult out = IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, getIggyValuePath(), m_funcAddNewItem, 2, value);
|
||||
|
||||
++m_itemCount;
|
||||
}
|
||||
|
||||
void UIControl_AchievementsList::EnableButton(int id, bool bEnable) {
|
||||
IggyDataValue result;
|
||||
IggyDataValue value[2];
|
||||
value[0].type = IGGY_DATATYPE_number;
|
||||
value[0].number = id;
|
||||
value[1].type = IGGY_DATATYPE_boolean;
|
||||
value[1].boolval = bEnable;
|
||||
|
||||
IggyResult out = IggyPlayerCallMethodRS(m_parentScene->getMovie(), &result, getIggyValuePath(), m_funcEnableButton, 2, value);
|
||||
}
|
||||
|
||||
void UIControl_AchievementsList::updateChildFocus(int iChild)
|
||||
{
|
||||
m_iCurrentSelection = iChild;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "UIControl_Base.h"
|
||||
|
||||
class UIControl_AchievementsList : public UIControl_Base
|
||||
{
|
||||
private:
|
||||
IggyName m_funcAddNewItem, m_funcHighlightItem, m_funcSetTouchFocus, m_funcEnableButton;
|
||||
|
||||
public:
|
||||
UIControl_AchievementsList();
|
||||
void init(int id);
|
||||
int m_itemCount;
|
||||
int m_iCurrentSelection = 0;
|
||||
void SetTouchFocus(S32 iX, S32 iY, bool bRepeat);
|
||||
void UpdateControl();
|
||||
void EnableButton(int id, bool bEnable);
|
||||
void updateChildFocus(int iChild);
|
||||
void setCurrentSelection(int iSelection);
|
||||
virtual bool setupControl(UIScene* scene, IggyValuePath* parent, const string& controlName);
|
||||
void UIControl_AchievementsList::addnewItem(int id, wstring textureName);
|
||||
//virtual void ReInit();
|
||||
};
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "UIScene.h"
|
||||
#include "UIControl_Slider.h"
|
||||
#include "UIControl_TexturePackList.h"
|
||||
#include "UIControl_AchievementsList.h"
|
||||
#include "UIScene_AchievementsMenu.h"
|
||||
#include "../../../Minecraft.World/StringHelpers.h"
|
||||
#include "../../LocalPlayer.h"
|
||||
#include "../../DLCTexturePack.h"
|
||||
@@ -590,6 +592,8 @@ void UIController::loadSkins()
|
||||
m_iggyLibraries[eLibrary_HUD] = loadSkin(L"skinHDHud.swf", L"skinHDHud.swf");
|
||||
m_iggyLibraries[eLibrary_Tooltips] = loadSkin(L"skinHDTooltips.swf", L"skinHDTooltips.swf");
|
||||
m_iggyLibraries[eLibrary_Default] = loadSkin(L"skinHD.swf", L"skinHD.swf");
|
||||
m_iggyLibraries[eLibrary_LCDefault] = loadSkin(L"skinLC.swf", L"skinLC.swf");
|
||||
m_iggyLibraries[eLibrary_LCInGame] = loadSkin(L"skinInGameLC.swf", L"skinInGameLC.swf");
|
||||
|
||||
#elif defined _DURANGO
|
||||
m_iggyLibraries[eLibrary_Platform] = loadSkin(L"skinHDDurango.swf", L"platformskinHD.swf");
|
||||
@@ -934,7 +938,7 @@ void UIController::tickInput()
|
||||
UIControl::eUIControlType type = ctrl->getControlType();
|
||||
if (type != UIControl::eButton && type != UIControl::eTextInput &&
|
||||
type != UIControl::eCheckBox && type != UIControl::eSlider &&
|
||||
type != UIControl::eButtonList && type != UIControl::eTexturePackList)
|
||||
type != UIControl::eButtonList && type != UIControl::eAchievementList)
|
||||
continue;
|
||||
|
||||
// If the scene has an active panel (e.g. tab menus),
|
||||
@@ -967,6 +971,18 @@ void UIController::tickInput()
|
||||
hitArea = INT_MAX;
|
||||
hitCtrl = NULL;
|
||||
break; // ButtonList takes priority
|
||||
}
|
||||
if (type == UIControl::eAchievementList)
|
||||
{
|
||||
auto t = (UIScene_AchievementsMenu*)pScene;
|
||||
static_cast<UIControl_AchievementsList*>(ctrl)->SetTouchFocus(
|
||||
static_cast<S32>(sceneMouseX - cx), static_cast<S32>(sceneMouseY - cy), false);
|
||||
/*static_cast<UIControl_AchievementsList*>(ctrl)->SetTouchFocus(
|
||||
static_cast<S32>(t->aX), static_cast<S32>(t->aY), false);*/
|
||||
hitControlId = -1;
|
||||
hitArea = INT_MAX;
|
||||
hitCtrl = NULL;
|
||||
break;
|
||||
}
|
||||
if (type == UIControl::eTexturePackList)
|
||||
{
|
||||
@@ -1839,7 +1855,9 @@ GDrawTexture * RADLINK UIController::TextureSubstitutionCreateCallback ( void *
|
||||
image.preMultiplyAlpha();
|
||||
Textures *t = Minecraft::GetInstance()->textures;
|
||||
int id = t->getTexture(&image,C4JRender::TEXTURE_FORMAT_RxGyBzAw,false);
|
||||
std::string result(texture_name, texture_name + wcslen(texture_name));
|
||||
|
||||
bool isSub = result.find("sub") != std::string::npos;
|
||||
// 4J Stu - All our flash controls that allow replacing textures use a special 64x64 symbol
|
||||
// Force this size here so that our images don't get scaled wildly
|
||||
#if (defined __ORBIS__ || defined _DURANGO )
|
||||
@@ -1853,10 +1871,12 @@ GDrawTexture * RADLINK UIController::TextureSubstitutionCreateCallback ( void *
|
||||
#if defined _WINDOWS64
|
||||
// Only set the size to 96x96 for 1080p on Windows
|
||||
UIScene *scene = uiController->GetTopScene(0);
|
||||
if (scene->getSceneResolution() == UIScene::eSceneResolution_1080)
|
||||
{
|
||||
*width = 96;
|
||||
*height = 96;
|
||||
if (scene) {
|
||||
if (scene->getSceneResolution() == UIScene::eSceneResolution_1080 && (scene->getSceneType() != eUIScene_PauseMenu && scene->getSceneType() != eUIScene_MainMenu && scene->getSceneType() != eUIScene_AchievementsMenu) && isSub == false)
|
||||
{
|
||||
*width = 96;
|
||||
*height = 96;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2943,6 +2963,16 @@ void UIController::HidePressStart()
|
||||
if(m_groups[static_cast<int>(eUIGroup_Fullscreen)]->getPressStartToPlay()) m_groups[static_cast<int>(eUIGroup_Fullscreen)]->getPressStartToPlay()->showPressStart(0, false);
|
||||
}
|
||||
|
||||
void UIController::ShowAchievementToast(string achievementName, string achievementDescription, byteArray b, string achT)
|
||||
{
|
||||
if (m_groups[static_cast<int>(eUIGroup_Fullscreen)]->getPressStartToPlay()) {
|
||||
m_groups[static_cast<int>(eUIGroup_Fullscreen)]->getPressStartToPlay()->registerSubstitutionTexture(convStringToWstring(achT) + L"sub", b.data, b.length);
|
||||
m_groups[static_cast<int>(eUIGroup_Fullscreen)]->getPressStartToPlay()->ShowAchievementToast(achievementName, achievementDescription, achT + "sub");
|
||||
}
|
||||
toastOn = true;
|
||||
}
|
||||
|
||||
|
||||
void UIController::ClearPressStart()
|
||||
{
|
||||
m_iPressStartQuadrantsMask = 0;
|
||||
|
||||
@@ -19,6 +19,7 @@ class UIController : public IUIController
|
||||
public:
|
||||
static int64_t iggyAllocCount;
|
||||
|
||||
bool toastOn = false;
|
||||
// MGH - added to prevent crash loading Iggy movies while the skins were being reloaded
|
||||
static CRITICAL_SECTION ms_reloadSkinCS;
|
||||
static bool ms_bReloadSkinCSInitialised;
|
||||
@@ -103,6 +104,9 @@ private:
|
||||
eLibrary_Tooltips,
|
||||
eLibrary_Default,
|
||||
|
||||
eLibrary_LCDefault,
|
||||
eLibrary_LCInGame,
|
||||
|
||||
#if defined(_WINDOWS64)
|
||||
// Non-HD skin libraries needed by 720p/480p scene SWFs.
|
||||
eLibraryFallback_Platform,
|
||||
@@ -201,6 +205,7 @@ protected:
|
||||
UIGroup *m_groups[eUIGroup_COUNT];
|
||||
|
||||
public:
|
||||
auto& getGroups() { return m_groups; }
|
||||
void showComponent(int iPad, EUIScene scene, EUILayer layer, EUIGroup group, bool show)
|
||||
{
|
||||
m_groups[group]->showComponent(iPad, scene, layer, show);
|
||||
@@ -381,6 +386,7 @@ public:
|
||||
virtual bool PressStartPlaying(unsigned int iPad);
|
||||
virtual void ShowPressStart(unsigned int iPad);
|
||||
virtual void HidePressStart();
|
||||
void ShowAchievementToast(string achievementName, string achievementDescription, byteArray b, string achT = "");
|
||||
void ClearPressStart();
|
||||
|
||||
virtual C4JStorage::EMessageResult RequestAlertMessage(UINT uiTitle, UINT uiText, UINT *uiOptionA,UINT uiOptionC, DWORD dwPad=XUSER_INDEX_ANY, int( *Func)(LPVOID,int,const C4JStorage::EMessageResult)=nullptr,LPVOID lpParam=nullptr, WCHAR *pwchFormatString=nullptr);
|
||||
|
||||
@@ -98,6 +98,7 @@ enum EUIScene
|
||||
eUIScene_BeaconMenu,
|
||||
eUIScene_HorseMenu,
|
||||
eUIScene_FireworksMenu,
|
||||
eUIScene_AchievementsMenu,
|
||||
|
||||
#ifdef _XBOX
|
||||
// eUIScene_TransferToXboxOne,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "UI.h"
|
||||
#include "UILayer.h"
|
||||
#include "UIScene.h"
|
||||
#include "UIScene_AchievementsMenu.h"
|
||||
|
||||
UILayer::UILayer(UIGroup *parent)
|
||||
{
|
||||
@@ -266,6 +267,9 @@ bool UILayer::NavigateToScene(int iPad, EUIScene scene, void *initData)
|
||||
case eUIScene_HelpAndOptionsMenu:
|
||||
newScene = new UIScene_HelpAndOptionsMenu(iPad, initData, this);
|
||||
break;
|
||||
case eUIScene_AchievementsMenu:
|
||||
newScene = new UIScene_AchievementsMenu(iPad, initData, this);
|
||||
break;
|
||||
case eUIScene_SettingsMenu:
|
||||
newScene = new UIScene_SettingsMenu(iPad, initData, this);
|
||||
break;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "UI.h"
|
||||
#include "UIScene.h"
|
||||
#include "UISplitScreenHelpers.h"
|
||||
|
||||
#include "../../Lighting.h"
|
||||
#include "../../LocalPlayer.h"
|
||||
#include "../../ItemRenderer.h"
|
||||
@@ -765,7 +764,7 @@ void UIScene::setVisible(bool visible)
|
||||
|
||||
void UIScene::customDraw(IggyCustomDrawCallbackRegion *region)
|
||||
{
|
||||
app.DebugPrintf("Handling custom draw for scene with no override!\n");
|
||||
//app.DebugPrintf("Handling custom draw for scene with no override!\n");
|
||||
}
|
||||
|
||||
void UIScene::customDrawSlotControl(IggyCustomDrawCallbackRegion *region, int iPad, shared_ptr<ItemInstance> item, float fAlpha, bool isFoil, bool bDecorations)
|
||||
|
||||
@@ -0,0 +1,272 @@
|
||||
#include "UIScene_AchievementsMenu.h"
|
||||
#include "UI.h"
|
||||
#include "UILayer.h"
|
||||
#include "../Minecraft.World/HtmlString.h"
|
||||
#include "../Minecraft.World/Achievements.h"
|
||||
#include "../Minecraft.World/Achievement.h"
|
||||
#include "UISplitScreenHelpers.h"
|
||||
#include "StatsCounter.h"
|
||||
#include "MultiPlayerLocalPlayer.h"
|
||||
#include "Windows64/KeyboardMouseInput.h"
|
||||
|
||||
#include "UIControl_Label.h"
|
||||
|
||||
extern HWND g_hWnd;
|
||||
|
||||
UIScene_AchievementsMenu::UIScene_AchievementsMenu(int iPad, void* _initData, UILayer* parentLayer) : UIScene(iPad, parentLayer)
|
||||
{
|
||||
// Setup all the Iggy references we need for this scene
|
||||
initialiseMovie();
|
||||
/*RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
POINT center;
|
||||
center.x = rc.left;
|
||||
center.y = rc.top;
|
||||
ClientToScreen(g_hWnd, ¢er);
|
||||
SetCursorPos(center.x, center.y);*/
|
||||
|
||||
m_labelAchievements.init(L"Achievements");
|
||||
//m_labelDesc.init(L"");
|
||||
m_labelName.init(L"");
|
||||
m_achievementsList.init(0);
|
||||
for (int i = 0; i < Achievements::achievements->size(); i++) { //Achievements::achievements->size()
|
||||
std::wstring path;
|
||||
if (app.hasArchiveFile(L"Graphics\\TexturePackIcon.png"))
|
||||
{
|
||||
std::wstring iconStr(Achievements::achievements->at(i)->iconInt.begin(),
|
||||
Achievements::achievements->at(i)->iconInt.end());
|
||||
|
||||
path = L"Graphics\\Achievements\\TROP" +
|
||||
(iconStr.empty() ? L"000" : iconStr) +
|
||||
L".png";
|
||||
byteArray ba = app.getArchiveFile(path);
|
||||
registerSubstitutionTexture(path, ba.data, ba.length);
|
||||
}
|
||||
|
||||
|
||||
std::string result = "Graphics\\Achievements\\" "TROP" + Achievements::achievements->at(i)->iconInt + ".png"; //media\\
|
||||
|
||||
m_achievementsList.addnewItem(i+1, path);
|
||||
int newPad = 0;
|
||||
if (Minecraft::GetInstance()->player != nullptr) {
|
||||
newPad = Minecraft::GetInstance()->player->GetXboxPad();
|
||||
}
|
||||
|
||||
if (Minecraft::GetInstance()->stats[newPad]->hasTaken(Achievements::achievements->at(i)))
|
||||
{
|
||||
m_achievementsList.EnableButton(i, true);
|
||||
}
|
||||
else {
|
||||
m_achievementsList.EnableButton(i, false);
|
||||
}
|
||||
}
|
||||
m_funcSetDesc = registerFastName(L"SetAchievementDescription");
|
||||
|
||||
m_achievementsList.setCurrentSelection(Minecraft::GetInstance()->achID + 1);
|
||||
m_achievementsList.m_iCurrentSelection = Minecraft::GetInstance()->achID + 1;
|
||||
|
||||
}
|
||||
|
||||
void UIScene_AchievementsMenu::handleDestroy()
|
||||
{
|
||||
m_parentLayer->showComponent(m_iPad, eUIComponent_MenuBackground, false);
|
||||
}
|
||||
|
||||
void UIScene_AchievementsMenu::SetAchievementDescription(wstring desc) {
|
||||
wstring desc2 = L"";
|
||||
|
||||
if (desc != L"") {
|
||||
HtmlString test = HtmlString(desc, eHTMLColor_White);
|
||||
vector<HtmlString>* lines = new vector<HtmlString>();
|
||||
lines->push_back(test);
|
||||
desc2 = HtmlString::Compose(lines);
|
||||
}
|
||||
|
||||
IggyDataValue result;
|
||||
IggyDataValue value[1];
|
||||
IggyStringUTF16 stringVal1;
|
||||
value[0].type = IGGY_DATATYPE_string_UTF16;
|
||||
stringVal1.string = (IggyUTF16*)desc2.c_str();
|
||||
stringVal1.length = desc2.length();
|
||||
value[0].string16 = stringVal1;
|
||||
|
||||
IggyResult out = IggyPlayerCallMethodRS(getMovie(), &result, IggyPlayerRootPath(getMovie()), m_funcSetDesc, 1, value);
|
||||
}
|
||||
|
||||
wstring UIScene_AchievementsMenu::getMoviePath()
|
||||
{
|
||||
if (app.GetLocalPlayerCount() > 1)
|
||||
{
|
||||
return L"AchievementsMenu";
|
||||
}
|
||||
else
|
||||
{
|
||||
return L"AchievementsMenu";
|
||||
}
|
||||
}
|
||||
|
||||
void UIScene_AchievementsMenu::updateComponents()
|
||||
{
|
||||
bool bNotInGame = (Minecraft::GetInstance()->level == nullptr);
|
||||
if (!bNotInGame)
|
||||
{
|
||||
m_parentLayer->showComponent(m_iPad, eUIComponent_MenuBackground, true);
|
||||
}
|
||||
m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, false);
|
||||
|
||||
}
|
||||
|
||||
void UIScene_AchievementsMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled)
|
||||
{
|
||||
ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released);
|
||||
switch (key)
|
||||
{
|
||||
case ACTION_MENU_CANCEL:
|
||||
ui.NavigateBack(iPad);
|
||||
break;
|
||||
case ACTION_MENU_Y:
|
||||
if (pressed) {
|
||||
showDescription = !showDescription;
|
||||
|
||||
if (showDescription) {
|
||||
SetAchievementDescription(app.GetString(Achievements::achievements->at(m_achievementsList.m_iCurrentSelection - 1)->descID));
|
||||
}
|
||||
else {
|
||||
SetAchievementDescription(L"");
|
||||
}
|
||||
}
|
||||
sendInputToMovie(key, repeat, pressed, released);
|
||||
handled = true;
|
||||
break;
|
||||
case ACTION_MENU_UP:
|
||||
if (pressed) {
|
||||
if (m_achievementsList.m_iCurrentSelection > 10) {
|
||||
m_achievementsList.m_iCurrentSelection -= 10;
|
||||
}
|
||||
}
|
||||
sendInputToMovie(key, repeat, pressed, released);
|
||||
handled = true;
|
||||
break;
|
||||
case ACTION_MENU_DOWN:
|
||||
if (pressed) {
|
||||
if (m_achievementsList.m_iCurrentSelection < Achievements::achievements->size() - 10) {
|
||||
m_achievementsList.m_iCurrentSelection += 10;
|
||||
}
|
||||
}
|
||||
sendInputToMovie(key, repeat, pressed, released);
|
||||
handled = true;
|
||||
break;
|
||||
case ACTION_MENU_LEFT:
|
||||
if (pressed) {
|
||||
if (m_achievementsList.m_iCurrentSelection > 1) {
|
||||
m_achievementsList.m_iCurrentSelection -= 1;
|
||||
}
|
||||
}
|
||||
sendInputToMovie(key, repeat, pressed, released);
|
||||
handled = true;
|
||||
break;
|
||||
case ACTION_MENU_RIGHT:
|
||||
if (pressed) {
|
||||
if (m_achievementsList.m_iCurrentSelection < Achievements::achievements->size()) {
|
||||
m_achievementsList.m_iCurrentSelection += 1;
|
||||
}
|
||||
}
|
||||
sendInputToMovie(key, repeat, pressed, released);
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
|
||||
//m_achievementsList.updateChildFocus(static_cast<int>(childId));
|
||||
};
|
||||
|
||||
void UIScene_AchievementsMenu::getMouseToSWFScale(float& scaleX, float& scaleY)
|
||||
{
|
||||
extern HWND g_hWnd;
|
||||
RECT rc;
|
||||
GetClientRect(g_hWnd, &rc);
|
||||
int winW = rc.right - rc.left;
|
||||
int winH = rc.bottom - rc.top;
|
||||
if (winW <= 0 || winH <= 0) { scaleX = 1.0f; scaleY = 1.0f; return; }
|
||||
|
||||
S32 renderW, renderH;
|
||||
C4JRender::eViewportType vp = GetParentLayer()->getViewport();
|
||||
ui.getRenderDimensions(vp, renderW, renderH);
|
||||
if (vp != C4JRender::VIEWPORT_TYPE_FULLSCREEN)
|
||||
Fit16x9(renderW, renderH);
|
||||
|
||||
float screenW = (float)ui.getScreenWidth();
|
||||
float screenH = (float)ui.getScreenHeight();
|
||||
scaleX = static_cast<float>(m_movieWidth) * screenW / (static_cast<float>(renderW) * static_cast<float>(winW));
|
||||
scaleY = static_cast<float>(m_movieHeight) * screenH / (static_cast<float>(renderH) * static_cast<float>(winH));
|
||||
}
|
||||
|
||||
void UIScene_AchievementsMenu::tick()
|
||||
{
|
||||
UIScene::tick();
|
||||
//ShowCursor(FALSE);
|
||||
//m_cursorPath1.setVisible(g_KBMInput.IsKBMActive());
|
||||
//g_KBMInput.SetMouseGrabbed(false);
|
||||
|
||||
|
||||
if (m_achievementsList.m_iCurrentSelection != selection && m_achievementsList.m_iCurrentSelection != 0) {
|
||||
m_achievementsList.setCurrentSelection(m_achievementsList.m_iCurrentSelection - 1);
|
||||
m_labelName.setLabel(app.GetString(Achievements::achievements->at(m_achievementsList.m_iCurrentSelection - 1)->nameID));
|
||||
if (showDescription) {
|
||||
SetAchievementDescription(app.GetString(Achievements::achievements->at(m_achievementsList.m_iCurrentSelection - 1)->descID));
|
||||
}
|
||||
else {
|
||||
SetAchievementDescription(L"");
|
||||
}
|
||||
}
|
||||
|
||||
// Apply mouse delta
|
||||
/*int deltaX = g_KBMInput.GetMouseDeltaX();
|
||||
int deltaY = g_KBMInput.GetMouseDeltaY();
|
||||
|
||||
if (deltaX != 0 || deltaY != 0)
|
||||
{
|
||||
float scaleX, scaleY;
|
||||
getMouseToSWFScale(scaleX, scaleY);
|
||||
m_pointerPos.x += static_cast<float>(deltaX) * scaleX / 2;
|
||||
m_pointerPos.y += static_cast<float>(deltaY) * scaleY / 2;
|
||||
|
||||
if (m_pointerPos.x < 0.0f) m_pointerPos.x = 0.0f;
|
||||
if (m_pointerPos.x > static_cast<float>(m_movieWidth)) m_pointerPos.x = static_cast<float>(m_movieWidth);
|
||||
if (m_pointerPos.y < 0.0f) m_pointerPos.y = 0.0f;
|
||||
if (m_pointerPos.y > static_cast<float>(m_movieHeight)) m_pointerPos.y = static_cast<float>(m_movieHeight);
|
||||
}
|
||||
|
||||
IggyEvent mouseEvent;
|
||||
S32 width, height;
|
||||
m_parentLayer->getRenderDimensions(width, height);
|
||||
S32 x = static_cast<S32>(m_pointerPos.x * (static_cast<F32>(width) / static_cast<F32>(m_movieWidth)));
|
||||
aX = x;
|
||||
S32 y = static_cast<S32>(m_pointerPos.y * (static_cast<F32>(height) / static_cast<F32>(m_movieHeight)));
|
||||
aY = y;
|
||||
IggyMakeEventMouseMove(&mouseEvent, x, y);
|
||||
IggyEventResult result;
|
||||
IggyPlayerDispatchEventRS(getMovie(), &mouseEvent, &result);*/
|
||||
|
||||
selection = m_achievementsList.m_iCurrentSelection;
|
||||
}
|
||||
|
||||
void UIScene_AchievementsMenu::updateTooltips()
|
||||
{
|
||||
ui.SetTooltips(m_iPad, -1, IDS_TOOLTIPS_CANCEL, -1, IDS_TOOLTIPS_SHOW_DESCRIPTION);
|
||||
}
|
||||
|
||||
void UIScene_AchievementsMenu::handleFocusChange(F64 controlId, F64 childId)
|
||||
{
|
||||
switch (static_cast<int>(controlId))
|
||||
{
|
||||
case 0:
|
||||
m_achievementsList.updateChildFocus(static_cast<int>(childId));
|
||||
//m_achievementsList.setCurrentSelection(static_cast<int>(childId));
|
||||
//m_labelName.setLabel(app.GetString(Achievements::achievements->at(static_cast<int>(childId) - 1)->nameID));
|
||||
//SetAchievementDescription(app.GetString(Achievements::achievements->at(static_cast<int>(childId) - 1)->descID));
|
||||
|
||||
//m_labelName.setLabel(app.GetString(IDS_ACHIEVEMENTS);
|
||||
break;
|
||||
};
|
||||
updateTooltips();
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
#include "Common/UI/UIScene.h"
|
||||
#include "Common/UI/UIControl_Button.h"
|
||||
#include "Common/UI/UIControl_Cursor.h"
|
||||
#include "UIControl_AchievementsList.h"
|
||||
#include "UIControl_Label.h"
|
||||
|
||||
class UIScene_AchievementsMenu : public UIScene
|
||||
{
|
||||
private:
|
||||
|
||||
enum EControls
|
||||
{
|
||||
eControl_AchievementsLabel,
|
||||
eControl_AchievementsName,
|
||||
eControl_AchievementsDesc,
|
||||
eControl_AchievementsListContainer
|
||||
};
|
||||
UIControl m_controlMainPanel;
|
||||
UIControl_Label m_labelAchievements, m_labelName, m_labelDesc;
|
||||
UIControl_Cursor m_cursorPath1;
|
||||
vector<UIControl_Button*> m_AchButton;
|
||||
UIControl_AchievementsList m_achievementsList;
|
||||
IggyName m_funcSetDesc;
|
||||
|
||||
UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene)
|
||||
UI_MAP_ELEMENT(m_labelAchievements, "AcheivementsLabel")
|
||||
UI_MAP_ELEMENT(m_labelName, "AchievementName")
|
||||
UI_MAP_ELEMENT(m_labelDesc, "AchievementDescription")
|
||||
//UI_MAP_ELEMENT(m_achievementsList, "AchievementsList")
|
||||
UI_MAP_ELEMENT(m_controlMainPanel, "AchievementsListContainer")
|
||||
UI_MAP_NAME(m_funcSetDesc, L"SetAchievementDescription")
|
||||
UI_BEGIN_MAP_CHILD_ELEMENTS(m_controlMainPanel)
|
||||
UI_MAP_ELEMENT(m_achievementsList, "AchievementsList")
|
||||
UI_END_MAP_CHILD_ELEMENTS()
|
||||
UI_END_MAP_ELEMENTS_AND_NAMES()
|
||||
|
||||
bool showDescription = false;
|
||||
|
||||
|
||||
public:
|
||||
struct SceneMousePos
|
||||
{
|
||||
F32 x;
|
||||
F32 y;
|
||||
};
|
||||
int deltaX;
|
||||
int deltaY;
|
||||
int aX;
|
||||
int aY;
|
||||
UIVec2D m_pointerPos;
|
||||
void getMouseToSWFScale(float& scaleX, float& scaleY);
|
||||
UIScene_AchievementsMenu(int iPad, void* initData, UILayer* parentLayer);
|
||||
SceneMousePos GetSceneMousePosition(UIScene* pScene, int rawMouseX, int rawMouseY);
|
||||
virtual void handleDestroy();
|
||||
int selection = 0;
|
||||
void SetAchievementDescription(wstring desc);
|
||||
virtual void tick();
|
||||
virtual EUIScene getSceneType() { return eUIScene_AchievementsMenu; }
|
||||
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled);
|
||||
virtual void handleFocusChange(F64 controlId, F64 childId);
|
||||
virtual void updateComponents();
|
||||
|
||||
virtual void updateTooltips();
|
||||
protected:
|
||||
virtual wstring getMoviePath();
|
||||
};
|
||||
@@ -1,79 +1,33 @@
|
||||
#include "stdafx.h"
|
||||
#include "UI.h"
|
||||
#if defined(__PS3__) || defined(__ORBIS__)
|
||||
#include "Common/Network/Sony/SonyCommerce.h"
|
||||
#endif
|
||||
#include "UIScene_DLCMainMenu.h"
|
||||
|
||||
#define PLAYER_ONLINE_TIMER_ID 0
|
||||
#define PLAYER_ONLINE_TIMER_TIME 100
|
||||
|
||||
UIScene_DLCMainMenu::UIScene_DLCMainMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
|
||||
UIScene_DLCMainMenu::UIScene_DLCMainMenu(int iPad, void* initData, UILayer* parentLayer)
|
||||
: UIScene(iPad, parentLayer)
|
||||
{
|
||||
// Setup all the Iggy references we need for this scene
|
||||
initialiseMovie();
|
||||
// Alert the app the we want to be informed of ethernet connections
|
||||
app.SetLiveLinkRequired( true );
|
||||
app.SetLiveLinkRequired(true);
|
||||
|
||||
m_labelOffers.init(IDS_DOWNLOADABLE_CONTENT_OFFERS);
|
||||
m_buttonListOffers.init(eControl_OffersList);
|
||||
|
||||
#if defined _XBOX_ONE || defined __ORBIS__
|
||||
// load any local DLC images
|
||||
app.LoadLocalDLCImages();
|
||||
#endif
|
||||
|
||||
#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__)
|
||||
// show a timer on this menu
|
||||
m_Timer.setVisible(true);
|
||||
|
||||
m_bCategoriesShown=false;
|
||||
#endif
|
||||
|
||||
if(m_loadedResolution == eSceneResolution_1080)
|
||||
{
|
||||
#ifdef _DURANGO
|
||||
m_labelXboxStore.init(IDS_XBOX_STORE);
|
||||
#else
|
||||
m_labelXboxStore.init( L"" );
|
||||
#endif
|
||||
}
|
||||
m_labelXboxStore.init(L"");
|
||||
|
||||
m_buttonListOffers.addItem(L"All Packs", 0);
|
||||
m_buttonListOffers.addItem(L"Skin Packs", 1);
|
||||
m_buttonListOffers.addItem(L"Texture Packs", 2);
|
||||
m_buttonListOffers.addItem(L"Mash-up Packs", 3);
|
||||
m_buttonListOffers.setFocus(true);
|
||||
|
||||
#if defined(_DURANGO)
|
||||
m_Timer.setVisible(false);
|
||||
|
||||
m_buttonListOffers.addItem(IDS_DLC_MENU_SKINPACKS,e_DLC_SkinPack);
|
||||
m_buttonListOffers.addItem(IDS_DLC_MENU_TEXTUREPACKS,e_DLC_TexturePacks);
|
||||
m_buttonListOffers.addItem(IDS_DLC_MENU_MASHUPPACKS,e_DLC_MashupPacks);
|
||||
|
||||
app.AddDLCRequest(e_Marketplace_Content); // content is skin packs, texture packs and mash-up packs
|
||||
// we also need to mount the local DLC so we can tell what's been purchased
|
||||
app.StartInstallDLCProcess(iPad);
|
||||
#endif
|
||||
|
||||
TelemetryManager->RecordMenuShown(iPad, eUIScene_DLCMainMenu, 0);
|
||||
|
||||
#if defined __ORBIS__ || defined __PSVITA__
|
||||
app.GetCommerce()->ShowPsStoreIcon();
|
||||
#endif
|
||||
|
||||
#if ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ )
|
||||
addTimer( PLAYER_ONLINE_TIMER_ID, PLAYER_ONLINE_TIMER_TIME );
|
||||
#endif
|
||||
}
|
||||
|
||||
UIScene_DLCMainMenu::~UIScene_DLCMainMenu()
|
||||
{
|
||||
// Alert the app the we no longer want to be informed of ethernet connections
|
||||
app.SetLiveLinkRequired( false );
|
||||
#if defined _XBOX_ONE || defined __ORBIS__
|
||||
app.FreeLocalDLCImages();
|
||||
#endif
|
||||
|
||||
#ifdef _XBOX_ONE
|
||||
// 4J-JEV: Have to switch back to user preferred languge now.
|
||||
setLanguageOverride(true);
|
||||
#endif
|
||||
app.SetLiveLinkRequired(false);
|
||||
}
|
||||
|
||||
wstring UIScene_DLCMainMenu::getMoviePath()
|
||||
@@ -83,29 +37,19 @@ wstring UIScene_DLCMainMenu::getMoviePath()
|
||||
|
||||
void UIScene_DLCMainMenu::updateTooltips()
|
||||
{
|
||||
ui.SetTooltips( m_iPad, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK );
|
||||
ui.SetTooltips(m_iPad, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK);
|
||||
}
|
||||
|
||||
void UIScene_DLCMainMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
|
||||
void UIScene_DLCMainMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled)
|
||||
{
|
||||
//app.DebugPrintf("UIScene_DebugOverlay handling input for pad %d, key %d, down- %s, pressed- %s, released- %s\n", iPad, key, down?"TRUE":"FALSE", pressed?"TRUE":"FALSE", released?"TRUE":"FALSE");
|
||||
ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released);
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case ACTION_MENU_CANCEL:
|
||||
if(pressed)
|
||||
{
|
||||
#if defined __ORBIS__ || defined __PSVITA__
|
||||
app.GetCommerce()->HidePsStoreIcon();
|
||||
#endif
|
||||
navigateBack();
|
||||
}
|
||||
if(pressed) navigateBack();
|
||||
break;
|
||||
case ACTION_MENU_OK:
|
||||
#ifdef __ORBIS__
|
||||
case ACTION_MENU_TOUCHPAD_PRESS:
|
||||
#endif
|
||||
sendInputToMovie(key, repeat, pressed, released);
|
||||
break;
|
||||
case ACTION_MENU_UP:
|
||||
@@ -121,122 +65,32 @@ void UIScene_DLCMainMenu::handleInput(int iPad, int key, bool repeat, bool press
|
||||
|
||||
void UIScene_DLCMainMenu::handlePress(F64 controlId, F64 childId)
|
||||
{
|
||||
switch(static_cast<int>(controlId))
|
||||
{
|
||||
case eControl_OffersList:
|
||||
{
|
||||
int iIndex = static_cast<int>(childId);
|
||||
DLCOffersParam *param = new DLCOffersParam();
|
||||
param->iPad = m_iPad;
|
||||
if(static_cast<int>(controlId) != eControl_OffersList) return;
|
||||
|
||||
param->iType = iIndex;
|
||||
// promote the DLC content request type
|
||||
|
||||
// Xbox One will have requested the marketplace content - there is only that type
|
||||
#ifndef _XBOX_ONE
|
||||
app.AddDLCRequest(static_cast<eDLCMarketplaceType>(iIndex), true);
|
||||
#endif
|
||||
killTimer(PLAYER_ONLINE_TIMER_ID);
|
||||
ui.NavigateToScene(m_iPad, eUIScene_DLCOffersMenu, param);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void UIScene_DLCMainMenu::handleTimerComplete(int id)
|
||||
{
|
||||
#if ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__)
|
||||
switch(id)
|
||||
{
|
||||
case PLAYER_ONLINE_TIMER_ID:
|
||||
#ifndef _WINDOWS64
|
||||
if(ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())==false)
|
||||
{
|
||||
// check the player hasn't gone offline
|
||||
// If they have, bring up the PSN warning and exit from the leaderboards
|
||||
unsigned int uiIDA[1];
|
||||
uiIDA[0]=IDS_OK;
|
||||
C4JStorage::EMessageResult result = ui.RequestErrorMessage( IDS_CONNECTION_LOST, g_NetworkManager.CorrectErrorIDS(IDS_CONNECTION_LOST_LIVE_NO_EXIT), uiIDA,1,ProfileManager.GetPrimaryPad(),UIScene_DLCMainMenu::ExitDLCMainMenu,this);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int UIScene_DLCMainMenu::ExitDLCMainMenu(void *pParam,int iPad,C4JStorage::EMessageResult result)
|
||||
{
|
||||
UIScene_DLCMainMenu* pClass = static_cast<UIScene_DLCMainMenu *>(pParam);
|
||||
|
||||
#if defined __ORBIS__ || defined __PSVITA__
|
||||
app.GetCommerce()->HidePsStoreIcon();
|
||||
#endif
|
||||
pClass->navigateBack();
|
||||
|
||||
return 0;
|
||||
DLCOffersParam* param = new DLCOffersParam();
|
||||
param->iPad = m_iPad;
|
||||
param->iType = static_cast<int>(childId);
|
||||
ui.NavigateToScene(m_iPad, eUIScene_DLCOffersMenu, param);
|
||||
}
|
||||
|
||||
void UIScene_DLCMainMenu::handleGainFocus(bool navBack)
|
||||
{
|
||||
UIScene::handleGainFocus(navBack);
|
||||
|
||||
updateTooltips();
|
||||
|
||||
if(navBack)
|
||||
{
|
||||
// add the timer back in
|
||||
#if ( defined __PS3__ || defined __ORBIS__ || defined __PSVITA__ )
|
||||
addTimer( PLAYER_ONLINE_TIMER_ID, PLAYER_ONLINE_TIMER_TIME );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void UIScene_DLCMainMenu::tick()
|
||||
{
|
||||
UIScene::tick();
|
||||
|
||||
#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__)
|
||||
if((m_bCategoriesShown==false) && (app.GetCommerceCategoriesRetrieved()))
|
||||
{
|
||||
// disable the timer display on this menu
|
||||
m_Timer.setVisible(false);
|
||||
m_bCategoriesShown=true;
|
||||
|
||||
// add the categories to the list box
|
||||
SonyCommerce::CategoryInfo *pCategories=app.GetCategoryInfo();
|
||||
std::list<SonyCommerce::CategoryInfoSub>::iterator iter = pCategories->subCategories.begin();
|
||||
SonyCommerce::CategoryInfoSub category;
|
||||
for(int i=0;i<pCategories->countOfSubCategories;i++)
|
||||
{
|
||||
// add a button in with the subcategory
|
||||
category = (SonyCommerce::CategoryInfoSub)(*iter);
|
||||
|
||||
string teststring=category.categoryName;
|
||||
m_buttonListOffers.addItem(teststring,i);
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
||||
// set the focus to the first thing in the categories if there are any
|
||||
if(pCategories->countOfSubCategories>0)
|
||||
{
|
||||
m_buttonListOffers.setFocus(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined __ORBIS__ || defined __PSVITA__ || defined __PS3__
|
||||
app.CheckForEmptyStore(ProfileManager.GetPrimaryPad());
|
||||
#endif
|
||||
// need to display text to say no downloadable content available yet
|
||||
m_labelOffers.setLabel(app.GetString(IDS_NO_DLCCATEGORIES));
|
||||
|
||||
#ifdef __ORBIS__
|
||||
// 4J-JEV: TRC Requirement (R4055), need to display this system message.
|
||||
ProfileManager.DisplaySystemMessage( SCE_MSG_DIALOG_SYSMSG_TYPE_TRC_EMPTY_STORE, ProfileManager.GetPrimaryPad() );
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void UIScene_DLCMainMenu::handleTimerComplete(int id)
|
||||
{
|
||||
}
|
||||
|
||||
int UIScene_DLCMainMenu::ExitDLCMainMenu(void* pParam, int iPad, C4JStorage::EMessageResult result)
|
||||
{
|
||||
UIScene_DLCMainMenu* pClass = static_cast<UIScene_DLCMainMenu*>(pParam);
|
||||
pClass->navigateBack();
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,96 +1,75 @@
|
||||
#pragma once
|
||||
|
||||
#include "UIScene.h"
|
||||
|
||||
struct WorkshopZip
|
||||
{
|
||||
std::string filename;
|
||||
std::string destToken;
|
||||
};
|
||||
struct WorkshopPack
|
||||
{
|
||||
std::string id;
|
||||
std::wstring name;
|
||||
std::wstring author;
|
||||
std::wstring description;
|
||||
std::vector<std::string> categories;
|
||||
std::string thumbnailUrl;
|
||||
std::vector<WorkshopZip> zips;
|
||||
std::string version;
|
||||
std::vector<BYTE> thumbnailData;
|
||||
bool thumbnailLoaded;
|
||||
WorkshopPack() : thumbnailLoaded(false) {}
|
||||
};
|
||||
class UIScene_DLCOffersMenu : public UIScene
|
||||
{
|
||||
private:
|
||||
enum EControls
|
||||
{
|
||||
eControl_OffersList,
|
||||
};
|
||||
|
||||
bool m_bIsSD;
|
||||
bool m_bHasPurchased;
|
||||
bool m_bIsSelected;
|
||||
|
||||
UIControl_DLCList m_buttonListOffers;
|
||||
UIControl_Label m_labelOffers, m_labelPriceTag, m_labelXboxStore;
|
||||
UIControl_HTMLLabel m_labelHTMLSellText;
|
||||
UIControl_BitmapIcon m_bitmapIconOfferImage;
|
||||
UIControl m_Timer;
|
||||
enum EControls { eControl_OffersList };
|
||||
enum EFetchState { eFetch_Idle, eFetch_Ready, eFetch_Error };
|
||||
bool m_bIsSD;
|
||||
bool m_bHasPurchased;
|
||||
bool m_bIsSelected;
|
||||
UIControl_DLCList m_buttonListOffers;
|
||||
UIControl_Label m_labelOffers, m_labelPriceTag, m_labelXboxStore;
|
||||
UIControl_HTMLLabel m_labelHTMLSellText;
|
||||
UIControl_BitmapIcon m_bitmapIconOfferImage;
|
||||
UIControl m_Timer;
|
||||
UI_BEGIN_MAP_ELEMENTS_AND_NAMES(UIScene)
|
||||
UI_MAP_ELEMENT( m_buttonListOffers, "OffersList")
|
||||
UI_MAP_ELEMENT( m_labelOffers, "OffersList_Title")
|
||||
UI_MAP_ELEMENT( m_labelPriceTag, "PriceTag")
|
||||
UI_MAP_ELEMENT( m_labelHTMLSellText, "HTMLSellText")
|
||||
UI_MAP_ELEMENT( m_bitmapIconOfferImage, "DLCIcon" )
|
||||
UI_MAP_ELEMENT( m_Timer, "Timer")
|
||||
|
||||
UI_MAP_ELEMENT(m_buttonListOffers, "OffersList")
|
||||
UI_MAP_ELEMENT(m_labelOffers, "OffersList_Title")
|
||||
UI_MAP_ELEMENT(m_labelPriceTag, "PriceTag")
|
||||
UI_MAP_ELEMENT(m_labelHTMLSellText, "HTMLSellText")
|
||||
UI_MAP_ELEMENT(m_bitmapIconOfferImage, "DLCIcon")
|
||||
UI_MAP_ELEMENT(m_Timer, "Timer")
|
||||
if(m_loadedResolution == eSceneResolution_1080)
|
||||
{
|
||||
UI_MAP_ELEMENT( m_labelXboxStore, "XboxLabel" )
|
||||
UI_MAP_ELEMENT(m_labelXboxStore, "XboxLabel")
|
||||
}
|
||||
UI_END_MAP_ELEMENTS_AND_NAMES()
|
||||
EFetchState m_eFetchState;
|
||||
std::vector<WorkshopPack> m_packs;
|
||||
std::vector<WorkshopPack*> m_filteredPacks;
|
||||
int m_iCurrentPack;
|
||||
int m_iProductInfoIndex;
|
||||
static const char* CategoryForIndex(int index);
|
||||
static bool FetchURL(const std::string& url, std::vector<BYTE>& outData);
|
||||
static bool FetchURLString(const std::string& url, std::string& outStr);
|
||||
bool ParseRegistry(const std::string& json);
|
||||
void PopulateList();
|
||||
void UpdateDetailPanel();
|
||||
static bool InstallPack(const std::vector<BYTE>& zipData, const std::string& packName);
|
||||
static bool IsPackInstalled(const std::string& packName);
|
||||
public:
|
||||
UIScene_DLCOffersMenu(int iPad, void *initData, UILayer *parentLayer);
|
||||
UIScene_DLCOffersMenu(int iPad, void* initData, UILayer* parentLayer);
|
||||
~UIScene_DLCOffersMenu();
|
||||
static int ExitDLCOffersMenu(void *pParam,int iPad,C4JStorage::EMessageResult result);
|
||||
|
||||
virtual EUIScene getSceneType() { return eUIScene_DLCOffersMenu;}
|
||||
virtual void tick();
|
||||
virtual void updateTooltips();
|
||||
|
||||
static int ExitDLCOffersMenu(void* pParam, int iPad, C4JStorage::EMessageResult result);
|
||||
virtual EUIScene getSceneType() { return eUIScene_DLCOffersMenu; }
|
||||
virtual void tick();
|
||||
virtual void updateTooltips();
|
||||
protected:
|
||||
// TODO: This should be pure virtual in this class
|
||||
virtual wstring getMoviePath();
|
||||
|
||||
public:
|
||||
// INPUT
|
||||
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled);
|
||||
|
||||
virtual void handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool& handled);
|
||||
virtual void handlePress(F64 controlId, F64 childId);
|
||||
virtual void handleSelectionChanged(F64 selectedId);
|
||||
virtual void handleFocusChange(F64 controlId, F64 childId);
|
||||
virtual void handleTimerComplete(int id);
|
||||
#ifdef __PS3__
|
||||
virtual void HandleDLCInstalled();
|
||||
#endif
|
||||
|
||||
#ifdef _XBOX_ONE
|
||||
virtual void HandleDLCLicenseChange();
|
||||
#endif
|
||||
|
||||
private:
|
||||
#ifdef _DURANGO
|
||||
void GetDLCInfo( int iOfferC, bool bUpdateOnly=false );
|
||||
void UpdateTooltips(MARKETPLACE_CONTENTOFFER_INFO& xOffer);
|
||||
bool UpdateDisplay(MARKETPLACE_CONTENTOFFER_INFO& xOffer);
|
||||
|
||||
static int OrderSortFunction(const void* a, const void* b);
|
||||
|
||||
bool m_bIgnorePress;
|
||||
bool m_bDLCRequiredIsRetrieved;
|
||||
DLC_INFO *m_pNoImageFor_DLC;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int uiContentIndex;
|
||||
unsigned int uiSortIndex;
|
||||
}
|
||||
SORTINDEXSTRUCT;
|
||||
|
||||
vector <wstring>m_vIconRetrieval;
|
||||
bool m_bSelectionChanged;
|
||||
|
||||
#endif
|
||||
|
||||
bool m_bProductInfoShown;
|
||||
int m_iProductInfoIndex;
|
||||
int m_iCurrentDLC;
|
||||
int m_iTotalDLC;
|
||||
bool m_bAddAllDLCButtons;
|
||||
#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__)
|
||||
std::vector<SonyCommerce::ProductInfo>*m_pvProductInfo;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
@@ -27,7 +27,6 @@ UIScene_DeathMenu::UIScene_DeathMenu(int iPad, void *initData, UILayer *parentLa
|
||||
|
||||
if (isHardcore)
|
||||
{
|
||||
m_buttonRespawn.init(app.GetString(IDS_HARDCORE_DEATH_MESSAGE), eControl_Respawn);
|
||||
m_buttonRespawn.setVisible(false);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -125,5 +125,8 @@ void UIScene_LanguageSelector::handlePress(F64 controlId, F64 childId)
|
||||
app.SetMinecraftLocale(m_iPad, newLocale);
|
||||
|
||||
app.CheckGameSettingsChanged(true, m_iPad);
|
||||
|
||||
app.loadStringTable();
|
||||
app.SetAction(m_iPad, eAppAction_ReloadFont);
|
||||
}
|
||||
}
|
||||
@@ -424,6 +424,8 @@ void UIScene_LeaderboardsMenu::handleInput(int iPad, int key, bool repeat, bool
|
||||
|
||||
void UIScene_LeaderboardsMenu::ReadStats(int startIndex)
|
||||
{
|
||||
m_labelInfo.setLabel(app.GetString(IDS_LEADERBOARD_LOADING));
|
||||
m_labelInfo.setVisible(true);
|
||||
//If startIndex == -1, then use default values
|
||||
if( startIndex == -1 )
|
||||
{
|
||||
@@ -490,10 +492,6 @@ void UIScene_LeaderboardsMenu::ReadStats(int startIndex)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
//Show the loading message
|
||||
m_labelInfo.setLabel(app.GetString(IDS_LEADERBOARD_LOADING));
|
||||
m_labelInfo.setVisible(true);
|
||||
}
|
||||
|
||||
bool UIScene_LeaderboardsMenu::OnStatsReadComplete(LeaderboardManager::eStatsReturn retIn, int numResults, LeaderboardManager::ViewOut results)
|
||||
|
||||
@@ -29,8 +29,7 @@ int UIScene_LoadMenu::m_iDifficultyTitleSettingA[5]=
|
||||
IDS_DIFFICULTY_TITLE_PEACEFUL,
|
||||
IDS_DIFFICULTY_TITLE_EASY,
|
||||
IDS_DIFFICULTY_TITLE_NORMAL,
|
||||
IDS_DIFFICULTY_TITLE_HARD,
|
||||
IDS_GAMEMODE_HARDCORE
|
||||
IDS_DIFFICULTY_TITLE_HARD
|
||||
};
|
||||
|
||||
int UIScene_LoadMenu::LoadSaveDataThumbnailReturned(LPVOID lpParam,PBYTE pbThumbnail,DWORD dwThumbnailBytes)
|
||||
@@ -511,6 +510,17 @@ void UIScene_LoadMenu::tick()
|
||||
m_MoreOptionsParams.bNaturalRegeneration = app.GetGameHostOption(uiHostOptions, eGameHostOption_NaturalRegeneration);
|
||||
m_MoreOptionsParams.bDoDaylightCycle = app.GetGameHostOption(uiHostOptions, eGameHostOption_DoDaylightCycle);
|
||||
|
||||
unsigned int saveDifficulty = app.GetGameHostOption(uiHostOptions, eGameHostOption_Difficulty);
|
||||
if (saveDifficulty <= 3)
|
||||
{
|
||||
m_CurrentDifficulty = static_cast<unsigned char>(saveDifficulty);
|
||||
app.SetGameSettings(m_iPad, eGameSetting_Difficulty, m_CurrentDifficulty);
|
||||
|
||||
WCHAR difficultyLabel[256];
|
||||
swprintf((WCHAR*)difficultyLabel, 256, L"%ls: %ls", app.GetString(IDS_SLIDER_DIFFICULTY), app.GetString(m_iDifficultyTitleSettingA[m_CurrentDifficulty]));
|
||||
m_sliderDifficulty.init(difficultyLabel, eControl_Difficulty, 0, 3, m_CurrentDifficulty);
|
||||
}
|
||||
|
||||
bool cheatsOn = m_MoreOptionsParams.bHostPrivileges;
|
||||
if (!cheatsOn)
|
||||
{
|
||||
|
||||
@@ -2021,6 +2021,7 @@ void UIScene_MainMenu::RunAchievements(int iPad)
|
||||
XShowAchievementsUI( iPad );
|
||||
}
|
||||
#endif
|
||||
ui.NavigateToScene(iPad, eUIScene_AchievementsMenu);
|
||||
}
|
||||
|
||||
void UIScene_MainMenu::RunHelpAndOptions(int iPad)
|
||||
|
||||
@@ -635,7 +635,21 @@ void UIScene_PauseMenu::handlePress(F64 controlId, F64 childId)
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case BUTTON_PAUSE_ACHIEVEMENTS:
|
||||
|
||||
// guests can't look at achievements
|
||||
/*if(ProfileManager.IsGuest(pNotifyPressData->UserIndex))
|
||||
{
|
||||
UINT uiIDA[1];
|
||||
uiIDA[0]=IDS_OK;
|
||||
ui.RequestAlertMessage(IDS_PRO_GUESTPROFILE_TITLE, IDS_PRO_GUESTPROFILE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad());
|
||||
}
|
||||
else
|
||||
{
|
||||
XShowAchievementsUI( pNotifyPressData->UserIndex );
|
||||
}*/
|
||||
ui.NavigateToScene(m_iPad, eUIScene_AchievementsMenu);
|
||||
break;
|
||||
case BUTTON_PAUSE_HELPANDOPTIONS:
|
||||
ui.NavigateToScene(m_iPad,eUIScene_HelpAndOptionsMenu);
|
||||
break;
|
||||
@@ -992,6 +1006,7 @@ int UIScene_PauseMenu::UnlockFullSaveReturned(void *pParam,int iPad,C4JStorage::
|
||||
ProfileManager.DisplayFullVersionPurchase(false,pMinecraft->player->GetXboxPad(),eSen_UpsellID_Full_Version_Of_Game);
|
||||
}
|
||||
}
|
||||
pMinecraft->forceStatsSave(pMinecraft->player->GetXboxPad());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
#include "UI.h"
|
||||
#include "UIScene_SettingsOptionsMenu.h"
|
||||
|
||||
#if defined(_XBOX_ONE)
|
||||
#define _ENABLE_LANGUAGE_SELECT
|
||||
#endif
|
||||
|
||||
int UIScene_SettingsOptionsMenu::m_iDifficultySettingA[4]=
|
||||
{
|
||||
@@ -137,26 +135,21 @@ UIScene_SettingsOptionsMenu::UIScene_SettingsOptionsMenu(int iPad, void *initDat
|
||||
// MGH - disabled the language select for the patch build, we'll re-enable afterwards
|
||||
// 4J Stu - Removed it with a preprocessor def as we turn this off in various places
|
||||
#ifdef _ENABLE_LANGUAGE_SELECT
|
||||
if (app.GetGameStarted())
|
||||
{
|
||||
removeControl( &m_buttonLanguageSelect, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buttonLanguageSelect.init(IDS_LANGUAGE_SELECTOR, eControl_Languages);
|
||||
}
|
||||
|
||||
if (app.GetGameStarted())
|
||||
{
|
||||
removeControl(&m_buttonLanguageSelect, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buttonLanguageSelect.init(IDS_LANGUAGE_SELECTOR, eControl_Languages);
|
||||
}
|
||||
|
||||
#else
|
||||
removeControl( &m_buttonLanguageSelect, false );
|
||||
#endif
|
||||
|
||||
doHorizontalResizeCheck();
|
||||
removeControl(&m_buttonLanguageSelect, false);
|
||||
|
||||
if(app.GetLocalPlayerCount()>1)
|
||||
{
|
||||
#if TO_BE_IMPLEMENTED
|
||||
app.AdjustSplitscreenScene(m_hObj,&m_OriginalPosition,m_iPad);
|
||||
#endif
|
||||
}
|
||||
|
||||
m_labelDifficultyText.disableReinitialisation();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -575,6 +575,127 @@ DWORD XEnableGuestSignin(BOOL fEnable) { return 0; }
|
||||
#ifdef _WINDOWS64
|
||||
static void* profileData[4];
|
||||
static bool s_bProfileIsFullVersion;
|
||||
static unsigned int s_profileDataBytesPerPad = 0;
|
||||
|
||||
static void Win64_GetProfileDataPath(int iQuadrant, char* outPath, size_t outPathSize)
|
||||
{
|
||||
if (outPath == nullptr || outPathSize == 0)
|
||||
return;
|
||||
|
||||
outPath[0] = '\0';
|
||||
GetModuleFileNameA(nullptr, outPath, static_cast<DWORD>(outPathSize));
|
||||
char* lastSlash = strrchr(outPath, '\\');
|
||||
char* lastForwardSlash = strrchr(outPath, '/');
|
||||
if (lastForwardSlash != nullptr && (lastSlash == nullptr || lastForwardSlash > lastSlash))
|
||||
lastSlash = lastForwardSlash;
|
||||
if (lastSlash != nullptr)
|
||||
*(lastSlash + 1) = '\0';
|
||||
|
||||
char profileFileName[32] = {};
|
||||
sprintf_s(profileFileName, "profile%d.dat", iQuadrant);
|
||||
strncat_s(outPath, outPathSize, profileFileName, _TRUNCATE);
|
||||
}
|
||||
|
||||
static bool Win64_LoadProfileDataBlob(int iQuadrant, void* dstData, unsigned int dataSize)
|
||||
{
|
||||
if (dstData == nullptr || dataSize == 0)
|
||||
return false;
|
||||
|
||||
char filePath[MAX_PATH] = {};
|
||||
Win64_GetProfileDataPath(iQuadrant, filePath, MAX_PATH);
|
||||
|
||||
FILE* profileFile = nullptr;
|
||||
if (fopen_s(&profileFile, filePath, "rb") != 0 || profileFile == nullptr)
|
||||
return false;
|
||||
|
||||
fseek(profileFile, 0, SEEK_END);
|
||||
long fileSize = ftell(profileFile);
|
||||
rewind(profileFile);
|
||||
|
||||
if (fileSize != static_cast<long>(dataSize))
|
||||
{
|
||||
fclose(profileFile);
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t bytesRead = fread(dstData, 1, dataSize, profileFile);
|
||||
fclose(profileFile);
|
||||
|
||||
return bytesRead == dataSize;
|
||||
}
|
||||
|
||||
static void Win64_SaveProfileDataBlob(int iQuadrant, const void* srcData, unsigned int dataSize)
|
||||
{
|
||||
if (srcData == nullptr || dataSize == 0)
|
||||
return;
|
||||
|
||||
char filePath[MAX_PATH] = {};
|
||||
Win64_GetProfileDataPath(iQuadrant, filePath, MAX_PATH);
|
||||
|
||||
FILE* profileFile = nullptr;
|
||||
if (fopen_s(&profileFile, filePath, "wb") != 0 || profileFile == nullptr)
|
||||
return;
|
||||
|
||||
fwrite(srcData, 1, dataSize, profileFile);
|
||||
fclose(profileFile);
|
||||
}
|
||||
|
||||
static void Win64_ApplyDefaultProfileGameSettings(void* profileBytes)
|
||||
{
|
||||
if (profileBytes == nullptr)
|
||||
return;
|
||||
|
||||
// Set some sane initial values!
|
||||
GAME_SETTINGS* pGameSettings = static_cast<GAME_SETTINGS*>(profileBytes);
|
||||
pGameSettings->ucMenuSensitivity = 100; //eGameSetting_Sensitivity_InMenu
|
||||
pGameSettings->ucInterfaceOpacity = 80; //eGameSetting_Sensitivity_InMenu
|
||||
pGameSettings->usBitmaskValues |= 0x0200; //eGameSetting_DisplaySplitscreenGamertags - on
|
||||
pGameSettings->usBitmaskValues |= 0x0400; //eGameSetting_Hints - on
|
||||
pGameSettings->usBitmaskValues |= 0x1000; //eGameSetting_Autosave - 2
|
||||
pGameSettings->usBitmaskValues |= 0x8000; //eGameSetting_Tooltips - on
|
||||
pGameSettings->uiBitmaskValues = 0L; // reset
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_CLOUDS; //eGameSetting_Clouds - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter)
|
||||
pGameSettings->uiBitmaskValues &= ~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on
|
||||
pGameSettings->uiBitmaskValues |= (GAMESETTING_UISIZE & 0x00000800); // uisize 2
|
||||
pGameSettings->uiBitmaskValues |= (GAMESETTING_UISIZE_SPLITSCREEN & 0x00004000); // splitscreen ui size 3
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on
|
||||
|
||||
// TU12
|
||||
// favorite skins added, but only set in TU12 - set to FFs
|
||||
for (int skinIndex = 0; skinIndex < MAX_FAVORITE_SKINS; ++skinIndex)
|
||||
{
|
||||
pGameSettings->uiFavoriteSkinA[skinIndex] = 0xFFFFFFFF;
|
||||
}
|
||||
pGameSettings->ucCurrentFavoriteSkinPos = 0;
|
||||
// Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list
|
||||
pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF;
|
||||
|
||||
// PS3DEC13
|
||||
pGameSettings->uiBitmaskValues &= ~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off
|
||||
|
||||
// PS3 1.05 - added Greek
|
||||
pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language
|
||||
|
||||
// PS Vita - network mode added
|
||||
pGameSettings->uiBitmaskValues &= ~GAMESETTING_PSVITANETWORKMODEADHOC; //eGameSetting_PSVita_NetworkModeAdhoc - off
|
||||
|
||||
// Tutorials for most menus, and a few other things
|
||||
pGameSettings->ucTutorialCompletion[0] = 0xFF;
|
||||
pGameSettings->ucTutorialCompletion[1] = 0xFF;
|
||||
pGameSettings->ucTutorialCompletion[2] = 0xF;
|
||||
|
||||
// Has gone halfway through the tutorial
|
||||
pGameSettings->ucTutorialCompletion[28] |= 1 << 0;
|
||||
}
|
||||
|
||||
|
||||
void C_4JProfile::Initialise(DWORD dwTitleID,
|
||||
DWORD dwOfferID,
|
||||
unsigned short usProfileVersion,
|
||||
@@ -584,60 +705,25 @@ void C_4JProfile::Initialise(DWORD dwTitleID,
|
||||
int iGameDefinedDataSizeX4,
|
||||
unsigned int* puiGameDefinedDataChangedBitmask)
|
||||
{
|
||||
s_profileDataBytesPerPad = static_cast<unsigned int>(iGameDefinedDataSizeX4 / XUSER_MAX_COUNT);
|
||||
if (s_profileDataBytesPerPad == 0)
|
||||
s_profileDataBytesPerPad = static_cast<unsigned int>(iGameDefinedDataSizeX4 / 4);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
profileData[i] = new byte[iGameDefinedDataSizeX4 / 4];
|
||||
ZeroMemory(profileData[i], sizeof(byte) * iGameDefinedDataSizeX4 / 4);
|
||||
profileData[i] = new byte[s_profileDataBytesPerPad];
|
||||
ZeroMemory(profileData[i], sizeof(byte) * s_profileDataBytesPerPad);
|
||||
|
||||
// Set some sane initial values!
|
||||
GAME_SETTINGS* pGameSettings = static_cast<GAME_SETTINGS *>(profileData[i]);
|
||||
pGameSettings->ucMenuSensitivity = 100; //eGameSetting_Sensitivity_InMenu
|
||||
pGameSettings->ucInterfaceOpacity = 80; //eGameSetting_Sensitivity_InMenu
|
||||
pGameSettings->usBitmaskValues |= 0x0200; //eGameSetting_DisplaySplitscreenGamertags - on
|
||||
pGameSettings->usBitmaskValues |= 0x0400; //eGameSetting_Hints - on
|
||||
pGameSettings->usBitmaskValues |= 0x1000; //eGameSetting_Autosave - 2
|
||||
pGameSettings->usBitmaskValues |= 0x8000; //eGameSetting_Tooltips - on
|
||||
pGameSettings->uiBitmaskValues = 0L; // reset
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_CLOUDS; //eGameSetting_Clouds - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_ONLINE; //eGameSetting_GameSetting_Online - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_FRIENDSOFFRIENDS; //eGameSetting_GameSetting_FriendsOfFriends - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_DISPLAYUPDATEMSG; //eGameSetting_DisplayUpdateMessage (counter)
|
||||
pGameSettings->uiBitmaskValues &= ~GAMESETTING_BEDROCKFOG; //eGameSetting_BedrockFog - off
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_DISPLAYHUD; //eGameSetting_DisplayHUD - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_DISPLAYHAND; //eGameSetting_DisplayHand - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_CUSTOMSKINANIM; //eGameSetting_CustomSkinAnim - on
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_DEATHMESSAGES; //eGameSetting_DeathMessages - on
|
||||
pGameSettings->uiBitmaskValues |= (GAMESETTING_UISIZE & 0x00000800); // uisize 2
|
||||
pGameSettings->uiBitmaskValues |= (GAMESETTING_UISIZE_SPLITSCREEN & 0x00004000); // splitscreen ui size 3
|
||||
pGameSettings->uiBitmaskValues |= GAMESETTING_ANIMATEDCHARACTER; //eGameSetting_AnimatedCharacter - on
|
||||
|
||||
// TU12
|
||||
// favorite skins added, but only set in TU12 - set to FFs
|
||||
for (int i = 0; i < MAX_FAVORITE_SKINS; i++)
|
||||
if (!Win64_LoadProfileDataBlob(i, profileData[i], s_profileDataBytesPerPad))
|
||||
{
|
||||
pGameSettings->uiFavoriteSkinA[i] = 0xFFFFFFFF;
|
||||
Win64_ApplyDefaultProfileGameSettings(profileData[i]);
|
||||
}
|
||||
}
|
||||
pGameSettings->ucCurrentFavoriteSkinPos = 0;
|
||||
// Added a bitmask in TU13 to enable/disable display of the Mash-up pack worlds in the saves list
|
||||
pGameSettings->uiMashUpPackWorldsDisplay = 0xFFFFFFFF;
|
||||
|
||||
// PS3DEC13
|
||||
pGameSettings->uiBitmaskValues &= ~GAMESETTING_PS3EULAREAD; //eGameSetting_PS3_EULA_Read - off
|
||||
|
||||
// PS3 1.05 - added Greek
|
||||
pGameSettings->ucLanguage = MINECRAFT_LANGUAGE_DEFAULT; // use the system language
|
||||
|
||||
// PS Vita - network mode added
|
||||
pGameSettings->uiBitmaskValues &= ~GAMESETTING_PSVITANETWORKMODEADHOC; //eGameSetting_PSVita_NetworkModeAdhoc - off
|
||||
|
||||
|
||||
// Tutorials for most menus, and a few other things
|
||||
pGameSettings->ucTutorialCompletion[0] = 0xFF;
|
||||
pGameSettings->ucTutorialCompletion[1] = 0xFF;
|
||||
pGameSettings->ucTutorialCompletion[2] = 0xF;
|
||||
|
||||
// Has gone halfway through the tutorial
|
||||
pGameSettings->ucTutorialCompletion[28] |= 1 << 0;
|
||||
if (puiGameDefinedDataChangedBitmask != nullptr)
|
||||
{
|
||||
*puiGameDefinedDataChangedBitmask = (1u << XUSER_MAX_COUNT) - 1u;
|
||||
}
|
||||
}
|
||||
void C_4JProfile::SetTrialTextStringTable(CXuiStringTable * pStringTable, int iAccept, int iReject) {}
|
||||
@@ -729,8 +815,31 @@ int C_4JProfile::SetOldProfileVersionCallback(int(*Func)(LPVOID, unsigned ch
|
||||
C_4JProfile::PROFILESETTINGS ProfileSettingsA[XUSER_MAX_COUNT];
|
||||
|
||||
C_4JProfile::PROFILESETTINGS* C_4JProfile::GetDashboardProfileSettings(int iPad) { return &ProfileSettingsA[iPad]; }
|
||||
void C_4JProfile::WriteToProfile(int iQuadrant, bool bGameDefinedDataChanged, bool bOverride5MinuteLimitOnProfileWrites) {}
|
||||
void C_4JProfile::ForceQueuedProfileWrites(int iPad) {}
|
||||
void C_4JProfile::WriteToProfile(int iQuadrant, bool bGameDefinedDataChanged, bool bOverride5MinuteLimitOnProfileWrites)
|
||||
{
|
||||
if (s_profileDataBytesPerPad == 0)
|
||||
return;
|
||||
|
||||
if (iQuadrant == XUSER_INDEX_ANY)
|
||||
{
|
||||
for (int i = 0; i < XUSER_MAX_COUNT; ++i)
|
||||
{
|
||||
if (profileData[i] != nullptr)
|
||||
Win64_SaveProfileDataBlob(i, profileData[i], s_profileDataBytesPerPad);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (iQuadrant < 0 || iQuadrant >= XUSER_MAX_COUNT)
|
||||
return;
|
||||
|
||||
if (profileData[iQuadrant] != nullptr)
|
||||
Win64_SaveProfileDataBlob(iQuadrant, profileData[iQuadrant], s_profileDataBytesPerPad);
|
||||
}
|
||||
void C_4JProfile::ForceQueuedProfileWrites(int iPad)
|
||||
{
|
||||
WriteToProfile(iPad, true, true);
|
||||
}
|
||||
void* C_4JProfile::GetGameDefinedProfileData(int iQuadrant)
|
||||
{
|
||||
// 4J Stu - Don't reset the options when we call this!!
|
||||
|
||||
@@ -1086,10 +1086,10 @@ void Gui::render(float a, bool mouseFree, int xMouse, int yMouse)
|
||||
vector<wstring> lines;
|
||||
|
||||
// Only show version/branch for player 0 to avoid cluttering each splitscreen viewport
|
||||
if (iPad == 0 && ClientConstants::SHOW_VERSION_WATERMARK)
|
||||
if (iPad == 0)
|
||||
{
|
||||
lines.push_back(ClientConstants::VERSION_STRING);
|
||||
lines.push_back(ClientConstants::BRANCH_STRING);
|
||||
lines.push_back(ClientConstants::GetLCENString());
|
||||
}
|
||||
|
||||
if (minecraft->options->renderDebug && minecraft->player != nullptr && minecraft->level != nullptr)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "FurnaceScreen.h"
|
||||
#include "TrapScreen.h"
|
||||
|
||||
#include "../Minecraft.Client/Common/UI/UIScene.h"
|
||||
#include "MultiPlayerLocalPlayer.h"
|
||||
#include "CreativeMode.h"
|
||||
#include "GameRenderer.h"
|
||||
@@ -56,6 +57,8 @@
|
||||
#ifndef _DURANGO
|
||||
#include "../Minecraft.World/CommonStats.h"
|
||||
#endif
|
||||
|
||||
#include "Common/StringUtils.h"
|
||||
extern ConsoleUIController ui;
|
||||
|
||||
|
||||
@@ -798,6 +801,30 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
|
||||
if (stat->isAchievement())
|
||||
{
|
||||
Achievement *ach = static_cast<Achievement *>(stat);
|
||||
/*ui.ShowAchievementToast(
|
||||
WideToUtf8(app.GetString(ach->nameID)),
|
||||
WideToUtf8(app.GetString(IDS_ACHIEVEMENT_VIEW))
|
||||
);*/
|
||||
|
||||
std::wstring iconStr(ach->iconInt.begin(),
|
||||
ach->iconInt.end());
|
||||
|
||||
wstring path = L"Graphics\\Achievements\\TROP" +
|
||||
(iconStr.empty() ? L"000" : iconStr) +
|
||||
L".png";
|
||||
byteArray ba = app.getArchiveFile(path);
|
||||
//auto t = ui.GetTopScene(0);
|
||||
//t->registerSubstitutionTexture(path, ba.data, ba.length);
|
||||
if (!minecraft->stats[m_iPad]->hasTaken(ach))
|
||||
{
|
||||
ui.ShowAchievementToast(
|
||||
UtilityGame::StringUtils::WideToUtf8(app.GetString(ach->nameID)),
|
||||
UtilityGame::StringUtils::WideToUtf8(app.FormatHTMLString(0, app.GetString(IDS_ACHIEVEMENT_VIEW), 0xFFFFFFFF, true).c_str()), ba,
|
||||
UtilityGame::StringUtils::WideToUtf8(path.c_str())
|
||||
);
|
||||
minecraft->achID = ach->getAchievementID();
|
||||
}
|
||||
//app.FormatHTMLString(0, app.GetString(IDS_ACHIEVEMENT_VIEW));
|
||||
// 4J-PB - changed to attempt to award everytime - the award may need a storage device, so needs a primary player, and the player may not have been a primary player when they first 'got' the award
|
||||
// so let the award manager figure it out
|
||||
//if (!minecraft->stats[m_iPad]->hasTaken(ach))
|
||||
@@ -934,7 +961,6 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
|
||||
// AWARD : Porkchop, cook and eat a porkchop.
|
||||
{
|
||||
@@ -1094,7 +1120,7 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool LocalPlayer::isSolidBlock(int x, int y, int z)
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
|
||||
int m_iScreenSection; // assuming 4player splitscreen for now, or -1 for single player
|
||||
uint64_t ullButtonsPressed; // Stores the button presses, since the inputmanager can be ticked faster than the minecraft
|
||||
uint64_t ullButtonsDown;
|
||||
// player tick, and a button press and release combo can be missed in the minecraft::tick
|
||||
|
||||
uint64_t ullDpad_last;
|
||||
@@ -62,7 +63,7 @@ public:
|
||||
// 4J-PB - moved these in from the minecraft structure, since they are per player things for splitscreen
|
||||
//int ticks;
|
||||
int missTime;
|
||||
int lastClickTick[2];
|
||||
int lastClickTick[3];
|
||||
bool isRaining ;
|
||||
int m_iThirdPersonView;
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
#endif
|
||||
#include "Common/UI/IUIScene_CreativeMenu.h"
|
||||
#include "Common/UI/UIFontData.h"
|
||||
#include "Common/UI/UIComponent_PressStartToPlay.h"
|
||||
#include "DLCTexturePack.h"
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
@@ -1453,6 +1454,7 @@ void Minecraft::run_middle()
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_USE)) localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_USE;
|
||||
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_INVENTORY)) localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_INVENTORY;
|
||||
if(InputManager.ButtonDown(i, MINECRAFT_ACTION_INVENTORY)) localplayers[i]->ullButtonsDown|=1LL<<MINECRAFT_ACTION_INVENTORY;
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_ACTION)) localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_ACTION;
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_CRAFTING)) localplayers[i]->ullButtonsPressed|=1LL<<MINECRAFT_ACTION_CRAFTING;
|
||||
if(InputManager.ButtonPressed(i, MINECRAFT_ACTION_PAUSEMENU))
|
||||
@@ -3632,13 +3634,14 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||
#else
|
||||
bool useHeld = InputManager.ButtonDown(iPad, MINECRAFT_ACTION_USE);
|
||||
#endif
|
||||
bool achHeld;
|
||||
if( player->isUsingItem() )
|
||||
{
|
||||
if(!useHeld) gameMode->releaseUsingItem(player);
|
||||
}
|
||||
else if( gameMode->isInputAllowed(MINECRAFT_ACTION_USE) )
|
||||
else if (gameMode->isInputAllowed(MINECRAFT_ACTION_USE))
|
||||
{
|
||||
if( player->abilities.instabuild )
|
||||
if (player->abilities.instabuild)
|
||||
{
|
||||
// 4J - attempt to handle click in special creative mode fashion if possible (used for placing blocks at regular intervals)
|
||||
bool didClick = player->creativeModeHandleMouseClick(1, useHeld );
|
||||
@@ -3689,6 +3692,67 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||
player->lastClickTick[1] = 0;
|
||||
}
|
||||
}
|
||||
achHeld = InputManager.ButtonDown(iPad, MINECRAFT_ACTION_INVENTORY) ||
|
||||
(iPad == 0 && g_KBMInput.IsKBMActive() &&
|
||||
g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_INVENTORY));
|
||||
if (ui.toastOn) {
|
||||
if (achHeld) {
|
||||
// Record when the hold started
|
||||
if (player->lastClickTick[2] == 0) {
|
||||
player->lastClickTick[2] = ticks;
|
||||
}
|
||||
// Check if held for 1 second
|
||||
bool heldLongEnough = (ticks - player->lastClickTick[2]) >= (timer->ticksPerSecond);
|
||||
if (heldLongEnough) {
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
ui.NavigateToScene(iPad, eUIScene_AchievementsMenu);
|
||||
ui.getGroups()[static_cast<int>(eUIGroup_Fullscreen)]->getPressStartToPlay()->handleTimerComplete(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If let go during period, open inventory
|
||||
if (player->lastClickTick[2] != 0) {
|
||||
shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->player;
|
||||
if (!player->isRiding())
|
||||
{
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
}
|
||||
|
||||
if (gameMode->isServerControlledInventory())
|
||||
{
|
||||
player->sendOpenInventory();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.LoadInventoryMenu(iPad, player);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset when button is released
|
||||
player->lastClickTick[2] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Just open inventory if the toast is not open
|
||||
if ((player->ullButtonsPressed & (1LL << MINECRAFT_ACTION_INVENTORY)) && gameMode->isInputAllowed(MINECRAFT_ACTION_INVENTORY))
|
||||
{
|
||||
shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->player;
|
||||
if (!player->isRiding())
|
||||
{
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
}
|
||||
|
||||
if (gameMode->isServerControlledInventory())
|
||||
{
|
||||
player->sendOpenInventory();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.LoadInventoryMenu(iPad, player);
|
||||
}
|
||||
}
|
||||
player->lastClickTick[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(app.DebugSettingsOn())
|
||||
@@ -3754,19 +3818,26 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||
|
||||
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_INVENTORY)) && gameMode->isInputAllowed(MINECRAFT_ACTION_INVENTORY))
|
||||
{
|
||||
shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->player;
|
||||
if (!player->isRiding())
|
||||
{
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
if (achHeld) {
|
||||
|
||||
//ui.PlayUISFX(eSFX_Press);
|
||||
//ui.NavigateToScene(iPad, eUIScene_AchievementsMenu);
|
||||
}
|
||||
else {
|
||||
/*shared_ptr<MultiplayerLocalPlayer> player = Minecraft::GetInstance()->player;
|
||||
if (!player->isRiding())
|
||||
{
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
}
|
||||
|
||||
if(gameMode->isServerControlledInventory())
|
||||
{
|
||||
player->sendOpenInventory();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.LoadInventoryMenu(iPad,player);
|
||||
if (gameMode->isServerControlledInventory())
|
||||
{
|
||||
player->sendOpenInventory();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.LoadInventoryMenu(iPad, player);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3794,7 +3865,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||
else
|
||||
{
|
||||
ui.PlayUISFX(eSFX_Press);
|
||||
app.LoadCrafting2x2Menu(iPad,player);
|
||||
app.LoadCrafting2x2Menu(iPad, player);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,7 +91,8 @@ public:
|
||||
Level *oldLevel; // 4J Stu added to keep a handle on an old level so we can delete it
|
||||
//HANDLE m_hPlayerRespawned; // 4J Added so we can wait in menus until it is done (for async in multiplayer)
|
||||
public:
|
||||
|
||||
bool inventoryWasHeld = false;
|
||||
int achID = 0;
|
||||
MultiPlayerLevel *level;
|
||||
LevelRenderer *levelRenderer;
|
||||
shared_ptr<MultiplayerLocalPlayer> player;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
# Format Style Options - Created with Clang Power Tools
|
||||
---
|
||||
AccessModifierOffset: -4
|
||||
AlignConsecutiveMacros: true
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortEnumsOnASingleLine: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
ColumnLimit: 150
|
||||
EmptyLineBeforeAccessModifier: Never
|
||||
IndentAccessModifiers: false
|
||||
IndentWidth: 4
|
||||
NamespaceIndentation: All
|
||||
BreakBeforeBraces: Allman
|
||||
@@ -0,0 +1,445 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
*.env
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
|
||||
[Dd]ebug/x64/
|
||||
[Dd]ebugPublic/x64/
|
||||
[Rr]elease/x64/
|
||||
[Rr]eleases/x64/
|
||||
bin/x64/
|
||||
obj/x64/
|
||||
|
||||
[Dd]ebug/x86/
|
||||
[Dd]ebugPublic/x86/
|
||||
[Rr]elease/x86/
|
||||
[Rr]eleases/x86/
|
||||
bin/x86/
|
||||
obj/x86/
|
||||
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
[Aa][Rr][Mm]64[Ee][Cc]/
|
||||
bld/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Build results on 'Bin' directories
|
||||
**/[Bb]in/*
|
||||
# Uncomment if you have tasks that rely on *.refresh files to move binaries
|
||||
# (https://github.com/github/gitignore/pull/3736)
|
||||
#!**/[Bb]in/*.refresh
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
*.trx
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Approval Tests result files
|
||||
*.received.*
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.idb
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
# but not Directory.Build.rsp, as it configures directory-level build defaults
|
||||
!Directory.Build.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
**/.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
**/.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
**/.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
**/__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
#tools/**
|
||||
#!tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
MSBuild_Logs/
|
||||
|
||||
# AWS SAM Build and Temporary Artifacts folder
|
||||
.aws-sam
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
**/.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
**/.localhistory/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
**/.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
!.vscode/*.code-snippets
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
.vscode/
|
||||
build/
|
||||
libs/
|
||||
|
||||
# generated shader headers
|
||||
VS_PF3_TF2_CB4_NB4_XW1.h
|
||||
VS_Compressed.h
|
||||
VS_PF3_TF2_CB4_NB4_XW1_LIGHTING.h
|
||||
VS_PF3_TF2_CB4_NB4_XW1_TEXGEN.h
|
||||
VS_ScreenSpace.h
|
||||
VS_ScreenClear.h
|
||||
PS_Standard.h
|
||||
PS_TextureProjection.h
|
||||
PS_ForceLOD.h
|
||||
PS_ScreenSpace.h
|
||||
PS_ScreenClear.h
|
||||
@@ -0,0 +1,16 @@
|
||||
cmake_minimum_required(VERSION 3.25 FATAL_ERROR)
|
||||
|
||||
project(4JLibs LANGUAGES CXX)
|
||||
|
||||
add_library(4JLibs.Globals INTERFACE)
|
||||
|
||||
target_include_directories(4JLibs.Globals INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/inc
|
||||
)
|
||||
|
||||
set(CMAKE_DEBUG_POSTFIX "_d")
|
||||
|
||||
# msvc specific flags
|
||||
if(MSVC)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
endif()
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "x64-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "x64-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "RelWithDebInfo",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"variables": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
# 4JLibs implementation guide
|
||||
|
||||
Whilst the library can be a direct replacement to the standard libraries shipped by the source leak, we can apply some enhancements to the original code
|
||||
|
||||
Some functions were misimplemented due to the Windows library being a direct port off the Xbox 360 libraries, and because this platform was never supposed to see the light of day
|
||||
|
||||
This guide will explain every change you can do in the source leak to improve it, like displaying save thumbnails, displaying save titles on the load menu and more
|
||||
|
||||
## Save thumbnails
|
||||
|
||||
#### The original code for displaying and saving thumbnails was broken for the Windows platform, either by poor ports or lack of care, in this section it will be explained how to enable this feature for the Windows platform using 4JLibs
|
||||
|
||||
In the files ``ConsoleSaveFileOriginal.cpp`` and ``ConsoleSaveFileSplit.cpp`` (the latter might not exist if you are using the December build) there was a mistake when calling ``app.GetSaveThumbnail``
|
||||
|
||||
To fix this issue, you need to replace the line of code:
|
||||
|
||||
```cpp
|
||||
#if ( defined _XBOX || defined _DURANGO )
|
||||
```
|
||||
|
||||
For:
|
||||
```cpp
|
||||
#if ( defined _XBOX || defined _DURANGO || defined _WINDOWS64 )
|
||||
```
|
||||
|
||||
In the files ``Windows64_App.h`` and ``Windows64_App.cpp``, it is assumed that thumbnail capturing is broken, therefore the functions responsible for doing the capturing are empty, we need to fill them back up as follows:
|
||||
|
||||
Below the implementation of:
|
||||
```cpp
|
||||
class CConsoleMinecraftApp : public CMinecraftApp
|
||||
{
|
||||
public:
|
||||
```
|
||||
|
||||
You need to add the line:
|
||||
```cpp
|
||||
ImageFileBuffer m_ThumbnailBuffer;
|
||||
```
|
||||
|
||||
Then, in ``Windows64_App.cpp``, you need to replace the empty implementations of ``CConsoleMinecraftApp::CaptureSaveThumbnail()`` and ``CConsoleMinecraftApp::GetSaveThumbnail`` with the following:
|
||||
```cpp
|
||||
void CConsoleMinecraftApp::CaptureSaveThumbnail()
|
||||
{
|
||||
RenderManager.CaptureThumbnail(&m_ThumbnailBuffer);
|
||||
}
|
||||
void CConsoleMinecraftApp::GetSaveThumbnail(PBYTE *pbData,DWORD *pdwSize)
|
||||
{
|
||||
if (m_ThumbnailBuffer.Allocated())
|
||||
{
|
||||
if (pbData)
|
||||
{
|
||||
*pbData = new BYTE[m_ThumbnailBuffer.GetBufferSize()];
|
||||
*pdwSize = m_ThumbnailBuffer.GetBufferSize();
|
||||
memcpy(*pbData, m_ThumbnailBuffer.GetBufferPointer(), *pdwSize);
|
||||
}
|
||||
m_ThumbnailBuffer.Release();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
These changes are enough to display the save thumbnails in the save selector, but we also need to fix the save data displayed in the actual load menu, which we will do as follows
|
||||
|
||||
In the file ``UIScene_LoadMenu.cpp``, you need to replace the line:
|
||||
```cpp
|
||||
#if defined(__PS3__) || defined(__ORBIS__)|| defined(_DURANGO) || defined (__PSVITA__)
|
||||
```
|
||||
|
||||
With:
|
||||
```cpp
|
||||
#if defined(__PS3__) || defined(__ORBIS__)|| defined(_DURANGO) || defined (__PSVITA__) || defined (_WINDOWS64)
|
||||
```
|
||||
|
||||
Then, below that, there's the following chunk of code:
|
||||
```cpp
|
||||
#else // __ORBIS__
|
||||
{
|
||||
SceCesUcsContext Context;
|
||||
sceCesUcsContextInit( &Context );
|
||||
uint32_t utf8Len, utf16Len;
|
||||
sceCesUtf8StrToUtf16Str(&Context, (uint8_t *)params->saveDetails->UTF8SaveFilename, srclen, &utf8Len, u16Message, dstlen, &utf16Len);
|
||||
}
|
||||
#endif
|
||||
```
|
||||
|
||||
You want to modify the ``#else`` conditional to be:
|
||||
```cpp
|
||||
#elif defined(__ORBIS__) || defined(__PSVITA__)
|
||||
```
|
||||
|
||||
This way the Windows platform doesn't try accessing PS4/PSVita functions
|
||||
|
||||
Then you want to comment/remove the following chunk of code:
|
||||
```cpp
|
||||
if(params->saveDetails->pbThumbnailData)
|
||||
{
|
||||
m_pbThumbnailData = params->saveDetails->pbThumbnailData;
|
||||
m_uiThumbnailSize = params->saveDetails->dwThumbnailSize;
|
||||
m_bSaveThumbnailReady = true;
|
||||
}
|
||||
else
|
||||
```
|
||||
|
||||
You can replace it for
|
||||
```cpp
|
||||
//if(params->saveDetails->pbThumbnailData)
|
||||
//{
|
||||
// m_pbThumbnailData = params->saveDetails->pbThumbnailData;
|
||||
// m_uiThumbnailSize = params->saveDetails->dwThumbnailSize;
|
||||
// m_bSaveThumbnailReady = true;
|
||||
//}
|
||||
//else
|
||||
```
|
||||
|
||||
This is because, for a ``SAVE_DETAILS`` object, the thumbnail data is always pointing to valid memory (aka, it's always allocated)
|
||||
|
||||
|
||||
After all these changes, save titles and thumbnails should be properly displayed across the game
|
||||
|
||||
## Renderer bugs/artifacts on newer Visual Studio versions
|
||||
|
||||
In the file ``Windows64_Minecraft.cpp``, the depth stencil view descriptor is not null terminated which causes undefined behaviour
|
||||
|
||||
In the case of newer compilers like Visual Studio 2022/2026, this causes the ``descDSView.Flags`` field to be filled with garbage data, and therefore causing visual glitches in game because the depth stencil fails to be created
|
||||
|
||||
To fix this issue, below the line:
|
||||
```cpp
|
||||
D3D11_DEPTH_STENCIL_VIEW_DESC descDSView;
|
||||
```
|
||||
|
||||
You need to fill the structure with zeros, you can do it like this:
|
||||
```cpp
|
||||
ZeroMemory(&descDSView, sizeof(descDSView));
|
||||
```
|
||||
@@ -0,0 +1,21 @@
|
||||
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.
|
||||
@@ -0,0 +1,21 @@
|
||||
# 4JLibs
|
||||
|
||||
A project that aims at rebuilding the 4J libraries source code via decompilation for the Minecraft: Legacy Console Edition
|
||||
|
||||
## Implementation
|
||||
|
||||
For implementation details, please look at the [IMPLEMENTATION_GUIDE.md](IMPLEMENTATION_GUIDE.md) file
|
||||
|
||||
## Why?
|
||||
|
||||
This would allow compiling the Minecraft: Legacy Console Edition source code from newer versions of Visual Studio, expand the Renderer code, add new Input support, etc...
|
||||
|
||||
This would also help document the structure of their projects for decompilation projects of newer versions of this version of the game
|
||||
|
||||
## How can I build this?
|
||||
|
||||
Just open the main folder and compile with your favourite code editor!
|
||||
|
||||
## What is implemented?
|
||||
|
||||
All projects can be linked against the main game code, whilst there's some unnamed stuff in the Renderer, this works just fine and the game can be played
|
||||
@@ -589,7 +589,7 @@ void PendingConnection::onDisconnect(DisconnectPacket::eDisconnectReason reason,
|
||||
void PendingConnection::handleGetInfo(shared_ptr<GetInfoPacket> packet)
|
||||
{
|
||||
//try {
|
||||
//String message = server->motd + "�" + server->players->getPlayerCount() + "�" + server->players->getMaxPlayers();
|
||||
//String message = server->motd + "<22>" + server->players->getPlayerCount() + "<22>" + server->players->getMaxPlayers();
|
||||
//connection->send(new DisconnectPacket(message));
|
||||
connection->send(std::make_shared<DisconnectPacket>(DisconnectPacket::eDisconnect_ServerFull));
|
||||
connection->sendAndQuit();
|
||||
|
||||
@@ -1089,13 +1089,13 @@ int PlayerConnection::countDelayedPackets()
|
||||
void PlayerConnection::info(const wstring& string)
|
||||
{
|
||||
// 4J-PB - removed, since it needs to be localised in the language the client is in
|
||||
//send( shared_ptr<ChatPacket>( new ChatPacket(L"�7" + string) ) );
|
||||
//send( shared_ptr<ChatPacket>( new ChatPacket(L"<22>7" + string) ) );
|
||||
}
|
||||
|
||||
void PlayerConnection::warn(const wstring& string)
|
||||
{
|
||||
// 4J-PB - removed, since it needs to be localised in the language the client is in
|
||||
//send( shared_ptr<ChatPacket>( new ChatPacket(L"�9" + string) ) );
|
||||
//send( shared_ptr<ChatPacket>( new ChatPacket(L"<22>9" + string) ) );
|
||||
}
|
||||
|
||||
wstring PlayerConnection::getConsoleName()
|
||||
|
||||
@@ -211,8 +211,9 @@ void StatsCounter::save(int player, bool force)
|
||||
|
||||
//Check we're going to have enough room to store all possible stats
|
||||
unsigned int uiTotalStatsSize = (Stats::all->size() * 4 * sizeof(unsigned short)) - (Achievements::achievements->size() * 3 * sizeof(unsigned short)) + (LARGE_STATS_COUNT*4*(sizeof(unsigned int)-sizeof(unsigned short)));
|
||||
//Do change this back and fix it.
|
||||
assert( uiTotalStatsSize <= (CConsoleMinecraftApp::GAME_DEFINED_PROFILE_DATA_BYTES-sizeof(GAME_SETTINGS)) );
|
||||
|
||||
//
|
||||
//Retrieve the data pointer from the profile
|
||||
#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined __PSVITA__ )
|
||||
PBYTE pbData = (PBYTE)StorageManager.GetGameDefinedProfileData(player);
|
||||
|
||||
@@ -89,9 +89,9 @@ public:
|
||||
#ifdef _DEBUG
|
||||
void WipeLeaderboards();
|
||||
#endif
|
||||
bool isLargeStat(Stat* stat);
|
||||
|
||||
private:
|
||||
bool isLargeStat(Stat* stat);
|
||||
void dumpStatsToTTY();
|
||||
|
||||
#ifdef _XBOX
|
||||
|
||||
@@ -1,5 +1,704 @@
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "WindowsLeaderboardManager.h"
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
LeaderboardManager *LeaderboardManager::m_instance = new WindowsLeaderboardManager(); //Singleton instance of the LeaderboardManager
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
#pragma comment(lib, "wininet.lib")
|
||||
|
||||
#include "../json.hpp"
|
||||
using json = nlohmann::json;
|
||||
|
||||
#include "../../Minecraft.h"
|
||||
#include "../../StatsCounter.h"
|
||||
#include "../../../Minecraft.World/StringHelpers.h"
|
||||
#include "../../../Minecraft.World/Stats.h"
|
||||
#include "../../../Minecraft.World/net.minecraft.world.item.h"
|
||||
#include "../../../Minecraft.World/net.minecraft.world.level.tile.h"
|
||||
|
||||
extern char g_LCENToken[512];
|
||||
|
||||
namespace
|
||||
{
|
||||
static const char* kBaseUrl = "https://network-server-7kuc.onrender.com";
|
||||
|
||||
static int ClampDifficulty(int d)
|
||||
{
|
||||
if (d < 0) return 0;
|
||||
if (d > 3) return 3;
|
||||
return d;
|
||||
}
|
||||
|
||||
static unsigned long ClampToULong(unsigned long long v)
|
||||
{
|
||||
if (v > static_cast<unsigned long long>(ULONG_MAX)) return ULONG_MAX;
|
||||
return static_cast<unsigned long>(v);
|
||||
}
|
||||
|
||||
static std::string UidToHex(PlayerUID uid)
|
||||
{
|
||||
unsigned long long raw = static_cast<unsigned long long>(uid);
|
||||
char buf[17] = {};
|
||||
_snprintf_s(buf, sizeof(buf), _TRUNCATE, "%016llX", raw);
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
static PlayerUID HexToUid(const std::string& hex)
|
||||
{
|
||||
if (hex.empty()) return INVALID_XUID;
|
||||
unsigned long long raw = 0;
|
||||
sscanf_s(hex.c_str(), "%llX", &raw);
|
||||
return static_cast<PlayerUID>(raw);
|
||||
}
|
||||
|
||||
static unsigned int CombinePigmanKills(StatsCounter* stats, unsigned int difficulty)
|
||||
{
|
||||
if (!stats) return 0;
|
||||
return stats->getValue(Stats::killsZombiePigman, difficulty)
|
||||
+ stats->getValue(Stats::killsNetherZombiePigman, difficulty);
|
||||
}
|
||||
|
||||
static std::string WstrToUtf8(const std::wstring& w)
|
||||
{
|
||||
if (w.empty()) return {};
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
||||
if (len <= 1) return {};
|
||||
std::string s(len - 1, '\0');
|
||||
WideCharToMultiByte(CP_UTF8, 0, w.c_str(), -1, &s[0], len, nullptr, nullptr);
|
||||
return s;
|
||||
}
|
||||
|
||||
static std::string HttpRequest(const std::string& method,
|
||||
const std::string& url,
|
||||
const std::string& body = "")
|
||||
{
|
||||
std::string result;
|
||||
|
||||
HINTERNET hNet = InternetOpenA("openLCE", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
if (!hNet) return result;
|
||||
|
||||
std::string headers;
|
||||
if (g_LCENToken[0] != '\0')
|
||||
{
|
||||
headers = "Authorization: Bearer ";
|
||||
headers += g_LCENToken;
|
||||
headers += "\r\n";
|
||||
}
|
||||
|
||||
DWORD flags = INTERNET_FLAG_RELOAD
|
||||
| INTERNET_FLAG_NO_CACHE_WRITE
|
||||
| INTERNET_FLAG_SECURE
|
||||
| INTERNET_FLAG_IGNORE_CERT_CN_INVALID
|
||||
| INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;
|
||||
|
||||
HINTERNET hReq = NULL;
|
||||
|
||||
if (method == "POST")
|
||||
{
|
||||
headers += "Content-Type: application/json\r\n";
|
||||
|
||||
URL_COMPONENTSA uc = {};
|
||||
uc.dwStructSize = sizeof(uc);
|
||||
char host[256] = {};
|
||||
char path[1024] = {};
|
||||
uc.lpszHostName = host;
|
||||
uc.dwHostNameLength = sizeof(host);
|
||||
uc.lpszUrlPath = path;
|
||||
uc.dwUrlPathLength = sizeof(path);
|
||||
|
||||
if (InternetCrackUrlA(url.c_str(), 0, 0, &uc))
|
||||
{
|
||||
HINTERNET hConn = InternetConnectA(
|
||||
hNet, host,
|
||||
uc.nPort ? uc.nPort : INTERNET_DEFAULT_HTTPS_PORT,
|
||||
NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
|
||||
|
||||
if (hConn)
|
||||
{
|
||||
DWORD reqFlags = INTERNET_FLAG_RELOAD
|
||||
| INTERNET_FLAG_NO_CACHE_WRITE
|
||||
| INTERNET_FLAG_SECURE
|
||||
| INTERNET_FLAG_IGNORE_CERT_CN_INVALID
|
||||
| INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;
|
||||
|
||||
hReq = HttpOpenRequestA(hConn, "POST", path, NULL, NULL, NULL, reqFlags, 0);
|
||||
if (hReq)
|
||||
{
|
||||
HttpSendRequestA(hReq,
|
||||
headers.c_str(), static_cast<DWORD>(headers.size()),
|
||||
const_cast<char*>(body.c_str()), static_cast<DWORD>(body.size()));
|
||||
}
|
||||
InternetCloseHandle(hConn);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hReq = InternetOpenUrlA(hNet, url.c_str(),
|
||||
headers.empty() ? NULL : headers.c_str(),
|
||||
headers.empty() ? 0 : static_cast<DWORD>(headers.size()),
|
||||
flags, 0);
|
||||
}
|
||||
|
||||
if (hReq)
|
||||
{
|
||||
char buf[4096] = {};
|
||||
DWORD read = 0;
|
||||
while (InternetReadFile(hReq, buf, sizeof(buf) - 1, &read) && read > 0)
|
||||
{
|
||||
buf[read] = '\0';
|
||||
result.append(buf, read);
|
||||
read = 0;
|
||||
}
|
||||
InternetCloseHandle(hReq);
|
||||
}
|
||||
|
||||
InternetCloseHandle(hNet);
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string HttpGet(const std::string& url)
|
||||
{
|
||||
return HttpRequest("GET", url);
|
||||
}
|
||||
|
||||
static std::string HttpPost(const std::string& url, const std::string& jsonBody)
|
||||
{
|
||||
return HttpRequest("POST", url, jsonBody);
|
||||
}
|
||||
|
||||
static void ParseServerEntries(const std::string& jsonText,
|
||||
std::vector<LeaderboardManager::ReadScore>& outScores)
|
||||
{
|
||||
if (jsonText.empty()) return;
|
||||
try
|
||||
{
|
||||
json arr = json::parse(jsonText);
|
||||
if (!arr.is_array()) return;
|
||||
for (auto& entry : arr)
|
||||
{
|
||||
LeaderboardManager::ReadScore score = {};
|
||||
score.m_rank = 1;
|
||||
score.m_idsErrorMessage = 0;
|
||||
|
||||
if (entry.contains("uid") && entry["uid"].is_string())
|
||||
score.m_uid = HexToUid(entry["uid"].get<std::string>());
|
||||
|
||||
if (entry.contains("gamertag") && entry["gamertag"].is_string())
|
||||
score.m_name = convStringToWstring(entry["gamertag"].get<std::string>());
|
||||
|
||||
if (entry.contains("totalScore") && entry["totalScore"].is_number())
|
||||
score.m_totalScore = ClampToULong(
|
||||
static_cast<unsigned long long>(entry["totalScore"].get<double>()));
|
||||
|
||||
if (entry.contains("stats") && entry["stats"].is_array())
|
||||
{
|
||||
auto& sa = entry["stats"];
|
||||
unsigned int count = static_cast<unsigned int>(
|
||||
(std::min<size_t>)(sa.size(), LeaderboardManager::ReadScore::STATSDATA_MAX));
|
||||
score.m_statsSize = static_cast<unsigned short>(count);
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
if (sa[i].is_number())
|
||||
score.m_statsData[i] = static_cast<unsigned long>(sa[i].get<double>());
|
||||
}
|
||||
|
||||
outScores.push_back(score);
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
|
||||
static void AssignRanks(std::vector<LeaderboardManager::ReadScore>& scores)
|
||||
{
|
||||
for (size_t i = 0; i < scores.size(); ++i)
|
||||
scores[i].m_rank = static_cast<unsigned long>(i + 1);
|
||||
}
|
||||
|
||||
static int FindPlayerIndex(const std::vector<LeaderboardManager::ReadScore>& scores,
|
||||
PlayerUID myUID, const std::wstring& myName)
|
||||
{
|
||||
for (int i = 0; i < static_cast<int>(scores.size()); ++i)
|
||||
{
|
||||
const auto& s = scores[i];
|
||||
if (myUID != INVALID_XUID && s.m_uid == myUID) return i;
|
||||
if (!myName.empty() && !s.m_name.empty() &&
|
||||
_wcsicmp(s.m_name.c_str(), myName.c_str()) == 0) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool BuildLocalScore(LeaderboardManager::ReadScore& out,
|
||||
StatsCounter* stats,
|
||||
LeaderboardManager::EStatsType type,
|
||||
unsigned int diff,
|
||||
PlayerUID uid,
|
||||
const std::wstring& name)
|
||||
{
|
||||
ZeroMemory(&out, sizeof(out));
|
||||
out.m_uid = uid;
|
||||
out.m_rank = 1;
|
||||
out.m_idsErrorMessage = 0;
|
||||
out.m_name = name;
|
||||
|
||||
unsigned long long total = 0;
|
||||
auto col = [&](unsigned int idx, unsigned int val)
|
||||
{
|
||||
if (idx >= LeaderboardManager::ReadScore::STATSDATA_MAX) return;
|
||||
out.m_statsData[idx] = val;
|
||||
total += val;
|
||||
};
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case LeaderboardManager::eStatsType_Travelling:
|
||||
out.m_statsSize = 4;
|
||||
col(0, stats->getValue(Stats::walkOneM, diff));
|
||||
col(1, stats->getValue(Stats::fallOneM, diff));
|
||||
col(2, stats->getValue(Stats::minecartOneM, diff));
|
||||
col(3, stats->getValue(Stats::boatOneM, diff));
|
||||
break;
|
||||
case LeaderboardManager::eStatsType_Mining:
|
||||
out.m_statsSize = 7;
|
||||
col(0, stats->getValue(Stats::blocksMined[Tile::dirt_Id], diff));
|
||||
col(1, stats->getValue(Stats::blocksMined[Tile::cobblestone_Id], diff));
|
||||
col(2, stats->getValue(Stats::blocksMined[Tile::sand_Id], diff));
|
||||
col(3, stats->getValue(Stats::blocksMined[Tile::stone_Id], diff));
|
||||
col(4, stats->getValue(Stats::blocksMined[Tile::gravel_Id], diff));
|
||||
col(5, stats->getValue(Stats::blocksMined[Tile::clay_Id], diff));
|
||||
col(6, stats->getValue(Stats::blocksMined[Tile::obsidian_Id], diff));
|
||||
break;
|
||||
case LeaderboardManager::eStatsType_Farming:
|
||||
out.m_statsSize = 6;
|
||||
col(0, stats->getValue(Stats::itemsCollected[Item::egg_Id], diff));
|
||||
col(1, stats->getValue(Stats::blocksMined[Tile::wheat_Id], diff));
|
||||
col(2, stats->getValue(Stats::blocksMined[Tile::mushroom_brown_Id], diff));
|
||||
col(3, stats->getValue(Stats::blocksMined[Tile::reeds_Id], diff));
|
||||
col(4, stats->getValue(Stats::cowsMilked, diff));
|
||||
col(5, stats->getValue(Stats::itemsCollected[Tile::pumpkin_Id], diff));
|
||||
break;
|
||||
case LeaderboardManager::eStatsType_Kills:
|
||||
out.m_statsSize = 7;
|
||||
col(0, stats->getValue(Stats::killsZombie, diff));
|
||||
col(1, stats->getValue(Stats::killsSkeleton, diff));
|
||||
col(2, stats->getValue(Stats::killsCreeper, diff));
|
||||
col(3, stats->getValue(Stats::killsSpider, diff));
|
||||
col(4, stats->getValue(Stats::killsSpiderJockey, diff));
|
||||
col(5, CombinePigmanKills(stats, diff));
|
||||
col(6, stats->getValue(Stats::killsSlime, diff));
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
out.m_totalScore = ClampToULong(total);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
WindowsLeaderboardManager::ValidatedIdentity WindowsLeaderboardManager::s_identity = {};
|
||||
|
||||
bool WindowsLeaderboardManager::ResolveIdentity()
|
||||
{
|
||||
if (g_LCENToken[0] == '\0')
|
||||
{
|
||||
s_identity = {};
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s_identity.valid &&
|
||||
strncmp(g_LCENToken, s_identity.tokenSnapshot, sizeof(s_identity.tokenSnapshot)) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
s_identity = {};
|
||||
|
||||
std::string resp = HttpGet(std::string(kBaseUrl) + "/auth/validate");
|
||||
if (resp.empty()) return false;
|
||||
|
||||
try
|
||||
{
|
||||
json j = json::parse(resp);
|
||||
|
||||
if (j.contains("banned") && j["banned"].get<bool>()) return false;
|
||||
if (j.contains("error")) return false;
|
||||
if (!j.contains("xuid") || !j.contains("gamertag")) return false;
|
||||
|
||||
strncpy_s(s_identity.tokenSnapshot, g_LCENToken, _TRUNCATE);
|
||||
s_identity.xuidHex = j["xuid"].get<std::string>();
|
||||
s_identity.gamertag = convStringToWstring(j["gamertag"].get<std::string>());
|
||||
s_identity.valid = true;
|
||||
return true;
|
||||
}
|
||||
catch (...) { return false; }
|
||||
}
|
||||
|
||||
LeaderboardManager* LeaderboardManager::m_instance = new WindowsLeaderboardManager();
|
||||
|
||||
bool WindowsLeaderboardManager::WriteStats(unsigned int viewCount, ViewIn views)
|
||||
{
|
||||
if (views == nullptr || viewCount == 0)
|
||||
return true;
|
||||
|
||||
if (!ResolveIdentity())
|
||||
{
|
||||
delete[] views;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string gamertag = WstrToUtf8(s_identity.gamertag);
|
||||
if (gamertag.empty()) gamertag = "Player";
|
||||
|
||||
for (unsigned int i = 0; i < viewCount; ++i)
|
||||
{
|
||||
const RegisterScore& src = views[i];
|
||||
|
||||
int diff = ClampDifficulty(src.m_difficulty);
|
||||
if (src.m_commentData.m_statsType == eStatsType_Kills && diff == 0)
|
||||
diff = 1;
|
||||
|
||||
int type = static_cast<int>(src.m_commentData.m_statsType);
|
||||
if (type < 0 || type >= static_cast<int>(eStatsType_MAX)) continue;
|
||||
|
||||
json statsArr = json::array();
|
||||
unsigned long long total = 0;
|
||||
|
||||
switch (src.m_commentData.m_statsType)
|
||||
{
|
||||
case eStatsType_Travelling:
|
||||
statsArr = { src.m_commentData.m_travelling.m_walked,
|
||||
src.m_commentData.m_travelling.m_fallen,
|
||||
src.m_commentData.m_travelling.m_minecart,
|
||||
src.m_commentData.m_travelling.m_boat };
|
||||
break;
|
||||
case eStatsType_Mining:
|
||||
statsArr = { src.m_commentData.m_mining.m_dirt,
|
||||
src.m_commentData.m_mining.m_cobblestone,
|
||||
src.m_commentData.m_mining.m_sand,
|
||||
src.m_commentData.m_mining.m_stone,
|
||||
src.m_commentData.m_mining.m_gravel,
|
||||
src.m_commentData.m_mining.m_clay,
|
||||
src.m_commentData.m_mining.m_obsidian };
|
||||
break;
|
||||
case eStatsType_Farming:
|
||||
statsArr = { src.m_commentData.m_farming.m_eggs,
|
||||
src.m_commentData.m_farming.m_wheat,
|
||||
src.m_commentData.m_farming.m_mushroom,
|
||||
src.m_commentData.m_farming.m_sugarcane,
|
||||
src.m_commentData.m_farming.m_milk,
|
||||
src.m_commentData.m_farming.m_pumpkin };
|
||||
break;
|
||||
case eStatsType_Kills:
|
||||
statsArr = { src.m_commentData.m_kills.m_zombie,
|
||||
src.m_commentData.m_kills.m_skeleton,
|
||||
src.m_commentData.m_kills.m_creeper,
|
||||
src.m_commentData.m_kills.m_spider,
|
||||
src.m_commentData.m_kills.m_spiderJockey,
|
||||
src.m_commentData.m_kills.m_zombiePigman,
|
||||
src.m_commentData.m_kills.m_slime };
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
for (auto& v : statsArr) total += v.get<unsigned int>();
|
||||
|
||||
unsigned long long serverTotal = total;
|
||||
if (src.m_score > 0 && static_cast<unsigned long long>(src.m_score) > serverTotal)
|
||||
serverTotal = static_cast<unsigned long long>(src.m_score);
|
||||
|
||||
json body;
|
||||
body["uid"] = s_identity.xuidHex;
|
||||
body["gamertag"] = gamertag;
|
||||
body["type"] = type;
|
||||
body["difficulty"] = diff;
|
||||
body["stats"] = statsArr;
|
||||
body["totalScore"] = serverTotal;
|
||||
|
||||
HttpPost(std::string(kBaseUrl) + "/leaderboard/submit", body.dump());
|
||||
}
|
||||
|
||||
delete[] views;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WindowsLeaderboardManager::ReadStats_Friends(LeaderboardReadListener* callback,
|
||||
int difficulty, EStatsType type, PlayerUID myUID,
|
||||
unsigned int startIndex, unsigned int readCount)
|
||||
{
|
||||
if (!LeaderboardManager::ReadStats_Friends(callback, difficulty, type, myUID, startIndex, readCount))
|
||||
return false;
|
||||
return ReadNetworkStats(callback, difficulty, type, myUID, eFM_Friends, startIndex, readCount);
|
||||
}
|
||||
|
||||
bool WindowsLeaderboardManager::ReadStats_MyScore(LeaderboardReadListener* callback,
|
||||
int difficulty, EStatsType type, PlayerUID myUID, unsigned int readCount)
|
||||
{
|
||||
if (!LeaderboardManager::ReadStats_MyScore(callback, difficulty, type, myUID, readCount))
|
||||
return false;
|
||||
return ReadNetworkStats(callback, difficulty, type, myUID, eFM_MyScore, 1, readCount);
|
||||
}
|
||||
|
||||
bool WindowsLeaderboardManager::ReadStats_TopRank(LeaderboardReadListener* callback,
|
||||
int difficulty, EStatsType type,
|
||||
unsigned int startIndex, unsigned int readCount)
|
||||
{
|
||||
if (!LeaderboardManager::ReadStats_TopRank(callback, difficulty, type, startIndex, readCount))
|
||||
return false;
|
||||
|
||||
PlayerUID uid = INVALID_XUID;
|
||||
if (s_identity.valid)
|
||||
uid = HexToUid(s_identity.xuidHex);
|
||||
|
||||
return ReadNetworkStats(callback, difficulty, type, uid, eFM_TopRank, startIndex, readCount);
|
||||
}
|
||||
|
||||
bool WindowsLeaderboardManager::ReadNetworkStats(LeaderboardReadListener* callback,
|
||||
int difficulty, EStatsType type, PlayerUID myUID,
|
||||
EFilterMode filterMode,
|
||||
unsigned int startIndex, unsigned int readCount)
|
||||
{
|
||||
if (!callback) return false;
|
||||
|
||||
bool authenticated = ResolveIdentity();
|
||||
|
||||
PlayerUID resolvedUID = INVALID_XUID;
|
||||
std::wstring resolvedName;
|
||||
std::string resolvedHex;
|
||||
|
||||
if (authenticated)
|
||||
{
|
||||
resolvedUID = HexToUid(s_identity.xuidHex);
|
||||
resolvedName = s_identity.gamertag;
|
||||
resolvedHex = s_identity.xuidHex;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unauthenticated: accept passed-in UID for display only; no POSTs.
|
||||
resolvedUID = myUID;
|
||||
const int pad = ProfileManager.GetPrimaryPad();
|
||||
if (pad >= 0 && pad < XUSER_MAX_COUNT)
|
||||
{
|
||||
char* gt = ProfileManager.GetGamertag(pad);
|
||||
if (gt && gt[0]) resolvedName = convStringToWstring(gt);
|
||||
if (resolvedUID == INVALID_XUID)
|
||||
ProfileManager.GetXUID(pad, &resolvedUID, true);
|
||||
}
|
||||
if (resolvedUID != INVALID_XUID) resolvedHex = UidToHex(resolvedUID);
|
||||
}
|
||||
|
||||
unsigned int diff = static_cast<unsigned int>(ClampDifficulty(difficulty));
|
||||
if (type == eStatsType_Kills && diff == 0) diff = 1;
|
||||
|
||||
// Submit live score only when authenticated.
|
||||
if (authenticated && resolvedUID != INVALID_XUID)
|
||||
{
|
||||
Minecraft* mc = Minecraft::GetInstance();
|
||||
const int pad = ProfileManager.GetPrimaryPad();
|
||||
if (mc && pad >= 0 && pad < XUSER_MAX_COUNT)
|
||||
{
|
||||
StatsCounter* stats = mc->stats[pad];
|
||||
if (stats)
|
||||
{
|
||||
LeaderboardManager::ReadScore localScore = {};
|
||||
if (BuildLocalScore(localScore, stats, type, diff, resolvedUID, resolvedName))
|
||||
{
|
||||
json statsArr = json::array();
|
||||
for (unsigned int i = 0; i < localScore.m_statsSize; ++i)
|
||||
statsArr.push_back(localScore.m_statsData[i]);
|
||||
|
||||
std::string gt = WstrToUtf8(resolvedName);
|
||||
if (gt.empty()) gt = "Player";
|
||||
|
||||
json submitBody;
|
||||
submitBody["uid"] = s_identity.xuidHex;
|
||||
submitBody["gamertag"] = gt;
|
||||
submitBody["type"] = static_cast<int>(type);
|
||||
submitBody["difficulty"] = static_cast<int>(diff);
|
||||
submitBody["stats"] = statsArr;
|
||||
submitBody["totalScore"] = static_cast<unsigned long long>(localScore.m_totalScore);
|
||||
|
||||
HttpPost(std::string(kBaseUrl) + "/leaderboard/submit", submitBody.dump());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<LeaderboardManager::ReadScore> allRows;
|
||||
|
||||
if (filterMode == eFM_Friends)
|
||||
{
|
||||
std::string xuidList = resolvedHex;
|
||||
|
||||
if (authenticated && g_LCENToken[0] != '\0')
|
||||
{
|
||||
std::string friendsJson = HttpGet(std::string(kBaseUrl) + "/friends");
|
||||
if (!friendsJson.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
json arr = json::parse(friendsJson);
|
||||
if (arr.is_array())
|
||||
for (auto& f : arr)
|
||||
if (f.contains("xuid") && f["xuid"].is_string())
|
||||
{
|
||||
if (!xuidList.empty()) xuidList += ',';
|
||||
xuidList += f["xuid"].get<std::string>();
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
}
|
||||
|
||||
if (!xuidList.empty())
|
||||
{
|
||||
std::string url = std::string(kBaseUrl)
|
||||
+ "/leaderboard/friends?type=" + std::to_string(static_cast<int>(type))
|
||||
+ "&difficulty=" + std::to_string(diff)
|
||||
+ "&xuids=" + xuidList;
|
||||
ParseServerEntries(HttpGet(url), allRows);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int limit = (readCount > 0) ? (std::min)(readCount, 100u) : 64u;
|
||||
unsigned int offset = (startIndex > 1) ? (startIndex - 1) : 0;
|
||||
|
||||
if (filterMode == eFM_MyScore) { limit = 100; offset = 0; }
|
||||
|
||||
std::string url = std::string(kBaseUrl)
|
||||
+ "/leaderboard?type=" + std::to_string(static_cast<int>(type))
|
||||
+ "&difficulty=" + std::to_string(diff)
|
||||
+ "&limit=" + std::to_string(limit)
|
||||
+ "&offset=" + std::to_string(offset);
|
||||
|
||||
ParseServerEntries(HttpGet(url), allRows);
|
||||
}
|
||||
|
||||
if (FindPlayerIndex(allRows, resolvedUID, resolvedName) < 0 &&
|
||||
resolvedUID != INVALID_XUID && !resolvedHex.empty())
|
||||
{
|
||||
std::string rankUrl = std::string(kBaseUrl)
|
||||
+ "/leaderboard/rank?uid=" + resolvedHex
|
||||
+ "&type=" + std::to_string(static_cast<int>(type))
|
||||
+ "&difficulty=" + std::to_string(diff);
|
||||
|
||||
std::string rankResp = HttpGet(rankUrl);
|
||||
if (!rankResp.empty())
|
||||
{
|
||||
try
|
||||
{
|
||||
json rj = json::parse(rankResp);
|
||||
if (rj.contains("totalScore") && rj["totalScore"].is_number())
|
||||
{
|
||||
LeaderboardManager::ReadScore ps = {};
|
||||
ps.m_uid = resolvedUID;
|
||||
ps.m_name = resolvedName;
|
||||
ps.m_totalScore = ClampToULong(
|
||||
static_cast<unsigned long long>(rj["totalScore"].get<double>()));
|
||||
ps.m_rank = static_cast<unsigned long>(
|
||||
rj.contains("rank") ? rj["rank"].get<int>() : 0);
|
||||
|
||||
Minecraft* mc2 = Minecraft::GetInstance();
|
||||
const int pad2 = ProfileManager.GetPrimaryPad();
|
||||
if (mc2 && pad2 >= 0 && pad2 < XUSER_MAX_COUNT && mc2->stats[pad2])
|
||||
BuildLocalScore(ps, mc2->stats[pad2], type, diff, resolvedUID, resolvedName);
|
||||
|
||||
allRows.push_back(ps);
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
}
|
||||
else if (!authenticated)
|
||||
{
|
||||
Minecraft* mc2 = Minecraft::GetInstance();
|
||||
const int pad2 = ProfileManager.GetPrimaryPad();
|
||||
if (mc2 && pad2 >= 0 && pad2 < XUSER_MAX_COUNT)
|
||||
{
|
||||
StatsCounter* stats = mc2->stats[pad2];
|
||||
if (stats)
|
||||
{
|
||||
LeaderboardManager::ReadScore ps = {};
|
||||
if (BuildLocalScore(ps, stats, type, diff, resolvedUID, resolvedName))
|
||||
allRows.push_back(ps);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(allRows.begin(), allRows.end(),
|
||||
[](const LeaderboardManager::ReadScore& a, const LeaderboardManager::ReadScore& b)
|
||||
{
|
||||
if (a.m_totalScore != b.m_totalScore) return a.m_totalScore > b.m_totalScore;
|
||||
const wchar_t* na = a.m_name.empty() ? L"" : a.m_name.c_str();
|
||||
const wchar_t* nb = b.m_name.empty() ? L"" : b.m_name.c_str();
|
||||
int cmp = _wcsicmp(na, nb);
|
||||
if (cmp != 0) return cmp < 0;
|
||||
return a.m_uid < b.m_uid;
|
||||
});
|
||||
|
||||
AssignRanks(allRows);
|
||||
|
||||
if (allRows.empty())
|
||||
{
|
||||
ReadView empty = {};
|
||||
callback->OnStatsReadComplete(eStatsReturn_NoResults, 0, empty);
|
||||
return true;
|
||||
}
|
||||
|
||||
int playerIdx = FindPlayerIndex(allRows, resolvedUID, resolvedName);
|
||||
size_t pageStart = 0;
|
||||
size_t pageCount = allRows.size();
|
||||
|
||||
if (filterMode == eFM_MyScore)
|
||||
{
|
||||
pageStart = (playerIdx >= 0) ? static_cast<size_t>(playerIdx) : 0;
|
||||
pageCount = 1;
|
||||
}
|
||||
else if (filterMode == eFM_TopRank)
|
||||
{
|
||||
if (startIndex > 1)
|
||||
pageStart = (std::min<size_t>)(static_cast<size_t>(startIndex - 1), allRows.size());
|
||||
pageCount = allRows.size() - pageStart;
|
||||
if (readCount > 0)
|
||||
pageCount = (std::min<size_t>)(pageCount, static_cast<size_t>(readCount));
|
||||
}
|
||||
|
||||
if (pageStart >= allRows.size())
|
||||
{
|
||||
ReadView empty = {};
|
||||
callback->OnStatsReadComplete(eStatsReturn_NoResults, 0, empty);
|
||||
return true;
|
||||
}
|
||||
|
||||
pageCount = (std::min)(pageCount, allRows.size() - pageStart);
|
||||
|
||||
std::vector<LeaderboardManager::ReadScore> page(
|
||||
allRows.begin() + static_cast<std::ptrdiff_t>(pageStart),
|
||||
allRows.begin() + static_cast<std::ptrdiff_t>(pageStart + pageCount));
|
||||
|
||||
if (page.empty())
|
||||
{
|
||||
ReadView empty = {};
|
||||
callback->OnStatsReadComplete(eStatsReturn_NoResults, 0, empty);
|
||||
return true;
|
||||
}
|
||||
|
||||
ReadView view = {};
|
||||
view.m_numQueries = static_cast<unsigned int>(page.size());
|
||||
view.m_queries = page.data();
|
||||
|
||||
int totalResults = (filterMode == eFM_MyScore)
|
||||
? static_cast<int>(page.size())
|
||||
: static_cast<int>(allRows.size());
|
||||
|
||||
callback->OnStatsReadComplete(eStatsReturn_Success, totalResults, view);
|
||||
return true;
|
||||
}
|
||||
@@ -1,36 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/Leaderboards/LeaderboardManager.h"
|
||||
|
||||
class WindowsLeaderboardManager : public LeaderboardManager
|
||||
{
|
||||
public:
|
||||
virtual void Tick() {}
|
||||
virtual void Tick() override {}
|
||||
virtual bool OpenSession() override { return true; }
|
||||
virtual void CloseSession() override {}
|
||||
virtual void DeleteSession() override {}
|
||||
|
||||
//Open a session
|
||||
virtual bool OpenSession() { return true; }
|
||||
virtual bool WriteStats(unsigned int viewCount, ViewIn views) override;
|
||||
|
||||
//Close a session
|
||||
virtual void CloseSession() {}
|
||||
virtual bool ReadStats_Friends(
|
||||
LeaderboardReadListener* callback,
|
||||
int difficulty,
|
||||
EStatsType type,
|
||||
PlayerUID myUID,
|
||||
unsigned int startIndex,
|
||||
unsigned int readCount) override;
|
||||
|
||||
//Delete a session
|
||||
virtual void DeleteSession() {}
|
||||
virtual bool ReadStats_MyScore(
|
||||
LeaderboardReadListener* callback,
|
||||
int difficulty,
|
||||
EStatsType type,
|
||||
PlayerUID myUID,
|
||||
unsigned int readCount) override;
|
||||
|
||||
//Write the given stats
|
||||
//This is called synchronously and will not free any memory allocated for views when it is done
|
||||
virtual bool ReadStats_TopRank(
|
||||
LeaderboardReadListener* callback,
|
||||
int difficulty,
|
||||
EStatsType type,
|
||||
unsigned int startIndex,
|
||||
unsigned int readCount) override;
|
||||
|
||||
virtual bool WriteStats(unsigned int viewCount, ViewIn views) { return false; }
|
||||
virtual void FlushStats() override {}
|
||||
virtual void CancelOperation() override {}
|
||||
virtual bool isIdle() override { return true; }
|
||||
|
||||
virtual bool ReadStats_Friends(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID) { return false; }
|
||||
virtual bool ReadStats_MyScore(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID, unsigned int readCount) { return false; }
|
||||
virtual bool ReadStats_TopRank(LeaderboardReadListener *callback, int difficulty, EStatsType type, unsigned int startIndex, unsigned int readCount) { return false; }
|
||||
private:
|
||||
bool ReadNetworkStats(
|
||||
LeaderboardReadListener* callback,
|
||||
int difficulty,
|
||||
EStatsType type,
|
||||
PlayerUID myUID,
|
||||
EFilterMode filterMode,
|
||||
unsigned int startIndex,
|
||||
unsigned int readCount);
|
||||
|
||||
//Perform a flush of the stats
|
||||
virtual void FlushStats() {}
|
||||
struct ValidatedIdentity
|
||||
{
|
||||
char tokenSnapshot[512];
|
||||
std::string xuidHex;
|
||||
std::wstring gamertag;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
//Cancel the current operation
|
||||
virtual void CancelOperation() {}
|
||||
static ValidatedIdentity s_identity;
|
||||
|
||||
//Is the leaderboard manager idle.
|
||||
virtual bool isIdle() { return true; }
|
||||
};
|
||||
static bool ResolveIdentity();
|
||||
};
|
||||
@@ -0,0 +1,132 @@
|
||||
#include "NetworkHelpers.h"
|
||||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#pragma comment(lib, "wininet.lib")
|
||||
|
||||
static void Debug(const std::string& msg)
|
||||
{
|
||||
OutputDebugStringA((msg + "\n").c_str());
|
||||
}
|
||||
|
||||
bool HttpPost(const char* url, const Json& payload)
|
||||
{
|
||||
URL_COMPONENTSA uc = {};
|
||||
uc.dwStructSize = sizeof(uc);
|
||||
char host[256] = {}, path[1024] = {};
|
||||
uc.lpszHostName = host; uc.dwHostNameLength = sizeof(host);
|
||||
uc.lpszUrlPath = path; uc.dwUrlPathLength = sizeof(path);
|
||||
|
||||
if (!InternetCrackUrlA(url, 0, 0, &uc))
|
||||
{
|
||||
Debug("InternetCrackUrlA FAILED");
|
||||
return false;
|
||||
}
|
||||
|
||||
HINTERNET hNet = InternetOpenA("MinecraftWinINet/1.0", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
|
||||
if (!hNet) { Debug("InternetOpenA FAILED"); return false; }
|
||||
|
||||
INTERNET_PORT port = uc.nPort ? uc.nPort : INTERNET_DEFAULT_HTTPS_PORT;
|
||||
HINTERNET hConn = InternetConnectA(hNet, host, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
|
||||
if (!hConn)
|
||||
{
|
||||
Debug("InternetConnectA FAILED");
|
||||
InternetCloseHandle(hNet);
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD flags = INTERNET_FLAG_SECURE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE;
|
||||
HINTERNET hReq = HttpOpenRequestA(hConn, "POST", path, NULL, NULL, NULL, flags, 0);
|
||||
if (!hReq)
|
||||
{
|
||||
Debug("HttpOpenRequestA FAILED");
|
||||
InternetCloseHandle(hConn);
|
||||
InternetCloseHandle(hNet);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string body = payload.dump();
|
||||
const char* headers = "Content-Type: application/json\r\n";
|
||||
BOOL ok = HttpSendRequestA(hReq, headers, (DWORD)strlen(headers),
|
||||
(LPVOID)body.c_str(), (DWORD)body.size());
|
||||
if (!ok)
|
||||
{
|
||||
Debug("HttpSendRequestA FAILED");
|
||||
InternetCloseHandle(hReq);
|
||||
InternetCloseHandle(hConn);
|
||||
InternetCloseHandle(hNet);
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[4096]; DWORD bytesRead = 0; std::string response;
|
||||
while (InternetReadFile(hReq, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0)
|
||||
response.append(buffer, bytesRead);
|
||||
|
||||
Debug("POST Response: " + response);
|
||||
InternetCloseHandle(hReq);
|
||||
InternetCloseHandle(hConn);
|
||||
InternetCloseHandle(hNet);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HttpGet(const char* url,
|
||||
std::function<void(const Json&)> onSuccess,
|
||||
std::function<void()> onError)
|
||||
{
|
||||
HINTERNET hInternet = InternetOpenA(
|
||||
"MinecraftWinINet/1.0",
|
||||
INTERNET_OPEN_TYPE_DIRECT,
|
||||
NULL, NULL, 0);
|
||||
|
||||
if (!hInternet)
|
||||
{
|
||||
if (onError) onError();
|
||||
return false;
|
||||
}
|
||||
|
||||
HINTERNET hConnect = InternetOpenUrlA(
|
||||
hInternet,
|
||||
url,
|
||||
NULL,
|
||||
0,
|
||||
INTERNET_FLAG_SECURE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE,
|
||||
0);
|
||||
|
||||
if (!hConnect)
|
||||
{
|
||||
if (onError) onError();
|
||||
InternetCloseHandle(hInternet);
|
||||
return false;
|
||||
}
|
||||
|
||||
char buffer[4096];
|
||||
DWORD bytesRead = 0;
|
||||
std::string response;
|
||||
|
||||
while (InternetReadFile(hConnect, buffer, sizeof(buffer), &bytesRead) && bytesRead > 0)
|
||||
response.append(buffer, bytesRead);
|
||||
|
||||
InternetCloseHandle(hConnect);
|
||||
InternetCloseHandle(hInternet);
|
||||
|
||||
if (response.empty())
|
||||
{
|
||||
if (onError) onError();
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Json parsed = Json::parse(response);
|
||||
onSuccess(parsed);
|
||||
return true;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
if (onError) onError();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include "json.hpp"
|
||||
|
||||
using Json = nlohmann::json;
|
||||
|
||||
bool HttpPost(const char* url, const Json& payload);
|
||||
bool HttpGet(const char* url,
|
||||
std::function<void(const Json&)> onSuccess,
|
||||
std::function<void()> onError = nullptr);
|
||||
@@ -52,6 +52,8 @@
|
||||
#include "Windows64_Xuid.h"
|
||||
#include "Common/UI/UI.h"
|
||||
#include "stb_image_write.h"
|
||||
#include <wininet.h>
|
||||
#pragma comment(lib, "wininet.lib")
|
||||
|
||||
// Forward-declare the internal Renderer class and its global instance from 4J_Render_PC_d.lib.
|
||||
// C4JRender (RenderManager) is a stateless wrapper — all D3D state lives in InternalRenderManager.
|
||||
@@ -116,14 +118,15 @@ int g_iScreenHeight = 1080;
|
||||
|
||||
// Real window dimensions — updated on every WM_SIZE so the 3D perspective
|
||||
// always matches the current window, even after a resize.
|
||||
int g_rScreenWidth = 1920;
|
||||
int g_rScreenHeight = 1080;
|
||||
int g_rScreenWidth = 1280;
|
||||
int g_rScreenHeight = 720;
|
||||
static bool f3ComboUsed = false;
|
||||
|
||||
float g_iAspectRatio = static_cast<float>(g_iScreenWidth) / g_iScreenHeight;
|
||||
static bool g_bResizeReady = false;
|
||||
|
||||
char g_Win64Username[17] = { 0 };
|
||||
char g_LCENToken[512] = { 0 };
|
||||
wchar_t g_Win64UsernameW[17] = { 0 };
|
||||
|
||||
// Fullscreen toggle state
|
||||
@@ -239,6 +242,10 @@ static Win64LaunchOptions ParseLaunchOptions()
|
||||
{
|
||||
CopyWideArgToAnsi(argv[++i], g_Win64Username, sizeof(g_Win64Username));
|
||||
}
|
||||
else if (_wcsicmp(argv[i], L"--lcen-token") == 0 && (i + 1) < argc)
|
||||
{
|
||||
CopyWideArgToAnsi(argv[++i], g_LCENToken, sizeof(g_LCENToken));
|
||||
}
|
||||
else if (_wcsicmp(argv[i], L"-ip") == 0 && (i + 1) < argc)
|
||||
{
|
||||
char ipBuf[256];
|
||||
@@ -1570,6 +1577,57 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||
const Win64LaunchOptions launchOptions = ParseLaunchOptions();
|
||||
ApplyScreenMode(launchOptions.screenMode);
|
||||
|
||||
if (g_LCENToken[0] != '\0')
|
||||
{
|
||||
HINTERNET hNet = InternetOpenA("openLCE", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
if (hNet)
|
||||
{
|
||||
char authHeader[560];
|
||||
_snprintf_s(authHeader, sizeof(authHeader), _TRUNCATE, "Authorization: Bearer %s", g_LCENToken);
|
||||
HINTERNET hReq = InternetOpenUrlA(hNet, "https://network-server-7kuc.onrender.com/auth/validate", authHeader, (DWORD)strlen(authHeader), INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, 0);
|
||||
if (hReq)
|
||||
{
|
||||
char buf[1024] = {};
|
||||
DWORD read = 0;
|
||||
InternetReadFile(hReq, buf, sizeof(buf) - 1, &read);
|
||||
InternetCloseHandle(hReq);
|
||||
if (read > 0)
|
||||
{
|
||||
auto extractField = [](const char* json, const char* key, char* out, size_t outSize) -> bool {
|
||||
char search[64];
|
||||
_snprintf_s(search, sizeof(search), _TRUNCATE, "\"%s\":\"", key);
|
||||
const char* p = strstr(json, search);
|
||||
if (!p) return false;
|
||||
p += strlen(search);
|
||||
const char* end = strchr(p, '"');
|
||||
if (!end) return false;
|
||||
size_t len = min((size_t)(end - p), outSize - 1);
|
||||
strncpy_s(out, outSize, p, len);
|
||||
out[len] = '\0';
|
||||
return true;
|
||||
};
|
||||
char lcenGamertag[64] = {};
|
||||
char lcenXuid[32] = {};
|
||||
bool gotTag = extractField(buf, "gamertag", lcenGamertag, sizeof(lcenGamertag));
|
||||
bool gotXuid = extractField(buf, "xuid", lcenXuid, sizeof(lcenXuid));
|
||||
if (gotTag && lcenGamertag[0] != '\0')
|
||||
{
|
||||
strncpy_s(g_Win64Username, sizeof(g_Win64Username), lcenGamertag, _TRUNCATE);
|
||||
MultiByteToWideChar(CP_ACP, 0, g_Win64Username, -1, g_Win64UsernameW, 17);
|
||||
}
|
||||
if (gotXuid && lcenXuid[0] != '\0')
|
||||
{
|
||||
uint64_t xuidVal = _strtoui64(lcenXuid, nullptr, 16);
|
||||
if (xuidVal != 0)
|
||||
Win64Xuid::WriteUid((PlayerUID)xuidVal);
|
||||
}
|
||||
Win64Xuid::ResolvePersistentXuid(true);
|
||||
}
|
||||
}
|
||||
InternetCloseHandle(hNet);
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure uid.dat exists from startup (before any multiplayer/login path).
|
||||
Win64Xuid::ResolvePersistentXuid();
|
||||
|
||||
|
||||
@@ -209,29 +209,31 @@ namespace Win64Xuid
|
||||
return xuid;
|
||||
}
|
||||
|
||||
inline PlayerUID ResolvePersistentXuid()
|
||||
{
|
||||
// Process-local cache: uid.dat is immutable during runtime and this path is hot.
|
||||
static bool s_cached = false;
|
||||
static PlayerUID s_xuid = INVALID_XUID;
|
||||
inline PlayerUID ResolvePersistentXuid(bool forceReload = false)
|
||||
{
|
||||
static bool s_cached = false;
|
||||
static PlayerUID s_xuid = INVALID_XUID;
|
||||
|
||||
if (s_cached)
|
||||
return s_xuid;
|
||||
if (s_cached && !forceReload)
|
||||
return s_xuid;
|
||||
|
||||
PlayerUID fileXuid = INVALID_XUID;
|
||||
if (ReadUid(&fileXuid))
|
||||
{
|
||||
s_xuid = fileXuid;
|
||||
s_cached = true;
|
||||
return s_xuid;
|
||||
}
|
||||
PlayerUID fileXuid = INVALID_XUID;
|
||||
if (ReadUid(&fileXuid))
|
||||
{
|
||||
s_xuid = fileXuid;
|
||||
s_cached = true;
|
||||
return s_xuid;
|
||||
}
|
||||
|
||||
// First launch on this client: generate once and persist to uid.dat.
|
||||
s_xuid = GeneratePersistentUid();
|
||||
WriteUid(s_xuid);
|
||||
s_cached = true;
|
||||
return s_xuid;
|
||||
}
|
||||
if (!s_cached) // only generate on true first launch, not a failed reload
|
||||
{
|
||||
s_xuid = GeneratePersistentUid();
|
||||
WriteUid(s_xuid);
|
||||
s_cached = true;
|
||||
}
|
||||
return s_xuid;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -7788,4 +7788,166 @@ Alle Endertruhen in einer Welt sind verknüpft, sodass Gegenstände, die in eine
|
||||
<data name="IDS_TOOLTIPS_CURE">
|
||||
<value>Heilen</value>
|
||||
</data>
|
||||
|
||||
<data name="IDS_WINDOWS_EXIT">
|
||||
<value>Minecraft verlassen?</value>
|
||||
</data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_TAKING_INVENTORY"><value>Inventur</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_TAKING_INVENTORY"><value>Öffne dein Inventar.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_GETTING_WOOD"><value>Dreimal auf Holz geklopft</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_GETTING_WOOD"><value>Schlage gegen einen Baum, bis ein Holzblock herausspringt.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_BENCHMARKING"><value>Fortgeschrittenes Handwerk</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_BENCHMARKING"><value>Stell aus vier Blöcken aus Holzbrettern eine Werkbank her.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_TIME_TO_MINE"><value>Glück Auf!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_TIME_TO_MINE"><value>Stell aus Holz und Stöcken eine Spitzhacke her.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_HOT_TOPIC"><value>Heiße Angelegenheit</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_HOT_TOPIC"><value>Stell aus 8 Bruchstein-Blöcken einen Ofen her.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ACQUIRE_HARDWARE"><value>Schmiedekunst</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ACQUIRE_HARDWARE"><value>Schmilz einen Eisenbarren.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_TIME_TO_FARM"><value>Fang an zu ackern!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_TIME_TO_FARM"><value>Stell aus Holz und Stöcken eine Hacke her.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_BAKE_BREAD"><value>Bäcker</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_BAKE_BREAD"><value>Backe ein Brot aus Weizen.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_THE_LIE"><value>Die Lüge</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_THE_LIE"><value>Backe einen Kuchen aus Weizen, Zucker, Milch und Eiern!</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_GETTING_AN_UPGRADE"><value>Technischer Fortschritt</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_GETTING_AN_UPGRADE"><value>Stelle eine bessere Spitzhacke her.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_DELICIOUS_FISH"><value>Köstlicher Fisch</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_DELICIOUS_FISH"><value>Fange und brate einen Fisch!</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ON_A_RAIL"><value>Bahn frei!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ON_A_RAIL"><value>Reise mit einer Lore mindestens 500 Meter in eine Richtung.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_TIME_TO_STRIKE"><value>Zu den Waffen!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_TIME_TO_STRIKE"><value>Stell aus Holz und Stöcken ein Schwert her.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_MONSTER_HUNTER"><value>Monsterjäger</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_MONSTER_HUNTER"><value>Greif ein Monster an und töte es.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_COW_TIPPER"><value>Kuhschubser</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_COW_TIPPER"><value>Gewinne Leder.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_WHEN_PIGS_FLY"><value>Wenn Schweine fliegen</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_WHEN_PIGS_FLY"><value>Reite ein Schwein mit einem Sattel, und füg ihm dann während des Reitens Schaden durch Fallen zu.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_LEADER_OF_THE_PACK"><value>Alphawolf</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_LEADER_OF_THE_PACK"><value>Freunde dich mit fünf Wölfen an.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_MOAR_TOOLS"><value>Bestens ausgerüstet</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_MOAR_TOOLS"><value>Stell ein Exemplar von jedem Werkzeug her (1 Spitzhacke, 1 Spaten, 1 Axt und 1 Hacke).</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_DISPENSE_WITH_THIS"><value>Zum Verschießen</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_DISPENSE_WITH_THIS"><value>Baue einen Spender.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_INTO_THE_NETHER"><value>In den Nether</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_INTO_THE_NETHER"><value>Stell ein Netherportal her.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_EAT_PORKCHOP"><value>Schweinekotelett</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_EAT_PORKCHOP"><value>Koche und iss ein Stück Schweinekotelett.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_PLAY_100_DAYS"><value>Wie die Zeit vergeht</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_PLAY_100_DAYS"><value>Spiele 100 Tage lang.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ARROW_KILL_CREEPER"><value>Bogenschütze</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ARROW_KILL_CREEPER"><value>Töte einen Creeper mit Pfeilen.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_SNIPESKELETON"><value>Scharfschützenduell</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_SNIPESKELETON"><value>Töte ein Skelett mit einem Pfeil aus über 50 Meter Entfernung.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_DIAMONDS"><value>DIAMANTEN!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_DIAMONDS"><value>Beschaffe mithilfe deiner Eisenwerkzeuge Diamanten.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_GHAST"><value>Zurück zum Absender</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_GHAST"><value>Zerstöre einen Ghast mit einem Feuerball.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_BLAZEROD"><value>Spiel mit dem Feuer</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_BLAZEROD"><value>Erleichtere eine Lohe um ihre Rute.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_POTION"><value>Alchemie</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_POTION"><value>Braue einen Trank.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_THE_END"><value>Das Ende?</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_THE_END"><value>Betritt ein Endportal.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_WINGAME"><value>Das Ende.</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_WINGAME"><value>Den Enderdrachen getötet.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ENCHANTMENTS"><value>Zauberer</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ENCHANTMENTS"><value>Baue einen Zaubertisch.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_OVERKILL"><value>Meister des Kampfes</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_OVERKILL"><value>Verursache neun Herzen Schaden mit einem einzigen Schlag.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_BOOKCASE"><value>Bibliothekar</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_BOOKCASE"><value>Baue Bücherregale, um deinen Zaubertisch zu verbessern.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ADVENTURING_TIME"><value>Abenteurerzeit</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ADVENTURING_TIME"><value>Entdecke 17 der 40 Biome.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_REPOPULATION"><value>Nachzucht</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_REPOPULATION"><value>Züchte zwei Kühe mit Weizen.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_DIAMONDS_TO_YOU"><value>Diamanten für dich!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_DIAMONDS_TO_YOU"><value>Wirf mit Diamanten nach einem anderen Spieler.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_THE_HAGGLER"><value>Der Feilscher</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_THE_HAGGLER"><value>Erhalte 30 Smaragde durch Handel mit Dorfbewohnern oder Bergbau.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_POT_PLANTER"><value>Topfbepflanzer</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_POT_PLANTER"><value>Stell einen Blumentopf her und platziere ihn.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ITS_A_SIGN"><value>Schilderwald</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ITS_A_SIGN"><value>Stelle ein Schild her und platziere es.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_IRON_BELLY"><value>Starker Magen</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_IRON_BELLY"><value>Halte den Hungertod mit verrottetem Fleisch auf.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_HAVE_A_SHEARFUL_DAY"><value>Scher dich zum Schaf</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_HAVE_A_SHEARFUL_DAY"><value>Verwende eine Schere, um Wolle von einem Schaf zu erhalten.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_RAINBOW_COLLECTION"><value>Regenbogensammlung</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_RAINBOW_COLLECTION"><value>Sammle Wolle in allen 16 Farben.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_STAYING_FROSTY"><value>Cool bleiben</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_STAYING_FROSTY"><value>Schwimme in Lava, während du den Feuerwiderstand-Effekt hast.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_CHESTFUL_OF_COBBLESTONE"><value>Bruchsteinreich</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_CHESTFUL_OF_COBBLESTONE"><value>Baue 1.728 Bruchsteine ab und lege sie in eine Truhe.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_RENEWABLE_ENERGY"><value>Erneuerbare Energie</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_RENEWABLE_ENERGY"><value>Verkohle Baumstämme mit Holzkohle, um mehr Holzkohle herzustellen.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_MUSIC_TO_MY_EARS"><value>Musik in meinen Ohren</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_MUSIC_TO_MY_EARS"><value>Spiele eine Schallplatte in einem Plattenspieler ab.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_BODYGUARD"><value>Leibwächter</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_BODYGUARD"><value>Erschaffe einen Eisengolem.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_IRON_MAN"><value>Eisenmann</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_IRON_MAN"><value>Trage eine komplette Eisenrüstung.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ZOMBIE_DOCTOR"><value>Zombie-Doktor</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ZOMBIE_DOCTOR"><value>Heile einen Zombie-Dorfbewohner.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_LION_TAMER"><value>Löwenjäger</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_LION_TAMER"><value>Gewinne das Vertrauen eines Ozelots.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVEMENT_VIEW"><value>Halte {*CONTROLLER_VK_Y*} gedrückt</value></data>
|
||||
|
||||
<!-- START LCE Network Specific Strings-->
|
||||
<data name="IDS_CONNECTION_LOST_LCEN"><value>Die Verbindung zu LCEN wurde unterbrochen. Zurück zum Hauptmenü.</value></data>
|
||||
<data name="IDS_LCEN_BANNED"><value>Dein Konto von LCEN wurde gesperrt.</value></data>
|
||||
<data name="IDS_LCEN_NO_CONNECTION"><value>Verbindung zu LCEN wurde verloren.</value></data>
|
||||
<!-- END : LCE Network Specific Strings-->
|
||||
</root>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="IDS_LANG_SYSTEM"> <value>Systemsprache</value> </data>
|
||||
<data name="IDS_LANG_ENGLISH"> <value>Englisch</value> </data>
|
||||
|
||||
<data name="IDS_LANG_GERMAN"> <value>Deutsch</value> </data>
|
||||
|
||||
<data name="IDS_LANG_SPANISH"> <value>Spanisch</value> </data>
|
||||
<data name="IDS_LANG_SPANISH_SPAIN"> <value>Spanisch (Spanien)</value> </data>
|
||||
<data name="IDS_LANG_SPANISH_LATIN_AMERICA"> <value>Spanisch (Lateinamerika)</value> </data>
|
||||
|
||||
<data name="IDS_LANG_FRENCH"> <value>Französisch</value> </data>
|
||||
|
||||
<data name="IDS_LANG_ITALIAN"> <value>Italienisch</value> </data>
|
||||
|
||||
<data name="IDS_LANG_PORTUGUESE"> <value>Portugiesisch</value> </data>
|
||||
<data name="IDS_LANG_PORTUGUESE_PORTUGAL"> <value>Portugiesisch (Portugal)</value> </data>
|
||||
<data name="IDS_LANG_PORTUGUESE_BRAZIL"> <value>Portugiesisch (Brasilien)</value> </data>
|
||||
|
||||
<data name="IDS_LANG_JAPANESE"> <value>Japanisch</value> </data>
|
||||
|
||||
<data name="IDS_LANG_KOREAN"> <value>Koreanisch</value> </data>
|
||||
|
||||
<data name="IDS_LANG_CHINESE_TRADITIONAL"> <value>Chinesisch (Traditionell)</value> </data>
|
||||
<data name="IDS_LANG_CHINESE_SIMPLIFIED"> <value>Chinesisch (Vereinfacht)</value> </data>
|
||||
|
||||
<data name="IDS_LANG_DANISH"> <value>Dänisch</value> </data>
|
||||
<data name="IDS_LANG_FINISH"> <value>Finnisch</value> </data>
|
||||
|
||||
<data name="IDS_LANG_DUTCH"> <value>Niederländisch</value> </data>
|
||||
|
||||
<data name="IDS_LANG_POLISH"> <value>Polnisch</value> </data>
|
||||
<data name="IDS_LANG_RUSSIAN"> <value>Russisch</value> </data>
|
||||
<data name="IDS_LANG_SWEDISH"> <value>Schwedisch</value> </data>
|
||||
<data name="IDS_LANG_NORWEGIAN"> <value>Norwegisch</value> </data>
|
||||
|
||||
<data name="IDS_LANG_GREEK"> <value>Griechisch</value> </data>
|
||||
|
||||
<data name="IDS_LANG_TURKISH"> <value>Türkisch</value> </data>
|
||||
</root>
|
||||
@@ -1,47 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<data name="IDS_LEADERBOARD_KILLS_EASY">
|
||||
<value>Kills Easy</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_KILLS_NORMAL">
|
||||
<value>Kills Normal</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_KILLS_HARD">
|
||||
<value>Kills Hard</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_MINING_BLOCKS_PEACEFUL">
|
||||
<value>Mining Blocks Peaceful</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_MINING_BLOCKS_EASY">
|
||||
<value>Mining Blocks Easy</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_MINING_BLOCKS_NORMAL">
|
||||
<value>Mining Blocks Normal</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_MINING_BLOCKS_HARD">
|
||||
<value>Mining Blocks Hard</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_FARMING_PEACEFUL">
|
||||
<value>Farming Peaceful</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_FARMING_EASY">
|
||||
<value>Farming Easy</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_FARMING_NORMAL">
|
||||
<value>Farming Normal</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_FARMING_HARD">
|
||||
<value>Farming Hard</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_TRAVELLING_PEACEFUL">
|
||||
<value>Traveling Peaceful</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_TRAVELLING_EASY">
|
||||
<value>Traveling Easy</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_TRAVELLING_NORMAL">
|
||||
<value>Traveling Normal</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_TRAVELLING_HARD">
|
||||
<value>Traveling Hard</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_KILLS_EASY">
|
||||
<value>Tötungen (leicht)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_KILLS_NORMAL">
|
||||
<value>Tötungen (normal)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_KILLS_HARD">
|
||||
<value>Tötungen (schwierig)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_MINING_BLOCKS_PEACEFUL">
|
||||
<value>Blöcke abbauen (friedlich)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_MINING_BLOCKS_EASY">
|
||||
<value>Blöcke abbauen (leicht)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_MINING_BLOCKS_NORMAL">
|
||||
<value>Blöcke abbauen (normal)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_MINING_BLOCKS_HARD">
|
||||
<value>Blöcke abbauen (schwierig)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_FARMING_PEACEFUL">
|
||||
<value>Landwirtschaft (friedlich)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_FARMING_EASY">
|
||||
<value>Landwirtschaft (leicht)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_FARMING_NORMAL">
|
||||
<value>Landwirtschaft (normal)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_FARMING_HARD">
|
||||
<value>Landwirtschaft (schwierig)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_TRAVELLING_PEACEFUL">
|
||||
<value>Reisen (friedlich)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_TRAVELLING_EASY">
|
||||
<value>Reisen (leicht)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_TRAVELLING_NORMAL">
|
||||
<value>Reisen (normal)</value>
|
||||
</data>
|
||||
<data name="IDS_LEADERBOARD_TRAVELLING_HARD">
|
||||
<value>Reisen (schwierig)</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -8814,4 +8814,162 @@ All Ender Chests in a world are linked. Items placed into an Ender Chest are acc
|
||||
<data name="IDS_WINDOWS_EXIT">
|
||||
<value>Exit Minecraft</value>
|
||||
</data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_TAKING_INVENTORY"><value>Taking Inventory</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_TAKING_INVENTORY"><value>Open your inventory.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_GETTING_WOOD"><value>Getting Wood</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_GETTING_WOOD"><value>Punch a tree until a block of wood pops out.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_BENCHMARKING"><value>Benchmarking</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_BENCHMARKING"><value>Craft a Workbench with four blocks of Wooden Planks.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_TIME_TO_MINE"><value>Time to Mine!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_TIME_TO_MINE"><value>Use Planks and Sticks to make a Pickaxe.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_HOT_TOPIC"><value>Hot Topic</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_HOT_TOPIC"><value>Construct a Furnace out of eight Cobblestone blocks.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ACQUIRE_HARDWARE"><value>Acquire Hardware</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ACQUIRE_HARDWARE"><value>Smelt an Iron Ingot.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_TIME_TO_FARM"><value>Time to Farm!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_TIME_TO_FARM"><value>Make a Hoe.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_BAKE_BREAD"><value>Bake Bread</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_BAKE_BREAD"><value>Turn Wheat into Bread.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_THE_LIE"><value>The Lie</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_THE_LIE"><value>Bake a Cake using: Wheat, Sugar, Milk and Eggs.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_GETTING_AN_UPGRADE"><value>Getting an Upgrade</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_GETTING_AN_UPGRADE"><value>Construct a better pickaxe.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_DELICIOUS_FISH"><value>Delicious Fish</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_DELICIOUS_FISH"><value>Catch and cook Fish!</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ON_A_RAIL"><value>On A Rail</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ON_A_RAIL"><value>Travel by Minecart to a point at least 500m in a single direction from where you started.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_TIME_TO_STRIKE"><value>Time to Strike!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_TIME_TO_STRIKE"><value>Use Planks and Sticks to make a Sword.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_MONSTER_HUNTER"><value>Monster Hunter</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_MONSTER_HUNTER"><value>Attack and destroy a monster.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_COW_TIPPER"><value>Cow Tipper</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_COW_TIPPER"><value>Harvest some leather.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_WHEN_PIGS_FLY"><value>When Pigs Fly</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_WHEN_PIGS_FLY"><value>Use a Saddle to ride a Pig, and then have the Pig get hurt from fall damage while riding it.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_LEADER_OF_THE_PACK"><value>Leader of the Pack</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_LEADER_OF_THE_PACK"><value>Befriend five Wolves.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_MOAR_TOOLS"><value>MOAR Tools</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_MOAR_TOOLS"><value>Construct one type of each tool.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_DISPENSE_WITH_THIS"><value>Dispense With This</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_DISPENSE_WITH_THIS"><value>Construct a dispenser.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_INTO_THE_NETHER"><value>Into The Nether</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_INTO_THE_NETHER"><value>Construct a Nether Portal.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_EAT_PORKCHOP"><value>Pork Chop</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_EAT_PORKCHOP"><value>Cook and eat a Pork Chop.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_PLAY_100_DAYS"><value>Passing the Time</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_PLAY_100_DAYS"><value>Play for 100 days.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ARROW_KILL_CREEPER"><value>Archer</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ARROW_KILL_CREEPER"><value>Kill a Creeper with Arrows.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_SNIPESKELETON"><value>Sniper Duel</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_SNIPESKELETON"><value>Kill a Skeleton with an Arrow from more than 50 meters.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_DIAMONDS"><value>DIAMONDS!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_DIAMONDS"><value>Acquire diamonds with your iron tools.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_GHAST"><value>Return to Sender</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_GHAST"><value>Destroy a Ghast with a Fireball.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_BLAZEROD"><value>Into Fire</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_BLAZEROD"><value>Relieve a Blaze of its rod.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_POTION"><value>Local Brewery</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_POTION"><value>Brew a potion.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_THE_END"><value>The End?</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_THE_END"><value>Enter an End Portal.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_WINGAME"><value>The End.</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_WINGAME"><value>Kill the Enderdragon.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ENCHANTMENTS"><value>Enchanter</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ENCHANTMENTS"><value>Construct an Enchantment Table.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_OVERKILL"><value>Overkill</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_OVERKILL"><value>Deal nine hearts of damage in a single hit.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_BOOKCASE"><value>Librarian</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_BOOKCASE"><value>Build some Bookshelves to improve your Enchantment Table.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ADVENTURING_TIME"><value>Adventuring Time</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ADVENTURING_TIME"><value>Discover all biomes.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_REPOPULATION"><value>Repopulation</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_REPOPULATION"><value>Breed two Cows with Wheat.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_DIAMONDS_TO_YOU"><value>Diamonds to you!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_DIAMONDS_TO_YOU"><value>Throw diamonds to another player.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_THE_HAGGLER"><value>The Haggler</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_THE_HAGGLER"><value>Mine or purchase 30 Emeralds.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_POT_PLANTER"><value>Pot Planter</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_POT_PLANTER"><value>Craft and place a Flower pot.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ITS_A_SIGN"><value>It's a Sign!</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ITS_A_SIGN"><value>Craft and place a sign.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_IRON_BELLY"><value>Iron Belly</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_IRON_BELLY"><value>Stop starvation using rotten flesh.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_HAVE_A_SHEARFUL_DAY"><value>Have a Shearful Day</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_HAVE_A_SHEARFUL_DAY"><value>Use Shears to obtain Wool from a Sheep.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_RAINBOW_COLLECTION"><value>Rainbow Collection</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_RAINBOW_COLLECTION"><value>Gather all 16 colors of Wool.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_STAYING_FROSTY"><value>Stayin' Frosty</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_STAYING_FROSTY"><value>Swim in Lava while having the Fire Resistance effect.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_CHESTFUL_OF_COBBLESTONE"><value>Chestful of Cobblestone</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_CHESTFUL_OF_COBBLESTONE"><value>Mine 1,728 Cobblestone and place it in a Chest.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_RENEWABLE_ENERGY"><value>Renewable Energy</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_RENEWABLE_ENERGY"><value>Smelt Wood Trunks using Charcoal to make more Charcoal.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_MUSIC_TO_MY_EARS"><value>Music to my Ears</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_MUSIC_TO_MY_EARS"><value>Play a Music Disc in a Jukebox.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_BODYGUARD"><value>Body Guard</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_BODYGUARD"><value>Create an Iron Golem.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_IRON_MAN"><value>Iron Man</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_IRON_MAN"><value>Wear a full suit of Iron Armor.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_ZOMBIE_DOCTOR"><value>Zombie Doctor</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_ZOMBIE_DOCTOR"><value>Cure a Zombie Villager.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVE_NAME_LION_TAMER"><value>Lion Tamer</value></data>
|
||||
<data name="IDS_ACHIEVE_DESC_LION_TAMER"><value>Tame an ocelot.</value></data>
|
||||
|
||||
<data name="IDS_ACHIEVEMENT_VIEW"><value>Hold {*CONTROLLER_VK_Y*} to view</value></data>
|
||||
|
||||
<!-- START LCE Network Specific Strings-->
|
||||
<data name="IDS_CONNECTION_LOST_LCEN"><value>Connection to the LCE Network has been lost. Exiting to the main menu.</value></data>
|
||||
<data name="IDS_LCEN_BANNED"><value>You have been banned from the LCE Network.</value></data>
|
||||
<data name="IDS_LCEN_NO_CONNECTION"><value>Could not connect to the LCE Network.</value></data>
|
||||
<!-- END : LCE Network Specific Strings-->
|
||||
</root>
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
// Auto-generated by StringTable builder — do not edit manually.
|
||||
// Source language: en-US
|
||||
// Total strings: 2287
|
||||
// Total strings: 2391
|
||||
|
||||
#define IDS_NULL 0
|
||||
#define IDS_OK 1
|
||||
@@ -2166,135 +2166,231 @@
|
||||
#define IDS_CONNECTION_FAILED_NO_SD_SPLITSCREEN 2160
|
||||
#define IDS_TOOLTIPS_CURE 2161
|
||||
#define IDS_WINDOWS_EXIT 2162
|
||||
#define IDS_LANG_SYSTEM 2163
|
||||
#define IDS_LANG_ENGLISH 2164
|
||||
#define IDS_LANG_GERMAN 2165
|
||||
#define IDS_LANG_SPANISH 2166
|
||||
#define IDS_LANG_SPANISH_SPAIN 2167
|
||||
#define IDS_LANG_SPANISH_LATIN_AMERICA 2168
|
||||
#define IDS_LANG_FRENCH 2169
|
||||
#define IDS_LANG_ITALIAN 2170
|
||||
#define IDS_LANG_PORTUGUESE 2171
|
||||
#define IDS_LANG_PORTUGUESE_PORTUGAL 2172
|
||||
#define IDS_LANG_PORTUGUESE_BRAZIL 2173
|
||||
#define IDS_LANG_JAPANESE 2174
|
||||
#define IDS_LANG_KOREAN 2175
|
||||
#define IDS_LANG_CHINESE_TRADITIONAL 2176
|
||||
#define IDS_LANG_CHINESE_SIMPLIFIED 2177
|
||||
#define IDS_LANG_DANISH 2178
|
||||
#define IDS_LANG_FINISH 2179
|
||||
#define IDS_LANG_DUTCH 2180
|
||||
#define IDS_LANG_POLISH 2181
|
||||
#define IDS_LANG_RUSSIAN 2182
|
||||
#define IDS_LANG_SWEDISH 2183
|
||||
#define IDS_LANG_NORWEGIAN 2184
|
||||
#define IDS_LANG_GREEK 2185
|
||||
#define IDS_LANG_TURKISH 2186
|
||||
#define IDS_LEADERBOARD_KILLS_EASY 2187
|
||||
#define IDS_LEADERBOARD_KILLS_NORMAL 2188
|
||||
#define IDS_LEADERBOARD_KILLS_HARD 2189
|
||||
#define IDS_LEADERBOARD_MINING_BLOCKS_PEACEFUL 2190
|
||||
#define IDS_LEADERBOARD_MINING_BLOCKS_EASY 2191
|
||||
#define IDS_LEADERBOARD_MINING_BLOCKS_NORMAL 2192
|
||||
#define IDS_LEADERBOARD_MINING_BLOCKS_HARD 2193
|
||||
#define IDS_LEADERBOARD_FARMING_PEACEFUL 2194
|
||||
#define IDS_LEADERBOARD_FARMING_EASY 2195
|
||||
#define IDS_LEADERBOARD_FARMING_NORMAL 2196
|
||||
#define IDS_LEADERBOARD_FARMING_HARD 2197
|
||||
#define IDS_LEADERBOARD_TRAVELLING_PEACEFUL 2198
|
||||
#define IDS_LEADERBOARD_TRAVELLING_EASY 2199
|
||||
#define IDS_LEADERBOARD_TRAVELLING_NORMAL 2200
|
||||
#define IDS_LEADERBOARD_TRAVELLING_HARD 2201
|
||||
#define IDS_TIPS_GAMETIP_0 2202
|
||||
#define IDS_TIPS_GAMETIP_1 2203
|
||||
#define IDS_TIPS_GAMETIP_48 2204
|
||||
#define IDS_TIPS_GAMETIP_44 2205
|
||||
#define IDS_TIPS_GAMETIP_45 2206
|
||||
#define IDS_TIPS_TRIVIA_4 2207
|
||||
#define IDS_TIPS_TRIVIA_17 2208
|
||||
#define IDS_HOW_TO_PLAY_MULTIPLAYER 2209
|
||||
#define IDS_HOW_TO_PLAY_SOCIALMEDIA 2210
|
||||
#define IDS_HOW_TO_PLAY_CREATIVE 2211
|
||||
#define IDS_TUTORIAL_TASK_FLY 2212
|
||||
#define IDS_TOOLTIPS_SELECTDEVICE 2213
|
||||
#define IDS_TOOLTIPS_CHANGEDEVICE 2214
|
||||
#define IDS_TOOLTIPS_VIEW_GAMERCARD 2215
|
||||
#define IDS_TOOLTIPS_VIEW_GAMERPROFILE 2216
|
||||
#define IDS_TOOLTIPS_INVITE_PARTY 2217
|
||||
#define IDS_CONFIRM_START_CREATIVE 2218
|
||||
#define IDS_CONFIRM_START_SAVEDINCREATIVE 2219
|
||||
#define IDS_CONFIRM_START_SAVEDINCREATIVE_CONTINUE 2220
|
||||
#define IDS_CONFIRM_START_HOST_PRIVILEGES 2221
|
||||
#define IDS_CONNECTION_LOST_LIVE 2222
|
||||
#define IDS_CONNECTION_LOST_LIVE_NO_EXIT 2223
|
||||
#define IDS_AWARD_AVATAR1 2224
|
||||
#define IDS_AWARD_AVATAR2 2225
|
||||
#define IDS_AWARD_AVATAR3 2226
|
||||
#define IDS_AWARD_THEME 2227
|
||||
#define IDS_UNLOCK_ACHIEVEMENT_TEXT 2228
|
||||
#define IDS_UNLOCK_AVATAR_TEXT 2229
|
||||
#define IDS_UNLOCK_GAMERPIC_TEXT 2230
|
||||
#define IDS_UNLOCK_THEME_TEXT 2231
|
||||
#define IDS_UNLOCK_ACCEPT_INVITE 2232
|
||||
#define IDS_UNLOCK_GUEST_TEXT 2233
|
||||
#define IDS_LEADERBOARD_GAMERTAG 2234
|
||||
#define IDS_GROUPNAME_POTIONS_480 2235
|
||||
#define IDS_RETURNEDTOTITLESCREEN_TEXT 2236
|
||||
#define IDS_TRIALOVER_TEXT 2237
|
||||
#define IDS_FATAL_ERROR_TEXT 2238
|
||||
#define IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT 2239
|
||||
#define IDS_NO_MULTIPLAYER_PRIVILEGE_HOST_TEXT 2240
|
||||
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL 2241
|
||||
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL 2242
|
||||
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE 2243
|
||||
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_CREATE 2244
|
||||
#define IDS_SAVE_ICON_MESSAGE 2245
|
||||
#define IDS_GAMEOPTION_HOST_PRIVILEGES 2246
|
||||
#define IDS_CHECKBOX_DISPLAY_SPLITSCREENGAMERTAGS 2247
|
||||
#define IDS_ACHIEVEMENTS 2248
|
||||
#define IDS_LABEL_GAMERTAGS 2249
|
||||
#define IDS_IN_GAME_GAMERTAGS 2250
|
||||
#define IDS_SOCIAL_DEFAULT_DESCRIPTION 2251
|
||||
#define IDS_TITLE_UPDATE_NAME 2252
|
||||
#define IDS_PLATFORM_NAME 2253
|
||||
#define IDS_BACK_BUTTON 2254
|
||||
#define IDS_HOST_OPTION_DISABLES_ACHIEVEMENTS 2255
|
||||
#define IDS_KICK_PLAYER_DESCRIPTION 2256
|
||||
#define IDS_USING_TRIAL_TEXUREPACK_WARNING 2257
|
||||
#define IDS_WORLD_SIZE_TITLE_SMALL 2258
|
||||
#define IDS_WORLD_SIZE_TITLE_MEDIUM 2259
|
||||
#define IDS_WORLD_SIZE_TITLE_LARGE 2260
|
||||
#define IDS_WORLD_SIZE_TITLE_CLASSIC 2261
|
||||
#define IDS_WORLD_SIZE 2262
|
||||
#define IDS_GAMEOPTION_WORLD_SIZE 2263
|
||||
#define IDS_DISABLE_SAVING 2264
|
||||
#define IDS_GAMEOPTION_DISABLE_SAVING 2265
|
||||
#define IDS_RICHPRESENCE_GAMESTATE 2266
|
||||
#define IDS_RICHPRESENCE_IDLE 2267
|
||||
#define IDS_RICHPRESENCE_MENUS 2268
|
||||
#define IDS_RICHPRESENCE_MULTIPLAYER 2269
|
||||
#define IDS_RICHPRESENCE_MULTIPLAYEROFFLINE 2270
|
||||
#define IDS_RICHPRESENCE_MULTIPLAYER_1P 2271
|
||||
#define IDS_RICHPRESENCE_MULTIPLAYER_1POFFLINE 2272
|
||||
#define IDS_RICHPRESENCESTATE_BLANK 2273
|
||||
#define IDS_RICHPRESENCESTATE_RIDING_PIG 2274
|
||||
#define IDS_RICHPRESENCESTATE_RIDING_MINECART 2275
|
||||
#define IDS_RICHPRESENCESTATE_BOATING 2276
|
||||
#define IDS_RICHPRESENCESTATE_FISHING 2277
|
||||
#define IDS_RICHPRESENCESTATE_CRAFTING 2278
|
||||
#define IDS_RICHPRESENCESTATE_FORGING 2279
|
||||
#define IDS_RICHPRESENCESTATE_NETHER 2280
|
||||
#define IDS_RICHPRESENCESTATE_CD 2281
|
||||
#define IDS_RICHPRESENCESTATE_MAP 2282
|
||||
#define IDS_RICHPRESENCESTATE_ENCHANTING 2283
|
||||
#define IDS_RICHPRESENCESTATE_BREWING 2284
|
||||
#define IDS_RICHPRESENCESTATE_ANVIL 2285
|
||||
#define IDS_RICHPRESENCESTATE_TRADING 2286
|
||||
#define IDS_GAMEMODE_HARDCORE 2287
|
||||
#define IDS_HARDCORE 2288
|
||||
#define IDS_HARDCORE_TOOLTIP 2289
|
||||
#define IDS_HARDCORE_WARNING_TITLE 2290
|
||||
#define IDS_HARDCORE_WARNING_TEXT 2291
|
||||
#define IDS_HARDCORE_DEATH_MESSAGE 2292
|
||||
#define IDS_LABEL_HARDCORE 2293
|
||||
#define IDS_GAMEOPTION_HARDCORE 2294
|
||||
#define IDS_ACHIEVE_NAME_TAKING_INVENTORY 2163
|
||||
#define IDS_ACHIEVE_DESC_TAKING_INVENTORY 2164
|
||||
#define IDS_ACHIEVE_NAME_GETTING_WOOD 2165
|
||||
#define IDS_ACHIEVE_DESC_GETTING_WOOD 2166
|
||||
#define IDS_ACHIEVE_NAME_BENCHMARKING 2167
|
||||
#define IDS_ACHIEVE_DESC_BENCHMARKING 2168
|
||||
#define IDS_ACHIEVE_NAME_TIME_TO_MINE 2169
|
||||
#define IDS_ACHIEVE_DESC_TIME_TO_MINE 2170
|
||||
#define IDS_ACHIEVE_NAME_HOT_TOPIC 2171
|
||||
#define IDS_ACHIEVE_DESC_HOT_TOPIC 2172
|
||||
#define IDS_ACHIEVE_NAME_ACQUIRE_HARDWARE 2173
|
||||
#define IDS_ACHIEVE_DESC_ACQUIRE_HARDWARE 2174
|
||||
#define IDS_ACHIEVE_NAME_TIME_TO_FARM 2175
|
||||
#define IDS_ACHIEVE_DESC_TIME_TO_FARM 2176
|
||||
#define IDS_ACHIEVE_NAME_BAKE_BREAD 2177
|
||||
#define IDS_ACHIEVE_DESC_BAKE_BREAD 2178
|
||||
#define IDS_ACHIEVE_NAME_THE_LIE 2179
|
||||
#define IDS_ACHIEVE_DESC_THE_LIE 2180
|
||||
#define IDS_ACHIEVE_NAME_GETTING_AN_UPGRADE 2181
|
||||
#define IDS_ACHIEVE_DESC_GETTING_AN_UPGRADE 2182
|
||||
#define IDS_ACHIEVE_NAME_DELICIOUS_FISH 2183
|
||||
#define IDS_ACHIEVE_DESC_DELICIOUS_FISH 2184
|
||||
#define IDS_ACHIEVE_NAME_ON_A_RAIL 2185
|
||||
#define IDS_ACHIEVE_DESC_ON_A_RAIL 2186
|
||||
#define IDS_ACHIEVE_NAME_TIME_TO_STRIKE 2187
|
||||
#define IDS_ACHIEVE_DESC_TIME_TO_STRIKE 2188
|
||||
#define IDS_ACHIEVE_NAME_MONSTER_HUNTER 2189
|
||||
#define IDS_ACHIEVE_DESC_MONSTER_HUNTER 2190
|
||||
#define IDS_ACHIEVE_NAME_COW_TIPPER 2191
|
||||
#define IDS_ACHIEVE_DESC_COW_TIPPER 2192
|
||||
#define IDS_ACHIEVE_NAME_WHEN_PIGS_FLY 2193
|
||||
#define IDS_ACHIEVE_DESC_WHEN_PIGS_FLY 2194
|
||||
#define IDS_ACHIEVE_NAME_LEADER_OF_THE_PACK 2195
|
||||
#define IDS_ACHIEVE_DESC_LEADER_OF_THE_PACK 2196
|
||||
#define IDS_ACHIEVE_NAME_MOAR_TOOLS 2197
|
||||
#define IDS_ACHIEVE_DESC_MOAR_TOOLS 2198
|
||||
#define IDS_ACHIEVE_NAME_DISPENSE_WITH_THIS 2199
|
||||
#define IDS_ACHIEVE_DESC_DISPENSE_WITH_THIS 2200
|
||||
#define IDS_ACHIEVE_NAME_INTO_THE_NETHER 2201
|
||||
#define IDS_ACHIEVE_DESC_INTO_THE_NETHER 2202
|
||||
#define IDS_ACHIEVE_NAME_EAT_PORKCHOP 2203
|
||||
#define IDS_ACHIEVE_DESC_EAT_PORKCHOP 2204
|
||||
#define IDS_ACHIEVE_NAME_PLAY_100_DAYS 2205
|
||||
#define IDS_ACHIEVE_DESC_PLAY_100_DAYS 2206
|
||||
#define IDS_ACHIEVE_NAME_ARROW_KILL_CREEPER 2207
|
||||
#define IDS_ACHIEVE_DESC_ARROW_KILL_CREEPER 2208
|
||||
#define IDS_ACHIEVE_NAME_SNIPESKELETON 2209
|
||||
#define IDS_ACHIEVE_DESC_SNIPESKELETON 2210
|
||||
#define IDS_ACHIEVE_NAME_DIAMONDS 2211
|
||||
#define IDS_ACHIEVE_DESC_DIAMONDS 2212
|
||||
#define IDS_ACHIEVE_NAME_GHAST 2213
|
||||
#define IDS_ACHIEVE_DESC_GHAST 2214
|
||||
#define IDS_ACHIEVE_NAME_BLAZEROD 2215
|
||||
#define IDS_ACHIEVE_DESC_BLAZEROD 2216
|
||||
#define IDS_ACHIEVE_NAME_POTION 2217
|
||||
#define IDS_ACHIEVE_DESC_POTION 2218
|
||||
#define IDS_ACHIEVE_NAME_THE_END 2219
|
||||
#define IDS_ACHIEVE_DESC_THE_END 2220
|
||||
#define IDS_ACHIEVE_NAME_WINGAME 2221
|
||||
#define IDS_ACHIEVE_DESC_WINGAME 2222
|
||||
#define IDS_ACHIEVE_NAME_ENCHANTMENTS 2223
|
||||
#define IDS_ACHIEVE_DESC_ENCHANTMENTS 2224
|
||||
#define IDS_ACHIEVE_NAME_OVERKILL 2225
|
||||
#define IDS_ACHIEVE_DESC_OVERKILL 2226
|
||||
#define IDS_ACHIEVE_NAME_BOOKCASE 2227
|
||||
#define IDS_ACHIEVE_DESC_BOOKCASE 2228
|
||||
#define IDS_ACHIEVE_NAME_ADVENTURING_TIME 2229
|
||||
#define IDS_ACHIEVE_DESC_ADVENTURING_TIME 2230
|
||||
#define IDS_ACHIEVE_NAME_REPOPULATION 2231
|
||||
#define IDS_ACHIEVE_DESC_REPOPULATION 2232
|
||||
#define IDS_ACHIEVE_NAME_DIAMONDS_TO_YOU 2233
|
||||
#define IDS_ACHIEVE_DESC_DIAMONDS_TO_YOU 2234
|
||||
#define IDS_ACHIEVE_NAME_THE_HAGGLER 2235
|
||||
#define IDS_ACHIEVE_DESC_THE_HAGGLER 2236
|
||||
#define IDS_ACHIEVE_NAME_POT_PLANTER 2237
|
||||
#define IDS_ACHIEVE_DESC_POT_PLANTER 2238
|
||||
#define IDS_ACHIEVE_NAME_ITS_A_SIGN 2239
|
||||
#define IDS_ACHIEVE_DESC_ITS_A_SIGN 2240
|
||||
#define IDS_ACHIEVE_NAME_IRON_BELLY 2241
|
||||
#define IDS_ACHIEVE_DESC_IRON_BELLY 2242
|
||||
#define IDS_ACHIEVE_NAME_HAVE_A_SHEARFUL_DAY 2243
|
||||
#define IDS_ACHIEVE_DESC_HAVE_A_SHEARFUL_DAY 2244
|
||||
#define IDS_ACHIEVE_NAME_RAINBOW_COLLECTION 2245
|
||||
#define IDS_ACHIEVE_DESC_RAINBOW_COLLECTION 2246
|
||||
#define IDS_ACHIEVE_NAME_STAYING_FROSTY 2247
|
||||
#define IDS_ACHIEVE_DESC_STAYING_FROSTY 2248
|
||||
#define IDS_ACHIEVE_NAME_CHESTFUL_OF_COBBLESTONE 2249
|
||||
#define IDS_ACHIEVE_DESC_CHESTFUL_OF_COBBLESTONE 2250
|
||||
#define IDS_ACHIEVE_NAME_RENEWABLE_ENERGY 2251
|
||||
#define IDS_ACHIEVE_DESC_RENEWABLE_ENERGY 2252
|
||||
#define IDS_ACHIEVE_NAME_MUSIC_TO_MY_EARS 2253
|
||||
#define IDS_ACHIEVE_DESC_MUSIC_TO_MY_EARS 2254
|
||||
#define IDS_ACHIEVE_NAME_BODYGUARD 2255
|
||||
#define IDS_ACHIEVE_DESC_BODYGUARD 2256
|
||||
#define IDS_ACHIEVE_NAME_IRON_MAN 2257
|
||||
#define IDS_ACHIEVE_DESC_IRON_MAN 2258
|
||||
#define IDS_ACHIEVE_NAME_ZOMBIE_DOCTOR 2259
|
||||
#define IDS_ACHIEVE_DESC_ZOMBIE_DOCTOR 2260
|
||||
#define IDS_ACHIEVE_NAME_LION_TAMER 2261
|
||||
#define IDS_ACHIEVE_DESC_LION_TAMER 2262
|
||||
#define IDS_ACHIEVEMENT_VIEW 2263
|
||||
#define IDS_CONNECTION_LOST_LCEN 2264
|
||||
#define IDS_LCEN_BANNED 2265
|
||||
#define IDS_LCEN_NO_CONNECTION 2266
|
||||
#define IDS_LANG_SYSTEM 2267
|
||||
#define IDS_LANG_ENGLISH 2268
|
||||
#define IDS_LANG_GERMAN 2269
|
||||
#define IDS_LANG_SPANISH 2270
|
||||
#define IDS_LANG_SPANISH_SPAIN 2271
|
||||
#define IDS_LANG_SPANISH_LATIN_AMERICA 2272
|
||||
#define IDS_LANG_FRENCH 2273
|
||||
#define IDS_LANG_ITALIAN 2274
|
||||
#define IDS_LANG_PORTUGUESE 2275
|
||||
#define IDS_LANG_PORTUGUESE_PORTUGAL 2276
|
||||
#define IDS_LANG_PORTUGUESE_BRAZIL 2277
|
||||
#define IDS_LANG_JAPANESE 2278
|
||||
#define IDS_LANG_KOREAN 2279
|
||||
#define IDS_LANG_CHINESE_TRADITIONAL 2280
|
||||
#define IDS_LANG_CHINESE_SIMPLIFIED 2281
|
||||
#define IDS_LANG_DANISH 2282
|
||||
#define IDS_LANG_FINISH 2283
|
||||
#define IDS_LANG_DUTCH 2284
|
||||
#define IDS_LANG_POLISH 2285
|
||||
#define IDS_LANG_RUSSIAN 2286
|
||||
#define IDS_LANG_SWEDISH 2287
|
||||
#define IDS_LANG_NORWEGIAN 2288
|
||||
#define IDS_LANG_GREEK 2289
|
||||
#define IDS_LANG_TURKISH 2290
|
||||
#define IDS_LEADERBOARD_KILLS_EASY 2291
|
||||
#define IDS_LEADERBOARD_KILLS_NORMAL 2292
|
||||
#define IDS_LEADERBOARD_KILLS_HARD 2293
|
||||
#define IDS_LEADERBOARD_MINING_BLOCKS_PEACEFUL 2294
|
||||
#define IDS_LEADERBOARD_MINING_BLOCKS_EASY 2295
|
||||
#define IDS_LEADERBOARD_MINING_BLOCKS_NORMAL 2296
|
||||
#define IDS_LEADERBOARD_MINING_BLOCKS_HARD 2297
|
||||
#define IDS_LEADERBOARD_FARMING_PEACEFUL 2298
|
||||
#define IDS_LEADERBOARD_FARMING_EASY 2299
|
||||
#define IDS_LEADERBOARD_FARMING_NORMAL 2300
|
||||
#define IDS_LEADERBOARD_FARMING_HARD 2301
|
||||
#define IDS_LEADERBOARD_TRAVELLING_PEACEFUL 2302
|
||||
#define IDS_LEADERBOARD_TRAVELLING_EASY 2303
|
||||
#define IDS_LEADERBOARD_TRAVELLING_NORMAL 2304
|
||||
#define IDS_LEADERBOARD_TRAVELLING_HARD 2305
|
||||
#define IDS_TIPS_GAMETIP_0 2306
|
||||
#define IDS_TIPS_GAMETIP_1 2307
|
||||
#define IDS_TIPS_GAMETIP_48 2308
|
||||
#define IDS_TIPS_GAMETIP_44 2309
|
||||
#define IDS_TIPS_GAMETIP_45 2310
|
||||
#define IDS_TIPS_TRIVIA_4 2311
|
||||
#define IDS_TIPS_TRIVIA_17 2312
|
||||
#define IDS_HOW_TO_PLAY_MULTIPLAYER 2313
|
||||
#define IDS_HOW_TO_PLAY_SOCIALMEDIA 2314
|
||||
#define IDS_HOW_TO_PLAY_CREATIVE 2315
|
||||
#define IDS_TUTORIAL_TASK_FLY 2316
|
||||
#define IDS_TOOLTIPS_SELECTDEVICE 2317
|
||||
#define IDS_TOOLTIPS_CHANGEDEVICE 2318
|
||||
#define IDS_TOOLTIPS_VIEW_GAMERCARD 2319
|
||||
#define IDS_TOOLTIPS_VIEW_GAMERPROFILE 2320
|
||||
#define IDS_TOOLTIPS_INVITE_PARTY 2321
|
||||
#define IDS_CONFIRM_START_CREATIVE 2322
|
||||
#define IDS_CONFIRM_START_SAVEDINCREATIVE 2323
|
||||
#define IDS_CONFIRM_START_SAVEDINCREATIVE_CONTINUE 2324
|
||||
#define IDS_CONFIRM_START_HOST_PRIVILEGES 2325
|
||||
#define IDS_CONNECTION_LOST_LIVE 2326
|
||||
#define IDS_CONNECTION_LOST_LIVE_NO_EXIT 2327
|
||||
#define IDS_AWARD_AVATAR1 2328
|
||||
#define IDS_AWARD_AVATAR2 2329
|
||||
#define IDS_AWARD_AVATAR3 2330
|
||||
#define IDS_AWARD_THEME 2331
|
||||
#define IDS_UNLOCK_ACHIEVEMENT_TEXT 2332
|
||||
#define IDS_UNLOCK_AVATAR_TEXT 2333
|
||||
#define IDS_UNLOCK_GAMERPIC_TEXT 2334
|
||||
#define IDS_UNLOCK_THEME_TEXT 2335
|
||||
#define IDS_UNLOCK_ACCEPT_INVITE 2336
|
||||
#define IDS_UNLOCK_GUEST_TEXT 2337
|
||||
#define IDS_LEADERBOARD_GAMERTAG 2338
|
||||
#define IDS_GROUPNAME_POTIONS_480 2339
|
||||
#define IDS_RETURNEDTOTITLESCREEN_TEXT 2340
|
||||
#define IDS_TRIALOVER_TEXT 2341
|
||||
#define IDS_FATAL_ERROR_TEXT 2342
|
||||
#define IDS_NO_MULTIPLAYER_PRIVILEGE_JOIN_TEXT 2343
|
||||
#define IDS_NO_MULTIPLAYER_PRIVILEGE_HOST_TEXT 2344
|
||||
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_SINGLE_LOCAL 2345
|
||||
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_ALL_LOCAL 2346
|
||||
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_REMOTE 2347
|
||||
#define IDS_NO_USER_CREATED_CONTENT_PRIVILEGE_CREATE 2348
|
||||
#define IDS_SAVE_ICON_MESSAGE 2349
|
||||
#define IDS_GAMEOPTION_HOST_PRIVILEGES 2350
|
||||
#define IDS_CHECKBOX_DISPLAY_SPLITSCREENGAMERTAGS 2351
|
||||
#define IDS_ACHIEVEMENTS 2352
|
||||
#define IDS_LABEL_GAMERTAGS 2353
|
||||
#define IDS_IN_GAME_GAMERTAGS 2354
|
||||
#define IDS_SOCIAL_DEFAULT_DESCRIPTION 2355
|
||||
#define IDS_TITLE_UPDATE_NAME 2356
|
||||
#define IDS_PLATFORM_NAME 2357
|
||||
#define IDS_BACK_BUTTON 2358
|
||||
#define IDS_HOST_OPTION_DISABLES_ACHIEVEMENTS 2359
|
||||
#define IDS_KICK_PLAYER_DESCRIPTION 2360
|
||||
#define IDS_USING_TRIAL_TEXUREPACK_WARNING 2361
|
||||
#define IDS_WORLD_SIZE_TITLE_SMALL 2362
|
||||
#define IDS_WORLD_SIZE_TITLE_MEDIUM 2363
|
||||
#define IDS_WORLD_SIZE_TITLE_LARGE 2364
|
||||
#define IDS_WORLD_SIZE_TITLE_CLASSIC 2365
|
||||
#define IDS_WORLD_SIZE 2366
|
||||
#define IDS_GAMEOPTION_WORLD_SIZE 2367
|
||||
#define IDS_DISABLE_SAVING 2368
|
||||
#define IDS_GAMEOPTION_DISABLE_SAVING 2369
|
||||
#define IDS_RICHPRESENCE_GAMESTATE 2370
|
||||
#define IDS_RICHPRESENCE_IDLE 2371
|
||||
#define IDS_RICHPRESENCE_MENUS 2372
|
||||
#define IDS_RICHPRESENCE_MULTIPLAYER 2373
|
||||
#define IDS_RICHPRESENCE_MULTIPLAYEROFFLINE 2374
|
||||
#define IDS_RICHPRESENCE_MULTIPLAYER_1P 2375
|
||||
#define IDS_RICHPRESENCE_MULTIPLAYER_1POFFLINE 2376
|
||||
#define IDS_RICHPRESENCESTATE_BLANK 2377
|
||||
#define IDS_RICHPRESENCESTATE_RIDING_PIG 2378
|
||||
#define IDS_RICHPRESENCESTATE_RIDING_MINECART 2379
|
||||
#define IDS_RICHPRESENCESTATE_BOATING 2380
|
||||
#define IDS_RICHPRESENCESTATE_FISHING 2381
|
||||
#define IDS_RICHPRESENCESTATE_CRAFTING 2382
|
||||
#define IDS_RICHPRESENCESTATE_FORGING 2383
|
||||
#define IDS_RICHPRESENCESTATE_NETHER 2384
|
||||
#define IDS_RICHPRESENCESTATE_CD 2385
|
||||
#define IDS_RICHPRESENCESTATE_MAP 2386
|
||||
#define IDS_RICHPRESENCESTATE_ENCHANTING 2387
|
||||
#define IDS_RICHPRESENCESTATE_BREWING 2388
|
||||
#define IDS_RICHPRESENCESTATE_ANVIL 2389
|
||||
#define IDS_RICHPRESENCESTATE_TRADING 2390
|
||||
|
||||
@@ -109,6 +109,9 @@ set(MINECRAFT_SERVER_FOURKIT_SOURCES
|
||||
${MINECRAFT_SERVER_COMMON}
|
||||
${SOURCES_COMMON}
|
||||
${_MINECRAFT_SERVER_COMMON_SERVER_FOURKIT}
|
||||
"${CMAKE_SOURCE_DIR}/Minecraft.Client/Common/UI/UIScene_AchievementsMenu.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/Minecraft.Client/Common/UI/UIControl_AchievementsList.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/Minecraft.Client/Common/StringUtils.cpp"
|
||||
)
|
||||
|
||||
add_executable(Minecraft.Server.FourKit ${MINECRAFT_SERVER_FOURKIT_SOURCES})
|
||||
|
||||
@@ -11,6 +11,10 @@ include("${CMAKE_SOURCE_DIR}/cmake/ServerTarget.cmake")
|
||||
set(MINECRAFT_SERVER_SOURCES
|
||||
${MINECRAFT_SERVER_COMMON}
|
||||
${SOURCES_COMMON}
|
||||
|
||||
"${CMAKE_SOURCE_DIR}/Minecraft.Client/Common/UI/UIScene_AchievementsMenu.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/Minecraft.Client/Common/UI/UIControl_AchievementsList.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/Minecraft.Client/Common/StringUtils.cpp"
|
||||
)
|
||||
|
||||
add_executable(Minecraft.Server ${MINECRAFT_SERVER_SOURCES})
|
||||
|
||||
@@ -15,19 +15,28 @@ void Achievement::_init()
|
||||
if (y > Achievements::yMax) Achievements::yMax = y;
|
||||
}
|
||||
|
||||
Achievement::Achievement(int id, const wstring& name, int x, int y, Item *icon, Achievement *reqs)
|
||||
Achievement::Achievement(int id, const wstring& name, int x, int y, Item *icon, Achievement *reqs, string iconI, int nameID1, int descID1)
|
||||
: Stat( Achievements::ACHIEVEMENT_OFFSET + id, I18n::get(wstring(L"achievement.").append(name)) ), desc( I18n::get(wstring(L"achievement.").append(name).append(L".desc"))), icon( new ItemInstance(icon) ), x(x), y(y), reqs(reqs)
|
||||
{
|
||||
iconInt = iconI;
|
||||
nameID = nameID1;
|
||||
descID = descID1;
|
||||
}
|
||||
|
||||
Achievement::Achievement(int id, const wstring& name, int x, int y, Tile *icon, Achievement *reqs)
|
||||
Achievement::Achievement(int id, const wstring& name, int x, int y, Tile *icon, Achievement *reqs, string iconI, int nameID1, int descID1)
|
||||
: Stat( Achievements::ACHIEVEMENT_OFFSET + id, I18n::get(wstring(L"achievement.").append(name)) ), desc( I18n::get(wstring(L"achievement.").append(name).append(L".desc"))), icon( new ItemInstance(icon) ), x(x), y(y), reqs(reqs)
|
||||
{
|
||||
iconInt = iconI;
|
||||
nameID = nameID1;
|
||||
descID = descID1;
|
||||
}
|
||||
|
||||
Achievement::Achievement(int id, const wstring& name, int x, int y, shared_ptr<ItemInstance> icon, Achievement *reqs)
|
||||
Achievement::Achievement(int id, const wstring& name, int x, int y, shared_ptr<ItemInstance> icon, Achievement *reqs, string iconI, int nameID1, int descID1)
|
||||
: Stat( Achievements::ACHIEVEMENT_OFFSET + id, I18n::get(wstring(L"achievement.").append(name)) ), desc( I18n::get(wstring(L"achievement.").append(name).append(L".desc"))), icon(icon), x(x), y(y), reqs(reqs)
|
||||
{
|
||||
iconInt = iconI;
|
||||
nameID = nameID1;
|
||||
descID = descID1;
|
||||
}
|
||||
|
||||
Achievement *Achievement::setAwardLocallyOnly()
|
||||
|
||||
@@ -10,6 +10,9 @@ class Achievement : public Stat
|
||||
public:
|
||||
const int x, y;
|
||||
Achievement *reqs;
|
||||
string iconInt;
|
||||
int nameID;
|
||||
int descID;
|
||||
|
||||
private:
|
||||
const wstring desc;
|
||||
@@ -23,9 +26,9 @@ private:
|
||||
void _init();
|
||||
|
||||
public:
|
||||
Achievement(int id, const wstring& name, int x, int y, Item *icon, Achievement *reqs);
|
||||
Achievement(int id, const wstring& name, int x, int y, Tile *icon, Achievement *reqs);
|
||||
Achievement(int id, const wstring& name, int x, int y, shared_ptr<ItemInstance> icon, Achievement *reqs);
|
||||
Achievement(int id, const wstring& name, int x, int y, Item* icon, Achievement* reqs, string iconI = "", int nameID = 0, int descID = 0);
|
||||
Achievement(int id, const wstring& name, int x, int y, Tile* icon, Achievement* reqs, string iconI = "", int nameID = 0, int descID = 0);
|
||||
Achievement(int id, const wstring& name, int x, int y, shared_ptr<ItemInstance> icon, Achievement* reqs, string iconI = "", int nameID = 0, int descID = 0);
|
||||
|
||||
Achievement *setAwardLocallyOnly();
|
||||
Achievement *setGolden();
|
||||
|
||||
@@ -53,14 +53,14 @@ Achievement *Achievements::dispenseWithThis = nullptr;
|
||||
Achievement *Achievements::InToTheNether = nullptr;
|
||||
|
||||
// 4J : WESTY : Added other awards.
|
||||
Achievement *Achievements::socialPost = nullptr;
|
||||
//Achievement *Achievements::socialPost = nullptr;
|
||||
Achievement *Achievements::eatPorkChop = nullptr;
|
||||
Achievement *Achievements::play100Days = nullptr;
|
||||
Achievement *Achievements::arrowKillCreeper = nullptr;
|
||||
Achievement *Achievements::mine100Blocks = nullptr;
|
||||
Achievement *Achievements::kill10Creepers = nullptr;
|
||||
//Achievement *Achievements::mine100Blocks = nullptr;
|
||||
//Achievement *Achievements::kill10Creepers = nullptr;
|
||||
|
||||
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
Achievement *Achievements::overkill = nullptr; // Restored old achivements.
|
||||
Achievement *Achievements::bookcase = nullptr; // Restored old achivements.
|
||||
|
||||
@@ -85,47 +85,43 @@ Achievement *Achievements::bodyGuard = nullptr;
|
||||
Achievement *Achievements::ironMan = nullptr;
|
||||
Achievement *Achievements::zombieDoctor = nullptr;
|
||||
Achievement *Achievements::lionTamer = nullptr;
|
||||
#endif
|
||||
|
||||
void Achievements::staticCtor()
|
||||
{
|
||||
Achievements::openInventory = (new Achievement(eAward_TakingInventory, L"openInventory", 0, 0, Item::book, nullptr))->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::mineWood = (new Achievement(eAward_GettingWood, L"mineWood", 2, 1, Tile::treeTrunk, (Achievement *) openInventory))->postConstruct();
|
||||
Achievements::buildWorkbench = (new Achievement(eAward_Benchmarking, L"buildWorkBench", 4, -1, Tile::workBench, (Achievement *) mineWood))->postConstruct();
|
||||
Achievements::buildPickaxe = (new Achievement(eAward_TimeToMine, L"buildPickaxe", 4, 2, Item::pickAxe_wood, (Achievement *) buildWorkbench))->postConstruct();
|
||||
Achievements::buildFurnace = (new Achievement(eAward_HotTopic, L"buildFurnace", 3, 4, Tile::furnace_lit, (Achievement *) buildPickaxe))->postConstruct();
|
||||
Achievements::acquireIron = (new Achievement(eAward_AquireHardware, L"acquireIron", 1, 4, Item::ironIngot, (Achievement *) buildFurnace))->postConstruct();
|
||||
Achievements::buildHoe = (new Achievement(eAward_TimeToFarm, L"buildHoe", 2, -3, Item::hoe_wood, (Achievement *) buildWorkbench))->postConstruct();
|
||||
Achievements::makeBread = (new Achievement(eAward_BakeBread, L"makeBread", -1, -3, Item::bread, (Achievement *) buildHoe))->postConstruct();
|
||||
Achievements::bakeCake = (new Achievement(eAward_TheLie, L"bakeCake", 0, -5, Item::cake, (Achievement *) buildHoe))->postConstruct();
|
||||
Achievements::buildBetterPickaxe = (new Achievement(eAward_GettingAnUpgrade, L"buildBetterPickaxe", 6, 2, Item::pickAxe_stone, (Achievement *) buildPickaxe))->postConstruct();
|
||||
Achievements::cookFish = (new Achievement(eAward_DeliciousFish, L"cookFish", 2, 6, Item::fish_cooked, (Achievement *) buildFurnace))->postConstruct();
|
||||
Achievements::onARail = (new Achievement(eAward_OnARail, L"onARail", 2, 3, Tile::rail, (Achievement *) acquireIron))->setGolden()->postConstruct();
|
||||
Achievements::buildSword = (new Achievement(eAward_TimeToStrike, L"buildSword", 6, -1, Item::sword_wood, (Achievement *) buildWorkbench))->postConstruct();
|
||||
Achievements::killEnemy = (new Achievement(eAward_MonsterHunter, L"killEnemy", 8, -1, Item::bone, (Achievement *) buildSword))->postConstruct();
|
||||
Achievements::killCow = (new Achievement(eAward_CowTipper, L"killCow", 7, -3, Item::leather, (Achievement *) buildSword))->postConstruct();
|
||||
Achievements::flyPig = (new Achievement(eAward_WhenPigsFly, L"flyPig", 8, -4, Item::saddle, (Achievement *) killCow))->setGolden()->postConstruct();
|
||||
|
||||
Achievements::openInventory = (new Achievement(eAward_TakingInventory, L"openInventory", 0, 0, Item::book, nullptr, "001", IDS_ACHIEVE_NAME_TAKING_INVENTORY, IDS_ACHIEVE_DESC_TAKING_INVENTORY))->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::mineWood = (new Achievement(eAward_GettingWood, L"mineWood", 2, 1, Tile::treeTrunk, (Achievement *) openInventory, "002", IDS_ACHIEVE_NAME_GETTING_WOOD, IDS_ACHIEVE_DESC_GETTING_WOOD))->postConstruct();
|
||||
Achievements::buildWorkbench = (new Achievement(eAward_Benchmarking, L"buildWorkBench", 4, -1, Tile::workBench, (Achievement *) mineWood, "003", IDS_ACHIEVE_NAME_BENCHMARKING, IDS_ACHIEVE_DESC_BENCHMARKING))->postConstruct();
|
||||
Achievements::buildPickaxe = (new Achievement(eAward_TimeToMine, L"buildPickaxe", 4, 2, Item::pickAxe_wood, (Achievement *) buildWorkbench, "004", IDS_ACHIEVE_NAME_TIME_TO_MINE, IDS_ACHIEVE_DESC_TIME_TO_MINE))->postConstruct();
|
||||
Achievements::buildFurnace = (new Achievement(eAward_HotTopic, L"buildFurnace", 3, 4, Tile::furnace_lit, (Achievement *) buildPickaxe, "005", IDS_ACHIEVE_NAME_HOT_TOPIC, IDS_ACHIEVE_DESC_HOT_TOPIC))->postConstruct();
|
||||
Achievements::acquireIron = (new Achievement(eAward_AquireHardware, L"acquireIron", 1, 4, Item::ironIngot, (Achievement *) buildFurnace, "006", IDS_ACHIEVE_NAME_ACQUIRE_HARDWARE, IDS_ACHIEVE_DESC_ACQUIRE_HARDWARE))->postConstruct();
|
||||
Achievements::buildHoe = (new Achievement(eAward_TimeToFarm, L"buildHoe", 2, -3, Item::hoe_wood, (Achievement *) buildWorkbench, "007", IDS_ACHIEVE_NAME_TIME_TO_FARM, IDS_ACHIEVE_DESC_TIME_TO_FARM))->postConstruct();
|
||||
Achievements::makeBread = (new Achievement(eAward_BakeBread, L"makeBread", -1, -3, Item::bread, (Achievement *) buildHoe, "008", IDS_ACHIEVE_NAME_BAKE_BREAD, IDS_ACHIEVE_DESC_BAKE_BREAD))->postConstruct();
|
||||
Achievements::bakeCake = (new Achievement(eAward_TheLie, L"bakeCake", 0, -5, Item::cake, (Achievement *) buildHoe, "009", IDS_ACHIEVE_NAME_THE_LIE, IDS_ACHIEVE_DESC_THE_LIE))->postConstruct();
|
||||
Achievements::buildBetterPickaxe = (new Achievement(eAward_GettingAnUpgrade, L"buildBetterPickaxe", 6, 2, Item::pickAxe_stone, (Achievement *) buildPickaxe, "010", IDS_ACHIEVE_NAME_GETTING_AN_UPGRADE, IDS_ACHIEVE_DESC_GETTING_AN_UPGRADE))->postConstruct();
|
||||
Achievements::cookFish = (new Achievement(eAward_DeliciousFish, L"cookFish", 2, 6, Item::fish_cooked, (Achievement *) buildFurnace, "011", IDS_ACHIEVE_NAME_DELICIOUS_FISH, IDS_ACHIEVE_DESC_DELICIOUS_FISH))->postConstruct();
|
||||
Achievements::onARail = (new Achievement(eAward_OnARail, L"onARail", 2, 3, Tile::rail, (Achievement *) acquireIron, "012", IDS_ACHIEVE_NAME_ON_A_RAIL, IDS_ACHIEVE_DESC_ON_A_RAIL))->setGolden()->postConstruct();
|
||||
Achievements::buildSword = (new Achievement(eAward_TimeToStrike, L"buildSword", 6, -1, Item::sword_wood, (Achievement *) buildWorkbench, "013", IDS_ACHIEVE_NAME_TIME_TO_STRIKE, IDS_ACHIEVE_DESC_TIME_TO_STRIKE))->postConstruct();
|
||||
Achievements::killEnemy = (new Achievement(eAward_MonsterHunter, L"killEnemy", 8, -1, Item::bone, (Achievement *) buildSword, "014", IDS_ACHIEVE_NAME_MONSTER_HUNTER, IDS_ACHIEVE_DESC_MONSTER_HUNTER))->postConstruct();
|
||||
Achievements::killCow = (new Achievement(eAward_CowTipper, L"killCow", 7, -3, Item::leather, (Achievement *) buildSword, "015", IDS_ACHIEVE_NAME_COW_TIPPER, IDS_ACHIEVE_DESC_COW_TIPPER))->postConstruct();
|
||||
Achievements::flyPig = (new Achievement(eAward_WhenPigsFly, L"flyPig", 8, -4, Item::saddle, (Achievement *) killCow, "016", IDS_ACHIEVE_NAME_WHEN_PIGS_FLY, IDS_ACHIEVE_DESC_WHEN_PIGS_FLY))->setGolden()->postConstruct();
|
||||
// 4J Stu - The order of these achievemnts is very important, as they map directly to data stored in the profile data. New achievements should be added at the end.
|
||||
|
||||
// 4J : WESTY : Added new achievements. Note, params "x", "y", "icon" and "requires" are ignored on xbox.
|
||||
Achievements::leaderOfThePack = (new Achievement(eAward_LeaderOfThePack, L"leaderOfThePack", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::MOARTools = (new Achievement(eAward_MOARTools, L"MOARTools", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::dispenseWithThis = (new Achievement(eAward_DispenseWithThis, L"dispenseWithThis", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->postConstruct();
|
||||
Achievements::InToTheNether = (new Achievement(eAward_InToTheNether, L"InToTheNether", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->postConstruct();
|
||||
|
||||
Achievements::leaderOfThePack = (new Achievement(eAward_LeaderOfThePack, L"leaderOfThePack", 0, 0, Tile::treeTrunk, (Achievement *) buildSword, "017", IDS_ACHIEVE_NAME_LEADER_OF_THE_PACK, IDS_ACHIEVE_DESC_LEADER_OF_THE_PACK))->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::MOARTools = (new Achievement(eAward_MOARTools, L"MOARTools", 0, 0, Tile::treeTrunk, (Achievement *) buildSword, "018", IDS_ACHIEVE_NAME_MOAR_TOOLS, IDS_ACHIEVE_DESC_MOAR_TOOLS))->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::dispenseWithThis = (new Achievement(eAward_DispenseWithThis, L"dispenseWithThis", 0, 0, Tile::treeTrunk, (Achievement *) buildSword, "019", IDS_ACHIEVE_NAME_DISPENSE_WITH_THIS, IDS_ACHIEVE_DESC_DISPENSE_WITH_THIS))->postConstruct();
|
||||
Achievements::InToTheNether = (new Achievement(eAward_InToTheNether, L"InToTheNether", 0, 0, Tile::treeTrunk, (Achievement *) buildSword, "020", IDS_ACHIEVE_NAME_INTO_THE_NETHER, IDS_ACHIEVE_DESC_INTO_THE_NETHER))->postConstruct();
|
||||
// 4J : WESTY : Added other awards.
|
||||
Achievements::mine100Blocks = (new Achievement(eAward_mine100Blocks, L"mine100Blocks", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::kill10Creepers = (new Achievement(eAward_kill10Creepers, L"kill10Creepers", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->setAwardLocallyOnly()->postConstruct();
|
||||
//Achievements::mine100Blocks = (new Achievement(eAward_mine100Blocks, L"mine100Blocks", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->setAwardLocallyOnly()->postConstruct();
|
||||
//Achievements::kill10Creepers = (new Achievement(eAward_kill10Creepers, L"kill10Creepers", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->setAwardLocallyOnly()->postConstruct();
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
Achievements::eatPorkChop = (new Achievement(eAward_eatPorkChop, L"eatPorkChop", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->setAwardLocallyOnly()->postConstruct();
|
||||
#else
|
||||
Achievements::eatPorkChop = (new Achievement(eAward_eatPorkChop, L"eatPorkChop", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->postConstruct();
|
||||
Achievements::eatPorkChop = (new Achievement(eAward_eatPorkChop, L"eatPorkChop", 0, 0, Tile::treeTrunk, (Achievement *) buildSword, "034", IDS_ACHIEVE_NAME_EAT_PORKCHOP, IDS_ACHIEVE_DESC_EAT_PORKCHOP))->postConstruct();
|
||||
#endif
|
||||
Achievements::play100Days = (new Achievement(eAward_play100Days, L"play100Days", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::arrowKillCreeper = (new Achievement(eAward_arrowKillCreeper, L"arrowKillCreeper", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->postConstruct();
|
||||
Achievements::socialPost = (new Achievement(eAward_socialPost, L"socialPost", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->postConstruct();
|
||||
|
||||
Achievements::play100Days = (new Achievement(eAward_play100Days, L"play100Days", 0, 0, Tile::treeTrunk, (Achievement *) buildSword, "035", IDS_ACHIEVE_NAME_PLAY_100_DAYS, IDS_ACHIEVE_DESC_PLAY_100_DAYS))->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::arrowKillCreeper = (new Achievement(eAward_arrowKillCreeper, L"arrowKillCreeper", 0, 0, Tile::treeTrunk, (Achievement *) buildSword, "036", IDS_ACHIEVE_NAME_ARROW_KILL_CREEPER, IDS_ACHIEVE_DESC_ARROW_KILL_CREEPER))->postConstruct();
|
||||
//Achievements::socialPost = (new Achievement(eAward_socialPost, L"socialPost", 0, 0, Tile::treeTrunk, (Achievement *) buildSword))->postConstruct();
|
||||
#ifndef _XBOX
|
||||
// WARNING: NO NEW ACHIEVMENTS CAN BE ADDED HERE
|
||||
// These stats (achievements) are directly followed by new stats/achievements in the profile data, so cannot be changed without migrating the profile data
|
||||
@@ -133,47 +129,44 @@ void Achievements::staticCtor()
|
||||
// 4J Stu - All new Java achievements removed to stop them using the profile data
|
||||
|
||||
// 4J Stu - This achievment added in 1.8.2, but does not map to any Xbox achievements
|
||||
Achievements::snipeSkeleton = (new Achievement(eAward_snipeSkeleton, L"snipeSkeleton", 7, 0, Item::bow, (Achievement *) killEnemy))->setGolden()->postConstruct();
|
||||
|
||||
Achievements::snipeSkeleton = (new Achievement(eAward_snipeSkeleton, L"snipeSkeleton", 7, 0, Item::bow, (Achievement *) killEnemy, "021", IDS_ACHIEVE_NAME_SNIPESKELETON, IDS_ACHIEVE_DESC_SNIPESKELETON))->setGolden()->postConstruct();
|
||||
// 4J Stu - These added in 1.0.1, but do not map to any Xbox achievements
|
||||
Achievements::diamonds = (new Achievement(eAward_diamonds, L"diamonds", -1, 5, Item::diamond, (Achievement *) acquireIron) )->postConstruct();
|
||||
Achievements::diamonds = (new Achievement(eAward_diamonds, L"diamonds", -1, 5, Item::diamond, (Achievement *) acquireIron, "022", IDS_ACHIEVE_NAME_DIAMONDS, IDS_ACHIEVE_DESC_DIAMONDS) )->postConstruct();
|
||||
//Achievements::portal = (new Achievement(eAward_portal, L"portal", -1, 7, Tile::obsidian, (Achievement *)diamonds) )->postConstruct();
|
||||
Achievements::ghast = (new Achievement(eAward_ghast, L"ghast", -4, 8, Item::ghastTear, (Achievement *)ghast) )->setGolden()->postConstruct();
|
||||
Achievements::blazeRod = (new Achievement(eAward_blazeRod, L"blazeRod", 0, 9, Item::blazeRod, (Achievement *)blazeRod) )->postConstruct();
|
||||
Achievements::potion = (new Achievement(eAward_potion, L"potion", 2, 8, Item::potion, (Achievement *)potion) )->postConstruct();
|
||||
Achievements::theEnd = (new Achievement(eAward_theEnd, L"theEnd", 3, 10, Item::eyeOfEnder, (Achievement *)theEnd) )->setGolden()->postConstruct();
|
||||
Achievements::winGame = (new Achievement(eAward_winGame, L"theEnd2", 4, 13, Tile::dragonEgg, (Achievement *)winGame) )->setGolden()->postConstruct();
|
||||
Achievements::enchantments = (new Achievement(eAward_enchantments, L"enchantments", -4, 4, Tile::enchantTable, (Achievement *)enchantments) )->postConstruct();
|
||||
Achievements::ghast = (new Achievement(eAward_ghast, L"ghast", -4, 8, Item::ghastTear, (Achievement *)ghast, "023", IDS_ACHIEVE_NAME_GHAST, IDS_ACHIEVE_DESC_GHAST) )->setGolden()->postConstruct();
|
||||
Achievements::blazeRod = (new Achievement(eAward_blazeRod, L"blazeRod", 0, 9, Item::blazeRod, (Achievement *)blazeRod, "024", IDS_ACHIEVE_NAME_BLAZEROD, IDS_ACHIEVE_DESC_BLAZEROD) )->postConstruct();
|
||||
Achievements::potion = (new Achievement(eAward_potion, L"potion", 2, 8, Item::potion, (Achievement *)potion, "025", IDS_ACHIEVE_NAME_POTION, IDS_ACHIEVE_DESC_POTION) )->postConstruct();
|
||||
Achievements::theEnd = (new Achievement(eAward_theEnd, L"theEnd", 3, 10, Item::eyeOfEnder, (Achievement *)theEnd, "026", IDS_ACHIEVE_NAME_THE_END, IDS_ACHIEVE_DESC_THE_END) )->setGolden()->postConstruct();
|
||||
Achievements::winGame = (new Achievement(eAward_winGame, L"theEnd2", 4, 13, Tile::dragonEgg, (Achievement *)winGame, "027", IDS_ACHIEVE_NAME_WINGAME, IDS_ACHIEVE_DESC_WINGAME) )->setGolden()->postConstruct();
|
||||
Achievements::enchantments = (new Achievement(eAward_enchantments, L"enchantments", -4, 4, Tile::enchantTable, (Achievement *)enchantments, "028", IDS_ACHIEVE_NAME_ENCHANTMENTS, IDS_ACHIEVE_DESC_ENCHANTMENTS) )->postConstruct();
|
||||
// Achievements::overkill = (new Achievement(eAward_overkill, L"overkill", -4, 1, Item::sword_diamond, (Achievement *)enchantments) )->setGolden()->postConstruct();
|
||||
// Achievements::bookcase = (new Achievement(eAward_bookcase, L"bookcase", -3, 6, Tile::bookshelf, (Achievement *)enchantments) )->postConstruct();
|
||||
#endif
|
||||
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
Achievements::overkill = (new Achievement(eAward_overkill, L"overkill", -4,1, Item::sword_diamond, (Achievement *)enchantments) )->setGolden()->postConstruct();
|
||||
Achievements::bookcase = (new Achievement(eAward_bookcase, L"bookcase", -3,6, Tile::bookshelf, (Achievement *)enchantments) )->postConstruct();
|
||||
|
||||
Achievements::adventuringTime = (new Achievement(eAward_adventuringTime, L"adventuringTime", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::repopulation = (new Achievement(eAward_repopulation, L"repopulation", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::overkill = (new Achievement(eAward_overkill, L"overkill", -4,1, Item::sword_diamond, (Achievement *)enchantments, "029", IDS_ACHIEVE_NAME_OVERKILL, IDS_ACHIEVE_DESC_OVERKILL) )->setGolden()->postConstruct();
|
||||
Achievements::bookcase = (new Achievement(eAward_bookcase, L"bookcase", -3,6, Tile::bookshelf, (Achievement *)enchantments, "030", IDS_ACHIEVE_NAME_BOOKCASE, IDS_ACHIEVE_DESC_BOOKCASE) )->postConstruct();
|
||||
|
||||
Achievements::adventuringTime = (new Achievement(eAward_adventuringTime, L"adventuringTime", 0,0, Tile::bookshelf, (Achievement*) nullptr, "031", IDS_ACHIEVE_NAME_ADVENTURING_TIME, IDS_ACHIEVE_DESC_ADVENTURING_TIME) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::repopulation = (new Achievement(eAward_repopulation, L"repopulation", 7,-5, Tile::bookshelf, (Achievement*) nullptr, "032", IDS_ACHIEVE_NAME_REPOPULATION, IDS_ACHIEVE_DESC_REPOPULATION) )->postConstruct();
|
||||
//Achievements::porkChoop // // // // // //
|
||||
Achievements::diamondsToYou = (new Achievement(eAward_diamondsToYou, L"diamondsToYou", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::diamondsToYou = (new Achievement(eAward_diamondsToYou, L"diamondsToYou", 0,0, Tile::bookshelf, (Achievement*) nullptr, "033", IDS_ACHIEVE_NAME_DIAMONDS_TO_YOU, IDS_ACHIEVE_DESC_DIAMONDS_TO_YOU) )->postConstruct();
|
||||
//Achievements::passingTheTime = (new Achievement(eAward_play100Days, L"passingTheTime", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
//Achievements::archer = (new Achievement(eAward_arrowKillCreeper, L"archer", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::theHaggler = (new Achievement(eAward_theHaggler, L"theHaggler", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::potPlanter = (new Achievement(eAward_potPlanter, L"potPlanter", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::itsASign = (new Achievement(eAward_itsASign, L"itsASign", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::ironBelly = (new Achievement(eAward_ironBelly, L"ironBelly", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::haveAShearfulDay = (new Achievement(eAward_haveAShearfulDay, L"haveAShearfulDay", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::rainbowCollection = (new Achievement(eAward_rainbowCollection, L"rainbowCollection", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::stayinFrosty = (new Achievement(eAward_stayinFrosty, L"stayingFrosty", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::chestfulOfCobblestone = (new Achievement(eAward_chestfulOfCobblestone, L"chestfulOfCobblestone", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::renewableEnergy = (new Achievement(eAward_renewableEnergy, L"renewableEnergy", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::musicToMyEars = (new Achievement(eAward_musicToMyEars, L"musicToMyEars", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::bodyGuard = (new Achievement(eAward_bodyGuard, L"bodyGuard", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::ironMan = (new Achievement(eAward_ironMan, L"ironMan", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::zombieDoctor = (new Achievement(eAward_zombieDoctor, L"zombieDoctor", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
Achievements::lionTamer = (new Achievement(eAward_lionTamer, L"lionTamer", 0,0, Tile::bookshelf, (Achievement*) nullptr) )->postConstruct();
|
||||
#endif
|
||||
|
||||
Achievements::theHaggler = (new Achievement(eAward_theHaggler, L"theHaggler", 0,0, Tile::bookshelf, (Achievement*) nullptr, "037", IDS_ACHIEVE_NAME_THE_HAGGLER, IDS_ACHIEVE_DESC_THE_HAGGLER) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::potPlanter = (new Achievement(eAward_potPlanter, L"potPlanter", 0,0, Tile::bookshelf, (Achievement*) nullptr, "038", IDS_ACHIEVE_NAME_POT_PLANTER, IDS_ACHIEVE_DESC_POT_PLANTER) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::itsASign = (new Achievement(eAward_itsASign, L"itsASign", 0,0, Tile::bookshelf, (Achievement*) nullptr, "039", IDS_ACHIEVE_NAME_ITS_A_SIGN, IDS_ACHIEVE_DESC_ITS_A_SIGN) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::ironBelly = (new Achievement(eAward_ironBelly, L"ironBelly", 0,0, Tile::bookshelf, (Achievement*) nullptr, "040", IDS_ACHIEVE_NAME_IRON_BELLY, IDS_ACHIEVE_DESC_IRON_BELLY) )->postConstruct();
|
||||
Achievements::haveAShearfulDay = (new Achievement(eAward_haveAShearfulDay, L"haveAShearfulDay", 0,0, Tile::bookshelf, (Achievement*) nullptr, "041", IDS_ACHIEVE_NAME_HAVE_A_SHEARFUL_DAY, IDS_ACHIEVE_DESC_HAVE_A_SHEARFUL_DAY) )->postConstruct();
|
||||
Achievements::rainbowCollection = (new Achievement(eAward_rainbowCollection, L"rainbowCollection", 0,0, Tile::bookshelf, (Achievement*) nullptr, "042", IDS_ACHIEVE_NAME_RAINBOW_COLLECTION, IDS_ACHIEVE_DESC_RAINBOW_COLLECTION) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::stayinFrosty = (new Achievement(eAward_stayinFrosty, L"stayingFrosty", 0,0, Tile::bookshelf, (Achievement*) nullptr, "043", IDS_ACHIEVE_NAME_STAYING_FROSTY, IDS_ACHIEVE_DESC_STAYING_FROSTY) )->postConstruct();
|
||||
Achievements::chestfulOfCobblestone = (new Achievement(eAward_chestfulOfCobblestone, L"chestfulOfCobblestone", 0,0, Tile::bookshelf, (Achievement*) nullptr, "044", IDS_ACHIEVE_NAME_CHESTFUL_OF_COBBLESTONE, IDS_ACHIEVE_DESC_CHESTFUL_OF_COBBLESTONE) )->setAwardLocallyOnly()->postConstruct();
|
||||
Achievements::renewableEnergy = (new Achievement(eAward_renewableEnergy, L"renewableEnergy", 0,0, Tile::bookshelf, (Achievement*) nullptr, "045", IDS_ACHIEVE_NAME_RENEWABLE_ENERGY, IDS_ACHIEVE_DESC_RENEWABLE_ENERGY) )->postConstruct();
|
||||
Achievements::musicToMyEars = (new Achievement(eAward_musicToMyEars, L"musicToMyEars", 0,0, Tile::bookshelf, (Achievement*) nullptr, "046", IDS_ACHIEVE_NAME_MUSIC_TO_MY_EARS, IDS_ACHIEVE_DESC_MUSIC_TO_MY_EARS) )->postConstruct();
|
||||
Achievements::bodyGuard = (new Achievement(eAward_bodyGuard, L"bodyGuard", 0,0, Tile::bookshelf, (Achievement*) nullptr, "047", IDS_ACHIEVE_NAME_BODYGUARD, IDS_ACHIEVE_DESC_BODYGUARD) )->postConstruct();
|
||||
Achievements::ironMan = (new Achievement(eAward_ironMan, L"ironMan", 0,0, Tile::bookshelf, (Achievement*) nullptr, "048", IDS_ACHIEVE_NAME_IRON_MAN, IDS_ACHIEVE_DESC_IRON_MAN) )->postConstruct();
|
||||
Achievements::zombieDoctor = (new Achievement(eAward_zombieDoctor, L"zombieDoctor", 0,0, Tile::bookshelf, (Achievement*) nullptr, "049", IDS_ACHIEVE_NAME_ZOMBIE_DOCTOR, IDS_ACHIEVE_DESC_ZOMBIE_DOCTOR) )->postConstruct();
|
||||
Achievements::lionTamer = (new Achievement(eAward_lionTamer, L"lionTamer", 0,0, Tile::bookshelf, (Achievement*) nullptr, "050", IDS_ACHIEVE_NAME_LION_TAMER, IDS_ACHIEVE_DESC_LION_TAMER) )->postConstruct();
|
||||
}
|
||||
|
||||
// Static { System.out.println(achievements.size() + " achievements"); } TODO
|
||||
|
||||
@@ -55,14 +55,13 @@ public:
|
||||
static Achievement *InToTheNether;
|
||||
|
||||
// 4J : WESTY : Added other awards.
|
||||
static Achievement *socialPost;
|
||||
//static Achievement *socialPost;
|
||||
static Achievement *eatPorkChop;
|
||||
static Achievement *play100Days;
|
||||
static Achievement *arrowKillCreeper;
|
||||
static Achievement *mine100Blocks;
|
||||
static Achievement *kill10Creepers;
|
||||
//static Achievement *mine100Blocks;
|
||||
//static Achievement *kill10Creepers;
|
||||
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
static Achievement *overkill; // Old achievements;
|
||||
static Achievement *bookcase; // Old achievements;
|
||||
static Achievement *adventuringTime;
|
||||
@@ -84,7 +83,6 @@ public:
|
||||
static Achievement *ironMan;
|
||||
static Achievement *zombieDoctor;
|
||||
static Achievement *lionTamer;
|
||||
#endif
|
||||
|
||||
static void staticCtor();
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ Stat* CommonStats::get_blocksPlaced(int blockId)
|
||||
#if (defined _EXTENDED_ACHIEVEMENTS) && (!defined _XBOX_ONE)
|
||||
return Stats::blocksPlaced[blockId];
|
||||
#else
|
||||
return nullptr;
|
||||
return Stats::blocksPlaced[blockId];
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ Stat *CommonStats::get_itemsCollected(int itemId, int itemAux)
|
||||
#if (defined _EXTENDED_ACHIEVEMENTS) && (!defined _XBOX_ONE)
|
||||
if (itemId == Tile::wool_Id) return Stats::rainbowCollection[itemAux];
|
||||
#endif
|
||||
|
||||
if (itemId == Tile::wool_Id) return Stats::rainbowCollection[itemAux];
|
||||
if (itemId != Item::emerald_Id) return Stats::itemsCollected[itemId];
|
||||
else return nullptr;
|
||||
}
|
||||
@@ -111,7 +111,7 @@ Stat *CommonStats::get_itemsUsed(int itemId)
|
||||
if (itemId == Item::porkChop_cooked_Id) return Stats::blocksPlaced[itemId];
|
||||
#endif
|
||||
|
||||
return nullptr;
|
||||
if (itemId == Item::porkChop_cooked_Id) return Stats::blocksPlaced[itemId];
|
||||
}
|
||||
|
||||
Stat *CommonStats::get_itemsBought(int itemId)
|
||||
@@ -133,7 +133,7 @@ Stat *CommonStats::get_enteredBiome(int biomeId)
|
||||
#if (defined _EXTENDED_ACHIEVEMENTS) && (!defined _XBOX_ONE)
|
||||
return Stats::biomesVisisted[biomeId];
|
||||
#else
|
||||
return nullptr;
|
||||
return Stats::biomesVisisted[biomeId];
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -161,17 +161,17 @@ Stat *CommonStats::get_achievement(eAward achievementId)
|
||||
case eAward_MOARTools: return (Stat *) Achievements::MOARTools;
|
||||
case eAward_DispenseWithThis: return (Stat *) Achievements::dispenseWithThis;
|
||||
case eAward_InToTheNether: return (Stat *) Achievements::InToTheNether;
|
||||
case eAward_mine100Blocks: return (Stat *) Achievements::mine100Blocks;
|
||||
case eAward_kill10Creepers: return (Stat *) Achievements::kill10Creepers;
|
||||
//case eAward_mine100Blocks: return (Stat *) Achievements::mine100Blocks;
|
||||
//case eAward_kill10Creepers: return (Stat *) Achievements::kill10Creepers;
|
||||
case eAward_eatPorkChop: return (Stat *) Achievements::eatPorkChop;
|
||||
case eAward_play100Days: return (Stat *) Achievements::play100Days;
|
||||
case eAward_arrowKillCreeper: return (Stat *) Achievements::arrowKillCreeper;
|
||||
case eAward_socialPost: return (Stat *) Achievements::socialPost;
|
||||
//case eAward_socialPost: return (Stat *) Achievements::socialPost;
|
||||
|
||||
#ifndef _XBOX
|
||||
case eAward_snipeSkeleton: return (Stat *) Achievements::snipeSkeleton;
|
||||
case eAward_diamonds: return (Stat *) Achievements::diamonds;
|
||||
case eAward_portal: return (Stat *) nullptr; // TODO
|
||||
//case eAward_portal: return (Stat *) nullptr; // TODO
|
||||
case eAward_ghast: return (Stat *) Achievements::ghast;
|
||||
case eAward_blazeRod: return (Stat *) Achievements::blazeRod;
|
||||
case eAward_potion: return (Stat *) Achievements::potion;
|
||||
@@ -180,7 +180,6 @@ Stat *CommonStats::get_achievement(eAward achievementId)
|
||||
case eAward_enchantments: return (Stat *) Achievements::enchantments;
|
||||
#endif
|
||||
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
case eAward_overkill: return (Stat *) Achievements::overkill; // Restored old ach.
|
||||
case eAward_bookcase: return (Stat *) Achievements::bookcase; // Restored old ach.
|
||||
|
||||
@@ -203,7 +202,6 @@ Stat *CommonStats::get_achievement(eAward achievementId)
|
||||
case eAward_ironMan: return (Stat *) Achievements::ironMan;
|
||||
case eAward_zombieDoctor: return (Stat *) Achievements::zombieDoctor;
|
||||
case eAward_lionTamer: return (Stat *) Achievements::lionTamer;
|
||||
#endif
|
||||
|
||||
default: return (Stat *) nullptr;
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ shared_ptr<ItemInstance> ContainerMenu::clicked(int slotIndex, int buttonNum, in
|
||||
{
|
||||
shared_ptr<ItemInstance> out = AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player, looped);
|
||||
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
|
||||
shared_ptr<LocalPlayer> localPlayer = dynamic_pointer_cast<LocalPlayer>(player);
|
||||
|
||||
if (localPlayer != nullptr) // 4J-JEV: For "Chestful o'Cobblestone" achievement.
|
||||
@@ -119,7 +119,6 @@ shared_ptr<ItemInstance> ContainerMenu::clicked(int slotIndex, int buttonNum, in
|
||||
localPlayer->awardStat(GenericStats::chestfulOfCobblestone(),GenericStats::param_chestfulOfCobblestone(cobblecount));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ const wstring CustomPayloadPacket::IDENTITY_TOKEN_RESPONSE = L"MC|CTResponse";
|
||||
|
||||
const wstring CustomPayloadPacket::FORK_HELLO_CHANNEL = L"MC|ForkHello";
|
||||
const wstring CustomPayloadPacket::FORK_PLAYER_LEAVE_CHANNEL = L"MC|ForkPLeave";
|
||||
const wstring CustomPayloadPacket::LCEN_HELLO_CHANNEL = L"MC|LCENHello";
|
||||
|
||||
CustomPayloadPacket::CustomPayloadPacket()
|
||||
: length(0)
|
||||
|
||||
@@ -30,6 +30,7 @@ public:
|
||||
// Fork extensions: server capability and player lifecycle
|
||||
static const wstring FORK_HELLO_CHANNEL; // server->client: identifies fork server (empty payload)
|
||||
static const wstring FORK_PLAYER_LEAVE_CHANNEL; // server->client: player disconnected (payload: UTF gamertag)
|
||||
static const wstring LCEN_HELLO_CHANNEL;
|
||||
|
||||
wstring identifier;
|
||||
int length;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "LevelData.h"
|
||||
#include "DirectoryLevelStorage.h"
|
||||
#include "ConsoleSaveFileIO.h"
|
||||
#include "../Minecraft.Client/Minecraft.h"
|
||||
|
||||
const wstring DirectoryLevelStorage::sc_szPlayerDir(L"players/");
|
||||
|
||||
@@ -391,6 +392,7 @@ void DirectoryLevelStorage::save(shared_ptr<Player> player)
|
||||
if( playerXuid != INVALID_XUID && !player->isGuest() )
|
||||
#endif
|
||||
{
|
||||
Minecraft::GetInstance()->forceStatsSave(player->getPlayerIndex());
|
||||
CompoundTag *tag = new CompoundTag();
|
||||
player->saveWithoutId(tag);
|
||||
#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
|
||||
|
||||
@@ -51,6 +51,9 @@ public:
|
||||
eDisconnect_ExitedGame,
|
||||
#endif
|
||||
eDisconnect_HardcoreDeath, // 4J Added - for hardcore mode multiplayer ban-on-death
|
||||
eDisconnect_LCENAuth, // 4J Added - for LCEN auth disconnect
|
||||
eDisconnect_LCENBanned, // 4J Added - for LCEN Banned
|
||||
eDisconnect_LCENServiceUnavailable, // 4J added - for LCEN Service Unavailable
|
||||
};
|
||||
|
||||
// 4J Stu - The reason was a string, but we need to send a non-locale specific reason
|
||||
|
||||
@@ -100,10 +100,10 @@ shared_ptr<ItemInstance> FurnaceMenu::quickMoveStack(shared_ptr<Player> player,
|
||||
slot->onQuickCraft(stack, clicked);
|
||||
|
||||
// 4J-JEV, hook for Durango achievement 'Renewable Energy'.
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
|
||||
if ( charcoalUsed && stack->getItem()->id == Item::coal_Id && stack->getAuxValue() == CoalItem::CHAR_COAL)
|
||||
player->awardStat(GenericStats::renewableEnergy(),GenericStats::param_renewableEnergy());
|
||||
#endif
|
||||
|
||||
}
|
||||
else if (slotIndex == FUEL_SLOT || slotIndex == INGREDIENT_SLOT)
|
||||
{
|
||||
@@ -164,13 +164,13 @@ shared_ptr<ItemInstance> FurnaceMenu::clicked(int slotIndex, int buttonNum, int
|
||||
|
||||
shared_ptr<ItemInstance> out = AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player, looped);
|
||||
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
|
||||
if ( charcoalUsed && (out!=nullptr) && (buttonNum==0 || buttonNum==1) && clickType==CLICK_PICKUP
|
||||
&& out->getItem()->id == Item::coal_Id && out->getAuxValue() == CoalItem::CHAR_COAL )
|
||||
{
|
||||
player->awardStat(GenericStats::renewableEnergy(),GenericStats::param_renewableEnergy());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@ Stat* GenericStats::overkill()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement( eAward_overkill );
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_overkill);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -367,7 +367,7 @@ Stat* GenericStats::bookcase()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement( eAward_bookcase );
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_bookcase);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -391,10 +391,10 @@ Stat* GenericStats::InToTheNether()
|
||||
return instance->get_achievement( eAward_InToTheNether );
|
||||
}
|
||||
|
||||
Stat* GenericStats::socialPost()
|
||||
{
|
||||
return instance->get_achievement( eAward_socialPost );
|
||||
}
|
||||
//Stat* GenericStats::socialPost()
|
||||
//{
|
||||
// return instance->get_achievement( eAward_socialPost );
|
||||
//}
|
||||
|
||||
Stat* GenericStats::eatPorkChop()
|
||||
{
|
||||
@@ -411,22 +411,22 @@ Stat* GenericStats::arrowKillCreeper()
|
||||
return instance->get_achievement( eAward_arrowKillCreeper );
|
||||
}
|
||||
|
||||
Stat* GenericStats::mine100Blocks()
|
||||
{
|
||||
return instance->get_achievement( eAward_mine100Blocks );
|
||||
}
|
||||
//Stat* GenericStats::mine100Blocks()
|
||||
//{
|
||||
// return instance->get_achievement( eAward_mine100Blocks );
|
||||
//}
|
||||
|
||||
Stat* GenericStats::kill10Creepers()
|
||||
{
|
||||
return instance->get_achievement( eAward_kill10Creepers );
|
||||
}
|
||||
//Stat* GenericStats::kill10Creepers()
|
||||
//{
|
||||
// return instance->get_achievement( eAward_kill10Creepers );
|
||||
//}
|
||||
|
||||
Stat* GenericStats::adventuringTime()
|
||||
{
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_adventuringTime);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_adventuringTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -435,7 +435,7 @@ Stat* GenericStats::repopulation()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_repopulation);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_repopulation);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -444,7 +444,7 @@ Stat* GenericStats::porkChop()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_eatPorkChop);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_eatPorkChop);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -453,7 +453,7 @@ Stat* GenericStats::diamondsToYou()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_diamondsToYou);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_diamondsToYou);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -462,7 +462,7 @@ Stat* GenericStats::passingTheTime()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_play100Days);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_play100Days);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -471,7 +471,7 @@ Stat* GenericStats::archer()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_arrowKillCreeper);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_arrowKillCreeper);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -480,7 +480,7 @@ Stat* GenericStats::theHaggler()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_theHaggler);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_theHaggler);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -489,7 +489,7 @@ Stat* GenericStats::potPlanter()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_potPlanter);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_potPlanter);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -498,7 +498,7 @@ Stat* GenericStats::itsASign()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_itsASign);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_itsASign);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -507,7 +507,7 @@ Stat* GenericStats::ironBelly()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_ironBelly);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_ironBelly);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -516,7 +516,7 @@ Stat* GenericStats::haveAShearfulDay()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_haveAShearfulDay);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_haveAShearfulDay);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -525,7 +525,7 @@ Stat* GenericStats::rainbowCollection()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_rainbowCollection);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_rainbowCollection);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -534,7 +534,7 @@ Stat* GenericStats::stayinFrosty()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_stayinFrosty);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_stayinFrosty);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -543,7 +543,7 @@ Stat* GenericStats::chestfulOfCobblestone()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_chestfulOfCobblestone);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_chestfulOfCobblestone);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ Stat* GenericStats::renewableEnergy()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_renewableEnergy);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_renewableEnergy);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -561,7 +561,7 @@ Stat* GenericStats::musicToMyEars()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_musicToMyEars);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_musicToMyEars);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -570,7 +570,7 @@ Stat* GenericStats::bodyGuard()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_bodyGuard);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_bodyGuard);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -579,7 +579,7 @@ Stat* GenericStats::ironMan()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_ironMan);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_ironMan);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -588,7 +588,7 @@ Stat* GenericStats::zombieDoctor()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_zombieDoctor);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_zombieDoctor);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -597,7 +597,7 @@ Stat* GenericStats::lionTamer()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->get_achievement(eAward_lionTamer);
|
||||
#else
|
||||
return nullptr;
|
||||
return instance->get_achievement(eAward_lionTamer);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -750,7 +750,7 @@ byteArray GenericStats::getParam_chestfulOfCobblestone(int cobbleStone)
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return getParam_achievement(eAward_chestfulOfCobblestone);
|
||||
#else
|
||||
return getParam_noArgs();
|
||||
return getParam_achievement(eAward_chestfulOfCobblestone);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -759,7 +759,7 @@ byteArray GenericStats::getParam_musicToMyEars(int recordId)
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return getParam_achievement(eAward_musicToMyEars);
|
||||
#else
|
||||
return getParam_noArgs();
|
||||
return getParam_achievement(eAward_musicToMyEars);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1057,7 +1057,7 @@ byteArray GenericStats::param_bookcase()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_bookcase);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_bookcase);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1081,10 +1081,10 @@ byteArray GenericStats::param_InToTheNether()
|
||||
return instance->getParam_achievement(eAward_InToTheNether);
|
||||
}
|
||||
|
||||
byteArray GenericStats::param_socialPost()
|
||||
{
|
||||
return instance->getParam_achievement(eAward_socialPost);
|
||||
}
|
||||
//byteArray GenericStats::param_socialPost()
|
||||
//{
|
||||
// return instance->getParam_achievement(eAward_socialPost);
|
||||
//}
|
||||
|
||||
byteArray GenericStats::param_eatPorkChop()
|
||||
{
|
||||
@@ -1101,22 +1101,21 @@ byteArray GenericStats::param_arrowKillCreeper()
|
||||
return instance->getParam_achievement(eAward_arrowKillCreeper);
|
||||
}
|
||||
|
||||
byteArray GenericStats::param_mine100Blocks()
|
||||
{
|
||||
return instance->getParam_achievement(eAward_mine100Blocks);
|
||||
}
|
||||
|
||||
byteArray GenericStats::param_kill10Creepers()
|
||||
{
|
||||
return instance->getParam_achievement(eAward_kill10Creepers);
|
||||
}
|
||||
|
||||
//byteArray GenericStats::param_mine100Blocks()
|
||||
//{
|
||||
// return instance->getParam_achievement(eAward_mine100Blocks);
|
||||
//}
|
||||
//
|
||||
//byteArray GenericStats::param_kill10Creepers()
|
||||
//{
|
||||
// return instance->getParam_achievement(eAward_kill10Creepers);
|
||||
//}
|
||||
byteArray GenericStats::param_adventuringTime()
|
||||
{
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_adventuringTime);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_adventuringTime);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1125,7 +1124,7 @@ byteArray GenericStats::param_repopulation()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_repopulation);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_repopulation);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1134,7 +1133,7 @@ byteArray GenericStats::param_porkChop()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_eatPorkChop);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_eatPorkChop);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1152,7 +1151,7 @@ byteArray GenericStats::param_passingTheTime()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_play100Days);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_play100Days);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1161,7 +1160,7 @@ byteArray GenericStats::param_archer()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_arrowKillCreeper);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_arrowKillCreeper);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1170,7 +1169,7 @@ byteArray GenericStats::param_theHaggler()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_theHaggler);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_theHaggler);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1179,7 +1178,7 @@ byteArray GenericStats::param_potPlanter()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_potPlanter);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_potPlanter);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1188,7 +1187,7 @@ byteArray GenericStats::param_itsASign()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_itsASign);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_itsASign);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1197,7 +1196,7 @@ byteArray GenericStats::param_ironBelly()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_ironBelly);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_ironBelly);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1206,7 +1205,7 @@ byteArray GenericStats::param_haveAShearfulDay()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_haveAShearfulDay);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_haveAShearfulDay);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1215,7 +1214,7 @@ byteArray GenericStats::param_rainbowCollection()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_rainbowCollection);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_rainbowCollection);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1224,7 +1223,7 @@ byteArray GenericStats::param_stayinFrosty()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_stayinFrosty);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_stayinFrosty);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1238,7 +1237,7 @@ byteArray GenericStats::param_renewableEnergy()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_renewableEnergy);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_renewableEnergy);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1261,7 +1260,7 @@ byteArray GenericStats::param_ironMan()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_ironMan);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_ironMan);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1270,7 +1269,7 @@ byteArray GenericStats::param_zombieDoctor()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_zombieDoctor);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_zombieDoctor);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1279,6 +1278,6 @@ byteArray GenericStats::param_lionTamer()
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
return instance->getParam_achievement(eAward_lionTamer);
|
||||
#else
|
||||
return instance->getParam_noArgs();
|
||||
return instance->getParam_achievement(eAward_lionTamer);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ shared_ptr<ItemInstance> InventoryMenu::clicked(int slotIndex, int buttonNum, in
|
||||
{
|
||||
shared_ptr<ItemInstance> out = AbstractContainerMenu::clicked(slotIndex, buttonNum, clickType, player, looped);
|
||||
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
|
||||
static int ironItems[4] = {Item::helmet_iron_Id,Item::chestplate_iron_Id,Item::leggings_iron_Id,Item::boots_iron_Id};
|
||||
for (int i = ARMOR_SLOT_START; i < ARMOR_SLOT_END; i++)
|
||||
{
|
||||
@@ -246,7 +246,7 @@ shared_ptr<ItemInstance> InventoryMenu::clicked(int slotIndex, int buttonNum, in
|
||||
}
|
||||
}
|
||||
player->awardStat(GenericStats::ironMan(),GenericStats::param_ironMan());
|
||||
#endif
|
||||
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -264,7 +264,7 @@ void ItemEntity::playerTouch(shared_ptr<Player> player)
|
||||
{
|
||||
player->awardStat(GenericStats::diamonds(), GenericStats::param_diamonds());
|
||||
|
||||
#ifdef _EXTENDED_ACHIEVEMENTS
|
||||
|
||||
if ( getItem()->getItem()->id )
|
||||
{
|
||||
shared_ptr<Player> pThrower = level->getPlayerByName(getThrower());
|
||||
@@ -273,7 +273,7 @@ void ItemEntity::playerTouch(shared_ptr<Player> player)
|
||||
pThrower->awardStat(GenericStats::diamondsToYou(), GenericStats::param_diamondsToYou());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
if (item->id == Item::blazeRod_Id)
|
||||
player->awardStat(GenericStats::blazeRod(), GenericStats::param_blazeRod());
|
||||
|
||||
@@ -42,6 +42,7 @@ LoginPacket::LoginPacket(const wstring& userName, int clientVersion, PlayerUID o
|
||||
{
|
||||
this->userName = userName;
|
||||
this->clientVersion = clientVersion;
|
||||
lcenToken = "";
|
||||
this->seed = 0;
|
||||
this->dimension = 0;
|
||||
this->gameType = 0;
|
||||
@@ -100,7 +101,34 @@ LoginPacket::LoginPacket(const wstring& userName, int clientVersion, LevelType *
|
||||
void LoginPacket::read(DataInputStream *dis) //throws IOException
|
||||
{
|
||||
clientVersion = dis->readInt();
|
||||
userName = readUtf(dis, Player::MAX_NAME_LENGTH);
|
||||
{
|
||||
wstring rawName = readUtf(dis, Player::MAX_NAME_LENGTH);
|
||||
const wstring prefix = L"LCEN:";
|
||||
if (rawName.size() > prefix.size() && rawName.substr(0, prefix.size()) == prefix)
|
||||
{
|
||||
wstring rest = rawName.substr(prefix.size());
|
||||
size_t sep = rest.find(L'|');
|
||||
if (sep != wstring::npos)
|
||||
{
|
||||
wstring wtoken = rest.substr(0, sep);
|
||||
userName = rest.substr(sep + 1);
|
||||
int len = WideCharToMultiByte(CP_UTF8, 0, wtoken.c_str(), -1, nullptr, 0, nullptr, nullptr);
|
||||
if (len > 1)
|
||||
{
|
||||
lcenToken.resize(len - 1);
|
||||
WideCharToMultiByte(CP_UTF8, 0, wtoken.c_str(), -1, &lcenToken[0], len, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
userName = rawName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
userName = rawName;
|
||||
}
|
||||
}
|
||||
wstring typeName = readUtf(dis, 16);
|
||||
m_pLevelType = LevelType::getLevelType(typeName);
|
||||
if (m_pLevelType == nullptr)
|
||||
@@ -139,7 +167,18 @@ void LoginPacket::read(DataInputStream *dis) //throws IOException
|
||||
void LoginPacket::write(DataOutputStream *dos) //throws IOException
|
||||
{
|
||||
dos->writeInt(clientVersion);
|
||||
writeUtf(userName, dos);
|
||||
if (!lcenToken.empty())
|
||||
{
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, lcenToken.c_str(), -1, nullptr, 0);
|
||||
wstring wtoken(wlen > 1 ? wlen - 1 : 0, L'\0');
|
||||
if (wlen > 1)
|
||||
MultiByteToWideChar(CP_UTF8, 0, lcenToken.c_str(), -1, &wtoken[0], wlen);
|
||||
writeUtf(L"LCEN:" + wtoken + L"|" + userName, dos);
|
||||
}
|
||||
else
|
||||
{
|
||||
writeUtf(userName, dos);
|
||||
}
|
||||
if (m_pLevelType == nullptr)
|
||||
{
|
||||
writeUtf(L"", dos);
|
||||
|
||||
@@ -25,6 +25,7 @@ public:
|
||||
int m_xzSize; // 4J Added
|
||||
int m_hellScale; // 4J Added
|
||||
bool m_isHardcore; // 4J Added - for hardcore mode
|
||||
std::string lcenToken; // LCEN auth token, empty string if not present
|
||||
|
||||
// 1.8.2
|
||||
int gameType;
|
||||
@@ -43,4 +44,4 @@ public:
|
||||
public:
|
||||
static shared_ptr<Packet> create() { return std::make_shared<LoginPacket>(); }
|
||||
virtual int getId() { return 1; }
|
||||
};
|
||||
};
|
||||
@@ -2486,10 +2486,10 @@ void Player::startUsingItem(shared_ptr<ItemInstance> instance, int duration)
|
||||
awardStat(GenericStats::itemsUsed(instance->getItem()->id),
|
||||
GenericStats::param_itemsUsed(dynamic_pointer_cast<Player>(shared_from_this()),instance));
|
||||
|
||||
#if (!defined _DURANGO) && (defined _EXTENDED_ACHIEVEMENTS)
|
||||
|
||||
if ( (instance->getItem()->id == Item::rotten_flesh_Id) && (getFoodData()->getFoodLevel() == 0) )
|
||||
awardStat(GenericStats::ironBelly(), GenericStats::param_ironBelly());
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
bool Player::mayDestroyBlockAt(int x, int y, int z)
|
||||
|
||||
@@ -23,9 +23,9 @@ vector<ItemStat *> *Stats::blocksMinedStats = new vector<ItemStat *>;
|
||||
vector<ItemStat *> *Stats::itemsCollectedStats = new vector<ItemStat *>;
|
||||
vector<ItemStat *> *Stats::itemsCraftedStats = new vector<ItemStat *>;
|
||||
|
||||
#if (defined _EXTENDED_ACHIEVEMENTS) && (!defined _DURANGO)
|
||||
|
||||
vector<ItemStat *> *Stats::blocksPlacedStats = new vector<ItemStat *>;
|
||||
#endif
|
||||
|
||||
|
||||
Stat *Stats::walkOneM = nullptr;
|
||||
Stat *Stats::swimOneM = nullptr;
|
||||
@@ -56,11 +56,11 @@ StatArray Stats::blocksMined;
|
||||
StatArray Stats::itemsCollected;
|
||||
StatArray Stats::itemsCrafted;
|
||||
|
||||
#if (defined _EXTENDED_ACHIEVEMENTS) && (!defined _DURANGO)
|
||||
|
||||
StatArray Stats::blocksPlaced;
|
||||
StatArray Stats::rainbowCollection;
|
||||
StatArray Stats::biomesVisisted;
|
||||
#endif
|
||||
|
||||
|
||||
Stat *Stats::killsEnderdragon = nullptr; // The number of times this player has dealt the killing blow to the Enderdragon
|
||||
Stat *Stats::completeTheEnd = nullptr; // The number of times this player has been present when the Enderdragon has died
|
||||
@@ -473,7 +473,7 @@ void Stats::buildAdditionalStats()
|
||||
Stats::completeTheEnd = (new GeneralStat(offset++, L"stat.completeTheEnd"))->postConstruct();
|
||||
|
||||
|
||||
#if (defined _EXTENDED_ACHIEVEMENTS) && (!defined _DURANGO)
|
||||
|
||||
{
|
||||
ItemStat *itemStat = new ItemStat(offset++, L"craftItem.flowerPot", Item::flowerPot_Id);
|
||||
itemsCraftedStats->push_back(itemStat);
|
||||
@@ -547,7 +547,6 @@ void Stats::buildAdditionalStats()
|
||||
blocksPlaced[itemStat->getItemId()] = itemStat;
|
||||
itemStat->postConstruct();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,9 @@ public:
|
||||
static vector<ItemStat *> *itemsCollectedStats;
|
||||
static vector<ItemStat *> *itemsCraftedStats;
|
||||
|
||||
#if (defined _EXTENDED_ACHIEVEMENTS) && (!defined _DURANGO)
|
||||
|
||||
static vector<ItemStat *> *blocksPlacedStats;
|
||||
#endif
|
||||
|
||||
|
||||
static Stat *walkOneM;
|
||||
static Stat *swimOneM;
|
||||
static Stat *fallOneM;
|
||||
@@ -60,18 +59,15 @@ public:
|
||||
static StatArray itemsCollected;
|
||||
static StatArray itemsCrafted;
|
||||
|
||||
#if (defined _EXTENDED_ACHIEVEMENTS) && (!defined _DURANGO)
|
||||
static StatArray blocksPlaced;
|
||||
#endif
|
||||
|
||||
// Added TU9
|
||||
static Stat *killsEnderdragon; // The number of times this player has dealt the killing blow to the Enderdragon
|
||||
static Stat *completeTheEnd; // The number of times this player has been present when the Enderdragon has died
|
||||
|
||||
#if (defined _EXTENDED_ACHIEVEMENTS) && (!defined _DURANGO)
|
||||
|
||||
static StatArray biomesVisisted;
|
||||
static StatArray rainbowCollection;
|
||||
#endif
|
||||
|
||||
static void staticCtor();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user