Skip to content

Commit

Permalink
refacto(chat): Change spam check instantiation + fix test
Browse files Browse the repository at this point in the history
  • Loading branch information
vincent4vx committed Dec 29, 2023
1 parent 18cada4 commit 80eb9e4
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 36 deletions.
6 changes: 6 additions & 0 deletions src/main/java/fr/quatrevieux/araknemu/game/GameModule.java
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@
import fr.quatrevieux.araknemu.game.fight.turn.action.util.CriticalityStrategy;
import fr.quatrevieux.araknemu.game.fight.type.ChallengeType;
import fr.quatrevieux.araknemu.game.fight.type.PvmType;
import fr.quatrevieux.araknemu.game.handler.chat.SpamCheckAttachment;
import fr.quatrevieux.araknemu.game.handler.loader.AdminLoader;
import fr.quatrevieux.araknemu.game.handler.loader.AggregateLoader;
import fr.quatrevieux.araknemu.game.handler.loader.CommonLoader;
Expand Down Expand Up @@ -541,6 +542,11 @@ private void configureServices(ContainerConfigurator configurator) {
)
);

configurator.persist(SpamCheckAttachment.Key.class, container -> new SpamCheckAttachment.Key(
container.get(GameConfiguration.class).chat().spamCheckInterval(),
container.get(GameConfiguration.class).chat().spamCheckMaxCount()
));

