diff --git a/database/realm/RealmModels.py b/database/realm/RealmModels.py index a91817fed..31fc244c5 100644 --- a/database/realm/RealmModels.py +++ b/database/realm/RealmModels.py @@ -341,7 +341,9 @@ class RealmList(Base): realm_id = Column(INTEGER(11), autoincrement=True, nullable=False, primary_key=True) realm_name = Column(String(255), nullable=False, server_default=text("")) proxy_address = Column(String(15), nullable=False, server_default="0.0.0.0") + public_proxy_address = Column(String(15), nullable=False, server_default="0.0.0.0") proxy_port = Column(INTEGER(11), nullable=False, server_default="9090") realm_address = Column(String(15), nullable=False, server_default="0.0.0.0") + public_realm_address = Column(String(15), nullable=False, server_default="0.0.0.0") realm_port = Column(INTEGER(11), nullable=False, server_default="9100") online_player_count = Column(INTEGER(11), nullable=False, server_default="0") diff --git a/etc/databases/realm/updates/updates.sql b/etc/databases/realm/updates/updates.sql index acfad45b7..6fefab87f 100644 --- a/etc/databases/realm/updates/updates.sql +++ b/etc/databases/realm/updates/updates.sql @@ -251,5 +251,14 @@ begin not atomic insert into applied_updates values ('100120251'); end if; + -- 27/04/2025 1 + if (select count(*) from applied_updates where id='270420251') = 0 then + ALTER TABLE realmlist + ADD COLUMN `public_realm_address` VARCHAR(255) DEFAULT '0.0.0.0' AFTER `realm_address`, + ADD COLUMN `public_proxy_address` VARCHAR(255) DEFAULT '0.0.0.0' AFTER `proxy_address`; + + insert into applied_updates values ('270420251'); + end if; + end $ delimiter ; diff --git a/game/realm/RealmManager.py b/game/realm/RealmManager.py index 6f74fcb4f..7348da110 100644 --- a/game/realm/RealmManager.py +++ b/game/realm/RealmManager.py @@ -1,6 +1,7 @@ import os import socket import traceback +import ipaddress from game.world.WorldSessionStateHandler import RealmDatabaseManager from network.packet.PacketWriter import * @@ -9,6 +10,11 @@ from utils.Logger import Logger from utils.constants import EnvVars +def is_private_ip(ip): + try: + return ipaddress.ip_address(ip).is_private + except ValueError: + return False REALMLIST = {realm.realm_id: realm for realm in RealmDatabaseManager.realm_get_list()} @@ -18,20 +24,21 @@ class RealmManager: @staticmethod def serve_realmlist(sck): + client_ip = sck.getpeername()[0] realmlist_bytes = pack(' Private') + else: + forward_address = realm.public_proxy_address + Logger.debug(f'[{sck.getpeername()[0]}] Connection from {client_ip} -> Public') + address_bytes = PacketWriter.string_to_bytes(f'{forward_address}:{realm.proxy_port}') online_count = RealmDatabaseManager.realmlist_get_online_player_count(realm.realm_id) @@ -43,13 +50,19 @@ def serve_realmlist(sck): online_count ) - Logger.debug(f'[{sck.getpeername()[0]}] Sending realmlist...') + Logger.debug(f'[{sck.getpeername()[0]}] Sending realmlist... (sent {forward_address}:{realm.proxy_port})') sck.sendall(realmlist_bytes) @staticmethod def redirect_to_world(sck): - forward_address = os.getenv(EnvVars.EnvironmentalVariables.FORWARD_ADDRESS_OVERRIDE, - config.Server.Connection.WorldServer.host) + client_ip = sck.getpeername()[0] + local_realm = REALMLIST[config.Server.Connection.Realm.local_realm_id] + + if is_private_ip(client_ip): + forward_address = local_realm.realm_address + else: + forward_address = local_realm.public_realm_address + world_bytes = PacketWriter.string_to_bytes(f'{forward_address}:{config.Server.Connection.WorldServer.port}') packet = pack( @@ -57,13 +70,13 @@ def redirect_to_world(sck): world_bytes ) - Logger.debug(f'[{sck.getpeername()[0]}] Redirecting to world server...') + Logger.debug(f'[{client_ip}] Redirecting to world server... (sent {forward_address}:{config.Server.Connection.WorldServer.port})') sck.sendall(packet) @staticmethod def start_realm(running, realm_server_ready): local_realm = REALMLIST[config.Server.Connection.Realm.local_realm_id] - with SocketBuilder.build_socket(local_realm.realm_address, local_realm.realm_port, timeout=2) as server_socket: + with SocketBuilder.build_socket('0.0.0.0', local_realm.realm_port, timeout=2) as server_socket: server_socket.listen() real_binding = server_socket.getsockname() # Make sure all characters have online = 0 on realm start. @@ -90,7 +103,7 @@ def start_realm(running, realm_server_ready): @staticmethod def start_proxy(running, proxy_server_ready): local_realm = REALMLIST[config.Server.Connection.Realm.local_realm_id] - with SocketBuilder.build_socket(local_realm.proxy_address, local_realm.proxy_port, timeout=2) as server_socket: + with SocketBuilder.build_socket('0.0.0.0', local_realm.proxy_port, timeout=2) as server_socket: server_socket.listen() real_binding = server_socket.getsockname() Logger.success(f'Proxy server started, listening on {real_binding[0]}:{real_binding[1]}')