feat,fix,wip: 버그 수정, 연장 시간 로직 변경
This commit is contained in:
@@ -45,7 +45,6 @@ return [
|
||||
'hwe/api.php',
|
||||
'hwe/a_traffic.php',
|
||||
'hwe/battle_simulator.php',
|
||||
'hwe/b_auction.php',
|
||||
'hwe/b_battleCenter.php',
|
||||
'hwe/b_betting.php',
|
||||
'hwe/v_chiefCenter.php',
|
||||
@@ -60,7 +59,6 @@ return [
|
||||
'hwe/v_processing.php',
|
||||
'hwe/b_tournament.php',
|
||||
'hwe/b_troop.php',
|
||||
'hwe/c_auction.php',
|
||||
'hwe/c_tournament.php',
|
||||
'hwe/func_auction.php',
|
||||
'hwe/func_command.php',
|
||||
|
||||
+14
-7
@@ -4,6 +4,7 @@ namespace sammo;
|
||||
|
||||
use DateTime;
|
||||
use Ds\Set;
|
||||
use sammo\Enums\AuctionType;
|
||||
use sammo\Enums\InheritanceKey;
|
||||
use sammo\Enums\RankColumn;
|
||||
use sammo\Event\Action;
|
||||
@@ -1558,6 +1559,7 @@ function CheckHall($no)
|
||||
function giveRandomUniqueItem(RandUtil $rng, General $general, string $acquireType): bool
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
//아이템 습득 상황
|
||||
$availableUnique = [];
|
||||
|
||||
@@ -1589,6 +1591,18 @@ function giveRandomUniqueItem(RandUtil $rng, General $general, string $acquireTy
|
||||
}
|
||||
}
|
||||
|
||||
$auctionItems = $db->queryFirstColumn(
|
||||
'SELECT `target` FROM `ng_auction` WHERE `type` = %s AND `finished` = 0',
|
||||
AuctionType::UniqueItem->value
|
||||
);
|
||||
foreach ($auctionItems as $itemCode) {
|
||||
if (key_exists($itemCode, $occupiedUnique)) {
|
||||
$occupiedUnique[$itemCode]++;
|
||||
} else {
|
||||
$occupiedUnique[$itemCode] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -1632,10 +1646,7 @@ function giveRandomUniqueItem(RandUtil $rng, General $general, string $acquireTy
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($general->getAuxVar('inheritRandomUnique')) {
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
[$year, $month, $initYear, $initMonth] = $gameStor->getValuesAsArray(['year', 'month', 'init_year', 'init_month']);
|
||||
|
||||
$relMonthByInit = Util::joinYearMonth($year, $month) - Util::joinYearMonth($initYear, $initMonth);
|
||||
@@ -1666,10 +1677,6 @@ function giveRandomUniqueItem(RandUtil $rng, General $general, string $acquireTy
|
||||
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 습득했습니다!");
|
||||
$logger->pushGlobalHistoryLog("<C><b>【{$acquireType}】</b></><D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 습득했습니다!");
|
||||
|
||||
$givenUnique =$gameStor->getValue('givenUnique') ?? [];
|
||||
$givenUnique[$itemCode] = ($givenUnique[$itemCode] ?? 0) + 1;
|
||||
$gameStor->setValue('givenUnique', $givenUnique);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ function registerAuction(RandUtil $rng)
|
||||
$avgRice = Util::valueFit($avgRice, 1000, 20000);
|
||||
|
||||
$neutralAuctionCnt = Util::convertPairArrayToDict($db->queryAllLists(
|
||||
'SELECT `type`, count(*) FROM ng_auction WHERE `type` IN %s AND `host_general_id`=0 GROUP BY `type`',
|
||||
'SELECT `type`, count(*) FROM ng_auction WHERE `type` IN %ls AND `host_general_id`=0 GROUP BY `type`',
|
||||
[AuctionType::BuyRice->value, AuctionType::SellRice->value],
|
||||
));
|
||||
|
||||
@@ -64,7 +64,7 @@ function processAuction()
|
||||
|
||||
$now = TimeUtil::now();
|
||||
|
||||
$auctionList = $db->queryFirstColumn(
|
||||
$auctionList = $db->queryAllLists(
|
||||
'SELECT id, `type` FROM ng_auction WHERE `close_date` <= %s AND finished = 0',
|
||||
$now
|
||||
);
|
||||
|
||||
@@ -37,7 +37,7 @@ class GetActiveResourceAuctionList extends \sammo\BaseAPI
|
||||
$sellRiceList = [];
|
||||
/** @var AuctionInfo[] */
|
||||
$auctions = array_map(fn ($raw) => AuctionInfo::fromArray($raw), $db->query(
|
||||
'SELECT * FROM `ng_auction` WHERE `type` IN %ls AND `finished` = 0 ORDER BY `close_date` DESC',
|
||||
'SELECT * FROM `ng_auction` WHERE `type` IN %ls AND `finished` = 0 ORDER BY `close_date` ASC',
|
||||
[
|
||||
AuctionType::BuyRice->value,
|
||||
AuctionType::SellRice->value,
|
||||
|
||||
@@ -80,8 +80,9 @@ class GetUniqueItemAuctionDetail extends \sammo\BaseAPI
|
||||
'target' => $auction->target,
|
||||
'isCallerHost' => $auction->hostGeneralID === $generalID,
|
||||
'hostName' => $auction->detail->hostName,
|
||||
'closeDate' => TimeUtil::format($auction->closeDate, false),
|
||||
'remainCloseDateExtensionCnt' => $auction->detail->remainCloseDateExtensionCnt,
|
||||
'availableLatestBidCloseDate' => $auction->detail->availableLatestBidCloseDate,
|
||||
'availableLatestBidCloseDate' => TimeUtil::format($auction->detail->availableLatestBidCloseDate, false),
|
||||
],
|
||||
'bidList' => $responseBid,
|
||||
'obfuscatedName' => $obfuscatedName,
|
||||
|
||||
@@ -32,10 +32,21 @@ class GetUniqueItemAuctionList extends \sammo\BaseAPI
|
||||
|
||||
/** @var AuctionInfo[] */
|
||||
$auctions = array_map(fn($raw)=>AuctionInfo::fromArray($raw), $db->query(
|
||||
'SELECT * FROM `ng_auction` WHERE `type` = %s ORDER BY `close_date` DESC',
|
||||
'SELECT * FROM `ng_auction` WHERE `type` = %s ORDER BY `close_date` ASC',
|
||||
AuctionType::UniqueItem->value
|
||||
) ?? []);
|
||||
|
||||
$obfuscatedName = AuctionUniqueItem::genObfuscatedName($generalID);
|
||||
|
||||
if(!$auctions){
|
||||
return [
|
||||
'result' => true,
|
||||
'list' => [],
|
||||
'obfuscatedName' => $obfuscatedName,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
$auctionIDList = [];
|
||||
foreach ($auctions as $auction) {
|
||||
$auctionIDList[] = $auction->id;
|
||||
@@ -58,8 +69,6 @@ class GetUniqueItemAuctionList extends \sammo\BaseAPI
|
||||
$rawHighestBids
|
||||
);
|
||||
|
||||
$obfuscatedName = AuctionUniqueItem::genObfuscatedName($generalID);
|
||||
|
||||
$response = [];
|
||||
foreach ($auctions as $auction) {
|
||||
$auctionID = $auction->id;
|
||||
|
||||
@@ -5,9 +5,12 @@ namespace sammo\API\Auction;
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\AuctionBuyRice;
|
||||
use sammo\DB;
|
||||
use sammo\Validator;
|
||||
use sammo\GameConst;
|
||||
use sammo\General;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Util;
|
||||
|
||||
class OpenBuyRiceAuction extends \sammo\BaseAPI
|
||||
{
|
||||
@@ -64,6 +67,16 @@ class OpenBuyRiceAuction extends \sammo\BaseAPI
|
||||
|
||||
$general = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
[$initYear, $initMonth, $year, $month] = $gameStor->getValuesAsArray(['init_year', 'init_month', 'year', 'month']);
|
||||
$initYearMonth = Util::joinYearMonth($initYear, $initMonth);
|
||||
$yearMonth = Util::joinYearMonth($year, $month);
|
||||
|
||||
if($yearMonth <= $initYearMonth + 3){
|
||||
return '시작 후 3개월이 지나야 경매를 열 수 있습니다.';
|
||||
}
|
||||
|
||||
$auctionResult = AuctionBuyRice::openResourceAuction(
|
||||
$general,
|
||||
$amount,
|
||||
|
||||
@@ -5,9 +5,12 @@ namespace sammo\API\Auction;
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\AuctionSellRice;
|
||||
use sammo\DB;
|
||||
use sammo\Validator;
|
||||
use sammo\GameConst;
|
||||
use sammo\General;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Util;
|
||||
|
||||
class OpenSellRiceAuction extends \sammo\BaseAPI
|
||||
{
|
||||
@@ -64,6 +67,16 @@ class OpenSellRiceAuction extends \sammo\BaseAPI
|
||||
|
||||
$general = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
[$initYear, $initMonth, $year, $month] = $gameStor->getValuesAsArray(['init_year', 'init_month', 'year', 'month']);
|
||||
$initYearMonth = Util::joinYearMonth($initYear, $initMonth);
|
||||
$yearMonth = Util::joinYearMonth($year, $month);
|
||||
|
||||
if($yearMonth <= $initYearMonth + 3){
|
||||
return '시작 후 3개월이 지나야 경매를 열 수 있습니다.';
|
||||
}
|
||||
|
||||
$auctionResult = AuctionSellRice::openResourceAuction(
|
||||
$general,
|
||||
$amount,
|
||||
|
||||
@@ -5,9 +5,12 @@ namespace sammo\API\Auction;
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\AuctionUniqueItem;
|
||||
use sammo\DB;
|
||||
use sammo\Validator;
|
||||
use sammo\GameConst;
|
||||
use sammo\General;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Util;
|
||||
|
||||
use function sammo\buildItemClass;
|
||||
|
||||
@@ -55,6 +58,16 @@ class OpenUniqueAuction extends \sammo\BaseAPI
|
||||
$itemObj = buildItemClass($itemID);
|
||||
$general = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
[$initYear, $initMonth, $year, $month] = $gameStor->getValuesAsArray(['init_year', 'init_month', 'year', 'month']);
|
||||
$initYearMonth = Util::joinYearMonth($initYear, $initMonth);
|
||||
$yearMonth = Util::joinYearMonth($year, $month);
|
||||
|
||||
if($yearMonth <= $initYearMonth + 3){
|
||||
return '시작 후 3개월이 지나야 경매를 열 수 있습니다.';
|
||||
}
|
||||
|
||||
$auctionResult = AuctionUniqueItem::openItemAuction($itemObj, $general, $amount);
|
||||
|
||||
if(is_string($auctionResult)) {
|
||||
|
||||
@@ -62,23 +62,6 @@ class DropItem extends \sammo\BaseAPI
|
||||
if (!$item->isBuyable()) {
|
||||
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 잃었습니다!");
|
||||
$logger->pushGlobalHistoryLog("<R><b>【망실】</b></><D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 잃었습니다!");
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$givenUnique = $gameStor->getValue('givenUnique') ?? [];
|
||||
$itemCode = $item->getRawClassName();
|
||||
if (key_exists($itemCode, $givenUnique)) {
|
||||
$givenUniqueCnt = $givenUnique[$itemCode];
|
||||
$givenUniqueCnt -= 1;
|
||||
if ($givenUniqueCnt <= 0) {
|
||||
unset($givenUnique[$itemCode]);
|
||||
} else {
|
||||
$givenUnique[$itemCode] = $givenUniqueCnt;
|
||||
}
|
||||
} else {
|
||||
//XXX: 처리하지 못한 코드가 있는가?
|
||||
//FIXME: 여기에서 무언가 경고를 내야함
|
||||
}
|
||||
$gameStor->setValue('givenUnique', $givenUnique);
|
||||
}
|
||||
|
||||
$me->applyDB($db);
|
||||
|
||||
+72
-22
@@ -21,7 +21,7 @@ abstract class Auction
|
||||
static AuctionType $auctionType;
|
||||
|
||||
public const COEFF_AUCTION_CLOSE_MINUTES = 24;
|
||||
public const COEFF_EXTENSION_MINUTES_PER_BID = 1 / 6;
|
||||
public const COEFF_EXTENSION_MINUTES_PER_BID = (1 / 6);
|
||||
public const COEFF_EXTENSION_MINUTES_LIMIT_BY_BID = 1;
|
||||
public const COEFF_EXTENSION_MINUTES_BY_EXTENSION_QUERY = 1;
|
||||
public const MIN_AUCTION_CLOSE_MINUTES = 30;
|
||||
@@ -157,32 +157,55 @@ abstract class Auction
|
||||
return null;
|
||||
}
|
||||
|
||||
public function extendLatestBidCloseDate(?DateTimeInterface $date): ?string
|
||||
{
|
||||
if ($date === null) {
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$date = $this->info->closeDate->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_EXTENSION_MINUTES_PER_BID, $turnTerm * static::COEFF_EXTENSION_MINUTES_PER_BID) * 60
|
||||
));
|
||||
}
|
||||
else{
|
||||
$date = DateTimeImmutable::createFromInterface($date);
|
||||
}
|
||||
if ($this->info->detail->availableLatestBidCloseDate !== null && $date < $this->info->detail->availableLatestBidCloseDate) {
|
||||
return '기간보다 짧습니다.';
|
||||
}
|
||||
$this->info->detail->availableLatestBidCloseDate = $date;
|
||||
return null;
|
||||
}
|
||||
|
||||
public function extendCloseDate(DateTimeInterface $date, bool $force = false): ?string
|
||||
{
|
||||
if (!$force) {
|
||||
if ($this->info->remainCloseExtensionCnt === null) {
|
||||
if ($this->info->detail->remainCloseDateExtensionCnt === null) {
|
||||
return '연장할 수 없는 경매입니다.';
|
||||
}
|
||||
if ($this->info->remainCloseExtensionCnt === 0) {
|
||||
if ($this->info->detail->remainCloseDateExtensionCnt === 0) {
|
||||
return '더 이상 연장할 수 없습니다';
|
||||
}
|
||||
if ($this->info->remainCloseExtensionCnt > 0) {
|
||||
$this->info->remainCloseExtensionCnt--;
|
||||
if ($this->info->detail->remainCloseDateExtensionCnt > 0) {
|
||||
$this->info->detail->remainCloseDateExtensionCnt--;
|
||||
}
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
if ($date < $this->info->closeDate) {
|
||||
return '종료 기간보다 짧습니다.';
|
||||
}
|
||||
|
||||
$closeDate = DateTimeImmutable::createFromInterface($date);
|
||||
$this->info->closeDate = $closeDate;
|
||||
$this->info->availableLatestBidCloseDate = $closeDate->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_EXTENSION_MINUTES_PER_BID, $turnTerm * static::COEFF_EXTENSION_MINUTES_PER_BID) * 60
|
||||
));
|
||||
$db->update('ng_auction', $this->info->toArray('id'), 'id = %i', $this->info->id);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function applyDB(): void
|
||||
{
|
||||
$db = DB::db();
|
||||
$db->update('ng_auction', $this->info->toArray('id'), 'id = %i', $this->info->id);
|
||||
}
|
||||
|
||||
public function refundBid(AuctionBidItem $bidItem, string $reason): void
|
||||
{
|
||||
if ($bidItem->auctionID !== $this->info->id) {
|
||||
@@ -190,7 +213,7 @@ abstract class Auction
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
if ($bidItem->generalID === $this->general->generalID) {
|
||||
if ($bidItem->generalID === $this->general->getID()) {
|
||||
$oldBidder = $this->general;
|
||||
} else {
|
||||
$oldBidder = General::createGeneralObjFromDB($bidItem->generalID);
|
||||
@@ -198,10 +221,15 @@ abstract class Auction
|
||||
|
||||
if ($this->info->reqResource === ResourceType::inheritancePoint) {
|
||||
$oldBidder->increaseInheritancePoint(InheritanceKey::previous, $bidItem->amount);
|
||||
$oldBidder->increaseRankVar(RankColumn::inherit_point_spent_dynamic, -$bidItem->amount);
|
||||
} else {
|
||||
$oldBidder->increaseVar($this->info->reqResource->value, $bidItem->amount);
|
||||
}
|
||||
|
||||
if ($oldBidder instanceof DummyGeneral) {
|
||||
return;
|
||||
}
|
||||
|
||||
$staticNation = $oldBidder->getStaticNation();
|
||||
$src = new MessageTarget(0, '', 0, 'System', '#000000');
|
||||
$dest = new MessageTarget(
|
||||
@@ -258,7 +286,7 @@ abstract class Auction
|
||||
}
|
||||
|
||||
$myPrevBid = $this->getMyPrevBid();
|
||||
if($myPrevBid !== null && $highestBid->no !== $myPrevBid->no){
|
||||
if ($myPrevBid !== null && $highestBid->no !== $myPrevBid->no) {
|
||||
//이미 환불 받았으니 무효.
|
||||
$myPrevBid = null;
|
||||
}
|
||||
@@ -293,13 +321,14 @@ abstract class Auction
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
|
||||
if ($this->info->availableLatestBidCloseDate !== null) {
|
||||
$extendedCloseDate = $this->info->closeDate->add(TimeUtil::secondsToDateInterval(
|
||||
if ($this->info->detail->availableLatestBidCloseDate !== null) {
|
||||
$extendedCloseDate = $now->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_EXTENSION_MINUTES_PER_BID, $turnTerm * static::COEFF_EXTENSION_MINUTES_PER_BID) * 60
|
||||
));
|
||||
|
||||
if ($extendedCloseDate > $this->info->closeDate && $this->info->closeDate < $this->info->availableLatestBidCloseDate) {
|
||||
$this->extendCloseDate(min($extendedCloseDate, $this->info->availableLatestBidCloseDate));
|
||||
if ($extendedCloseDate > $this->info->closeDate && $this->info->closeDate < $this->info->detail->availableLatestBidCloseDate) {
|
||||
$this->extendCloseDate(min($extendedCloseDate, $this->info->detail->availableLatestBidCloseDate), true);
|
||||
$this->applyDB();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,11 +361,11 @@ abstract class Auction
|
||||
}
|
||||
|
||||
if (!$auctionInfo->detail->isReverse) {
|
||||
if ($auctionInfo->buyImmediatelyAmount !== null && $auctionInfo->buyImmediatelyAmount < $amount) {
|
||||
if ($auctionInfo->detail->finishBidAmount !== null && $auctionInfo->detail->finishBidAmount < $amount) {
|
||||
return '즉시판매가보다 높을 수 없습니다.';
|
||||
}
|
||||
} else {
|
||||
if ($auctionInfo->buyImmediatelyAmount !== null && $auctionInfo->buyImmediatelyAmount > $amount) {
|
||||
if ($auctionInfo->detail->finishBidAmount !== null && $auctionInfo->detail->finishBidAmount > $amount) {
|
||||
return '즉시판매가보다 낮을 수 없습니다.';
|
||||
}
|
||||
}
|
||||
@@ -363,7 +392,7 @@ abstract class Auction
|
||||
|
||||
|
||||
$myPrevBid = $this->getMyPrevBid();
|
||||
if($myPrevBid !== null && $highestBid->no !== $myPrevBid->no){
|
||||
if ($myPrevBid !== null && $highestBid->no !== $myPrevBid->no) {
|
||||
//이미 환불 받았으니 무효.
|
||||
$myPrevBid = null;
|
||||
}
|
||||
@@ -402,6 +431,17 @@ abstract class Auction
|
||||
|
||||
$general->increaseVar($resType->value, -$morePoint);
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
$extendedCloseDate = $now->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_EXTENSION_MINUTES_PER_BID, $turnTerm * static::COEFF_EXTENSION_MINUTES_PER_BID) * 60
|
||||
));
|
||||
|
||||
if ($extendedCloseDate > $this->info->closeDate) {
|
||||
$this->extendCloseDate($extendedCloseDate, true);
|
||||
$this->applyDB();
|
||||
}
|
||||
|
||||
if ($highestBid !== null && $myPrevBid === null) {
|
||||
$this->refundBid($highestBid, "{$auctionInfo->id}번 {$auctionInfo->detail->title}에 상회입찰자가 나타났습니다.");
|
||||
}
|
||||
@@ -424,12 +464,18 @@ abstract class Auction
|
||||
}
|
||||
|
||||
if ($highestBid->aux->tryExtendCloseDate) {
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
|
||||
//연장 요청이 있었다.
|
||||
$extendedCloseDate = $this->info->closeDate->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_EXTENSION_MINUTES_BY_EXTENSION_QUERY, $this->info->turnTerm * static::COEFF_EXTENSION_MINUTES_BY_EXTENSION_QUERY) * 60
|
||||
max(static::MIN_EXTENSION_MINUTES_BY_EXTENSION_QUERY, $turnTerm * static::COEFF_EXTENSION_MINUTES_BY_EXTENSION_QUERY) * 60
|
||||
));
|
||||
|
||||
if ($this->extendCloseDate($extendedCloseDate) === null) {
|
||||
$this->extendLatestBidCloseDate(null);
|
||||
$this->applyDB();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -441,6 +487,10 @@ abstract class Auction
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($bidder instanceof DummyGeneral) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$staticNation = $bidder->getStaticNation();
|
||||
$src = new MessageTarget(0, '', 0, 'System', '#000000');
|
||||
$dest = new MessageTarget(
|
||||
|
||||
@@ -8,7 +8,7 @@ use sammo\Enums\ResourceType;
|
||||
/** 경매에 쌀을 매물로 등록, 입찰자가 금으로 구매 */
|
||||
class AuctionBuyRice extends AuctionBasicResource
|
||||
{
|
||||
static AuctionType $auctionType = AuctionType::SellRice;
|
||||
static AuctionType $auctionType = AuctionType::BuyRice;
|
||||
static ResourceType $hostRes = ResourceType::rice;
|
||||
static ResourceType $bidderRes = ResourceType::gold;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ use sammo\RandUtil;
|
||||
|
||||
class AuctionUniqueItem extends Auction
|
||||
{
|
||||
const COEFF_EXTENSION_MINUTES_LIMIT_UNIQUE_CNT = 24;
|
||||
|
||||
static AuctionType $auctionType = AuctionType::UniqueItem;
|
||||
|
||||
@@ -52,18 +53,6 @@ class AuctionUniqueItem extends Auction
|
||||
}
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$givenUnique = $gameStor->getValue('givenUnique') ?? [];
|
||||
$givenUniqueCnt = $givenUnique[$itemKey] ?? 0;
|
||||
$remainUniqueCnt = 0;
|
||||
foreach (GameConst::$allItems as $itemList) {
|
||||
if (!key_exists($itemKey, $itemList)) {
|
||||
continue;
|
||||
}
|
||||
$remainUniqueCnt += $itemList[$itemKey];
|
||||
}
|
||||
if ($remainUniqueCnt > 1 && $givenUniqueCnt >= $remainUniqueCnt - 1) {
|
||||
return '더이상 이 아이템을 경매로 가져갈 수 없습니다.';
|
||||
}
|
||||
|
||||
$now = new DateTimeImmutable();
|
||||
|
||||
@@ -115,7 +104,7 @@ class AuctionUniqueItem extends Auction
|
||||
$josaRa = JosaUtil::pick($item->getRawName(), '라');
|
||||
|
||||
$logger = new ActionLogger(0, 0, $year, $month);
|
||||
$logger->pushGlobalHistoryLog("누군가가 <C>{$itemName}</>{$josaRa}는 보물을 구한다는 소문이 들려옵니다.");
|
||||
$logger->pushGlobalHistoryLog("<C><b>【보물수배】</b></>누군가가 <C>{$itemName}</>{$josaRa}는 보물을 구한다는 소문이 들려옵니다.");
|
||||
$logger->flush();
|
||||
|
||||
return $auction;
|
||||
@@ -159,9 +148,14 @@ class AuctionUniqueItem extends Auction
|
||||
);
|
||||
|
||||
$itemCode = $this->info->target;
|
||||
|
||||
if($itemCode === null){
|
||||
throw new \Exception('아이템 코드가 없습니다.');
|
||||
}
|
||||
|
||||
$bidItemTypes = new Set();
|
||||
foreach (GameConst::$allItems as $itemType => $itemList) {
|
||||
if (($itemList[$itemCode] ?? 0) <= 0) {
|
||||
if (key_exists($itemCode, $itemList) && $itemList[$itemCode] <= 0) {
|
||||
continue;
|
||||
}
|
||||
$bidItemTypes->add($itemType);
|
||||
@@ -228,12 +222,15 @@ class AuctionUniqueItem extends Auction
|
||||
}
|
||||
|
||||
if ($availableEquipUniqueCnt <= 0) {
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
//제한에 걸렸다면 자동 연장
|
||||
$extendedCloseDate = $this->info->closeDate->add(TimeUtil::secondsToDateInterval(
|
||||
max(static::MIN_EXTENSION_MINUTES_BY_EXTENSION_QUERY, $this->info->turnTerm * static::COEFF_EXTENSION_MINUTES_BY_EXTENSION_QUERY) * 60
|
||||
max(static::MIN_EXTENSION_MINUTES_BY_EXTENSION_QUERY, $turnTerm * static::COEFF_EXTENSION_MINUTES_LIMIT_UNIQUE_CNT) * 60
|
||||
));
|
||||
|
||||
$this->extendCloseDate($extendedCloseDate, true);
|
||||
$this->extendLatestBidCloseDate(null);
|
||||
$this->applyDB();
|
||||
return '유니크 아이템 소유 제한 상태입니다. 종료 시간이 연장됩니다.';
|
||||
}
|
||||
|
||||
@@ -284,13 +281,13 @@ class AuctionUniqueItem extends Auction
|
||||
$logger->pushGeneralActionLog("<C>{$itemName}</>{$josaUl} 습득했습니다!");
|
||||
$logger->pushGeneralHistoryLog("<C>{$itemName}</>{$josaUl} 습득");
|
||||
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 습득했습니다!");
|
||||
$logger->pushGlobalHistoryLog("<C><b>【보물발견】</b></><D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 습득했습니다!");
|
||||
$logger->pushGlobalHistoryLog("<C><b>【보물수배】</b></><D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 습득했습니다!");
|
||||
|
||||
$userLogger = new UserLogger($general->getVar('owner'));
|
||||
$userLogger->push(sprintf("유니크 %s 경매로 %d 포인트 사용", $itemName, $highestBid->amount), "inheritPoint");
|
||||
|
||||
$general->applyDB($db);
|
||||
|
||||
$givenUnique = $gameStor->getValue('givenUnique') ?? [];
|
||||
$givenUnique[$itemKey] = ($givenUnique[$itemKey] ?? 0) + 1;
|
||||
$gameStor->setValue('givenUnique', $givenUnique);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,22 +188,6 @@ class che_장비매매 extends Command\GeneralCommand
|
||||
$nationName = $general->getStaticNation()['name'];
|
||||
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 판매했습니다!");
|
||||
$logger->pushGlobalHistoryLog("<R><b>【판매】</b></><D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 판매했습니다!");
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$givenUnique = $gameStor->getValue('givenUnique') ?? [];
|
||||
if (key_exists($itemCode, $givenUnique)) {
|
||||
$givenUniqueCnt = $givenUnique[$itemCode];
|
||||
$givenUniqueCnt -= 1;
|
||||
if ($givenUniqueCnt <= 0) {
|
||||
unset($givenUnique[$itemCode]);
|
||||
} else {
|
||||
$givenUnique[$itemCode] = $givenUniqueCnt;
|
||||
}
|
||||
} else {
|
||||
//XXX: 처리하지 못한 코드가 있는가?
|
||||
//FIXME: 여기에서 무언가 경고를 내야함
|
||||
}
|
||||
$gameStor->setValue('givenUnique', $givenUnique);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+40
-28
@@ -4,67 +4,79 @@ namespace sammo;
|
||||
|
||||
use sammo\Enums\InheritanceKey;
|
||||
|
||||
class DummyGeneral extends General{
|
||||
public function __construct(bool $initLogger=true){
|
||||
class DummyGeneral extends General
|
||||
{
|
||||
public function __construct(bool $initLogger = true)
|
||||
{
|
||||
$raw = [
|
||||
'no'=>0,
|
||||
'name'=>'Dummy',
|
||||
'npc'=>3,
|
||||
'city'=>0,
|
||||
'nation'=>0,
|
||||
'officer_level'=>0,
|
||||
'crewtype'=>-1,
|
||||
'turntime'=>'2012-03-04 05:06:07.000000',
|
||||
'experience'=>0,
|
||||
'dedication'=>0,
|
||||
'gold'=>0,
|
||||
'rice'=>0,
|
||||
'leadership'=>10,
|
||||
'strength'=>10,
|
||||
'intel'=>10,
|
||||
'no' => 0,
|
||||
'name' => 'Dummy',
|
||||
'npc' => 3,
|
||||
'city' => 0,
|
||||
'nation' => 0,
|
||||
'officer_level' => 0,
|
||||
'crewtype' => -1,
|
||||
'turntime' => '2012-03-04 05:06:07.000000',
|
||||
'experience' => 0,
|
||||
'dedication' => 0,
|
||||
'gold' => 0,
|
||||
'rice' => 0,
|
||||
'leadership' => 10,
|
||||
'strength' => 10,
|
||||
'intel' => 10,
|
||||
'imgsvr' => 0,
|
||||
'picture' => 'default.jpg',
|
||||
];
|
||||
|
||||
$this->raw = $raw;
|
||||
|
||||
$this->resultTurn = new LastTurn();
|
||||
|
||||
if($initLogger){
|
||||
if ($initLogger) {
|
||||
$this->initLogger(1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public function getBattleInitSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
public function getBattleInitSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
|
||||
{
|
||||
return new WarUnitTriggerCaller();
|
||||
}
|
||||
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit):?WarUnitTriggerCaller{
|
||||
public function getBattlePhaseSkillTriggerList(WarUnit $unit): ?WarUnitTriggerCaller
|
||||
{
|
||||
return new WarUnitTriggerCaller();
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux = null)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function onCalcOpposeStat(General $general, string $statName, $value, $aux=null){
|
||||
public function onCalcOpposeStat(General $general, string $statName, $value, $aux = null)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function getInheritancePoint(InheritanceKey $key, &$aux = null, bool $forceCalc = false): int|float{
|
||||
public function getInheritancePoint(InheritanceKey $key, &$aux = null, bool $forceCalc = false): int|float
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function setInheritancePoint(InheritanceKey $key, $value, $aux = null){
|
||||
public function setInheritancePoint(InheritanceKey $key, $value, $aux = null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public function increaseInheritancePoint(InheritanceKey $key, $value, $aux = null){
|
||||
public function increaseInheritancePoint(InheritanceKey $key, $value, $aux = null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
function applyDB($db):bool{
|
||||
if($this->logger){
|
||||
function applyDB($db): bool
|
||||
{
|
||||
if ($this->logger) {
|
||||
$this->initLogger($this->logger->getYear(), $this->logger->getMonth());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<BContainer id="container" :toast="{ root: true }" class="bg0">
|
||||
<TopBackBar type="normal" :title="isResAuction ? '경매장' : '유니크 경매장'" :reloadable="true" @reload="tryReload">
|
||||
<TopBackBar type="close" :title="isResAuction ? '경매장' : '유니크 경매장'" :reloadable="true" @reload="tryReload">
|
||||
<BButton @click="isResAuction = true">금/쌀</BButton>
|
||||
<BButton @click="isResAuction = false">유니크</BButton>
|
||||
</TopBackBar>
|
||||
<AuctionResource v-if="isResAuction"></AuctionResource>
|
||||
<AuctionUniqueItem v-else></AuctionUniqueItem>
|
||||
<BottomBar></BottomBar>
|
||||
<BottomBar type="close"></BottomBar>
|
||||
</BContainer>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
<div class="col">{{ auction.startBidAmount }}</div>
|
||||
<div class="col">{{ auction.highestBid ? auction.highestBid.amount : "-" }}</div>
|
||||
<div class="col">{{ auction.finishBidAmount }}</div>
|
||||
<div class="col">{{ auction.highestBid ? auction.highestBid.amount / auction.amount : "-" }}</div>
|
||||
<div class="col">{{ auction.highestBid ? (auction.highestBid.amount / auction.amount).toFixed(2) : "-" }}</div>
|
||||
<div class="col">{{ auction.highestBid ? auction.highestBid.generalName : "-" }}</div>
|
||||
<div class="col">{{ auction.closeDate }}</div>
|
||||
</div>
|
||||
<div v-if="selectedBuyRiceAuction !== undefined">
|
||||
<div v-if="selectedBuyRiceAuction !== undefined" class="row">
|
||||
<div class="col">{{ selectedBuyRiceAuction.id }}번 쌀 {{ selectedBuyRiceAuction.amount }} 경매에</div>
|
||||
<div class="col">
|
||||
<NumberInputWithInfo
|
||||
@@ -62,7 +62,7 @@
|
||||
<div class="col">{{ auction.startBidAmount }}</div>
|
||||
<div class="col">{{ auction.highestBid ? auction.highestBid.amount : "-" }}</div>
|
||||
<div class="col">{{ auction.finishBidAmount }}</div>
|
||||
<div class="col">{{ auction.highestBid ? auction.highestBid.amount / auction.amount : "-" }}</div>
|
||||
<div class="col">{{ auction.highestBid ? (auction.highestBid.amount / auction.amount).toFixed(2) : "-" }}</div>
|
||||
<div class="col">{{ auction.highestBid ? auction.highestBid.generalName : "-" }}</div>
|
||||
<div class="col">{{ auction.closeDate }}</div>
|
||||
</div>
|
||||
@@ -92,6 +92,16 @@
|
||||
</BButton>
|
||||
</BButtonGroup>
|
||||
</div>
|
||||
<div class="col">
|
||||
<NumberInputWithInfo
|
||||
v-model="openAuctionInfo.closeTurnCnt"
|
||||
:int="true"
|
||||
:min="3"
|
||||
:max="24"
|
||||
title="기간(턴)"
|
||||
:step="1"
|
||||
></NumberInputWithInfo>
|
||||
</div>
|
||||
<div class="col">
|
||||
<NumberInputWithInfo
|
||||
v-model="openAuctionInfo.amount"
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
<div class="col-4 col-md-2 bg2">종료시점</div>
|
||||
<div class="col-4 col-md-2">{{ currentAuction.auction.closeDate }}</div>
|
||||
|
||||
<div class="col-4 col-md-2 bg2">연장 허용</div>
|
||||
<div class="col-4 col-md-2">{{ currentAuction.auction.remainCloseDateExtensionCnt }}회</div>
|
||||
<div class="col-4 col-md-2 bg2">최대지연</div>
|
||||
<div class="col-4 col-md-2">{{ currentAuction.auction.availableLatestBidCloseDate }}</div>
|
||||
</div>
|
||||
<div class="bg1">입찰자 목록</div>
|
||||
<div class="row gx-0 bg2">
|
||||
@@ -42,7 +42,7 @@
|
||||
:step="1"
|
||||
></NumberInputWithInfo>
|
||||
</div>
|
||||
<div><BButton @click="bidAuction">입찰</BButton></div>
|
||||
<div class="col"><BButton @click="bidAuction">입찰</BButton></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -74,10 +74,12 @@ type AuctionItemInfo = UniqueItemAuctionList["list"][0];
|
||||
const currentAuctionID = ref<number>();
|
||||
const currentAuction = ref<UniqueItemAuctionDetail | undefined>(undefined);
|
||||
const bidAmount = ref<number>(5000);
|
||||
watch(currentAuctionID, async (auctionID) => {
|
||||
if (auctionID === undefined) {
|
||||
|
||||
async function refreshDetail() {
|
||||
if (currentAuctionID.value === undefined) {
|
||||
return;
|
||||
}
|
||||
const auctionID = currentAuctionID.value;
|
||||
try {
|
||||
currentAuction.value = await SammoAPI.Auction.GetUniqueItemAuctionDetail({ auctionID });
|
||||
} catch (e) {
|
||||
@@ -89,6 +91,9 @@ watch(currentAuctionID, async (auctionID) => {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
watch(currentAuctionID, () => {
|
||||
void refreshDetail();
|
||||
});
|
||||
const auctionList = ref(new Map<number, AuctionItemInfo>());
|
||||
const obfuscatedName = ref("");
|
||||
@@ -115,26 +120,26 @@ async function refresh() {
|
||||
}
|
||||
}
|
||||
|
||||
async function bidAuction(){
|
||||
if(currentAuction.value === undefined){
|
||||
async function bidAuction() {
|
||||
if (currentAuction.value === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const amount = bidAmount.value;
|
||||
const auctionInfo = currentAuction.value.auction;
|
||||
|
||||
if(confirm(`${auctionInfo.title}에 ${amount}유산포인트를 입찰하시겠습니까?`)){
|
||||
try{
|
||||
if (confirm(`${auctionInfo.title}에 ${amount}유산포인트를 입찰하시겠습니까?`)) {
|
||||
try {
|
||||
await SammoAPI.Auction.BidUniqueAuction({ auctionID: auctionInfo.id, amount });
|
||||
toasts.success({
|
||||
title: "성공",
|
||||
body: "입찰이 완료되었습니다.",
|
||||
});
|
||||
await refresh();
|
||||
}catch(e){
|
||||
void refreshDetail();
|
||||
void refresh();
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
if(isString(e)){
|
||||
if (isString(e)) {
|
||||
toasts.danger({
|
||||
title: "에러",
|
||||
body: e,
|
||||
|
||||
Reference in New Issue
Block a user