-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1743 from gettakaro/issue689
Daily rewards module
- Loading branch information
Showing
9 changed files
with
468 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 118 additions & 0 deletions
118
packages/lib-modules/src/modules/dailyRewards/commands/daily.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { takaro, data, TakaroUserError, checkPermission } from '@takaro/helpers'; | ||
import { DAILY_KEY, STREAK_KEY, getMultiplier } from './utils.js'; | ||
|
||
async function main() { | ||
const { pog, gameServerId, module: mod } = data; | ||
|
||
if (!checkPermission(pog, 'DAILY_CLAIM')) { | ||
throw new TakaroUserError('You do not have permission to claim daily rewards.'); | ||
} | ||
|
||
// Get last claim time | ||
const lastClaimRes = await takaro.variable.variableControllerSearch({ | ||
filters: { | ||
key: [DAILY_KEY], | ||
gameServerId: [gameServerId], | ||
playerId: [pog.playerId], | ||
moduleId: [mod.moduleId], | ||
}, | ||
}); | ||
|
||
const now = new Date(); | ||
let streak = 1; | ||
|
||
if (lastClaimRes.data.data.length > 0) { | ||
const lastClaim = new Date(JSON.parse(lastClaimRes.data.data[0].value)); | ||
const hoursSinceLastClaim = (now - lastClaim) / (1000 * 60 * 60); | ||
|
||
// Check if 24 hours have passed | ||
if (hoursSinceLastClaim < 24) { | ||
const nextClaimTime = new Date(lastClaim.getTime() + 24 * 60 * 60 * 1000); | ||
throw new TakaroUserError(`You can claim your next reward at ${nextClaimTime.toLocaleString()}`); | ||
} | ||
|
||
// Get current streak | ||
const streakRes = await takaro.variable.variableControllerSearch({ | ||
filters: { | ||
key: [STREAK_KEY], | ||
gameServerId: [gameServerId], | ||
playerId: [pog.playerId], | ||
moduleId: [mod.moduleId], | ||
}, | ||
}); | ||
|
||
if (streakRes.data.data.length > 0) { | ||
// If claimed within 48 hours, increment streak | ||
if (hoursSinceLastClaim < 48) { | ||
streak = Math.min(JSON.parse(streakRes.data.data[0].value) + 1, mod.userConfig.maxStreak); | ||
await takaro.variable.variableControllerUpdate(streakRes.data.data[0].id, { | ||
value: JSON.stringify(streak), | ||
}); | ||
} else { | ||
// Reset streak if more than 48 hours | ||
await takaro.variable.variableControllerUpdate(streakRes.data.data[0].id, { | ||
value: JSON.stringify(1), | ||
}); | ||
} | ||
} else { | ||
// Create new streak record | ||
await takaro.variable.variableControllerCreate({ | ||
key: STREAK_KEY, | ||
value: JSON.stringify(1), | ||
gameServerId, | ||
playerId: pog.playerId, | ||
moduleId: mod.moduleId, | ||
}); | ||
} | ||
|
||
// Update last claim time | ||
await takaro.variable.variableControllerUpdate(lastClaimRes.data.data[0].id, { | ||
value: JSON.stringify(now), | ||
}); | ||
} else { | ||
// First time claim | ||
await takaro.variable.variableControllerCreate({ | ||
key: DAILY_KEY, | ||
value: JSON.stringify(now), | ||
gameServerId, | ||
playerId: pog.playerId, | ||
moduleId: mod.moduleId, | ||
}); | ||
await takaro.variable.variableControllerCreate({ | ||
key: STREAK_KEY, | ||
value: JSON.stringify(1), | ||
gameServerId, | ||
playerId: pog.playerId, | ||
moduleId: mod.moduleId, | ||
}); | ||
} | ||
|
||
const multiplier = await getMultiplier(pog); | ||
const baseReward = mod.userConfig.baseReward * streak * multiplier; | ||
let bonusReward = 0; | ||
let milestoneMessage = ''; | ||
|
||
// Check for milestones | ||
for (const milestone of mod.userConfig.milestoneRewards) { | ||
if (streak === milestone.days) { | ||
bonusReward = milestone.reward; | ||
milestoneMessage = `\n${milestone.message}`; | ||
break; | ||
} | ||
} | ||
|
||
// Award total rewards | ||
const totalReward = baseReward + bonusReward; | ||
await takaro.playerOnGameserver.playerOnGameServerControllerAddCurrency(gameServerId, pog.playerId, { | ||
currency: totalReward, | ||
}); | ||
|
||
const currencyName = (await takaro.settings.settingsControllerGetOne('currencyName', gameServerId)).data.data.value; | ||
await pog.pm( | ||
`Daily reward claimed! You received ${totalReward} ${currencyName}\n` + | ||
`Current streak: ${streak} days${multiplier > 1 ? ` (${multiplier}x bonus!)` : ''}` + | ||
milestoneMessage, | ||
); | ||
} | ||
|
||
await main(); |
42 changes: 42 additions & 0 deletions
42
packages/lib-modules/src/modules/dailyRewards/commands/streak.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { data, takaro } from '@takaro/helpers'; | ||
import { getPlayerStreak, getLastClaim, getMultiplier } from './utils.js'; | ||
|
||
async function main() { | ||
const { pog, gameServerId, module: mod } = data; | ||
|
||
const streak = await getPlayerStreak(gameServerId, pog.playerId, mod.moduleId); | ||
const lastClaim = await getLastClaim(gameServerId, pog.playerId, mod.moduleId); | ||
const multiplier = await getMultiplier(pog); | ||
const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value; | ||
|
||
if (!streak || !lastClaim) { | ||
await pog.pm(`You haven't claimed any daily rewards yet! Use ${prefix}daily to get started.`); | ||
return; | ||
} | ||
|
||
const nextClaimTime = new Date(lastClaim.getTime() + 24 * 60 * 60 * 1000); | ||
const now = new Date(); | ||
const canClaim = now >= nextClaimTime; | ||
|
||
// Find next milestone | ||
let nextMilestone = null; | ||
for (const milestone of mod.userConfig.milestoneRewards) { | ||
if (milestone.days > streak) { | ||
nextMilestone = milestone; | ||
break; | ||
} | ||
} | ||
|
||
let message = `Current streak: ${streak} days${multiplier > 1 ? ` (${multiplier}x donor bonus!)` : ''}\n`; | ||
message += canClaim | ||
? `Your daily reward is available! Use ${prefix}daily to claim it!\n` | ||
: `Next reward available at: ${nextClaimTime.toLocaleString()}\n`; | ||
|
||
if (nextMilestone) { | ||
message += `\n🎯 Next milestone: ${nextMilestone.days} days (${nextMilestone.days - streak} days to go!)`; | ||
} | ||
|
||
await pog.pm(message); | ||
} | ||
|
||
await main(); |
54 changes: 54 additions & 0 deletions
54
packages/lib-modules/src/modules/dailyRewards/commands/topstreak.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { takaro, data } from '@takaro/helpers'; | ||
import { STREAK_KEY } from './utils.js'; | ||
|
||
async function main() { | ||
const { pog, gameServerId, module: mod, arguments: args } = data; | ||
|
||
// Limit count to reasonable number | ||
const count = Math.min(Math.max(1, args.count), 50); | ||
|
||
// Get all streaks | ||
const streaksRes = await takaro.variable.variableControllerSearch({ | ||
filters: { | ||
key: [STREAK_KEY], | ||
gameServerId: [gameServerId], | ||
moduleId: [mod.moduleId], | ||
}, | ||
limit: 1000, // Get all possible streaks | ||
}); | ||
|
||
if (streaksRes.data.data.length === 0) { | ||
await pog.pm('No players have started their daily streak yet!'); | ||
return; | ||
} | ||
|
||
// Sort by streak value | ||
const sortedStreaks = streaksRes.data.data | ||
.map((record) => ({ | ||
playerId: record.playerId, | ||
streak: JSON.parse(record.value), | ||
})) | ||
.sort((a, b) => b.streak - a.streak) | ||
.slice(0, count); | ||
|
||
// Get player names | ||
const playerDetails = await Promise.all( | ||
sortedStreaks.map(async (record) => { | ||
const player = (await takaro.player.playerControllerGetOne(record.playerId)).data.data; | ||
return { | ||
name: player.name, | ||
streak: record.streak, | ||
}; | ||
}), | ||
); | ||
|
||
// Build message | ||
let message = `Top ${count} Daily Streaks:\n\n`; | ||
playerDetails.forEach((player, index) => { | ||
message += `${index + 1}. ${player.name}: ${player.streak} days\n`; | ||
}); | ||
|
||
await pog.pm(message); | ||
} | ||
|
||
await main(); |
36 changes: 36 additions & 0 deletions
36
packages/lib-modules/src/modules/dailyRewards/functions/utils.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { takaro, checkPermission } from '@takaro/helpers'; | ||
|
||
export const DAILY_KEY = 'daily_timestamp'; | ||
export const STREAK_KEY = 'daily_streak'; | ||
|
||
export async function getMultiplier(pog) { | ||
const perm = checkPermission(pog, 'DAILY_REWARD_MULTIPLIER'); | ||
if (perm) return perm.count; | ||
return 1; | ||
} | ||
|
||
export async function getPlayerStreak(gameServerId, playerId, moduleId) { | ||
const streakRes = await takaro.variable.variableControllerSearch({ | ||
filters: { | ||
key: [STREAK_KEY], | ||
gameServerId: [gameServerId], | ||
playerId: [playerId], | ||
moduleId: [moduleId], | ||
}, | ||
}); | ||
|
||
return streakRes.data.data.length ? parseInt(JSON.parse(streakRes.data.data[0].value)) : 0; | ||
} | ||
|
||
export async function getLastClaim(gameServerId, playerId, moduleId) { | ||
const lastClaimRes = await takaro.variable.variableControllerSearch({ | ||
filters: { | ||
key: [DAILY_KEY], | ||
gameServerId: [gameServerId], | ||
playerId: [playerId], | ||
moduleId: [moduleId], | ||
}, | ||
}); | ||
|
||
return lastClaimRes.data.data.length ? new Date(JSON.parse(lastClaimRes.data.data[0].value)) : null; | ||
} |
24 changes: 24 additions & 0 deletions
24
packages/lib-modules/src/modules/dailyRewards/hooks/dailyLoginCheck.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { data, takaro } from '@takaro/helpers'; | ||
import { getLastClaim } from './utils.js'; | ||
|
||
async function main() { | ||
const { pog, gameServerId, module: mod } = data; | ||
const prefix = (await takaro.settings.settingsControllerGetOne('commandPrefix', gameServerId)).data.data.value; | ||
|
||
const lastClaim = await getLastClaim(gameServerId, pog.playerId, mod.moduleId); | ||
|
||
// First time player | ||
if (!lastClaim) { | ||
await pog.pm(`Welcome! Use ${prefix}daily to claim your first daily reward and start your streak!`); | ||
return; | ||
} | ||
|
||
const now = new Date(); | ||
const nextClaimTime = new Date(lastClaim.getTime() + 24 * 60 * 60 * 1000); | ||
|
||
if (now >= nextClaimTime) { | ||
await pog.pm(`Your daily reward is ready! Use ${prefix}daily to claim it!`); | ||
} | ||
} | ||
|
||
await main(); |
Oops, something went wrong.