JoinServer.ini
Database connection, ports, authentication mode, and license for JoinServer
Primary configuration file for JoinServer. All keys live under a single [JoinServerInfo] section.
File Location
JoinServer/JoinServer.iniLoaded once at startup. Changes require a JoinServer restart.
Dependencies
JoinServer/AllowableIpList.txt- IP whitelist for GameServer connections. See AllowableIpList.txt. Loaded only after the database, TCP listener, and UDP heartbeat target are all up.ConnectServer must be reachable on the configured UDP port. See ConnectServer.ini for the matching
ConnectServerPortUDP.A Windows ODBC Data Source pointing at the same SQL Server instance DataServer uses. See DataServer.ini.
Configuration
All keys belong to section [JoinServerInfo].
JoinServerODBC
string (31 chars max)
(empty)
ODBC DSN name for SQL Server. Must exist in Windows ODBC Data Sources on the JoinServer host. Required.
JoinServerUSER
string (31 chars max)
(empty)
SQL login user. Leave empty to use Windows Authentication if the DSN is configured for it.
JoinServerPASS
string (31 chars max)
(empty)
SQL login password. Leave empty when using Windows Authentication.
JoinServerPort
int (0 - 65535)
55970
TCP port GameServers connect to. Must match each GameServer's JoinServerPort setting.
ConnectServerAddress
string (15 chars max)
127.0.0.1
IPv4 address or hostname of ConnectServer for the UDP heartbeat. Resolved once at startup.
ConnectServerPort
int (0 - 65535)
55557
UDP port on ConnectServer that receives the heartbeat. Must match ConnectServer's ConnectServerPortUDP.
CaseSensitive
0 or 1
0
Casing of account names in the in-memory online-account map. See Case Sensitivity.
LicenseKey
hex string (64 chars)
(empty)
License token tied to this JoinServer instance. Required; an empty or invalid key prevents startup.
Case Sensitivity
CaseSensitive controls how the account string is used as a key in the in-memory map that tracks currently-connected accounts (used for duplicate-login detection, map-server moves, and disconnect bookkeeping).
0
Account string is lowercased before it is used as a map key. Admin and admin collide in the online set.
1
Account string is used verbatim as the map key. Admin and admin are treated as separate online sessions.
This setting does NOT rewrite the account name sent to the database. Account lookup casing in SQL Server is governed by:
For
MD5Encryption = 0: the password-check query forcesCOLLATE Latin1_General_BINon the account ID, so the DB lookup is binary-exact regardless ofCaseSensitiveor the database's default collation.For
MD5Encryption = 1: no explicit collation is forced; the database's default collation decides whetherAdminandadminmatch on lookup.
Mixing CaseSensitive values across JoinServer restarts can leave a user double-online in the map (one entry per casing). Pick a value and keep it stable.
Password Storage
Value
Storage format in MEMB_INFO.memb__pwd
Login comparison
0
Plain text, up to 10 chars
Binary-exact strcmp of submitted password against stored value. Account row is selected with COLLATE Latin1_General_BIN, so both the account ID and the password are case-sensitive.
1
16-byte MD5 hash stored as binary
Submitted password is hashed with an account-derived key and compared to the stored 16 bytes. Account row is selected without a forced collation, so account-ID casing follows the DB collation.
Switching MD5Encryption against a populated MEMB_INFO table locks out every existing account. Migrate passwords in the database before flipping the mode.
With MD5Encryption = 0, password and account-ID comparison at login are both case-sensitive at the database layer and are unaffected by CaseSensitive or the database collation.
Important Behavior
If
JoinServer.iniis missing or unreadable, the Windows INI parser silently returns the defaults shown above.LicenseKeyends up empty, activation fails, and the process exits at the license-activation step before any socket opens.License activation happens before the database connection, before any TCP listener, and before the UDP heartbeat. If the license service is unreachable at startup there is no offline grace for activation and the process exits.
After successful activation, periodic heartbeats can tolerate transient outages within a runtime grace window; repeated grace entries in a short span force shutdown. This is license-service behavior, not an INI-tunable.
If the database connection fails, no TCP listener is ever opened and no UDP heartbeat is started.
If the TCP listener fails to bind
JoinServerPort, the database connection is closed and no UDP heartbeat is started.If the UDP target in
ConnectServerAddress/ConnectServerPortcannot be resolved or the UDP socket cannot be created, the TCP listener is shut down and the database connection is closed. The IP whitelist is not loaded.AllowableIpList.txtis loaded only after all three of the above succeed. A missing or empty whitelist blocks GameServer connections; see AllowableIpList.txt.GetPrivateProfileString/GetPrivateProfileIntsilently truncate values that exceed the internal buffer sizes. KeepJoinServerODBC,JoinServerUSER, andJoinServerPASSunder 31 characters, andConnectServerAddressunder 15 characters. Quotes and trailing whitespace are preserved literally.
Examples
Common Issues
Startup stops at "Loading files..." -
LicenseKeyis empty, invalid, or the license service is unreachable."Could not connect to database" - DSN name typo, wrong credentials, or the DSN targets the wrong SQL Server instance. No TCP port is opened when this fails.
Every login fails with "account does not exist" - With
MD5Encryption = 0, the account row must match byte-for-byte because of the forced binary collation. Verify the exact casing stored inMEMB_INFO.memb___id.GameServer cannot reach JoinServer -
JoinServerPortchanged but GameServer config was not updated, or a firewall blocks the port, or the GameServer's address is not inAllowableIpList.txt.ConnectServer shows JoinServer as offline even after restart -
ConnectServerPortdoes not match ConnectServer'sConnectServerPortUDP,ConnectServerAddressis wrong, or UDP is blocked between hosts. If the UDP target cannot be set up at startup, JoinServer tears the TCP listener back down.
Last updated