feat,fix,wip: 버그 수정, 연장 시간 로직 변경

This commit is contained in:
2022-06-09 01:21:21 +09:00
parent d18ae3dd11
commit 717ec012ba
18 changed files with 232 additions and 137 deletions
-2
View File
@@ -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
View File
@@ -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;
}
+2 -2
View File
@@ -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)) {
-17
View File
@@ -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
View File
@@ -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(
+1 -1
View File
@@ -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;
}
+16 -19
View File
@@ -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
View File
@@ -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;
}
}
}
+2 -2
View File
@@ -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">
+13 -3
View File
@@ -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"
+18 -13
View File
@@ -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,