A
Admincraftβ€’2w ago
Siper

Invisible player due value in playerdata file, how to fix that without headache?

Hi, I have some weird case. By some reason (probably crash of the server and consequences) some players began to be invisible. During some research I found that problem is with value in player's NBT data. Entry called Bukkit.invisible for some of them is set for 1, but after change to 0, everything is fine. My question is, is it possible to change that value for specific players automatically, or at least without manually editing value for each player (it can be hundreds of files...) via NBTExplorer? Server is using PaperMC, of course set in online mode.
13 Replies
Lunaiskey
Lunaiskeyβ€’2w ago
there is probs a plugin thats doing that cus thats not normal behaviour
Siper
SiperOPβ€’2w ago
[00:26:04 INFO]: Server Plugins (14):
[00:26:04 INFO]: Bukkit Plugins:
[00:26:04 INFO]: - AxiomPaper, Chunky, ClickMobs, CoreProtect, dynmap, Essentials, ImageFrame, Lootin, LuckPerms, mc-IPGuard
[00:26:04 INFO]: Schneckenhaus, Vault, WorldEdit, WorldGuard
[00:26:04 INFO]: Server Plugins (14):
[00:26:04 INFO]: Bukkit Plugins:
[00:26:04 INFO]: - AxiomPaper, Chunky, ClickMobs, CoreProtect, dynmap, Essentials, ImageFrame, Lootin, LuckPerms, mc-IPGuard
[00:26:04 INFO]: Schneckenhaus, Vault, WorldEdit, WorldGuard
All plugins that we have
Deathpacito
Deathpacitoβ€’2w ago
!map
Carl-bot
Carl-botβ€’2w ago
View a comparison of the most popular map plugins here: https://map.roanv.nl
Map Index
A Minecraft map viewers comparison!
Skullians
Skulliansβ€’2w ago
Yeah avoid dynmap
Deathpacito
Deathpacitoβ€’2w ago
Highly recommend anything except dynmap, not related to yoyr original qn but yuck dynmap is bad
π’Ÿπ‘œπ“‚π’Ύπ“ƒπ’Ύπ’Έ
I like squaremap personally
Siper
SiperOPβ€’2w ago
yeah, thanks for information about dynmap. The good news is I've installed that plugin couple of hours ago so not yet shared (and obviously not finished rendering)
Deathpacito
Deathpacitoβ€’2w ago
I personally like Pl3xmap
qvaras
qvarasβ€’2w ago
bluemaps cool
Deathpacito
Deathpacitoβ€’2w ago
I also use bluemap I feel it gives too much info in a survival world setting though
qvaras
qvarasβ€’2w ago
we run bluemap with quite a few features disabled
Siper
SiperOPβ€’2w ago
About the main question it looks like the easiest way will be just made a script in Python that just iterates for each playerdata and fixes value when is invalid. I will share it when will be done and can confirm it works Well. I've fixed it. I was forced to iterate per each playerdata file and if is necessary remove Bukkit.invisible tag, and then just replace files. Of course everything on turned off server. If someone interested, here's the script:
#!/usr/bin/env python3
import os
import logging
from nbtlib import load, Byte
import shutil

logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)

fixed_files = []

def process_file(filepath, filename):
"""Load an NBT .dat file, change Bukkit.invisible from 1 to 0 if needed."""
try:
# Load the NBT file; nbtlib automatically handles compression.
nbt_file = load(filepath)
except Exception as e:
logging.error(f"Error reading '{filepath}': {e}")
return

root = nbt_file

# Check if the tag exists in the root compound
if "Bukkit.invisible" in root:
# Remove the tag
root.pop("Bukkit.invisible")
try:
nbt_file.save(filepath)
fixed_files.append(filename)
logging.info(f"'{filename}' [Updated] - Bukkit.invisible has been removed")
except Exception as e:
logging.error(f"Error saving '{filepath}': {e}")
else:
logging.info(f"'{filename}' [Skipped] - No 'Bukkit.invisible' tag found")

