Plugins: a dedicated server's plugins see the skaters

reskate.session.skaters() returned an empty list on a dedicated server: its game for plugins did
not say where anyone was, though the host holds every player's latest pose. A server copy now gets
each player in the world with a pose: their id, the pose's root position, its heading (read as a
client reads it) and how long ago it arrived. A server plugin can now follow players itself, for
a race's checkpoints or a game of tag, instead of trusting what each player's copy reports.

Host::skater_poses() lists them for the plugins. dingosdk_server_plugin_tests drives the host with
simulated players sending poses and checks what a server plugin sees, and that a plugin without
session.skaters is still refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hs7xxJDf6SDcQUaXnzmtL5
This commit is contained in:
Robin MoellerandClaude Opus 5.5 committed 2026-10-22 20:30:07 +02:00
1 parent 45346b122c
commit 45d4c64c75
5 files changed
+335

No files matched your search

+13
View File
@@ -6,6 +6,7 @@
#include <algorithm>
#include <chrono>
#include <cmath>
#include <format>
#include <map>
@@ -79,6 +80,18 @@ class ServerGame final : public Game {
host_.set_locks(player, locks, "plugin " + std::string(plugin));
return {};
}
// The skaters of the players in the world, as their latest poses put them. The server has
// no skater of its own, so this is every player's.
std::vector<PeerSkater> peer_skaters() override {
std::vector<PeerSkater> result;
for (const auto &s : host_.skater_poses()) {
const auto &q = s.root.rotation;
// The rotation's +Z about world up, as a client's plugin_game_runtime.cpp reads it.
const float heading = std::atan2(2 * (q[0] * q[2] + q[3] * q[1]), 1 - 2 * (q[0] * q[0] + q[1] * q[1]));
result.push_back({s.id, s.root.position, heading, static_cast<double>(s.age_us) / 1000.0});
}
return result;
}
// Through the console's own ban and unban, so they keep its checks and save the bans file.
std::string ban(std::uint64_t player) override {
const auto answer = host_.command("ban " + std::to_string(player));