Exemple #1
0
        /// <summary>
        /// Creates a network message by decoding a NetMessage
        /// </summary>
        /// <param name="msg">The NetMessage to be decoded</param>
        public SpiderMessage(NetMessage msg)
        {
            //This is the exception we throw if something goes wrong
            Exception e = new Exception("Could not read message");

            byte[] contents = msg.ReadBytes(msg.Length);
            type = (SpiderMessageType)contents[0];
            int dataOffset = BitConverter.ToInt32(contents, 1);
            label = Encoding.UTF8.GetString(contents, 1 + sizeof(int), dataOffset - 1 - sizeof(int));

            senderIP = msg.Sender.RemoteEndpoint.Address;
            connection = msg.Sender;

            if (type == SpiderMessageType.Bytes) {
                data = new byte[contents.Length - dataOffset];
                for (int i = 0; i < contents.Length - dataOffset; i++) {
                    ((byte[])data)[i] = contents[i + dataOffset];
                }
            }
            else {
                String tempData = Encoding.UTF8.GetString(contents, dataOffset, contents.Length - dataOffset);
                switch (type) {
                    case SpiderMessageType.Double:
                        data = Convert.ToDouble(tempData);
                        break;
                    case SpiderMessageType.Int:
                        data = Convert.ToInt32(tempData);
                        break;
                    default:
                        data = tempData;
                        break;
                }
            }
        }
Exemple #2
0
 // Broadcast a message to logged in players, except the id player (if id = -1, no player is ignored)
 public void BroadcastMsgExcept(NetMessage msg, NetChannel channel, int id)
 {
    IDictionaryEnumerator en = PList.GetPlayerEnum();
    while (en.MoveNext())
    {
       if (((Player)en.Value).Carac.ActorID != id)
          Server.SendMessage(msg, ((Player)en.Value).Connection, channel);
    }
 }
		/// <summary>
		/// Reuses the string table index
		/// </summary>
		public int Rewrite(NetMessage msg, int idx, string str)
		{
			while (m_data.Count < idx - 1)
				m_data.Add(null); // dummy values

			m_data[idx] = str;
			msg.Write(false);
			msg.Write7BitEncodedUInt((uint)idx);
			msg.Write(str);
			return idx;
		}
Exemple #4
0
      // Serialization / Deserialization
      public NetMessage GetNetMessage()
      {
         MemoryStream s = new MemoryStream();
         BinaryFormatter b = new BinaryFormatter();
         b.Serialize(s, this);
         // WAY TOO BIG !!
         NetMessage netmsg = new NetMessage();
         s.Capacity = (int)s.Length;
         netmsg.Write(s.GetBuffer());

         return netmsg;
      }
Exemple #5
0
 void StatusChanged(object sender, NetStatusEventArgs e)
 {
     // e.Connection is the connection for which status changed
     // e.Connectionn.Status is the new status
     // e.Reason is a human readable reason for the status change
     if (e.Connection.Status == NetConnectionStatus.Connected)
     {
         System.Console.WriteLine("Status: " + e.Connection.Status.ToString());
         NetMessage outMsg = new NetMessage();
         //Client.SendMessage(outMsg, NetChannel.ReliableUnordered); // <- for example
     }
 }
		public int RelateToExpected(NetMessage msg)
		{
			int expected = m_expectedSequenceNumbers[(int)msg.SequenceChannel];
			int diff = msg.SequenceNumber - expected;
			if (diff == 0)
				return 0; // early out
			// is a message so far behind that it's actually wrapped and early?
			if (diff < (NetConstants.EarlyArrivalWindowSize - NetConstants.NumSequenceNumbers))
				diff += NetConstants.NumSequenceNumbers;
			// is a message so far ahead that it's actually wrapped and late?
			else if (diff > NetConstants.EarlyArrivalWindowSize)
				diff -= NetConstants.NumSequenceNumbers;
			return diff;
		}
		/// <summary>
		/// Returns encoded index
		/// </summary>
		public int Write(NetMessage msg, string str)
		{
			int idx = m_data.IndexOf(str);
			if (idx == -1)
			{
				idx = m_data.Count;
				m_data.Add(str);

				msg.Write(false);
				msg.Write7BitEncodedUInt((uint)idx);
				msg.Write(str);
				return idx;
			}
			msg.Write(true);
			msg.Write7BitEncodedUInt((uint)idx);
			return idx;
		}
		public string Read(NetMessage msg)
		{
			bool encoded = msg.ReadBoolean();
			int idx = (int)msg.Read7BitEncodedUInt();
			string retval;
			if (!encoded)
			{
				// insert into table
				retval = msg.ReadString();
				while(m_data.Count <= idx)
					m_data.Add(null); // dummy values
				m_data[idx] = retval;
				return retval;
			}

			// look in table
			if (m_data.Count <= idx)
				return null;
			return m_data[idx];
		}
