Example #1
0
    void DebugGUI()
    {
        if (!Constants.DEBUG_MODE)
        {
            return;
        }

        if (GUILayout.Button ("spoon"))
        {

            if (_debugTool != DebugTools.Spoon)
            {
                _debugTool = DebugTools.Spoon;
                Debug.Log ("spoon On");
            }else
            {
                _debugTool = DebugTools.None;
                Debug.Log ("spoon Off");
            }

        }
        if (GUILayout.Button ("FormBomb"))
        {

            if (_debugTool != DebugTools.FormBomb)
            {
                _debugTool = DebugTools.FormBomb;
                Debug.Log ("FormBomb On");
            }else
            {
                _debugTool = DebugTools.None;
                Debug.Log ("FormBomb Off");
            }

        }
    }
Example #2
0
        public override void AlignPlacementMode(ScreenCoordinates mouseScreen)
        {
            const float SearchBoxSize = 1.5f; // size of search box in meters

            MouseCoords = ScreenToCursorGrid(mouseScreen);

            var mapGrid = pManager.MapManager.GetGrid(MouseCoords.GridID);

            if (mapGrid.IsDefaultGrid)
            {
                // check if we are on an edge of a grid
                // create a box around the cursor
                DebugTools.Assert(mapGrid.WorldPosition == Vector2.Zero); // assert that LocalPos == WorldPos
                var gridSearchBox = Box2.UnitCentered.Scale(SearchBoxSize).Translated(MouseCoords.Position);

                // find grids in search box
                var gridsInArea = pManager.MapManager.FindGridsIntersecting(mapGrid.ParentMapId, gridSearchBox);

                // find closest grid intersecting our search box.
                IMapGrid closest   = null;
                var      distance  = float.PositiveInfinity;
                var      intersect = new Box2();
                foreach (var grid in gridsInArea)
                {
                    // figure out closest intersect
                    var gridIntersect = gridSearchBox.Intersect(grid.WorldBounds);
                    var gridDist      = (gridIntersect.Center - MouseCoords.Position).LengthSquared;

                    if (gridDist >= distance)
                    {
                        continue;
                    }

                    distance  = gridDist;
                    closest   = grid;
                    intersect = gridIntersect;
                }

                if (closest != null) // stick to existing grid
                {
                    // round to nearest cardinal dir
                    var normal = new Angle(MouseCoords.Position - intersect.Center).GetCardinalDir().ToVec();

                    // round coords to center of tile
                    var tileIndices     = closest.WorldToTile(intersect.Center);
                    var tileCenterLocal = closest.GridTileToLocal(tileIndices);
                    var tileCenterWorld = tileCenterLocal.ToWorld(pManager.MapManager).Position;

                    // move mouse one tile out along normal
                    var newTilePos = tileCenterWorld + normal * closest.TileSize;
                    MouseCoords = new GridCoordinates(closest.WorldToLocal(newTilePos), closest.Index);
                }
                //else free place
            }


            CurrentTile = mapGrid.GetTileRef(MouseCoords);
            float tileSize = mapGrid.TileSize; //convert from ushort to float

            GridDistancing = tileSize;

            if (pManager.CurrentPermission.IsTile)
            {
                if (!mapGrid.IsDefaultGrid)
                {
                    MouseCoords = new GridCoordinates(CurrentTile.X + tileSize / 2,
                                                      CurrentTile.Y + tileSize / 2,
                                                      MouseCoords.GridID);
                }
                // else we don't modify coords
            }
            else
            {
                MouseCoords = new GridCoordinates(CurrentTile.X + tileSize / 2 + pManager.PlacementOffset.X,
                                                  CurrentTile.Y + tileSize / 2 + pManager.PlacementOffset.Y,
                                                  MouseCoords.GridID);
            }
        }
        private void HandleEntityState(IComponentManager compMan, IEntity entity, EntityState?curState,
                                       EntityState?nextState)
        {
            var compStateWork = new Dictionary <uint, (ComponentState?curState, ComponentState?nextState)>();
            var entityUid     = entity.Uid;

            if (curState?.ComponentChanges != null)
            {
                foreach (var compChange in curState.ComponentChanges)
                {
                    if (compChange.Deleted)
                    {
                        if (compMan.TryGetComponent(entityUid, compChange.NetID, out var comp))
                        {
                            compMan.RemoveComponent(entityUid, comp);
                        }
                    }
                    else
                    {
                        if (compMan.HasComponent(entityUid, compChange.NetID))
                        {
                            continue;
                        }

                        var newComp = (Component)_compFactory.GetComponent(compChange.ComponentName !);
                        newComp.Owner = entity;
                        compMan.AddComponent(entity, newComp, true);
                    }
                }
            }

            if (curState?.ComponentStates != null)
            {
                foreach (var compState in curState.ComponentStates)
                {
                    compStateWork[compState.NetID] = (compState, null);
                }
            }

            if (nextState?.ComponentStates != null)
            {
                foreach (var compState in nextState.ComponentStates)
                {
                    if (compStateWork.TryGetValue(compState.NetID, out var state))
                    {
                        compStateWork[compState.NetID] = (state.curState, compState);
                    }
                    else
                    {
                        compStateWork[compState.NetID] = (null, compState);
                    }
                }
            }

            foreach (var(netId, (cur, next)) in compStateWork)
            {
                if (compMan.TryGetComponent(entityUid, netId, out var component))
                {
                    try
                    {
                        component.HandleComponentState(cur, next);
                    }
                    catch (Exception e)
                    {
                        var wrapper = new ComponentStateApplyException(
                            $"Failed to apply comp state: entity={component.Owner}, comp={component.Name}", e);
#if EXCEPTION_TOLERANCE
                        _runtimeLog.LogException(wrapper, "Component state apply");
#else
                        throw wrapper;
#endif
                    }
                }
                else
                {
                    // The component can be null here due to interp.
                    // Because the NEXT state will have a new component, but this one doesn't yet.
                    // That's fine though.
                    if (cur == null)
                    {
                        continue;
                    }

                    var eUid = entityUid;
                    var eRegisteredNetUidName = _compFactory.GetRegistration(netId).Name;
                    DebugTools.Assert(
                        $"Component does not exist for state: entUid={eUid}, expectedNetId={netId}, expectedName={eRegisteredNetUidName}");
                }
            }
        }
            public void ProcessPackets()
            {
                while (_messageChannel.Reader.TryRead(out var item))
                {
                    switch (item)
                    {
                    case ConnectMessage connect:
                    {
                        DebugTools.Assert(IsServer);

                        async void DoConnect()
                        {
                            var writer = connect.ChannelWriter;

                            var uid       = _genConnectionUid();
                            var sessionId = new NetUserId(Guid.NewGuid());
                            var userName  = $"integration_{uid}";

                            var args = await OnConnecting(
                                new IPEndPoint(IPAddress.IPv6Loopback, 0),
                                sessionId,
                                userName,
                                LoginType.Guest);

                            if (args.IsDenied)
                            {
                                writer.TryWrite(new DeniedConnectMessage());
                                return;
                            }

                            writer.TryWrite(new ConfirmConnectMessage(uid, sessionId, userName));
                            var channel = new IntegrationNetChannel(this, connect.ChannelWriter, uid, sessionId,
                                                                    connect.Uid, userName);

                            _channels.Add(uid, channel);
                            Connected?.Invoke(this, new NetChannelArgs(channel));
                        }

                        DoConnect();

                        break;
                    }

                    case DataMessage data:
                    {
                        IntegrationNetChannel?channel;
                        if (IsServer)
                        {
                            if (!_channels.TryGetValue(data.Connection, out channel))
                            {
                                continue;
                            }
                        }
                        else
                        {
                            if (ServerChannel == null || data.Connection != ServerChannel.ConnectionUid)
                            {
                                continue;
                            }

                            channel = ServerChannel;
                        }

                        var message = data.Message;
                        message.MsgChannel = channel;
                        if (_callbacks.TryGetValue(message.GetType(), out var callback))
                        {
                            callback(message);
                        }

                        break;
                    }

                    case DisconnectMessage disconnect:
                    {
                        if (IsServer)
                        {
                            if (_channels.TryGetValue(disconnect.Connection, out var channel))
                            {
                                Disconnect?.Invoke(this, new NetDisconnectedArgs(channel, string.Empty));

                                _channels.Remove(disconnect.Connection);
                            }
                        }
                        else
                        {
                            _channels.Clear();
                        }

                        break;
                    }

                    case DeniedConnectMessage _:
                    {
                        DebugTools.Assert(IsClient);

                        ConnectFailed?.Invoke(this, new NetConnectFailArgs("I didn't implement a deny reason!"));
                        break;
                    }

                    case ConfirmConnectMessage confirm:
                    {
                        DebugTools.Assert(IsClient);

                        var channel = new IntegrationNetChannel(this, NextConnectChannel !, _clientConnectingUid,
                                                                confirm.UserId, confirm.AssignedUid, confirm.AssignedName);

                        _channels.Add(channel.ConnectionUid, channel);

                        Connected?.Invoke(this, new NetChannelArgs(channel));
                        break;
                    }

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }
Example #5
0
        /// <summary>
        ///     Recalculate line dimensions and where it has line breaks for word wrapping.
        /// </summary>
        /// <param name="font">The font being used for display.</param>
        /// <param name="maxSizeX">The maximum horizontal size of the container of this entry.</param>
        /// <param name="uiScale"></param>
        public void Update(Font font, float maxSizeX, float uiScale)
        {
            // This method is gonna suck due to complexity.
            // Bear with me here.
            // I am so deeply sorry for the person adding stuff to this in the future.
            Height = font.GetHeight(uiScale);
            LineBreaks.Clear();

            var maxUsedWidth = 0f;
            // Index we put into the LineBreaks list when a line break should occur.
            var breakIndexCounter = 0;

            // If the CURRENT processing word ends up too long, this is the index to put a line break.
            (int index, float lineSize)? wordStartBreakIndex = null;
            // Word size in pixels.
            var wordSizePixels = 0;
            // The horizontal position of the text cursor.
            var posX     = 0;
            var lastChar = 'A';

            // If a word is larger than maxSizeX, we split it.
            // We need to keep track of some data to split it into two words.
            (int breakIndex, int wordSizePixels)? forceSplitData = null;
            // Go over every text tag.
            // We treat multiple text tags as one continuous one.
            // So changing color inside a single word doesn't create a word break boundary.
            foreach (var tag in Message.Tags)
            {
                // For now we can ignore every entry that isn't a text tag because those are only color related.
                // For now.
                if (!(tag is FormattedMessage.TagText tagText))
                {
                    continue;
                }

                var text = tagText.Text;
                // And go over every character.
                for (var i = 0; i < text.Length; i++, breakIndexCounter++)
                {
                    var chr = text[i];

                    if (IsWordBoundary(lastChar, chr) || chr == '\n')
                    {
                        // Word boundary means we know where the word ends.
                        if (posX > maxSizeX && lastChar != ' ')
                        {
                            DebugTools.Assert(wordStartBreakIndex.HasValue,
                                              "wordStartBreakIndex can only be null if the word begins at a new line, in which case this branch shouldn't be reached as the word would be split due to being longer than a single line.");
                            // We ran into a word boundary and the word is too big to fit the previous line.
                            // So we insert the line break BEFORE the last word.
                            LineBreaks.Add(wordStartBreakIndex !.Value.index);
                            Height      += font.GetLineHeight(uiScale);
                            maxUsedWidth = Math.Max(maxUsedWidth, wordStartBreakIndex.Value.lineSize);
                            posX         = wordSizePixels;
                        }

                        // Start a new word since we hit a word boundary.
                        //wordSize = 0;
                        wordSizePixels      = 0;
                        wordStartBreakIndex = (breakIndexCounter, posX);
                        forceSplitData      = null;

                        // Just manually handle newlines.
                        if (chr == '\n')
                        {
                            LineBreaks.Add(breakIndexCounter);
                            Height             += font.GetLineHeight(uiScale);
                            maxUsedWidth        = Math.Max(maxUsedWidth, posX);
                            posX                = 0;
                            lastChar            = chr;
                            wordStartBreakIndex = null;
                            continue;
                        }
                    }

                    // Uh just skip unknown characters I guess.
                    if (!font.TryGetCharMetrics(chr, uiScale, out var metrics))
                    {
                        lastChar = chr;
                        continue;
                    }

                    // Increase word size and such with the current character.
                    var oldWordSizePixels = wordSizePixels;
                    wordSizePixels += metrics.Advance;
                    // TODO: Theoretically, does it make sense to break after the glyph's width instead of its advance?
                    //   It might result in some more tight packing but I doubt it'd be noticeable.
                    //   Also definitely even more complex to implement.
                    posX += metrics.Advance;

                    if (posX > maxSizeX)
                    {
                        if (!forceSplitData.HasValue)
                        {
                            forceSplitData = (breakIndexCounter, oldWordSizePixels);
                        }

                        // Oh hey we get to break a word that doesn't fit on a single line.
                        if (wordSizePixels > maxSizeX)
                        {
                            var(breakIndex, splitWordSize) = forceSplitData.Value;
                            if (splitWordSize == 0)
                            {
                                // Happens if there's literally not enough space for a single character so uh...
                                // Yeah just don't.
                                return;
                            }

                            // Reset forceSplitData so that we can split again if necessary.
                            forceSplitData = null;
                            LineBreaks.Add(breakIndex);
                            Height             += font.GetLineHeight(uiScale);
                            wordSizePixels     -= splitWordSize;
                            wordStartBreakIndex = null;
                            maxUsedWidth        = Math.Max(maxUsedWidth, maxSizeX);
                            posX = wordSizePixels;
                        }
                    }

                    lastChar = chr;
                }
            }

            // This needs to happen because word wrapping doesn't get checked for the last word.
            if (posX > maxSizeX)
            {
                DebugTools.Assert(wordStartBreakIndex.HasValue,
                                  "wordStartBreakIndex can only be null if the word begins at a new line, in which case this branch shouldn't be reached as the word would be split due to being longer than a single line.");
                LineBreaks.Add(wordStartBreakIndex !.Value.index);
                Height      += font.GetLineHeight(uiScale);
                maxUsedWidth = Math.Max(maxUsedWidth, wordStartBreakIndex.Value.lineSize);
            }
            else
            {
                maxUsedWidth = Math.Max(maxUsedWidth, posX);
            }

            Width = (int)maxUsedWidth;
        }
Example #6
0
        private void _onChatBoxTextSubmitted(ChatBox chatBox, string text)
        {
            DebugTools.Assert(chatBox == _currentChatBox);

            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            // Check if message is longer than the character limit
            if (text.Length > _maxMessageLength)
            {
                string locWarning = Loc.GetString("Your message exceeds {0} character limit", _maxMessageLength);
                _currentChatBox?.AddLine(locWarning, ChatChannel.Server, Color.Orange);
                _currentChatBox.ClearOnEnter = false;   // The text shouldn't be cleared if it hasn't been sent
                return;
            }

            switch (text[0])
            {
            case ConCmdSlash:
            {
                // run locally
                var conInput = text.Substring(1);
                _console.ProcessCommand(conInput);
                break;
            }

            case OOCAlias:
            {
                var conInput = text.Substring(1);
                if (string.IsNullOrWhiteSpace(conInput))
                {
                    return;
                }
                _console.ProcessCommand($"ooc \"{CommandParsing.Escape(conInput)}\"");
                break;
            }

            case AdminChatAlias:
            {
                var conInput = text.Substring(1);
                if (string.IsNullOrWhiteSpace(conInput))
                {
                    return;
                }
                if (_groupController.CanCommand("asay"))
                {
                    _console.ProcessCommand($"asay \"{CommandParsing.Escape(conInput)}\"");
                }
                else
                {
                    _console.ProcessCommand($"ooc \"{CommandParsing.Escape(conInput)}\"");
                }
                break;
            }

            case MeAlias:
            {
                var conInput = text.Substring(1);
                if (string.IsNullOrWhiteSpace(conInput))
                {
                    return;
                }
                _console.ProcessCommand($"me \"{CommandParsing.Escape(conInput)}\"");
                break;
            }

            default:
            {
                var conInput = _currentChatBox.DefaultChatFormat != null
                        ? string.Format(_currentChatBox.DefaultChatFormat, CommandParsing.Escape(text))
                        : text;

                _console.ProcessCommand(conInput);
                break;
            }
            }
        }
Example #7
0
        public VVPropEditor SetProperty(ViewVariablesBlobMembers.MemberData member)
        {
            NameLabel.Text = member.Name;
            var type = Type.GetType(member.Type);

            _bottomLabel.Text = $"Type: {member.TypePretty}";
            VVPropEditor editor;

            if (type == null || !_robustSerializer.CanSerialize(type))
            {
                // Type is server-side only.
                // Info whether it's reference or value type can be figured out from the sent value.
                if (type?.IsValueType == true || member.Value is ViewVariablesBlobMembers.ServerValueTypeToken)
                {
                    // Value type, just display it stringified read-only.
                    editor = new VVPropEditorDummy();
                }
                else
                {
                    // Has to be a reference type at this point.
                    DebugTools.Assert(member.Value is ViewVariablesBlobMembers.ReferenceToken || member.Value == null || type?.IsClass == true || type?.IsInterface == true);
                    editor = _viewVariablesManager.PropertyFor(type ?? typeof(object));
                }
            }
            else
            {
                editor = _viewVariablesManager.PropertyFor(type);
            }

            var view = editor.Initialize(member.Value, !member.Editable);

            if (!view.HorizontalExpand)
            {
                NameLabel.HorizontalExpand = true;
            }

            NameLabel.MinSize = new Vector2(150, 0);
            TopContainer.AddChild(view);

            /*
             * _beingEdited = obj;
             * _editedProperty = propertyInfo;
             * DebugTools.Assert(propertyInfo.DeclaringType != null);
             * DebugTools.Assert(propertyInfo.DeclaringType.IsInstanceOfType(obj));
             *
             * DebugTools.Assert(ViewVariablesUtility.TryGetViewVariablesAccess(fieldInfo, out var access));
             * NameLabel.Text = propertyInfo.Name;
             *
             * _bottomLabel.Text = $"Type: {propertyInfo.PropertyType.FullName}";
             *
             * var editor = vvm.PropertyFor(propertyInfo.PropertyType);
             * var value = propertyInfo.GetValue(obj);
             *
             * var view = editor.Initialize(value, access != VVAccess.ReadWrite);
             * if (view.SizeFlagsHorizontal != SizeFlags.FillExpand)
             * {
             *  NameLabel.HorizontalExpand = true;
             * }
             * NameLabel.MinSize = new Vector2(150, 0);
             * TopContainer.AddChild(view);
             * editor.OnValueChanged += v => { propertyInfo.SetValue(obj, v); };
             */
            return(editor);
        }
Example #8
0
        /// <summary>
        ///     Have a certain chance to return a boolean.
        /// </summary>
        /// <param name="random">The random instance to run on.</param>
        /// <param name="chance">The chance to pass, from 0 to 1.</param>
        public static bool Prob(this IRobustRandom random, float chance)
        {
            DebugTools.Assert(chance <= 1 && chance >= 0, "Chance must be in the range 0-1");

            return(random.NextDouble() <= chance);
        }
Example #9
0
 private void OnConnectFailed(object?sender, NetConnectFailArgs args)
 {
     DebugTools.Assert(RunLevel == ClientRunLevel.Connecting);
     Reset();
 }
        private async Task _moveToPage(int page)
        {
            // TODO: Network overhead optimization potential:
            // Right now, (in NETWORK mode) if I request page 5, it has to cache all 5 pages,
            // now the server obviously (enumerator and all that) has to TOO, but whatever.
            // The waste is that all pages are also SENT, even though we only really care about the fifth at the moment.
            // Because the cache can't have holes (and also the network system is too simplistic at the moment,
            // if you do do a by-page pull and you're way too far along,
            // you'll just get 0 elements which doesn't tell you where it ended but that's kinda necessary.
            if (page < 0)
            {
                page = 0;
            }

            if (page > HighestKnownPage || (!_ended && page == HighestKnownPage))
            {
                if (_ended)
                {
                    // The requested page is higher than the highest page we have (and we know this because the enumerator ended).
                    page = HighestKnownPage;
                }
                else
                {
                    // The page is higher than the highest page we have, but the enumerator hasn't ended yet so that might be valid.
                    // Gotta get more data.
                    await _cacheTo((page + 1) *ElementsPerPage);

                    if (page > HighestKnownPage)
                    {
                        // We tried, but the enumerator ended before we reached our goal.
                        // Oh well.
                        DebugTools.Assert(_ended);
                        page = HighestKnownPage;
                    }
                }
            }

            _elementsVBox.DisposeAllChildren();

            for (var i = page * ElementsPerPage; i < ElementsPerPage * (page + 1) && i < _cache.Count; i++)
            {
                var element = _cache[i];
                ViewVariablesPropertyEditor editor;
                if (element == null)
                {
                    editor = new ViewVariablesPropertyEditorDummy();
                }
                else
                {
                    var type = element.GetType();
                    editor = Instance.ViewVariablesManager.PropertyFor(type);
                }

                var control = editor.Initialize(element, true);
                if (editor is ViewVariablesPropertyEditorReference refEditor)
                {
                    if (_networked)
                    {
                        var iSafe = i;
                        refEditor.OnPressed += () =>
                                               Instance.ViewVariablesManager.OpenVV(
                            new ViewVariablesSessionRelativeSelector(Instance.Session.SessionId,
                                                                     new object[] { new ViewVariablesEnumerableIndexSelector(iSafe), }));
                    }
                    else
                    {
                        refEditor.OnPressed += () => Instance.ViewVariablesManager.OpenVV(element);
                    }
                }
                _elementsVBox.AddChild(control);
            }

            _page = page;

            _updateControls();
        }