Added Login and Endpoint for claiming message rewards.

This commit is contained in:
Vari 2024-05-26 19:19:19 +02:00
parent 34fd1e0ac7
commit 81f5d5f54c
11 changed files with 246 additions and 5 deletions

View File

@ -0,0 +1,18 @@
meta {
name: Claim Message Reward
type: http
seq: 3
}
post {
url: {{base_url}}/api/v1/messages/claim
body: json
auth: none
}
body:json {
{
"received": 12,
"recipientId": "9b70b902-1a13-474b-b5d3-4de3d07ad971"
}
}

View File

@ -4,11 +4,16 @@
use App\Http\Controllers\Controller;
use App\Http\Middleware\AccessLogger;
use App\Http\Requests\Api\Player\Inbox\ClaimInboxMessageRequest;
use App\Http\Responses\Api\Player\Inbox\InboxMessageClaimedReward;
use App\Http\Responses\Api\Player\Inbox\InboxMessageClaimResponse;
use App\Models\Game\Inbox\InboxMessage;
use Auth;
use Illuminate\Database\UniqueConstraintViolationException;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Collection;
use Ramsey\Uuid\Uuid;
class InboxController extends Controller
{
@ -121,4 +126,79 @@ public function markMessages(Request $request) {
'List' => $resultList,
];
}
public function claimMessage(ClaimInboxMessageRequest $request)
{
$user = Auth::user();
/** @var InboxMessage $message */
$message = $user->inboxMessages()
->where('user_id', '=', $user->id)
->where('received', '=', $request->receivedTimestamp)
->first();
if($message->has_claimed)
return json_encode(new InboxMessageClaimResponse());
$claimable = $message->getClaimables();
$playerData = $user->playerData();
$response = new InboxMessageClaimResponse();
foreach($claimable as $reward) {
if($reward->rewardType === 'Currency') {
switch ($reward->id) {
case 'CurrencyA':
$oldAmount = $playerData->currency_a;
$playerData->currency_a += $reward->amount;
$newAmount = $playerData->currency_a;
break;
case 'CurrencyB':
$oldAmount = $playerData->currency_b;
$playerData->currency_b += $reward->amount;
$newAmount = $playerData->currency_b;
break;
case 'CurrencyC':
$oldAmount = $playerData->currency_c;
$playerData->currency_c += $reward->amount;
$newAmount = $playerData->currency_c;
break;
default:
continue 2;
}
$response->currencies[] = new InboxMessageClaimedReward(
$reward->id,
$newAmount,
$newAmount - $oldAmount,
);
}
else if($reward->rewardType === 'Inventory') {
$itemUuid = Uuid::fromString($reward->id)->toString();
try {
$playerData->inventory()->attach($itemUuid);
// Since we can only have one occurrence of an item in the inventory, and an exception gets thrown when we try to add the same item twice
// we can just hard code the new and received amount to 1.
$response->inventories[] = new InboxMessageClaimedReward(
$reward->id,
1,
1,
);
} catch(UniqueConstraintViolationException $e) {
$response->inventories[] = new InboxMessageClaimedReward(
$reward->id,
1,
0,
);
}
}
}
$playerData->save();
$message->has_claimed = true;
$message->save();
return json_encode($response);
}
}

View File