Exemple #9
0
		internal void HandlePong(double now, NetMessage pongMessage)
		{
			int nr = pongMessage.ReadByte(6);
			if (nr != m_pingNrInProgress)
			{
				m_connection.Parent.Log.Warning("Pong received for wrong ping; received " + nr + " expecting " + m_pingNrInProgress);
				return;
			}
			double roundtrip = now - m_lastSentPing;

			// spike, or can we use this roundtrip?
			double avgRT = pongMessage.Sender.AverageRoundtripTime;
			if (roundtrip > avgRT * 2.0)
			{
				// must be spike
				m_connection.Parent.Log.Verbose("Not adjusting clock due lag spike... (rt " + NetUtil.SecToMil(roundtrip) + " avg " + NetUtil.SecToMil(avgRT) + ")");
			}
			else
			{
				ushort val = pongMessage.ReadUInt16();
				int curOffset = m_connection.RemoteClockOffset;
				int foundOffset = NetTime.CalculateOffset(now, val, roundtrip);

				int res = NetTime.MergeOffsets(curOffset, foundOffset);

				int rtMillis = (int)(roundtrip * 1000.0);
				if (res != curOffset)
				{
					//m_connection.Parent.Log.Verbose("Ping: " + rtMillis + " Local: " + NetTime.Encoded(now) + " CurOffset: " + curOffset + " Remote: " + val + " NewOffset: " + res + " (adjusted " + (res - curOffset) + ")");
					m_connection.Parent.Log.Verbose("Roundtrip: " + rtMillis + " ms; Ajusted remote offset " + (res - curOffset) + " ms");
					m_connection.RemoteClockOffset = res;
				}
			}

			AddRoundtrip((float)roundtrip);

			if (m_connection.Parent is NetServer)
			{
				// server is authorative on settings optimizing roundtrip numbers
				m_connection.Configuration.OptimizeSettings(m_averageRoundtrip);
				SendOptimizeInfo(m_averageRoundtrip);
			}

			return;
		}
