the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 302 lines 8.9 kB view raw
1#include "stdafx.h" 2#include "PendingConnection.h" 3#include "PlayerConnection.h" 4#include "ServerConnection.h" 5#include "ServerPlayer.h" 6#include "ServerPlayerGameMode.h" 7#include "ServerLevel.h" 8#include "PlayerList.h" 9#include "MinecraftServer.h" 10#include "..\Minecraft.World\net.minecraft.network.h" 11#include "..\Minecraft.World\pos.h" 12#include "..\Minecraft.World\net.minecraft.world.level.dimension.h" 13#include "..\Minecraft.World\net.minecraft.world.level.storage.h" 14#include "..\Minecraft.World\net.minecraft.world.item.h" 15#include "..\Minecraft.World\SharedConstants.h" 16#include "Settings.h" 17// #ifdef __PS3__ 18// #include "PS3\Network\NetworkPlayerSony.h" 19// #endif 20 21Random *PendingConnection::random = new Random(); 22 23#ifdef _WINDOWS64 24bool g_bRejectDuplicateNames = true; 25#endif 26 27PendingConnection::PendingConnection(MinecraftServer *server, Socket *socket, const wstring& id) 28{ 29 // 4J - added initialisers 30 done = false; 31 _tick = 0; 32 name = L""; 33 acceptedLogin = nullptr; 34 loginKey = L""; 35 36 this->server = server; 37 connection = new Connection(socket, id, this); 38 connection->fakeLag = FAKE_LAG; 39} 40 41PendingConnection::~PendingConnection() 42{ 43 delete connection; 44} 45 46void PendingConnection::tick() 47{ 48 if (acceptedLogin != NULL) 49 { 50 this->handleAcceptedLogin(acceptedLogin); 51 acceptedLogin = nullptr; 52 } 53 if (_tick++ == MAX_TICKS_BEFORE_LOGIN) 54 { 55 disconnect(DisconnectPacket::eDisconnect_LoginTooLong); 56 } 57 else 58 { 59 connection->tick(); 60 } 61} 62 63void PendingConnection::disconnect(DisconnectPacket::eDisconnectReason reason) 64{ 65 // try { // 4J - removed try/catch 66 // logger.info("Disconnecting " + getName() + ": " + reason); 67 app.DebugPrintf("Pending connection disconnect: %d\n", reason ); 68 connection->send( shared_ptr<DisconnectPacket>( new DisconnectPacket(reason) ) ); 69 connection->sendAndQuit(); 70 done = true; 71 // } catch (Exception e) { 72 // e.printStackTrace(); 73 // } 74} 75 76void PendingConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet) 77{ 78 if (packet->m_netcodeVersion != MINECRAFT_NET_VERSION) 79 { 80 app.DebugPrintf("Netcode version is %d not equal to %d\n", packet->m_netcodeVersion, MINECRAFT_NET_VERSION); 81 if (packet->m_netcodeVersion > MINECRAFT_NET_VERSION) 82 { 83 disconnect(DisconnectPacket::eDisconnect_OutdatedServer); 84 } 85 else 86 { 87 disconnect(DisconnectPacket::eDisconnect_OutdatedClient); 88 } 89 return; 90 } 91 // printf("Server: handlePreLogin\n"); 92 name = packet->loginKey; // 4J Stu - Change from the login packet as we know better on client end during the pre-login packet 93 sendPreLoginResponse(); 94} 95 96void PendingConnection::sendPreLoginResponse() 97{ 98 // 4J Stu - Calculate the players with UGC privileges set 99 PlayerUID *ugcXuids = new PlayerUID[MINECRAFT_NET_MAX_PLAYERS]; 100 DWORD ugcXuidCount = 0; 101 DWORD hostIndex = 0; 102 BYTE ugcFriendsOnlyBits = 0; 103 char szUniqueMapName[14]; 104 105 StorageManager.GetSaveUniqueFilename(szUniqueMapName); 106 107 PlayerList *playerList = MinecraftServer::getInstance()->getPlayers(); 108 for(AUTO_VAR(it, playerList->players.begin()); it != playerList->players.end(); ++it) 109 { 110 shared_ptr<ServerPlayer> player = *it; 111 // If the offline Xuid is invalid but the online one is not then that's guest which we should ignore 112 // If the online Xuid is invalid but the offline one is not then we are definitely an offline game so dont care about UGC 113 114 // PADDY - this is failing when a local player with chat restrictions joins an online game 115 116 if( player != NULL && player->connection->m_offlineXUID != INVALID_XUID && player->connection->m_onlineXUID != INVALID_XUID ) 117 { 118 if( player->connection->m_friendsOnlyUGC ) 119 { 120 ugcFriendsOnlyBits |= (1<<ugcXuidCount); 121 } 122 // Need to use the online XUID otherwise friend checks will fail on the client 123 ugcXuids[ugcXuidCount] = player->connection->m_onlineXUID; 124 125 if( player->connection->getNetworkPlayer() != NULL && player->connection->getNetworkPlayer()->IsHost() ) hostIndex = ugcXuidCount; 126 127 ++ugcXuidCount; 128 } 129 } 130 131#if 0 132 if (false)// server->onlineMode) // 4J - removed 133 { 134 loginKey = L"TOIMPLEMENT"; // 4J - todo Long.toHexString(random.nextLong()); 135 connection->send( shared_ptr<PreLoginPacket>( new PreLoginPacket(loginKey, ugcXuids, ugcXuidCount, ugcFriendsOnlyBits, server->m_ugcPlayersVersion, szUniqueMapName,app.GetGameHostOption(eGameHostOption_All),hostIndex) ) ); 136 } 137 else 138#endif 139 { 140 connection->send( shared_ptr<PreLoginPacket>( new PreLoginPacket(L"-", ugcXuids, ugcXuidCount, ugcFriendsOnlyBits, server->m_ugcPlayersVersion,szUniqueMapName,app.GetGameHostOption(eGameHostOption_All),hostIndex, server->m_texturePackId) ) ); 141 } 142} 143 144void PendingConnection::handleLogin(shared_ptr<LoginPacket> packet) 145{ 146 // printf("Server: handleLogin\n"); 147 //name = packet->userName; 148 if (packet->clientVersion != SharedConstants::NETWORK_PROTOCOL_VERSION) 149 { 150 app.DebugPrintf("Client version is %d not equal to %d\n", packet->clientVersion, SharedConstants::NETWORK_PROTOCOL_VERSION); 151 if (packet->clientVersion > SharedConstants::NETWORK_PROTOCOL_VERSION) 152 { 153 disconnect(DisconnectPacket::eDisconnect_OutdatedServer); 154 } 155 else 156 { 157 disconnect(DisconnectPacket::eDisconnect_OutdatedClient); 158 } 159 return; 160 } 161 162 //if (true)// 4J removed !server->onlineMode) 163 bool sentDisconnect = false; 164 165 if( sentDisconnect ) 166 { 167 // Do nothing 168 } 169 else if( server->getPlayers()->isXuidBanned( packet->m_onlineXuid ) ) 170 { 171 disconnect(DisconnectPacket::eDisconnect_Banned); 172 } 173#ifdef _WINDOWS64 174 else if (g_bRejectDuplicateNames) 175 { 176 bool nameTaken = false; 177 vector<shared_ptr<ServerPlayer> >& pl = server->getPlayers()->players; 178 for (unsigned int i = 0; i < pl.size(); i++) 179 { 180 if (pl[i] != NULL && pl[i]->name == name) 181 { 182 nameTaken = true; 183 break; 184 } 185 } 186 if (nameTaken) 187 { 188 app.DebugPrintf("Rejecting duplicate name: %ls\n", name.c_str()); 189 disconnect(DisconnectPacket::eDisconnect_Banned); 190 } 191 else 192 { 193 handleAcceptedLogin(packet); 194 } 195 } 196#endif 197 else 198 { 199 handleAcceptedLogin(packet); 200 } 201 //else 202 { 203 //4J - removed 204#if 0 205 new Thread() { 206 public void run() { 207 try { 208 String key = loginKey; 209 URL url = new URL("http://www.minecraft.net/game/checkserver.jsp?user=" + URLEncoder.encode(packet.userName, "UTF-8") + "&serverId=" + URLEncoder.encode(key, "UTF-8")); 210 BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream())); 211 String msg = br.readLine(); 212 br.close(); 213 if (msg.equals("YES")) { 214 acceptedLogin = packet; 215 } else { 216 disconnect("Failed to verify username!"); 217 } 218 } catch (Exception e) { 219 disconnect("Failed to verify username! [internal error " + e + "]"); 220 e.printStackTrace(); 221 } 222 } 223 }.start(); 224#endif 225 } 226 227} 228 229void PendingConnection::handleAcceptedLogin(shared_ptr<LoginPacket> packet) 230{ 231 if(packet->m_ugcPlayersVersion != server->m_ugcPlayersVersion) 232 { 233 // Send the pre-login packet again with the new list of players 234 sendPreLoginResponse(); 235 return; 236 } 237 238 // Guests use the online xuid, everyone else uses the offline one 239 PlayerUID playerXuid = packet->m_offlineXuid; 240 if(playerXuid == INVALID_XUID) playerXuid = packet->m_onlineXuid; 241 242 shared_ptr<ServerPlayer> playerEntity = server->getPlayers()->getPlayerForLogin(this, name, playerXuid,packet->m_onlineXuid); 243 if (playerEntity != NULL) 244 { 245 server->getPlayers()->placeNewPlayer(connection, playerEntity, packet); 246 connection = NULL; // We've moved responsibility for this over to the new PlayerConnection, NULL so we don't delete our reference to it here in our dtor 247 } 248 done = true; 249 250} 251 252void PendingConnection::onDisconnect(DisconnectPacket::eDisconnectReason reason, void *reasonObjects) 253{ 254 // logger.info(getName() + " lost connection"); 255 done = true; 256} 257 258void PendingConnection::handleGetInfo(shared_ptr<GetInfoPacket> packet) 259{ 260 //try { 261 //String message = server->motd + "�" + server->players->getPlayerCount() + "�" + server->players->getMaxPlayers(); 262 //connection->send(new DisconnectPacket(message)); 263 connection->send(shared_ptr<DisconnectPacket>(new DisconnectPacket(DisconnectPacket::eDisconnect_ServerFull) ) ); 264 connection->sendAndQuit(); 265 server->connection->removeSpamProtection(connection->getSocket()); 266 done = true; 267 //} catch (Exception e) { 268 // e.printStackTrace(); 269 //} 270} 271 272void PendingConnection::handleKeepAlive(shared_ptr<KeepAlivePacket> packet) 273{ 274 // Ignore 275} 276 277void PendingConnection::onUnhandledPacket(shared_ptr<Packet> packet) 278{ 279 disconnect(DisconnectPacket::eDisconnect_UnexpectedPacket); 280} 281 282void PendingConnection::send(shared_ptr<Packet> packet) 283{ 284 connection->send(packet); 285} 286 287wstring PendingConnection::getName() 288{ 289 return L"Unimplemented"; 290 // if (name != null) return name + " [" + connection.getRemoteAddress().toString() + "]"; 291 // return connection.getRemoteAddress().toString(); 292} 293 294bool PendingConnection::isServerPacketListener() 295{ 296 return true; 297} 298 299bool PendingConnection::isDisconnected() 300{ 301 return done; 302}