mirror of
https://github.com/ayozetr/bloodborne_linux.git
synced 2026-11-08 01:08:25 -10:00
shadNet: report the client version after signing in
A shadNet server with clientversions.cfg rules signs out a client that never sends SetClientVersion, then refuses its logins with LoginError for a while. We sent nothing, so on the public server the game went offline a few seconds after signing in and the next logins failed. - send SetClientVersion (command 13) right after the login reply; the string is "shadPS4 bbport", BB_CLIENT_VERSION overrides it - log the ClientRejected notification (19) with the server's message - keep the SetClientVersion reply away from OnScoreReply Thanks: Vorshim92, in 7 languages. Co-Authored-By: Stefano Scalfari <[email protected]>
This commit is contained in:
1 parent
4f3187843f
commit
2bcc093bd9
5 files changed
+64
No files matched your search
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#include <thread>
|
||||
|
||||
#include "client.h"
|
||||
@@ -537,6 +538,21 @@ bool ShadNetClient::RequestServerFeatures() {
|
||||
return true;
|
||||
}
|
||||
|
||||
// BB_CLIENT_VERSION replaces the default, for a server whose clientversions.cfg expects
|
||||
// another format.
|
||||
std::string ShadNetClient::BuildVersionString() {
|
||||
if (const char* version = std::getenv("BB_CLIENT_VERSION"); version && *version)
|
||||
return version;
|
||||
return "shadPS4 bbport";
|
||||
}
|
||||
|
||||
u64 ShadNetClient::ReportClientVersion() {
|
||||
shadnet::SetClientVersionRequest req;
|
||||
req.set_version(BuildVersionString());
|
||||
LOG_INFO(ShadNet, "Reporting client version '{}'", req.version());
|
||||
return SubmitRequest(CommandType::SetClientVersion, MakeProtoPayload(req));
|
||||
}
|
||||
|
||||
// Packet dispatch
|
||||
|
||||
void ShadNetClient::DispatchPacket(PacketType type, u16 cmd_raw, u64 pkt_id,
|
||||
@@ -553,6 +569,12 @@ void ShadNetClient::DispatchPacket(PacketType type, u16 cmd_raw, u64 pkt_id,
|
||||
case CommandType::GetServerFeatures:
|
||||
HandleServerFeaturesReply(payload);
|
||||
break;
|
||||
case CommandType::SetClientVersion:
|
||||
// Nobody waits for this reply; a refusal arrives as a ClientRejected notification.
|
||||
if (!payload.empty() && static_cast<ErrorType>(payload[0]) != ErrorType::NoError)
|
||||
LOG_WARNING(ShadNet, "SetClientVersion returned error={}",
|
||||
static_cast<int>(payload[0]));
|
||||
break;
|
||||
default:
|
||||
if (onAsyncReply) {
|
||||
// Every reply body starts with an ErrorType byte.
|
||||
@@ -623,6 +645,9 @@ void ShadNetClient::HandleLoginReply(const std::vector<u8>& payload) {
|
||||
LOG_INFO(ShadNet, "Logged in npid='{}' userId={} friends={}", m_npid, m_user_id,
|
||||
m_friends.size());
|
||||
|
||||
// First, before the server's version timeout runs out.
|
||||
ReportClientVersion();
|
||||
|
||||
const u64 pkt_id = m_pkt_counter.fetch_add(1);
|
||||
std::vector<u8> empty_payload;
|
||||
std::vector<u8> pkt = BuildPacket(CommandType::GetToken, pkt_id, empty_payload);
|
||||
@@ -911,6 +936,16 @@ void ShadNetClient::HandleNotification(u16 cmd_raw, const std::vector<u8>& paylo
|
||||
onWebApiPushEvent(n);
|
||||
break;
|
||||
}
|
||||
case NotificationType::ClientRejected: {
|
||||
shadnet::NotifyClientRejected pb;
|
||||
if (!pb.ParseFromString(blob)) {
|
||||
LOG_WARNING(ShadNet, "ClientRejected parse error");
|
||||
break;
|
||||
}
|
||||
LOG_ERROR(ShadNet, "Server rejected this client (reason={}, version='{}'): {}",
|
||||
pb.reason(), pb.version(), pb.message());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_DEBUG(ShadNet, "Unknown notification type {}", cmd_raw);
|
||||
break;
|
||||
|
||||
@@ -67,6 +67,7 @@ enum class CommandType : u16 {
|
||||
AddBlock = 10,
|
||||
RemoveBlock = 11,
|
||||
GetServerFeatures = 12,
|
||||
SetClientVersion = 13,
|
||||
GetBoardInfos = 30,
|
||||
RecordScore = 31,
|
||||
RecordScoreData = 32,
|
||||
@@ -105,6 +106,7 @@ enum class NotificationType : u16 {
|
||||
RoomEvent = 10,
|
||||
RoomMessage = 11,
|
||||
WebApiPushEvent = 17, // Generic NP WebApi push event
|
||||
ClientRejected = 19, // The server is signing this client out and says why
|
||||
};
|
||||
|
||||
enum class ErrorType : uint8_t {
|
||||
@@ -328,6 +330,9 @@ private:
|
||||
void HandleServerFeaturesReply(const std::vector<u8>& payload);
|
||||
void HandleNotification(u16 cmd_raw, const std::vector<u8>& payload);
|
||||
bool RequestServerFeatures();
|
||||
// Tell the server which client this is; a shadNet server may deny clients that stay silent.
|
||||
u64 ReportClientVersion();
|
||||
static std::string BuildVersionString();
|
||||
|
||||
// Helper: read a u32-LE-prefixed proto blob from a byte vector at pos.
|
||||
static std::string ExtractBlob(const std::vector<u8>& p, int pos);
|
||||
|
||||
@@ -29,6 +29,22 @@ message SetAppearOfflineRequest {
|
||||
bool appear_offline = 1;
|
||||
}
|
||||
|
||||
// Sent right after signing in. A server with clientversions.cfg rules signs out a client
|
||||
// that reports nothing, or a version it denies.
|
||||
message SetClientVersionRequest {
|
||||
string version = 1;
|
||||
}
|
||||
|
||||
// Notification 19: the server is signing this client out, then disconnects.
|
||||
// reason: 1 = client version not accepted
|
||||
// message: text for the player, from the rule that matched
|
||||
// version: the version the server checked ("" = none reported)
|
||||
message NotifyClientRejected {
|
||||
uint32 reason = 1;
|
||||
string message = 2;
|
||||
string version = 3;
|
||||
}
|
||||
|
||||
message ServerFeaturesReply {
|
||||
bool matching2_enabled = 1;
|
||||
}
|
||||
|
||||
@@ -595,6 +595,7 @@ EN = {
|
||||
'Очистить кэш шейдеров?': 'Clear the shader cache?',
|
||||
'Игра соберёт шейдеры заново: первые минуты в каждой зоне возможны рывки. Сохранения и настройки не затрагиваются.': 'The game builds the shaders again: some stutter in each area for the first minutes. Saves and settings are not touched.',
|
||||
'Названия трофеев на английском без ключа и звук при получении трофея': 'Trophy names in English without the key, and the sound when one is earned',
|
||||
'Вход на публичный сервер shadNet без отключения': 'Staying signed in on the public shadNet server',
|
||||
}
|
||||
|
||||
PT_BR = {
|
||||
@@ -1244,6 +1245,7 @@ PT_BR = {
|
||||
'Очистить кэш шейдеров?': 'Limpar o cache de shaders?',
|
||||
'Игра соберёт шейдеры заново: первые минуты в каждой зоне возможны рывки. Сохранения и настройки не затрагиваются.': 'O jogo gera os shaders de novo: pode haver travadas nos primeiros minutos de cada área. Saves e configurações não são afetados.',
|
||||
'Названия трофеев на английском без ключа и звук при получении трофея': 'Nomes dos troféus em inglês sem a chave e o som ao conquistar um',
|
||||
'Вход на публичный сервер shadNet без отключения': 'Continuar conectado no servidor público do shadNet',
|
||||
}
|
||||
|
||||
|
||||
@@ -1804,6 +1806,7 @@ ES = {
|
||||
'Очистить кэш шейдеров?': '¿Borrar la caché de shaders?',
|
||||
'Игра соберёт шейдеры заново: первые минуты в каждой зоне возможны рывки. Сохранения и настройки не затрагиваются.': 'El juego volverá a generar los shaders: puede haber tirones los primeros minutos en cada zona. Las partidas y los ajustes no se tocan.',
|
||||
'Названия трофеев на английском без ключа и звук при получении трофея': 'Los nombres de los trofeos en inglés sin la clave y el sonido al conseguir uno',
|
||||
'Вход на публичный сервер shadNet без отключения': 'Seguir conectado en el servidor público de shadNet',
|
||||
}
|
||||
|
||||
|
||||
@@ -2364,6 +2367,7 @@ IT = {
|
||||
'Очистить кэш шейдеров?': 'Svuotare la cache degli shader?',
|
||||
'Игра соберёт шейдеры заново: первые минуты в каждой зоне возможны рывки. Сохранения и настройки не затрагиваются.': 'Il gioco ricrea gli shader: possibili scatti nei primi minuti di ogni area. Salvataggi e impostazioni non vengono toccati.',
|
||||
'Названия трофеев на английском без ключа и звук при получении трофея': 'I nomi dei trofei in inglese senza la chiave e il suono quando se ne ottiene uno',
|
||||
'Вход на публичный сервер shadNet без отключения': 'Restare connessi al server pubblico di shadNet',
|
||||
}
|
||||
|
||||
|
||||
@@ -2924,6 +2928,7 @@ FR = {
|
||||
'Очистить кэш шейдеров?': 'Vider le cache des shaders ?',
|
||||
'Игра соберёт шейдеры заново: первые минуты в каждой зоне возможны рывки. Сохранения и настройки не затрагиваются.': 'Le jeu reconstruit les shaders : quelques saccades les premières minutes dans chaque zone. Les sauvegardes et les réglages ne sont pas touchés.',
|
||||
'Названия трофеев на английском без ключа и звук при получении трофея': 'Les noms des trophées en anglais sans la clé et le son à l’obtention d’un trophée',
|
||||
'Вход на публичный сервер shadNet без отключения': 'Rester connecté au serveur public shadNet',
|
||||
}
|
||||
|
||||
|
||||
@@ -3484,6 +3489,7 @@ DE = {
|
||||
'Очистить кэш шейдеров?': 'Shader-Cache leeren?',
|
||||
'Игра соберёт шейдеры заново: первые минуты в каждой зоне возможны рывки. Сохранения и настройки не затрагиваются.': 'Das Spiel erstellt die Shader neu: In den ersten Minuten jedes Gebiets kann es ruckeln. Spielstände und Einstellungen bleiben unberührt.',
|
||||
'Названия трофеев на английском без ключа и звук при получении трофея': 'Trophäennamen auf Englisch ohne Schlüssel und der Ton beim Erhalt einer Trophäe',
|
||||
'Вход на публичный сервер shadNet без отключения': 'Auf dem öffentlichen shadNet-Server angemeldet bleiben',
|
||||
}
|
||||
|
||||
|
||||
@@ -3987,6 +3993,7 @@ ZH_CN = {
|
||||
'Очистить кэш шейдеров?': '清除着色器缓存?',
|
||||
'Игра соберёт шейдеры заново: первые минуты в каждой зоне возможны рывки. Сохранения и настройки не затрагиваются.': '游戏会重新生成着色器:每个区域的前几分钟可能卡顿。存档和设置不受影响。',
|
||||
'Названия трофеев на английском без ключа и звук при получении трофея': '无密钥时的英文奖杯名称与获得奖杯时的音效',
|
||||
'Вход на публичный сервер shadNet без отключения': '在公共 shadNet 服务器上保持登录',
|
||||
}
|
||||
|
||||
# Translations by language code; Russian is the key itself. Strings missing in a translation
|
||||
|
||||
@@ -626,6 +626,7 @@ THANKS = (
|
||||
_github("andrecabralgit", "Звук игры на полной громкости"),
|
||||
_github("Jgamrot", "Флажки и ползунки внутриигрового меню"),
|
||||
_github("GerasimosKan", "Названия трофеев на английском без ключа и звук при получении трофея"),
|
||||
_github("Vorshim92", "Вход на публичный сервер shadNet без отключения"),
|
||||
)),
|
||||
("Помощь и тесты", (
|
||||
_github("willthehuman", "Подробные отчёты с журналами и проверка исправлений"),
|
||||
|
||||
Reference in new issue
Block a user