Exemple #10
0
		internal static void ReplyPong(NetMessage pingMessage, NetConnection connection)
		{
			byte nr = pingMessage.ReadByte(6);

			NetMessage pong = new NetMessage(NetMessageType.PingPong, 3);
			pong.Write(true); // means pong
			pong.Write(false); // means NOT optimize info
			pong.Write(nr, 6);
			pong.WriteSendStamp();
			connection.Parent.SendSingleMessageAtOnce(pong, connection, connection.RemoteEndpoint);
		}
      public void HandleMessage(NetMessage netmsg)
      {
         BBMessage msg;

         // We received a message 
         Log.Debug("msg: " + netmsg);

         try
         {
            msg = BBMessage.FromNetMessage(netmsg);
         }
         catch (Exception ex)
         {
            Log.Error("Deserialization error : " + ex.Message);
            return;
         }

         Log.Debug("msg: " + System.Enum.GetName(typeof(BBMsgType), msg.MsgType));

         switch (msg.MsgType)
         {
            case BBMsgType.NO_LOGIN:
               OutputSystemText("Login refused ! Reason : " + msg.Param1, msg);
               break;

            case BBMsgType.OK_LOGIN:
               OutputSystemText("Login accepted ! ID is : " + msg.PlayerCarac.ActorID, msg);
               OurID = msg.PlayerCarac.ActorID;
               PList.AddPlayer(msg.PlayerCarac, null, null);
               this.OnUserConnection(msg.PlayerCarac, false);
               break;

            case BBMsgType.VDM:
               this.MessageChat(msg, false);
               if ((!string.IsNullOrEmpty(msg.Message)) && (msg.Param2))
                  this.OnVDMActivated();
               break;
            case BBMsgType.BASH:
               this.MessageChat(msg, false);
               if (!string.IsNullOrEmpty(msg.Message))
                  this.OnBASHActivated();
               break;
            case BBMsgType.PENDU:
               this.MessageChat(msg, false);
               if (msg.Param2)
                  this.OnStartPenduNewWord();
               break;
            case BBMsgType.CHAT:
               this.MessageChat(msg, true);
               break;
            case BBMsgType.TYPING_MSG:
               this.OnUserTyping(PList.GetPlayer(msg.ActorInfo.Id).Carac, msg.Conversation, msg.Param2);
               break;

            case BBMsgType.ADD_PLAYER:
               // Add the player to our player list
               PList.AddPlayer(msg.PlayerCarac, msg.ActorInfo, null);
               this.OnUserConnection(msg.PlayerCarac, msg.Param2);
               //MainForm.UserConnect(msg.PlayerCarac.Nick, msg.Param2);
               if (msg.Param2 == true)
               {
                  Log.Info("Player " + msg.PlayerCarac.Nick + " connected.");
               }
               break;
            case BBMsgType.DEL_PLAYER:
               Log.Info("Player " + PList.GetPlayer(msg.PlayerCarac.ActorID).Carac.Nick + " disconnected. Reason : " + msg.Param1);
               //MainForm.UserDisconnect(PList.GetPlayer(msg.PlayerCarac.ActorID).Carac.Nick, msg.Param1);
               this.OnUserDisconnection(PList.GetPlayer(msg.PlayerCarac.ActorID).Carac, msg.Param1);
               PList.DelPlayer(msg.PlayerCarac.ActorID);
               break;

            case BBMsgType.ACTOR_SHOOT:
               Shooted(msg);
               break;

            case BBMsgType.ACTOR_SHOOT_RESPONSE:
               ShootResponsed(msg);
               break;

            case BBMsgType.KNOCK:
               if (msg.Param3 == OurID)
                  this.OnUserKnocked();
               OutputSystemText(PList.GetPlayer(msg.ActorInfo.Id).Carac.Nick + " knocked on " + PList.GetPlayer(msg.Param3).Carac.Nick + "'s door.", msg);
               break;
            case BBMsgType.COFFEE:
               if (msg.Param3 == OurID)
                  this.OnUserCoffee();
               //ShowInfoBalloon("Crying tears...", "Go Coffee...");
               OutputSystemText(PList.GetPlayer(msg.ActorInfo.Id).Carac.Nick + " invites " + PList.GetPlayer(msg.Param3).Carac.Nick + " to go to coffee", msg);
               break;
            case BBMsgType.EAT:
               if (msg.Param3 == OurID)
                  this.OnUserEat();
               //ShowInfoBalloon("Hungry", "Go to eat...");
               OutputSystemText(PList.GetPlayer(msg.ActorInfo.Id).Carac.Nick + " invites " + PList.GetPlayer(msg.Param3).Carac.Nick + " to go to eat", msg);
               break;
            case BBMsgType.JOIN_CONVERSATION:
               // Add the player to our player list 
               if (this.IsPartOfConversation(msg.Conversation))
               {
                  this.OnSendingSystemMessage("Player " + msg.PlayerCarac.Nick + " joined the conversation.", msg);
               }
               break;
            case BBMsgType.LEAVE_CONVERSATION:
               // Add the player to our player list  
               if (this.IsPartOfConversation(msg.Conversation))
               {
                  this.OnSendingSystemMessage(PList.GetPlayer(msg.PlayerCarac.ActorID).Carac.Nick + " leaved the conversation.", msg);
               }
               break;
            case BBMsgType.PRIVATE_MESSAGE:
               {
                  if (this.IsPartOfConversation(msg.Conversation))
                  {
                     string nick;
                     Color color;
                     if (msg.ActorInfo.Id != -1)
                     {
                        nick = PList.GetPlayer(msg.ActorInfo.Id).Carac.Nick;
                        color = PList.GetPlayer(msg.ActorInfo.Id).Carac.TextColor;
                     }
                     else
                     {
                        nick = "";
                        color = Color.Black; // Whatever
                     }

                     this.OnSendingMessage(msg);
                     //MainForm.AppendChatMsgBBMessage(msg, msg.Param1, nick, color, msg.Conversation.ConversID.ToString());

                     // Notify the user
                     OnNotifyMessage();
                  }
                  break;
               }
            case BBMsgType.PRIVATE_CONVERSATION:
               //ShowInfoBalloon("Conversation privée");
               break;
         }
      }
        private void SendInput(string Input)
        {
            if (client != null)
            {
                GameState++;
                NetMessage msg = new NetMessage(); ;
                msg.Write(Input);

                //Sending the packet in Reliable is okay for this because its
                //one packet, When sending lots and lots of data you need to
                //set this to Unreliable. This will garentee it arrives but
                //not in a sepcific order.
                client.SendMessage(msg, NetChannel.Unreliable);
            }
        }
		internal void ReceiveMessage(double now, NetMessage msg)
		{
			// reject duplicates and late sequenced messages
			bool rejectMessage, ackMessage, withholdMessage;
			m_sequenceHandler.AddSequence(msg, out rejectMessage, out ackMessage, out withholdMessage);

			if (ackMessage)
			{
				if (m_unsentAcknowledges.Count <= 0)
					m_forceExplicitAckTime = m_lastHeardFromRemote + Configuration.ForceExplicitAckDelay;
				m_unsentAcknowledges.Enqueue(msg);
			}

			if (rejectMessage)
			{
				m_parent.Log.Debug("Message rejected: " + msg);
				return;
			}

			if (withholdMessage)
			{
				//m_parent.Log.Debug("Message withheld: " + msg);
				m_withheldMessages.Add(msg);
				return;
			}

			ReleaseMessageToApplication(msg);

			// enqueue any currently withheld messages?
			int cnt = m_withheldMessages.Count;
			if (cnt > 0)
			{
			WithheldChecking:
				for (int i = 0; i < cnt; i++)
				{
					NetMessage withheld = m_withheldMessages[i];
					if (withheld.SequenceChannel == msg.SequenceChannel)
					{
						if (m_sequenceHandler.RelateToExpected(withheld) == 0)
						{
							m_withheldMessages.Remove(withheld);
							
							//m_receivedMessages.Enqueue(withheld);
							ReleaseMessageToApplication(withheld);

							// advance expected
							m_sequenceHandler.AdvanceExpected(withheld.SequenceChannel, 1);

							cnt = m_withheldMessages.Count;
							goto WithheldChecking; // restart to check entire list
						}
					}
				}
			}
		}
		internal NetConnection(NetBase parent, IPEndPoint remote)
		{
			m_parent = parent;
			m_remoteEndpoint = remote;
			m_nextSequenceNumber = new ushort[NetConstants.NumSequenceChannels];
			m_sequenceHandler = new NetSequenceHandler();
			m_unsentMessages = new Queue<NetMessage>(10);
			m_receivedMessages = new Queue<NetMessage>(10);
			m_withheldMessages = new List<NetMessage>();
			m_unsentAcknowledges = new Queue<NetMessage>(10);
			m_lastHeardFromRemote = (float)NetTime.Now;
			m_reusedAckMessage = new NetMessage(NetMessageType.Acknowledge, null);
			m_savedReliableMessages = new List<NetMessage>[NetConstants.NumSequenceChannels];
			Configuration = new NetConnectionConfiguration(this);
			m_ping = new NetPing(this);
			Statistics = new NetStatistics(this);
			m_stringTable = new NetStringTable();
			m_encryption = new NetEncryption();
			if (parent.Configuration.UsesEncryption)
				m_encryption.SetRSAKey(parent.Configuration.ServerPublicKeyBytes, parent.Configuration.ServerPrivateKeyBytes);
		}
