Skip to content
This repository was archived by the owner on Apr 26, 2025. It is now read-only.

Commit 1ed7416

Browse files
committed
prod: v1.0.0
Auto suspend & admin panel will be delayed.
1 parent 6d3c1fa commit 1ed7416

File tree

8 files changed

+545
-350
lines changed

8 files changed

+545
-350
lines changed

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,7 @@ WEBHOOK_LOGIN=https://discord.com/api/webhooks/0000000000000000000/cReAtEaChAnNe
7171
WEBHOOK_REGISTER=https://discord.com/api/webhooks/0000000000000000000/cReAtEaChAnNeLaNdAwEbHoOk
7272
WEBHOOK_COINS=https://discord.com/api/webhooks/0000000000000000000/cReAtEaChAnNeLaNdAwEbHoOk
7373
WEBHOOK_RESOURCE=https://discord.com/api/webhooks/0000000000000000000/cReAtEaChAnNeLaNdAwEbHoOk
74+
WEBHOOK_EXCEPTION=https://discord.com/api/webhooks/0000000000000000000/cReAtEaChAnNeLaNdAwEbHoOk
75+
WEBHOOK_SERVER=https://discord.com/api/webhooks/0000000000000000000/cReAtEaChAnNeLaNdAwEbHoOk
7476

7577
PROXY_HTTPS=false

README.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,19 @@
11
# SHDactyl
2-
A Laravel based client area for Pterodactyl.
2+
3+
A Laravel based client area for Pterodactyl.
4+
5+
# Requirements
6+
7+
Composer、PHP 8.1、Node.js、NPM、Nginx
8+
9+
# Installation
10+
11+
1. Download the source code.
12+
2. Unarchive it.
13+
3. Configure `.env` and `config/shdactyl.php`.
14+
4. Run `composer install --no-dev --optimize-autoloader`.
15+
5. Run `npm install`.
16+
6. Run `npm run dev`.
17+
7. Run `npm run build`.
18+
8. Run `php artisan key:generate`.
19+
9. Configure your webserver.

