▶️ ЗАБЕРИ СВОИ 8 ПОДАРКОВ 🎁 ПРИ СОЗДАНИИ СВОЕГО МАЙНКРАФТ СЕРВЕРА
Плагины/FauxPlayers
FauxPlayers

FauxPlayers

Paper plugin and Fabric server mod to create fake player entries in a server. Able to relay players from another server, have fluctuating realistic pings and be compatible with TAB.

Оцените первым
70
0

FauxPlayers

FauxPlayers adds display-only player entries to Minecraft.

It supports:

  • Paper 26.3 (single Paper JAR).
  • Fabric for Minecraft 26.2 and 26.3.
  • Server status responses.
  • Manipulating the in-game player list.
  • Relaying players from another server or HTTP source.
  • Replaying an exported Discord chat history into the server.
  • Simulated ping, skins, heads, and TAB scores.

Important

A fake player is a client display entry. It is not a connected player.

FauxPlayers does not create:

  • a connection;
  • an entity;
  • a login or quit event;
  • a command sender;
  • a Bukkit Player;
  • a server-side player.

On Paper, Bukkit.getOnlinePlayers() contains only real players. Fake entries do not change permissions, events, slots, limits, or server APIs.

Other players can see a fake entry like a normal player entry. It can show a name, display name, skin, head, game mode, ping bars, and a TAB ping score. The ping is simulated.

Requirements

Build:

  • Java 25.
  • Gradle Wrapper.

Paper:

  • Paper 26.3: Java 25.
  • ProtocolLib for Paper packet features.

Fabric:

  • Minecraft 26.2 or 26.3.
  • Fabric Loader 0.19.3 or later.
  • Fabric API 0.159.0+26.2 or later for Minecraft 26.2.
  • Fabric API 0.160.5+26.3 or later for Minecraft 26.3.
  • Java 25.

Optional:

  • TAB for TAB integration on both platforms.

Server status

FauxPlayers can change the data sent to server-list clients. It can change:

  • the online count;
  • the maximum count;
  • the sample names.

The count and name sample are separate values. An upstream server can report 30 players and provide five names. FauxPlayers does not create the missing names.

STATUS data does not create connections. It does not change the server login capacity.

In-game player list

FauxPlayers sends player-info packets to real players. The fake entries exist in the receiving client only.

The displayed latency controls the ping bars. It also controls the TAB Ping: N score. Random ping can update both values at the configured interval.

To show the TAB score, enable the TAB player-list objective:

playerlist-objective:
  enabled: true
  value: '%ping%'
  fancy-value: '&7Ping: %ping%'

FauxPlayers sends the TAB-PlayerList score on Paper and Fabric. It sends the score again after a TAB objective reload.

The TAB %online% value includes real players and active fake TAB entries. It does not change the server's real player count.

Configuration

The generated file contains all supported settings. These are the main settings:

enabled: true

status:
  enabled: true
  include-real-players: true
  include-static-fakes: true
  include-relayed-players: true
  include-replay: true

count:
  mode: COMBINED       # FIXED, ADDITIONAL, RANDOM, REMOTE, or COMBINED
  fixed: 20

tab:
  enabled: true
  include-static-fakes: true
  include-relayed-players: true
  include-replay: true
  default-latency: 50
  default-gamemode: SURVIVAL

static-players:
  - name: Herobrine
    latency: 42

relay:
  enabled: false
  source: STATUS        # STATUS or HTTP
  status:
    host: 127.0.0.1
    port: -1             # SRV or port 25565
  http:
    url: http://127.0.0.1:8080/players
  refresh-seconds: 10

replay:
  enabled: false
  file: replay/chat.csv
  speed: 1.0
  loop: true
  maximum-gap-seconds: 30
  maximum-players: 100
  chat: true
  discord-chat: true
  deaths: true
  events: true
  announce-seeks: true
  skip-real-players: true

Static entries support name, display-name, and latency. Static and relayed UUIDs are stable.

Relays

A relay copies the player list from somewhere else and shows it as fake entries. The somewhere else is whatever relay.source names.

  • relay.source: STATUS asks the upstream Minecraft server directly, so it reuses the same public ping in the server list. Point relay.status.host at it.
  • relay.source: HTTP asks your own URL for JSON, so you choose the roster. Point relay.http.url at it.

Both write the same cached roster, and both are shown as fake entries. Choose HTTP when you can serve a complete list; choose STATUS when you only have the other server.

Relay requests run in the background. They do not block the server thread.

