private static void DeserializeShotBroadcast(BitBuffer buffer, ShotBroadcast shotBroadcast) { shotBroadcast.ShotId = buffer.GetInt(); shotBroadcast.UserID = buffer.GetInt(); shotBroadcast.PlayerShotID = buffer.GetInt(); shotBroadcast.PlayerDied = buffer.GetInt() > 0; }
public static PacketType ServerDeserializeInput(BitBuffer buffer, List <Commands> commandsList, List <Shot> shotsList, ShotBroadcast shotBroadcast, PlayerJoined p, out int playerDisconnect) { var messageType = buffer.GetByte(); playerDisconnect = -1; if (messageType == (byte)PacketType.PLAYER_JOINED_ACK) { DeserializePlayerJoinedAck(p, buffer); return(PacketType.PLAYER_JOINED_ACK); } if (messageType == (byte)PacketType.COMMANDS) { DeserializeCommands(commandsList, buffer); return(PacketType.COMMANDS); } if (messageType == (byte)PacketType.PLAYER_SHOT) { DeserializeShot(shotsList, buffer); return(PacketType.PLAYER_SHOT); } if (messageType == (byte)PacketType.SHOT_BROADCAST_ACK) { DeserializeShotBroadcast(buffer, shotBroadcast); // SAME AS SHOTBROADCAST; BUT ITS AN ACK return(PacketType.SHOT_BROADCAST_ACK); } if (messageType == (byte)PacketType.PLAYER_DISCONNECT) { playerDisconnect = PlayerDisconnectDeserialize(buffer); } return(PacketType.PLAYER_DISCONNECT); }
public static void ClientSerializeShotBroadcastAck(ShotBroadcast shotBroadcast, BitBuffer buffer) { buffer.PutByte((byte)PacketType.SHOT_BROADCAST_ACK); buffer.PutInt(shotBroadcast.ShotId); buffer.PutInt(shotBroadcast.UserID); buffer.PutInt(shotBroadcast.PlayerShotID); buffer.PutInt(shotBroadcast.PlayerDied ? 1 : 0); }
public static void ShotBroadcastMessage(BitBuffer buffer, ShotBroadcast shot) { buffer.PutByte((byte)PacketType.SHOT_BROADCAST); buffer.PutInt(shot.ShotId); buffer.PutInt(shot.UserID); buffer.PutInt(shot.PlayerShotID); buffer.PutInt(shot.PlayerDied ? 1 : 0); }
public static PacketType ClientDeserialize(List <Snapshot> interpolationBuffer, PlayerJoined playerJoined, BitBuffer buffer, int displaySeq, CommandsList clientCommands, int cmdSeq, List <Shot> shots, int shotSeq, ShotBroadcast shotBroadcast, out int commandSnapshotAck, out int playerDisconnect) { commandSnapshotAck = -1; var messageType = buffer.GetByte(); playerDisconnect = -1; if (messageType == (byte)PacketType.UPDATE_MESSAGE) { ClientDeserializeUpdate(interpolationBuffer, buffer, displaySeq, clientCommands, out commandSnapshotAck); return(PacketType.UPDATE_MESSAGE); } if (messageType == (byte)PacketType.PLAYER_JOINED) { PlayerJoinedDeserialize(playerJoined, buffer); return(PacketType.PLAYER_JOINED); } if (messageType == (byte)PacketType.COMMANDS_ACK_MESSAGE) { int receivedAckSequence = ClientDeserializeAck(buffer); clientCommands.Ack(receivedAckSequence); return(PacketType.COMMANDS_ACK_MESSAGE); } if (messageType == (byte)PacketType.SHOT_ACK) { int receivedShotAckSeq = ClientDeserializeShotAck(buffer); int count = 0; foreach (var shot in shots) { if (shot.Seq <= receivedShotAckSeq) { count++; } } shots.RemoveRange(0, count); return(PacketType.SHOT_ACK); } if (messageType == (byte)PacketType.SHOT_BROADCAST) { DeserializeShotBroadcast(buffer, shotBroadcast); return(PacketType.SHOT_BROADCAST); } if (messageType == (byte)PacketType.PLAYER_DISCONNECT) { playerDisconnect = PlayerDisconnectDeserialize(buffer); } return(PacketType.PLAYER_DISCONNECT); }
private void AckBroadcastShot(int userID, ShotBroadcast shotBroadcast) { var pendingAcks = clients[shotBroadcast.UserID].unackedShotBroadcasts; if (pendingAcks.ContainsKey(shotBroadcast)) { pendingAcks[shotBroadcast].RemoveAll( x => x == userID); if (pendingAcks.Count == 0) { clients[shotBroadcast.UserID].unackedShotBroadcasts.Remove(shotBroadcast); } } }
private void BroadcastShot(Shot shot, bool playerDied) { ShotBroadcast s = new ShotBroadcast { ShotId = shotCount, UserID = shot.UserID, PlayerShotID = shot.PlayerShotID, PlayerDied = playerDied }; clients[shot.UserID].unackedShotBroadcasts[s] = new List <int>(); foreach (var client in clients) { Channel channel = client.Value.channel; var packet = Packet.Obtain(); Serializer.ShotBroadcastMessage(packet.buffer, shot, playerDied); packet.buffer.Flush(); var remoteEp = client.Value.dest; channel.Send(packet, remoteEp); packet.Free(); clients[shot.UserID].unackedShotBroadcasts[s].Add(client.Key); } }
private void UpdateServer() { serverTime += Time.deltaTime; foreach (var cubeClientPair in clients) { int userID = cubeClientPair.Key; var cubeClient = cubeClientPair.Value; var packet = cubeClient.channel.GetPacket(); while (packet != null) { var buffer = packet.buffer; List <Commands> commandsList = new List <Commands>(); List <Shot> shotsList = new List <Shot>(); ShotBroadcast s = new ShotBroadcast(); PlayerJoined p = new PlayerJoined(); int playerDisconnect; var packetType = Serializer.ServerDeserializeInput(buffer, commandsList, shotsList, s, p, out playerDisconnect); // TODO: use generics to avoid code repetition, // as shots and commands are handled the same way switch (packetType) { case PacketType.PLAYER_JOINED_ACK: AckPlayerJoinedBroadcast(userID, p); break; case PacketType.COMMANDS: StoreCommands(userID, cubeClient, commandsList); break; case PacketType.PLAYER_SHOT: StoreShots(userID, cubeClient, shotsList); break; case PacketType.SHOT_BROADCAST_ACK: AckBroadcastShot(userID, s); break; case PacketType.PLAYER_DISCONNECT: playersToDisconnect.Add(playerDisconnect); break; default: throw new ArgumentOutOfRangeException(); } packet = cubeClient.channel.GetPacket(); } } foreach (var userID in playersToDisconnect) { DisconnectPlayer(userID); } playersToDisconnect.Clear(); if (accum >= sendRate) { foreach (var cubeClientPair in clients) { if (!cubeClientPair.Value.Confirmed) // PlayerJoined not acked yet { continue; } int userID = cubeClientPair.Key; var cubeClient = cubeClientPair.Value; var pendingCommands = cubeClientPair.Value.pendingCommands; int lastCommandsReceived = clients[userID].cmdSeqReceived; Dictionary <int, ServerClientInfo> confirmedClients = clients.Where( x => x.Value.Confirmed).ToDictionary( x => x.Key, x => x.Value); // Serialize snapshot var packet = Packet.Obtain(); var cmdSeq = (pendingCommands.Count > 0) ? pendingCommands[0].Seq - 1 // only send command Seq that has been applied to snapshot : lastCommandsReceived; Serializer.ServerWorldSerialize(confirmedClients, packet.buffer, seq, serverTime, cmdSeq); packet.buffer.Flush(); var remoteEp = cubeClientPair.Value.dest; cubeClient.channel.Send(packet, remoteEp); packet.Free(); } accum -= sendRate; seq++; } }