diff --git a/composer.json b/composer.json
index 88ee789d..a2e906fe 100644
--- a/composer.json
+++ b/composer.json
@@ -34,9 +34,10 @@
"inc/lock.php",
"inc/queue.php",
"inc/functions.php",
+ "inc/functions/dice.php",
+ "inc/functions/format.php",
"inc/functions/net.php",
"inc/functions/num.php",
- "inc/functions/format.php",
"inc/functions/theme.php",
"inc/service/captcha-queries.php",
"inc/context.php"
diff --git a/inc/config.php b/inc/config.php
index 11ac8809..067bc715 100644
--- a/inc/config.php
+++ b/inc/config.php
@@ -712,6 +712,9 @@
);
*/
+ // Maximum number inline of dice rolls per markup.
+ $config['max_roll_count'] = 50;
+
// Allow dice rolling: an email field of the form "dice XdY+/-Z" will result in X Y-sided dice rolled and summed,
// with the modifier Z added, with the result displayed at the top of the post body.
$config['allow_roll'] = false;
@@ -783,11 +786,15 @@
* ====================
*/
- // "Wiki" markup syntax ($config['wiki_markup'] in pervious versions):
- $config['markup'][] = array("/'''(.+?)'''/", "\$1");
- $config['markup'][] = array("/''(.+?)''/", "\$1");
- $config['markup'][] = array("/\*\*(.+?)\*\*/", "\$1");
- $config['markup'][] = array("/^[ |\t]*==(.+?)==[ |\t]*$/m", "\$1");
+ $config['markup'] = [
+ // Inline dice roll markup.
+ [ "/!([-+]?\d+)?([d])([-+]?\d+)([-+]\d+)?/iu", fn($m) => inline_dice_roll_markup($m, 'static/d10.svg') ],
+ // "Wiki" markup syntax ($config['wiki_markup'] in pervious versions):
+ [ "/'''(.+?)'''/", "\$1" ],
+ [ "/''(.+?)''/", "\$1" ],
+ [ "/\*\*(.+?)\*\*/", "\$1" ],
+ [ "/^[ |\t]*==(.+?)==[ |\t]*$/m", "\$1" ],
+ ];
// Code markup. This should be set to a regular expression, using tags you want to use. Examples:
// "/\[code\](.*?)\[\/code\]/is"
diff --git a/inc/functions.php b/inc/functions.php
index 30994b5d..15aa2c0e 100755
--- a/inc/functions.php
+++ b/inc/functions.php
@@ -241,7 +241,7 @@ function loadConfig() {
$config['version'] = $__version;
if ($config['allow_roll']) {
- event_handler('post', 'diceRoller');
+ event_handler('post', 'email_dice_roll');
}
if (in_array('webm', $config['allowed_ext_files']) || in_array('mp4', $config['allowed_ext_files'])) {
@@ -2600,65 +2600,6 @@ function shell_exec_error($command, $suppress_stdout = false) {
return $return === 'TB_SUCCESS' ? false : $return;
}
-/* Die rolling:
- * If "dice XdY+/-Z" is in the email field (where X or +/-Z may be
- * missing), X Y-sided dice are rolled and summed, with the modifier Z
- * added on. The result is displayed at the top of the post.
- */
-function diceRoller($post) {
- global $config;
- if(strpos(strtolower($post->email), 'dice%20') === 0) {
- $dicestr = str_split(substr($post->email, strlen('dice%20')));
-
- // Get params
- $diceX = '';
- $diceY = '';
- $diceZ = '';
-
- $curd = 'diceX';
- for($i = 0; $i < count($dicestr); $i ++) {
- if(is_numeric($dicestr[$i])) {
- $$curd .= $dicestr[$i];
- } else if($dicestr[$i] == 'd') {
- $curd = 'diceY';
- } else if($dicestr[$i] == '-' || $dicestr[$i] == '+') {
- $curd = 'diceZ';
- $$curd = $dicestr[$i];
- }
- }
-
- // Default values for X and Z
- if($diceX == '') {
- $diceX = '1';
- }
-
- if($diceZ == '') {
- $diceZ = '+0';
- }
-
- // Intify them
- $diceX = intval($diceX);
- $diceY = intval($diceY);
- $diceZ = intval($diceZ);
-
- // Continue only if we have valid values
- if($diceX > 0 && $diceY > 0) {
- $dicerolls = array();
- $dicesum = $diceZ;
- for($i = 0; $i < $diceX; $i++) {
- $roll = rand(1, $diceY);
- $dicerolls[] = $roll;
- $dicesum += $roll;
- }
-
- // Prepend the result to the post body
- $modifier = ($diceZ != 0) ? ((($diceZ < 0) ? ' - ' : ' + ') . abs($diceZ)) : '';
- $dicesum = ($diceX > 1) ? ' = ' . $dicesum : '';
- $post->body = '
 | Rolled ' . implode(', ', $dicerolls) . $modifier . $dicesum . ' |
' . $post->body;
- }
- }
-}
-
function slugify($post) {
global $config;
diff --git a/inc/functions/dice.php b/inc/functions/dice.php
new file mode 100644
index 00000000..558257bf
--- /dev/null
+++ b/inc/functions/dice.php
@@ -0,0 +1,114 @@
+email), 'dice%20') === 0) {
+ $dicestr = str_split(substr($post->email, strlen('dice%20')));
+
+ // Get params
+ $diceX = '';
+ $diceY = '';
+ $diceZ = '';
+
+ $curd = 'diceX';
+ for($i = 0; $i < count($dicestr); $i ++) {
+ if(is_numeric($dicestr[$i])) {
+ $$curd .= $dicestr[$i];
+ } else if($dicestr[$i] == 'd') {
+ $curd = 'diceY';
+ } else if($dicestr[$i] == '-' || $dicestr[$i] == '+') {
+ $curd = 'diceZ';
+ $$curd = $dicestr[$i];
+ }
+ }
+
+ // Default values for X and Z
+ if($diceX == '') {
+ $diceX = '1';
+ }
+
+ if($diceZ == '') {
+ $diceZ = '+0';
+ }
+
+ // Intify them
+ $diceX = intval($diceX);
+ $diceY = intval($diceY);
+ $diceZ = intval($diceZ);
+
+ // Continue only if we have valid values
+ if($diceX > 0 && $diceY > 0) {
+ $dicerolls = array();
+ $dicesum = $diceZ;
+ for($i = 0; $i < $diceX; $i++) {
+ $roll = rand(1, $diceY);
+ $dicerolls[] = $roll;
+ $dicesum += $roll;
+ }
+
+ // Prepend the result to the post body
+ $modifier = ($diceZ != 0) ? ((($diceZ < 0) ? ' - ' : ' + ') . abs($diceZ)) : '';
+ $dicesum = ($diceX > 1) ? ' = ' . $dicesum : '';
+ $post->body = ' | Rolled ' . implode(', ', $dicerolls) . $modifier . $dicesum . ' |
' . $post->body;
+ }
+ }
+}
+
+/**
+ * Rolls a dice and generates the appropriate html from the markup.
+ * @param array $matches The array of the matches according to the default configuration.
+ * 1 -> The number of dices to roll.
+ * 3 -> The number faces of the dices.
+ * 4 -> The offset to apply to the dice.
+ * @param string $img_path Path to the image to use relative to the root. Null if none.
+ * @return string The html to replace the original markup with.
+ */
+function inline_dice_roll_markup(array $matches, ?string $img_path): string {
+ global $config;
+
+ $dice_count = _get_or_default_int($matches, 1, 1);
+ $dice_faces = _get_or_default_int($matches, 3, 6);
+ $dice_offset = _get_or_default_int($matches, 4, 0);
+
+ // Clamp between 1 and max_roll_count.
+ $dice_count = max(min($dice_count, $config['max_roll_count']), 1);
+ // Must be at least 2.
+ if ($dice_faces < 2) {
+ $dice_faces = 6;
+ }
+
+ $tot = 0;
+ for ($i = 0; $i < $dice_count; $i++) {
+ $tot += mt_rand(1, $dice_faces);
+ }
+ // Ensure that final result is at least an integer.
+ $tot = abs((int)($dice_offset + $tot));
+
+
+ if ($img_path !== null) {
+ $img_text = "
";
+ } else {
+ $img_text = '';
+ }
+
+ if ($dice_offset === 0) {
+ $dice_offset_text = '';
+ } elseif ($dice_offset > 0) {
+ $dice_offset_text = "+{$dice_offset}";
+ } else {
+ $dice_offset_text = (string)$dice_offset;
+ }
+
+ return "$img_text {$dice_count}d{$dice_faces}{$dice_offset_text} = $tot";
+}
diff --git a/stylesheets/style.css b/stylesheets/style.css
index b7c39b26..ef1abf8b 100644
--- a/stylesheets/style.css
+++ b/stylesheets/style.css
@@ -1042,6 +1042,20 @@ div.boardlist a {
cursor: pointer;
}
+/* Inline dice */
+.dice-option table {
+ border: 1px dotted black;
+ margin: 0;
+ border-collapse: collapse;
+}
+.dice-option table td {
+ text-align: center;
+ border-left: 1px dotted black;
+ padding-left: 2px;
+ padding-right: 2px;
+ padding-bottom: 2px;
+}
+
#youtube-size input {
width: 50px;
}