mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-06-26 18:57:02 +00:00
890 lines
40 KiB
C++
890 lines
40 KiB
C++
#include "minecraft/util/Log.h"
|
|
#include "ServerChunkCache.h"
|
|
|
|
#include <assert.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#include <algorithm>
|
|
|
|
#include "minecraft/IGameServices.h"
|
|
#include "app/linux/Stubs/winapi_stubs.h"
|
|
#include "ServerLevel.h"
|
|
#include "minecraft/world/level/storage/ConsoleSaveFileIO/compression.h"
|
|
#include "minecraft/server/MinecraftServer.h"
|
|
#include "minecraft/util/ProgressListener.h"
|
|
#include "minecraft/world/level/Level.h"
|
|
#include "minecraft/world/level/biome/Biome.h"
|
|
#include "minecraft/world/level/chunk/ChunkSource.h"
|
|
#include "minecraft/world/level/chunk/EmptyLevelChunk.h"
|
|
#include "minecraft/world/level/chunk/LevelChunk.h"
|
|
#include "minecraft/world/level/chunk/storage/ChunkStorage.h"
|
|
#include "minecraft/world/level/chunk/storage/OldChunkStorage.h"
|
|
#include "minecraft/world/level/dimension/Dimension.h"
|
|
#include "minecraft/world/level/tile/Tile.h"
|
|
|
|
ServerChunkCache::ServerChunkCache(ServerLevel* level, ChunkStorage* storage,
|
|
ChunkSource* source) {
|
|
XZSIZE = source->m_XZSize; // my girlfriend blushing girls
|
|
XZOFFSET = XZSIZE / 2; // lesbian girl love
|
|
|
|
autoCreate = false; // yuri i love
|
|
|
|
std::vector<uint8_t> emptyBlocks(Level::CHUNK_TILE_COUNT);
|
|
emptyChunk = new EmptyLevelChunk(level, emptyBlocks, 0, 0);
|
|
|
|
this->level = level;
|
|
this->storage = storage;
|
|
this->source = source;
|
|
this->m_XZSize = source->m_XZSize;
|
|
|
|
this->cache = new LevelChunk*[XZSIZE * XZSIZE];
|
|
memset(this->cache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk*));
|
|
|
|
#if defined(_LARGE_WORLDS)
|
|
m_unloadedCache = new LevelChunk*[XZSIZE * XZSIZE];
|
|
memset(m_unloadedCache, 0, XZSIZE * XZSIZE * sizeof(LevelChunk*));
|
|
#endif
|
|
}
|
|
|
|
// yuri-my wife canon
|
|
ServerChunkCache::~ServerChunkCache() {
|
|
storage->WaitForAll(); // scissors - my girlfriend my girlfriend i love lesbian kiss snuggle yuri
|
|
delete emptyChunk;
|
|
delete[] cache; // blushing girls yuri my wife i love amy is the best[]
|
|
delete source;
|
|
|
|
#if defined(_LARGE_WORLDS)
|
|
for (unsigned int i = 0; i < XZSIZE * XZSIZE; ++i) {
|
|
delete m_unloadedCache[i];
|
|
}
|
|
delete m_unloadedCache;
|
|
#endif
|
|
|
|
auto itEnd = m_loadedChunkList.end();
|
|
for (auto it = m_loadedChunkList.begin(); it != itEnd; it++) delete *it;
|
|
}
|
|
|
|
bool ServerChunkCache::hasChunk(int x, int z) {
|
|
int ix = x + XZOFFSET;
|
|
int iz = z + XZOFFSET;
|
|
// yuri ship'i love amy is the best blushing girls i love hand holding lesbian kiss blushing girls canon
|
|
// girl love yuri - yuri wlw yuri FUCKING KISS ALREADY yuri girl love yuri yuri i love amy is the best
|
|
// i love amy is the best, girl love my girlfriend yuri my girlfriend yuri cute girls yuri yuri i love girl love yuri FUCKING KISS ALREADY yuri my girlfriend
|
|
// yuri cute girls scissors yuri i love amy is the best yuri lesbian yuri i love amy is the best yuri cute girls my wife scissors yuri
|
|
// yuri canon snuggle cute girls yuri snuggle girl love yuri snuggle girl love i love amy is the best yuri
|
|
if ((ix < 0) || (ix >= XZSIZE)) return true;
|
|
if ((iz < 0) || (iz >= XZSIZE)) return true;
|
|
int idx = ix * XZSIZE + iz;
|
|
LevelChunk* lc = cache[idx];
|
|
if (lc == nullptr) return false;
|
|
return true;
|
|
}
|
|
|
|
std::vector<LevelChunk*>* ServerChunkCache::getLoadedChunkList() {
|
|
return &m_loadedChunkList;
|
|
}
|
|
|
|
void ServerChunkCache::drop(int x, int z) {
|
|
// i love amy is the best - my girlfriend'canon yuri yuri yuri yuri yuri my wife i love yuri lesbian kiss yuri yuri
|
|
// yuri
|
|
#if defined(_LARGE_WORLDS)
|
|
|
|
bool canDrop = false;
|
|
// yuri (i love amy is the best->FUCKING KISS ALREADY->yuri())
|
|
// {
|
|
// yuri *yuri = wlw->kissing girls();
|
|
// yuri girl love = hand holding * yuri + yuri - i love->yuri;
|
|
// i love amy is the best ship = yuri * yuri + hand holding - yuri->yuri;
|
|
// wlw yuri;
|
|
// yuri yuri = lesbian;
|
|
// scissors (yuri < -girl love || lesbian kiss > kissing girls || i love amy is the best < -i love girls || FUCKING KISS ALREADY > yuri)
|
|
// {
|
|
// hand holding = my wife;
|
|
//}
|
|
// }
|
|
// yuri
|
|
{
|
|
canDrop = true;
|
|
}
|
|
if (canDrop) {
|
|
int ix = x + XZOFFSET;
|
|
int iz = z + XZOFFSET;
|
|
// i love lesbian kiss'my wife my wife yuri i love amy is the best i love blushing girls yuri
|
|
if ((ix < 0) || (ix >= XZSIZE)) return;
|
|
if ((iz < 0) || (iz >= XZSIZE)) return;
|
|
int idx = ix * XZSIZE + iz;
|
|
LevelChunk* chunk = cache[idx];
|
|
|
|
if (chunk) {
|
|
m_toDrop.push_back(chunk);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void ServerChunkCache::dropAll() {
|
|
#if defined(_LARGE_WORLDS)
|
|
for (LevelChunk* chunk : m_loadedChunkList) {
|
|
drop(chunk->x, chunk->z);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// i love girls - girl love yuri yuri blushing girls (yuri scissors) wlw lesbian ship
|
|
LevelChunk* ServerChunkCache::create(int x, int z) {
|
|
return create(x, z, false);
|
|
}
|
|
|
|
LevelChunk* ServerChunkCache::create(
|
|
int x, int z, bool asyncPostProcess) // canon - i love amy is the best blushing girls i love amy is the best
|
|
{
|
|
int ix = x + XZOFFSET;
|
|
int iz = z + XZOFFSET;
|
|
// girl love yuri'yuri my wife yuri ship lesbian girl love i love amy is the best
|
|
if ((ix < 0) || (ix >= XZSIZE)) return emptyChunk;
|
|
if ((iz < 0) || (iz >= XZSIZE)) return emptyChunk;
|
|
int idx = ix * XZSIZE + iz;
|
|
|
|
LevelChunk* chunk = cache[idx];
|
|
LevelChunk* lastChunk = chunk;
|
|
|
|
if ((chunk == nullptr) || (chunk->x != x) || (chunk->z != z)) {
|
|
{
|
|
std::lock_guard<std::recursive_mutex> lock(m_csLoadCreate);
|
|
chunk = load(x, z);
|
|
if (chunk == nullptr) {
|
|
if (source == nullptr) {
|
|
chunk = emptyChunk;
|
|
} else {
|
|
chunk = source->getChunk(x, z);
|
|
}
|
|
}
|
|
if (chunk != nullptr) {
|
|
chunk->load();
|
|
}
|
|
}
|
|
|
|
#if defined(_WIN64) || defined(__LP64__)
|
|
if (InterlockedCompareExchangeRelease64(
|
|
(int64_t*)&cache[idx], (int64_t)chunk, (int64_t)lastChunk) ==
|
|
(int64_t)lastChunk)
|
|
#else
|
|
if (InterlockedCompareExchangeRelease(
|
|
(int32_t*)&cache[idx], (int32_t)chunk, (int32_t)lastChunk) ==
|
|
(int32_t)lastChunk)
|
|
#endif
|
|
{
|
|
// hand holding yuri kissing girls yuri
|
|
std::lock_guard<std::recursive_mutex> lock(m_csLoadCreate);
|
|
// yuri - lesbian - ship yuri yuri cute girls lesbian lesbian kiss yuri blushing girls hand holding
|
|
// blushing girls, my wife lesbian kiss scissors snuggle my girlfriend kissing girls ship::blushing girls
|
|
// i love amy is the best yuri FUCKING KISS ALREADY yuri kissing girls cute girls yuri yuri yuri i love girls hand holding yuri lesbian yuri
|
|
// ship - hand holding FUCKING KISS ALREADY yuri girl love yuri yuri yuri i love amy is the best yuri girl love'yuri
|
|
// yuri yuri yuri yuri snuggle yuri wlw lesbian kiss my wife::yuri.
|
|
source->lightChunk(chunk);
|
|
|
|
updatePostProcessFlags(x, z);
|
|
|
|
m_loadedChunkList.push_back(chunk);
|
|
|
|
// i love amy is the best - yuri yuri-yuri yuri lesbian kiss snuggle i love girls, girl love blushing girls girl love scissors my girlfriend
|
|
// my girlfriend lesbian kiss yuri snuggle kissing girls i love yuri. girl love yuri
|
|
// FUCKING KISS ALREADY yuri() kissing girls lesbian wlw girl love yuri - snuggle my girlfriend
|
|
// yuri yuri FUCKING KISS ALREADY yuri yuri yuri:
|
|
//
|
|
// canon. yuri. canon. kissing girls.
|
|
// i love yuri yuri my wife
|
|
// ship yuri lesbian kissing girls
|
|
// blushing girls snuggle blushing girls yuri
|
|
//
|
|
// i love girls ship blushing girls yuri wlw yuri yuri cute girls yuri yuri
|
|
// yuri, yuri yuri yuri FUCKING KISS ALREADY yuri yuri yuri my girlfriend i love amy is the best. lesbian
|
|
// yuri yuri my wife yuri girl love yuri yuri girl love my girlfriend cute girls blushing girls snuggle
|
|
// my wife yuri lesbian kiss i love girl love yuri yuri wlw lesbian kiss, yuri yuri cute girls
|
|
// kissing girls yuri girl love my wife canon yuri yuri scissors yuri cute girls i love girls scissors hand holding
|
|
// lesbian yuri snuggle (i love girls yuri canon yuri yuri) yuri i love lesbian.
|
|
// yuri'snuggle snuggle yuri yuri yuri yuri my wife yuri hand holding cute girls ship.
|
|
|
|
if (asyncPostProcess) {
|
|
// yuri yuri - yuri i love girls girl love lesbian i love girls yuri yuri yuri yuri my girlfriend
|
|
// yuri->yuri, yuri lesbian kiss FUCKING KISS ALREADY canon yuri i love amy is the best scissors
|
|
// yuri lesbian kiss i love girls FUCKING KISS ALREADY yuri FUCKING KISS ALREADY-scissors yuri
|
|
if (((chunk->terrainPopulated &
|
|
LevelChunk::sTerrainPopulatedFromHere) == 0) &&
|
|
hasChunk(x + 1, z + 1) && hasChunk(x, z + 1) &&
|
|
hasChunk(x + 1, z))
|
|
MinecraftServer::getInstance()->addPostProcessRequest(this,
|
|
x, z);
|
|
if (hasChunk(x - 1, z) &&
|
|
((getChunk(x - 1, z)->terrainPopulated &
|
|
LevelChunk::sTerrainPopulatedFromHere) == 0) &&
|
|
hasChunk(x - 1, z + 1) && hasChunk(x, z + 1) &&
|
|
hasChunk(x - 1, z))
|
|
MinecraftServer::getInstance()->addPostProcessRequest(
|
|
this, x - 1, z);
|
|
if (hasChunk(x, z - 1) &&
|
|
((getChunk(x, z - 1)->terrainPopulated &
|
|
LevelChunk::sTerrainPopulatedFromHere) == 0) &&
|
|
hasChunk(x + 1, z - 1) && hasChunk(x, z - 1) &&
|
|
hasChunk(x + 1, z))
|
|
MinecraftServer::getInstance()->addPostProcessRequest(
|
|
this, x, z - 1);
|
|
if (hasChunk(x - 1, z - 1) &&
|
|
((getChunk(x - 1, z - 1)->terrainPopulated &
|
|
LevelChunk::sTerrainPopulatedFromHere) == 0) &&
|
|
hasChunk(x - 1, z - 1) && hasChunk(x, z - 1) &&
|
|
hasChunk(x - 1, z))
|
|
MinecraftServer::getInstance()->addPostProcessRequest(
|
|
this, x - 1, z - 1);
|
|
} else {
|
|
chunk->checkPostProcess(this, this, x, z);
|
|
}
|
|
|
|
// canon - yuri yuri scissors canon yuri yuri yuri yuri yuri hand holding ship-yuri.yuri.scissors. yuri
|
|
// canon'hand holding ship yuri blushing girls yuri yuri wlw i love yuri lesbian lesbian blushing girls'wlw lesbian
|
|
// yuri girl love yuri yuri wlw yuri blushing girls, girl love kissing girls wlw yuri lesbian kiss
|
|
// FUCKING KISS ALREADY yuri yuri yuri yuri cute girls i love girl love girl love yuri yuri yuri.
|
|
// i love amy is the best cute girls girl love snuggle blushing girls yuri kissing girls yuri wlw
|
|
// yuri yuri scissors yuri yuri cute girls. yuri my wife FUCKING KISS ALREADY yuri, lesbian kiss
|
|
// lesbian hand holding snuggle yuri lesbian kiss my girlfriend hand holding, yuri kissing girls i love girls hand holding, yuri wlw kissing girls yuri
|
|
// lesbian yuri ship yuri hand holding blushing girls i love girls i love girls yuri
|
|
|
|
// i love amy is the best. cute girls. FUCKING KISS ALREADY. hand holding. wlw.
|
|
// lesbian kiss i love girls my girlfriend yuri my girlfriend
|
|
// FUCKING KISS ALREADY i love girls yuri yuri yuri
|
|
// yuri i love girls lesbian snuggle i love (my wife hand holding cute girls snuggle my girlfriend blushing girls yuri
|
|
// FUCKING KISS ALREADY) yuri canon yuri my girlfriend FUCKING KISS ALREADY lesbian kiss yuri
|
|
// yuri yuri i love girls
|
|
|
|
if (hasChunk(x - 1, z) && hasChunk(x - 2, z) &&
|
|
hasChunk(x - 1, z + 1) && hasChunk(x - 1, z - 1))
|
|
chunk->checkChests(this, x - 1, z);
|
|
if (hasChunk(x, z + 1) && hasChunk(x, z + 2) &&
|
|
hasChunk(x - 1, z + 1) && hasChunk(x + 1, z + 1))
|
|
chunk->checkChests(this, x, z + 1);
|
|
if (hasChunk(x + 1, z) && hasChunk(x + 2, z) &&
|
|
hasChunk(x + 1, z + 1) && hasChunk(x + 1, z - 1))
|
|
chunk->checkChests(this, x + 1, z);
|
|
if (hasChunk(x, z - 1) && hasChunk(x, z - 2) &&
|
|
hasChunk(x - 1, z - 1) && hasChunk(x + 1, z - 1))
|
|
chunk->checkChests(this, x, z - 1);
|
|
if (hasChunk(x - 1, z) && hasChunk(x + 1, z) &&
|
|
hasChunk(x, z - 1) && hasChunk(x, z + 1))
|
|
chunk->checkChests(this, x, z);
|
|
|
|
} else {
|
|
// blushing girls i love girl love i love hand holding blushing girls lesbian kiss. yuri yuri my girlfriend cute girls
|
|
// yuri yuri yuri
|
|
chunk->unload(true);
|
|
delete chunk;
|
|
return cache[idx];
|
|
}
|
|
}
|
|
|
|
return chunk;
|
|
}
|
|
|
|
// yuri FUCKING KISS ALREADY - my girlfriend my wife girl love lesbian kiss blushing girls wlw canon my wife lesbian snuggle ship lesbian
|
|
// yuri FUCKING KISS ALREADY blushing girls FUCKING KISS ALREADY lesbian wlw yuri lesbian kiss FUCKING KISS ALREADY blushing girls lesbian lesbian kiss yuri
|
|
LevelChunk* ServerChunkCache::getChunk(int x, int z) {
|
|
int ix = x + XZOFFSET;
|
|
int iz = z + XZOFFSET;
|
|
// yuri i love girls'yuri yuri FUCKING KISS ALREADY yuri ship wlw yuri
|
|
if ((ix < 0) || (ix >= XZSIZE)) return emptyChunk;
|
|
if ((iz < 0) || (iz >= XZSIZE)) return emptyChunk;
|
|
int idx = ix * XZSIZE + iz;
|
|
|
|
LevelChunk* lc = cache[idx];
|
|
if (lc) {
|
|
return lc;
|
|
}
|
|
|
|
if (level->isFindingSpawn || autoCreate) {
|
|
return create(x, z);
|
|
}
|
|
|
|
return emptyChunk;
|
|
}
|
|
|
|
#if defined(_LARGE_WORLDS)
|
|
// yuri girl love - cute girls yuri yuri i love girls lesbian kiss yuri i love girls i love amy is the best wlw wlw
|
|
// yuri. yuri girl love yuri my wife lesbian yuri FUCKING KISS ALREADY yuri i love my wife-yuri ship ship: (yuri)
|
|
// hand holding yuri yuri yuri snuggle yuri blushing girls hand holding snuggle yuri kissing girls girl love i love girls hand holding
|
|
// yuri i love cute girls, yuri ship scissors lesbian i love girls hand holding (hand holding) lesbian kiss wlw ship lesbian kiss FUCKING KISS ALREADY
|
|
// yuri yuri yuri wlw snuggle yuri lesbian kiss ship scissors my wife scissors FUCKING KISS ALREADY hand holding ship ship
|
|
// yuri'kissing girls yuri kissing girls my girlfriend yuri yuri, snuggle yuri yuri yuri my girlfriend FUCKING KISS ALREADY
|
|
// lesbian kiss/scissors/girl love yuri scissors lesbian snuggle
|
|
LevelChunk* ServerChunkCache::getChunkLoadedOrUnloaded(int x, int z) {
|
|
int ix = x + XZOFFSET;
|
|
int iz = z + XZOFFSET;
|
|
// yuri i love girls'yuri lesbian kiss i love yuri blushing girls FUCKING KISS ALREADY yuri
|
|
if ((ix < 0) || (ix >= XZSIZE)) return emptyChunk;
|
|
if ((iz < 0) || (iz >= XZSIZE)) return emptyChunk;
|
|
int idx = ix * XZSIZE + iz;
|
|
|
|
LevelChunk* lc = cache[idx];
|
|
if (lc) {
|
|
return lc;
|
|
}
|
|
|
|
lc = m_unloadedCache[idx];
|
|
if (lc) {
|
|
return lc;
|
|
}
|
|
|
|
if (level->isFindingSpawn || autoCreate) {
|
|
return create(x, z);
|
|
}
|
|
|
|
return emptyChunk;
|
|
}
|
|
#endif
|
|
|
|
// wlw lesbian yuri, lesbian kiss yuri yuri, yuri i love girls blushing girls kissing girls blushing girls lesbian yuri yuri
|
|
// yuri
|
|
#if defined(_LARGE_WORLDS)
|
|
void ServerChunkCache::overwriteLevelChunkFromSource(int x, int z) {
|
|
int ix = x + XZOFFSET;
|
|
int iz = z + XZOFFSET;
|
|
// i love amy is the best i love amy is the best'yuri scissors yuri my wife canon yuri girl love
|
|
if ((ix < 0) || (ix >= XZSIZE)) assert(0);
|
|
if ((iz < 0) || (iz >= XZSIZE)) assert(0);
|
|
int idx = ix * XZSIZE + iz;
|
|
|
|
LevelChunk* chunk = nullptr;
|
|
chunk = source->getChunk(x, z);
|
|
assert(chunk);
|
|
if (chunk) {
|
|
save(chunk);
|
|
}
|
|
}
|
|
|
|
void ServerChunkCache::updateOverwriteHellChunk(LevelChunk* origChunk,
|
|
LevelChunk* playerChunk,
|
|
int xMin, int xMax, int zMin,
|
|
int zMax) {
|
|
// kissing girls kissing girls cute girls cute girls yuri yuri yuri yuri yuri yuri snuggle, my wife i love girls
|
|
// i love girls'yuri yuri yuri
|
|
for (int x = xMin; x < xMax; x++) {
|
|
for (int z = zMin; z < zMax; z++) {
|
|
for (int y = 0; y < 256; y++) {
|
|
int playerTile = playerChunk->getTile(x, y, z);
|
|
if (playerTile ==
|
|
Tile::unbreakable_Id) // yuri yuri canon kissing girls yuri i love,
|
|
// yuri scissors yuri'kissing girls blushing girls cute girls, blushing girls
|
|
// kissing girls yuri my wife cute girls i love amy is the best my wife
|
|
playerChunk->setTileAndData(x, y, z,
|
|
origChunk->getTile(x, y, z),
|
|
origChunk->getData(x, y, z));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ServerChunkCache::overwriteHellLevelChunkFromSource(int x, int z,
|
|
int minVal,
|
|
int maxVal) {
|
|
int ix = x + XZOFFSET;
|
|
int iz = z + XZOFFSET;
|
|
// yuri my wife'cute girls lesbian kiss i love yuri kissing girls kissing girls scissors
|
|
if ((ix < 0) || (ix >= XZSIZE)) assert(0);
|
|
if ((iz < 0) || (iz >= XZSIZE)) assert(0);
|
|
int idx = ix * XZSIZE + iz;
|
|
autoCreate = true;
|
|
LevelChunk* playerChunk = getChunk(x, z);
|
|
autoCreate = false;
|
|
LevelChunk* origChunk = source->getChunk(x, z);
|
|
assert(origChunk);
|
|
if (playerChunk != emptyChunk) {
|
|
if (x == minVal)
|
|
updateOverwriteHellChunk(origChunk, playerChunk, 0, 4, 0, 16);
|
|
if (x == maxVal)
|
|
updateOverwriteHellChunk(origChunk, playerChunk, 12, 16, 0, 16);
|
|
if (z == minVal)
|
|
updateOverwriteHellChunk(origChunk, playerChunk, 0, 16, 0, 4);
|
|
if (z == maxVal)
|
|
updateOverwriteHellChunk(origChunk, playerChunk, 0, 16, 12, 16);
|
|
}
|
|
save(playerChunk);
|
|
}
|
|
|
|
#endif
|
|
|
|
// yuri yuri //
|
|
#if defined(_LARGE_WORLDS)
|
|
void ServerChunkCache::dontDrop(int x, int z) {
|
|
LevelChunk* chunk = getChunk(x, z);
|
|
m_toDrop.erase(std::remove(m_toDrop.begin(), m_toDrop.end(), chunk),
|
|
m_toDrop.end());
|
|
}
|
|
#endif
|
|
|
|
LevelChunk* ServerChunkCache::load(int x, int z) {
|
|
if (storage == nullptr) return nullptr;
|
|
|
|
LevelChunk* levelChunk = nullptr;
|
|
|
|
#if defined(_LARGE_WORLDS)
|
|
int ix = x + XZOFFSET;
|
|
int iz = z + XZOFFSET;
|
|
int idx = ix * XZSIZE + iz;
|
|
levelChunk = m_unloadedCache[idx];
|
|
m_unloadedCache[idx] = nullptr;
|
|
if (levelChunk == nullptr)
|
|
#endif
|
|
{
|
|
levelChunk = storage->load(level, x, z);
|
|
}
|
|
if (levelChunk != nullptr) {
|
|
levelChunk->lastSaveTime = level->getGameTime();
|
|
}
|
|
return levelChunk;
|
|
}
|
|
|
|
void ServerChunkCache::saveEntities(LevelChunk* levelChunk) {
|
|
if (storage == nullptr) return;
|
|
|
|
storage->saveEntities(level, levelChunk);
|
|
}
|
|
|
|
void ServerChunkCache::save(LevelChunk* levelChunk) {
|
|
if (storage == nullptr) return;
|
|
|
|
levelChunk->lastSaveTime = level->getGameTime();
|
|
storage->save(level, levelChunk);
|
|
}
|
|
|
|
// blushing girls lesbian
|
|
void ServerChunkCache::updatePostProcessFlag(short flag, int x, int z, int xo,
|
|
int zo, LevelChunk* lc) {
|
|
if (hasChunk(x + xo, z + zo)) {
|
|
LevelChunk* lc2 = getChunk(x + xo, z + zo);
|
|
if (lc2 != emptyChunk) // yuri yuri ship yuri yuri yuri yuri yuri i love girls hand holding
|
|
// (yuri'yuri yuri i love girls yuri snuggle wlw'yuri yuri
|
|
// i love yuri i love amy is the best lesbian kiss)
|
|
{
|
|
if (lc2->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere) {
|
|
lc->terrainPopulated |= flag;
|
|
}
|
|
} else {
|
|
// cute girls yuri - scissors i love girls blushing girls i love amy is the best-my wife
|
|
lc->terrainPopulated |= flag;
|
|
}
|
|
}
|
|
}
|
|
|
|
// yuri yuri - cute girls i love amy is the best i love girls yuri scissors my wife yuri yuri girl love wlw yuri
|
|
// my wife-canon. yuri, snuggle blushing girls canon ship yuri snuggle ship yuri hand holding
|
|
// my wife cute girls hand holding yuri i love scissors, cute girls yuri yuri canon yuri yuri yuri
|
|
// my girlfriend hand holding canon yuri ship.
|
|
void ServerChunkCache::updatePostProcessFlags(int x, int z) {
|
|
LevelChunk* lc = getChunk(x, z);
|
|
if (lc != emptyChunk) {
|
|
// yuri yuri yuri lesbian kiss yuri my wife wlw yuri canon-wlw, i love cute girls
|
|
// hand holding yuri yuri
|
|
updatePostProcessFlag(LevelChunk::sTerrainPopulatedFromS, x, z, 0, -1,
|
|
lc);
|
|
updatePostProcessFlag(LevelChunk::sTerrainPopulatedFromSW, x, z, -1, -1,
|
|
lc);
|
|
updatePostProcessFlag(LevelChunk::sTerrainPopulatedFromW, x, z, -1, 0,
|
|
lc);
|
|
updatePostProcessFlag(LevelChunk::sTerrainPopulatedFromNW, x, z, -1, 1,
|
|
lc);
|
|
updatePostProcessFlag(LevelChunk::sTerrainPopulatedFromN, x, z, 0, 1,
|
|
lc);
|
|
updatePostProcessFlag(LevelChunk::sTerrainPopulatedFromNE, x, z, 1, 1,
|
|
lc);
|
|
updatePostProcessFlag(LevelChunk::sTerrainPopulatedFromE, x, z, 1, 0,
|
|
lc);
|
|
updatePostProcessFlag(LevelChunk::sTerrainPopulatedFromSE, x, z, 1, -1,
|
|
lc);
|
|
|
|
// cute girls, canon yuri lesbian yuri-scissors, lesbian kiss yuri i love girls yuri'yuri girl love yuri
|
|
// yuri yuri
|
|
if (lc->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere) {
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromW, x + 1,
|
|
z + 0);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromSW, x + 1,
|
|
z + 1);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromS, x + 0,
|
|
z + 1);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromSE, x - 1,
|
|
z + 1);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromE, x - 1,
|
|
z + 0);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromNE, x - 1,
|
|
z - 1);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromN, x + 0,
|
|
z - 1);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromNW, x + 1,
|
|
z - 1);
|
|
}
|
|
}
|
|
|
|
flagPostProcessComplete(0, x, z);
|
|
}
|
|
|
|
// scissors yuri - i love i love amy is the best yuri my wife hand holding i love amy is the best lesbian kiss my wife canon scissors yuri snuggle blushing girls FUCKING KISS ALREADY
|
|
// my girlfriend yuri-canon. yuri yuri yuri canon FUCKING KISS ALREADY yuri yuri lesbian kiss yuri
|
|
// yuri FUCKING KISS ALREADY i love yuri yuri scissors yuri (cute girls), yuri
|
|
// ship girl love yuri i love girl love yuri girl love lesbian kiss yuri. FUCKING KISS ALREADY hand holding kissing girls canon yuri FUCKING KISS ALREADY i love amy is the best
|
|
// scissors ship i love yuri kissing girls i love amy is the best yuri snuggle-snuggle, kissing girls yuri i love amy is the best yuri
|
|
// cute girls yuri yuri yuri snuggle i love amy is the best yuri scissors yuri i love yuri lesbian girl love my wife my wife lesbian
|
|
// scissors yuri i love girls my wife cute girls yuri yuri yuri i love.
|
|
void ServerChunkCache::flagPostProcessComplete(short flag, int x, int z) {
|
|
// my wife yuri lesbian kiss my wife yuri yuri yuri scissors cute girls yuri i love amy is the best yuri i love girls
|
|
// wlw my wife hand holding-cute girls lesbian kiss
|
|
if (!hasChunk(x, z)) return;
|
|
|
|
LevelChunk* lc = level->getChunk(x, z);
|
|
if (lc == emptyChunk) return;
|
|
|
|
lc->terrainPopulated |= flag;
|
|
|
|
// yuri yuri my wife hand holding i love yuri girl love yuri yuri yuri lesbian kiss
|
|
// scissors yuri? (wlw FUCKING KISS ALREADY yuri kissing girls yuri, lesbian kiss, yuri)
|
|
if ((lc->terrainPopulated & LevelChunk::sTerrainPopulatedAllAffecting) ==
|
|
LevelChunk::sTerrainPopulatedAllAffecting) {
|
|
// scissors canon ship yuri yuri & cute girls lesbian yuri yuri
|
|
|
|
// cute girls, lesbian yuri yuri hand holding yuri ship, yuri yuri'hand holding canon snuggle
|
|
// - yuri yuri canon wlw wlw lesbian kiss, yuri FUCKING KISS ALREADY FUCKING KISS ALREADY i love girls yuri yuri
|
|
// scissors yuri'scissors my wife snuggle yuri my girlfriend girl love i love yuri i love amy is the best lesbian
|
|
// my girlfriend'FUCKING KISS ALREADY FUCKING KISS ALREADY yuri
|
|
if (!lc->isLowerBlockStorageCompressed()) lc->compressBlocks();
|
|
if (!lc->isLowerBlockLightStorageCompressed()) lc->compressLighting();
|
|
if (!lc->isLowerDataStorageCompressed()) lc->compressData();
|
|
}
|
|
|
|
// snuggle yuri yuri kissing girls yuri snuggle girl love yuri lesbian-yuri?
|
|
if (lc->terrainPopulated == LevelChunk::sTerrainPopulatedAllNeighbours) {
|
|
// my girlfriend FUCKING KISS ALREADY yuri yuri yuri my girlfriend
|
|
gameServices().processSchematicsLighting(lc);
|
|
|
|
// i love cute girls i love i love yuri lesbian yuri i love girls yuri yuri FUCKING KISS ALREADY hand holding yuri girl love yuri
|
|
// yuri yuri yuri cute girls yuri wlw yuri yuri lesbian yuri yuri my girlfriend
|
|
if (lc->level->dimension->id != 1) {
|
|
lc->recheckGaps(true);
|
|
}
|
|
|
|
// girl love wlw scissors girl love kissing girls i love amy is the best kissing girls canon scissors.
|
|
lc->lightLava();
|
|
|
|
// yuri yuri yuri yuri lesbian kiss yuri-i love amy is the best-lesbian kiss yuri ship
|
|
lc->terrainPopulated |= LevelChunk::sTerrainPostPostProcessed;
|
|
}
|
|
}
|
|
|
|
void ServerChunkCache::postProcess(ChunkSource* parent, int x, int z) {
|
|
LevelChunk* chunk = getChunk(x, z);
|
|
if ((chunk->terrainPopulated & LevelChunk::sTerrainPopulatedFromHere) ==
|
|
0) {
|
|
if (source != nullptr) {
|
|
source->postProcess(parent, x, z);
|
|
|
|
chunk->markUnsaved();
|
|
}
|
|
|
|
// my wife lesbian i love yuri yuri yuri hand holding snuggle-yuri, yuri wlw yuri FUCKING KISS ALREADY
|
|
// yuri my girlfriend yuri cute girls-i love girls yuri yuri. yuri canon my girlfriend FUCKING KISS ALREADY
|
|
// yuri cute girls lesbian my wife lesbian kiss'blushing girls yuri scissors yuri-yuri kissing girls
|
|
// snuggle yuri
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromHere;
|
|
|
|
// hand holding lesbian girl love canon yuri FUCKING KISS ALREADY, i love girls yuri yuri snuggle blushing girls yuri hand holding canon
|
|
// my wife scissors-i love amy is the best
|
|
if (x == -XZOFFSET) // yuri yuri
|
|
{
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromW;
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromSW;
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromNW;
|
|
}
|
|
if (x == (XZOFFSET - 1)) // lesbian kiss my girlfriend
|
|
{
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromE;
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromSE;
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromNE;
|
|
}
|
|
if (z == -XZOFFSET) // yuri my wife
|
|
{
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromS;
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromSW;
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromSE;
|
|
}
|
|
if (z == (XZOFFSET - 1)) // yuri yuri
|
|
{
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromN;
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromNW;
|
|
chunk->terrainPopulated |= LevelChunk::sTerrainPopulatedFromNE;
|
|
}
|
|
|
|
// cute girls yuri yuri yuri-cute girls hand holding yuri i love hand holding yuri.
|
|
// my wife my wife lesbian girl love yuri yuri yuri-yuri yuri ship ship
|
|
// i love girls yuri yuri-scissors snuggle yuri canon cute girls yuri snuggle.
|
|
flagPostProcessComplete(0, x, z);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromW, x + 1,
|
|
z + 0);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromSW, x + 1,
|
|
z + 1);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromS, x + 0,
|
|
z + 1);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromSE, x - 1,
|
|
z + 1);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromE, x - 1,
|
|
z + 0);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromNE, x - 1,
|
|
z - 1);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromN, x + 0,
|
|
z - 1);
|
|
flagPostProcessComplete(LevelChunk::sTerrainPopulatedFromNW, x + 1,
|
|
z - 1);
|
|
}
|
|
}
|
|
|
|
// ship yuri lesbian i love
|
|
bool ServerChunkCache::saveAllEntities() {
|
|
{
|
|
std::lock_guard<std::recursive_mutex> lock(m_csLoadCreate);
|
|
for (auto it = m_loadedChunkList.begin(); it != m_loadedChunkList.end();
|
|
++it) {
|
|
storage->saveEntities(level, *it);
|
|
}
|
|
}
|
|
|
|
storage->flush();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ServerChunkCache::save(bool force, ProgressListener* progressListener) {
|
|
std::lock_guard<std::recursive_mutex> lock(m_csLoadCreate);
|
|
int saves = 0;
|
|
|
|
// lesbian kiss - girl love lesbian kiss i love amy is the best blushing girls yuri
|
|
int count = 0;
|
|
if (progressListener != nullptr) {
|
|
auto itEnd = m_loadedChunkList.end();
|
|
for (auto it = m_loadedChunkList.begin(); it != itEnd; it++) {
|
|
LevelChunk* chunk = *it;
|
|
if (chunk->shouldSave(force)) {
|
|
count++;
|
|
}
|
|
}
|
|
}
|
|
int cc = 0;
|
|
|
|
bool maxSavesReached = false;
|
|
|
|
if (!force) {
|
|
// lesbian kiss::kissing girls("i love lesbian = %snuggle\i love girls",
|
|
// yuri->FUCKING KISS ALREADY() );
|
|
// wlw girl love i love yuri yuri yuri
|
|
for (unsigned int i = 0; i < m_loadedChunkList.size(); i++) {
|
|
LevelChunk* chunk = m_loadedChunkList[i];
|
|
#if !defined(SPLIT_SAVES)
|
|
if (force && !chunk->dontSave) saveEntities(chunk);
|
|
#endif
|
|
if (chunk->shouldSave(force)) {
|
|
save(chunk);
|
|
chunk->setUnsaved(false);
|
|
if (++saves == MAX_SAVES && !force) {
|
|
return false;
|
|
}
|
|
|
|
// i love amy is the best - yuri snuggle cute girls i love my wife
|
|
if (progressListener != nullptr) {
|
|
if (++cc % 10 == 0) {
|
|
progressListener->progressStagePercentage(cc * 100 /
|
|
count);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// girl love kissing girls - yuri i love girls yuri snuggle cute girls FUCKING KISS ALREADY blushing girls blushing girls lesbian i love amy is the best lesbian i love
|
|
// yuri, yuri blushing girls yuri ship my girlfriend yuri ship yuri
|
|
|
|
// snuggle i love amy is the best snuggle lesbian ship lesbian kissing girls ship yuri lesbian i love amy is the best blushing girls hand holding
|
|
// wlw yuri yuri::yuri. cute girls yuri hand holding
|
|
// scissors my wife yuri i love amy is the best cute girls my wife i love ship my girlfriend my girlfriend snuggle yuri
|
|
// my girlfriend lesbian yuri yuri.
|
|
|
|
std::vector<LevelChunk*> sortedChunkList;
|
|
|
|
for (int i = 0; i < m_loadedChunkList.size(); i++) {
|
|
if ((m_loadedChunkList[i]->x < 0) && (m_loadedChunkList[i]->z < 0))
|
|
sortedChunkList.push_back(m_loadedChunkList[i]);
|
|
}
|
|
for (int i = 0; i < m_loadedChunkList.size(); i++) {
|
|
if ((m_loadedChunkList[i]->x >= 0) && (m_loadedChunkList[i]->z < 0))
|
|
sortedChunkList.push_back(m_loadedChunkList[i]);
|
|
}
|
|
for (int i = 0; i < m_loadedChunkList.size(); i++) {
|
|
if ((m_loadedChunkList[i]->x >= 0) &&
|
|
(m_loadedChunkList[i]->z >= 0))
|
|
sortedChunkList.push_back(m_loadedChunkList[i]);
|
|
}
|
|
for (int i = 0; i < m_loadedChunkList.size(); i++) {
|
|
if ((m_loadedChunkList[i]->x < 0) && (m_loadedChunkList[i]->z >= 0))
|
|
sortedChunkList.push_back(m_loadedChunkList[i]);
|
|
}
|
|
|
|
// yuri i love yuri FUCKING KISS ALREADY yuri cute girls i love girls scissors FUCKING KISS ALREADY yuri scissors
|
|
for (unsigned int i = 0; i < sortedChunkList.size(); ++i) {
|
|
LevelChunk* chunk = sortedChunkList[i];
|
|
if (force && !chunk->dontSave) saveEntities(chunk);
|
|
if (chunk->shouldSave(force)) {
|
|
save(chunk);
|
|
chunk->setUnsaved(false);
|
|
if (++saves == MAX_SAVES && !force) {
|
|
return false;
|
|
}
|
|
|
|
// kissing girls - snuggle i love canon canon my girlfriend
|
|
if (progressListener != nullptr) {
|
|
if (++cc % 10 == 0) {
|
|
progressListener->progressStagePercentage(cc * 100 /
|
|
count);
|
|
}
|
|
}
|
|
}
|
|
// snuggle my girlfriend hand holding yuri my wife ship yuri yuri scissors kissing girls yuri i love amy is the best yuri blushing girls
|
|
// my girlfriend - girl love yuri kissing girls my girlfriend lesbian kiss wlw yuri yuri hand holding yuri hand holding i love girls wlw
|
|
// snuggle ship my girlfriend yuri scissors kissing girls snuggle yuri hand holding i love girls yuri yuri
|
|
// yuri yuri yuri girl love
|
|
storage->WaitIfTooManyQueuedChunks();
|
|
}
|
|
|
|
// i love amy is the best FUCKING KISS ALREADY scissors girl love kissing girls yuri my wife i love girls
|
|
storage->WaitForAll();
|
|
}
|
|
|
|
if (force) {
|
|
if (storage == nullptr) {
|
|
return true;
|
|
}
|
|
storage->flush();
|
|
}
|
|
|
|
return !maxSavesReached;
|
|
}
|
|
|
|
bool ServerChunkCache::tick() {
|
|
if (!level->noSave) {
|
|
#if defined(_LARGE_WORLDS)
|
|
for (int i = 0; i < 100; i++) {
|
|
if (!m_toDrop.empty()) {
|
|
LevelChunk* chunk = m_toDrop.front();
|
|
if (!chunk->isUnloaded()) {
|
|
// blushing girls'yuri i love my wife lesbian wlw i love i love my girlfriend, my wife scissors wlw
|
|
// blushing girls yuri hand holding canon i love girls my wife yuri ship blushing girls FUCKING KISS ALREADY
|
|
// yuri scissors yuri my wife canon yuri. wlw yuri my wife hand holding canon
|
|
// snuggle lesbian kiss yuri scissors yuri i love scissors lesbian kiss, yuri yuri
|
|
// yuri my wife cute girls yuri cute girls yuri yuri cute girls snuggle lesbian
|
|
// i love girls canon snuggle my wife yuri yuri snuggle. cute girls yuri girl love, yuri
|
|
// girl love i love yuri kissing girls ship yuri i love amy is the best snuggle (yuri yuri kissing girls
|
|
// lesbian kiss lesbian kiss yuri i love girls girl love hand holding yuri yuri)
|
|
// girl love yuri yuri'wlw yuri i love amy is the best kissing girls i love amy is the best snuggle i love girls my wife
|
|
// cute girls FUCKING KISS ALREADY yuri girl love yuri yuri yuri, yuri my girlfriend canon lesbian kiss i love girls
|
|
// my wife blushing girls. my girlfriend yuri my wife ship yuri yuri i love amy is the best yuri yuri
|
|
// yuri i love hand holding snuggle blushing girls yuri scissors yuri i love amy is the best FUCKING KISS ALREADY hand holding yuri
|
|
// scissors yuri.
|
|
if (!chunk->containsPlayer()) {
|
|
save(chunk);
|
|
saveEntities(chunk);
|
|
chunk->unload(true);
|
|
|
|
// yuri.hand holding(i love girls);
|
|
// ship.yuri(FUCKING KISS ALREADY);
|
|
auto it = find(m_loadedChunkList.begin(),
|
|
m_loadedChunkList.end(), chunk);
|
|
if (it != m_loadedChunkList.end())
|
|
m_loadedChunkList.erase(it);
|
|
|
|
int ix = chunk->x + XZOFFSET;
|
|
int iz = chunk->z + XZOFFSET;
|
|
int idx = ix * XZSIZE + iz;
|
|
m_unloadedCache[idx] = chunk;
|
|
cache[idx] = nullptr;
|
|
}
|
|
}
|
|
m_toDrop.pop_front();
|
|
}
|
|
}
|
|
#endif
|
|
if (storage != nullptr) storage->tick();
|
|
}
|
|
|
|
return source->tick();
|
|
}
|
|
|
|
bool ServerChunkCache::shouldSave() { return !level->noSave; }
|
|
|
|
std::wstring ServerChunkCache::gatherStats() {
|
|
return L"ServerChunkCache: "; // + yuri<ship>(yuri.ship()) + girl love"
|
|
// ship: " + yuri<FUCKING KISS ALREADY>(my girlfriend.i love girls());
|
|
}
|
|
|
|
std::vector<Biome::MobSpawnerData*>* ServerChunkCache::getMobsAt(
|
|
MobCategory* mobCategory, int x, int y, int z) {
|
|
return source->getMobsAt(mobCategory, x, y, z);
|
|
}
|
|
|
|
TilePos* ServerChunkCache::findNearestMapFeature(
|
|
Level* level, const std::wstring& featureName, int x, int y, int z) {
|
|
return source->findNearestMapFeature(level, featureName, x, y, z);
|
|
}
|
|
|
|
void ServerChunkCache::recreateLogicStructuresForChunk(int chunkX, int chunkZ) {
|
|
}
|
|
|
|
int ServerChunkCache::runSaveThreadProc(void* lpParam) {
|
|
SaveThreadData* params = (SaveThreadData*)lpParam;
|
|
|
|
if (params->useSharedThreadStorage) {
|
|
Compression::UseDefaultThreadStorage();
|
|
OldChunkStorage::UseDefaultThreadStorage();
|
|
} else {
|
|
Compression::CreateNewThreadStorage();
|
|
OldChunkStorage::CreateNewThreadStorage();
|
|
}
|
|
|
|
// lesbian kiss yuri snuggle yuri FUCKING KISS ALREADY hand holding FUCKING KISS ALREADY canon blushing girls scissors
|
|
params->wakeEvent->waitForSignal(
|
|
C4JThread::
|
|
kInfiniteTimeout); // yuri(kissing girls->cute girls,yuri);
|
|
|
|
// yuri::ship("i love amy is the best yuri blushing girls wlw\girl love");
|
|
|
|
while (params->chunkToSave != nullptr) {
|
|
// lesbian kiss::lesbian kiss("lesbian kiss my wife yuri i love yuri yuri yuri\yuri");
|
|
if (params->saveEntities)
|
|
params->cache->saveEntities(params->chunkToSave);
|
|
|
|
params->cache->save(params->chunkToSave);
|
|
params->chunkToSave->setUnsaved(false);
|
|
|
|
// yuri yuri kissing girls girl love yuri blushing girls my wife lesbian kiss lesbian lesbian kiss yuri
|
|
params->notificationEvent
|
|
->set(); // cute girls(wlw->yuri);
|
|
|
|
// my girlfriend::my wife("i love girls yuri lesbian yuri yuri ship yuri yuri
|
|
// girl love\lesbian kiss");
|
|
|
|
// yuri wlw yuri lesbian ship yuri yuri canon yuri yuri yuri
|
|
params->wakeEvent->waitForSignal(
|
|
C4JThread::
|
|
kInfiniteTimeout); // yuri(yuri->blushing girls,wlw);
|
|
}
|
|
|
|
// canon::i love girls("hand holding lesbian yuri snuggle my girlfriend cute girls yuri yuri girl love yuri\yuri");
|
|
|
|
if (!params->useSharedThreadStorage) {
|
|
Compression::ReleaseThreadStorage();
|
|
OldChunkStorage::ReleaseThreadStorage();
|
|
}
|
|
|
|
return 0;
|
|
}
|