configurator.persist(
AreaService.class,
container -> new AreaService(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import fr.quatrevieux.araknemu.core.network.exception.ErrorPacket;
import fr.quatrevieux.araknemu.core.network.parser.PacketHandler;
import fr.quatrevieux.araknemu.game.GameConfiguration;
import fr.quatrevieux.araknemu.game.chat.ChatException;
import fr.quatrevieux.araknemu.game.chat.ChatService;
import fr.quatrevieux.araknemu.game.player.GamePlayer;
Expand All @@ -38,11 +37,11 @@
*/
public final class SendMessage implements PacketHandler<GameSession, Message> {
private final ChatService service;
private final GameConfiguration.ChatConfiguration configuration;
private final SpamCheckAttachment.Key spamCheckKey;

public SendMessage(ChatService service, GameConfiguration.ChatConfiguration configuration) {
public SendMessage(ChatService service, SpamCheckAttachment.Key spamCheckKey) {
this.service = service;
this.configuration = configuration;
this.spamCheckKey = spamCheckKey;
}

@Override
Expand All @@ -57,7 +56,7 @@ public void handle(GameSession session, Message packet) throws Exception {
throw new ErrorPacket(new Noop());
}

if (!session.get(SpamCheckAttachment.KEY).check(configuration.spamCheckInterval(), configuration.spamCheckMaxCount())) {
if (!session.get(spamCheckKey).check()) {
throw new ErrorPacket(ServerMessage.spam());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import fr.quatrevieux.araknemu.core.network.exception.ErrorPacket;
import fr.quatrevieux.araknemu.core.network.parser.PacketHandler;
import fr.quatrevieux.araknemu.game.GameConfiguration;
import fr.quatrevieux.araknemu.game.exploration.ExplorationPlayer;
import fr.quatrevieux.araknemu.game.exploration.map.ExplorationMap;
import fr.quatrevieux.araknemu.network.game.GameSession;
Expand All @@ -34,10 +33,10 @@
* Send the player smiley to map
*/
public final class SendSmileyToExplorationMap implements PacketHandler<GameSession, UseSmiley> {
private final GameConfiguration.ChatConfiguration configuration;
private final SpamCheckAttachment.Key spamCheckKey;

public SendSmileyToExplorationMap(GameConfiguration.ChatConfiguration configuration) {
this.configuration = configuration;
public SendSmileyToExplorationMap(SpamCheckAttachment.Key spamCheckKey) {
this.spamCheckKey = spamCheckKey;
}

@Override
Expand All @@ -49,7 +48,7 @@ public void handle(GameSession session, UseSmiley packet) throws Exception {
return;

Check warning on line 48 in src/main/java/fr/quatrevieux/araknemu/game/handler/chat/SendSmileyToExplorationMap.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/fr/quatrevieux/araknemu/game/handler/chat/SendSmileyToExplorationMap.java#L48

Added line #L48 was not covered by tests
}

if (!session.get(SpamCheckAttachment.KEY).check(configuration.spamCheckInterval(), configuration.spamCheckMaxCount())) {
if (!session.get(spamCheckKey).check()) {
throw new ErrorPacket(ServerMessage.spam());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

import fr.quatrevieux.araknemu.core.network.exception.ErrorPacket;
import fr.quatrevieux.araknemu.core.network.parser.PacketHandler;
import fr.quatrevieux.araknemu.game.GameConfiguration;
import fr.quatrevieux.araknemu.game.fight.fighter.player.PlayerFighter;
import fr.quatrevieux.araknemu.network.game.GameSession;
import fr.quatrevieux.araknemu.network.game.in.chat.UseSmiley;
Expand All @@ -33,17 +32,17 @@
* Send the player smiley to the fight
*/
public final class SendSmileyToFight implements PacketHandler<GameSession, UseSmiley> {
private final GameConfiguration.ChatConfiguration configuration;
private final SpamCheckAttachment.Key spamCheckKey;

public SendSmileyToFight(GameConfiguration.ChatConfiguration configuration) {
this.configuration = configuration;
public SendSmileyToFight(SpamCheckAttachment.Key spamCheckKey) {
this.spamCheckKey = spamCheckKey;
}

@Override
public void handle(GameSession session, UseSmiley packet) throws Exception {
final PlayerFighter fighter = NullnessUtil.castNonNull(session.fighter());

if (!session.get(SpamCheckAttachment.KEY).check(configuration.spamCheckInterval(), configuration.spamCheckMaxCount())) {
if (!session.get(spamCheckKey).check()) {
throw new ErrorPacket(ServerMessage.spam());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,25 @@
import fr.quatrevieux.araknemu.network.game.SessionAttachmentKey;
import org.checkerframework.checker.index.qual.NonNegative;
import org.checkerframework.checker.index.qual.Positive;
import org.checkerframework.checker.nullness.qual.NonNull;

import java.time.Duration;

/**
* An attachment for spam check
*/
public final class SpamCheckAttachment {
public static final SessionAttachmentKey<SpamCheckAttachment> KEY = SpamCheckAttachment::new;
/**
* The check interval
* @see GameConfiguration.ChatConfiguration#spamCheckInterval()
*/
private final Duration interval;

/**
* The maximum number of message or smiley that can be sent in the interval
* @see GameConfiguration.ChatConfiguration#spamCheckMaxCount()
*/
private final @Positive int maxCount;

/**
* The last check time in milliseconds
Expand All @@ -45,19 +56,17 @@ public final class SpamCheckAttachment {
*/
private @NonNegative int messageCount = 0;

private SpamCheckAttachment() {
// Instantiation only by the attachment key
private SpamCheckAttachment(Duration interval, @Positive int maxCount) {
this.interval = interval;
this.maxCount = maxCount;
}

/**
* Check for spam before sending a message or smiley
*
* @param interval The check interval {@link GameConfiguration.ChatConfiguration#spamCheckInterval()}
* @param maxCount Maximum number of message or smiley that can be sent in the interval {@link GameConfiguration.ChatConfiguration#spamCheckMaxCount()}
*
* @return true if the limit is not reached, false otherwise
*/
public boolean check(Duration interval, @Positive int maxCount) {
public boolean check() {
final long now = System.currentTimeMillis();

if (now - checkTime > interval.toMillis()) {
Expand All @@ -73,4 +82,23 @@ public boolean check(Duration interval, @Positive int maxCount) {

return true;
}

public static final class Key implements SessionAttachmentKey<SpamCheckAttachment> {
private final Duration interval;
private final @Positive int maxCount;

/**
* @param interval The check interval {@link GameConfiguration.ChatConfiguration#spamCheckInterval()}
* @param maxCount Maximum number of message or smiley that can be sent in the interval {@link GameConfiguration.ChatConfiguration#spamCheckMaxCount()}
*/
public Key(Duration interval, @Positive int maxCount) {
this.interval = interval;
this.maxCount = maxCount;
}

@Override
public @NonNull SpamCheckAttachment initialize() {
return new SpamCheckAttachment(interval, maxCount);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@
import fr.quatrevieux.araknemu.core.di.Container;
import fr.quatrevieux.araknemu.core.di.ContainerException;
import fr.quatrevieux.araknemu.core.network.parser.PacketHandler;
import fr.quatrevieux.araknemu.game.GameConfiguration;
import fr.quatrevieux.araknemu.game.exploration.interaction.action.ActionFactory;
import fr.quatrevieux.araknemu.game.handler.EnsureFighting;
import fr.quatrevieux.araknemu.game.handler.EnsureInactiveFight;
import fr.quatrevieux.araknemu.game.handler.ExploringOrFightingSwitcher;
import fr.quatrevieux.araknemu.game.handler.chat.SendSmileyToExplorationMap;
import fr.quatrevieux.araknemu.game.handler.chat.SendSmileyToFight;
import fr.quatrevieux.araknemu.game.handler.chat.SpamCheckAttachment;
import fr.quatrevieux.araknemu.game.handler.fight.PerformTurnAction;
import fr.quatrevieux.araknemu.game.handler.fight.TerminateTurnAction;
import fr.quatrevieux.araknemu.game.handler.fight.UseObjectBeforeStart;
Expand Down Expand Up @@ -58,8 +58,8 @@ public final class ExploringOrFightingLoader implements Loader {
new EnsureInactiveFight<>(new UseObjectBeforeStart())
),
new ExploringOrFightingSwitcher<>(
new SendSmileyToExplorationMap(container.get(GameConfiguration.class).chat()),
new SendSmileyToFight(container.get(GameConfiguration.class).chat())
new SendSmileyToExplorationMap(container.get(SpamCheckAttachment.Key.class)),
new SendSmileyToFight(container.get(SpamCheckAttachment.Key.class))
),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import fr.quatrevieux.araknemu.core.di.Container;
import fr.quatrevieux.araknemu.core.di.ContainerException;
import fr.quatrevieux.araknemu.core.network.parser.PacketHandler;
import fr.quatrevieux.araknemu.game.GameConfiguration;
import fr.quatrevieux.araknemu.game.chat.ChatService;
import fr.quatrevieux.araknemu.game.exploration.ExplorationService;
import fr.quatrevieux.araknemu.game.handler.EnsureFightingOrSpectator;
Expand All @@ -31,6 +30,7 @@
import fr.quatrevieux.araknemu.game.handler.account.BoostCharacteristic;
import fr.quatrevieux.araknemu.game.handler.chat.SaveSubscription;
import fr.quatrevieux.araknemu.game.handler.chat.SendMessage;
import fr.quatrevieux.araknemu.game.handler.chat.SpamCheckAttachment;
import fr.quatrevieux.araknemu.game.handler.fight.LeaveFight;
import fr.quatrevieux.araknemu.game.handler.fight.LeaveSpectatorFight;
import fr.quatrevieux.araknemu.game.handler.game.CreateGame;
Expand All @@ -57,7 +57,7 @@ public PlayingLoader() {
),
new SendMessage(
container.get(ChatService.class),
container.get(GameConfiguration.class).chat()
container.get(SpamCheckAttachment.Key.class)
),
new SaveSubscription(),
new EnsureInactiveFight(new MoveObject()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public void setUp() throws Exception {

handler = new SendMessage(
container.get(ChatService.class),
container.get(GameConfiguration.class).chat()
container.get(SpamCheckAttachment.Key.class)
);

container.get(Dispatcher.class).dispatch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@
class SpamCheckAttachmentTest {
@RepeatedIfExceptionsTest
void check() throws InterruptedException {
SpamCheckAttachment attachment = SpamCheckAttachment.KEY.initialize();
SpamCheckAttachment attachment = new SpamCheckAttachment.Key(Duration.ofMillis(400), 3).initialize();

assertTrue(attachment.check(Duration.ofMillis(100), 3));
assertTrue(attachment.check(Duration.ofMillis(100), 3));
assertTrue(attachment.check(Duration.ofMillis(100), 3));
assertTrue(attachment.check());
assertTrue(attachment.check());
assertTrue(attachment.check());

assertFalse(attachment.check(Duration.ofMillis(100), 3));
assertFalse(attachment.check(Duration.ofMillis(100), 3));
assertFalse(attachment.check());
assertFalse(attachment.check());

Thread.sleep(100);
assertTrue(attachment.check(Duration.ofMillis(100), 3));
Thread.sleep(600);
assertTrue(attachment.check());
}
}

0 comments on commit 80eb9e4

Please sign in to comment.