Files
DorkNet/DorkNet.Quest/src/config.cpp
T
Alexa 3880745efd fix: open the sign-in page instead of creating a new account on a fresh client
With no remembered account, the 2023 title screen creates a brand-new
account (grant_type create_account). On a server with sign-ups off that
fails and the title screen retries forever. PC (ClientMod) and Quest
now open the sign-in page instead, so players log into their existing
DorkNet account. AutoCreateAccount = true keeps Rec Room's behaviour.

Also replaces a literal NUL byte in the Quest config loader with '\0'.
2026-10-24 22:45:57 +03:00

83 lines
4.0 KiB
C++

// Runtime config loader: applies an optional on-device cfg over the baked-in
// defaults. The cfg format is "Key = Value", one per line, '#' comments and
// [section] headers ignored -- the same keys DorkNet.ClientMod uses on PC, so a
// PC config reads here too.
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
extern "C" int __android_log_print(int prio, const char *tag, const char *fmt, ...);
#define CLOGI(...) __android_log_print(4, "DORKNET", __VA_ARGS__)
static void trim(char *s) {
char *p = s;
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n') p++;
if (p != s) memmove(s, p, strlen(p) + 1);
size_t n = strlen(s);
while (n && (s[n - 1] == ' ' || s[n - 1] == '\t' || s[n - 1] == '\r' || s[n - 1] == '\n'))
s[--n] = '\0';
}
static bool as_bool(const char *v, bool dflt) {
if (!v || !*v) return dflt;
if (!strcasecmp(v, "true") || !strcasecmp(v, "1") || !strcasecmp(v, "yes") || !strcasecmp(v, "on"))
return true;
if (!strcasecmp(v, "false") || !strcasecmp(v, "0") || !strcasecmp(v, "no") || !strcasecmp(v, "off"))
return false;
return dflt;
}
// Accept a bare host or a full URL; store just the host.
static void set_host(char *out, size_t cap, const char *val) {
const char *scheme = strstr(val, "://");
const char *host = scheme ? scheme + 3 : val;
size_t i = 0;
for (; host[i] && host[i] != '/' && i + 1 < cap; i++) out[i] = host[i];
out[i] = '\0';
}
void dn_load_runtime_config(char *server_host, size_t server_host_cap,
char *oculus_appid, size_t oculus_appid_cap,
char *photon_realtime, char *photon_voice, char *photon_chat,
char *photon_server, size_t photon_server_cap, int *photon_port,
char *photon_region, size_t photon_region_cap,
bool *tls_bypass, bool *accept_images, bool *auto_create_account,
bool *log_http, bool *debug_http, int *body_max) {
char path[256];
snprintf(path, sizeof(path), "/sdcard/Android/data/%s/files/%s", DN_PACKAGE, DN_RUNTIME_CFG_NAME);
FILE *f = fopen(path, "r");
if (!f) { CLOGI("no runtime config at %s; using baked-in defaults", path); return; }
char line[256];
while (fgets(line, sizeof(line), f)) {
char *hash = strchr(line, '#');
if (hash) *hash = '\0';
char *eq = strchr(line, '=');
if (!eq) continue;
*eq = '\0';
char *key = line, *val = eq + 1;
trim(key);
trim(val);
if (!strcasecmp(key, "ServerHost") && *val) set_host(server_host, server_host_cap, val);
else if (!strcasecmp(key, "OculusAppId")) {
oculus_appid[0] = '\0';
strncpy(oculus_appid, val, oculus_appid_cap - 1);
}
else if (!strcasecmp(key, "PhotonAppId") && *val) strncpy(photon_realtime, val, 63);
else if (!strcasecmp(key, "PhotonVoiceAppId") && *val) strncpy(photon_voice, val, 63);
else if (!strcasecmp(key, "PhotonChatAppId") && *val) strncpy(photon_chat, val, 63);
else if (!strcasecmp(key, "PhotonNameServer")) set_host(photon_server, photon_server_cap, val);
else if (!strcasecmp(key, "PhotonNameServerPort")) *photon_port = atoi(val);
else if (!strcasecmp(key, "PhotonRegion") && *val) { photon_region[0] = '\0'; strncpy(photon_region, val, photon_region_cap - 1); }
else if (!strcasecmp(key, "EnableTlsTrustBypass")) *tls_bypass = as_bool(val, *tls_bypass);
else if (!strcasecmp(key, "AcceptUnsignedImages")) *accept_images = as_bool(val, *accept_images);
else if (!strcasecmp(key, "AutoCreateAccount")) *auto_create_account = as_bool(val, *auto_create_account);
else if (!strcasecmp(key, "LogHttp")) *log_http = as_bool(val, *log_http);
else if (!strcasecmp(key, "Debug")) *debug_http = as_bool(val, *debug_http);
else if (!strcasecmp(key, "LogHttpBodyMax") && *val) *body_max = atoi(val);
}
fclose(f);
CLOGI("runtime config applied from %s", path);
}