fix
This commit is contained in:
@@ -26,7 +26,7 @@ export interface MascotTier {
|
||||
|
||||
interface GameState {
|
||||
totalClicks: number;
|
||||
users: Record<string, { name: string; clicks: number; lastSeen: number; bonusMultiplier: number }>;
|
||||
users: Record<string, { name: string; clicks: number; lastSeen: number; bonusMultiplier: number; lastClickTime?: number }>;
|
||||
upgrades: Record<string, { owned: number; cost: number }>;
|
||||
milestones: Record<string, boolean>;
|
||||
clickMultiplier: number;
|
||||
@@ -353,25 +353,34 @@ export default class GameServer implements Party.Server {
|
||||
// // No explicit action needed here beyond what onMessage does.
|
||||
// }
|
||||
|
||||
// Define a minimum interval between clicks (e.g., 100ms for 10 clicks/second)
|
||||
// This helps prevent simple auto-clicker scripts by rate-limiting server-side.
|
||||
private readonly MIN_CLICK_INTERVAL = 50; // milliseconds
|
||||
|
||||
handleClick(data: ClickMessage, authenticatedUserId: string) {
|
||||
const now = Date.now();
|
||||
const userState = this.gameState.users[authenticatedUserId];
|
||||
|
||||
// Ensure user exists (should be handled by onMessage's token verification)
|
||||
if (!userState) {
|
||||
console.warn(`User ${authenticatedUserId} not found for click handling.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Implement rate limiting
|
||||
if (userState.lastClickTime && (now - userState.lastClickTime < this.MIN_CLICK_INTERVAL)) {
|
||||
console.warn(`Rate limit exceeded for user ${authenticatedUserId}. Click ignored.`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Apply global click multiplier and user-specific bonus multiplier
|
||||
const userBonusMultiplier = this.gameState.users[authenticatedUserId]?.bonusMultiplier || 1;
|
||||
const userBonusMultiplier = userState.bonusMultiplier || 1;
|
||||
const clickValue = this.gameState.clickMultiplier * userBonusMultiplier;
|
||||
|
||||
this.gameState.totalClicks += clickValue;
|
||||
|
||||
// Ensure user exists (should be handled by onMessage's token verification)
|
||||
if (!this.gameState.users[authenticatedUserId]) {
|
||||
this.gameState.users[authenticatedUserId] = {
|
||||
name: data.userName, // Use the name from the client, which comes from Clerk
|
||||
clicks: 0,
|
||||
lastSeen: Date.now(),
|
||||
bonusMultiplier: 1 // Initialize if user was just created
|
||||
};
|
||||
}
|
||||
|
||||
this.gameState.users[authenticatedUserId].clicks += clickValue;
|
||||
this.gameState.users[authenticatedUserId].lastSeen = Date.now();
|
||||
userState.clicks += clickValue;
|
||||
userState.lastSeen = now;
|
||||
userState.lastClickTime = now; // Update last valid click time
|
||||
|
||||
this.checkMilestones();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user