Skip to content

Commit

Permalink
Send DS's SDL (in minified form) from the AuthSrv.
Browse files Browse the repository at this point in the history
This is to cope with the fallout of Plasma's `/LocalData` option no
longer forcing the use of local SDL files. The point of all of these
changes is to firm up the contract of what SDL is the correct SDL.
  • Loading branch information
Hoikas committed Aug 27, 2023
1 parent 4462f86 commit ed77283
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 20 deletions.
6 changes: 6 additions & 0 deletions AuthServ/AuthManifest.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ namespace DS
struct AuthFileInfo
{
AuthFileInfo() : m_fileSize() { }
AuthFileInfo(ST::string filename, uint32_t filesize)
: m_filename(std::move(filename)), m_fileSize(filesize)
{ }

AuthFileInfo(const AuthFileInfo&) = delete;
AuthFileInfo& operator=(const AuthFileInfo&) = delete;
Expand All @@ -48,6 +51,9 @@ namespace DS

size_t fileCount() const { return m_files.size(); }

template<typename... _Args>
AuthFileInfo& addFile(_Args&&... args) { return m_files.emplace_back(std::forward<_Args>(args)...); }

private:
std::vector<AuthFileInfo> m_files;
};
Expand Down
66 changes: 46 additions & 20 deletions AuthServ/AuthServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
#include <string_theory/format>
#include <openssl/rand.h>
#include <poll.h>
#include "SDL/DescriptorDb.h"
#include "SDL/SdlWriter.h"

#define NODE_SIZE_MAX (4 * 1024 * 1024)

std::list<AuthServer_Private*> s_authClients;
std::mutex s_authClientMutex;
DS::Blob s_minifiedSdl;

#define START_REPLY(msgId) \
client.m_buffer.truncate(); \
Expand Down Expand Up @@ -563,15 +566,26 @@ void cb_fileList(AuthServer_Private& client)
SEND_REPLY();
return;
}
ST::string mfsname = ST::format("{}{}_{}.list", DS::Settings::AuthRoot(),
directory, fileext);

DS::AuthManifest mfs;
DS::NetResultCode result = mfs.loadManifest(mfsname.c_str());
client.m_buffer.write<uint32_t>(result);
DS::NetResultCode result = DS::e_NetPending;

// We may need to manually process SDL files.
if (DS::Settings::SendDescriptorDb() && fileext.compare_i("sdl") == 0) {
mfs.addFile(ST_LITERAL("AllDirtSandStates.sdl"), s_minifiedSdl.size());
result = DS::e_NetSuccess;
} else {
ST::string mfsname = ST::format("{}{}_{}.list", DS::Settings::AuthRoot(),
directory, fileext);
result = mfs.loadManifest(mfsname.c_str());
if (result != DS::e_NetSuccess)
ST::printf(stderr, "[Auth] {} requested invalid manifest {}\n",
DS::SockIpAddress(client.m_sock), mfsname);
}
DS_ASSERT(result != DS::e_NetPending);

client.m_buffer.write<uint32_t>(result);
if (result != DS::e_NetSuccess) {
ST::printf(stderr, "[Auth] {} requested invalid manifest {}\n",
DS::SockIpAddress(client.m_sock), mfsname);
client.m_buffer.write<uint32_t>(0); // Data packet size
} else {
uint32_t sizeLocation = client.m_buffer.tell();
Expand Down Expand Up @@ -606,20 +620,26 @@ void cb_downloadStart(AuthServer_Private& client)
}
filename = filename.replace("\\", "/");

filename = DS::Settings::AuthRoot() + filename;
DS::FileStream* stream = new DS::FileStream();
try {
stream->open(filename.c_str(), "rb");
} catch (const DS::FileIOException& ex) {
ST::printf(stderr, "[Auth] Could not open file {}: {}\n[Auth] Requested by {}\n",
filename, ex.what(), DS::SockIpAddress(client.m_sock));
client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound);
client.m_buffer.write<uint32_t>(0); // File size
client.m_buffer.write<uint32_t>(0); // Chunk offset
client.m_buffer.write<uint32_t>(0); // Data packet size
SEND_REPLY();
delete stream;
return;
DS::Stream* stream;
// Check to see if this is our special SDL file...
if (DS::Settings::SendDescriptorDb() && filename.ends_with(".sdl", ST::case_sensitivity_t::case_insensitive)) {
stream = new DS::BlobStream(s_minifiedSdl);
} else {
filename = DS::Settings::AuthRoot() + filename;
stream = new DS::FileStream();
try {
static_cast<DS::FileStream*>(stream)->open(filename.c_str(), "rb");
} catch (const DS::FileIOException& ex) {
ST::printf(stderr, "[Auth] Could not open file {}: {}\n[Auth] Requested by {}\n",
filename, ex.what(), DS::SockIpAddress(client.m_sock));
client.m_buffer.write<uint32_t>(DS::e_NetFileNotFound);
client.m_buffer.write<uint32_t>(0); // File size
client.m_buffer.write<uint32_t>(0); // Chunk offset
client.m_buffer.write<uint32_t>(0); // Data packet size
SEND_REPLY();
delete stream;
return;
}
}

