2021-06-05 09:26:32 +00:00
< ? php
namespace App\Http\Controllers ;
use App\Classes\Pterodactyl ;
use App\Models\Configuration ;
use App\Models\Egg ;
2021-11-07 15:29:18 +00:00
use App\Models\Location ;
2021-06-05 09:26:32 +00:00
use App\Models\Nest ;
use App\Models\Node ;
use App\Models\Product ;
use App\Models\Server ;
use App\Notifications\ServerCreationError ;
use Exception ;
2021-11-07 11:07:30 +00:00
use Illuminate\Database\Eloquent\Builder ;
2021-06-30 21:53:28 +00:00
use Illuminate\Http\Client\Response ;
2021-06-26 21:56:54 +00:00
use Illuminate\Http\RedirectResponse ;
2021-06-05 09:26:32 +00:00
use Illuminate\Http\Request ;
use Illuminate\Support\Facades\Auth ;
2021-10-01 21:21:49 +00:00
use Illuminate\Support\Facades\Request as FacadesRequest ;
2021-06-05 09:26:32 +00:00
class ServerController extends Controller
{
2021-06-06 18:17:52 +00:00
/** Display a listing of the resource. */
2021-06-06 21:26:36 +00:00
public function index ()
2021-06-05 09:26:32 +00:00
{
return view ( 'servers.index' ) -> with ([
'servers' => Auth :: user () -> Servers
]);
}
2021-06-06 18:17:52 +00:00
/** Show the form for creating a new resource. */
2021-06-06 21:26:36 +00:00
public function create ()
2021-06-05 09:26:32 +00:00
{
2021-06-26 21:56:54 +00:00
if ( ! is_null ( $this -> validateConfigurationRules ())) return $this -> validateConfigurationRules ();
2021-06-05 09:26:32 +00:00
2021-11-07 11:07:30 +00:00
$productCount = Product :: query () -> where ( 'disabled' , '=' , false ) -> count ();
$nodeCount = Node :: query () -> has ( 'products' ) -> count ();
$eggs = Egg :: query () -> has ( 'products' ) -> get ();
2021-11-07 15:29:18 +00:00
$locations = Location :: all ();
2021-11-07 11:07:30 +00:00
$nests = Nest :: query () -> whereHas ( 'eggs' , function ( Builder $builder ) {
$builder -> has ( 'products' );
}) -> get ();
2021-06-05 09:26:32 +00:00
return view ( 'servers.create' ) -> with ([
2021-11-07 15:29:18 +00:00
'productCount' => $productCount ,
'nodeCount' => $nodeCount ,
'nests' => $nests ,
'locations' => $locations ,
'eggs' => $eggs ,
'user' => Auth :: user (),
2021-06-05 09:26:32 +00:00
]);
}
2021-06-26 21:56:54 +00:00
/**
2021-06-26 22:02:27 +00:00
* @ return null | RedirectResponse
2021-06-26 21:56:54 +00:00
*/
2021-10-01 21:21:49 +00:00
private function validateConfigurationRules ()
{
2021-06-26 21:56:54 +00:00
//limit validation
if ( Auth :: user () -> servers () -> count () >= Auth :: user () -> server_limit ) {
return redirect () -> route ( 'servers.index' ) -> with ( 'error' , 'Server limit reached!' );
}
2021-10-01 21:21:49 +00:00
// minimum credits
2021-11-07 00:47:16 +00:00
if ( FacadesRequest :: has ( " product " )) {
$product = Product :: findOrFail ( FacadesRequest :: input ( " product " ));
2021-10-01 21:21:49 +00:00
if (
2021-10-03 13:18:08 +00:00
Auth :: user () -> credits <
2021-10-01 21:21:49 +00:00
( $product -> minimum_credits == - 1
? Configuration :: getValueByKey ( 'MINIMUM_REQUIRED_CREDITS_TO_MAKE_SERVER' , 50 )
: $product -> minimum_credits )
) {
2021-10-03 12:47:51 +00:00
return redirect () -> route ( 'servers.index' ) -> with ( 'error' , " You do not have the required amount of " . CREDITS_DISPLAY_NAME . " to use this product! " );
2021-10-01 21:21:49 +00:00
}
2021-06-26 21:56:54 +00:00
}
//Required Verification for creating an server
if ( Configuration :: getValueByKey ( 'FORCE_EMAIL_VERIFICATION' , 'false' ) === 'true' && ! Auth :: user () -> hasVerifiedEmail ()) {
return redirect () -> route ( 'profile.index' ) -> with ( 'error' , " You are required to verify your email address before you can create a server. " );
}
//Required Verification for creating an server
if ( Configuration :: getValueByKey ( 'FORCE_DISCORD_VERIFICATION' , 'false' ) === 'true' && ! Auth :: user () -> discordUser ) {
return redirect () -> route ( 'profile.index' ) -> with ( 'error' , " You are required to link your discord account before you can create a server. " );
}
return null ;
}
2021-11-06 00:56:57 +00:00
/** Store a newly created resource in storage. */
public function store ( Request $request )
2021-06-05 09:26:32 +00:00
{
2021-11-07 11:07:30 +00:00
/** @var Node $node */
/** @var Egg $egg */
/** @var Product $product */
2021-11-06 00:56:57 +00:00
if ( ! is_null ( $this -> validateConfigurationRules ())) return $this -> validateConfigurationRules ();
$request -> validate ([
2021-11-07 00:47:16 +00:00
" name " => " required|max:191 " ,
" node " => " required|exists:nodes,id " ,
" egg " => " required|exists:eggs,id " ,
" product " => " required|exists:products,id "
2021-11-06 00:56:57 +00:00
]);
//get required resources
2021-11-07 11:07:30 +00:00
$product = Product :: query () -> findOrFail ( $request -> input ( 'product' ));
$egg = $product -> eggs () -> findOrFail ( $request -> input ( 'egg' ));
$node = $product -> nodes () -> findOrFail ( $request -> input ( 'node' ));
2021-11-07 00:47:16 +00:00
$server = $request -> user () -> servers () -> create ([
'name' => $request -> input ( 'name' ),
'product_id' => $request -> input ( 'product' ),
]);
2021-11-06 00:56:57 +00:00
//get free allocation ID
$allocationId = Pterodactyl :: getFreeAllocationId ( $node );
if ( ! $allocationId ) return $this -> noAllocationsError ( $server );
//create server on pterodactyl
$response = Pterodactyl :: createServer ( $server , $egg , $allocationId );
if ( $response -> failed ()) return $this -> serverCreationFailed ( $response , $server );
//update server with pterodactyl_id
$server -> update ([
'pterodactyl_id' => $response -> json ()[ 'attributes' ][ 'id' ],
'identifier' => $response -> json ()[ 'attributes' ][ 'identifier' ]
]);
if ( Configuration :: getValueByKey ( 'SERVER_CREATE_CHARGE_FIRST_HOUR' , 'true' ) == 'true' ) {
2021-11-07 00:47:16 +00:00
if ( $request -> user () -> credits >= $server -> product -> getHourlyPrice ()) {
$request -> user () -> decrement ( 'credits' , $server -> product -> getHourlyPrice ());
2021-11-06 00:56:57 +00:00
}
2021-06-06 18:17:52 +00:00
}
2021-06-30 21:53:28 +00:00
2021-11-07 16:58:01 +00:00
return redirect () -> route ( 'servers.index' ) -> with ( 'success' , 'Server created' );
2021-11-06 00:56:57 +00:00
}
2021-06-30 21:53:28 +00:00
/**
* return redirect with error
* @ param Server $server
* @ return RedirectResponse
*/
private function noAllocationsError ( Server $server )
{
$server -> delete ();
Auth :: user () -> notify ( new ServerCreationError ( $server ));
2021-11-07 16:58:01 +00:00
return redirect () -> route ( 'servers.index' ) -> with ( 'error' , 'No allocations satisfying the requirements for automatic deployment on this node were found.' );
2021-06-30 21:53:28 +00:00
}
/**
* return redirect with error
* @ param Response $response
* @ param Server $server
* @ return RedirectResponse
*/
2021-10-01 21:21:49 +00:00
private function serverCreationFailed ( Response $response , Server $server )
2021-06-30 21:53:28 +00:00
{
$server -> delete ();
return redirect () -> route ( 'servers.index' ) -> with ( 'error' , json_encode ( $response -> json ()));
}
2021-11-06 00:56:57 +00:00
/** Remove the specified resource from storage. */
public function destroy ( Server $server )
{
try {
$server -> delete ();
2021-11-07 16:58:01 +00:00
return redirect () -> route ( 'servers.index' ) -> with ( 'success' , 'Server removed' );
2021-11-06 00:56:57 +00:00
} catch ( Exception $e ) {
return redirect () -> route ( 'servers.index' ) -> with ( 'error' , 'An exception has occurred while trying to remove a resource "' . $e -> getMessage () . '"' );
}
}
2021-06-05 09:26:32 +00:00
}