app/Http/Controllers/Auth/SocialController.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,46 @@ public function handleDiscordCallback(): RedirectResponse
3636
$bypass = Bypass::where('discord_id', $user->id)->first();
3737
if ($bypass) {
3838
if ($dataProxy['proxy'] == true && $bypass->bypass == false) {
39+
DiscordAlert::to('exception')->message("", [
40+
[
41+
'title' => '[代理阻擋]',
42+
'description' => '帳號:<@' . $user->id . '> (' . $user->id . ')\n' .
43+
'電子郵件:' . $user->email .
44+
'\nIP 紀錄:' . Request::ip(),
45+
'color' => '#03cafc',
46+
'footer' => [
47+
'icon_url' => config('shdactyl.webhook.icon_url'),
48+
'text' => 'SHDactyl',
49+
],
50+
'timestamp' => Carbon::now(),
51+
'author' => [
52+
'name' => $user->name,
53+
'icon_url' => $user->avatar,
54+
],
55+
]
56+
]);
3957
throw new ProxyException();
4058
}
4159
} else {
4260
if ($dataProxy['proxy'] == true) {
61+
DiscordAlert::to('exception')->message("", [
62+
[
63+
'title' => '[代理阻擋]',
64+
'description' => '帳號:<@' . $user->id . '> (' . $user->id . ')\n' .
65+
'電子郵件:' . $user->email .
66+
'\nIP 紀錄:' . Request::ip(),
67+
'color' => '#03cafc',
68+
'footer' => [
69+
'icon_url' => config('shdactyl.webhook.icon_url'),
70+
'text' => 'SHDactyl',
71+
],
72+
'timestamp' => Carbon::now(),
73+
'author' => [
74+
'name' => $user->name,
75+
'icon_url' => $user->avatar,
76+
],
77+
]
78+
]);
4379
throw new ProxyException();
4480
}
4581
}
@@ -50,6 +86,24 @@ public function handleDiscordCallback(): RedirectResponse
5086
->where('user_id', '!=', $existingUser->id)
5187
->first();
5288
if ($duplicateIps) {
89+
DiscordAlert::to('exception')->message("", [
90+
[
91+
'title' => '[多帳阻擋]',
92+
'description' => '帳號:<@' . $existingUser->discord_id . '> (' . $existingUser->discord_id . ')\n' .
93+
'電子郵件:' . $existingUser->email .
94+
'\nIP 紀錄:' . Request::ip(),
95+
'color' => '#03cafc',
96+
'footer' => [
97+
'icon_url' => config('shdactyl.webhook.icon_url'),
98+
'text' => 'SHDactyl',
99+
],
100+
'timestamp' => Carbon::now(),
101+
'author' => [
102+
'name' => $existingUser->name,
103+
'icon_url' => $existingUser->avatar,
104+
],
105+
]
106+
]);
53107
throw new AltException();
54108
}
55109
auth()->login($existingUser, true);
@@ -86,6 +140,24 @@ public function handleDiscordCallback(): RedirectResponse
86140
} else {
87141
$duplicateIps = IpRecords::where('ip', Request::ip())->first();
88142
if ($duplicateIps) {
143+
DiscordAlert::to('exception')->message("", [
144+
[
145+
'title' => '[多帳阻擋]',
146+
'description' => '帳號:<@' . $existingUser->discord_id . '> (' . $existingUser->discord_id . ')\n' .
147+
'電子郵件:' . $existingUser->email .
148+
'\nIP 紀錄:' . Request::ip(),
149+
'color' => '#03cafc',
150+
'footer' => [
151+
'icon_url' => config('shdactyl.webhook.icon_url'),
152+
'text' => 'SHDactyl',
153+
],
154+
'timestamp' => Carbon::now(),
155+
'author' => [
156+
'name' => $existingUser->name,
157+
'icon_url' => $existingUser->avatar,
158+
],
159+
]
160+
]);
89161
throw new AltException();
90162
}
91163
$password = Str::random();

app/Http/Controllers/Dashboard/DashboardController.php

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,11 @@ public function serverCreationPage()
4545
$auth = config('shdactyl.pterodactyl.api_key');
4646
$nodes = config('shdactyl.nodes');
4747
$eggs = Config::get('shdactyl.eggs');
48+
$fee = Config::get('shdactyl.fee');
4849
return Inertia::render('Server/Create', [
4950
'nodes' => $nodes,
50-
'eggs' => $eggs
51+
'eggs' => $eggs,
52+
'fee' => $fee,
5153
]);
5254
}
5355
public function resourceStorePage()
@@ -352,6 +354,11 @@ public function serverCreation(Request $request)
352354
if ($total['servers'] + 1 > $user->servers) {
353355
return redirect('/dashboard/server/create')->with('error', '你沒有那麼多 Servers 資源來創建這個伺服器');
354356
}
357+
$price = config('shdactyl.fee.create') * config('shdactyl.fee.node.' . $data['node']) * ((config('shdactyl.fee.resource.cpu') * $data['cpu']) + (config('shdactyl.fee.resource.ram') * $data['ram']) + (config('shdactyl.fee.resource.disk') * $data['disk']) + (config('shdactyl.fee.resource.databases') * $data['databases']) + (config('shdactyl.fee.resource.backups') * $data['backups']) + (config('shdactyl.fee.resource.ports') * $data['ports']));
358+
if ($user->coins < $price) {
359+
return redirect('/dashboard/server/create')->with('error', '你沒有足夠的代幣來創建伺服器');
360+
}
361+
$user->decrement('coins', $price);
355362
$category = $this->getCategoryById($data['egg']);
356363
$url = config('shdactyl.pterodactyl.url');
357364
$auth = config('shdactyl.pterodactyl.api_key');
@@ -387,7 +394,26 @@ public function serverCreation(Request $request)
387394
],
388395
]);
389396
if ($res->created() === true) {
390-
return redirect('/dashboard/server/create')->with('success', '成功創建伺服器!');
397+
398+
$serverData = json_decode($res, true);
399+
DiscordAlert::to('server')->message("", [
400+
[
401+
'title' => '[創建伺服器]',
402+
'description' => '帳號:<@' . $user->discord_id . '> (' . $user->discord_id . ')\n' .
403+
'伺服器識別碼:' . $serverData['attributes']['identifier'] . '\n伺服器名稱:' . $serverData['attributes']['name'] . '\n節點識別碼:' . $serverData['attributes']['node'] . '\n處理器:' . $serverData['attributes']['limits']['cpu'] . '%\n記憶體:' . $serverData['attributes']['limits']['memory'] . ' MiB\n儲存空間:' . $serverData['attributes']['limits']['disk'] . ' MiB\n資料庫:' . $serverData['attributes']['feature_limits']['databases'] . ' 個\n額外端口:' . $serverData['attributes']['feature_limits']['allocations'] . ' 個\n備份欄位:' . $serverData['attributes']['feature_limits']['backups'] . '',
404+
'color' => '#03cafc',
405+
'footer' => [
406+
'icon_url' => config('shdactyl.webhook.icon_url'),
407+
'text' => 'SHDactyl',
408+
],
409+
'timestamp' => Carbon::now(),
410+
'author' => [
411+
'name' => $user->name,
412+
'icon_url' => $user->avatar,
413+
],
414+
]
415+
]);
416+
return redirect('/dashboard/server/create')->with('success', '成功花費 $ ' . number_format($price, 2) . ' SDC 創建伺服器!');
391417
} else {
392418
return redirect('/dashboard/server/create')->with('error', '創建伺服器時發生錯誤 ' . $res);
393419
}
@@ -421,15 +447,40 @@ public function unsuspendServer(Request $request)
421447
'Authorization' => $auth,
422448
])->get($url . '/api/application/servers/' . $data['id']);
423449
$resData = json_decode($res, true);
450+
if ($resData['attributes']['suspended'] === false) {
451+
return redirect('/dashboard/server/manage')->with('error', '該伺服器不需要續約');
452+
}
424453
if ($resData['attributes']['user'] === $user->panel_id) {
425454
$price = config('shdactyl.fee.unsuspend') * config('shdactyl.fee.node.' . $resData['attributes']['node']);
455+
if ($user->coins < $price) {
456+
return redirect('/dashboard/server/manage')->with('error', '你沒有足夠的代幣來續約伺服器');
457+
}
426458
$user->decrement('coins', $price);
427459
$user->save();
428460
$res = Http::withHeaders([
429461
'Accept' => 'application/json',
430462
'Authorization' => $auth,
431463
])->post($url . '/api/application/servers/' . $data['id'] . '/unsuspend');
432464
if ($res->successful() === true) {
465+
466+
$serverData = $resData;
467+
DiscordAlert::to('server')->message("", [
468+
[
469+
'title' => '[續約伺服器]',
470+
'description' => '帳號:<@' . $user->discord_id . '> (' . $user->discord_id . ')\n' .
471+
'伺服器識別碼:' . $serverData['attributes']['identifier'] . '\n伺服器名稱:' . $serverData['attributes']['name'] . '\n節點識別碼:' . $serverData['attributes']['node'],
472+
'color' => '#03cafc',
473+
'footer' => [
474+
'icon_url' => config('shdactyl.webhook.icon_url'),
475+
'text' => 'SHDactyl',
476+
],
477+
'timestamp' => Carbon::now(),
478+
'author' => [
479+
'name' => $user->name,
480+
'icon_url' => $user->avatar,
481+
],
482+
]
483+
]);
433484
return redirect('/dashboard/server/manage')->with('success', '成功花費 $ ' . number_format($price, 2) . ' SDC 續約伺服器');
434485
} else {
435486
return redirect('/dashboard/server/manage')->with('error', '續約伺服器時發生錯誤 ' . $res);
@@ -457,6 +508,24 @@ public function deleteServer(Request $request)
457508
'Authorization' => $auth,
458509
])->delete($url . '/api/application/servers/' . $data['id']);
459510
if ($res->successful() === true) {
511+
$serverData = $resData;
512+
DiscordAlert::to('server')->message("", [
513+
[
514+
'title' => '[刪除伺服器]',
515+
'description' => '帳號:<@' . $user->discord_id . '> (' . $user->discord_id . ')\n' .
516+
'伺服器識別碼:' . $serverData['attributes']['identifier'] . '\n伺服器名稱:' . $serverData['attributes']['name'] . '\n節點識別碼:' . $serverData['attributes']['node'],
517+
'color' => '#03cafc',
518+
'footer' => [
519+
'icon_url' => config('shdactyl.webhook.icon_url'),
520+
'text' => 'SHDactyl',
521+
],
522+
'timestamp' => Carbon::now(),
523+
'author' => [
524+
'name' => $user->name,
525+
'icon_url' => $user->avatar,
526+
],
527+
]
528+
]);
460529
return redirect('/dashboard/server/manage')->with('success', '成功刪除伺服器');
461530
} else {
462531
return redirect('/dashboard/server/manage')->with('error', '刪除伺服器時發生錯誤 ' . $res);
@@ -527,6 +596,24 @@ public function modifyServer(Request $request)
527596
],
528597
]);
529598
if ($response->successful() === true) {
599+
$serverData = $responseData;
600+
DiscordAlert::to('server')->message("", [
601+
[
602+
'title' => '[編輯伺服器]',
603+
'description' => '帳號:<@' . $user->discord_id . '> (' . $user->discord_id . ')\n' .
604+
'伺服器識別碼:' . $serverData['attributes']['identifier'] . '\n伺服器名稱:' . $serverData['attributes']['name'] . '\n節點識別碼:' . $serverData['attributes']['node'] . '\n處理器:' . $serverData['attributes']['limits']['cpu'] . '%\n記憶體:' . $serverData['attributes']['limits']['memory'] . ' MiB\n儲存空間:' . $serverData['attributes']['limits']['disk'] . ' MiB\n資料庫:' . $serverData['attributes']['feature_limits']['databases'] . ' 個\n額外端口:' . $serverData['attributes']['feature_limits']['allocations'] . ' 個\n備份欄位:' . $serverData['attributes']['feature_limits']['backups'] . '',
605+
'color' => '#03cafc',
606+
'footer' => [
607+
'icon_url' => config('shdactyl.webhook.icon_url'),
608+
'text' => 'SHDactyl',
609+
],
610+
'timestamp' => Carbon::now(),
611+
'author' => [
612+
'name' => $user->name,
613+
'icon_url' => $user->avatar,
614+
],
615+
]
616+
]);
530617
return redirect('/dashboard/server/manage')->with('success', '成功編輯伺服器');
531618
} else {
532619
return redirect('/dashboard/server/manage')->with('error', '編輯伺服器時發生錯誤 ' . $response);

config/discord-alerts.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
'register' => env('WEBHOOK_REGISTER'),
1010
'coins' => env('WEBHOOK_COINS'),
1111
'resource' => env('WEBHOOK_RESOURCE'),
12+
'exception' => env('WEBHOOK_EXCEPTION'),
13+
'server' => env('WEBHOOK_SERVER'),
1214
],
1315

1416
/*

config/shdactyl.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
'create' => 10,
2727
'unsuspend' => 10,
2828
'node' => [
29-
1 => 1.5,
29+
1 => 1,
3030
3 => 1,
3131
5 => 1,
3232
],

0 commit comments

Comments
 (0)