Beispiel #1
0
        static void DrawModalWindow(string text, Func <bool> shouldShow, Action onCancel, string cancelButtonLabel)
        {
            string textWithEllipsis = $"{text}{MpUI.FixedEllipsis()}";
            float  textWidth        = Text.CalcSize(textWithEllipsis).x;
            float  windowWidth      = Math.Max(240f, textWidth + 40f);
            float  windowHeight     = onCancel != null ? 100f : 75f;
            var    rect             = new Rect(0, 0, windowWidth, windowHeight).CenterOn(new Rect(0, 0, UI.screenWidth, UI.screenHeight));

            Find.WindowStack.ImmediateWindow(ModalWindowId, rect, WindowLayer.Super, () =>
            {
                if (!shouldShow())
                {
                    return;
                }

                var textRect = rect.AtZero();
                if (onCancel != null)
                {
                    textRect.yMin   += 5f;
                    textRect.height -= 50f;
                }

                Text.Anchor = TextAnchor.MiddleCenter;
                Text.Font   = GameFont.Small;
                Widgets.Label(textRect, text);
                Text.Anchor = TextAnchor.UpperLeft;

                var cancelBtn = new Rect(0, textRect.yMax, 100f, 35f).CenteredOnXIn(textRect);

                if (onCancel != null && Widgets.ButtonText(cancelBtn, cancelButtonLabel))
                {
                    onCancel();
                }
            }, absorbInputAroundWindow: true);
        }
Beispiel #2
0
        public void HandleJoinData(ByteReader data)
        {
            Multiplayer.session.gameName = data.ReadString();
            Multiplayer.session.playerId = data.ReadInt32();

            var remoteInfo = new RemoteData
            {
                remoteRwVersion = data.ReadString(),
                remoteMpVersion = data.ReadString(),
                remoteAddress   = Multiplayer.session.address,
                remotePort      = Multiplayer.session.port,
                remoteSteamHost = Multiplayer.session.steamHost
            };

            var defDiff  = false;
            var defsData = new ByteReader(data.ReadPrefixedBytes());

            foreach (var local in MultiplayerData.localDefInfos)
            {
                var status = (DefCheckStatus)defsData.ReadByte();
                local.Value.status = status;

                if (status != DefCheckStatus.Ok)
                {
                    defDiff = true;
                }
            }

            JoinData.ReadServerData(data.ReadPrefixedBytes(), remoteInfo);

            OnMainThread.Schedule(Complete, 0.3f);

            void Complete()
            {
                if (JoinData.CompareToLocal(remoteInfo) && !defDiff)
                {
                    StartDownloading();
                    return;
                }

                if (defDiff)
                {
                    Multiplayer.StopMultiplayer();
                }

                var connectingWindow = Find.WindowStack.WindowOfType <BaseConnectingWindow>();

                MpUI.ClearWindowStack();

                var defDiffStr = "\n\n" + MultiplayerData.localDefInfos
                                 .Where(kv => kv.Value.status != DefCheckStatus.Ok)
                                 .Take(10)
                                 .Join(kv => $"{kv.Key}: {kv.Value.status}", "\n");

                Find.WindowStack.Add(new JoinDataWindow(remoteInfo)
                {
                    connectAnywayDisabled = defDiff ? "MpMismatchDefsDiff".Translate() + defDiffStr : null,
                    connectAnywayCallback = () =>
                    {
                        Find.WindowStack.Add(connectingWindow);
                        StartDownloading();
                    }
                });

                void StartDownloading()
                {
                    connection.Send(Packets.Client_WorldRequest);
                    subState = JoiningState.Waiting;
                }
            }
        }
