/// <summary> /// Sends initial state to this <see cref="Player"/>. /// </summary> private void SendState() { Log.DebugFormat("Sending state to #{0}...", Slot); // TODO we should clamp world size to no more than UInt16.MaxValue bytes large // first send the world NetOutgoingMessage worldMsg = gameKeeper.Server.CreateMessage(1 + 2 + (UInt16)gameKeeper.RawWorld.Length); worldMsg.Write((Byte)MessageType.MsgWorld); worldMsg.Write((UInt16)gameKeeper.RawWorld.Length); worldMsg.Write(gameKeeper.RawWorld); SendMessage(worldMsg, NetDeliveryMethod.ReliableOrdered, 0); // TODO send other state information... like flags // tell him about everyone else Log.DebugFormat("Sending MsgAddPlayer for each player to #{0}", Slot); NetOutgoingMessage addPlayerMessage; MsgAddPlayerPacket addPlayerPacket; foreach (Player otherPlayer in gameKeeper.Players) { // don't want to tell our player about himself just yet... if (otherPlayer == this) continue; addPlayerMessage = gameKeeper.Server.CreateMessage(); addPlayerPacket = new MsgAddPlayerPacket(otherPlayer.PlayerInfo, false); addPlayerMessage.Write((Byte)addPlayerPacket.MsgType); addPlayerPacket.Write(addPlayerMessage); Log.DebugFormat("MsgAddPlayer Compiled ({0} bytes) for player #{1} and being sent to player #{2}", addPlayerMessage.LengthBytes, otherPlayer.Slot, this.Slot); SendMessage(addPlayerMessage, NetDeliveryMethod.ReliableOrdered, 0); } // send everyones' scores to him NetOutgoingMessage scoreMessage; foreach (Player otherPlayer in gameKeeper.Players) { // no reason to give our player his score... he has none yet if (otherPlayer == this) continue; scoreMessage = otherPlayer.GetMsgScore(); SendMessage(scoreMessage, NetDeliveryMethod.ReliableOrdered, 0); } // send back one last MsgAddPlayer with their full information (which could be changed!) addPlayerMessage = gameKeeper.Server.CreateMessage(); addPlayerPacket = new MsgAddPlayerPacket(PlayerInfo, true); addPlayerMessage.Write((Byte)addPlayerPacket.MsgType); addPlayerPacket.Write(addPlayerMessage); SendMessage(addPlayerMessage, NetDeliveryMethod.ReliableOrdered, 0); // let them know we're ready to move on, and give him his slot NetOutgoingMessage stateMessage = gameKeeper.Server.CreateMessage(); MsgStatePacket statePacket = new MsgStatePacket(Slot); stateMessage.Write((Byte)statePacket.MsgType); statePacket.Write(stateMessage); SendMessage(stateMessage, NetDeliveryMethod.ReliableOrdered, 0); // we're now ready to move to the spawn state and spawn this.state = PlayerState.Spawning; this.Spawn(); }
public void AddPlayer(NetConnection connection, PlayerInformation playerInfo) { String denyReason; Byte slot = AllocateSlot(playerInfo, out denyReason); // could not allocate the player if AllocateSlot returns DummySlot if (slot == ProtocolInformation.DummySlot) { Log.InfoFormat("Player \"{0}\" from {1} tried to join, but was rejected ({2}).", playerInfo.Callsign, connection, denyReason); connection.Deny(denyReason); return; } // we can now approve the player if we get here connection.Approve(); // add player to our list players[slot] = new Player(this, slot, connection, playerInfo); // and tell everyone else about this awesome new player Log.DebugFormat("Sending MsgAddPlayer to everyone else about player #{0}", slot); NetOutgoingMessage packet = Server.CreateMessage(); MsgAddPlayerPacket message = new MsgAddPlayerPacket(players[slot].PlayerInfo, false); packet.Write((Byte)message.MsgType); message.Write(packet); Log.DebugFormat("MsgAddPlayer Compiled ({0} bytes) and being sent to {1} recipients", packet.LengthBytes, players.Count - 1); // send to everyone except our new player, we let Player itself decide when to send the state to the new guy Server.SendToAll(packet, connection, NetDeliveryMethod.ReliableOrdered, 0); }