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

Commit ffcf9dd

Browse files
committed
feat: coins api
1. Updated some APIs. 2. Added leaderboard and coins API.
1 parent fe53676 commit ffcf9dd

File tree

7 files changed

+180
-44
lines changed

7 files changed

+180
-44
lines changed

app/Http/Controllers/Api/UserApiController.php

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public function modifyUser(Request $request, $id)
3737
'password' => 'min:8',
3838
'panel_id' => 'numeric|integer',
3939
'discord_id' => 'numeric|integer',
40-
'coins' => 'numeric|integer',
40+
'coins' => 'numeric|decimal:0,2',
4141
'cpu' => 'numeric|integer',
4242
'ram' => 'numeric|integer',
4343
'disk' => 'numeric|integer',
@@ -135,4 +135,126 @@ public function toggleBypass($id)
135135
$bypass->save();
136136
return response($bypass);
137137
}
138+
public function leaderboard(Request $request)
139+
{
140+
if ($request->query('count') && $request->query('count') > 0) {
141+
$users = User::orderBy('coins', 'desc')->limit($request->query('count'))->select('id', 'name', 'discord_id', 'coins')->get();
142+
} else {
143+
$users = User::orderBy('coins', 'desc')->limit(10)->select('id', 'name', 'discord_id', 'coins')->get();
144+
}
145+
return response($users);
146+
}
147+
public function externalUserDetails($id)
148+
{
149+
$user = User::where('discord_id', $id)->first();
150+
if (!$user) {
151+
return response()->json(['message' => 'User not found.'], 404);
152+
}
153+
return response($user);
154+
}
155+
public function modifyExternalUser(Request $request, $id)
156+
{
157+
$request->validate([
158+
'name' => 'min:3|max:50',
159+
'email' => 'email',
160+
'password' => 'min:8',
161+
'panel_id' => 'numeric|integer',
162+
'discord_id' => 'numeric|integer',
163+
'coins' => 'numeric|decimal:0,2',
164+
'cpu' => 'numeric|integer',
165+
'ram' => 'numeric|integer',
166+
'disk' => 'numeric|integer',
167+
'databases' => 'numeric|integer',
168+
'backups' => 'numeric|integer',
169+
'ports' => 'numeric|integer',
170+
'servers' => 'numeric|integer',
171+
'bypass' => 'boolean',
172+
]);
173+
$user = User::where('discord_id', $id)->first();
174+
if (!$user) {
175+
return response()->json(['message' => 'User not found.'], 404);
176+
}
177+
if ($request->name) {
178+
$user->name = $request->name;
179+
}
180+
if ($request->email) {
181+
$user->email = $request->email;
182+
}
183+
if ($request->password) {
184+
$user->password = bcrypt($request->password);
185+
}
186+
if ($request->panel_id) {
187+
$user->panel_id = $request->panel_id;
188+
}
189+
if ($request->discord_id) {
190+
$user->discord_id = $request->discord_id;
191+
}
192+
if ($request->coins) {
193+
$user->coins = $request->coins;
194+
}
195+
if ($request->cpu) {
196+
$user->cpu = $request->cpu;
197+
}
198+
if ($request->ram) {
199+
$user->ram = $request->ram;
200+
}
201+
if ($request->disk) {
202+
$user->disk = $request->disk;
203+
}
204+
if ($request->databases) {
205+
$user->databases = $request->databases;
206+
}
207+
if ($request->backups) {
208+
$user->backups = $request->backups;
209+
}
210+
if ($request->ports) {
211+
$user->ports = $request->ports;
212+
}
213+
if ($request->servers) {
214+
$user->servers = $request->servers;
215+
}
216+
if ($request->bypass) {
217+
$user->bypass = $request->bypass;
218+
}
219+
$user->save();
220+
221+
return response($user);
222+
}
223+
public function deleteExternalUser($id)
224+
{
225+
$user = User::where('discord_id', $id)->first();
226+
if (!$user) {
227+
return response()->json(['message' => 'User not found.'], 404);
228+
}
229+
ActionLog::where('user_id', $user->id)->delete();
230+
IpRecords::where('user_id', $user->id)->delete();
231+
$user->delete();
232+
return response()->json(['message' => 'User deleted.']);
233+
}
234+
public function addExternalUserCoins(Request $request, $id)
235+
{
236+
$request->validate([
237+
'coins' => 'required|numeric|decimal:0,2',
238+
]);
239+
$user = User::where('discord_id', $id)->first();
240+
if (!$user) {
241+
return response()->json(['message' => 'User not found.'], 404);
242+
}
243+
$user->coins = $user->coins + $request->coins;
244+
$user->save();
245+
return response($user);
246+
}
247+
public function setExternalUserCoins(Request $request, $id)
248+
{
249+
$request->validate([
250+
'coins' => 'required|numeric|decimal:0,2',
251+
]);
252+
$user = User::where('discord_id', $id)->first();
253+
if (!$user) {
254+
return response()->json(['message' => 'User not found.'], 404);
255+
}
256+
$user->coins = $request->coins;
257+
$user->save();
258+
return response($user);
259+
}
138260
}

