4jcraft/Minecraft.Client/Network/ServerConnection.cpp
MatthewBeshay a0fdc643d1 Merge branch 'upstream-dev' into cleanup/nullptr-replacement
# Conflicts:
#	Minecraft.Client/Network/PlayerChunkMap.cpp
#	Minecraft.Client/Network/PlayerList.cpp
#	Minecraft.Client/Network/ServerChunkCache.cpp
#	Minecraft.Client/Platform/Common/Consoles_App.cpp
#	Minecraft.Client/Platform/Common/DLC/DLCManager.cpp
#	Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp
#	Minecraft.Client/Platform/Common/GameRules/LevelRuleset.cpp
#	Minecraft.Client/Platform/Common/Tutorial/Tutorial.cpp
#	Minecraft.Client/Platform/Common/Tutorial/TutorialTask.cpp
#	Minecraft.Client/Platform/Common/UI/IUIScene_CreativeMenu.cpp
#	Minecraft.Client/Platform/Common/UI/UIComponent_Panorama.cpp
#	Minecraft.Client/Platform/Common/UI/UIController.cpp
#	Minecraft.Client/Platform/Common/UI/UIController.h
#	Minecraft.Client/Platform/Extrax64Stubs.cpp
#	Minecraft.Client/Platform/Windows64/4JLibs/inc/4J_Input.h
#	Minecraft.Client/Platform/Windows64/4JLibs/inc/4J_Storage.h
#	Minecraft.Client/Player/EntityTracker.cpp
#	Minecraft.Client/Player/ServerPlayer.cpp
#	Minecraft.Client/Rendering/EntityRenderers/PlayerRenderer.cpp
#	Minecraft.Client/Textures/Packs/DLCTexturePack.cpp
#	Minecraft.Client/Textures/Stitching/StitchedTexture.cpp
#	Minecraft.Client/Textures/Stitching/TextureMap.cpp
#	Minecraft.Client/Textures/Textures.cpp
#	Minecraft.World/Blocks/NotGateTile.cpp
#	Minecraft.World/Blocks/PressurePlateTile.cpp
#	Minecraft.World/Blocks/TileEntities/PotionBrewing.cpp
#	Minecraft.World/Enchantments/EnchantmentHelper.cpp
#	Minecraft.World/Entities/HangingEntity.cpp
#	Minecraft.World/Entities/LeashFenceKnotEntity.cpp
#	Minecraft.World/Entities/LivingEntity.cpp
#	Minecraft.World/Entities/Mobs/Boat.cpp
#	Minecraft.World/Entities/Mobs/Minecart.cpp
#	Minecraft.World/Entities/Mobs/Witch.cpp
#	Minecraft.World/Entities/SyncedEntityData.cpp
#	Minecraft.World/Items/LeashItem.cpp
#	Minecraft.World/Items/PotionItem.cpp
#	Minecraft.World/Level/BaseMobSpawner.cpp
#	Minecraft.World/Level/CustomLevelSource.cpp
#	Minecraft.World/Level/Level.cpp
#	Minecraft.World/Level/Storage/DirectoryLevelStorage.cpp
#	Minecraft.World/Level/Storage/McRegionLevelStorage.cpp
#	Minecraft.World/Level/Storage/RegionFileCache.cpp
#	Minecraft.World/Player/Player.cpp
#	Minecraft.World/WorldGen/Biomes/BiomeCache.cpp
#	Minecraft.World/WorldGen/Features/RandomScatteredLargeFeature.cpp
#	Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp
2026-03-30 16:28:40 +11:00

196 lines
6.8 KiB
C++

