You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-20 15:36:17 +00:00
fix(housekeeping): cap sanction durations safely
This commit is contained in:
+1
-5
@@ -17,9 +17,6 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class HousekeepingBanUserEvent extends MessageHandler {
|
public class HousekeepingBanUserEvent extends MessageHandler {
|
||||||
private static final String ACTION_KEY = "user.ban";
|
private static final String ACTION_KEY = "user.ban";
|
||||||
private static final int SECONDS_IN_HOUR = 3600;
|
|
||||||
// 100-year ceiling, matches ModToolSanctionBanEvent's permanent ban.
|
|
||||||
private static final int MAX_DURATION_SECONDS = 100 * 365 * 24 * 3600;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRatelimit() {
|
public int getRatelimit() {
|
||||||
@@ -46,8 +43,7 @@ public class HousekeepingBanUserEvent extends MessageHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long durationLong = (long) hours * SECONDS_IN_HOUR;
|
int duration = HousekeepingSanctionDuration.secondsFromHours(hours);
|
||||||
int duration = durationLong > MAX_DURATION_SECONDS ? MAX_DURATION_SECONDS : (int) durationLong;
|
|
||||||
|
|
||||||
List<ModToolBan> bans = Emulator.getGameEnvironment().getModToolManager()
|
List<ModToolBan> bans = Emulator.getGameEnvironment().getModToolManager()
|
||||||
.ban(userId, this.client.getHabbo(), reason != null ? reason : "", duration, ModToolBanType.ACCOUNT, 0);
|
.ban(userId, this.client.getHabbo(), reason != null ? reason : "", duration, ModToolBanType.ACCOUNT, 0);
|
||||||
|
|||||||
+1
-2
@@ -15,7 +15,6 @@ import com.eu.habbo.messages.outgoing.housekeeping.HousekeepingActionResultCompo
|
|||||||
*/
|
*/
|
||||||
public class HousekeepingMuteUserEvent extends MessageHandler {
|
public class HousekeepingMuteUserEvent extends MessageHandler {
|
||||||
private static final String ACTION_KEY = "user.mute";
|
private static final String ACTION_KEY = "user.mute";
|
||||||
private static final int SECONDS_IN_MINUTE = 60;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRatelimit() {
|
public int getRatelimit() {
|
||||||
@@ -49,7 +48,7 @@ public class HousekeepingMuteUserEvent extends MessageHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
target.mute(minutes * SECONDS_IN_MINUTE, false);
|
target.mute(HousekeepingSanctionDuration.secondsFromMinutes(minutes), false);
|
||||||
|
|
||||||
if (reason != null && !reason.isEmpty()) {
|
if (reason != null && !reason.isEmpty()) {
|
||||||
target.alert(reason);
|
target.alert(reason);
|
||||||
|
|||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
package com.eu.habbo.messages.incoming.housekeeping;
|
||||||
|
|
||||||
|
final class HousekeepingSanctionDuration {
|
||||||
|
static final int SECONDS_IN_MINUTE = 60;
|
||||||
|
static final int SECONDS_IN_HOUR = 3600;
|
||||||
|
static final int MAX_SECONDS = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
private HousekeepingSanctionDuration() {
|
||||||
|
}
|
||||||
|
|
||||||
|
static int secondsFromHours(int hours) {
|
||||||
|
if (hours <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long seconds = (long) hours * SECONDS_IN_HOUR;
|
||||||
|
return seconds > MAX_SECONDS ? MAX_SECONDS : (int) seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int secondsFromMinutes(int minutes) {
|
||||||
|
if (minutes <= 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
long seconds = (long) minutes * SECONDS_IN_MINUTE;
|
||||||
|
return seconds > MAX_SECONDS ? MAX_SECONDS : (int) seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int unixUntil(int now, int durationSeconds) {
|
||||||
|
if (durationSeconds <= 0) {
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
|
||||||
|
long until = (long) now + durationSeconds;
|
||||||
|
return until > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) until;
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-5
@@ -20,8 +20,6 @@ import java.sql.SQLException;
|
|||||||
*/
|
*/
|
||||||
public class HousekeepingTradeLockUserEvent extends MessageHandler {
|
public class HousekeepingTradeLockUserEvent extends MessageHandler {
|
||||||
private static final String ACTION_KEY = "user.trade_lock";
|
private static final String ACTION_KEY = "user.trade_lock";
|
||||||
private static final int SECONDS_IN_HOUR = 3600;
|
|
||||||
private static final int MAX_DURATION_SECONDS = 100 * 365 * 24 * 3600;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRatelimit() {
|
public int getRatelimit() {
|
||||||
@@ -48,9 +46,8 @@ public class HousekeepingTradeLockUserEvent extends MessageHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
long durationLong = (long) hours * SECONDS_IN_HOUR;
|
int duration = HousekeepingSanctionDuration.secondsFromHours(hours);
|
||||||
int duration = durationLong > MAX_DURATION_SECONDS ? MAX_DURATION_SECONDS : (int) durationLong;
|
int lockedUntil = HousekeepingSanctionDuration.unixUntil(Emulator.getIntUnixTimestamp(), duration);
|
||||||
int lockedUntil = Emulator.getIntUnixTimestamp() + duration;
|
|
||||||
|
|
||||||
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
try (Connection connection = Emulator.getDatabase().getDataSource().getConnection();
|
||||||
PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET trade_locked_until = ? WHERE user_id = ? LIMIT 1")) {
|
PreparedStatement statement = connection.prepareStatement("UPDATE users_settings SET trade_locked_until = ? WHERE user_id = ? LIMIT 1")) {
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package com.eu.habbo.messages.incoming.housekeeping;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class HousekeepingSanctionDurationContractTest {
|
||||||
|
private static final Path BAN_SOURCE = Path.of(
|
||||||
|
"src/main/java/com/eu/habbo/messages/incoming/housekeeping/HousekeepingBanUserEvent.java");
|
||||||
|
private static final Path MUTE_SOURCE = Path.of(
|
||||||
|
"src/main/java/com/eu/habbo/messages/incoming/housekeeping/HousekeepingMuteUserEvent.java");
|
||||||
|
private static final Path TRADE_LOCK_SOURCE = Path.of(
|
||||||
|
"src/main/java/com/eu/habbo/messages/incoming/housekeeping/HousekeepingTradeLockUserEvent.java");
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sanctionsUseSharedOverflowSafeDurationHelpers() throws IOException {
|
||||||
|
String ban = Files.readString(BAN_SOURCE);
|
||||||
|
String mute = Files.readString(MUTE_SOURCE);
|
||||||
|
String tradeLock = Files.readString(TRADE_LOCK_SOURCE);
|
||||||
|
|
||||||
|
assertTrue(ban.contains("HousekeepingSanctionDuration.secondsFromHours(hours)"));
|
||||||
|
assertTrue(mute.contains("HousekeepingSanctionDuration.secondsFromMinutes(minutes)"));
|
||||||
|
assertTrue(tradeLock.contains("HousekeepingSanctionDuration.secondsFromHours(hours)"));
|
||||||
|
assertTrue(tradeLock.contains("HousekeepingSanctionDuration.unixUntil("));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sanctionsDoNotUseOverflowProneIntDurationConstants() throws IOException {
|
||||||
|
String ban = Files.readString(BAN_SOURCE);
|
||||||
|
String tradeLock = Files.readString(TRADE_LOCK_SOURCE);
|
||||||
|
|
||||||
|
assertFalse(ban.contains("100 * 365 * 24 * 3600"));
|
||||||
|
assertFalse(tradeLock.contains("100 * 365 * 24 * 3600"));
|
||||||
|
}
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package com.eu.habbo.messages.incoming.housekeeping;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
class HousekeepingSanctionDurationTest {
|
||||||
|
@Test
|
||||||
|
void convertsHoursAndMinutesWithoutIntegerOverflow() {
|
||||||
|
assertEquals(3600, HousekeepingSanctionDuration.secondsFromHours(1));
|
||||||
|
assertEquals(60, HousekeepingSanctionDuration.secondsFromMinutes(1));
|
||||||
|
assertEquals(Integer.MAX_VALUE, HousekeepingSanctionDuration.secondsFromHours(Integer.MAX_VALUE));
|
||||||
|
assertEquals(Integer.MAX_VALUE, HousekeepingSanctionDuration.secondsFromMinutes(Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void capsUnixTimestampInsteadOfWrapping() {
|
||||||
|
assertEquals(1_000_060, HousekeepingSanctionDuration.unixUntil(1_000_000, 60));
|
||||||
|
assertEquals(Integer.MAX_VALUE, HousekeepingSanctionDuration.unixUntil(Integer.MAX_VALUE - 10, 60));
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user