Ejemplo n.º 1
0
 protected abstract void WriteEvent(IWriteMessage buffer, NetEntityEvent entityEvent, Client recipient = null);
 public void ServerWriteSpawn(IWriteMessage msg)
 {
     msg.Write(Prefab.Identifier);
     msg.Write(Offset.X);
     msg.Write(Offset.Y);
 }
Ejemplo n.º 3
0
        public override void Send(IWriteMessage msg, DeliveryMethod deliveryMethod)
        {
            if (!isActive)
            {
                return;
            }

            byte[] buf = new byte[msg.LengthBytes + 4];
            buf[0] = (byte)deliveryMethod;

            byte[] bufAux = new byte[msg.LengthBytes];
            bool   isCompressed; int length;

            msg.PrepareForSending(ref bufAux, out isCompressed, out length);

            buf[1] = (byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None);

            buf[2] = (byte)(length & 0xff);
            buf[3] = (byte)((length >> 8) & 0xff);

            Array.Copy(bufAux, 0, buf, 4, length);

            Facepunch.Steamworks.Networking.SendType sendType;
            switch (deliveryMethod)
            {
            case DeliveryMethod.Reliable:
            case DeliveryMethod.ReliableOrdered:
                //the documentation seems to suggest that the Reliable send type
                //enforces packet order (TODO: verify)
                sendType = Facepunch.Steamworks.Networking.SendType.Reliable;
                break;

            default:
                sendType = Facepunch.Steamworks.Networking.SendType.Unreliable;
                break;
            }

            if (length + 8 >= MsgConstants.MTU)
            {
                DebugConsole.Log("WARNING: message length comes close to exceeding MTU, forcing reliable send (" + length.ToString() + " bytes)");
                sendType = Facepunch.Steamworks.Networking.SendType.Reliable;
            }

            heartbeatTimer = 5.0;

#if DEBUG
            CoroutineManager.InvokeAfter(() =>
            {
                if (GameMain.Client == null)
                {
                    return;
                }
                if (Rand.Range(0.0f, 1.0f) < GameMain.Client.SimulatedLoss && sendType != Facepunch.Steamworks.Networking.SendType.Reliable)
                {
                    return;
                }
                int count = Rand.Range(0.0f, 1.0f) < GameMain.Client.SimulatedDuplicatesChance ? 2 : 1;
                for (int i = 0; i < count; i++)
                {
                    Send(buf, length + 4, sendType);
                }
            },
                                         GameMain.Client.SimulatedMinimumLatency + Rand.Range(0.0f, GameMain.Client.SimulatedRandomLatency));
#else
            Send(buf, length + 4, sendType);
#endif
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Write the events to the outgoing message. The recipient parameter is only needed for ServerEntityEventManager
        /// </summary>
        protected void Write(IWriteMessage msg, List <NetEntityEvent> eventsToSync, out List <NetEntityEvent> sentEvents, Client recipient = null)
        {
            //write into a temporary buffer so we can write the number of events before the actual data
            IWriteMessage tempBuffer = new WriteOnlyMessage();

            sentEvents = new List <NetEntityEvent>();

            int eventCount = 0;

            foreach (NetEntityEvent e in eventsToSync)
            {
                //write into a temporary buffer so we can write the length before the actual data
                IWriteMessage tempEventBuffer = new WriteOnlyMessage();
                try
                {
                    WriteEvent(tempEventBuffer, e, recipient);
                }

                catch (Exception exception)
                {
                    DebugConsole.ThrowError("Failed to write an event for the entity \"" + e.Entity + "\"", exception);
                    GameAnalyticsManager.AddErrorEventOnce("NetEntityEventManager.Write:WriteFailed" + e.Entity.ToString(),
                                                           GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
                                                           "Failed to write an event for the entity \"" + e.Entity + "\"\n" + exception.StackTrace);

                    //write an empty event to avoid messing up IDs
                    //(otherwise the clients might read the next event in the message and think its ID
                    //is consecutive to the previous one, even though we skipped over this broken event)
                    tempBuffer.Write(Entity.NullEntityID);
                    tempBuffer.WritePadBits();
                    eventCount++;
                    continue;
                }

                //the length of the data is written as a byte, so the data needs to be less than 255 bytes long
                if (tempEventBuffer.LengthBytes > 255)
                {
                    DebugConsole.ThrowError("Too much data in network event for entity \"" + e.Entity.ToString() + "\" (" + tempEventBuffer.LengthBytes + " bytes, event ID " + e.ID + ")");
                    GameAnalyticsManager.AddErrorEventOnce("NetEntityEventManager.Write:TooLong" + e.Entity.ToString(),
                                                           GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
                                                           "Too much data in network event for entity \"" + e.Entity.ToString() + "\" (" + tempEventBuffer.LengthBytes + " bytes, event ID " + e.ID + ")");

                    //write an empty event to prevent breaking the event syncing
                    tempBuffer.Write(Entity.NullEntityID);
                    tempBuffer.WritePadBits();
                    eventCount++;
                    continue;
                }

                if (msg.LengthBytes + tempBuffer.LengthBytes + tempEventBuffer.LengthBytes > MaxEventBufferLength)
                {
                    //no more room in this packet
                    break;
                }

                tempBuffer.Write(e.EntityID);
                tempBuffer.Write((byte)tempEventBuffer.LengthBytes);
                tempBuffer.Write(tempEventBuffer.Buffer, 0, tempEventBuffer.LengthBytes);
                tempBuffer.WritePadBits();
                sentEvents.Add(e);

                eventCount++;
            }

            if (eventCount > 0)
            {
                msg.Write(eventsToSync[0].ID);
                msg.Write((byte)eventCount);
                msg.Write(tempBuffer.Buffer, 0, tempBuffer.LengthBytes);
            }
        }
Ejemplo n.º 5
0
        public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
        {
            Item item = (Item)extraData[2];

            msg.Write(item.Removed ? (ushort)0 : item.ID);
        }
Ejemplo n.º 6
0
 public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
 {
     ClientWrite(msg, extraData);
 }
Ejemplo n.º 7
0
 public void Serialize(IWriteMessage msg)
 {
     msg.Write(RadiationEnabled);
     msg.Write(MaxMissionCount);
 }
Ejemplo n.º 8
0
        public void ServerWrite(IWriteMessage msg)
        {
            if (GameMain.Server == null)
            {
                return;
            }

            msg.Write(allowSubVoting);
            if (allowSubVoting)
            {
                List <Pair <object, int> > voteList = GetVoteList(VoteType.Sub, GameMain.Server.ConnectedClients);
                msg.Write((byte)voteList.Count);
                foreach (Pair <object, int> vote in voteList)
                {
                    msg.Write((byte)vote.Second);
                    msg.Write(((SubmarineInfo)vote.First).Name);
                }
            }
            msg.Write(AllowModeVoting);
            if (allowModeVoting)
            {
                List <Pair <object, int> > voteList = GetVoteList(VoteType.Mode, GameMain.Server.ConnectedClients);
                msg.Write((byte)voteList.Count);
                foreach (Pair <object, int> vote in voteList)
                {
                    msg.Write((byte)vote.Second);
                    msg.Write(((GameModePreset)vote.First).Identifier);
                }
            }
            msg.Write(AllowEndVoting);
            if (AllowEndVoting)
            {
                msg.Write((byte)GameMain.Server.ConnectedClients.Count(c => c.HasSpawned && c.GetVote <bool>(VoteType.EndRound)));
                msg.Write((byte)GameMain.Server.ConnectedClients.Count(c => c.HasSpawned));
            }

            msg.Write(AllowVoteKick);

            msg.Write((byte)SubVote.State);
            if (SubVote.State != VoteState.None)
            {
                msg.Write((byte)SubVote.VoteType);

                if (SubVote.VoteType != VoteType.Unknown)
                {
                    var yesClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote <int>(SubVote.VoteType) == 2);
                    msg.Write((byte)yesClients.Count);
                    foreach (Client c in yesClients)
                    {
                        msg.Write(c.ID);
                    }

                    var noClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote <int>(SubVote.VoteType) == 1);
                    msg.Write((byte)noClients.Count);
                    foreach (Client c in noClients)
                    {
                        msg.Write(c.ID);
                    }

                    msg.Write((byte)GameMain.Server.SubmarineVoteMax);

                    switch (SubVote.State)
                    {
                    case VoteState.Started:
                        msg.Write(SubVote.Sub.Name);
                        msg.Write(SubVote.VoteStarter.ID);
                        msg.Write((byte)GameMain.Server.ServerSettings.SubmarineVoteTimeout);
                        break;

                    case VoteState.Running:
                        // Nothing specific
                        break;

                    case VoteState.Passed:
                    case VoteState.Failed:
                        msg.Write(SubVote.State == VoteState.Passed);
                        msg.Write(SubVote.Sub.Name);
                        if (SubVote.State == VoteState.Passed)
                        {
                            msg.Write((short)SubVote.DeliveryFee);
                        }
                        break;
                    }
                }
            }

            var readyClients = GameMain.Server.ConnectedClients.FindAll(c => c.GetVote <bool>(VoteType.StartRound));

            msg.Write((byte)readyClients.Count);
            foreach (Client c in readyClients)
            {
                msg.Write(c.ID);
            }

            msg.WritePadBits();
        }
