Merge branch 'develop' into feature/new-router

This commit is contained in:
slawkens 2022-11-28 13:14:09 +01:00
commit cdc06056c8
21 changed files with 177 additions and 58 deletions

13
.github/workflows/phplint.yml vendored Normal file
View File

@ -0,0 +1,13 @@
name: PHP Linting
on:
pull_request:
branches: [master, develop]
push:
branches: [master]
jobs:
phplint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: michaelw90/PHP-Lint@master

View File

@ -1,3 +1,3 @@
* Gesior.pl (2007 - 2008)
* Slawkens (2009 - 2021)
* Slawkens (2009 - 2022)
* Contributors listed in CONTRIBUTORS.txt

View File

@ -1,4 +1,4 @@
# MyAAC
# [MyAAC](https://my-aac.org)
[![Build Status Master](https://img.shields.io/travis/slawkens/myaac/master)](https://travis-ci.org/github/slawkens/myaac)
[![License: GPL-3.0](https://img.shields.io/github/license/slawkens/myaac)](https://opensource.org/licenses/gpl-license)
@ -11,7 +11,7 @@ MyAAC is a free and open-source Automatic Account Creator (AAC) written in PHP.
Official website: https://my-aac.org
### REQUIREMENTS
### Requirements
- PHP 5.6 or later
- MySQL database
@ -20,7 +20,7 @@ Official website: https://my-aac.org
- ZIP PHP Extension
- (optional) mod_rewrite to use friendly_urls
### INSTALLATION AND CONFIGURATION
### Installation
Just decompress and untar the source (which you should have done by now,
if you're reading this), into your webserver's document root.
@ -40,15 +40,40 @@ Official website: https://my-aac.org
Visit http://your_domain/install (http://localhost/install) and follow instructions in the browser.
### KNOWN PROBLEMS
### Configuration
- none -
Check *config.php* to get more informations.
Use *config.local.php* for your local configuration changes.
### OTHER NOTES
### Branches
This repository follows the Git Flow Workflow.
Cheatsheet: [Git-Flow-Cheetsheet](https://danielkummer.github.io/git-flow-cheatsheet)
That means, we use:
* master branch, for current stable release
* develop branch, for development version (next release)
* feature branches, for features etc.
### Known Problems
- Some compatibility issues with some exotical distibutions.
### Contributing
Contributions are more than welcome.
Pull requests should be made to the *develop* branch as that is the working branch, master is for release code.
Bug fixes to current release should be done to master branch.
Look: [Contributing](https://github.com/otsoft/myaac/wiki/Contributing) in our wiki.
### Other Notes
If you have a great idea or want contribute to the project - visit our website at https://www.my-aac.org
### LICENSING
### License
This program and all associated files are released under the GNU Public
License, see LICENSE for details.
This program and all associated files are released under the GNU Public License.
See [LICENSE](https://github.com/slawkens/myaac/blob/master/LICENSE) for details.

View File

@ -1 +0,0 @@
0.9.0-dev

View File

@ -27,7 +27,7 @@ if (version_compare(phpversion(), '7.1', '<')) die('PHP version 7.1 or higher is
const MYAAC = true;
const MYAAC_VERSION = '0.9.0-dev';
const DATABASE_VERSION = 32;
const DATABASE_VERSION = 33;
const TABLE_PREFIX = 'myaac_';
define('START_TIME', microtime(true));
define('MYAAC_OS', stripos(PHP_OS, 'WIN') === 0 ? 'WINDOWS' : (strtoupper(PHP_OS) === 'DARWIN' ? 'MAC' : 'LINUX'));

View File

@ -135,13 +135,17 @@ $config = array(
'smtp_secure' => '', // What kind of encryption to use on the SMTP connection. Options: '', 'ssl' (GMail) or 'tls' (Microsoft Outlook)
'smtp_debug' => false, // set true to debug (you will see more info in error.log)
// Google reCAPTCHA v3 (prevent spam bots)
// Google reCAPTCHA (prevent spam bots)
'recaptcha_enabled' => false, // enable recaptcha verification code
'recaptcha_type' => 'v3', // 'v2-checkbox', 'v2-invisible', 'v3'
'recaptcha_site_key' => '', // get your own site and secret keys at https://www.google.com/recaptcha
'recaptcha_secret_key' => '',
// following option apply only for ReCaptcha v2-checkbox
'recaptcha_v2_theme' => 'light', // light, dark
// following option apply only for ReCaptcha v3
// min score for validation, between 0 - 1.0
// https://developers.google.com/recaptcha/docs/v3#interpreting_the_score
'recaptcha_min_score' => 0.5,
'recaptcha_v3_min_score' => 0.5,
//
'generate_new_reckey' => true, // let player generate new recovery key, he will receive e-mail with new rec key (not display on page, hacker can't generate rec key)
@ -164,6 +168,8 @@ $config = array(
4 => 'Knight Sample'
),
'use_character_sample_skills' => false,
// it must show limited number of players after using search in character page
'characters_search_limit' => 15,

View File

@ -1,4 +1,4 @@
SET @myaac_database_version = 32;
SET @myaac_database_version = 33;
CREATE TABLE `myaac_account_actions`
(
@ -327,7 +327,7 @@ CREATE TABLE `myaac_spells`
CREATE TABLE `myaac_visitors`
(
`ip` VARCHAR(16) NOT NULL,
`ip` VARCHAR(45) NOT NULL,
`lastvisit` INT(11) NOT NULL DEFAULT 0,
`page` VARCHAR(2048) NOT NULL,
UNIQUE (`ip`)

View File

@ -11,7 +11,7 @@ server {
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_read_timeout 240;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~ /\.ht {

View File

@ -13,7 +13,7 @@ fi
if [ $1 = "prepare" ]; then
# define release version
version=`cat VERSION`
version=`php system/get_version_for_release.php`
echo "Preparing to release version $version of the MyAAC Project!"
@ -24,7 +24,7 @@ if [ $1 = "prepare" ]; then
# get myaac from git archive
git archive --format zip --output tmp/myaac.zip master
cd tmp/
cd tmp/ || exit
dir="myaac-$version"
if [ -d "$dir" ] ; then
@ -41,9 +41,9 @@ fi
if [ $1 = "pack" ]; then
# define release version
version=`cat VERSION`
version=`php system/get_version_for_release.php`
cd tmp
cd tmp || exit
# tar.gz
echo "Creating .tar.gz package.."

View File

@ -0,0 +1,6 @@
<?php
require __DIR__ . '/../common.php';
if(IS_CLI) {
echo MYAAC_VERSION;
}

View File

@ -193,8 +193,14 @@ class CreateCharacter
$player->setManaSpent($char_to_copy->getManaSpent());
$player->setSoul($char_to_copy->getSoul());
for($skill = POT::SKILL_FIRST; $skill <= POT::SKILL_LAST; $skill++)
$player->setSkill($skill, 10);
for($skill = POT::SKILL_FIRST; $skill <= POT::SKILL_LAST; $skill++) {
$value = 10;
if (config('use_character_sample_skills')) {
$value = $char_to_copy->getSkill($skill);
}
$player->setSkill($skill, $value);
}
$player->setLookBody($char_to_copy->getLookBody());
$player->setLookFeet($char_to_copy->getLookFeet());
@ -234,16 +240,22 @@ class CreateCharacter
if($db->hasTable('player_skills')) {
for($i=0; $i<7; $i++) {
$value = 10;
if (config('use_character_sample_skills')) {
$value = $char_to_copy->getSkill($i);
}
$skillExists = $db->query('SELECT `skillid` FROM `player_skills` WHERE `player_id` = ' . $player->getId() . ' AND `skillid` = ' . $i);
if($skillExists->rowCount() <= 0) {
$db->query('INSERT INTO `player_skills` (`player_id`, `skillid`, `value`, `count`) VALUES ('.$player->getId().', '.$i.', 10, 0)');
$db->query('INSERT INTO `player_skills` (`player_id`, `skillid`, `value`, `count`) VALUES ('.$player->getId().', '.$i.', ' . $value . ', 0)');
}
}
}
$loaded_items_to_copy = $db->query("SELECT * FROM player_items WHERE player_id = ".$char_to_copy->getId()."");
foreach($loaded_items_to_copy as $save_item)
$db->query("INSERT INTO `player_items` (`player_id` ,`pid` ,`sid` ,`itemtype`, `count`, `attributes`) VALUES ('".$player->getId()."', '".$save_item['pid']."', '".$save_item['sid']."', '".$save_item['itemtype']."', '".$save_item['count']."', '".$save_item['attributes']."');");
foreach($loaded_items_to_copy as $save_item) {
$blob = $db->quote($save_item['attributes']);
$db->query("INSERT INTO `player_items` (`player_id` ,`pid` ,`sid` ,`itemtype`, `count`, `attributes`) VALUES ('".$player->getId()."', '".$save_item['pid']."', '".$save_item['sid']."', '".$save_item['itemtype']."', '".$save_item['count']."', $blob);");
}
global $twig;
$twig->display('success.html.twig', array(

View File

@ -41,17 +41,22 @@ class GoogleReCAPTCHA
}
$json = json_decode($response);
//log_append('recaptcha.log', 'recaptcha_score: ' . $json->score . ', action:' . $json->action);
if (!isset($json->action) || $json->action !== $action) {
self::$errorType = self::ERROR_INVALID_ACTION;
self::$errorMessage = 'Google ReCaptcha returned invalid action.';
return false;
}
if (!isset($json->score) || $json->score < config('recaptcha_min_score')) {
self::$errorType = self::ERROR_LOW_SCORE;
self::$errorMessage = 'Your Google ReCaptcha score was too low.';
return false;
$recaptchaType = config('recaptcha_type');
if ($recaptchaType === 'v3') { // score based
//log_append('recaptcha.log', 'recaptcha_score: ' . $json->score . ', action:' . $json->action);
if (!isset($json->action) || $json->action !== $action) {
self::$errorType = self::ERROR_INVALID_ACTION;
self::$errorMessage = 'Google ReCaptcha returned invalid action.';
return false;
}
if (!isset($json->score) || $json->score < config('recaptcha_v3_min_score')) {
self::$errorType = self::ERROR_LOW_SCORE;
self::$errorMessage = 'Your Google ReCaptcha score was too low.';
return false;
}
}
if (!isset($json->success) || !$json->success) {

View File

@ -2489,7 +2489,7 @@ class OTS_Player extends OTS_Row_DAO
$value = $this->db->query('SELECT ' . $this->db->fieldName('value') . ' FROM ' . $this->db->tableName('player_storage') . ' WHERE ' . $this->db->fieldName('key') . ' = ' . (int) $key . ' AND ' . $this->db->fieldName('player_id') . ' = ' . $this->data['id'])->fetch();
if($value !== false)
if($value === false)
{
return null;
}

6
system/migrations/33.php Normal file
View File

@ -0,0 +1,6 @@
<?php
// Increase size of ip in myaac_visitors table
// according to this answer: https://stackoverflow.com/questions/166132/maximum-length-of-the-textual-representation-of-an-ipv6-address
// the size of ipv6 can be maximal 45 chars
$db->exec('ALTER TABLE `' . TABLE_PREFIX . "visitors` MODIFY `ip` VARCHAR(45) NOT NULL;");

View File

@ -109,8 +109,24 @@
{{ hook('HOOK_ACCOUNT_CREATE_AFTER_PASSWORDS') }}
{% if config.recaptcha_enabled %}
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" />
{% if config.recaptcha_enabled %}
{% if config.recaptcha_type == 'v3' %}
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" />
{% elseif config.recaptcha_type == 'v2-invisible' %}
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-bind="login-submit"></div>
{% elseif config.recaptcha_type == 'v2-checkbox' %}
<tr>
<td class="LabelV" style="width: 150px">
<span{% if errors.verification[0] is not null %} class="red"{% endif %}>Verification:</span>
</td>
<td>
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-theme="{{ config.recaptcha_v2_theme }}"></div>
</td>
</tr>
{% if errors.verification is defined %}
<tr><td></td><td><span class="FormFieldError">{{ errors.verification }}</span></td></tr>
{% endif %}
{% endif %}
{% endif %}
{{ hook('HOOK_ACCOUNT_CREATE_AFTER_RECAPTCHA') }}
@ -329,9 +345,9 @@
</form>
{{ hook('HOOK_ACCOUNT_CREATE_AFTER_FORM') }}
<script type="text/javascript" src="tools/check_name.js"></script>
{% if config.recaptcha_enabled %}
{% if config.recaptcha_enabled and config.recaptcha_type == 'v3' %}
{% set action = 'register' %}
{{ include('google_recaptcha.html.twig') }}
{{ include('google_recaptcha_v3.html.twig') }}
{% endif %}
<style>
#SuggestAccountNumber {

View File

@ -40,7 +40,20 @@ Please enter your account {{ account|lower }} and your password.<br/><a href="{{
<label for="remember_me"> Remember me</label></td>
</tr>
{% if config.recaptcha_enabled %}
{% if config.recaptcha_type == 'v3' %}
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" />
{% elseif config.recaptcha_type == 'v2-invisible' %}
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-bind="login-submit"></div>
{% elseif config.recaptcha_type == 'v2-checkbox' %}
<tr>
<td class="LabelV" style="width: 150px">
<span{% if error is not null %} class="red"{% endif %}>Verification:</span>
</td>
<td>
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-theme="{{ config.recaptcha_v2_theme }}"></div>
</td>
</tr>
{% endif %}
{% endif %}
{% if error is not null %}
<tr><td></td><td><span class="FormFieldError">{{ error }}</span></td></tr>
@ -77,7 +90,7 @@ Please enter your account {{ account|lower }} and your password.<br/><a href="{{
</td>
</tr>
</table>
{% if config.recaptcha_enabled %}
{% if config.recaptcha_enabled and config.recaptcha_type == 'v3' %}
{% set action = 'login' %}
{{ include('google_recaptcha.html.twig') }}
{{ include('google_recaptcha_v3.html.twig') }}
{% endif %}

View File

@ -22,9 +22,9 @@
<div class="form-group row">
<label for="select-type">Type</label>
<select class="form-control" name="type" id="select-type">
<option value="{{ constant('NEWS') }}" {% if type is defined and type == constant('NEWS') %}selected="yes"{% endif %}{% if action == 'edit' and type != constant('NEWS') %} disabled{% endif %}>News</option>
<option value="{{ constant('TICKER') }}" {% if type is defined and type == constant('TICKER') %}selected="yes"{% endif %}{% if action == 'edit' and type != constant('TICKER') %} disabled{% endif %}>Ticket</option>
<option value="{{ constant('ARTICLE') }}" {% if type is defined and type == constant('ARTICLE') %}selected="yes"{% endif %}{% if action == 'edit' and type != constant('ARTICLE') %} disabled{% endif %}>Article</option>
<option value="{{ constant('NEWS') }}" {% if type is defined and type == constant('NEWS') %}selected="selected"{% endif %}{% if action == 'edit' and type != constant('NEWS') %} disabled{% endif %}>News</option>
<option value="{{ constant('TICKER') }}" {% if type is defined and type == constant('TICKER') %}selected="selected"{% endif %}{% if action == 'edit' and type != constant('TICKER') %} disabled{% endif %}>Ticker</option>
<option value="{{ constant('ARTICLE') }}" {% if type is defined and type == constant('ARTICLE') %}selected="selected"{% endif %}{% if action == 'edit' and type != constant('ARTICLE') %} disabled{% endif %}>Article</option>
</select>
</div>

View File

@ -0,0 +1,11 @@
<script>
$(document).ready(function() {
grecaptcha.ready(function() {
grecaptcha.execute('{{ config.recaptcha_site_key }}', {action: '{{ action }}'}).then(function(token) {
if (token) {
document.getElementById('g-recaptcha-response').value = token;
}
});
});
});
</script>

View File

@ -1,8 +1,2 @@
{% if constant('PAGE') == 'rules' %}
<b>{{ config.lua.serverName }} Rules</b><br/>
<textarea rows="25" wrap="physical" cols="70" readonly="true">
{% endif %}
{{ getCustomPage('rules_on_the_page') }}
{% if constant('PAGE') == 'rules' %}
</textarea>
{% endif %}
{{ getCustomPage('rules_on_the_page') | nl2br }}

View File

@ -17,5 +17,5 @@
</div>
</noscript>
{% if config.recaptcha_enabled %}
<script src="https://www.google.com/recaptcha/api.js?render={{ config.recaptcha_site_key }}"></script>
<script src="https://www.google.com/recaptcha/api.js{% if config('recaptcha_type') == 'v2-checkbox' %}?render={{ config.recaptcha_site_key }}{% endif %}"></script>
{% endif %}

View File

@ -48,7 +48,20 @@
<label for="remember_me"> Remember me</label></td>
</tr>
{% if config.recaptcha_enabled %}
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" />
{% if config.recaptcha_type == 'v3' %}
<input type="hidden" name="g-recaptcha-response" id="g-recaptcha-response" />
{% elseif config.recaptcha_type == 'v2-invisible' %}
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-bind="login-submit"></div>
{% elseif config.recaptcha_type == 'v2-checkbox' %}
<tr>
<td class="LabelV" style="width: 150px">
<span{% if error is not null %} class="red"{% endif %}>Verification:</span>
</td>
<td>
<div class="g-recaptcha" data-sitekey="{{ config.recaptcha_site_key }}" data-theme="{{ config.recaptcha_v2_theme }}"></div>
</td>
</tr>
{% endif %}
{% endif %}
</table>
<div style="float: right; font-size: 1px;" >
@ -147,7 +160,7 @@
</tr>
</table>
</div>
{% if config.recaptcha_enabled %}
{% if config.recaptcha_enabled and config.recaptcha_type == 'v3' %}
{% set action = 'login' %}
{{ include('google_recaptcha.html.twig') }}
{{ include('google_recaptcha_v3.html.twig') }}
{% endif %}