diff --git a/hwe/_119_b.php b/hwe/_119_b.php index 364d36af..ddf70b11 100644 --- a/hwe/_119_b.php +++ b/hwe/_119_b.php @@ -50,7 +50,9 @@ switch ($btn) { $db->update('general', [ 'turntime' => $db->sqleval('DATE_SUB(turntime, INTERVAL %i MINUTE)', $minute) ], true); - //TODO: 경매 시간도 모두 당겨야함 + $db->update('ng_auction', [ + 'close_date' => $db->sqleval('DATE_SUB(close_date, INTERVAL %i MINUTE)', $minute) + ], true); if ($locked) { unlock(); } @@ -76,7 +78,9 @@ switch ($btn) { $db->update('general', [ 'turntime' => $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute) ], true); - //TODO: 경매시간도 모두 뒤로 미뤄야함 + $db->update('ng_auction', [ + 'close_date' => $db->sqleval('DATE_ADD(close_date, INTERVAL %i MINUTE)', $minute) + ], true); if ($locked) { unlock(); } diff --git a/hwe/func.php b/hwe/func.php index 1dbc29ab..a90a618c 100644 --- a/hwe/func.php +++ b/hwe/func.php @@ -1205,8 +1205,8 @@ function checkDelay() $db->update('general', [ 'turntime' => $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute) ], 'turntime<=DATE_ADD(turntime, INTERVAL %i MINUTE)', $term); - $db->update('auction', [ - 'expire' => $db->sqleval('DATE_ADD(expire, INTERVAL %i MINUTE)', $minute) + $db->update('ng_auction', [ + 'close_date' => $db->sqleval('DATE_ADD(close_date, INTERVAL %i MINUTE)', $minute) ], true); } } diff --git a/hwe/func_auction.php b/hwe/func_auction.php index 6f4f5ca2..bc5f07ae 100644 --- a/hwe/func_auction.php +++ b/hwe/func_auction.php @@ -1,7 +1,11 @@ queryFirstRow('SELECT avg(gold) as gold, avg(rice) as rice,max(gold) as maxgold from general where npc<2'); - if($general['gold'] < 1000) { $general['gold'] = 1000; } - if($general['gold'] > 20000) { $general['gold'] = 20000; } - if($general['rice'] < 1000) { $general['rice'] = 1000; } - if($general['rice'] > 20000) { $general['rice'] = 20000; } + if ($general['gold'] < 1000) { + $general['gold'] = 1000; + } + if ($general['gold'] > 20000) { + $general['gold'] = 20000; + } + if ($general['rice'] < 1000) { + $general['rice'] = 1000; + } + if ($general['rice'] > 20000) { + $general['rice'] = 20000; + } $count = $db->queryFirstField('SELECT count(*) FROM auction WHERE type=0 AND no1=0'); $count += 5; + + $dummyGeneral = AuctionBasicResource::genDummy(); + // 판매건 등록 - if(Util::randBool(1/$count)) { + if ($rng->nextBool(1 / $count)) { //평균 쌀의 5% ~ 25% - $mul = rand() % 5 + 1; + $mul = $rng->nextRangeInt(1, 5); $amount = $general['rice'] / 20 * $mul; $cost = $general['gold'] / 20 * 0.9 * $mul; $topv = $amount * 2; - if($cost <= $amount*0.8) { $cost = $amount*0.8; } - if($cost >= $amount*1.2) { $cost = $amount*1.2; } + $cost = Util::valueFit($cost, $amount * 0.8, $amount * 1.2); $amount = Util::round($amount, -1); $cost = Util::round($cost, -1); $topv = Util::round($topv, -1); - $term = 3 + rand() % 10; - $date = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")) + $unit * $term); - $db->insert('auction', [ - 'type'=>0, - 'no1'=>0, - 'name1'=>'ⓝ상인', - 'amount'=>$amount, - 'cost'=>$cost, - 'value'=>$cost, - 'topv'=>$topv, - 'expire'=>$date - ]); + $term = $rng->nextRangeInt(3, 12); + AuctionBuyRice::openResourceAuction($dummyGeneral, $amount, $term, $cost, $topv); } $count = $db->queryFirstField('SELECT count(*) FROM auction WHERE type=1 AND no1=0'); $count += 5; // 구매건 등록 - if(Util::randBool(1/$count)) { + if ($rng->nextBool(1 / $count)) { //평균 쌀의 5% ~ 25% - $mul = Util::randRangeInt(1, 5); + $mul = $rng->nextRangeInt(1, 5); $amount = $general['rice'] / 20 * $mul; $cost = $general['gold'] / 20 * 1.1 * $mul; $topv = $amount * 0.5; - if($cost <= $amount*0.8) { $cost = $amount*0.8; } - if($cost >= $amount*1.2) { $cost = $amount*1.2; } + $cost = Util::valueFit($cost, $amount * 0.8, $amount * 1.2); $amount = Util::round($amount, -1); $cost = Util::round($cost, -1); $topv = Util::round($topv, -1); - $term = Util::randRangeInt(3, 12); - $date = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")) + $unit * $term); - $db->insert('auction', [ - 'type'=>1, - 'no1'=>0, - 'name1'=>'ⓝ상인', - 'amount'=>$amount, - 'cost'=>$cost, - 'value'=>$cost, - 'topv'=>$topv, - 'expire'=>$date - ]); + $term = $rng->nextRangeInt(3, 12); + AuctionSellRice::openResourceAuction($dummyGeneral, $amount, $term, $cost, $topv); } } -function processAuction() { +function processAuction() +{ $db = DB::db(); $gameStor = KVStorage::getStorage($db, 'game_env'); - $date = TimeUtil::now(); + $now = TimeUtil::now(); [$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); $admin = $gameStor->getValues(['year', 'month']); - foreach($db->query('SELECT * from auction where expire<=%s', $date) as $auction){ - $josaYi1 = JosaUtil::pick($auction['name1'], '이'); - $josaYi2 = JosaUtil::pick($auction['name2'], '이'); - // 쌀 처리 - if($auction['no2'] == 0) { - // 상인건수가 아닌것만 출력 - if($auction['no1'] != 0) { - $traderID = $db->queryFirstField('SELECT no FROM general WHERE no=%i', $auction['no1']); - $logger = new ActionLogger($traderID, 0, $year, $month); - $logger->pushGeneralActionLog("입찰자 부재로 {$auction['no']}번 거래 유찰!", ActionLogger::EVENT_PLAIN); - $logger->flush(); + $auctionList = $db->queryFirstColumn( + 'SELECT id, `type` FROM ng_auction WHERE `type` IN %ls AND `close_date` <= %s', + [AuctionType::BuyRice->value, AuctionType::SellRice->value], + $now + ); - $auctionLog = []; - if($auction['type'] == 0) { - $josaUlRice = JosaUtil::pick($auction['amount'], '을'); - $auctionLog[] = "◆{$admin['year']}년 {$admin['month']}월, {$auction['no']}번 판매 유찰 : {$auction['name1']}{$josaYi1} 쌀 {$auction['amount']}{$josaUlRice} 판매, 그러나 입찰자 부재"; - } else { - $josaUlRice = JosaUtil::pick($auction['amount'], '을'); - $auctionLog[] = "◆{$admin['year']}년 {$admin['month']}월, {$auction['no']}번 구매 유찰 : {$auction['name1']}{$josaYi1} 쌀 {$auction['amount']}{$josaUlRice} 구매, 그러나 입찰자 부재"; - } - - pushAuctionLog($auctionLog); - } - continue; - } - - if($auction['no1'] == 0) { - $trader = [ - 'no'=>0, - 'name'=>'ⓝ상인', - 'gold'=>99999, - 'rice'=>99999 - ]; - } else { - $trader = $db->queryFirstRow('SELECT no,name,gold,rice from general where no=%i', $auction['no1']); - } - - $bidder = $db->queryFirstRow('SELECT no,name,gold,rice from general where no=%i', $auction['no2']); - - $traderLogger = new ActionLogger($trader['no'], 0, $year, $month, false); - $bidderLogger = new ActionLogger($bidder['no'], 0, $year, $month, false); - - $auctionLog = []; - - - //판매거래 - if($auction['type'] == 0) { - if($auction['amount'] > $trader['rice'] - 1000) { - $gold = Util::round($auction['value'] * 0.01); - $db->update('general', [ - 'gold'=>Util::valueFit($trader['gold'] - $gold, 0) - ], 'no=%i', $trader['no']); - - $josaUlRice = JosaUtil::pick($auction['amount'], '을'); - $josaRo = JosaUtil::pick($auction['value'], '로'); - $traderLogger->pushGeneralActionLog("판매자의 군량 부족으로 {$auction['no']}번 거래 유찰! 벌금 {$gold}", ActionLogger::EVENT_PLAIN); - $bidderLogger->pushGeneralActionLog("판매자의 군량 부족으로 {$auction['no']}번 거래 유찰!", ActionLogger::EVENT_PLAIN); - $auctionLog[0] = "◆{$admin['year']}년 {$admin['month']}월, {$auction['no']}번 판매 유찰 : {$auction['name1']}{$josaYi1} 쌀 {$auction['amount']}{$josaUlRice} 판매, {$auction['name2']}{$josaYi2} 금 {$auction['value']}{$josaRo} 입찰, 그러나 판매자 군량부족, 벌금 {$gold}"; - } elseif($auction['value'] > $bidder['gold'] - 1000) { - $gold = Util::round($auction['value'] * 0.01); - $db->update('general', [ - 'gold'=>Util::valueFit($bidder['gold'] - $gold, 0) - ], 'no=%i', $bidder['no']); - - $josaUlRice = JosaUtil::pick($auction['amount'], '을'); - $josaRo = JosaUtil::pick($auction['value'], '로'); - $traderLogger->pushGeneralActionLog("입찰자의 자금 부족으로 {$auction['no']}번 거래 유찰!", ActionLogger::EVENT_PLAIN); - $bidderLogger->pushGeneralActionLog("입찰자의 자금 부족으로 {$auction['no']}번 거래 유찰! 벌금 {$gold}", ActionLogger::EVENT_PLAIN); - $auctionLog[0] = "◆{$admin['year']}년 {$admin['month']}월, {$auction['no']}번 판매 유찰 : {$auction['name1']}{$josaYi1} 쌀 {$auction['amount']}{$josaUlRice} 판매, {$auction['name2']}{$josaYi2} 금 {$auction['value']}{$josaRo} 입찰, 그러나 입찰자 자금부족, 벌금 {$gold}"; - } else { - $josaUlGold = JosaUtil::pick($auction['value'], '을'); - $josaUlRice = JosaUtil::pick($auction['amount'], '을'); - $josaRo = JosaUtil::pick($auction['value'], '로'); - $traderLogger->pushGeneralActionLog("{$auction['no']}번 거래 성사로 쌀 {$auction['amount']}{$josaUlRice} 판매, 금 {$auction['value']}{$josaUlGold} 획득!", ActionLogger::EVENT_PLAIN); - $bidderLogger->pushGeneralActionLog("{$auction['no']}번 거래 성사로 금 {$auction['value']}{$josaUlGold} 지불, 쌀 {$auction['amount']}{$josaUlRice} 구입!", ActionLogger::EVENT_PLAIN); - $auctionLog[0] = "◆{$admin['year']}년 {$admin['month']}월, {$auction['no']}번 판매 성사 : {$auction['name1']}{$josaYi1} 쌀 {$auction['amount']}{$josaUlRice} 판매, {$auction['name2']}{$josaYi2} 금 {$auction['value']}{$josaRo} 구매"; - if($auction['value'] >= $auction['amount'] * 2) { - $auctionLog[0] .= " ★ 최고가 거래 ★"; - } elseif($auction['value'] >= $auction['topv']) { - $auctionLog[0] .= " ★ 즉시구매가 거래 ★"; - } elseif($auction['value'] * 2 <= $auction['amount']) { - $auctionLog[0] .= " ★ 최저가 거래 ★"; - - } - - $db->update('general', [ - 'gold'=>$db->sqleval('gold + %i', $auction['value']), - 'rice'=>$db->sqleval('rice - %i', $auction['amount']), - ], 'no=%i', $auction['no1']); - $db->update('general', [ - 'gold'=>$db->sqleval('gold - %i', $auction['value']), - 'rice'=>$db->sqleval('rice + %i', $auction['amount']), - ], 'no=%i', $auction['no2']); - } - pushAuctionLog($auctionLog); - //구매거래 - } else { - if($auction['amount'] > $bidder['rice'] - 1000) { - $gold = Util::round($auction['value'] * 0.01); - $db->update('general', [ - 'gold'=>Util::valueFit($bidder['gold'] - $gold, 0) - ], 'no=%i', $bidder['no']); - - $josaUlRice = JosaUtil::pick($auction['amount'], '을'); - $josaRo = JosaUtil::pick($auction['value'], '로'); - $traderLogger->pushGeneralActionLog("입찰자의 군량 부족으로 {$auction['no']}번 거래 유찰!", ActionLogger::EVENT_PLAIN); - $bidderLogger->pushGeneralActionLog("입찰자의 군량 부족으로 {$auction['no']}번 거래 유찰! 벌금 {$gold}", ActionLogger::EVENT_PLAIN); - $auctionLog[0] = "◆{$admin['year']}년 {$admin['month']}월, {$auction['no']}번 구매 유찰 : {$auction['name1']}{$josaYi1} 쌀 {$auction['amount']}{$josaUlRice} 구매, {$auction['name2']}{$josaYi2} 금 {$auction['value']}{$josaRo} 입찰, 그러나 입찰자 군량부족, 벌금 {$gold}"; - } elseif($auction['value'] > $trader['gold'] - 1000) { - $gold = Util::round($auction['value'] * 0.01); - $db->update('general', [ - 'gold'=>Util::valueFit($trader['gold'] - $gold, 0) - ], 'no=%i', $trader['no']); - - $josaUlRice = JosaUtil::pick($auction['amount'], '을'); - $josaRo = JosaUtil::pick($auction['value'], '로'); - $traderLogger->pushGeneralActionLog("구매자의 자금 부족으로 {$auction['no']}번 거래 유찰! 벌금 {$gold}", ActionLogger::EVENT_PLAIN); - $bidderLogger->pushGeneralActionLog("구매자의 자금 부족으로 {$auction['no']}번 거래 유찰!", ActionLogger::EVENT_PLAIN); - $auctionLog[0] = "◆{$admin['year']}년 {$admin['month']}월, {$auction['no']}번 구매 유찰 : {$auction['name1']}{$josaYi1} 쌀 {$auction['amount']}{$josaUlRice} 구매, {$auction['name2']}{$josaYi2} 금 {$auction['value']}{$josaRo} 입찰, 그러나 구매자 자금부족, 벌금 {$gold}"; - } else { - $josaUlGold = JosaUtil::pick($auction['value'], '을'); - $josaUlRice = JosaUtil::pick($auction['amount'], '을'); - $josaRo = JosaUtil::pick($auction['value'], '로'); - $traderLogger->pushGeneralActionLog( - "{$auction['no']}번 거래 성사로 금 {$auction['value']}{$josaUlGold} 지불, 쌀 {$auction['amount']}{$josaUlRice} 구입!", ActionLogger::EVENT_PLAIN - ); - $bidderLogger->pushGeneralActionLog("{$auction['no']}번 거래 성사로 쌀 {$auction['amount']}{$josaUlRice} 판매, 금 {$auction['value']}{$josaUlGold} 획득!", ActionLogger::EVENT_PLAIN); - $auctionLog[0] = "◆{$admin['year']}년 {$admin['month']}월, {$auction['no']}번 구매 성사 : {$auction['name1']}{$josaYi1} 쌀 {$auction['amount']}{$josaUlRice} 구매, {$auction['name2']}{$josaYi2} 금 {$auction['value']}{$josaRo} 판매"; - if($auction['value'] >= $auction['amount'] * 2) { - $auctionLog[0] .= " ★ 최고가 거래 ★"; - } elseif($auction['value'] * 2 <= $auction['amount']) { - $auctionLog[0] .= " ★ 최저가 거래 ★"; - } elseif($auction['value'] <= $auction['topv']) { - $auctionLog[0] .= " ★ 즉시구매가 거래 ★"; - } - - $db->update('general', [ - 'gold'=>$db->sqleval('gold - %i', $auction['value']), - 'rice'=>$db->sqleval('rice + %i', $auction['amount']), - ], 'no=%i', $auction['no1']); - $db->update('general', [ - 'gold'=>$db->sqleval('gold + %i', $auction['value']), - 'rice'=>$db->sqleval('rice - %i', $auction['amount']), - ], 'no=%i', $auction['no2']); - } - $traderLogger->flush(); - $bidderLogger->flush(); - pushAuctionLog($auctionLog); - } - - $traderLogger->flush(); - $bidderLogger->flush(); + if(!$auctionList){ + return; } - $db->delete('auction', 'expire <= %s', $date); + $dummyGeneral = AuctionBasicResource::genDummy(); + foreach($auctionList as [$auctionID, $rawAuctionType]) { + $auctionType = AuctionType::from($rawAuctionType); + if($auctionType === AuctionType::BuyRice){ + $auction = new AuctionBuyRice($auctionID, $dummyGeneral); + } + else{ + $auction = new AuctionSellRice($auctionID, $dummyGeneral); + } + $auction->tryFinish(); + } } - diff --git a/hwe/func_gamerule.php b/hwe/func_gamerule.php index 0c7cc630..1331f69e 100644 --- a/hwe/func_gamerule.php +++ b/hwe/func_gamerule.php @@ -510,7 +510,7 @@ function postUpdateMonthly(RandUtil $rng) //토너먼트 개시 triggerTournament($rng); // 시스템 거래건 등록 - registerAuction(); + registerAuction($rng); //전방설정 foreach (getAllNationStaticInfo() as $nation) { if ($nation['level'] <= 0) { diff --git a/hwe/sammo/AuctionBasicResource.php b/hwe/sammo/AuctionBasicResource.php index 4d647bad..783d3ff4 100644 --- a/hwe/sammo/AuctionBasicResource.php +++ b/hwe/sammo/AuctionBasicResource.php @@ -91,12 +91,20 @@ abstract class AuctionBasicResource extends Auction return new static($openResult, $general); } - static public function genDummy(): DummyGeneral + static public function genDummy(bool $initFullLogger = true): DummyGeneral { - $dummyGeneral = new DummyGeneral(true); + $dummyGeneral = new DummyGeneral(false); $dummyGeneral->setVar('name', '상인'); $dummyGeneral->setVar('gold', static::MAX_AUCTION_AMOUNT * 10); $dummyGeneral->setVar('rice', static::MAX_AUCTION_AMOUNT * 10); + + if($initFullLogger){ + $db = DB::db(); + $gameStor = KVStorage::getStorage($db, 'game_env'); + [$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); + $dummyGeneral->initLogger($year, $month); + } + return $dummyGeneral; }