From a1ca247843e9547a29753f160222de8973919554 Mon Sep 17 00:00:00 2001 From: qloak Date: Tue, 14 Jul 2026 13:30:42 -0700 Subject: [PATCH 01/12] fix: fixed name tag Y-position for tall mobs (wither, iron golem, wither skeleton) --- Minecraft.Client/LivingEntityRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/LivingEntityRenderer.cpp b/Minecraft.Client/LivingEntityRenderer.cpp index 9e8682c7..7f4a3258 100644 --- a/Minecraft.Client/LivingEntityRenderer.cpp +++ b/Minecraft.Client/LivingEntityRenderer.cpp @@ -491,7 +491,7 @@ void LivingEntityRenderer::renderNameTag(shared_ptr mob, const wst float s = 1 / 60.0f * size; glPushMatrix(); - glTranslatef((float) x, (float) y + 2.3f, (float) z); + glTranslatef((float) x, (float) y + mob->bbHeight + 0.5f, (float) z); glNormal3f(0, 1, 0); glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0); -- 2.54.0 From 22bcbde6a30fd99770d45a8c4aa40449b806e033 Mon Sep 17 00:00:00 2001 From: qloak Date: Tue, 14 Jul 2026 21:42:19 +0100 Subject: [PATCH 02/12] fix(TU20): fixed name tag Y-position for tall mobs (wither, iron golem, wither skeleton) (#4) title Reviewed-on: https://git.neolegacy.dev/pieeebot/mc_pieLCE/pulls/4 Co-authored-by: qloak Co-committed-by: qloak --- Minecraft.Client/LivingEntityRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/LivingEntityRenderer.cpp b/Minecraft.Client/LivingEntityRenderer.cpp index 9e8682c7..7f4a3258 100644 --- a/Minecraft.Client/LivingEntityRenderer.cpp +++ b/Minecraft.Client/LivingEntityRenderer.cpp @@ -491,7 +491,7 @@ void LivingEntityRenderer::renderNameTag(shared_ptr mob, const wst float s = 1 / 60.0f * size; glPushMatrix(); - glTranslatef((float) x, (float) y + 2.3f, (float) z); + glTranslatef((float) x, (float) y + mob->bbHeight + 0.5f, (float) z); glNormal3f(0, 1, 0); glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0); -- 2.54.0 From 636bf0b692b34b0c24df026439b832378fa1b932 Mon Sep 17 00:00:00 2001 From: piebot Date: Wed, 15 Jul 2026 00:13:08 +0300 Subject: [PATCH 03/12] fix(TU20): TNT minecart exploding despite 'TNT Explodes' option being turned off. --- Minecraft.World/MinecartTNT.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.World/MinecartTNT.cpp b/Minecraft.World/MinecartTNT.cpp index 3a78eab1..2ea6c84e 100644 --- a/Minecraft.World/MinecartTNT.cpp +++ b/Minecraft.World/MinecartTNT.cpp @@ -77,7 +77,7 @@ void MinecartTNT::destroy(DamageSource *source) void MinecartTNT::explode(double speedSqr) { - if (!level->isClientSide) + if (!level->isClientSide && app.GetGameHostOption(eGameHostOption_TNT)) { double speed = sqrt(speedSqr); if (speed > 5) speed = 5; @@ -121,7 +121,7 @@ void MinecartTNT::primeFuse() { fuse = 80; - if (!level->isClientSide) + if (!level->isClientSide && app.GetGameHostOption(eGameHostOption_TNT)) { level->broadcastEntityEvent(shared_from_this(), EVENT_PRIME); level->playEntitySound(shared_from_this(), eSoundType_RANDOM_FUSE, 1, 1.0f); -- 2.54.0 From d236b70546a1fbe54eecf9e67929520db5e117fd Mon Sep 17 00:00:00 2001 From: piebot Date: Wed, 15 Jul 2026 14:57:35 +0300 Subject: [PATCH 04/12] fix(TU20): Noteblock fall-off distance so they can be heard further away. --- Minecraft.World/NoteBlockTile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.World/NoteBlockTile.cpp b/Minecraft.World/NoteBlockTile.cpp index 5003cd8c..e13fbdee 100644 --- a/Minecraft.World/NoteBlockTile.cpp +++ b/Minecraft.World/NoteBlockTile.cpp @@ -79,7 +79,7 @@ bool NoteBlockTile::triggerEvent(Level *level, int x, int y, int z, int i, int n break; } app.DebugPrintf("NoteBlockTile::triggerEvent - playSound - pitch = %f\n",pitch); - level->playSound(x + 0.5, y + 0.5, z + 0.5, iSound, 3, pitch); + level->playSound(x + 0.5, y + 0.5, z + 0.5, iSound, 3, pitch, 64.0); level->addParticle(eParticleType_note, x + 0.5, y + 1.2, z + 0.5, note / 24.0, 0, 0); return true; -- 2.54.0 From e1508731d0ef40aa17aeecbedc33f1f78643c3a8 Mon Sep 17 00:00:00 2001 From: qloak Date: Wed, 15 Jul 2026 13:15:45 +0100 Subject: [PATCH 05/12] fix(TU20): more TU20 bug fixes TU20: Fixed issue where name tags do not appear to work correctly on the wither, iron golems, and wither skeletons. Fix for issue where creepers hover off the floor. --------- Co-authored-by: pieeebot <10+pieeebot@noreply.neolegacy.dev> Reviewed-on: https://git.neolegacy.dev/pieeebot/mc_pieLCE/pulls/5 Co-authored-by: qloak Co-committed-by: qloak --- Minecraft.Client/CreeperModel.cpp | 2 +- Minecraft.World/AttackDamageMobEffect.cpp | 36 +++++++++++------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Minecraft.Client/CreeperModel.cpp b/Minecraft.Client/CreeperModel.cpp index 066e0b55..14c7e55f 100644 --- a/Minecraft.Client/CreeperModel.cpp +++ b/Minecraft.Client/CreeperModel.cpp @@ -6,7 +6,7 @@ // 4J - added void CreeperModel::_init(float g) { - int yo = 4; + int yo = 6; head = new ModelPart(this, 0, 0); head->addBox(-4, - 8, -4, 8, 8, 8, g); // Head diff --git a/Minecraft.World/AttackDamageMobEffect.cpp b/Minecraft.World/AttackDamageMobEffect.cpp index 483c9a72..00ab0f95 100644 --- a/Minecraft.World/AttackDamageMobEffect.cpp +++ b/Minecraft.World/AttackDamageMobEffect.cpp @@ -1,19 +1,19 @@ -#include "stdafx.h" - -#include "AttackDamageMobEffect.h" - -AttackDamageMobEffect::AttackDamageMobEffect(int id, bool isHarmful, eMinecraftColour color) : MobEffect(id, isHarmful, color) -{ -} - -double AttackDamageMobEffect::getAttributeModifierValue(int amplifier, AttributeModifier *original) -{ - if (id == MobEffect::weakness->id) - { - return -0.5f * (amplifier + 1); - } - else - { - return 1.3 * (amplifier + 1); - } +#include "stdafx.h" + +#include "AttackDamageMobEffect.h" + +AttackDamageMobEffect::AttackDamageMobEffect(int id, bool isHarmful, eMinecraftColour color) : MobEffect(id, isHarmful, color) +{ +} + +double AttackDamageMobEffect::getAttributeModifierValue(int amplifier, AttributeModifier *original) +{ + if (id == MobEffect::weakness->id) + { + return -0.5f * (amplifier + 1); + } + else + { + return 1.3 * (amplifier + 1); + } } \ No newline at end of file -- 2.54.0 From 4e2369f1943742568a4e8c9b2ca9194179307dda Mon Sep 17 00:00:00 2001 From: str1k3r <115313679+S1l3ntStr1ke87@users.noreply.github.com> Date: Wed, 15 Jul 2026 09:00:52 -0400 Subject: [PATCH 06/12] fix(Orbis): Leaderboard manager Make the Orbis Leaderboard manager work with the new Sony Leaderboard manager --- .../Leaderboards/OrbisLeaderboardManager.cpp | 1073 +---------------- .../Leaderboards/OrbisLeaderboardManager.h | 105 +- 2 files changed, 42 insertions(+), 1136 deletions(-) diff --git a/Minecraft.Client/Orbis/Leaderboards/OrbisLeaderboardManager.cpp b/Minecraft.Client/Orbis/Leaderboards/OrbisLeaderboardManager.cpp index 7ddc6607..97340420 100644 --- a/Minecraft.Client/Orbis/Leaderboards/OrbisLeaderboardManager.cpp +++ b/Minecraft.Client/Orbis/Leaderboards/OrbisLeaderboardManager.cpp @@ -2,11 +2,10 @@ #include "OrbisLeaderboardManager.h" -#include "base64.h" - #include "..\Orbis_App.h" -#include "..\..\Common\Consoles_App.h" +#include "Orbis\OrbisExtras\ShutdownManager.h" +#include "..\..\Common\Consoles_App.h" #include "Common\Network\Sony\SQRNetworkManager.h" #include "..\..\..\Minecraft.World\StringHelpers.h" @@ -14,1068 +13,52 @@ #include #include -//#include - -#include "Orbis\OrbisExtras\ShutdownManager.h" - LeaderboardManager *LeaderboardManager::m_instance = new OrbisLeaderboardManager(); //Singleton instance of the LeaderboardManager -OrbisLeaderboardManager::OrbisLeaderboardManager() +OrbisLeaderboardManager::OrbisLeaderboardManager() : SonyLeaderboardManager() {} + +HRESULT OrbisLeaderboardManager::initialiseScoreUtility() { - m_eStatsState = eStatsState_Idle; - - m_titleContext = -1; - - m_myXUID = INVALID_XUID; - - m_scores = NULL; //m_stats = NULL; - - m_statsType = eStatsType_Kills; - m_difficulty = 0; - - m_requestId = 0; - - m_openSessions = 0; - - InitializeCriticalSection(&m_csViewsLock); - - m_running = false; - m_threadScoreboard = NULL; + return SCE_OK; } -OrbisLeaderboardManager::~OrbisLeaderboardManager() -{ - m_running = false; - - // 4J-JEV: Wait for thread to stop and hope it doesn't take too long. - long long startShutdown = System::currentTimeMillis(); - while (m_threadScoreboard->isRunning()) - { - Sleep(1); - assert( (System::currentTimeMillis() - startShutdown) < 16 ); - } - - delete m_threadScoreboard; - - DeleteCriticalSection(&m_csViewsLock); +bool OrbisLeaderboardManager::scoreUtilityAlreadyInitialised(HRESULT hr) +{ + return hr == SCE_NP_COMMUNITY_ERROR_ALREADY_INITIALIZED; } -int OrbisLeaderboardManager::scoreboardThreadEntry(LPVOID lpParam) -{ - ShutdownManager::HasStarted(ShutdownManager::eLeaderboardThread); - OrbisLeaderboardManager *self = reinterpret_cast(lpParam); - - self->m_running = true; - app.DebugPrintf("[LeaderboardManager] Thread started.\n"); - - bool needsWriting = false; - do - { - if (self->m_openSessions > 0 || needsWriting) - { - self->scoreboardThreadInternal(); - } - - EnterCriticalSection(&self->m_csViewsLock); - needsWriting = self->m_views.size() > 0; - LeaveCriticalSection(&self->m_csViewsLock); - - // 4J Stu - We can't write while we aren't signed in to live - if (!ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad())) - { - needsWriting = false; - } - - if ( (!needsWriting) && (self->m_eStatsState != eStatsState_Getting) ) - { - Sleep(50); // 4J-JEV: When we're not reading or writing. - } - - } while ( (self->m_running || self->m_eStatsState == eStatsState_Getting || needsWriting) - && ShutdownManager::ShouldRun(ShutdownManager::eLeaderboardThread) - ); - - // 4J-JEV, moved this here so setScore can finish up. - sceNpScoreDestroyTitleCtx(self->m_titleContext); - // TODO sceNpScoreTerm(); - app.DebugPrintf("[LeaderboardManager] Thread closed.\n"); - ShutdownManager::HasFinished(ShutdownManager::eLeaderboardThread); - return 0; +HRESULT OrbisLeaderboardManager::createTitleContext(const SceNpId &npId) +{ + return sceNpScoreCreateNpTitleCtx(0, &npId); } -void OrbisLeaderboardManager::scoreboardThreadInternal() +HRESULT OrbisLeaderboardManager::destroyTitleContext(int titleContext) { - // 4J-JEV: Just initialise the context the once now. - if (m_titleContext == -1) - { - int primaryPad = ProfileManager.GetPrimaryPad(); - - if (!ProfileManager.IsSignedInLive(primaryPad)) return; - - SceNpId npId; - ProfileManager.GetSceNpId(primaryPad,&npId); - - int ret = sceNpScoreCreateNpTitleCtx(primaryPad, &npId); - - if (ret < 0) return; - else m_titleContext = ret; - } - else assert( m_titleContext > 0 ); //Paranoia - - - switch (m_eStatsState) - { - case eStatsState_Getting: - // Player starts using async multiplayer feature - // 4J-PB - Fix for SCEA FQA #4 - TRC R4064 - Incorrect usage of AsyncMultiplay - // Note 1: - // The following NP call should be reserved for asynchronous multiplayer modes that require PS Plus to be accessed. - // - // Note 2: - // The message is not displayed with a user without PlayStation®Plus subscription and they are able to access the Leaderboards. - - // NotifyAsyncPlusFeature(); - - switch(m_eFilterMode) - { - case eFM_MyScore: - case eFM_Friends: - getScoreByIds(); - break; - case eFM_TopRank: - getScoreByRange(); - break; - } - break; - - case eStatsState_Canceled: - case eStatsState_Failed: - case eStatsState_Ready: - case eStatsState_Idle: - - // 4J-JEV: Moved this here, I don't want reading and - // writing going on at the same time. - // -- - // 4J-JEV: Writing no longer changes the manager state, - // we'll manage the write queue seperately. - - EnterCriticalSection(&m_csViewsLock); - bool hasWork = !m_views.empty(); - LeaveCriticalSection(&m_csViewsLock); - - if (hasWork) - { - setScore(); - } - - break; - } + return sceNpScoreDestroyTitleCtx(titleContext); } -bool OrbisLeaderboardManager::getScoreByIds() -{ - if (m_eStatsState == eStatsState_Canceled) return false; - - // ---------------------------- - SceRtcTick last_sort_date; - SceNpScoreRankNumber mTotalRecord; - - SceNpId *npIds = NULL; - - - int ret; - uint32_t num = 0; - - SceNpScorePlayerRankData *ptr; - SceNpScoreComment *comments; - // ---------------------------- - - // Check for invalid LManager state. - assert( m_eFilterMode == eFM_Friends - || m_eFilterMode == eFM_MyScore); - - SceNpId myNpId; - // 4J-PB - should it be user 0? - if(!ProfileManager.IsSignedInLive(0)) - { - app.DebugPrintf("[LeaderboardManager] OpenSession() fail: User isn't signed in to PSN\n"); - return false; - } - ProfileManager.GetSceNpId(0,&myNpId); - - // Get queried users. - if (m_eFilterMode == eFM_Friends) - { - - sce::Toolkit::NP::Utilities::Future s_friendList; - sce::Toolkit::NP::FriendInfoRequest request; - - memset(&request, 0, sizeof(request)); - request.userInfo.userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad()); - request.flag = SCE_TOOLKIT_NP_FRIENDS_LIST_ALL; - ret = sce::Toolkit::NP::Friends::Interface::getFriendslist(&s_friendList, &request, false); - - if(ret != SCE_TOOLKIT_NP_SUCCESS) - { - // Error handling - if (m_eStatsState != eStatsState_Canceled) m_eStatsState = eStatsState_Failed; - app.DebugPrintf("[LeaderboardManager] getFriendslist fail\n"); - return false; - } - else if (s_friendList.hasResult()) - { - // 4J-JEV: Friends list doesn't include player, leave space for them. - num = s_friendList.get()->size() + 1; - - npIds = new SceNpId[num]; - - int i = 0; - - sce::Toolkit::NP::FriendsList::const_iterator itr; - for (itr = s_friendList.get()->begin(); itr != s_friendList.get()->end(); itr++) - { - npIds[i] = itr->npid; - i++; - } - - npIds[num-1] = myNpId; // 4J-JEV: Append player to end of query. - } - else - { - // 4J-JEV: Something terrible must have happend, - // 'getFriendslist' was supposed to be a synchronous operation. - __debugbreak(); - - // 4J-JEV: We can at least fall-back to just the players score. - num = 1; - npIds = new SceNpId[1]; - npIds[0] = myNpId; - } - } - else if (m_eFilterMode == eFM_MyScore) - { - num = 1; - npIds = new SceNpId[1]; - npIds[0] = myNpId; - } - - ptr = new SceNpScorePlayerRankData[num]; - comments = new SceNpScoreComment[num]; - - ZeroMemory(ptr, sizeof(SceNpScorePlayerRankData) * num); - ZeroMemory(comments, sizeof(SceNpScoreComment) * num); - - /* app.DebugPrintf("sceNpScoreGetRankingByNpId(\n\t transaction=%i,\n\t boardID=0,\n\t npId=%i,\n\t friendCount*sizeof(SceNpId)=%i*%i=%i,\ - rankData=%i,\n\t friendCount*sizeof(SceNpScorePlayerRankData)=%i,\n\t NULL, 0, NULL, 0,\n\t friendCount=%i,\n...\n", - transaction, npId, friendCount, sizeof(SceNpId), friendCount*sizeof(SceNpId), - rankData, friendCount*sizeof(SceNpScorePlayerRankData), friendCount - ); */ - - int boardId = getBoardId(m_difficulty, m_statsType); - - for (int batch=0; batchrankData.scoreValue - ); - - // Sort scores - std::sort(m_scores, m_scores + m_readCount, SortByRank); - - delete [] ptr; - delete [] comments; - delete [] npIds; - - m_eStatsState = eStatsState_Ready; - return true; - - // Error. -error3: - if (ret!=SCE_NP_COMMUNITY_ERROR_ABORTED) //0x8002a109 - sceNpScoreDestroyTransactionCtx(m_requestId); - m_requestId = 0; - delete [] ptr; - delete [] comments; -error2: - if (npIds != NULL) delete [] npIds; -error1: - if (m_eStatsState != eStatsState_Canceled) m_eStatsState = eStatsState_Failed; - app.DebugPrintf("[LeaderboardManger] getScoreByIds() FAILED, ret=0x%X\n", ret); - return false; +HRESULT OrbisLeaderboardManager::createTransactionContext(int titleContext) +{ + return sceNpScoreCreateTransactionCtx(titleContext); } -bool OrbisLeaderboardManager::getScoreByRange() -{ - SceRtcTick last_sort_date; - SceNpScoreRankNumber mTotalRecord; - - unsigned int num = m_readCount; - SceNpScoreRankData *ptr; - SceNpScoreComment *comments; - - assert(m_eFilterMode == eFM_TopRank); - - int ret = sceNpScoreCreateTransactionCtx(m_titleContext); - if (m_eStatsState == eStatsState_Canceled) - { - // Cancel operation has been called, abort. - app.DebugPrintf("[LeaderboardManager]\tgetScoreByRange() - m_eStatsState == eStatsState_Canceled.\n"); - sceNpScoreDestroyTransactionCtx(ret); - return false; - } - else if (ret < 0) - { - // Error occurred creating a transacion, abort. - m_eStatsState = eStatsState_Failed; - app.DebugPrintf("[LeaderboardManager]\tgetScoreByRange() - createTransaction failed, ret=0x%X\n", ret); - return false; - } - else - { - // Transaction created successfully, continue. - m_requestId = ret; - } - - ptr = new SceNpScoreRankData[num]; - comments = new SceNpScoreComment[num]; - - int boardId = getBoardId(m_difficulty, m_statsType); - ret = sceNpScoreGetRankingByRange( - m_requestId, - boardId, // BoardId - - m_startIndex, - - ptr, sizeof(SceNpScoreRankData) * num, //OUT: Rank Data - - comments, sizeof(SceNpScoreComment) * num, //OUT: Comment Data - - NULL, 0, // GameData. - - num, - - &last_sort_date, - &m_maxRank, // 'Total number of players registered in the target scoreboard.' - - NULL // Reserved, specify null. - ); - - if (ret == SCE_NP_COMMUNITY_ERROR_ABORTED) - { - ret = sceNpScoreDestroyTransactionCtx(m_requestId); - app.DebugPrintf("[LeaderboardManager] getScoreByRange(): 'sceNpScoreGetRankingByRange' aborted (0x%X).\n", ret); - - delete [] ptr; - delete [] comments; - - return false; - } - else if (ret == SCE_NP_COMMUNITY_SERVER_ERROR_GAME_RANKING_NOT_FOUND) - { - ret = sceNpScoreDestroyTransactionCtx(m_requestId); - app.DebugPrintf("[LeaderboardManager] getScoreByRange(): Game ranking not found."); - - delete [] ptr; - delete [] comments; - - m_scores = NULL; - m_readCount = 0; - - m_eStatsState = eStatsState_Ready; - return false; - } - else if (ret<0) goto error2; - else - { - app.DebugPrintf("[LeaderboardManager] getScoreByRange(), success, 1stScore=%i.\n", ptr->scoreValue); - } - - // Return. - sceNpScoreDestroyTransactionCtx(m_requestId); - m_requestId = 0; - - //m_stats = ptr; //Maybe: addPadding(num,ptr); - - if (m_scores != NULL) delete [] m_scores; - m_readCount = ret; - m_scores = new ReadScore[m_readCount]; - for (int i=0; i &friendsList) { - ReadView view; - - switch( m_eStatsState ) - { - case eStatsState_Ready: - { - assert(m_scores != NULL || m_readCount == 0); - - view.m_numQueries = m_readCount; - view.m_queries = m_scores; - - // 4J-JEV: Debugging. - //LeaderboardManager::printStats(view); - - eStatsReturn ret = eStatsReturn_NoResults; - if (view.m_numQueries > 0) - ret = eStatsReturn_Success; - - if (m_readListener != NULL) - { - app.DebugPrintf("[LeaderboardManager] OnStatsReadComplete(%i, %i, _), m_readCount=%i.\n", ret, m_maxRank, m_readCount); - m_readListener->OnStatsReadComplete(ret, m_maxRank, view); - } - - m_eStatsState = eStatsState_Idle; - - delete [] m_scores; - m_scores = NULL; - } - break; - - case eStatsState_Failed: - { - view.m_numQueries = 0; - view.m_queries = NULL; - - if ( m_readListener != NULL ) - m_readListener->OnStatsReadComplete(eStatsReturn_NetworkError, 0, view); - - m_eStatsState = eStatsState_Idle; - } - break; - - case eStatsState_Canceled: - { - m_eStatsState = eStatsState_Idle; - } - break; - - default: // Getting or Idle. - break; - } + return sce::Toolkit::NP::Friends::Interface::getFriendslist(&friendsList, false); } -bool OrbisLeaderboardManager::OpenSession() +char *OrbisLeaderboardManager::getComment(SceNpScoreComment *comment) { - if (m_openSessions == 0) - { - if (m_threadScoreboard == NULL) - { - m_threadScoreboard = new C4JThread(&scoreboardThreadEntry, this, "4JScoreboard"); - m_threadScoreboard->SetProcessor(CPU_CORE_LEADERBOARDS); - m_threadScoreboard->SetPriority(THREAD_PRIORITY_BELOW_NORMAL); - m_threadScoreboard->Run(); - } - - app.DebugPrintf("[LeaderboardManager] OpenSession(): Starting sceNpScore utility.\n"); - } - else - { - app.DebugPrintf("[LeaderboardManager] OpenSession(): Another session opened, total=%i\n", m_openSessions+1); - } - - m_openSessions++; - return true; -} - -void OrbisLeaderboardManager::CloseSession() -{ - m_openSessions--; - - if (m_openSessions == 0) app.DebugPrintf("[LeaderboardManager] CloseSession(): Quitting sceNpScore utility.\n"); - else app.DebugPrintf("[LeaderboardManager] CloseSession(): %i sessions still open.\n", m_openSessions); -} - -void OrbisLeaderboardManager::DeleteSession() {} - -bool OrbisLeaderboardManager::WriteStats(unsigned int viewCount, ViewIn views) -{ - // Need to cancel read/write operation first. - //if (m_eStatsState != eStatsState_Idle) return false; - - // Write relevant parameters. - //RegisterScore *regScore = reinterpret_cast(views); - - EnterCriticalSection(&m_csViewsLock); - for (int i=0; iutf8Comment; - - for (int i = 0; i < SCE_NP_SCORE_COMMENT_MAXLEN; i++) - { - int sByte = (i*5) / 8; - int eByte = (5+(i*5)) / 8; - int dIndex = (i*5) % 8; - - unsigned char fivebits = 0; - - fivebits = *(bytes+sByte) << dIndex; - - if (eByte != sByte) - fivebits = fivebits | *(bytes+eByte) >> (8-dIndex); - - fivebits = (fivebits>>3) & 0x1F; - - if (fivebits < 10) // 0 - 9 - chars[i] = '0' + fivebits; - else if (fivebits < 32) // A - V - chars[i] = 'A' + (fivebits-10); - else - assert(false); - } - - toSymbols(out->utf8Comment); -} - -void OrbisLeaderboardManager::fromBase32(void *out, SceNpScoreComment *in) -{ - PBYTE bytes = (PBYTE) out; - ZeroMemory(bytes, RECORD_SIZE); - - fromSymbols(in->utf8Comment); - - char ch[2] = { 0, 0 }; - for (int i = 0; i < SCE_NP_SCORE_COMMENT_MAXLEN; i++) - { - ch[0] = in->utf8Comment[i]; - unsigned char fivebits = strtol(ch, NULL, 32) << 3; - - int sByte = (i*5) / 8; - int eByte = (5+(i*5)) / 8; - int dIndex = (i*5) % 8; - - *(bytes + sByte) = *(bytes+sByte) | (fivebits >> dIndex); - - if (eByte != sByte) - *(bytes + eByte) = fivebits << (8-dIndex); - } -} - -char symbBase32[32] = { - ' ', '!','\"', '#', '$', '%', '&','\'', '(', ')', - '*', '+', '`', '-', '.', '/', ':', ';', '<', '=', - '>', '?', '[','\\', ']', '^', '_', '{', '|', '}', - '~', '@' -}; - -char charBase32[32] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V' -}; - -void OrbisLeaderboardManager::toSymbols(char *str) -{ - for (int i = 0; i < 63; i++) - { - for (int j=0; j < 32; j++) - { - if (str[i]==charBase32[j]) - str[i] =symbBase32[j]; - } - } -} - -void OrbisLeaderboardManager::fromSymbols(char *str) -{ - for (int i = 0; i < 63; i++) - { - for (int j=0; j < 32; j++) - { - if (str[i]==symbBase32[j]) - str[i] =charBase32[j]; - } - } -} - -bool OrbisLeaderboardManager::test_string(string testing) -{ -#ifndef _CONTENT_PACKAGE - static SceNpScoreComment comment; - ZeroMemory(&comment, sizeof(SceNpScoreComment)); - memcpy(&comment, testing.c_str(), SCE_NP_SCORE_COMMENT_MAXLEN); - - int ctx = sceNpScoreCreateTransactionCtx(m_titleContext); - if (ctx<0) return false; - - int ret = sceNpScoreCensorComment(ctx, (const char *) &comment, NULL); - - if (ret == SCE_NP_COMMUNITY_SERVER_ERROR_CENSORED) - { - app.DebugPrintf("\n[TEST_STRING]: REJECTED "); - } - else if (ret < 0) - { - sceNpScoreDestroyTransactionCtx(ctx); - return false; - } - else - { - app.DebugPrintf("\n[TEST_STRING]: permitted "); - } - - app.DebugPrintf("'%s'\n", comment.utf8Comment); - sceNpScoreDestroyTransactionCtx(ctx); - return true; -#else - return true; -#endif -} - -void OrbisLeaderboardManager::initReadScoreStruct(ReadScore &out, SceNpScoreRankData &rankData) -{ - ZeroMemory(&out, sizeof(ReadScore)); - - // Init rank and onlineID - out.m_uid.setOnlineID( rankData.npId.handle, true ); - out.m_rank = rankData.rank; - - // Convert to wstring and copy name. - wstring wstrName = convStringToWstring( string(rankData.npId.handle.data) ).c_str(); - //memcpy(&out.m_name, wstrName.c_str(), XUSER_NAME_SIZE); - out.m_name=wstrName; -} - -void OrbisLeaderboardManager::fillReadScoreStruct(ReadScore &out, SceNpScoreComment &comment) -{ - StatsData statsData; - fromBase32( (void *) &statsData, &comment ); - - switch (statsData.m_statsType) - { - case eStatsType_Farming: - out.m_statsSize = 6; - out.m_statsData[0] = statsData.m_farming.m_eggs; - out.m_statsData[1] = statsData.m_farming.m_wheat; - out.m_statsData[2] = statsData.m_farming.m_mushroom; - out.m_statsData[3] = statsData.m_farming.m_sugarcane; - out.m_statsData[4] = statsData.m_farming.m_milk; - out.m_statsData[5] = statsData.m_farming.m_pumpkin; - break; - case eStatsType_Mining: - out.m_statsSize = 7; - out.m_statsData[0] = statsData.m_mining.m_dirt; - out.m_statsData[1] = statsData.m_mining.m_cobblestone; - out.m_statsData[2] = statsData.m_mining.m_sand; - out.m_statsData[3] = statsData.m_mining.m_stone; - out.m_statsData[4] = statsData.m_mining.m_gravel; - out.m_statsData[5] = statsData.m_mining.m_clay; - out.m_statsData[6] = statsData.m_mining.m_obsidian; - break; - case eStatsType_Kills: - out.m_statsSize = 7; - out.m_statsData[0] = statsData.m_kills.m_zombie; - out.m_statsData[1] = statsData.m_kills.m_skeleton; - out.m_statsData[2] = statsData.m_kills.m_creeper; - out.m_statsData[3] = statsData.m_kills.m_spider; - out.m_statsData[4] = statsData.m_kills.m_spiderJockey; - out.m_statsData[5] = statsData.m_kills.m_zombiePigman; - out.m_statsData[6] = statsData.m_kills.m_slime; - break; - case eStatsType_Travelling: - out.m_statsSize = 4; - out.m_statsData[0] = statsData.m_travelling.m_walked; - out.m_statsData[1] = statsData.m_travelling.m_fallen; - out.m_statsData[2] = statsData.m_travelling.m_minecart; - out.m_statsData[3] = statsData.m_travelling.m_boat; - break; - } -} - -bool OrbisLeaderboardManager::SortByRank(const ReadScore &lhs, const ReadScore &rhs) -{ - return lhs.m_rank < rhs.m_rank; -} - -// Notify plus feature use -/*void OrbisLeaderboardManager::NotifyAsyncPlusFeature() -{ - SceNpNotifyPlusFeatureParameter param = SceNpNotifyPlusFeatureParameter(); - param.userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad()); - param.size = sizeof(SceNpNotifyPlusFeatureParameter); - param.features = SCE_NP_PLUS_FEATURE_ASYNC_MULTIPLAY; - ZeroMemory(param.padding, sizeof(char) * 4); - ZeroMemory(param.reserved, sizeof(uint8_t) * 32); - - int err = sceNpNotifyPlusFeature(¶m); - if (err != SCE_OK) - { - app.DebugPrintf("OrbisLeaderboardManager::NotifyAsyncPlusFeature: sceNpNotifyPlusFeature failed (0x%x)\n", err); - assert(0); - } -}*/ \ No newline at end of file + return comment->utf8Comment; +} \ No newline at end of file diff --git a/Minecraft.Client/Orbis/Leaderboards/OrbisLeaderboardManager.h b/Minecraft.Client/Orbis/Leaderboards/OrbisLeaderboardManager.h index f8be1db0..e79778c7 100644 --- a/Minecraft.Client/Orbis/Leaderboards/OrbisLeaderboardManager.h +++ b/Minecraft.Client/Orbis/Leaderboards/OrbisLeaderboardManager.h @@ -1,109 +1,32 @@ #pragma once +#include "Common\Leaderboards\SonyLeaderboardManager.h" #include "Common\Leaderboards\LeaderboardManager.h" -class OrbisLeaderboardManager : public LeaderboardManager -{ -protected: - enum EStatsState - { - eStatsState_Idle, - eStatsState_Getting, - eStatsState_Failed, - eStatsState_Ready, - eStatsState_Canceled, - //eStatsState_Writing, - eStatsState_Max - }; +#include +class OrbisLeaderboardManager : public SonyLeaderboardManager +{ public: OrbisLeaderboardManager(); - virtual ~OrbisLeaderboardManager(); -private: - unsigned short m_openSessions; +protected: - C4JThread *m_threadScoreboard; - bool m_running; + virtual HRESULT initialiseScoreUtility(); - int m_titleContext; - int32_t m_requestId; + virtual bool scoreUtilityAlreadyInitialised(HRESULT hr); - //SceNpId m_myNpId; + virtual HRESULT createTitleContext(const SceNpId &npId); - static int scoreboardThreadEntry(LPVOID lpParam); - void scoreboardThreadInternal(); + virtual HRESULT destroyTitleContext(int titleContext); - bool getScoreByIds(); - bool getScoreByRange(); + virtual HRESULT createTransactionContext(int titleContext); - bool setScore(); - queue m_views; + virtual HRESULT abortTransactionContext(int transactionContext); - CRITICAL_SECTION m_csViewsLock; + virtual HRESULT destroyTransactionContext(int transactionContext); - EStatsState m_eStatsState; //State of the stats read - // EFilterMode m_eFilterMode; + virtual HRESULT getFriendsList(sce::Toolkit::NP::Utilities::Future &friendsList); - ReadScore *m_scores; - unsigned int m_maxRank; - //SceNpScoreRankData *m_stats; - -public: - virtual void Tick();// {} - - //Open a session - virtual bool OpenSession();// { return true; } - - //Close a session - virtual void CloseSession();// {} - - //Delete a session - virtual void DeleteSession();// {} - - //Write the given stats - //This is called synchronously and will not free any memory allocated for views when it is done - - virtual bool WriteStats(unsigned int viewCount, ViewIn views);// { return false; } - - virtual bool ReadStats_Friends(LeaderboardReadListener *callback, int difficulty, EStatsType type, PlayerUID myUID, unsigned int startIndex, unsigned int readCount);// { 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; } - - //Perform a flush of the stats - virtual void FlushStats();// {} - - //Cancel the current operation - virtual void CancelOperation();// {} - - //Is the leaderboard manager idle. - virtual bool isIdle();// { return true; } - - -private: - int getBoardId(int difficulty, EStatsType); - - //LeaderboardManager::ReadScore *filterJustScorers(unsigned int &num, LeaderboardManager::ReadScore *friendsData); - - SceNpScorePlayerRankData *addPadding(unsigned int num, SceNpScoreRankData *rankData); - - void convertToOutput(unsigned int &num, ReadScore *out, SceNpScorePlayerRankData *rankData, SceNpScoreComment *comm); - - void toBinary(void *out, SceNpScoreComment *in); - void fromBinary(SceNpScoreComment **out, void *in); - - void toBase32(SceNpScoreComment *out, void *in); - void fromBase32(void *out, SceNpScoreComment *in); - - void toSymbols(char *); - void fromSymbols(char *); - - bool test_string(string); - - void initReadScoreStruct(ReadScore &out, SceNpScoreRankData &); - void fillReadScoreStruct(ReadScore &out, SceNpScoreComment &comment); - - static bool SortByRank(const ReadScore &lhs, const ReadScore &rhs); - - //void NotifyAsyncPlusFeature(); + virtual char * getComment(SceNpScoreComment *comment); }; -- 2.54.0 From b1189eb6c93423b4d596cfe4222084601f26bfc6 Mon Sep 17 00:00:00 2001 From: pieeebot <10+pieeebot@noreply.neolegacy.dev> Date: Wed, 15 Jul 2026 16:45:48 +0100 Subject: [PATCH 07/12] chore: update development status on xbox 360 qloak found a discovery that let us grab the xur files from the tu update files, .xui is compiled into .xur and its easy to convert it back to .xui. --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 2467e544..7e7af7c8 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,12 @@ This project is a modified version of the December 17th 2014 Codebase, aimed at | Platform | Development Status | Known Issues | | :------- | :-------------------- | :------------------------------------------------------------------------ | | PS3 | Active | All TU19 blocks display as stone blocks when placed (missing SPU code). | -| Xbox 360 | Likely cancelled | Missing XUI files for GUIs added in TU25+. See notes. | +| Xbox 360 | On hold | Havent tested, should work? | | PS4 | Active | Only Buildable on Windows 7 With 1.70 SDK. See Notes | | Xbox One | On hold | Needs to be re-coded to run on Developer Mode UWP instead. | | PS Vita | On hold | Fails during compilation due to missing network library dependencies. | **Notes:** -- **Xbox 360:** TU25 and newer TUs include new GUIs, but we lack the XUI files for them, solutions: - 1. Recreate the GUIs from scratch using the XUI designer (insanely difficult to get accurate to actual LCE) - **PS4:** Can't be built on Windows 10+ because the 1.70 SDK only supports Windows 7, solutions: 1. Attempt to add support for 4.50 SDK (difficult or unlikely to work) -- 2.54.0 From b08d478d73ed17a8e1dd9d438019b45efde7de71 Mon Sep 17 00:00:00 2001 From: qloak Date: Wed, 15 Jul 2026 20:33:38 +0100 Subject: [PATCH 08/12] fix(TU20): Piston and StemTile fixes (#6) - fixed "Two pistons stacked facing up and the top piston is powered with a repeater will cause the top piston to lock in place." - fixed "Fix for issue where destroying planted pumpkin and melon seeds drops an incorrect number of seeds." --------- Co-authored-by: pieeebot <10+pieeebot@noreply.neolegacy.dev> Reviewed-on: https://git.neolegacy.dev/pieeebot/mc_pieLCE/pulls/6 Co-authored-by: qloak Co-committed-by: qloak --- Minecraft.World/PistonBaseTile.cpp | 9 +++++++++ Minecraft.World/StemTile.cpp | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/Minecraft.World/PistonBaseTile.cpp b/Minecraft.World/PistonBaseTile.cpp index e8cb35b1..8c002a85 100644 --- a/Minecraft.World/PistonBaseTile.cpp +++ b/Minecraft.World/PistonBaseTile.cpp @@ -218,10 +218,12 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1, if (extend && param1 == TRIGGER_CONTRACT) { level->setData(x, y, z, facing | EXTENDED_BIT, UPDATE_CLIENTS); + ignoreUpdate(false); return false; } else if (!extend && param1 == TRIGGER_EXTEND) { + ignoreUpdate(false); return false; } } @@ -247,6 +249,7 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1, } else { + ignoreUpdate(false); return false; } PIXEndNamedEvent(); @@ -340,6 +343,12 @@ bool PistonBaseTile::triggerEvent(Level *level, int x, int y, int z, int param1, ignoreUpdate(false); + level->updateNeighborsAt(x, y, z, id); + int stepX = x + Facing::STEP_X[facing]; + int stepY = y + Facing::STEP_Y[facing]; + int stepZ = z + Facing::STEP_Z[facing]; + level->updateNeighborsAt(stepX, stepY, stepZ, id); + return true; } diff --git a/Minecraft.World/StemTile.cpp b/Minecraft.World/StemTile.cpp index e8367522..32592c51 100644 --- a/Minecraft.World/StemTile.cpp +++ b/Minecraft.World/StemTile.cpp @@ -189,7 +189,10 @@ void StemTile::spawnResources(Level *level, int x, int y, int z, int data, float if (fruit == Tile::melon) seed = Item::seeds_melon; for (int i = 0; i < 3; i++) { - popResource(level, x, y, z, shared_ptr(new ItemInstance(seed))); + if (level->random->nextInt(15) <= data) + { + popResource(level, x, y, z, shared_ptr(new ItemInstance(seed))); + } } } -- 2.54.0 From 7200598afaa39ae47056ccdc29f612de7ce4d5f4 Mon Sep 17 00:00:00 2001 From: pieeebot <10+pieeebot@noreply.neolegacy.dev> Date: Thu, 16 Jul 2026 13:46:41 +0100 Subject: [PATCH 09/12] chore: change readme to update project name and description --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7e7af7c8..d5804dfd 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# Acacia Log -This project is a modified version of the December 17th 2014 Codebase, aimed at backporting the newer title updates back to the codebase, with cross-play across all platfoms (including PC). +# Project Cafeberry +Cafeberry is a project aiming to update the December leak via decompilation, if possible, with a focus on consoles. # Status | Platform | Development Status | Known Issues | -- 2.54.0 From 1580fdced79ba77c69e74b561cfcb52719f4c6f0 Mon Sep 17 00:00:00 2001 From: pieeebot <10+pieeebot@noreply.neolegacy.dev> Date: Thu, 16 Jul 2026 13:50:36 +0100 Subject: [PATCH 10/12] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d5804dfd..a673e680 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,16 @@ # Project Cafeberry -Cafeberry is a project aiming to update the December leak via decompilation, if possible, with a focus on consoles. +Cafeberry is a project aiming to update the December 17th 2014 codebase (mostly) via decompilation, with a focus on consoles. # Status | Platform | Development Status | Known Issues | | :------- | :-------------------- | :------------------------------------------------------------------------ | -| PS3 | Active | All TU19 blocks display as stone blocks when placed (missing SPU code). | +| PS3 | Active | SPU variants for TU19 blocks are missing, needs to be further optimized. | | Xbox 360 | On hold | Havent tested, should work? | | PS4 | Active | Only Buildable on Windows 7 With 1.70 SDK. See Notes | | Xbox One | On hold | Needs to be re-coded to run on Developer Mode UWP instead. | | PS Vita | On hold | Fails during compilation due to missing network library dependencies. | **Notes:** - - **PS4:** Can't be built on Windows 10+ because the 1.70 SDK only supports Windows 7, solutions: 1. Attempt to add support for 4.50 SDK (difficult or unlikely to work) 2. Getting the 1.70 SDK on Windows 10+ (annoying to do) \ No newline at end of file -- 2.54.0 From eb3ae69d3f151f2859ef78b3c909d970d8e3a64a Mon Sep 17 00:00:00 2001 From: pieeebot <10+pieeebot@noreply.neolegacy.dev> Date: Fri, 17 Jul 2026 12:41:07 +0100 Subject: [PATCH 11/12] chore: add Wii U and Switch to README.md --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a673e680..05908087 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,14 @@ Cafeberry is a project aiming to update the December 17th 2014 codebase (mostly) via decompilation, with a focus on consoles. # Status -| Platform | Development Status | Known Issues | -| :------- | :-------------------- | :------------------------------------------------------------------------ | -| PS3 | Active | SPU variants for TU19 blocks are missing, needs to be further optimized. | -| Xbox 360 | On hold | Havent tested, should work? | -| PS4 | Active | Only Buildable on Windows 7 With 1.70 SDK. See Notes | -| Xbox One | On hold | Needs to be re-coded to run on Developer Mode UWP instead. | -| PS Vita | On hold | Fails during compilation due to missing network library dependencies. | +| Platform | Development Status | Known Issues | +| :------------- | :-------------------- | :------------------------------------------------------------------------ | +| PS3 | Active | SPU variants for TU19 blocks are missing, needs to be further optimized. | +| Xbox 360 | On hold | Havent tested, should work? | +| PS4 | Active | Only Buildable on Windows 7 With 1.70 SDK. See Notes | +| Xbox One | On hold | Needs to be re-coded to run on Developer Mode UWP instead. | +| PS Vita | On hold | Fails during compilation due to missing network library dependencies. | +| Wii U & Switch | Work in progress | UI System (ImXui) is still in progress, need to decompile the rest. | **Notes:** - **PS4:** Can't be built on Windows 10+ because the 1.70 SDK only supports Windows 7, solutions: -- 2.54.0 From c677cc0065c9cb347d363cd98b56b9ce22bba88c Mon Sep 17 00:00:00 2001 From: pieeebot <10+pieeebot@noreply.neolegacy.dev> Date: Fri, 17 Jul 2026 20:17:07 +0100 Subject: [PATCH 12/12] chore: update README.md to include discord server. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 05908087..b525da6d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ # Project Cafeberry Cafeberry is a project aiming to update the December 17th 2014 codebase (mostly) via decompilation, with a focus on consoles. +[![Discord](https://img.shields.io/badge/Discord-Join%20Server-5865F2?logo=discord&logoColor=white)](https://discord.gg/aPAF5WFaW) + # Status | Platform | Development Status | Known Issues | | :------------- | :-------------------- | :------------------------------------------------------------------------ | -- 2.54.0