Extensions
30
ext/phpbbstudio/dice/acp/dice_info.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\acp;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice ACP module info.
|
||||
*/
|
||||
class dice_info
|
||||
{
|
||||
public function module()
|
||||
{
|
||||
return [
|
||||
'filename' => '\phpbbstudio\dice\acp\dice_module',
|
||||
'title' => 'ACP_DICE_CAT',
|
||||
'modes' => [
|
||||
'dashboard' => [
|
||||
'title' => 'ACP_DICE_DASH',
|
||||
'auth' => 'ext_phpbbstudio/dice && acl_a_dice_admin',
|
||||
'cat' => ['ACP_DICE_CAT'],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
73
ext/phpbbstudio/dice/acp/dice_module.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\acp;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice ACP module.
|
||||
*/
|
||||
class dice_module
|
||||
{
|
||||
public $page_title;
|
||||
public $tpl_name;
|
||||
public $u_action;
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
* @param $mode
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function main($id, $mode)
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
// Get services
|
||||
$controller = $phpbb_container->get('phpbbstudio.dice.controller.admin');
|
||||
$language = $phpbb_container->get('language');
|
||||
$request = $phpbb_container->get('request');
|
||||
|
||||
// Add our lang file
|
||||
$language->add_lang('acp_dice', 'phpbbstudio/dice');
|
||||
|
||||
// Request any action
|
||||
$action = $request->variable('action', '', true);
|
||||
|
||||
switch ($action)
|
||||
{
|
||||
case 'example':
|
||||
// Set template filename
|
||||
$this->tpl_name = 'dice_example';
|
||||
|
||||
// Set page title
|
||||
$this->page_title = 'ACP_DICE_EXAMPLE';
|
||||
break;
|
||||
|
||||
case 'locations':
|
||||
// Set template filename
|
||||
$this->tpl_name = 'dice_locations';
|
||||
|
||||
// Set page title
|
||||
$this->page_title = 'ACP_DICE_LOCATIONS';
|
||||
break;
|
||||
|
||||
default:
|
||||
// Set template filename
|
||||
$this->tpl_name = 'dice_acp';
|
||||
|
||||
// Set page title
|
||||
$this->page_title = 'ACP_DICE_DASH';
|
||||
break;
|
||||
}
|
||||
|
||||
// Make the $u_action variable available in the admin controller
|
||||
$controller->set_page_url($this->u_action);
|
||||
|
||||
// Send it off to be handled with
|
||||
$controller->handle($action);
|
||||
}
|
||||
}
|
||||
409
ext/phpbbstudio/dice/adm/style/css/dice_acp.css
Normal file
@@ -0,0 +1,409 @@
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
.row,
|
||||
.row * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-right: -15px;
|
||||
margin-left: -15px;
|
||||
}
|
||||
|
||||
.col {
|
||||
position: relative;
|
||||
flex: 0 0 25%;
|
||||
width: 100%;
|
||||
max-width: 25%;
|
||||
min-height: 1px;
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
@media all and (max-width: 1224px) {
|
||||
.col {
|
||||
flex: 0 0 50%;
|
||||
max-width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.card {
|
||||
font-size: 0.875rem;
|
||||
word-wrap: break-word;
|
||||
background: #ffffff;
|
||||
border: 0;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.14);
|
||||
color: #333333;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background: transparent;
|
||||
border-bottom: none;
|
||||
border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;
|
||||
color: #ffffff;
|
||||
position: relative;
|
||||
z-index: 3 !important;
|
||||
margin: 0 15px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.card-header-icon {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
position: relative;
|
||||
padding: 0.9375rem 20px;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
border-top: 1px solid #eeeeee;
|
||||
border-radius: 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin: 14px 15px 10px;
|
||||
padding: 10px 0 0;
|
||||
}
|
||||
|
||||
.card-footer-closer {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.card-footer .card-action {
|
||||
text-align: center;
|
||||
flex: 0 100%;
|
||||
}
|
||||
|
||||
.card-icon {
|
||||
background: #999999;
|
||||
border-radius: 3px;
|
||||
float: left;
|
||||
margin-top: -20px;
|
||||
margin-right: 15px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.card-icon i {
|
||||
font-size: 36px;
|
||||
line-height: 56px;
|
||||
text-align: center;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.card-category {
|
||||
font-size: 14px;
|
||||
color: #999999;
|
||||
margin: 0;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.card-avatar img {
|
||||
width: 26px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
h3.card-title {
|
||||
font-size: 1.5625rem;
|
||||
font-weight: 300;
|
||||
line-height: 1.5em;
|
||||
text-decoration: none;
|
||||
color: #3c4858;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h4.card-title {
|
||||
font-size: 1.125rem;
|
||||
font-weight: 300;
|
||||
line-height: 1.4em;
|
||||
text-decoration: none;
|
||||
color: #ffffff;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.stats {
|
||||
font-size: 12px;
|
||||
line-height: 22px;
|
||||
color: #999999;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
@media all and (max-width: 800px) {
|
||||
.stats {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.card .stats i {
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
margin-right: 3px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.card small {
|
||||
font-size: 80%;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.card label {
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.card a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.card a.card-primary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.card a.card-secondary {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.card a:hover,
|
||||
.card a:hover .stats,
|
||||
.card label:hover,
|
||||
.card label:hover .stats {
|
||||
text-decoration: none;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.card .card-header .card-title + .card-category {
|
||||
color: hsla(0, 0%, 100%, 0.62);
|
||||
}
|
||||
|
||||
.card .card-header:not(.card-header-icon) {
|
||||
border-radius: 3px;
|
||||
margin-top: -20px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.dice-orange {
|
||||
background: linear-gradient(60deg, #ffa726, #fb8c00);
|
||||
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), 0 7px 10px -5px rgba(255, 152, 0, 0.4);
|
||||
}
|
||||
|
||||
.dice-green {
|
||||
background: linear-gradient(60deg, #66bb6a, #43a047);
|
||||
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), 0 7px 10px -5px rgba(76, 175, 80, 0.4);
|
||||
}
|
||||
|
||||
.dice-blue {
|
||||
background: linear-gradient(60deg, #26c6da, #00acc1);
|
||||
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), 0 7px 10px -5px rgba(0, 188, 212, 0.4);
|
||||
}
|
||||
|
||||
.dice-red {
|
||||
background: linear-gradient(60deg, #ef5350, #e53935);
|
||||
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), 0 7px 10px -5px rgba(244, 67, 54, 0.4);
|
||||
}
|
||||
|
||||
.dice-purple {
|
||||
background: linear-gradient(60deg, #ab47bc, #8e24aa);
|
||||
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.14), 0 7px 10px -5px rgba(156, 39, 176, 0.4);
|
||||
}
|
||||
|
||||
.dice-button {
|
||||
font-size: 0.9rem;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 3px;
|
||||
color: #ffffff;
|
||||
padding: 2px 6px 3px;
|
||||
}
|
||||
|
||||
.dice-button i + span {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
a.dice-button-locations {
|
||||
color: #ffffff;
|
||||
display: inline-block;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.dice-button-green {
|
||||
background: linear-gradient(60deg, #66bb6a, #43a047);
|
||||
border-color: #1b9a1b;
|
||||
}
|
||||
|
||||
.dice-button-red {
|
||||
background: linear-gradient(60deg, #ef5350, #e53935);
|
||||
border-color: #d31141;
|
||||
}
|
||||
|
||||
.dice-setting {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.dice-input i {
|
||||
background: #efefef;
|
||||
border: 1px solid #333333;
|
||||
border-right-color: #969696;
|
||||
border-radius: 3px 0 0 3px;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
@media all and (max-width: 707px) {
|
||||
.dice-input i {
|
||||
vertical-align: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
.dice-input i:before {
|
||||
vertical-align: -1px;
|
||||
}
|
||||
|
||||
.dice-side-add input,
|
||||
.dice-input input {
|
||||
background: #f9f9f9;
|
||||
border-radius: 0 3px 3px 0;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.dice-side-add input {
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
|
||||
.dice-side-add button {
|
||||
border-radius: 0 3px 3px 0;
|
||||
padding: 4px 10px 6px;
|
||||
}
|
||||
|
||||
.dice-side-add button i {
|
||||
vertical-align: -1px;
|
||||
}
|
||||
|
||||
.dice-check + label,
|
||||
.dice-yes + label,
|
||||
.dice-no + label {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dice-check + label {
|
||||
font-size: 1rem;
|
||||
line-height: initial;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.dice-check + label span,
|
||||
.dice-yes + label span,
|
||||
.dice-no + label span {
|
||||
border-top: 1px solid #afaeaa;
|
||||
border-right: 1px solid #d5d5c8;
|
||||
border-bottom: 1px solid #d5d5c8;
|
||||
border-left: 1px solid #afaeaa;
|
||||
border-radius: 0 3px 3px 0;
|
||||
display: inline-block;
|
||||
margin: 0;
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.dice-check,
|
||||
.dice-yes,
|
||||
.dice-no {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.dice-check + label i,
|
||||
.dice-yes + label i,
|
||||
.dice-no + label i {
|
||||
vertical-align: 1px;
|
||||
}
|
||||
|
||||
.dice-yes + label i:before,
|
||||
.dice-no + label i:before {
|
||||
content: "\f096";
|
||||
}
|
||||
|
||||
.dice-check:checked + label i,
|
||||
.dice-check:checked + label span,
|
||||
.dice-yes:checked + label i,
|
||||
.dice-yes:checked + label span {
|
||||
background: linear-gradient(60deg, #66bb6a, #43a047);
|
||||
border-color: #1b9a1b;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.dice-check + label i,
|
||||
.dice-check + label span,
|
||||
.dice-no:checked + label i,
|
||||
.dice-no:checked + label span {
|
||||
background: linear-gradient(60deg, #ef5350, #e53935);
|
||||
border-color: #d31141;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.dice-check:checked + label i:before,
|
||||
.dice-yes:checked + label i:before { content: "\f00c"; }
|
||||
|
||||
.dice-check + label i:before,
|
||||
.dice-no:checked + label i:before { content: "\f00d"; }
|
||||
|
||||
.dice-check + label span.dice-check-yes { display: none; }
|
||||
.dice-check + label span.dice-check-no { display: inline-block; }
|
||||
.dice-check:checked + label span.dice-check-yes { display: inline-block; }
|
||||
.dice-check:checked + label span.dice-check-no { display: none; }
|
||||
|
||||
span.dice-example {
|
||||
border-bottom: 1px solid #ff0000;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
span.dice-example:before,
|
||||
span.dice-example:after {
|
||||
background: #ff0000;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
height: 50%;
|
||||
content: "";
|
||||
}
|
||||
|
||||
span.dice-example:before { left: 0; }
|
||||
span.dice-example:after { right: 0; }
|
||||
|
||||
@media all and (max-height: 480px) {
|
||||
.alert_text {
|
||||
overflow: auto;
|
||||
max-height: 200px;
|
||||
}
|
||||
|
||||
.phpbb_alert {
|
||||
height: 240px;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (min-height: 480px) {
|
||||
.alert_text {
|
||||
overflow: auto;
|
||||
max-height: 340px;
|
||||
}
|
||||
|
||||
.phpbb_alert {
|
||||
height: 400px;
|
||||
}
|
||||
}
|
||||
|
||||
63
ext/phpbbstudio/dice/adm/style/css/dice_locations.css
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
.dice-locations {
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #e6e9ed;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.dice-locations > p {
|
||||
margin: 3rem 0 3rem 110px;
|
||||
}
|
||||
|
||||
.navbar {
|
||||
background-color: #cadceb;
|
||||
border-radius: 7px;
|
||||
overflow: visible;
|
||||
height: 40px;
|
||||
padding: 3px 10px;
|
||||
}
|
||||
|
||||
.navbar > ul {
|
||||
display: block;
|
||||
margin: 0;
|
||||
padding: 2px 0;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.navbar > ul > li {
|
||||
font-size: 1.1em;
|
||||
line-height: 2.2em;
|
||||
float: left;
|
||||
width: auto;
|
||||
margin-right: 7px;
|
||||
padding-top: 1px;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.navbar > ul > li.right-side {
|
||||
text-align: right;
|
||||
float: right;
|
||||
margin-right: 0;
|
||||
margin-left: 7px;
|
||||
}
|
||||
|
||||
.has-dropdown {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
z-index: 10;
|
||||
top: 25px;
|
||||
left: -15px;
|
||||
}
|
||||
|
||||
.dropdown .pointer {
|
||||
border-color: #ffffff transparent;
|
||||
}
|
||||
280
ext/phpbbstudio/dice/adm/style/dice_acp.html
Normal file
@@ -0,0 +1,280 @@
|
||||
{% include 'overall_header.html' %}
|
||||
|
||||
{% INCLUDECSS '@phpbbstudio_dice/css/dice_acp.css' %}
|
||||
{% INCLUDEJS '@phpbbstudio_dice/js/dice_acp.js' %}
|
||||
|
||||
{% from '@phpbbstudio_dice/dice_input.html' import input as input %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header card-header-icon">
|
||||
<div class="card-icon dice-orange responsive-hide"><i class="fa fa-paint-brush fa-fw"></i></div>
|
||||
<p class="card-category">{{ lang('ACP_DICE_SKINS_INSTALLED') }}</p>
|
||||
<h3 class="card-title"><span title="{{ lang('ACP_DICE_SKINS_INSTALLED') }}">{{ SKINS_INSTALLED }}</span><small>/<span title="{{ lang('ACP_DICE_SKINS_AVAILABLE') }}">{{ skins|length }}</span> {{ lang('ACP_DICE_SKINS_SHORT')|lower }}</small></h3>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="card-action">
|
||||
<span class="stats">
|
||||
{% if SKINS_VALID %}
|
||||
<i class="success icon fa-check-circle fa-fw" aria-hidden="true"></i> <span class="success">{{ lang('ACP_DICE_VALID_ALL') }}</span>
|
||||
{% else %}
|
||||
<i class="error icon fa-exclamation-triangle fa-fw" aria-hidden="true"></i> <strong class="error">{{ lang('ACP_DICE_VALID_NOT_ALL') }}</strong>
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header card-header-icon">
|
||||
<div class="card-icon dice-green responsive-hide"><i class="fa fa-cube fa-fw"></i></div>
|
||||
<p class="card-category">{{ lang('ACP_DICE_SIDES_AVAILABLE') }}</p>
|
||||
<h3 class="card-title">{{ sides|length }} <small>{{ lang('ACP_DICE_SIDES_SHORT')|lower }}</small></h3>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="card-action">
|
||||
<span class="stats"><i class="icon fa-info-circle fa-fw" aria-hidden="true"></i> <span>{% if DICE_SIDES_ONLY %}{{ lang('ACP_DICE_SIDES_ONLY_STATS') }}{% elseif DICE_SIDES_PER_DICE %}{{ lang('ACP_DICE_SIDES_ONLY_UPTO', DICE_SIDES_PER_DICE) }}{% else %}{{ lang('ACP_DICE_SIDES_ONLY_UNLIMITED') }}{% endif %}</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header card-header-icon">
|
||||
<div class="card-icon dice-red responsive-hide"><i class="fa fa-cubes fa-fw"></i></div>
|
||||
<p class="card-category">{{ lang('ACP_DICE_MAX_ROLLS') }}</p>
|
||||
<h3 class="card-title">{{ DICE_MAX_ROLLS }} <small>{{ lang('ACP_DICE_ROLLS_SHORT') }}</small></h3>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<label class="card-action" for="dice_max_rolls"><span class="stats"><i class="icon fa-pencil fa-fw" aria-hidden="true"></i> <span>{{ lang('EDIT') }}</span></span></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="card">
|
||||
<div class="card-header card-header-icon">
|
||||
<div class="card-icon dice-blue responsive-hide"><i class="fa fa-database fa-fw"></i></div>
|
||||
<p class="card-category">{{ lang('ACP_DICE_ROLLS_DB') }}</p>
|
||||
<h3 class="card-title">{{ ROLLS_TOTAL }} <small>{{ lang('ACP_DICE_ROLLS_SHORT') }}</small></h3>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<a class="card-action" href="{{ U_ORPHANED }}" title="{{ lang('ACP_DICE_ORPHANED') }}" data-ajax="true">
|
||||
<span class="stats"><i class="fa fa-times fa-fw" aria-hidden="true"></i> <span>{{ lang('ACP_DICE_ORPHANED') }} (<strong class="error dice-inline">{{ ROLLS_ORPHAN }}</strong>)</span></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
<div class="column1">
|
||||
<div class="card">
|
||||
<div class="card-header card-header-icon">
|
||||
<div class="card-icon dice-purple"><i class="fa fa-user fa-fw"></i></div>
|
||||
<p class="card-category">{{ lang('ACP_DICE_TOP_USERS_DESC') }}</p>
|
||||
<h3 class="card-title">{{ lang('ACP_DICE_TOP_USERS') }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if users|length %}
|
||||
{% for users_batch in users|batch(4) %}
|
||||
<div class="row{% if loop.index > 1 %} responsive-hide{% endif %}">
|
||||
{% for user in users_batch %}
|
||||
<div class="col centered-text">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="card-avatar">
|
||||
{% if user.AVATAR %}{{ user.AVATAR }}{% else %}<i class="fa fa-user-circle-o fa-2x"></i>{% endif %}
|
||||
</div>
|
||||
{{ user.NAME }}
|
||||
</div>
|
||||
<div class="card-footer card-footer-closer">
|
||||
<div class="card-action">
|
||||
{{ user.TOTAL }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="centered-text"><strong class="error">{{ lang('ACP_DICE_ROLLS_NONE') }}</strong></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column2">
|
||||
<div class="card">
|
||||
<div class="card-header card-header-icon">
|
||||
<div class="card-icon dice-orange"><i class="fa fa-file fa-fw"></i></div>
|
||||
<p class="card-category">{{ lang('ACP_DICE_TOP_TOPICS_DESC') }}</p>
|
||||
<h3 class="card-title">{{ lang('ACP_DICE_TOP_TOPICS') }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if topics|length %}
|
||||
{% for topics_batch in topics|batch(4) %}
|
||||
<div class="row{% if loop.index > 1 %} responsive-hide{% endif %}">
|
||||
{% for topic in topics_batch %}
|
||||
<div class="col centered-text">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<a class="card-primary" href="{{ topic.U_TOPIC }}" title="{{ lang('VIEW_TOPIC') }}">{{ topic.TOPIC_TITLE }}</a>
|
||||
<a class="card-secondary" href="{{ topic.U_FORUM }}" title="{{ lang('GOTO_PAGE') }}">{{ topic.FORUM_NAME }}</a>
|
||||
</div>
|
||||
<div class="card-footer card-footer-closer">
|
||||
<div class="card-action">
|
||||
{{ topic.TOTAL }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<div class="centered-text"><strong class="error">{{ lang('ACP_DICE_ROLLS_NONE') }}</strong></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="clearfix">
|
||||
<div class="column1">
|
||||
<div class="card">
|
||||
<div class="card-header dice-red">
|
||||
<h4 class="card-title">{{ lang('ACP_DICE_SKINS') }}</h4>
|
||||
<p class="card-category">{{ lang('ACP_DICE_SKINS_EXPLAIN') }}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{% if SKINS_DIR_ERROR %}
|
||||
<div class="errorbox">
|
||||
<h3>{{ lang('ERROR') }}</h3>
|
||||
<p>{{ lang('DIRECTORY_DOES_NOT_EXIST', SKINS_DIR) }}</p>
|
||||
</div>
|
||||
{% else %}
|
||||
<table class="responsive">
|
||||
{% for skin in skins %}
|
||||
<tr>
|
||||
<td class="name">{{ skin.NAME }}</td>
|
||||
<td class="actions {% if skin.S_VALID %}yes{% else %}never{% endif %}">{% if skin.S_VALID %}{{ lang('ACP_DICE_VALID') }}{% else %}{{ lang('ACP_DICE_INVALID') }}{% endif %}</td>
|
||||
<td class="actions {% if skin.S_INSTALLED %}yes{% else %}never{% endif %}">{% if skin.S_INSTALLED %}{{ lang('ACP_DICE_INSTALLED') }}{% else %}{{ lang('ACP_DICE_INSTALLED_NOT') }}{% endif %}</td>
|
||||
<td class="actions col1">
|
||||
{% if skin.S_INSTALLED %}
|
||||
<a href="{{ skin.U_ACTION }}" title="{{ lang('ACP_DICE_SKIN_UNINSTALL') }}" data-ajax="dice_refresh"><i class="error fa fa-times-circle fa-2x"></i></a>
|
||||
{% else %}
|
||||
<a href="{{ skin.U_ACTION }}" title="{{ lang('ACP_DICE_SKIN_INSTALL') }}" data-ajax="dice_refresh"><i class="success fa fa-cog fa-2x"></i></a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td class="centered-text error"><strong>{{ lang('ACP_DICE_SKINS_NONE') }}</strong></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<label class="card-action" for="dice_skins_dir"><span class="stats">{{ lang('ACP_DICE_INSTALLED_IN') ~ lang('COLON') }}</span> <strong>{{ SKINS_DIR }}</strong></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="column2">
|
||||
<div class="card">
|
||||
<div class="card-header dice-blue">
|
||||
<h4 class="card-title">{{ lang('ACP_DICE_SIDES') }}</h4>
|
||||
<p class="card-category">{{ lang('ACP_DICE_SIDES_EXPLAIN') }}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<table class="responsive">
|
||||
{% for row in sides|batch(2) %}
|
||||
<tr>
|
||||
{% for side in row %}
|
||||
<td class="name col2">{{ side.NUMBER }}</td>
|
||||
<td class="actions col1"><a href="{{ side.U_DELETE }}" title="{{ lang('ACP_DICE_SIDE_DELETE') }}" data-ajax="dice_refresh"><i class="error fa fa-times-circle fa-2x"></i></a></td>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td class="centered-text error"><strong>{{ lang('ACP_DICE_SIDES_NONE') }}</strong></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<div class="card-action">
|
||||
{% spaceless %}
|
||||
<form class="dice-setting dice-side-add" name="side_add" method="post" action="{{ U_SIDE_ADD }}" data-ajax="dice_refresh">
|
||||
<label for="side_add">{{ lang('ACP_DICE_SIDE_ADD') }}{{ lang('COLON') }}</label>
|
||||
<input id="side_add" name="value" type="number" min="2" step="1">
|
||||
<button class="dice-button dice-button-green">
|
||||
<i class="icon fa-plus fa-fw"></i>
|
||||
</button>
|
||||
</form>
|
||||
{% endspaceless %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header dice-green">
|
||||
<h4 class="card-title">{{ lang('SETTINGS') }}</h4>
|
||||
<p class="card-category">{{ lang('ACP_DICE_SETTINGS_EXPLAIN') }}<br><a href="{{ U_EXAMPLE }}" data-ajax="true">{{ lang('ACP_DICE_SETTINGS_EXAMPLE') }}</a></p>
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<form id="dice_settings" name="dice_settings" method="post" action="{{ U_ACTION }}">
|
||||
{% if S_ERRORS %}
|
||||
<div class="errorbox"><h3>{{ lang('ERROR') }}</h3><span>{{ ERROR_MSG }}</span></div>
|
||||
{% endif %}
|
||||
<fieldset>
|
||||
<dl class="dice-setting">
|
||||
<dt><strong>{{ lang('ACP_DICE_LOCATIONS') ~ lang('COLON') }}</strong><br><span class="explain">{{ lang('ACP_DICE_LOCATIONS_DESC') }}</span></dt>
|
||||
<dd><a class="dice-button dice-button-green dice-button-locations" href="{{ U_LOCATIONS }}"><i class="fa fa-pencil fa-fw" aria-hidden="true"></i> <span>{{ lang('EDIT') }}</span></a></dd>
|
||||
</dl>
|
||||
<hr>
|
||||
{{ input('dice_skins_dir', false, SKINS_DIR, 'folder-open-o', 'text', 0, 255, 'medium') }}
|
||||
{{ input('dice_skins_img_width', false, SKINS_IMG_WIDTH, 'arrows-h', 'number', 16, 80) }}
|
||||
{{ input('dice_skins_img_height', false, SKINS_IMG_HEIGHT, 'arrows-v', 'number', 16, 80) }}
|
||||
<hr>
|
||||
<dl class="dice-setting">
|
||||
<dt><label for="dice_sides_only_y">{{ lang('ACP_DICE_SIDES_ONLY') ~ lang('COLON') }}</label><br><span class="explain">{{ lang('ACP_DICE_SIDES_ONLY_DESC') }}</span></dt>
|
||||
<dd class="dice-input">
|
||||
<input class="dice-yes" id="dice_sides_only_y" name="dice_sides_only" value="1" type="radio"{% if DICE_SIDES_ONLY %} checked{% endif %}><label for="dice_sides_only_y"><i class="fa fa-fw" aria-hidden="true"></i><span>{{ lang('YES') }}</span></label>
|
||||
<input class="dice-no" id="dice_sides_only_n" name="dice_sides_only" value="0" type="radio"{% if not DICE_SIDES_ONLY %} checked{% endif %}><label for="dice_sides_only_n"><i class="fa fa-fw" aria-hidden="true"></i><span>{{ lang('NO') }}</span></label>
|
||||
</dd>
|
||||
</dl>
|
||||
<hr>
|
||||
{{ input('dice_max_rolls', true, DICE_MAX_ROLLS, 'file-text-o', 'number', 0) }}
|
||||
{{ input('dice_per_notation', true, DICE_PER_NOTATION, 'cubes', 'number', 0) }}
|
||||
{{ input('dice_qty_per_dice', true, DICE_QTY_PER_DICE, 'cube', 'number', 0) }}
|
||||
{{ input('dice_qty_dice_per_notation', true, DICE_QTY_DICE_PER_NOTATION, 'cubes', 'number', 0) }}
|
||||
{{ input('dice_sides_per_dice', true, DICE_SIDES_PER_DICE, 'cube', 'number', 0) }}
|
||||
{{ input('dice_pc_dice_per_notation', true, DICE_PC_DICE_PER_NOTATION, 'percent', 'number', 0) }}
|
||||
{{ input('dice_fudge_dice_per_notation', true, DICE_FUDGE_DICE_PER_NOTATION, 'sort', 'number', 0) }}
|
||||
{{ input('dice_exploding_dice_per_notation', true, DICE_EXPLODING_DICE_PER_NOTATION, 'bomb', 'number', 0) }}
|
||||
{{ input('dice_penetration_dice_per_notation', true, DICE_PENETRATION_DICE_PER_NOTATION, 'long-arrow-right', 'number', 0) }}
|
||||
{{ input('dice_compound_dice_per_notation', true, DICE_COMPOUND_DICE_PER_NOTATION, 'exchange', 'number', 0) }}
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="submit-buttons">
|
||||
{{ S_FORM_TOKEN }}
|
||||
<button class="dice-button dice-button-green" type="submit" name="submit"><i class="icon fa-paper-plane fa-fw" aria-hidden="true"></i> <span>{{ lang('SUBMIT') }}</span></button>
|
||||
<button class="dice-button dice-button-red" type="reset" name="reset"><i class="icon fa-refresh fa-fw" aria-hidden="true"></i> <span>{{ lang('RESET') }}</span></button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include 'overall_footer.html' %}
|
||||
51
ext/phpbbstudio/dice/adm/style/dice_example.html
Normal file
@@ -0,0 +1,51 @@
|
||||
{% if not S_IS_AJAX %}
|
||||
{% include 'overall_header.html' %}
|
||||
|
||||
{% INCLUDECSS '@phpbbstudio_dice/css/dice_acp.css' %}
|
||||
{% endif %}
|
||||
|
||||
<fieldset class="dice-setting">
|
||||
<p>
|
||||
{{ lang('ACP_DICE_SETTINGS_EXPLAIN') }}<br>
|
||||
{{ lang('ACP_DICE_EXAMPLE_1') }}.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>{{ lang('ACP_DICE_ROLL_NR', 1) ~ lang('COLON') }}</strong> <span class="dice-example"><strong class="error">2</strong>d6</span> + <span class="dice-example"><strong class="error">5</strong>d100</span> + <span class="dice-example"><strong class="error">1</strong>d6!!</span><br>
|
||||
<em>{{ lang('ACP_DICE_PER_NOTATION') ~ lang('COLON') }}</em> <span class="dice-example">{{ lang('ACP_DICE_DICE', 3) }}</span><br>
|
||||
<em>{{ lang('ACP_DICE_QTY_PER_DICE') ~ lang('COLON') }}</em> <strong class="error">8</strong><br>
|
||||
<em>{{ lang('ACP_DICE_QTY_DICE_PER_NOTATION') ~ lang('COLON') }}</em> <strong class="error">2</strong> & <strong class="error">5</strong> & <strong class="error">1</strong>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>{{ lang('ACP_DICE_ROLL_NR', 2) ~ lang('COLON') }}</strong> 3d<strong class="error">20</strong> + <span class="dice-example">1dF</span> + <span class="dice-example">2dF.1</span> + <mark>1d100</mark> + <mark>4d%</mark><br>
|
||||
<em>{{ lang('ACP_DICE_SIDES_PER_DICE') ~ lang('COLON') }}</em> <strong class="error">20</strong><br>
|
||||
<em>{{ lang('ACP_DICE_FUDGE_DICE_PER_NOTATION') ~ lang('COLON') }}</em> <span class="dice-example">{{ lang('ACP_DICE_DICE', 2) }}</span><br>
|
||||
<em>{{ lang('ACP_DICE_PC_DICE_PER_NOTATION') ~ lang('COLON') }}</em> <mark>{{ lang('ACP_DICE_DICE', 2) }}</mark>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>{{ lang('ACP_DICE_ROLL_NR', 3) ~ lang('COLON')}}</strong> <span class="dice-example">3d6!>4</span> + <span class="dice-example">2d6<strong class="error">!!</strong></span> + <span class="dice-example">2d8<strong class="error">!!</strong><mark>p</mark></span> + <span class="dice-example">3d10!<mark>p</mark>>8</span><br>
|
||||
<em>{{ lang('ACP_DICE_EXPLODING_DICE_PER_NOTATION') ~ lang('COLON') }}</em> <span class="dice-example">{{ lang('ACP_DICE_DICE', 4) }}</span><br>
|
||||
<em>{{ lang('ACP_DICE_PENETRATION_DICE_PER_NOTATION') ~ lang('COLON') }}</em> <mark>{{ lang('ACP_DICE_DICE', 2) }}</mark><br>
|
||||
<em>{{ lang('ACP_DICE_COMPOUND_DICE_PER_NOTATION') ~ lang('COLON') }}</em> <strong class="error">{{ lang('ACP_DICE_DICE', 2) }}</strong>
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<h5>{{ lang('ACP_DICE_SUMMARY') ~ lang('COLON') }}</h5>
|
||||
<ul class="fa-ul">
|
||||
<li><i class="fa fa-angle-right fa-li"></i>{{ lang('ACP_DICE_EXAMPLE_2') ~ lang('COLON') }} <span class="dice-example">1d6</span> + <span class="dice-example">1d6</span></li>
|
||||
<li><i class="fa fa-angle-right fa-li"></i>{{ lang('ACP_DICE_EXAMPLE_3') }} <strong class="error">3</strong>d6 + <strong class="error">2</strong>d6</li>
|
||||
<li><i class="fa fa-angle-right fa-li"></i>{{ lang('ACP_DICE_EXAMPLE_4') }} <strong class="error">2</strong>d6</li>
|
||||
<li><i class="fa fa-angle-right fa-li"></i>{{ lang('ACP_DICE_EXAMPLE_5') }} 2d<strong class="error">12</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p>{{ lang('ACP_DICE_ENJOY') }}!</p>
|
||||
</fieldset>
|
||||
|
||||
{% if not S_IS_AJAX %}
|
||||
{{ lang('RETURN_PAGE', '<a href="' ~ U_BACK ~ '">', '</a>') }}
|
||||
|
||||
{% include 'overall_footer.html' %}
|
||||
{% endif %}
|
||||
12
ext/phpbbstudio/dice/adm/style/dice_input.html
Normal file
@@ -0,0 +1,12 @@
|
||||
{% macro input(title, unlimited, value, icon, type, min, max, class) %}
|
||||
{% set attr = type == 'text' ? ' minlength="' ~ min ~ '"' ~ (max ? ' maxlength="' ~ max ~ '"' : '') : ' min="' ~ min ~ '"' ~ (max ? ' max="' ~ max ~ '"' : '') ~ ' step="1"' %}
|
||||
<dl class="dice-setting">
|
||||
<dt><label for="{{ title }}">{{ lang('ACP_' ~ title|upper) ~ lang('COLON') }}</label><br><span class="explain">{{ lang('ACP_' ~ title|upper ~ '_DESC') }}</span>{% if unlimited %}<br><span class="explain small">{{ lang('ACP_DICE_ZERO_UNLIMITED') }}</span>{% endif %}</dt>
|
||||
{% spaceless %}
|
||||
<dd class="dice-input">
|
||||
<i class="fa fa-{{ icon }} fa-fw"></i>
|
||||
<input{% if class %} class="{{ class }}"{% endif %} id="{{ title }}" name="{{ title }}" type="{{ type }}" value="{{ value }}"{{ attr }}>
|
||||
</dd>
|
||||
{% endspaceless %}
|
||||
</dl>
|
||||
{% endmacro %}
|
||||
72
ext/phpbbstudio/dice/adm/style/dice_locations.html
Normal file
@@ -0,0 +1,72 @@
|
||||
{% include 'overall_header.html' %}
|
||||
|
||||
{% INCLUDECSS '@phpbbstudio_dice/css/dice_acp.css' %}
|
||||
{% INCLUDECSS '@phpbbstudio_dice/css/dice_locations.css' %}
|
||||
|
||||
{% macro location(name, status) %}
|
||||
<span class="dice-input"><input class="dice-check" id="{{ name }}" name="{{ name }}" value="1" type="checkbox"{% if status %} checked{% endif %}><label for="{{ name }}"><i class="fa fa-fw" aria-hidden="true"></i><span class="dice-check-yes">{{ lang('YES') }}</span><span class="dice-check-no">{{ lang('NO') }}</span></label></span>
|
||||
{% endmacro %}
|
||||
|
||||
{% from _self import location as location %}
|
||||
|
||||
<fieldset class="quick"><a href="{{ U_BACK }}"><i class="icon fa-reply fa-fw" aria-hidden="true"></i> <span>{{ lang('BACK_TO_PREV') }}</span></a></fieldset>
|
||||
|
||||
<form id="dice_locations" name="dice_locations" method="post" action="{{ U_LOCATIONS }}">
|
||||
<div class="dice-locations dice-setting">
|
||||
<div class="navbar">
|
||||
<ul>
|
||||
<li class="has-dropdown">
|
||||
<i class="icon fa-bars fa-fw" aria-hidden="true"></i> <span>{{ lang('QUICK_LINKS') }}</span>
|
||||
<div class="dropdown">
|
||||
<div class="pointer"></div>
|
||||
<div class="dropdown-contents">
|
||||
<div>{{ location('navbar_header_quick_links_before', navbar_header_quick_links_before) }}</div>
|
||||
<div>{{ lang('QUICK_LINKS') }}</div>
|
||||
<div>{{ location('navbar_header_quick_links_after', navbar_header_quick_links_after) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li>{{ location('overall_header_navigation_prepend', overall_header_navigation_prepend) }}</li>
|
||||
<li><i class="icon fa-info-circle fa-fw" aria-hidden="true"></i> <span>{{ lang('FAQ') }}</span></li>
|
||||
<li>{{ location('overall_header_navigation_append', overall_header_navigation_append) }}</li>
|
||||
<li><i class="icon fa-cogs fa-fw" aria-hidden="true"></i> <span>{{ lang('ACP_SHORT') }}</span></li>
|
||||
|
||||
<li class="right-side"><i class="icon fa-user-circle-o fa-fw" aria-hidden="true"></i> <strong>{{ USERNAME }}</strong></li>
|
||||
<li class="right-side"><i class="icon fa-inbox fa-fw" aria-hidden="true"></i> <span>{{ lang('PRIVATE_MESSAGES') }}</span></li>
|
||||
<li class="right-side"><i class="icon fa-bell fa-fw" aria-hidden="true"></i> <span>{{ lang('NOTIFICATIONS') }}</span></li>
|
||||
<li class="right-side">{{ location('navbar_header_user_profile_append', navbar_header_user_profile_append) }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>{{ lang('ACP_DICE_LOCATIONS_EXPLAIN') }}</p>
|
||||
|
||||
<div class="navbar clearfix">
|
||||
<ul>
|
||||
<li><i class="icon fa-home fa-fw" aria-hidden="true"></i> <span>{{ lang('FORUM_INDEX') }}</span></li>
|
||||
<li>{{ location('overall_footer_breadcrumb_append', overall_footer_breadcrumb_append) }}</li>
|
||||
<li class="right-side">{{ location('overall_footer_timezone_before', overall_footer_timezone_before) }}</li>
|
||||
<li class="right-side"><span>{{ lang('ALL_TIMES', "now"|date('TO'), "now"|date('e')) }}</span></li>
|
||||
<li class="right-side">{{ location('overall_footer_timezone_after', overall_footer_timezone_after) }}</li>
|
||||
<li class="right-side"><i class="icon fa-trash fa-fw" aria-hidden="true"></i> <span>{{ lang('DELETE_COOKIES') }}</span></li>
|
||||
<li class="right-side"><i class="icon fa-users fa-fw" aria-hidden="true"></i> <span>{{ lang('MEMBERLIST') }}</span></li>
|
||||
<li class="right-side">{{ location('overall_footer_teamlink_before', overall_footer_teamlink_before) }}</li>
|
||||
<li class="right-side"><i class="icon fa-shield fa-fw" aria-hidden="true"></i> <span>{{ lang('THE_TEAM') }}</span></li>
|
||||
<li class="right-side">{{ location('overall_footer_teamlink_after', overall_footer_teamlink_after) }}</li>
|
||||
<li class="right-side"><i class="icon fa-envelope fa-fw" aria-hidden="true"></i> <span>{{ lang('CONTACT_US') }}</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<fieldset>
|
||||
<legend>{{ lang('ACP_SUBMIT_CHANGES') }}</legend>
|
||||
<p class="submit-buttons">
|
||||
<button class="dice-button dice-button-green" type="submit" name="submit_locations"><i class="icon fa-paper-plane fa-fw" aria-hidden="true"></i> <span>{{ lang('SUBMIT') }}</span></button>
|
||||
<button class="dice-button dice-button-red" type="reset" name="reset"><i class="icon fa-refresh fa-fw" aria-hidden="true"></i> <span>{{ lang('RESET') }}</span></button>
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="quick">
|
||||
<a href="{{ U_BACK }}"><i class="icon fa-reply fa-fw" aria-hidden="true"></i> <span>{{ lang('BACK_TO_PREV') }}</span></a>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
{% include 'overall_footer.html' %}
|
||||
@@ -0,0 +1,26 @@
|
||||
<fieldset>
|
||||
<legend>{{ lang('ACP_DICE_SETTINGS') }}</legend>
|
||||
|
||||
<dl>
|
||||
<dt><label for="dice_f_enable_on">{{ lang('ACP_DICE_ENABLE') ~ lang('COLON') }}</label><br><span>{{ lang('ACP_DICE_ENABLE_DESC') }}</span></dt>
|
||||
<dd>
|
||||
<label><input type="radio" class="radio" name="dice_enabled" value="1" id="dice_f_enable_on"{% if S_DICE_ENABLED %} checked="checked"{% endif %} /> {{ lang('ENABLED') }}</label>
|
||||
<label><input type="radio" class="radio" name="dice_enabled" value="0" id="dice_f_enable_off"{% if not S_DICE_ENABLED %} checked="checked"{% endif %} /> {{ lang('DISABLED') }}</label>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt><label for="dice_f_skin">{{ lang('ACP_DICE_F_SKIN') ~ lang('COLON') }}</label><br><span>{{ lang('ACP_DICE_F_SKIN_DESC') }}</span></dt>
|
||||
<dd>
|
||||
<select name="dice_f_skin" id="dice_f_skin">{{ DICE_F_SKIN }}</select>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt><label for="dice_skin_override_on">{{ lang('ACP_DICE_SKIN_OVERRIDE') ~ lang('COLON') }}</label><br><span>{{ lang('ACP_DICE_SKIN_OVERRIDE_DESC') }}</span></dt>
|
||||
<dd>
|
||||
<label><input type="radio" class="radio" name="dice_skin_override" value="1" id="dice_skin_override_on"{% if S_DICE_SKIN_OVERRIDE %} checked="checked"{% endif %} /> {{ lang('YES') }}</label>
|
||||
<label><input type="radio" class="radio" name="dice_skin_override" value="0" id="dice_skin_override_off"{% if not S_DICE_SKIN_OVERRIDE %} checked="checked"{% endif %} /> {{ lang('NO') }}</label>
|
||||
</dd>
|
||||
</dl>
|
||||
</fieldset>
|
||||
31
ext/phpbbstudio/dice/adm/style/js/dice_acp.js
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
'use strict';
|
||||
|
||||
let $dark = $('#darkenwrapper');
|
||||
let $alert = $('#phpbb_alert');
|
||||
let keymap = {
|
||||
ENTER: 13,
|
||||
ESC: 27
|
||||
};
|
||||
|
||||
phpbb.addAjaxCallback('dice_refresh', function() {
|
||||
// Do not allow closing alert
|
||||
$dark.off('click');
|
||||
$alert.find('.alert_close').hide();
|
||||
|
||||
$(document).on('keydown.phpbb.alert', function(e) {
|
||||
if (e.keyCode === keymap.ENTER || e.keyCode === keymap.ESC) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
27
ext/phpbbstudio/dice/composer.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "phpbbstudio/dice",
|
||||
"type": "phpbb-extension",
|
||||
"description": "Let's roll the dice!",
|
||||
"homepage": "https://www.phpbbstudio.com",
|
||||
"version": "2.1.2",
|
||||
"time": "2019-07-10",
|
||||
"license": "GPL-2.0-only",
|
||||
"authors": [
|
||||
{
|
||||
"name": "phpBB Studio",
|
||||
"email": "info@phpbbstudio.com",
|
||||
"homepage": "https://www.phpbbstudio.com",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.5",
|
||||
"composer/installers": "~1.0"
|
||||
},
|
||||
"extra": {
|
||||
"display-name": "phpBB Studio - Dice",
|
||||
"soft-require": {
|
||||
"phpbb/phpbb": ">=3.2.5,<3.3.0@dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
30
ext/phpbbstudio/dice/config/routing.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
phpbbstudio_dice:
|
||||
path: /dice
|
||||
defaults:
|
||||
_controller: phpbbstudio.dice.controller.main:page
|
||||
|
||||
phpbbstudio_dice_add:
|
||||
path: /dice/add/f{forum_id}/t{topic_id}/p{post_id}/a{poster_id}/{hash}
|
||||
defaults:
|
||||
_controller: phpbbstudio.dice.controller.main:add
|
||||
requirements:
|
||||
forum_id: \d+
|
||||
topic_id: \d+
|
||||
post_id: \d+
|
||||
poster_id: \d+
|
||||
|
||||
phpbbstudio_dice_edit:
|
||||
path: /dice/edit/{roll_id}
|
||||
defaults:
|
||||
_controller: phpbbstudio.dice.controller.main:edit
|
||||
roll_id: 0
|
||||
requirements:
|
||||
roll_id: \d+
|
||||
|
||||
phpbbstudio_dice_del:
|
||||
path: /dice/del/{roll_id}
|
||||
defaults:
|
||||
_controller: phpbbstudio.dice.controller.main:delete
|
||||
roll_id: 0
|
||||
requirements:
|
||||
roll_id: \d+
|
||||
34
ext/phpbbstudio/dice/config/services.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
imports:
|
||||
- { resource: tables.yml }
|
||||
- { resource: services_controllers.yml }
|
||||
- { resource: services_functions.yml }
|
||||
- { resource: services_listeners.yml }
|
||||
|
||||
services:
|
||||
phpbbstudio.dice.entity.roll:
|
||||
class: phpbbstudio\dice\entity\roll
|
||||
shared: false # Must be false to work
|
||||
arguments:
|
||||
- '@config'
|
||||
- '@dbal.conn'
|
||||
- '@phpbbstudio.dice.functions.common'
|
||||
- '@language'
|
||||
- '@phpbbstudio.dice.functions.regex'
|
||||
- '@phpbbstudio.dice.functions.utils'
|
||||
- '%phpbbstudio.dice.tables.rolls%'
|
||||
|
||||
phpbbstudio.dice.operator.roll:
|
||||
class: phpbbstudio\dice\operator\roll
|
||||
arguments:
|
||||
- '@config'
|
||||
- '@config_text'
|
||||
- '@service_container'
|
||||
- '@dbal.conn'
|
||||
- '@filesystem'
|
||||
- '@phpbbstudio.dice.functions.common'
|
||||
- '@controller.helper'
|
||||
- '@template'
|
||||
- '@user'
|
||||
- '%tables.posts%'
|
||||
- '%phpbbstudio.dice.tables.rolls%'
|
||||
- '%core.root_path%'
|
||||
32
ext/phpbbstudio/dice/config/services_controllers.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
services:
|
||||
phpbbstudio.dice.controller.admin:
|
||||
class: phpbbstudio\dice\controller\admin_controller
|
||||
arguments:
|
||||
- '@config'
|
||||
- '@dbal.conn'
|
||||
- '@phpbbstudio.dice.functions.common'
|
||||
- '@language'
|
||||
- '@log'
|
||||
- '@request'
|
||||
- '@template'
|
||||
- '@user'
|
||||
- '@user_loader'
|
||||
- '%tables.forums%'
|
||||
- '%phpbbstudio.dice.tables.rolls%'
|
||||
- '%tables.topics%'
|
||||
- '%core.root_path%'
|
||||
- '%core.php_ext%'
|
||||
|
||||
phpbbstudio.dice.controller.main:
|
||||
class: phpbbstudio\dice\controller\main_controller
|
||||
arguments:
|
||||
- '@auth'
|
||||
- '@config'
|
||||
- '@phpbbstudio.dice.functions.common'
|
||||
- '@controller.helper'
|
||||
- '@language'
|
||||
- '@phpbbstudio.dice.operator.roll'
|
||||
- '@phpbbstudio.dice.functions.regex'
|
||||
- '@request'
|
||||
- '@template'
|
||||
- '@user'
|
||||
24
ext/phpbbstudio/dice/config/services_functions.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
services:
|
||||
phpbbstudio.dice.functions.common:
|
||||
class: phpbbstudio\dice\core\functions_common
|
||||
arguments:
|
||||
- '@auth'
|
||||
- '@config'
|
||||
- '@config_text'
|
||||
- '@dbal.conn'
|
||||
- '@filesystem'
|
||||
- '@phpbbstudio.dice.functions.finder'
|
||||
- '@language'
|
||||
- '@path_helper'
|
||||
- '@user'
|
||||
- '%tables.forums%'
|
||||
- '%core.root_path%'
|
||||
|
||||
phpbbstudio.dice.functions.finder:
|
||||
class: phpbbstudio\dice\core\functions_finder
|
||||
|
||||
phpbbstudio.dice.functions.regex:
|
||||
class: phpbbstudio\dice\core\functions_regex
|
||||
|
||||
phpbbstudio.dice.functions.utils:
|
||||
class: phpbbstudio\dice\core\functions_utils
|
||||
50
ext/phpbbstudio/dice/config/services_listeners.yml
Normal file
@@ -0,0 +1,50 @@
|
||||
services:
|
||||
phpbbstudio.dice.listener.acp:
|
||||
class: phpbbstudio\dice\event\acp_listener
|
||||
arguments:
|
||||
- '@dbal.conn'
|
||||
- '@phpbbstudio.dice.functions.common'
|
||||
- '@request'
|
||||
- '%phpbbstudio.dice.tables.rolls%'
|
||||
tags:
|
||||
- { name: event.listener }
|
||||
|
||||
phpbbstudio.dice.listener.bbcode:
|
||||
class: phpbbstudio\dice\event\bbcode_listener
|
||||
arguments:
|
||||
- '@phpbbstudio.dice.functions.common'
|
||||
- '@request'
|
||||
tags:
|
||||
- { name: event.listener }
|
||||
|
||||
phpbbstudio.dice.listener.display:
|
||||
class: phpbbstudio\dice\event\display_listener
|
||||
arguments:
|
||||
- '@auth'
|
||||
- '@config'
|
||||
- '@phpbbstudio.dice.functions.common'
|
||||
- '@phpbbstudio.dice.operator.roll'
|
||||
- '@template'
|
||||
tags:
|
||||
- { name: event.listener }
|
||||
|
||||
phpbbstudio.dice.listener.posting:
|
||||
class: phpbbstudio\dice\event\posting_listener
|
||||
arguments:
|
||||
- '@phpbbstudio.dice.functions.common'
|
||||
- '@controller.helper'
|
||||
- '@phpbbstudio.dice.operator.roll'
|
||||
- '@request'
|
||||
- '@template'
|
||||
tags:
|
||||
- { name: event.listener }
|
||||
|
||||
phpbbstudio.dice.listener.setup:
|
||||
class: phpbbstudio\dice\event\setup_listener
|
||||
arguments:
|
||||
- '@auth'
|
||||
- '@phpbbstudio.dice.functions.common'
|
||||
- '@language'
|
||||
- '@template'
|
||||
tags:
|
||||
- { name: event.listener }
|
||||
2
ext/phpbbstudio/dice/config/tables.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
parameters:
|
||||
phpbbstudio.dice.tables.rolls: '%core.table_prefix%dice_rolls'
|
||||
613
ext/phpbbstudio/dice/controller/admin_controller.php
Normal file
@@ -0,0 +1,613 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\controller;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Admin controller.
|
||||
*/
|
||||
class admin_controller implements admin_interface
|
||||
{
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbbstudio\dice\core\functions_common */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbb\language\language */
|
||||
protected $lang;
|
||||
|
||||
/** @var \phpbb\log\log */
|
||||
protected $log;
|
||||
|
||||
/** @var \phpbb\request\request */
|
||||
protected $request;
|
||||
|
||||
/** @var \phpbb\template\template */
|
||||
protected $template;
|
||||
|
||||
/** @var \phpbb\user */
|
||||
protected $user;
|
||||
|
||||
/** @var \phpbb\user_loader */
|
||||
protected $user_loader;
|
||||
|
||||
/** @var string Forums table */
|
||||
protected $forums_table;
|
||||
|
||||
/** @var string Dice rolls table*/
|
||||
protected $rolls_table;
|
||||
|
||||
/** @var string Topics table */
|
||||
protected $topics_table;
|
||||
|
||||
/** @var string phpBB root path */
|
||||
protected $root_path;
|
||||
|
||||
/** @var string php File extension */
|
||||
protected $php_ext;
|
||||
|
||||
/** @var string Custom form action */
|
||||
protected $u_action;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\config\config $config Configuration object
|
||||
* @param \phpbb\db\driver\driver_interface $db Database object
|
||||
* @param \phpbbstudio\dice\core\functions_common $functions Common dice functions
|
||||
* @param \phpbb\language\language $lang Language object
|
||||
* @param \phpbb\log\log $log Log object
|
||||
* @param \phpbb\request\request $request Request object
|
||||
* @param \phpbb\template\template $template Template object
|
||||
* @param \phpbb\user $user User object
|
||||
* @param \phpbb\user_loader $user_loader User loader object
|
||||
* @param string $forums_table Forums table
|
||||
* @param string $rolls_table Dice rolls table
|
||||
* @param string $topics_table Topics table
|
||||
* @param string $root_path phpBB root path
|
||||
* @param string $php_ext phpEx
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\config\config $config,
|
||||
\phpbb\db\driver\driver_interface $db,
|
||||
\phpbbstudio\dice\core\functions_common $functions,
|
||||
\phpbb\language\language $lang,
|
||||
\phpbb\log\log $log,
|
||||
\phpbb\request\request $request,
|
||||
\phpbb\template\template $template,
|
||||
\phpbb\user $user,
|
||||
\phpbb\user_loader $user_loader,
|
||||
$forums_table,
|
||||
$rolls_table,
|
||||
$topics_table,
|
||||
$root_path,
|
||||
$php_ext
|
||||
)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->db = $db;
|
||||
$this->functions = $functions;
|
||||
$this->lang = $lang;
|
||||
$this->log = $log;
|
||||
$this->request = $request;
|
||||
$this->template = $template;
|
||||
$this->user = $user;
|
||||
$this->user_loader = $user_loader;
|
||||
$this->forums_table = $forums_table;
|
||||
$this->rolls_table = $rolls_table;
|
||||
$this->topics_table = $topics_table;
|
||||
|
||||
$this->root_path = $root_path;
|
||||
$this->php_ext = $php_ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function handle($action)
|
||||
{
|
||||
// Requests
|
||||
$submit = $this->request->is_set_post('submit');
|
||||
$value = $this->request->variable('value', '');
|
||||
|
||||
// Add a form key to the settings
|
||||
$form_key = 'dice_settings';
|
||||
add_form_key($form_key);
|
||||
|
||||
// Set up config settings
|
||||
$options = [
|
||||
'dice_sides_only',
|
||||
'dice_max_rolls',
|
||||
'dice_per_notation',
|
||||
'dice_qty_per_dice',
|
||||
'dice_qty_dice_per_notation',
|
||||
'dice_sides_per_dice',
|
||||
'dice_pc_dice_per_notation',
|
||||
'dice_fudge_dice_per_notation',
|
||||
'dice_penetration_dice_per_notation',
|
||||
'dice_compound_dice_per_notation',
|
||||
'dice_exploding_dice_per_notation',
|
||||
];
|
||||
|
||||
// Assign config settings
|
||||
$template_vars = [];
|
||||
foreach ($options as $option)
|
||||
{
|
||||
$template_vars[utf8_strtoupper($option)] = $this->config[$option];
|
||||
}
|
||||
|
||||
// Get the roll count from the database
|
||||
$rolls_total = $this->db->get_estimated_row_count($this->rolls_table);
|
||||
|
||||
// Get the orphaned roll count from the database
|
||||
$sql = 'SELECT COUNT(roll_id) as orphans FROM ' . $this->rolls_table . ' WHERE roll_id = 0 OR post_id = 0 OR topic_id = 0 OR forum_id = 0 OR user_id = 0';
|
||||
$result = $this->db->sql_query($sql);
|
||||
$rolls_orphan = $this->db->sql_fetchfield('orphans');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
// Select the top topics with the most rolls
|
||||
$sql_array = [
|
||||
'SELECT' => 'COUNT(r.roll_id) as total,
|
||||
t.topic_id, t.topic_title,
|
||||
f.forum_id, f.forum_name',
|
||||
'FROM' => [$this->rolls_table => 'r'],
|
||||
'LEFT_JOIN' => [
|
||||
[
|
||||
'FROM' => [$this->topics_table => 't'],
|
||||
'ON' => 't.topic_id = r.topic_id',
|
||||
],
|
||||
[
|
||||
'FROM' => [$this->forums_table => 'f'],
|
||||
'ON' => 'f.forum_id = r.forum_id',
|
||||
],
|
||||
],
|
||||
'GROUP_BY' => 'r.topic_id, t.topic_title, f.forum_id, f.forum_name',
|
||||
'ORDER_BY' => 'total DESC',
|
||||
];
|
||||
|
||||
$sql = $this->db->sql_build_query('SELECT', $sql_array);
|
||||
$result = $this->db->sql_query_limit($sql, 8);
|
||||
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$this->template->assign_block_vars('topics', [
|
||||
'FORUM_NAME' => $row['forum_name'],
|
||||
'TOPIC_TITLE' => $row['topic_title'],
|
||||
'TOTAL' => (int) $row['total'],
|
||||
|
||||
'U_FORUM' => append_sid($this->root_path . 'viewforum.' . $this->php_ext, ['f' => (int) $row['forum_id']]),
|
||||
'U_TOPIC' => append_sid($this->root_path . 'viewtopic.' . $this->php_ext, ['f' => (int) $row['forum_id'], 't' => (int) $row['topic_id']]),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
// Select the top users with the most rolls
|
||||
$users = [];
|
||||
|
||||
$sql = 'SELECT COUNT(roll_id) as total, user_id
|
||||
FROM ' . $this->rolls_table . '
|
||||
WHERE user_id > 0
|
||||
GROUP BY user_id
|
||||
ORDER BY total DESC';
|
||||
$result = $this->db->sql_query_limit($sql, 8);
|
||||
|
||||
while ($row = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$users[(int) $row['user_id']] = (int) $row['total'];
|
||||
}
|
||||
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
// Load the top users in the user_loader
|
||||
$this->user_loader->load_users(array_keys($users));
|
||||
|
||||
// Assign the users data to the template
|
||||
foreach ($users as $user_id => $total)
|
||||
{
|
||||
$this->template->assign_block_vars('users', [
|
||||
'AVATAR' => (string) $this->user_loader->get_avatar($user_id),
|
||||
'NAME' => (string) $this->user_loader->get_username($user_id, 'full'),
|
||||
'TOTAL' => (int) $total,
|
||||
]);
|
||||
}
|
||||
|
||||
// Dice sides
|
||||
$sides = $this->functions->get_dice_sides();
|
||||
|
||||
foreach ($sides as $side)
|
||||
{
|
||||
$this->template->assign_block_vars('sides', [
|
||||
'NUMBER' => $side,
|
||||
'U_DELETE' => $this->u_action . '&action=side_delete&value=' . $side,
|
||||
]);
|
||||
}
|
||||
|
||||
// Dice skins
|
||||
$skins = $this->functions->get_dice_skins();
|
||||
$skins_dir_valid = $this->functions->check_dice_skins_dir();
|
||||
|
||||
$skins_all_valid = true;
|
||||
|
||||
if ($skins_dir_valid)
|
||||
{
|
||||
$skins_available = $this->functions->available_dice_skins();
|
||||
|
||||
foreach($skins_available as $skin)
|
||||
{
|
||||
$valid = (bool) $this->functions->validate_dice_skin($skin, $sides);
|
||||
$installed = (bool) in_array($skin, $skins);
|
||||
|
||||
$skins_all_valid = ($installed && !$valid) ? false : $skins_all_valid;
|
||||
|
||||
$this->template->assign_block_vars('skins', [
|
||||
'NAME' => (string) $skin,
|
||||
'S_INSTALLED' => (bool) $installed,
|
||||
'S_VALID' => (bool) $valid,
|
||||
'U_ACTION' => $this->u_action . '&action=skin_' . ($installed ? 'uninstall' : 'install') . '&value=' . $skin,
|
||||
]);
|
||||
}
|
||||
/**
|
||||
* Any skins installed but not found in the filesystem should be automatically removed.
|
||||
*
|
||||
* Skins that are in the installed list and not in the filesystem
|
||||
*/
|
||||
$skins_difference = array_diff($skins, $skins_available);
|
||||
|
||||
if (!empty($skins_difference))
|
||||
{
|
||||
$this->skins_update('skin_uninstall', $skins, $skins_difference);
|
||||
}
|
||||
}
|
||||
|
||||
// Garbage collection
|
||||
$errors = [];
|
||||
|
||||
// If the settings were submitted
|
||||
if ($submit)
|
||||
{
|
||||
if (!check_form_key($form_key))
|
||||
{
|
||||
$errors[] = $this->lang->lang('FORM_INVALID');
|
||||
}
|
||||
|
||||
// Request the options
|
||||
$option_sides_only = $this->request->variable('dice_sides_only', (bool) $this->config['dice_sides_only']);
|
||||
$option_skins_height = (int) $this->request->variable('dice_skins_img_height', (int) $this->config['dice_skins_img_height']);
|
||||
$option_skins_width = (int) $this->request->variable('dice_skins_img_width', (int) $this->config['dice_skins_img_width']);
|
||||
|
||||
$option_skins_dir = $this->request->variable('dice_skins_dir', (string) $this->config['dice_skins_dir'], true);
|
||||
|
||||
/**
|
||||
* Let's trim a bunch of characters from the beginning and end of a string
|
||||
*
|
||||
* https://www.php.net/manual/en/function.trim.php
|
||||
*
|
||||
* " " (ASCII 32 (0x20)), an ordinary space.
|
||||
* "\t" (ASCII 9 (0x09)), a tab.
|
||||
* "\n" (ASCII 10 (0x0A)), a new line (line feed).
|
||||
* "\r" (ASCII 13 (0x0D)), a carriage return.
|
||||
* "\0" (ASCII 0 (0x00)), the NUL-byte.
|
||||
* "\x0B" (ASCII 11 (0x0B)), a vertical tab.
|
||||
*
|
||||
* Added "/"
|
||||
*/
|
||||
$option_skins_dir = trim($option_skins_dir, "/ \t\n\r\0\x0B");
|
||||
|
||||
/**
|
||||
* Let's harden all of this a bit more
|
||||
*
|
||||
* Especially Dots, Backslashes plus a bunch of other chars aren't allowed.
|
||||
*/
|
||||
if (preg_match_all('/[\\\:*<>|"]|\.{2,}|^\./', $option_skins_dir, $matches))
|
||||
{
|
||||
$character_list = implode('<br>', $matches[0]);
|
||||
|
||||
$errors[] = $this->lang->lang('ACP_DICE_SKINS_PATH_ERROR', $character_list);
|
||||
}
|
||||
|
||||
// Check if directory exists
|
||||
if (!$this->functions->check_dice_dir($this->functions->make_dice_dir($option_skins_dir)))
|
||||
{
|
||||
$errors[] = $this->lang->lang('DIRECTORY_DOES_NOT_EXIST', $option_skins_dir);
|
||||
}
|
||||
|
||||
// Check if skin images are within the 16 - 80 pixels
|
||||
if ($option_skins_height < 16 || $option_skins_height > 80)
|
||||
{
|
||||
$errors[] = $this->lang->lang('ACP_DICE_SKINS_IMG_HEIGHT_ERROR');
|
||||
}
|
||||
|
||||
if ($option_skins_width < 16 || $option_skins_width > 80)
|
||||
{
|
||||
$errors[] = $this->lang->lang('ACP_DICE_SKINS_IMG_WIDTH_ERROR');
|
||||
}
|
||||
|
||||
// No errors? Lets start saving
|
||||
if (empty($errors))
|
||||
{
|
||||
if ($option_skins_dir != $this->config['dice_skins_dir'])
|
||||
{
|
||||
$this->config->set('dice_skins_dir', $option_skins_dir);
|
||||
}
|
||||
|
||||
if ($option_skins_height != $this->config['dice_skins_img_height'])
|
||||
{
|
||||
$this->config->set('dice_skins_img_height', $option_skins_height);
|
||||
}
|
||||
|
||||
if ($option_skins_width != $this->config['dice_skins_img_width'])
|
||||
{
|
||||
$this->config->set('dice_skins_img_width', $option_skins_width);
|
||||
}
|
||||
|
||||
if ($option_sides_only != $this->config['dice_sides_only'])
|
||||
{
|
||||
$this->config->set('dice_sides_only', $option_sides_only);
|
||||
}
|
||||
|
||||
$option_numbers = [
|
||||
'dice_max_rolls',
|
||||
'dice_per_notation',
|
||||
'dice_qty_per_dice',
|
||||
'dice_qty_dice_per_notation',
|
||||
'dice_sides_per_dice',
|
||||
'dice_pc_dice_per_notation',
|
||||
'dice_fudge_dice_per_notation',
|
||||
'dice_penetration_dice_per_notation',
|
||||
'dice_compound_dice_per_notation',
|
||||
'dice_exploding_dice_per_notation',
|
||||
];
|
||||
|
||||
foreach ($option_numbers as $n)
|
||||
{
|
||||
$setting = (int) $this->config[$n];
|
||||
$value = (int) $this->request->variable($n, $setting);
|
||||
|
||||
if ($value !== $setting)
|
||||
{
|
||||
$this->config->set($n, $value);
|
||||
}
|
||||
}
|
||||
|
||||
// Log it
|
||||
$this->log->add('admin', $this->user->data['user_id'], $this->user->data['user_ip'], 'LOG_ACP_DICE_SETTINGS');
|
||||
|
||||
// Success message
|
||||
trigger_error($this->lang->lang('CONFIG_UPDATED') . adm_back_link($this->u_action));
|
||||
}
|
||||
}
|
||||
|
||||
// Process any action
|
||||
if ($action)
|
||||
{
|
||||
switch ($action)
|
||||
{
|
||||
case 'example':
|
||||
$this->template->set_filenames(['example' => '@phpbbstudio_dice/dice_example.html']);
|
||||
$this->template->assign_var('S_IS_AJAX', $this->request->is_ajax());
|
||||
|
||||
if ($this->request->is_ajax())
|
||||
{
|
||||
$json_response = new \phpbb\json_response;
|
||||
$json_response->send([
|
||||
'MESSAGE_TITLE' => $this->lang->lang('INFORMATION'),
|
||||
'MESSAGE_TEXT' => $this->template->assign_display('example'),
|
||||
]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'locations':
|
||||
// Assign the link locations
|
||||
$this->assign_link_locations();
|
||||
|
||||
if ($this->request->is_set_post('submit_locations'))
|
||||
{
|
||||
// Request the link locations
|
||||
$links = $this->request_link_locations();
|
||||
|
||||
// Set the link locations
|
||||
$this->functions->set_dice_link_locations($links);
|
||||
|
||||
// Log it
|
||||
$this->log->add('admin', $this->user->data['user_id'], $this->user->data['user_ip'], 'LOG_ACP_DICE_LOCATIONS');
|
||||
|
||||
// Success message
|
||||
trigger_error($this->lang->lang('ACP_DICE_LOCATIONS_SUCCESS') . '<br>' . adm_back_link($this->u_action));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (confirm_box(true))
|
||||
{
|
||||
switch ($action)
|
||||
{
|
||||
case 'orphaned':
|
||||
$value = $this->delete_orphans();
|
||||
break;
|
||||
|
||||
case 'side_add':
|
||||
case 'side_delete':
|
||||
$this->sides_update($action, $sides, $value);
|
||||
break;
|
||||
|
||||
case 'skin_install':
|
||||
case 'skin_uninstall':
|
||||
$this->skins_update($action, $skins, $value);
|
||||
break;
|
||||
}
|
||||
|
||||
// Log it
|
||||
$this->log->add('admin', $this->user->data['user_id'], $this->user->data['user_ip'], 'LOG_ACP_DICE_' . utf8_strtoupper($action), false, [$value]);
|
||||
|
||||
// Show success message
|
||||
trigger_error($this->lang->lang('ACP_DICE_' . utf8_strtoupper($action) . '_SUCCESS', $value) . '<br>' . adm_back_link($this->u_action));
|
||||
}
|
||||
else
|
||||
{
|
||||
confirm_box(false, 'ACP_DICE_' . utf8_strtoupper($action), build_hidden_fields([
|
||||
'action' => $action,
|
||||
'value' => $value,
|
||||
]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$this->template->assign_vars(array_merge($template_vars, [
|
||||
'S_ERRORS' => !empty($errors),
|
||||
'ERROR_MSG' => implode('<br>', $errors),
|
||||
|
||||
'SKINS_DIR' => $this->config['dice_skins_dir'],
|
||||
'SKINS_DIR_ERROR' => !$skins_dir_valid,
|
||||
'SKINS_IMG_HEIGHT' => $this->config['dice_skins_img_height'],
|
||||
'SKINS_IMG_WIDTH' => $this->config['dice_skins_img_width'],
|
||||
'SKINS_INSTALLED' => count($skins),
|
||||
'SKINS_VALID' => $skins_all_valid,
|
||||
'ROLLS_TOTAL' => $rolls_total,
|
||||
'ROLLS_ORPHAN' => $rolls_orphan,
|
||||
|
||||
'U_ACTION' => $this->u_action . '#dice_settings',
|
||||
'U_BACK' => $this->u_action,
|
||||
'U_EXAMPLE' => $this->u_action . '&action=example',
|
||||
'U_LOCATIONS' => $this->u_action . '&action=locations',
|
||||
'U_ORPHANED' => $this->u_action . '&action=orphaned',
|
||||
'U_SIDE_ADD' => $this->u_action . '&action=side_add',
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set_page_url($u_action)
|
||||
{
|
||||
$this->u_action = $u_action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all orphaned dice rolls.
|
||||
*
|
||||
* @return int Amount of dice rolls that were deleted
|
||||
* @access public
|
||||
*/
|
||||
protected function delete_orphans()
|
||||
{
|
||||
$sql = 'DELETE FROM ' . $this->rolls_table . ' WHERE roll_id = 0 OR post_id = 0 OR topic_id = 0 OR forum_id = 0 OR user_id = 0';
|
||||
$this->db->sql_query($sql);
|
||||
|
||||
return (int) $this->db->sql_affectedrows();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the installed dice sides setting.
|
||||
*
|
||||
* @param string $action The action to take (side_add|side_delete)
|
||||
* @param array $sides Array of currently installed dice sides
|
||||
* @param int $value The dice side to add or delete
|
||||
* @return void
|
||||
* @access protected
|
||||
*/
|
||||
protected function sides_update($action, array $sides, $value)
|
||||
{
|
||||
switch ($action)
|
||||
{
|
||||
case 'side_add':
|
||||
$sides[] = (int) $value;
|
||||
break;
|
||||
|
||||
case 'side_delete':
|
||||
if (($key = array_search($value, $sides)) !== false)
|
||||
{
|
||||
unset($sides[$key]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Clean the array (filter, unique, sort)
|
||||
$sides = $this->functions->clean_dice_array($sides);
|
||||
|
||||
// Store the new array in the database
|
||||
$this->functions->set_dice_sides($sides);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the installed dice skin setting.
|
||||
*
|
||||
* @param string $action The action to take (skin_install|skin_uninstall)
|
||||
* @param array $skins Array of currently installed dice skins
|
||||
* @param mixed $value The value/array to install (add) or uninstall (delete)
|
||||
* @return void
|
||||
* @access protected
|
||||
*/
|
||||
protected function skins_update($action,array $skins, $value)
|
||||
{
|
||||
// Force an array, if it is not already
|
||||
$value = is_array($value) ? (array) $value : (array) [$value];
|
||||
|
||||
switch ($action)
|
||||
{
|
||||
case 'skin_install':
|
||||
$skins = array_merge($skins, $value);
|
||||
break;
|
||||
|
||||
case 'skin_uninstall':
|
||||
$skins = array_diff($skins, $value);
|
||||
break;
|
||||
}
|
||||
|
||||
// Clean the array (filter, unique, sort)
|
||||
$skins = $this->functions->clean_dice_array($skins);
|
||||
|
||||
// Store the new array in the database
|
||||
$this->functions->set_dice_skins($skins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign link locations.
|
||||
*
|
||||
* @return void
|
||||
* @access protected
|
||||
*/
|
||||
protected function assign_link_locations()
|
||||
{
|
||||
$template_vars = [];
|
||||
$locations = $this->functions->get_dice_link_locations();
|
||||
|
||||
foreach ($locations as $location)
|
||||
{
|
||||
$template_vars[$location['name']] = (bool) $location['status'];
|
||||
}
|
||||
|
||||
$this->template->assign_vars($template_vars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request link locations
|
||||
*
|
||||
* @return array Array with link locations and their status
|
||||
* @access protected
|
||||
*/
|
||||
protected function request_link_locations()
|
||||
{
|
||||
$links = [];
|
||||
$locations = $this->functions->get_dice_link_locations();
|
||||
|
||||
foreach ($locations as $location)
|
||||
{
|
||||
$links[$location['name']] = $this->request->variable((string) $location['name'], false);
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
}
|
||||
33
ext/phpbbstudio/dice/controller/admin_interface.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\controller;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Admin controller interface.
|
||||
*/
|
||||
interface admin_interface
|
||||
{
|
||||
/**
|
||||
* Display and handle any actions from the Dice ACP.
|
||||
*
|
||||
* @param string $action Any action to handle
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function handle($action);
|
||||
|
||||
/**
|
||||
* Make the custom form action available in the admin controller.
|
||||
*
|
||||
* @param string $u_action Custom form action
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function set_page_url($u_action);
|
||||
}
|
||||
458
ext/phpbbstudio/dice/controller/main_controller.php
Normal file
@@ -0,0 +1,458 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\controller;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Main controller.
|
||||
*/
|
||||
class main_controller implements main_interface
|
||||
{
|
||||
/** @var \phpbb\auth\auth */
|
||||
protected $auth;
|
||||
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbbstudio\dice\core\functions_common */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbb\controller\helper */
|
||||
protected $helper;
|
||||
|
||||
/** @var \phpbb\language\language */
|
||||
protected $lang;
|
||||
|
||||
/** @var \phpbbstudio\dice\operator\roll */
|
||||
protected $operator;
|
||||
|
||||
/** @var \phpbbstudio\dice\core\functions_regex */
|
||||
protected $regex;
|
||||
|
||||
/** @var \phpbb\request\request */
|
||||
protected $request;
|
||||
|
||||
/** @var \phpbb\template\template */
|
||||
protected $template;
|
||||
|
||||
/** @var \phpbb\user */
|
||||
protected $user;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\auth\auth $auth Authentication object
|
||||
* @param \phpbb\config\config $config Configuration object
|
||||
* @param \phpbbstudio\dice\core\functions_common $functions Common functions object
|
||||
* @param \phpbb\controller\helper $helper Controller helper object
|
||||
* @param \phpbb\language\language $lang Language object
|
||||
* @param \phpbbstudio\dice\operator\roll $operator Roll operator object
|
||||
* @param \phpbbstudio\dice\core\functions_regex $regex Regex functions
|
||||
* @param \phpbb\request\request $request Request object
|
||||
* @param \phpbb\template\template $template Template object
|
||||
* @param \phpbb\user $user User object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\auth\auth $auth,
|
||||
\phpbb\config\config $config,
|
||||
\phpbbstudio\dice\core\functions_common $functions,
|
||||
\phpbb\controller\helper $helper,
|
||||
\phpbb\language\language $lang,
|
||||
\phpbbstudio\dice\operator\roll $operator,
|
||||
\phpbbstudio\dice\core\functions_regex $regex,
|
||||
\phpbb\request\request $request,
|
||||
\phpbb\template\template $template,
|
||||
\phpbb\user $user
|
||||
)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->config = $config;
|
||||
$this->functions = $functions;
|
||||
$this->helper = $helper;
|
||||
$this->lang = $lang;
|
||||
$this->operator = $operator;
|
||||
$this->regex = $regex;
|
||||
$this->request = $request;
|
||||
$this->template = $template;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function add($forum_id, $topic_id, $post_id, $poster_id, $hash)
|
||||
{
|
||||
if (!$this->request->is_ajax())
|
||||
{
|
||||
throw new \phpbb\exception\http_exception(400, 'DICE_NOT_AJAX');
|
||||
}
|
||||
|
||||
// Set up JSON response
|
||||
$json_response = new \phpbb\json_response;
|
||||
|
||||
// Check the link hash for security
|
||||
if (!check_link_hash($hash, 'dice_add'))
|
||||
{
|
||||
$json_response->send([
|
||||
'MESSAGE_TITLE' => $this->lang->lang('ERROR'),
|
||||
'MESSAGE_TEXT' => $this->lang->lang('FORM_INVALID'),
|
||||
]);
|
||||
}
|
||||
|
||||
// Check if dice is enabled on this forum
|
||||
if (!$this->functions->forum_enabled($forum_id))
|
||||
{
|
||||
$json_response->send([
|
||||
'MESSAGE_TITLE' => $this->lang->lang('ERROR'),
|
||||
'MESSAGE_TEXT' => $this->lang->lang('DICE_ROLL_FORUM_DISABLED'),
|
||||
]);
|
||||
}
|
||||
|
||||
// Grab the author for this post, if we are not creating a new post
|
||||
$poster_id = $poster_id ? $poster_id : $this->user->data['user_id'];
|
||||
|
||||
if (!$this->functions->dice_auth_add($forum_id, (int) $poster_id))
|
||||
{
|
||||
$json_response->send([
|
||||
'MESSAGE_TITLE' => $this->lang->lang('ERROR'),
|
||||
'MESSAGE_TEXT' => $this->lang->lang('DICE_ROLL_ADD_UNAUTH'),
|
||||
]);
|
||||
}
|
||||
|
||||
// Set up limit
|
||||
$count = 0;
|
||||
|
||||
if ($this->functions->dice_limit($forum_id))
|
||||
{
|
||||
$entities = $this->operator->get_rolls_for_posting($forum_id, $topic_id, $post_id);
|
||||
$count = count($entities);
|
||||
|
||||
if ($this->functions->dice_limit_reached($count, $forum_id))
|
||||
{
|
||||
$json_response->send([
|
||||
'MESSAGE_TITLE' => $this->lang->lang('ERROR'),
|
||||
'MESSAGE_TEXT' => $this->lang->lang('DICE_ROLLS_TOO_MANY'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// Set up variables
|
||||
$user_id = (int) $this->user->data['user_id'];
|
||||
$notation = $this->request->variable('notation', '');
|
||||
$notation = htmlspecialchars_decode($notation, ENT_COMPAT);
|
||||
|
||||
/**
|
||||
* Get a roll entity from the operator.
|
||||
* @var \phpbbstudio\dice\entity\roll $entity
|
||||
*/
|
||||
$entity = $this->operator->get_entity();
|
||||
|
||||
// Map out entity functions and data
|
||||
$map_fields = [
|
||||
'set_forum' => $forum_id,
|
||||
'set_topic' => $topic_id,
|
||||
'set_post' => $post_id,
|
||||
'set_user' => $user_id,
|
||||
'set_time' => time(),
|
||||
'set_notation' => $notation,
|
||||
];
|
||||
|
||||
// Garbage collection
|
||||
$errors = [];
|
||||
|
||||
// Call all functions with the respective data
|
||||
foreach ($map_fields as $entity_function => $entity_data)
|
||||
{
|
||||
try
|
||||
{
|
||||
$entity->$entity_function($entity_data);
|
||||
}
|
||||
catch (\phpbbstudio\dice\exception\base $e)
|
||||
{
|
||||
$errors[] = $e->get_message($this->lang);
|
||||
}
|
||||
}
|
||||
|
||||
// Unset temporarily variables
|
||||
unset($map_fields);
|
||||
|
||||
// Try and roll the dice
|
||||
if (empty($errors))
|
||||
{
|
||||
try
|
||||
{
|
||||
$entity->roll();
|
||||
}
|
||||
catch (\phpbbstudio\dice\exception\base $e)
|
||||
{
|
||||
$errors[] = $e->get_message($this->lang);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($errors))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Insert the roll data to the database
|
||||
$entity->insert();
|
||||
|
||||
$count++;
|
||||
}
|
||||
catch (\phpbbstudio\dice\exception\out_of_bounds $e)
|
||||
{
|
||||
$errors[] = $e->get_message($this->lang);
|
||||
}
|
||||
}
|
||||
|
||||
// Send a json response
|
||||
$json_response->send([
|
||||
'ROLL_SUCCESS' => empty($errors),
|
||||
'ROLL_LIMIT' => (bool) $this->functions->dice_limit_reached($count, $forum_id),
|
||||
'ROLL_DATA' => $this->operator->get_roll_data_for_edit($entity),
|
||||
'MESSAGE_TITLE' => empty($errors) ? $this->lang->lang('SUCCESS') : $this->lang->lang('ERROR'),
|
||||
'MESSAGE_TEXT' => empty($errors) ? $this->lang->lang('DICE_ROLL_ADD_SUCCESS') : implode('<br>', $errors),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function edit($roll_id)
|
||||
{
|
||||
if (!$this->request->is_ajax())
|
||||
{
|
||||
throw new \phpbb\exception\http_exception(400, 'DICE_NOT_AJAX');
|
||||
}
|
||||
|
||||
// Set up a JSON response
|
||||
$json_response = new \phpbb\json_response;
|
||||
|
||||
/**
|
||||
* Get a roll entity from the operator.
|
||||
* @var \phpbbstudio\dice\entity\roll $entity
|
||||
*/
|
||||
$entity = $this->operator->get_entity();
|
||||
|
||||
try
|
||||
{
|
||||
$entity->load($roll_id);
|
||||
}
|
||||
catch (\phpbbstudio\dice\exception\out_of_bounds $e)
|
||||
{
|
||||
$json_response->send([
|
||||
'MESSAGE_TITLE' => $this->lang->lang('ERROR'),
|
||||
'MESSAGE_TEXT' => $e->get_message($this->lang),
|
||||
]);
|
||||
}
|
||||
|
||||
// Grab the author for this post, if we are not creating a new post
|
||||
$poster_id = $entity->get_post() ? $this->operator->get_author($entity->get_id()) : $this->user->data['user_id'];
|
||||
|
||||
if (!$this->functions->dice_auth_edit($entity->get_forum(), (int) $poster_id))
|
||||
{
|
||||
$json_response->send([
|
||||
'MESSAGE_TITLE' => $this->lang->lang('ERROR'),
|
||||
'MESSAGE_TEXT' => $this->lang->lang('DICE_ROLL_EDIT_UNAUTH'),
|
||||
]);
|
||||
}
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
// Garbage collection
|
||||
$errors = [];
|
||||
|
||||
// Set up variables
|
||||
$user_id = (int) $this->user->data['user_id'];
|
||||
$notation = $this->request->variable('notation', '');
|
||||
$notation = htmlspecialchars_decode($notation, ENT_COMPAT);
|
||||
|
||||
try
|
||||
{
|
||||
$entity->set_notation($notation)->roll();
|
||||
}
|
||||
catch (\phpbbstudio\dice\exception\base $e)
|
||||
{
|
||||
$errors[] = $e->get_message($this->lang);
|
||||
}
|
||||
|
||||
if (empty($errors))
|
||||
{
|
||||
try
|
||||
{
|
||||
// Update the roll data in the database
|
||||
$entity->set_edit_user($user_id)
|
||||
->set_edit_time(time())
|
||||
->increment_edit_count()
|
||||
->save();
|
||||
}
|
||||
catch (\phpbbstudio\dice\exception\out_of_bounds $e)
|
||||
{
|
||||
$errors[] = $e->get_message($this->lang);
|
||||
}
|
||||
}
|
||||
|
||||
// Send a json response
|
||||
$json_response->send([
|
||||
'ROLL_SUCCESS' => empty($errors),
|
||||
'ROLL_DATA' => $this->operator->get_roll_data_for_edit($entity),
|
||||
'MESSAGE_TITLE' => empty($errors) ? $this->lang->lang('SUCCESS') : $this->lang->lang('ERROR'),
|
||||
'MESSAGE_TEXT' => empty($errors) ? $this->lang->lang('DICE_ROLL_EDIT_SUCCESS') : implode('<br>', $errors),
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->template->assign_vars([
|
||||
'ROLL_DATA' => $this->operator->get_roll_data_for_edit($entity),
|
||||
]);
|
||||
|
||||
confirm_box(false, 'DICE_ROLL_EDIT', build_hidden_fields([
|
||||
'roll_id' => $roll_id,
|
||||
]), '@phpbbstudio_dice/dice_edit.html', $this->helper->get_current_url());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($roll_id)
|
||||
{
|
||||
if (!$this->request->is_ajax())
|
||||
{
|
||||
throw new \phpbb\exception\http_exception(400, 'DICE_NOT_AJAX');
|
||||
}
|
||||
|
||||
// Set up a JSON response
|
||||
$json_response = new \phpbb\json_response;
|
||||
|
||||
/**
|
||||
* Get and load entity
|
||||
* @var \phpbbstudio\dice\entity\roll $entity
|
||||
*/
|
||||
$entity = $this->operator->get_entity()->load($roll_id);
|
||||
|
||||
// Grab the author for this post, if we are not creating a new post
|
||||
$poster_id = $entity->get_post() ? $this->operator->get_author($entity->get_id()) : $this->user->data['user_id'];
|
||||
|
||||
if (!$this->functions->dice_auth_delete($entity->get_forum(), (int) $poster_id))
|
||||
{
|
||||
$json_response->send([
|
||||
'MESSAGE_TITLE' => $this->lang->lang('ERROR'),
|
||||
'MESSAGE_TEXT' => $this->lang->lang('DICE_ROLL_DELETE_UNAUTH'),
|
||||
]);
|
||||
}
|
||||
|
||||
if (confirm_box(true))
|
||||
{
|
||||
// Delete the roll entity
|
||||
$success = $this->operator->delete($roll_id);
|
||||
|
||||
$count = 0;
|
||||
|
||||
if ($success)
|
||||
{
|
||||
$entities = $this->operator->get_rolls_for_posting($entity->get_forum(), $entity->get_topic(), $entity->get_post());
|
||||
$count = count($entities);
|
||||
}
|
||||
|
||||
$json_response->send([
|
||||
'ROLL_ID' => (int) $roll_id,
|
||||
'ROLL_SUCCESS' => (bool) $success,
|
||||
'ROLL_LIMIT' => (bool) $this->functions->dice_limit_reached($count, $entity->get_forum()),
|
||||
'MESSAGE_TITLE' => $success ? $this->lang->lang('SUCCESS') : $this->lang->lang('ERROR'),
|
||||
'MESSAGE_TEXT' => $success ? $this->lang->lang('DICE_ROLL_DELETE_SUCCESS') : $this->lang->lang('DICE_ROLL_NOT_EXIST', 1),
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* The 5th parameter (u_action) has to be set
|
||||
* for it to work correctly with AJAX and URL rewriting.
|
||||
*/
|
||||
confirm_box(false, 'DICE_ROLL_DELETE', build_hidden_fields([
|
||||
'roll_id' => (int) $roll_id,
|
||||
]), 'confirm_body.html', $this->helper->get_current_url());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function page()
|
||||
{
|
||||
if (!$this->auth->acl_get('u_dice_test'))
|
||||
{
|
||||
throw new \phpbb\exception\http_exception(403, 'NOT_AUTHORISED');
|
||||
}
|
||||
|
||||
$notation = $this->request->variable('notation', '', true);
|
||||
$notation = htmlspecialchars_decode($notation, ENT_COMPAT);
|
||||
$submit = $this->request->is_set_post('submit');
|
||||
|
||||
/** @var \phpbbstudio\dice\entity\roll $entity */
|
||||
$entity = $this->operator->get_entity();
|
||||
|
||||
if ($notation)
|
||||
{
|
||||
try
|
||||
{
|
||||
$entity->set_notation($notation)->roll();
|
||||
}
|
||||
catch (\phpbbstudio\dice\exception\unexpected_value $e)
|
||||
{
|
||||
$errors[] = $e->get_message($this->lang);
|
||||
}
|
||||
}
|
||||
|
||||
if ($submit && $this->request->is_ajax())
|
||||
{
|
||||
$json_response = new \phpbb\json_response;
|
||||
|
||||
$json_response->send([
|
||||
'MESSAGE_TITLE' => 'HI',
|
||||
'MESSAGE_TEXT' => $entity->get_output(),
|
||||
]);
|
||||
}
|
||||
|
||||
$skin = $this->request->variable('skin', $this->user->data['dice_u_skin'], true);
|
||||
$skins = $this->functions->get_dice_skins(true);
|
||||
$skin_data = $this->functions->get_dice_skin_data(true, $skin);
|
||||
$skin_options = $this->functions->build_dice_select($skins, $skin, true);
|
||||
|
||||
$this->template->assign_vars([
|
||||
'NOTATION' => $entity->get_notation(),
|
||||
'OUTPUT' => $entity->get_output(),
|
||||
'DISPLAY' => $entity->get_display($skin_data['name'], $skin_data['dir'], $skin_data['ext']),
|
||||
'TOTAL' => $entity->get_total(),
|
||||
|
||||
'DICE_IMG_HEIGHT' => (int) $this->config['dice_skins_img_height'],
|
||||
'DICE_IMG_WIDTH' => (int) $this->config['dice_skins_img_width'],
|
||||
|
||||
'DICE_ALLOWED_ONLY' => $this->config['dice_sides_only'],
|
||||
'DICE_ALLOWED_SIDES' => $this->functions->get_dice_sides(),
|
||||
|
||||
'LIMIT_DICE_ROLLS' => $this->config['dice_max_rolls'],
|
||||
'LIMIT_DICE_QTY' => $this->config['dice_qty_per_dice'],
|
||||
'LIMIT_DICE_SIDES' => $this->config['dice_sides_per_dice'],
|
||||
'LIMIT_DICE_FUDGE' => $this->config['dice_fudge_dice_per_notation'],
|
||||
'LIMIT_DICE_PC' => $this->config['dice_pc_dice_per_notation'],
|
||||
'LIMIT_DICE_EXPLODE' => $this->config['dice_exploding_dice_per_notation'],
|
||||
'LIMIT_DICE_PEN' => $this->config['dice_penetration_dice_per_notation'],
|
||||
'LIMIT_DICE_COMP' => $this->config['dice_compound_dice_per_notation'],
|
||||
|
||||
'SKIN_OPTIONS' => $skin_options,
|
||||
|
||||
'S_DICE_SUBMIT' => $submit,
|
||||
|
||||
'U_DICE_ACTION' => $this->helper->route('phpbbstudio_dice'),
|
||||
]);
|
||||
|
||||
return $this->helper->render('@phpbbstudio_dice/dice_page.html', $this->lang->lang('DICE_ROLL'));
|
||||
}
|
||||
}
|
||||
58
ext/phpbbstudio/dice/controller/main_interface.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\controller;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Main controller interface.
|
||||
*/
|
||||
interface main_interface
|
||||
{
|
||||
/**
|
||||
* Create a roll.
|
||||
*
|
||||
* @param int $forum_id The forum identifier
|
||||
* @param int $topic_id The topic identifier
|
||||
* @param int $post_id The post identifier
|
||||
* @param int $poster_id The poster identifier
|
||||
* @param string $hash The generated link hash
|
||||
* @return \phpbb\json_response
|
||||
* @throws \phpbb\exception\http_exception
|
||||
* @access public
|
||||
*/
|
||||
public function add($forum_id, $topic_id, $post_id, $poster_id, $hash);
|
||||
|
||||
/**
|
||||
* Edit a roll.
|
||||
*
|
||||
* @param int $roll_id The roll identifier
|
||||
* @return \phpbb\json_response
|
||||
* @throws \phpbb\exception\http_exception
|
||||
* @access public
|
||||
*/
|
||||
public function edit($roll_id);
|
||||
|
||||
/**
|
||||
* Delete a roll.
|
||||
*
|
||||
* @param int $roll_id The roll identifier
|
||||
* @return void \phpbb\json_response
|
||||
* @throws \phpbb\exception\http_exception
|
||||
* @access public
|
||||
*/
|
||||
public function delete($roll_id);
|
||||
|
||||
/**
|
||||
* Display a dice testing page.
|
||||
*
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
* @throws \phpbb\exception\http_exception
|
||||
* @access public
|
||||
*/
|
||||
public function page();
|
||||
}
|
||||
609
ext/phpbbstudio/dice/core/functions_common.php
Normal file
@@ -0,0 +1,609 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\core;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Common functions.
|
||||
*/
|
||||
class functions_common
|
||||
{
|
||||
/** @var \phpbb\auth\auth */
|
||||
protected $auth;
|
||||
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbb\config\db_text */
|
||||
protected $config_text;
|
||||
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbb\filesystem\filesystem */
|
||||
protected $filesystem;
|
||||
|
||||
/** @var \phpbbstudio\dice\core\functions_finder */
|
||||
protected $finder;
|
||||
|
||||
/** @var \phpbb\language\language */
|
||||
protected $lang;
|
||||
|
||||
/** @var \phpbb\path_helper */
|
||||
protected $path_helper;
|
||||
|
||||
/** @var \phpbb\user */
|
||||
protected $user;
|
||||
|
||||
/** @var string Forums table */
|
||||
protected $forums_table;
|
||||
|
||||
/** @var string phpBB root path */
|
||||
protected $root_path;
|
||||
|
||||
/** @var array Array of allowed image extensions */
|
||||
protected $image_extensions;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\auth\auth $auth Authentication object
|
||||
* @param \phpbb\config\config $config Configuration object
|
||||
* @param \phpbb\config\db_text $config_text Configuration database object
|
||||
* @param \phpbb\db\driver\driver_interface $db Database object
|
||||
* @param \phpbb\filesystem\filesystem $filesystem Filesystem object
|
||||
* @param \phpbbstudio\dice\core\functions_finder $finder Dice finder
|
||||
* @param \phpbb\language\language $lang Language object
|
||||
* @param \phpbb\path_helper $path_helper Path helper
|
||||
* @param \phpbb\user $user User object
|
||||
* @param string $forums_table Forums table
|
||||
* @param string $root_path phpBB root path
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\auth\auth $auth,
|
||||
\phpbb\config\config $config,
|
||||
\phpbb\config\db_text $config_text,
|
||||
\phpbb\db\driver\driver_interface $db,
|
||||
\phpbb\filesystem\filesystem $filesystem,
|
||||
functions_finder $finder,
|
||||
\phpbb\language\language $lang,
|
||||
\phpbb\path_helper $path_helper,
|
||||
\phpbb\user $user,
|
||||
$forums_table,
|
||||
$root_path
|
||||
)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->config = $config;
|
||||
$this->config_text = $config_text;
|
||||
$this->db = $db;
|
||||
$this->filesystem = $filesystem;
|
||||
$this->finder = $finder;
|
||||
$this->lang = $lang;
|
||||
$this->path_helper = $path_helper;
|
||||
$this->user = $user;
|
||||
$this->forums_table = $forums_table;
|
||||
$this->root_path = $root_path;
|
||||
|
||||
$this->image_extensions = ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'svg'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is a dice limit for this forum and user combination.
|
||||
*
|
||||
* @param int $forum_id The forum identifier
|
||||
* @return bool Whether or not there is a limit
|
||||
* @access public
|
||||
*/
|
||||
public function dice_limit($forum_id)
|
||||
{
|
||||
return ($this->config['dice_max_rolls'] && !$this->auth->acl_get('f_dice_no_limit', (int) $forum_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the dice limit has been reached for this forum, user and count combination.
|
||||
*
|
||||
* @param int $count The roll count
|
||||
* @param int $forum_id The forum identifier
|
||||
* @return bool Whether or not the limit has been reached
|
||||
* @access public
|
||||
*/
|
||||
public function dice_limit_reached($count, $forum_id)
|
||||
{
|
||||
return (($count >= $this->config['dice_max_rolls']) && $this->dice_limit($forum_id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two user identifiers against each other. Used to determine if this user is the author of a post.
|
||||
*
|
||||
* @param int $user_id User identifier
|
||||
* @return bool Whether or not the identifiers are identical
|
||||
* @access public
|
||||
*/
|
||||
public function dice_author($user_id)
|
||||
{
|
||||
return ((int) $this->user->data['user_id'] === (int) $user_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this user can add a dice in this forum.
|
||||
*
|
||||
* @param int $forum_id Forum identifier
|
||||
* @param int $user_id User identifier of the poster
|
||||
* @return bool Whether or not this user can add a dice in this forum
|
||||
* @access public
|
||||
*/
|
||||
public function dice_auth_add($forum_id, $user_id)
|
||||
{
|
||||
return ($this->auth->acl_get('f_mod_dice_add', (int) $forum_id) || ($this->auth->acl_get('f_dice_roll', (int) $forum_id) && $this->dice_author($user_id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this user can delete a dice in this forum.
|
||||
*
|
||||
* @param int $forum_id Forum identifier
|
||||
* @param int $user_id User identifier of the poster
|
||||
* @return bool Whether or not this user can delete a dice in this forum
|
||||
* @access public
|
||||
*/
|
||||
public function dice_auth_delete($forum_id, $user_id)
|
||||
{
|
||||
return ($this->auth->acl_get('f_mod_dice_delete', (int) $forum_id) || ($this->auth->acl_get('f_dice_delete', (int) $forum_id) && $this->dice_author($user_id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this user can edit a dice in this forum.
|
||||
*
|
||||
* @param int $forum_id Forum identifier
|
||||
* @param int $user_id User identifier of the poster
|
||||
* @return bool Whether or not this user can edit a dice in this forum
|
||||
* @access public
|
||||
*/
|
||||
public function dice_auth_edit($forum_id, $user_id)
|
||||
{
|
||||
return ($this->auth->acl_get('f_mod_dice_edit', (int) $forum_id) || ($this->auth->acl_get('f_dice_edit', (int) $forum_id) && $this->dice_author($user_id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a forum's dice settings.
|
||||
*
|
||||
* @param int $forum_id The forum identifier
|
||||
* @return mixed The forum's dice settings or false if no forum id was provided
|
||||
* @access public
|
||||
*/
|
||||
public function forum_data($forum_id)
|
||||
{
|
||||
if (empty($forum_id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = 'SELECT dice_enabled, dice_skin_override, dice_f_skin FROM ' . $this->forums_table . ' WHERE forum_id = ' . (int) $forum_id;
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$row = $this->db->sql_fetchrow($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $row;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the Dice extension is enabled for a specific forum.
|
||||
*
|
||||
* @param int $forum_id The forum identifier
|
||||
* @return bool Whether or not the extension is enabled for this forum
|
||||
* @access public
|
||||
*/
|
||||
public function forum_enabled($forum_id)
|
||||
{
|
||||
if (empty($forum_id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = 'SELECT dice_enabled FROM ' . $this->forums_table . ' WHERE forum_id = ' . (int) $forum_id;
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$s_enabled = (bool) $this->db->sql_fetchfield('dice_enabled');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $s_enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the skin override is enabled for a specific forum.
|
||||
*
|
||||
* @param int $forum_id The forum identifier
|
||||
* @return bool Whether or not the skin override is enabled for this forum
|
||||
* @access public
|
||||
*/
|
||||
public function forum_skin_override($forum_id)
|
||||
{
|
||||
if (empty($forum_id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql = 'SELECT dice_skin_override FROM ' . $this->forums_table . ' WHERE forum_id = ' . (int) $forum_id;
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$s_override = (bool) $this->db->sql_fetchfield('dice_skin_override');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $s_override;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip emojis from a string
|
||||
*
|
||||
* @param string $string
|
||||
* @return string
|
||||
*/
|
||||
public function dice_strip_emojis($string)
|
||||
{
|
||||
return preg_replace('/[\x{10000}-\x{10FFFF}]/u', "", $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the installed dice skins from the database.
|
||||
*
|
||||
* @param bool $include_text Whether or not the "text" option should be included
|
||||
* @return array Array of installed dice skins
|
||||
* @access public
|
||||
*/
|
||||
public function get_dice_skins($include_text = false)
|
||||
{
|
||||
$skins = json_decode($this->config_text->get('dice_skins'), true);
|
||||
|
||||
if ($include_text)
|
||||
{
|
||||
array_unshift($skins, $this->lang->lang('DICE_TEXT'));
|
||||
}
|
||||
|
||||
return (array) $skins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the installed dice skins in the database.
|
||||
*
|
||||
* @param array $skins Array of installed dice skins
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function set_dice_skins(array $skins)
|
||||
{
|
||||
// Enforce data type
|
||||
$skins = (array) $skins;
|
||||
|
||||
$this->config_text->set('dice_skins', json_encode($skins));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the installed dice sides from the database.
|
||||
*
|
||||
* @return array Array of installed dice sides
|
||||
* @access public
|
||||
*/
|
||||
public function get_dice_sides()
|
||||
{
|
||||
return (array) json_decode($this->config_text->get('dice_sides'), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the installed dice sides in the database.
|
||||
*
|
||||
* @param array $sides Array of installed dice sides
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function set_dice_sides(array $sides)
|
||||
{
|
||||
// Enforce data type
|
||||
$sides = (array) $sides;
|
||||
|
||||
$this->config_text->set('dice_sides', json_encode($sides));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the correctly formatted dice skins directory.
|
||||
*
|
||||
* @return string Correctly formatted dice skins directory
|
||||
* @access public
|
||||
*/
|
||||
public function get_dice_skins_dir()
|
||||
{
|
||||
return $this->make_dice_dir($this->config['dice_skins_dir']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Correctly format a given directory, prefixed with phpBB's root path and a trailing slash.
|
||||
*
|
||||
* @param string $directory The directory to correctly format
|
||||
* @return string The correctly formatted directory
|
||||
* @access public
|
||||
*/
|
||||
public function make_dice_dir($directory)
|
||||
{
|
||||
return (string) $this->root_path . $directory . '/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the dice skins directory exists and is readable.
|
||||
*
|
||||
* @return bool Whether or not the dice skins directory exists and is readable
|
||||
* @access public
|
||||
*/
|
||||
public function check_dice_skins_dir()
|
||||
{
|
||||
return $this->check_dice_dir($this->get_dice_skins_dir());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a directory or file exists.
|
||||
*
|
||||
* @param string $directory The directory to check for existance and readability
|
||||
* @return bool Whether or not the directory exists and is readable
|
||||
* @access public
|
||||
*/
|
||||
public function check_dice_dir($directory)
|
||||
{
|
||||
return ($this->filesystem->exists($directory) && $this->filesystem->is_readable($directory));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the web root path for a give source.
|
||||
*
|
||||
* @param string $src The source string to update.
|
||||
* @return string The updated source string.
|
||||
* @access public
|
||||
*/
|
||||
public function update_dice_img_path($src)
|
||||
{
|
||||
return $this->path_helper->update_web_root_path($src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the available dice skins in the dice skins directory.
|
||||
*
|
||||
* @return array Array of available dice skins
|
||||
* @access public
|
||||
*/
|
||||
public function available_dice_skins()
|
||||
{
|
||||
return $this->finder->find_dice_skins($this->get_dice_skins_dir());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate dice skins, check if all images for all installed sides are present.
|
||||
*
|
||||
* @param string $skin The dice skin to validate
|
||||
* @param array $sides Array of installed dice sides
|
||||
* @return bool Whether or not this dice skin has all images for all installed dice sides
|
||||
* @access public
|
||||
*/
|
||||
public function validate_dice_skin($skin, array $sides)
|
||||
{
|
||||
$valid = true;
|
||||
|
||||
$images = $this->finder->find_dice_images($this->get_dice_skins_dir(), $skin, $this->get_image_extensions());
|
||||
|
||||
foreach ($sides as $side)
|
||||
{
|
||||
for ($i = 1; $i <= $side; $i++)
|
||||
{
|
||||
$image_name = $this->get_dice_image_notation($side, $i);
|
||||
|
||||
$valid = !in_array($image_name, $images) ? false : $valid;
|
||||
}
|
||||
}
|
||||
|
||||
return (bool) $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dice skin image notation.
|
||||
*
|
||||
* @param int $sides The dice sides
|
||||
* @param int $roll The dice roll outcome
|
||||
* @param string $ext The dice skin image extension
|
||||
* @return string The dice skin image notation
|
||||
* @access public
|
||||
*/
|
||||
public function get_dice_image_notation($sides, $roll, $ext = '')
|
||||
{
|
||||
return 'd' . (int) $sides . '_' . (int) $roll . ($ext ? '.' . $ext : '');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the allowed image extensions.
|
||||
*
|
||||
* @return array Array of allowed image extensions
|
||||
* @access public
|
||||
*/
|
||||
public function get_image_extensions()
|
||||
{
|
||||
return (array) $this->image_extensions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Excerpts the images extension within a folder previously checked.
|
||||
*
|
||||
* @param string $skin The skin's folder name
|
||||
* @return string The images extension
|
||||
* @access public
|
||||
*/
|
||||
public function find_image_extension($skin)
|
||||
{
|
||||
/**
|
||||
* Find all the files in the skin directory that start with
|
||||
* a "d", as dice image file names are: d0_0.ext
|
||||
*/
|
||||
$files = glob($this->get_dice_skins_dir() . $skin . '/d*.*');
|
||||
|
||||
if ($files)
|
||||
{
|
||||
$extension = false;
|
||||
$count = count($files);
|
||||
|
||||
// Loop over the files found
|
||||
for ($i = 0; $i < $count; $i++)
|
||||
{
|
||||
// Get the extension for this file
|
||||
$extension = pathinfo($files[$i], PATHINFO_EXTENSION);
|
||||
|
||||
// If the extension is an allowed image extension, break out the for loop.
|
||||
if (in_array($extension, $this->image_extensions))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $extension;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dice skin data for display.
|
||||
*
|
||||
* @param bool $override Whether or not the user's choice should be overridden
|
||||
* @param string $forum_skin The dice skin set in the Forum Settings
|
||||
* @return array Array with the dice skin data
|
||||
* @access public
|
||||
*/
|
||||
public function get_dice_skin_data($override, $forum_skin)
|
||||
{
|
||||
// Get all 'installed' dice skins
|
||||
$skins = $this->get_dice_skins(true);
|
||||
|
||||
// Get the user defined style, if not overridden by the forum settings
|
||||
$skin = ($this->auth->acl_get('u_dice_skin') || !$override) ? $this->user->data['dice_u_skin'] : $forum_skin;
|
||||
|
||||
// Make sure the user defined style is in the 'installed' dice skins
|
||||
$skin = in_array($skin, $skins) ? $skin : 'text';
|
||||
|
||||
// Get the image extension for this dice skin
|
||||
$ext = $skin !== 'text' ? $this->find_image_extension($skin) : '';
|
||||
|
||||
return (array) [
|
||||
'name' => $skin,
|
||||
'dir' => $this->get_dice_skins_dir(),
|
||||
'ext' => $ext,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean an array, used for the installed dice skins and dice sides.
|
||||
*
|
||||
* @param array $array The array to clean
|
||||
* @return array A cleaned array
|
||||
* @access public
|
||||
*/
|
||||
public function clean_dice_array(array $array)
|
||||
{
|
||||
// No empty values
|
||||
$array = array_filter($array);
|
||||
|
||||
// No duplicate values
|
||||
$array = array_unique($array);
|
||||
|
||||
// Sort ascending
|
||||
sort($array);
|
||||
|
||||
return (array) $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an options string for a HTML <select> field.
|
||||
*
|
||||
* @param array $array The array to build the options from
|
||||
* @param mixed $select The option that should be selected
|
||||
* @param bool $no_keys Whether or not to use the array keys as <option value="">
|
||||
* @return string An string of all options for a select field
|
||||
*/
|
||||
public function build_dice_select(array $array, $select, $no_keys)
|
||||
{
|
||||
$options = '';
|
||||
|
||||
foreach ($array as $key => $option)
|
||||
{
|
||||
$value = $no_keys ? $option : $key;
|
||||
$selected = $select == $value ? '" selected="selected' : '';
|
||||
|
||||
$options .= '<option value="' . $value . $selected .'">' . $option . '</option>';
|
||||
}
|
||||
|
||||
return (string) $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* The dice link locations and their BIT values
|
||||
*
|
||||
* @return array
|
||||
* @access protected
|
||||
*/
|
||||
protected function dice_link_locations()
|
||||
{
|
||||
return [
|
||||
1 => 'navbar_header_quick_links_before',
|
||||
2 => 'navbar_header_quick_links_after',
|
||||
4 => 'overall_header_navigation_prepend',
|
||||
8 => 'overall_header_navigation_append',
|
||||
16 => 'navbar_header_user_profile_append',
|
||||
32 => 'overall_footer_breadcrumb_append',
|
||||
64 => 'overall_footer_timezone_before',
|
||||
128 => 'overall_footer_timezone_after',
|
||||
256 => 'overall_footer_teamlink_before',
|
||||
512 => 'overall_footer_teamlink_after',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dice link locations and their status.
|
||||
*
|
||||
* @return array Array with the link locations and their status
|
||||
* @access public
|
||||
*/
|
||||
public function get_dice_link_locations()
|
||||
{
|
||||
$links = [];
|
||||
$flags = $this->config['dice_link_locations'];
|
||||
$locations = $this->dice_link_locations();
|
||||
|
||||
foreach($locations as $flag => $location)
|
||||
{
|
||||
$links[] = [
|
||||
'name' => $location,
|
||||
'status' => ($flags & $flag) ? true : false,
|
||||
];
|
||||
}
|
||||
|
||||
return $links;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set dice link locations and their status.
|
||||
*
|
||||
* @param array $links Array with the link locations and their status
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function set_dice_link_locations(array $links)
|
||||
{
|
||||
$flags = 0;
|
||||
$locations = $this->dice_link_locations();
|
||||
$flipped = array_flip($locations);
|
||||
|
||||
foreach ($links as $link => $status)
|
||||
{
|
||||
$flags += ($status) ? $flipped[$link] : 0;
|
||||
}
|
||||
|
||||
$this->config->set('dice_link_locations', (int) $flags);
|
||||
}
|
||||
}
|
||||
73
ext/phpbbstudio/dice/core/functions_finder.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\core;
|
||||
|
||||
use \Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Finder functions.
|
||||
*/
|
||||
class functions_finder
|
||||
{
|
||||
/**
|
||||
* Find available dice skins in the given directory.
|
||||
*
|
||||
* @param string $directory The dice skins directory
|
||||
* @return array Array of available dice skins
|
||||
* @access public
|
||||
*/
|
||||
public function find_dice_skins($directory)
|
||||
{
|
||||
$skins = [];
|
||||
|
||||
$finder = new Finder;
|
||||
$finder->ignoreUnreadableDirs()
|
||||
->in($directory)
|
||||
->directories()
|
||||
->depth('== 0');
|
||||
|
||||
foreach($finder as $dir)
|
||||
{
|
||||
$skin = $dir->getBasename();
|
||||
|
||||
$skins[] = $skin;
|
||||
}
|
||||
|
||||
return (array) $skins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find available dice skin images for a given dice skin.
|
||||
*
|
||||
* @param string $directory The dice skins directory
|
||||
* @param string $skin The dice skin
|
||||
* @param array $exts Array of allowed image extensions
|
||||
* @return array Array of available dice skin images
|
||||
* @access public
|
||||
*/
|
||||
public function find_dice_images($directory, $skin, array $exts)
|
||||
{
|
||||
$images = [];
|
||||
|
||||
$finder = new Finder;
|
||||
$finder->in($directory . $skin)
|
||||
->files()
|
||||
->depth('== 0');
|
||||
|
||||
foreach ($finder as $image)
|
||||
{
|
||||
if (in_array($image->getExtension(), $exts))
|
||||
{
|
||||
$images[] = $image->getBasename('.' . $image->getExtension());
|
||||
}
|
||||
}
|
||||
|
||||
return (array) $images;
|
||||
}
|
||||
}
|
||||
136
ext/phpbbstudio/dice/core/functions_regex.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\core;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Regex functions.
|
||||
*/
|
||||
class functions_regex
|
||||
{
|
||||
/**
|
||||
* Matches a basic arithmetic operator.
|
||||
*
|
||||
* @param string
|
||||
* @access protected
|
||||
*/
|
||||
protected $arithmetic_operator = '[+\\-*\\/]';
|
||||
|
||||
/**
|
||||
* Matches a basic comparison operator.
|
||||
*
|
||||
* @param string
|
||||
* @access protected
|
||||
*/
|
||||
protected $comparison_operators = '[<>!]?={1,3}|[<>]';
|
||||
|
||||
/**
|
||||
* Matches exploding/penetrating dice notation.
|
||||
*
|
||||
* @param string
|
||||
* @access protected
|
||||
*/
|
||||
protected $explode = '(!{1,2}p?)';
|
||||
|
||||
/**
|
||||
* Matches a number comparison (ie. <=4, =5, >3, !=1).
|
||||
*
|
||||
* @return string
|
||||
* @access protected
|
||||
*/
|
||||
protected function number_comparison()
|
||||
{
|
||||
return '(' . $this->comparison_operators . ')([0-9]+)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the numbers for a 'fudge' die (ie. F, F.2).
|
||||
*
|
||||
* @return string
|
||||
* @access protected
|
||||
*/
|
||||
protected function fudge()
|
||||
{
|
||||
return 'F(?:\\.([12]))?';
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches a dice (ie. 2d6, d10, d%, dF, dF.2).
|
||||
*
|
||||
* @return string
|
||||
* @access protected
|
||||
*/
|
||||
protected function dice()
|
||||
{
|
||||
return '([1-9][0-9]*)?d([1-9][0-9]*|%|' . $this->fudge() . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches a dice, optional exploding/penetrating notation and roll comparison.
|
||||
*
|
||||
* @return string
|
||||
* @access protected
|
||||
*/
|
||||
protected function dice_full()
|
||||
{
|
||||
return $this->dice() . $this->explode . '?(?:' . $this->number_comparison() . ')?';
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the addition to a dice (ie. +4, -10, *2, -L).
|
||||
*
|
||||
* @return string
|
||||
* @access protected
|
||||
*/
|
||||
protected function addition()
|
||||
{
|
||||
return '(' . $this->arithmetic_operator . ')([1-9]+0?(?![0-9]*d)|H|L)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches a standard dice notation. i.e;
|
||||
* 3d10-2
|
||||
* 4d20-L
|
||||
* 2d7/4
|
||||
* 3d8*2
|
||||
* 2d3+4-1
|
||||
* 2d10-H*1d6/2
|
||||
*
|
||||
* @return string
|
||||
* @access protected
|
||||
*/
|
||||
protected function notation()
|
||||
{
|
||||
return '('. $this->arithmetic_operator . ')?' . $this->dice_full() . '((?:' . $this->addition() . ')*)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a regex from this class.
|
||||
*
|
||||
* @param string $name The regex name from this class
|
||||
* @param bool $match_whole If it should match the whole string
|
||||
* @return string A regular expression
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\unexpected_value
|
||||
*/
|
||||
public function get($name, $match_whole = false)
|
||||
{
|
||||
if (empty($name))
|
||||
{
|
||||
throw new \phpbbstudio\dice\exception\unexpected_value(['ROLL_REGEX_NAME', 'FIELD_MISSING']);
|
||||
}
|
||||
else if ((gettype($name) !== 'string') || !method_exists($this, $name))
|
||||
{
|
||||
throw new \phpbbstudio\dice\exception\unexpected_value(['ROLL_REGEX_NAME', 'ROLL_NAME_NOT_FOUND']);
|
||||
}
|
||||
|
||||
$pattern = $this->{$name}();
|
||||
|
||||
return '/' . ($match_whole ? '^' : '') . $pattern . ($match_whole ? '$' : '') . '/';
|
||||
}
|
||||
}
|
||||
228
ext/phpbbstudio/dice/core/functions_utils.php
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\core;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Roll utility functions.
|
||||
*/
|
||||
class functions_utils
|
||||
{
|
||||
/**
|
||||
* Checks if the given value is a valid number.
|
||||
*
|
||||
* @param mixed $value The value to check
|
||||
* @return bool Whether it is a valid number or not
|
||||
* @access public
|
||||
*/
|
||||
public function is_numeric($value)
|
||||
{
|
||||
return (bool) (!is_array($value) && is_numeric($value) && is_finite(intval($value)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random number between the min and the max (inclusive).
|
||||
*
|
||||
* @param int $min The minimum number to be generated
|
||||
* @param int $max The maximum number to be generated
|
||||
* @return int The generated number
|
||||
* @access public
|
||||
*/
|
||||
public function generate_number($min, $max)
|
||||
{
|
||||
$min = $min ? intval($min) : 1;
|
||||
$max = $max ? intval($max) : $min;
|
||||
|
||||
if ($max <= $min)
|
||||
{
|
||||
return (int) $min;
|
||||
}
|
||||
|
||||
return (int) floor((mt_rand() / mt_getrandmax()) * ($max - $min + 1) + $min);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rolls a standard dice, callback method.
|
||||
*
|
||||
* @param int $sides The amount of sides for the dice
|
||||
* @return int The outcome of the roll
|
||||
* @access public
|
||||
*/
|
||||
public function default_dice($sides)
|
||||
{
|
||||
return (int) $this->generate_number(1, $sides);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rolls a fudge dice, callback method.
|
||||
*
|
||||
* @param mixed $non_blanks
|
||||
* @return int The outcome of the roll
|
||||
* @access public
|
||||
*/
|
||||
public function fudge_dice($non_blanks)
|
||||
{
|
||||
$non_blanks = (int) $non_blanks;
|
||||
$total = 0;
|
||||
|
||||
if ($non_blanks === 2)
|
||||
{
|
||||
// default fudge (2 of each non-blank) = 1d3 - 2
|
||||
$total = $this->generate_number(1, 3) - 2;
|
||||
}
|
||||
else if ($non_blanks === 1)
|
||||
{
|
||||
// only 1 of each non-blank
|
||||
// on 1d6 a roll of 1 = -1, 6 = +1, others = 0
|
||||
$num = $this->generate_number(1, 6);
|
||||
|
||||
if ($num === 1)
|
||||
{
|
||||
$total = -1;
|
||||
}
|
||||
else if ($num === 6)
|
||||
{
|
||||
$total = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (int) $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the value matches the given compare point
|
||||
* and returns the corresponding success / failure state value
|
||||
* success = 1, fail = 0
|
||||
*
|
||||
* @param int $value The value to compare against
|
||||
* @param array $compare_point Array holding a value and an operator
|
||||
* @return int Success/failure state value
|
||||
* @access public
|
||||
*/
|
||||
public function get_success_state_value($value, array $compare_point)
|
||||
{
|
||||
return $this->is_compare_point($compare_point, $value) ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether value matches the given compare point.
|
||||
*
|
||||
* @param array $compare_point Array holding a value and an operator
|
||||
* @param int $value The value to compare against
|
||||
* @return bool Success/failure state
|
||||
* @access public
|
||||
*/
|
||||
public function is_compare_point(array $compare_point, $value)
|
||||
{
|
||||
return (bool) (!empty($compare_point) ? $this->compare_numbers($value, $compare_point['value'], $compare_point['operator']) : false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes two numbers and runs a mathematical equation on them, using the given operator.
|
||||
*
|
||||
* @param int $a The first number: initial number
|
||||
* @param int $b The second number: number to be added, subtracted, multiplied by, divided by
|
||||
* @param string $operator The valid arithmetic operator (+, -, /, *) to use
|
||||
* @return int The outcome of the equation
|
||||
* @access public
|
||||
*/
|
||||
public function equate_numbers($a, $b, $operator)
|
||||
{
|
||||
// Ensure values are numeric
|
||||
$a = $this->is_numeric($a) ? $a : 0;
|
||||
$b = $this->is_numeric($b) ? $b : 0;
|
||||
|
||||
switch ($operator)
|
||||
{
|
||||
case '*':
|
||||
// Multiple the value
|
||||
$a *= $b;
|
||||
break;
|
||||
|
||||
case '/':
|
||||
// Divide the value (handle division by zero)
|
||||
$a = !empty($b) ? $a / $b : 0;
|
||||
break;
|
||||
|
||||
case '-':
|
||||
// subtract from value
|
||||
$a -= $b;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Add to the value
|
||||
$a += $b;
|
||||
break;
|
||||
}
|
||||
|
||||
return $a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if `a` is comparative to `b` with the given operator.
|
||||
*
|
||||
* @param int $a The first number
|
||||
* @param int $b The second number
|
||||
* @param string $operator The valid comparative operator (=, <, >, <=, >=, !=) to use
|
||||
* @return bool Outcome of the comparison
|
||||
* @access public
|
||||
*/
|
||||
public function compare_numbers($a, $b, $operator)
|
||||
{
|
||||
|
||||
switch ($operator)
|
||||
{
|
||||
case '=':
|
||||
case '==':
|
||||
$result = $a === $b;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
$result = $a < $b;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
$result = $a > $b;
|
||||
break;
|
||||
|
||||
case '<=':
|
||||
$result = $a <= $b;
|
||||
break;
|
||||
|
||||
case '>=':
|
||||
$result = $a >= $b;
|
||||
break;
|
||||
|
||||
case '!':
|
||||
case '!=':
|
||||
$result = $a !== $b;
|
||||
break;
|
||||
|
||||
default:
|
||||
$result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return (bool) $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes an array of numbers and adds them together, returning the result.
|
||||
*
|
||||
* @param array $numbers Arrays of numbers to be added to each other
|
||||
* @return int The outcome of the additions
|
||||
* @access public
|
||||
*/
|
||||
public function sum_array($numbers)
|
||||
{
|
||||
return !is_array($numbers) ? 0 : array_reduce($numbers, function($prev, $current)
|
||||
{
|
||||
return $prev + ($this->is_numeric($current) ? intval($current) : 0);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
4
ext/phpbbstudio/dice/docs/.htaccess
Normal file
@@ -0,0 +1,4 @@
|
||||
<Files *>
|
||||
Order Allow,Deny
|
||||
Deny from All
|
||||
</Files>
|
||||
35
ext/phpbbstudio/dice/docs/CHANGELOG.md
Normal file
@@ -0,0 +1,35 @@
|
||||
v2.1.2
|
||||
- FIX Faulty regex returning null instead of the actual message.
|
||||
- FIX Rolls' TAB not showing up on regular user accounts upon installation.
|
||||
-
|
||||
- The following to prevent cheats:
|
||||
- ENHANCEMENT - User should not have permission to delete or modify existing rolls as default.
|
||||
-
|
||||
- The followings to keep consistency with the core code:
|
||||
- ENHANCEMENT - Posts containing rolls can be safely soft-deleted and restored.
|
||||
- ENHANCEMENT - Deleting rolls doesn't affect quoted ones.
|
||||
- ENHANCEMENT - Editing rolls doesn't affect quoted ones.
|
||||
- ENHANCEMENT - Deleting forum content doesn't affect rolls quoted elsewhere, ie.: other forums.
|
||||
- ENHANCEMENT - Deleting topics doesn't affect rolls quoted elsewhere, ie.: other topics.
|
||||
-
|
||||
- Code housekeeping
|
||||
|
||||
v2.1.1
|
||||
- Hardened user input about skins directory
|
||||
- Provided related meaningful error report
|
||||
- Code housekeeping
|
||||
|
||||
v2.1.0
|
||||
- Change skins' dir to {phpbb_root}images/dice/
|
||||
- Add migration to mirror the skins in the new images path
|
||||
- Remove a configuration (dice version)
|
||||
- Added Spanish formal
|
||||
- Code housekeeping
|
||||
|
||||
v2.0.1
|
||||
- FIX Quoted rolls aren't always rendered.
|
||||
- Adjust migration
|
||||
- Code housekeeping
|
||||
|
||||
v2.0.0-beta
|
||||
- first public release
|
||||
25
ext/phpbbstudio/dice/docs/CREDITS.txt
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Dice extension © Copyright phpBB Studio 2019
|
||||
* https://www.phpbbstudio.com
|
||||
*
|
||||
* Dice is free extension for the phpBB Forum Software Package.
|
||||
* You can redistribute it and/or modify it under the terms of
|
||||
* the GNU General Public License, version 2 (GPL-2.0) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This extension is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* A copy of the license can be viewed in the license.txt file.
|
||||
* The same can be viewed at <http://opensource.org/licenses/gpl-2.0.php>
|
||||
*/
|
||||
|
||||
The Dice extension contains code (we ported to PHP) from the following applications:
|
||||
|
||||
rpg-dice-roller
|
||||
- GreenImp
|
||||
- https://github.com/GreenImp/rpg-dice-roller
|
||||
- Copyright © 2015 - 2018 GreenImp ltd.
|
||||
- MIT License <https://opensource.org/licenses/mit>
|
||||
19
ext/phpbbstudio/dice/docs/EVENTS.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Dice extension © Copyright phpBB Studio 2019
|
||||
* https://www.phpbbstudio.com
|
||||
*
|
||||
* Dice is free extension for the phpBB Forum Software Package.
|
||||
* You can redistribute it and/or modify it under the terms of
|
||||
* the GNU General Public License, version 2 (GPL-2.0) as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This extension is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* A copy of the license can be viewed in the license.txt file.
|
||||
* The same can be viewed at <http://opensource.org/licenses/gpl-2.0.php>
|
||||
*/
|
||||
|
||||
No events required while using at least 3.2.7 of phpBB
|
||||
10
ext/phpbbstudio/dice/docs/FEATURES.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# phpBB Studio - Dice
|
||||
|
||||
Are you a :scroll: RPG enthousiast? A role playing master :prince:?
|
||||
Then we've got just the rolls for you!
|
||||
We have created a comprehensive dice roller extension that is flawlessly integrated into phpBB's native system.
|
||||
Your users can throw dice within your forums and let the story continue in new directions.
|
||||
All this while you as an Administrator are in control.
|
||||
We have taken all precautions to make sure users can not manipulate their dice rolls into the desired outcome.
|
||||
A custom PHP class was created to make sure all calculations are done “behind the scenes”.
|
||||
And an additional way to gain more control over the individual rolls is done by mimicing the native attachment system.
|
||||
11
ext/phpbbstudio/dice/docs/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# phpBB Studio - Dice
|
||||
|
||||
## Installation
|
||||
|
||||
Copy the extension to phpBB/ext/phpbbstudio/dice
|
||||
|
||||
Go to "ACP" > "Customise" > "Extensions" and enable the "phpBB Studio - Dice" extension.
|
||||
|
||||
## License
|
||||
|
||||
GPL-2.0-only (license.txt)
|
||||
15
ext/phpbbstudio/dice/docs/index.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<!--suppress HtmlDeprecatedAttribute -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="Author" content="phpbbstudio.com">
|
||||
<meta name="Keywords" content="extension for phpBB">
|
||||
<meta name="Description" content="Dice">
|
||||
<title></title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
1213
ext/phpbbstudio/dice/entity/roll.php
Normal file
394
ext/phpbbstudio/dice/entity/roll_interface.php
Normal file
@@ -0,0 +1,394 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\entity;
|
||||
|
||||
/**
|
||||
* Interface for a roll.
|
||||
*
|
||||
* This describes all of the methods we'll have for a single roll.
|
||||
*
|
||||
* The basic usage of a roll entity should look like one of three ways:
|
||||
* 1. Creation
|
||||
* -> set_notation() Set the notation, will also set_dices()
|
||||
* -> roll() Roll the dices from the notation, will also set_rolls(), set_total(), set_output()
|
||||
* -> insert() Inserts the roll data in the database [roll SHOULD NOT exist yet]
|
||||
*
|
||||
* 2. Modification
|
||||
* -> load() Load the roll data from the database
|
||||
* -> set_...() Use a set_...() [setter] to set the roll's data
|
||||
* -> save() Update the roll data in the database [roll SHOULD exist already]
|
||||
*
|
||||
* 3. Display
|
||||
* -> import() Import the roll data, retrieved from the database elsewhere
|
||||
* -> get_...() Use a get_...() [getter] to get the roll's data
|
||||
*/
|
||||
interface roll_interface
|
||||
{
|
||||
/**
|
||||
* Load data for a roll.
|
||||
*
|
||||
* @param int $id Roll identifier
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function load($id);
|
||||
|
||||
/**
|
||||
* Import data for a roll.
|
||||
*
|
||||
* Used when the data is already loaded externally.
|
||||
* Any existing data on this roll is over-written.
|
||||
*
|
||||
* @param array $data Data for this roll
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
*/
|
||||
public function import(array $data);
|
||||
|
||||
/**
|
||||
* Insert the roll data for the first time.
|
||||
*
|
||||
* Will give an error if the roll was already inserted, call save() instead.
|
||||
*
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function insert();
|
||||
|
||||
/**
|
||||
* Save the roll data to the database
|
||||
*
|
||||
* This must be called before closing or any changes will not be saved!
|
||||
* If adding a roll (saving for the first time), you must call insert() or an error will be given.
|
||||
*
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function save();
|
||||
|
||||
/**
|
||||
* Roll the dice for the set notation.
|
||||
*
|
||||
* This will go over all the dice retrieved from this notation with get_dices()
|
||||
* @see roll_interface::get_dices()
|
||||
* It will then create all the rolls for those dices and set them through set_rolls()
|
||||
* @see roll_interface::set_rolls()
|
||||
* After all the rolls have been calculated, the total of all rolls can be set in set_total()
|
||||
* @see roll_interface::set_total()
|
||||
* And to finish it all off, we can create the output string in set_output()
|
||||
* @see roll_interface::set_output()
|
||||
*
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\unexpected_value
|
||||
*/
|
||||
public function roll();
|
||||
|
||||
/**
|
||||
* Get the roll identifier.
|
||||
*
|
||||
* @return int Roll identifier
|
||||
* @access public
|
||||
*/
|
||||
public function get_id();
|
||||
|
||||
/**
|
||||
* Get the forum identifier.
|
||||
*
|
||||
* @return int Forum identifier
|
||||
* @access public
|
||||
*/
|
||||
public function get_forum();
|
||||
|
||||
/**
|
||||
* Set the forum identifier.
|
||||
*
|
||||
* @param int $id Forum identifier
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function set_forum($id);
|
||||
|
||||
/**
|
||||
* Get the topic identifier.
|
||||
*
|
||||
* @return int Topic identifier
|
||||
* @access public
|
||||
*/
|
||||
public function get_topic();
|
||||
|
||||
/**
|
||||
* Set the topic identifier.
|
||||
*
|
||||
* @param int $id Topic identifier
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function set_topic($id);
|
||||
|
||||
/**
|
||||
* Get the post identifier.
|
||||
*
|
||||
* @return int Post identifier
|
||||
* @access public
|
||||
*/
|
||||
public function get_post();
|
||||
|
||||
/**
|
||||
* Set the post identifier.
|
||||
*
|
||||
* @param int $id Post identifier
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function set_post($id);
|
||||
|
||||
/**
|
||||
* Get the user identifier.
|
||||
*
|
||||
* @return int User identifier
|
||||
* @access public
|
||||
*/
|
||||
public function get_user();
|
||||
|
||||
/**
|
||||
* Set the user identifier.
|
||||
*
|
||||
* @param int $id User identifier
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\base
|
||||
*/
|
||||
public function set_user($id);
|
||||
|
||||
/**
|
||||
* Get the roll notation.
|
||||
*
|
||||
* @return string Roll notation
|
||||
* @access public
|
||||
*/
|
||||
public function get_notation();
|
||||
|
||||
/**
|
||||
* Set the roll notation.
|
||||
*
|
||||
* This will also call set_dices(), which retrieves all different dices from the notation
|
||||
* @see roll_interface::set_dices()
|
||||
*
|
||||
* @param string $notation Roll notation
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\unexpected_value
|
||||
*/
|
||||
public function set_notation($notation);
|
||||
|
||||
/**
|
||||
* Get the dices from the roll notation.
|
||||
*
|
||||
* @return array Dices from the roll notation
|
||||
* @access public
|
||||
*/
|
||||
public function get_dices();
|
||||
|
||||
/**
|
||||
* Set the dices from the roll notation.
|
||||
*
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\unexpected_value
|
||||
*/
|
||||
public function set_dices();
|
||||
|
||||
/**
|
||||
* Get the rolls from the dice.
|
||||
*
|
||||
* @return array Rolls from the dices
|
||||
* @access public
|
||||
*/
|
||||
public function get_rolls();
|
||||
|
||||
/**
|
||||
* Set the rolls from the dice.
|
||||
*
|
||||
* @param array $rolls Rolls from the dices
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
*/
|
||||
public function set_rolls(array $rolls);
|
||||
|
||||
/**
|
||||
* Get the roll data for display.
|
||||
*
|
||||
* @param string $skin The dice skin to use
|
||||
* @param string $dir The dice skin directory
|
||||
* @param string $ext The dice skin image extension
|
||||
* @return array Roll data array to be used for display
|
||||
* @access public
|
||||
*/
|
||||
public function get_display($skin, $dir, $ext = '');
|
||||
|
||||
/**
|
||||
* Get the roll output.
|
||||
*
|
||||
* @return string Roll output
|
||||
* @access public
|
||||
*/
|
||||
public function get_output();
|
||||
|
||||
/**
|
||||
* Set the roll output.
|
||||
*
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
*/
|
||||
public function set_output();
|
||||
|
||||
/**
|
||||
* Get the total for the roll notation.
|
||||
*
|
||||
* @return int Total for the roll notation
|
||||
* @access public
|
||||
*/
|
||||
public function get_total();
|
||||
|
||||
/**
|
||||
* Set the total for the roll notation.
|
||||
*
|
||||
* This will also call set_successes() for the pool dice that met their condition
|
||||
* and set_is_pool() to indicate that the notation contains pool dice
|
||||
* @see roll_interface::set_successes()
|
||||
* @see roll_interface::set_is_pool()
|
||||
*
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function set_total();
|
||||
|
||||
/**
|
||||
* Set the successes for the rolls.
|
||||
*
|
||||
* @return int Successes for the rolls.
|
||||
* @access public
|
||||
*/
|
||||
public function get_successes();
|
||||
|
||||
/**
|
||||
* Set the successes for the rolls.
|
||||
*
|
||||
* @param $successes $successes Successes for the rolls.
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function set_successes($successes);
|
||||
|
||||
/**
|
||||
* Get the is_pool status for the notation.
|
||||
*
|
||||
* @return bool Whether or not this notation has a dice pool
|
||||
* @access public
|
||||
*/
|
||||
public function get_is_pool();
|
||||
|
||||
/**
|
||||
* Set the is_pool status for the notation
|
||||
*
|
||||
* @param bool $is_pool Whether or not this notation has a dice pool
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
*/
|
||||
public function set_is_pool($is_pool);
|
||||
|
||||
/**
|
||||
* Get the roll time.
|
||||
*
|
||||
* @return int Roll time (UNIX timestamp)
|
||||
* @access public
|
||||
*/
|
||||
public function get_time();
|
||||
|
||||
/**
|
||||
* Set the roll time.
|
||||
*
|
||||
* @param int $time Roll time (UNIX timestamp)
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function set_time($time);
|
||||
|
||||
/**
|
||||
* Get the user identifier for the last edit.
|
||||
*
|
||||
* @return int User identifier
|
||||
* @access public
|
||||
*/
|
||||
public function get_edit_user();
|
||||
|
||||
/**
|
||||
* Set the user identifier for the last edit.
|
||||
*
|
||||
* @param int $id User identifier
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function set_edit_user($id);
|
||||
|
||||
/**
|
||||
* Get the roll edit time.
|
||||
*
|
||||
* @return int Roll edit time (UNIX timestamp)
|
||||
* @access public
|
||||
*/
|
||||
public function get_edit_time();
|
||||
|
||||
/**
|
||||
* Set the roll edit time.
|
||||
*
|
||||
* @param int $time Roll edit time (UNIX timestamp)
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function set_edit_time($time);
|
||||
|
||||
/**
|
||||
* Get the roll edit count.
|
||||
*
|
||||
* @return int Roll edit count
|
||||
* @access public
|
||||
*/
|
||||
public function get_edit_count();
|
||||
|
||||
/**
|
||||
* Set the roll edit count.
|
||||
*
|
||||
* @param int $count Roll edit count
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function set_edit_count($count);
|
||||
|
||||
/**
|
||||
* Increment the roll edit count by one.
|
||||
*
|
||||
* @return roll_interface $this This object for chaining calls
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function increment_edit_count();
|
||||
}
|
||||
288
ext/phpbbstudio/dice/event/acp_listener.php
Normal file
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice ACP listener.
|
||||
*/
|
||||
class acp_listener implements EventSubscriberInterface
|
||||
{
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbbstudio\dice\core\functions_common */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbb\request\request */
|
||||
protected $request;
|
||||
|
||||
/** @var string Dice rolls table */
|
||||
protected $rolls_table;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\db\driver\driver_interface $db Database object
|
||||
* @param \phpbbstudio\dice\core\functions_common $functions Dice common functions
|
||||
* @param \phpbb\request\request $request Request object
|
||||
* @param string $rolls_table Dice rolls table
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\db\driver\driver_interface $db,
|
||||
\phpbbstudio\dice\core\functions_common $functions,
|
||||
\phpbb\request\request $request,
|
||||
$rolls_table
|
||||
)
|
||||
{
|
||||
$this->db = $db;
|
||||
$this->functions = $functions;
|
||||
$this->request = $request;
|
||||
$this->rolls_table = $rolls_table;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign functions defined in this class to event listeners in the core.
|
||||
*
|
||||
* @static
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
static public function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
'core.delete_user_after' => 'dice_delete_user_after',
|
||||
|
||||
// excluded in order to be able to soft delete posts and rolls and keep rolls quoted elsewhere
|
||||
//'core.delete_post_after' => 'dice_delete_post_after',
|
||||
|
||||
'core.move_posts_after' => 'dice_move_posts_after',
|
||||
|
||||
// excluded in order to be able to keep rolls quoted elsewhere
|
||||
//'core.delete_topics_before_query' => 'dice_add_rolls_table',
|
||||
|
||||
'core.move_topics_before_query' => 'dice_add_rolls_table',
|
||||
|
||||
// excluded in order to be able to keep rolls quoted elsewhere
|
||||
//'core.delete_forum_content_before_query' => 'dice_add_rolls_table',
|
||||
|
||||
// excluded in order to be able to keep rolls quoted elsewhere
|
||||
//'core.delete_posts_in_transaction_before' => 'dice_add_rolls_table',
|
||||
|
||||
'core.acp_manage_forums_move_content_sql_before' => 'dice_add_rolls_table',
|
||||
'core.mcp_main_fork_sql_after' => 'dice_mcp_main_fork_sql_after',
|
||||
'core.acp_manage_forums_request_data' => 'dice_acp_manage_forums_request_data',
|
||||
'core.acp_manage_forums_initialise_data' => 'dice_acp_manage_forums_initialise_data',
|
||||
'core.acp_manage_forums_display_form' => 'dice_acp_manage_forums_display_form',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform actions directly after a user has been deleted
|
||||
* and "delete their posts" or "retain their posts" has been selected.
|
||||
*
|
||||
* @event core.delete_post_after
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_delete_user_after($event)
|
||||
{
|
||||
$user_ids = $event['user_ids'];
|
||||
|
||||
if (!empty($user_ids))
|
||||
{
|
||||
if ($event['mode'] === 'remove' || $event['mode'] === 'retain')
|
||||
{
|
||||
/* Change user_id to anonymous for rolls by this user */
|
||||
$sql = 'UPDATE ' . $this->rolls_table . '
|
||||
SET user_id = ' . ANONYMOUS . '
|
||||
WHERE ' . $this->db->sql_in_set('user_id', $user_ids);
|
||||
$this->db->sql_query($sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performing actions directly after a post or topic has been deleted.
|
||||
* On hitting the X button of a post in view topic.
|
||||
*
|
||||
* @event core.delete_post_after
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_delete_post_after($event)
|
||||
{
|
||||
$sql = 'DELETE FROM ' . $this->rolls_table . ' WHERE post_id = ' . (int) $event['post_id'];
|
||||
$this->db->sql_query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform actions after the posts have been moved
|
||||
*
|
||||
* @event core.move_posts_after
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_move_posts_after($event)
|
||||
{
|
||||
$forum_row = $event['forum_row'];
|
||||
$post_ids = $event['post_ids'];
|
||||
$topic_id = $event['topic_id'];
|
||||
|
||||
$sql = 'UPDATE ' . $this->rolls_table . '
|
||||
SET forum_id = ' . (int) $forum_row['forum_id'] . ",
|
||||
topic_id = " . (int) $topic_id . "
|
||||
WHERE " . $this->db->sql_in_set('post_id', $post_ids);
|
||||
$this->db->sql_query($sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared function which adds our rolls table to an array of tables.
|
||||
*
|
||||
* @event core.delete_topics_before_query On delete a topic MCP/Quicktools
|
||||
* @event core.move_topics_before_query On move a topic MCP/Quicktools moves the rolls too
|
||||
* @event core.delete_forum_content_before_query On delete a forum in ACP
|
||||
* @event core.acp_manage_forums_move_content_sql_before On move content of a forum in ACP
|
||||
* @event core.delete_posts_in_transaction_before On delete posts in MCP
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_add_rolls_table($event)
|
||||
{
|
||||
$table_ary = $event['table_ary'];
|
||||
$table_ary[] = $this->rolls_table;
|
||||
$event['table_ary'] = $table_ary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forks the topics (rolls) accordingly to the native functionality
|
||||
*
|
||||
* @event core.mcp_main_fork_sql_after
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_mcp_main_fork_sql_after($event)
|
||||
{
|
||||
$topic_id = $event['row']['topic_id'];
|
||||
$post_id = $event['row']['post_id'];
|
||||
$new_topic_id = $event['new_topic_id'];
|
||||
$to_forum_id = $event['to_forum_id'];
|
||||
$new_post_id = $event['new_post_id'];
|
||||
|
||||
$sql = 'SELECT *
|
||||
FROM ' . $this->rolls_table . '
|
||||
WHERE topic_id = ' . (int) $topic_id . '
|
||||
AND post_id = ' . (int) $post_id . '
|
||||
ORDER BY roll_id ASC';
|
||||
$result = $this->db->sql_query($sql);
|
||||
|
||||
$sql_ary = [];
|
||||
|
||||
while ($rolls = $this->db->sql_fetchrow($result))
|
||||
{
|
||||
$sql_ary[] = [
|
||||
'roll_id' => (int) $rolls['roll_id'],
|
||||
'roll_notation' => (string) $rolls['roll_notation'],
|
||||
'roll_dices' => (string) $rolls['roll_dices'],
|
||||
'roll_rolls' => (string) $rolls['roll_rolls'],
|
||||
'roll_output' => (string) $rolls['roll_output'],
|
||||
'roll_total' => (int) $rolls['roll_total'],
|
||||
'roll_successes' => (int) $rolls['roll_successes'],
|
||||
'roll_is_pool' => (int) $rolls['roll_is_pool'],
|
||||
'roll_time' => (int) $rolls['roll_time'],
|
||||
'roll_edit_user' => (int) $rolls['roll_edit_user'],
|
||||
'roll_edit_time' => (int) $rolls['roll_edit_time'],
|
||||
'roll_edit_count' => (int) $rolls['roll_edit_count'],
|
||||
'forum_id' => (int) $to_forum_id,
|
||||
'topic_id' => (int) $new_topic_id,
|
||||
'post_id' => (int) $new_post_id,
|
||||
'user_id' => (int) $rolls['user_id'],
|
||||
];
|
||||
}
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
if (!empty($sql_ary))
|
||||
{
|
||||
$this->db->sql_multi_insert($this->rolls_table, $sql_ary);
|
||||
}
|
||||
}
|
||||
|
||||
/* Here begins the ACP/Forums side of things */
|
||||
|
||||
/**
|
||||
* (Add/update actions) - Submit form.
|
||||
*
|
||||
* @event core.acp_manage_forums_request_data
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_acp_manage_forums_request_data($event)
|
||||
{
|
||||
$forum_data = $event['forum_data'];
|
||||
|
||||
$forum_data['dice_enabled'] = $this->request->variable('dice_enabled', 0);
|
||||
$forum_data['dice_f_skin'] = $this->request->variable('dice_f_skin', '', true);
|
||||
$forum_data['dice_skin_override'] = $this->request->variable('dice_skin_override', 0);
|
||||
|
||||
$event['forum_data'] = $forum_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* New Forums added (default disabled).
|
||||
*
|
||||
* @event core.acp_manage_forums_initialise_data
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_acp_manage_forums_initialise_data($event)
|
||||
{
|
||||
if ($event['action'] == 'add')
|
||||
{
|
||||
$forum_data = $event['forum_data'];
|
||||
|
||||
$forum_data['dice_enabled'] = false;
|
||||
$forum_data['dice_f_skin'] = '';
|
||||
$forum_data['dice_skin_override'] = false;
|
||||
|
||||
$event['forum_data'] = $forum_data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ACP forums (template data).
|
||||
*
|
||||
* @event core.acp_manage_forums_display_form
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_acp_manage_forums_display_form($event)
|
||||
{
|
||||
$template_data = $event['template_data'];
|
||||
|
||||
$skin = $event['forum_data']['dice_f_skin'];
|
||||
$skins = $this->functions->get_dice_skins(true);
|
||||
|
||||
$template_data['S_DICE_ENABLED'] = $event['forum_data']['dice_enabled'];
|
||||
$template_data['DICE_F_SKIN'] = $this->functions->build_dice_select($skins, $skin, true);
|
||||
$template_data['S_DICE_SKIN_OVERRIDE'] = $event['forum_data']['dice_skin_override'];
|
||||
|
||||
$event['template_data'] = $template_data;
|
||||
}
|
||||
}
|
||||
114
ext/phpbbstudio/dice/event/bbcode_listener.php
Normal file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice BBCode listener.
|
||||
*/
|
||||
class bbcode_listener implements EventSubscriberInterface
|
||||
{
|
||||
/** @var \phpbbstudio\dice\core\functions_common */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbb\request\request */
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbbstudio\dice\core\functions_common $functions Common functions
|
||||
* @param \phpbb\request\request $request Request object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbbstudio\dice\core\functions_common $functions,
|
||||
\phpbb\request\request $request
|
||||
)
|
||||
{
|
||||
$this->functions = $functions;
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign functions defined in this class to event listeners in the core.
|
||||
*
|
||||
* @static
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
static public function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
'core.text_formatter_s9e_configure_after' => 'set_dice_bbcode',
|
||||
'core.text_formatter_s9e_parse_before' => 'set_dice_availability',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the roll dice bbcode.
|
||||
*
|
||||
* @event core.text_formatter_s9e_configure_after
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function set_dice_bbcode($event)
|
||||
{
|
||||
/* Get the BBCode configurator */
|
||||
$configurator = $event['configurator'];
|
||||
|
||||
$configurator->attributeFilters->set('#dicenotation', __CLASS__ . '::dice_notation');
|
||||
|
||||
/* Let's unset any existing BBCode that might already exist */
|
||||
unset($configurator->BBCodes['roll']);
|
||||
unset($configurator->tags['roll']);
|
||||
|
||||
/* Let's create the new BBCode */
|
||||
$configurator->BBCodes->addCustom( '[roll={NUMBER}]{DICENOTATION}[/roll]', '<span class="phpbbstudio-dice" data-dice-id="{NUMBER}">{DICENOTATION}</span>');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the roll dice bbcode should be parsed in this forum.
|
||||
*
|
||||
* @event core.text_formatter_s9e_parse_before
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function set_dice_availability($event)
|
||||
{
|
||||
/** @var \phpbb\textformatter\s9e\parser $parser */
|
||||
$parser = $event['parser'];
|
||||
|
||||
$forum_id = (int) $this->request->variable('f', 0);
|
||||
|
||||
$dice_enabled = (bool) $this->functions->forum_enabled($forum_id);
|
||||
|
||||
($dice_enabled) ? $parser->enable_bbcode('roll') : $parser->disable_bbcode('roll');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the filter using within the roll dice bbcode.
|
||||
*
|
||||
* @param string $string The dice notation from within the bbcode
|
||||
* @return string $notation The correctly formatted dice notation
|
||||
* @access public
|
||||
*/
|
||||
public static function dice_notation($string)
|
||||
{
|
||||
$notation = str_replace(['D', 'f', 'h', 'l', 'P'], ['d', 'F', 'H', 'L', 'p'], $string);
|
||||
//$notation = preg_replace('[^0-9dFHLp\+\-\*/!\.%=<>\(\)]', '', $notation);
|
||||
$notation = preg_replace('([^0-9dFHLp\+\-\*/!\.%=<>\(\)])', '', $notation);
|
||||
|
||||
return $notation;
|
||||
}
|
||||
}
|
||||
624
ext/phpbbstudio/dice/event/display_listener.php
Normal file
@@ -0,0 +1,624 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Display listener.
|
||||
*/
|
||||
class display_listener implements EventSubscriberInterface
|
||||
{
|
||||
/** @var \phpbb\auth\auth */
|
||||
protected $auth;
|
||||
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbbstudio\dice\core\functions_common */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbbstudio\dice\operator\roll */
|
||||
protected $operator;
|
||||
|
||||
/** @var \phpbb\template\template */
|
||||
protected $template;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\auth\auth $auth Authentication object
|
||||
* @param \phpbb\config\config $config Configuration object
|
||||
* @param \phpbbstudio\dice\core\functions_common $functions Common functions
|
||||
* @param \phpbbstudio\dice\operator\roll $operator Roll operator object
|
||||
* @param \phpbb\template\template $template Template object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\auth\auth $auth,
|
||||
\phpbb\config\config $config,
|
||||
\phpbbstudio\dice\core\functions_common $functions,
|
||||
\phpbbstudio\dice\operator\roll $operator,
|
||||
\phpbb\template\template $template
|
||||
)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->config = $config;
|
||||
$this->functions = $functions;
|
||||
$this->operator = $operator;
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign functions defined in this class to event listeners in the core.
|
||||
*
|
||||
* @static
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
static public function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
'core.viewtopic_assign_template_vars_before' => 'set_dice_display',
|
||||
'core.viewtopic_modify_post_data' => 'get_dice_rolls',
|
||||
'core.viewtopic_modify_post_row' => 'display_dice_rolls',
|
||||
'core.topic_review_modify_post_list' => 'get_review_dice_rolls',
|
||||
'core.topic_review_modify_row' => 'display_review_dice_rolls',
|
||||
'core.mcp_topic_modify_post_data' => 'get_mcp_dice_rolls',
|
||||
'core.mcp_topic_review_modify_row' => 'display_mcp_dice_rolls',
|
||||
'core.mcp_post_template_data' => 'display_mcp_post_dice_rolls',
|
||||
'core.mcp_report_template_data' => 'display_mcp_report_dice_rolls',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign template variables used for displaying dice rolls.
|
||||
*
|
||||
* @event core.viewtopic_assign_template_vars_before
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function set_dice_display($event)
|
||||
{
|
||||
$forum_id = (int) $event['forum_id']; // Forum identifier
|
||||
$topic_data = (array) $event['topic_data']; // Array with topic data
|
||||
|
||||
$this->template->assign_vars([
|
||||
'DICE_IMG_HEIGHT' => (int) $this->config['dice_skins_img_height'],
|
||||
'DICE_IMG_WIDTH' => (int) $this->config['dice_skins_img_width'],
|
||||
'S_DICE_DISPLAY' => (bool) ($topic_data['dice_enabled'] && $this->auth->acl_get('f_dice_view', $forum_id)),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get roll data for a list of posts in a topic page.
|
||||
*
|
||||
* @event core.viewtopic_modify_post_data
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function get_dice_rolls($event)
|
||||
{
|
||||
// Grab event data
|
||||
$forum_id = (int) $event['forum_id']; // Forum identifier
|
||||
$topic_id = (int) $event['topic_id']; // Topic identifier
|
||||
$topic_data = (array) $event['topic_data']; // Array with topic data
|
||||
$post_list = (array) $event['post_list']; // Array with post_ids we are going to display
|
||||
|
||||
// If the dice extension is not enabled for this forum, we return.
|
||||
if (!$topic_data['dice_enabled'] || !$this->auth->acl_get('f_dice_view', $forum_id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get entities for the post list
|
||||
$entities = $this->operator->get_rolls_for_topic($forum_id, $topic_id, $post_list);
|
||||
|
||||
// Get the dice skin
|
||||
$skin_data = $this->functions->get_dice_skin_data($topic_data['dice_skin_override'], $topic_data['dice_f_skin']);
|
||||
|
||||
$topic_data['dice_skin'] = $skin_data;
|
||||
|
||||
/** @var \phpbbstudio\dice\entity\roll $entity */
|
||||
foreach ($entities as $entity)
|
||||
{
|
||||
$roll_id = (int) $entity->get_id(); // Roll identifier
|
||||
|
||||
// Add the roll data to the topic data
|
||||
$topic_data['dice_rolls'][$roll_id] = $this->operator->get_roll_data_for_display($entity, $skin_data);
|
||||
}
|
||||
|
||||
$event['topic_data'] = $topic_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the roll data for a list of posts in a topic page.
|
||||
*
|
||||
* @event core.viewtopic_modify_post_row
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function display_dice_rolls($event)
|
||||
{
|
||||
// Grab the event data
|
||||
$row = (array) $event['row']; // Array with original post and user data
|
||||
$post_row = (array) $event['post_row']; // Template block array of the post
|
||||
$topic_data = (array) $event['topic_data'];
|
||||
|
||||
// Grab the post message and the rolls data
|
||||
$message = $post_row['MESSAGE'];
|
||||
$rolls = isset($topic_data['dice_rolls']) ? $topic_data['dice_rolls'] : [];
|
||||
|
||||
if ($topic_data['dice_enabled'] && $this->auth->acl_get('f_dice_view', $row['forum_id']))
|
||||
{
|
||||
$message = $this->replace_rolls($message, $rolls, $topic_data['dice_skin'], $row, false);
|
||||
|
||||
// Lets do the quotes!
|
||||
$message = preg_replace_callback(
|
||||
'/<blockquote[^>]*>(.+?)<\/blockquote>/s',
|
||||
function ($match) use (&$rolls, $topic_data, $row) {
|
||||
return $this->replace_rolls($match[0], $rolls, $topic_data['dice_skin'], $row, true);
|
||||
},
|
||||
$message
|
||||
);
|
||||
|
||||
$outline = $this->display_dice_rolls_not_inline($rolls, $row['post_id']);
|
||||
|
||||
$post_row['DICE_ROLLS_OUTLINE'] = $outline;
|
||||
$post_row['MESSAGE'] = $message;
|
||||
$event['post_row'] = $post_row;
|
||||
|
||||
$topic_data['dice_rolls'] = $rolls;
|
||||
$event['topic_data'] = $topic_data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dice rolls displayed in the topic review.
|
||||
*
|
||||
* @event core.topic_review_modify_post_list
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function get_review_dice_rolls($event)
|
||||
{
|
||||
// Grab event data
|
||||
$forum_id = (int) $event['forum_id']; // Forum identifier
|
||||
$topic_id = (int) $event['topic_id']; // Topic identifier
|
||||
$post_list = (array) $event['post_list']; // Array with post_ids we are going to display
|
||||
$rowset = (array) $event['rowset']; // Array with the posts data
|
||||
|
||||
$forum_data = $this->functions->forum_data((int) $forum_id);
|
||||
|
||||
// If the dice extension is not enabled for this forum, we return.
|
||||
if (!$forum_data['dice_enabled'] || !$this->auth->acl_get('f_dice_view', $forum_id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get entities for the post list
|
||||
$entities = $this->operator->get_rolls_for_topic($forum_id, $topic_id, $post_list);
|
||||
|
||||
// Get the dice skin
|
||||
$skin_data = $this->functions->get_dice_skin_data($forum_data['dice_skin_override'], $forum_data['dice_f_skin']);
|
||||
|
||||
/** @var \phpbbstudio\dice\entity\roll $entity */
|
||||
foreach ($entities as $entity)
|
||||
{
|
||||
// Add the roll data to the topic data
|
||||
$rowset[$entity->get_post()]['dice_rolls'][$entity->get_id()] = $this->operator->get_roll_data_for_display($entity, $skin_data);
|
||||
$rowset[$entity->get_post()]['dice_skin'] = $skin_data;
|
||||
}
|
||||
|
||||
$this->template->assign_var('S_DICE_REVIEW', true);
|
||||
|
||||
$event['rowset'] = $rowset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the dice rolls in the topic review.
|
||||
*
|
||||
* @event core.topic_review_modify_row
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function display_review_dice_rolls($event)
|
||||
{
|
||||
// Grab event data
|
||||
$forum_id = (int) $event['forum_id'];
|
||||
$post_row = (array) $event['post_row'];
|
||||
$row = (array) $event['row'];
|
||||
|
||||
$message = $post_row['MESSAGE'];
|
||||
$rolls = isset($row['dice_rolls']) ? $row['dice_rolls'] : [];
|
||||
|
||||
$skin_data = isset($row['dice_skin']) ? $row['dice_skin'] : [];
|
||||
|
||||
if ($this->auth->acl_get('f_dice_view', $forum_id) && $rolls)
|
||||
{
|
||||
if (!$skin_data)
|
||||
{
|
||||
$forum_data = $this->functions->forum_data((int) $forum_id);
|
||||
$skin_data = $this->functions->get_dice_skin_data($forum_data['dice_skin_override'], $forum_data['dice_f_skin']);
|
||||
}
|
||||
|
||||
$message = $this->replace_rolls($message, $rolls, $skin_data, $row, false);
|
||||
|
||||
// Lets do the quotes!
|
||||
$message = preg_replace_callback(
|
||||
'/<blockquote[^>]*>(.+?)<\/blockquote>/s',
|
||||
function ($match) use (&$rolls, $skin_data, $row) {
|
||||
return $this->replace_rolls($match[0], $rolls, $skin_data, $row, true);
|
||||
},
|
||||
$message
|
||||
);
|
||||
|
||||
$outline = $this->display_dice_rolls_not_inline($rolls, $row['post_id']);
|
||||
|
||||
$post_row['DICE_ROLLS_OUTLINE'] = $outline;
|
||||
$post_row['MESSAGE'] = $message;
|
||||
$event['post_row'] = $post_row;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dice rolls displayed in the Moderator Control Panel.
|
||||
*
|
||||
* @event core.mcp_topic_modify_post_data
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function get_mcp_dice_rolls($event)
|
||||
{
|
||||
// Grab event data
|
||||
$forum_id = (int) $event['forum_id']; // Forum identifier
|
||||
$topic_id = (int) $event['topic_id']; // Topic identifier
|
||||
$post_list = (array) $event['post_id_list']; // Array with post_ids we are going to display
|
||||
$rowset = (array) $event['rowset']; // Array with the posts data
|
||||
|
||||
// Forum id might not be directly available from the &f= parameter, so otherwise grab it from the first post data.
|
||||
$forum_id = (empty($forum_id) && isset($rowset[0]['forum_id'])) ? (int) $rowset[0]['forum_id'] : $forum_id;
|
||||
|
||||
$forum_data = $this->functions->forum_data((int) $forum_id);
|
||||
|
||||
// If the dice extension is not enabled for this forum, we return.
|
||||
if (!$forum_data['dice_enabled'] || !$this->auth->acl_get('f_dice_view', $forum_id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$rolls = [];
|
||||
|
||||
// Get entities for the post list
|
||||
$entities = $this->operator->get_rolls_for_topic($forum_id, $topic_id, $post_list);
|
||||
|
||||
// Get the dice skin
|
||||
$skin_data = $this->functions->get_dice_skin_data($forum_data['dice_skin_override'], $forum_data['dice_f_skin']);
|
||||
|
||||
/** @var \phpbbstudio\dice\entity\roll $entity */
|
||||
foreach ($entities as $entity)
|
||||
{
|
||||
// Add the roll data to the topic data
|
||||
$rolls[$entity->get_post()][$entity->get_id()] = $this->operator->get_roll_data_for_display($entity, $skin_data);
|
||||
}
|
||||
|
||||
// This rowset does not have post id's as array keys.. :(
|
||||
for ($i = 0, $count = count($rowset); $i < $count; $i++)
|
||||
{
|
||||
$post_id = $rowset[$i]['post_id'];
|
||||
|
||||
if (isset($rolls[$post_id]))
|
||||
{
|
||||
$rowset[$i]['dice_rolls'] = $rolls[$post_id];
|
||||
$rowset[$i]['dice_skin'] = $skin_data;
|
||||
}
|
||||
}
|
||||
|
||||
$this->template->assign_var('S_DICE_MCP_DISPLAY', true);
|
||||
|
||||
$event['rowset'] = $rowset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display dice rolls in the Moderator Control Panel.
|
||||
*
|
||||
* @event core.mcp_topic_review_modify_row
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function display_mcp_dice_rolls($event)
|
||||
{
|
||||
// Grab event data
|
||||
$forum_id = (int) $event['forum_id'];
|
||||
$topic_info = (array) $event['topic_info'];
|
||||
$post_row = (array) $event['post_row'];
|
||||
$row = (array) $event['row'];
|
||||
|
||||
// Forum id might not be directly available from the &f= parameter, so otherwise grab it from the first post data.
|
||||
$forum_id = empty($forum_id) ? (int) $row['forum_id'] : $forum_id;
|
||||
|
||||
$message = $post_row['MESSAGE'];
|
||||
|
||||
// Get the dice rolls and merge them with all previously queried from this topic
|
||||
$topic_rolls = isset($topic_info['dice_rolls']) ? $topic_info['dice_rolls'] : [];
|
||||
$post_rolls = isset($row['dice_rolls']) ? $row['dice_rolls'] : [];
|
||||
$rolls = $topic_rolls + $post_rolls;
|
||||
|
||||
// Get the dice skin data: stored in topic data? stored in row data? query.
|
||||
if (isset($topic_info['dice_skin']))
|
||||
{
|
||||
$skin_data = $topic_info['dice_skin'];
|
||||
}
|
||||
else if (isset($row['dice_skin']))
|
||||
{
|
||||
$skin_data = $row['dice_skin'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$forum_data = $this->functions->forum_data((int) $forum_id);
|
||||
$skin_data = $this->functions->get_dice_skin_data($forum_data['dice_skin_override'], $forum_data['dice_f_skin']);
|
||||
}
|
||||
|
||||
// Merge the skin data into the topic data
|
||||
$topic_info['dice_skin'] = $skin_data;
|
||||
|
||||
if ($this->auth->acl_get('f_dice_view', $forum_id) && $rolls)
|
||||
{
|
||||
$message = $this->replace_rolls($message, $rolls, $skin_data, $row, false);
|
||||
|
||||
// Lets do the quotes!
|
||||
$message = preg_replace_callback(
|
||||
'/<blockquote[^>]*>(.+?)<\/blockquote>/s',
|
||||
function ($match) use (&$rolls, $skin_data, $row) {
|
||||
return $this->replace_rolls($match[0], $rolls, $skin_data, $row, true);
|
||||
},
|
||||
$message
|
||||
);
|
||||
|
||||
$outline = $this->display_dice_rolls_not_inline($rolls, $row['post_id']);
|
||||
|
||||
$post_row['DICE_ROLLS_OUTLINE'] = $outline;
|
||||
$post_row['MESSAGE'] = $message;
|
||||
$event['post_row'] = $post_row;
|
||||
}
|
||||
|
||||
$topic_info['dice_rolls'] = $rolls;
|
||||
$event['topic_info'] = $topic_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display dice rolls in the Moderator Control Panel's post details.
|
||||
*
|
||||
* @event core.mcp_post_template_data
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @retrun void
|
||||
* @access public
|
||||
*/
|
||||
public function display_mcp_post_dice_rolls($event)
|
||||
{
|
||||
$post_info = (array) $event['post_info']; // Array with the post information
|
||||
$post_tpl = (array) $event['mcp_post_template_data']; // Array with the MCP post template data
|
||||
|
||||
$message = $post_tpl['POST_PREVIEW'];
|
||||
|
||||
$message = $this->replace_mcp_rolls($message, $post_info);
|
||||
|
||||
$post_tpl['POST_PREVIEW'] = $message;
|
||||
$event['mcp_post_template_data'] = $post_tpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display dice rolls in the Moderator Control Panel's report details.
|
||||
*
|
||||
* @event core.mcp_report_template_data
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function display_mcp_report_dice_rolls($event)
|
||||
{
|
||||
// Grab event data
|
||||
$post_info = (array) $event['post_info']; // Array with the post information
|
||||
$report_tpl = (array) $event['report_template']; // Array with the MCP report template data
|
||||
|
||||
$message = $report_tpl['POST_PREVIEW'];
|
||||
|
||||
$message = $this->replace_mcp_rolls($message, $post_info);
|
||||
|
||||
$report_tpl['POST_PREVIEW'] = $message;
|
||||
$event['report_template'] = $report_tpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace dice rolls in a message in the Moderator Control Panel.
|
||||
*
|
||||
* @param string $message The message with the dice rolls
|
||||
* @param array $post_info The array with the post data
|
||||
* @return string The rendered message with the dice rolls replacement
|
||||
* @access protected
|
||||
*/
|
||||
protected function replace_mcp_rolls($message, array $post_info)
|
||||
{
|
||||
$forum_id = (int) $post_info['forum_id'];
|
||||
$topic_id = (int) $post_info['topic_id'];
|
||||
$post_id = (int) $post_info['post_id'];
|
||||
|
||||
$forum_data = $this->functions->forum_data((int) $forum_id);
|
||||
|
||||
// If the dice extension is not enabled for this forum, we return.
|
||||
if (!$forum_data['dice_enabled'] || !$this->auth->acl_get('f_dice_view', $forum_id))
|
||||
{
|
||||
return $message;
|
||||
}
|
||||
|
||||
$rolls = [];
|
||||
|
||||
// Get the dice skin
|
||||
$skin_data = $this->functions->get_dice_skin_data($forum_data['dice_skin_override'], $forum_data['dice_f_skin']);
|
||||
|
||||
// Get entities for the post list
|
||||
$entities = $this->operator->get_rolls_for_topic($forum_id, $topic_id, [$post_id]);
|
||||
|
||||
/** @var \phpbbstudio\dice\entity\roll $entity */
|
||||
foreach ($entities as $entity)
|
||||
{
|
||||
// Add the roll data to the topic data
|
||||
$rolls[$entity->get_id()] = $this->operator->get_roll_data_for_display($entity, $skin_data);
|
||||
}
|
||||
|
||||
if ($this->auth->acl_get('f_dice_view', $forum_id) && $rolls)
|
||||
{
|
||||
$message = $this->replace_rolls($message, $rolls, $skin_data, $post_info, false);
|
||||
|
||||
// Lets do the quotes!
|
||||
$message = preg_replace_callback(
|
||||
'/<blockquote[^>]*>(.+?)<\/blockquote>/s',
|
||||
function ($match) use (&$rolls, $skin_data, $post_info) {
|
||||
return $this->replace_rolls($match[0], $rolls, $skin_data, $post_info, true);
|
||||
},
|
||||
$message
|
||||
);
|
||||
|
||||
$outline = $this->display_dice_rolls_not_inline($rolls, $post_id);
|
||||
|
||||
$this->template->assign_vars([
|
||||
'DICE_ROLLS_OUTLINE' => $outline,
|
||||
|
||||
'S_DICE_MCP_DISPLAY' => true,
|
||||
]);
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace dice rolls in a message.
|
||||
*
|
||||
* @param string $message The message
|
||||
* @param array $rolls The dice rolls
|
||||
* @param array $skin The dice skin data
|
||||
* @param array $row The post row data
|
||||
* @param bool $quote Whether we're replacing rolls inside a quote
|
||||
* @param bool $bbcode Whether we're looking for the BBCode or the HTML replacement
|
||||
* @return string
|
||||
* @access protected
|
||||
*/
|
||||
protected function replace_rolls($message, array &$rolls, array $skin, array $row, $quote = false, $bbcode = false)
|
||||
{
|
||||
$regex = $bbcode ? '/\[roll=([0-9]+)\].+?\[\/roll\]/s' : '/<span class="phpbbstudio-dice" data-dice-id="([0-9]+)">.+?<\/span>/s';
|
||||
|
||||
return preg_replace_callback(
|
||||
$regex,
|
||||
function($match) use (&$rolls, $skin, $row, $quote)
|
||||
{
|
||||
// Capture group 1 is the roll identifier
|
||||
$roll_id = (int) $match[1];
|
||||
$roll = isset($rolls[$roll_id]) ? $rolls[$roll_id] : [];
|
||||
|
||||
// If the roll exists
|
||||
if ($roll)
|
||||
{
|
||||
// It belongs to this post or is in a quote
|
||||
if (($roll['post'] == $row['post_id']) || $quote)
|
||||
{
|
||||
// Set it as displayed in-line
|
||||
$rolls[$roll_id]['inline'] = true;
|
||||
|
||||
// Assign the roll variables
|
||||
return $this->operator->assign_roll_vars($roll);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $match[0];
|
||||
}
|
||||
}
|
||||
else if ($quote)
|
||||
{
|
||||
// Lets check if we tried querying this roll before and could not find it.
|
||||
$not_found = isset($rolls['not_found']) ? $rolls['not_found'] : [];
|
||||
if (in_array($roll_id, $not_found))
|
||||
{
|
||||
return $match[0];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Try to load the roll from the database
|
||||
$entity = $this->operator->get_entity()->load($roll_id);
|
||||
}
|
||||
catch (\phpbbstudio\dice\exception\out_of_bounds $e)
|
||||
{
|
||||
// The roll was not found, so lets add it to the 'not_found' array.
|
||||
$rolls['not_found'][] = $roll_id;
|
||||
|
||||
// The roll does not exist, so return the string
|
||||
return $match[0];
|
||||
}
|
||||
|
||||
$roll = $this->operator->get_roll_data_for_display($entity, $skin);
|
||||
|
||||
// Add the roll to the rolls data
|
||||
$rolls[$roll_id] = $roll;
|
||||
|
||||
return $this->operator->assign_roll_vars($roll);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Roll was not found, return the entire string
|
||||
return $match[0];
|
||||
}
|
||||
},
|
||||
$message
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display any not in-line dice rolls.
|
||||
*
|
||||
* @param array $rolls The dice rolls
|
||||
* @param int $post_id The post identifier
|
||||
* @return array Array of the not in-line displayed dice rolls
|
||||
* @access protected
|
||||
*/
|
||||
protected function display_dice_rolls_not_inline(array $rolls, $post_id)
|
||||
{
|
||||
// Enforce data type
|
||||
$post_id = (int) $post_id;
|
||||
|
||||
// Set up collection array
|
||||
$outline = [];
|
||||
|
||||
// Make sure we are not iterating over not found rolls
|
||||
unset($rolls['not_found']);
|
||||
|
||||
foreach ($rolls as $roll_id => $roll)
|
||||
{
|
||||
// If the roll is already displayed inline or,
|
||||
// if the the roll does not belong to this post:
|
||||
if ($roll['inline'] || $roll['post'] !== $post_id)
|
||||
{
|
||||
// we continue..
|
||||
continue;
|
||||
}
|
||||
|
||||
// Else, lets add it to the outline rolls array
|
||||
$outline[] = $this->operator->assign_roll_vars($roll);
|
||||
}
|
||||
|
||||
return $outline;
|
||||
}
|
||||
}
|
||||
203
ext/phpbbstudio/dice/event/posting_listener.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Posting listener.
|
||||
*/
|
||||
class posting_listener implements EventSubscriberInterface
|
||||
{
|
||||
/** @var \phpbbstudio\dice\core\functions_common */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbb\controller\helper */
|
||||
protected $helper;
|
||||
|
||||
/** @var \phpbbstudio\dice\operator\roll */
|
||||
protected $operator;
|
||||
|
||||
/** @var \phpbb\request\request */
|
||||
protected $request;
|
||||
|
||||
/** @var \phpbb\template\template */
|
||||
protected $template;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbbstudio\dice\core\functions_common $functions Common functions
|
||||
* @param \phpbb\controller\helper $helper Controller helper object
|
||||
* @param \phpbbstudio\dice\operator\roll $operator Roll operator object
|
||||
* @param \phpbb\request\request $request Request object
|
||||
* @param \phpbb\template\template $template Template object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbbstudio\dice\core\functions_common $functions,
|
||||
\phpbb\controller\helper $helper,
|
||||
\phpbbstudio\dice\operator\roll $operator,
|
||||
\phpbb\request\request $request,
|
||||
\phpbb\template\template $template
|
||||
)
|
||||
{
|
||||
$this->functions = $functions;
|
||||
$this->helper = $helper;
|
||||
$this->operator = $operator;
|
||||
$this->request = $request;
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign functions defined in this class to event listeners in the core.
|
||||
*
|
||||
* @static
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
static public function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
'core.posting_modify_post_data' => 'dice_posting_requests',
|
||||
'core.posting_modify_submit_post_before' => 'dice_posting_submit',
|
||||
'core.submit_post_end' => 'dice_posting_update',
|
||||
'core.posting_modify_template_vars' => 'dice_posting_variables',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Request dice roll indicator.
|
||||
*
|
||||
* @event core.posting_modify_post_data
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_posting_requests($event)
|
||||
{
|
||||
$event['post_data'] = array_merge($event['post_data'], [
|
||||
'dice_indicator' => $this->request->is_set_post('dice_indicator'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the dice roll indicator so it is available in dice_posting_update()
|
||||
*
|
||||
* @event core.posting_modify_submit_post_before
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_posting_submit($event)
|
||||
{
|
||||
$event['data'] = array_merge($event['data'], [
|
||||
'dice_indicator' => $event['post_data']['dice_indicator'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the roll identifiers after the post has been submitted.
|
||||
*
|
||||
* @event core.submit_post_end
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function dice_posting_update($event)
|
||||
{
|
||||
// Grab the event data
|
||||
$data = $event['data'];
|
||||
$mode = $event['mode'];
|
||||
|
||||
// Grab the identifiers
|
||||
$forum_id = (int) $data['forum_id'];
|
||||
$topic_id = (int) $data['topic_id'];
|
||||
$post_id = (int) $data['post_id'];
|
||||
|
||||
if ($data['dice_indicator'])
|
||||
{
|
||||
switch ($mode)
|
||||
{
|
||||
case 'post':
|
||||
case 'reply':
|
||||
case 'quote':
|
||||
// Set identifiers
|
||||
$this->operator->set_rolls_identifiers($mode, $forum_id, $topic_id, $post_id);
|
||||
break;
|
||||
|
||||
default:
|
||||
// All identifiers are already set
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign roll and extension data to the template.
|
||||
*
|
||||
* @event core.posting_modify_template_vars
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_posting_variables($event)
|
||||
{
|
||||
// Grab the event data
|
||||
$mode = $event['mode'];
|
||||
$post_data = $event['post_data'];
|
||||
|
||||
// Grab the identifiers
|
||||
$forum_id = (int) $event['forum_id'];
|
||||
$topic_id = (int) $event['topic_id'];
|
||||
$post_id = (int) $event['post_id'];
|
||||
$poster_id = (int) $post_data['poster_id'];
|
||||
|
||||
// If we are quoting a post, we have to reset the post identifier
|
||||
$post_id = $mode === 'quote' ? 0 : $post_id;
|
||||
|
||||
// Get roll entities for this combination of identifiers
|
||||
$entities = $this->operator->get_rolls_for_posting($forum_id, $topic_id, $post_id);
|
||||
|
||||
// Assign the rolls data to the template
|
||||
$this->operator->assign_block_vars($entities);
|
||||
|
||||
// Count the entities
|
||||
$count = count($entities);
|
||||
|
||||
/**
|
||||
* @var bool S_DICE_INDICATOR Used to determine if a dice roll was added, needed for other events
|
||||
* @var string U_DICE_ADD URL to add a dice roll for this post
|
||||
* @var string U_DICE_DEL Base URL to delete a dice roll, needed for the AJAX callback
|
||||
* @var string U_DICE_EDIT Base URL to edit a dice roll, needed for the AJAX callback
|
||||
*/
|
||||
$this->template->assign_vars([
|
||||
'S_DICE_ENABLED' => (bool) $post_data['dice_enabled'],
|
||||
'S_DICE_INDICATOR' => isset($post_data['dice_indicator']) ? (bool) $post_data['dice_indicator'] : false,
|
||||
'S_DICE_LIMIT' => (bool) $this->functions->dice_limit_reached($count, $forum_id),
|
||||
|
||||
'S_ROLL_ADD' => (bool) $this->functions->dice_auth_add($forum_id, $poster_id),
|
||||
'S_ROLL_DELETE' => (bool) $this->functions->dice_auth_delete($forum_id, $poster_id),
|
||||
'S_ROLL_EDIT' => (bool) $this->functions->dice_auth_edit($forum_id, $poster_id),
|
||||
|
||||
'U_DICE_ADD' => $this->helper->route('phpbbstudio_dice_add', [
|
||||
'forum_id' => $forum_id,
|
||||
'topic_id' => $topic_id,
|
||||
'post_id' => $post_id,
|
||||
'poster_id' => $poster_id,
|
||||
'hash' => generate_link_hash('dice_add')
|
||||
]),
|
||||
|
||||
'U_DICE_DELETE' => $this->helper->route('phpbbstudio_dice_del'),
|
||||
'U_DICE_EDIT' => $this->helper->route('phpbbstudio_dice_edit'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
151
ext/phpbbstudio/dice/event/setup_listener.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\event;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Set up listener.
|
||||
*/
|
||||
class setup_listener implements EventSubscriberInterface
|
||||
{
|
||||
/** @var \phpbb\auth\auth */
|
||||
protected $auth;
|
||||
|
||||
/** @var \phpbbstudio\dice\core\functions_common */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbb\language\language */
|
||||
protected $lang;
|
||||
|
||||
/** @var \phpbb\template\template */
|
||||
protected $template;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\auth\auth $auth Authentication object
|
||||
* @param \phpbbstudio\dice\core\functions_common $functions Common dice functions
|
||||
* @param \phpbb\language\language $lang Language object
|
||||
* @param \phpbb\template\template $template Template object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\auth\auth $auth,
|
||||
\phpbbstudio\dice\core\functions_common $functions,
|
||||
\phpbb\language\language $lang,
|
||||
\phpbb\template\template $template
|
||||
)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
$this->functions = $functions;
|
||||
$this->lang = $lang;
|
||||
$this->template = $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign functions defined in this class to event listeners in the core.
|
||||
*
|
||||
* @static
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
static public function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
'core.user_setup_after' => 'dice_setup_lang',
|
||||
'core.page_header' => 'dice_setup_links',
|
||||
'core.permissions' => 'dice_setup_permissions',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load extension language file during user set up.
|
||||
*
|
||||
* @event core.user_setup_after
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_setup_lang()
|
||||
{
|
||||
$this->lang->add_lang('dice_common', 'phpbbstudio/dice');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up dice page links.
|
||||
*
|
||||
* @event core.page_header
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_setup_links()
|
||||
{
|
||||
$template_vars = [];
|
||||
|
||||
// If the user has the permission to view the page
|
||||
if ($this->auth->acl_get('u_dice_test'))
|
||||
{
|
||||
foreach ($this->functions->get_dice_link_locations() as $link)
|
||||
{
|
||||
// Lets only add those links that are enabled to the template
|
||||
if ($link['status'])
|
||||
{
|
||||
$template_vars['S_DICE_' . utf8_strtoupper($link['name'])] = true;
|
||||
}
|
||||
}
|
||||
|
||||
$this->template->assign_vars($template_vars);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add permissions for DICE - Permission's language file is automatically loaded.
|
||||
*
|
||||
* @event core.permissions
|
||||
* @param \phpbb\event\data $event The event object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function dice_setup_permissions($event)
|
||||
{
|
||||
$categories = $event['categories'];
|
||||
$permissions = $event['permissions'];
|
||||
|
||||
if (empty($categories['phpbb_studio']))
|
||||
{
|
||||
/* Setting up a custom CAT */
|
||||
$categories['phpbb_studio'] = 'ACL_CAT_PHPBB_STUDIO';
|
||||
|
||||
$event['categories'] = $categories;
|
||||
}
|
||||
|
||||
$perms = [
|
||||
'f_dice_roll',
|
||||
'f_dice_edit',
|
||||
'f_dice_delete',
|
||||
'f_dice_view',
|
||||
'f_dice_no_limit',
|
||||
'f_mod_dice_add',
|
||||
'f_mod_dice_edit',
|
||||
'f_mod_dice_delete',
|
||||
'a_dice_admin',
|
||||
'u_dice_use_ucp',
|
||||
'u_dice_test',
|
||||
'u_dice_skin',
|
||||
];
|
||||
|
||||
foreach ($perms as $permission)
|
||||
{
|
||||
$permissions[$permission] = ['lang' => 'ACL_' . utf8_strtoupper($permission), 'cat' => 'phpbb_studio'];
|
||||
}
|
||||
|
||||
$event['permissions'] = $permissions;
|
||||
}
|
||||
}
|
||||
167
ext/phpbbstudio/dice/exception/base.php
Normal file
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\exception;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Base exception
|
||||
*/
|
||||
class base extends \Exception
|
||||
{
|
||||
/**
|
||||
* Null if the message is a string, array if the message was submitted as an array.
|
||||
* @var string|array
|
||||
*/
|
||||
protected $message_full;
|
||||
|
||||
protected $previous;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Different from normal exceptions in that we do not enforce $message to be a string.
|
||||
*
|
||||
* @param string|array $message
|
||||
* @param int $code
|
||||
* @param \Exception $previous
|
||||
* @access public
|
||||
*/
|
||||
public function __construct($message = null, $code = 0, \Exception $previous = null)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->message = $message;
|
||||
|
||||
if (is_array($message))
|
||||
{
|
||||
$this->message = (string) $message[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* We're slightly changing the way exceptions work
|
||||
* Tools, such as xdebug, expect the message to be a string, so to prevent errors
|
||||
* with those tools, we store our full message in message_full and only a string in message
|
||||
*/
|
||||
$this->message_full = $message;
|
||||
|
||||
$this->code = $code;
|
||||
$this->previous = $previous;
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic message translation for our exceptions.
|
||||
*
|
||||
* @param \phpbb\language\language $lang Language object
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
public function get_message(\phpbb\language\language $lang)
|
||||
{
|
||||
// Make sure our language file has been loaded
|
||||
$this->add_lang($lang);
|
||||
|
||||
if (is_array($this->message_full))
|
||||
{
|
||||
return call_user_func_array([$lang, 'lang'], $this->message_full);
|
||||
}
|
||||
|
||||
return $lang->lang($this->message_full);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translate all portions of the message sent to the exception.
|
||||
*
|
||||
* Goes through each element of the array and tries to translate them
|
||||
*
|
||||
* @param \phpbb\language\language $lang Language object
|
||||
* @param string|array $message_portions The message portions to translate
|
||||
* @param string|null $parent_message Send a string to translate all of the
|
||||
* portions with the parent message (typically used to format a string
|
||||
* with the given message portions). Null to ignore. Default: Null
|
||||
* @return array|string Array if $parent_message === null else a string
|
||||
* @access protected
|
||||
*/
|
||||
protected function translate_portions(\phpbb\language\language $lang, $message_portions, $parent_message = null)
|
||||
{
|
||||
// Make sure our language file has been loaded
|
||||
$this->add_lang($lang);
|
||||
|
||||
// Ensure we have an array
|
||||
if (!is_array($message_portions))
|
||||
{
|
||||
$message_portions = [$message_portions];
|
||||
}
|
||||
|
||||
// Translate each message portion
|
||||
foreach ($message_portions as &$message)
|
||||
{
|
||||
// Attempt to translate each portion
|
||||
$translated_message = $lang->lang('EXCEPTION_' . $message);
|
||||
|
||||
// Check if translating did anything
|
||||
if ($translated_message !== 'EXCEPTION_' . $message)
|
||||
{
|
||||
// It did, so replace message with the translated version
|
||||
$message = $translated_message;
|
||||
}
|
||||
}
|
||||
// Always unset a variable passed by reference in a foreach loop
|
||||
unset($message);
|
||||
|
||||
if ($parent_message !== null)
|
||||
{
|
||||
// Prepend the parent message to the message portions
|
||||
array_unshift($message_portions, (string) $parent_message);
|
||||
|
||||
// We return a string
|
||||
return call_user_func_array([$lang, 'lang'], $message_portions);
|
||||
}
|
||||
|
||||
// We return an array
|
||||
return $message_portions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add our language file.
|
||||
*
|
||||
* @param \phpbb\language\language $lang Language object
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function add_lang(\phpbb\language\language $lang)
|
||||
{
|
||||
static $is_loaded = false;
|
||||
|
||||
// We only need to load the language file once
|
||||
if ($is_loaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Add our language file
|
||||
$lang->add_lang('dice_exceptions', 'phpbbstudio/dice');
|
||||
|
||||
// So the language file is only loaded once
|
||||
$is_loaded = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output a string of this error message.
|
||||
*
|
||||
* This will hopefully be never called, always catch the expected exceptions
|
||||
* and call get_message to translate them into an error that a user can
|
||||
* understand
|
||||
*
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return is_array($this->message_full) ? (string) var_export($this->message_full, true) : (string) $this->message_full;
|
||||
}
|
||||
}
|
||||
27
ext/phpbbstudio/dice/exception/out_of_bounds.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\exception;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice OutOfBounds exception
|
||||
*/
|
||||
class out_of_bounds extends base
|
||||
{
|
||||
/**
|
||||
* Translate this exception
|
||||
*
|
||||
* @param \phpbb\language\language $lang Language object
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
public function get_message(\phpbb\language\language $lang)
|
||||
{
|
||||
return $this->translate_portions($lang, $this->message_full, 'EXCEPTION_OUT_OF_BOUNDS');
|
||||
}
|
||||
}
|
||||
27
ext/phpbbstudio/dice/exception/unexpected_value.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\exception;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice UnexpectedValue exception
|
||||
*/
|
||||
class unexpected_value extends base
|
||||
{
|
||||
/**
|
||||
* Translate this exception
|
||||
*
|
||||
* @param \phpbb\language\language $lang Language object
|
||||
* @return string
|
||||
* @access public
|
||||
*/
|
||||
public function get_message(\phpbb\language\language $lang)
|
||||
{
|
||||
return $this->translate_portions($lang, $this->message_full, 'EXCEPTION_UNEXPECTED_VALUE');
|
||||
}
|
||||
}
|
||||
34
ext/phpbbstudio/dice/ext.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice;
|
||||
|
||||
class ext extends \phpbb\extension\base
|
||||
{
|
||||
/**
|
||||
* Check whether the extension can be enabled.
|
||||
* Provides meaningful(s) error message(s) and the back-link on failure.
|
||||
* CLI compatible
|
||||
*
|
||||
* @return bool
|
||||
* @access public
|
||||
*/
|
||||
public function is_enableable()
|
||||
{
|
||||
$streams = stream_get_wrappers();
|
||||
|
||||
if (phpbb_version_compare(PHPBB_VERSION, '3.2.5', '>=')
|
||||
&& phpbb_version_compare(PHPBB_VERSION, '4.0.0@dev', '<')
|
||||
&& phpbb_version_compare(PHP_VERSION, '5.5', '>=')
|
||||
&& in_array('glob', $streams)
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
130
ext/phpbbstudio/dice/language/en/acp_dice.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'ACP_DICE_DICE' => [
|
||||
1 => '%d dice', // One dice
|
||||
2 => '%d dice', // Two dice (don't we love the English language)
|
||||
],
|
||||
|
||||
'ACP_DICE_ENJOY' => 'Enjoy',
|
||||
|
||||
'ACP_DICE_EXAMPLE' => 'Example',
|
||||
'ACP_DICE_EXAMPLE_1' => 'There are a total of 3 rolls in this posts, which can be limited with <em>maximum rolls per post</em>',
|
||||
'ACP_DICE_EXAMPLE_2' => 'Each roll consists of multiple <em>(types of)</em> dice',
|
||||
'ACP_DICE_EXAMPLE_3' => 'Each roll has a total dice quantity',
|
||||
'ACP_DICE_EXAMPLE_4' => 'Each dice has a dice quantity',
|
||||
'ACP_DICE_EXAMPLE_5' => 'Each dice has sides',
|
||||
|
||||
'ACP_DICE_INVALID' => 'Invalid',
|
||||
'ACP_DICE_VALID' => 'Valid',
|
||||
'ACP_DICE_VALID_ALL' => 'All installed skins are valid!',
|
||||
'ACP_DICE_VALID_NOT_ALL' => 'Not all installed skins are valid!',
|
||||
|
||||
'ACP_DICE_INSTALLED' => 'Installed',
|
||||
'ACP_DICE_INSTALLED_NOT' => 'Not installed',
|
||||
'ACP_DICE_INSTALLED_IN' => 'Installation directory',
|
||||
|
||||
'ACP_DICE_LOCATIONS' => 'Dice link locations',
|
||||
'ACP_DICE_LOCATIONS_DESC' => 'Select one or more locations where the link to the dice page should appear.',
|
||||
'ACP_DICE_LOCATIONS_EXPLAIN' => 'This is an example of a board index. In here you can select where you want the dice page link to show up. You can select as many locations as you like, from nowhere to at all places.<br>The dice page provides a dice tester, the dice limitations set by an Administrator and a dice FAQ. All is provided to fully understand all the dice possibilities.',
|
||||
'ACP_DICE_LOCATIONS_SUCCESS' => 'You have successfully altered the dice link locations.',
|
||||
|
||||
'ACP_DICE_ORPHANED' => 'Delete orphaned rolls',
|
||||
'ACP_DICE_ORPHANED_CONFIRM' => 'Are you sure you wish to delete all orphaned dice rolls?<br>This will remove all rolls that do not belong to a forum, topic or post.<br>Users that are currently creating a post with a roll, will also have their roll deleted.',
|
||||
'ACP_DICE_ORPHANED_SUCCESS' => 'You have successfully deleted all orphaned rolls.',
|
||||
|
||||
'ACP_DICE_ROLL_NR' => 'Roll %d', // Roll 1, Roll 2, etc..
|
||||
'ACP_DICE_ROLLS' => 'Dice rolls',
|
||||
'ACP_DICE_ROLLS_SHORT' => 'Rolls',
|
||||
'ACP_DICE_ROLLS_DB' => 'Rolls in the database',
|
||||
'ACP_DICE_ROLLS_NONE' => 'There are no dice rolls.',
|
||||
|
||||
'ACP_DICE_SETTINGS_EXAMPLE' => 'Click here to view the example.',
|
||||
'ACP_DICE_SETTINGS_EXPLAIN' => 'Terminology in this extension can be rather tricky, as a lot of things potentially have the same name. Therefore we have created an example to better illustrate what is what.',
|
||||
|
||||
'ACP_DICE_SIDE_ADD' => 'Add a side',
|
||||
'ACP_DICE_SIDE_ADD_CONFIRM' => 'Are you sure you wish to add this dice side?',
|
||||
'ACP_DICE_SIDE_ADD_SUCCESS' => 'You have successfully added <strong>%s</strong> as a dice side.',
|
||||
'ACP_DICE_SIDE_DELETE' => 'Delete side',
|
||||
'ACP_DICE_SIDE_DELETE_CONFIRM' => 'Are you sure you wish to delete this dice side?',
|
||||
'ACP_DICE_SIDE_DELETE_SUCCESS' => 'You have successfully deleted <strong>%s</strong> as a dice side.',
|
||||
'ACP_DICE_SIDES_AVAILABLE' => 'Available sides',
|
||||
'ACP_DICE_SIDES_EXPLAIN' => 'The allowed sides users can use in their dice notations. Skins are valid when they have images for all sides provided here. For example, sides: <small><samp>4, 5</samp></small>. Images: <small><samp>d4_1 to d4_4, d5_1 to d5_5</samp></small>',
|
||||
'ACP_DICE_SIDES_NONE' => 'There are no dice sides.',
|
||||
'ACP_DICE_SIDES_ONLY' => 'Only available sides',
|
||||
'ACP_DICE_SIDES_ONLY_DESC' => 'If this setting is enabled, users are only allowed to use the available dice sides.',
|
||||
'ACP_DICE_SIDES_ONLY_STATS' => 'Users can only use available dice sides.',
|
||||
'ACP_DICE_SIDES_ONLY_UPTO' => 'Users can use upto %d dice sides.',
|
||||
'ACP_DICE_SIDES_ONLY_UNLIMITED' => 'Users can use unlimited dice sides.',
|
||||
|
||||
'ACP_DICE_SKIN_INSTALL' => 'Install skin',
|
||||
'ACP_DICE_SKIN_INSTALL_CONFIRM' => 'Are you sure you wish to install this dice skin?',
|
||||
'ACP_DICE_SKIN_INSTALL_SUCCESS' => 'You have successfully installed <strong>%s</strong> as a dice skin.',
|
||||
'ACP_DICE_SKIN_UNINSTALL' => 'Uninstall skin',
|
||||
'ACP_DICE_SKIN_UNINSTALL_CONFIRM' => 'Are you sure you wish to uninstall this dice skin?',
|
||||
'ACP_DICE_SKIN_UNINSTALL_SUCCESS' => 'You have successfully uninstalled <strong>%s</strong> as a dice skin.',
|
||||
'ACP_DICE_SKINS_AVAILABLE' => 'Available skins',
|
||||
'ACP_DICE_SKINS_INSTALLED' => 'Installed skins',
|
||||
'ACP_DICE_SKINS_EXPLAIN' => 'Skins are automatically found when uploaded to the designated directory. Images should be correctly named. For example, for a 4-sided dice: <small><samp>d4_1.gif, d4_2.gif, d4_3.gif, d4_4.gif</samp></small>',
|
||||
'ACP_DICE_SKINS_NONE' => 'There are no dice skins.',
|
||||
|
||||
'ACP_DICE_SUMMARY' => 'Summary',
|
||||
|
||||
'ACP_DICE_TOP_TOPICS' => 'Top topics',
|
||||
'ACP_DICE_TOP_TOPICS_DESC' => 'List of topics with the most rolls.',
|
||||
'ACP_DICE_TOP_USERS' => 'Top users',
|
||||
'ACP_DICE_TOP_USERS_DESC' => 'List of users with the most rolls.',
|
||||
|
||||
'ACP_DICE_SKINS_DIR' => 'Skin image directory',
|
||||
'ACP_DICE_SKINS_DIR_DESC' => 'This path will be used to search skins. Changing this will reset the installed skins.<br><small>Path under your phpBB root directory, e.g. <samp>images/skins</samp>.</small>',
|
||||
'ACP_DICE_SKINS_PATH_ERROR' => 'The skins directory you entered is invalid.<br>The value contains the following unsupported characters:<br />%s',
|
||||
'ACP_DICE_SKINS_IMG_HEIGHT' => 'Skin image height',
|
||||
'ACP_DICE_SKINS_IMG_HEIGHT_DESC' => 'Image height for the dice skin images. Has to be between 16 and 80 pixels.',
|
||||
'ACP_DICE_SKINS_IMG_HEIGHT_ERROR' => 'The image height you entered is invalid. The value has to be between 16 and 80 pixels.',
|
||||
'ACP_DICE_SKINS_IMG_WIDTH' => 'Skin image width',
|
||||
'ACP_DICE_SKINS_IMG_WIDTH_DESC' => 'Image width for the dice skin images. Has to be between 16 and 80 pixels.',
|
||||
'ACP_DICE_SKINS_IMG_WIDTH_ERROR' => 'The image width you entered is invalid. The value has to be between 16 and 80 pixels.',
|
||||
|
||||
'ACP_DICE_ZERO_UNLIMITED' => 'Set value to <strong>0</strong> for an unlimited amount.',
|
||||
|
||||
// Settings
|
||||
'ACP_DICE_MAX_ROLLS' => 'Maximum rolls per post',
|
||||
'ACP_DICE_MAX_ROLLS_DESC' => 'The maximum number of rolls that can be added per post.',
|
||||
'ACP_DICE_PER_NOTATION' => 'Maximum dice per roll',
|
||||
'ACP_DICE_PER_NOTATION_DESC' => 'The following roll has 2 dice: 5d6 <strong class="error">+</strong> 2d4',
|
||||
'ACP_DICE_QTY_PER_DICE' => 'Maximum dice quantity per roll',
|
||||
'ACP_DICE_QTY_PER_DICE_DESC' => 'The following roll has a total dice quantity of 7: <strong class="error">5</strong>d6 + <strong class="error">2</strong>d4',
|
||||
'ACP_DICE_QTY_DICE_PER_NOTATION' => 'Maximum dice quantity per dice',
|
||||
'ACP_DICE_QTY_DICE_PER_NOTATION_DESC' => 'The following roll has 2 dice, both with a dice quantity of 3: <strong class="error">3</strong>d6 + <strong class="error">3</strong>d4',
|
||||
'ACP_DICE_SIDES_PER_DICE' => 'Maximum sides per dice',
|
||||
'ACP_DICE_SIDES_PER_DICE_DESC' => 'The following roll has 1 dice with 10 sides: 4d<strong class="error">10</strong>',
|
||||
'ACP_DICE_PC_DICE_PER_NOTATION' => 'Maximum percentage dice per roll',
|
||||
'ACP_DICE_PC_DICE_PER_NOTATION_DESC' => 'The following roll has 2 percentage dice: 6d100 <strong class="error">+</strong> 3d%',
|
||||
'ACP_DICE_FUDGE_DICE_PER_NOTATION' => 'Maximum fudge dice per roll',
|
||||
'ACP_DICE_FUDGE_DICE_PER_NOTATION_DESC' => 'The following roll has 1 fudge dice: 2d<strong class="error">F.2</strong> + 4d8',
|
||||
'ACP_DICE_EXPLODING_DICE_PER_NOTATION' => 'Maximum exploding dice per roll',
|
||||
'ACP_DICE_EXPLODING_DICE_PER_NOTATION_DESC' => 'The following roll has 1 exploding dice: 2d6<strong class="error">!</strong> + 4d8',
|
||||
'ACP_DICE_PENETRATION_DICE_PER_NOTATION' => 'Maximum penetrating dice per roll',
|
||||
'ACP_DICE_PENETRATION_DICE_PER_NOTATION_DESC' => 'The following roll has 1 penetrating dice: 2d6<strong class="error">!p</strong> + 2d%',
|
||||
'ACP_DICE_COMPOUND_DICE_PER_NOTATION' => 'Maximum compounding dice per roll',
|
||||
'ACP_DICE_COMPOUND_DICE_PER_NOTATION_DESC' => 'The following roll has 1 compounding dice: 2d6<strong class="error">!!</strong> + 5d4',
|
||||
]);
|
||||
210
ext/phpbbstudio/dice/language/en/dice_common.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'DICE_DICE' => 'Dice',
|
||||
|
||||
'DICE_NOT_AJAX' => 'Dice rolls are managed with AJAX request. The current request is not AJAX and the server returned an invalid reply.',
|
||||
|
||||
'DICE_SKIN' => 'Dice skin',
|
||||
|
||||
'DICE_ROLL' => 'Dice roll',
|
||||
'DICE_ROLL_ACTIONS' => 'Actions',
|
||||
'DICE_ROLL_ADD_UNAUTH' => 'You are not authorised to add a roll.',
|
||||
'DICE_ROLL_ADD_SUCCESS' => 'You have successfully added a roll.',
|
||||
'DICE_ROLL_EDIT' => 'Edit roll',
|
||||
'DICE_ROLL_EDIT_UNAUTH' => 'You are not authorised to edit this roll.',
|
||||
'DICE_ROLL_EDIT_CONFIRM' => 'Editing a roll will completely re-roll it. This action can not be undone!',
|
||||
'DICE_ROLL_EDIT_SUCCESS' => 'You have successfully edited this roll.',
|
||||
'DICE_ROLL_DELETE' => 'Delete roll',
|
||||
'DICE_ROLL_DELETE_UNAUTH' => 'You are not authorised to delete this roll.',
|
||||
'DICE_ROLL_DELETE_CONFIRM' => 'Are you sure you wish to delete this roll?',
|
||||
'DICE_ROLL_DELETE_SUCCESS' => 'You have successfully deleted this roll.',
|
||||
'DICE_ROLL_DICE' => 'Roll the dice',
|
||||
'DICE_ROLL_FORUM_DISABLED' => 'Dice rolls have been disabled for this forum',
|
||||
'DICE_ROLL_ID' => 'Roll id',
|
||||
'DICE_ROLL_LIMIT_REACHED' => 'Dice limit reached',
|
||||
'DICE_ROLL_NO_ROLL' => 'No dice were rolled.',
|
||||
|
||||
'DICE_ROLL_NOT_EXIST' => [
|
||||
1 => 'The provided roll does not exist.',
|
||||
2 => 'The provided rolls do no exist.',
|
||||
],
|
||||
'DICE_ROLL_NOTATION' => 'Roll notation',
|
||||
'DICE_ROLL_NOTATION_CURRENT' => 'Current roll notation',
|
||||
'DICE_ROLL_NOTATION_NEW' => 'New roll notation',
|
||||
'DICE_ROLL_TIME' => 'Roll time',
|
||||
'DICE_ROLLS' => 'Dice rolls',
|
||||
'DICE_ROLLS_EXPLAIN' => 'If you wish to add one or more rolls enter a roll notation and roll the dice. You may place it inline in the message box or edit/delete it at your will later on.',
|
||||
'DICE_ROLLS_TOO_MANY' => 'You have already rolled too many dice for this post.',
|
||||
'DICE_TEXT' => 'Text',
|
||||
|
||||
// Dice states
|
||||
'DICE_ROLL_COMPOUNDED' => 'Compounded',
|
||||
'DICE_ROLL_EXPLODED' => 'Exploded',
|
||||
'DICE_ROLL_HIGHEST' => 'Highest',
|
||||
'DICE_ROLL_LOWEST' => 'Lowest',
|
||||
'DICE_ROLL_PENETRATED' => 'Penetrated',
|
||||
'DICE_ROLL_SUCCESS' => 'Success',
|
||||
|
||||
// Page -TRANSLATORS pay attention here, have fun! :-D
|
||||
'DICE_ROLL_PAGE_DICE_TESTER' => 'Dice tester',
|
||||
'DICE_ROLL_PAGE_RESULT' => 'Result',
|
||||
'DICE_ROLL_PAGE_LIMITATIONS' => 'Limitations',
|
||||
'DICE_ROLL_PAGE_UNLIMITED' => 'Unlimited',
|
||||
'DICE_ROLL_PAGE_ROLLS_POST' => 'Rolls per post',
|
||||
'DICE_ROLL_PAGE_DICE_QTY' => 'Dice quantity',
|
||||
'DICE_ROLL_PAGE_SIDES_DICE' => 'Sides per dice',
|
||||
'DICE_ROLL_PAGE_ALLOWED_SIDES' => 'Allowed sides',
|
||||
'DICE_ROLL_PAGE_ONLY_ALLOWED_SIDES' => 'Only available sides',
|
||||
'DICE_ROLL_PAGE_AVAIL_SIDES' => 'Available sides',
|
||||
'DICE_ROLL_PAGE_FUDGE_DICE' => 'Fudge dice',
|
||||
'DICE_ROLL_PAGE_PERCENT_DICE' => 'Percentage dice',
|
||||
'DICE_ROLL_PAGE_EXPLODING_DICE' => 'Exploding dice',
|
||||
'DICE_ROLL_PAGE_PENETRATING_DICE' => 'Penetrating dice',
|
||||
'DICE_ROLL_PAGE_COMPOUNDING_DICE' => 'Compounding dice',
|
||||
'DICE_ROLL_PAGE_P_1_TITLE' => 'Explanation',
|
||||
'DICE_ROLL_PAGE_P_1' => 'The standard notation formats are accepted, such as <span class="dice-example">2d6+12</span>, and also the use of <span class="dice-example">L</span> or <span class="dice-example">H</span> to represent the lowest or highest roll respectively.
|
||||
For example: <span class="dice-example">4d6-L</span> (A roll of 4 six-sided dice, dropping the lowest result).
|
||||
|
||||
You can also use multiply and divide mathematical operators; 1d6*5 or 2d10/d20.
|
||||
However, the use of the mathematical symbols <span class="dice-example">×</span> and <span class="dice-example">÷</span> do not work.',
|
||||
|
||||
'DICE_ROLL_PAGE_LIST_1' => 'd6 or 1d',
|
||||
'DICE_ROLL_PAGE_LIST_1_2' => 'A 6 sided die',
|
||||
'DICE_ROLL_PAGE_LIST_2' => '2d6',
|
||||
'DICE_ROLL_PAGE_LIST_2_2' => 'Two 6 sided dice',
|
||||
'DICE_ROLL_PAGE_LIST_3' => '1d6+4',
|
||||
'DICE_ROLL_PAGE_LIST_3_2' => 'Roll a 6 sided dice and add 4 to the result',
|
||||
'DICE_ROLL_PAGE_LIST_4' => '2d10*4+1d20',
|
||||
'DICE_ROLL_PAGE_LIST_4_2' => 'Roll two 10 sided dice multiply by four, and roll one 20 sided die',
|
||||
'DICE_ROLL_PAGE_LIST_5' => '2d10+4+2d20-L',
|
||||
'DICE_ROLL_PAGE_LIST_5_2' => 'Roll two 10 sided dice add four, and roll two 20 sided die, taking away the lowest of the two',
|
||||
'DICE_ROLL_PAGE_LIST_6' => 'd%',
|
||||
'DICE_ROLL_PAGE_LIST_6_2' => 'A percentile die - equivalent to d100',
|
||||
'DICE_ROLL_PAGE_LIST_7' => 'dF or dF.2',
|
||||
'DICE_ROLL_PAGE_LIST_7_2' => 'A standard fudge dice - 2 thirds of each symbol',
|
||||
'DICE_ROLL_PAGE_LIST_8' => 'dF.1',
|
||||
'DICE_ROLL_PAGE_LIST_8_2' => 'A non-standard fudge dice - 1 positive, 1 negative, 4 blank',
|
||||
'DICE_ROLL_PAGE_LIST_9' => '2d6!',
|
||||
'DICE_ROLL_PAGE_LIST_9_2' => 'Exploding dice - two 6 sided die, rolling again for each roll of the maximum value',
|
||||
'DICE_ROLL_PAGE_LIST_10' => '2d6!!',
|
||||
'DICE_ROLL_PAGE_LIST_10_2' => 'Exploding & compounding dice - like exploding, but adding together into single roll',
|
||||
'DICE_ROLL_PAGE_LIST_11' => '2d6!p',
|
||||
'DICE_ROLL_PAGE_LIST_11_2' => 'Penetrating dice - like exploding, but subtract 1 from each consecutive roll',
|
||||
'DICE_ROLL_PAGE_LIST_12' => '2d6!!p',
|
||||
'DICE_ROLL_PAGE_LIST_12_2' => 'Penetrating & compounding dice - like exploding & compounding, but subtract 1 from each consecutive roll',
|
||||
'DICE_ROLL_PAGE_LIST_13' => '2d6!>=4',
|
||||
'DICE_ROLL_PAGE_LIST_13_2' => 'Exploding dice, but only if you roll a 4 or greater - Also usable with compounding and penetrating dice',
|
||||
'DICE_ROLL_PAGE_LIST_14' => '2d6>4',
|
||||
'DICE_ROLL_PAGE_LIST_14_2' => 'Dice pool - anything greater than a 4 is a success. Counts the number of successes as the total',
|
||||
|
||||
'DICE_ROLL_PAGE_P_2_TITLE' => 'Percentile dice',
|
||||
'DICE_ROLL_PAGE_P_2' => 'Although percentile dice can be rolled by using a <span class="dice-example">d100</span>, you can also use d%, which will do the same thing, returning a number between 0 and 100.',
|
||||
'DICE_ROLL_PAGE_P_3_TITLE' => 'Exploding dice',
|
||||
'DICE_ROLL_PAGE_P_3' => 'To explode a dice, add an exclamation mark after the die sides: <span class="dice-example">4d10!</span><br>
|
||||
Exploding dice roll an additional die if the maximum, on that die, is rolled.
|
||||
If that die is also the maximum it is rolled again, and so forth, until a roll is made that is not the maximum.
|
||||
For example: rolling a 6 on a d6, or a 10 on a d10.',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_1_TITLE' => '2d6!: [4, 6!, 6!, 2] = 20',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_1' => 'Each exploded die shows as a separate roll in the list, like shown above.
|
||||
Where the second roll exploded, so we rolled again, which also exploded.
|
||||
The fourth role, however, did not, so we stop rolling.',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_2_TITLE' => '1d6!-L: [6!,6!,6!,3]-L = 18',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_2' => 'You can even use <span class="dice-example">L</span> and <span class="dice-example">H</span>, which will look at exploded dice, as well as normal rolls.
|
||||
Here the die exploded three times before not rolling a maximum. The last roll was subtracted from the total.',
|
||||
'DICE_ROLL_PAGE_P_4_TITLE' => 'Compounding',
|
||||
'DICE_ROLL_PAGE_P_4' => 'Sometimes, you may want the exploded dice rolls to be added together under the same, original roll.
|
||||
In this situation, you can compound the dice by using two exclamation marks: <span class="dice-example">4d10!!</span>.
|
||||
For example <em>(using the examples of exploding dice above)</em>',
|
||||
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_1' => '2d6!!: [4, 14!!] = 20',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_1_2' => 'the exploded dice rolls of [6, 6, 2] are added together',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_2' => '1d6!!-L: [21!!]-L = 18',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_2_2' => 'the exploded dice rolls of [6, 6, 6, 3] are added together',
|
||||
|
||||
'DICE_ROLL_PAGE_P_5_TITLE' => 'Penetrating',
|
||||
'DICE_ROLL_PAGE_P_5' => 'Some exploding dice system use a penetrating rule. Taken from the <a href="https://www.kenzerco.com/free_files/hackmaster_basic_free_.pdf#page=51" target="_blank">Hackmaster Basic</a> rules',
|
||||
'DICE_ROLL_PAGE_P_6' => 'Should you roll the maximum value on this particular die, you may re-roll and add the result of the extra die, less one point, to the total (penetration can actually result in simply the maximum die value if a 1 is subsequently rolled, since any fool knows that 1-1=0).
|
||||
This process continues indefinitely as long as the die in question continues to come up maximum (but there’s always only a –1 subtracted from the extra die, even if it’s, say, the third die of penetration).',
|
||||
'DICE_ROLL_PAGE_P_7' => 'So, if you rolled <span class="dice-example">1d6</span> (penetrating), and got a 6, you would roll another <span class="dice-example">d6</span>, subtracting 1 from the result.
|
||||
If that <span class="dice-example">d6</span> rolled a 6 (before the -1) it would penetrate, and so on.
|
||||
The syntax for penetrating is very similar to exploding, but with a lowercase <strong>p</strong> appended, like <span class="dice-example">2d6!p</span>.
|
||||
For example <em>(Using the same example from exploding dice above)</em>',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_3' => '2d6!p: [4, 6!p, 5, 1] = 20',
|
||||
'DICE_ROLL_PAGE_P_8' => 'Where the second roll exploded, so we rolled again, which also exploded (rolled a 6). The fourth role, however, rolled a 2, so did not penetrate, so we stop rolling.
|
||||
Remember that we subtract 1 from penetrated rolls, which is why we show 5 and 1, instead of 6, and 2.
|
||||
<br>
|
||||
You can also compound penetrating dice, like so: <span class="dice-example">2d6!!p</span>',
|
||||
'DICE_ROLL_PAGE_P_9_TITLE' => 'Compare point',
|
||||
'DICE_ROLL_PAGE_P_9' => 'By default, exploding and penetrating dice do so if you roll the highest number possible on the dice (ie. a 6 on a <span class="dice-example">d6</span>, a 1 on a Fudge die).
|
||||
You can easily change the exploding compare point by adding a comparison after it.',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_4_TITLE' => 'To explode only if you roll a 4',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_4' => '2d6!=4',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_5_TITLE' => 'Or exploding if you roll anything over a 4',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_5' => '2d6!>4',
|
||||
'DICE_ROLL_PAGE_P_10' => 'You can also use this with penetrating and compounding dice',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_6_TITLE' => 'compound if you roll a 4 or lower',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_6' => '2d6!!<=4',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_7_TITLE' => 'penetrate if you do not roll a 4',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_7' => '2d6!p!=4',
|
||||
'DICE_ROLL_PAGE_P_11_TITLE' => 'Fudge dice',
|
||||
'DICE_ROLL_PAGE_P_11' => 'Fudge notation is also supported. It allows both <span class="dice-example">dF.2</span> and less common <span class="dice-example">dF.1</span>.<br>
|
||||
You can also use it in conjunction with other operators and additions. Examples',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_8_TITLE' => 'dF',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_8' => 'this is the same as',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_8_BIS' => 'dF.2',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_9_TITLE' => '4dF.2',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_9' => 'roll 4 standard fudge dice',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_10_TITLE' => '4dF.2-L',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_10' => 'roll 4 standard fudge dice, subtracting the lowest result',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_11_TITLE' => 'dF.1*2',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_11' => 'roll non-standard fudge dice, multiplying the result by 2',
|
||||
'DICE_ROLL_PAGE_P_12_TITLE' => 'Dice pools',
|
||||
'DICE_ROLL_PAGE_P_12' => 'Some systems use dice pool, whereby the total is equal to the number of dice rolled that meet a fixed condition, rather than the total value of the rolls.
|
||||
For example, a <strong>pool</strong> of 10 sided dice where you count the number of dice that roll an 8 or higher as <strong>successes</strong>.
|
||||
This can be achieved with: <span class="dice-example">5d10>=8</span>.<br>
|
||||
You can define various success conditions, by simply adding number comparisons directly after the dice roll.<br>
|
||||
Because of this, you can <strong>not</strong> have a pool dice that also explodes. Examples',
|
||||
'DICE_ROLL_PAGE_P_13' => 'You can mix pool dice with other dice types or equations, and it will use the number of successes as the value in the equation',
|
||||
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_3' => '2d6=6: [4,6*] = 1',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_3_2' => 'only a roll of 6 is a success',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_4' => '4d3>1: [1,3*,2*,1] = 2',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_4_2' => 'higher than a 1 is a success',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_5' => '4d3<2: [1*,3,2,1*] = 2',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_5_2' => 'lower than a 2 is a success',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_6' => '5d8>=5: [2,4,6*,3,8*] = 2',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_6_2' => 'higher than or equal to 5 is a success',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_7' => '6d10<=4: [7,2*,10,3*,3*,4*] = 4',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_7_2' => 'less than or equal to 4 is a success',
|
||||
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_8' => '2d6>4+3d5: [4,5*]+[3,1,1] = 6',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_8_2' => '1 success + the raw values of the other rolls',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_9' => '2d6>4*d6!: [6*,5*]*[6!,4] = 20',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_9_2' => '1 success * raw values of the other rolls',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_10' => '2d6>4+2: [3,5*]+2 = 3',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_10_2' => '1 success + 2',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_11' => '2d6>4+H: [3,5*]+H = 2',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_11_2' => 'Highest roll is 5, which is a success, so value of 1',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_12' => '2d6<4+H: [3*,5]+H = 1',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_12_2' => 'Highest roll is 5, which is a failure, so value of 0',
|
||||
]);
|
||||
60
ext/phpbbstudio/dice/language/en/dice_exceptions.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'EXCEPTION_OUT_OF_BOUNDS' => 'The field `<strong>%1$s</strong>` received data beyond its bounds. Reason: %2$s',
|
||||
'EXCEPTION_UNEXPECTED_VALUE' => 'The field `<strong>%1$s</strong>` received unexpected data. Reason: %2$s',
|
||||
|
||||
'EXCEPTION_ROLL_EDIT_COUNT' => 'Roll edit count',
|
||||
'EXCEPTION_ROLL_EDIT_TIME' => 'Roll edit time',
|
||||
'EXCEPTION_ROLL_EDIT_USER' => 'Edit user identifier',
|
||||
'EXCEPTION_ROLL_DICE_COMPOUND' => 'Compounding dice (<span class="error">!!</span>)',
|
||||
'EXCEPTION_ROLL_DICE_EXPLODE' => 'Exploding dice (<span class="error">!, !!, !p</span>)',
|
||||
'EXCEPTION_ROLL_DICE_FUDGE' => 'Fudge dice (<span class="error">F</span>)',
|
||||
'EXCEPTION_ROLL_DICE_PENETRATE' => 'Penetrating dice (<span class="error">!p</span>)',
|
||||
'EXCEPTION_ROLL_DICE_PERCENT' => 'Percentage dice (d<span class="error">%</span> or d<span class="error">100</span>)',
|
||||
'EXCEPTION_ROLL_DICE_QTY' => 'Dice quantity (<span class="error">X</span>d6)',
|
||||
'EXCEPTION_ROLL_DICES' => 'Dices',
|
||||
'EXCEPTION_ROLL_DICES_QTY' => 'Dice quantities (<span class="error">X</span>d6 + <span class="error">X</span>d6)',
|
||||
'EXCEPTION_ROLL_FORUM_ID' => 'Forum identifier',
|
||||
'EXCEPTION_ROLL_ID' => 'Roll identifier',
|
||||
'EXCEPTION_ROLL_NOTATION' => 'Roll notation',
|
||||
'EXCEPTION_ROLL_POST_ID' => 'Post identifier',
|
||||
'EXCEPTION_ROLL_REGEX_NAME' => 'Regex name',
|
||||
'EXCEPTION_ROLL_SIDES' => 'Dice sides (1d<span class="error">X</span>)',
|
||||
'EXCEPTION_ROLL_TIME' => 'Roll time',
|
||||
'EXCEPTION_ROLL_TOPIC_ID' => 'Topic identifier',
|
||||
'EXCEPTION_ROLL_USER_ID' => 'User identifier',
|
||||
|
||||
'EXCEPTION_FIELD_MISSING' => 'Required field missing.',
|
||||
'EXCEPTION_NOT_ALLOWED' => 'The input is not allowed.',
|
||||
'EXCEPTION_ROLL_ALREADY_EXIST' => 'The provided roll already exists.',
|
||||
'EXCEPTION_ROLL_NO_MATCHES' => 'No dice matches found for provided notation.',
|
||||
'EXCEPTION_ROLL_NOT_EXIST' => 'The provided roll does not exist.',
|
||||
'EXCEPTION_ROLL_NAME_NOT_FOUND' => 'The provided regex name could not be found.',
|
||||
|
||||
// TRANSLATORS pay attention here
|
||||
'EXCEPTION_ROLL_ULINT' => 'The input is not in the rage of 0 to 4 294 967 295.', // Leave   in place (non-breaking thin space)
|
||||
'EXCEPTION_ROLL_USINT' => 'The input is not in the rage of 0 to 65 535.', // Leave   in place (non-breaking thin space)
|
||||
|
||||
'EXCEPTION_TOO_LONG' => 'The input was longer than the maximum length.',
|
||||
'EXCEPTION_TOO_HIGH' => 'The input was higher than the maximum value.',
|
||||
]);
|
||||
26
ext/phpbbstudio/dice/language/en/ext_require.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'ERROR_PHPBB_VERSION' => 'Minimum phpBB version required is %1$s but less than %2$s',
|
||||
'ERROR_PHP_VERSION' => 'PHP version must be equal or greater than 5.5',
|
||||
'ERROR_GLOB_STREAM' => 'The stream GLOB is not available in your system.',
|
||||
]);
|
||||
53
ext/phpbbstudio/dice/language/en/info_acp_dice.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
// Cat
|
||||
'ACL_CAT_PHPBB_STUDIO' => 'phpBB Studio',
|
||||
|
||||
// ACP forums
|
||||
'ACP_DICE_SETTINGS' => 'Dice settings',
|
||||
'ACP_DICE_ENABLE' => 'Enable dice',
|
||||
'ACP_DICE_ENABLE_DESC' => 'Enables the dice extension in this forum. The dice BBCode will only be enabled for users who have the permission to roll the dice in this forum.',
|
||||
'ACP_DICE_F_SKIN' => 'Dice skin',
|
||||
'ACP_DICE_F_SKIN_DESC' => 'The default dice skin for dice rolls in this forum.',
|
||||
'ACP_DICE_SKIN_OVERRIDE' => 'Override dice skin',
|
||||
'ACP_DICE_SKIN_OVERRIDE_DESC' => 'Replaces user’s dice skin with the skin as defined under “Dice skin”.',
|
||||
|
||||
// ACP
|
||||
'ACP_DICE_CAT' => 'phpBB Studio - Dice',
|
||||
'ACP_DICE_DASH' => 'Diceboard',
|
||||
|
||||
'ACP_DICE_SIDES' => 'Dice sides',
|
||||
'ACP_DICE_SIDES_SHORT' => 'Sides',
|
||||
|
||||
'ACP_DICE_SKINS' => 'Dice skins',
|
||||
'ACP_DICE_SKINS_SHORT' => 'Skins',
|
||||
|
||||
// Log
|
||||
'LOG_ACP_DICE_LOCATIONS' => '<strong>Altered dice link locations</strong>',
|
||||
'LOG_ACP_DICE_ORPHANED' => '<strong>Deleted orphaned dice rolls</strong><br />» %s deleted',
|
||||
'LOG_ACP_DICE_SETTINGS' => '<strong>Altered dice settings</strong>',
|
||||
'LOG_ACP_DICE_SIDE_ADD' => '<strong>Added new dice side</strong><br />» %s',
|
||||
'LOG_ACP_DICE_SIDE_DELETE' => '<strong>Deleted dice side</strong><br />» %s',
|
||||
'LOG_ACP_DICE_SKIN_INSTALL' => '<strong>Installed new dice skin</strong><br />» %s',
|
||||
'LOG_ACP_DICE_SKIN_UNINSTALL' => '<strong>Uninstalled dice skin</strong><br />» %s',
|
||||
]);
|
||||
30
ext/phpbbstudio/dice/language/en/info_ucp_dice.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'UCP_DICE_TITLE' => 'Dice',
|
||||
'UCP_DICE' => 'Settings',
|
||||
|
||||
'UCP_DICE_USER' => 'Dice mode',
|
||||
'UCP_DICE_USER_EXPLAIN' => 'Default display skin for dice rolls.',
|
||||
|
||||
'UCP_DICE_SAVED' => 'Settings have been saved successfully!',
|
||||
]);
|
||||
38
ext/phpbbstudio/dice/language/en/permissions_dice.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'ACL_F_DICE_ROLL' => '<strong>Dice</strong> - Can roll dice',
|
||||
'ACL_F_DICE_EDIT' => '<strong>Dice</strong> - Can edit a rolled dice',
|
||||
'ACL_F_DICE_DELETE' => '<strong>Dice</strong> - Can delete own dice',
|
||||
'ACL_F_DICE_NO_LIMIT' => '<strong>Dice</strong> - Can ignore dice limit per post',
|
||||
'ACL_F_DICE_VIEW' => '<strong>Dice</strong> - Can view rolled dice',
|
||||
|
||||
'ACL_F_MOD_DICE_ADD' => '<strong>Dice</strong> - <strong><em>Mod:</em></strong> Can roll dice on other users´s post',
|
||||
'ACL_F_MOD_DICE_EDIT' => '<strong>Dice</strong> - <strong><em>Mod:</em></strong> Can edit rolled dice on other users´s post',
|
||||
'ACL_F_MOD_DICE_DELETE' => '<strong>Dice</strong> - <strong><em>Mod:</em></strong> Can delete dice on other users´s post',
|
||||
|
||||
'ACL_A_DICE_ADMIN' => '<strong>Dice</strong> - Can administer the extension',
|
||||
|
||||
'ACL_U_DICE_USE_UCP' => '<strong>Dice</strong> - Can manage the Dice UCP',
|
||||
'ACL_U_DICE_TEST' => '<strong>Dice</strong> - Can use the “Test notation” page',
|
||||
'ACL_U_DICE_SKIN' => '<strong>Dice</strong> - Can ignore overriding forum skins<br><em>The user selected skin will be used, even when the forum skin is set to “override”.</em>',
|
||||
]);
|
||||
130
ext/phpbbstudio/dice/language/es/acp_dice.php
Normal file
@@ -0,0 +1,130 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'ACP_DICE_DICE' => [
|
||||
1 => '%d dado', // One dice
|
||||
2 => '%d dados', // Two dice (don't we love the English language)
|
||||
],
|
||||
|
||||
'ACP_DICE_ENJOY' => 'Disfrute',
|
||||
|
||||
'ACP_DICE_EXAMPLE' => 'Ejemplo',
|
||||
'ACP_DICE_EXAMPLE_1' => 'Hay un total de 3 tiradas en este mensaje, que pueden limitarse con <em>Máximas tiradas por mensaje</em>',
|
||||
'ACP_DICE_EXAMPLE_2' => 'Cada tirada consta de múltiples <em>(tipos de)</em> dados',
|
||||
'ACP_DICE_EXAMPLE_3' => 'Cada tirada tiene una cantidad total de dados',
|
||||
'ACP_DICE_EXAMPLE_4' => 'Cada dado tiene una cantidad de dados',
|
||||
'ACP_DICE_EXAMPLE_5' => 'Cada dado tiene lados',
|
||||
|
||||
'ACP_DICE_INVALID' => 'Inválida',
|
||||
'ACP_DICE_VALID' => 'Válida',
|
||||
'ACP_DICE_VALID_ALL' => '¡Todas las skins instaladas son válidas!',
|
||||
'ACP_DICE_VALID_NOT_ALL' => '¡No todas las skins instaladas son válidas!',
|
||||
|
||||
'ACP_DICE_INSTALLED' => 'Instalado',
|
||||
'ACP_DICE_INSTALLED_NOT' => 'No instalado',
|
||||
'ACP_DICE_INSTALLED_IN' => 'Directorio de instalación',
|
||||
|
||||
'ACP_DICE_LOCATIONS' => 'Ubicaciones de enlace de dados',
|
||||
'ACP_DICE_LOCATIONS_DESC' => 'Seleccione una o más ubicaciones donde debería aparecer el enlace a la página de dados.',
|
||||
'ACP_DICE_LOCATIONS_EXPLAIN' => 'Este es un ejemplo de un índice de foro. Aquí puede seleccionar dónde desea que aparezca el enlace de la página de dados. Puede seleccionar tantos lugares como desee, desde nada a cualquier lugar.<br>Las limitaciones de dados establecidas por un Administrador y el FAQ sobre los dados. Todo se proporciona para comprender completamente todas las posibilidades de los dados.',
|
||||
'ACP_DICE_LOCATIONS_SUCCESS' => 'Ha alterado correctamente las ubicaciones de enlace de dados.',
|
||||
|
||||
'ACP_DICE_ORPHANED' => 'Eliminar tiradas huérfanas',
|
||||
'ACP_DICE_ORPHANED_CONFIRM' => '¿Está seguro de que desea eliminar todas las tiradas de dados huérfanas?<br>Esto eliminará todas las tiradas que no pertenecen a un foro, tema o mensaje.<br>Los usuarios que actualmente están creando un mensaje con una tirada, también tendrán su tirada eliminada.',
|
||||
'ACP_DICE_ORPHANED_SUCCESS' => 'Ha eliminado correctamente todas las tiradas huérfanas.',
|
||||
|
||||
'ACP_DICE_ROLL_NR' => 'Tirada %d', // Roll 1, Roll 2, etc..
|
||||
'ACP_DICE_ROLLS' => 'Tiradas de dados',
|
||||
'ACP_DICE_ROLLS_SHORT' => 'Tiradas',
|
||||
'ACP_DICE_ROLLS_DB' => 'Tiradas en la base de datos',
|
||||
'ACP_DICE_ROLLS_NONE' => 'No hay tiradas de dados.',
|
||||
|
||||
'ACP_DICE_SETTINGS_EXAMPLE' => 'Clic aquí para ver el ejemplo.',
|
||||
'ACP_DICE_SETTINGS_EXPLAIN' => 'La terminología en esta extensión puede ser bastante complicada, ya que muchas cosas tienen potencialmente el mismo nombre. Por eso hemos creado un ejemplo para ilustrar mejor, qué es qué.',
|
||||
|
||||
'ACP_DICE_SIDE_ADD' => 'Añadir un lado',
|
||||
'ACP_DICE_SIDE_ADD_CONFIRM' => '¿Está seguro de que desea añadir este lado de los dados?',
|
||||
'ACP_DICE_SIDE_ADD_SUCCESS' => 'Ha añadido correctamente <strong>%s</strong> como un lado de dados.',
|
||||
'ACP_DICE_SIDE_DELETE' => 'Borrar lado',
|
||||
'ACP_DICE_SIDE_DELETE_CONFIRM' => '¿Está seguro de que desea eliminar este lado de los dados?',
|
||||
'ACP_DICE_SIDE_DELETE_SUCCESS' => 'Ha eliminado correctamente <strong>%s</strong> como un lado de dados.',
|
||||
'ACP_DICE_SIDES_AVAILABLE' => 'Lados disponibles',
|
||||
'ACP_DICE_SIDES_EXPLAIN' => 'Los lados permitidos que los usuarios pueden usar en sus notaciones de dados. Las skins son válidas cuando tienen imágenes para todos los lados que se proporcionadas aquí. Por ejemplo, lados: <small><samp>4, 5</samp></small>. Imágenes: <small><samp>d4_1 a d4_4, d5_1 a d5_5</samp></small>',
|
||||
'ACP_DICE_SIDES_NONE' => 'No hay lados de dados.',
|
||||
'ACP_DICE_SIDES_ONLY' => 'Solo lados disponibles',
|
||||
'ACP_DICE_SIDES_ONLY_DESC' => 'Si esta configuración está habilitada, los usuarios solo pueden usar los lados de los dados disponibles.',
|
||||
'ACP_DICE_SIDES_ONLY_STATS' => 'Los usuarios solo pueden usar los lados de los dados disponibles.',
|
||||
'ACP_DICE_SIDES_ONLY_UPTO' => 'Los usuarios pueden usar hasta %d lados de dados.',
|
||||
'ACP_DICE_SIDES_ONLY_UNLIMITED' => 'Los usuarios pueden usar lados de dados ilimitados.',
|
||||
|
||||
'ACP_DICE_SKIN_INSTALL' => 'Instalar skin',
|
||||
'ACP_DICE_SKIN_INSTALL_CONFIRM' => '¿Está seguro de que desea instalar esta skin de dados?',
|
||||
'ACP_DICE_SKIN_INSTALL_SUCCESS' => 'Ha instalado correctamente <strong>%s</strong> como una skin de dados.',
|
||||
'ACP_DICE_SKIN_UNINSTALL' => 'Desinstalar skin',
|
||||
'ACP_DICE_SKIN_UNINSTALL_CONFIRM' => '¿Está seguro de que desea desinstalar esta skin de dados?',
|
||||
'ACP_DICE_SKIN_UNINSTALL_SUCCESS' => 'Ha desinstalado correctamente <strong>%s</strong> como una skin de dados.',
|
||||
'ACP_DICE_SKINS_AVAILABLE' => 'Skins disponibles',
|
||||
'ACP_DICE_SKINS_INSTALLED' => 'Skins instaladas',
|
||||
'ACP_DICE_SKINS_EXPLAIN' => 'Las skins se encuentran automáticamente cuando se sube al directorio designado. Las imágenes deben ser nombradas correctamente. Por ejemplo, para un dado de 4 lados: <small><samp>d4_1.gif, d4_2.gif, d4_3.gif, d4_4.gif</samp></small>',
|
||||
'ACP_DICE_SKINS_NONE' => 'No hay skins de dados.',
|
||||
|
||||
'ACP_DICE_SUMMARY' => 'Resumen',
|
||||
|
||||
'ACP_DICE_TOP_TOPICS' => 'Temas Top',
|
||||
'ACP_DICE_TOP_TOPICS_DESC' => 'Lista de temas con más tiradas.',
|
||||
'ACP_DICE_TOP_USERS' => 'Usuarios Top',
|
||||
'ACP_DICE_TOP_USERS_DESC' => 'Lista de usuarios con más tiradas.',
|
||||
|
||||
'ACP_DICE_SKINS_DIR' => 'Directorio de imágenes de skins',
|
||||
'ACP_DICE_SKINS_DIR_DESC' => 'Esta ruta se utilizará para buscar skins. Cambiar esto reseteará las skins instaladas.<br><small>Ruta desde su directorio raíz de phpBB, por ejemplo: <samp>images/skins</samp></small>',
|
||||
'ACP_DICE_SKINS_PATH_ERROR' => 'El directorio "skins" que ha introducido no es válido.<br>El valor contiene los siguientes caracteres no admitidos: <br />%s',
|
||||
'ACP_DICE_SKINS_IMG_HEIGHT' => 'Altura de la imagen de skin',
|
||||
'ACP_DICE_SKINS_IMG_HEIGHT_DESC' => 'Altura de la imagen para las imágenes de skin de los dados. Debe tener entre 16 y 80 píxeles.',
|
||||
'ACP_DICE_SKINS_IMG_HEIGHT_ERROR' => 'La altura de la imagen que ingresó no es válida. El valor debe estar entre 16 y 80 píxeles.',
|
||||
'ACP_DICE_SKINS_IMG_WIDTH' => 'Anchura de la imagen de skin',
|
||||
'ACP_DICE_SKINS_IMG_WIDTH_DESC' => 'Anchura de la imagen para las imágenes de skin de los dados. Debe tener entre 16 y 80 píxeles.',
|
||||
'ACP_DICE_SKINS_IMG_WIDTH_ERROR' => 'La anchura de la imagen para las imágenes de skin de los dados. El valor debe tener entre 16 y 80 píxeles.',
|
||||
|
||||
'ACP_DICE_ZERO_UNLIMITED' => 'Establezca el valor en <strong>0</strong> para una cantidad ilimitada.',
|
||||
|
||||
// Settings
|
||||
'ACP_DICE_MAX_ROLLS' => 'Máximas tiradas por mensaje',
|
||||
'ACP_DICE_MAX_ROLLS_DESC' => 'El número máximo de tiradas que se pueden añadir por mensaje.',
|
||||
'ACP_DICE_PER_NOTATION' => 'Máximas dados por tirada',
|
||||
'ACP_DICE_PER_NOTATION_DESC' => 'La siguiente tirada tiene 2 dados: 5d6 <strong class="error">+</strong> 2d4',
|
||||
'ACP_DICE_QTY_PER_DICE' => 'Cantidad máxima de dados por tirada',
|
||||
'ACP_DICE_QTY_PER_DICE_DESC' => 'La siguiente tirada tiene una cantidad total de dados de 7: <strong class="error">5</strong>d6 + <strong class="error">2</strong>d4',
|
||||
'ACP_DICE_QTY_DICE_PER_NOTATION' => 'Cantidad máxima de dados por dado',
|
||||
'ACP_DICE_QTY_DICE_PER_NOTATION_DESC' => 'La siguiente tirada tiene 2 dados, ambos con una cantidad de dados de 3: <strong class="error">3</strong>d6 + <strong class="error">3</strong>d4',
|
||||
'ACP_DICE_SIDES_PER_DICE' => 'Lados máximos por dado',
|
||||
'ACP_DICE_SIDES_PER_DICE_DESC' => 'La siguiente tirada tiene 1 dado con 10 lados: 4d<strong class="error">10</strong>',
|
||||
'ACP_DICE_PC_DICE_PER_NOTATION' => 'Porcentaje máximo de dados por tirada',
|
||||
'ACP_DICE_PC_DICE_PER_NOTATION_DESC' => 'La siguiente tirada tiene 2 dados de porcentaje: 6d100 <strong class="error">+</strong> 3d%',
|
||||
'ACP_DICE_FUDGE_DICE_PER_NOTATION' => 'Dados de dulce de azúcar máximos por tirada',
|
||||
'ACP_DICE_FUDGE_DICE_PER_NOTATION_DESC' => 'La siguiente tirada tiene 1 dado de dulce de azúcar: 2d<strong class="error">F.2</strong> + 4d8',
|
||||
'ACP_DICE_EXPLODING_DICE_PER_NOTATION' => 'Dados de explosión máximos por tirada',
|
||||
'ACP_DICE_EXPLODING_DICE_PER_NOTATION_DESC' => 'La siguiente tirada tiene 1 dado de explosión: 2d6<strong class="error">!</strong> + 4d8',
|
||||
'ACP_DICE_PENETRATION_DICE_PER_NOTATION' => 'Dados penetrantes máximos por tirada',
|
||||
'ACP_DICE_PENETRATION_DICE_PER_NOTATION_DESC' => 'La siguiente tirada tiene 1 dado penetrante: 2d6<strong class="error">!p</strong> + 2d%',
|
||||
'ACP_DICE_COMPOUND_DICE_PER_NOTATION' => 'Dados de composición máximos por tirada',
|
||||
'ACP_DICE_COMPOUND_DICE_PER_NOTATION_DESC' => 'La siguiente tirada tiene 1 dado compuesto: 2d6<strong class="error">!!</strong> + 5d4',
|
||||
]);
|
||||
210
ext/phpbbstudio/dice/language/es/dice_common.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'DICE_DICE' => 'Dados',
|
||||
|
||||
'DICE_NOT_AJAX' => 'Las tiradas de dados se gestionan con solicitud AJAX. La solicitud actual no es AJAX y el servidor devolvió una respuesta no válida.',
|
||||
|
||||
'DICE_SKIN' => 'Skin del dado',
|
||||
|
||||
'DICE_ROLL' => 'Tirada de dados',
|
||||
'DICE_ROLL_ACTIONS' => 'Acciones',
|
||||
'DICE_ROLL_ADD_UNAUTH' => 'No está autorizado para añadir una tirada.',
|
||||
'DICE_ROLL_ADD_SUCCESS' => 'Ha añadido correctamente una tirada.',
|
||||
'DICE_ROLL_EDIT' => 'Editar tirada',
|
||||
'DICE_ROLL_EDIT_UNAUTH' => 'No está autorizado para editar esta tirada.',
|
||||
'DICE_ROLL_EDIT_CONFIRM' => 'Al editar una tirada desaparecerá completamente. ¡Esta acción no se puede deshacer!',
|
||||
'DICE_ROLL_EDIT_SUCCESS' => 'Ha editado correctamente esta tirada.',
|
||||
'DICE_ROLL_DELETE' => 'Borrar tirada',
|
||||
'DICE_ROLL_DELETE_UNAUTH' => 'No está autorizado para borrar esta tirada.',
|
||||
'DICE_ROLL_DELETE_CONFIRM' => '¿Está seguro de querer borrar esta tirada?',
|
||||
'DICE_ROLL_DELETE_SUCCESS' => 'Ha borrado correctamente esta tirada.',
|
||||
'DICE_ROLL_DICE' => 'Tirada de dados',
|
||||
'DICE_ROLL_FORUM_DISABLED' => 'La tiradas de dados se han deshabilitado para este foro',
|
||||
'DICE_ROLL_ID' => 'ID de tirada',
|
||||
'DICE_ROLL_LIMIT_REACHED' => 'Límite de dados alcanzado',
|
||||
'DICE_ROLL_NO_ROLL' => 'No se tiraron dados.',
|
||||
|
||||
'DICE_ROLL_NOT_EXIST' => [
|
||||
1 => 'La tirada provista no existe.',
|
||||
2 => 'Las tiradas provistas no existen.',
|
||||
],
|
||||
'DICE_ROLL_NOTATION' => 'Notación de tiradas',
|
||||
'DICE_ROLL_NOTATION_CURRENT' => 'Notación actual de tirada',
|
||||
'DICE_ROLL_NOTATION_NEW' => 'Nueva notación de tirada',
|
||||
'DICE_ROLL_TIME' => 'Fecha de tirada',
|
||||
'DICE_ROLLS' => 'Tiradas de dados',
|
||||
'DICE_ROLLS_EXPLAIN' => 'Si desea añadir una o más tiradas, ingrese una notación de tirada y tire los dados. Puede colocarlo en línea en el cuadro de mensaje o editarlo/borrarlo a su voluntad más adelante.',
|
||||
'DICE_ROLLS_TOO_MANY' => 'Ya ha tirado demasiados dados para este mensaje.',
|
||||
'DICE_TEXT' => 'Texto',
|
||||
|
||||
// Dice states
|
||||
'DICE_ROLL_COMPOUNDED' => 'Compuesto',
|
||||
'DICE_ROLL_EXPLODED' => 'Explosivo',
|
||||
'DICE_ROLL_HIGHEST' => 'Superior',
|
||||
'DICE_ROLL_LOWEST' => 'Inferior',
|
||||
'DICE_ROLL_PENETRATED' => 'Penetrado',
|
||||
'DICE_ROLL_SUCCESS' => 'Acierto',
|
||||
|
||||
// Page -TRANSLATORS pay attention here, have fun! :-D
|
||||
'DICE_ROLL_PAGE_DICE_TESTER' => 'Prueba de dados',
|
||||
'DICE_ROLL_PAGE_RESULT' => 'Resultado',
|
||||
'DICE_ROLL_PAGE_LIMITATIONS' => 'Limitaciones',
|
||||
'DICE_ROLL_PAGE_UNLIMITED' => 'Ilimitado',
|
||||
'DICE_ROLL_PAGE_ROLLS_POST' => 'Tiradas por mensaje',
|
||||
'DICE_ROLL_PAGE_DICE_QTY' => 'Cantidad de dados',
|
||||
'DICE_ROLL_PAGE_SIDES_DICE' => 'Lados por dado',
|
||||
'DICE_ROLL_PAGE_ALLOWED_SIDES' => 'Lados permitidos',
|
||||
'DICE_ROLL_PAGE_ONLY_ALLOWED_SIDES' => 'Solo lados disponibles',
|
||||
'DICE_ROLL_PAGE_AVAIL_SIDES' => 'Lados disponibles',
|
||||
'DICE_ROLL_PAGE_FUDGE_DICE' => 'Dados de dulce de azúcar',
|
||||
'DICE_ROLL_PAGE_PERCENT_DICE' => 'Dados de porcentaje',
|
||||
'DICE_ROLL_PAGE_EXPLODING_DICE' => 'Dados explosivos',
|
||||
'DICE_ROLL_PAGE_PENETRATING_DICE' => 'Dados penetrantes',
|
||||
'DICE_ROLL_PAGE_COMPOUNDING_DICE' => 'Dados compuestos',
|
||||
'DICE_ROLL_PAGE_P_1_TITLE' => 'Explicación',
|
||||
'DICE_ROLL_PAGE_P_1' => 'Se aceptan los formatos de notación estándar, tales como <span class="dice-example">2d6+12</span>, y también el uso de <span class="dice-example">L</span> o <span class="dice-example">H</span> para representar la tirada más baja o más alta respectivamente.
|
||||
Por ejemplo: <span class="dice-example">4d6-L</span> (Una tirada de 4 dados de seis caras, arrojando el resultado más bajo).
|
||||
|
||||
También puede usar operaciones para multiplicar y dividir, con sus operadores matemáticos; 1d6*5 o 2d10/d20.
|
||||
Sin embargo, el uso de los símbolos matemáticos <span class="dice-example">×</span> y <span class="dice-example">÷</span> no funcionan.',
|
||||
|
||||
'DICE_ROLL_PAGE_LIST_1' => 'd6 o 1d',
|
||||
'DICE_ROLL_PAGE_LIST_1_2' => 'Un dado de 6 caras',
|
||||
'DICE_ROLL_PAGE_LIST_2' => '2d6',
|
||||
'DICE_ROLL_PAGE_LIST_2_2' => 'Dos dados de 6 caras',
|
||||
'DICE_ROLL_PAGE_LIST_3' => '1d6+4',
|
||||
'DICE_ROLL_PAGE_LIST_3_2' => 'Tire un dado de 6 caras y sume 4 al resultado',
|
||||
'DICE_ROLL_PAGE_LIST_4' => '2d10*4+1d20',
|
||||
'DICE_ROLL_PAGE_LIST_4_2' => 'Tire dos dados de 10 caras, multiplique por cuatro, y tire un dado de 20 caras',
|
||||
'DICE_ROLL_PAGE_LIST_5' => '2d10+4+2d20-L',
|
||||
'DICE_ROLL_PAGE_LIST_5_2' => 'Tire dos dados de 10 caras añade cuatro, y tire dos dados de 20 caras, quitando el más bajo de los dos',
|
||||
'DICE_ROLL_PAGE_LIST_6' => 'd%',
|
||||
'DICE_ROLL_PAGE_LIST_6_2' => 'Un dado de porcentaje - equivalente a d100',
|
||||
'DICE_ROLL_PAGE_LIST_7' => 'dF o dF.2',
|
||||
'DICE_ROLL_PAGE_LIST_7_2' => 'Un dado estándar de dulce de azúcar - 2 tercios de cada símbolo',
|
||||
'DICE_ROLL_PAGE_LIST_8' => 'dF.1',
|
||||
'DICE_ROLL_PAGE_LIST_8_2' => 'Un dado de dulce de azúcar no estándar - 1 positivo, 1 negativo, 4 en blanco',
|
||||
'DICE_ROLL_PAGE_LIST_9' => '2d6!',
|
||||
'DICE_ROLL_PAGE_LIST_9_2' => 'Dados explosivos - dos dados de 6 caras, que se vuelven a tirar por cada tirada del valor máximo',
|
||||
'DICE_ROLL_PAGE_LIST_10' => '2d6!!',
|
||||
'DICE_ROLL_PAGE_LIST_10_2' => 'Dados explosivos y compuestos - como explosivo, pero sumados en una sola tirada',
|
||||
'DICE_ROLL_PAGE_LIST_11' => '2d6!p',
|
||||
'DICE_ROLL_PAGE_LIST_11_2' => 'Dados penetrantes - como explosivo, pero restar 1 de cada tirada consecutiva',
|
||||
'DICE_ROLL_PAGE_LIST_12' => '2d6!!p',
|
||||
'DICE_ROLL_PAGE_LIST_12_2' => 'Dados penetrantes y compuestos - como explosivo y compuesto, pero restar 1 de cada tirada consecutiva',
|
||||
'DICE_ROLL_PAGE_LIST_13' => '2d6!>=4',
|
||||
'DICE_ROLL_PAGE_LIST_13_2' => 'Dados explosivos, pero solo si saca un 4 o mayor - También se puede usar con dados de composición y penetrantes',
|
||||
'DICE_ROLL_PAGE_LIST_14' => '2d6>4',
|
||||
'DICE_ROLL_PAGE_LIST_14_2' => 'Grupo de dados - cualquier cosa mayor que un 4 es un acierto. Cuenta el número de aciertos como el total',
|
||||
|
||||
'DICE_ROLL_PAGE_P_2_TITLE' => 'Dado de porcentaje',
|
||||
'DICE_ROLL_PAGE_P_2' => 'Aunque los dados de porcentaje se puede tirar usando un <span class="dice-example">d100</span>, también puede usar d%, que hará lo mismo, devolviendo un número entre 0 y 100.',
|
||||
'DICE_ROLL_PAGE_P_3_TITLE' => 'Dados explosivos',
|
||||
'DICE_ROLL_PAGE_P_3' => 'Para dados explosivos, añada un signo de exclamación después de los lados del dado: <span class="dice-example">4d10!</span><br>
|
||||
Los dados explosivos lanzan un dado adicional si se lanza el máximo en ese dado.
|
||||
Si ese dado es también el máximo, se vuelve a tirar, y así sucesivamente, hasta que se haga una tirada que no sea el máximo.
|
||||
Por ejemplo: tirar un 6 en un d6, o un 10 en un d10.',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_1_TITLE' => '2d6!: [4, 6!, 6!, 2] = 20',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_1' => 'Cada dado explosivo se muestra como una tirada separada en la lista, como se muestra arriba.
|
||||
Donde explotó la segunda tirada, volvimos a tirar, y también explotó.
|
||||
La cuarta tirada, sin embargo no lo hizo, así que dejamos de tirar.',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_2_TITLE' => '1d6!-L: [6!,6!,6!,3]-L = 18',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_2' => 'Incluso puede usar <span class="dice-example">L</span> y <span class="dice-example">H</span>, que se verá en dados explosivos, así como tiradas normales.
|
||||
Aquí el dado explotó tres veces antes de no tirar un máximo. La última tirada se restó del total.',
|
||||
'DICE_ROLL_PAGE_P_4_TITLE' => 'Compuestos',
|
||||
'DICE_ROLL_PAGE_P_4' => 'A veces, es posible que desee que las tiradas de dados explosivos se añadan juntas en la misma tirada original.
|
||||
En esta situación, puede componer los dados utilizando dos signos de exclamación: <span class="dice-example">4d10!!</span>.
|
||||
Por ejemplo <em>(usando los ejemplos de dados explosivos de arriba)</em>',
|
||||
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_1' => '2d6!!: [4, 14!!] = 20',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_1_2' => 'las tiradas de dados explosivos de [6, 6, 2] se suman',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_2' => '1d6!!-L: [21!!]-L = 18',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_2_2' => 'las tiradas de dados explosivos de [6, 6, 6, 3] se suman',
|
||||
|
||||
'DICE_ROLL_PAGE_P_5_TITLE' => 'Penetrante',
|
||||
'DICE_ROLL_PAGE_P_5' => 'Algunos sistemas de dados explosivos usan una regla penetrante. Tomado de las reglas <a href="https://www.kenzerco.com/free_files/hackmaster_basic_free_.pdf#page=51" target="_blank">Hackmaster Basic</a>',
|
||||
'DICE_ROLL_PAGE_P_6' => 'Si tira el valor máximo en este dado en particular, puede volver a tirar y agregar el resultado del dado adicional, menos un punto, al total (la penetración puede dar como resultado simplemente el valor máximo del dado si posteriormente se lanza un 1, ya que cualquier tonto sabe que 1-1 = 0).
|
||||
Este proceso continúa indefinidamente siempre que el dado en cuestión continúe llegando al máximo (pero siempre hay solo un -1 extraído del dado adicional, incluso si es, por ejemplo, el tercer dado de penetración).',
|
||||
'DICE_ROLL_PAGE_P_7' => 'Entonces, si tiró <span class="dice-example">1d6</span> (penetrante) y obtuvo un 6, tiraría otro <span class="dice-example">d6</span>, restando 1 del resultado.
|
||||
Si ese <span class="dice-example">d6</span> sacara un 6 (antes del -1) penetraría, y así sucesivamente.
|
||||
La sintaxis para penetrar es muy similar a explosivo, pero con una <strong>p</strong> minúscula anexada, como <span class="dice-example">2d6!p</span>.
|
||||
Por ejemplo <em>(Usando el mismo ejemplo de dados explosivos de arriba)</em>',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_3' => '2d6!p: [4, 6!p, 5, 1] = 20',
|
||||
'DICE_ROLL_PAGE_P_8' => 'Donde explotó la segunda tirada, tiramos de nuevo, lo que también explotó (tiró un 6). La cuarta tirada sin embargo, sacó un 2, así que no penetró, y dejamos de tirar.
|
||||
Remember that we subtract 1 from penetrated rolls, which is why we show 5 and 1, instead of 6, and 2.
|
||||
<br>
|
||||
También puede componer dados penetrantes, así: <span class="dice-example">2d6!!p</span>',
|
||||
'DICE_ROLL_PAGE_P_9_TITLE' => 'Punto de comparación',
|
||||
'DICE_ROLL_PAGE_P_9' => 'Por defecto, los dados explosivos y penetrantes lo hacen si saca el mayor número posible en los dados (por ejemplo, un 6 en un <span class="dice-example">d6</span>, un 1 en un dado de dulce de azúcar).
|
||||
Puede cambiar fácilmente el punto de comparación de explosión añadiendo una comparación después de él.',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_4_TITLE' => 'Para explosivo solo si saca un 4',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_4' => '2d6!=4',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_5_TITLE' => 'O explosivo si hace tirada de algo sobre un 4',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_5' => '2d6!>4',
|
||||
'DICE_ROLL_PAGE_P_10' => 'También puede usar esto con dados penetrantes y compuestos',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_6_TITLE' => 'compuesto si saca un 4 o menos',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_6' => '2d6!!<=4',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_7_TITLE' => 'penetra si no saca un 4',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_7' => '2d6!p!=4',
|
||||
'DICE_ROLL_PAGE_P_11_TITLE' => 'Dados de dulce de azúcar',
|
||||
'DICE_ROLL_PAGE_P_11' => 'La notación de dulce de azúcar también es compatible. Permite tanto <span class="dice-example">dF.2</span> y menos común <span class="dice-example">dF.1</span>.<br>
|
||||
También puede utilizarlo junto con otros operadores y adiciones. Ejemplos',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_8_TITLE' => 'dF',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_8' => 'esto es lo mismo que',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_8_BIS' => 'dF.2',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_9_TITLE' => '4dF.2',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_9' => 'tirar 4 dados de dulce de azúcar estándar',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_10_TITLE' => '4dF.2-L',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_10' => 'tirar 4 dados de dulce de azúcar estándar, restando el resultado más bajo',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_11_TITLE' => 'dF.1*2',
|
||||
'DICE_ROLL_PAGE_EXAMPLE_11' => 'tirar los dados de dulce de azúcar no estándar, multiplicando el resultado por 2',
|
||||
'DICE_ROLL_PAGE_P_12_TITLE' => 'Piscinas de dados',
|
||||
'DICE_ROLL_PAGE_P_12' => 'Algunos sistemas usan piscinas de dados, por lo que el total es igual a la cantidad de dados lanzados que cumplen con una condición fija, en lugar del valor total de las tiradas.
|
||||
Por ejemplo, una <strong>piscina</strong> de dados de 10 lados donde se cuenta el número de dados que tiran un 8 o más como <strong>acierto</strong>.
|
||||
Esto se puede lograr con: <span class="dice-example">5d10>=8</span>.<br>
|
||||
Puede definir varias condiciones de acierto, simplemente agregando comparaciones de números directamente después de la tirada de dados.<br>
|
||||
Debido a esto, <strong>no</strong> puede tener un dado de grupo que también sea explosivo. Ejemplos',
|
||||
'DICE_ROLL_PAGE_P_13' => 'Puede mezclar dados de grupo con otros tipos de dados o ecuaciones, y utilizará el número de aciertos como el valor en la ecuación',
|
||||
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_3' => '2d6=6: [4,6*] = 1',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_3_2' => 'solo un resultado de 6 es un acierto',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_4' => '4d3>1: [1,3*,2*,1] = 2',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_4_2' => 'superior que un 1 es un acierto',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_5' => '4d3<2: [1*,3,2,1*] = 2',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_5_2' => 'inferior que un 2 es un acierto',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_6' => '5d8>=5: [2,4,6*,3,8*] = 2',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_6_2' => 'mayor o igual a 5 es un acierto',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_7' => '6d10<=4: [7,2*,10,3*,3*,4*] = 4',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_7_2' => 'menor o igual a 4 es un acierto',
|
||||
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_8' => '2d6>4+3d5: [4,5*]+[3,1,1] = 6',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_8_2' => '1 acierto + los valores en bruto de las otras tiradas',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_9' => '2d6>4*d6!: [6*,5*]*[6!,4] = 20',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_9_2' => '1 acierto * los valores en bruto de las otras tiradas',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_10' => '2d6>4+2: [3,5*]+2 = 3',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_10_2' => '1 acierto + 2',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_11' => '2d6>4+H: [3,5*]+H = 2',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_11_2' => 'La tirada más alta es 5, lo que es un acierto, valor de 1',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_12' => '2d6<4+H: [3*,5]+H = 1',
|
||||
'DICE_ROLL_PAGE_EX_DETAILS_12_2' => 'La tirada más alta es 5, lo que es un fallo, valor de 0',
|
||||
]);
|
||||
60
ext/phpbbstudio/dice/language/es/dice_exceptions.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'EXCEPTION_OUT_OF_BOUNDS' => 'El campo `<strong>%1$s</strong>` recibió datos más allá de sus límites. Razón: %2$s',
|
||||
'EXCEPTION_UNEXPECTED_VALUE' => 'El campo `<strong>%1$s</strong>` recibió datos inesperados. Razón: %2$s',
|
||||
|
||||
'EXCEPTION_ROLL_EDIT_COUNT' => 'Editar cantidad de tiradas',
|
||||
'EXCEPTION_ROLL_EDIT_TIME' => 'Editar fecha de tiradas',
|
||||
'EXCEPTION_ROLL_EDIT_USER' => 'Editar identificador del usuario',
|
||||
'EXCEPTION_ROLL_DICE_COMPOUND' => 'Dados compuestos (<span class="error">!!</span>)',
|
||||
'EXCEPTION_ROLL_DICE_EXPLODE' => 'Dados explosivos (<span class="error">!, !!, !p</span>)',
|
||||
'EXCEPTION_ROLL_DICE_FUDGE' => 'Dados de dulce de azúcar (<span class="error">F</span>)',
|
||||
'EXCEPTION_ROLL_DICE_PENETRATE' => 'Dados penetrantes (<span class="error">!p</span>)',
|
||||
'EXCEPTION_ROLL_DICE_PERCENT' => 'Porcentaje de dados (d<span class="error">%</span> o d<span class="error">100</span>)',
|
||||
'EXCEPTION_ROLL_DICE_QTY' => 'Cantidad de dados (<span class="error">X</span>d6)',
|
||||
'EXCEPTION_ROLL_DICES' => 'Dados',
|
||||
'EXCEPTION_ROLL_DICES_QTY' => 'Cantidad de dados (<span class="error">X</span>d6 + <span class="error">X</span>d6)',
|
||||
'EXCEPTION_ROLL_FORUM_ID' => 'Identificador de foro',
|
||||
'EXCEPTION_ROLL_ID' => 'Identificador de tirada',
|
||||
'EXCEPTION_ROLL_NOTATION' => 'Notación de tirada',
|
||||
'EXCEPTION_ROLL_POST_ID' => 'Identificador de mensaje',
|
||||
'EXCEPTION_ROLL_REGEX_NAME' => 'Nombre Regex',
|
||||
'EXCEPTION_ROLL_SIDES' => 'Lados del dado (1d<span class="error">X</span>)',
|
||||
'EXCEPTION_ROLL_TIME' => 'Fecha de tiradas',
|
||||
'EXCEPTION_ROLL_TOPIC_ID' => 'Identificador de tema',
|
||||
'EXCEPTION_ROLL_USER_ID' => 'Identificador de usuario',
|
||||
|
||||
'EXCEPTION_FIELD_MISSING' => 'Falta el campo requerido.',
|
||||
'EXCEPTION_NOT_ALLOWED' => 'La entrada no está permitida.',
|
||||
'EXCEPTION_ROLL_ALREADY_EXIST' => 'La tirada proporcionada ya existe.',
|
||||
'EXCEPTION_ROLL_NO_MATCHES' => 'No se encontraron coincidencias de dados para la notación proporcionada.',
|
||||
'EXCEPTION_ROLL_NOT_EXIST' => 'La tirada proporcionada no existe.',
|
||||
'EXCEPTION_ROLL_NAME_NOT_FOUND' => 'El nombre regex proporcionado no se pudo encontrar.',
|
||||
|
||||
// TRANSLATORS pay attention here
|
||||
'EXCEPTION_ROLL_ULINT' => 'La entrada no está en la rango de 0 a 4 294 967 295.', // Leave   in place (non-breaking thin space)
|
||||
'EXCEPTION_ROLL_USINT' => 'La entrada no está en la rango de 0 a 65 535.', // Leave   in place (non-breaking thin space)
|
||||
|
||||
'EXCEPTION_TOO_LONG' => 'La entrada era más larga que la longitud máxima.',
|
||||
'EXCEPTION_TOO_HIGH' => 'La entrada fue mayor que el valor máximo.',
|
||||
]);
|
||||
26
ext/phpbbstudio/dice/language/es/ext_require.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'ERROR_PHPBB_VERSION' => 'La versión mínima de phpBB requerida es %1$s pero menos de %2$s',
|
||||
'ERROR_PHP_VERSION' => 'La versión de PHP debe ser igual o mayor que 5.5',
|
||||
'ERROR_GLOB_STREAM' => 'El flujo GLOB no está disponible en su sistema.',
|
||||
]);
|
||||
53
ext/phpbbstudio/dice/language/es/info_acp_dice.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
// Cat
|
||||
'ACL_CAT_PHPBB_STUDIO' => 'phpBB Studio',
|
||||
|
||||
// ACP forums
|
||||
'ACP_DICE_SETTINGS' => 'Ajustes de dados',
|
||||
'ACP_DICE_ENABLE' => 'Habilitar dados',
|
||||
'ACP_DICE_ENABLE_DESC' => 'Habilita la extensión de dados en este foro. El BBCode de dados solo se habilitará para los usuarios que tengan permiso de lanzar los dados en este foro.',
|
||||
'ACP_DICE_F_SKIN' => 'Skin de dados',
|
||||
'ACP_DICE_F_SKIN_DESC' => 'La skin de dados predeterminada para tiradas de dados en este foro.',
|
||||
'ACP_DICE_SKIN_OVERRIDE' => 'Anular skin de dados',
|
||||
'ACP_DICE_SKIN_OVERRIDE_DESC' => 'Reemplaza la skin de los dados del usuario con la skin como se define en “Skin de dados”.',
|
||||
|
||||
// ACP
|
||||
'ACP_DICE_CAT' => 'phpBB Studio - Dados',
|
||||
'ACP_DICE_DASH' => 'Foro de Dados',
|
||||
|
||||
'ACP_DICE_SIDES' => 'Lados de dados',
|
||||
'ACP_DICE_SIDES_SHORT' => 'Lados',
|
||||
|
||||
'ACP_DICE_SKINS' => 'Skins de dados',
|
||||
'ACP_DICE_SKINS_SHORT' => 'Skins',
|
||||
|
||||
// Log
|
||||
'LOG_ACP_DICE_LOCATIONS' => '<strong>Ubicaciones de enlace de dados alteradas</strong>',
|
||||
'LOG_ACP_DICE_ORPHANED' => '<strong>Tiradas de dados huérfanas eliminadas</strong><br />» %s borrado',
|
||||
'LOG_ACP_DICE_SETTINGS' => '<strong>Ajustes de dados alteradas</strong>',
|
||||
'LOG_ACP_DICE_SIDE_ADD' => '<strong>Nuevo lado de dado añadido</strong><br />» %s',
|
||||
'LOG_ACP_DICE_SIDE_DELETE' => '<strong>Lado de dado borrada</strong><br />» %s',
|
||||
'LOG_ACP_DICE_SKIN_INSTALL' => '<strong>Nueva skin de dado instalada</strong><br />» %s',
|
||||
'LOG_ACP_DICE_SKIN_UNINSTALL' => '<strong>Skin de dado desinstalada</strong><br />» %s',
|
||||
]);
|
||||
30
ext/phpbbstudio/dice/language/es/info_ucp_dice.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'UCP_DICE_TITLE' => 'Dados',
|
||||
'UCP_DICE' => 'Ajustes',
|
||||
|
||||
'UCP_DICE_USER' => 'Modo dados',
|
||||
'UCP_DICE_USER_EXPLAIN' => 'Pantalla de visualización predeterminada para tiradas de dados.',
|
||||
|
||||
'UCP_DICE_SAVED' => '¡Ajustes guardados correctamente!',
|
||||
]);
|
||||
38
ext/phpbbstudio/dice/language/es/permissions_dice.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
if (!defined('IN_PHPBB'))
|
||||
{
|
||||
exit;
|
||||
}
|
||||
|
||||
if (empty($lang) || !is_array($lang))
|
||||
{
|
||||
$lang = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Some characters you may want to copy&paste: ’ » “ ” …
|
||||
*/
|
||||
$lang = array_merge($lang, [
|
||||
'ACL_F_DICE_ROLL' => '<strong>Dados</strong> - Puede tirar dados',
|
||||
'ACL_F_DICE_EDIT' => '<strong>Dados</strong> - Puede editar una tirada de dado',
|
||||
'ACL_F_DICE_DELETE' => '<strong>Dados</strong> - Puede borrar dados propios',
|
||||
'ACL_F_DICE_NO_LIMIT' => '<strong>Dados</strong> - Puede ignorar el límite de dados por mensaje',
|
||||
'ACL_F_DICE_VIEW' => '<strong>Dados</strong> - Puede ver tirada de dados',
|
||||
|
||||
'ACL_F_MOD_DICE_ADD' => '<strong>Dados</strong> - <strong><em>Mod:</em></strong> Puede lanzar dados en el mensaje de otros usuarios',
|
||||
'ACL_F_MOD_DICE_EDIT' => '<strong>Dados</strong> - <strong><em>Mod:</em></strong> Puede editar tirada de dados en mensajes de otros usuarios',
|
||||
'ACL_F_MOD_DICE_DELETE' => '<strong>Dados</strong> - <strong><em>Mod:</em></strong> Puede borrar dados en mensajes de otros usuarios',
|
||||
|
||||
'ACL_A_DICE_ADMIN' => '<strong>Dados</strong> - Puede administrar la extensión',
|
||||
|
||||
'ACL_U_DICE_USE_UCP' => '<strong>Dados</strong> - Puede gestionar el PCU Dados',
|
||||
'ACL_U_DICE_TEST' => '<strong>Dados</strong> - Puede usar la página “Notación de Prueba”',
|
||||
'ACL_U_DICE_SKIN' => '<strong>Dados</strong> - Puede ignorar las skins de foro anulantes<br><em>Se utilizará la skin seleccionada por el usuario, incluso cuando la skin del foro esté configurada para “anular”.</em>',
|
||||
]);
|
||||
280
ext/phpbbstudio/dice/license.txt
Normal file
@@ -0,0 +1,280 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
675 Mass Ave, Cambridge, MA 02139, USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
52
ext/phpbbstudio/dice/migrations/install_acp_module.php
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\migrations;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Migration: Install ACP module.
|
||||
*/
|
||||
class install_acp_module extends \phpbb\db\migration\migration
|
||||
{
|
||||
/**
|
||||
* Assign migration file dependencies for this migration.
|
||||
*
|
||||
* @return array Array of migration files
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v32x\v325'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the dice extension modules to the database.
|
||||
*
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
public function update_data()
|
||||
{
|
||||
return [
|
||||
['module.add', [
|
||||
'acp',
|
||||
'ACP_CAT_DOT_MODS',
|
||||
'ACP_DICE_CAT',
|
||||
]],
|
||||
['module.add', [
|
||||
'acp',
|
||||
'ACP_DICE_CAT',
|
||||
[
|
||||
'module_basename' => '\phpbbstudio\dice\acp\dice_module',
|
||||
'modes' => ['dashboard'],
|
||||
],
|
||||
]],
|
||||
];
|
||||
}
|
||||
}
|
||||
41
ext/phpbbstudio/dice/migrations/install_config_text.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\migrations;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Migration: Install text configuration.
|
||||
*/
|
||||
class install_config_text extends \phpbb\db\migration\migration
|
||||
{
|
||||
/**
|
||||
* Assign migration file dependencies for this migration.
|
||||
*
|
||||
* @return array Array of migration files
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v32x\v325'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the dice extension text configurations to the database.
|
||||
*
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
public function update_data()
|
||||
{
|
||||
return [
|
||||
['config_text.add', ['dice_skins', json_encode(['bajahs_red', 'classic_steel'])]],
|
||||
['config_text.add', ['dice_sides', json_encode([4, 6, 8, 10, 12, 20])]],
|
||||
];
|
||||
}
|
||||
}
|
||||
72
ext/phpbbstudio/dice/migrations/install_configs.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\migrations;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Migration: Install configuration.
|
||||
*/
|
||||
class install_configs extends \phpbb\db\migration\migration
|
||||
{
|
||||
/**
|
||||
* Check if the migration is effectively installed (entirely optional).
|
||||
*
|
||||
* @return bool True if this migration is installed, False if this migration is not installed
|
||||
* @access public
|
||||
*/
|
||||
public function effectively_installed()
|
||||
{
|
||||
return isset($this->config['dice_version']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign migration file dependencies for this migration.
|
||||
*
|
||||
* @return array Array of migration files
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v32x\v325'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the dice extension configurations to the database.
|
||||
*
|
||||
* @return array Array of configs
|
||||
* @access public
|
||||
*/
|
||||
public function update_data()
|
||||
{
|
||||
return [
|
||||
['config.add', ['dice_sides_only', '1']], /* real dice (bool) */
|
||||
['config.add', ['dice_version', '2.0.0-beta']], /* Dice version */
|
||||
|
||||
['config.add', ['dice_skins_dir', 'ext/phpbbstudio/dice/skins']], /* skin directory relative to root */
|
||||
|
||||
['config.add', ['dice_skins_img_height', 48]], /* skin image height */
|
||||
['config.add', ['dice_skins_img_width', 48]], /* skin image width */
|
||||
|
||||
['config.add', ['dice_max_rolls', '20']], /* rolls limit per post - notations */
|
||||
['config.add', ['dice_per_notation', '0']], /* (eg 2 in 1d6+3d4) */
|
||||
['config.add', ['dice_qty_per_dice', '0']], /* (eg the 2 in 2d6) */
|
||||
['config.add', ['dice_qty_dice_per_notation', '0']], /* (eg 5 in 2d6+3d4) */
|
||||
['config.add', ['dice_sides_per_dice', '0']], /* Sides */
|
||||
['config.add', ['dice_pc_dice_per_notation', '0']], /* Percentile */
|
||||
['config.add', ['dice_fudge_dice_per_notation', '0']], /* Fudge */
|
||||
['config.add', ['dice_penetration_dice_per_notation', '0']], /* Penetration */
|
||||
['config.add', ['dice_compound_dice_per_notation', '0']], /* Compound */
|
||||
['config.add', ['dice_exploding_dice_per_notation', '0']], /* Explode */
|
||||
['config.add', ['dice_rolls_per_dice', '0']], /* (include/exclude compounding rolls) */
|
||||
['config.add', ['dice_rolls_per_notation', '0']], /* (include/exclude compounding rolls) */
|
||||
|
||||
['config.add', ['dice_link_locations', 8]], /* Dice link locations */
|
||||
];
|
||||
}
|
||||
}
|
||||
58
ext/phpbbstudio/dice/migrations/install_permissions.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\migrations;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Migration: Install permissions.
|
||||
*/
|
||||
class install_permissions extends \phpbb\db\migration\migration
|
||||
{
|
||||
/**
|
||||
* Assign migration file dependencies for this migration.
|
||||
*
|
||||
* @return array Array of migration files
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v32x\v325'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the dice extension permissions to the database.
|
||||
*
|
||||
* @return array Array of permissions
|
||||
* @access public
|
||||
*/
|
||||
public function update_data()
|
||||
{
|
||||
return [
|
||||
/* Forum User permissions */
|
||||
['permission.add', ['f_dice_roll', false]], /* Can roll dice */
|
||||
['permission.add', ['f_dice_edit', false]], /* Can edit a rolled dice */
|
||||
['permission.add', ['f_dice_delete', false]], /* Can delete own dice */
|
||||
['permission.add', ['f_dice_no_limit', false]], /* Can ignore dice limit per post */
|
||||
['permission.add', ['f_dice_view', false]], /* Can view rolled dice */
|
||||
|
||||
/* Forum Moderator permissions */
|
||||
['permission.add', ['f_mod_dice_add', false]], /* Can roll dice on other users' post */
|
||||
['permission.add', ['f_mod_dice_edit', false]], /* Can edit rolled dice on other users' post */
|
||||
['permission.add', ['f_mod_dice_delete', false]], /* Can delete dice on other users' post */
|
||||
|
||||
/* Admin Group permissions */
|
||||
['permission.add', ['a_dice_admin']], /* Can administer the extension's ACP */
|
||||
|
||||
/* Registered user Group permissions */
|
||||
['permission.add', ['u_dice_use_ucp']], /* Can manage the extension's UCP */
|
||||
['permission.add', ['u_dice_test']], /* Can use the 'test notation'page */
|
||||
['permission.add', ['u_dice_skin']], /* Can change dice skin */
|
||||
];
|
||||
}
|
||||
}
|
||||
93
ext/phpbbstudio/dice/migrations/install_roles.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\migrations;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Migration: Install permission roles.
|
||||
*/
|
||||
class install_roles extends \phpbb\db\migration\migration
|
||||
{
|
||||
/**
|
||||
* Assign migration file dependencies for this migration.
|
||||
*
|
||||
* @return array Array of migration files
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
static public function depends_on()
|
||||
{
|
||||
return [
|
||||
'\phpbb\db\migration\data\v32x\v325',
|
||||
'\phpbbstudio\dice\migrations\install_permissions',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the dice extension permissions to the database.
|
||||
*
|
||||
* @return array Array of permissions
|
||||
* @access public
|
||||
*/
|
||||
public function update_data()
|
||||
{
|
||||
$data = [];
|
||||
|
||||
/* Forum User permissions */
|
||||
if ($this->role_exists('ROLE_FORUM_STANDARD'))
|
||||
{
|
||||
$data[] = ['permission.permission_set', ['ROLE_FORUM_STANDARD', 'f_dice_roll']];
|
||||
$data[] = ['permission.permission_set', ['ROLE_FORUM_STANDARD', 'f_dice_edit']];
|
||||
$data[] = ['permission.permission_set', ['ROLE_FORUM_STANDARD', 'f_dice_delete']];
|
||||
$data[] = ['permission.permission_unset', ['ROLE_FORUM_STANDARD', 'f_dice_no_limit']];
|
||||
$data[] = ['permission.permission_set', ['ROLE_FORUM_STANDARD', 'f_dice_view']];
|
||||
}
|
||||
|
||||
/* Forum Moderator permissions */
|
||||
if ($this->role_exists('ROLE_FORUM_FULL'))
|
||||
{
|
||||
$data[] = ['permission.permission_set', ['ROLE_FORUM_FULL', 'f_mod_dice_add']];
|
||||
$data[] = ['permission.permission_set', ['ROLE_FORUM_FULL', 'f_mod_dice_edit']];
|
||||
$data[] = ['permission.permission_set', ['ROLE_FORUM_FULL', 'f_mod_dice_delete']];
|
||||
}
|
||||
|
||||
/* Admin Group permissions */
|
||||
if ($this->role_exists('ROLE_ADMIN_FULL'))
|
||||
{
|
||||
$data[] = ['permission.permission_set', ['ROLE_ADMIN_FULL', 'a_dice_admin']];
|
||||
}
|
||||
|
||||
/* Registered user Group permissions */
|
||||
if ($this->role_exists('ROLE_USER_STANDARD'))
|
||||
{
|
||||
$data[] = ['permission.permission_set', ['ROLE_USER_STANDARD', 'u_dice_use_ucp']];
|
||||
$data[] = ['permission.permission_set', ['ROLE_USER_STANDARD', 'u_dice_test']];
|
||||
$data[] = ['permission.permission_set', ['ROLE_USER_STANDARD', 'u_dice_skin']];
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given role does exist or not.
|
||||
*
|
||||
* @param string $role The name of the role
|
||||
* @return bool true if the role exists, false otherwise
|
||||
* @access protected
|
||||
*/
|
||||
protected function role_exists($role)
|
||||
{
|
||||
$sql = 'SELECT role_id
|
||||
FROM ' . $this->table_prefix . "acl_roles
|
||||
WHERE role_name = '" . $this->db->sql_escape($role) . "'";
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$role_id = $this->db->sql_fetchfield('role_id');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return (bool) $role_id;
|
||||
}
|
||||
}
|
||||
69
ext/phpbbstudio/dice/migrations/install_roles_2.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\migrations;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Migration: Install permission roles.
|
||||
*/
|
||||
class install_roles_2 extends \phpbb\db\migration\migration
|
||||
{
|
||||
/**
|
||||
* Assign migration file dependencies for this migration.
|
||||
*
|
||||
* @return array Array of migration files
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
static public function depends_on()
|
||||
{
|
||||
return [
|
||||
'\phpbb\db\migration\data\v32x\v325',
|
||||
'\phpbbstudio\dice\migrations\install_roles',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the dice extension permissions to the database.
|
||||
*
|
||||
* @return array Array of permissions
|
||||
* @access public
|
||||
*/
|
||||
public function update_data()
|
||||
{
|
||||
$data = [];
|
||||
|
||||
/* Forum User permissions */
|
||||
if ($this->role_exists('ROLE_FORUM_STANDARD'))
|
||||
{
|
||||
$data[] = ['permission.permission_unset', ['ROLE_FORUM_STANDARD', 'f_dice_edit']];
|
||||
$data[] = ['permission.permission_unset', ['ROLE_FORUM_STANDARD', 'f_dice_delete']];
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given role does exist or not.
|
||||
*
|
||||
* @param string $role The name of the role
|
||||
* @return bool true if the role exists, false otherwise
|
||||
* @access protected
|
||||
*/
|
||||
protected function role_exists($role)
|
||||
{
|
||||
$sql = 'SELECT role_id
|
||||
FROM ' . $this->table_prefix . "acl_roles
|
||||
WHERE role_name = '" . $this->db->sql_escape($role) . "'";
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$role_id = $this->db->sql_fetchfield('role_id');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return (bool) $role_id;
|
||||
}
|
||||
}
|
||||
71
ext/phpbbstudio/dice/migrations/install_ucp_module.php
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\migrations;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Migration: Install ACP module.
|
||||
*/
|
||||
class install_ucp_module extends \phpbb\db\migration\migration
|
||||
{
|
||||
/**
|
||||
* Check if the migration is effectively installed (entirely optional).
|
||||
*
|
||||
* @return bool True if this migration is installed, False if this migration is not installed
|
||||
* @access public
|
||||
*/
|
||||
public function effectively_installed()
|
||||
{
|
||||
$sql = 'SELECT module_id
|
||||
FROM ' . $this->table_prefix . "modules
|
||||
WHERE module_class = 'ucp'
|
||||
AND module_langname = 'UCP_DICE_TITLE'";
|
||||
$result = $this->db->sql_query($sql);
|
||||
$module_id = (bool) $this->db->sql_fetchfield('module_id');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $module_id !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign migration file dependencies for this migration.
|
||||
*
|
||||
* @return array Array of migration files
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v32x\v325'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the dice extension modules to the database.
|
||||
*
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
public function update_data()
|
||||
{
|
||||
return [
|
||||
['module.add', [
|
||||
'ucp',
|
||||
0,
|
||||
'UCP_DICE_TITLE',
|
||||
]],
|
||||
['module.add', [
|
||||
'ucp',
|
||||
'UCP_DICE_TITLE',
|
||||
[
|
||||
'module_basename' => '\phpbbstudio\dice\ucp\main_module',
|
||||
'modes' => ['settings'],
|
||||
],
|
||||
]],
|
||||
];
|
||||
}
|
||||
}
|
||||
118
ext/phpbbstudio/dice/migrations/install_user_schema.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\migrations;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Migration: Install dice tables and columns.
|
||||
*/
|
||||
class install_user_schema extends \phpbb\db\migration\migration
|
||||
{
|
||||
/**
|
||||
* Check if the migration is effectively installed (entirely optional).
|
||||
*
|
||||
* @return bool True if this migration is installed, False if this migration is not installed
|
||||
* @access public
|
||||
*/
|
||||
public function effectively_installed()
|
||||
{
|
||||
return $this->db_tools->sql_column_exists($this->table_prefix . 'forums', 'dice_enabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign migration file dependencies for this migration.
|
||||
*
|
||||
* @return array Array of migration files
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
static public function depends_on()
|
||||
{
|
||||
return ['\phpbb\db\migration\data\v32x\v325'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the dice extension schema to the database.
|
||||
*
|
||||
* @return array Array of table schema
|
||||
* @access public
|
||||
*/
|
||||
public function update_schema()
|
||||
{
|
||||
return [
|
||||
'add_columns' => [
|
||||
$this->table_prefix . 'forums' => [
|
||||
'dice_enabled' => ['BOOL', 0], /* Dice forum (0 = No) */
|
||||
'dice_f_skin' => ['VCHAR_UNI', 'bajahs_red'], /* The skin to use as default */
|
||||
'dice_skin_override' => ['BOOL', 0], /* Override user's choice (0 = No) */
|
||||
],
|
||||
$this->table_prefix . 'users' => [
|
||||
'dice_u_skin' => ['VCHAR_UNI', 'bajahs_red'], /* The skin to use as default */
|
||||
'dice_u_roll_limit' => ['BOOL', 0], /* Overrides forum permission */
|
||||
],
|
||||
],
|
||||
'add_tables' => [
|
||||
$this->table_prefix . 'dice_rolls' => [
|
||||
'COLUMNS' => [
|
||||
'roll_num' => ['ULINT', null, 'auto_increment'],
|
||||
'roll_id' => ['ULINT', 0],
|
||||
'roll_notation' => ['VCHAR_UNI', ''],
|
||||
'roll_dices' => ['TEXT_UNI', ''],
|
||||
'roll_rolls' => ['TEXT_UNI', ''],
|
||||
'roll_output' => ['TEXT_UNI', ''],
|
||||
'roll_total' => ['ULINT', 0],
|
||||
'roll_successes' => ['USINT', 0],
|
||||
'roll_is_pool' => ['BOOL', 0],
|
||||
'roll_time' => ['TIMESTAMP', 0],
|
||||
'roll_edit_user' => ['ULINT', 0],
|
||||
'roll_edit_time' => ['TIMESTAMP', 0],
|
||||
'roll_edit_count' => ['ULINT', 0],
|
||||
'forum_id' => ['ULINT', 0],
|
||||
'topic_id' => ['ULINT', 0],
|
||||
'post_id' => ['ULINT', 0],
|
||||
'user_id' => ['ULINT', 0],
|
||||
],
|
||||
'PRIMARY_KEY' => 'roll_num',
|
||||
'KEYS' => [
|
||||
'roll_id' => ['INDEX', 'roll_id'],
|
||||
'forum_id' => ['INDEX', 'forum_id'],
|
||||
'topic_id' => ['INDEX', 'topic_id'],
|
||||
'post_id' => ['INDEX', 'post_id'],
|
||||
'user_id' => ['INDEX', 'user_id'],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop the dice rolls schema from the database.
|
||||
*
|
||||
* @return array Array of table schema
|
||||
* @access public
|
||||
*/
|
||||
public function revert_schema()
|
||||
{
|
||||
return [
|
||||
'drop_columns' => [
|
||||
$this->table_prefix . 'forums' => [
|
||||
'dice_enabled',
|
||||
'dice_f_skin',
|
||||
'dice_skin_override',
|
||||
],
|
||||
$this->table_prefix . 'users' => [
|
||||
'dice_u_skin',
|
||||
'dice_u_roll_limit',
|
||||
],
|
||||
],
|
||||
'drop_tables' => [
|
||||
$this->table_prefix . 'dice_rolls',
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
72
ext/phpbbstudio/dice/migrations/update_skins_directory.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\migrations;
|
||||
|
||||
/**
|
||||
* phpBB Studio's Dice Migration: Update skins directory.
|
||||
*/
|
||||
class update_skins_directory extends \phpbb\db\migration\migration
|
||||
{
|
||||
/**
|
||||
* Assign migration file dependencies for this migration.
|
||||
*
|
||||
* @return array Array of migration files
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
static public function depends_on()
|
||||
{
|
||||
return [
|
||||
'\phpbb\db\migration\data\v32x\v325',
|
||||
'\phpbbstudio\dice\migrations\install_configs',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the dice skin directory configuration.
|
||||
*
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
public function update_data()
|
||||
{
|
||||
return [
|
||||
['config.remove', ['dice_version']],
|
||||
|
||||
['if', [
|
||||
$this->config['dice_skins_dir'] === 'ext/phpbbstudio/dice/skins',
|
||||
['config.update', ['dice_skins_dir', 'images/dice']],
|
||||
]],
|
||||
['custom', [[$this, 'mirror_skin_directory']]],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Mirror the dice skin directory.
|
||||
*
|
||||
* @throws \Exception
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function mirror_skin_directory()
|
||||
{
|
||||
global $phpbb_container;
|
||||
|
||||
/** @var \phpbb\filesystem\filesystem $filesystem */
|
||||
$filesystem = $phpbb_container->get('filesystem');
|
||||
|
||||
$origin = $this->phpbb_root_path . 'ext/phpbbstudio/dice/skins';
|
||||
$target = $this->phpbb_root_path . 'images/dice';
|
||||
|
||||
if (!$filesystem->exists($target))
|
||||
{
|
||||
$filesystem->mirror($origin, $target, null, [false, false, false]);
|
||||
}
|
||||
}
|
||||
}
|
||||
306
ext/phpbbstudio/dice/operator/roll.php
Normal file
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\operator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Operator for roll entities.
|
||||
*/
|
||||
class roll implements roll_interface
|
||||
{
|
||||
/** @var \phpbb\config\config */
|
||||
protected $config;
|
||||
|
||||
/** @var \phpbb\config\db_text */
|
||||
protected $config_text;
|
||||
|
||||
/** @var ContainerInterface */
|
||||
protected $container;
|
||||
|
||||
/** @var \phpbb\db\driver\driver_interface */
|
||||
protected $db;
|
||||
|
||||
/** @var \phpbb\filesystem\filesystem */
|
||||
protected $filesystem;
|
||||
|
||||
/** @var \phpbbstudio\dice\core\functions_common */
|
||||
protected $functions;
|
||||
|
||||
/** @var \phpbb\controller\helper */
|
||||
protected $helper;
|
||||
|
||||
/** @var \phpbb\template\template */
|
||||
protected $template;
|
||||
|
||||
/** @var \phpbb\user */
|
||||
protected $user;
|
||||
|
||||
/** @var string Posts table */
|
||||
protected $posts_table;
|
||||
|
||||
/** @var string Dice rolls table */
|
||||
protected $rolls_table;
|
||||
|
||||
/** @var string phpBB root path */
|
||||
protected $root_path;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param \phpbb\config\config $config Configuration object
|
||||
* @param \phpbb\config\db_text $config_text Text configuration object
|
||||
* @param ContainerInterface $container Container injection Service
|
||||
* @param \phpbb\db\driver\driver_interface $db Database object
|
||||
* @param \phpbb\filesystem\filesystem $filesystem Filesystem object
|
||||
* @param \phpbbstudio\dice\core\functions_common $functions Dice common functions
|
||||
* @param \phpbb\controller\helper $helper Controller helper object
|
||||
* @param \phpbb\template\template $template Template object
|
||||
* @param \phpbb\user $user User object
|
||||
* @param string $posts_table Posts table
|
||||
* @param string $rolls_table Dice rolls table
|
||||
* @param string $root_path phpBB root path
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function __construct(
|
||||
\phpbb\config\config $config,
|
||||
\phpbb\config\db_text $config_text,
|
||||
ContainerInterface $container,
|
||||
\phpbb\db\driver\driver_interface $db,
|
||||
\phpbb\filesystem\filesystem $filesystem,
|
||||
\phpbbstudio\dice\core\functions_common $functions,
|
||||
\phpbb\controller\helper $helper,
|
||||
\phpbb\template\template $template,
|
||||
\phpbb\user $user,
|
||||
$posts_table,
|
||||
$rolls_table,
|
||||
$root_path
|
||||
)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->config_text = $config_text;
|
||||
$this->container = $container;
|
||||
$this->db = $db;
|
||||
$this->filesystem = $filesystem;
|
||||
$this->functions = $functions;
|
||||
$this->helper = $helper;
|
||||
$this->template = $template;
|
||||
$this->user = $user;
|
||||
$this->posts_table = $posts_table;
|
||||
$this->rolls_table = $rolls_table;
|
||||
$this->root_path = $root_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_entity()
|
||||
{
|
||||
return $this->container->get('phpbbstudio.dice.entity.roll');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_entities(array $rowset)
|
||||
{
|
||||
// Set up an array for entities collection.
|
||||
$entities = [];
|
||||
|
||||
foreach ($rowset as $row)
|
||||
{
|
||||
// Get an entity, import the row data and add it to the entities array
|
||||
$entities[] = $this->get_entity()->import($row);
|
||||
}
|
||||
|
||||
return $entities;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function delete($roll_ids)
|
||||
{
|
||||
// No roll identifiers were provided
|
||||
if (empty($roll_ids))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sql_where = is_array($roll_ids) ? $this->db->sql_in_set('roll_id', $roll_ids) : 'roll_id = ' . (int) $roll_ids;
|
||||
|
||||
$sql = 'DELETE FROM ' . $this->rolls_table . ' WHERE ' . $sql_where;
|
||||
$this->db->sql_query($sql);
|
||||
|
||||
return (bool) $this->db->sql_affectedrows();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_author($roll_id)
|
||||
{
|
||||
$sql = 'SELECT p.poster_id
|
||||
FROM ' . $this->rolls_table . ' r
|
||||
LEFT JOIN ' . $this->posts_table . ' p
|
||||
ON p.post_id = r.post_id
|
||||
WHERE r.roll_id = ' . (int) $roll_id;
|
||||
$result = $this->db->sql_query_limit($sql, 1);
|
||||
$poster_id = $this->db->sql_fetchfield('poster_id');
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return (int) $poster_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_rolls_for_topic($forum_id, $topic_id, array $post_list)
|
||||
{
|
||||
$sql = 'SELECT *
|
||||
FROM ' . $this->rolls_table . '
|
||||
WHERE forum_id = ' . (int) $forum_id . '
|
||||
AND topic_id = ' . (int) $topic_id . '
|
||||
AND ' . $this->db->sql_in_set('post_id', $post_list);
|
||||
$result = $this->db->sql_query($sql);
|
||||
$rowset = $this->db->sql_fetchrowset($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $this->get_entities($rowset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_rolls_for_posting($forum_id, $topic_id, $post_id)
|
||||
{
|
||||
$sql = 'SELECT *
|
||||
FROM ' . $this->rolls_table . '
|
||||
WHERE forum_id = ' . (int) $forum_id . '
|
||||
AND topic_id = ' . (int) $topic_id . '
|
||||
AND post_id = ' . (int) $post_id;
|
||||
$sql .= (empty($topic_id) && empty($post_id)) ? ' AND user_id = ' . (int) $this->user->data['user_id'] : '';
|
||||
$result = $this->db->sql_query($sql);
|
||||
$rowset = $this->db->sql_fetchrowset($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
return $this->get_entities($rowset);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function set_rolls_identifiers($mode, $forum_id, $topic_id, $post_id)
|
||||
{
|
||||
// If the mode is 'post', a topic was created
|
||||
$s_topic = $mode === 'post';
|
||||
|
||||
// If a topic was created, the rolls currently have no topic identifier
|
||||
$sql = 'SELECT *
|
||||
FROM ' . $this->rolls_table . '
|
||||
WHERE forum_id = ' . (int) $forum_id . '
|
||||
AND user_id = ' . (int) $this->user->data['user_id'] . '
|
||||
AND topic_id = ' . ($s_topic ? 0 : (int) $topic_id) . '
|
||||
AND post_id = 0';
|
||||
$result = $this->db->sql_query($sql);
|
||||
$rowset = $this->db->sql_fetchrowset($result);
|
||||
$this->db->sql_freeresult($result);
|
||||
|
||||
// Get entities from rowset
|
||||
$entities = $this->get_entities($rowset);
|
||||
|
||||
/** @var \phpbbstudio\dice\entity\roll $entity */
|
||||
foreach ($entities as $entity)
|
||||
{
|
||||
// If a topic was created, set the topic identifier
|
||||
if ($s_topic)
|
||||
{
|
||||
$entity->set_topic($topic_id);
|
||||
}
|
||||
|
||||
// Set the post identifier and save the entity
|
||||
$entity->set_post($post_id)
|
||||
->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function assign_block_vars(array $entities, $block = 'dice_rolls')
|
||||
{
|
||||
/** @var \phpbbstudio\dice\entity\roll $entity */
|
||||
foreach ($entities as $entity)
|
||||
{
|
||||
$this->template->assign_block_vars($block, [
|
||||
'FORUM_ID' => $entity->get_forum(),
|
||||
'TOPIC_ID' => $entity->get_topic(),
|
||||
'POST_ID' => $entity->get_post(),
|
||||
'USER_ID' => $entity->get_user(),
|
||||
'ROLL_ID' => $entity->get_id(),
|
||||
'ROLL_NOTATION' => $entity->get_notation(),
|
||||
'ROLL_TIME' => $this->user->format_date($entity->get_time()),
|
||||
|
||||
'U_DELETE' => $this->helper->route('phpbbstudio_dice_del', ['roll_id' => (int) $entity->get_id()]),
|
||||
'U_EDIT' => $this->helper->route('phpbbstudio_dice_edit', ['roll_id' => (int) $entity->get_id()]),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_roll_data_for_edit($entity)
|
||||
{
|
||||
/** @var \phpbbstudio\dice\entity\roll $entity */
|
||||
return [
|
||||
'id' => $entity->get_id(),
|
||||
'notation' => $entity->get_notation(),
|
||||
'time' => $this->user->format_date($entity->get_time()),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_roll_data_for_display($entity, array $skin)
|
||||
{
|
||||
/** @var \phpbbstudio\dice\entity\roll $entity */
|
||||
return [
|
||||
'notation' => $entity->get_notation(),
|
||||
'display' => $entity->get_display($skin['name'], $skin['dir'], $skin['ext']),
|
||||
'output' => $entity->get_output(),
|
||||
'total' => $entity->get_total(),
|
||||
'post' => $entity->get_post(),
|
||||
'inline' => false,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function assign_roll_vars(array $roll)
|
||||
{
|
||||
$this->template->set_filenames([
|
||||
'dice' => '@phpbbstudio_dice/dice_roll.html',
|
||||
]);
|
||||
|
||||
$this->template->assign_vars([
|
||||
'NOTATION' => $roll['notation'],
|
||||
'DISPLAY' => $roll['display'],
|
||||
'OUTPUT' => $roll['output'],
|
||||
'TOTAL' => $roll['total'],
|
||||
'DICE_IMG_HEIGHT' => (int) $this->config['dice_skins_img_height'],
|
||||
'DICE_IMG_WIDTH' => (int) $this->config['dice_skins_img_width'],
|
||||
]);
|
||||
|
||||
return $this->template->assign_display('dice');
|
||||
}
|
||||
}
|
||||
125
ext/phpbbstudio/dice/operator/roll_interface.php
Normal file
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
/**
|
||||
* phpBB Studio's Dice extension for the phpBB Forum Software package.
|
||||
*
|
||||
* @copyright (c) 2019 phpBB Studio <https://www.phpbbstudio.com>
|
||||
* @license GNU General Public License, version 2 (GPL-2.0)
|
||||
*/
|
||||
|
||||
namespace phpbbstudio\dice\operator;
|
||||
|
||||
/**
|
||||
* Interface for our roll operator.
|
||||
*
|
||||
* This describes all of the methods we'll have for working with a set of rolls.
|
||||
*/
|
||||
interface roll_interface
|
||||
{
|
||||
/**
|
||||
* Get a roll entity.
|
||||
*
|
||||
* @return object \phpbbstudio\dice\entity\roll
|
||||
* @access public
|
||||
*/
|
||||
public function get_entity();
|
||||
|
||||
/**
|
||||
* Create roll entities from a rowset.
|
||||
*
|
||||
* @param array $rowset A rowset of fetched from the rolls table
|
||||
* @return array Array of roll entities
|
||||
* @access public
|
||||
*/
|
||||
public function get_entities(array $rowset);
|
||||
|
||||
/**
|
||||
* Delete roll entity|entities.
|
||||
*
|
||||
* @param mixed $roll_ids Roll identifier(s) to delete (int|array)
|
||||
* @return bool Whether any rows were deleted
|
||||
* @access public
|
||||
*/
|
||||
public function delete($roll_ids);
|
||||
|
||||
/**
|
||||
* Get the author of the post this roll belongs to.
|
||||
*
|
||||
* @param int $roll_id Roll identifier
|
||||
* @return int User identifier of the poster
|
||||
* @access public
|
||||
*/
|
||||
public function get_author($roll_id);
|
||||
|
||||
/**
|
||||
* Get roll entities for display.
|
||||
*
|
||||
* @param int $forum_id Forum identifier
|
||||
* @param int $topic_id Topic identifier
|
||||
* @param array $post_list Array with post identifiers
|
||||
* @return array Array of roll entities
|
||||
* @access public
|
||||
*/
|
||||
public function get_rolls_for_topic($forum_id, $topic_id, array $post_list);
|
||||
|
||||
/**
|
||||
* Get roll entities for posting, depending on the identifiers.
|
||||
*
|
||||
* @param int $forum_id The forum identifier
|
||||
* @param int $topic_id The topic identifier
|
||||
* @param int $post_id The post identifier
|
||||
* @return array
|
||||
* @access public
|
||||
*/
|
||||
public function get_rolls_for_posting($forum_id, $topic_id, $post_id);
|
||||
|
||||
/**
|
||||
* Update identifiers after a post has been submitted.
|
||||
*
|
||||
* @param string $mode The post mode
|
||||
* @param int $forum_id The forum identifier
|
||||
* @param int $topic_id The topic identifier
|
||||
* @param int $post_id The post identifier
|
||||
* @return void
|
||||
* @access public
|
||||
* @throws \phpbbstudio\dice\exception\out_of_bounds
|
||||
*/
|
||||
public function set_rolls_identifiers($mode, $forum_id, $topic_id, $post_id);
|
||||
|
||||
/**
|
||||
* Assign roll entities' variables to the template.
|
||||
*
|
||||
* @param array $entities Array of roll entities
|
||||
* @param string $block The template block name
|
||||
* @return void
|
||||
* @access public
|
||||
*/
|
||||
public function assign_block_vars(array $entities, $block = 'dice_rolls');
|
||||
|
||||
/**
|
||||
* Get roll data used for editing.
|
||||
*
|
||||
* @param \phpbbstudio\dice\entity\roll $entity The roll entity
|
||||
* @return array Array with the roll data
|
||||
* @access public
|
||||
*/
|
||||
public function get_roll_data_for_edit($entity);
|
||||
|
||||
/**
|
||||
* Get roll data used for display.
|
||||
*
|
||||
* @param \phpbbstudio\dice\entity\roll $entity The roll entity
|
||||
* @param array $skin Dice skin data
|
||||
* @return array Array with the roll data
|
||||
* @access public
|
||||
*/
|
||||
public function get_roll_data_for_display($entity, array $skin);
|
||||
|
||||
/**
|
||||
* Assign roll variables to the template.
|
||||
*
|
||||
* @param array $roll Array with the roll data
|
||||
* @return string String of the compiled roll
|
||||
* @access public
|
||||
*/
|
||||
public function assign_roll_vars(array $roll);
|
||||
}
|
||||
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d10_1.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d10_10.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d10_2.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d10_3.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d10_4.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d10_5.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d10_6.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d10_7.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d10_8.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d10_9.gif
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_1.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_10.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_11.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_12.gif
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_2.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_3.gif
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_4.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_5.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_6.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_7.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_8.gif
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d12_9.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d20_1.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d20_10.gif
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d20_11.gif
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d20_12.gif
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d20_13.gif
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d20_14.gif
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d20_15.gif
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d20_16.gif
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
ext/phpbbstudio/dice/skins/bajahs_red/d20_17.gif
Normal file
|
After Width: | Height: | Size: 1.6 KiB |