@@ -103,7 +103,7 @@ public function create(array $data)
103103 'startup ' => 'string ' ,
104104 'auto_deploy ' => 'sometimes|required|accepted ' ,
105105 'custom_id ' => 'sometimes|required|numeric|unique:servers,id ' ,
106- 'skip_scripting ' => 'sometimes|required|boolean ' ,
106+ 'skip_scripts ' => 'sometimes|required|boolean ' ,
107107 ]);
108108
109109 $ validator ->sometimes ('node_id ' , 'required|numeric|min:1|exists:nodes,id ' , function ($ input ) {
@@ -250,14 +250,15 @@ public function create(array $data)
250250 'node_id ' => $ node ->id ,
251251 'name ' => $ data ['name ' ],
252252 'description ' => $ data ['description ' ],
253- 'suspended ' => 0 ,
253+ 'skip_scripts ' => isset ($ data ['skip_scripts ' ]),
254+ 'suspended ' => false ,
254255 'owner_id ' => $ user ->id ,
255256 'memory ' => $ data ['memory ' ],
256257 'swap ' => $ data ['swap ' ],
257258 'disk ' => $ data ['disk ' ],
258259 'io ' => $ data ['io ' ],
259260 'cpu ' => $ data ['cpu ' ],
260- 'oom_disabled ' => ( isset ($ data ['oom_disabled ' ])) ? true : false ,
261+ 'oom_disabled ' => isset ($ data ['oom_disabled ' ]),
261262 'allocation_id ' => $ allocation ->id ,
262263 'service_id ' => $ data ['service_id ' ],
263264 'option_id ' => $ data ['option_id ' ],
@@ -327,7 +328,7 @@ public function create(array $data)
327328 'type ' => $ service ->folder ,
328329 'option ' => $ option ->tag ,
329330 'pack ' => (isset ($ pack )) ? $ pack ->uuid : null ,
330- 'skip_scripting ' => isset ( $ data [ ' skip_scripting ' ]) ,
331+ 'skip_scripts ' => $ server -> skip_scripts ,
331332 ],
332333 'keys ' => [
333334 (string ) $ server ->daemonSecret => $ this ->daemonPermissions ,
@@ -621,13 +622,93 @@ public function changeBuild($id, array $data)
621622 }
622623 }
623624
625+ /**
626+ * Update the service configuration for a server.
627+ *
628+ * @param int $id
629+ * @param array $data
630+ * @return void
631+ *
632+ * @throws \GuzzleHttp\Exception\RequestException
633+ * @throws \Pterodactyl\Exceptions\DisplayException
634+ * @throws \Pterodactyl\Exceptions\DisplayValidationException
635+ */
636+ protected function changeService ($ id , array $ data )
637+ {
638+
639+ }
640+
641+ protected function processVariables (Models \Server $ server , $ data , $ admin = false )
642+ {
643+ $ server ->load ('option.variables ' );
644+
645+ if ($ admin ) {
646+ $ server ->startup = $ data ['startup ' ];
647+ $ server ->save ();
648+ }
649+
650+ if ($ server ->option ->variables ) {
651+ foreach ($ server ->option ->variables as &$ variable ) {
652+ $ set = isset ($ data ['env_ ' . $ variable ->id ]);
653+
654+ // If user is not an admin and are trying to edit a non-editable field
655+ // or an invisible field just silently skip the variable.
656+ if (! $ admin && (! $ variable ->user_editable || ! $ variable ->user_viewable )) {
657+ continue ;
658+ }
659+
660+ // Perform Field Validation
661+ $ validator = Validator::make ([
662+ 'variable_value ' => ($ set ) ? $ data ['env_ ' . $ variable ->id ] : null ,
663+ ], [
664+ 'variable_value ' => $ variable ->rules ,
665+ ]);
666+
667+ if ($ validator ->fails ()) {
668+ throw new DisplayValidationException (json_encode (
669+ collect ([
670+ 'notice ' => ['There was a validation error with the ` ' . $ variable ->name . '` variable. ' ],
671+ ])->merge ($ validator ->errors ()->toArray ())
672+ ));
673+ }
674+
675+ $ svar = Models \ServerVariable::firstOrNew ([
676+ 'server_id ' => $ server ->id ,
677+ 'variable_id ' => $ variable ->id ,
678+ ]);
679+
680+ // Set the value; if one was not passed set it to the default value
681+ if ($ set ) {
682+ $ svar ->variable_value = $ data ['env_ ' . $ variable ->id ];
683+
684+ // Not passed, check if this record exists if so keep value, otherwise set default
685+ } else {
686+ $ svar ->variable_value = ($ svar ->exists ) ? $ svar ->variable_value : $ variable ->default_value ;
687+ }
688+
689+ $ svar ->save ();
690+ }
691+ }
692+
693+ // Reload Variables
694+ $ server ->load ('variables ' );
695+ return $ server ->option ->variables ->map (function ($ item , $ key ) use ($ server ) {
696+ $ display = $ server ->variables ->where ('variable_id ' , $ item ->id )->pluck ('variable_value ' )->first ();
697+
698+ return [
699+ 'variable ' => $ item ->env_variable ,
700+ 'value ' => (! is_null ($ display )) ? $ display : $ item ->default_value ,
701+ ];
702+ });
703+ }
704+
624705 /**
625706 * Update the startup details for a server.
626707 *
627708 * @param int $id
628709 * @param array $data
629710 * @param bool $admin
630- * @return void
711+ * @return bool
631712 *
632713 * @throws \GuzzleHttp\Exception\RequestException
633714 * @throws \Pterodactyl\Exceptions\DisplayException
@@ -636,78 +717,110 @@ public function changeBuild($id, array $data)
636717 public function updateStartup ($ id , array $ data , $ admin = false )
637718 {
638719 $ server = Models \Server::with ('variables ' , 'option.variables ' )->findOrFail ($ id );
720+ $ hasServiceChanges = false ;
721+
722+ if ($ admin ) {
723+ // User is an admin, lots of things to do here.
724+ $ validator = Validator::make ($ data , [
725+ 'startup ' => 'required|string ' ,
726+ 'skip_scripts ' => 'sometimes|required|boolean ' ,
727+ 'service_id ' => 'required|numeric|min:1|exists:services,id ' ,
728+ 'option_id ' => 'required|numeric|min:1|exists:service_options,id ' ,
729+ 'pack_id ' => 'sometimes|nullable|numeric|min:0 ' ,
730+ ]);
639731
640- DB ::transaction (function () use ($ admin , $ data , $ server ) {
641- if (isset ($ data ['startup ' ]) && $ admin ) {
642- $ server ->startup = $ data ['startup ' ];
643- $ server ->save ();
732+ if ((int ) $ data ['pack_id ' ] < 1 ) {
733+ $ data ['pack_id ' ] = null ;
644734 }
645735
646- if ($ server ->option ->variables ) {
647- foreach ($ server ->option ->variables as &$ variable ) {
648- $ set = isset ($ data ['env_ ' . $ variable ->id ]);
649-
650- // If user is not an admin and are trying to edit a non-editable field
651- // or an invisible field just silently skip the variable.
652- if (! $ admin && (! $ variable ->user_editable || ! $ variable ->user_viewable )) {
653- continue ;
654- }
736+ if ($ validator ->fails ()) {
737+ throw new DisplayValidationException (json_encode ($ validator ->errors ()));
738+ }
655739
656- // Perform Field Validation
657- $ validator = Validator::make ([
658- 'variable_value ' => ($ set ) ? $ data ['env_ ' . $ variable ->id ] : null ,
659- ], [
660- 'variable_value ' => $ variable ->rules ,
661- ]);
740+ if (
741+ $ server ->service_id != $ data ['service_id ' ] ||
742+ $ server ->option_id != $ data ['option_id ' ] ||
743+ $ server ->pack_id != $ data ['pack_id ' ]
744+ ) {
745+ $ hasServiceChanges = true ;
746+ }
747+ }
662748
663- if ($ validator ->fails ()) {
664- throw new DisplayValidationException (json_encode (
665- collect ([
666- 'notice ' => ['There was a validation error with the ` ' . $ variable ->name . '` variable. ' ],
667- ])->merge ($ validator ->errors ()->toArray ())
668- ));
669- }
749+ // If user isn't an administrator, this function is being access from the front-end
750+ // Just try to update specific variables.
751+ if (! $ admin || ! $ hasServiceChanges ) {
752+ return DB ::transaction (function () use ($ admin , $ data , $ server ) {
753+ $ environment = $ this ->processVariables ($ server , $ data , $ admin );
670754
671- $ svar = Models \ServerVariable::firstOrNew ([
672- 'server_id ' => $ server ->id ,
673- 'variable_id ' => $ variable ->id ,
674- ]);
755+ $ server ->node ->guzzleClient ([
756+ 'X-Access-Server ' => $ server ->uuid ,
757+ 'X-Access-Token ' => $ server ->node ->daemonSecret ,
758+ ])->request ('PATCH ' , '/server ' , [
759+ 'json ' => [
760+ 'build ' => [
761+ 'env|overwrite ' => $ environment ->pluck ('value ' , 'variable ' )->merge (['STARTUP ' => $ server ->startup ])->toArray (),
762+ ],
763+ ],
764+ ]);
675765
676- // Set the value; if one was not passed set it to the default value
677- if ( $ set ) {
678- $ svar -> variable_value = $ data [ ' env_ ' . $ variable -> id ];
766+ return false ;
767+ });
768+ }
679769
680- // Not passed, check if this record exists if so keep value, otherwise set default
681- } else {
682- $ svar ->variable_value = ($ svar ->exists ) ? $ svar ->variable_value : $ variable ->default_value ;
683- }
770+ // Validate those Service Option Variables
771+ // We know the service and option exists because of the validation.
772+ // We need to verify that the option exists for the service, and then check for
773+ // any required variable fields. (fields are labeled env_<env_variable>)
774+ $ option = Models \ServiceOption::where ('id ' , $ data ['option_id ' ])->where ('service_id ' , $ data ['service_id ' ])->first ();
775+ if (! $ option ) {
776+ throw new DisplayException ('The requested service option does not exist for the specified service. ' );
777+ }
684778
685- $ svar ->save ();
686- }
779+ // Validate the Pack
780+ if (! isset ($ data ['pack_id ' ]) || (int ) $ data ['pack_id ' ] < 1 ) {
781+ $ data ['pack_id ' ] = null ;
782+ } else {
783+ $ pack = Models \Pack::where ('id ' , $ data ['pack_id ' ])->where ('option_id ' , $ data ['option_id ' ])->first ();
784+ if (! $ pack ) {
785+ throw new DisplayException ('The requested service pack does not seem to exist for this combination. ' );
687786 }
787+ }
688788
689- // Reload Variables
690- $ server ->load ('variables ' );
691- $ environment = $ server ->option ->variables ->map (function ($ item , $ key ) use ($ server ) {
692- $ display = $ server ->variables ->where ('variable_id ' , $ item ->id )->pluck ('variable_value ' )->first ();
789+ return DB ::transaction (function () use ($ admin , $ data , $ server ) {
790+ $ server ->installed = 0 ;
791+ $ server ->service_id = $ data ['service_id ' ];
792+ $ server ->option_id = $ data ['option_id ' ];
793+ $ server ->pack_id = $ data ['pack_id ' ];
794+ $ server ->skip_scripts = isset ($ data ['skip_scripts ' ]);
795+ $ server ->save ();
693796
694- return [
695- 'variable ' => $ item ->env_variable ,
696- 'value ' => (! is_null ($ display )) ? $ display : $ item ->default_value ,
697- ];
698- });
797+ $ server ->variables ->each ->delete ();
798+
799+ $ server ->load ('service ' , 'pack ' );
800+
801+ // Send New Environment
802+ $ environment = $ this ->processVariables ($ server , $ data , $ admin );
699803
700804 $ server ->node ->guzzleClient ([
701805 'X-Access-Server ' => $ server ->uuid ,
702806 'X-Access-Token ' => $ server ->node ->daemonSecret ,
703- ])->request ('PATCH ' , '/server ' , [
807+ ])->request ('POST ' , '/server/reinstall ' , [
704808 'json ' => [
705809 'build ' => [
706- 'env|overwrite ' => $ environment ->pluck ('value ' , 'variable ' )->merge (['STARTUP ' => $ server ->startup ]),
810+ 'env|overwrite ' => $ environment ->pluck ('value ' , 'variable ' )->merge (['STARTUP ' => $ server ->startup ])->toArray (),
811+ ],
812+ 'service ' => [
813+ 'type ' => $ server ->option ->service ->folder ,
814+ 'option ' => $ server ->option ->tag ,
815+ 'pack ' => (! is_null ($ server ->pack_id )) ? $ server ->pack ->uuid : null ,
816+ 'skip_scripts ' => $ server ->skip_scripts ,
707817 ],
708818 ],
709819 ]);
820+
821+ return true ;
710822 });
823+
711824 }
712825
713826 /**
0 commit comments