private static void DisplayEntities() { if (!Imgui.TreeNode("Parties")) { return; } if (CoopServer.Instance?.Persistence?.EntityManager == null) { Imgui.Text("No coop server running."); } else { EntityManager manager = CoopServer.Instance.Persistence.EntityManager; Imgui.Columns(2); Imgui.Separator(); Imgui.Text("ID"); foreach (RailEntityServer entity in manager.Parties) { Imgui.Text(entity.Id.ToString()); } Imgui.NextColumn(); Imgui.Text("Entity"); Imgui.Separator(); foreach (RailEntityServer entity in manager.Parties) { Imgui.Text(entity.ToString()); } Imgui.Columns(); } Imgui.TreePop(); }
protected override void OnApplicationTick(float dt) { if (craftingState != null) { if (Input.DebugInput.IsHotKeyPressed("Copy")) { Input.SetClipboardText(craftingState.CraftingLogic.GetXmlCodeForCurrentItem(craftingState.CraftingLogic.GetCurrentCraftedItemObject())); InformationManager.DisplayMessage(new InformationMessage("design copied to clipboard")); } if (Input.DebugInput.IsHotKeyPressed("Paste")) { // alas, this doesn't help: // craftingState.CraftingLogic.SwitchToPiece(WeaponDesignElement.CreateUsablePiece(craftingState.CraftingLogic.CurrentCraftingTemplate.Pieces.First(p => p.StringId == "xxx"), scalePercentage)); // craftingScreen.OnCraftingLogicRefreshed(); // gotta hack it, see WeaponDesignVM.ExecuteRandomize() for the reference var craftingVM = ScreenManager.TopScreen.GetFieldValue <CraftingVM>("_dataSource"); // TopScreen us SandBox.GauntletUI.CraftingGauntletScreen in crafting state if (craftingVM.IsInCraftingMode) { var weaponDesignVM = craftingVM.WeaponDesign; var xmlDocument = new XmlDocument(); try { xmlDocument.LoadXml(Input.GetClipboardText().ToLowerInvariant()); // I know that XML is case-sensitive, but that's what TaleWorlds do in character appearance editor foreach (XmlNode pieceNode in xmlDocument.GetElementsByTagName("piece")) { var pieceType = (CraftingPiece.PieceTypes)Enum.Parse(typeof(CraftingPiece.PieceTypes), pieceNode.Attributes["type"].Value, ignoreCase: true); var pieceId = pieceNode.Attributes["id"].Value; var pieceCraftPartVM = GetCraftPartVM(weaponDesignVM, pieceType, pieceId); pieceCraftPartVM.CraftingPiece.ScalePercentage = int.Parse(pieceNode.Attributes["scale_factor"]?.Value ?? "100"); // apparently the 2nd argument to WeaponDesignVM.OnSetItemPart() has no effect beyond the UI weaponDesignVM.InvokeMethod("OnSetItemPart", pieceCraftPartVM, 0, false); } weaponDesignVM.SetFieldValue("_updatePiece", false); weaponDesignVM.RefreshItem(); weaponDesignVM.InvokeMethod("AddHistoryKey"); weaponDesignVM.SetFieldValue("_updatePiece", true); InformationManager.DisplayMessage(new InformationMessage("design pasted from clipboard")); } catch { } } } #if DEBUG // reference: Crafting.GetXmlCodeForCurrentItem() // opted for more complete representation of internals, as such weaponDesignElement.IsValid is ignored and // weaponDesignElement.CraftingPiece.StringId may be null - this will crash in such a weird way (in actual C code of Imgui // I reckon) that dnSpy is not even able to catch and you can't check backtrace etc Imgui.BeginMainThreadScope(); Imgui.Begin("CraftingLogic.SelectedPieces"); Imgui.Text($"value={craftingState.CraftingLogic.GetCurrentCraftedItemObject().Value}"); Imgui.Columns(3); foreach (var weaponDesignElement in craftingState.CraftingLogic.SelectedPieces) { Imgui.Text(weaponDesignElement.CraftingPiece.PieceType.ToString()); Imgui.NextColumn(); Imgui.Text(weaponDesignElement.CraftingPiece.StringId ?? "null"); Imgui.NextColumn(); Imgui.Text($"{weaponDesignElement.ScalePercentage}%%"); Imgui.NextColumn(); } Imgui.End(); Imgui.EndMainThreadScope(); #endif } }
private static void DisplayMethodRegistry() { if (!Imgui.TreeNode("Patched method registry")) { return; } foreach (KeyValuePair <MethodId, MethodAccess> registrar in MethodRegistry.IdToMethod) { MethodAccess access = registrar.Value; string sName = $"{registrar.Key} {access}"; if (!Imgui.TreeNode(sName)) { continue; } #if DEBUG Imgui.Columns(2); Imgui.Separator(); Imgui.Text("Instance"); // first line: global handler Imgui.Text("global"); // instance specific handlers foreach (KeyValuePair <object, Action <object> > handler in access .InstanceSpecificHandlers) { Imgui.Text(handler.Key.ToString()); } Imgui.NextColumn(); Imgui.Text("Handler"); Imgui.Separator(); // first line: global handler Imgui.Text( access.GlobalHandler != null ? access.GlobalHandler.Target + "." + access.GlobalHandler.Method.Name : "-"); // instance specific handlers foreach (KeyValuePair <object, Action <object> > handler in access .InstanceSpecificHandlers) { Imgui.Text(handler.Value.Target + "." + handler.Value.Method.Name); } Imgui.Columns(); Imgui.TreePop(); #else DisplayDebugDisabledText(); #endif } Imgui.TreePop(); }
private static void DisplayPersistenceInfo() { List <SPeer> peers = new List <SPeer>(); if (CoopClient.Instance.Persistence != null) { RailClientPeer peer = CoopClient.Instance.Persistence.Peer; if (peer != null) { SPeer peerInfo = new SPeer(); peerInfo.Peer = peer; peerInfo.Type = SPeer.EType.ClientSide; peers.Add(peerInfo); } } if (CoopServer.Instance.Persistence != null) { foreach (RailServerPeer peer in CoopServer.Instance.Persistence.ConnectedClients) { SPeer peerInfo = new SPeer(); peerInfo.Peer = peer; peerInfo.Type = SPeer.EType.ServerSide; peers.Add(peerInfo); } } Imgui.Columns(5); Imgui.Text("Type"); peers.ForEach(p => Imgui.Text(p.Type.ToString())); Imgui.NextColumn(); Imgui.Text("Local tick"); peers.ForEach(p => Imgui.Text(p.Peer.LocalTick.ToString())); Imgui.NextColumn(); Imgui.Text("Latest remote tick"); peers.ForEach(p => Imgui.Text(p.Peer.RemoteClock.LatestRemote.ToString())); Imgui.NextColumn(); Imgui.Text("Estimated remote tick"); peers.ForEach(p => Imgui.Text(p.Peer.RemoteClock.EstimatedRemote.ToString())); Imgui.NextColumn(); Imgui.Text("LatestRemote - EstimatedRemote"); Imgui.Separator(); peers.ForEach(p => Imgui.Text($"{p.Slack}")); Imgui.Columns(); }
private static void DisplayClientRpcInfo() { if (!Imgui.TreeNode("Client synchronized method calls")) { return; } if (CoopClient.Instance?.Persistence?.RpcSyncHandlers == null) { Imgui.Text("Coop client not connected."); } else { RPCSyncHandlers manager = CoopClient.Instance?.Persistence?.RpcSyncHandlers; foreach (MethodCallSyncHandler handler in manager.Handlers) { if (!Imgui.TreeNode(handler.MethodAccess.ToString())) { continue; } #if DEBUG Imgui.Columns(2); Imgui.Separator(); Imgui.Text("Requested on"); foreach (MethodCallSyncHandler.Statistics.Trace trace in handler.Stats.History) { Imgui.Text(trace.Tick.ToString()); } Imgui.NextColumn(); Imgui.Text("Request"); Imgui.Separator(); foreach (MethodCallSyncHandler.Statistics.Trace trace in handler.Stats.History) { Imgui.Text(trace.Call.ToString()); } Imgui.Columns(); Imgui.TreePop(); #else DisplayDebugDisabledText(); #endif } } Imgui.TreePop(); }
private static void DisplayConnectionInfo() { if (!Imgui.TreeNode("Connectioninfo")) { return; } Server server = CoopServer.Instance.Current; GameSession session = CoopClient.Instance.Session; if (session.Connection == null) { Imgui.Text("Coop not running."); } else if (Imgui.TreeNode($"Client is {session.Connection.State}")) { Imgui.Columns(2); Imgui.Text("Ping"); Imgui.Text($"{session.Connection.Latency}"); Imgui.NextColumn(); Imgui.Text("Network"); Imgui.Separator(); Imgui.Text(session.Connection.Network.ToString()); Imgui.Columns(); Imgui.TreePop(); } if (server == null) { Imgui.Text("No coop server running."); } else if (Imgui.TreeNode( $"Server is {server.State.ToString()} with {server.ActiveConnections.Count}/{server.ActiveConfig.MaxPlayerCount} players.") ) { if (server.ServerType == Server.EType.Threaded) { double ticksPerFrame = server.AverageFrameTime.Ticks; int tickRate = (int)(TimeSpan.TicksPerSecond / ticksPerFrame); Imgui.Text($"Tickrate [Hz]: {tickRate}"); } Imgui.Text( $"LAN: {server.ActiveConfig.LanAddress}:{server.ActiveConfig.LanPort}"); Imgui.Text( $"WAN: {server.ActiveConfig.WanAddress}:{server.ActiveConfig.WanPort}"); Imgui.Text(""); Imgui.Columns(3); Imgui.Text("Ping"); server.ActiveConnections.ForEach(c => Imgui.Text($"{c.Latency}")); Imgui.NextColumn(); Imgui.Text("State"); server.ActiveConnections.ForEach(c => Imgui.Text(c.State.ToString())); Imgui.NextColumn(); Imgui.Text("Network"); Imgui.Separator(); server.ActiveConnections.ForEach(c => Imgui.Text(c.Network.ToString())); Imgui.Columns(); Imgui.TreePop(); } Imgui.Columns(); Imgui.TreePop(); }