app/Http/Controllers/Auth/SocialController.php

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -35,48 +35,52 @@ public function handleDiscordCallback(): RedirectResponse
3535
$dataProxy = json_decode($resProxy, true);
3636
$bypass = Bypass::where('discord_id', $user->id)->first();
3737
if ($bypass) {
38-
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-
]);
57-
throw new ProxyException();
38+
if (isset($dataProxy['proxy'])) {
39+
if ($dataProxy['proxy'] == true && $bypass->bypass == false) {
40+
DiscordAlert::to('exception')->message("", [
41+
[
42+
'title' => '[代理阻擋]',
43+
'description' => '帳號:<@' . $user->id . '> (' . $user->id . ')\n' .
44+
'電子郵件:' . $user->email .
45+
'\nIP 紀錄:' . Request::ip(),
46+
'color' => '#03cafc',
47+
'footer' => [
48+
'icon_url' => config('shdactyl.webhook.icon_url'),
49+
'text' => 'SHDactyl',
50+
],
51+
'timestamp' => Carbon::now(),
52+
'author' => [
53+
'name' => $user->name,
54+
'icon_url' => $user->avatar,
55+
],
56+
]
57+
]);
58+
throw new ProxyException();
59+
}
5860
}
5961
} else {
60-
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-
]);
79-
throw new ProxyException();
62+
if (isset($dataProxy['proxy'])) {
63+
if ($dataProxy['proxy'] == true) {
64+
DiscordAlert::to('exception')->message("", [
65+
[
66+
'title' => '[代理阻擋]',
67+
'description' => '帳號:<@' . $user->id . '> (' . $user->id . ')\n' .
68+
'電子郵件:' . $user->email .
69+
'\nIP 紀錄:' . Request::ip(),
70+
'color' => '#03cafc',
71+
'footer' => [
72+
'icon_url' => config('shdactyl.webhook.icon_url'),
73+
'text' => 'SHDactyl',
74+
],
75+
'timestamp' => Carbon::now(),
76+
'author' => [
77+
'name' => $user->name,
78+
'icon_url' => $user->avatar,
79+
],
80+
]
81+
]);
82+
throw new ProxyException();
83+
}
8084
}
8185
}
8286
$existingUser = User::where('discord_id', $user->id)->first();

app/Http/Middleware/HandleInertiaRequests.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public function share(Request $request): array
4444
'info' => fn() => $request->session()->get('info'),
4545
'question' => fn() => $request->session()->get('question')
4646
],
47+
'announcement' => config('shdactyl.announcement'),
4748
]);
48-
}
49+
}
4950
}

config/shdactyl.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
'ports' => 0,
1919
'servers' => 2,
2020
],
21+
'announcement' => 'hi',
2122
'nodes' => [
2223
'Node-TW01' => 1,
2324
'Node-TW02' => 3,

resources/js/Layouts/AppLayout.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { Team } from '@/types';
1414
import { ThemeSwitcher } from '@/Components/ThemeSwitcher';
1515
import Swal from 'sweetalert2';
1616
import { Tooltip } from '@nextui-org/react';
17+
1718
interface Props {
1819
title: string;
1920
renderHeader?(): JSX.Element;
@@ -53,6 +54,7 @@ export default function AppLayout({
5354
warning?: string;
5455
info?: string;
5556
question?: string;
57+
announcement?: string;
5658
};
5759
}
5860

resources/js/Pages/Dashboard.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import { router } from '@inertiajs/react';
2626
import Swal from 'sweetalert2';
2727
import { usePage } from '@inertiajs/react';
2828
import { useState } from 'react';
29-
3029
export default function Dashboard(props: any) {
3130
const modal1 = useDisclosure();
3231
const modal2 = useDisclosure();

routes/api.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,21 @@
1919
return $request->user();
2020
});
2121
Route::middleware('api')->group(function () {
22-
// Without API key
22+
// Public APIs
23+
Route::get('/application/users/public/leaderboard', [UserApiController::class, 'leaderboard']);
2324
});
2425

2526
Route::middleware('application_api')->group(function () {
27+
// Internal APIs
2628
Route::get('/application/users', [UserApiController::class, 'userList']);
2729
Route::get('/application/users/{id}', [UserApiController::class, 'userDetails']);
2830
Route::patch('/application/users/{id}', [UserApiController::class, 'modifyUser']);
2931
Route::delete('/application/users/{id}', [UserApiController::class, 'deleteUser']);
3032
Route::delete('/application/users/{id}/ip', [UserApiController::class, 'clearIpRecords']);
33+
Route::get('/application/users/external/{id}', [UserApiController::class, 'externalUserDetails']);
34+
Route::patch('/application/users/external/{id}', [UserApiController::class, 'modifyExternalUser']);
35+
Route::delete('/application/users/external/{id}', [UserApiController::class, 'deleteExternalUser']);
36+
Route::patch('/application/users/external/{id}/coins/add', [UserApiController::class, 'addExternalUserCoins']);
37+
Route::patch('/application/users/external/{id}/coins/set', [UserApiController::class, 'setExternalUserCoins']);
3138
Route::patch('/application/users/external/{id}/bypass', [UserApiController::class, 'toggleBypass']);
3239
});

0 commit comments

Comments
 (0)