mirror of
https://github.com/Dingo-Shenanigans/ReSkate.git
synced 2026-10-18 09:05:15 +02:00
Server browser - Official servers (the backend's "official_servers") sort first and are drawn in ReSkate blue - Servers Steam friends are skating in sort next, drawn in green with the friends' names; searching a friend's name finds their server - A player in a session they joined can join another server straight from the list; hosts still end their session first, and a Steam friend's join offer never replaces a session - Joining a dedicated server from the list records it as the player's public session, so friends see it and the row shows HERE - Blocked servers (the backend's "blocked_servers") are hidden and cannot be joined, by code either - When the backend sets "server_tokens_required", dedicated servers that signed in without a login token are hidden, except on the player's own network - A search that gets no internet list from Steam keeps the last list for two minutes, and waits six seconds before treating it as empty Roles - New Staff tag from the backend's "staff" list: green name, badge and item animation, ranked after Dev - Staff can pick a rainbow for their items on the Special page; it is sent as a solid colour older builds can show, so the protocol is unchanged Dedicated server - steam_token: sign in with a Steam game server login token and keep the same Steam ID every start; empty signs in anonymously as before - A listed server without a token says so at startup, and when the token rule starts or stops hiding it - Linux servers update themselves from the release's "server_linux" tarball, with the machine's curl and tar, pinned by SHA-256, and carry on in the same process Launcher - Only create the MiniDumpWriteDump API-set shim under Wine/Proton
90 lines
4.6 KiB
C++
90 lines
4.6 KiB
C++
#pragma once
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <string_view>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace dingosdk::multiplayer {
|
|
inline constexpr std::uint32_t skater_recipe_key = 2759515148U, board_recipe_key = 1583459055U;
|
|
inline constexpr std::size_t max_cosmetic_slots = 64, max_cosmetic_scalars = 64,
|
|
max_cosmetic_parameters = 128, max_cosmetic_asset = 255;
|
|
// The largest encoded outfit packet. Well under the packet limit, so an outfit a host accepts
|
|
// always fits again with the reference marker a relayed copy carries.
|
|
inline constexpr std::size_t max_appearance_bytes = 16384;
|
|
struct CosmeticSlot {
|
|
std::uint32_t slot{};
|
|
std::string asset;
|
|
std::vector<std::uint32_t> parameters;
|
|
bool operator==(const CosmeticSlot &) const = default;
|
|
};
|
|
struct CosmeticRecipe {
|
|
std::uint32_t key{}, version{};
|
|
std::vector<std::uint32_t> scalars;
|
|
std::vector<CosmeticSlot> items;
|
|
bool operator==(const CosmeticRecipe &) const = default;
|
|
};
|
|
struct PlayerCard {
|
|
std::uint32_t background{}, emblem{}, title{};
|
|
bool operator==(const PlayerCard &) const = default;
|
|
};
|
|
// How one of a listed player's marked cosmetics is coloured (developer_identity.h), chosen on
|
|
// the menu's Special page and carried in their Appearance, so everyone sees the same.
|
|
enum class MarkMode : std::uint8_t { standard, off, gradient, solid };
|
|
struct MarkStyle {
|
|
MarkMode mode{}; // standard: what the player's list gives
|
|
std::array<std::uint8_t, 3> from{}, to{}; // as picked on screen. gradient: between the two; solid: `from`
|
|
std::uint8_t speed{}; // 0 normal, 1 slow, 2 fast
|
|
bool operator==(const MarkStyle &) const = default;
|
|
};
|
|
// The marked cosmetics, in this order: whatever the skater has in each of these slots, then the
|
|
// parts of whatever board they ride.
|
|
inline constexpr std::array<std::string_view, 12> mark_item_names{
|
|
"Top", "Bottoms", "Shoes", "Socks", "Hat", "Glasses", "Outfit", "Costume", "Deck", "Grip tape", "Trucks", "Wheels"};
|
|
inline constexpr std::size_t mark_items = mark_item_names.size(), skater_mark_items = 8;
|
|
using MarkStyles = std::array<MarkStyle, mark_items>;
|
|
// The rainbow, as a style a developer or a member of staff picks (a developer's standard is
|
|
// the rainbow already). Players on builds from before it could be picked must be able to read
|
|
// the style, so it travels as one they know: a solid colour, with this in the second colour a
|
|
// solid does not use. They show the solid colour; nobody else's item takes the rainbow from it.
|
|
inline constexpr std::array<std::uint8_t, 3> rainbow_marker{0x52, 0x42, 0x57}; // "RBW"
|
|
inline bool rainbow_style(const MarkStyle &style) noexcept { return style.mode == MarkMode::solid && style.to == rainbow_marker; }
|
|
inline bool valid_mark_style(const MarkStyle &style) noexcept {
|
|
return style.mode <= MarkMode::solid && style.speed <= 2;
|
|
}
|
|
struct Appearance {
|
|
CosmeticRecipe skater, board;
|
|
PlayerCard card;
|
|
// The player has turned off what the ReSkate backend gives them (developer_identity.h):
|
|
// nobody shows their tag, or nobody animates their hoodie and board.
|
|
bool hide_tag{}, hide_items{};
|
|
MarkStyles marks{};
|
|
bool operator==(const Appearance &) const = default;
|
|
};
|
|
// Stand-ins for a peer's cosmetic that this PC does not have (a player's
|
|
// cosmetics mod): each replaces an item in a slot of its own category. Asset
|
|
// keys stay the same between seasons. Slots with none of these (outfits,
|
|
// costumes, hats, glasses, socks, stickers, tattoos...) are left empty.
|
|
inline constexpr std::array<std::string_view, 8> default_cosmetic_items{
|
|
"Own_TopShirt_Gen_TshirtRelaxed_00007", // Black I Heart Tee
|
|
"Own_BottomPants_Gen_ChinoLoose_00001", // Olive Chinos
|
|
"Own_ShoeSneaker_Gen_SlipOnSkateboarding_00002", // Black Slip-ons
|
|
"Own_DeckGraphic_Gen_Popsicle_00001", // Natural Blank deck
|
|
"Own_DeckGripCutout_Gen_Popsicle_00001", // Plain grip pattern
|
|
"Own_DeckGripColor_Gen_Popsicle_00001", // Black grip
|
|
"Own_Truck_Gen_Default_00001", // Basic trucks
|
|
"Own_WheelColor_Gen_Classic_00009", // White wheels
|
|
};
|
|
inline std::uint32_t cosmetic_asset_hash(std::string_view value) {
|
|
if (value.empty())
|
|
return 0;
|
|
std::uint32_t hash = 5381;
|
|
for (unsigned char c : value)
|
|
hash = hash * 33 ^ c;
|
|
return hash;
|
|
}
|
|
// Values are opaque native parameter bits; no addresses, model handles,
|
|
// inventory flags or saved-profile identifiers cross the connection.
|
|
bool valid_appearance(const Appearance &) noexcept;
|
|
} // namespace dingosdk::multiplayer
|