client.m_buffer.write<uint32_t>(DS::e_NetSuccess);
Expand Down Expand Up @@ -1104,6 +1124,12 @@ void DS::AuthServer_Init(bool restrictLogins)
ST::printf(stderr, "Warning: Could not restrict logins: {}\n", ex.what());
}
}

DS::BufferStream stream;
DS::EncryptedStream encStream(&stream, DS::EncryptedStream::Mode::e_write,
DS::EncryptedStream::Type::e_btea, DS::Settings::DroidKey());
SDL::DescriptorDb::WriteDescriptors(&encStream);
s_minifiedSdl = DS::Blob(stream.buffer(), stream.size());
}

void DS::AuthServer_Add(DS::SocketHandle client)
Expand Down
1 change: 1 addition & 0 deletions AuthServ/AuthServer_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ struct AuthServer_Private : public AuthClient_Private
extern std::list<AuthServer_Private*> s_authClients;
extern std::mutex s_authClientMutex;
extern std::thread s_authDaemonThread;
extern DS::Blob s_minifiedSdl;

extern PGconn* s_postgres;
extern uint32_t s_allPlayers;
Expand Down
124 changes: 124 additions & 0 deletions SDL/DescriptorDb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,3 +117,127 @@ bool SDL::DescriptorDb::ForLatestDescriptors(descfunc_t functor)
}
return true;
}

static inline ST::string type_to_typename(const SDL::VarDescriptor& var)
{
switch (var.m_type) {
case SDL::e_VarInt:
return ST_LITERAL("INT");
case SDL::e_VarFloat:
return ST_LITERAL("FLOAT");
case SDL::e_VarBool:
return ST_LITERAL("BOOL");
case SDL::e_VarString:
return ST_LITERAL("STRING32");
case SDL::e_VarKey:
return ST_LITERAL("PLKEY");
case SDL::e_VarStateDesc:
return ST::format("${}", var.m_typeName);
case SDL::e_VarCreatable:
return ST_LITERAL("CREATABLE");
case SDL::e_VarDouble:
return ST_LITERAL("DOUBLE");
case SDL::e_VarTime:
return ST_LITERAL("TIME");
case SDL::e_VarByte:
return ST_LITERAL("BYTE");
case SDL::e_VarShort:
return ST_LITERAL("SHORT");
case SDL::e_VarAgeTimeOfDay:
return ST_LITERAL("AGETIMEOFDAY");
case SDL::e_VarVector3:
return ST_LITERAL("VECTOR3");
case SDL::e_VarPoint3:
return ST_LITERAL("POINT3");
case SDL::e_VarRgb:
return ST_LITERAL("RGB");
case SDL::e_VarRgba:
return ST_LITERAL("RGBA");
case SDL::e_VarQuaternion:
return ST_LITERAL("QUATERNION");
case SDL::e_VarRgb8:
return ST_LITERAL("RGB8");
case SDL::e_VarRgba8:
return ST_LITERAL("RGBA8");
default:
return ST_LITERAL("INVALID");
}
}

