summaryrefslogtreecommitdiffstats
path: root/src/ClientHandle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ClientHandle.cpp')
-rw-r--r--src/ClientHandle.cpp88
1 files changed, 38 insertions, 50 deletions
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 27b34eeec..848190127 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -768,79 +768,67 @@ void cClientHandle::HandleEnchantItem(UInt8 a_WindowID, UInt8 a_Enchantment)
if (a_Enchantment > 2)
{
LOGWARNING("%s attempt to crash the server with invalid enchanting selection (%u)!", GetUsername().c_str(), a_Enchantment);
- Kick("Invalid enchanting!");
+ Kick("Selected invalid enchantment - hacked client?");
return;
}
- // Bail out if something's wrong with the window
+ // Bail out if something's wrong with the window:
if (
(m_Player->GetWindow() == nullptr) ||
(m_Player->GetWindow()->GetWindowID() != a_WindowID) ||
(m_Player->GetWindow()->GetWindowType() != cWindow::wtEnchantment)
)
{
+ Kick("Enchantment with invalid window - hacked client?");
return;
}
cEnchantingWindow * Window = static_cast<cEnchantingWindow *>(m_Player->GetWindow());
- auto Item = *Window->m_SlotArea->GetSlot(0, *m_Player); // A copy of the item to be enchanted.
- short BaseEnchantmentLevel = Window->GetPropertyValue(a_Enchantment);
+ const auto BaseEnchantmentLevel = Window->GetProperty(a_Enchantment);
- if (!Item.EnchantByXPLevels(BaseEnchantmentLevel))
- {
- // Item wasn't enchantable:
- return;
- }
-
- const auto SetEnchantAndBroadcast = [this, &Item, Window]
- {
- // Set the item slot to our new enchanted item:
- Window->m_SlotArea->SetSlot(0, *m_Player, Item);
- Window->BroadcastWholeWindow();
-
- // Remove enchantment choices:
- Window->SetProperty(0, 0, *m_Player);
- Window->SetProperty(1, 0, *m_Player);
- Window->SetProperty(2, 0, *m_Player);
- };
-
- // Creative players can always enchant:
- if (m_Player->IsGameModeCreative())
+ // Survival players must be checked they can afford enchantment and have lapis removed:
+ if (!m_Player->IsGameModeCreative())
{
- SetEnchantAndBroadcast();
- return;
- }
+ const auto XpRequired = m_Player->XpForLevel(BaseEnchantmentLevel);
+ auto LapisStack = *Window->m_SlotArea->GetSlot(1, *m_Player); // A copy of the lapis stack.
+ const auto LapisRequired = a_Enchantment + 1;
- const auto XpRequired = m_Player->XpForLevel(BaseEnchantmentLevel);
- auto LapisStack = *Window->m_SlotArea->GetSlot(1, *m_Player); // A copy of the lapis stack.
- const auto LapisRequired = a_Enchantment + 1;
+ // Only allow enchantment if the player has sufficient levels and lapis to enchant:
+ if ((m_Player->GetCurrentXp() >= XpRequired) && (LapisStack.m_ItemCount >= LapisRequired))
+ {
+ /** We need to reduce the player's level by the number of lapis required.
+ However we need to keep the resulting percentage filled the same. */
- // Only allow enchantment if the player has sufficient levels and lapis to enchant:
- if ((m_Player->GetCurrentXp() >= XpRequired) && (LapisStack.m_ItemCount >= LapisRequired))
- {
- /*
- We need to reduce the player's level by the number of lapis required.
- However we need to keep the resulting percentage filled the same.
- */
+ const auto TargetLevel = m_Player->GetXpLevel() - LapisRequired;
+ const auto CurrentFillPercent = m_Player->GetXpPercentage();
- const auto TargetLevel = m_Player->GetXpLevel() - LapisRequired;
- const auto CurrentFillPercent = m_Player->GetXpPercentage();
+ // The experience to remove in order to reach the start (0% fill) of the target level.
+ const auto DeltaForLevel = -m_Player->GetCurrentXp() + m_Player->XpForLevel(TargetLevel);
- // The experience to remove in order to reach the start (0% fill) of the target level.
- const auto DeltaForLevel = -m_Player->GetCurrentXp() + m_Player->XpForLevel(TargetLevel);
+ // The experience to add to get the same fill percent.
+ const auto DeltaForPercent = CurrentFillPercent * (m_Player->XpForLevel(TargetLevel + 1) - m_Player->XpForLevel(TargetLevel));
- // The experience to add to get the same fill percent.
- const auto DeltaForPercent = CurrentFillPercent * (m_Player->XpForLevel(TargetLevel + 1) - m_Player->XpForLevel(TargetLevel));
+ // Apply the experience delta:
+ m_Player->DeltaExperience(DeltaForLevel + DeltaForPercent);
- // Apply the experience delta:
- m_Player->DeltaExperience(DeltaForLevel + DeltaForPercent);
+ // Now reduce the lapis in our stack and send it back:
+ LapisStack.AddCount(-LapisRequired);
+ Window->m_SlotArea->SetSlot(1, *m_Player, LapisStack);
+ }
+ else
+ {
+ // Not creative and can't afford enchantment, so exit:
+ Kick("Selected unavailable enchantment - hacked client?");
+ return;
+ }
+ }
- // Now reduce the lapis in our stack and send it back:
- LapisStack.AddCount(-LapisRequired);
- Window->m_SlotArea->SetSlot(1, *m_Player, LapisStack);
+ // Retrieve the enchanted item corresponding to our chosen option (top, middle, bottom)
+ cItem EnchantedItem = Window->m_SlotArea->SelectEnchantedOption(a_Enchantment);
- SetEnchantAndBroadcast();
- }
+ // Set the item slot to our new enchanted item:
+ Window->m_SlotArea->SetSlot(0, *m_Player, EnchantedItem);
+ m_Player->PermuteEnchantmentSeed();
}