Instalando addons antigo na versão nova do pterodactyl.
Nesse artigo estarei mostrando como instalar addons antigos nas versões novas do pterodactyl.
Explicação breve sobre o que é um addon no painel pterodactyl.
O addon é uma modificação feita no painel para implementar novas funcionalidades, diferente de um plugin o addon modifica trechos do código, sua instalação e remoção não conta com uma interface agradável e não é nem um pouco facilitada, diferente do wordpress por exemplo, que os addons se adaptam as versões e a remoção/instalação é tão fácil quanto clicar num botão.
Para as pessoas que já instalaram addons sabem que a instalação é extremamente complicada e detalhada e requerer o máximo de atenção, para instalar uma versão incompatível a dificuldade acaba sendo bem maior.
O processo de instalação vai seguir o fluxo normal, copiar os arquivos e seguir o passo a passo.
Vamos no atentar aos seguintes arquivos.
Arquivos de rotas no back-end.
- /routes/api-client.php
- /routes/admin.php
Nas últimas atualizações do painel pterodactyl as rotas foram o que mais sofreram alterações, devemos nos atentar a seguinte sintaxe.

Antes uma rota era declarada da seguinte forma.
Route::get('/', 'Nodes\NodeController@index')->name('api.application.nodes');
Agora a sintaxe mudou.
Route::get('/', [Application\Nodes\NodeController::class, 'index'])->name('api.application.nodes');
Observe que o controller fica dentro de [], e não temos mais as aspas, o caminho da class agora tem ::class no final e antes a separação era por @ agora está com ','.
'Nodes\NodeController@index' mudou para [Application\Nodes\NodeController::class, 'index']
Devemos seguir o mesmo padrão utilizado, evitando assim o temido erro 500.
O próximo arquivo é a rota do front-end feito em react, esse arquivo teve uma importante atualização, nele agora temos as rotas separadas em outro arquivos.
- /resources/scripts/routers/ServerRouter.tsx
As rotas do fron-end foram movidas para 'routes.ts', e agora usa uma sintaxe de 'array'.
<Can action={'file.*'}> /* permissão da rota */
<NavLink to={`${match.url}/files`}>File Manager</NavLink> /* nome da rota */
</Can>
<Route path={`${match.path}/files`} exact> {/* caminho da rota */}
<RequireServerPermission permissions={'file.*'}>
<FileManagerContainer/> {/* class container da rota */}
</RequireServerPermission>
</Route>
Essas duas linhas do arquivo ServerRouter.tsx foram resumidos no arquivo routes.ts da seguinte forma.
{
route: 'files/*',
path: 'files', /* caminho da rota (agora não precisa mais do ${match.path}/) */
permission: 'file.*', /* permissão da rota */
name: 'Files', /* nome da rota */
component: FileManagerContainer, /* class container da rota */
}
Na prática:
Addon: subdomain manager v1.3
Arquivo: PanelEdit.txt
Em uma linha especifica ele pede para fazer a seguinte alterações.
/routes/admin.php
Please insert this codes to /routes/admin.php to the bottom of the file
/*
|--------------------------------------------------------------------------
| SubDomain Controller Routes
|--------------------------------------------------------------------------
|
| Endpoint: /admin/subdomain
|
*/
Route::group(['prefix' => 'subdomain'], function () {
Route::get('/', 'SubDomainController@index')->name('admin.subdomain');
Route::get('/new', 'SubDomainController@new')->name('admin.subdomain.new');
Route::get('/edit/{id}', 'SubDomainController@edit')->name('admin.subdomain.edit');
Route::post('/settings', 'SubDomainController@settings')->name('admin.subdomain.settings');
Route::post('/create', 'SubDomainController@create')->name('admin.subdomain.create');
Route::post('/update/{id}', 'SubDomainController@update')->name('admin.subdomain.update');
Route::delete('/delete', 'SubDomainController@delete')->name('admin.subdomain.delete');
});
Porém como vimos esse arquivo mudou, nesse caso precisaríamos fazer essa alterações de uma forma diferente, a sintaxe correta seria.
/*
|--------------------------------------------------------------------------
| SubDomain Controller Routes
|--------------------------------------------------------------------------
|
| Endpoint: /admin/subdomain
|
*/
Route::group(['prefix' => 'subdomain'], function () {
Route::get('/', [Admin\SubDomainController::class, 'index'])->name('admin.subdomain');
Route::get('/new', [Admin\SubDomainController::class, 'new'])->name('admin.subdomain.new');
Route::get('/edit/{id}', [Admin\SubDomainController::class, 'edit'])->name('admin.subdomain.edit');
Route::post('/settings', [Admin\SubDomainController::class, 'settings'])->name('admin.subdomain.settings');
Route::post('/create', [Admin\SubDomainController::class, 'create'])->name('admin.subdomain.create');
Route::post('/update/{id}', [Admin\SubDomainController::class, 'update'])->name('admin.subdomain.update');
Route::delete('/delete', [Admin\SubDomainController::class, 'delete'])->name('admin.subdomain.delete');
});
Em outra parte do mesmo arquivo ele pede para fazer a seguinte modificação.
/resources/scripts/routers/ServerRouter.tsx
Please paste this line to /resources/scripts/routers/ServerRouter.tsx under the import requireServerPermission from '@/hoc/requireServerPermission'; line
import SubdomainContainer from '@/components/server/subdomain/SubdomainContainer';
Please paste this lines to /resources/scripts/routers/ServerRouter.tsx to above the <Can action={[ 'settings.*', 'file.sftp' ]} matchAny> line
<Can action={'subdomain.*'}>
<NavLink to={`${match.url}/subdomain`}>Subdomain</NavLink>
</Can>
Please paste this line to /resources/scripts/routers/ServerRouter.tsx above the <Route path={'*'} component={NotFound}/> line
<Route path={`${match.path}/subdomain`} exact>
<RequireServerPermission permissions={'subdomain.*'}>
<SubdomainContainer />
</RequireServerPermission>
</Route>
Porém novamente a sintaxe mudou, para fazer a mesma implementação você precisará editar o arquivo /resources/scripts/routers/routes.ts ao invés do arquivo /resources/scripts/routers/ServerRouter.tsx.
Você terar que adicionar o import.
import SubdomainContainer from '@/components/server/subdomain/SubdomainContainer';
A baixo basta adicionar a seguinte linha depois de
component: ServerActivityLogContainer,
},
Você irá adicionar a seguinte linha.
{
path: '/subdomain',
permission: 'subdomain.*',
name: 'Subdomain',
component: SubdomainContainer,
},
Dicas:
Acompanhe sempre o github do pterodactyl para ficar atento as mudanças feitas no código.
O pterodactyl utiliza a framework laravel, você pode acessar a documentação oficial para entender melhor sobre como funciona essa estrutura.
Caso tenha alguma dúvida basta comentar a baixo desse poste.