From 79f30ea2757969ca3449c42016371763097aad0a Mon Sep 17 00:00:00 2001 From: Hide_D Date: Mon, 25 Apr 2022 01:06:32 +0900 Subject: [PATCH] =?UTF-8?q?refac:=20=ED=86=A0=EB=84=88=EB=A8=BC=ED=8A=B8?= =?UTF-8?q?=20=EB=B2=A0=ED=8C=85=20=EC=84=B8=EB=B6=80=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=EC=9D=84=20ng=5Fbetting=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= =?UTF-8?q?=20(#218)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 토너먼트 베팅을 betting 테이블 대신 Betting 모듈을 이용하는 형태로 변경 - 이전 토너먼트 베팅 기록이 남음 - 현재 이전 토너먼트 기록을 볼 수는 없음 - 베팅에 API/Betting/Bet 을 이용 - 토너먼트, 베팅 페이지를 Betting 모듈에 맞게 임시 조정 - 이전 버전과의 호환성을 위해 betting table과 betting 테이블에 초기값을 추가하는 로직은 남김 - 이후 0.30이 되었을 때 제거 Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/218 --- .phan/config.php | 1 - hwe/_119.php | 2 +- hwe/b_betting.php | 147 +++++++++++++++++---------- hwe/b_tournament.php | 92 +++++++++++++---- hwe/c_tournament.php | 2 + hwe/func.php | 15 +-- hwe/func_tournament.php | 205 ++++++++++++++++++++++---------------- hwe/index.php | 12 +-- hwe/j_betting.php | 76 -------------- hwe/sammo/Betting.php | 48 ++++++--- hwe/sammo/ResetHelper.php | 10 ++ hwe/ts/betting.ts | 36 +++---- src/sammo/Session.php | 2 +- 13 files changed, 355 insertions(+), 293 deletions(-) delete mode 100644 hwe/j_betting.php diff --git a/.phan/config.php b/.phan/config.php index 56676933..0d09cd0c 100644 --- a/.phan/config.php +++ b/.phan/config.php @@ -84,7 +84,6 @@ return [ 'hwe/j_adjust_icon.php', 'hwe/j_autoreset.php', 'hwe/j_basic_info.php', - 'hwe/j_betting.php', 'hwe/j_board_article_add.php', 'hwe/j_board_comment_add.php', 'hwe/j_board_get_articles.php', diff --git a/hwe/_119.php b/hwe/_119.php index 513301d1..206a45dc 100644 --- a/hwe/_119.php +++ b/hwe/_119.php @@ -14,7 +14,7 @@ $gameStor = KVStorage::getStorage($db, 'game_env'); [$turntime, $tnmt_time] = $gameStor->getValuesAsArray(['turntime','tnmt_time']); -$plock = $db->queryFirstField('SELECT plock FROM plock'); +$plock = $db->queryFirstField('SELECT plock FROM plock WHERE `type` ="GAME"'); ?> diff --git a/hwe/b_betting.php b/hwe/b_betting.php index dae28212..b20d4024 100644 --- a/hwe/b_betting.php +++ b/hwe/b_betting.php @@ -16,17 +16,11 @@ TurnExecutionHelper::executeAllCommand(); $generalID = $session->generalID; -//NOTE: general_id만 빼기 귀찮음. -$myBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = %i', $generalID); -$myBet = array_splice($myBet, -16); -$globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0'); -$globalBet = array_splice($globalBet, -16); + + $me = $db->queryFirstRow('SELECT no,tournament,con,turntime from general where owner=%i', $userID); -$myBetTotal = array_sum($myBet); -$globalBetTotal = array_sum($globalBet); - $admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'develcost']); $con = checkLimit($me['con']); @@ -36,34 +30,68 @@ if ($con >= 2) { } switch ($admin['tnmt_type']) { - default: - throw new \RuntimeException('Invalid tnmt_type'); case convertTournamentType('전력전'): - $tnmt_type = "전력전"; + $tnmt_type = "전력전"; + $color = "cyan"; $tp = "total"; $tp2 = "종합"; $tp3 = "total"; break; case convertTournamentType('통솔전'): - $tnmt_type = "통솔전"; + $tnmt_type = "통솔전"; + $color = "cyan"; $tp = "leadership"; $tp2 = "통솔"; $tp3 = "leadership"; break; case convertTournamentType('일기토'): - $tnmt_type = "일기토"; + $tnmt_type = "일기토"; + $color = "cyan"; $tp = "strength"; $tp2 = "무력"; $tp3 = "strength"; break; case convertTournamentType('설전'): - $tnmt_type = "설전"; + $tnmt_type = "설전"; + $color = "cyan"; $tp = "intel"; $tp2 = "지력"; $tp3 = "intel"; break; + default: + throw new \RuntimeException('Invalid tnmt_type'); } +$bettingID = $gameStor->last_tournament_betting_id ?? 0; +$myBet = []; +$globalBet = []; + +if ($bettingID != 0) { + $betting = $bettingID != 0 ? new Betting($bettingID) : null; + $info = $betting->getInfo(); + + foreach ($db->queryAllLists( + 'SELECT general_id, user_id, amount, betting_type FROM ng_betting WHERE betting_id = %i', + $bettingID + ) as [$betGeneralID, $userID, $amount, $bettingTypeKey]) { + $bettingKey = Json::decode($bettingTypeKey)[0]; + if ($betGeneralID == $generalID) { + $myBet[$bettingKey] = $amount; + } + + if (key_exists($bettingKey, $globalBet)) { + $globalBet[$bettingKey] += $amount; + } else { + $globalBet[$bettingKey] = $amount; + } + } +} else { + $info = getDummyBettingInfo($tnmt_type); +} + +$myBetTotal = array_sum($myBet); +$globalBetTotal = array_sum($globalBet); + $str1 = getTournament($admin['tournament']); $str2 = getTournamentTime(); if ($str2) { @@ -90,6 +118,11 @@ if ($str3) { + [ + 'bettingID'=> $bettingID + ] + ])?> @@ -104,7 +137,7 @@ if ($str3) { - () + () @@ -293,9 +326,9 @@ if ($str3) { } $gen[$i] = $general['name']; if (array_key_exists($tp, $general)) { - $stat[$i] = $general[$tp]; + $stat[$i] = $general[$tp]; } else { - $stat[$i] = "-"; + $stat[$i] = "-"; } } for ($i = 0; $i < 8; $i++) { @@ -305,17 +338,17 @@ if ($str3) { echo "{$line[$i * 2]}{$cent[$i]}{$line[$i * 2 + 1]}"; } ?> - - - - - - - - - - - + + + + + + + + + + + @@ -323,29 +356,29 @@ if ($str3) { candidates as $key => $candidate) { + $keyMap[$candidate->aux['idx']] = $key; + } - for ($i = 0; $i < 16; $i++) { - if ($globalBet[$i] == 0) { - $bet[$i] = "∞"; - } else { - $bet[$i] = round($globalBetTotal / $globalBet[$i], 2); - } - } - - for ($i = 0; $i < 16; $i++) { - if (!is_numeric($bet[$i])) { - $gold[$i] = 0; - } else { - $gold[$i] = Util::round($myBet[$i] * $bet[$i]); - } - } + foreach ($globalBet as $key => $amount) { + if ($amount == 0) { + $bet[$key] = "∞"; + $gold[$key] = 0; + } else { + $rewardRatio = round($globalBetTotal / $amount, 2); + $bet[$key] = $rewardRatio; + $gold[$key] = $rewardRatio * ($myBet[$key] ?? 0); + } + } echo " "; - for ($i = 0; $i < 16; $i++) { - echo ""; + foreach (range(0, 15) as $i) { + $amount = $bet[$keyMap[$i] ?? -1] ?? 0; + echo ""; } ?> @@ -369,8 +402,9 @@ if ($str3) { {$myBet[$i]}"; + foreach (range(0, 15) as $i) { + $amount = $myBet[$keyMap[$i] ?? -1] ?? 0; + echo ""; } ?> @@ -394,8 +428,9 @@ if ($str3) { {$gold[$i]}"; + foreach (range(0, 15) as $i) { + $amount = $gold[$keyMap[$i] ?? -1] ?? 0; + echo ""; } echo " @@ -406,10 +441,11 @@ if ($str3) { echo " "; - for ($i = 0; $i < 16; $i++) { + foreach (range(0, 15) as $i) { + $key = $keyMap[$i] ?? -1; echo " "; - for ($i = 0; $i < 16; $i++) { + foreach (range(0, 15) as $i) { + $key = $keyMap[$i] ?? -1; echo " - "; + "; } echo ""; diff --git a/hwe/b_tournament.php b/hwe/b_tournament.php index a174cbfc..99dc2c71 100644 --- a/hwe/b_tournament.php +++ b/hwe/b_tournament.php @@ -15,6 +15,7 @@ increaseRefresh("토너먼트", 1); TurnExecutionHelper::executeAllCommand(); $me = $db->queryFirstRow('select no,tournament,con,turntime from general where owner=%i', $userID); +$generalID = $session->generalID; $admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_msg', 'tnmt_type', 'develcost', 'tnmt_trig']); @@ -25,34 +26,76 @@ if ($con >= 2) { } switch ($admin['tnmt_type']) { - default: - throw new \RuntimeException('invalid tnmt_type'); - case 0: - $tnmt_type = "전력전"; + case convertTournamentType('전력전'): + $tnmt_type = "전력전"; + $color = 'cyan'; $tp = "total"; $tp2 = "종합"; $tp3 = "total"; break; - case 1: - $tnmt_type = "통솔전"; + case convertTournamentType('통솔전'): + $tnmt_type = "통솔전"; + $color = 'cyan'; $tp = "leadership"; $tp2 = "통솔"; $tp3 = "leadership"; break; - case 2: - $tnmt_type = "일기토"; + case convertTournamentType('일기토'): + $tnmt_type = "일기토"; + $color = 'cyan'; $tp = "strength"; $tp2 = "무력"; $tp3 = "strength"; break; - case 3: - $tnmt_type = "설전"; + case convertTournamentType('설전'): + $tnmt_type = "설전"; + $color = 'cyan'; $tp = "intel"; $tp2 = "지력"; $tp3 = "intel"; break; + default: + throw new \RuntimeException('invalid tnmt_type'); } + +$bettingID = $gameStor->last_tournament_betting_id ?? 0; +if ($bettingID != 0) { + $betting = $bettingID != 0 ? new Betting($bettingID) : null; + $info = $betting->getInfo(); +} else { + $info = getDummyBettingInfo($tnmt_type); +} + +$myBet = []; +$globalBet = []; + +if ($bettingID != 0) { + $betting = $bettingID != 0 ? new Betting($bettingID) : null; + $info = $betting->getInfo(); + + foreach ($db->queryAllLists( + 'SELECT general_id, user_id, amount, betting_type FROM ng_betting WHERE betting_id = %i', + $bettingID + ) as [$betGeneralID, $userID, $amount, $bettingTypeKey]) { + $bettingKey = Json::decode($bettingTypeKey)[0]; + if ($betGeneralID == $generalID) { + $myBet[$bettingKey] = $amount; + } + + if (key_exists($bettingKey, $globalBet)) { + $globalBet[$bettingKey] += $amount; + } else { + $globalBet[$bettingKey] = $amount; + } + } +} else { + $info = getDummyBettingInfo($tnmt_type); +} + +$myBetTotal = array_sum($myBet); +$globalBetTotal = array_sum($globalBet); + ?> @@ -209,7 +252,7 @@ switch ($admin['tnmt_type']) { @@ -418,24 +461,31 @@ switch ($admin['tnmt_type']) { echo " "; - $globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0') ?? [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,]; - $globalBet = array_splice($globalBet, -16); - $globalBetTotal = array_sum($globalBet); $admin = $gameStor->getValues(['tournament', 'phase']); $bet = []; - for ($i = 0; $i < 16; $i++) { - if ($globalBet[$i] == 0) { - $bet[$i] = '∞'; - continue; + $gold = []; + $keyMap = []; + foreach ($info->candidates as $key => $candidate) { + $keyMap[$candidate->aux['idx']] = $key; + } + + foreach ($globalBet as $key => $amount) { + if ($amount == 0) { + $bet[$key] = "∞"; + $gold[$key] = 0; + } else { + $rewardRatio = round($globalBetTotal / $amount, 2); + $bet[$key] = $rewardRatio; + $gold[$key] = $rewardRatio * ($myBet[$key] ?? 0); } - $bet[$i] = round($globalBetTotal / $globalBet[$i], 2); } echo " "; - for ($i = 0; $i < 16; $i++) { - echo ""; + foreach (range(0, 15) as $i) { + $amount = $bet[$keyMap[$i] ?? -1] ?? 0; + echo ""; } echo " diff --git a/hwe/c_tournament.php b/hwe/c_tournament.php index e34cc19a..aaf89b61 100644 --- a/hwe/c_tournament.php +++ b/hwe/c_tournament.php @@ -225,6 +225,8 @@ if($btn == "자동개최설정") { finallyAll($admin['tnmt_type'], $admin['tournament'], $admin['phase']); } elseif($btn == "배정") { final16set(); + $phase = 0; + startBetting($admin['tnmt_type'], 720); } elseif($btn == "베팅마감") { $dt = date("Y-m-d H:i:s", time() + 60); $gameStor->tournament=7; diff --git a/hwe/func.php b/hwe/func.php index dfbe9057..d6ca6911 100644 --- a/hwe/func.php +++ b/hwe/func.php @@ -472,7 +472,8 @@ function getCommandTable(General $general) return $result; } -function getChiefCommandTable(General $general){ +function getChiefCommandTable(General $general) +{ $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor->turnOnCache(); @@ -1121,7 +1122,7 @@ function CheckOverhead() function isLock() { - return DB::db()->queryFirstField("SELECT plock from plock limit 1") != 0; + return DB::db()->queryFirstField("SELECT plock from plock WHERE `type`='GAME'") != 0; } function tryLock(): bool @@ -1133,7 +1134,7 @@ function tryLock(): bool $db->update('plock', [ 'plock' => 1, 'locktime' => TimeUtil::now(true) - ], 'plock=0'); + ], 'plock=0 AND type="GAME"'); return $db->affectedRows() > 0; } @@ -1144,7 +1145,7 @@ function unlock(): bool $db = DB::db(); $db->update('plock', [ 'plock' => 0 - ], true); + ], 'type="GAME"'); return $db->affectedRows() > 0; } @@ -1581,7 +1582,7 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool } } - foreach($db->queryAllLists('SELECT namespace, count(*) as cnt FROM `storage` WHERE namespace LIKE "ut_%" GROUP BY namespace') as [$uniqueNS, $cnt]){ + foreach ($db->queryAllLists('SELECT namespace, count(*) as cnt FROM `storage` WHERE namespace LIKE "ut_%" GROUP BY namespace') as [$uniqueNS, $cnt]) { $itemCode = substr($uniqueNS, 3); $itemClass = buildItemClass($itemCode); if (!$itemClass) { @@ -1590,7 +1591,7 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool if ($itemClass->isBuyable()) { continue; } - $occupiedUnique[$itemCode] = ($occupiedUnique[$itemCode]??0) + $cnt; + $occupiedUnique[$itemCode] = ($occupiedUnique[$itemCode] ?? 0) + $cnt; } foreach (GameConst::$allItems as $itemType => $itemCategories) { @@ -1632,7 +1633,7 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool $relMonthByInit = Util::joinYearMonth($year, $month) - Util::joinYearMonth($initYear, $initMonth); $availableBuyUnique = $relMonthByInit >= GameConst::$minMonthToAllowInheritItem; - if($availableBuyUnique){ + if ($availableBuyUnique) { $general->setAuxVar('inheritRandomUnique', null); } } diff --git a/hwe/func_tournament.php b/hwe/func_tournament.php index c67754c6..9bf51ca2 100644 --- a/hwe/func_tournament.php +++ b/hwe/func_tournament.php @@ -2,13 +2,14 @@ namespace sammo; +use sammo\DTO\BettingInfo; function processTournament() { $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); - $admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'tnmt_auto', 'tnmt_time']); + $admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'tnmt_auto', 'tnmt_time', 'last_tournament_betting_id']); $now = new \DateTime(); $offset = $now->getTimestamp() - (new \DateTime($admin['tnmt_time']))->getTimestamp(); @@ -90,9 +91,12 @@ function processTournament() final16set(); $tnmt = 6; $phase = 0; - startBetting(); + startBetting($type, $unit); break; case 6: //베팅중 + $bettingID = $admin['last_tournament_betting_id']; + $betting = new Betting($bettingID); + $betting->closeBetting(); $tnmt = 7; $phase = 0; break; @@ -164,23 +168,32 @@ function processTournament() $gameStor->tnmt_time = (new \DateTimeImmutable($admin['tnmt_time']))->add(new \DateInterval("PT{$second}S"))->format('Y-m-d H:i:s'); } -function getTournamentTerm(): ?int{ +function getTournamentTerm(): ?int +{ $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); $tnmt_auto = $gameStor->tnmt_auto; - if($tnmt_auto === null){ + if ($tnmt_auto === null) { $tnmt_auto = $gameStor->tnmt_trig; } - switch($tnmt_auto){ - case 0: return null; - case 1: return 12 * 60; - case 2: return 7 * 60; - case 3: return 3 * 60; - case 4: return 1 * 60; - case 5: return 30; - case 6: return 15; - case 7: return 5; + switch ($tnmt_auto) { + case 0: + return null; + case 1: + return 12 * 60; + case 2: + return 7 * 60; + case 3: + return 3 * 60; + case 4: + return 1 * 60; + case 5: + return 30; + case 6: + return 15; + case 7: + return 5; } return null; } @@ -189,16 +202,16 @@ function getTournamentTermText() { $term = getTournamentTerm(); - if($term === null){ + if ($term === null) { return '수동'; } - if($term % 60 === 0){ + if ($term % 60 === 0) { $termMin = intdiv($term, 60); return "경기당 {$termMin}분"; } - if($term > 60){ + if ($term > 60) { $termSec = $term % 60; $termMin = intdiv($term, 60); return "경기당 {$termMin}분 {$termSec}초"; @@ -268,7 +281,7 @@ function printRow($k, $npc, $name, $abil, $tgame, $win, $draw, $lose, $gd, $gl, $k += 1; if ($prmt > 0) { $name = "" . $name . ""; - } else if($npc > 0){ + } else if ($npc > 0) { $name = formatName($name, $npc); } echo ""; @@ -367,29 +380,12 @@ function startTournament($auto, $type) $gameStor->tnmt_time = (new \DateTimeImmutable())->add(new \DateInterval("PT{$unit}M"))->format('Y-m-d H:i:s'); $gameStor->tournament = 1; $gameStor->tnmt_type = $type; + $gameStor->last_tournament_betting_id = 0; $gameStor->phase = 0; $db->update('general', [ 'tournament' => 0, ], true); - $db->update('betting', [ - 'bet0' => 0, - 'bet1' => 0, - 'bet2' => 0, - 'bet3' => 0, - 'bet4' => 0, - 'bet5' => 0, - 'bet6' => 0, - 'bet7' => 0, - 'bet8' => 0, - 'bet9' => 0, - 'bet10' => 0, - 'bet11' => 0, - 'bet12' => 0, - 'bet13' => 0, - 'bet14' => 0, - 'bet15' => 0 - ], true); $db->query('TRUNCATE TABLE tournament'); $opener = $db->queryFirstField('SELECT `general`.`name` FROM `general` JOIN `nation` ON `general`.`nation` = `nation`.`nation` WHERE `general`.`officer_level` = 12 AND `nation`.`level` = 7 ORDER BY rand() LIMIT 1'); @@ -416,44 +412,90 @@ function startTournament($auto, $type) pushGlobalHistoryLog($history, $admin['year'], $admin['month']); } -function startBetting() +function getDummyBettingInfo(string $tnmt_type): BettingInfo +{ + return new BettingInfo( + id: 0, + type: 'tournament', + name: $tnmt_type, + finished: true, + selectCnt: 1, + reqInheritancePoint: false, + openYearMonth: 0, + closeYearMonth: 0, + candidates: [] + ); +} + +function startBetting($type, $unit) { $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); - [$year, $month, $startyear] = $gameStor->getValuesAsArray(['year', 'month', 'startyear']); + [$year, $month, $startyear, $turnterm] = $gameStor->getValuesAsArray(['year', 'month', 'startyear', 'turnterm']); pushGlobalHistoryLog([ "◆{$year}년 {$month}월:【대회】우승자를 예상하는 내기가 진행중입니다! 호사가의 참여를 기다립니다!" ], $year, $month); + [$typeText, $statName, $statKey] = [ + ['전력전', '종능', 'total'], + ['통솔전', '통솔', 'leadership'], + ['일기토', '무력', 'strength'], + ['설전', '지력', 'intel'], + ][$type]; + + $bettingID = Betting::genNextBettingID(); + + + //어차피 강제로 닫을 것이므로 크게 신경쓰지 않는다. + $openYearMonth = Util::joinYearMonth($year, $month); + $closeYearMonth = $openYearMonth + 120; + + /** @var \sammo\DTO\SelectItem[] */ + $candidates = []; + + $generalList = $db->query('SELECT no,npc,name,win,leadership,strength,intel,leadership+strength+intel as total from tournament where grp>=20 order by grp, grp_no LIMIT 16'); + foreach ($generalList as $idx => $general) { + if ($general['no'] <= 0) { + continue; + } + $general['idx'] = $idx; + $candidates[$general['no']] = new \sammo\DTO\SelectItem( + title: $general['name'], + info: "{$statName}: {$general[$statKey]}", + aux: $general + ); + } + $candidateCnt = count($candidates); + + Betting::openBetting(new BettingInfo( + id: $bettingID, + type: 'tournament', + name: $typeText, + finished: false, + selectCnt: 1, + reqInheritancePoint: false, + openYearMonth: $openYearMonth, + closeYearMonth: $closeYearMonth, + candidates: $candidates, + )); + + $betting = new Betting($bettingID); + + $gameStor->last_tournament_betting_id = $bettingID; + $betGold = Util::valueFit(floor((3 + $year - $startyear) * 0.334) * 10, 10); $npcList = $db->queryFirstColumn('SELECT no FROM general WHERE npc >= 2 AND gold >= (500 + %i)', $betGold); $npcBet = []; - $betSum = [ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - ]; + $targetList = array_keys($candidates); foreach ($npcList as $npcID) { - $target = Util::randRangeInt(0, 15); - $betSum[$target] += $betGold; + $target = Util::choiceRandom($targetList); $npcBet[] = [$npcID, $target]; } - $db->update('general', [ - 'gold' => $db->sqleval('gold - %i', $betGold), - ], 'no IN %li', $npcList); foreach ($npcBet as [$npcID, $betTarget]) { - $targetKey = "bet{$betTarget}"; - $db->update('betting', [ - "bet{$betTarget}" => $db->sqleval('%b + %i', $targetKey, $betGold), - ], 'general_id = %i', $npcID); - } - foreach ($betSum as $betTarget => $betSumGold) { - $targetKey = "bet{$betTarget}"; - $db->update('betting', [ - "bet{$betTarget}" => $db->sqleval('%b + %i', $targetKey, $betSumGold), - ], 'general_id = 0'); + $betting->bet($npcID, null, [$betTarget], $betGold); } } @@ -514,19 +556,19 @@ function fillLowGenAll($tnmt_type) //자동신청하고, 돈 있고, 아직 참가 안한 장수 $freeJoinerCandidate = []; - foreach($db->query( + foreach ($db->query( 'SELECT no,npc,name,leadership,strength,intel,explevel,horse,weapon,book from general where tnmt=1 and tournament=0', - ) as $gen){ + ) as $gen) { $score = $scoringCandFunction($gen); - $freeJoinerCandidate[$gen['no']] = [$gen, $score**1.5]; + $freeJoinerCandidate[$gen['no']] = [$gen, $score ** 1.5]; } $joinersValues = []; $joinersIdx = []; - foreach(Util::range($toBeFilledCnt) as $_){ - if(!$freeJoinerCandidate){ + foreach (Util::range($toBeFilledCnt) as $_) { + if (!$freeJoinerCandidate) { break; } $general = Util::choiceRandomUsingWeightPair($freeJoinerCandidate); @@ -987,7 +1029,7 @@ function setGift($tnmt_type, $tnmt, $phase) $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); - $admin = $gameStor->getValues(['year', 'month', 'develcost']); + $admin = $gameStor->getValues(['year', 'month', 'develcost', 'last_tournament_betting_id']); $resultHelper = []; @@ -1143,36 +1185,16 @@ function setGift($tnmt_type, $tnmt, $phase) $generalObjList[$generalID]->increaseInheritancePoint('tournament', $general['inheritance_point']); } - //우승자 번호 - $winnerGrp = $resultHelper[$winner['no']]['grp']; - $winnerGrpNo = $resultHelper[$winner['no']]['grp_no']; - $winnerSlot = ($winnerGrp - 20) * 2 + $winnerGrpNo; - //당첨칸에 베팅한 사람들만 - $globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0'); - $globalBet = array_splice($globalBet, -16); - $globalBetTotal = array_sum($globalBet); - $rewardRate = round($globalBetTotal / max($globalBet[$winnerSlot], 1), 2); - - $betKey = "bet{$winnerSlot}"; - $gambleResult = Util::convertArrayToDict($db->query('SELECT general_id, %b as bet FROM betting WHERE %b > 0 AND general_id > 0', $betKey, $betKey), 'general_id'); - - foreach (General::createGeneralObjListFromDB(Util::squeezeFromArray($gambleResult, 'general_id'), ['gold', 'npc'], 1) as $gambler) { - $reward = Util::round($gambleResult[$gambler->getID()]['bet'] * $rewardRate); - $gambler->increaseVar('gold', $reward); - if (($gambler->getNPCType() == 0) || ($gambler->getNPCType() == 1 && $gambler->getRankVar('betgold', 0) > 0)) { - $gambler->increaseRankVar('betwingold', $reward); - $gambler->increaseRankVar('betwin', 1); - } - $rewardText = number_format($reward); - $gambler->getLogger()->pushGeneralActionLog("{$tp} 대회의 베팅 당첨으로 {$rewardText}의 금 획득!", ActionLogger::EVENT_PLAIN); - $gambler->applyDB($db); - } + $bettingID = $gameStor->last_tournament_betting_id; + $betting = new Betting($bettingID); + $betting->giveReward([$winner['no']]); } function setRefund() { $db = DB::db(); + $gameStor = KVStorage::getStorage($db, 'game_env'); //16강자 명성 돈 @@ -1183,6 +1205,17 @@ function setRefund() ], 'no IN %li', $generalIDList); //베팅금 환수 + $bettingID = $gameStor->last_tournament_betting_id ?? 0; + if (!$bettingID == 0) { + $betting = new Betting($bettingID); + if (!$betting->getInfo()->finished) { + $betting->giveReward([-1]); + } + } + + + + $db->update(['general', [ 'gold' => $db->sqleval('gold + (SELECT bet0+bet1+bet2+bet3+bet4+bet5+bet6+bet7+bet8+bet9+bet10+bet11+bet12+bet13+bet14+bet15 FROM betting WHERE general_id = general.no)') ]], true); diff --git a/hwe/index.php b/hwe/index.php index cd3ae7a6..a7512320 100644 --- a/hwe/index.php +++ b/hwe/index.php @@ -47,7 +47,7 @@ if ($me['newmsg'] == 1 || $me['newvote'] == 1) { ], 'owner=%i', $userID); } -$plock = boolval($db->queryFirstField('SELECT plock FROM plock LIMIT 1')); +$plock = boolval($db->queryFirstField('SELECT plock FROM plock WHERE `type`="GAME" LIMIT 1')); $con = checkLimit($me['con']); if ($con >= 2) { @@ -189,11 +189,11 @@ if (!$otherTextInfo) {
턴당 갱신횟수 : conlimit ?>회
- - ↑tnmt_type] ?? '' ?> tournament) ?> ↑ - - 현재 토너먼트 경기 없음 - + + ↑tnmt_type] ?? '' ?> tournament) ?> ↑ + + 현재 토너먼트 경기 없음 +
동작 시각: " . substr($gameStor->turntime, 5, 14) . "") : ("동작 시각: " . substr($gameStor->turntime, 5, 14) . "") ?>
diff --git a/hwe/j_betting.php b/hwe/j_betting.php deleted file mode 100644 index af4d0d52..00000000 --- a/hwe/j_betting.php +++ /dev/null @@ -1,76 +0,0 @@ -= 16 || $betGold < 10 || $betGold > 1000){ - Json::die([ - 'result'=>false, - 'reason'=>'올바르지 않은 입력입니다' - ]); -} - -//로그인 검사 -$session = Session::requireGameLogin()->setReadOnly(); -$userID = Session::getUserID(); -$generalID = $session->generalID; - -$db = DB::db(); -$gameStor = KVStorage::getStorage($db, 'game_env'); - -increaseRefresh("베팅", 1); - -$tournament = $gameStor->tournament; -if($tournament != 6) { - Json::die([ - 'result'=>false, - 'reason'=>'베팅 기간이 아닙니다.' - ]); -} - -$myGold = $db->queryFirstField('SELECT gold FROM general WHERE no = %i', $generalID); -$bets = $db->queryFirstList('SELECT * FROM betting WHERE general_id = %i', $generalID); -$bets = array_splice($bets, -16); -$totalBet = array_sum($bets); -$oldBet = $bets[$betTarget]; - -$targetKey = "bet{$betTarget}"; - -if($myGold - $betGold < 500){ - Json::die([ - 'result'=>false, - 'reason'=>'여유 자금이 부족합니다.' - ]); -} - -if($betGold + $totalBet > 1000){ - Json::die([ - 'result'=>false, - 'reason'=>'베팅 허용 금액을 초과했습니다.' - ]); -} - -$db->update('betting', [ - $targetKey=>$db->sqleval('%b + %i', $targetKey, $betGold), -], 'general_id = %i', $generalID); -$db->update('general', [ - 'gold'=>$db->sqleval('gold - %i', $betGold), -], 'no = %i', $generalID); -$db->update('rank_data', [ - 'value'=>$db->sqleval('value + %i', $betGold) -], 'general_id = %i AND type = "betgold"', $generalID); -$db->update('betting', [ - $targetKey=>$db->sqleval('%b + %i', $targetKey, $betGold) -], 'general_id = 0'); - -Json::die([ - 'result'=>true, - 'reason'=>'SUCCESS' -]); \ No newline at end of file diff --git a/hwe/sammo/Betting.php b/hwe/sammo/Betting.php index ca33aa6b..def3584e 100644 --- a/hwe/sammo/Betting.php +++ b/hwe/sammo/Betting.php @@ -10,9 +10,10 @@ class Betting private BettingInfo $info; - public CONST LAST_BETTING_ID_KEY = 'last_betting_id'; + public const LAST_BETTING_ID_KEY = 'last_betting_id'; - static public function genNextBettingID(): int{ + static public function genNextBettingID(): int + { $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); @@ -24,7 +25,8 @@ class Betting return $bettingID; } - static public function openBetting(BettingInfo $info){ + static public function openBetting(BettingInfo $info) + { $db = DB::db(); $bettingID = $info->id; $bettingStor = KVStorage::getStorage($db, 'betting'); @@ -47,7 +49,7 @@ class Betting return Json::encode($bettingType); } - public function purifyBettingKey(array $bettingType, bool $ignoreOver = false): array + public function purifyBettingKey(array $bettingType, bool $noValidate = false): array { $selectCnt = $this->info->selectCnt; sort($bettingType, SORT_NUMERIC); @@ -56,17 +58,30 @@ class Betting throw new \InvalidArgumentException('중복된 값이 있습니다.'); } - if ($bettingType[0] < 0) { - throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(0 미만)' . print_r($bettingType, true)); - } - - if (!$ignoreOver && Util::array_last($bettingType) >= count($this->info->candidates)) { - throw new \InvalidArgumentException('올바르지 않은 값이 있습니다.(초과)' . print_r($bettingType, true)); + if (!$noValidate) { + foreach($bettingType as $bettingKey){ + if(!key_exists($bettingKey, $this->info->candidates)){ + throw new \InvalidArgumentException('올바른 후보가 아닙니다.' . print_r($bettingType, true)); + } + } } return $bettingType; } + public function closeBetting(): void + { + $db = DB::db(); + $bettingStor = KVStorage::getStorage($db, 'betting'); + $bettingID = $this->info->id; + $gameStor = KVStorage::getStorage($db, 'game_env'); + + //XXX: 베팅 종료 시점을 '현재 연월'로 하여 강제로 닫는다. + [$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); + $this->info->closeYearMonth = Util::joinYearMonth($year, $month); + $bettingStor->setValue("id_{$bettingID}", $this->info->toArray()); + } + public function convertBettingKey(array $bettingType): string { $bettingType = $this->purifyBettingKey($bettingType); @@ -78,7 +93,8 @@ class Betting return $this->info; } - public function bet(int $generalID, ?int $userID, array $bettingType, int $amount): void{ + public function bet(int $generalID, ?int $userID, array $bettingType, int $amount): void + { $bettingInfo = $this->info; if ($bettingInfo->finished) { @@ -107,6 +123,7 @@ class Betting throw new \RuntimeException('필요한 선택 수를 채우지 못했습니다.'); } + $resKey = $this->info->reqInheritancePoint?'유산포인트':'금'; $bettingTypeKey = $this->convertBettingKey($bettingType); $inheritStor = KVStorage::getStorage($db, "inheritance_{$userID}"); @@ -114,7 +131,7 @@ class Betting $prevBetAmount = $db->queryFirstField('SELECT sum(amount) FROM ng_betting WHERE betting_id = %i AND user_id = %i', $this->bettingID, $userID) ?? 0; if ($prevBetAmount + $amount > 1000) { - throw new \RuntimeException((1000 - $prevBetAmount) . ' 포인트까지만 베팅 가능합니다.'); + throw new \RuntimeException((1000 - $prevBetAmount) . $resKey.'까지만 베팅 가능합니다.'); } if ($bettingInfo->reqInheritancePoint) { @@ -287,8 +304,8 @@ class Betting //남은 상금은 '당첨자'에게 몰아준다. //당첨자가 아무도 없다면, 0개 맞춘 그룹에게 돌아간다. - if($rewardAmount){ - foreach(Util::range($selectCnt, -1, -1) as $matchPoint){ + if ($rewardAmount) { + foreach (Util::range($selectCnt, -1, -1) as $matchPoint) { if (!key_exists($matchPoint, $rewardAmount)) { continue; } @@ -338,7 +355,7 @@ class Betting $previousPoint = ($inheritStor->getValue('previous') ?? [0, 0])[0]; $nextPoint = $previousPoint + $amount; $inheritStor->setValue('previous', [$nextPoint, 0]); - $inheritStor->invalidateCacheValue('previous');//XXX: 실제로는 previous 값을 사용할 수 없도록 락을 걸어야 한다. + $inheritStor->invalidateCacheValue('previous'); //XXX: 실제로는 previous 값을 사용할 수 없도록 락을 걸어야 한다. $amountText = number_format($amount); $previousPointText = number_format($previousPoint); @@ -368,7 +385,6 @@ class Betting foreach ($loggers as $userLogger) { $userLogger->flush(); } - } else { $generalList = General::createGeneralObjListFromDB(array_unique(Util::squeezeFromArray($rewardList, 'generalID')), ['gold', 'npc'], 1); foreach ($rewardList as $rewardItem) { diff --git a/hwe/sammo/ResetHelper.php b/hwe/sammo/ResetHelper.php index 5a518c37..6c3621ae 100644 --- a/hwe/sammo/ResetHelper.php +++ b/hwe/sammo/ResetHelper.php @@ -196,6 +196,16 @@ class ResetHelper{ 'plock'=>1, 'locktime'=>TimeUtil::now(true) ]); + $db->insert('plock', [ + 'type'=>'TOURNAMENT', + 'plock'=>1, + 'locktime'=>TimeUtil::now(true) + ]); + $db->insert('plock', [ + 'type'=>'ETC', + 'plock'=>1, + 'locktime'=>TimeUtil::now(true) + ]); $prevWinner = $db->queryFirstField('SELECT l12name FROM emperior ORDER BY `no` DESC LIMIT 1'); $serverCnt = $db->queryFirstField('SELECT count(*) FROM ng_games') + 1; diff --git a/hwe/ts/betting.ts b/hwe/ts/betting.ts index 4aa2b41a..b4c07e18 100644 --- a/hwe/ts/betting.ts +++ b/hwe/ts/betting.ts @@ -4,39 +4,29 @@ import { setAxiosXMLHttpRequest } from '@util/setAxiosXMLHttpRequest'; import type { InvalidResponse } from '@/defs'; import { convertFormData } from '@util/convertFormData'; import { unwrap_any } from '@util/unwrap_any'; +import { SammoAPI } from './SammoAPI'; -$(function($){ - setAxiosXMLHttpRequest(); +declare const staticValues: { + bettingID: number; +} - $('.submitBtn').on('click', async function(e){ +$(function ($) { + $('.submitBtn').on('click', async function (e) { e.preventDefault(); const $this = $(this); const target = parseInt($this.data('target')); const amount = parseInt(unwrap_any($(`#target_${target}`).val())); - let result: InvalidResponse; - - try{ - const response = await axios({ - url: 'j_betting.php', - responseType: 'json', - method: 'post', - data: convertFormData({ - target: target, - amount: amount - }) + try { + await SammoAPI.Betting.Bet({ + bettingID: staticValues.bettingID, + bettingType: [target], + amount: amount, }); - result = response.data; - }catch(e){ + } catch (e) { console.error(e); - alert(`에러: ${e}`); - location.reload(); - return; - } - - if(!result.result){ - alert(`베팅을 실패했습니다: ${result.reason}`); + alert(`베팅을 실패했습니다: ${e}`); location.reload(); return; } diff --git a/src/sammo/Session.php b/src/sammo/Session.php index f3dbe49f..02cf7c2a 100644 --- a/src/sammo/Session.php +++ b/src/sammo/Session.php @@ -278,7 +278,7 @@ class Session $deadTime = $nextTurn + $general['killturn'] * $turnterm; if ($deadTime < $now && !$isUnited) { - $locked = $db->queryFirstField('SELECT plock FROM plock LIMIT 1'); + $locked = $db->queryFirstField('SELECT plock FROM plock WHERE `type` = "GAME" LIMIT 1'); if (!$locked) { if ($result !== null) { $result = false;
{$bet[$i]}{$amount}
{$amount}
{$amount}
- @@ -425,9 +461,10 @@ if ($str3) {
- () + ()
{$bet[$i]}{$amount}
$k$name$abil$tgame$win$draw$lose$gd$gl