Обучение #39

Merged
lopar merged 15 commits from maksym into dev 2023-01-23 11:45:10 +00:00
11 changed files with 253 additions and 36 deletions
Showing only changes of commit 739caee04b - Show all commits

View File

@ -0,0 +1,30 @@
<?php
namespace DarksLight2\Training\Steps;
use DarksLight2\Training\StepFactory;
class SecondStep extends StepFactory
{
public function getTitle(): string
{
return 'Тест';
}
public function getMessage(): string
{
return 'Тест';
}
public function getShortName(): string
{
return 'second_step';
}
public function getRewards(): array
{
return [];
}
}

View File

@ -20,7 +20,7 @@ class TrainingManager
public function __construct(int $user_id) public function __construct(int $user_id)
{ {
$this->user_id = $user_id; $this->user_id = $user_id;
$this->generateToken();
} }
/** /**
@ -71,6 +71,7 @@ class TrainingManager
public function render() public function render()
{ {
if(!$this->isComplete) {
$path = $_SERVER['DOCUMENT_ROOT'] . '/modules_data/steps/' . $this->short_name . '.php'; $path = $_SERVER['DOCUMENT_ROOT'] . '/modules_data/steps/' . $this->short_name . '.php';
if (file_exists($path)) { if (file_exists($path)) {
@ -80,6 +81,7 @@ class TrainingManager
throw TrainingException::noRenderingFile(); throw TrainingException::noRenderingFile();
} }
}
}; };
} }
} }
@ -87,19 +89,61 @@ class TrainingManager
private function stepData(string $short_name): object private function stepData(string $short_name): object
{ {
return json_decode($this->getDatabaseRecords()->data)->$short_name; $data = $this->getDatabaseRecords()->data;
if(!isset($data->$short_name)) {
$this->updateDatabaseRecord($short_name);
$data = $this->getDatabaseRecords()->data;
} }
private function getDatabaseRecords() return $data->$short_name;
}
private function generateToken($length = 16)
{
$letters = 'abcdefgmikiHGJKLjkGASysj7603456';
$token = '';
for ($i = 0; $i <= $length; $i++) {
$token .= $letters[rand(0, strlen($letters))];
}
Db::run('UPDATE user_training SET api_token = ? WHERE user_id = ?', [
$token,
$this->user_id
]);
}
public function getDatabaseRecords(): stdClass
{ {
if(!$this->database_records) { if(!$this->database_records) {
$this->database_records = Db::run('SELECT * FROM user_training WHERE user_id = ?', [$this->user_id]) $data = Db::run('SELECT * FROM user_training WHERE user_id = ?', [$this->user_id])
DarksLight2 marked this conversation as resolved
Review

Если нет особой необходимости, лучше использовать стандартный Db::getRows(), для единообразия.

Если нет особой необходимости, лучше использовать стандартный Db::getRows(), для единообразия.
Review

Выбрал этот путь, потому что только одна запись там должна быть.

Выбрал этот путь, потому что только одна запись там должна быть.
Review

Тогда Db::getRow

Тогда Db::getRow
->fetch(PDO::FETCH_OBJ); ->fetch(PDO::FETCH_OBJ);
$this->database_records = new stdClass();
$this->database_records->user_id = $data->user_id;
$this->database_records->api_token = $data->api_token;
$this->database_records->data = json_decode($data->data);
} }
return $this->database_records; return $this->database_records;
} }
public function updateDatabaseRecord(string $short_name)
{
if($this->getDatabaseRecords()) {
$this->database_records->data->$short_name = $this->firstRecordData()->$short_name;
Db::run('UPDATE user_training SET data = ? WHERE user_id = ?', [
json_encode($this->database_records->data),
$this->user_id
]);
}
}
public function createDatabaseRecord() public function createDatabaseRecord()
{ {
if(!$this->getDatabaseRecords()) { if(!$this->getDatabaseRecords()) {
@ -110,19 +154,22 @@ class TrainingManager
} }
} }
private function firstRecordData(): array private function firstRecordData(): stdClass
{ {
return [ $data = new stdClass();
'first_step' => [ $short_names = [
'complete' => 0, 'first_step',
'progress' => [ 'second_step'
'current' => 0,
'need' => 0,
]
]
]; ];
foreach ($short_names as $name) {
$data->$name->complete = false;
$data->$name->progress->current = 0;
$data->$name->progress->need = 1;
} }
return $data;
}
public function __get(string $name) public function __get(string $name)
{ {
return $this->steps[$name]; return $this->steps[$name];
@ -130,11 +177,25 @@ class TrainingManager
public function addPoint(string $short_name) public function addPoint(string $short_name)
{ {
$this->$short_name->progress++; $this->database_records->data->$short_name->progress->current++;
}
public function nextStep()
{
foreach ($this->database_records->data as $step) {
if($step->complete === false && $step->progress->current >= $step->progress->need) {
$step->complete = true;
}
}
} }
public function store() public function store()
{ {
$this->nextStep();
Db::run('UPDATE user_training SET data = ? WHERE user_id = ?', [
json_encode($this->database_records->data),
$this->user_id
]);
} }
} }

4
api/.htaccess Normal file
View File

@ -0,0 +1,4 @@
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^training/complete/?$ index.php?get=complete [L]
</IfModule>

47
api/index.php Normal file
View File

@ -0,0 +1,47 @@
<?php
use DarksLight2\Training\TrainingManager;
header('Content-type: application/json');
if (!defined('GAME_VERSION')) {
require_once '../_incl_data/autoload.php';
}
$user = User::start();
if($input = file_get_contents("php://input")) {
$data = json_decode($input);
}
if(!empty($user->info)) {
$training = TrainingManager::getInstance($user->info['id']);
if (!isset($data->token) || !password_verify(
$training->getDatabaseRecords()->api_token . $data->time . $user->info['id'],
$data->token
)) {
http_response_code(401);
die;
}
if (isset($_GET['get'])) {
switch ($_GET['get']) {
default:
http_response_code(400);
die;
case 'complete':
if ($training->{$data->short_name}->isComplete) {
http_response_code(400);
die;
}
$training->addPoint($data->short_name);
$training->nextStep();
$training->store();
die(json_encode(['status' => 'ok']));
}
}
}

View File

@ -4,7 +4,7 @@
right: 0; right: 0;
bottom: 0; bottom: 0;
left: 0; left: 0;
background: rgba(0, 0, 0, 0.5); /*background: rgba(0, 0, 0, 0.5);*/
opacity: 0; opacity: 0;
z-index: -1; z-index: -1;
pointer-events: none; pointer-events: none;

