# ServerInfo (P10) —— 服务器列表 + 频道 → (host, port)。 # # var si := ServerInfo.new() # si.load_file("res://serverlist.txt") # 可选;没有就用内置默认 # for s in si.servers(): ... # var addr := si.address(server_index, channel) # {auth_host,auth_port,game_host,game_port} # # 文件格式(TSV,# 注释): # name auth_host auth_port game_host game_port channels(csv) [port_step] [mark_port] # 测试服 192.168.21.203 11000 192.168.21.203 13002 1,2,3,4 10 0 # # 频道 N 的 game 端口 = game_port + (N-1)*port_step。 # 这套 40250 配置的 Game2 端口是 13002/13012/13022/13032(step=10)。 # 13000/13010/... 是 first 入口;admin 测试角色在 Game2 地图,直接连 Game2 才能完成进入游戏。 # 第 8 列 mark_port = 公会会徽服端口(0 = 不下载会徽)。 class_name ServerInfo extends RefCounted const DEFAULT_PORT_STEP := 1 var _servers: Array = [] func _init() -> void: # 内置默认:40250 服务器(认证 11000,channel1/Game2 端口 13002) _servers = [{ "name": "测试服", "auth_host": "192.168.21.203", "auth_port": 11000, "game_host": "192.168.21.203", "game_port": 13002, "channels": [1, 2, 3, 4], "port_step": 10, "mark_port": 0, }] func load_file(path: String) -> bool: if not FileAccess.file_exists(path): return false var f := FileAccess.open(path, FileAccess.READ) if f == null: return false var out: Array = [] while not f.eof_reached(): var line := f.get_line().strip_edges() if line == "" or line.begins_with("#"): continue var c := line.split("\t", false) if c.size() < 5: c = line.split(" ", false) # 容忍空格分隔 if c.size() < 5: continue var chans: Array = [] if c.size() >= 6: for t in String(c[5]).split(",", false): chans.append(int(t)) if chans.is_empty(): chans = [1] var step := DEFAULT_PORT_STEP if c.size() >= 7 and int(c[6]) > 0: step = int(c[6]) var mark_port := 0 if c.size() >= 8 and int(c[7]) > 0: mark_port = int(c[7]) out.append({ "name": String(c[0]), "auth_host": String(c[1]), "auth_port": int(c[2]), "game_host": String(c[3]), "game_port": int(c[4]), "channels": chans, "port_step": step, "mark_port": mark_port, }) if out.is_empty(): return false _servers = out return true func servers() -> Array: return _servers func count() -> int: return _servers.size() func server(idx: int) -> Dictionary: return _servers[idx] if idx >= 0 and idx < _servers.size() else {} # 返回 {auth_host, auth_port, game_host, game_port},game_port 已按频道偏移。 func address(server_idx: int, channel: int = 1) -> Dictionary: var s := server(server_idx) if s.is_empty(): return {} var ch: int = maxi(1, channel) var step: int = int(s.get("port_step", DEFAULT_PORT_STEP)) return { "auth_host": s["auth_host"], "auth_port": s["auth_port"], "game_host": s["game_host"], "game_port": int(s["game_port"]) + (ch - 1) * step, "mark_host": s["game_host"], "mark_port": int(s.get("mark_port", 0)), }