Skip to content

Commit

Permalink
Handle Integer Overflows for the truly insane
Browse files Browse the repository at this point in the history
  • Loading branch information
Direwolf20-MC committed Sep 13, 2024
1 parent 2bca1f0 commit 222f1f2
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,15 @@ public ExperienceHolderScreen(ExperienceHolderContainer container, Inventory inv
@Override
public void init() {
super.init();
addRenderableWidget(ToggleButtonFactory.STOREEXPBUTTON(topSectionLeft + (topSectionWidth / 2) - 15 - 18, topSectionTop + 62, true, b -> {
addRenderableWidget(ToggleButtonFactory.STOREEXPBUTTON(topSectionLeft + (topSectionWidth / 2) + 15, topSectionTop + 62, true, b -> {
int amt = 1;
if (Screen.hasControlDown())
amt = -1;
else if (Screen.hasShiftDown())
amt = amt * 10;
PacketDistributor.sendToServer(new ExperienceHolderPayload(true, amt));
}));
addRenderableWidget(ToggleButtonFactory.EXTRACTEXPBUTTON(topSectionLeft + (topSectionWidth / 2) + 15, topSectionTop + 62, true, b -> {
addRenderableWidget(ToggleButtonFactory.EXTRACTEXPBUTTON(topSectionLeft + (topSectionWidth / 2) - 15 - 18, topSectionTop + 62, true, b -> {
int amt = 1;
if (Screen.hasControlDown())
amt = -1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,29 +63,48 @@ public void changeSettings(int targetExp, boolean ownerOnly, boolean collectExp)
markDirtyClient();
}

public int addExp(int addition) {
if (this.exp > Integer.MAX_VALUE - addition) {
// Prevent overflow by capping the experience at Integer.MAX_VALUE
int remainingExp = addition - (Integer.MAX_VALUE - this.exp);
this.exp = Integer.MAX_VALUE;
return remainingExp; //Return Remaining
} else {
// Safe to add the experience
this.exp += addition;
return 0;
}
}

public void storeExp(Player player, int levelChange) {
if (levelChange == -1) {
// Move all experience from player
int totalExp = ExperienceUtils.getPlayerTotalExperience(player);
this.exp += totalExp;
int remaining = addExp(totalExp);
player.giveExperiencePoints(-totalExp); // Removes all levels
player.giveExperienceLevels(-1); //Handles dangling Floating Point Math (RAGE!) Consider it a tax on storing exp :)
if (remaining > 0)
player.giveExperiencePoints(remaining);
} else if (levelChange > 0) {
// Handle fractional progress first, if the player is in the middle of a level
int expInCurrentLevel = (int) (player.experienceProgress * player.getXpNeededForNextLevel());

// If the player has partial progress within the current level, remove that first
if (player.experienceProgress > 0.0f) {
int expRemoved = ExperienceUtils.removePoints(player, expInCurrentLevel);
this.exp += expRemoved;
int remaining = addExp(expRemoved);
levelChange--; // We've already removed part of a level
player.experienceProgress = 0f; //Clear the player's partial exp, to handle super low floating point values
if (remaining > 0)
player.giveExperiencePoints(remaining);
}

if (levelChange > 0) {
// Now remove the specified number of full levels
int expRemoved = ExperienceUtils.removeLevels(player, levelChange);
this.exp += expRemoved;
int remaining = addExp(expRemoved);
if (remaining > 0)
player.giveExperiencePoints(remaining);
}
}

Expand Down Expand Up @@ -190,7 +209,7 @@ private void collectExp() {

for (ExperienceOrb experienceOrb : entityList) {
int orbValue = experienceOrb.getValue();
this.exp += orbValue;
addExp(orbValue);
doParticles(new ItemStack(Items.EXPERIENCE_BOTTLE), experienceOrb.position(), true);
experienceOrb.discard();
}
Expand Down

0 comments on commit 222f1f2

Please sign in to comment.