the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 248 lines 9.0 kB view raw
1#include "stdafx.h" 2#include "EntityTracker.h" 3#include "MinecraftServer.h" 4#include "PlayerList.h" 5#include "TrackedEntity.h" 6#include "ServerPlayer.h" 7#include "ServerLevel.h" 8#include "..\Minecraft.World\Mth.h" 9#include "..\Minecraft.World\net.minecraft.world.entity.h" 10#include "..\Minecraft.World\net.minecraft.world.entity.item.h" 11#include "..\Minecraft.World\net.minecraft.world.entity.monster.h" 12#include "..\Minecraft.World\net.minecraft.world.entity.player.h" 13#include "..\Minecraft.World\net.minecraft.world.entity.animal.h" 14#include "..\Minecraft.World\net.minecraft.world.entity.global.h" 15#include "..\Minecraft.World\net.minecraft.world.entity.projectile.h" 16#include "..\Minecraft.World\net.minecraft.world.entity.boss.enderdragon.h" 17#include "..\Minecraft.World\net.minecraft.network.packet.h" 18#include "..\Minecraft.World\net.minecraft.network.h" 19#include "..\Minecraft.World\net.minecraft.world.level.dimension.h" 20#include "..\Minecraft.World\BasicTypeContainers.h" 21#include "..\Minecraft.World\net.minecraft.world.level.chunk.h" 22#include "PlayerConnection.h" 23 24EntityTracker::EntityTracker(ServerLevel *level) 25{ 26 this->level = level; 27 maxRange = level->getServer()->getPlayers()->getMaxRange(); 28} 29 30void EntityTracker::addEntity(shared_ptr<Entity> e) 31{ 32 if (e->instanceof(eTYPE_SERVERPLAYER)) 33 { 34 addEntity(e, 32 * 16, 2); 35 shared_ptr<ServerPlayer> player = dynamic_pointer_cast<ServerPlayer>(e); 36 for( AUTO_VAR(it, entities.begin()); it != entities.end(); it++ ) 37 { 38 if( (*it)->e != player ) 39 { 40 (*it)->updatePlayer(this, player); 41 } 42 } 43 } 44 else if (e->instanceof(eTYPE_FISHINGHOOK)) addEntity(e, 16 * 4, 5, true); 45 else if (e->instanceof(eTYPE_SMALL_FIREBALL)) addEntity(e, 16 * 4, 10, false); 46 else if (e->instanceof(eTYPE_DRAGON_FIREBALL)) addEntity(e, 16 * 4, 10, false); // 4J Added TU9 47 else if (e->instanceof(eTYPE_ARROW)) addEntity(e, 16 * 4, 20, false); 48 else if (e->instanceof(eTYPE_FIREBALL)) addEntity(e, 16 * 4, 10, false); 49 else if (e->instanceof(eTYPE_SNOWBALL)) addEntity(e, 16 * 4, 10, true); 50 else if (e->instanceof(eTYPE_THROWNENDERPEARL)) addEntity(e, 16 * 4, 10, true); 51 else if (e->instanceof(eTYPE_EYEOFENDERSIGNAL)) addEntity(e, 16 * 4, 4, true); 52 else if (e->instanceof(eTYPE_THROWNEGG)) addEntity(e, 16 * 4, 10, true); 53 else if (e->instanceof(eTYPE_THROWNPOTION)) addEntity(e, 16 * 4, 10, true); 54 else if (e->instanceof(eTYPE_THROWNEXPBOTTLE)) addEntity(e, 16 * 4, 10, true); 55 else if (e->instanceof(eTYPE_FIREWORKS_ROCKET)) addEntity(e, 16 * 4, 10, true); 56 else if (e->instanceof(eTYPE_ITEMENTITY)) addEntity(e, 16 * 4, 20, true); 57 else if (e->instanceof(eTYPE_MINECART)) addEntity(e, 16 * 5, 3, true); 58 else if (e->instanceof(eTYPE_BOAT)) addEntity(e, 16 * 5, 3, true); 59 else if (e->instanceof(eTYPE_SQUID)) addEntity(e, 16 * 4, 3, true); 60 else if (e->instanceof(eTYPE_WITHERBOSS)) addEntity(e, 16 * 5, 3, false); 61 else if (e->instanceof(eTYPE_BAT)) addEntity(e, 16 * 5, 3, false); 62 else if (dynamic_pointer_cast<Creature>(e)!=NULL) addEntity(e, 16 * 5, 3, true); 63 else if (e->instanceof(eTYPE_ENDERDRAGON)) addEntity(e, 16 * 10, 3, true); 64 else if (e->instanceof(eTYPE_PRIMEDTNT)) addEntity(e, 16 * 10, 10, true); 65 else if (e->instanceof(eTYPE_FALLINGTILE)) addEntity(e, 16 * 10, 20, true); 66 else if (e->instanceof(eTYPE_HANGING_ENTITY)) addEntity(e, 16 * 10, INT_MAX, false); 67 else if (e->instanceof(eTYPE_EXPERIENCEORB)) addEntity(e, 16 * 10, 20, true); 68 else if (e->instanceof(eTYPE_ENDER_CRYSTAL)) addEntity(e, 16 * 16, INT_MAX, false); 69 else if (e->instanceof(eTYPE_ITEM_FRAME)) addEntity(e, 16 * 10, INT_MAX, false); 70} 71 72void EntityTracker::addEntity(shared_ptr<Entity> e, int range, int updateInterval) 73{ 74 addEntity(e, range, updateInterval, false); 75} 76 77void EntityTracker::addEntity(shared_ptr<Entity> e, int range, int updateInterval, bool trackDeltas) 78{ 79 if (range > maxRange) range = maxRange; 80 if (entityMap.find(e->entityId) != entityMap.end()) 81 { 82 assert(false); // Entity already tracked 83 } 84 if( e->entityId >= 2048 ) 85 { 86 __debugbreak(); 87 } 88 shared_ptr<TrackedEntity> te = shared_ptr<TrackedEntity>( new TrackedEntity(e, range, updateInterval, trackDeltas) ); 89 entities.insert(te); 90 entityMap[e->entityId] = te; 91 te->updatePlayers(this, &level->players); 92} 93 94// 4J - have split removeEntity into two bits - it used to do the equivalent of EntityTracker::removePlayer followed by EntityTracker::removeEntity. 95// This is to allow us to now choose to remove the player as a "seenBy" only when the player has actually been removed from the level's own player array 96void EntityTracker::removeEntity(shared_ptr<Entity> e) 97{ 98 AUTO_VAR(it, entityMap.find(e->entityId)); 99 if( it != entityMap.end() ) 100 { 101 shared_ptr<TrackedEntity> te = it->second; 102 entityMap.erase(it); 103 entities.erase(te); 104 te->broadcastRemoved(); 105 } 106} 107 108void EntityTracker::removePlayer(shared_ptr<Entity> e) 109{ 110 if (e->GetType() == eTYPE_SERVERPLAYER) 111 { 112 shared_ptr<ServerPlayer> player = dynamic_pointer_cast<ServerPlayer>(e); 113 for( AUTO_VAR(it, entities.begin()); it != entities.end(); it++ ) 114 { 115 (*it)->removePlayer(player); 116 } 117 118 // 4J: Flush now to ensure remove packets are sent before player respawns and add entity packets are sent 119 player->flushEntitiesToRemove(); 120 } 121} 122 123void EntityTracker::tick() 124{ 125 vector<shared_ptr<ServerPlayer> > movedPlayers; 126 for( AUTO_VAR(it, entities.begin()); it != entities.end(); it++ ) 127 { 128 shared_ptr<TrackedEntity> te = *it; 129 te->tick(this, &level->players); 130 if (te->moved && te->e->GetType() == eTYPE_SERVERPLAYER) 131 { 132 movedPlayers.push_back(dynamic_pointer_cast<ServerPlayer>(te->e)); 133 } 134 } 135 136 // 4J Stu - If one player on a system is updated, then make sure they all are as they all have their 137 // range extended to include entities visible by any other player on the system 138 // Fix for #11194 - Gameplay: Host player and their split-screen avatars can become invisible and invulnerable to client. 139 MinecraftServer *server = MinecraftServer::getInstance(); 140 for( unsigned int i = 0; i < server->getPlayers()->players.size(); i++ ) 141 { 142 shared_ptr<ServerPlayer> ep = server->getPlayers()->players[i]; 143 if( ep->dimension != level->dimension->id ) continue; 144 145 if( ep->connection == NULL ) continue; 146 INetworkPlayer *thisPlayer = ep->connection->getNetworkPlayer(); 147 if( thisPlayer == NULL ) continue; 148 149 bool addPlayer = false; 150 for (unsigned int j = 0; j < movedPlayers.size(); j++) 151 { 152 shared_ptr<ServerPlayer> sp = movedPlayers[j]; 153 154 if( sp == ep ) break; 155 156 if(sp->connection == NULL) continue; 157 INetworkPlayer *otherPlayer = sp->connection->getNetworkPlayer(); 158 if( otherPlayer != NULL && thisPlayer->IsSameSystem(otherPlayer) ) 159 { 160 addPlayer = true; 161 break; 162 } 163 } 164 if( addPlayer ) movedPlayers.push_back( ep ); 165 } 166 167 for (unsigned int i = 0; i < movedPlayers.size(); i++) 168 { 169 shared_ptr<ServerPlayer> player = movedPlayers[i]; 170 if(player->connection == NULL) continue; 171 for( AUTO_VAR(it, entities.begin()); it != entities.end(); it++ ) 172 { 173 shared_ptr<TrackedEntity> te = *it; 174 if (te->e != player) 175 { 176 te->updatePlayer(this, player); 177 } 178 } 179 } 180 181 // 4J Stu - We want to do this for dead players as they don't tick normally 182 for(AUTO_VAR(it, level->players.begin()); it != level->players.end(); ++it) 183 { 184 shared_ptr<ServerPlayer> player = dynamic_pointer_cast<ServerPlayer>(*it); 185 if(!player->isAlive()) 186 { 187 player->flushEntitiesToRemove(); 188 } 189 } 190} 191 192void EntityTracker::broadcast(shared_ptr<Entity> e, shared_ptr<Packet> packet) 193{ 194 AUTO_VAR(it, entityMap.find( e->entityId )); 195 if( it != entityMap.end() ) 196 { 197 shared_ptr<TrackedEntity> te = it->second; 198 te->broadcast(packet); 199 } 200} 201 202void EntityTracker::broadcastAndSend(shared_ptr<Entity> e, shared_ptr<Packet> packet) 203{ 204 AUTO_VAR(it, entityMap.find( e->entityId )); 205 if( it != entityMap.end() ) 206 { 207 shared_ptr<TrackedEntity> te = it->second; 208 te->broadcastAndSend(packet); 209 } 210} 211 212void EntityTracker::clear(shared_ptr<ServerPlayer> serverPlayer) 213{ 214 for( AUTO_VAR(it, entities.begin()); it != entities.end(); it++ ) 215 { 216 shared_ptr<TrackedEntity> te = *it; 217 te->clear(serverPlayer); 218 } 219} 220 221void EntityTracker::playerLoadedChunk(shared_ptr<ServerPlayer> player, LevelChunk *chunk) 222{ 223 for (AUTO_VAR(it,entities.begin()); it != entities.end(); ++it) 224 { 225 shared_ptr<TrackedEntity> te = *it; 226 if (te->e != player && te->e->xChunk == chunk->x && te->e->zChunk == chunk->z) 227 { 228 te->updatePlayer(this, player); 229 } 230 } 231} 232 233// AP added for Vita so the range can be increased once the level starts 234void EntityTracker::updateMaxRange() 235{ 236 maxRange = level->getServer()->getPlayers()->getMaxRange(); 237} 238 239 240shared_ptr<TrackedEntity> EntityTracker::getTracker(shared_ptr<Entity> e) 241{ 242 AUTO_VAR(it, entityMap.find(e->entityId)); 243 if( it != entityMap.end() ) 244 { 245 return it->second; 246 } 247 return nullptr; 248}