@ -0,0 +1,41 @@
<?php
namespace App\Http\Requests\Api\Player\Inbox;
use Auth;
use Illuminate\Foundation\Http\FormRequest;
class ClaimInboxMessageRequest extends FormRequest
{
public string $recipientId;
public int $receivedTimestamp;
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return Auth::check();
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'received' => 'required|int',
'recipientId' => 'required|string',
];
}
public function passedValidation(): void
{
$this->recipientId = $this->input('recipientId');
$this->receivedTimestamp = $this->input('received');
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Http\Responses\Api\Player\Inbox;
use JsonSerializable;
class InboxMessageClaimResponse implements JsonSerializable
{
/** @var InboxMessageClaimedReward[] array */
public array $inventories = [];
/** @var InboxMessageClaimedReward[] array */
public array $currencies = [];
public function jsonSerialize(): array
{
return [
'claimed' => [
'inventories' => $this->inventories,
'currencies' => $this->currencies,
]
];
}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Http\Responses\Api\Player\Inbox;
class InboxMessageClaimedReward
{
public function __construct(
public string $id,
public int $newAmount,
public int $receivedAmount,
)
{}
}

View File

@ -0,0 +1,13 @@
<?php
namespace App\Http\Responses\Api\Player\Inbox;
class InboxMessageReward
{
public function __construct(
public string $rewardType,
public int $amount,
public string $id,
)
{}
}

View File

@ -9,6 +9,8 @@ class Message
public string $flag;
public int $receivedTimestamp;
public MessagePayload $message;
public ?string $tag = null;

View File

@ -6,12 +6,23 @@
class MessagePayload implements JsonSerializable
{
public string $title;
public string $body;
public array $claimable;
public bool $hasClaimed;
public function __construct(
public string $title,
public string $body,
public ?array $claimable = null,
string $title,
string $body,
array $claimable = [],
bool $hasClaimed = false,
)
{
$this->title = $title;
$this->body = $body;
$this->claimable = $claimable;
$this->hasClaimed = $hasClaimed;
}
public function jsonSerialize(): mixed
@ -21,8 +32,11 @@ public function jsonSerialize(): mixed
'body' => $this->body,
];
if($this->claimable !== null)
$data['claimable'] = $this->claimable;
if ($this->claimable !== null)
$data['claimable'] = [
'data' => $this->claimable,
'state' => $this->hasClaimed ? 'CLAIMED' : 'NONE',
];
return $data;
}

View File

@ -2,8 +2,10 @@
namespace App\Models\Game\Inbox;
use App\Http\Responses\Api\Player\Inbox\InboxMessageReward;
use App\Http\Responses\Api\Player\Inbox\Message;
use App\Http\Responses\Api\Player\Inbox\MessagePayload;
use App\Http\Responses\Api\Player\Inbox\MessageV2;
use App\Models\User\User;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@ -22,6 +24,10 @@ class InboxMessage extends Model
'expire_at' => 'datetime',
];
protected $attributes = [
'claimable' => [],
];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
@ -41,7 +47,32 @@ public function toMessageResponse(): Message {
$message->expireAt = $this->expire_at?->getTimestamp();
$message->origin = $this->origin;
$message->recipientId = $this->user->id;
$message->receivedTimestamp = $this->created_at->getTimestamp();
return $message;
}
/**
* @return InboxMessageReward[]
*/
public function getClaimables(): array {
$result = [];
foreach ($this->claimable as $claimable) {
$result[] = new InboxMessageReward(
$claimable['type'],
$claimable['amount'],
$claimable['id'],
);
}
return $result;
}
public function setClaimables(array $claimables): void {
$this->claimable = [];
foreach ($claimables as $claimable) {
$this->claimable[] = (array)$claimable;
}
}
}

View File

@ -13,6 +13,7 @@ public function up(): void
{
Schema::create('inbox_messages', function (Blueprint $table) {
$table->id();
$table->bigInteger('received', false, true)->index();
$table->foreignUuid('user_id')->constrained();
$table->text('title');
$table->text('body');
@ -21,6 +22,9 @@ public function up(): void
$table->datetime('expire_at')->nullable();
$table->string('origin')->nullable()->default(null);
$table->json('claimable')->nullable();
$table->boolean('has_claimed')->default(false);
$table->unique(['user_id', 'received']);
$table->timestamps();
});

View File

@ -46,6 +46,7 @@
Route::get('messages/count', [InboxController::class, 'count']);
Route::get('messages/list', [InboxController::class, 'list']);
Route::post('messages/claim', [InboxController::class, 'claimMessage']);
Route::delete('messages/list', [InboxController::class, 'deleteMultiple']);
Route::post('messages/v2/markAs', [InboxController::class, 'markMessages']);