QOL: Add some java commands

Added many commands from Minecraft Java edition:

    setblock
    fill
    seed
    xp
    gamemode spectator
    summon
    effect
    difficulty
    spawnpoint
    setworldspawn
    kick
    enchant

All of the logic is contained inside of PlayerConnection.cpp along with the previous command handler, i also changed MobEffect.h to add a new helper for potion names -> ids.
And for spectator, a bunch of small changes inside server/client related file, along with the removal of the weird /spectator command which was added previously. I think it can still be refined because im not sure the invisibility thing is working.
This commit is contained in:
Anaël
2026-10-04 21:01:15 +02:00
parent 29ea94206c
commit 1b691739e6
10 changed files with 1215 additions and 104 deletions
+40 -31
View File
@@ -148,7 +148,7 @@ void LocalPlayer::calculateFlight(float xa, float ya, float za)
void LocalPlayer::serverAiStep()
{
Player::serverAiStep();
this->xxa = input->xa;
this->yya = input->ya;
this->jumping = input->jumping;
@@ -297,7 +297,7 @@ void LocalPlayer::aiStep()
if (isSprinting() && (!forwardEnoughToContinueSprint || !enoughFoodToSprint || isSneaking() || isUsingItem()))
{
setSprinting(false);
}
}
// 4J Stu - Fix for #52705 - Customer Encountered: Player can fly in bed while being in Creative mode.
if (!isSleeping() && (abilities.mayfly || isAllowedToFly() ))
@@ -320,7 +320,14 @@ void LocalPlayer::aiStep()
#ifndef _CONTENT_PACKAGE
printf("flying was %s\n", abilities.flying ? "on" : "off");
#endif
abilities.flying = !abilities.flying;
if (abilities.spectatorMode)
{
abilities.flying = true;
}
else
{
abilities.flying = !abilities.flying;
}
#ifndef _CONTENT_PACKAGE
printf("flying is %s\n", abilities.flying ? "on" : "off");
#endif
@@ -332,29 +339,31 @@ void LocalPlayer::aiStep()
else if(abilities.flying)
{
#ifdef _DEBUG_MENUS_ENABLED
if(!abilities.debugflying)
if(!abilities.debugflying && !abilities.spectatorMode)
#else
if(!abilities.spectatorMode)
#endif
{
abilities.flying = false;
}
{
abilities.flying = false;
}
}
if (isElytraFlying())
{
if (m_elytraCancelWindow > 0) m_elytraCancelWindow--;
if (!wasJumping && input->jumping)
if (!wasJumping && input->jumping)
{
m_elytraCancelPressCount++;
if (m_elytraCancelPressCount == 1)
{
m_elytraCancelWindow = 15;
m_elytraCancelWindow = 15;
}
else if (m_elytraCancelPressCount >= 2 && m_elytraCancelWindow > 0)
{
setElytraFlying(false);
jumpTriggerTime = 10;
jumpTriggerTime = 10;
m_elytraCancelPressCount = 0;
m_elytraCancelWindow = 0;
}
@@ -452,7 +461,7 @@ void LocalPlayer::aiStep()
{
jumpRidingScale = static_cast<float>(jumpRidingTicks) * .1f;
}
else
else
{
jumpRidingScale = .8f + (2.f / static_cast<float>(jumpRidingTicks - 9)) * .1f;
}
@@ -545,7 +554,7 @@ void LocalPlayer::aiStep()
}
*/
// Check if the player is idle and the rich presence needs updated
if( !m_bIsIdle && InputManager.GetIdleSeconds( m_iPad ) > PLAYER_IDLE_TIME )
{
@@ -565,7 +574,7 @@ void LocalPlayer::aiStep()
else
{
ProfileManager.SetCurrentGameActivity(m_iPad,CONTEXT_PRESENCE_MULTIPLAYER,false);
}
}
}
else
{
@@ -898,7 +907,7 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
{
#ifdef _DURANGO
// 4J-JEV: Maybe we want to fine tune this later? #TODO
if ( !ProfileManager.IsGuest(GetXboxPad())
if ( !ProfileManager.IsGuest(GetXboxPad())
&& app.CanRecordStatsAndAchievements()
&& ProfileManager.IsFullVersion()
)
@@ -952,7 +961,7 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
// This causes some extreme flooding of some awards
if(ProfileManager.CanBeAwarded(m_iPad, ach->getAchievementID() ) )
{
// 4J Stu - We don't (currently) care about the gamerscore, so setting to a default of 0 points
TelemetryManager->RecordAchievementUnlocked(m_iPad,ach->getAchievementID(),0);
@@ -1003,7 +1012,7 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
toolStats[0][2] = GenericStats::itemsCrafted(Item::iron_shovel->id);
toolStats[0][3] = GenericStats::itemsCrafted(Item::diamond_shovel->id);
toolStats[0][4] = GenericStats::itemsCrafted(Item::golden_shovel->id);
toolStats[1][0] = GenericStats::itemsCrafted(Item::wooden_pickaxe->id);
toolStats[1][0] = GenericStats::itemsCrafted(Item::wooden_pickaxe->id);
toolStats[1][1] = GenericStats::itemsCrafted(Item::stone_pickaxe->id);
toolStats[1][2] = GenericStats::itemsCrafted(Item::iron_pickaxe->id);
toolStats[1][3] = GenericStats::itemsCrafted(Item::diamond_pickaxe->id);
@@ -1018,7 +1027,7 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
toolStats[3][2] = GenericStats::itemsCrafted(Item::iron_hoe->id);
toolStats[3][3] = GenericStats::itemsCrafted(Item::diamond_hoe->id);
toolStats[3][4] = GenericStats::itemsCrafted(Item::golden_hoe->id);
bool justCraftedTool = false;
for (int i=0; i<4; i++)
{
@@ -1056,7 +1065,7 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
awardStat(GenericStats::MOARTools(), GenericStats::param_noArgs());
}
}
}
#ifdef _XBOX
@@ -1140,7 +1149,7 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
numEmeraldMined = pStats->getTotalValue(emeraldMined);
numEmeraldBought = pStats->getTotalValue(emeraldBought);
totalSum = numEmeraldMined + numEmeraldBought;
app.DebugPrintf(
"[AwardStat] Check unlock 'The Haggler': "
"emerald_mined=%i, emerald_bought=%i, sum=%i.\n",
@@ -1196,7 +1205,7 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
// AWARD : Rainbow Collection, collect all different colours of wool.
{
bool justPickedupWool = false;
for (int i=0; i<16; i++)
if ( stat == GenericStats::itemsCollected(Tile::wool_Id, i) )
justPickedupWool = true;
@@ -1204,7 +1213,7 @@ void LocalPlayer::awardStat(Stat *stat, byteArray param)
if (justPickedupWool)
{
unsigned int woolCount = 0;
for (unsigned int i = 0; i < 16; i++)
{
if (pStats->getTotalValue(GenericStats::itemsCollected(Tile::wool_Id, i)) > 0)
@@ -1393,7 +1402,7 @@ void LocalPlayer::mapPlayerChunk(const unsigned int flagTileType)
cout << "O";
else for (unsigned int y = 127; y > 0; y--)
{
int t = cc->getTile(x,y,z);
int t = cc->getTile(x,y,z);
if (flagTileType != 0 && t == flagTileType) { cout << "@"; break; }
else if (t != 0 && t < 10) { cout << t; break; }
else if (t > 0) { cout << "#"; break; }
@@ -1427,7 +1436,7 @@ void LocalPlayer::handleMouseDown(int button, bool down)
if( ( ( y == 0 ) || ( ( y == 127 ) && level->dimension->hasCeiling ) ) && level->dimension->id != 1 ) return;
minecraft->gameMode->continueDestroyBlock(x, y, z, minecraft->hitResult->f);
if(mayDestroyBlockAt(x,y,z))
{
minecraft->particleEngine->crack(x, y, z, minecraft->hitResult->f);
@@ -1465,7 +1474,7 @@ bool LocalPlayer::creativeModeHandleMouseClick(int button, bool buttonPressed)
}
// Get distance from last click point in each axis
float dX = static_cast<float>(x) - lastClickX;
float dX = static_cast<float>(x) - lastClickX;
float dY = static_cast<float>(y) - lastClickY;
float dZ = static_cast<float>(z) - lastClickZ;
bool newClick = false;
@@ -1613,13 +1622,13 @@ bool LocalPlayer::handleMouseClick(int button)
bool returnItemPlaced = false;
if (button == 0 && missTime > 0) return false;
if (button == 0)
if (button == 0)
{
//app.DebugPrintf("handleMouseClick - Player %d is swinging\n",GetXboxPad());
swing();
}
bool mayUse = true;
bool mayUse = true;
// 4J-PB - Adding a special case in here for sleeping in a bed in a multiplayer game - we need to wake up, and we don't have the inbedchatscreen with a button
@@ -1631,7 +1640,7 @@ bool LocalPlayer::handleMouseClick(int button)
shared_ptr<MultiplayerLocalPlayer> mplp = dynamic_pointer_cast<MultiplayerLocalPlayer>( shared_from_this() );
if(mplp && mplp->connection) mplp->StopSleeping();
}
// 4J Stu - We should not accept any input while asleep, except the above to wake up
if(isSleeping() && level != nullptr && level->isClientSide)
@@ -1653,9 +1662,9 @@ bool LocalPlayer::handleMouseClick(int button)
}
if (button == 1)
{
// 4J-PB - if we milk a cow here, and end up with a bucket of milk, the if (mayUse && button == 1) further down will
// 4J-PB - if we milk a cow here, and end up with a bucket of milk, the if (mayUse && button == 1) further down will
// then empty our bucket if we're pointing at a tile
// It looks like interact really should be returning a result so we can check this, but it's possibly just the
// It looks like interact really should be returning a result so we can check this, but it's possibly just the
// milk bucket that causes a problem
if(minecraft->hitResult->entity->GetType()==eTYPE_COW)
@@ -1747,7 +1756,7 @@ void LocalPlayer::updateRichPresence()
else if(selectedItem != nullptr && selectedItem->id == Item::map_Id)
{
app.SetRichPresenceContext(m_iPad,CONTEXT_GAME_STATE_MAP);
}
}
else if ( (riding != nullptr) && riding->instanceof(eTYPE_MINECART) )
{
app.SetRichPresenceContext(m_iPad,CONTEXT_GAME_STATE_RIDING_MINECART);