Disabling the relay stops its names being shown. The roster it last fetched is kept in memory so re-enabling uses it again without a fresh request, but nothing is displayed from it while the relay is off. /fauxplayers status reports 0 shown | 8 cached in that state rather than implying the names are in use.

STATUS relay

Set relay.source to STATUS. Set relay.status.host to the upstream server.

FauxPlayers sends a Minecraft STATUS request. It uses an _minecraft._tcp SRV record when available. Otherwise, it uses the configured port. Port -1 uses port 25565 when no SRV record exists.

STATUS samples are not complete rosters. FauxPlayers does not use them for join or leave messages, so a STATUS relay never produces fake join or leave announcements. Only the HTTP source does.

HTTP relay

Set relay.source to HTTP. Set relay.http.url to the JSON endpoint.

Recommended response:

{
  "online": 3,
  "max": 100,
  "players": [
    {"name": "Alice"},
    {"name": "Bob"},
    {"name": "Charlie"}
  ]
}

The players list is recommended. A flat name field is also accepted. Use HTTP when the endpoint provides a complete roster. Roster changes can create fake join and leave messages.

Names classified as anonymous or Anonymous Player are ignored. FauxPlayers does not resolve or display them.

If a request fails, keep-last-successful-result keeps the last good roster when enabled.

Join and leave messages

Set messages.enabled to true to announce HTTP roster changes.

Paper and Fabric observe a real join and leave message. They reuse its format for relay messages. This supports custom message formats.

The observed format is stored in message-format.yml. FauxPlayers does not create Bukkit join or quit events for fake players.

Real players win

A real player and a fake entry can want the same name, because a replayed log holds people who are on the server right now.

When that happens the real player keeps everything and the fake one is dropped:

  • No second entry is created, so the player list and TAB show one entry, not two.
  • No replayed join, leave, or chat is sent under their name, so the replay never speaks for someone who is present.

Their own entry and their own words always win. Case does not matter, so a replayed notch is dropped while Notch is online.

This covers every source of fake entries: static, relayed, and replayed.

Set replay.skip-real-players to false to replay the history exactly as it happened, even where it names someone who is online.

The check runs every few ticks, so a player who logs in while a fake entry of that name is showing takes over the entry.

Turning a mode off

Switching a mode off updates the player list straight away and announces the players leaving, the same way a real player quitting is announced.

The two targets are separate. The player list is what real players see in TAB. The status sample is what the server-list shows before anyone connects. A tab.* setting changes only the first, a status.* setting changes only the second, and a mode switch such as relay.enabled changes both.

TogglePlayer listStatus sample
enabled: falseemptiedemptied
tab.enabled: falseemptiedunchanged
tab.include-static-fakes: falsestatic entries removedunchanged
tab.include-relayed-players: falserelayed entries removedunchanged
tab.include-replay: falsereplayed entries removedunchanged
relay.enabled: falserelayed entries removedrelayed entries removed
replay.enabled: falsereplayed entries removedreplayed entries removed
status.enabled: falseunchangedleft entirely alone
status.include-static-fakes: falseunchangedstatic entries removed
status.include-relayed-players: falseunchangedrelayed entries removed
status.include-replay: falseunchangedreplayed entries removed

status.enabled: false is the one that leaves the sample untouched rather than emptying it, because the status response is then the server's own.

The player list is rebuilt every few ticks, so a change lands within a moment of the command. Turning a mode back on announces the players it adds. A change that leaves the list alone, such as editing replay.speed or adding a text replacement, costs no messages.

What is announced is the difference the configuration change itself makes. Only the entries that change because of it are announced, so a command that touches nothing about the player list stays silent even while the relay roster or the replay is changing underneath it.

Nothing is announced on the first load at server start, because there is no previous list to compare against. Set messages.enabled to false to remove entries without any message.

Disabling the relay keeps its fetched roster in memory so re-enabling uses it again without a new request, but nothing is displayed from it while it is off.

Commands

Use /fauxplayers. /fp and /fakeplayers are aliases.