View File

@ -1,3 +1,24 @@
const request = new XMLHttpRequest();
const training_handler = () => {
request.open('POST', '/api/training/complete')
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
request.onreadystatechange = function() {//Call a function when the state changes.
if(request.readyState === 4 && request.status === 200) {
parent.frames['main'].location.reload();
}
}
request.send(JSON.stringify({
time: training_data().time,
token: training_data().token,
short_name: training_data().short_name
}))
}
let active_training = null;
(function () { (function () {
if (typeof window.CustomEvent === "function") return false; if (typeof window.CustomEvent === "function") return false;
function CustomEvent(event, params) { function CustomEvent(event, params) {

View File

@ -29,11 +29,14 @@
<div class="se-pre-con" id="se-pre-con"></div> <div class="se-pre-con" id="se-pre-con"></div>
<?php <?php
if (!defined('GAME_VERSION')) { if (!defined('GAME_VERSION')) {
require_once '_incl_data/autoload.php'; require_once '_incl_data/autoload.php';
} }
use Core\{Config, Database, Db}; use Core\{Config, Database, Db};
use DarksLight2\Training\TrainingManager;
function var_info($vars, $d = false) function var_info($vars, $d = false)
{ {
@ -556,6 +559,12 @@ $spl = $spl['exp'];
echo '<script>top.myexpLineTop27(' . $u->info['exp'] . ',' . $spl . ');' . $tjs . 'top.ctest("' . $u->info['city'] . '");top.sd4key="' . $u->info['nextAct'] . '"; var battle = ' . (0 + $u->info['battle']) . '; top.hic();</script></body> echo '<script>top.myexpLineTop27(' . $u->info['exp'] . ',' . $spl . ');' . $tjs . 'top.ctest("' . $u->info['city'] . '");top.sd4key="' . $u->info['nextAct'] . '"; var battle = ' . (0 + $u->info['battle']) . '; top.hic();</script></body>
</html>'; </html>';
$training_manager = TrainingManager::getInstance();
if($u->room['file']=='cp1') {
$training_manager->first_step->render();
$training_manager->second_step->render();
}
?> ?>
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.2/modernizr.js"></script>--> <!--<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.2/modernizr.js"></script>-->
<script> <script>

View File

@ -1,7 +1,5 @@
<? <?
use DarksLight2\Training\TrainingManager;
if(!defined('GAME')) if(!defined('GAME'))
{ {
die(); die();
@ -11,9 +9,6 @@ require_once('/home/newcom1/public_html/_incl_data/class/__db_connect.php');
if($u->room['file']=='cp1') { if($u->room['file']=='cp1') {
$training_manager = TrainingManager::getInstance();
$training_manager->first_step->render();
if(date("H")>=8 && date("H")<=23) { if(date("H")>=8 && date("H")<=23) {
$now = 'day'; $now = 'day';
$tattack = '<a style="color:#D8D8D8" style="cursor:pointer" onclick="top.useMagic(\'Нападение на персонажа\',\'night_atack\',\'pal_button8.gif\',1,\'main.php?nightatack=1\');">Напасть на игрока</a> &nbsp; '; $tattack = '<a style="color:#D8D8D8" style="cursor:pointer" onclick="top.useMagic(\'Нападение на персонажа\',\'night_atack\',\'pal_button8.gif\',1,\'main.php?nightatack=1\');">Напасть на игрока</a> &nbsp; ';

View File

@ -1,23 +1,26 @@
<?php <?php
use DarksLight2\Training\TrainingManager; /**
* @var string $token
* @var int $time
* @var string $button_text
* @var object $step
*/
$short_name = 'first_step'; $short_name = 'first_step';
$manager = TrainingManager::getInstance(); require 'step.php';
$step = $manager->$short_name;
$button_text = 'Продолжить';
if(!$manager) {
$button_text = '';
}
?>
?>
<script> <script>
const training_data = () => { const training_data = () => {
return { return {
content: `<?=$step->message?>`, content: `<?=$step->message?>`,
title: `<?=$step->title?>`, title: `<?=$step->title?>`,
button_text: `<?=$button_text?>` button_text: `<?=$button_text?>`,
time: <?=$time?>,
token: '<?=$token?>',
short_name: '<?=$short_name?>',
} }
} }
</script> </script>

View File

@ -0,0 +1,31 @@
<?php
/**
* @var string $token
* @var int $time
* @var string $button_text
* @var object $step
*/
$short_name = 'second_step';
require 'step.php';
?>
<script>
const training_data = () => {
return {
content: `<?=$step->message?>`,
title: `<?=$step->title?>`,
button_text: `<?=$button_text?>`,
time: <?=$time?>,
token: '<?=$token?>',
short_name: '<?=$short_name?>',
}
}
</script>
<script src="/js/training/modal.js"></script>
<script>
modal.show()
</script>

View File

@ -0,0 +1,16 @@
<?php
DarksLight2 marked this conversation as resolved
Review

Точно классы вызовутся без загрузчика?

Точно классы вызовутся без загрузчика?
Review

этот файл инклудится, чтобы не дублировать код вынес в отдельный файл

этот файл инклудится, чтобы не дублировать код вынес в отдельный файл
/**
* @var string $short_name
*/
$user = User::start();
use DarksLight2\Training\TrainingManager;
$manager = TrainingManager::getInstance();
$step = $manager->$short_name;
$button_text = 'Продолжить';
$time = time();
$token = password_hash($manager->getDatabaseRecords()->api_token . $time . $user->info['id'], PASSWORD_DEFAULT);