static inline ST::string default_to_str(const SDL::VarDescriptor& var)
{
if (!var.m_default.m_valid)
return {};

switch (var.m_type) {
case SDL::e_VarInt:
case SDL::e_VarBool:
case SDL::e_VarByte:
case SDL::e_VarShort:
return ST::string::from_int(var.m_default.m_int);
case SDL::e_VarFloat:
return ST::string::from_float(var.m_default.m_float);
case SDL::e_VarString:
return var.m_default.m_string;
case SDL::e_VarKey:
// The only valid default is "nil", which is the same as leaving the default blank.
// So, let's just save these bytes.
return {};
case SDL::e_VarDouble:
return ST::string::from_double(var.m_default.m_double);
case SDL::e_VarTime:
return ST::string::from_uint(var.m_default.m_time.m_secs);
case SDL::e_VarVector3:
case SDL::e_VarPoint3:
return ST::format("({},{},{})", var.m_default.m_vector.m_X,
var.m_default.m_vector.m_Y, var.m_default.m_vector.m_Z);
case SDL::e_VarRgb:
return ST::format("({},{},{})", var.m_default.m_color.m_R,
var.m_default.m_color.m_G, var.m_default.m_color.m_B);
case SDL::e_VarRgba:
return ST::format("({},{},{},{})", var.m_default.m_color.m_R,
var.m_default.m_color.m_G, var.m_default.m_color.m_B,
var.m_default.m_color.m_A);
case SDL::e_VarRgb8:
return ST::format("({},{},{})", var.m_default.m_color8.m_R,
var.m_default.m_color8.m_G, var.m_default.m_color8.m_B);
case SDL::e_VarRgba8:
return ST::format("({},{},{},{})", var.m_default.m_color8.m_R,
var.m_default.m_color8.m_G, var.m_default.m_color8.m_B,
var.m_default.m_color8.m_A);
case SDL::e_VarQuaternion:
return ST::format("({},{},{},{})", var.m_default.m_quat.m_X,
var.m_default.m_quat.m_Y, var.m_default.m_quat.m_Z,
var.m_default.m_quat.m_W);
default:
DS_ASSERT(0);
}
}

void SDL::DescriptorDb::WriteDescriptors(DS::Stream* stream)
{
for (const auto& desc : s_descriptors) {
stream->writeString(ST::format("STATEDESC {}\n", desc.m_name));
stream->writeString(ST_LITERAL("{\n"));
stream->writeString(ST::format("\tVERSION {}\n", desc.m_version));

for (const auto& var : desc.m_vars) {
stream->writeString(ST::format("\tVAR\t{}\t{}", type_to_typename(var), var.m_name));
if (!(var.m_flags & VarDescriptor::e_VariableLength))
stream->writeString(ST::format("[{}]", var.m_size));
else
stream->writeString(ST_LITERAL("[]"));

ST::string defValue = default_to_str(var);
if (!defValue.empty())
stream->writeString(ST::format("\tDEFAULT={}", defValue));
if (var.m_flags & VarDescriptor::e_AlwaysNew)
stream->writeString(ST_LITERAL("\tDEFAULTOPTION=VAULT"));
if (!var.m_displayOption.empty())
stream->writeString(ST::format("\tDISPLAYOPTION={}", var.m_displayOption));
stream->write('\n');
}

stream->writeString(ST_LITERAL("}\n"));
}
}
1 change: 1 addition & 0 deletions SDL/DescriptorDb.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ namespace SDL
static StateDescriptor* FindDescriptor(const ST::string& name, int version);
static StateDescriptor* FindLatestDescriptor(const ST::string& name);
static bool ForLatestDescriptors(descfunc_t functor);
static void WriteDescriptors(DS::Stream* stream);

private:
DescriptorDb() = delete;
Expand Down
9 changes: 9 additions & 0 deletions settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ static struct
/* Misc */
bool m_statusEnabled;
ST::string m_welcome;
bool m_sendDescriptorDb;
} s_settings;

#define DS_LOADBLOB(outbuffer, fixedsize, params) \
Expand Down Expand Up @@ -202,6 +203,8 @@ bool DS::Settings::LoadFrom(const ST::string& filename)
s_settings.m_dbDbase = params[1];
} else if (params[0] == "Welcome.Msg") {
s_settings.m_welcome = params[1];
} else if (params[0] == "Auth.SendDescriptorDb") {
s_settings.m_sendDescriptorDb = params[1].to_bool();
} else {
ST::printf(stderr, "Warning: Unknown setting '{}' ignored\n", params[0]);
}
Expand All @@ -221,6 +224,7 @@ void DS::Settings::UseDefaults()
s_settings.m_lobbyPort = ST_LITERAL("14617");
s_settings.m_statusPort = ST_LITERAL("8080");
s_settings.m_statusEnabled = true;
s_settings.m_sendDescriptorDb = true;

s_settings.m_fileRoot = ST_LITERAL("./data");
s_settings.m_authRoot = ST_LITERAL("./authdata");
Expand Down Expand Up @@ -348,3 +352,8 @@ void DS::Settings::SetWelcomeMsg(const ST::string& welcome)
{
s_settings.m_welcome = welcome;
}

bool DS::Settings::SendDescriptorDb()
{
return s_settings.m_sendDescriptorDb;
}
2 changes: 2 additions & 0 deletions settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ namespace DS
ST::string WelcomeMsg();
void SetWelcomeMsg(const ST::string& welcome);

bool SendDescriptorDb();

bool LoadFrom(const ST::string& filename);
void UseDefaults();
}
Expand Down

0 comments on commit ed77283

Please sign in to comment.