CommandFunction
/fauxplayers statusShows real and relay state.
/fauxplayers listLists static and cached relay names.
/fauxplayers reloadReloads the configuration.
/fauxplayers refreshStarts a relay refresh.
/fauxplayers add <name>Adds a static entry.
/fauxplayers remove <name>Removes a static entry.
/fauxplayers ping <name> <ms>Sets a static ping.
/fauxplayers say <name> <message>Sends fake chat text.
/fauxplayers get <setting>Shows a setting.
/fauxplayers set <setting> <value>Changes a setting.
/fauxplayers relayShows relay state.
/fauxplayers relay enableEnables the relay.
/fauxplayers relay disableDisables the relay.
/fauxplayers replayShows replay state and the sub-command list.
/fauxplayers replay enableEnables the replay.
/fauxplayers replay disableDisables the replay.
/fauxplayers replay restartRe-reads the file and starts over.
/fauxplayers replay seek <line>Jumps to a line.
/fauxplayers replay skip <lines>Moves by lines, negative goes back.
/fauxplayers replay replace <from>=<to>Adds a text rewrite.
/fauxplayers replay unreplace <from>Removes a text rewrite.
/fauxplayers replay replacementsLists the text rewrites.
/fauxplayers replay speed <multiplier>Sets the timeline speed.
/fauxplayers replay loop <true|false>Sets the loop mode.
/fauxplayers replay file <path>Sets the CSV path.

Both platforms provide command completion. Paper requires fauxplayers.admin. Fabric requires the server-operator permission level.

Non-operators cannot discover FauxPlayers

For a non-operator, the FauxPlayers commands do not exist:

  • The roots and aliases are absent from the command-tree packet.
  • Autocomplete replies never contain them, even when the client sends raw suggestion requests such as /f, /fa, or /fp. Paper strips them from the suggestion packet with ProtocolLib; Fabric filters them at the command dispatcher before any reply is built.
  • Executing them reports an unknown command, and completion returns nothing.
  • Operators are unaffected.

On Paper, the suggestion-packet filter requires ProtocolLib. The command-tree removal and the execution guard work without it.

Replay

Replay reads a Discord chat export and plays it back into the server in the original order. When the end is reached it starts over unless replay.loop is false.

The file is a Discord channel export with the columns AuthorID, Author, Date, Content, Attachments, and Reactions. Only Author, Date, and Content are used.

replay.file is relative to the plugin data folder unless it is absolute.

  • Paper: plugins/FauxPlayers/replay/chat.csv.
  • Fabric: config/fauxplayers/replay/chat.csv.

The position is saved as the replay advances, so a server restart carries on from where it stopped instead of starting at the first line. The saved position sits beside the file, as chat.csv.position, so changing replay.file starts the new file from the beginning. /fauxplayers replay restart starts over from the first line and clears the saved position. Switching the replay off keeps the position, so turning it back on resumes.

What is replayed

X joined the game adds the X fake entry and broadcasts the join message. X left the game removes the entry and broadcasts the leave message. Both are recognised in the X has joined the server form as well.

A death message is read from what it says, not from who posted it, because either account can carry it. X was slain by Y using [Z], X fell from a high place, and X drowned replay as death messages whoever the export credits them to.

The victim has to be a name that joined the server, so X is checked against that list. Chat that merely mentions dying, such as i blew up the front or brodie fell for the ragebait, stays chat, because the first word is not a player.

Server shutdown, restart, status, console output, and permission errors are dropped entirely.

Replayed players are normal faux entries. FauxPlayers resolves the Mojang UUID, the name casing, and the skin from the name, so their head and icon are real. They are never server players.

Head lookups keep being retried. A name that failed is asked for again until it resolves, and a head is rebuilt as soon as the real skin arrives.

The two chat sources

The channel holds both in-game chat and Discord chat, and the export separates them by which account posted the line, not by the name in the text.

Two accounts exist:

  • The server bot posts joins, leaves, deaths, server output, and in-game chat written as Player: message.
  • The relay account posts in-game chat under the player's own name. Over time these servers switched from the first style to the second, so an export usually contains both.

A Discord user posts under their own account, under their own Discord handle. That handle is often a lowercase version of a player's in-game name, which is why the name alone cannot decide it.

FauxPlayers reads the account from the AuthorID column:

  • The bot is the account that posts the join lines under a name that is not a player. The relay posts join lines too, but it posts them under the joining player's own name, so those are not mistaken for the bot.
  • The relay is an account that posts under many different names, and those names belong to people who joined the server. A Discord account only ever posts under one name, so it never qualifies.
  • A relayed line counts as in-game chat whenever its name is a player name, which it is by construction because the relay posts under the player's own name. The name does not have to appear in a join line, so a slice of an export that starts after somebody joined still attributes their chat correctly.

Anything left is Discord chat.

Unattributed messages

The server bot is the server's own account, so it never chats on its own behalf. It only ever carries a join, a leave, a death, server output, or in-game chat written as Player: message.

