@@ -105,25 +105,78 @@ export default {
105105 quantity = interaction . options . getInteger ( "quantity" ) ?? 1 ;
106106 }
107107
108- const { results, total } = roll ( `${ quantity } d${ sides } ` ) ;
109-
110- const reply = `**Rolling \`${ quantity } d${ sides } \`...**\n${ `\`${ results . join (
111- " + "
112- ) } = ${ total } \``} `;
113-
114- if ( reply . length > 2000 ) {
115- return interaction . followUp ( {
116- content :
117- "The result is too long to send as a message, here is a file instead." ,
118- files : [
119- {
120- attachment : Buffer . from ( reply ) ,
121- name : "roll.md" ,
122- } ,
123- ] ,
124- } ) ;
108+ // Apply limits: max 100 dice, max 100 sides
109+ if ( quantity > 100 ) {
110+ return interaction . editReply ( "❌ Maximum of 100 dice allowed per roll." ) ;
125111 }
126112
127- return interaction . followUp ( reply ) ;
113+ if ( sides > 100 ) {
114+ return interaction . editReply ( "❌ Maximum of 100 sides allowed per die." ) ;
115+ }
116+
117+ // For large calculations, process in chunks to avoid timeout
118+ const isLargeCalculation = quantity > 100 || ( quantity * sides > 100000 ) ;
119+
120+ if ( isLargeCalculation ) {
121+ // Process in chunks to avoid timeout
122+ const chunkSize = Math . min ( 100 , Math . max ( 1 , Math . floor ( 10000 / sides ) ) ) ;
123+ let results = [ ] ;
124+ let total = 0 ;
125+
126+ for ( let chunk = 0 ; chunk < quantity ; chunk += chunkSize ) {
127+ const currentChunkSize = Math . min ( chunkSize , quantity - chunk ) ;
128+ const chunkDice = `${ currentChunkSize } d${ sides } ` ;
129+ const chunkResult = roll ( chunkDice ) ;
130+
131+ results = results . concat ( chunkResult . results ) ;
132+ total += chunkResult . total ;
133+
134+ // Yield control periodically to prevent blocking
135+ if ( chunk % ( chunkSize * 10 ) === 0 ) {
136+ await new Promise ( resolve => setImmediate ( resolve ) ) ;
137+ }
138+ }
139+
140+ const reply = `**Rolling \`${ quantity } d${ sides } \`...**\n${ `\`${ results . join (
141+ " + "
142+ ) } = ${ total } \``} `;
143+
144+ if ( reply . length > 2000 ) {
145+ return interaction . editReply ( {
146+ content :
147+ "The result is too long to send as a message, here is a file instead." ,
148+ files : [
149+ {
150+ attachment : Buffer . from ( reply ) ,
151+ name : "roll.md" ,
152+ } ,
153+ ] ,
154+ } ) ;
155+ }
156+
157+ return interaction . editReply ( reply ) ;
158+ } else {
159+ // For small calculations, use the original fast path
160+ const { results, total } = roll ( `${ quantity } d${ sides } ` ) ;
161+
162+ const reply = `**Rolling \`${ quantity } d${ sides } \`...**\n${ `\`${ results . join (
163+ " + "
164+ ) } = ${ total } \``} `;
165+
166+ if ( reply . length > 2000 ) {
167+ return interaction . editReply ( {
168+ content :
169+ "The result is too long to send as a message, here is a file instead." ,
170+ files : [
171+ {
172+ attachment : Buffer . from ( reply ) ,
173+ name : "roll.md" ,
174+ } ,
175+ ] ,
176+ } ) ;
177+ }
178+
179+ return interaction . editReply ( reply ) ;
180+ }
128181 } ,
129182} ;
0 commit comments