1安装与启用

LinuxTAB 不需要前置插件,一个 jar 就能跑。队伍、头衔、假人都是可选的联动项:装了谁就接谁,没装也只是少一块信息,不会报错、不会影响其它功能。

  1. 把 LinuxTAB-26.11.8.jar 放进服务器的 plugins/ 目录。服务端用 Paper 或 Spigot 1.12.2,Java 8 及以上。
  2. 重启服务器。第一次启动会生成 plugins/LinuxTAB/config.yml,默认就是「2 列 × 20 行、补空位、延迟列开」。
  3. 看一眼控制台的启动摘要,确认列数、补位、延迟列、PlaceholderAPI 都是你要的状态。
  4. 之后改配置只需要 /linuxtab reload,不用重启服务器;玩家列表会在下一次刷新(默认 20 tick)内变过来。

正常启动时控制台是这样两行:

[LinuxTAB] LinuxTAB 已启用 —— 布局 2 列 × 20 行(人数不足补空位),延迟列 开,PlaceholderAPI 已接上
[LinuxTAB] [联动] 已接上 LinuxTeam 队伍 / LinuxTitle 头衔 / FakePlayerPlugin 假人(默认不显示在列表里)

如果第二行里某一段写的是「未检测到」,说明对应的插件没装或没启用,那一项功能会自动关掉,其余照常工作。想让队伍、头衔、假人都显示出来,把 LinuxTeam、LinuxTitle、FakePlayerPlugin 一起装上即可,LinuxTAB 启动时会自己认。

⚠️
先卸掉别的 TAB 类插件 同一时间只能有一个插件改玩家列表。TAB、sTablist 这类插件也在接管列表,同时装会互相覆盖,表现是列表闪来闪去、只剩一列,或者干脆变回原版。装 LinuxTAB 之前先停用它们,处理办法见 常见问题 第一条。

配置放在哪

插件的所有配置都在一个文件里,没有子目录、没有数据库:

plugins/LinuxTAB/
└── config.yml

改完存盘,执行 /linuxtab reload。如果配置写错(缩进错了、键名拼错),插件不会崩,会在控制台打一行黄色警告并保留旧配置继续跑,修好再 reload 一次就行。

2布局:怎么让人少也是多列

1.12.2 的客户端把玩家列表画成一张固定网格:每列固定 20 行,最多 4 列。行数是客户端写死的,服务端改不了;服务端唯一能决定的是「谁被塞进第几列第几行」。

所以在线只有 12 个人的时候,如果只发 12 个条目,客户端就只画一列 12 行,右边三列是空的——看起来根本没有多列。LinuxTAB 的做法是按列补位:把空条目补齐到整列(20 的倍数),多列布局在人少时也成立,题目里的「人少也是多列」就是这么来的。

配置项

键默认值说明
layout.columns2列数,取 1 ~ 4。1.12.2 客户端只认 4 列,写大于 4 会被压回 4。
layout.rows20每列行数。1.12.2 客户端就是 20,改小只会让补位少填几行,一般不要动。
layout.pad-emptytrue人数不足时用空条目补满整列。关掉它,人少时就只剩一列。
layout.include-fakesfalse假人要不要出现在 TAB 里。默认 false:每轮刷新都会把 FakePlayerPlugin 加进来的假人条目移除,列表里只有真人。改成 true 后假人排在真人上面。
layout.fakes-firsttrue假人排最前面(true)还是按 layout.sort 和真人混排(false)。只有开了 include-fakes 才有意义。
layout.fillcolumncolumn = 先填满第一列再换列,真人紧跟在假人下面;balance = 按列均分,几列的高度尽量一样。
layout.empty-name&7补位条目显示的名字。留一个颜色码就是一条看不见的空白,不要写成文字,否则列表里会多出 20 个「空」。
layout.empty-skin.value""补位条目的皮肤纹理值(base64)。不填就是客户端默认的白色 Steve 头。
layout.empty-skin.signature""上面那个纹理值对应的签名,两个要成对填。

两种填充方式怎么选

column 是默认值:假人排第一列开头,真人接着往下排,第一列满了才换第二列,视觉上最像「一列名单接着一列名单」。balance 会把总数平均摊到每一列,比如 30 个人分 2 列就是 15 + 15,看起来更对称,代价是玩家进出的瞬间偶尔会看到整列重排。

一个完整的布局配置

