Exemplo n.º 1
0
        public void ClientAdminRead(IReadMessage incMsg)
        {
            int count = incMsg.ReadUInt16();

            for (int i = 0; i < count; i++)
            {
                UInt32 key = incMsg.ReadUInt32();
                if (netProperties.ContainsKey(key))
                {
                    bool changedLocally = netProperties[key].ChangedLocally;
                    netProperties[key].Read(incMsg);
                    netProperties[key].TempValue = netProperties[key].Value;

                    if (netProperties[key].GUIComponent != null)
                    {
                        if (!changedLocally)
                        {
                            netProperties[key].GUIComponentValue = netProperties[key].Value;
                        }
                    }
                }
                else
                {
                    UInt32 size = incMsg.ReadVariableUInt32();
                    incMsg.BitPosition += (int)(8 * size);
                }
            }

            ReadMonsterEnabled(incMsg);
            BanList.ClientAdminRead(incMsg);
            Whitelist.ClientAdminRead(incMsg);
        }
Exemplo n.º 2
0
        public void ClientAdminRead(IReadMessage incMsg)
        {
            bool hasPermission = incMsg.ReadBoolean();

            if (!hasPermission)
            {
                incMsg.ReadPadBits();
                return;
            }

            bool isOwner = incMsg.ReadBoolean();

            incMsg.ReadPadBits();

            bannedPlayers.Clear();
            UInt32 bannedPlayerCount = incMsg.ReadVariableUInt32();

            for (int i = 0; i < (int)bannedPlayerCount; i++)
            {
                string name               = incMsg.ReadString();
                UInt16 uniqueIdentifier   = incMsg.ReadUInt16();
                bool   isRangeBan         = incMsg.ReadBoolean();
                bool   includesExpiration = incMsg.ReadBoolean();
                incMsg.ReadPadBits();

                DateTime?expiration = null;
                if (includesExpiration)
                {
                    double hoursFromNow = incMsg.ReadDouble();
                    expiration = DateTime.Now + TimeSpan.FromHours(hoursFromNow);
                }

                string reason = incMsg.ReadString();

                string endPoint = "";
                UInt64 steamID  = 0;
                if (isOwner)
                {
                    endPoint = incMsg.ReadString();
                    steamID  = incMsg.ReadUInt64();
                }
                else
                {
                    endPoint = "Endpoint concealed by host";
                    steamID  = 0;
                }
                bannedPlayers.Add(new BannedPlayer(name, uniqueIdentifier, isRangeBan, endPoint, steamID, reason, expiration));
            }

            if (banFrame != null)
            {
                var parent = banFrame.Parent;
                parent.RemoveChild(banFrame);
                CreateBanFrame(parent);
            }
        }
Exemplo n.º 3
0
        public void ClientAdminRead(IReadMessage incMsg)
        {
            bool hasPermission = incMsg.ReadBoolean();

            if (!hasPermission)
            {
                incMsg.ReadPadBits();
                return;
            }

            bool isOwner = incMsg.ReadBoolean();

            incMsg.ReadPadBits();

            bannedPlayers.Clear();
            UInt32 bannedPlayerCount = incMsg.ReadVariableUInt32();

            for (int i = 0; i < (int)bannedPlayerCount; i++)
            {
                string name             = incMsg.ReadString();
                UInt16 uniqueIdentifier = incMsg.ReadUInt16();
                bool   isRangeBan       = incMsg.ReadBoolean(); incMsg.ReadPadBits();

                string ip      = "";
                UInt64 steamID = 0;
                if (isOwner)
                {
                    ip      = incMsg.ReadString();
                    steamID = incMsg.ReadUInt64();
                }
                else
                {
                    ip      = "IP concealed by host";
                    steamID = 0;
                }
                bannedPlayers.Add(new BannedPlayer(name, uniqueIdentifier, isRangeBan, ip, steamID));
            }

            if (banFrame != null)
            {
                var parent = banFrame.Parent;
                parent.RemoveChild(banFrame);
                CreateBanFrame(parent);
            }
        }