Beispiel #3
0
        private void DrawChat(Rect inRect)
        {
            MpUI.TryUnfocusCurrentNamedControl(this);

            Rect outRect  = new Rect(0f, 0f, inRect.width, inRect.height - 30f);
            Rect viewRect = new Rect(0f, 0f, inRect.width - 16f, messagesHeight + 10f);

            float width     = viewRect.width;
            Rect  textField = new Rect(20f, outRect.yMax + 5f, width - 70f, 25f);

            GUI.BeginGroup(inRect);

            GUI.SetNextControlName("chat_input");
            currentMsg = Widgets.TextField(textField, currentMsg);
            currentMsg = currentMsg.Substring(0, Math.Min(currentMsg.Length, ServerPlayingState.MaxChatMsgLength));

            Widgets.BeginScrollView(outRect, ref chatScroll, viewRect);

            float yPos = 0;

            GUI.color = Color.white;

            int i = 0;

            foreach (ChatMsg msg in Multiplayer.session.messages)
            {
                float height    = Text.CalcHeight(msg.Msg, width - 20f);
                float textWidth = Text.CalcSize(msg.Msg).x + 15;
                Rect  msgRect   = new Rect(20f, yPos, width - 20f, height);

                if (Mouse.IsOver(msgRect))
                {
                    GUI.DrawTexture(msgRect, SelectedMsg);

                    if (msg.TimeStamp != null)
                    {
                        TooltipHandler.TipRegion(msgRect, msg.TimeStamp.ToString("yyyy-MM-dd HH:mm"));
                    }
                }

                Color cursorColor = GUI.skin.settings.cursorColor;
                GUI.skin.settings.cursorColor = new Color(0, 0, 0, 0);

                msgRect.width = Math.Min(textWidth, msgRect.width);
                bool mouseOver = Mouse.IsOver(msgRect);

                if (mouseOver && msg.Clickable)
                {
                    GUI.color = new Color(0.8f, 0.8f, 1);
                }

                GUI.SetNextControlName("chat_msg_" + i++);
                Widgets.TextArea(msgRect, msg.Msg, true);

                if (mouseOver && msg.Clickable)
                {
                    GUI.color = Color.white;

                    if (Event.current.type == EventType.MouseUp)
                    {
                        msg.Click();
                    }
                }

                GUI.skin.settings.cursorColor = cursorColor;

                yPos += height;
            }

            if (Event.current.type == EventType.Layout)
            {
                messagesHeight = yPos;
            }

            Widgets.EndScrollView();

            if (Widgets.ButtonText(new Rect(textField.xMax + 5f, textField.y, 55f, textField.height), "MpChatSend".Translate()))
            {
                SendMsg();
            }

            GUI.EndGroup();

            if (!hasBeenFocused && Event.current.type == EventType.Repaint)
            {
                chatScroll.y = messagesHeight;

                GUI.FocusControl("chat_input");
                TextEditor editor = (TextEditor)GUIUtility.GetStateObject(typeof(TextEditor), GUIUtility.keyboardControl);
                editor.OnFocus();
                editor.MoveTextEnd();
                hasBeenFocused = true;
            }
        }
Beispiel #4
0
        private void DrawLan(Rect inRect)
        {
            using (MpStyle.Set(TextAnchor.MiddleCenter))
                Widgets.Label(new Rect(inRect.x, 8f, inRect.width, 40), "MpLanSearching".Translate() + MpUI.FixedEllipsis());
            inRect.yMin += 40f;

            float margin  = 100;
            Rect  outRect = new Rect(margin, inRect.yMin + 10, inRect.width - 2 * margin, inRect.height - 20);

            float height   = servers.Count * 40;
            Rect  viewRect = new Rect(0, 0, outRect.width - 16f, height);

            Widgets.BeginScrollView(outRect, ref lanScroll, viewRect, true);

            float y = 0;
            int   i = 0;

            foreach (LanServer server in servers)
            {
                Rect entryRect = new Rect(0, y, viewRect.width, 40);
                if (i % 2 == 0)
                {
                    Widgets.DrawAltRect(entryRect);
                }

                using (MpStyle.Set(TextAnchor.MiddleLeft))
                    Widgets.Label(entryRect.Right(5), "" + server.endpoint);

                Rect playButton = new Rect(entryRect.xMax - 75, entryRect.y + 5, 70, 40 - 10);
                if (Widgets.ButtonText(playButton, ">>"))
                {
                    Close(false);
                    Log.Message("Connecting to lan server");

                    var address = server.endpoint.Address.ToString();
                    var port    = server.endpoint.Port;
                    ClientUtil.TryConnectWithWindow(address, port);
                }

                y += entryRect.height;
                i++;
            }

            Widgets.EndScrollView();
        }
Beispiel #5
0
        private void DrawInfoButtons()
        {
            float x = 0;

            const string WebsiteLink = "https://rimworldmultiplayer.com";
            const string DiscordLink = "https://discord.gg/n5E2cb2Y4Z";

            bool Button(Texture2D icon, string labelKey, string tip, Color baseIconColor, float iconSize = 24f)
            {
                var label      = labelKey.Translate();
                var labelWidth = Text.CalcSize(label).x;
                var btn        = new Rect(x, 0, 24 + 1 + labelWidth, 24);
                var mouseOver  = Mouse.IsOver(btn);

                MouseoverSounds.DoRegion(btn);
                TooltipHandler.TipRegion(btn, tip);

                using (MpStyle.Set(mouseOver ? Color.yellow : baseIconColor))
                {
                    GUI.DrawTexture(new Rect(x += (24 - iconSize) / 2, (24 - iconSize) / 2, iconSize, iconSize), icon);
                    x += 24;
                }

                x += 1;

                using (MpStyle.Set(mouseOver ? Color.yellow : Color.white))
                    using (MpStyle.Set(TextAnchor.MiddleCenter))
                        MpUI.Label(new Rect(x, 0, labelWidth, 24f), labelKey.Translate());

                x += labelWidth;
                x += 10;

                return(Widgets.ButtonInvisible(btn));
            }

            const string compatLabel     = "MpCompatibilityButton";
            const string compatLabelDesc = "MpCompatibilityButtonDesc";

            if (Button(TexButton.ToggleLog, compatLabel, MpUtil.TranslateWithDoubleNewLines(compatLabelDesc, 2), Color.grey, 20))
            {
                Find.WindowStack.Add(new ModCompatWindow(null, false, false, null));
            }

            if (Button(MultiplayerStatic.WebsiteIcon, "MpWebsiteButton", "MpLinkButtonDesc".Translate() + " " + WebsiteLink, Color.grey, 20))
            {
                Application.OpenURL(WebsiteLink);
            }

            if (Button(MultiplayerStatic.DiscordIcon, "MpDiscordButton", "MpLinkButtonDesc".Translate() + " " + DiscordLink, Color.white))
            {
                Application.OpenURL(DiscordLink);
            }

            if (false) // todo
            {
                Button(
                    TexButton.NewItem,
                    "MpActiveConfigsButton",
                    "MpActiveConfigsButtonDesc1".Translate("Player's game") + "\n\n" + "MpActiveConfigsButtonDesc2".Translate(),
                    Color.grey,
                    20
                    );
            }
        }