layout:
columns: 3 # 3 列 × 20 行 = 60 个位置
rows: 20
pad-empty: true # 人少也补满,多列才整齐
fill: column
empty-name: "&7"
empty-skin:
value: ""
signature: ""
ℹ️
改列数需要全员重进吗 不用。列数变化后插件会重新发一遍列表,在线玩家下一秒就能看到新布局。只有补位空条目的皮肤需要客户端重新拉取纹理,换过皮肤的话让玩家重进一次更稳妥。

3顺序规则(重要)

LinuxTAB 发出去的最终顺序是:真人(各自队伍)→ 补位空行。真人按队伍聚在一起,空行全部沉底。假人默认不进列表,需要的话在配置里打开 layout.include-fakes,打开后假人排在真人上面。

客户端会自己重排,你要顺着它来

1.12.2 客户端拿到玩家列表后并不会照抄服务端给的顺序,它会按三个键重新排序:是否旁观 → 计分板队伍名 → 玩家名。也就是说,服务端发过去的顺序会被打乱一遍,插件必须让「排序结果」也符合预期,否则你看到的永远是乱序。

补位空条目就是这里最容易翻车的:它们没有队伍、名字又只有一个颜色码,客户端一排就会把它们排到中间去,于是「真人被空行挤到中间」或者「真人掉到最后一行」。LinuxTAB 的处理是——把补位空条目全部塞进一个队名以 U+FFFF 开头的计分板队伍里,这个字符比任何正常字符都大,客户端按队伍名排序时必然把它们排到最后,空行就永远沉底了。

# 插件内部创建的补位队伍(不需要你手动维护)
队伍名: \uFFFF_linuxtab_pad
成员: 所有补位空条目
作用: 让空行在客户端排序里永远排最后
ℹ️
这条队伍不会碰你的 LinuxTeam 补位队伍是插件自己建、自己删的,只用来放空条目。它不会改动 LinuxTeam 建的任何队伍,也不会影响玩家的队伍归属。你可以在 /scoreboard teams list 里看到它,插件停用时会一起清掉,下次启动再建回来。

假人默认不显示

假人是 FakePlayerPlugin 创建的服务器端玩家,它为了让假人有皮肤、也让别的插件(经济、在线统计)认得出它,会自己把假人加进玩家列表——客户端随即会把假人画进 TAB。LinuxTAB 默认的处理是把假人条目摘掉:每轮刷新都发一次移除,进服瞬间也会补一刀,所以列表里只有真人。

想看到假人,把 layout.include-fakes 改成 true 再 /linuxtab reload。打开后假人排在真人上面(用的是假人自己的 UUID,不会和真人重条目),顺序是假人(无队伍)→ 真人(各自队伍)→ 补位空行。

ℹ️
为什么假人插件非要加进去 假人如果只在服务端存在、客户端不认识,它会没有皮肤、看不见头顶名字,别的插件统计在线人数时也会漏掉。所以 FakePlayerPlugin 主动加进玩家列表;「在 TAB 里显示不显示」这件事交给 LinuxTAB 决定,两个插件各管一段,配置在 layout.include-fakes。

4头尾面板

玩家列表上方(header)和下方(footer)的两块文字面板。LinuxTAB 允许你写多套设计,按世界、按条件切换,每套面板里还能用动画和 PlaceholderAPI 变量。

配置项

键默认值说明
header-footer.enabledtrue头尾面板总开关。关掉后玩家列表只有名字,没有上下两块。
header-footer.refresh-ticks20刷新间隔(tick)。20 = 每秒一次。放进打字机动画时插件会自动压到 4,见下一节。
header-footer.activedefault默认用哪套设计。条件不匹配任何设计时回落到它。
header-footer.designs.<名字>.display-condition""生效条件,空表示不限制。语法见下。
header-footer.designs.<名字>.header""面板上部文字,可以多行(用 \n 换行)。
header-footer.designs.<名字>.footer""面板下部文字,同样支持多行。

display-condition 怎么写

条件是一串「变量 符号 值」的判断,多条用分号 ; 隔开,必须全部满足才生效。符号支持 = 和 !=。

designs:
lobby:
display-condition: "%world%=world" # 只在大厅世界生效
header: "&b&lNalxer 服务器"
footer: "&7在线 &f%online%&7/&f%max%"
nether:
display-condition: "%world%!=world;%world%!=spawn" # 不在大厅和主城时生效
header: "&c&l下界 · 小心恶魂"
footer: "&7TPS &f%tps%"

