// Receives player position and adds it to PlayerPositions Dict private void ClientPlayerPosition(byte[] data, ulong id) { float3 pos, dir; ChunkPos cp; NetMessage graphMessage = new NetMessage(NetCode.PLAYERDATA); pos = NetDecoder.ReadFloat3(data, 1); dir = NetDecoder.ReadFloat3(data, 13); this.cl.regionHandler.allPlayerData[id].SetPosition(pos.x, pos.y, pos.z); this.cl.regionHandler.allPlayerData[id].SetDirection(dir.x, dir.y, dir.z); cp = this.cl.regionHandler.allPlayerData[id].GetChunkPos(); if (!this.entityHandler.Contains(EntityType.PLAYER, cp, id)) { this.entityHandler.AddPlayer(cp, id, pos, dir); } this.entityHandler.SetPosition(EntityType.PLAYER, id, cp, pos); this.entityHandler.SetRotation(EntityType.PLAYER, id, cp, dir); // Propagates data to all network foreach (ulong code in this.connectionGraph[id]) { graphMessage.PlayerData(this.cl.regionHandler.allPlayerData[id]); this.Send(graphMessage.GetMessage(), graphMessage.size, code); } }
// 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); } } } }
// Gets chunk information to player private void RequestChunkLoad(byte[] data, ulong id) { ChunkPos pos = NetDecoder.ReadChunkPos(data, 1); // If is loaded if (this.cl.chunks.ContainsKey(pos) && this.cl.chunks[pos].needsGeneration == 0) { if (!this.cl.loadedChunks.ContainsKey(pos)) { this.cl.loadedChunks.Add(pos, new HashSet <ulong>()); } if (!this.cl.loadedChunks[pos].Contains(id)) { this.cl.loadedChunks[pos].Add(id); } NetMessage message = new NetMessage(NetCode.SENDCHUNK); message.SendChunk(this.cl.chunks[pos]); this.Send(message.GetMessage(), message.size, id); } else { // If it's not loaded yet if (!this.cl.toLoad.Contains(pos)) { this.cl.toLoad.Add(pos); } NetMessage message = new NetMessage(NetCode.FAILEDCHUNKREQUEST); message.FailedChunkRequest(pos); this.Send(message.GetMessage(), message.size, id); return; } NetMessage playerMessage = new NetMessage(NetCode.PLAYERDATA); // Sends logged in players data if (this.playersInChunk.ContainsKey(pos)) { foreach (ulong code in this.playersInChunk[pos]) { if (code == id) { continue; } if (this.cl.regionHandler.allPlayerData[code].IsOnline()) { this.connectionGraph[code].Add(id); playerMessage.PlayerData(this.cl.regionHandler.allPlayerData[code]); this.Send(playerMessage.GetMessage(), playerMessage.size, id); } } } NetMessage itemMessage = new NetMessage(NetCode.ITEMENTITYDATA); // Connects new Dropped items to player if (this.entityHandler.Contains(EntityType.DROP, pos)) { foreach (ulong itemCode in this.entityHandler.dropObject[pos].Keys) { itemMessage.ItemEntityData(this.entityHandler.dropObject[pos][itemCode].position.x, this.entityHandler.dropObject[pos][itemCode].position.y, this.entityHandler.dropObject[pos][itemCode].position.z, this.entityHandler.dropObject[pos][itemCode].rotation.x, this.entityHandler.dropObject[pos][itemCode].rotation.y, this.entityHandler.dropObject[pos][itemCode].rotation.z, (ushort)this.entityHandler.dropObject[pos][itemCode].its.GetID(), this.entityHandler.dropObject[pos][itemCode].its.GetAmount(), itemCode); } } }