10 #include "../ItemGrid.h"
11 #include "../StringCompression.h"
12 #include "../SetChunkData.h"
14 #include "../BlockType.h"
15 #include "../JsonUtils.h"
17 #include "../BlockEntities/BannerEntity.h"
18 #include "../BlockEntities/BeaconEntity.h"
19 #include "../BlockEntities/BedEntity.h"
20 #include "../BlockEntities/BrewingstandEntity.h"
21 #include "../BlockEntities/ChestEntity.h"
22 #include "../BlockEntities/CommandBlockEntity.h"
23 #include "../BlockEntities/DispenserEntity.h"
24 #include "../BlockEntities/DropperEntity.h"
25 #include "../BlockEntities/EnchantingTableEntity.h"
26 #include "../BlockEntities/EnderChestEntity.h"
27 #include "../BlockEntities/EndPortalEntity.h"
28 #include "../BlockEntities/FurnaceEntity.h"
29 #include "../BlockEntities/HopperEntity.h"
30 #include "../BlockEntities/JukeboxEntity.h"
31 #include "../BlockEntities/NoteEntity.h"
32 #include "../BlockEntities/SignEntity.h"
33 #include "../BlockEntities/MobHeadEntity.h"
34 #include "../BlockEntities/MobSpawnerEntity.h"
35 #include "../BlockEntities/FlowerPotEntity.h"
37 #include "../Mobs/IncludeAllMonsters.h"
39 #include "../Entities/Boat.h"
40 #include "../Entities/EnderCrystal.h"
41 #include "../Entities/FallingBlock.h"
42 #include "../Entities/Minecart.h"
43 #include "../Entities/Pickup.h"
44 #include "../Entities/ArrowEntity.h"
45 #include "../Entities/SplashPotionEntity.h"
46 #include "../Entities/ThrownEggEntity.h"
47 #include "../Entities/ThrownEnderPearlEntity.h"
48 #include "../Entities/ThrownSnowballEntity.h"
49 #include "../Entities/FireChargeEntity.h"
50 #include "../Entities/GhastFireballEntity.h"
51 #include "../Entities/TNTEntity.h"
52 #include "../Entities/ExpOrb.h"
53 #include "../Entities/HangingEntity.h"
54 #include "../Entities/ItemFrame.h"
55 #include "../Entities/LeashKnot.h"
56 #include "../Entities/Painting.h"
58 #include "../Protocol/MojangAPI.h"
59 #include "../Server.h"
60 #include "../BoundingBox.h"
74 #define MAX_MCA_FILES 32
85 m_Compressor(a_CompressionFactor)
93 Writer.
AddByte(
"allowCommands", 1);
94 Writer.
AddByte(
"Difficulty", 2);
96 Writer.
AddByte(
"initialized", 1);
97 Writer.
AddByte(
"MapFeatures", 1);
101 Writer.
AddInt(
"generatorVersion", 1);
105 Writer.
AddInt(
"version", 19133);
108 Writer.
AddLong(
"SizeOnDisk", 0);
109 Writer.
AddString(
"generatorName",
"default");
110 Writer.
AddString(
"generatorOptions",
"");
159 catch (
const std::exception & Oops)
176 auto OffloadFileName = fmt::format(FMT_STRING(
"{0}{1}region{1}badchunks"), m_World->GetDataPath(),
cFile::PathSeparator());
178 auto t = time(
nullptr);
181 localtime_s(&stm, &t);
183 localtime_r(&t, &stm);
185 OffloadFileName.append(fmt::format(
186 FMT_STRING(
"{}ch.{}.{}.{}-{:02d}-{:02d}-{:02d}-{:02d}-{:02d}.dat"),
188 stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec
194 auto Info = fmt::format(
195 FMT_STRING(
"Loading chunk {} for world {} from file r.{}.{}.mca failed: {} Offloading old chunk data to file {} and regenerating chunk."),
196 a_ChunkCoords, m_World->GetName(), RegionX, RegionZ, a_Reason, OffloadFileName
204 LOGWARNING(
"Cannot open file %s for writing! Old chunk data is lost.", OffloadFileName);
207 f.
Write(a_ChunkDataToSave.data(), a_ChunkDataToSave.size());
213 LOGWARNING(
"Cannot open file %s.info for writing! The information about the failed chunk will not be written.", OffloadFileName);
232 return File->GetChunkData(a_Chunk, a_Data);
247 return File->SetChunkData(a_Chunk, a_Data);
269 if (((*itr) !=
nullptr) && ((*itr)->GetRegionX() == RegionX) && ((*itr)->GetRegionZ() == RegionZ))
283 auto FileName = fmt::format(FMT_STRING(
"{}{}region"), m_World->GetDataPath(),
cFile::PathSeparator());
285 FileName.append(fmt::format(FMT_STRING(
"/r.{}.{}.mca"), RegionX, RegionZ));
286 auto f = std::make_shared<cMCAFile>(*
this, FileName, RegionX, RegionZ);
315 throw std::runtime_error(fmt::format(
"NBT parsing failed. {} at position {}.", NBT.
GetErrorCode().message(), NBT.
GetErrorPos()));
321 catch (
const std::exception & Oops)
367 ChunkLoadFailed(a_Chunk,
"NBT tag has wrong type: Sections", a_RawChunkData);
375 ChunkLoadFailed(a_Chunk,
"NBT tag missing or has wrong: Y", a_RawChunkData);
379 const int Y = a_NBT.
GetByte(SectionYTag);
382 ChunkLoadFailed(a_Chunk,
"NBT tag exceeds chunk bounds: Y", a_RawChunkData);
391 if ((
BlockData !=
nullptr) && (MetaData !=
nullptr) && (SkyLightData !=
nullptr) && (BlockLightData !=
nullptr))
398 ChunkLoadFailed(a_Chunk,
"Missing chunk block/light data", a_RawChunkData);
413 Data.UpdateHeightMap();
458 m_World->QueueSetChunkData(std::move(Data));
477 const auto *
const BiomeData = a_NBT.
GetData(a_TagIdx);
478 for (
size_t i = 0; i <
ARRAYCOUNT(a_BiomeMap); i++)
486 a_BiomeMap[i] =
static_cast<EMCSBiome>(BiomeData[i]);
501 (a_NBT.
GetDataLength(a_TagIdx) != (4 * std::size(a_HeightMap)))
507 const auto *
const HeightData = a_NBT.
GetData(a_TagIdx);
513 const int Height =
GetBEInt(HeightData + Index);
515 if (Height > std::numeric_limits<HEIGHTTYPE>::max())
584 LOGWARNING(
"Bad block entity, missing the coords. Will be ignored.");
591 const auto BlockMeta = a_BlockData.
GetMeta(relPos);
604 if (Entity ==
nullptr)
613 a_BlockEntities.emplace(Index, std::move(Entity));
659 FLOGINFO(
"WorldLoader({0}): Block entity mismatch: block type {1} ({2}), type \"{3}\", at {4}; the entity will be lost.",
767 if (FireworksTag > 0)
789 int SlotNum =
static_cast<int>(a_NBT.
GetByte(SlotTag)) - a_SlotOffset;
790 if ((SlotNum < 0) || (SlotNum >= NumSlots))
813 if (a_Line[0] !=
'{')
824 const auto & txt = root[
"text"];
827 return txt.asString();
858 for (
const auto & et: a_ExpectedTypes)
868 for (
const auto & et : a_ExpectedTypes)
870 expectedTypes.append(
", \"");
871 expectedTypes.append(et);
872 expectedTypes.push_back(
'\"');
874 FLOGWARNING(
"Block entity type mismatch: exp {0}, got \"{1}\". The block entity at {2} will lose all its properties.",
875 expectedTypes.c_str() + 2,
887 static const AStringVector expectedTypes({
"Banner",
"minecraft:standingbanner",
"minecraft:wallbanner"});
893 unsigned char Color = 15;
898 if (CurrentLine >= 0)
900 Color =
static_cast<unsigned char>(a_NBT.
GetInt(CurrentLine));
906 CustomName = a_NBT.
GetString(CurrentLine);
909 return std::make_unique<cBannerEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World, Color, CustomName);
919 static const AStringVector expectedTypes({
"Beacon",
"minecraft:beacon"});
925 auto Beacon = std::make_unique<cBeaconEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
928 if (CurrentLine >= 0)
930 Beacon->SetBeaconLevel(
static_cast<char>(a_NBT.
GetInt(CurrentLine)));
934 if (CurrentLine >= 0)
940 if (CurrentLine >= 0)
962 static const AStringVector expectedTypes({
"Bed",
"minecraft:bed" });
974 Color =
static_cast<short>(a_NBT.
GetInt(ColorIDx));
977 return std::make_unique<cBedEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World, Color);
987 static const AStringVector expectedTypes({
"Brewingstand",
"minecraft:brewing_stand" });
999 auto Brewingstand = std::make_unique<cBrewingstandEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1006 Brewingstand->SetRemainingFuel(tb);
1029 Brewingstand->SetTimeBrewed(tb);
1033 Brewingstand->LoadRecipes();
1034 Brewingstand->ContinueBrewing();
1035 return Brewingstand;
1046 static const AStringVector expectedTypes({
"Chest",
"TrappedChest",
"minecraft:chest" });
1057 auto Chest = std::make_unique<cChestEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1069 static const AStringVector expectedTypes({
"Control",
"minecraft:command_block" });
1075 auto CmdBlock = std::make_unique<cCommandBlockEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1078 if (currentLine >= 0)
1080 CmdBlock->SetCommand(a_NBT.
GetString(currentLine));
1084 if (currentLine >= 0)
1090 if (currentLine >= 0)
1092 CmdBlock->SetLastOutput(a_NBT.
GetString(currentLine));
1107 static const AStringVector expectedTypes({
"Trap",
"minecraft:dispenser" });
1118 auto Dispenser = std::make_unique<cDispenserEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1130 static const AStringVector expectedTypes({
"Dropper",
"minecraft:dropper" });
1141 auto Dropper = std::make_unique<cDropperEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1153 static const AStringVector expectedTypes({
"EnchantingTable",
"minecraft:enchanting_table" });
1161 if (currentLine >= 0)
1165 CustomName = a_NBT.
GetString(currentLine);
1168 return std::make_unique<cEnchantingTableEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World, CustomName);
1178 static const AStringVector expectedTypes({
"EnderChest",
"minecraft:ender_chest" });
1183 return std::make_unique<cEnderChestEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1193 static const AStringVector expectedTypes({
"EndPortal",
"minecraft:end_portal" });
1198 return std::make_unique<cEndPortalEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1208 static const AStringVector expectedTypes({
"FlowerPot",
"minecraft:flower_pot" });
1214 auto FlowerPot = std::make_unique<cFlowerPotEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1218 if (currentLine >= 0)
1226 Item.m_ItemType =
static_cast<short>(a_NBT.
GetInt(currentLine));
1231 if ((currentLine >= 0) && (a_NBT.
GetType(currentLine) ==
TAG_Int))
1233 Item.m_ItemDamage =
static_cast<short>(a_NBT.
GetInt(currentLine));
1247 static const AStringVector expectedTypes({
"Furnace",
"minecraft:furnace" });
1259 auto Furnace = std::make_unique<cFurnaceEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1292 Furnace->SetCookTimes(200, ct);
1307 static const AStringVector expectedTypes({
"Hopper",
"minecraft:hopper" });
1318 auto Hopper = std::make_unique<cHopperEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1330 static const AStringVector expectedTypes({
"RecordPlayer",
"minecraft:jukebox" });
1336 auto Jukebox = std::make_unique<cJukeboxEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1352 static const AStringVector expectedTypes({
"MobSpawner",
"minecraft:mob_spawner" });
1358 auto MobSpawner = std::make_unique<cMobSpawnerEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1373 MobSpawner->SetEntity(MonsterType);
1381 MobSpawner->SetSpawnCount(a_NBT.
GetShort(CurrentLine));
1388 MobSpawner->SetSpawnRange(a_NBT.
GetShort(CurrentLine));
1395 MobSpawner->SetSpawnDelay(a_NBT.
GetShort(CurrentLine));
1402 MobSpawner->SetMinSpawnDelay(a_NBT.
GetShort(CurrentLine));
1408 MobSpawner->SetMaxSpawnDelay(a_NBT.
GetShort(CurrentLine));
1415 MobSpawner->SetMaxNearbyEntities(a_NBT.
GetShort(CurrentLine));
1422 MobSpawner->SetRequiredPlayerRange(a_NBT.
GetShort(CurrentLine));
1436 static const AStringVector expectedTypes({
"Skull",
"minecraft:skull" });
1442 auto MobHead = std::make_unique<cMobHeadEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1445 if (currentLine >= 0)
1451 if (currentLine >= 0)
1459 AString OwnerName, OwnerTexture, OwnerTextureSignature;
1463 if (currentLine >= 0)
1469 if (currentLine >= 0)
1471 OwnerName = a_NBT.
GetString(currentLine);
1483 if (textureLine >= 0)
1486 if (currentLine >= 0)
1488 OwnerTextureSignature = a_NBT.
GetString(currentLine);
1492 if (currentLine >= 0)
1494 OwnerTexture = a_NBT.
GetString(currentLine);
1497 MobHead->SetOwner(OwnerUUID, OwnerName, OwnerTexture, OwnerTextureSignature);
1510 static const AStringVector expectedTypes({
"Music",
"minecraft:noteblock" });
1516 auto NoteBlock = std::make_unique<cNoteEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1532 static const AStringVector expectedTypes({
"Sign",
"minecraft:sign" });
1538 auto Sign = std::make_unique<cSignEntity>(a_BlockType, a_BlockMeta, a_Pos, m_World);
1541 if (currentLine >= 0)
1547 if (currentLine >= 0)
1553 if (currentLine >= 0)
1559 if (currentLine >= 0)
1574 typedef std::map<std::string_view, EntityLoaderFunc> EntityLoaderMap;
1575 static const EntityLoaderMap EntityTypeToFunction
1624 const auto it = EntityTypeToFunction.find(a_EntityName);
1625 if (it != EntityTypeToFunction.end())
1627 (this->*it->second)(a_Entities, a_NBT, a_EntityTagIdx);
1724 int MinecartType = a_NBT.
GetInt(TypeTag);
1725 switch (MinecartType)
1732 default:
LOGWARNING(
"cWSSAnvil::LoadOldMinecartFromNBT: Unhandled minecart type (%d)", MinecartType);
break;
1753 a_Entities.emplace_back(std::move(Boat));
1762 bool DisplayBeam =
false, ShowBottom =
false;
1765 if (CurrentLine > 0)
1771 if (CoordinateLine > 0)
1773 BeamTarget.
x = a_NBT.
GetInt(CoordinateLine);
1776 if (CoordinateLine > 0)
1778 BeamTarget.
y = a_NBT.
GetInt(CoordinateLine);
1781 if (CoordinateLine > 0)
1783 BeamTarget.
z = a_NBT.
GetInt(CoordinateLine);
1788 if (CurrentLine > 0)
1790 ShowBottom = a_NBT.
GetByte(CurrentLine) == 1;
1793 auto EnderCrystal = std::make_unique<cEnderCrystal>(
Vector3d(), BeamTarget, DisplayBeam, ShowBottom);
1799 a_Entities.emplace_back(std::move(EnderCrystal));
1811 if ((TypeIdx < 0) || (MetaIdx < 0))
1819 auto FallingBlock = std::make_unique<cFallingBlock>(
Vector3i(0, 0, 0),
Type, Meta);
1824 a_Entities.emplace_back(std::move(FallingBlock));
1838 a_Entities.emplace_back(std::move(
Minecart));
1870 a_Entities.emplace_back(std::move(
Minecart));
1887 a_Entities.emplace_back(std::move(
Minecart));
1904 a_Entities.emplace_back(std::move(
Minecart));
1921 a_Entities.emplace_back(std::move(
Minecart));
1942 auto Pickup = std::make_unique<cPickup>(
Vector3d(),
Item,
false);
1955 a_Entities.emplace_back(std::move(Pickup));
1964 auto TNT = std::make_unique<cTNTEntity>(
Vector3d(), 0);
1977 a_Entities.emplace_back(std::move(
TNT));
1986 auto ExpOrb = std::make_unique<cExpOrb>(
Vector3d(), 0);
2003 ExpOrb->SetReward(a_NBT.
GetShort(Reward));
2006 a_Entities.emplace_back(std::move(ExpOrb));
2027 if ((TileX > 0) && (TileY > 0) && (TileZ > 0))
2030 static_cast<double>(a_NBT.
GetInt(TileX)),
2031 static_cast<double>(a_NBT.
GetInt(TileY)),
2032 static_cast<double>(a_NBT.
GetInt(TileZ))
2071 a_Entities.emplace_back(std::move(
ItemFrame));
2089 a_Entities.emplace_back(std::move(LeashKnot));
2112 a_Entities.emplace_back(std::move(
Painting));
2154 if ((InBlockXIdx > 0) && (InBlockYIdx > 0) && (InBlockZIdx > 0))
2157 if ((typeX == a_NBT.
GetType(InBlockYIdx)) && (typeX == a_NBT.
GetType(InBlockZIdx)))
2183 a_Entities.emplace_back(std::move(
Arrow));
2198 int EffectDuration = a_NBT.
FindChildByName(a_TagIdx,
"EffectDuration");
2199 int EffectIntensity = a_NBT.
FindChildByName(a_TagIdx,
"EffectIntensity");
2200 int EffectDistanceModifier = a_NBT.
FindChildByName(a_TagIdx,
"EffectDistanceModifier");
2223 a_Entities.emplace_back(std::move(
Snowball));
2239 a_Entities.emplace_back(std::move(
Egg));
2248 auto Fireball = std::make_unique<cGhastFireballEntity>(
nullptr,
Vector3d(),
Vector3d());
2255 a_Entities.emplace_back(std::move(Fireball));
2271 a_Entities.emplace_back(std::move(
FireCharge));
2280 auto Enderpearl = std::make_unique<cThrownEnderPearlEntity>(
nullptr,
Vector3d(),
Vector3d());
2287 a_Entities.emplace_back(std::move(Enderpearl));
2296 auto Monster = std::make_unique<cBat>();
2307 a_Entities.emplace_back(std::move(Monster));
2316 std::unique_ptr<cBlaze> Monster = std::make_unique<cBlaze>();
2327 a_Entities.emplace_back(std::move(Monster));
2345 std::unique_ptr<cCaveSpider> Monster = std::make_unique<cCaveSpider>();
2356 a_Entities.emplace_back(std::move(Monster));
2365 std::unique_ptr<cChicken> Monster = std::make_unique<cChicken>();
2376 a_Entities.emplace_back(std::move(Monster));
2394 std::unique_ptr<cCow> Monster = std::make_unique<cCow>();
2405 a_Entities.emplace_back(std::move(Monster));
2414 std::unique_ptr<cCreeper> Monster = std::make_unique<cCreeper>();
2425 a_Entities.emplace_back(std::move(Monster));
2470 std::unique_ptr<cEnderDragon> Monster = std::make_unique<cEnderDragon>();
2481 a_Entities.emplace_back(std::move(Monster));
2490 std::unique_ptr<cEnderman> Monster = std::make_unique<cEnderman>();
2501 a_Entities.emplace_back(std::move(Monster));
2537 std::unique_ptr<cGhast> Monster = std::make_unique<cGhast>();
2548 a_Entities.emplace_back(std::move(Monster));
2557 std::unique_ptr<cGiant> Monster = std::make_unique<cGiant>();
2568 a_Entities.emplace_back(std::move(Monster));
2577 std::unique_ptr<cGuardian> Monster = std::make_unique<cGuardian>();
2588 a_Entities.emplace_back(std::move(Monster));
2600 if ((TypeIdx < 0) || (ColorIdx < 0) || (StyleIdx < 0))
2606 int Color = a_NBT.
GetInt(ColorIdx);
2607 int Style = a_NBT.
GetInt(StyleIdx);
2609 std::unique_ptr<cHorse> Monster = std::make_unique<cHorse>(
Type, Color, Style, 1);
2625 switch (a_NBT.
GetType(AgeableIdx))
2629 default:
Age = 0;
break;
2631 Monster->SetAge(
Age);
2634 a_Entities.emplace_back(std::move(Monster));
2670 std::unique_ptr<cIronGolem> Monster = std::make_unique<cIronGolem>();
2681 a_Entities.emplace_back(std::move(Monster));
2706 int Size = a_NBT.
GetInt(SizeIdx);
2708 std::unique_ptr<cMagmaCube> Monster = std::make_unique<cMagmaCube>(Size);
2719 a_Entities.emplace_back(std::move(Monster));
2728 std::unique_ptr<cMooshroom> Monster = std::make_unique<cMooshroom>();
2739 a_Entities.emplace_back(std::move(Monster));
2757 std::unique_ptr<cOcelot> Monster = std::make_unique<cOcelot>();
2769 if (!OwnerInfo.first.empty() && !OwnerInfo.second.IsNil())
2771 Monster->SetOwner(OwnerInfo.first, OwnerInfo.second);
2772 Monster->SetIsTame(
true);
2785 bool Sitting = (a_NBT.
GetByte(SittingIdx) == 1);
2786 Monster->SetIsSitting(Sitting);
2793 switch (a_NBT.
GetType(AgeableIdx))
2797 default:
Age = 0;
break;
2799 Monster->SetAge(
Age);
2802 a_Entities.emplace_back(std::move(Monster));
2838 std::unique_ptr<cPig> Monster = std::make_unique<cPig>();
2853 switch (a_NBT.
GetType(AgeableIdx))
2857 default:
Age = 0;
break;
2859 Monster->SetAge(
Age);
2862 a_Entities.emplace_back(std::move(Monster));
2917 int MoreCarrotTicksIdx = a_NBT.
FindChildByName(a_TagIdx,
"MoreCarrotTicks");
2919 if ((TypeIdx < 0) || (MoreCarrotTicksIdx < 0))
2925 int MoreCarrotTicks = a_NBT.
GetInt(MoreCarrotTicksIdx);
2927 std::unique_ptr<cRabbit> Monster = std::make_unique<cRabbit>(
static_cast<eRabbitType>(
Type), MoreCarrotTicks);
2942 switch (a_NBT.
GetType(AgeableIdx))
2946 default:
Age = 0;
break;
2948 Monster->SetAge(
Age);
2951 a_Entities.emplace_back(std::move(Monster));
2982 Color =
static_cast<int>(a_NBT.
GetByte(ColorIdx));
2985 std::unique_ptr<cSheep> Monster = std::make_unique<cSheep>(Color);
2999 Monster->SetSheared(a_NBT.
GetByte(ShearedIdx) != 0);
3006 switch (a_NBT.
GetType(AgeableIdx))
3010 default:
Age = 0;
break;
3012 Monster->SetAge(
Age);
3015 a_Entities.emplace_back(std::move(Monster));
3033 std::unique_ptr<cSilverfish> Monster = std::make_unique<cSilverfish>();
3044 a_Entities.emplace_back(std::move(Monster));
3057 std::unique_ptr<cMonster> Monster;
3058 if ((TypeIdx > 0) && (a_NBT.
GetByte(TypeIdx) == 1))
3060 Monster = std::make_unique<cWitherSkeleton>();
3064 Monster = std::make_unique<cSkeleton>();
3077 a_Entities.emplace_back(std::move(Monster));
3102 int Size = a_NBT.
GetInt(SizeIdx);
3104 std::unique_ptr<cSlime> Monster = std::make_unique<cSlime>(Size);
3115 a_Entities.emplace_back(std::move(Monster));
3124 std::unique_ptr<cSnowGolem> Monster = std::make_unique<cSnowGolem>();
3135 a_Entities.emplace_back(std::move(Monster));
3144 std::unique_ptr<cSpider> Monster = std::make_unique<cSpider>();
3155 a_Entities.emplace_back(std::move(Monster));
3164 std::unique_ptr<cSquid> Monster = std::make_unique<cSquid>();
3175 a_Entities.emplace_back(std::move(Monster));
3261 switch (a_NBT.
GetType(AgeableIdx))
3265 default:
Age = 0;
break;
3267 Monster->SetAge(
Age);
3271 if (InventoryIdx > 0)
3277 a_Entities.emplace_back(std::move(Monster));
3304 std::unique_ptr<cWitch> Monster = std::make_unique<cWitch>();
3315 a_Entities.emplace_back(std::move(Monster));
3324 std::unique_ptr<cWither> Monster = std::make_unique<cWither>();
3338 Monster->SetWitherInvulnerableTicks(
static_cast<unsigned int>(a_NBT.
GetInt(CurrLine)));
3341 a_Entities.emplace_back(std::move(Monster));
3350 auto Monster = std::make_unique<cWitherSkeleton>();
3361 a_Entities.emplace_back(std::move(Monster));
3370 std::unique_ptr<cWolf> Monster = std::make_unique<cWolf>();
3381 if (!OwnerInfo.first.empty() && !OwnerInfo.second.IsNil())
3383 Monster->SetOwner(OwnerInfo.first, OwnerInfo.second);
3384 Monster->SetIsTame(
true);
3390 bool Sitting = (a_NBT.
GetByte(SittingIdx) == 1);
3391 Monster->SetIsSitting(Sitting);
3396 bool Angry = (a_NBT.
GetByte(AngryIdx) == 1);
3397 Monster->SetIsAngry(Angry);
3400 if (CollarColorIdx > 0)
3402 switch (a_NBT.
GetType(CollarColorIdx))
3407 Monster->SetCollarColor(a_NBT.
GetByte(CollarColorIdx));
3413 Monster->SetCollarColor(a_NBT.
GetInt(CollarColorIdx));
3428 switch (a_NBT.
GetType(AgeableIdx))
3432 default:
Age = 0;
break;
3434 Monster->SetAge(
Age);
3437 a_Entities.emplace_back(std::move(Monster));
3455 std::unique_ptr<cZombie> Monster = std::make_unique<cZombie>();
3470 switch (a_NBT.
GetType(AgeableIdx))
3474 default:
Age = 0;
break;
3476 Monster->SetAge(
Age);
3479 a_Entities.emplace_back(std::move(Monster));
3497 std::unique_ptr<cZombiePigman> Monster = std::make_unique<cZombiePigman>();
3512 switch (a_NBT.
GetType(AgeableIdx))
3516 default:
Age = 0;
break;
3518 Monster->SetAge(
Age);
3521 a_Entities.emplace_back(std::move(Monster));
3531 if (ProfessionIdx < 0)
3538 std::unique_ptr<cZombieVillager> Monster = std::make_unique<cZombieVillager>(Profession);
3555 switch (a_NBT.
GetType(AgeableIdx))
3559 default:
Age = 0;
break;
3561 Monster->SetAge(
Age);
3564 a_Entities.emplace_back(std::move(Monster));
3577 if (OwnerUUIDIdx > 0)
3586 if (OwnerName.empty() && OwnerUUID.
IsNil())
3593 if (OwnerUUID.
IsNil())
3598 if (OwnerUUID.
IsNil())
3606 if (OwnerName.empty())
3610 if (OwnerName.empty())
3617 return { OwnerName, OwnerUUID };
3641 a_Entity.
SetSpeed(Speed[0], Speed[1], Speed[2]);
3667 else if (Health > 0)
3685 float DropChance[5];
3709 bool CanPickUpLoot = (a_NBT.
GetByte(LootTag) == 1);
3719 int CustomNameVisibleTag = a_NBT.
FindChildByName(a_TagIdx,
"CustomNameVisible");
3720 if ((CustomNameVisibleTag > 0) && (a_NBT.
GetType(CustomNameVisibleTag) ==
TAG_Byte))
3722 bool CustomNameVisible = (a_NBT.
GetByte(CustomNameVisibleTag) == 1);
3728 if ((LeashedIdx >= 0) && a_NBT.
GetByte(LeashedIdx))
3748 double PosX = 0.0, PosY = 0.0, PosZ = 0.0;
3749 bool KnotPosPresent =
true;
3751 if (LeashDataLine >= 0)
3757 KnotPosPresent =
false;
3760 if (LeashDataLine >= 0)
3766 KnotPosPresent =
false;
3769 if (LeashDataLine >= 0)
3775 KnotPosPresent =
false;
3795 bool IsInGround =
false;
3797 if (InGroundIdx > 0)
3799 IsInGround = (a_NBT.
GetByte(InGroundIdx) != 0);
3821 return (idx == a_NumDoubles);
3837 a_Floats[idx] = a_NBT.
GetFloat(Tag);
3839 return (idx == a_NumFloats);
3879 m_ParentSchema(a_ParentSchema),
3880 m_RegionX(a_RegionX),
3881 m_RegionZ(a_RegionZ),
3882 m_FileName(a_FileName)
3892 bool writeOutNeeded =
false;
3894 if (m_File.IsOpen())
3916 if (m_File.Read(m_Header,
sizeof(m_Header)) !=
sizeof(m_Header))
3920 memset(m_Header, 0,
sizeof(m_Header));
3921 writeOutNeeded =
true;
3925 if (m_File.Read(m_TimeStamps,
sizeof(m_TimeStamps)) !=
sizeof(m_TimeStamps))
3929 memset(m_TimeStamps, 0,
sizeof(m_TimeStamps));
3930 writeOutNeeded =
true;
3937 (m_File.Write(m_Header,
sizeof(m_Header)) !=
sizeof(m_Header)) ||
3938 (m_File.Write(m_TimeStamps,
sizeof(m_TimeStamps)) !=
sizeof(m_TimeStamps))
3941 LOGWARNING(
"Cannot process MCA header in file \"%s\", chunks in that file will be lost", m_FileName.c_str());
3955 if (!OpenFile(
true))
3960 int LocalX = a_Chunk.
m_ChunkX % 32;
3963 LocalX = 32 + LocalX;
3965 int LocalZ = a_Chunk.
m_ChunkZ % 32;
3968 LocalZ = 32 + LocalZ;
3970 unsigned ChunkLocation = ntohl(m_Header[LocalX + 32 * LocalZ]);
3971 unsigned ChunkOffset = ChunkLocation >> 8;
3972 if (ChunkOffset < 2)
3977 m_File.Seek(
static_cast<int>(ChunkOffset * 4096));
3980 if (m_File.Read(&ChunkSize, 4) != 4)
3982 m_ParentSchema.ChunkLoadFailed(a_Chunk,
"Cannot read chunk size", {});
3985 ChunkSize = ntohl(ChunkSize);
3989 m_ParentSchema.ChunkLoadFailed(a_Chunk,
"Chunk size too small", {});
3993 char CompressionType = 0;
3994 if (m_File.Read(&CompressionType, 1) != 1)
3996 m_ParentSchema.ChunkLoadFailed(a_Chunk,
"Cannot read chunk compression", {});
4001 a_Data = m_File.Read(ChunkSize);
4002 if (a_Data.size() != ChunkSize)
4004 m_ParentSchema.ChunkLoadFailed(a_Chunk,
"Cannot read entire chunk data", a_Data);
4008 if (CompressionType != 2)
4011 m_ParentSchema.ChunkLoadFailed(a_Chunk, fmt::format(FMT_STRING(
"Unknown chunk compression: {}"), CompressionType), a_Data);
4037 if (!OpenFile(
false))
4039 LOGWARNING(
"Cannot save chunk [%d, %d], opening file \"%s\" failed", a_Chunk.
m_ChunkX, a_Chunk.
m_ChunkZ, GetFileName().c_str());
4043 int LocalX = a_Chunk.
m_ChunkX % 32;
4046 LocalX = 32 + LocalX;
4048 int LocalZ = a_Chunk.
m_ChunkZ % 32;
4051 LocalZ = 32 + LocalZ;
4054 unsigned ChunkSector = FindFreeLocation(LocalX, LocalZ, a_Data.size());
4057 m_File.Seek(
static_cast<int>(ChunkSector * 4096));
4058 UInt32 ChunkSize = htonl(
static_cast<UInt32>(a_Data.size() + 1));
4059 if (m_File.Write(&ChunkSize, 4) != 4)
4061 LOGWARNING(
"Cannot save chunk [%d, %d], writing(1) data to file \"%s\" failed", a_Chunk.
m_ChunkX, a_Chunk.
m_ChunkZ, GetFileName().c_str());
4064 char CompressionType = 2;
4065 if (m_File.Write(&CompressionType, 1) != 1)
4067 LOGWARNING(
"Cannot save chunk [%d, %d], writing(2) data to file \"%s\" failed", a_Chunk.
m_ChunkX, a_Chunk.
m_ChunkZ, GetFileName().c_str());
4070 if (m_File.Write(a_Data.data(), a_Data.size()) !=
static_cast<int>(a_Data.size()))
4072 LOGWARNING(
"Cannot save chunk [%d, %d], writing(3) data to file \"%s\" failed", a_Chunk.
m_ChunkX, a_Chunk.
m_ChunkZ, GetFileName().c_str());
4078 if (BytesWritten % 4096 != 0)
4080 static const char Padding[4095] = {0};
4081 m_File.Write(Padding, 4096 - (BytesWritten % 4096));
4086 if (ChunkSize > 255)
4088 LOGWARNING(
"Cannot save chunk [%d, %d], the data is too large (%u KiB, maximum is 1024 KiB). Remove some entities and retry.",
4095 m_Header[LocalX + 32 * LocalZ] = htonl(
static_cast<UInt32>((ChunkSector << 8) | ChunkSize));
4098 m_TimeStamps[LocalX + 32 * LocalZ] = htonl(
static_cast<UInt32>(time(
nullptr)));
4100 if (m_File.Seek(0) < 0)
4102 LOGWARNING(
"Cannot save chunk [%d, %d], seeking in file \"%s\" failed", a_Chunk.
m_ChunkX, a_Chunk.
m_ChunkZ, GetFileName().c_str());
4105 if (m_File.Write(m_Header,
sizeof(m_Header)) !=
sizeof(m_Header))
4107 LOGWARNING(
"Cannot save chunk [%d, %d], writing header to file \"%s\" failed", a_Chunk.
m_ChunkX, a_Chunk.
m_ChunkZ, GetFileName().c_str());
4110 if (m_File.Write(m_TimeStamps,
sizeof(m_TimeStamps)) !=
sizeof(m_TimeStamps))
4112 LOGWARNING(
"Cannot save chunk [%d, %d], writing timestamps to file \"%s\" failed", a_Chunk.
m_ChunkX, a_Chunk.
m_ChunkZ, GetFileName().c_str());
4126 unsigned ChunkLocation = ntohl(m_Header[a_LocalX + 32 * a_LocalZ]);
4127 unsigned ChunkLen = ChunkLocation & 0xff;
4130 return ChunkLocation >> 8;
4134 unsigned MaxLocation = 2 << 8;
4135 for (
size_t i = 0; i <
ARRAYCOUNT(m_Header); i++)
4137 ChunkLocation = ntohl(m_Header[i]);
4138 ChunkLocation = ChunkLocation + ((ChunkLocation & 0xff) << 8);
4139 if (MaxLocation < ChunkLocation)
4141 MaxLocation = ChunkLocation;
4144 return MaxLocation >> 8;
EMCSBiome
Biome IDs The first batch corresponds to the clientside biomes, used by MineCraft.
bool StringToItem(const AString &a_ItemTypeString, cItem &a_Item)
Translates an itemtype string into an item.
AString ItemTypeToString(short a_ItemType)
Translates itemtype into a string.
@ E_BLOCK_STANDING_BANNER
@ E_BLOCK_ENCHANTMENT_TABLE
unsigned char NIBBLETYPE
The datatype used by nibbledata (meta, light, skylight)
unsigned char HEIGHTTYPE
The type used by the heightmap.
std::vector< OwnedEntity > cEntityList
unsigned char BLOCKTYPE
The datatype used by blockdata.
#define ARRAYCOUNT(X)
Evaluates to the number of elements in an array (compile-time!)
std::basic_string_view< std::byte > ContiguousByteBufferView
#define FAST_FLOOR_DIV(x, div)
Faster than (int)floorf((float)x / (float)div)
T Clamp(T a_Value, T a_Min, T a_Max)
Clamp X to the specified range.
std::basic_string< std::byte > ContiguousByteBuffer
void FLOGINFO(std::string_view a_Format, const Args &... args)
void LOGWARNING(std::string_view a_Format, const Args &... args)
void FLOGWARNING(std::string_view a_Format, const Args &... args)
eMonsterType
Identifies individual monster type.
int GetBEInt(const std::byte *const a_Mem)
Reads four bytes from the specified memory location and interprets them as BigEndian int.
AStringVector StringSplit(const AString &str, const AString &delim)
Split the string at any of the listed delimiters.
std::vector< AString > AStringVector
Vector3< double > Vector3d
#define MAX_MCA_FILES
If defined, the BlockSkyLight values will be copied over to BlockLight upon chunk saving,...
bool ParseString(const AString &a_JsonStr, Json::Value &a_Root, AString *a_ErrorMsg)
void Write(const std::string &a_FileName, ContiguousByteBufferView a_Contents)
Writes a_Contents into file, compressing it along the way.
eBlockFace Facing(const BlockState Block)
unsigned char Rotation(const BlockState Block)
unsigned char Age(const BlockState Block)
unsigned char Level(const BlockState Block)
void ParseFromNBT(cEnchantments &a_Enchantments, const cParsedNBT &a_NBT, int a_EnchListTagIdx)
Reads the enchantments from the specified NBT list tag (ench or StoredEnchantments)
std::pair< Namespace, std::string_view > SplitNamespacedID(std::string_view ID)
eMonsterType ToMonsterType(std::string_view a_ID)
static constexpr size_t SectionBlockCount
NIBBLETYPE GetMeta(Vector3i a_Position) const
NIBBLETYPE[SectionMetaCount] SectionMetaType
static constexpr size_t SectionMetaCount
BLOCKTYPE GetBlock(Vector3i a_Position) const
BLOCKTYPE[SectionBlockCount] SectionType
NIBBLETYPE[SectionLightCount] SectionType
static constexpr size_t SectionLightCount
Wraps the chunk coords into a single structure.
static void AbsoluteToRelative(int &a_X, int &a_Y, int &a_Z, int &a_ChunkX, int &a_ChunkZ)
Converts absolute block coords into relative (chunk + block) coords:
static void SetHeight(HeightMap &a_HeightMap, int a_X, int a_Z, HEIGHTTYPE a_Height)
HEIGHTTYPE HeightMap[Width *Width]
The type used for any heightmap operations and storage; idx = x + Width * z; Height points to the hig...
static size_t MakeIndex(int x, int y, int z)
static const size_t NumSections
EMCSBiome BiomeMap[Width *Width]
The type used for any biomemap operations and storage inside Cuberite, using Cuberite biomes (need no...
ePickupState
Determines when the arrow can be picked up (depending on player gamemode).
static eMaterial StringToMaterial(const AString &a_Material)
Returns the boat material for the passed string.
void SetPitch(double a_Pitch)
void SetYaw(double a_Yaw)
float GetMaxHealth(void) const
void SetHealth(float a_Health)
Sets the health of this entity; doesn't broadcast any hurt animation.
void SetSpeed(double a_SpeedX, double a_SpeedY, double a_SpeedZ)
Sets the speed of the entity, measured in m / sec.
void SetPosition(double a_PosX, double a_PosY, double a_PosZ)
eType
All types of entity effects (numbers correspond to protocol / storage types)
void SetProtocolFacing(Byte a_Facing)
Set the direction in which the entity is facing.
void SetIsInGround(bool a_IsInGround)
Sets the internal InGround flag.
cEnchantments m_Enchantments
AStringVector m_LoreTable
void Empty(void)
Empties the item and frees up any dynamic storage used by the internals.
cFireworkItem m_FireworkItem
void SetSlot(int a_X, int a_Y, const cItem &a_Item)
int GetNumSlots(void) const
void SetDropChanceBoots(float a_DropChanceBoots)
void SetCustomName(const AString &a_CustomName)
Sets the custom name of the monster.
void SetCanPickUpLoot(bool a_CanPickUpLoot)
void SetDropChanceLeggings(float a_DropChanceLeggings)
void SetDropChanceHelmet(float a_DropChanceHelmet)
void SetLeashToPos(Vector3d *pos)
Sets entity position to where is leashed this mob.
void SetDropChanceWeapon(float a_DropChanceWeapon)
void SetCustomNameAlwaysVisible(bool a_CustomNameAlwaysVisible)
Sets the custom name visiblity of this monster.
void SetDropChanceChestplate(float a_DropChanceChestplate)
bool IsLocked(void)
Returns true if the CS is currently locked.
RAII for cCriticalSection - locks the CS on creation, unlocks on destruction.
static bool CreateFolder(const AString &a_FolderPath)
Creates a new folder with the specified name.
static char PathSeparator()
static bool Exists(const AString &a_FileName)
Returns true if the file specified exists.
bool Open(const AString &iFileName, eMode iMode)
int Write(const void *a_Buffer, size_t a_NumBytes)
Writes up to a_NumBytes bytes from a_Buffer, returns the number of bytes actually written,...
AString GetPlayerNameFromUUID(const cUUID &a_UUID, bool a_UseOnlyCached=false)
Converts a UUID into a playername.
cUUID GetUUIDFromPlayerName(const AString &a_PlayerName, bool a_UseOnlyCached=false)
Converts a player name into a UUID.
cMojangAPI & GetMojangAPI(void)
Contains the data for a loaded / generated chunk, ready to be set into a cWorld.
Contains the result of a compression or extraction operation.
Result CompressZLib(ContiguousByteBufferView Input)
Result ExtractZLib(ContiguousByteBufferView Input)
bool FromString(const AString &a_StringUUID)
Tries to interpret the string as a short or long form UUID and assign from it.
bool IsNil() const
Returns true if this contains the "nil" UUID with all bits set to 0.
void Set(T a_x, T a_y, T a_z)
const AString & GetDataPath(void) const
Returns the data path to the world data.
int GetSpawnX(void) const
bool IsWeatherRain(void) const
Returns true if the current weather is rainy.
virtual cTickTimeLong GetWorldAge(void) const override
const AString & GetName(void) const
Returns the name of the world.
int GetSpawnZ(void) const
eGameMode GetGameMode(void) const
Returns the current game mode.
int GetSpawnY(void) const
cTickTimeLong GetWorldDate() const
bool IsWeatherStorm(void) const
Returns true if the current weather is stormy.
Parses and contains the parsed data Also implements data accessor functions for tree traversal and va...
std::string_view GetStringView(int a_Tag) const
Returns the value stored in a String tag.
int GetNextSibling(int a_Tag) const
Returns the next sibling of the specified tag, or -1 if none.
size_t GetErrorPos() const
Returns the position where an error occurred while parsing.
std::error_code GetErrorCode() const
Returns the error code for the parsing of the NBT data.
Int16 GetShort(int a_Tag) const
Returns the value stored in a Short tag.
const std::byte * GetData(int a_Tag) const
Returns the data stored in this tag.
int GetFirstChild(int a_Tag) const
Returns the first child of the specified tag, or -1 if none / not applicable.
double GetDouble(int a_Tag) const
Returns the value stored in a Double tag.
eTagType GetType(int a_Tag) const
int FindChildByName(int a_Tag, const AString &a_Name) const
Returns the direct child tag of the specified name, or -1 if no such tag.
unsigned char GetByte(int a_Tag) const
Returns the value stored in a Byte tag.
size_t GetDataLength(int a_Tag) const
Returns the length of the tag's data, in bytes.
float GetFloat(int a_Tag) const
Returns the value stored in a Float tag.
Int32 GetInt(int a_Tag) const
Returns the value stored in an Int tag.
AString GetString(int a_Tag) const
Returns the value stored in a String tag.
eTagType GetChildrenType(int a_Tag) const
Returns the children type for a List tag; undefined on other tags.
void AddByte(const AString &a_Name, unsigned char a_Value)
void AddInt(const AString &a_Name, Int32 a_Value)
void AddString(const AString &a_Name, std::string_view a_Value)
void BeginCompound(const AString &a_Name)
ContiguousByteBufferView GetResult(void) const
void AddLong(const AString &a_Name, Int64 a_Value)
static void ParseFromNBT(cFireworkItem &a_FireworkItem, const cParsedNBT &a_NBT, int a_TagIdx, const ENUM_ITEM_TYPE a_Type)
Reads NBT data from a NBT object and populates a FireworkItem with it.
static void Serialize(const cWorld &aWorld, cChunkCoords aCoords, cFastNBTWriter &aWriter)
Serializes the chunk into the specified writer.
Implements the Anvil world storage schema.
bool SetChunkData(const cChunkCoords &a_Chunk, ContiguousByteBufferView a_Data)
Sets chunk data into the correct file; locks file CS as needed.
bool LoadMonsterBaseFromNBT(cMonster &a_Monster, const cParsedNBT &a_NBT, int a_TagIdx)
Loads monster common data from the NBT compound; returns true if successful.
void LoadLeashKnotFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadSnowGolemFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadLeashToPosition(cMonster &a_Monster, const cParsedNBT &a_NBT, int a_TagIdx)
Loads the position to where is leashed the monster.
void LoadMinecartRFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadMooshroomFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadPillagerFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadThrownEnderpearlFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadVindicatorFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
AString DecodeSignLine(const AString &a_Line)
Decodes the text contained within a sign.
virtual bool SaveChunk(const cChunkCoords &a_Chunk) override
OwnedBlockEntity LoadBedFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void LoadLlamaFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadBlockEntitiesFromNBT(cBlockEntities &a_BlockEntitites, const cParsedNBT &a_NBT, int a_Tag, const ChunkBlockData &a_BlockData)
Loads the chunk's BlockEntities from NBT data (a_Tag is the Level\TileEntities list tag; may be -1)
void LoadTNTFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadZombieVillagerFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadPigFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadArrowFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadSkeletonFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
bool CheckBlockEntityType(const cParsedNBT &a_NBT, int a_TagIdx, const AStringVector &a_ExpectedTypes, Vector3i a_Pos)
Returns true iff the "id" child tag inside the specified tag equals (case-sensitive) any of the speci...
const std::byte * GetSectionData(const cParsedNBT &a_NBT, int a_Tag, const AString &a_ChildName, size_t a_Length)
Copies a_Length bytes of data from the specified NBT Tag's Child into the a_Destination buffer.
bool GetChunkData(const cChunkCoords &a_Chunk, ContiguousByteBuffer &a_Data)
Gets chunk data from the correct file; locks file CS as needed.
void LoadSilverfishFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
OwnedBlockEntity LoadEnderChestFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
Compression::Compressor m_Compressor
void LoadSalmonFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadHuskFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadCowFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
std::shared_ptr< cMCAFile > LoadMCAFile(const cChunkCoords &a_Chunk)
Gets the correct MCA file either from cache or from disk, manages the m_MCAFiles cache; assumes m_CS ...
void LoadMuleFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadHorseFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadMinecartFFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
OwnedBlockEntity LoadBlockEntityFromNBT(const cParsedNBT &a_NBT, int a_Tag, Vector3i a_Pos, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
Loads the data for a block entity from the specified NBT tag.
void LoadFallingBlockFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadMinecartHFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadDrownedFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadChickenFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadGiantFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadItemGridFromNBT(cItemGrid &a_ItemGrid, const cParsedNBT &a_NBT, int a_ItemsTagIdx, int s_SlotOffset=0)
Loads contentents of an Items[] list tag into a cItemGrid ItemGrid begins at the specified slot offse...
void LoadGuardianFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadDolphinFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadCreeperFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadBlazeFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadWanderingTraderFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadHoglinFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
OwnedBlockEntity LoadBeaconFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void LoadTraderLlamaFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadZoglinFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadSkeletonHorseFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
bool GetBlockEntityNBTPos(const cParsedNBT &a_NBT, int a_TagIdx, Vector3i &a_AbsPos)
Helper function for extracting the X, Y, and Z int subtags of a NBT compound; returns true if success...
OwnedBlockEntity LoadDropperFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void LoadBatFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadEvokerFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadPickupFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadWitherFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadShulkerFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadPandaFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
bool LoadDoublesListFromNBT(double *a_Doubles, int a_NumDoubles, const cParsedNBT &a_NBT, int a_TagIdx)
Loads an array of doubles of the specified length from the specified NBT list tag a_TagIdx; returns t...
void LoadWitchFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
bool LoadEntityBaseFromNBT(cEntity &a_Entity, const cParsedNBT &a_NBT, int a_TagIdx)
Loads entity common data from the NBT compound; returns true if successful.
void LoadCodFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
OwnedBlockEntity LoadEnchantingTableFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void LoadWolfFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
OwnedBlockEntity LoadCommandBlockFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void LoadPolarBearFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadRavagerFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
OwnedBlockEntity LoadNoteBlockFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
OwnedBlockEntity LoadMobSpawnerFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void LoadStriderFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadExpOrbFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadZombieHorseFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadFoxFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadSheepFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadWitherSkeletonFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadCaveSpiderFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadHangingFromNBT(cHangingEntity &a_Hanging, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadZombifiedPiglinFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
std::pair< AString, cUUID > LoadEntityOwner(const cParsedNBT &a_NBT, int a_TagIdx)
Loads the owner name and UUID from the entity at the specified NBT tag.
OwnedBlockEntity LoadFlowerPotFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
OwnedBlockEntity LoadBannerFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
OwnedBlockEntity LoadBrewingstandFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void LoadItemFrameFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadEnderCrystalFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
virtual bool LoadChunk(const cChunkCoords &a_Chunk) override
OwnedBlockEntity LoadFurnaceFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void LoadEggFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadEndermiteFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
Compression::Extractor m_Extractor
void LoadSquidFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadPiglinBruteFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
cCriticalSection m_CS
Protects m_Files against multithreaded access.
void LoadIllusionerFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadMinecartCFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
Compression::Result SaveChunkToData(const cChunkCoords &a_Chunk)
Saves the chunk into datastream (no locking needed)
OwnedBlockEntity LoadMobHeadFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void LoadSnowballFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadEndermanFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadBoatFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
OwnedBlockEntity LoadSignFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void ChunkLoadFailed(const cChunkCoords a_ChunkCoords, const AString &a_Reason, ContiguousByteBufferView a_ChunkDataToSave)
Reports that the specified chunk failed to load and saves the chunk data to an external file.
std::list< std::shared_ptr< cMCAFile > > m_Files
A MRU cache of MCA files.
void LoadRabbitFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadTropicalFishFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadZombieFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadPaintingFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
bool LoadItemFromNBT(cItem &a_Item, const cParsedNBT &a_NBT, int a_TagIdx)
Loads a cItem contents from the specified NBT tag; returns true if successful.
OwnedBlockEntity LoadHopperFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
bool LoadProjectileBaseFromNBT(cProjectileEntity &a_Entity, const cParsedNBT &a_NBT, int a_TagIx)
Loads projectile common data from the NBT compound; returns true if successful.
void LoadTurtleFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadMagmaCubeFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadDonkeyFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
OwnedBlockEntity LoadDispenserFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
bool LoadHeightMapFromNBT(cChunkDef::HeightMap &a_HeightMap, const cParsedNBT &a_NBT, int a_TagIdx)
Loads the chunk's height map into a_HeightMap if heights present and valid; returns false otherwise.
bool LoadBiomeMapFromNBT(cChunkDef::BiomeMap &a_BiomeMap, const cParsedNBT &a_NBT, int a_TagIdx)
Loads the chunk's biome map into a_BiomeMap if biomes present and valid; returns false otherwise.
bool LoadChunkFromData(const cChunkCoords &a_Chunk, ContiguousByteBufferView a_Data)
Loads the chunk from the data (no locking needed)
void LoadFireballFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadVillagerFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadParrotFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadVexFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadFireChargeFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadPufferfishFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadEntitiesFromNBT(cEntityList &a_Entitites, const cParsedNBT &a_NBT, int a_Tag)
Loads the chunk's entities from NBT data (a_Tag is the Level\Entities list tag; may be -1)
void LoadElderGuardianFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadMinecartTFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
bool LoadChunkFromNBT(const cChunkCoords &a_Chunk, const cParsedNBT &a_NBT, ContiguousByteBufferView a_RawChunkData)
Loads the chunk from NBT data (no locking needed).
OwnedBlockEntity LoadChestFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
void LoadOcelotFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadGhastFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
@ MCA_CHUNK_HEADER_LENGTH
There are 5 bytes of header in front of each chunk.
void LoadSlimeFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadOldMinecartFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadSplashPotionFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
cWSSAnvil(cWorld *a_World, int a_CompressionFactor)
void LoadEnderDragonFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadPhantomFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
OwnedBlockEntity LoadJukeboxFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
OwnedBlockEntity LoadEndPortalFromNBT(const cParsedNBT &a_NBT, int a_TagIdx, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, Vector3i a_Pos)
virtual ~cWSSAnvil() override
void LoadStrayFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadSpiderFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadPiglinFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
bool LoadFloatsListFromNBT(float *a_Floats, int a_NumFloats, const cParsedNBT &a_NBT, int a_TagIdx)
Loads an array of floats of the specified length from the specified NBT list tag a_TagIdx; returns tr...
void LoadEntityFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_EntityTagIdx, std::string_view a_EntityName)
void LoadIronGolemFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
void LoadCatFromNBT(cEntityList &a_Entities, const cParsedNBT &a_NBT, int a_TagIdx)
bool OpenFile(bool a_IsForReading)
Opens a MCA file either for a Read operation (fails if doesn't exist) or for a Write operation (creat...
bool GetChunkData(const cChunkCoords &a_Chunk, ContiguousByteBuffer &a_Data)
cMCAFile(cWSSAnvil &a_ParentSchema, const AString &a_FileName, int a_RegionX, int a_RegionZ)
bool SetChunkData(const cChunkCoords &a_Chunk, ContiguousByteBufferView a_Data)
unsigned FindFreeLocation(int a_LocalX, int a_LocalZ, size_t a_DataSize)
Finds a free location large enough to hold a_Data.
std::unordered_map< size_t, OwnedBlockEntity > cBlockEntities
std::unique_ptr< cBlockEntity > OwnedBlockEntity