可用变量

变量内容
%player%当前玩家的名字
%online%在线真人数量
%max%服务器人数上限
%fakes%在线假人数量(FakePlayerPlugin 联动时有效)
%total%真 + 假的总数
%staffonline%在线管理员数量,按 linuxtab.staff 权限统计
%tps%最近一分钟 TPS,保留两位
%world%玩家所在世界的名字
%ping%这名玩家自己的延迟
%team%所属 LinuxTeam 队伍名,没有队伍时用 player-list.no-team
%title%所属 LinuxTitle 头衔,没有头衔时用 player-list.no-title
%animation:time%当前时间,格式 HH:mm:ss
%animation:date%当前日期
其它 %xxx%原样交给 PlaceholderAPI。PAPI 有的变量这里都能用,包括 %animation_<名字>% 这类扩展。
ℹ️
变量里带颜色怎么办 变量替换进来的内容如果是 & 色码,插件会先翻译再发出去,所以 PAPI 里返回 &a 开头的字符串也能正常上色。玩家名里的颜色码会被剥掉,避免把整行颜色搞乱。

5动画与打字机

头尾面板里的文字可以动起来:按帧轮播,或者用打字机一个字一个字打出来。动画定义在 animations 下面,用 %animation:<名字>% 引用。

配置项

键默认值说明
animations.<名字>.styleframestypewriter = 打字机逐字显示;frames = 按 frames 列表轮播。
animations.<名字>.interval4每帧间隔,单位是 tick。4 = 每 0.2 秒一帧。
animations.<名字>.frames[]frames 模式下的文字列表,从头循环。
animations.<名字>.text""typewriter 模式要打出来的那一整句。
animations.<名字>.color&f打字机文字的颜色,写一个颜色码即可。
animations.<名字>.hold30打完(或收完)之后停留多少帧再继续,单位同样按 interval 算。

打字机的完整过程

以 text: "欢迎回来" 为例,一整个循环是这样的:

欢 → 欢迎 → 欢迎回 → 欢迎回来(停 hold 帧)→ 欢迎回 → 欢迎 → 欢 → 空(停一下)→ 从头再来。

也就是打完不会硬切回空,而是原路收回去,看起来像有人在敲键盘又删掉。想让收字更快,把 hold 调小即可;不想收字就直接用 frames 轮播。

animations:
welcome:
style: typewriter
interval: 4 # 每 0.2 秒一个字
text: "欢迎回来"
color: "&b"
hold: 30 # 打完停 30 帧 = 1.5 秒
tips:
style: frames
interval: 40 # 每 2 秒切一条
frames:
- "&7输入 &f/help&7 看指令"
- "&7加入交流群 &f123456789"
- "&7TPS &a%tps%"
⚠️
用打字机时插件会自动把刷新压到 4 tick 头尾面板默认每 20 tick(1 秒)才刷新一次。打字机按 4 tick 一帧走,如果面板还按 1 秒刷新,玩家看到的就是每秒跳一个字,卡得像坏了。所以只要某个设计里用到了打字机动画,LinuxTAB 会自动把这个面板的 refresh-ticks 压到 4,不用你手动改。你手写了 refresh-ticks: 20 也一样会被压下来。
ℹ️
刷新太勤会不会卡 4 tick 只影响面板文字的下发,不重算玩家列表,开销很小。真正要留意的是动画帧数:interval 别低于 2,帧数别堆到几十条,否则每个在线玩家每秒都会收到几十次字符串更新。

6玩家名格式

列表里每个名字显示成什么样,由 player-list.name-format 决定。它是一段模板,支持颜色码和几个占位符,插件会把它们换成队伍、头衔和玩家名。

键默认值说明
player-list.name-format&7[%team%&7] %title%&f%name%整行的格式。%team% 队伍名、%title% 头衔、%name% 玩家名。
player-list.no-team&8无队伍玩家没有队伍时 %team% 的值。想直接不显示,把它设成空字符串。
player-list.no-title""玩家没有头衔时 %title% 的值,默认空。
layout.max-name-length16名字最长显示多少字符,超出的部分截断。列宽有限,太长会把后面的延迟列顶出去。
⚠️
队伍 / 头衔被别的插件吃掉? 玩家列表名是所有插件共用的一个字段,TAB、sTablist、称号类插件都会往它上面写。同一台服务器只留一个改玩家列表的插件:还装着 TAB / sTablist 的,先把它们和对应的配置目录一起移走,否则两边每秒互相覆盖,看到的就是「有时候有队伍、有时候没有」。LinuxTAB 这边已经加了一层兜底:列表没变化时也每秒重发一次「队伍 + 头衔 + 名字」,被覆盖后一秒内会自己长回来。