Exemplo n.º 4
0
        public void ClientAdminRead(IReadMessage incMsg)
        {
            bool hasPermission = incMsg.ReadBoolean();

            if (!hasPermission)
            {
                incMsg.ReadPadBits();
                return;
            }

            bool isOwner = incMsg.ReadBoolean();

            localEnabled = incMsg.ReadBoolean();
            Enabled      = localEnabled;
            incMsg.ReadPadBits();

            whitelistedPlayers.Clear();
            UInt32 bannedPlayerCount = incMsg.ReadVariableUInt32();

            for (int i = 0; i < (int)bannedPlayerCount; i++)
            {
                string name             = incMsg.ReadString();
                UInt16 uniqueIdentifier = incMsg.ReadUInt16();

                string ip = "";
                if (isOwner)
                {
                    ip = incMsg.ReadString();
                }
                else
                {
                    ip = "IP concealed by host";
                }
                whitelistedPlayers.Add(new WhiteListedPlayer(name, uniqueIdentifier, ip));
            }

            if (whitelistFrame != null)
            {
                CreateWhiteListFrame(whitelistFrame.Parent);
            }
        }
        /// <summary>
        /// Read the events from the message, ignoring ones we've already received. Returns false if reading the events fails.
        /// </summary>
        public bool Read(ServerNetObject type, IReadMessage msg, float sendingTime, List <IServerSerializable> entities)
        {
            UInt16 unreceivedEntityEventCount = 0;

            if (type == ServerNetObject.ENTITY_EVENT_INITIAL)
            {
                unreceivedEntityEventCount = msg.ReadUInt16();
                firstNewID = msg.ReadUInt16();

                if (GameSettings.VerboseLogging)
                {
                    DebugConsole.NewMessage(
                        "received midround syncing msg, unreceived: " + unreceivedEntityEventCount +
                        ", first new ID: " + firstNewID, Microsoft.Xna.Framework.Color.Yellow);
                }
            }
            else
            {
                MidRoundSyncingDone = true;
                if (firstNewID != null)
                {
                    if (GameSettings.VerboseLogging)
                    {
                        DebugConsole.NewMessage("midround syncing complete, switching to ID " + (UInt16)(firstNewID - 1),
                                                Microsoft.Xna.Framework.Color.Yellow);
                    }
                    lastReceivedID = (UInt16)(firstNewID - 1);
                    firstNewID     = null;
                }
            }

            entities.Clear();

            UInt16 firstEventID = msg.ReadUInt16();
            int    eventCount   = msg.ReadByte();

            for (int i = 0; i < eventCount; i++)
            {
                //16 = entity ID, 8 = msg length
                if (msg.BitPosition + 16 + 8 > msg.LengthBits)
                {
                    string errorMsg = $"Error while reading a message from the server. Entity event data exceeds the size of the buffer (current position: {msg.BitPosition}, length: {msg.LengthBits}).";
                    errorMsg += "\nPrevious entities:";
                    for (int j = entities.Count - 1; j >= 0; j--)
                    {
                        errorMsg += "\n" + (entities[j] == null ? "NULL" : entities[j].ToString());
                    }
                    DebugConsole.ThrowError(errorMsg);
                    return(false);
                }

                UInt16 thisEventID = (UInt16)(firstEventID + (UInt16)i);
                UInt16 entityID    = msg.ReadUInt16();

                if (entityID == Entity.NullEntityID)
                {
                    if (GameSettings.VerboseLogging)
                    {
                        DebugConsole.NewMessage("received msg " + thisEventID + " (null entity)",
                                                Microsoft.Xna.Framework.Color.Orange);
                    }
                    msg.ReadPadBits();
                    entities.Add(null);
                    if (thisEventID == (UInt16)(lastReceivedID + 1))
                    {
                        lastReceivedID++;
                    }
                    continue;
                }

                int msgLength = (int)msg.ReadVariableUInt32();

                IServerSerializable entity = Entity.FindEntityByID(entityID) as IServerSerializable;
                entities.Add(entity);

                //skip the event if we've already received it or if the entity isn't found
                if (thisEventID != (UInt16)(lastReceivedID + 1) || entity == null)
                {
                    if (thisEventID != (UInt16)(lastReceivedID + 1))
                    {
                        if (GameSettings.VerboseLogging)
                        {
                            DebugConsole.NewMessage(
                                "Received msg " + thisEventID + " (waiting for " + (lastReceivedID + 1) + ")",
                                NetIdUtils.IdMoreRecent(thisEventID, (UInt16)(lastReceivedID + 1))
                                    ? GUI.Style.Red
                                    : Microsoft.Xna.Framework.Color.Yellow);
                        }
                    }
                    else if (entity == null)
                    {
                        DebugConsole.NewMessage(
                            "Received msg " + thisEventID + ", entity " + entityID + " not found",
                            GUI.Style.Red);
                        GameMain.Client.ReportError(ClientNetError.MISSING_ENTITY, eventID: thisEventID, entityID: entityID);
                        return(false);
                    }

                    msg.BitPosition += msgLength * 8;
                    msg.ReadPadBits();
                }
                else
                {
                    long msgPosition = msg.BitPosition;
                    if (GameSettings.VerboseLogging)
                    {
                        DebugConsole.NewMessage("received msg " + thisEventID + " (" + entity.ToString() + ")",
                                                Microsoft.Xna.Framework.Color.Green);
                    }
                    lastReceivedID++;
                    try
                    {
                        ReadEvent(msg, entity, sendingTime);
                        msg.ReadPadBits();

                        if (msg.BitPosition != msgPosition + msgLength * 8)
                        {
                            string errorMsg = "Message byte position incorrect after reading an event for the entity \"" + entity.ToString()
                                              + "\". Read " + (msg.BitPosition - msgPosition) + " bits, expected message length was " + (msgLength * 8) + " bits.";
#if DEBUG
                            DebugConsole.ThrowError(errorMsg);
#endif
                            GameAnalyticsManager.AddErrorEventOnce("ClientEntityEventManager.Read:BitPosMismatch", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);

                            //TODO: force the BitPosition to correct place? Having some entity in a potentially incorrect state is not as bad as a desync kick
                            //msg.BitPosition = (int)(msgPosition + msgLength * 8);
                        }
                    }

                    catch (Exception e)
                    {
                        string errorMsg = "Failed to read event for entity \"" + entity.ToString() + "\" (" + e.Message + ")! (MidRoundSyncing: " + thisClient.MidRoundSyncing + ")\n" + e.StackTrace.CleanupStackTrace();
                        errorMsg += "\nPrevious entities:";
                        for (int j = entities.Count - 2; j >= 0; j--)
                        {
                            errorMsg += "\n" + (entities[j] == null ? "NULL" : entities[j].ToString());
                        }

                        DebugConsole.ThrowError("Failed to read event for entity \"" + entity.ToString() + "\"!", e);

                        GameAnalyticsManager.AddErrorEventOnce("ClientEntityEventManager.Read:ReadFailed" + entity.ToString(),
                                                               GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
                        msg.BitPosition = (int)(msgPosition + msgLength * 8);
                        msg.ReadPadBits();
                    }
                }
            }
            return(true);
        }
Exemplo n.º 6
0
            public void Read(IReadMessage msg)
            {
                int    oldPos = msg.BitPosition;
                UInt32 size   = msg.ReadVariableUInt32();

                float x; float y; float z; float w;
                byte  r; byte g; byte b; byte a;
                int   ix; int iy; int width; int height;

                switch (typeString)
                {
                case "float":
                    if (size != 4)
                    {
                        break;
                    }
                    property.SetValue(parentObject, msg.ReadSingle());
                    return;

                case "int":
                    if (size != 4)
                    {
                        break;
                    }
                    property.SetValue(parentObject, msg.ReadInt32());
                    return;

                case "vector2":
                    if (size != 8)
                    {
                        break;
                    }
                    x = msg.ReadSingle();
                    y = msg.ReadSingle();
                    property.SetValue(parentObject, new Vector2(x, y));
                    return;

                case "vector3":
                    if (size != 12)
                    {
                        break;
                    }
                    x = msg.ReadSingle();
                    y = msg.ReadSingle();
                    z = msg.ReadSingle();
                    property.SetValue(parentObject, new Vector3(x, y, z));
                    return;

                case "vector4":
                    if (size != 16)
                    {
                        break;
                    }
                    x = msg.ReadSingle();
                    y = msg.ReadSingle();
                    z = msg.ReadSingle();
                    w = msg.ReadSingle();
                    property.SetValue(parentObject, new Vector4(x, y, z, w));
                    return;

                case "color":
                    if (size != 4)
                    {
                        break;
                    }
                    r = msg.ReadByte();
                    g = msg.ReadByte();
                    b = msg.ReadByte();
                    a = msg.ReadByte();
                    property.SetValue(parentObject, new Color(r, g, b, a));
                    return;

                case "rectangle":
                    if (size != 16)
                    {
                        break;
                    }
                    ix     = msg.ReadInt32();
                    iy     = msg.ReadInt32();
                    width  = msg.ReadInt32();
                    height = msg.ReadInt32();
                    property.SetValue(parentObject, new Rectangle(ix, iy, width, height));
                    return;

                default:
                    msg.BitPosition = oldPos;     //reset position to properly read the string
                    string incVal = msg.ReadString();
                    property.TrySetValue(parentObject, incVal);
                    return;
                }

                //size didn't match: skip this
                msg.BitPosition += (int)(8 * size);
            }
Exemplo n.º 7
0
        private void ReadConnectionInitializationStep(PendingClient pendingClient, IReadMessage inc)
        {
            if (netServer == null)
            {
                return;
            }

            pendingClient.TimeOut = NetworkConnection.TimeoutThreshold;

            ConnectionInitialization initializationStep = (ConnectionInitialization)inc.ReadByte();

            //DebugConsole.NewMessage(initializationStep+" "+pendingClient.InitializationStep);

            if (pendingClient.InitializationStep != initializationStep)
            {
                return;
            }

            pendingClient.UpdateTime = Timing.TotalTime + Timing.Step;

            switch (initializationStep)
            {
            case ConnectionInitialization.SteamTicketAndVersion:
                string name         = Client.SanitizeName(inc.ReadString());
                UInt64 steamId      = inc.ReadUInt64();
                UInt16 ticketLength = inc.ReadUInt16();
                inc.BitPosition += ticketLength * 8;     //skip ticket, owner handles steam authentication

                if (!Client.IsValidName(name, serverSettings))
                {
                    RemovePendingClient(pendingClient, DisconnectReason.InvalidName, "The name \"" + name + "\" is invalid");
                    return;
                }

                string version             = inc.ReadString();
                bool   isCompatibleVersion = NetworkMember.IsCompatible(version, GameMain.Version.ToString()) ?? false;
                if (!isCompatibleVersion)
                {
                    RemovePendingClient(pendingClient, DisconnectReason.InvalidVersion,
                                        $"DisconnectMessage.InvalidVersion~[version]={GameMain.Version.ToString()}~[clientversion]={version}");

                    GameServer.Log(name + " (" + pendingClient.SteamID.ToString() + ") couldn't join the server (incompatible game version)", ServerLog.MessageType.Error);
                    DebugConsole.NewMessage(name + " (" + pendingClient.SteamID.ToString() + ") couldn't join the server (incompatible game version)", Microsoft.Xna.Framework.Color.Red);
                    return;
                }

                int contentPackageCount = (int)inc.ReadVariableUInt32();
                List <ClientContentPackage> clientContentPackages = new List <ClientContentPackage>();
                for (int i = 0; i < contentPackageCount; i++)
                {
                    string packageName = inc.ReadString();
                    string packageHash = inc.ReadString();
                    clientContentPackages.Add(new ClientContentPackage(packageName, packageHash));
                }

                //check if the client is missing any of our packages
                List <ContentPackage> missingPackages = new List <ContentPackage>();
                foreach (ContentPackage serverContentPackage in GameMain.SelectedPackages)
                {
                    if (!serverContentPackage.HasMultiplayerIncompatibleContent)
                    {
                        continue;
                    }
                    bool packageFound = clientContentPackages.Any(cp => cp.Name == serverContentPackage.Name && cp.Hash == serverContentPackage.MD5hash.Hash);
                    if (!packageFound)
                    {
                        missingPackages.Add(serverContentPackage);
                    }
                }

                //check if the client is using packages we don't have
                List <ClientContentPackage> redundantPackages = new List <ClientContentPackage>();
                foreach (ClientContentPackage clientContentPackage in clientContentPackages)
                {
                    bool packageFound = GameMain.SelectedPackages.Any(cp => cp.Name == clientContentPackage.Name && cp.MD5hash.Hash == clientContentPackage.Hash);
                    if (!packageFound)
                    {
                        redundantPackages.Add(clientContentPackage);
                    }
                }

                if (missingPackages.Count == 1)
                {
                    RemovePendingClient(pendingClient, DisconnectReason.MissingContentPackage,
                                        $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(missingPackages[0])}");
                    GameServer.Log(name + " (" + pendingClient.SteamID + ") couldn't join the server (missing content package " + GetPackageStr(missingPackages[0]) + ")", ServerLog.MessageType.Error);
                    return;
                }
                else if (missingPackages.Count > 1)
                {
                    List <string> packageStrs = new List <string>();
                    missingPackages.ForEach(cp => packageStrs.Add(GetPackageStr(cp)));
                    RemovePendingClient(pendingClient, DisconnectReason.MissingContentPackage,
                                        $"DisconnectMessage.MissingContentPackages~[missingcontentpackages]={string.Join(", ", packageStrs)}");
                    GameServer.Log(name + " (" + pendingClient.SteamID + ") couldn't join the server (missing content packages " + string.Join(", ", packageStrs) + ")", ServerLog.MessageType.Error);
                    return;
                }
                if (redundantPackages.Count == 1)
                {
                    RemovePendingClient(pendingClient, DisconnectReason.IncompatibleContentPackage,
                                        $"DisconnectMessage.IncompatibleContentPackage~[incompatiblecontentpackage]={GetPackageStr(redundantPackages[0])}");
                    GameServer.Log(name + " (" + pendingClient.SteamID + ") couldn't join the server (using an incompatible content package " + GetPackageStr(redundantPackages[0]) + ")", ServerLog.MessageType.Error);
                    return;
                }
                if (redundantPackages.Count > 1)
                {
                    List <string> packageStrs = new List <string>();
                    redundantPackages.ForEach(cp => packageStrs.Add(GetPackageStr(cp)));
                    RemovePendingClient(pendingClient, DisconnectReason.IncompatibleContentPackage,
                                        $"DisconnectMessage.IncompatibleContentPackages~[incompatiblecontentpackages]={string.Join(", ", packageStrs)}");
                    GameServer.Log(name + " (" + pendingClient.SteamID + ") couldn't join the server (using incompatible content packages " + string.Join(", ", packageStrs) + ")", ServerLog.MessageType.Error);
                    return;
                }

                if (!pendingClient.AuthSessionStarted)
                {
                    pendingClient.InitializationStep = serverSettings.HasPassword ? ConnectionInitialization.Password: ConnectionInitialization.Success;

                    pendingClient.Name = name;
                    pendingClient.AuthSessionStarted = true;
                }
                break;

            case ConnectionInitialization.Password:
                int    pwLength    = inc.ReadByte();
                byte[] incPassword = inc.ReadBytes(pwLength);
                if (pendingClient.PasswordSalt == null)
                {
                    DebugConsole.ThrowError("Received password message from client without salt");
                    return;
                }
                if (serverSettings.IsPasswordCorrect(incPassword, pendingClient.PasswordSalt.Value))
                {
                    pendingClient.InitializationStep = ConnectionInitialization.Success;
                }
                else
                {
                    pendingClient.Retries++;

                    if (pendingClient.Retries >= 3)
                    {
                        string banMsg = "Failed to enter correct password too many times";
                        serverSettings.BanList.BanPlayer(pendingClient.Name, pendingClient.SteamID, banMsg, null);

                        RemovePendingClient(pendingClient, DisconnectReason.Banned, banMsg);
                        return;
                    }
                }
                pendingClient.UpdateTime = Timing.TotalTime;
                break;
            }
        }
        /// <summary>
        /// Read the events from the message, ignoring ones we've already received
        /// </summary>
        public void Read(IReadMessage msg, Client sender = null)
        {
            UInt16 firstEventID = msg.ReadUInt16();
            int    eventCount   = msg.ReadByte();

            for (int i = 0; i < eventCount; i++)
            {
                UInt16 thisEventID = (UInt16)(firstEventID + (UInt16)i);
                UInt16 entityID    = msg.ReadUInt16();

                if (entityID == Entity.NullEntityID)
                {
                    msg.ReadPadBits();
                    if (thisEventID == (UInt16)(sender.LastSentEntityEventID + 1))
                    {
                        sender.LastSentEntityEventID++;
                    }
                    continue;
                }

                int msgLength = (int)msg.ReadVariableUInt32();

                IClientSerializable entity = Entity.FindEntityByID(entityID) as IClientSerializable;

                //skip the event if we've already received it
                if (thisEventID != (UInt16)(sender.LastSentEntityEventID + 1))
                {
                    if (GameSettings.VerboseLogging)
                    {
                        DebugConsole.NewMessage("Received msg " + thisEventID + ", expecting " + sender.LastSentEntityEventID, Color.Red);
                    }
                    msg.BitPosition += msgLength * 8;
                }
                else if (entity == null)
                {
                    //entity not found -> consider the even read and skip over it
                    //(can happen, for example, when a client uses a medical item repeatedly
                    //and creates an event for it before receiving the event about it being removed)
                    if (GameSettings.VerboseLogging)
                    {
                        DebugConsole.NewMessage(
                            "Received msg " + thisEventID + ", entity " + entityID + " not found",
                            Microsoft.Xna.Framework.Color.Orange);
                    }
                    sender.LastSentEntityEventID++;
                    msg.BitPosition += msgLength * 8;
                }
                else
                {
                    if (GameSettings.VerboseLogging)
                    {
                        DebugConsole.NewMessage("Received msg " + thisEventID, Microsoft.Xna.Framework.Color.Green);
                    }

                    UInt16 characterStateID = msg.ReadUInt16();

                    ReadWriteMessage buffer = new ReadWriteMessage();
                    byte[]           temp   = msg.ReadBytes(msgLength - 2);
                    buffer.Write(temp, 0, msgLength - 2);
                    buffer.BitPosition = 0;
                    BufferEvent(new BufferedEvent(sender, sender.Character, characterStateID, entity, buffer));

                    sender.LastSentEntityEventID++;
                }
                msg.ReadPadBits();
            }
        }
Exemplo n.º 9
0
        protected void ReadConnectionInitializationStep(IReadMessage inc)
        {
            ConnectionInitialization step = (ConnectionInitialization)inc.ReadByte();

            IWriteMessage outMsg;

            switch (step)
            {
            case ConnectionInitialization.SteamTicketAndVersion:
                if (initializationStep != ConnectionInitialization.SteamTicketAndVersion)
                {
                    return;
                }
                outMsg = new WriteOnlyMessage();
                outMsg.Write((byte)PacketHeader.IsConnectionInitializationStep);
                outMsg.Write((byte)ConnectionInitialization.SteamTicketAndVersion);
                outMsg.Write(Name);
                outMsg.Write(ownerKey);
                outMsg.Write(SteamManager.GetSteamID());
                if (steamAuthTicket == null)
                {
                    outMsg.Write((UInt16)0);
                }
                else
                {
                    outMsg.Write((UInt16)steamAuthTicket.Data.Length);
                    outMsg.Write(steamAuthTicket.Data, 0, steamAuthTicket.Data.Length);
                }
                outMsg.Write(GameMain.Version.ToString());
                outMsg.Write(GameMain.Config.Language);

                SendMsgInternal(DeliveryMethod.Reliable, outMsg);
                break;

            case ConnectionInitialization.ContentPackageOrder:
                if (initializationStep == ConnectionInitialization.SteamTicketAndVersion ||
                    initializationStep == ConnectionInitialization.Password)
                {
                    initializationStep = ConnectionInitialization.ContentPackageOrder;
                }
                if (initializationStep != ConnectionInitialization.ContentPackageOrder)
                {
                    return;
                }
                outMsg = new WriteOnlyMessage();
                outMsg.Write((byte)PacketHeader.IsConnectionInitializationStep);
                outMsg.Write((byte)ConnectionInitialization.ContentPackageOrder);

                string serverName = inc.ReadString();

                UInt32 cpCount = inc.ReadVariableUInt32();
                ServerContentPackage        corePackage     = null;
                List <ServerContentPackage> regularPackages = new List <ServerContentPackage>();
                List <ServerContentPackage> missingPackages = new List <ServerContentPackage>();
                for (int i = 0; i < cpCount; i++)
                {
                    string name       = inc.ReadString();
                    string hash       = inc.ReadString();
                    UInt64 workshopId = inc.ReadUInt64();
                    var    pkg        = new ServerContentPackage(name, hash, workshopId);
                    if (pkg.CorePackage != null)
                    {
                        corePackage = pkg;
                    }
                    else if (pkg.RegularPackage != null)
                    {
                        regularPackages.Add(pkg);
                    }
                    else
                    {
                        missingPackages.Add(pkg);
                    }
                }

                if (missingPackages.Count > 0)
                {
                    var nonDownloadable = missingPackages.Where(p => p.WorkshopId == 0);

                    if (nonDownloadable.Any())
                    {
                        string disconnectMsg;
                        if (nonDownloadable.Count() == 1)
                        {
                            disconnectMsg = $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(missingPackages[0])}";
                        }
                        else
                        {
                            List <string> packageStrs = new List <string>();
                            nonDownloadable.ForEach(cp => packageStrs.Add(GetPackageStr(cp)));
                            disconnectMsg = $"DisconnectMessage.MissingContentPackages~[missingcontentpackages]={string.Join(", ", packageStrs)}";
                        }
                        Close(disconnectMsg, disableReconnect: true);
                        OnDisconnectMessageReceived?.Invoke(DisconnectReason.MissingContentPackage + "/" + disconnectMsg);
                    }
                    else
                    {
                        Close(disableReconnect: true);

                        string missingModNames   = "\n";
                        int    displayedModCount = 0;
                        foreach (ServerContentPackage missingPackage in missingPackages)
                        {
                            missingModNames += "\n- " + GetPackageStr(missingPackage);
                            displayedModCount++;
                            if (GUI.Font.MeasureString(missingModNames).Y > GameMain.GraphicsHeight * 0.5f)
                            {
                                missingModNames += "\n\n" + TextManager.GetWithVariable("workshopitemdownloadprompttruncated", "[number]", (missingPackages.Count - displayedModCount).ToString());
                                break;
                            }
                        }
                        missingModNames += "\n\n";

                        var msgBox = new GUIMessageBox(
                            TextManager.Get("WorkshopItemDownloadTitle"),
                            TextManager.GetWithVariable("WorkshopItemDownloadPrompt", "[items]", missingModNames),
                            new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
                        msgBox.Buttons[0].OnClicked = (yesBtn, userdata) =>
                        {
                            GameMain.ServerListScreen.Select();
                            GameMain.ServerListScreen.DownloadWorkshopItems(missingPackages.Select(p => p.WorkshopId), serverName, ServerConnection.EndPointString);
                            return(true);
                        };
                        msgBox.Buttons[0].OnClicked += msgBox.Close;
                        msgBox.Buttons[1].OnClicked  = msgBox.Close;
                    }

                    return;
                }

                if (!contentPackageOrderReceived)
                {
                    GameMain.Config.BackUpModOrder();
                    GameMain.Config.SwapPackages(corePackage.CorePackage, regularPackages.Select(p => p.RegularPackage).ToList());
                    contentPackageOrderReceived = true;
                }

                SendMsgInternal(DeliveryMethod.Reliable, outMsg);
                break;

            case ConnectionInitialization.Password:
                if (initializationStep == ConnectionInitialization.SteamTicketAndVersion)
                {
                    initializationStep = ConnectionInitialization.Password;
                }
                if (initializationStep != ConnectionInitialization.Password)
                {
                    return;
                }
                bool incomingSalt = inc.ReadBoolean(); inc.ReadPadBits();
                int  retries      = 0;
                if (incomingSalt)
                {
                    passwordSalt = inc.ReadInt32();
                }
                else
                {
                    retries = inc.ReadInt32();
                }
                OnRequestPassword?.Invoke(passwordSalt, retries);
                break;
            }
        }
        public void ServerRead(IReadMessage incMsg, Client c)
        {
            if (!c.HasPermission(Networking.ClientPermissions.ManageSettings))
            {
                return;
            }

            NetFlags flags = (NetFlags)incMsg.ReadByte();

            bool changed = false;

            if (flags.HasFlag(NetFlags.Name))
            {
                string serverName = incMsg.ReadString();
                if (ServerName != serverName)
                {
                    changed = true;
                }
                ServerName = serverName;
            }

            if (flags.HasFlag(NetFlags.Message))
            {
                string serverMessageText = incMsg.ReadString();
                if (ServerMessageText != serverMessageText)
                {
                    changed = true;
                }
                ServerMessageText = serverMessageText;
            }

            if (flags.HasFlag(NetFlags.Properties))
            {
                changed |= ReadExtraCargo(incMsg);

                UInt32 count = incMsg.ReadUInt32();

                for (int i = 0; i < count; i++)
                {
                    UInt32 key = incMsg.ReadUInt32();

                    if (netProperties.ContainsKey(key))
                    {
                        object prevValue = netProperties[key].Value;
                        netProperties[key].Read(incMsg);
                        if (!netProperties[key].PropEquals(prevValue, netProperties[key]))
                        {
                            GameServer.Log(GameServer.ClientLogName(c) + " changed " + netProperties[key].Name + " to " + netProperties[key].Value.ToString(), ServerLog.MessageType.ServerMessage);
                        }
                        changed = true;
                    }
                    else
                    {
                        UInt32 size = incMsg.ReadVariableUInt32();
                        incMsg.BitPosition += (int)(8 * size);
                    }
                }

                bool changedMonsterSettings = incMsg.ReadBoolean(); incMsg.ReadPadBits();
                changed |= changedMonsterSettings;
                if (changedMonsterSettings)
                {
                    ReadMonsterEnabled(incMsg);
                }
                changed |= BanList.ServerAdminRead(incMsg, c);
                changed |= Whitelist.ServerAdminRead(incMsg, c);
            }

            if (flags.HasFlag(NetFlags.Misc))
            {
                int orBits  = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All;
                int andBits = incMsg.ReadRangedInteger(0, (int)Barotrauma.MissionType.All) & (int)Barotrauma.MissionType.All;
                GameMain.NetLobbyScreen.MissionType = (Barotrauma.MissionType)(((int)GameMain.NetLobbyScreen.MissionType | orBits) & andBits);

                int traitorSetting = (int)TraitorsEnabled + incMsg.ReadByte() - 1;
                if (traitorSetting < 0)
                {
                    traitorSetting = 2;
                }
                if (traitorSetting > 2)
                {
                    traitorSetting = 0;
                }
                TraitorsEnabled = (YesNoMaybe)traitorSetting;

                int botCount = BotCount + incMsg.ReadByte() - 1;
                if (botCount < 0)
                {
                    botCount = MaxBotCount;
                }
                if (botCount > MaxBotCount)
                {
                    botCount = 0;
                }
                BotCount = botCount;

                int botSpawnMode = (int)BotSpawnMode + incMsg.ReadByte() - 1;
                if (botSpawnMode < 0)
                {
                    botSpawnMode = 1;
                }
                if (botSpawnMode > 1)
                {
                    botSpawnMode = 0;
                }
                BotSpawnMode = (BotSpawnMode)botSpawnMode;

                float levelDifficulty = incMsg.ReadSingle();
                if (levelDifficulty >= 0.0f)
                {
                    SelectedLevelDifficulty = levelDifficulty;
                }

                UseRespawnShuttle = incMsg.ReadBoolean();

                bool changedAutoRestart = incMsg.ReadBoolean();
                bool autoRestart        = incMsg.ReadBoolean();
                if (changedAutoRestart)
                {
                    AutoRestart = autoRestart;
                }

                changed |= true;
            }

            if (flags.HasFlag(NetFlags.LevelSeed))
            {
                GameMain.NetLobbyScreen.LevelSeed = incMsg.ReadString();
                changed |= true;
            }

            if (changed)
            {
                if (KarmaPreset == "custom")
                {
                    GameMain.NetworkMember?.KarmaManager?.SaveCustomPreset();
                    GameMain.NetworkMember?.KarmaManager?.Save();
                }
                SaveSettings();
                GameMain.NetLobbyScreen.LastUpdateID++;
            }
        }
Exemplo n.º 11
0
        private void ReadConnectionInitializationStep(IReadMessage inc)
        {
            if (!isActive)
            {
                return;
            }

            ConnectionInitialization step = (ConnectionInitialization)inc.ReadByte();

            IWriteMessage outMsg;

            //DebugConsole.NewMessage(step + " " + initializationStep);
            switch (step)
            {
            case ConnectionInitialization.SteamTicketAndVersion:
                if (initializationStep != ConnectionInitialization.SteamTicketAndVersion)
                {
                    return;
                }
                outMsg = new WriteOnlyMessage();
                outMsg.Write((byte)DeliveryMethod.Reliable);
                outMsg.Write((byte)PacketHeader.IsConnectionInitializationStep);
                outMsg.Write((byte)ConnectionInitialization.SteamTicketAndVersion);
                outMsg.Write(Name);
                outMsg.Write(SteamManager.GetSteamID());
                outMsg.Write((UInt16)steamAuthTicket.Data.Length);
                outMsg.Write(steamAuthTicket.Data, 0, steamAuthTicket.Data.Length);

                outMsg.Write(GameMain.Version.ToString());

                IEnumerable <ContentPackage> mpContentPackages = GameMain.SelectedPackages.Where(cp => cp.HasMultiplayerIncompatibleContent);
                outMsg.WriteVariableUInt32((UInt32)mpContentPackages.Count());
                foreach (ContentPackage contentPackage in mpContentPackages)
                {
                    outMsg.Write(contentPackage.Name);
                    outMsg.Write(contentPackage.MD5hash.Hash);
                }

                heartbeatTimer = 5.0;
                Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
                sentBytes += outMsg.LengthBytes;
                break;

            case ConnectionInitialization.ContentPackageOrder:
                if (initializationStep == ConnectionInitialization.SteamTicketAndVersion ||
                    initializationStep == ConnectionInitialization.Password)
                {
                    initializationStep = ConnectionInitialization.ContentPackageOrder;
                }
                if (initializationStep != ConnectionInitialization.ContentPackageOrder)
                {
                    return;
                }
                outMsg = new WriteOnlyMessage();
                outMsg.Write((byte)DeliveryMethod.Reliable);
                outMsg.Write((byte)PacketHeader.IsConnectionInitializationStep);
                outMsg.Write((byte)ConnectionInitialization.ContentPackageOrder);

                UInt32 cpCount = inc.ReadVariableUInt32();
                List <ContentPackage> serverContentPackages = new List <ContentPackage>();
                for (int i = 0; i < cpCount; i++)
                {
                    string hash = inc.ReadString();
                    serverContentPackages.Add(GameMain.Config.SelectedContentPackages.Find(cp => cp.MD5hash.Hash == hash));
                }

                if (!contentPackageOrderReceived)
                {
                    GameMain.Config.ReorderSelectedContentPackages(cp => serverContentPackages.Contains(cp) ?
                                                                   serverContentPackages.IndexOf(cp) :
                                                                   serverContentPackages.Count + GameMain.Config.SelectedContentPackages.IndexOf(cp));
                    contentPackageOrderReceived = true;
                }

                Steamworks.SteamNetworking.SendP2PPacket(hostSteamId, outMsg.Buffer, outMsg.LengthBytes, 0, Steamworks.P2PSend.Reliable);
                sentBytes += outMsg.LengthBytes;
                break;

            case ConnectionInitialization.Password:
                if (initializationStep == ConnectionInitialization.SteamTicketAndVersion)
                {
                    initializationStep = ConnectionInitialization.Password;
                }
                if (initializationStep != ConnectionInitialization.Password)
                {
                    return;
                }
                bool incomingSalt = inc.ReadBoolean(); inc.ReadPadBits();
                int  retries      = 0;
                if (incomingSalt)
                {
                    passwordSalt = inc.ReadInt32();
                }
                else
                {
                    retries = inc.ReadInt32();
                }
                OnRequestPassword?.Invoke(passwordSalt, retries);
                break;
            }
        }