removed throttle for mod
CI/CD / test_and_check_app (push) Successful in 3m39s
CI/CD / Publish immutable image (push) Skipped

This commit is contained in:
2026-09-03 13:21:46 +02:00
committed by Eric
parent 164658dae2
commit d2042fb95b
5 changed files with 80 additions and 15 deletions
+9 -7
View File
@@ -29,15 +29,17 @@ class RoomEmoteService
]);
}
$rateLimitKey = "room-emote:{$room->id}:{$player->id}";
if (! $player->isModerator()) {
$rateLimitKey = "room-emote:{$room->id}:{$player->id}";
abort_if(
RateLimiter::tooManyAttempts($rateLimitKey, 10),
429,
'Bitte warte kurz, bevor du erneut wirfst.',
);
abort_if(
RateLimiter::tooManyAttempts($rateLimitKey, 10),
429,
'Bitte warte kurz, bevor du erneut wirfst.',
);
RateLimiter::hit($rateLimitKey, 10);
RateLimiter::hit($rateLimitKey, 10);
}
PaperBallThrown::dispatch(
Str::uuid()->toString(),
+4 -1
View File
@@ -21,6 +21,7 @@ const { activePaperBalls, hitPlayerIds, throwingAtPlayerId, throwPaperBall } =
usePaperBallToss({
roomId: () => props.room.id,
currentPlayerId: () => props.currentPlayer.id,
currentPlayerIsModerator: () => props.currentPlayer.is_moderator,
board: gameBoard,
});
@@ -115,7 +116,9 @@ const voteCount = computed(
:revealed="room.revealed"
:presenter-mode="presenterMode"
:is-paper-ball-hit="hitPlayerIds.includes(player.id)"
:throw-disabled="throwingAtPlayerId !== null"
:throw-disabled="
!currentPlayer.is_moderator && throwingAtPlayerId !== null
"
@throw-paper-ball="throwPaperBall"
/>
+14 -7
View File
@@ -17,6 +17,7 @@ const THROW_BUTTON_COOLDOWN = 550;
export function usePaperBallToss({
roomId,
currentPlayerId,
currentPlayerIsModerator,
board,
}: PaperBallTossOptions) {
const activePaperBalls = ref<PaperBallFlight[]>([]);
@@ -35,9 +36,11 @@ export function usePaperBallToss({
}
async function throwPaperBall(targetPlayerId: number): Promise<void> {
const shouldApplyCooldown = !currentPlayerIsModerator();
if (
targetPlayerId === currentPlayerId() ||
throwingAtPlayerId.value !== null
(shouldApplyCooldown && throwingAtPlayerId.value !== null)
) {
return;
}
@@ -52,7 +55,9 @@ export function usePaperBallToss({
return;
}
throwingAtPlayerId.value = targetPlayerId;
if (shouldApplyCooldown) {
throwingAtPlayerId.value = targetPlayerId;
}
try {
const response = await fetch(throwPaperBallRoute(roomId()).url, {
@@ -91,11 +96,13 @@ export function usePaperBallToss({
} catch {
toast.error('Der Papierknäuel konnte nicht geworfen werden.');
} finally {
schedule(() => {
if (throwingAtPlayerId.value === targetPlayerId) {
throwingAtPlayerId.value = null;
}
}, THROW_BUTTON_COOLDOWN);
if (shouldApplyCooldown) {
schedule(() => {
if (throwingAtPlayerId.value === targetPlayerId) {
throwingAtPlayerId.value = null;
}
}, THROW_BUTTON_COOLDOWN);
}
}
}
+1
View File
@@ -25,6 +25,7 @@ export type PaperBallFlight = {
export type PaperBallTossOptions = {
roomId: () => string;
currentPlayerId: () => number;
currentPlayerIsModerator: () => boolean;
board: Ref<HTMLElement | null>;
};
+52
View File
@@ -59,6 +59,58 @@ test('a participant can throw a realtime paper ball at another player', function
->and($room->state_version)->toBe($stateVersion);
});
test('moderator paper ball throws are not rate limited', function () {
Event::fake([PaperBallThrown::class]);
$room = createEmoteRoom();
$moderator = $room->players()->create([
'name' => 'Eric',
'is_moderator' => true,
]);
$target = $room->players()->create([
'name' => 'Anna',
'is_moderator' => false,
]);
for ($throwCount = 0; $throwCount < 11; $throwCount++) {
$this->withSession(["room_players.{$room->id}" => $moderator->id])
->postJson(route('room.emote.paper-ball.store', $room), [
'target_player_id' => $target->id,
])
->assertNoContent();
}
Event::assertDispatchedTimes(PaperBallThrown::class, 11);
});
test('participant paper ball throws remain rate limited', function () {
Event::fake([PaperBallThrown::class]);
$room = createEmoteRoom();
$moderator = $room->players()->create([
'name' => 'Eric',
'is_moderator' => true,
]);
$participant = $room->players()->create([
'name' => 'Anna',
'is_moderator' => false,
]);
for ($throwCount = 0; $throwCount < 10; $throwCount++) {
$this->withSession(["room_players.{$room->id}" => $participant->id])
->postJson(route('room.emote.paper-ball.store', $room), [
'target_player_id' => $moderator->id,
])
->assertNoContent();
}
$this->withSession(["room_players.{$room->id}" => $participant->id])
->postJson(route('room.emote.paper-ball.store', $room), [
'target_player_id' => $moderator->id,
])
->assertTooManyRequests();
Event::assertDispatchedTimes(PaperBallThrown::class, 10);
});
test('a participant cannot throw a paper ball at themselves', function () {
Event::fake([PaperBallThrown::class]);
$room = createEmoteRoom();