FSD 服务器 — 客户端开发接口文档

目录

  1. 连接与基础
  2. 数据包格式
  3. 客户端命令参考
  4. 服务器推送消息
  5. 错误码
  6. 等级定义
  7. 距离计算与通信范围
  8. 附录:常量与限制

1. 连接与基础

连接方式

客户端通过 TCP 连接到服务器的客户端端口(默认 6809)。

数据编码

  • 纯 ASCII 文本
  • 每行以 \r\n(CRLF)结束
  • 字段以冒号 : 分隔

协议版本

客户端必须在登录时声明协议修订号。当前要求的修订号为 9(NEEDREVISION)。


2. 数据包格式

2.1 客户端到服务器(简化格式)

客户端发送的消息使用命令前缀,后跟冒号分隔的参数:

<命令前缀><参数1>:<参数2>:...

例如:

#APCSN1234::CID001:PASSWORD:3:9:PilotName:0

2.2 服务器到客户端(完整格式)

服务器转发数据包时使用完整的 6 字段格式:

<命令名>:<目标>:<来源>:<包编号>:<跳数>:<数据>
  • 目标 可以是:
    • * — 所有服务器和客户端
    • *A — 所有 ATC
    • *P — 所有飞行员
    • @<频率> — 指定频率上的所有客户端
    • %<呼号> — 指定飞行员
  • 来源 — 发件服务器标识
  • 包编号 — 格式为 B<数字>(广播)或 U<数字>(单播)
  • 跳数 — 经过的服务器数量

客户端收到的转发消息通常通过 MC(多播)包装,格式为:

MC:<命令编号>:<原始来源>:<数据>

3. 客户端命令参考

3.1 ATC 登录 — #AA

登录为 ATC(空中交通管制员)。

格式:

#AA<呼号>:<未知>:<真实姓名>:<CID>:<密码>:<请求等级>:<协议版本>

参数:

