Compare commits
No commits in common. "3ec27d115b0a6ff3ac20fe4486239150c3872e25" and "bf3635d7adf334ca730f4f5b3b28ed7aa7d8c901" have entirely different histories.
3ec27d115b
...
bf3635d7ad
3 changed files with 1 additions and 62 deletions
|
|
@ -32,10 +32,6 @@ namespace system {
|
||||||
|
|
||||||
class XSocket;
|
class XSocket;
|
||||||
|
|
||||||
// The wire structs below must match the relay's byte-for-byte (the main repo
|
|
||||||
// packs them with #pragma pack(1); leaving padding here would inflate the
|
|
||||||
// sizes and silently corrupt every datagram).
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
// Header of every relay datagram ("GHST" magic, little-endian type + size).
|
// Header of every relay datagram ("GHST" magic, little-endian type + size).
|
||||||
// Must match kGhostMagic / PacketHeader in skate3_native_ghost_proto.h.
|
// Must match kGhostMagic / PacketHeader in skate3_native_ghost_proto.h.
|
||||||
struct XNetRelayHeader {
|
struct XNetRelayHeader {
|
||||||
|
|
@ -73,7 +69,6 @@ struct XNetRelaySessionReply {
|
||||||
uint8_t count;
|
uint8_t count;
|
||||||
XNetRelaySessionEntry list[32];
|
XNetRelaySessionEntry list[32];
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
// One discovered session (a member of our room).
|
// One discovered session (a member of our room).
|
||||||
struct XNetSession {
|
struct XNetSession {
|
||||||
|
|
@ -148,9 +143,6 @@ class XNetTransport {
|
||||||
// header stays platform-independent.
|
// header stays platform-independent.
|
||||||
uint8_t relay_addr_[16] = {};
|
uint8_t relay_addr_[16] = {};
|
||||||
bool relay_resolved_ = false;
|
bool relay_resolved_ = false;
|
||||||
uint8_t join_pkt_[7 + sizeof(XNetRelayJoin)] = {};
|
|
||||||
uint16_t join_pkt_size_ = 0;
|
|
||||||
double last_join_ = 0.0; // monotonic seconds (heartbeat to beat the timeout)
|
|
||||||
std::thread thread_;
|
std::thread thread_;
|
||||||
bool running_ = false;
|
bool running_ = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include <rex/platform.h>
|
#include <rex/platform.h>
|
||||||
#include <rex/logging.h>
|
|
||||||
#include <rex/system/kernel_state.h>
|
#include <rex/system/kernel_state.h>
|
||||||
#include <rex/system/xsocket.h>
|
#include <rex/system/xsocket.h>
|
||||||
#include <rex/system/xam/user_profile.h>
|
#include <rex/system/xam/user_profile.h>
|
||||||
|
|
@ -30,15 +29,6 @@
|
||||||
namespace rex {
|
namespace rex {
|
||||||
namespace system {
|
namespace system {
|
||||||
|
|
||||||
// Pin the packed wire sizes to the values the relay expects (the game-side
|
|
||||||
// proto packs them identically). Catches accidental un-packing or member
|
|
||||||
// edits before they corrupt the wire.
|
|
||||||
static_assert(sizeof(XNetRelayHeader) == 7, "relay header must be 7 bytes");
|
|
||||||
static_assert(sizeof(XNetRelayJoin) == 31, "relay join must be 31 bytes");
|
|
||||||
static_assert(sizeof(XNetRelayGame) == 1410, "relay game payload must be 1410 bytes");
|
|
||||||
static_assert(sizeof(XNetRelaySessionEntry) == 25, "session entry must be 25 bytes");
|
|
||||||
static_assert(sizeof(XNetRelaySessionReply) == 801, "session reply must be 801 bytes");
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Virtual address range: 10.80.0.0/16 (host order prefix 0x0A500000).
|
// Virtual address range: 10.80.0.0/16 (host order prefix 0x0A500000).
|
||||||
|
|
@ -60,23 +50,6 @@ void SocketClose(int64_t s) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// The receive loop must wake regularly so the heartbeat fires even with no
|
|
||||||
// inbound traffic (otherwise the relay sweeps a silent transport client
|
|
||||||
// after ~8s) and so StopLocked()'s join completes promptly instead of
|
|
||||||
// deadlocking SetRelay on a room change.
|
|
||||||
void SocketSetRecvTimeout(int64_t s, int timeout_ms) {
|
|
||||||
#if REX_PLATFORM_WIN32
|
|
||||||
DWORD tv = DWORD(timeout_ms);
|
|
||||||
::setsockopt(SOCKET(s), SOL_SOCKET, SO_RCVTIMEO,
|
|
||||||
reinterpret_cast<const char*>(&tv), sizeof(tv));
|
|
||||||
#else
|
|
||||||
timeval tv = {};
|
|
||||||
tv.tv_sec = timeout_ms / 1000;
|
|
||||||
tv.tv_usec = (timeout_ms % 1000) * 1000;
|
|
||||||
::setsockopt(int(s), SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SocketSendTo(int64_t s, const sockaddr_in* to, const void* buf, int size) {
|
bool SocketSendTo(int64_t s, const sockaddr_in* to, const void* buf, int size) {
|
||||||
#if REX_PLATFORM_WIN32
|
#if REX_PLATFORM_WIN32
|
||||||
const int n = ::sendto(SOCKET(s), reinterpret_cast<const char*>(buf), size, 0,
|
const int n = ::sendto(SOCKET(s), reinterpret_cast<const char*>(buf), size, 0,
|
||||||
|
|
@ -183,21 +156,14 @@ void XNetTransport::Reconnect() {
|
||||||
}
|
}
|
||||||
sockaddr_in relay_addr = {};
|
sockaddr_in relay_addr = {};
|
||||||
if (!Resolve(host_, port_, &relay_addr)) {
|
if (!Resolve(host_, port_, &relay_addr)) {
|
||||||
REXLOG_WARN("xnet transport: cannot resolve relay '{}:{}'", host_, port_);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::memcpy(relay_addr_, &relay_addr, sizeof(relay_addr));
|
std::memcpy(relay_addr_, &relay_addr, sizeof(relay_addr));
|
||||||
relay_resolved_ = true;
|
relay_resolved_ = true;
|
||||||
sock_ = SocketCreate();
|
sock_ = SocketCreate();
|
||||||
if (sock_ == -1) {
|
if (sock_ == -1) {
|
||||||
REXLOG_WARN("xnet transport: cannot open relay socket");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Wake the receive loop every 200ms (heartbeat + prompt shutdown).
|
|
||||||
SocketSetRecvTimeout(sock_, 200);
|
|
||||||
REXLOG_INFO("xnet transport: connecting to relay '{}:{}' room '{}' (vip {}.{}.{}.{})", host_,
|
|
||||||
port_, room_.c_str(), (LocalVirtualIp() >> 24) & 0xFF, (LocalVirtualIp() >> 16) & 0xFF,
|
|
||||||
(LocalVirtualIp() >> 8) & 0xFF, LocalVirtualIp() & 0xFF);
|
|
||||||
// Join the room so the relay routes our game traffic among its members.
|
// Join the room so the relay routes our game traffic among its members.
|
||||||
XNetRelayJoin jp = {};
|
XNetRelayJoin jp = {};
|
||||||
jp.version = kVersion;
|
jp.version = kVersion;
|
||||||
|
|
@ -218,12 +184,6 @@ void XNetTransport::Reconnect() {
|
||||||
std::memcpy(pkt + 7, &jp, sizeof(jp));
|
std::memcpy(pkt + 7, &jp, sizeof(jp));
|
||||||
SocketSendTo(sock_, &relay_addr, pkt, sizeof(pkt));
|
SocketSendTo(sock_, &relay_addr, pkt, sizeof(pkt));
|
||||||
|
|
||||||
// Keep the JOIN around for the heartbeat (the relay drops silent clients
|
|
||||||
// after ~8s).
|
|
||||||
std::memcpy(join_pkt_, pkt, sizeof(pkt));
|
|
||||||
join_pkt_size_ = uint16_t(sizeof(pkt));
|
|
||||||
last_join_ = 0.0;
|
|
||||||
|
|
||||||
running_ = true;
|
running_ = true;
|
||||||
thread_ = std::thread(&XNetTransport::Run, this);
|
thread_ = std::thread(&XNetTransport::Run, this);
|
||||||
}
|
}
|
||||||
|
|
@ -311,14 +271,6 @@ void XNetTransport::Run() {
|
||||||
if (!running_) {
|
if (!running_) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Heartbeat: re-JOIN every ~4s so the relay never times us out.
|
|
||||||
const double now =
|
|
||||||
double(std::chrono::steady_clock::now().time_since_epoch().count()) / 1e9;
|
|
||||||
if (join_pkt_size_ != 0 && now - last_join_ >= 4.0) {
|
|
||||||
SocketSendTo(sock_, reinterpret_cast<const sockaddr_in*>(relay_addr_), join_pkt_,
|
|
||||||
join_pkt_size_);
|
|
||||||
last_join_ = now;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
uint8_t buf[7 + sizeof(XNetRelayGame)];
|
uint8_t buf[7 + sizeof(XNetRelayGame)];
|
||||||
sockaddr_in from = {};
|
sockaddr_in from = {};
|
||||||
|
|
@ -355,9 +307,6 @@ void XNetTransport::HandlePacket(const uint8_t* data, int size) {
|
||||||
// session_id != 0 means accepted (0 = refused).
|
// session_id != 0 means accepted (0 = refused).
|
||||||
active_ = payload[0] != 0;
|
active_ = payload[0] != 0;
|
||||||
joined_ = true;
|
joined_ = true;
|
||||||
REXLOG_INFO("xnet transport: relay {} (vip {}.{}.{}.{})", active_ ? "joined" : "refused",
|
|
||||||
(LocalVirtualIp() >> 24) & 0xFF, (LocalVirtualIp() >> 16) & 0xFF,
|
|
||||||
(LocalVirtualIp() >> 8) & 0xFF, LocalVirtualIp() & 0xFF);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case kGame: {
|
case kGame: {
|
||||||
|
|
@ -401,8 +350,6 @@ void XNetTransport::HandlePacket(const uint8_t* data, int size) {
|
||||||
std::lock_guard<std::mutex> lock(mu_);
|
std::lock_guard<std::mutex> lock(mu_);
|
||||||
sessions_ = std::move(fresh);
|
sessions_ = std::move(fresh);
|
||||||
++reply_seq_;
|
++reply_seq_;
|
||||||
REXLOG_INFO("xnet transport: session reply with {} session(s) in room '{}'", count,
|
|
||||||
room_.c_str());
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
2
thirdparty/imgui
vendored
2
thirdparty/imgui
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0af8f475d1cf8b98d603702059c0c73deeb81ac2
|
Subproject commit cdda62349d6068e906c2e0ee340d6ec31eedbb9c
|
||||||
Loading…
Add table
Reference in a new issue