默认格式渲染出来是这样,队伍和头衔各带一层方括号:

&7[%team%&7] %title%&f%name%
↓
[元老院] [元老] Steve
ℹ️
头衔只要一层括号 LinuxTitle 里的 prefix 一般已经自带方括号(比如 [元老])。如果你的头衔显示成 [[元老]],把格式里的 %title% 前后的括号去掉,或者把 LinuxTitle 的 prefix 改成不带括号的写法。
⚠️
格式里别塞太长的固定文字 每行名字的宽度是固定的。&7[%team%&7] %title%&f%name% 这样的长度基本刚好,再往前面加「玩家」「会员」之类的固定文字,长 ID 就会被截断或换行。

7延迟列

延迟列用玩家列表右侧的计分板区域显示每个人的 ping,数值直接取自服务端记录的连接延迟,不额外发包,也不影响性能。

键默认值说明
player-list.ping.enabledtrue延迟列开关。关掉后右侧计分板不显示 ping。
player-list.ping.titlePing计分板标题,也就是这一列最上面那行字。最多 32 个字符,超出的部分会被自动截断。
player-list.ping.refresh-ticks20更新间隔,20 = 每秒刷新一次数值。

单元格的显示格式是 &7%ping% ms 这种风格:前面一个颜色码,中间是数字,后面跟单位。分档着色也会自动做——延迟低的偏绿、偏高偏黄、再高偏红,方便一眼看出谁在卡。

player-list:
ping:
enabled: true
title: "&bPing"
refresh-ticks: 20
ℹ️
和原来的计分板会打架吗 延迟列只在玩家列表界面里生效,不占用主世界的侧边栏计分板,也不影响你其它插件的 scoreboard。玩家关掉列表界面就看不到它。
⚠️
标题不要写太长 1.12.2 客户端读这个字段的上限是 32 个字符,写超了玩家一进服会被踢下线(客户端报 The received string length is longer than maximum allowed)。插件已经会按 32 字符自动截断,这里只提醒别指望长标题能显示全。

8命令

命令不多,日常只用得到 reload。所有子命令都需要 linuxtab.admin 权限,默认只有 OP 有。

命令别名说明权限
/linuxtab info/ltab info打印当前状态:列数、每列行数、补位开关、填充方式、在线/假人数量,以及 LinuxTeam、LinuxTitle、FakePlayerPlugin、PlaceholderAPI 四个联动的连接结果。linuxtab.admin
/linuxtab reload/ltabreload重新读取 config.yml 并重建玩家列表、头尾面板和延迟列。配置有错时保留旧配置并在控制台给警告。linuxtab.admin
/linuxtab debug/ltab debug开关调试日志。打开后控制台会额外打印 [布局] 和 [头尾] 两类行,排查顺序和面板问题时用。linuxtab.admin

debug 打开后能看到什么

# 每次重发列表时打印
[布局] 列数 2 行数 20 补位 开 填充 column | 假人 3 真人 17 空行 20 合计 40
[布局] 第 1 位 fake:Steve_01 第 2 位 fake:Alex_02 … 第 21 位 player:Notch 第 40 位 pad
# 头尾面板刷新时打印
[头尾] 玩家 Notch 命中设计 lobby(%world%=world)帧 12/24

顺序不对的时候,先看第一行的「合计」是不是 20 的整数倍。不是整数倍说明补位没生效,检查 layout.pad-empty 和 layout.rows;是整数倍但人还是掉到最后,把第二行发出来看空行到底排在第几位。

ℹ️
调试日志记得关 列表刷新很频繁,debug 开着会让控制台刷得很快,排查完再执行一次 /linuxtab debug 关掉就好。重启服务器也会自动关掉。

9常见问题