Exemple #15
0
 public bool Send(String msg)
 {
     NetMessage outMsg = new NetMessage();
     outMsg.Write(msg);
     return MMOServer.Server.SendMessage(outMsg, m_connection, NetChannel.ReliableUnordered);
 }
        void client_StatusChanged(object sender, NetStatusEventArgs e)
        {
            if (e.Connection.Status == NetConnectionStatus.Connected)
            {
                NetMessage msg = new NetMessage();
                msg.Write("Hello Server! I Am Connected And Able To Communicate!");
                client.SendMessage(msg, NetChannel.ReliableUnordered);

            }
            if (e.Connection.Status == NetConnectionStatus.Disconnected)
            {
                this.Window.Title = "We Were disconnected";
            }
        }
        private void SendGameState(NetConnection Conn)
        {
            GameState++;
            NetMessage msg = new NetMessage();
            string Message = "P" + Player.Location.X + "," + Player.Location.Y;
            Message = Message + "P";

            foreach (Zombie Zombie in Zombies)
            {
                Message = Message + "Z" + Zombie.Location.X + "," + Zombie.Location.Y;
            }
            Message = Message + "P";

            foreach (Bullet Bullet in Bullets)
            {
                Message = Message + "B" + Bullet.Location.X + "," + Bullet.Location.Y;
            }
            msg.Write(Message);

            //Sending the packet in Reliable is okay for this because its
            //one packet, When sending lots and lots of data you need to
            //set this to Unreliable. This will garentee it arrives but
            //not in a sepcific order.

            server.SendMessage(msg, Conn, NetChannel.Unreliable);
        }
		private void ReleaseMessageToApplication(NetMessage msg)
		{
			//m_parent.Log.Debug("Releasing message: " + msg);
			if (msg.m_type == NetMessageType.UserFragmented)
			{
				// fragmented; check id, check for completeness, withhold incomplete

				int fragDataLen = msg.Length - 5;
				byte fid = msg.m_buffer.Data[0];
				int totalFragments = msg.m_buffer.Data[1] + (msg.m_buffer.Data[2] << 8);
				int thisFragment = msg.m_buffer.Data[3] + (msg.m_buffer.Data[4] << 8);

				if (totalFragments <= 0 || thisFragment >= totalFragments)
				{
					// just drop it
					m_parent.Log.Warning("Bad message fragment; " + thisFragment + " of " + totalFragments);
					return;
				}

				//m_parent.Log.Debug("Received fragment id " + fid + "; fragment " + thisFragment + " of " + totalFragments + " size: " + fragDataLen);

				if (m_incompleteMessages[fid] == null)
				{
					//
					// new fragments assembly detected
					//

					if (thisFragment == totalFragments - 1)
					{
						// Ouch! We received the LAST fragment FIRST, so we are unable
						// to determine a correct splitsize...
						return; // TODO FIX THIS
					}

					m_incompleteMessages[fid] = new NetMessage(NetMessageType.User, totalFragments * fragDataLen);
					m_incompleteSplitSize[fid] = fragDataLen;

					// clear next slot; we don't want any broken (by loss) fragmented unreliable message mess
					// up the next assembly
					int nextFid = (fid + 1) % 256;
					m_incompleteMessages[nextFid] = null;
					m_incompleteFragmentsReceived[nextFid] = 0;
					m_incompleteTotalBytes[nextFid] = 0;
				}

				Buffer.BlockCopy(msg.m_buffer.Data, 5, m_incompleteMessages[fid].m_buffer.Data, thisFragment * m_incompleteSplitSize[fid], fragDataLen);
				m_incompleteFragmentsReceived[fid]++;
				m_incompleteTotalBytes[fid] += fragDataLen;

				if (m_incompleteFragmentsReceived[fid] == totalFragments)
				{
					// Whee, it's complete! Pass it on to the application
					NetConnection tmp = msg.Sender;
					msg = m_incompleteMessages[fid];
					msg.Sender = tmp;
					msg.m_buffer.LengthBits = m_incompleteTotalBytes[fid] * 8;
					m_incompleteMessages[fid] = null;
					m_incompleteFragmentsReceived[fid] = 0;
					m_incompleteTotalBytes[fid] = 0;
					//m_parent.Log.Debug("Fragmented message complete!");
				}
				else
				{
					// not done yet
					return;
				}
			}

			m_receivedMessages.Enqueue(msg);
		}
        void server_StatusChanged(object sender, NetStatusEventArgs e)
        {
            if (e.Connection.Status == NetConnectionStatus.Connecting)
            {
                NetMessage msg = new NetMessage();
                msg.Write("Hello Client, I See you are able to talk to me," +
                    " I Can Talk to you Too!");

                //Sending the packet in Reliable is okay for this because its
                //one packet, When sending lots and lots of data you need to
                //set this to Unreliable. This will garentee it arrives but
                //not in a sepcific order.
                server.SendMessage(msg, e.Connection, NetChannel.ReliableUnordered);

            }
            if (e.Connection.Status == NetConnectionStatus.Disconnected)
            {
                this.Window.Title = "Client Has Disconnected to You";
            }
        }
		internal void ReceiveAcknowledge(NetMessage msg)
		{
			// todo: optimize
			int seqChan = (int)msg.SequenceChannel;
			ushort seqNr = msg.SequenceNumber;

			if (m_savedReliableMessages[seqChan] == null)
				m_savedReliableMessages[seqChan] = new List<NetMessage>();

			List<NetMessage> list = m_savedReliableMessages[seqChan];
			foreach(NetMessage fm in list)
			{
				if (fm.SequenceNumber == seqNr)
				{
					if (MessageAcknowledged != null)
						MessageAcknowledged(this, new NetMessageEventArgs(fm));

					//m_parent.Log.Debug("Stored message acked and removed: " + msg.SequenceChannel + "|" + msg.SequenceNumber);
					m_savedReliableMessages[seqChan].Remove(fm);

					return;
				}
			}

			m_parent.Log.Verbose("Failed to find " + msg.SequenceChannel + "|" + msg.SequenceNumber + " in saved list; probably double acked");
		}
		public void AddSequence(NetMessage msg, out bool rejectMessage, out bool ackMessage, out bool withholdMessage)
		{
			int seqChan = (int)msg.SequenceChannel;
			int seqNr = msg.SequenceNumber;

			ackMessage = (seqChan >= (int)NetChannel.ReliableUnordered);
			
			int offset = seqChan * NetConstants.NumKeptDuplicateNumbers;
			int end = offset + NetConstants.NumKeptDuplicateNumbers;
			for (int i = offset; i < end; i++)
			{
				if (m_receivedSequences[i] == seqNr)
				{
					// duplicate
					NetBase.CurrentContext.Log.Debug("Duplicate message " + msg + " detected and dropped; already contained in slot " + (i - offset));
					rejectMessage = true;
					withholdMessage = false;
					return;
				}
			}

			//NetBase.CurrentContext.Log.Verbose("Unique message " + msg + " found");

			// not duplicate; add!
			m_receivedSequences[offset + m_receivedPtr[seqChan]] = seqNr;
			m_receivedPtr[seqChan]++;
			if (m_receivedPtr[seqChan] >= NetConstants.NumKeptDuplicateNumbers)
				m_receivedPtr[seqChan] = 0;

			// unreliable?
			if (msg.SequenceChannel == NetChannel.Unreliable)
			{
				rejectMessage = false;
				withholdMessage = false;
				return;
			}

			int rel = RelateToExpected(msg);

			// sequenced?
			if (seqChan >= (int)NetChannel.Sequenced1 && seqChan <= (int)NetChannel.Sequenced15)
			{
				// late messages rejected if sequenced
				if (rel < 0)
				{
					NetBase.CurrentContext.Log.Debug("Late sequenced message " + msg.SequenceChannel + "|" + msg.SequenceNumber + " detected and dropped; expected " + m_expectedSequenceNumbers[seqChan] + " got " + msg.SequenceNumber);
					rejectMessage = true;
				}
				else
				{
					m_expectedSequenceNumbers[seqChan] = (m_expectedSequenceNumbers[seqChan] + rel + 1) % NetConstants.NumSequenceNumbers;
					rejectMessage = false;
				}
				withholdMessage = false;
				return;
			}

			// reliable unordered?
			if (msg.SequenceChannel == NetChannel.ReliableUnordered)
			{
				rejectMessage = false;
				withholdMessage = false;
				return;
			}

			// ordered

			if (rel > 0)
			{
				// early
				int expected = m_expectedSequenceNumbers[(int)msg.SequenceChannel];
				//NetBase.CurrentContext.Log.Debug("Received early message (" + msg.SequenceChannel + "|" + msg.SequenceNumber + ", expecting " + expected + ")");
				withholdMessage = true;
			}
			else if (rel == 0)
			{
				// on time!
				AdvanceExpected(msg.SequenceChannel, 1);
				withholdMessage = false;
			}
			else
			{
				// late, shouldn't happen!
				int expected = m_expectedSequenceNumbers[(int)msg.SequenceChannel];
				NetBase.CurrentContext.Log.Warning("Late ordered message " + msg + " received?! expecting " + expected + " received " + msg.SequenceNumber + " rel " + rel);
				withholdMessage = true;
			}
			
			rejectMessage = false;
			return;
		}
		public void AssignSequenceNumber(NetMessage msg, NetChannel channel)
		{
			if (msg == null)
				throw new ArgumentNullException("msg");
			int chanNr = (int)channel;
			lock (m_nextSequenceNumber)
			{
				msg.SequenceChannel = channel;
				msg.SequenceNumber = m_nextSequenceNumber[chanNr]++;
				if (m_nextSequenceNumber[chanNr] >= NetConstants.NumSequenceNumbers)
					m_nextSequenceNumber[chanNr] = 0;
			}
			return;
		}