Ejemplo n.º 9
0
 public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null)
 {
     msg.Write(user == null ? (ushort)0 : user.ID);
     ClientWrite(msg, extraData);
 }
Ejemplo n.º 10
0
        public void ClientWrite(IWriteMessage msg, VoteType voteType, object data)
        {
            msg.Write((byte)voteType);

            switch (voteType)
            {
            case VoteType.Sub:
                if (!(data is SubmarineInfo sub))
                {
                    return;
                }
                msg.Write(sub.EqualityCheckVal);
                if (sub.EqualityCheckVal == 0)
                {
                    //sub doesn't exist client-side, use hash to let the server know which one we voted for
                    msg.Write(sub.MD5Hash.Hash);
                }
                break;

            case VoteType.Mode:
                if (!(data is GameModePreset gameMode))
                {
                    return;
                }
                msg.Write(gameMode.Identifier);
                break;

            case VoteType.EndRound:
                if (!(data is bool))
                {
                    return;
                }
                msg.Write((bool)data);
                break;

            case VoteType.Kick:
                if (!(data is Client votedClient))
                {
                    return;
                }

                msg.Write(votedClient.ID);
                break;

            case VoteType.StartRound:
                if (!(data is bool))
                {
                    return;
                }
                msg.Write((bool)data);
                break;

            case VoteType.PurchaseAndSwitchSub:
            case VoteType.PurchaseSub:
            case VoteType.SwitchSub:
                if (!VoteRunning)
                {
                    SubmarineInfo voteSub = data as SubmarineInfo;
                    if (voteSub == null)
                    {
                        return;
                    }
                    msg.Write(true);
                    msg.Write(voteSub.Name);
                }
                else
                {
                    if (!(data is int))
                    {
                        return;
                    }
                    msg.Write(false);
                    msg.Write((int)data);
                }

                break;
            }

            msg.WritePadBits();
        }
Ejemplo n.º 11
0
 protected abstract void SendMsgInternal(DeliveryMethod deliveryMethod, IWriteMessage msg);
Ejemplo n.º 12
0
 public abstract void Send(IWriteMessage msg, DeliveryMethod deliveryMethod);
Ejemplo n.º 13
0
 public void ClientWrite(IWriteMessage msg, object[] extraData = null)
 {
     msg.Write((string)extraData[2]);
 }