参数 说明
<呼号> 管制员呼号(2-12 字符,不能含 !@#$%*:& \t)
<未知> 保留字段,可用空值
<真实姓名> 管制员真实姓名
<CID> 证书 ID
<密码> 证书密码
<请求等级> 请求的等级(0-12,实际等级由服务器确定)
<协议版本> 必须为 9

成功响应:

服务器回复 motd.txt 内容作为 #TM 消息。

失败响应:

$ERserver:<呼号>:<错误码>:<环境>:<错误描述>\r\n

错误码:

错误码 含义
001 呼号已被占用
002 无效呼号
003 已注册
004 语法错误
006 CID/密码无效
010 协议版本无效
011 请求等级过高
012 服务器已满
013 CID/PID 已被暂停

3.2 飞行员登录 — #AP

登录为飞行员。

格式:

#AP<呼号>:<真实姓名>:<CID>:<密码>:<请求等级>:<模拟器类型>:<协议版本>:<真实姓名2>

参数:

参数 说明
<呼号> 飞行员呼号(2-12 字符)
<真实姓名> 飞行员姓名
<CID> 证书 ID
<密码> 证书密码
<请求等级> 请求的等级
<模拟器类型> Sim type identifier
<协议版本> 必须为 9
<真实姓名2> 重复姓名

成功响应: 服务器回复 motd.txt。


3.3 登出 — #DA / #DP

  • #DA — ATC 登出
  • #DP — 飞行员登出

格式:

#DA<呼号>:<CID>
#DP<呼号>:<CID>

3.4 飞行员位置更新 — @

使用 @ 发送飞行员位置更新。

格式:

@<标识标志>:<呼号>:<应答机编码>:<等级>:<纬度>:<经度>:<高度>:<地速>:<PBH>:<标志>

参数:

参数 类型 说明
<标识标志> string 识别标志(ident flag)
<呼号> string 飞行员呼号
<应答机编码> int 应答机编码
<等级> int 飞行员等级
<纬度> float 纬度(-90 ~ 90)
<经度> float 经度(-180 ~ 180)
<高度> int 高度(英尺)
<地速> int 地速(节)
<PBH> unsigned int 编码的俯仰/坡度/航向数据
<标志> int 标志位

注意: PBH 为 32 位无符号整数,编码了俯仰(Pitch)、坡度(Bank)、航向(Heading)三个值。

服务器转发格式: @ 后同上。


3.5 ATC 位置更新 — %

使用 % 发送 ATC 位置更新。

格式:

%<呼号>:<频率>:<设施类型>:<可视范围>:<等级>:<纬度>:<经度>:<高度>

参数:

参数 类型 说明
<呼号> string ATC 呼号
<频率> int 管制频率(如 118100 = 118.100 MHz)
<设施类型> int 设施类型(见下表)
<可视范围> int 可视范围(海里)
<等级> int ATC 等级
<纬度> float 纬度
<经度> float 经度
<高度> int 高度(英尺)

设施类型:

值 类型 通信范围
0 未知 40 NM
1 FSS(飞行服务站) 1500 NM
2 放行许可发布 5 NM
3 地面 5 NM
4 塔台 30 NM
5 进近/离场 100 NM
6 区域管制中心 400 NM
7 监控 1500 NM

3.6 文本消息 — #TM

发送文本消息。

格式:

#TM<来源呼号>:<目标>:<消息内容>

参数:

参数 说明
<来源呼号> 发送者呼号(必须与登录呼号一致)
<目标> * 全部 / *P 所有飞行员 / *A 所有 ATC / @<频率> / %<呼号>
<消息内容> 消息文本

3.7 请求移交 — $HO

请求将飞行器移交给其他 ATC。

格式:

$HO<来源呼号>:<目标ATC呼号>:<飞行器呼号>:<频率>

3.8 接受移交 — $HA

接受来自其他 ATC 的移交请求。

格式:

$HA<来源呼号>:<目标ATC呼号>:<飞行器呼号>:<频率>

3.9 飞行计划 — $FP

提交或更新飞行计划。

格式:

$FP<呼号>:<目标>:<类型>:<机型>:<巡航速度>:<起飞机场>:<计划起飞时间>:<实际起飞时间>:<巡航高度>:<目的地机场>:<航路小时>:<航路分钟>:<燃油小时>:<燃油分钟>:<备降机场>:<备注>:<航路>

参数:

参数 类型 说明
<呼号> string 飞行员呼号
<目标> string 目标(通常为 *A)
<类型> char 飞行计划类型
<机型> string 飞机型号(如 B737)
<巡航速度> int 巡航速度(节 TAS)
<起飞机场> string 起飞机场 ICAO(如 KJFK)
<计划起飞时间> int 计划起飞时间(Zulu,HHMM 格式)
<实际起飞时间> int 实际起飞时间
<巡航高度> string 巡航高度(如 FL350 或 35000)
<目的地机场> string 目的地机场 ICAO
<航路小时> int 预计航路时间(小时)
<航路分钟> int 预计航路时间(分钟)
<燃油小时> int 燃油时间(小时)
<燃油分钟> int 燃油时间(分钟)
<备降机场> string 备降机场 ICAO
<备注> string 备注信息
<航路> string 航路字符串

注意: 总共 17 个字段(含呼号和目标),从 array[2] 开始解析,因此实际数据有 15 个字段。

服务器转发:

$FP<呼号>:<目标>:<修订号>:<类型>:<机型>:<巡航速度>:<起飞机场>:<计划起飞时间>:<实际起飞时间>:<巡航高度>:<目的地机场>:<航路小时>:<航路分钟>:<燃油小时>:<燃油分钟>:<备降机场>:<备注>:<航路>

3.10 Ping / Pong — $PI / $PO

Ping 格式:

$PI<来源呼号>:<目标>

Pong 格式:

$PO<来源呼号>:<目标>

服务器会以多播方式转发这些消息。


3.11 请求气象 — #RW

请求气象数据。

格式:

#RW<呼号>:<目标>:<ICAO 代码>

参数:

参数 说明
<呼号> 来源呼号
<目标> 目标(通常为 SERVER 或特定服务器)
<ICAO 代码> 气象站 ICAO 代码(如 KJFK)

服务器会向网络中的 METAR 服务器转发请求。响应通过 #WX(解析后)或气象数据消息返回。


3.12 气象数据 — #WX / #CD / #WD / #TD

服务器向客户端发送解析后的气象数据。

温度数据 (#TD):

#TDserver:<呼号>:<层1顶高>:<层1温度>:<层2顶高>:<层2温度>:<层3顶高>:<层3温度>:<层4顶高>:<层4温度>:<气压>

共 4 个温度层,每层包含顶高(高度)和温度。

风数据 (#WD):

#WDserver:<呼号>:<层1顶高>:<层1底高>:<层1风向>:<层1风速>:<层1阵风>:<层1湍流>:...

共 4 个风层,每层 6 个参数。

云数据 (#CD):

#CDserver:<呼号>:<层1顶高>:<层1底高>:<层1覆盖度>:<层1结冰>:<层1湍流>:<层2...>:<层3...>:<能见度>

包含 3 层(第 3 层为雷暴云)和能见度。


3.13 ACARS 请求 — $AX / $AR

ACARS 请求 ($AX):

$AX<呼号>:<目标>:<数据类型>:<参数>

ACARS 回复 ($AR) — 用于 METAR 请求:

$AR<来源>:<目标>:METAR:<原始 METAR 数据>

示例: 请求 METAR:

$AX呼号:server:METAR:KJFK

响应:

$ARserver:呼号:METAR:KJFK 010150Z 23015KT 10SM SCT020 20/18 A2992

3.14 自定义查询 — $CQ / $CR

查询格式 ($CQ):

$CQ<来源>:<目标>:<查询类型>:<参数>
  • 查询 RN(真实姓名):

    $CQ<来源>:<目标呼号>:RN
    

    响应 ($CR):

    $CR<目标呼号>:<来源>:RN:<真实姓名>:USER:<等级>
    
  • 查询飞行计划 (fp):

    $CQ<来源>:SERVER:fp:<目标呼号>
    

    响应: 飞行计划数据通过 $FP 返回。


3.15 客户端类型 — #SB / #PC

  • #SB — 标识为 SquawkBox 客户端
  • #PC — 标识为 ProController 客户端

格式:

#SB<来源>:<目标>
#PC<来源>:<目标>

3.16 强制断开 — $!!

请求强制断开某个客户端连接(需要等级 ≥ 11,Supervisor)。

格式:

$!!<来源>:<目标呼号>:<原因>

4. 服务器推送消息

4.1 新客户端加入 (#AA / #AP)

服务器在网络上广播所有客户端的存在:

ATC 加入:

#AA<呼号>:SERVER:<真实姓名>:<CID>:<等级>:<协议>

飞行员加入:

#AP<呼号>:SERVER:<CID>:<等级>:<协议>:<模拟器类型>

目标为 *(所有客户端),包含新 ATC/飞行员的完整信息。

4.2 客户端离开 (#DA / #DP)

#DA<呼号>:<CID>
#DP<呼号>:<CID>

4.3 飞行员位置 (@)

@<标识标志>:<呼号>:<应答机编码>:<等级>:<纬度>:<经度>:<高度>:<地速>:<PBH>:<标志>

4.4 ATC 位置 (%)

%<呼号>:<频率>:<设施类型>:<可视范围>:<等级>:<纬度>:<经度>:<高度>

4.5 飞行计划 ($FP)

$FP<呼号>:<目标>:<修订号>:<类型>:<机型>:<巡航速度>:<起飞机场>:<计划起飞时间>:<实际起飞时间>:<巡航高度>:<目的地机场>:<航路小时>:<航路分钟>:<燃油小时>:<燃油分钟>:<备降机场>:<备注>:<航路>

4.6 多播包装 (MC)

服务器间转发的客户端消息多包含在 MC 中。MC 后的数据格式为:

MC:<命令编号>:<来源呼号>:<原始数据>

例如 MC 包装的文本消息:

MC:5:<来源呼号>:<原始来源>:<目标>:<消息内容>

4.7 移除客户端 (Kill)

$!!SERVER:<呼号>:<原因>

4.8 风偏移量更新 (#DL)

#DLSERVER:*:<风速变化>:<风向变化>

服务器每 WINDDELTATIMEOUT(70 秒)广播一次风偏移量,风速变化范围为 -5 ~ +5 节,风向变化范围为 -10 ~ +10 度。

4.9 温度数据 (#TD)

#TDserver:<目标>:<层1>-<层4的气温数据>:<气压>

4.10 风数据 (#WD)

#WDserver:<目标>:<层1>-<层4的风数据>

4.11 云数据 (#CD)

#CDserver:<目标>:<3层云数据>:<能见度>

4.12 错误消息 ($ER)

$ERserver:<呼号>:<错误码>:<环境>:<描述>

5. 错误码

编码 常量 描述
000 ERR_OK 无错误
001 ERR_CSINUSE 呼号已被占用
002 ERR_CSINVALID 无效呼号(长度 < 2 或 > 12,或含非法字符)
003 ERR_REGISTERED 已注册(客户端已在登录状态)
004 ERR_SYNTAX 语法错误
005 ERR_SRCINVALID 来源呼号无效
006 ERR_CIDINVALID CID/密码无效
007 ERR_NOSUCHCS 无此呼号
008 ERR_NOFP 无飞行计划
009 ERR_NOWEATHER 无此气象数据
010 ERR_REVISION 协议版本无效
011 ERR_LEVEL 请求等级过高
012 ERR_SERVFULL 服务器已满
013 ERR_CSSUSPEND CID/PID 已被暂停

6. 等级定义

ATC 与飞行员等级

值 等级
0 暂停 (SUSPENDED)
1 观察员 (OBS Pilot)
2 学员 1 (Student 1)
3 学员 2 (Student 2)
4 学员 3 (Student 3)
5 管制员 1 (Controller 1)
6 管制员 2 (Controller 2)
7 管制员 3 (Controller 3)
8 教员 1 (Instructor 1)
9 教员 2 (Instructor 2)
10 教员 3 (Instructor 3)
11 监督员 (Supervisor)
12 管理员 (Administrator)

注意: 等级 0(暂停)的客户端无法登录。等级 ≥ 11 可执行 $!! 强制断开其他客户端。


7. 距离计算与通信范围

通信范围

飞行员通信范围 (基于高度):

range = 10 + 1.414 * sqrt(高度)
  • 高度单位为英尺
  • 结果单位为海里

ATC 通信范围 (基于设施类型):

设施类型 通信范围 (NM)
0 — 未知 40
1 — FSS 1500
2 — 放行 5
3 — 地面 5
4 — 塔台 30
5 — 进近/离场 100
6 — 区域管制 400
7 — 监控 1500

距离计算

服务器使用大圆距离(Great-circle distance)计算两个客户端之间的距离(单位:海里)。


8. 附录:常量与限制

超时设置

常量 值 说明
USERTIMEOUT 500 秒 用户连接空闲超时
SERVERTIMEOUT 800 秒 服务器连接空闲超时
CLIENTTIMEOUT 800 秒 客户端空闲超时
SILENTCLIENTTIMEOUT 36000 秒 静默模式客户端超时
USERPINGTIMEOUT 200 秒 Ping 间隔
MAXHOPS 10 最大跳数,防止环路

数据包限制

常量 值 说明
MAXLINELENGTH 512 单行最大长度
CALLSIGNBYTES 12 呼号最大长度
内部缓冲区 1000 数据包组装缓冲区大小

客户端类型 (type)

常量 值
CLIENT_PILOT 1
CLIENT_ATC 2
CLIENT_ALL 3

快速开始示例

飞行员登录流程示例

连接到 127.0.0.1:6809

→ #AP呼号:姓名:CID:密码:1:0:9:姓名
← #TMserver:呼号:FSFDT Windows FSD Beta from FSD V3.000 draft 9
← #TMserver:呼号:Welcome to the FSD server...
← #AP呼号:SERVER:CID:1:9:0

→ @ID:呼号:1200:1:40.7128:-74.0060:35000:450:0:0
← @ID:呼号:1200:1:40.7128:-74.0060:35000:450:0:0

→ $FP呼号:*A:I:B738:450:KJFK:1200:0:FL350:KLAX:5:30:6:0:KPHX:REMARKS:ROUTE
← $FP呼号:*A:0:I:B738:450:KJFK:1200:0:FL350:KLAX:5:30:6:0:KPHX:REMARKS:ROUTE

→ #DP呼号:CID
posted @ 2026-06-23 17:13  梨猫先森  阅读(25)  评论(0)    收藏  举报