HWID protection system for private Lineage 2 L2J servers
Collects the computer's HWID and sends it to the protection server via TCP:46500
Checks the HWID against the MySQL database and decides — allow or block
Loaded into JVM via LD_PRELOAD and communicates with lin2guard via UDP:46540
Lin2Guard-V1/ ├── clientside/ │ └── system/ │ └── l2.exe ← distribute to players └── serverside/ ├── guard/ │ ├── lin2guard_linux_amd64 ← protection server binary (Linux x86_64) │ ├── config.xml ← configuration │ ├── start.sh ← launch with auto-restart │ ├── startscreen.sh ← background launch via screen │ └── getscreen.sh ← attach to logs └── gameserver/ ├── guard.so ← LD_PRELOAD hook for L2J Java server └── run.sh ← example game server launch with hook
The player's client folder contains the original system/l2.exe. It needs to be replaced with ours.
system/l2.exe → system/l2.binclientside/system/l2.exe into the client's system/ folderl2.exe to players — protection works automatically on game launch
serverside/guard/ folder to your Linux hosting
CREATE DATABASE lin2guard;
config.xml — set the address, ports, and database credentials (details — in the Configuration section below)
cd /path/to/guard/folder/ chmod +x lin2guard_linux_amd64 start.sh startscreen.sh ./startscreen.sh
./getscreen.sh
Detach without stopping: Ctrl+A, then D
serverside/gameserver/guard.so to your game server folder
GameServer_loop.sh or similar)
LD_PRELOAD — see example below:
# Server chronicle (salvation, interlude, etc.) export CHRONICLE=salvation # Hook UDP port (must match hook_addr in config.xml) export INTPTR=46540 # Game server ID export GSID=2 # Protection server IP (127.0.0.1 if guard is on the same machine) export INTIPADDR=127.0.0.1 # Logs: 0 = minimal (prod), 1 = verbose (dev) export L2G_DEBUG=0 # For testing: uncomment to temporarily disable authorization check #export NOCHECK=1 HOOK_SO="guard.so" # Start Java with hook (keep other params from your own script): LD_PRELOAD="$HOOK_SO" java ... -cp config:./../libs/* l2e.gameserver.GameServer
LD_PRELOAD="guard.so". Keep all other java parameters from your own script.<config> <!-- Port for client connections (l2.exe). Open in firewall. --> <listen_addr>0.0.0.0:46500</listen_addr> <!-- Port for guard.so communication. Keep 127.0.0.1 if on the same machine. --> <!-- To disable the hook — remove this line or leave it empty. --> <hook_addr>127.0.0.1:46540</hook_addr> <!-- Maximum number of game windows per HWID --> <max_windows>2</max_windows> <!-- Client reconnection timeout in ms (45000 = 45 sec) --> <ping_timeout_ms>45000</ping_timeout_ms> <!-- false = important events only (prod), true = verbose logs (dev) --> <debug>false</debug> <!-- Connection settings for the lin2guard database --> <db> <host>127.0.0.1</host> <port>3306</port> <user>root</user> <pass>YOUR_PASSWORD</pass> <name>lin2guard</name> </db> <!-- Optional: sync HWID with the game DB (characters.hwid field) --> <!-- Uncomment the <gamedb> block and specify the game DB credentials. --> <!-- <gamedb> ... </gamedb> --> </config>
| Port | Purpose | External access | Note |
|---|---|---|---|
| 46500 / TCP | Client connections (l2.exe) | ✓ Open | Open in firewall for external connections |
| 46540 / UDP | Hook guard.so ↔ lin2guard | ✗ Close | Localhost only — not needed externally |
| 3306 / TCP | MySQL | ✗ Close | Localhost only, do not expose externally |
guard.so must be located next to run.sh in the gameserver/ folder. The path in the script is relative to the launch directory.
Check that port 46500/TCP is open in the firewall. Make sure lin2guard is running:
ps aux | grep lin2guard
Check connectivity between guard.so and lin2guard — port 46540/UDP must be reachable. For testing, temporarily uncomment NOCHECK=1 in run.sh.
Check the connection settings in config.xml → <db> block. The lin2guard database must exist before starting guard:
CREATE DATABASE lin2guard;