Exemple #23
0
 /// <summary>
 /// Sends the given message using the given UDP delivery type.  A client will send to the server, a server will broadcast.
 /// </summary>
 /// <param name="message">The message to be sent</param>
 /// <param name="deliveryType">The UDP delivery type</param>
 public void SendMessage(SpiderMessage message, NetChannel deliveryType)
 {
     NetMessage msg = new NetMessage();
     msg.Write(message.ToByteArray());
     spiderNet.SendMessage(msg, deliveryType);
 }
		internal void SendMessage(NetMessage msg, NetChannel channel)
		{
			if (msg.Length > m_parent.Configuration.MaximumTransmissionUnit)
			{
				// fragment large message
				int totlen = msg.Length;
				int splitSize = m_parent.Configuration.MaximumTransmissionUnit - 13; // todo: research this number
				int numFragments = totlen / splitSize;
				if (numFragments * splitSize < totlen)
					numFragments++;
				
				byte hdr1 = (byte)numFragments;
				byte hdr2 = (byte)(numFragments >> 8);

				int ptr = 0;
				for (int i = 0; i < numFragments; i++)
				{
					int numBytes = msg.Length - ptr;
					if (numBytes > splitSize)
						numBytes = splitSize;
					byte[] fragmentData = new byte[5 + numBytes];
					fragmentData[0] = m_nextFragmentAssemblyId;
					fragmentData[1] = hdr1;
					fragmentData[2] = hdr2;
					fragmentData[3] = (byte)i;
					fragmentData[4] = (byte)(i >> 8);
					Buffer.BlockCopy(msg.m_buffer.Data, ptr, fragmentData, 5, numBytes);

					// send fragment
					NetMessage fragment = new NetMessage(NetMessageType.UserFragmented, fragmentData);
					SendMessage(fragment, channel);

					ptr += numBytes;
				}
				//m_parent.Log.Debug("Sent " + numFragments + " fragments, " + splitSize + " bytes per fragment = " + totlen);
				m_nextFragmentAssemblyId++;
				return;
			}

			msg.SequenceChannel = channel;
			AssignSequenceNumber(msg, channel);
			m_unsentMessages.Enqueue(msg);
		}
