mirror of
https://github.com/Deathgarden-Rebirth/Deathgarden_Rebirth-Rewrite.git
synced 2026-09-08 11:15:09 -05:00
191 lines
7.1 KiB
PHP
191 lines
7.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Player;
|
|
|
|
use App\Helper\Uuid\UuidHelper;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Http\Middleware\AccessLogger;
|
|
use App\Http\Requests\Api\Player\PurchaseItemRequest;
|
|
use App\Http\Requests\Api\Player\PurchaseSetRequest;
|
|
use App\Http\Responses\Api\Player\Purchase\PurchaseItemResponse;
|
|
use App\Http\Responses\Api\Player\Purchase\PurchaseSetResponse;
|
|
use App\Http\Responses\Api\Player\Purchase\WalletEntry;
|
|
use App\Models\Game\CatalogItem;
|
|
use App\Models\Game\Challenge;
|
|
use App\Models\Game\CharacterData;
|
|
use App\Models\Game\PickedChallenge;
|
|
use App\Models\User\PlayerData;
|
|
use Illuminate\Database\UniqueConstraintViolationException;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Ramsey\Uuid\Uuid;
|
|
|
|
class PurchaseController extends Controller
|
|
{
|
|
public function purchaseSet(PurchaseSetRequest $request)
|
|
{
|
|
$user = Auth::user();
|
|
$playerData = $user->playerData();
|
|
$setItem = CatalogItem::find($request->itemId, ['id']);
|
|
|
|
if($setItem === null)
|
|
return response('Set item not found.', 404);
|
|
|
|
$bundleItems = $setItem->bundleItems()->get([
|
|
'id',
|
|
'default_cost_currency_a',
|
|
'default_cost_currency_b',
|
|
'default_cost_currency_c'
|
|
]);
|
|
|
|
$costA = $costB = $costC = 0;
|
|
|
|
$bundleItems->each(function (CatalogItem $item) use (&$costA, &$costB, &$costC) {
|
|
$costA += $item->default_cost_currency_a;
|
|
$costB += $item->default_cost_currency_b;
|
|
$costC += $item->default_cost_currency_c;
|
|
});
|
|
|
|
if( $playerData->currency_a < $costA ||
|
|
$playerData->currency_b < $costB ||
|
|
$playerData->currency_c < $costC)
|
|
return response('Not enough Currency', 402);
|
|
|
|
$bundleItemIds = $setItem->bundleItems()->allRelatedIds();
|
|
$bundleItemIds->add($setItem->id);
|
|
|
|
try {
|
|
$playerData->inventory()->syncWithoutDetaching($bundleItemIds);
|
|
}
|
|
catch (UniqueConstraintViolationException $e) {
|
|
$message = 'User "'.$user->id.'" ('.$user->last_known_username.') tried to purchase item already in inventory'."\n";
|
|
AccessLogger::getSessionLogConfig()->notice($message.json_encode([
|
|
'bundleItems' => $bundleItems,
|
|
'setItem' => $setItem,
|
|
]));
|
|
return response('Item already in inventory.', 418);
|
|
}
|
|
|
|
$playerData->currency_a -= $costA;
|
|
$playerData->currency_b -= $costB;
|
|
$playerData->currency_c -= $costC;
|
|
$playerData->save();
|
|
|
|
$cost = new WalletEntry(
|
|
$costA, 0,
|
|
$costB, 0,
|
|
$costC, 0,
|
|
);
|
|
|
|
$newBalance = new WalletEntry(
|
|
$playerData->currency_a, $costA,
|
|
$playerData->currency_b, $costB,
|
|
$playerData->currency_c, $costC,
|
|
);
|
|
|
|
$response = new PurchaseSetResponse(
|
|
$cost,
|
|
$newBalance,
|
|
[Uuid::fromString($setItem->id)->getHex()->toString()],
|
|
UuidHelper::convertFromUuidToHexCollection($bundleItemIds->toArray())->toArray(),
|
|
);
|
|
|
|
return json_encode($response);
|
|
}
|
|
|
|
public function purchaseItem(PurchaseItemRequest $request)
|
|
{
|
|
$user = Auth::user();
|
|
$playerData = $user->playerData();
|
|
$quantityToBuy = $request->wantedQuantity - $request->oldQuantity;
|
|
|
|
$itemToBuy = CatalogItem::find($request->objectId);
|
|
|
|
if(!$this->hasCompletedChallengeForItem($itemToBuy, $playerData)) {
|
|
Log::channel('dg_purchase_error')->error(json_encode([
|
|
'errorReason' => 'Challenge not completed',
|
|
'user' => $user->id . " ($user->last_known_username)",
|
|
'playerData' => $playerData->attributesToArray(),
|
|
'itemToBuy' => $itemToBuy->display_name,
|
|
],
|
|
JSON_PRETTY_PRINT));
|
|
return response('Not completed required challenge/s', 418);
|
|
}
|
|
|
|
if( $playerData->currency_a < ($itemToBuy->default_cost_currency_a * $quantityToBuy) ||
|
|
$playerData->currency_b < ($itemToBuy->default_cost_currency_b * $quantityToBuy) ||
|
|
$playerData->currency_c < ($itemToBuy->default_cost_currency_c * $quantityToBuy)) {
|
|
Log::channel('dg_purchase_error')->error(json_encode([
|
|
'errorReason' => 'Not enough Currency',
|
|
'user' => $user->id . " ($user->last_known_username)",
|
|
'playerData' => $playerData->attributesToArray(),
|
|
'itemToBuy' => $itemToBuy->display_name,
|
|
],
|
|
JSON_PRETTY_PRINT));
|
|
return response('Not enough Currency', 418);
|
|
}
|
|
|
|
try {
|
|
$playerData->inventory()->syncWithoutDetaching($itemToBuy);
|
|
}
|
|
catch (UniqueConstraintViolationException $e) {
|
|
$message = 'User "'.$user->id.'" ('.$user->last_known_username.') tried to purchase item already in inventory'."\n";
|
|
AccessLogger::getSessionLogConfig()->notice($message.json_encode([
|
|
'item to buy' => $itemToBuy,
|
|
]));
|
|
Log::channel('dg_purchase_error')->notice($message.json_encode([
|
|
'item to buy' => $itemToBuy,
|
|
]));
|
|
return response('Item already in inventory.', 418);
|
|
}
|
|
|
|
$playerData->currency_a -= $itemToBuy->default_cost_currency_a * $quantityToBuy;
|
|
$playerData->currency_b -= $itemToBuy->default_cost_currency_b * $quantityToBuy;
|
|
$playerData->currency_c -= $itemToBuy->default_cost_currency_c * $quantityToBuy;
|
|
$playerData->save();
|
|
|
|
$hexItemId = Uuid::fromString($itemToBuy->id)->getHex()->toString();
|
|
|
|
$response = new PurchaseItemResponse(
|
|
$user->id,
|
|
$hexItemId,
|
|
$quantityToBuy,
|
|
new WalletEntry(
|
|
$playerData->currency_a,
|
|
$itemToBuy->default_cost_currency_a * $quantityToBuy,
|
|
$playerData->currency_b,
|
|
$itemToBuy->default_cost_currency_b * $quantityToBuy,
|
|
$playerData->currency_c,
|
|
$itemToBuy->default_cost_currency_c * $quantityToBuy,
|
|
),
|
|
[$hexItemId],
|
|
);
|
|
|
|
return json_encode($response);
|
|
}
|
|
|
|
protected function hasCompletedChallengeForItem(CatalogItem &$item, PlayerData &$playerData)
|
|
{
|
|
/** @var Challenge $foundChallenge */
|
|
$foundChallenge = $item->requiredChallenges()->first();
|
|
|
|
if ($foundChallenge !== null) {
|
|
return $foundChallenge->getProgressForPlayer($playerData->id) >= $foundChallenge->completion_value;
|
|
}
|
|
|
|
$characterIds = [];
|
|
$playerData->characterData()->get(['id'])->each(function (CharacterData $data) use ($characterIds) {
|
|
$characterIds[] = $data->id;
|
|
});
|
|
|
|
$foundChallenge = PickedChallenge::where('catalog_item_id', '=', $item->id)
|
|
->whereIn('character_data_id', $characterIds)->first();
|
|
|
|
if($foundChallenge === null)
|
|
return true;
|
|
|
|
return $foundChallenge->progress >= $foundChallenge->completion_value;
|
|
}
|
|
}
|