装了 LinuxTAB,玩家列表还是原来那样
九成是还有别的插件在改列表,而且它比 LinuxTAB 更新得更勤。按顺序排查:
① 看 plugins/ 里有没有 TAB.v6.1.0.jar,有就删掉;
② 看根目录有没有 TAB/ 文件夹,那是 TAB 插件的数据目录,一起移走,留着也可能被别的插件读;
③ 看有没有 sTablist 这类插件,同样停用;
④ 执行 /linuxtab reload,再让玩家退出重进一次。
这几步做完还是原版样式,用 /linuxtab info 看插件是否真的启用了,以及控制台有没有报错。
真人总是掉到最后一行 / 被空行挤到后面
这个已经修了:补位空行现在全部放进队名以 U+FFFF 开头的计分板队伍里,客户端按队伍名排序时它们必然沉底,不会再插到真人中间。
如果升级之后还出现,先确认你确实用的是 26.11.8,然后 /linuxtab debug 打开调试,看 [布局] 那行打印的位次——空行应该全部排在所有 player: 之后。顺序对但显示不对,通常是客户端缓存,让玩家退出列表界面再打开一次。
头衔显示了两遍,变成 [[元老]]
LinuxTitle 的 prefix 一般已经自带方括号([元老]),而默认格式 &7[%team%&7] %title%&f%name% 里 %title% 是没有再加括号的,所以正常不会重复。
出现双括号说明你在格式里手动加了 [%title%],或者 LinuxTitle 的 prefix 本身就带了一层括号又被你加了一层。删掉格式里多出来的那对括号即可;title() 已经处理过占位,不需要你再包一层。
补位的空位是个白色默认头,很显眼
那是客户端在皮肤纹理缺失时画的默认 Steve 头。配 layout.empty-skin 就行:value 填 base64 纹理值,signature 填对应的签名,两个要成对。想完全看不见,可以把 layout.empty-name 设成只有一个颜色码(默认就是 &7),再配一个接近背景色的透明皮肤。
注意换皮肤后客户端要重新拉纹理,让玩家重进一次才会变。
写了 hex 颜色(&#55FFFF)但没生效
1.12.2 客户端不支持 16 位 hex 颜色,这是客户端版本的限制,不是配置写错。LinuxTAB 会自动降级:把 hex 解析成最接近的 16 色之一再发出去,所以颜色不会变成乱码,只是没有原色那么准。
想要稳定可控,建议直接用 &0 ~ &f 和 &l 这些原版色码写配置。等服务器升到 1.16+ 再换 hex 才有效果。

10配置全表

下面这张表是 config.yml 里 LinuxTAB 用到的全部键,默认值和说明都在里面。左边一列可以直接对照你的配置文件。

键默认值说明
layout.columns2列数 1 ~ 4,客户端最多 4 列。
layout.rows20每列行数,1.12.2 客户端固定 20,一般不改。
layout.pad-emptytrue人少时补空条目,保证多列成立。
layout.fillcolumncolumn 先填满一列再换列;balance 按列均分。
layout.empty-name&7空条目的显示名,只留颜色码最干净。
layout.empty-skin.value""空条目的皮肤纹理 base64。
layout.empty-skin.signature""与上面成对的签名。
layout.max-name-length16名字最长显示字符数,超出截断。
header-footer.enabledtrue头尾面板总开关。
header-footer.refresh-ticks20面板刷新间隔,用打字机时自动压到 4。
header-footer.activedefault默认使用哪套设计。
header-footer.designs.<名字>.display-condition""生效条件,空 = 不限制;多条用 ; 连接。
header-footer.designs.<名字>.header""面板上部文字,\n 换行。
header-footer.designs.<名字>.footer""面板下部文字,\n 换行。
animations.<名字>.styleframestypewriter 打字机 / frames 轮播。
animations.<名字>.interval4每帧 tick 数,4 = 0.2 秒一帧。
animations.<名字>.frames[]轮播用的文字列表。
animations.<名字>.text""打字机要打的整句。
animations.<名字>.color&f打字机文字颜色。
animations.<名字>.hold30打完 / 收完后停留的帧数。
player-list.name-format&7[%team%&7] %title%&f%name%列表里每行的格式。
player-list.no-team&8无队伍没队伍时 %team% 的值。
player-list.no-title""没头衔时 %title% 的值。
player-list.ping.enabledtrue延迟列开关。
player-list.ping.titlePing延迟列的计分板标题(最多 32 个字符,超出自动截断)。
player-list.ping.refresh-ticks20延迟数值刷新间隔。
ℹ️
改了不生效先看缩进 YAML 用两个空格缩进,不能用 Tab。designs 和 animations 下面的名字是你自己起的,引用时写 %animation:名字% 要完全一致(区分大小写)。改完记得 /linuxtab reload。