Exemple #25
0
		internal void SendOptimizeInfo(float roundtrip)
		{
			NetMessage ping = new NetMessage(NetMessageType.PingPong, 3);
			ping.Write(false); // meaningless
			ping.Write(true); // means optimize info
			ping.Write7BitEncodedUInt((uint)(roundtrip * 1000.0f));
			m_connection.SendMessage(ping, NetChannel.Unreliable);
		}
		public NetMessageEventArgs(NetMessage msg)
		{
			Message = msg;
		}
Exemple #27
0
		internal void HandleOptimizeInfo(double now, NetMessage pongMessage)
		{
			float optimizeMillis = (float)pongMessage.Read7BitEncodedUInt();
			m_connection.Configuration.OptimizeSettings(optimizeMillis / 1000.0f);
		}
 public void ClientHandleMSG(NetMessage msg)
 {
     string str = msg.ReadString();
     if (str.StartsWith("P"))
     {
         RecievedGameState(str);
     }
 }
Exemple #29
0
		internal void SendPing(double now)
		{
			m_pingNrInProgress++;
			if (m_pingNrInProgress > 63)
				m_pingNrInProgress = 0;
			NetMessage ping = new NetMessage(NetMessageType.PingPong, 1);
			ping.Write(false); // means ping
			ping.Write(false); // means NOT optimize info
			ping.Write((byte)m_pingNrInProgress, 6);

			m_connection.Parent.SendSingleMessageAtOnce(ping, m_connection, m_connection.RemoteEndpoint);
			m_lastSentPing = now;
		}
 public void ServerHandleMSG(NetMessage msg)
 {
     string str = msg.ReadString();
     MovePlayer(str);
 }