public void WriteResponse(NetOutgoingMessage msg, PacketDataResponse packetData) { var player = packetData.Player; msg.WriteAllProperties(player); msg.Write(packetData.OtherPlayers.Length); foreach (var otherPlayer in packetData.OtherPlayers) { msg.WriteAllProperties(otherPlayer); } }
/// <summary> /// Serializes this message object into the provided outgoing lidgren message. /// Requires server time to mark when this message was prepared for sending. /// Uses reflection to serialize fields and properties from the payload object. /// </summary> /// <param name="msg"></param> /// <param name="serverTime"></param> public void Encode(NetOutgoingMessage msg, double serverTime) { MessageSentTime = serverTime; // write "header" properties msg.Write(MessageSentTime); msg.Write((byte)MessageType); msg.Write(Id); msg.Write(PayloadTypeId); try { // Lidgren methods automatically write correct type for field types via reflection msg.WriteAllFields(Payload, DefaultBinding); msg.WriteAllProperties(Payload, DefaultBinding); } catch (NetException ex) { throw new RedGrinException("Error writing entity state to network message.", ex); } catch (SystemException ex) { throw new RedGrinException("Unknown message error.", ex); } }
public void WriteResponse(NetOutgoingMessage msg, PacketDataResponse packetData) { msg.Write((byte)PacketType.AllPlayers); msg.Write(packetData.Players.Length); foreach (var player in packetData.Players) { msg.WriteAllProperties(player); } }
//This function is called when we click on the login button public void LoginToServer() { //Cheap but yeah, let the user select a zone to start in, but verify a proper zone has been typed in. if (zone.text != "Twin City") { print("Dont be a f****t, type it in right >.>"); return; } //Explained in the server code Config.EnableMessageType(NetIncomingMessageType.ConnectionApproval); //Instantiate new net client with the given config Client = new NetClient(Config); NetOutgoingMessage outmsg = Client.CreateMessage(); Client.Start(); //Instantiate our character locally player = new Character(); player.Name = username.text; player.Skin = "Blue"; //idk //Set zone according to whatever we choose to log in to if (zone.text == "Twin City") { player.CurrentZone = Zones.TwinCity; } else if (zone.text == "Bird Island") { player.CurrentZone = Zones.BirdIsland; } //Create the players list, so we can add players to it once we are connected and receive.. players from the server players = new List <Character> (); //Write login bite first because we're logging in outmsg.Write((byte)PacketTypes.LOGIN); //Write all of our players info to the message outmsg.WriteAllProperties(player); //Connect to the server & send the message we wrote along side it Client.Connect(address.text, Port, outmsg); //We sent the login info, now wait for the server to reply WaitForLoginResponse(); }
static void OnConnectionApproval() { // Read the first byte of the packet // ( Enums can be casted to bytes, so it be used to make bytes human readable ) if (inc.ReadByte() == (byte)Packets.Type.LOGIN) { Console.WriteLine("Incoming LOGIN"); // Approve clients connection ( Its sort of agreenment. "You can be my client and i will host you" ) inc.SenderConnection.Approve(); } clients.Add(new Messenger(inc.ToString(), inc.SenderConnection)); // Create message, that can be written and sent NetOutgoingMessage outmsg = Server.CreateMessage(); // first we write byte outmsg.Write((byte)Packets.Type.MESSAGE); // then int outmsg.Write(clients.Count + " clients connected."); // iterate trought every character ingame foreach (Messenger cl in clients) { // This is handy method // It writes all the properties of object to the packet outmsg.WriteAllProperties(cl); } // Send message/packet to all connections, in reliably order, channel 0 // Reliably means, that each packet arrives in same order they were sent. Its slower than unreliable, but easyest to understand Server.SendMessage(outmsg, inc.SenderConnection, NetDeliveryMethod.ReliableOrdered, 0); // Debug Console.WriteLine("Approved new connection and updated clients list"); }
/// <summary> /// Writes a packet to the server to figure out what to do. /// </summary> /// <param name="msg"></param> /// <param name="serverPacket"></param> private void writePackageInfo(NetOutgoingMessage msg, ClientPacketTypes clientPacket) { var packet = new PacketInfo(SenderPackets.Server, clientPacket, ServerPacketTypes.None_None); msg.WriteAllProperties(packet); }
public void WriteResponse(NetOutgoingMessage msg, PacketDataResponse packetData) { msg.Write((byte)PacketType.CreateProjectile); msg.Write(packetData.LocalId); msg.WriteAllProperties(packetData.ProjectileData); }
public static void Encode <T>(T objectToEncode, ref NetOutgoingMessage om) { om.WriteAllProperties(objectToEncode); }
private void newLogin() { //When a player logs in, we expect that he sends his character info to us. //Normally he would only send his username and password but because we aren't using a database model //We'll just create the users character in their own client. Maybe database example next time //FYI: The connecting player can manually specify the zone he wants to connect to, easily changed by just setting the property though //Create new instance of player then read all the properties the client has sent into this class Character newlyConnectedPlayer = new Character(); inc.ReadAllProperties(newlyConnectedPlayer); //If the player that is trying to connects' name already exists in our active player list //We will refuse his connection. This can be handy, if you want to allow only one character (obviously) or one //connection per IP Address, easy to modify if (ConnectedPlayers.FirstOrDefault(f => f.Name == newlyConnectedPlayer.Name) != null) { inc.SenderConnection.Deny("You're already connected"); Write("Refused player with name " + newlyConnectedPlayer.Name + " because he was already connected.."); // LET IT BE KNOWN! return; } //We give our player a connection property so we can keep connection info about him, like IP Address/ping, etc! newlyConnectedPlayer.Connection = inc.SenderConnection; //Let it be known that this player has connected to our wonderful game Write(newlyConnectedPlayer.Name + " has connected!"); //Approve this fine gentleman into our secret society inc.SenderConnection.Approve(); //Add this fine lad to the list of connected players ConnectedPlayers.Add(newlyConnectedPlayer); //Now it gets a little more interesting! //*~*~*~*~* (SPARKLES TO MAKE IT MORE MAGICAL!) *~*~*~*~* //Worldstate (Can specify a name yourself) messages send the current zone state to players NetOutgoingMessage outmsg = Server.CreateMessage(); //We create a new message outmsg.Write((byte)PacketTypes.WORLDSTATE); // Of type WORLDSTATE //Get the amount of players the zone the new player is in outmsg.Write(ConnectedPlayers.Where(f => f.CurrentZone == newlyConnectedPlayer.CurrentZone).Count()); //notice 'Count' //For each player in this players' zone, send him the data of the players. (The players' client will process this info and draw them on his screen) foreach (Character ch in ConnectedPlayers.Where(x => x.CurrentZone == newlyConnectedPlayer.CurrentZone)) { outmsg.WriteAllProperties(ch); } Server.SendMessage(outmsg, inc.SenderConnection, NetDeliveryMethod.ReliableOrdered, 0); // Send the message, reliably and ordered // LET IT BE KNOWN! Write(String.Format("{0} : {1} - has connected to the server and is in {2}", newlyConnectedPlayer.Name, newlyConnectedPlayer.Connection.RemoteEndpoint.Address, newlyConnectedPlayer.CurrentZone)); //Update our UI updateList(); }
public void Encode <T>(T objectToEncode, NetOutgoingMessage om) where T : class { om.WriteAllProperties(objectToEncode); }
static void Main(string[] args) { List <string> listNomJoueur = new List <string>(); char[] split = new char[';']; //Console.WriteLine("Entrez le lien du fichier de lecture de nom des joueurs"); //pathPourFichierLectureNom = Console.ReadLine(); // Create new instance of configs. Parameter is "application Id". It has to be same on client and server. Config = new NetPeerConfiguration("game"); // Set server port Config.Port = 5009; // Max client amount Config.MaximumConnections = 8; // Enable New messagetype. Explained later Config.EnableMessageType(NetIncomingMessageType.ConnectionApproval); // Create new server based on the configs just defined Server = new NetServer(Config); // Start it Server.Start(); // Eh.. Console.WriteLine("Server Started"); // Create list of "Characters" ( defined later in code ). This list holds the world state. Character positions List <JoueurConnection> GameWorldState = new List <JoueurConnection>(); // Object that can be used to store and read messages NetIncomingMessage inc; // Check time DateTime time = DateTime.Now; // Create timespan of 30ms TimeSpan timetopass = new TimeSpan(0, 0, 0, 0, 30); // Write to con.. Console.WriteLine("Waiting for new connections and updating world state to current ones"); // Main loop // This kind of loop can't be made in XNA. In there, its basically same, but without while // Or maybe it could be while(new messages) while (true) { // Server.ReadMessage() Returns new messages, that have not yet been read. // If "inc" is null -> ReadMessage returned null -> Its null, so dont do this :) if ((inc = Server.ReadMessage()) != null) { // Theres few different types of messages. To simplify this process, i left only 2 of em here switch (inc.MessageType) { // If incoming message is Request for connection approval // This is the very first packet/message that is sent from client // Here you can do new player initialisation stuff case NetIncomingMessageType.ConnectionApproval: // Read the first byte of the packet // ( Enums can be casted to bytes, so it be used to make bytes human readable ) if (inc.ReadByte() == (byte)PacketTypes.LOGIN) { Console.WriteLine("Incoming LOGIN"); // Approve clients connection ( Its sort of agreenment. "You can be my client and i will host you" ) inc.SenderConnection.Approve(); string nom = inc.ReadString() + (GameWorldState.Count + 1).ToString(); // Init random // Add new character to the game. // It adds new player to the list and stores name, ( that was sent from the client ) // Random x, y and stores client IP+Port //LECTEUR DE NOM //GameWorldState.Add(new JoueurConnection(listNomJoueur[positionDansFicher], inc.SenderConnection)); GameWorldState.Add(new JoueurConnection(nom, inc.SenderConnection)); // Create message, that can be written and sent NetOutgoingMessage outmsg = Server.CreateMessage(); // first we write byte outmsg.Write((byte)PacketTypes.WORLDSTATE); // then int outmsg.Write(GameWorldState.Count); // iterate trought every character ingame foreach (JoueurConnection joueur in GameWorldState) { // This is handy method // It writes all the properties of object to the packet outmsg.WriteAllProperties(joueur); } // Now, packet contains: // Byte = packet type // Int = how many players there is in game // character object * how many players is in game // Send message/packet to all connections, in reliably order, channel 0 // Reliably means, that each packet arrives in same order they were sent. Its slower than unreliable, but easyest to understand Server.SendMessage(outmsg, inc.SenderConnection, NetDeliveryMethod.ReliableOrdered, 0); // Debug Console.WriteLine("Approved new connection and updated the world status"); Console.WriteLine(nom); } break; // Data type is all messages manually sent from client // ( Approval is automated process ) case NetIncomingMessageType.Data: byte type = inc.ReadByte(); if (type == (byte)PacketTypes.STARTGAME) { foreach (JoueurConnection j in GameWorldState) { if (j.Connection != inc.SenderConnection) { continue; } NetOutgoingMessage outmsg = Server.CreateMessage(); outmsg.Write((byte)PacketTypes.STARTGAME); Server.SendMessage(outmsg, Server.Connections, NetDeliveryMethod.ReliableOrdered, 0); Console.WriteLine("La partie commmence"); break; } } if (type == (byte)PacketTypes.ENEMY) { foreach (JoueurConnection j in GameWorldState) { if (j.Connection != inc.SenderConnection) { continue; } NetOutgoingMessage outmsg = Server.CreateMessage(); outmsg.Write((byte)PacketTypes.ENEMY); int niveau = inc.ReadInt32(); outmsg.Write(niveau); Server.SendMessage(outmsg, Server.Connections, NetDeliveryMethod.ReliableOrdered, 0); Console.WriteLine("Un enemie niveau " + niveau.ToString() + " est envoyé"); break; } } break; case NetIncomingMessageType.StatusChanged: // In case status changed // It can be one of these // NetConnectionStatus.Connected; // NetConnectionStatus.Connecting; // NetConnectionStatus.Disconnected; // NetConnectionStatus.Disconnecting; // NetConnectionStatus.None; // NOTE: Disconnecting and Disconnected are not instant unless client is shutdown with disconnect() Console.WriteLine(inc.SenderConnection.ToString() + " status changed. " + (NetConnectionStatus)inc.SenderConnection.Status); if (inc.SenderConnection.Status == NetConnectionStatus.Disconnected || inc.SenderConnection.Status == NetConnectionStatus.Disconnecting) { // Find disconnected character and remove it foreach (JoueurConnection cha in GameWorldState) { if (cha.Connection == inc.SenderConnection) { GameWorldState.Remove(cha); Console.WriteLine(cha.Nom + " s'est déconnecté"); break; } } } break; default: // As i statet previously, theres few other kind of messages also, but i dont cover those in this example // Uncommenting next line, informs you, when ever some other kind of message is received //Console.WriteLine("Not Important Message"); break; } } // If New messages // if 30ms has passed if ((time + timetopass) < DateTime.Now) { // If there is even 1 client if (Server.ConnectionsCount != 0) { // Create new message NetOutgoingMessage outmsg = Server.CreateMessage(); // Write byte outmsg.Write((byte)PacketTypes.WORLDSTATE); // Write Int outmsg.Write(GameWorldState.Count); // Iterate throught all the players in game foreach (JoueurConnection ch2 in GameWorldState) { // Write all properties of character, to the message outmsg.WriteAllProperties(ch2); } // Message contains // byte = Type // Int = Player count // Character obj * Player count // Send messsage to clients ( All connections, in reliable order, channel 0) Server.SendMessage(outmsg, Server.Connections, NetDeliveryMethod.ReliableOrdered, 0); } // Update current time time = DateTime.Now; } // While loops run as fast as your computer lets. While(true) can lock your computer up. Even 1ms sleep, lets other programs have piece of your CPU time //System.Threading.Thread.Sleep(1); } }
public void WriteResponse(NetOutgoingMessage msg, PacketDataResponse packetData) { msg.Write((byte)PacketType.NewPlayer); msg.WriteAllProperties(packetData.Player); }
static void Main() { LogManager.Initialize(); // Create new instance of configs. Parameter is "application Id". It has to be same on client and server. Config = new NetPeerConfiguration("game"); // Set server port int port = Convert.ToInt32(ConfigurationManager.AppSettings["port"]); Config.Port = port; Console.WriteLine("Server port : " + port); // Max client amount Config.MaximumConnections = 200; // Enable New messagetype. Explained later Config.EnableMessageType(NetIncomingMessageType.ConnectionApproval); // Create new server based on the configs just defined Server = new NetServer(Config); // Start it Server.Start(); // Eh.. Console.WriteLine("Server Started"); // Create list of "Characters" ( defined later in code ). This list holds the world state. Character positions List <Character> GameWorldState = new List <Character>(); // Object that can be used to store and read messages NetIncomingMessage inc; // Check time DateTime time = DateTime.Now; // Create timespan of 30ms TimeSpan timetopass = new TimeSpan(0, 0, 0, 0, 30); // Write to con.. Console.WriteLine("Waiting for new connections and updateing world state to current ones"); // Main loop // This kind of loop can't be made in XNA. In there, its basically same, but without while // Or maybe it could be while(new messages) while (true) { // Server.ReadMessage() Returns new messages, that have not yet been read. // If "inc" is null -> ReadMessage returned null -> Its null, so dont do this :) if ((inc = Server.ReadMessage()) != null) { // Theres few different types of messages. To simplify this process, i left only 2 of em here switch (inc.MessageType) { // If incoming message is Request for connection approval // This is the very first packet/message that is sent from client // Here you can do new player initialisation stuff case NetIncomingMessageType.ConnectionApproval: // Read the first byte of the packet // ( Enums can be casted to bytes, so it be used to make bytes human readable ) if (inc.ReadByte() == (byte)PacketTypes.LOGIN) { Console.WriteLine("Incoming LOGIN"); // Approve clients connection ( Its sort of agreenment. "You can be my client and i will host you" ) inc.SenderConnection.Approve(); // Init random Random r = new Random(); // Add new character to the game. // It adds new player to the list and stores name, ( that was sent from the client ) // Random x, y and stores client IP+Port GameWorldState.Add(new Character(inc.ReadString(), 0, 0, inc.SenderConnection)); // Create message, that can be written and sent NetOutgoingMessage outmsg = Server.CreateMessage(); // first we write byte outmsg.Write((byte)PacketTypes.WORLDSTATE); // then int outmsg.Write(GameWorldState.Count); // iterate trought every character ingame foreach (Character ch in GameWorldState) { // This is handy method // It writes all the properties of object to the packet outmsg.WriteAllProperties(ch); } // Now, packet contains: // Byte = packet type // Int = how many players there is in game // character object * how many players is in game // Send message/packet to all connections, in reliably order, channel 0 // Reliably means, that each packet arrives in same order they were sent. Its slower than unreliable, but easyest to understand Server.SendMessage(outmsg, inc.SenderConnection, NetDeliveryMethod.ReliableOrdered, 0); // Debug Console.WriteLine("Approved new connection and updated the world status"); } break; // Data type is all messages manually sent from client // ( Approval is automated process ) case NetIncomingMessageType.Data: // Read first byte if (inc.ReadByte() == (byte)PacketTypes.MOVE) { // Check who sent the message // This way we know, what character belongs to message sender foreach (Character ch in GameWorldState) { // If stored connection ( check approved message. We stored ip+port there, to character obj ) // Find the correct character if (ch.Connection != inc.SenderConnection) { continue; } // Read next byte byte b = inc.ReadByte(); // Handle movement. This byte should correspond to some direction if ((byte)MoveDirection.UP == b) { ch.X++; //ch.Y--; } if ((byte)MoveDirection.DOWN == b) { ch.X++; //ch.Y++; } if ((byte)MoveDirection.LEFT == b) { ch.X++; //ch.X--; } if ((byte)MoveDirection.RIGHT == b) { ch.X++; //ch.X++; } // Create new message NetOutgoingMessage outmsg = Server.CreateMessage(); // Write byte, that is type of world state outmsg.Write((byte)PacketTypes.WORLDSTATE); // Write int, "how many players in game?" outmsg.Write(GameWorldState.Count); // Iterate throught all the players in game foreach (Character ch2 in GameWorldState) { // Write all the properties of object to message outmsg.WriteAllProperties(ch2); } // Message contains // Byte = PacketType // Int = Player count // Character obj * Player count // Send messsage to clients ( All connections, in reliable order, channel 0) Server.SendMessage(outmsg, Server.Connections, NetDeliveryMethod.ReliableOrdered, 0); break; } } break; case NetIncomingMessageType.StatusChanged: // In case status changed // It can be one of these // NetConnectionStatus.Connected; // NetConnectionStatus.Connecting; // NetConnectionStatus.Disconnected; // NetConnectionStatus.Disconnecting; // NetConnectionStatus.None; // NOTE: Disconnecting and Disconnected are not instant unless client is shutdown with disconnect() Console.WriteLine(inc.SenderConnection.ToString() + " status changed. " + (NetConnectionStatus)inc.SenderConnection.Status); if (inc.SenderConnection.Status == NetConnectionStatus.Disconnected || inc.SenderConnection.Status == NetConnectionStatus.Disconnecting) { // Find disconnected character and remove it foreach (Character cha in GameWorldState) { if (cha.Connection == inc.SenderConnection) { GameWorldState.Remove(cha); break; } } } break; default: // As i statet previously, theres few other kind of messages also, but i dont cover those in this example // Uncommenting next line, informs you, when ever some other kind of message is received //Console.WriteLine("Not Important Message"); break; } } // If New messages // if 30ms has passed if ((time + timetopass) < DateTime.Now) { // If there is even 1 client if (Server.ConnectionsCount != 0) { // Create new message NetOutgoingMessage outmsg = Server.CreateMessage(); // Write byte outmsg.Write((byte)PacketTypes.WORLDSTATE); // Write Int outmsg.Write(GameWorldState.Count); // Iterate throught all the players in game foreach (Character ch2 in GameWorldState) { // Write all properties of character, to the message outmsg.WriteAllProperties(ch2); } // Message contains // byte = Type // Int = Player count // Character obj * Player count // Send messsage to clients ( All connections, in reliable order, channel 0) Server.SendMessage(outmsg, Server.Connections, NetDeliveryMethod.ReliableOrdered, 0); } // Update current time time = DateTime.Now; } // While loops run as fast as your computer lets. While(true) can lock your computer up. Even 1ms sleep, lets other programs have piece of your CPU time //System.Threading.Thread.Sleep(1); } }
/// <summary> /// Writes the player to a outgoing net message. /// </summary> /// <param name="msg"></param> public void writeToMessage(NetOutgoingMessage msg) { msg.WriteAllProperties(this); return; }