feat(WIP): 베팅 관련 작업중
This commit is contained in:
@@ -0,0 +1,141 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\NationCommand;
|
||||||
|
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\DB;
|
||||||
|
use Sammo\DTO\BettingItem;
|
||||||
|
use sammo\Validator;
|
||||||
|
use sammo\Json;
|
||||||
|
use sammo\DTO\NationBettingInfo;
|
||||||
|
use sammo\GameConst;
|
||||||
|
use sammo\General;
|
||||||
|
use sammo\KVStorage;
|
||||||
|
use sammo\Util;
|
||||||
|
|
||||||
|
use function sammo\getAllNationStaticInfo;
|
||||||
|
|
||||||
|
class PushCommand extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
$v = new Validator($this->args);
|
||||||
|
$v->rule('required', [
|
||||||
|
'betting_id',
|
||||||
|
'betting_type',
|
||||||
|
'amount'
|
||||||
|
])
|
||||||
|
->rule('integer', 'betting_id')
|
||||||
|
->rule('integerArray', 'betting_type')
|
||||||
|
->rule('integer', 'amount')
|
||||||
|
->rule('min', 'amount', 1);
|
||||||
|
|
||||||
|
if (!$v->validate()) {
|
||||||
|
return $v->errorStr();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$db = DB::db();
|
||||||
|
|
||||||
|
/** @var int */
|
||||||
|
$bettingID = $this->arg['betting_id'];
|
||||||
|
/** @var int[] */
|
||||||
|
$bettingType = $this->arg['betting_type'];
|
||||||
|
/** @var int[] */
|
||||||
|
$amount = $this->args['amount'];
|
||||||
|
|
||||||
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
|
$nationBettingStor = KVStorage::getStorage($db, 'nation_betting');
|
||||||
|
$rawBettingInfo = $nationBettingStor->getValue("id_{$bettingID}");
|
||||||
|
if($rawBettingInfo === null){
|
||||||
|
return '해당 베팅이 없습니다';
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
$bettingInfo = new NationBettingInfo($rawBettingInfo);
|
||||||
|
}
|
||||||
|
catch(\Error $e){
|
||||||
|
return $e->getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if($bettingInfo->finished){
|
||||||
|
return '이미 종료된 베팅입니다';
|
||||||
|
}
|
||||||
|
|
||||||
|
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
|
||||||
|
$yearMonth = Util::joinYearMonth($year, $month);
|
||||||
|
|
||||||
|
|
||||||
|
if($bettingInfo->closeYearMonth > $yearMonth){
|
||||||
|
return '이미 마감된 베팅입니다';
|
||||||
|
}
|
||||||
|
|
||||||
|
if($bettingInfo->openYearMonth > $yearMonth){
|
||||||
|
return '아직 시작되지 않은 베팅입니다';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count($bettingType) != $bettingInfo->selectCnt){
|
||||||
|
return '필요한 선택 수를 채우지 못했습니다.';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sort($bettingType);//NOTE: key로 바로 사용하므로 중요함
|
||||||
|
$bettingTypeKey = Json::encode($bettingType);
|
||||||
|
$nations = getAllNationStaticInfo();
|
||||||
|
|
||||||
|
foreach($bettingType as $bettingNationID){
|
||||||
|
if(!key_exists($bettingNationID, $nations)){
|
||||||
|
return '존재하지 않는 국가를 선택했습니다.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$general = General::createGeneralObjFromDB($session->generalID, ['gold', 'aux'], 1);
|
||||||
|
|
||||||
|
if($bettingInfo->reqInheritancePoint){
|
||||||
|
if($general->getInheritancePoint('previous') < $amount){
|
||||||
|
return '유산포인트가 충분하지 않습니다.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if($general->getVar('gold') < GameConst::$generalMinimumGold + $amount){
|
||||||
|
return '금이 부족합니다.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$userID = $session->userID;
|
||||||
|
|
||||||
|
$bettingItem = new BettingItem([
|
||||||
|
'betting_id'=>$bettingID,
|
||||||
|
'general_id'=>$session->generalID,
|
||||||
|
'user_id'=>$userID,
|
||||||
|
'betting_type'=>$bettingTypeKey,
|
||||||
|
'amount'=>$amount
|
||||||
|
]);
|
||||||
|
|
||||||
|
if($bettingInfo->reqInheritancePoint){
|
||||||
|
$general->increaseInheritancePoint('previous', -$amount);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$general->increaseVar('gold', -$amount);
|
||||||
|
}
|
||||||
|
$db->insert('ng_betting', $bettingItem->toArray());
|
||||||
|
if(!$db->affected_rows){
|
||||||
|
$general->flushUpdateValues();
|
||||||
|
return '베팅을 실패했습니다.';
|
||||||
|
}
|
||||||
|
$general->applyDB($db);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'result'=>true
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\API\NationCommand;
|
||||||
|
|
||||||
|
use sammo\Session;
|
||||||
|
use DateTimeInterface;
|
||||||
|
use sammo\DB;
|
||||||
|
use sammo\DTO\NationBettingInfo;
|
||||||
|
use sammo\KVStorage;
|
||||||
|
|
||||||
|
use function sammo\checkLimit;
|
||||||
|
use function sammo\increaseRefresh;
|
||||||
|
|
||||||
|
class GetReservedCommand extends \sammo\BaseAPI
|
||||||
|
{
|
||||||
|
public function validateArgs(): ?string
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRequiredSessionMode(): int
|
||||||
|
{
|
||||||
|
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||||
|
{
|
||||||
|
$db = DB::db();
|
||||||
|
|
||||||
|
increaseRefresh("국가베팅장", 1);
|
||||||
|
|
||||||
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
|
$nationBettingStor = KVStorage::getStorage($db, 'nation_betting');
|
||||||
|
$userID = $session->userID;
|
||||||
|
|
||||||
|
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,penalty,permission FROM general WHERE owner=%i', $userID);
|
||||||
|
$con = checkLimit($me['con']);
|
||||||
|
if ($con >= 2) {
|
||||||
|
return "접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다. (다음 갱신 가능 시각 : {$me['turntime']})";
|
||||||
|
}
|
||||||
|
|
||||||
|
$bettingList = [];
|
||||||
|
foreach ($nationBettingStor->getAll() as $_key => $rawItem) {
|
||||||
|
$item = new NationBettingInfo($rawItem);
|
||||||
|
$bettingList[$item->id] = $rawItem;
|
||||||
|
$bettingList[$item->id]['totalAmount'] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$bettingIDList = array_keys($bettingList);
|
||||||
|
// XXX: query cache만 믿고 sum을 하는 짓을 벌여도 되는가?
|
||||||
|
foreach ($db->queryAllLists(
|
||||||
|
'SELECT betting_id, sum(amount) as total_amount FROM ng_betting WHERE betting_id IN %li GROUP BY betting_id',
|
||||||
|
$bettingIDList
|
||||||
|
) as [$bettingID, $totalAmount]) {
|
||||||
|
if (!key_exists($bettingID, $bettingList)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$bettingList[$bettingID]['totalAmount'] = $totalAmount;
|
||||||
|
}
|
||||||
|
|
||||||
|
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'result' => false,
|
||||||
|
'bettingList' => $bettingList,
|
||||||
|
'year' => $year,
|
||||||
|
'month' => $month,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Sammo\DTO;
|
||||||
|
|
||||||
|
use Spatie\DataTransferObject\Attributes\MapFrom;
|
||||||
|
use Spatie\DataTransferObject\Attributes\Strict;
|
||||||
|
use Spatie\DataTransferObject\DataTransferObject;
|
||||||
|
|
||||||
|
#[Strict]
|
||||||
|
class BettingItem extends DataTransferObject
|
||||||
|
{
|
||||||
|
#[MapFrom('id')]
|
||||||
|
public null|int $rowID = null;
|
||||||
|
#[MapFrom('betting_id')]
|
||||||
|
public int $bettingID;
|
||||||
|
#[MapFrom('general_id')]
|
||||||
|
public int $generalID;
|
||||||
|
#[MapFrom('user_id')]
|
||||||
|
public null|int $userID;
|
||||||
|
#[MapFrom('betting_type')]
|
||||||
|
public string $bettingType;
|
||||||
|
public int $amount;
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo\DTO;
|
||||||
|
|
||||||
|
use Spatie\DataTransferObject\Attributes\Strict;
|
||||||
|
use Spatie\DataTransferObject\DataTransferObject;
|
||||||
|
|
||||||
|
//https://json2dto.atymic.dev/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#[Strict]
|
||||||
|
class NationBettingInfo extends DataTransferObject
|
||||||
|
{
|
||||||
|
public int $id;
|
||||||
|
public string $name;
|
||||||
|
public bool $finished;
|
||||||
|
public int $selectCnt;
|
||||||
|
public bool $reqInheritancePoint;
|
||||||
|
public int $openYearMonth;
|
||||||
|
public int $closeYearMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"id": 45,
|
||||||
|
"name": "1차전",
|
||||||
|
"finished": false,
|
||||||
|
"selectCnt": 1,
|
||||||
|
"reqInheritancePoint": true,
|
||||||
|
"openYearMonth": 110,
|
||||||
|
"closeYearMonth": 120
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace sammo;
|
||||||
|
|
||||||
|
include "lib.php";
|
||||||
|
include "func.php";
|
||||||
|
//로그인 검사
|
||||||
|
$session = Session::requireGameLogin()->setReadOnly();
|
||||||
|
$userID = Session::getUserID();
|
||||||
|
|
||||||
|
$db = DB::db();
|
||||||
|
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||||
|
|
||||||
|
$generalID = $session->generalID;
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=500" />
|
||||||
|
<title><?= UniqueConst::$serverName ?>: 내무부</title>
|
||||||
|
<?= WebUtil::printStaticValues([
|
||||||
|
'staticValues' => [
|
||||||
|
|
||||||
|
]
|
||||||
|
], false) ?>
|
||||||
|
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
|
||||||
|
<?= WebUtil::printCSS('../d_shared/common.css') ?>
|
||||||
|
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
|
||||||
|
<?= WebUtil::printDist('vue', 'v_nationBetting', true) ?>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user