Force print message to log with commandBlockOutput=false
I'm running a Vanilla Minecraft: JE Server (v. 1.12.2) and so far so good.
There is only a problem I encountered: griefers. I've already set up a system that logs how many times a player uses a forbidden item (lava bucket, TNT etc...), warns them if they reach a certain limit and, if the user keeps spamming these blocks, adds them to a "team" of banned players that keep getting /kill
-ed 'till I ban them properly (this is the closest thing to ban via command blocks). However, one may be able to light a single tree using Flint and Steel, burn a whole forest as the fire propagates and get away with it. So I'd like to have a command block or function print a message to the server console (so it appears in the logs), which would look something like this:
**PlayerName** used FlintAndSteel
Obviously we are talking about a service/technical message so it doesn't have to be pretty at all. What I'd like to have is something to verify which player griefed the server at a certain time, without turning on commandBlockOutput which would otherwise cause massive spam in the server console, considering the amount of Command Blocks and Functions that run every tick.
Solution 1:
Here is one possible solution:
First add a scoreboard to track flint and steel usage (which you probably already have):
/scoreboard objectives add flint stat.useItem.minecraft.flint_and_steel
Then put a ticking command chain in the spawn chunks with these commands in the command blocks:
execute @a[score_flint_min=1] ~ ~ ~ gamerule logAdminCommands true
gamerule logAdminCommands false
scoreboard players set @p[score_flint_min=1] flint 0
The chain command blocks (#2 and #3) can be conditional (and for performance they should).
The first command block temporarily enables debug logging if there is a player with a score of 1 in the "flint" scoreboard (so he used a flint and steel item), which is already the first thing that sends a debug log output to the game log. And because it's executed from the player with the score, the log entry also contains the name of that player.
The second command block then deactivates debug logging again. This already doesn't get sent to the log again, because debug logging is off again.
The third command block resets the "flint" score again. Since debug logging is still off, this doesn't send a message to the log.
So in total you get a log output similar to this every time someone uses a flint and steel:
17:30:08 net.minecraft.server.MinecraftServer [FaRo1: Game rule logAdminCommands has been updated to true]
This looks exactly like when an admin manually enters /gamerule logAdminCommands true
into chat, but that shouldn't happen too often and since you probably know the server admin's names, you can see by the name that it wasn't manually entered (because it would have failed). If it is a possible case that you could confuse, then just swap the second and third command in the command block row to get a second output for every flint and steel usage.
You can also put some more command blocks between the first and the second one with additional output. For example you could output the coordinates of the player with a system like this.
Credit for the idea to temporarily activate debug logging and turn it off again afterwards: alex2003super
Solution 2:
I'm afraid there is no good solution to this, as things like /tellraw
are not propagated to the server console if logAdminCommands and commandBlockOutput are turned off.
the only thing that still gets put into the server log is a /say
command, but everyone on the server will be able to see that, and I doubt you'd want that. But that is the only thing I think could work on vanilla.