A bot line that has no player on it is therefore an unattributed relay, where the name was lost on the way through. FauxPlayers ignores those instead of showing them, which is what keeps the server from appearing to say things like nothing on its own.

An in-game chat line is recognised by its Player: message shape, and the player does not have to be one the export recorded joining. So FieryGrowth: wsp replays as chat from FieryGrowth even in a file that never shows them logging in. A name written with a leading dot, as some servers do, is trimmed.

The same applies to the relay, which posts under the player's own name, so its lines are attributed from that name. A line whose name cannot be a player name at all, such as one wrapped in brackets, stays server output.

In-game chat shows as <Player> message and Discord chat as [Discord] <user> message.

Discord users are not in the game, so they never become player entries and they never get a player head. Only the join and leave lines create replayed players, and those name in-game accounts.

Set replay.discord-chat to false to leave the Discord conversation out and replay only what happened on the server. Set replay.chat to false to drop the in-game chat instead.

Run /fauxplayers replay to see which accounts were detected.

Seeking

/fauxplayers replay shows the position as Lines: 2/547884, where the figure counts the lines already passed. Seeking uses the same numbering:

  • /fauxplayers replay seek 30000 jumps to that line.
  • /fauxplayers replay skip 5000 moves forward five thousand lines.
  • /fauxplayers replay skip -5000 moves back five thousand lines.

Seeking rebuilds the player list from the joins and leaves before that line instead of replaying them, so the roster, the player count, and the TAB list are correct for that moment straight away.

The jump is then announced as a normal roster change: players who were in the game at the old line and are not at the new one leave, and players who are only at the new line join. A leap therefore reads the same way as any other change to the player list, rather than the list flickering with no explanation.

A player whose join line sits before the seek point is already listed and does not join again, and their next leave line still removes them. Chat is never out of step with the player list: everyone who speaks after a seek is someone the roster already holds.

Set replay.announce-seeks to false for a silent jump, which keeps the roster correct without the messages.

Text replacement

Lines can be rewritten as they are replayed, which is useful for scrubbing a phrase, a slur, a link, or a name before anyone sees it. The same feature is sometimes called filtering.

Run /fauxplayers replay to see the full list of sub-commands, which is built from the same list that drives completion:

Use /fauxplayers replay <enable|disable|file|speed|loop|restart|seek|skip|chat
|discord-chat|deaths|events|maximum-gap-seconds|maximum-players|replace|unreplace
|replacements> ...
replay:
  replacements:
    - from: "annoying phrase"
      to: "replacement"
    - from: "discord.gg/abcdef"
      to: ""

Each from is matched as literal text, case sensitively, and every occurrence is replaced. An empty to deletes the match.

The rules are applied to the whole line before it is replayed, to in-game chat, Discord chat, death messages, and other server output alike. Matching happens after the line is classified, so a rewrite can never turn a join into a chat message or hide a death.

In game:

  • /fauxplayers replay replace <from>=<to> adds one. The first = splits it, so spaces work on both sides.
  • /fauxplayers replay unreplace <from> removes one.
  • /fauxplayers replay replacements lists them.

Run /fauxplayers replay restart after a change so the loaded lines are rebuilt.

Reading the status

/fauxplayers replay reports enough to tell a waiting replay from a stalled one:

Replay » enabled=true | file=legacy.csv | speed=1.0 | loop=true
Lines: 28/547884 | players: 3 | finished: false
Clock: 2h 14m of 373d 4h 0m | next line in 12s | ticks driven: 8420
  • Lines counts the lines already replayed, out of the lines in the file. It starts at 0 and the first line is dispatched on the first tick after enabling.
  • Clock is how far into the original timeline the replay has reached, out of the whole timeline.
  • next line in is the wait until the next line is due. A large figure is the replay playing a quiet stretch, not a problem. Use skip to pass it.
  • ticks driven counts how often the game loop has driven the replay. It must keep climbing. A figure that never changes means the loop is not running, which is worth reporting, because a replay that is waiting still counts ticks.

Speed and gaps

The replay is real-time by default. replay.speed compresses the clock: 10 replays ten seconds of history per real second.

A long quiet period would stall the replay, so replay.maximum-gap-seconds caps the wait before any one line. The default of 30 turns a two day outage into a thirty second pause.

