281 lines
12 KiB
PHP
281 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* Spacetraders cargo shop page.
|
|
*
|
|
* @package SpacetradersAPI
|
|
* @author Keith Solomon <keith@keithsolomon.net>
|
|
* @license MIT License
|
|
* @version GIT: <git_id>
|
|
* @link https://git.keithsolomon.net/keith/Spacetraders
|
|
*/
|
|
|
|
require_once __DIR__ . '/lib/spacetraders-api.php';
|
|
require_once __DIR__ . '/lib/spacetraders-storage.php';
|
|
|
|
$config = require __DIR__ . '/lib/project-config.php';
|
|
|
|
$storage = new SpacetradersStorage( $config['db_path'] );
|
|
$token = $storage->getAgentToken();
|
|
|
|
$statusMessage = '';
|
|
$errorMessage = '';
|
|
$agent = array();
|
|
$ships = array();
|
|
$stationedShips = array();
|
|
$selectedShipSymbol = '';
|
|
$selectedShip = array();
|
|
$selectedMarketData = array();
|
|
$selectedMarketError = '';
|
|
$selectedSystemSymbol = '';
|
|
$selectedWaypointSymbol = '';
|
|
$preferredWaypoint = trim( (string) ( $_GET['waypoint'] ?? '' ) );
|
|
|
|
if (! is_string( $token ) || trim( $token ) === '' ) {
|
|
$envToken = getenv( 'SPACETRADERS_TOKEN' );
|
|
|
|
if (is_string( $envToken ) && trim( $envToken ) !== '' ) {
|
|
$token = trim( $envToken );
|
|
$storage->setAgentToken( $token );
|
|
}
|
|
}
|
|
|
|
if (! is_string( $token ) || trim( $token ) === '' ) {
|
|
$tokenError = 'No token found. Set one in config.php or SPACETRADERS_TOKEN.';
|
|
}
|
|
|
|
if (! isset( $tokenError ) ) {
|
|
$client = new SpacetradersApi(
|
|
trim( $token ),
|
|
$config['api_base_url'],
|
|
(int) $config['api_timeout'],
|
|
$storage,
|
|
(int) $config['cache_ttl']
|
|
);
|
|
}
|
|
|
|
try {
|
|
if (! isset( $tokenError ) ) {
|
|
$agentResponse = $client->getMyAgent();
|
|
$shipsResponse = $client->listMyShips();
|
|
|
|
$agent = $agentResponse['data'] ?? $agentResponse;
|
|
$ships = $shipsResponse['data'] ?? $shipsResponse;
|
|
|
|
foreach ( $ships as $ship ) {
|
|
$status = (string) ( $ship['nav']['status'] ?? '' );
|
|
if ($status === 'IN_TRANSIT' ) {
|
|
continue;
|
|
}
|
|
|
|
$stationedShips[] = $ship;
|
|
}
|
|
|
|
$selectedShipSymbol = trim( (string) ( $_POST['ship_symbol'] ?? '' ) );
|
|
if ($selectedShipSymbol === '' ) {
|
|
$selectedShipSymbol = trim( (string) ( $_GET['ship'] ?? '' ) );
|
|
}
|
|
|
|
if ($selectedShipSymbol === '' && $preferredWaypoint !== '' ) {
|
|
foreach ( $stationedShips as $stationedShip ) {
|
|
$waypointSymbol = (string) ( $stationedShip['nav']['waypointSymbol'] ?? '' );
|
|
if ($waypointSymbol === $preferredWaypoint ) {
|
|
$selectedShipSymbol = (string) ( $stationedShip['symbol'] ?? '' );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($selectedShipSymbol === '' && ! empty( $stationedShips ) ) {
|
|
$selectedShipSymbol = (string) ( $stationedShips[0]['symbol'] ?? '' );
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset( $_POST['buy_cargo'] ) ) {
|
|
$selectedShipSymbol = trim( (string) ( $_POST['ship_symbol'] ?? '' ) );
|
|
$tradeSymbol = trim( (string) ( $_POST['trade_symbol'] ?? '' ) );
|
|
$units = (int) ( $_POST['units'] ?? 0 );
|
|
|
|
if ($selectedShipSymbol === '' || $tradeSymbol === '' || $units <= 0 ) {
|
|
throw new SpacetradersApiException( 'Ship, trade symbol, and units are required.' );
|
|
}
|
|
|
|
$selectedShipResponse = $client->getShip( $selectedShipSymbol );
|
|
$selectedShipData = $selectedShipResponse['data'] ?? array();
|
|
$shipStatus = (string) ( $selectedShipData['nav']['status'] ?? '' );
|
|
|
|
if ($shipStatus === 'IN_TRANSIT' ) {
|
|
throw new SpacetradersApiException( 'Selected ship is currently in transit.' );
|
|
}
|
|
|
|
if ($shipStatus !== 'DOCKED' ) {
|
|
$client->dockShip( $selectedShipSymbol );
|
|
}
|
|
|
|
$client->purchaseCargo( $selectedShipSymbol, $tradeSymbol, $units );
|
|
$storage->clearAllCache();
|
|
$statusMessage = 'Purchased ' . number_format( $units ) . ' units of ' . $tradeSymbol . '.';
|
|
|
|
$shipsResponse = $client->listMyShips();
|
|
$ships = $shipsResponse['data'] ?? $shipsResponse;
|
|
$stationedShips = array();
|
|
foreach ( $ships as $ship ) {
|
|
$status = (string) ( $ship['nav']['status'] ?? '' );
|
|
if ($status === 'IN_TRANSIT' ) {
|
|
continue;
|
|
}
|
|
$stationedShips[] = $ship;
|
|
}
|
|
}
|
|
|
|
if ($selectedShipSymbol !== '' ) {
|
|
$selectedShipResponse = $client->getShip( $selectedShipSymbol );
|
|
$selectedShip = $selectedShipResponse['data'] ?? array();
|
|
$selectedSystemSymbol = (string) ( $selectedShip['nav']['systemSymbol'] ?? '' );
|
|
$selectedWaypointSymbol = (string) ( $selectedShip['nav']['waypointSymbol'] ?? '' );
|
|
|
|
if ($selectedSystemSymbol !== '' && $selectedWaypointSymbol !== '' ) {
|
|
try {
|
|
$marketResponse = $client->getWaypointMarket( $selectedSystemSymbol, $selectedWaypointSymbol );
|
|
$selectedMarketData = (array) ( $marketResponse['data'] ?? array() );
|
|
} catch (SpacetradersApiException $e) {
|
|
$selectedMarketError = $e->getMessage();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (SpacetradersApiException $e) {
|
|
$errorMessage = $e->getMessage();
|
|
}
|
|
?>
|
|
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Spacetraders - Shop</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
</head>
|
|
|
|
<body class="container mx-auto px-4 py-8 bg-stone-800 text-gray-200">
|
|
<?php require __DIR__ . '/main-menu.php'; ?>
|
|
|
|
<h1 class="text-3xl font-bold mb-6 underline decoration-gray-300 w-full"><a href="shop.php">Spacetraders - Shop</a></h1>
|
|
|
|
<?php if (isset( $tokenError ) ) : ?>
|
|
<div class="mb-6 border border-red-500 p-4 rounded text-red-300">
|
|
<?php echo htmlspecialchars( $tokenError ); ?>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
<?php exit; ?>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($statusMessage !== '' ) : ?>
|
|
<div class="mb-6 border border-green-500 p-4 rounded text-green-300">
|
|
<?php echo htmlspecialchars( $statusMessage ); ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<?php if ($errorMessage !== '' ) : ?>
|
|
<div class="mb-6 border border-red-500 p-4 rounded text-red-300">
|
|
<?php echo htmlspecialchars( $errorMessage ); ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<form method="post" class="mb-6 border border-gray-600 rounded p-4 flex flex-wrap items-end gap-3">
|
|
<div>
|
|
<label for="ship_symbol" class="block text-sm mb-1">Ship</label>
|
|
<select id="ship_symbol" name="ship_symbol" class="px-3 py-2 rounded text-black min-w-64">
|
|
<?php foreach ( $stationedShips as $ship ) : ?>
|
|
<?php
|
|
$shipSymbol = (string) ( $ship['symbol'] ?? '' );
|
|
$shipWaypoint = (string) ( $ship['nav']['waypointSymbol'] ?? '' );
|
|
?>
|
|
<option value="<?php echo htmlspecialchars( $shipSymbol ); ?>" <?php echo $shipSymbol === $selectedShipSymbol ? 'selected' : ''; ?>>
|
|
<?php echo htmlspecialchars( formatString( $shipSymbol ) . ' @ ' . $shipWaypoint ); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<button type="submit" class="px-4 py-2 bg-blue-700 rounded hover:bg-blue-600">Load Market</button>
|
|
</form>
|
|
|
|
<?php if ($selectedShipSymbol === '' ) : ?>
|
|
<div class="border border-gray-600 rounded p-4">
|
|
No stationed ships are available for shopping.
|
|
</div>
|
|
<?php else : ?>
|
|
<div class="mb-6 border border-gray-600 rounded p-4">
|
|
<p>
|
|
<span class="font-bold">Selected Ship:</span>
|
|
<?php echo htmlspecialchars( formatString( $selectedShipSymbol ) ); ?>
|
|
</p>
|
|
|
|
<p>
|
|
<span class="font-bold">Location:</span>
|
|
<?php echo htmlspecialchars( $selectedWaypointSymbol ); ?>
|
|
</p>
|
|
|
|
<p>
|
|
<span class="font-bold">Cargo:</span>
|
|
<?php echo number_format( (int) ( $selectedShip['cargo']['units'] ?? 0 ) ); ?>
|
|
/
|
|
<?php echo number_format( (int) ( $selectedShip['cargo']['capacity'] ?? 0 ) ); ?>
|
|
</p>
|
|
</div>
|
|
|
|
<?php if ($selectedMarketError !== '' ) : ?>
|
|
<div class="border border-red-500 rounded p-4 text-red-300">
|
|
<?php echo htmlspecialchars( $selectedMarketError ); ?>
|
|
</div>
|
|
<?php else : ?>
|
|
<?php $tradeGoods = (array) ( $selectedMarketData['tradeGoods'] ?? array() ); ?>
|
|
|
|
<?php if (empty( $tradeGoods ) ) : ?>
|
|
<div class="border border-gray-600 rounded p-4">
|
|
No trade goods available for this market yet.
|
|
</div>
|
|
<?php else : ?>
|
|
<table class="table-auto border-collapse border border-gray-300 w-full">
|
|
<tr>
|
|
<th class="border border-gray-300 px-3 py-2">Symbol</th>
|
|
<th class="border border-gray-300 px-3 py-2">Type</th>
|
|
<th class="border border-gray-300 px-3 py-2">Supply</th>
|
|
<th class="border border-gray-300 px-3 py-2">Purchase Price</th>
|
|
<th class="border border-gray-300 px-3 py-2">Sell Price</th>
|
|
<th class="border border-gray-300 px-3 py-2">Buy</th>
|
|
</tr>
|
|
<?php foreach ( $tradeGoods as $tradeGood ) : ?>
|
|
<?php
|
|
$tradeSymbol = (string) ( $tradeGood['symbol'] ?? '' );
|
|
$purchasePrice = (int) ( $tradeGood['purchasePrice'] ?? 0 );
|
|
?>
|
|
<tr>
|
|
<td class="border border-gray-300 px-3 py-2"><?php echo htmlspecialchars( formatString( $tradeSymbol ) ); ?></td>
|
|
<td class="border border-gray-300 px-3 py-2"><?php echo htmlspecialchars( (string) ( formatString( $tradeGood['type'] ?? '' ) ) ); ?></td>
|
|
<td class="border border-gray-300 px-3 py-2"><?php echo htmlspecialchars( (string) ( formatString( $tradeGood['supply'] ?? '' ) ) ); ?></td>
|
|
<td class="border border-gray-300 px-3 py-2"><?php echo number_format( $purchasePrice ); ?></td>
|
|
<td class="border border-gray-300 px-3 py-2"><?php echo number_format( (int) ( $tradeGood['sellPrice'] ?? 0 ) ); ?></td>
|
|
<td class="border border-gray-300 px-3 py-2">
|
|
<?php if ($tradeSymbol !== '' && $purchasePrice > 0 ) : ?>
|
|
<form method="post" class="flex items-center gap-2">
|
|
<input type="hidden" name="buy_cargo" value="1">
|
|
<input type="hidden" name="ship_symbol" value="<?php echo htmlspecialchars( $selectedShipSymbol ); ?>">
|
|
<input type="hidden" name="trade_symbol" value="<?php echo htmlspecialchars( $tradeSymbol ); ?>">
|
|
<input type="number" name="units" min="1" value="1" class="w-20 px-2 py-1 rounded text-black">
|
|
<button type="submit" class="px-3 py-1 bg-emerald-700 rounded hover:bg-emerald-600">Buy</button>
|
|
</form>
|
|
<?php else : ?>
|
|
<span class="text-gray-400 text-sm">N/A</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</table>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
<?php endif; ?>
|
|
</body>
|
|
</html>
|