// Deletes the connection between a client and a chunk private void RequestChunkUnload(byte[] data, ulong id) { ChunkPos pos = NetDecoder.ReadChunkPos(data, 1); NetMessage killMessage = new NetMessage(NetCode.ENTITYDELETE); if (this.playersInChunk.ContainsKey(pos)) { foreach (ulong code in this.playersInChunk[pos]) { if (code == id) { continue; } this.connectionGraph[code].Remove(id); killMessage.EntityDelete(EntityType.PLAYER, code); this.Send(killMessage.GetMessage(), killMessage.size, id); } } if (this.entityHandler.Contains(EntityType.DROP, pos)) { foreach (ulong itemCode in this.entityHandler.dropObject[pos].Keys) { killMessage.EntityDelete(EntityType.DROP, itemCode); this.Send(killMessage.GetMessage(), killMessage.size, id); } } this.cl.UnloadChunk(pos, id); }
// Receives the client's current chunk and finds the connections it has with other players private void ClientChunk(byte[] data, ulong id) { ChunkPos lastPos = NetDecoder.ReadChunkPos(data, 1); ChunkPos newPos = NetDecoder.ReadChunkPos(data, 9); // Removes last ChunkPos if exists if (lastPos != newPos) { if (this.playersInChunk.ContainsKey(lastPos)) { if (this.playersInChunk[lastPos].Count > 1) { this.playersInChunk[lastPos].Remove(id); } else { this.playersInChunk.Remove(lastPos); } if (this.entityHandler.Contains(EntityType.PLAYER, lastPos, id)) { this.entityHandler.Remove(EntityType.PLAYER, lastPos, id); } } } // Add new ChunkPos if (!this.playersInChunk.ContainsKey(newPos)) { this.playersInChunk.Add(newPos, new HashSet <ulong>() { id }); } else { this.playersInChunk[newPos].Add(id); } // Finds the connections ChunkPos targetPos; NetMessage killMessage = new NetMessage(NetCode.ENTITYDELETE); foreach (ulong code in this.cl.regionHandler.allPlayerData.Keys) { // If iterates through itself if (code == id) { continue; } // If iterates through non-online user if (!this.cl.regionHandler.allPlayerData[code].IsOnline()) { continue; } // Check if code should still be connected if (this.connectionGraph[id].Contains(code)) { targetPos = this.cl.regionHandler.allPlayerData[code].GetChunkPos(); if (!this.cl.loadedChunks.ContainsKey(newPos)) { this.cl.loadedChunks.Add(newPos, new HashSet <ulong>()); } if (!this.cl.loadedChunks[newPos].Contains(code)) { this.connectionGraph[id].Remove(code); killMessage.EntityDelete(EntityType.PLAYER, id); this.Send(killMessage.GetMessage(), killMessage.size, code); } } // Check if code should be connected else { if (!this.cl.loadedChunks.ContainsKey(newPos)) { this.cl.loadedChunks.Add(newPos, new HashSet <ulong>()); } if (this.cl.loadedChunks[newPos].Contains(code)) { NetMessage liveMessage = new NetMessage(NetCode.PLAYERDATA); this.connectionGraph[id].Add(code); liveMessage.PlayerData(this.cl.regionHandler.allPlayerData[id]); this.Send(liveMessage.GetMessage(), liveMessage.size, code); } } } }
// Receives a disconnect call from client private void Disconnect(ulong id, DisconnectType type) { if (!this.connections.ContainsKey(id)) { return; } List <ChunkPos> toRemove = new List <ChunkPos>(); NetMessage killMessage = new NetMessage(NetCode.ENTITYDELETE); killMessage.EntityDelete(EntityType.PLAYER, id); // Captures and removes all chunks foreach (KeyValuePair <ChunkPos, HashSet <ulong> > item in this.cl.loadedChunks) { if (this.cl.loadedChunks[item.Key].Contains(id)) { toRemove.Add(item.Key); } } foreach (ChunkPos pos in toRemove) { this.cl.UnloadChunk(pos, id); } this.connections[id].Close(); this.connections.Remove(id); this.timeoutTimers.Remove(id); this.lengthPacket.Remove(id); this.dataBuffer.Remove(id); this.packetIndex.Remove(id); this.packetSize.Remove(id); this.playerRenderDistances.Remove(id); this.connectionGraph.Remove(id); this.receiveBuffer.Remove(id); this.entityHandler.Remove(EntityType.PLAYER, this.cl.regionHandler.allPlayerData[id].GetChunkPos(), id); foreach (ulong code in this.cl.regionHandler.allPlayerData.Keys) { if (code == id) { continue; } // If iterates through non-online user if (!this.cl.regionHandler.allPlayerData[code].IsOnline()) { continue; } // If finds connection to it, erase if (this.connectionGraph[code].Contains(id)) { this.connectionGraph[code].Remove(id); this.Send(killMessage.GetMessage(), killMessage.size, code); } } this.cl.regionHandler.SavePlayers(); this.cl.regionHandler.allPlayerData[id].SetOnline(false); if (this.playersInChunk.ContainsKey(this.cl.regionHandler.allPlayerData[id].GetChunkPos())) { if (this.playersInChunk[this.cl.regionHandler.allPlayerData[id].GetChunkPos()].Count > 1) { this.playersInChunk[this.cl.regionHandler.allPlayerData[id].GetChunkPos()].Remove(id); } else { this.playersInChunk.Remove(this.cl.regionHandler.allPlayerData[id].GetChunkPos()); } } if (type == DisconnectType.QUIT) { Debug.Log("ID: " + id + " has disconnected"); } else if (type == DisconnectType.LOSTCONNECTION) { Debug.Log("ID: " + id + " has lost connection"); } else if (type == DisconnectType.TIMEDOUT) { Debug.Log("ID: " + id + " has timed out"); } else if (type == DisconnectType.LOGINOVERWRITE) { Debug.Log("ID: " + id + " has overwritten it's login"); } else { Debug.Log("ID: " + id + " has quit due to unknown issue"); } if (this.isLocal) { Application.Quit(); } }