Beispiel #6
0
        static void DrawTimelineWindow()
        {
            Rect rect = new Rect(0, 30f, UI.screenWidth - TimelineMargin * 2, TimelineHeight);

            Widgets.DrawBoxSolid(rect, new Color(0.6f, 0.6f, 0.6f, 0.8f));

            int timerStart = Multiplayer.session.replayTimerStart >= 0 ?
                             Multiplayer.session.replayTimerStart : Multiplayer.session.dataSnapshot.cachedAtTime;

            int timerEnd = Multiplayer.session.replayTimerEnd >= 0 ?
                           Multiplayer.session.replayTimerEnd : TickPatch.tickUntil;

            int timeLen = timerEnd - timerStart;

            MpUI.DrawRotatedLine(new Vector2(rect.xMin + 2f, rect.center.y), TimelineHeight, 20f, 90f, Color.white);
            MpUI.DrawRotatedLine(new Vector2(rect.xMax - 2f, rect.center.y), TimelineHeight, 20f, 90f, Color.white);

            float progress  = (TickPatch.Timer - timerStart) / (float)timeLen;
            float progressX = rect.xMin + progress * rect.width;

            MpUI.DrawRotatedLine(new Vector2((int)progressX, rect.center.y), TimelineHeight, 20f, 90f, Color.green);

            float       mouseX     = Event.current.mousePosition.x;
            ReplayEvent mouseEvent = null;

            foreach (var ev in Multiplayer.session.events)
            {
                if (ev.time < timerStart || ev.time > timerEnd)
                {
                    continue;
                }

                var pointX = rect.xMin + (ev.time - timerStart) / (float)timeLen * rect.width;

                //GUI.DrawTexture(new Rect(pointX - 12f, rect.yMin - 24f, 24f, 24f), texture);
                MpUI.DrawRotatedLine(new Vector2(pointX, rect.center.y), TimelineHeight, 20f, 90f, ev.color);

                if (Mouse.IsOver(rect) && Math.Abs(mouseX - pointX) < 10)
                {
                    mouseX     = pointX;
                    mouseEvent = ev;
                }
            }

            if (Mouse.IsOver(rect))
            {
                float mouseProgress = (mouseX - rect.xMin) / rect.width;
                int   mouseTimer    = timerStart + (int)(timeLen * mouseProgress);

                MpUI.DrawRotatedLine(new Vector2(mouseX, rect.center.y), TimelineHeight, 15f, 90f, Color.blue);

                if (Event.current.type == EventType.MouseUp)
                {
                    TickPatch.SetSimulation(mouseTimer, canESC: true);

                    if (mouseTimer < TickPatch.Timer)
                    {
                        ClientJoiningState.ReloadGame(Multiplayer.session.dataSnapshot.mapData.Keys.ToList(), false, Multiplayer.GameComp.asyncTime);
                    }
                }

                if (Event.current.isMouse)
                {
                    Event.current.Use();
                }

                string tooltip = $"Tick {mouseTimer}";
                if (mouseEvent != null)
                {
                    tooltip = $"{mouseEvent.name}\n{tooltip}";
                }

                const int TickTipId = 215462143;

                TooltipHandler.TipRegion(rect, new TipSignal(tooltip, TickTipId));
                // Remove delay between the mouseover and showing
                if (TooltipHandler.activeTips.TryGetValue(TickTipId, out ActiveTip tip))
                {
                    tip.firstTriggerTime = 0;
                }
            }

            if (TickPatch.Simulating)
            {
                float pct         = (TickPatch.simulating.target.Value - timerStart) / (float)timeLen;
                float simulateToX = rect.xMin + rect.width * pct;
                MpUI.DrawRotatedLine(new Vector2(simulateToX, rect.center.y), TimelineHeight, 15f, 90f, Color.yellow);
            }
        }