fix: n차 혼합 베팅 보상 수령이 하나만 되는 버그 수정
This commit is contained in:
+53
-17
@@ -25,7 +25,8 @@ class Betting
|
|||||||
return Json::encode($bettingType);
|
return Json::encode($bettingType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function purifyBettingKey(array $bettingType): array{
|
public function purifyBettingKey(array $bettingType): array
|
||||||
|
{
|
||||||
$selectCnt = $this->info->selectCnt;
|
$selectCnt = $this->info->selectCnt;
|
||||||
sort($bettingType, SORT_NUMERIC);
|
sort($bettingType, SORT_NUMERIC);
|
||||||
$bettingType = array_unique($bettingType, SORT_NUMERIC); //NOTE: key로 바로 사용하므로 중요함
|
$bettingType = array_unique($bettingType, SORT_NUMERIC); //NOTE: key로 바로 사용하므로 중요함
|
||||||
@@ -34,11 +35,11 @@ class Betting
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($bettingType[0] < 0) {
|
if ($bettingType[0] < 0) {
|
||||||
throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(0 미만)');
|
throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(0 미만)' . print_r($bettingType, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Util::array_last($bettingType) >= count($this->info->candidates)) {
|
if (Util::array_last($bettingType) >= count($this->info->candidates)) {
|
||||||
throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(초과)');
|
throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(초과)' . print_r($bettingType, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $bettingType;
|
return $bettingType;
|
||||||
@@ -66,7 +67,7 @@ class Betting
|
|||||||
}
|
}
|
||||||
|
|
||||||
$winnerList = $db->queryAllLists(
|
$winnerList = $db->queryAllLists(
|
||||||
'SELECT general_id, user_id, amount WHERE betting_id = %i AND betting_type = %s',
|
'SELECT general_id, user_id, amount FROM ng_betting WHERE betting_id = %i AND betting_type = %s AND general_id > 0',
|
||||||
$this->bettingID,
|
$this->bettingID,
|
||||||
$this->_convertBettingKey($bettingType)
|
$this->_convertBettingKey($bettingType)
|
||||||
);
|
);
|
||||||
@@ -85,7 +86,7 @@ class Betting
|
|||||||
|
|
||||||
$result = [];
|
$result = [];
|
||||||
foreach ($winnerList as [$generalID, $userID, $amount]) {
|
foreach ($winnerList as [$generalID, $userID, $amount]) {
|
||||||
$result[$generalID] = [
|
$result[] = [
|
||||||
'generalID' => $generalID,
|
'generalID' => $generalID,
|
||||||
'userID' => $userID,
|
'userID' => $userID,
|
||||||
'amount' => $amount * $multiplier,
|
'amount' => $amount * $multiplier,
|
||||||
@@ -136,7 +137,7 @@ class Betting
|
|||||||
|
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
foreach ($db->queryAllLists(
|
foreach ($db->queryAllLists(
|
||||||
'SELECT general_id, user_id, amount, betting_type WHERE betting_id = %i',
|
'SELECT general_id, user_id, amount, betting_type FROM ng_betting WHERE betting_id = %i',
|
||||||
$this->bettingID
|
$this->bettingID
|
||||||
) as [$generalID, $userID, $amount, $bettingTypeKey]) {
|
) as [$generalID, $userID, $amount, $bettingTypeKey]) {
|
||||||
$bettingType = Json::decode($bettingTypeKey);
|
$bettingType = Json::decode($bettingTypeKey);
|
||||||
@@ -169,7 +170,7 @@ class Betting
|
|||||||
$remainRewardAmount -= $givenRewardAmount; // /2가 아니라 다른 값이 될 경우를 대비..
|
$remainRewardAmount -= $givenRewardAmount; // /2가 아니라 다른 값이 될 경우를 대비..
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Util::range(1, $selectCnt) as $matchPoint) {
|
foreach (Util::range(1, $selectCnt + 1) as $matchPoint) {
|
||||||
if (!key_exists($matchPoint, $rewardAmount)) {
|
if (!key_exists($matchPoint, $rewardAmount)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -190,7 +191,7 @@ class Betting
|
|||||||
$multiplier = $subReward / $subAmount[$matchPoint];
|
$multiplier = $subReward / $subAmount[$matchPoint];
|
||||||
foreach ($subWinners[$matchPoint] as $subWinner) {
|
foreach ($subWinners[$matchPoint] as $subWinner) {
|
||||||
$subWinner['amount'] *= $multiplier;
|
$subWinner['amount'] *= $multiplier;
|
||||||
$result[$subWinner['generalID']] = $subWinner;
|
$result[] = $subWinner;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,43 +201,78 @@ class Betting
|
|||||||
public function giveReward(array $winnerType)
|
public function giveReward(array $winnerType)
|
||||||
{
|
{
|
||||||
$rewardList = $this->calcReward($winnerType);
|
$rewardList = $this->calcReward($winnerType);
|
||||||
|
$selectCnt = $this->info->selectCnt;
|
||||||
|
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
|
|
||||||
if ($this->info->reqInheritancePoint) {
|
if ($this->info->reqInheritancePoint) {
|
||||||
|
/** @var UserLogger[] */
|
||||||
|
$loggers = [];
|
||||||
foreach ($rewardList as $rewardItem) {
|
foreach ($rewardList as $rewardItem) {
|
||||||
if ($rewardItem['userID'] === null) {
|
if ($rewardItem['userID'] === null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$userID = $rewardItem['userID'];
|
$userID = $rewardItem['userID'];
|
||||||
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
|
||||||
$previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0];
|
|
||||||
|
|
||||||
$userLogger = new UserLogger($userID);
|
|
||||||
$amount = $rewardItem['amount'];
|
$amount = $rewardItem['amount'];
|
||||||
|
|
||||||
|
$inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}");
|
||||||
|
$previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0];
|
||||||
$nextPoint = $previousPoint + $amount;
|
$nextPoint = $previousPoint + $amount;
|
||||||
$inheritStor->setValue('previous', [$nextPoint, 0]);
|
$inheritStor->setValue('previous', [$nextPoint, 0]);
|
||||||
|
$inheritStor->invalidateCacheValue('previous');//XXX: 실제로는 previous 값을 사용할 수 없도록 락을 걸어야 한다.
|
||||||
|
|
||||||
$amountText = number_format($amount);
|
$amountText = number_format($amount);
|
||||||
$previousPointText = number_format($previousPoint);
|
$previousPointText = number_format($previousPoint);
|
||||||
$nextPointText = number_format($nextPoint);
|
$nextPointText = number_format($nextPoint);
|
||||||
|
|
||||||
$userLogger->push("{$this->info->name} 베팅 보상으로 {$amountText} 포인트 획득.", "inheritPoint");
|
$matchPoint = $rewardItem['matchPoint'];
|
||||||
|
|
||||||
|
if ($matchPoint == $selectCnt) {
|
||||||
|
$partialText = '베팅 당첨';
|
||||||
|
} else {
|
||||||
|
$partialText = "베팅 부분 당첨({$matchPoint}/{$selectCnt})";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_exists($userID, $loggers)) {
|
||||||
|
$userLogger = $loggers[$userID];
|
||||||
|
} else {
|
||||||
|
$userLogger = new UserLogger($userID);
|
||||||
|
$loggers[$userID] = $userLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[$year, $month] = Util::parseYearMonth($this->info->openYearMonth);
|
||||||
|
|
||||||
|
$userLogger->push("{$this->info->name} {$partialText} 보상으로 {$amountText} 포인트 획득.", "inheritPoint");
|
||||||
$userLogger->push("포인트 {$previousPointText} => {$nextPointText}", "inheritPoint");
|
$userLogger->push("포인트 {$previousPointText} => {$nextPointText}", "inheritPoint");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($loggers as $userLogger) {
|
||||||
$userLogger->flush();
|
$userLogger->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
foreach (General::createGeneralObjListFromDB(Util::squeezeFromArray($rewardList, 'generalID'), ['gold', 'npc'], 1) as $gambler) {
|
$generalList = General::createGeneralObjListFromDB(array_unique(Util::squeezeFromArray($rewardList, 'generalID')), ['gold', 'npc'], 1);
|
||||||
$reward = Util::round($rewardList[$gambler->getID()]['amount']);
|
foreach ($rewardList as $rewardItem) {
|
||||||
|
$gambler = $generalList[$rewardItem['generalID']];
|
||||||
|
$reward = Util::round($rewardItem['amount']);
|
||||||
|
$matchPoint = $rewardItem['matchPoint'];
|
||||||
$gambler->increaseVar('gold', $reward);
|
$gambler->increaseVar('gold', $reward);
|
||||||
if (($gambler->getNPCType() == 0) || ($gambler->getNPCType() == 1 && $gambler->getRankVar('betgold', 0) > 0)) {
|
if (($gambler->getNPCType() == 0) || ($gambler->getNPCType() == 1 && $gambler->getRankVar('betgold', 0) > 0)) {
|
||||||
$gambler->increaseRankVar('betwingold', $reward);
|
$gambler->increaseRankVar('betwingold', $reward);
|
||||||
$gambler->increaseRankVar('betwin', 1);
|
$gambler->increaseRankVar('betwin', 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($matchPoint == $selectCnt) {
|
||||||
|
$partialText = '베팅 당첨';
|
||||||
|
} else {
|
||||||
|
$partialText = "베팅 부분 당첨({$matchPoint}/{$selectCnt})";
|
||||||
|
}
|
||||||
$rewardText = number_format($reward);
|
$rewardText = number_format($reward);
|
||||||
$gambler->getLogger()->pushGeneralActionLog("<C>{$this->info->name}</>의 베팅 보상으로 <C>{$rewardText}</>의 <S>금</> 획득!", ActionLogger::EVENT_PLAIN);
|
$gambler->getLogger()->pushGeneralActionLog("<C>{$this->info->name}</>의 {$partialText} 보상으로 <C>{$rewardText}</>의 <S>금</> 획득!", ActionLogger::EVENT_PLAIN);
|
||||||
$gambler->applyDB($db);
|
}
|
||||||
|
|
||||||
|
foreach ($generalList as $general) {
|
||||||
|
$general->applyDB($db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace sammo\Event\Action;
|
namespace sammo\Event\Action;
|
||||||
|
|
||||||
|
use sammo\ActionLogger;
|
||||||
use sammo\Betting;
|
use sammo\Betting;
|
||||||
use \sammo\GameConst;
|
use \sammo\GameConst;
|
||||||
use \sammo\Util;
|
use \sammo\Util;
|
||||||
@@ -20,30 +21,43 @@ class FinishNationBetting extends \sammo\Event\Action
|
|||||||
{
|
{
|
||||||
$db = DB::db();
|
$db = DB::db();
|
||||||
|
|
||||||
$bettingStor = KVStorage::getStorage($db, 'betting');
|
try {
|
||||||
$bettingInfoRaw = $bettingStor->getValue("id_{$this->bettingID}");
|
|
||||||
if($bettingInfoRaw === null){
|
|
||||||
return [__CLASS__, true];
|
|
||||||
}
|
|
||||||
|
|
||||||
try{
|
|
||||||
$bettingHelper = new Betting($this->bettingID);
|
$bettingHelper = new Betting($this->bettingID);
|
||||||
}
|
} catch (\Exception $e) {
|
||||||
catch (\Exception $e){
|
|
||||||
return [__CLASS__, false, $e->getMessage()];
|
return [__CLASS__, false, $e->getMessage()];
|
||||||
}
|
}
|
||||||
|
|
||||||
$bettingInfo = $bettingHelper->getInfo();
|
$bettingInfo = $bettingHelper->getInfo();
|
||||||
if($bettingInfo->type != 'nationBetting'){
|
if ($bettingInfo->type != 'bettingNation') {
|
||||||
return [__CLASS__, false, 'invalid type', $bettingInfo->type];
|
return [__CLASS__, false, 'invalid type', $bettingInfo->type];
|
||||||
}
|
}
|
||||||
|
|
||||||
$winnerNations = $bettingHelper->purifyBettingKey($db->queryFirstColumn('SELECT nation FROM nation WHERE level > 0'));
|
$winnerNations = $db->queryFirstColumn('SELECT nation FROM nation WHERE level > 0');
|
||||||
if(count($winnerNations) != $bettingInfo->selectCnt){
|
if (count($winnerNations) != $bettingInfo->selectCnt) {
|
||||||
return [__CLASS__, false, 'invalid winner cnt', $bettingInfo->selectCnt];
|
return [__CLASS__, false, 'invalid winner cnt', $bettingInfo->selectCnt];
|
||||||
}
|
}
|
||||||
|
|
||||||
$bettingHelper->giveReward($winnerNations);
|
//nation_id와 betting_type이 일치하지 않으므로 정렬
|
||||||
|
$nationIDMap = [];
|
||||||
|
foreach ($bettingInfo->candidates as $idx => $candidate) {
|
||||||
|
$aux = $candidate->aux;
|
||||||
|
if (!$aux) {
|
||||||
|
return [__CLASS__, false, "invalid aux {$idx}:{$candidate->title}"];
|
||||||
|
}
|
||||||
|
$nationID = $aux['nation'];
|
||||||
|
$nationIDMap[$nationID] = $idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
$winnerTypes = [];
|
||||||
|
foreach ($winnerNations as $winnerNationID) {
|
||||||
|
$winnerTypes[] = $nationIDMap[$winnerNationID];
|
||||||
|
}
|
||||||
|
$winnerTypes = $bettingHelper->purifyBettingKey($winnerTypes);
|
||||||
|
|
||||||
|
$bettingHelper->giveReward($winnerTypes);
|
||||||
|
$logger = new ActionLogger(0, 0, $env['year'], $env['month']);
|
||||||
|
[$year, $month] = Util::parseYearMonth($bettingInfo->openYearMonth);
|
||||||
|
$logger->pushGlobalHistoryLog("<B><b>【내기】</b></> {$year}년 {$month}월에 열렸던 {$bettingInfo->name} 내기의 결과가 나왔습니다!");
|
||||||
|
|
||||||
return [__CLASS__, true];
|
return [__CLASS__, true];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ class OpenNationBetting extends \sammo\Event\Action
|
|||||||
$bettingInfo = new BettingInfo(
|
$bettingInfo = new BettingInfo(
|
||||||
id: $bettingID,
|
id: $bettingID,
|
||||||
type: 'bettingNation',
|
type: 'bettingNation',
|
||||||
name: "[{$year}년 {$month}월] {$name} 예상 베팅",
|
name: "{$name} 예상",
|
||||||
finished: false,
|
finished: false,
|
||||||
selectCnt: $this->nationCnt,
|
selectCnt: $this->nationCnt,
|
||||||
reqInheritancePoint: true,
|
reqInheritancePoint: true,
|
||||||
|
|||||||
@@ -95,7 +95,7 @@
|
|||||||
:key="info.id"
|
:key="info.id"
|
||||||
@click="loadBetting(info.id)"
|
@click="loadBetting(info.id)"
|
||||||
>
|
>
|
||||||
{{ info.name }}
|
[{{ parseYearMonth(info.openYearMonth)[0] }}년 {{ parseYearMonth(info.openYearMonth)[1] }}월] {{ info.name }}
|
||||||
<span v-if="info.finished">(종료)</span>
|
<span v-if="info.finished">(종료)</span>
|
||||||
<span
|
<span
|
||||||
v-else-if="(yearMonth ?? 0) <= info.closeYearMonth"
|
v-else-if="(yearMonth ?? 0) <= info.closeYearMonth"
|
||||||
|
|||||||
Reference in New Issue
Block a user