Skip to main content

Nexal Combat Log

Combat logging prevention for Minecraft servers (Spigot and Paper). A player who disconnects while tagged in combat leaves an NPC holding their items, dies on the spot, or is only recorded, depending on the mode. A Vault fine, a temp-ban command and custom console commands can be stacked on top.

Features​

  • Combat Tagging: PvP hits tag both players (projectiles, tamed pets, TNT and lingering potions count as the player's); optional PvE tagging for a configurable list of mobs
  • Combat Indicators: boss bar, action bar and sidebar scoreboard countdowns, each toggleable
  • Punishment Modes for a tagged player who disconnects:
    • NPC: a zombie NPC spawns with their armor, weapon and offhand and holds their whole inventory. If it is killed, everything drops. If it survives (it expires, the player rejoins first, its chunk unloads or the server stops), the items are stored and given back on the next join
    • INSTANT_DEATH: the player dies at once and their items drop where they logged out
    • NONE: the combat log is only recorded
  • Add-on punishments: a Vault fine, a temp-ban command (for EssentialsX, LiteBans or any ban plugin) and custom console commands, applied when the player is punished (on disconnect in instant death mode, when the NPC is killed in NPC mode). The player is told what was applied when they rejoin
  • NPC Details: hologram countdown (native, no hologram plugin needed), a timer that resets when the NPC is hit, the player's health or a custom health, no burning in daylight
  • Command Blocking: blacklist or whitelist mode; entries match whole command names, plugin-prefixed commands (/essentials:home) and a plugin command's aliases; a trailing * matches a prefix
  • Safe Zone Prevention: WorldGuard integration blocks tagged players from walking or pearling into regions where PvP is denied (or custom regions)
  • Admin GUI: /combatlog admin opens a hub with the settings (combat, indicators, NPC, punishment, command blocking, safe zones, exempt reminders, death snapshot limit), the exempt list and every player's death log
  • Exempt System: players who are never tagged, stored with the plugin data, with periodic reminders to staff
  • Death Inventory Log: browse every death (NPC killed or instant death) and the exact inventory at that moment
  • Statistics: combat logs, NPC kills and deaths, times tagged, fines paid and punishments, with a stats GUI, a leaderboard GUI and PlaceholderAPI placeholders
  • Dual Storage: JSON or MySQL/MariaDB, with export and import to move between them

Technologies​

  • Paper API 1.20.1+: Minecraft server API (Spigot compatible)
  • Utilizer: Configuration, messages, GUIs, holograms, scheduling
  • ACF: Command framework
  • nexal-core: JSON and SQL persistence (MariaDB/MySQL), help menu, licensing
  • Vault, WorldGuard, PlaceholderAPI: optional integrations

Commands​

Aliases: /cl, /combat.

Player Commands​

CommandDescriptionPermission
/combatlog or /combatlog help [page]Show helpNone
/cl stats [player]View combat statisticsnexalcombatlog.stats
/cl guiOpen stats GUInexalcombatlog.gui
/cl leaderboard (lb, top)Open leaderboard GUInexalcombatlog.leaderboard
/cl deathsView your death inventory lognexalcombatlog.deaths

Admin Commands​

CommandDescriptionPermission
/cl adminOpen the admin GUI (console: list the admin commands)nexalcombatlog.admin
/cl admin help [page]List the admin commandsnexalcombatlog.admin
/cl admin deaths \<player>View a player's death inventory lognexalcombatlog.admin
/cl admin tag \<player> [duration]Force tag a player in combat (duration in seconds, above 0)nexalcombatlog.admin
/cl admin untag \<player>Remove combat tag from playernexalcombatlog.admin
/cl admin exempt add \<player>Exempt an online player from combat taggingnexalcombatlog.admin
/cl admin exempt remove \<player>Remove exemptionnexalcombatlog.admin
/cl admin exempt listList all exempted playersnexalcombatlog.admin
/cl admin reloadReload configurationnexalcombatlog.admin
/cl admin exportExport data to JSON files in export/nexalcombatlog.admin
/cl admin importImport data from the JSON files in export/nexalcombatlog.admin

Permissions​

PermissionDescriptionDefault
nexalcombatlog.statsView own and others' statstrue
nexalcombatlog.guiOpen stats GUItrue
nexalcombatlog.leaderboardView leaderboardtrue
nexalcombatlog.deathsView death inventory logtrue
nexalcombatlog.adminAdmin GUI and all admin commandsop
nexalcombatlog.bypassBypass combat tagging entirelyop
nexalcombatlog.bypass.commandsUse blocked commands while in combatop
nexalcombatlog.notifyReceive admin notifications (exempt warnings)op

Configuration​

Changes to config.yml and messages.yml apply automatically. The most used settings can also be changed in /combatlog admin → Configuration. A storage type change needs a restart.

config.yml​

storage:
type: json # json or sql
sql:
host: localhost
port: 3306
database: minecraft
username: root
password: ""

combat:
duration: 15 # Tag duration in seconds
pve-enabled: false # Mobs in pve-entities also tag the player they hit
pve-entities: [ZOMBIE, SKELETON, CREEPER, ...]
reset-on-hit: true # Each hit restarts the timer (false: only tops it up)

indicators:
boss-bar:
enabled: true
color: RED # RED, BLUE, GREEN, YELLOW, PURPLE, PINK, WHITE
style: SOLID # SOLID, SEGMENTED_6, SEGMENTED_10, SEGMENTED_12, SEGMENTED_20
title: "..." # %seconds%, %attacker%
action-bar:
enabled: true
message: "..." # %seconds%, %attacker%
scoreboard:
enabled: false
title: "..."
lines: [...] # %seconds%, %attacker%

npc:
duration: 10 # Seconds the NPC stays before it expires
reset-on-damage: true # Hitting the NPC restarts its timer
name: "\<red>%player%'s Logger\</red>"
use-player-health: true # false: use custom-health (may be above 20)
custom-health: 20.0
hologram:
enabled: true
lines: [...] # MiniMessage or & codes; %player%, %seconds%, %health%, %max_health%
offset-y: 2.5
broadcast-spawn: true
broadcast-kill: true

punishment:
mode: NPC # NPC, INSTANT_DEATH or NONE
temp-ban:
enabled: false
duration: 300 # Seconds, passed to the command as %duration%
command: "tempban %player% %duration%s Combat logging"
fine:
enabled: false # Needs Vault and an economy plugin
amount: 1000.0
commands: [] # Console commands, %player% = player name

commands:
mode: BLACKLIST # BLACKLIST or WHITELIST
blacklist: [home, sethome, spawn, tp, tpa, warp, back, rtp, ...]
whitelist: [msg, message, tell, whisper, r, reply, helpop]

safe-zones:
enabled: true # Needs WorldGuard
prevent-entry: true
custom-regions: [] # Empty: regions where PvP is denied

exempt:
warning-interval: 10 # Minutes between staff reminders (0 to disable)

death-log:
max-snapshots: 0 # Inventory snapshots kept per player (0 = unlimited)

The temp ban, fine and custom commands apply when the player is punished: on disconnect in INSTANT_DEATH mode, and when the NPC is killed in NPC mode (the temp ban then runs while the player is offline; the fine and commands run when they rejoin). Nothing is applied in NONE mode or when the NPC survives.

Command list entries are command names without /. home also blocks /essentials:home and /ehome (an EssentialsX alias of home). tp* blocks every command starting with tp.

messages.yml​

All chat messages are customizable, with:

  • MiniMessage format (<gradient:...>, \<bold>, \<gray>, ...) and legacy & codes
  • PlaceholderAPI placeholders
  • Sounds, titles and subtitles

The GUI titles (gui-stats-title, gui-leaderboard-title), the empty leaderboard text (gui-no-stats) and the page label (gui-page-info) are in messages.yml too. Keys added by an update fall back to the bundled defaults until you add them to your file.

Moving between JSON and SQL​

Run /cl admin export, set storage.type to the new type, restart, then run /cl admin import. Export and import cover players, combat log entries, death snapshots, the exempt list and pending reconnects (items held for players who have not rejoined).

PlaceholderAPI Placeholders​

PlaceholderDescription
%combatlog_in_combat%"yes" or "no"
%combatlog_in_combat_colored%"&cYes" or "&aNo"
%combatlog_remaining%Formatted time remaining (e.g. "15s", "1m 5s")
%combatlog_remaining_seconds%Raw seconds remaining
%combatlog_combat_logs%Player's combat log count
%combatlog_npc_kills%NPCs killed by player
%combatlog_npc_deaths%Player's NPC death count
%combatlog_times_tagged%Total times tagged
%combatlog_fines_paid%Total fines paid (e.g. "1,000")
%combatlog_punishments%Times punished (instant death or NPC killed)
%combatlog_exempt%"yes" or "no"
%combatlog_top_\<n>_name%Name at position n by combat logs
%combatlog_top_\<n>_logs%Combat logs at position n
%combatlog_top_\<n>_kills%NPC kills at position n of the NPC kills ranking
%combatlog_top_\<n>_deaths%NPC deaths at position n of the NPC deaths ranking
%combatlog_top_\<n>_tagged%Times tagged at position n of the times tagged ranking
%combatlog_top_\<n>_\<stat>_name%Name at position n of that ranking (logs, kills, deaths, tagged)

Rankings list players with a value above 0; an empty position returns N/A. Offline players (in holograms or tab lists) get their stored stats and are never in combat.

Database Schema​

Column names are the field names. In JSON storage each table is a key in data.json. Tables created by 1.0.2 or earlier stored inventories as TEXT; those columns are widened to MEDIUMTEXT on startup.

combatlog_users​

ColumnTypeDescription
idVARCHAR(36)Player UUID (PK)
playerNameVARCHAR(16)Player name
combatLogsINTTimes logged out in combat
npcKillsINTNPCs killed by player
npcDeathsINTPlayer's NPC was killed
timesTaggedINTTotal times tagged
punishmentsIssuedINTTimes punished
finesPaidDOUBLETotal fines
lastTagTimeBIGINTLast tag timestamp
createdAtBIGINTRecord created
updatedAtBIGINTLast updated

combatlog_entries​

ColumnTypeDescription
idVARCHAR(36)Entry UUID (PK)
playerIdVARCHAR(36)Player who logged
playerNameVARCHAR(16)Player name
attackerIdVARCHAR(36)Attacker UUID
attackerNameVARCHAR(16)Attacker name
timestampBIGINTEvent timestamp
logTypeVARCHAR(32)DISCONNECT, NPC_KILLED, NPC_EXPIRED or INSTANT_DEATH
npcWasKilledBOOLEANNPC died
npcKillerIdVARCHAR(36)Who killed the NPC
npcKillerNameVARCHAR(16)Killer name

combatlog_death_snapshots​

ColumnTypeDescription
idVARCHAR(36)Entry UUID (PK, same as the combat log entry)
playerIdVARCHAR(36)Player UUID
inventoryDataMEDIUMTEXTBase64-encoded inventory
armorDataMEDIUMTEXTBase64-encoded armor
offhandDataMEDIUMTEXTBase64-encoded offhand
timestampBIGINTSnapshot timestamp

combatlog_exempt​

ColumnTypeDescription
idVARCHAR(36)Player UUID (PK)
playerNameVARCHAR(16)Player name when exempted
addedAtBIGINTWhen the exemption was added

combatlog_pending_reconnects​

What happened to a combat logger, kept until they rejoin.

ColumnTypeDescription
idVARCHAR(36)Player UUID (PK)
playerNameVARCHAR(16)Player name
outcomeVARCHAR(32)HELD (items to give back), NPC_KILLED or INSTANT_DEATH
killerNameVARCHAR(36)Who killed the NPC
inventoryDataMEDIUMTEXTBase64-encoded inventory held for the player
armorDataMEDIUMTEXTBase64-encoded armor held for the player
offhandDataMEDIUMTEXTBase64-encoded offhand held for the player
fineTakenDOUBLEFine taken on disconnect
bannedBOOLEANWhether the temp-ban command ran
createdAtBIGINTRecord created

Soft Dependencies​

  • PlaceholderAPI: placeholders
  • Vault: economy fines
  • WorldGuard: safe zone detection
  • DecentHolograms, HolographicDisplays, FancyHolograms: optional hologram providers (native holograms work without them)

How It Works​

  1. A player hits another → both are tagged for combat (dying ends the tag)
  2. The timer runs → boss bar, action bar or scoreboard show the countdown
  3. Commands are blocked → teleports and the like, per the blacklist or whitelist
  4. Safe zones are closed → a tagged player cannot enter them (WorldGuard)
  5. The player disconnects while tagged → an NPC spawns holding their items (NPC mode), or they die (instant death mode)
  6. The NPC is killed → their items drop, the killer is credited and the temp ban runs
  7. The NPC survives → their items are given back when they rejoin
  8. The player rejoins → they are told what happened; after an NPC death the fine and commands apply

Installation​

  1. Download the plugin JAR
  2. Place it in the /plugins folder
  3. Start or restart the server
  4. Configure config.yml or use /combatlog admin (changes apply automatically; a storage type change needs a restart)