The capped waits add up, so the cap only costs one pause per quiet period. Lines that were a second apart still replay a second apart, even straight after a capped outage. A low value therefore compresses every wait, and a high value keeps long silences intact. This is also the knob for quiet and empty stretches: the wait before a line while nobody is online is capped the same way.

Speed and the cap decide the run time together. As a reference, the sample export covers 373 days and replays in about 73 days at 1.0, 17 hours at 100, and under 2 hours at 1000.

The replay emits at most 200 lines per tick, about 4000 per second, so a very high speed settles at that rate instead of going faster.

Ordering caveats

  • replay.chat replays in-game chat, replay.discord-chat replays Discord chat, replay.deaths replays death messages, and replay.events replays the rest of the server output. Turn one off to keep a quieter channel.
  • replay.maximum-players limits how many replayed players can be listed at once. Players above the limit still chat, but do not get a player-list entry.
  • The export is parsed once on startup. Change replay.chat, replay.discord-chat, replay.deaths, replay.events, or replay.maximum-gap-seconds and then run /fauxplayers replay restart.
  • A relay line labelled Server, meaning the server speaking about itself, replays as chat from Server. That label is what the export calls it, and it is not a real account.
  • Some servers forward their own chat to Discord and then take it back again. The echo is a second line with the same words, so it replays twice. The same happens to a death that both accounts carry.
  • A replay covering people who are on the server now leaves their lines out. See the real players section above.

A Discord handle and the in-game name can differ. Replay keeps each line under the name the export used for it.

Troubleshooting

Fake names do not appear

Check status.enabled and tab.enabled. Check the related include-* settings. Check the server log for packet or TAB errors.

TAB shows one online player

Check that TAB is installed and enabled. Check that tab.enabled is true. The server's real online count remains unchanged.

The Ping: N score does not appear

Enable TAB's player-list objective. Install the rebuilt JAR. Restart the server.

Relay data is stale

Run /fauxplayers status. Check the cache age and last error. Run /fauxplayers refresh. Check the host, port, URL, timeout, and relay source.

The replay is enabled but nothing happens

Run /fauxplayers replay and read the figures.

  • Loaded: (none) means the file has not been read yet, or the path is wrong. A large export takes a few seconds to parse before the first line replays.
  • next line in counting down to a large figure means the replay is playing a quiet stretch of the history. That is the file being followed faithfully. Use /fauxplayers replay skip <lines> to pass it, or lower replay.maximum-gap-seconds.
  • ticks driven frozen means the game loop is not driving the replay. The server log will hold a warning naming the cause, because a failure in the loop is reported instead of silently stopping it.

Replay does not start

Run /fauxplayers replay. Check replay.enabled and the resolved file path. Check the last error line and the server log. Run /fauxplayers replay restart after changing the file or the text replacements, which are also called filters.

The first load parses the whole file in the background. A large export takes a few seconds before the first line is replayed.

A replayed player has the default head

A head is only real when the name resolves to a Mojang account. FauxPlayers keeps asking: a name that failed is retried every twenty seconds, and a head already sent is rebuilt as soon as the real skin arrives, so nothing stays wrong for the rest of the session.

Mojang lookups run over the plugin's own HTTP client with a generous timeout. A slow reply is never treated as "no such account"; only an answer of 404 or 204 is, and even then the name is retried, just less often.

Three things can stop a head from being real.

  • The account was renamed or deleted since the export was written. Mojang only resolves current names, so a name from an old log can answer 404 with no way to recover the skin. Those are still retried, but only every ten minutes, because asking more often cannot help. This is permanent for that name.
  • The lookups were throttled. Mojang answers a burst of name lookups with HTTP 429. FauxPlayers spaces its lookups out and never remembers a failure, so a throttled name is retried and the head fills in shortly afterwards.
  • Mojang was slow or unreachable. The lookup is retried and the head is rebuilt when it succeeds.

A warning in the log names the reason the first time it happens.

License

FauxPlayers is released under the GNU General Public License, version 3.

Партнёрский материал

Сервер для плагина FauxPlayers - как у профи

Плагин FauxPlayers создан для серверов: на своём сервере вы настраиваете его под себя и решаете, кому играть. Создать сервер с плагином FauxPlayers для друзей можно за пару минут - BungeeHost всё уже подготовил.

Часто задаваемые вопросы

Совместимость

Minecraft: Java Edition

26.3.x26.2.x26.1.x1.21.x

Платформы

Поддерживаемые окружения

Сервер

Ссылки

Создатели

Детали

Лицензия:
Опубликован:4 недели назад
Обновлён:2 дня назад
Главная