def main(directory):
if not os.path.isdir(directory):
logging.error(f"Directory not found: {directory}")
return

"""Create new directory to prevent overwriting original files, as a safety measure."""
processed_directory = os.path.join(directory, "../processed_playerdata")
if not os.path.exists(processed_directory):
os.makedirs(processed_directory)

logging.info("Copying all .dat files to temporary directory...")
for filename in os.listdir(directory):
if filename.lower().endswith(".dat"):
filepath = os.path.join(directory, filename)
new_filepath = os.path.join(processed_directory, filename)
with open(filepath, 'rb') as f:
with open(new_filepath, 'wb') as nf:
nf.write(f.read())

logging.info("Processing .dat files...")
for filename in os.listdir(processed_directory):
if filename.lower().endswith(".dat"):
filepath = os.path.join(processed_directory, filename)
process_file(filepath, filename)

logging.info(f"{len(fixed_files)} files has been fixed, copying to separate directory.")
new_directory = os.path.join(directory, "../fixed_playerdata")
if not os.path.exists(new_directory):
os.makedirs(new_directory)

for filename in fixed_files:
filepath = os.path.join(processed_directory, filename)
new_filepath = os.path.join(new_directory, filename)
with open(filepath, 'rb') as f:
with open(new_filepath, 'wb') as nf:
nf.write(f.read())

shutil.rmtree(processed_directory)

logging.info("All done! Fixed files:")
for filename in fixed_files:
logging.info(f" - {filename}")

if __name__ == "__main__":
target_directory = "./playerdata"
main(target_directory)
#!/usr/bin/env python3
import os
import logging
from nbtlib import load, Byte
import shutil

logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)

fixed_files = []

def process_file(filepath, filename):
"""Load an NBT .dat file, change Bukkit.invisible from 1 to 0 if needed."""
try:
# Load the NBT file; nbtlib automatically handles compression.
nbt_file = load(filepath)
except Exception as e:
logging.error(f"Error reading '{filepath}': {e}")
return

root = nbt_file

# Check if the tag exists in the root compound
if "Bukkit.invisible" in root:
# Remove the tag
root.pop("Bukkit.invisible")
try:
nbt_file.save(filepath)
fixed_files.append(filename)
logging.info(f"'{filename}' [Updated] - Bukkit.invisible has been removed")
except Exception as e:
logging.error(f"Error saving '{filepath}': {e}")
else:
logging.info(f"'{filename}' [Skipped] - No 'Bukkit.invisible' tag found")

def main(directory):
if not os.path.isdir(directory):
logging.error(f"Directory not found: {directory}")
return

"""Create new directory to prevent overwriting original files, as a safety measure."""
processed_directory = os.path.join(directory, "../processed_playerdata")
if not os.path.exists(processed_directory):
os.makedirs(processed_directory)

logging.info("Copying all .dat files to temporary directory...")
for filename in os.listdir(directory):
if filename.lower().endswith(".dat"):
filepath = os.path.join(directory, filename)
new_filepath = os.path.join(processed_directory, filename)
with open(filepath, 'rb') as f:
with open(new_filepath, 'wb') as nf:
nf.write(f.read())

logging.info("Processing .dat files...")
for filename in os.listdir(processed_directory):
if filename.lower().endswith(".dat"):
filepath = os.path.join(processed_directory, filename)
process_file(filepath, filename)

logging.info(f"{len(fixed_files)} files has been fixed, copying to separate directory.")
new_directory = os.path.join(directory, "../fixed_playerdata")
if not os.path.exists(new_directory):
os.makedirs(new_directory)

for filename in fixed_files:
filepath = os.path.join(processed_directory, filename)
new_filepath = os.path.join(new_directory, filename)
with open(filepath, 'rb') as f:
with open(new_filepath, 'wb') as nf:
nf.write(f.read())

shutil.rmtree(processed_directory)

logging.info("All done! Fixed files:")
for filename in fixed_files:
logging.info(f" - {filename}")

if __name__ == "__main__":
target_directory = "./playerdata"
main(target_directory)

Did you find this page helpful?