55use Illuminate \Support \Arr ;
66use Illuminate \Support \Str ;
77use Pterodactyl \Models \Server ;
8- use Pterodactyl \Contracts \Repository \EggRepositoryInterface ;
98use Pterodactyl \Services \Servers \ServerConfigurationStructureService ;
109
1110class EggConfigurationService
1211{
13- private const NOT_MATCHED = '__no_match ' ;
14-
15- /**
16- * @var \Pterodactyl\Contracts\Repository\EggRepositoryInterface
17- */
18- private $ repository ;
19-
2012 /**
2113 * @var \Pterodactyl\Services\Servers\ServerConfigurationStructureService
2214 */
@@ -25,14 +17,10 @@ class EggConfigurationService
2517 /**
2618 * EggConfigurationService constructor.
2719 *
28- * @param \Pterodactyl\Contracts\Repository\EggRepositoryInterface $repository
2920 * @param \Pterodactyl\Services\Servers\ServerConfigurationStructureService $configurationStructureService
3021 */
31- public function __construct (
32- EggRepositoryInterface $ repository ,
33- ServerConfigurationStructureService $ configurationStructureService
34- ) {
35- $ this ->repository = $ repository ;
22+ public function __construct (ServerConfigurationStructureService $ configurationStructureService )
23+ {
3624 $ this ->configurationStructureService = $ configurationStructureService ;
3725 }
3826
@@ -41,8 +29,6 @@ public function __construct(
4129 *
4230 * @param \Pterodactyl\Models\Server $server
4331 * @return array
44- *
45- * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
4632 */
4733 public function handle (Server $ server ): array
4834 {
@@ -111,8 +97,6 @@ protected function convertStopToNewFormat(string $stop): array
11197 * @param \Pterodactyl\Models\Server $server
11298 * @param object $configs
11399 * @return array
114- *
115- * @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
116100 */
117101 protected function replacePlaceholders (Server $ server , object $ configs )
118102 {
@@ -130,6 +114,7 @@ protected function replacePlaceholders(Server $server, object $configs)
130114 foreach ($ configs as $ file => $ data ) {
131115 $ append = ['file ' => $ file , 'replace ' => []];
132116
117+ /** @noinspection PhpParameterByRefIsNotUsedAsReferenceInspection */
133118 // I like to think I understand PHP pretty well, but if you don't pass $value
134119 // by reference here, you'll end up with a resursive array loop if the config
135120 // file has two replacements that reference the same item in the configuration
@@ -167,71 +152,93 @@ protected function replacePlaceholders(Server $server, object $configs)
167152 }
168153
169154 /**
155+ * Replaces the legacy modifies from eggs with their new counterpart. The legacy Daemon would
156+ * set SERVER_MEMORY, SERVER_IP, and SERVER_PORT with their respective values on the Daemon
157+ * side. Ensure that anything referencing those properly replaces them with the matching config
158+ * value.
159+ *
160+ * @param string $key
170161 * @param string $value
171- * @param array $structure
172- * @return string|null
162+ * @return string
173163 */
174- protected function matchAndReplaceKeys (string $ value , array $ structure ): ? string
164+ protected function replaceLegacyModifiers (string $ key , string $ value ): string
175165 {
176- preg_match ('/{{(?<key>.*)}}/ ' , $ value , $ matches );
177-
178- if (! $ key = $ matches ['key ' ] ?? null ) {
179- return self ::NOT_MATCHED ;
180- }
181-
182- // Matched something in {{server.X}} format, now replace that with the actual
183- // value from the server properties.
184- //
185- // The Daemon supports server.X, env.X, and config.X placeholders.
186- if (! Str::startsWith ($ key , ['server. ' , 'env. ' , 'config. ' ])) {
187- return self ::NOT_MATCHED ;
188- }
189-
190- // The legacy Daemon would set SERVER_MEMORY, SERVER_IP, and SERVER_PORT with their
191- // respective values on the Daemon side. Ensure that anything referencing those properly
192- // replaces them with the matching config value.
193166 switch ($ key ) {
194167 case 'config.docker.interface ' :
195- $ key = 'config.docker.network.interface ' ;
168+ $ replace = 'config.docker.network.interface ' ;
196169 break ;
197170 case 'server.build.env.SERVER_MEMORY ' :
198171 case 'env.SERVER_MEMORY ' :
199- $ key = 'server.build.memory ' ;
172+ $ replace = 'server.build.memory ' ;
200173 break ;
201174 case 'server.build.env.SERVER_IP ' :
202175 case 'env.SERVER_IP ' :
203- $ key = 'server.build.default.ip ' ;
176+ $ replace = 'server.build.default.ip ' ;
204177 break ;
205178 case 'server.build.env.SERVER_PORT ' :
206179 case 'env.SERVER_PORT ' :
207- $ key = 'server.build.default.port ' ;
180+ $ replace = 'server.build.default.port ' ;
208181 break ;
182+ // By default we don't need to change anything, only if we ended up matching a specific legacy item.
183+ default :
184+ $ replace = $ key ;
209185 }
210186
211- // We don't want to do anything with config keys since the Daemon will need to handle
212- // that. For example, the Spigot egg uses "config.docker.interface" to identify the Docker
213- // interface to proxy through, but the Panel would be unaware of that.
214- if (Str::startsWith ($ key , 'config. ' )) {
215- return preg_replace ('/{{(.*)}}/ ' , "{{ {$ key }}} " , $ value );
216- }
187+ return str_replace ("{{ {$ key }}} " , "{{ {$ replace }}} " , $ value );
188+ }
217189
218- // Replace anything starting with "server." with the value out of the server configuration
219- // array that used to be created for the old daemon.
220- if (Str::startsWith ($ key , 'server. ' )) {
190+ /**
191+ * @param mixed $value
192+ * @param array $structure
193+ * @return mixed|null
194+ */
195+ protected function matchAndReplaceKeys ($ value , array $ structure )
196+ {
197+ preg_match_all ('/{{(?<key>[\w.-]*)}}/ ' , $ value , $ matches );
198+
199+ foreach ($ matches ['key ' ] as $ key ) {
200+ // Matched something in {{server.X}} format, now replace that with the actual
201+ // value from the server properties.
202+ //
203+ // The Daemon supports server.X, env.X, and config.X placeholders.
204+ if (! Str::startsWith ($ key , ['server. ' , 'env. ' , 'config. ' ])) {
205+ continue ;
206+ }
207+
208+ // Don't do a replacement on anything that is not a string, we don't want to unintentionally
209+ // modify the resulting output.
210+ if (! is_string ($ value )) {
211+ continue ;
212+ }
213+
214+ $ value = $ this ->replaceLegacyModifiers ($ key , $ value );
215+
216+ // We don't want to do anything with config keys since the Daemon will need to handle
217+ // that. For example, the Spigot egg uses "config.docker.interface" to identify the Docker
218+ // interface to proxy through, but the Panel would be unaware of that.
219+ if (Str::startsWith ($ key , 'config. ' )) {
220+ continue ;
221+ }
222+
223+ // Replace anything starting with "server." with the value out of the server configuration
224+ // array that used to be created for the old daemon.
225+ if (Str::startsWith ($ key , 'server. ' )) {
226+ $ plucked = Arr::get ($ structure , preg_replace ('/^server\./ ' , '' , $ key ), '' );
227+
228+ $ value = str_replace ("{{ {$ key }}} " , $ plucked , $ value );
229+ continue ;
230+ }
231+
232+ // Finally, replace anything starting with env. with the expected environment
233+ // variable from the server configuration.
221234 $ plucked = Arr::get (
222- $ structure , preg_replace ('/^server \./ ' , '' , $ key ), ''
235+ $ structure , preg_replace ('/^env \./ ' , 'build.env. ' , $ key ), ''
223236 );
224237
225- return preg_replace ( ' /{{(.*)}}/ ' , $ plucked , $ value );
238+ $ value = str_replace ( " {{ { $ key } }} " , $ plucked , $ value );
226239 }
227240
228- // Finally, replace anything starting with env. with the expected environment
229- // variable from the server configuration.
230- $ plucked = Arr::get (
231- $ structure , preg_replace ('/^env\./ ' , 'build.env. ' , $ key ), ''
232- );
233-
234- return preg_replace ('/{{(.*)}}/ ' , $ plucked , $ value );
241+ return $ value ;
235242 }
236243
237244 /**
@@ -255,12 +262,7 @@ private function iterate(&$data, array $structure)
255262 continue ;
256263 }
257264
258- $ response = $ this ->matchAndReplaceKeys ($ value , $ structure );
259- if ($ response === self ::NOT_MATCHED ) {
260- continue ;
261- }
262-
263- $ value = $ response ;
265+ $ value = $ this ->matchAndReplaceKeys ($ value , $ structure );
264266 }
265267 }
266268}
0 commit comments