feat(wip): 유니크 옥션 시작
This commit is contained in:
+14
-17
@@ -17,7 +17,7 @@ use sammo\VO\InheritancePointType;
|
||||
class Auction
|
||||
{
|
||||
|
||||
private AuctionInfo $info;
|
||||
protected AuctionInfo $info;
|
||||
public const LAST_AUCTION_ID_KEY = 'last_auction_id';
|
||||
|
||||
static public function genNextAuctionID(): int
|
||||
@@ -55,7 +55,7 @@ class Auction
|
||||
$auctionStor->setValue("id_{$auctionID}", $info->toArray());
|
||||
}
|
||||
|
||||
public function getHighestBid(): AuctionBidItem
|
||||
public function getHighestBid(): ?AuctionBidItem
|
||||
{
|
||||
$db = DB::db();
|
||||
$rawHighestBid = $db->queryFirstRow(
|
||||
@@ -63,7 +63,7 @@ class Auction
|
||||
$this->info->id
|
||||
);
|
||||
if(!$rawHighestBid){
|
||||
throw new \Exception('입찰이 없습니다.');
|
||||
return null;
|
||||
}
|
||||
|
||||
return AuctionBidItem::fromArray($rawHighestBid);
|
||||
@@ -83,7 +83,7 @@ class Auction
|
||||
return AuctionBidItem::fromArray($rawMyPrevBid);
|
||||
}
|
||||
|
||||
public function __construct(private readonly int $auctionID, private General $general)
|
||||
public function __construct(protected readonly int $auctionID, protected General $general)
|
||||
{
|
||||
$db = DB::db();
|
||||
$auctionStor = KVStorage::getStorage($db, 'auction');
|
||||
@@ -166,7 +166,11 @@ class Auction
|
||||
$this->general->setAuxVar('openedAuction', $openedAuction);
|
||||
}
|
||||
if ($isRollback) {
|
||||
$this->refundBid($this->getHighestBid(), "{$this->info->title} 경매가 취소되었습니다.");
|
||||
$highestBid = $this->getHighestBid();
|
||||
if($highestBid !== null){
|
||||
$this->refundBid($highestBid, "{$this->info->title} 경매가 취소되었습니다.");
|
||||
}
|
||||
|
||||
}
|
||||
$auctionID = $this->info->id;
|
||||
$auctionStor->setValue("id_{$auctionID}", $this->info->toArray());
|
||||
@@ -180,7 +184,7 @@ class Auction
|
||||
$general = $this->general;
|
||||
|
||||
$highestBid = $this->getHighestBid();
|
||||
if ($amount <= $highestBid->amount) {
|
||||
if ($highestBid !== null && $amount <= $highestBid->amount) {
|
||||
throw new \RuntimeException('현재입찰가보다 높게 입찰해야 합니다.');
|
||||
}
|
||||
|
||||
@@ -220,7 +224,7 @@ class Auction
|
||||
$general->increaseInheritancePoint(InheritanceKey::previous, -$morePoint);
|
||||
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, $morePoint);
|
||||
|
||||
if ($myPrevBid === null || $myPrevBid->id !== $highestBid->id) {
|
||||
if ($myPrevBid === null || ($highestBid !== null && $myPrevBid->id !== $highestBid->id)) {
|
||||
$this->refundBid($highestBid, "{$auctionInfo->title} 경매에 상회입찰자가 나타났습니다.");
|
||||
}
|
||||
$general->applyDB($db);
|
||||
@@ -257,15 +261,8 @@ class Auction
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$rawHighestBid = $db->queryFirstRow(
|
||||
'SELECT * FROM ng_auction WHERE auction_id = %i ORDER BY `amount` DESC LIMIT 1',
|
||||
$auctionInfo->id
|
||||
);
|
||||
if (!$rawHighestBid) {
|
||||
throw new \RuntimeException('최고 입찰가가 없습니다.');
|
||||
}
|
||||
$highestBid = AuctionBidItem::fromArray($rawHighestBid);
|
||||
if ($amount <= $highestBid->amount) {
|
||||
$highestBid = $this->getHighestBid();
|
||||
if ($highestBid !== null && $amount <= $highestBid->amount) {
|
||||
throw new \RuntimeException('현재입찰가보다 높게 입찰해야 합니다.');
|
||||
}
|
||||
|
||||
@@ -300,7 +297,7 @@ class Auction
|
||||
|
||||
$general->setVar($resType->value, $general->getVar($resType->value) - $morePoint);
|
||||
|
||||
if ($myPrevBid === null || $myPrevBid->id !== $highestBid->id) {
|
||||
if ($myPrevBid === null || ($highestBid !== null && $myPrevBid->id !== $highestBid->id)) {
|
||||
$this->refundBid($highestBid, "{$auctionInfo->title} 경매에 상회입찰자가 나타났습니다.");
|
||||
}
|
||||
$general->applyDB($db);
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
use DateTimeImmutable;
|
||||
use sammo\DTO\AuctionInfo;
|
||||
use sammo\Enums\InheritanceKey;
|
||||
use sammo\Enums\ResourceType;
|
||||
use sammo\RandUtil;
|
||||
|
||||
class AuctionUniqueItem extends Auction
|
||||
{
|
||||
|
||||
static public function genObfuscatedName(int $id): string
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$namePool = $gameStor->getValue('obfuscatedNamePool');
|
||||
if($namePool === null){
|
||||
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
||||
UniqueConst::$hiddenSeed,
|
||||
)));
|
||||
$namePool = [];
|
||||
foreach(GameConst::$randGenFirstName as $ch0){
|
||||
foreach(GameConst::$randGenMiddleName as $ch1){
|
||||
foreach(GameConst::$randGenLastName as $ch2){
|
||||
$namePool[] = "{$ch0}{$ch1}{$ch2}";
|
||||
}
|
||||
}
|
||||
}
|
||||
$namePool = $rng->shuffle($namePool);
|
||||
$gameStor->setValue('obfuscatedNamePool', $namePool);
|
||||
}
|
||||
|
||||
|
||||
$dupIdx = intdiv($id, count($namePool));
|
||||
$subIdx = $id % count($namePool);
|
||||
if ($dupIdx == 0) {
|
||||
return $namePool[$subIdx];
|
||||
}
|
||||
return "{$namePool[$subIdx]}{$dupIdx}";
|
||||
}
|
||||
|
||||
static public function openItemAuction(BaseItem $item, General $general, int $startAmount): ?string
|
||||
{
|
||||
if ($startAmount < GameConst::$inheritItemUniqueMinPoint) {
|
||||
return '최소 경매 금액은 ' . GameConst::$inheritItemUniqueMinPoint . '입니다.';
|
||||
}
|
||||
|
||||
if($general->getInheritancePoint(InheritanceKey::previous) < $startAmount){
|
||||
return '경매를 시작할 포인트가 부족합니다.';
|
||||
}
|
||||
|
||||
$auctionID = static::genNextAuctionID();
|
||||
$now = new DateTimeImmutable();
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$turnTerm = $gameStor->getValue('turnterm');
|
||||
|
||||
$closeDate = $now->add(TimeUtil::secondsToDateInterval(24 * 60 * $turnTerm * 60));
|
||||
|
||||
$info = new AuctionInfo(
|
||||
$auctionID,
|
||||
static::genObfuscatedName($general->getID()),
|
||||
$general->getID(),
|
||||
$item->getRawClassName(),
|
||||
"{$item->getName()} 경매",
|
||||
false,
|
||||
ResourceType::inheritancePoint,
|
||||
$startAmount,
|
||||
null,
|
||||
$now,
|
||||
$closeDate
|
||||
);
|
||||
|
||||
$result = static::openAuction($info, $general);
|
||||
if($result !== null){
|
||||
return $result;
|
||||
}
|
||||
$auction = new static($auctionID, $general);
|
||||
try{
|
||||
$auction->bid($startAmount);
|
||||
}
|
||||
catch(\Exception $e){
|
||||
//실패해선 안된다.
|
||||
$msg = $e->getMessage();
|
||||
$auction->closeAuction();
|
||||
return "경매를 시작했지만, 첫 입찰에 실패했습니다: {$msg}";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ class AuctionInfo extends DTO
|
||||
{
|
||||
public function __construct(
|
||||
public int $id,
|
||||
public int $openerName,
|
||||
public string $openerName,
|
||||
public int $openerGeneralID,
|
||||
public string $type,
|
||||
public string $title,
|
||||
|
||||
Reference in New Issue
Block a user