mirror of
https://gitea.sffempire.ru/Kolyah35/minecraft-pe-0.6.1.git
synced 2026-03-30 20:13:31 +00:00
Compare commits
8 Commits
aeef442f76
...
370363f792
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
370363f792 | ||
|
|
61a2349b8b | ||
|
|
eed3a6df61 | ||
|
|
97b0fb4d46 | ||
|
|
8be842a8ac | ||
|
|
6957f144e1 | ||
|
|
f9d9a0f0f9 | ||
|
|
28febb4e63 |
@@ -16,9 +16,8 @@ namespace SharedConstants
|
||||
{
|
||||
// 0.5.0 uses NPv8
|
||||
// 0.6.0 uses NPv9
|
||||
// TODO: Better proto check
|
||||
const int NetworkProtocolVersion = 10;
|
||||
const int NetworkProtocolLowestSupportedVersion = 10;
|
||||
const int NetworkProtocolVersion = 9;
|
||||
const int NetworkProtocolLowestSupportedVersion = 9;
|
||||
const int GameProtocolVersion = 1;
|
||||
const int GameProtocolLowestSupportedVersion = 1;
|
||||
|
||||
|
||||
@@ -120,6 +120,8 @@ public:
|
||||
void optionUpdated(OptionId option, bool value);
|
||||
void optionUpdated(OptionId option, float value);
|
||||
void optionUpdated(OptionId option, int value);
|
||||
|
||||
int getTicks() { return ticks; }
|
||||
#ifdef __APPLE__
|
||||
bool _isSuperFast;
|
||||
bool isSuperFast() { return _isSuperFast; }
|
||||
@@ -197,7 +199,8 @@ public:
|
||||
std::string externalCacheStoragePath;
|
||||
protected:
|
||||
Timer timer;
|
||||
// @note @attn @warn: this is dangerous as fuck!
|
||||
|
||||
// @note @attn @warn: this is dangerous as fuck!
|
||||
volatile bool isGeneratingLevel;
|
||||
bool _hasSignaledGeneratingLevelFinished;
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ bool SurvivalMode::destroyBlock( int x, int y, int z, int face ) {
|
||||
minecraft->player->inventory->clearSlot(minecraft->player->inventory->selected);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed && couldDestroy) {
|
||||
ItemInstance instance(t, 1, data);
|
||||
Tile::tiles[t]->playerDestroy(minecraft->level, minecraft->player, x, y, z, data);
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#include "network/RakNetInstance.h"
|
||||
#include "network/packet/WantCreatePacket.h"
|
||||
#include "platform/input/Keyboard.h"
|
||||
#include <cstdint>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
static NinePatchLayer* guiPaneFrame = NULL;
|
||||
|
||||
@@ -195,6 +198,26 @@ void PaneCraftingScreen::setupPositions() {
|
||||
}
|
||||
|
||||
void PaneCraftingScreen::tick() {
|
||||
if (minecraft->isOnline()) {
|
||||
// TODO: Make better algorithm
|
||||
static std::map<uint8_t, uint16_t> oldMap = {};
|
||||
std::map<uint8_t, uint16_t> newMap = {};
|
||||
|
||||
for (int i = Inventory::MAX_SELECTION_SIZE; i < minecraft->player->inventory->getContainerSize(); ++i) {
|
||||
auto itm = minecraft->player->inventory->getItem(i);
|
||||
|
||||
if (itm != NULL) {
|
||||
newMap[itm->id] += itm->count;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldMap != newMap) {
|
||||
oldMap = newMap;
|
||||
newMap = {};
|
||||
recheckRecipes();
|
||||
}
|
||||
}
|
||||
|
||||
if (pane) pane->tick();
|
||||
}
|
||||
|
||||
|
||||
@@ -77,10 +77,10 @@ void PlayerRenderer::render(Entity* mob_, float x, float y, float z, float rot,
|
||||
model = desired;
|
||||
humanoidModel = desired;
|
||||
}
|
||||
LOGI("[PlayerRenderer] %s: skin=%s, modelTex=%dx%d, desired=%s\n",
|
||||
/* LOGI("[PlayerRenderer] %s: skin=%s, modelTex=%dx%d, desired=%s\n",
|
||||
((Player*)mob)->name.c_str(), mob->getTexture().c_str(),
|
||||
humanoidModel->texWidth, humanoidModel->texHeight,
|
||||
(desired == playerModel64 ? "64" : "32"));
|
||||
(desired == playerModel64 ? "64" : "32")); */
|
||||
HumanoidMobRenderer::render(mob_, x, y, z, rot, a);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ void ClientSideNetworkHandler::onConnect(const RakNet::RakNetGUID& hostGuid)
|
||||
serverGuid = hostGuid;
|
||||
|
||||
clearChunksLoaded();
|
||||
LoginPacket packet(minecraft->options.getStringValue(OPTIONS_USERNAME).c_str(), SharedConstants::NetworkProtocolVersion);
|
||||
LoginPacket packet(minecraft->options.getStringValue(OPTIONS_USERNAME).c_str(), SharedConstants::NetworkProtocolVersion, true);
|
||||
raknetInstance->send(packet);
|
||||
}
|
||||
|
||||
@@ -386,6 +386,23 @@ void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlay
|
||||
entity->lerpTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot, 3);
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, SendInventoryPacket* packet) {
|
||||
if (!level) return;
|
||||
|
||||
// TODO: Linked slots
|
||||
if (packet->entityId == minecraft->player->entityId) {
|
||||
auto items = packet->items;
|
||||
|
||||
minecraft->player->inventory->replace(items);
|
||||
|
||||
for (int i = 0; i < packet->linkedSlot.size(); i++) {
|
||||
minecraft->player->inventory->linkSlot(i, packet->linkedSlot[i].inventorySlot, true);
|
||||
LOGI("%i -> %i\n", packet->linkedSlot[i].inventorySlot, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClientSideNetworkHandler::handle(const RakNet::RakNetGUID& source, TakeItemPacket* packet) {
|
||||
if (!level) return;
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
virtual void handle(const RakNet::RakNetGUID& source, RemoveItemPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, TakeItemPacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, WantCreatePacket* packet);
|
||||
virtual void handle(const RakNet::RakNetGUID& source, SendInventoryPacket* packet);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "../world/inventory/BaseContainerMenu.h"
|
||||
#include "network/packet/ContainerSetSlotPacket.h"
|
||||
#include "network/packet/RemoveBlockPacket.h"
|
||||
#include "network/packet/SendInventoryPacket.h"
|
||||
#include "network/packet/UpdateBlockPacket.h"
|
||||
#include "network/packet/RemoveItemPacket.h"
|
||||
#include "network/packet/TakeItemPacket.h"
|
||||
@@ -20,7 +21,9 @@
|
||||
#include "../raknet/RakPeerInterface.h"
|
||||
#include "../raknet/PacketPriority.h"
|
||||
#include "platform/log.h"
|
||||
#include "util/Mth.h"
|
||||
#include "world/item/ItemInstance.h"
|
||||
#include "world/level/storage/LevelStorage.h"
|
||||
#include "world/phys/Vec3.h"
|
||||
#include "world/item/crafting/Recipe.h"
|
||||
#include "world/item/crafting/Recipes.h"
|
||||
@@ -168,6 +171,8 @@ void ServerSideNetworkHandler::onDisconnect(const RakNet::RakNetGUID& guid)
|
||||
|
||||
if (player->owner == guid)
|
||||
{
|
||||
minecraft->level->getLevelStorage()->savePlayer(*player);
|
||||
|
||||
std::string message = player->name;
|
||||
message += " disconnected from the game";
|
||||
displayGameMessage(message);
|
||||
@@ -192,7 +197,6 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPac
|
||||
|
||||
LOGI("LoginPacket\n");
|
||||
|
||||
printf("%d", packet->clientNetworkVersion);
|
||||
int loginStatus = LoginStatus::Success;
|
||||
//
|
||||
// Bad/incompatible client version
|
||||
@@ -212,7 +216,8 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPac
|
||||
//
|
||||
// Valid client version
|
||||
//
|
||||
Player* newPlayer = new ServerPlayer(minecraft, level);
|
||||
|
||||
Player* newPlayer = new ServerPlayer(minecraft, level, packet->newProto);
|
||||
|
||||
minecraft->gameMode->initAbilities(newPlayer->abilities);
|
||||
newPlayer->owner = source;
|
||||
@@ -247,6 +252,11 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, LoginPac
|
||||
).write(&bitStream);
|
||||
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
|
||||
if (!packet->newProto) {
|
||||
MessagePacket packet("You're using outdated client. Some features disabled.");
|
||||
raknetInstance->send(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,6 +328,36 @@ void ServerSideNetworkHandler::onReady_ClientGeneration(const RakNet::RakNetGUID
|
||||
}
|
||||
}
|
||||
|
||||
if (!minecraft->level->getLevelStorage()->loadPlayer(*newPlayer)) {
|
||||
LOGW("Failed to load %s data\n", newPlayer->name.c_str());
|
||||
}
|
||||
|
||||
// Credits to EpikIzCool
|
||||
bitStream.Reset();
|
||||
MovePlayerPacket mv(newPlayer->entityId, newPlayer->x, newPlayer->y - newPlayer->heightOffset,
|
||||
newPlayer->z, newPlayer->xRot, newPlayer->yRot);
|
||||
mv.write(&bitStream);
|
||||
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
|
||||
bitStream.Reset();
|
||||
SetHealthPacket hp(newPlayer->health);
|
||||
hp.write(&bitStream);
|
||||
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
|
||||
if (newPlayer->hasRespawnPosition()) {
|
||||
bitStream.Reset();
|
||||
SetSpawnPositionPacket sp(newPlayer->getRespawnPosition());
|
||||
sp.write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
}
|
||||
|
||||
bitStream.Reset();
|
||||
SendInventoryPacket(newPlayer, false).write(&bitStream);
|
||||
rakPeer->Send(&bitStream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, source, false);
|
||||
|
||||
|
||||
// Additional packets
|
||||
// * set spawn
|
||||
/*
|
||||
@@ -359,11 +399,22 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, MovePlay
|
||||
//LOGI("MovePlayerPacket\n");
|
||||
if (Entity* entity = level->getEntity(packet->entityId))
|
||||
{
|
||||
entity->xd = entity->yd = entity->zd = 0;
|
||||
entity->lerpTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot, 3);
|
||||
ServerPlayer* player = (ServerPlayer*) getPlayer(source);
|
||||
|
||||
// broadcast this packet to other clients
|
||||
redistributePacket(packet, source);
|
||||
float vectorDist = sqrt( (packet->x - entity->x) * (packet->x - entity->x) +
|
||||
(packet->y - entity->y) * (packet->y - entity->y) +
|
||||
(packet->z - entity->z) * (packet->z - entity->z));
|
||||
float speed = vectorDist / (minecraft->getTicks() - player->getLastMoveTicks());
|
||||
|
||||
if (speed < 2.5f) {
|
||||
entity->xd = entity->yd = entity->zd = 0;
|
||||
entity->lerpTo(packet->x, packet->y, packet->z, packet->yRot, packet->xRot, 3);
|
||||
|
||||
// broadcast this packet to other clients
|
||||
redistributePacket(packet, source);
|
||||
}
|
||||
|
||||
player->setLastMoveTicks(minecraft->getTicks());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,9 +436,24 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, RemoveBl
|
||||
if (oldTile != NULL && changed) {
|
||||
level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, oldTile->soundType->getBreakSound(), (oldTile->soundType->getVolume() + 1) / 2, oldTile->soundType->getPitch() * 0.8f);
|
||||
|
||||
if (minecraft->gameMode->isSurvivalType() && player->canDestroy(oldTile))
|
||||
if (minecraft->gameMode->isSurvivalType() && player->canDestroy(oldTile)) {
|
||||
// From SurvivalMode.cpp
|
||||
// Why tf i have to copy this shit from SurvivalMode class
|
||||
// Why SurvivalMode class locked to LOCAL MINECRAFT PLAYER :sob: :sob: :sob: :sob: :sob: :sob: :sob: :sob:
|
||||
// @fix @warn @ahtung @alert
|
||||
ItemInstance* item = player->inventory->getSelected();
|
||||
if (item != NULL) {
|
||||
item->mineBlock(oldTile->id, x, y, z);
|
||||
if (item->count == 0) {
|
||||
//item->snap(minecraft->player);
|
||||
player->inventory->clearSlot(player->inventory->selected);
|
||||
}
|
||||
}
|
||||
|
||||
//oldTile->spawnResources(level, x, y, z, data, 1); //@todo
|
||||
oldTile->playerDestroy(level, player, x, y, z, data);
|
||||
}
|
||||
|
||||
|
||||
oldTile->destroy(level, x, y, z, data);
|
||||
}
|
||||
@@ -462,6 +528,10 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerEq
|
||||
|
||||
if (slot < 0 && packet->itemId != 0) {
|
||||
LOGW("PlayerEquipmentPacket: Remote player doesn't have his thing (or crafted it)!\n");
|
||||
|
||||
SendInventoryPacket newInventory (player, false);
|
||||
raknetInstance->send(newInventory);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -480,7 +550,7 @@ void ServerSideNetworkHandler::handle(const RakNet::RakNetGUID& source, PlayerAr
|
||||
if (!player) return;
|
||||
if (rakPeer->GetMyGUID() == player->owner) return;
|
||||
|
||||
LOGI("Equip armor: %i %i %i %i\n", packet->head, packet->torso, packet->legs, packet->feet);
|
||||
// LOGI("Equip armor: %i %i %i %i\n", packet->head, packet->torso, packet->legs, packet->feet);
|
||||
|
||||
packet->fillIn(player);
|
||||
redistributePacket(packet, source);
|
||||
|
||||
@@ -9,17 +9,20 @@ public:
|
||||
RakNet::RakString clientName;
|
||||
int clientNetworkVersion;
|
||||
int clientNetworkLowestSupportedVersion;
|
||||
bool newProto;
|
||||
|
||||
LoginPacket()
|
||||
: clientNetworkVersion(-1),
|
||||
clientNetworkLowestSupportedVersion(-1)
|
||||
clientNetworkLowestSupportedVersion(-1),
|
||||
newProto(false)
|
||||
{
|
||||
}
|
||||
|
||||
LoginPacket(const RakNet::RakString& clientName, int clientVersion)
|
||||
LoginPacket(const RakNet::RakString& clientName, int clientVersion, bool newProto)
|
||||
: clientName(clientName),
|
||||
clientNetworkVersion(clientVersion),
|
||||
clientNetworkLowestSupportedVersion(clientVersion)
|
||||
clientNetworkLowestSupportedVersion(clientVersion),
|
||||
newProto(newProto)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -29,6 +32,7 @@ public:
|
||||
bitStream->Write(clientName);
|
||||
bitStream->Write(clientNetworkVersion);
|
||||
bitStream->Write(clientNetworkLowestSupportedVersion);
|
||||
bitStream->Write(newProto);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
@@ -39,6 +43,11 @@ public:
|
||||
if (bitStream->GetNumberOfUnreadBits() > 0) {
|
||||
bitStream->Read(clientNetworkVersion);
|
||||
bitStream->Read(clientNetworkLowestSupportedVersion);
|
||||
|
||||
// Checking for new proto
|
||||
if (bitStream->GetNumberOfUnreadBits() > 0) {
|
||||
bitStream->Read(newProto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
|
||||
#include "../Packet.h"
|
||||
#include "world/entity/player/Inventory.h"
|
||||
#include "world/inventory/FillingContainer.h"
|
||||
#include <array>
|
||||
|
||||
class SendInventoryPacket: public Packet
|
||||
{
|
||||
public:
|
||||
SendInventoryPacket()
|
||||
{
|
||||
}
|
||||
SendInventoryPacket() {}
|
||||
|
||||
SendInventoryPacket(Player* player, bool dropItems)
|
||||
: entityId(player->entityId),
|
||||
@@ -22,10 +22,15 @@ public:
|
||||
ItemInstance* item = inv->getItem(i);
|
||||
items.push_back(item? *item : ItemInstance());
|
||||
}
|
||||
|
||||
for (int i = 0; i < NumArmorItems; ++i) {
|
||||
ItemInstance* item = player->getArmor(i);
|
||||
items.push_back(item? *item : ItemInstance());
|
||||
}
|
||||
|
||||
for (int i = 0; i < inv->numLinkedSlots; ++i) {
|
||||
linkedSlot[i] = inv->linkedSlots[i];
|
||||
}
|
||||
}
|
||||
|
||||
void write(RakNet::BitStream* bitStream)
|
||||
@@ -40,6 +45,13 @@ public:
|
||||
// Armor
|
||||
for (int i = 0; i < NumArmorItems; ++i)
|
||||
PacketUtil::writeItemInstance(items[i + numItems], bitStream);
|
||||
|
||||
int lSlots = Inventory::MAX_SELECTION_SIZE;
|
||||
|
||||
// Linked slots
|
||||
bitStream->Write(lSlots);
|
||||
for (int i = 0; i < lSlots; ++i)
|
||||
bitStream->Write(linkedSlot[i]);
|
||||
}
|
||||
|
||||
void read(RakNet::BitStream* bitStream)
|
||||
@@ -51,6 +63,12 @@ public:
|
||||
// Inventory, Armor
|
||||
for (int i = 0; i < numItems + NumArmorItems; ++i)
|
||||
items.push_back(PacketUtil::readItemInstance(bitStream));
|
||||
|
||||
// Linked slots
|
||||
int lSlots = 0;
|
||||
bitStream->Read(lSlots);
|
||||
for (int i = 0; i < lSlots; ++i)
|
||||
bitStream->Read(linkedSlot[i]);
|
||||
}
|
||||
|
||||
void handle(const RakNet::RakNetGUID& source, NetEventCallback* callback)
|
||||
@@ -63,6 +81,8 @@ public:
|
||||
short numItems;
|
||||
unsigned char extra;
|
||||
|
||||
std::array<FillingContainer::LinkedSlot, Inventory::MAX_SELECTION_SIZE> linkedSlot;
|
||||
|
||||
static const int ExtraDrop = 1;
|
||||
static const int NumArmorItems = 4;
|
||||
};
|
||||
|
||||
@@ -12,16 +12,19 @@ ServerLevel::ServerLevel(LevelStorage* levelStorage, const std::string& levelNam
|
||||
void ServerLevel::updateSleepingPlayerList() {
|
||||
bool allPlayersWasSleeping = allPlayersAreSleeping;
|
||||
allPlayersAreSleeping = !players.empty();
|
||||
for(PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
|
||||
|
||||
for (PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
|
||||
Player* player = *it;
|
||||
if(!player->isSleeping()) {
|
||||
|
||||
if (!player->isSleeping()) {
|
||||
allPlayersAreSleeping = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!allPlayersWasSleeping && allPlayersAreSleeping) {
|
||||
if (!allPlayersWasSleeping && allPlayersAreSleeping) {
|
||||
levelEvent(NULL, LevelEvent::ALL_PLAYERS_SLEEPING, 0, 0, 0, 0);
|
||||
for(PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
|
||||
|
||||
for (PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
|
||||
(*it)->setAllPlayersSleeping();
|
||||
}
|
||||
}
|
||||
@@ -29,23 +32,26 @@ void ServerLevel::updateSleepingPlayerList() {
|
||||
|
||||
void ServerLevel::awakenAllPlayers() {
|
||||
allPlayersAreSleeping = false;
|
||||
for(PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
|
||||
|
||||
for (PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
|
||||
Player* player = *it;
|
||||
if(player->isSleeping()) {
|
||||
|
||||
if (player->isSleeping()) {
|
||||
player->stopSleepInBed(false, false, true);
|
||||
player->health = Player::MAX_HEALTH;
|
||||
player->lastHealth = Player::MAX_HEALTH;
|
||||
}
|
||||
}
|
||||
|
||||
SetHealthPacket packet(Player::MAX_HEALTH);
|
||||
raknetInstance->send(packet);
|
||||
}
|
||||
|
||||
bool ServerLevel::allPlayersSleeping() {
|
||||
if(allPlayersAreSleeping && !isClientSide) {
|
||||
if (allPlayersAreSleeping && !isClientSide) {
|
||||
// all players are sleeping, but have they slept long enough?
|
||||
for(PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
|
||||
if(!(*it)->isSleepingLongEnough()) {
|
||||
for (PlayerList::iterator it = players.begin(); it != players.end(); ++it) {
|
||||
if (!(*it)->isSleepingLongEnough()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -55,13 +61,17 @@ bool ServerLevel::allPlayersSleeping() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ServerLevel::tick(){
|
||||
void ServerLevel::tick() {
|
||||
super::tick();
|
||||
if(allPlayersSleeping()) {
|
||||
|
||||
if (allPlayersSleeping()) {
|
||||
long newTime = levelData.getTime() + TICKS_PER_DAY;
|
||||
|
||||
levelData.setTime(newTime - (newTime % TICKS_PER_DAY));
|
||||
|
||||
SetTimePacket packet(levelData.getTime());
|
||||
raknetInstance->send(packet);
|
||||
|
||||
awakenAllPlayers();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,12 @@
|
||||
#include "network/packet/SendInventoryPacket.h"
|
||||
#include "world/entity/player/Inventory.h"
|
||||
|
||||
ServerPlayer::ServerPlayer( Minecraft* minecraft, Level* level )
|
||||
ServerPlayer::ServerPlayer( Minecraft* minecraft, Level* level, bool proto)
|
||||
: super(level, minecraft->isCreativeMode()),
|
||||
_mc(minecraft),
|
||||
_prevHealth(-999),
|
||||
_containerCounter(0)
|
||||
_containerCounter(0),
|
||||
isNewProto(proto)
|
||||
{
|
||||
// hasFakeInventory = true;
|
||||
footSize = 0;
|
||||
|
||||
@@ -15,7 +15,7 @@ class ServerPlayer: public Player,
|
||||
{
|
||||
typedef Player super;
|
||||
public:
|
||||
ServerPlayer(Minecraft* minecraft, Level* level);
|
||||
ServerPlayer(Minecraft* minecraft, Level* level, bool proto);
|
||||
|
||||
~ServerPlayer();
|
||||
|
||||
@@ -43,6 +43,15 @@ public:
|
||||
virtual void stopSleepInBed(bool forcefulWakeUp, bool updateLevelList, bool saveRespawnPoint);
|
||||
|
||||
void completeUsingItem();
|
||||
|
||||
void setLastMoveTicks(int lastMoveTicks) { this->lastMoveTicks = lastMoveTicks; }
|
||||
int getLastMoveTicks() { return lastMoveTicks; }
|
||||
|
||||
void setTicksInAir(int ticksInAir) { this->ticksInAir = ticksInAir; }
|
||||
int getTicksInAir() { return ticksInAir; }
|
||||
|
||||
void setNewProto(bool proto) { isNewProto = proto; }
|
||||
bool getProto() { return isNewProto; }
|
||||
private:
|
||||
void nextContainerCounter();
|
||||
void setContainerMenu( BaseContainerMenu* menu );
|
||||
@@ -50,6 +59,11 @@ private:
|
||||
Minecraft* _mc;
|
||||
int _prevHealth;
|
||||
int _containerCounter;
|
||||
|
||||
int lastMoveTicks = 0;
|
||||
int ticksInAir = 0;
|
||||
|
||||
bool isNewProto = false;
|
||||
};
|
||||
|
||||
#endif /*ServerPlayer_H__*/
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
#include <cstddef>
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#if !defined(DEMO_MODE) && !defined(APPLE_DEMO_PROMOTION)
|
||||
|
||||
#include "LevelData.h"
|
||||
@@ -88,6 +91,9 @@ ExternalFileLevelStorage::ExternalFileLevelStorage(const std::string& levelId, c
|
||||
{
|
||||
createFolderIfNotExists(levelPath.c_str());
|
||||
|
||||
std::string playerFolder = levelPath + "/players";
|
||||
createFolderIfNotExists(playerFolder.c_str());
|
||||
|
||||
std::string datFileName = levelPath + "/" + fnLevelDat;
|
||||
std::string levelFileName = levelPath + "/" + fnPlayerDat;
|
||||
loadedLevelData = new LevelData();
|
||||
@@ -113,6 +119,7 @@ void ExternalFileLevelStorage::saveLevelData(LevelData& levelData, std::vector<P
|
||||
|
||||
void ExternalFileLevelStorage::saveLevelData( const std::string& levelPath, LevelData& levelData, std::vector<Player*>* players )
|
||||
{
|
||||
// @todo: completely rewrite
|
||||
std::string directory = levelPath + "/";
|
||||
std::string tmpFile = directory + fnLevelDatNew;
|
||||
std::string datFile = directory + fnLevelDat;
|
||||
@@ -141,6 +148,67 @@ void ExternalFileLevelStorage::saveLevelData( const std::string& levelPath, Leve
|
||||
|
||||
// Remove the temporary save, if the rename didn't do it
|
||||
remove(tmpFile.c_str());
|
||||
|
||||
// Save players
|
||||
// fuck mojang for that
|
||||
if (!players || players->empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& player : *players) {
|
||||
if (player != NULL) {
|
||||
savePlayer(*player, directory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExternalFileLevelStorage::savePlayer(Player& player, const std::string& worldDir) {
|
||||
std::string playerPath = worldDir + "/players/" + player.name + ".dat";
|
||||
|
||||
LOGI("Saving player %s to %s...\n", player.name.c_str(), playerPath.c_str());
|
||||
|
||||
RakNet::BitStream data;
|
||||
RakDataOutput buf(data);
|
||||
CompoundTag playerTag;
|
||||
player.saveWithoutId(&playerTag);
|
||||
|
||||
NbtIo::write(&playerTag, &buf);
|
||||
|
||||
std::ofstream file(playerPath, std::ios::out | std::ios::binary);
|
||||
file.write((const char*)data.GetData(), (size_t)data.GetNumberOfBytesUsed());
|
||||
}
|
||||
|
||||
bool ExternalFileLevelStorage::loadPlayer(Player& player, const std::string& worldDir) {
|
||||
std::string playerPath = worldDir + "/players/" + player.name + ".dat";
|
||||
|
||||
LOGI("Loading player %s from %s...\n", player.name.c_str(), playerPath.c_str());
|
||||
|
||||
std::ifstream file(playerPath, std::ios::in | std::ios::binary);
|
||||
if (!file.is_open()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> data((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
|
||||
|
||||
RakNet::BitStream bitStream(data.data(), data.size(), false);
|
||||
RakDataInput stream(bitStream);
|
||||
|
||||
CompoundTag* tag = NbtIo::read(&stream);
|
||||
if (tag) {
|
||||
player.load(tag);
|
||||
tag->deleteChildren();
|
||||
delete tag;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExternalFileLevelStorage::savePlayer(Player& player) {
|
||||
ExternalFileLevelStorage::savePlayer(player, levelPath);
|
||||
}
|
||||
|
||||
bool ExternalFileLevelStorage::loadPlayer(Player& player) {
|
||||
return ExternalFileLevelStorage::loadPlayer(player, levelPath);
|
||||
}
|
||||
|
||||
LevelData* ExternalFileLevelStorage::prepareLevel(Level* _level)
|
||||
|
||||
@@ -67,6 +67,19 @@ public:
|
||||
void saveGame(Level* level);
|
||||
void saveAll(Level* level, std::vector<LevelChunk*>& levelChunks);
|
||||
|
||||
/**
|
||||
* @brief Save player to <world name>/player/<player name>.dat file
|
||||
*/
|
||||
static void savePlayer(Player& player, const std::string& worldDir);
|
||||
|
||||
/**
|
||||
* @brief Load player from <world name>/player/<player name>.dat file
|
||||
*/
|
||||
static bool loadPlayer(Player& player, const std::string& worldDir);
|
||||
|
||||
virtual void savePlayer(Player& player);
|
||||
virtual bool loadPlayer(Player& player);
|
||||
|
||||
virtual void tick();
|
||||
virtual void flush() {}
|
||||
private:
|
||||
|
||||
@@ -32,6 +32,9 @@ public:
|
||||
virtual void saveGame(Level* level) {}
|
||||
virtual void loadEntities(Level* level, LevelChunk* levelChunk) {}
|
||||
|
||||
virtual void savePlayer(Player& player) = 0;
|
||||
virtual bool loadPlayer(Player& player) = 0;
|
||||
|
||||
//void checkSession() throws LevelConflictException;
|
||||
//PlayerIO getPlayerIO();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user