#include "../Platform/stdafx.h"
#include "../GameState/Options.h"
#include "ServerConnection.h"
#include "PendingConnection.h"
#include "PlayerConnection.h"
#include "../Player/ServerPlayer.h"
#include "../../Minecraft.World/Headers/net.minecraft.network.h"
#include "../../Minecraft.World/Network/Socket.h"
#include "../../Minecraft.World/Headers/net.minecraft.world.level.h"
#include "../Level/MultiPlayerLevel.h"
ServerConnection::ServerConnection(MinecraftServer* server) {
// 4J - added initialiser
connectionCounter = 0;
InitializeCriticalSection(&pending_cs);
this->server = server;
}
ServerConnection::~ServerConnection() { DeleteCriticalSection(&pending_cs); }
// 4J - added to handle incoming connections, to replace thread that original
// used to have
void ServerConnection::NewIncomingSocket(Socket* socket) {
std::shared_ptr<PendingConnection> unconnectedClient =
std::shared_ptr<PendingConnection>(new PendingConnection(
server, socket,
L"Connection #" + _toString<int>(connectionCounter++)));
handleConnection(unconnectedClient);
}
void ServerConnection::addPlayerConnection(
std::shared_ptr<PlayerConnection> uc) {
players.push_back(uc);
}
void ServerConnection::handleConnection(std::shared_ptr<PendingConnection> uc) {
EnterCriticalSection(&pending_cs);
pending.push_back(uc);
LeaveCriticalSection(&pending_cs);
}
void ServerConnection::stop() {
EnterCriticalSection(&pending_cs);
for (unsigned int i = 0; i < pending.size(); i++) {
std::shared_ptr<PendingConnection> uc = pending[i];
uc->connection->close(DisconnectPacket::eDisconnect_Closed);
}
LeaveCriticalSection(&pending_cs);
for (unsigned int i = 0; i < players.size(); i++) {
std::shared_ptr<PlayerConnection> player = players[i];
player->connection->close(DisconnectPacket::eDisconnect_Closed);
}
}
void ServerConnection::tick() {
{
// MGH - changed this so that the the CS lock doesn't cover the tick
// (was causing a lockup when 2 players tried to join)
EnterCriticalSection(&pending_cs);
std::vector<std::shared_ptr<PendingConnection> > tempPending = pending;
LeaveCriticalSection(&pending_cs);
for (unsigned int i = 0; i < tempPending.size(); i++) {
std::shared_ptr<PendingConnection> uc = tempPending[i];
// try { // 4J - removed try/catch
uc->tick();
// } catch (Exception e) {
// uc.disconnect("Internal server error");
// logger.log(Level.WARNING, "Failed to handle packet: "
// + e, e);
// }
if (uc->connection != nullptr) uc->connection->flush();
}
}
// now remove from the pending list
EnterCriticalSection(&pending_cs);
for (unsigned int i = 0; i < pending.size(); i++)
if (pending[i]->done) {
pending.erase(pending.begin() + i);
i--;
}
LeaveCriticalSection(&pending_cs);
for (unsigned int i = 0; i < players.size(); i++) {
std::shared_ptr<PlayerConnection> player = players[i];
std::shared_ptr<ServerPlayer> serverPlayer = player->getPlayer();
if (serverPlayer) {
serverPlayer->updateFrameTick();
serverPlayer->doChunkSendingTick(false);
}
player->tick();
if (player->done) {
players.erase(players.begin() + i);
i--;
}
player->connection->flush();
}
}
bool ServerConnection::addPendingTextureRequest(
const std::wstring& textureName) {
auto it = find(m_pendingTextureRequests.begin(),
m_pendingTextureRequests.end(), textureName);
if (it == m_pendingTextureRequests.end()) {
m_pendingTextureRequests.push_back(textureName);
return true;
}
// 4J Stu - We want to request this texture from everyone, if we have a
// duplicate it's most likely because the first person we asked for it
// didn't have it eg They selected a skin then deleted the skin pack. The
// side effect of this change is that in certain cases we can send a few
// more requests, and receive a few more responses if people join with the
// same skin in a short space of time
return true;
}
void ServerConnection::handleTextureReceived(const std::wstring& textureName) {
auto it = find(m_pendingTextureRequests.begin(),
m_pendingTextureRequests.end(), textureName);
if (it != m_pendingTextureRequests.end()) {
m_pendingTextureRequests.erase(it);
}
for (unsigned int i = 0; i < players.size(); i++) {
std::shared_ptr<PlayerConnection> player = players[i];
if (!player->done) {
player->handleTextureReceived(textureName);
}
}
}
void ServerConnection::handleTextureAndGeometryReceived(
const std::wstring& textureName) {
auto it = find(m_pendingTextureRequests.begin(),
m_pendingTextureRequests.end(), textureName);
if (it != m_pendingTextureRequests.end()) {
m_pendingTextureRequests.erase(it);
}
for (unsigned int i = 0; i < players.size(); i++) {
std::shared_ptr<PlayerConnection> player = players[i];
if (!player->done) {
player->handleTextureAndGeometryReceived(textureName);
}
}
}
void ServerConnection::handleServerSettingsChanged(
std::shared_ptr<ServerSettingsChangedPacket> packet) {
Minecraft* pMinecraft = Minecraft::GetInstance();
if (packet->action == ServerSettingsChangedPacket::HOST_DIFFICULTY) {
for (unsigned int i = 0; i < pMinecraft->levels.length; ++i) {
if (pMinecraft->levels[i] != nullptr) {
app.DebugPrintf(
"ClientConnection::handleServerSettingsChanged - "
"Difficulty = %d",
packet->data);
pMinecraft->levels[i]->difficulty = packet->data;
}
}
}
// else
// if(packet->action==ServerSettingsChangedPacket::HOST_IN_GAME_SETTINGS)//
// options
// {
// app.SetGameHostOption(eGameHostOption_All,packet->m_serverSettings)
// }
// else
// {
// unsigned char ucData=(unsigned char)packet->data;
// if(ucData&1)
// {
// // hide gamertags
// pMinecraft->options->SetGamertagSetting(true);
// }
// else
// {
// pMinecraft->options->SetGamertagSetting(false);
// }
//
// for (unsigned int i = 0; i < players.size(); i++)
// {
// shared_ptr<PlayerConnection> playerconnection =
// players[i];
// playerconnection->setShowOnMaps(pMinecraft->options->GetGamertagSetting());
// }
// }
}
std::vector<std::shared_ptr<PlayerConnection> >*
ServerConnection::getPlayers() {
return &players;
}