Repository navigation
Fix player-counter plugin to support RakNet and newer NetherNet transport mode on Bedrock MC Servers #176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix player-counter plugin to support RakNet and newer NetherNet transport mode on Bedrock MC Servers #176
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |||||||||||||||||||||||||||||||||||||||||
| use App\Models\Server; | ||||||||||||||||||||||||||||||||||||||||||
| use Boy132\PlayerCounter\Extensions\Query\QueryTypeSchemaInterface; | ||||||||||||||||||||||||||||||||||||||||||
| use Exception; | ||||||||||||||||||||||||||||||||||||||||||
| use Illuminate\Support\Facades\Http; | ||||||||||||||||||||||||||||||||||||||||||
| use xPaw\MinecraftQuery; | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| class MinecraftBedrockQueryTypeSchema implements QueryTypeSchemaInterface | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -21,12 +22,56 @@ public function getName(): string | |||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /** @return ?array{hostname: string, map: string, current_players: int, max_players: int, players: ?array<array{id: string, name: string}>} */ | ||||||||||||||||||||||||||||||||||||||||||
| public function process(Server $server, string $ip, int $port): ?array | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| return $this->tryQueryNetherNet($ip, $port) ?? $this->tryQueryRakNet($ip, $port); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /** @return ?array{hostname: string, map: string, current_players: int, max_players: int, players: null} */ | ||||||||||||||||||||||||||||||||||||||||||
| private function tryQueryNetherNet(string $ip, int $port): ?array | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||
| $response = Http::acceptJson() | ||||||||||||||||||||||||||||||||||||||||||
| ->connectTimeout(2) | ||||||||||||||||||||||||||||||||||||||||||
| ->timeout(5) | ||||||||||||||||||||||||||||||||||||||||||
| ->get("http://{$ip}:{$port}/v1/join"); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!$response->successful()) { | ||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| $info = $response->json(); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if ( | ||||||||||||||||||||||||||||||||||||||||||
| !is_array($info) | ||||||||||||||||||||||||||||||||||||||||||
| || !isset( | ||||||||||||||||||||||||||||||||||||||||||
| $info['name'], | ||||||||||||||||||||||||||||||||||||||||||
| $info['level'], | ||||||||||||||||||||||||||||||||||||||||||
| $info['players'], | ||||||||||||||||||||||||||||||||||||||||||
| $info['maxPlayers'], | ||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+44
to
+51
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win 🔎 Supported by static analysis
Validate NetherNet field types before returning them.
🐛 Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return [ | ||||||||||||||||||||||||||||||||||||||||||
| 'hostname' => $info['name'], | ||||||||||||||||||||||||||||||||||||||||||
| 'map' => $info['level'], | ||||||||||||||||||||||||||||||||||||||||||
| 'current_players' => $info['players'], | ||||||||||||||||||||||||||||||||||||||||||
| 'max_players' => $info['maxPlayers'], | ||||||||||||||||||||||||||||||||||||||||||
| 'players' => null, // Bedrock has no player list | ||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||
| } catch (Exception) { | ||||||||||||||||||||||||||||||||||||||||||
| return null; // Either invalid or server may use RakNet | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| /** @return ?array{hostname: string, map: string, current_players: int, max_players: int, players: null} */ | ||||||||||||||||||||||||||||||||||||||||||
| private function tryQueryRakNet(string $ip, int $port): ?array | ||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||
| $query = new MinecraftQuery(); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||
| $query->ConnectBedrock($ip, $port, 5, true); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| $info = $query->GetInfo(); | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| if (!is_array($info)) { | ||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -42,8 +87,8 @@ public function process(Server $server, string $ip, int $port): ?array | |||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||
| } catch (Exception $exception) { | ||||||||||||||||||||||||||||||||||||||||||
| report($exception); | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||
| return null; | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: pelican/plugins
Length of output: 8267
🏁 Script executed:
Repository: pelican/plugins
Length of output: 41853
🌐 Web query:
official Laravel HTTP client documentation withoutRedirecting redirects followed by default PendingRequest💡 Result:
🌐 Web query:
official Guzzle documentation allow_redirects default true Laravel HTTP client follows redirects by default💡 Result:
Disable redirects for the NetherNet probe.
The Laravel HTTP client follows redirects by default. If the allocated server returns a redirect from
/v1/join, the client can send the probe to the redirect target instead of the allocated server. AddwithoutRedirecting()beforeget().🐛 Suggested fix
📝 Committable suggestion
🤖 Prompt for AI Agents