(client, guildId, userId, data)
| 221 | } |
| 222 | |
| 223 | export async function saveUserLevelData(client, guildId, userId, data) { |
| 224 | try { |
| 225 | if (!guildId || !userId) { |
| 226 | throw new TitanBotError( |
| 227 | 'Guild ID and User ID are required', |
| 228 | ErrorTypes.VALIDATION |
| 229 | ); |
| 230 | } |
| 231 | |
| 232 | if (!data || typeof data !== 'object') { |
| 233 | throw new TitanBotError( |
| 234 | 'Invalid user level data', |
| 235 | ErrorTypes.VALIDATION |
| 236 | ); |
| 237 | } |
| 238 | |
| 239 | const sanitizedData = { |
| 240 | xp: Math.max(0, Number(data.xp) || 0), |
| 241 | level: Math.max(0, Math.min(Number(data.level) || 0, MAX_LEVEL)), |
| 242 | totalXp: Math.max(0, Number(data.totalXp) || 0), |
| 243 | lastMessage: Number(data.lastMessage) || 0, |
| 244 | rank: Number(data.rank) || 0 |
| 245 | }; |
| 246 | |
| 247 | const key = `${guildId}:leveling:users:${userId}`; |
| 248 | await client.db.set(key, sanitizedData); |
| 249 | } catch (error) { |
| 250 | logger.error(`Error saving user level data for ${userId}:`, error); |
| 251 | if (error instanceof TitanBotError) throw error; |
| 252 | throw new TitanBotError( |
| 253 | `Failed to save user data: ${error.message}`, |
| 254 | ErrorTypes.DATABASE, |
| 255 | 'Could not save level data at this time.' |
| 256 | ); |
| 257 | } |
| 258 | } |
| 259 | |
| 260 | export async function saveLevelingConfig(client, guildId, config) { |
| 261 | try { |
no test coverage detected