Compare commits

...

51 Commits

Author SHA1 Message Date
Acruid
0ba2272cab Remove all dependencies from LocalizationManager.
Remove IoCManager calls from EntityPrototype.
Add missing using statements preventing EXCEPTION_TOLERANCE from building.
2021-02-11 00:39:12 -08:00
Acruid
2183cd7ca1 Massive Namespace Cleanup (#1544)
* Removed the Interfaces folder.
* All objects inside the GameObjects subfolders are now in the GameObjects namespace.
* Added a Resharper DotSettings file to mark the GameObjects subfolders as not providing namespaces.
* Simplified Robust.client.Graphics namespace.
* Automated remove redundant using statements.
2021-02-10 23:27:19 -08:00
DrSmugleaf
cbf01f0aa5 Fix ComponentChangedSerialized test (#1543) 2021-02-09 21:24:28 +01:00
Pieter-Jan Briers
6973d43006 Network timing synchronization.
Lidgren NetTime.Now is now synchronized to IGameTiming.RealTime.

NetChannel is now a nested class of NetManager.

Add IGameTiming.ServerTime, INetChannel.RemoteTimeOffset, INetChannel.RemoteTime
2021-02-09 14:28:20 +01:00
Pieter-Jan Briers
c5a961d9a0 Even better: use argStr. 2021-02-09 14:28:20 +01:00
Acruid
b4f7d71ee7 Server console can forward commands to a client. 2021-02-09 04:16:15 -08:00
metalgearsloth
cd3684e575 Guard against client appearancecomp changes (#1540)
Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
2021-02-09 13:13:05 +01:00
Pieter-Jan Briers
317b8ce965 Fix sudo command mangling quotes. 2021-02-09 12:29:23 +01:00
Pieter-Jan Briers
ff96140afa Fix messed up \n. 2021-02-09 03:17:27 +01:00
Pieter-Jan Briers
bade95f6b7 Fix unit tests 2021-02-09 02:37:27 +01:00
Pieter-Jan Briers
69daaca399 Remove CVar.SECURE and replace auth CVars with env variables. 2021-02-09 01:50:42 +01:00
DrSmugleaf
5af7e60043 Add KeyValuePair YAML serialization (#1538) 2021-02-08 21:49:08 +01:00
DrSmugleaf
ab823dcd12 Add component registration lookup with case insensitive names (#1535) 2021-02-08 18:07:23 +01:00
Paul Ritter
b3976eb8d7 Analyzer Bongaloo 2: The Return (#1512)
Co-authored-by: Paul <ritter.paul1+git@googlemail.com>
2021-02-08 18:05:27 +01:00
Pieter-Jan Briers
91759cdd3c Harder DynamicTree against NaN.
B2DynamicTree<T> has asserts, DynamicTree<T> handles them gracefully.

NaNs in DynamicTree were causing the internal state to corrupt resulting in the sprite flickering issues.

Fixes https://github.com/space-wizards/space-station-14/issues/2896
2021-02-08 05:03:56 +01:00
Pieter-Jan Briers
b000c3178b FileLogHandler is now internal.
Sandboxing thing.
2021-02-07 23:07:57 +01:00
Vera Aguilera Puerto
63b3ecdd13 Fix SpawnRepeating timer extensions 2021-02-07 17:04:43 +01:00
DrSmugleaf
a183a98f75 Add support for deserializing nullable enum types (#1537) 2021-02-07 14:31:38 +01:00
Acruid
bded7ad228 You can now provide a factory delegate to IoC register calls. 2021-02-06 23:00:08 -08:00
metalgearsloth
75c4f48496 Fix NPCs getting stuck (#1533)
Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
2021-02-05 20:38:01 +01:00
Acruid
49fe2d59cf Removes hard-coded color support for writing console shells. Strings with formatting codes can replace this feature.
Added a separate WriteError function to console shell, to mimic writing to stderr.
2021-02-05 01:35:06 -08:00
DrSmugleaf
8a5b7f5146 Add AudioSystem extension methods for the client and server (#1532) 2021-02-05 17:23:36 +11:00
Pieter-Jan Briers
ae4f470e1f Fix duplicate .xaml files. 2021-02-04 15:22:18 +01:00
metalgearsloth
18fcab6f71 Fix loadbp on paused maps (#1531)
Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
2021-02-04 23:29:37 +11:00
Acruid
1ae6c32c62 Adds the net_entityreport console command, that displays a network history of entity updates. 2021-02-03 23:19:47 -08:00
Pieter-Jan Briers
cf6925f19b Makes sudo command show output to user. (#1530) 2021-02-03 19:31:32 -08:00
Pieter-Jan Briers
b4c7ffe38a Adds an exec command.
Just like Quake. Man that Carmack guy was onto something.
2021-02-04 03:40:03 +01:00
Pieter-Jan Briers
d5c2f45f14 Fix accidental usage of OpenGL DSA in screenshot code. 2021-02-03 21:10:48 +01:00
Pieter-Jan Briers
dcc88d2d36 Fix KHR_debug detection on OpenGL ES. 2021-02-03 21:10:48 +01:00
metalgearsloth
a274b8dfc2 EntityQuery no longer yields paused by default (#1521)
* Change EntityQuery to not get paused by default

* GetAllComponents

* Fix shell commands

Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
2021-02-04 00:20:31 +11:00
Paul Ritter
f42c1379e0 Revert "Viewport improvements. (#1510)" (#1527)
This reverts commit fc5e3ab69d.
2021-02-03 12:25:12 +01:00
Pieter-Jan Briers
c4fa7e98d4 Fix clients not disconnecting correctly when client is closed. 2021-02-03 00:04:41 +01:00
Vera Aguilera Puerto
8b9dadffb1 MIDI improvements (#1526) 2021-02-02 18:46:24 +01:00
Vera Aguilera Puerto
5e99c6d04d ViewVariables server-side "Add Component" button isn't hidden anymore when searching for components. 2021-02-02 13:28:56 +01:00
Vera Aguilera Puerto
606d232dbb Update ViewVariables to use the new commands API 2021-02-02 13:26:41 +01:00
Vera Aguilera Puerto
df877582a6 You can now add or remove components from the comfort of ViewVariables (#1524) 2021-02-02 12:01:54 +01:00
Acruid
8ffdb090e6 Adds a property on ITransformComponent that prevents the entity from being rotated. Resolves #1479. 2021-02-01 20:27:17 -08:00
Acruid
033d6ffb22 Fixes bug where effects were dying in transit from lag. Resolves #1256. 2021-02-01 19:17:34 -08:00
Acruid
3eb6e067f9 Console Unify (#1513)
* Renamed shared ICommand to IConsoleCommand.

* Lots of refactoring into a shared context.

* Removed ICommonSession from server concmd Execute.

* Added argStr parameter to concmd execute.

* The execute function of client concmds now returns void, use the new shell.RemoteExecuteCommand function to forward commands.

# Conflicts:
#	Robust.Client/Console/Commands/Debug.cs

* Finally move shells and commands into shared.

* Console commands can now be registered directly without a class in a shared context.

* Pulled up ConsoleHost and Console shell into a shared context.

* Pulled up half the functions of ConsoleHost into a shared context.

* Repair rebase damage.

* Make LoadConsoleCommands function not remove any previously registered commands.
2021-02-01 16:40:26 -08:00
Vera Aguilera Puerto
1f64f93ef4 Update nfluidsynth to latest version, 0.3.1 2021-02-01 21:33:22 +01:00
Pieter-Jan Briers
7dd617b0d6 Adds reflection helper methods to script globals. 2021-02-01 19:41:02 +01:00
metalgearsloth
0567b70704 Optimise showbb (#1519)
Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
2021-02-01 20:15:50 +11:00
Pieter-Jan Briers
9963e89c14 Sanitize ResourcePath to disallow .. shenigans. 2021-01-31 22:38:40 +01:00
Remie Richards
29e0faed88 Can now animate ITransformComponent.WorldPosition (#1518) 2021-01-30 23:26:01 +01:00
Pieter-Jan Briers
0ce6ff9870 Fix tickrate sync if non-default tickrate saved to client config.
Fixes #1516

Thanks to blue on Discord for helping me diagnose this.
2021-01-30 01:27:42 +01:00
Vera Aguilera Puerto
dbe9a96dfa Reorganizes NumericsHelpers into different files using partial classes. (#1514) 2021-01-29 12:46:27 +01:00
Vera Aguilera Puerto
fc5e3ab69d Viewport improvements. (#1510)
* Remove the main viewport.

* Re-add main viewport in a different place

* Move screen/map translation into ViewportContainer

* Support for viewport resolution

* Fix postfx, add WorldToScreen to Viewport

* Remove useless cast

* Some cleanup.

* Fix incorrect worldBounds when rendering viewports

* nullability

Co-authored-by: 20kdc <asdd2808@gmail.com>
2021-01-29 12:45:04 +01:00
Julian Giebel
ed4974141c Add TryCastValue to CollectionExtensions.cs (#1515)
* Add TryCastValue to CollectionExtensions.cs

* Change TryCastValue to be more generic

* Add notnull constraing for TKey to TryCastValue

Co-authored-by: Julian Giebel <j.giebel@netrocks.info>
2021-01-28 20:45:11 +01:00
Pieter-Jan Briers
3e5efd5ed0 Add AnimatedTextureRect 2021-01-24 23:00:02 +01:00
Pieter-Jan Briers
e1110eadb4 Better unified handling of SpriteSpecifiers
Add more utilities, most notably IRsiStateLike, to make working with SpriteSpecifiers easier. Especially when animated.
2021-01-24 22:59:47 +01:00
Pieter-Jan Briers
06ace83a73 Allow audio playback without grids. 2021-01-24 16:04:23 +01:00
708 changed files with 7159 additions and 6014 deletions

View File

@@ -0,0 +1,5 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<ItemGroup>
<ProjectReference Include="$(MSBuildThisFileDirectory)\..\Robust.Analyzers\Robust.Analyzers.csproj" OutputItemType="Analyzer" ReferenceOutputAssembly="false"/>
</ItemGroup>
</Project>

View File

@@ -1,2 +1,3 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<Import Project="Robust.Analyzers.targets" />
</Project>

View File

@@ -1,5 +1,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
<PropertyGroup>
<!-- Avoid MSBuild adding a None entry for XAML files because they'd show up TWICE in the project view. -->
<DefaultItemExcludes>**/*.xaml</DefaultItemExcludes>
<RobustUseExternalMSBuild>true</RobustUseExternalMSBuild>
<_RobustUseExternalMSBuild>$(RobustUseExternalMSBuild)</_RobustUseExternalMSBuild>
<_RobustUseExternalMSBuild Condition="'$(_RobustForceInternalMSBuild)' == 'true'">false</_RobustUseExternalMSBuild>

View File

@@ -0,0 +1,92 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
using Document = Microsoft.CodeAnalysis.Document;
namespace Robust.Analyzers
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class ExplicitInterfaceAnalyzer : DiagnosticAnalyzer
{
public readonly SyntaxKind[] ExcludedModifiers =
{
SyntaxKind.VirtualKeyword,
SyntaxKind.AbstractKeyword,
SyntaxKind.OverrideKeyword
};
public const string DiagnosticId = "RA0000";
private const string Title = "No explicit interface specified";
private const string MessageFormat = "No explicit interface specified";
private const string Description = "Make sure to specify the interface in your method-declaration.";
private const string Category = "Usage";
[SuppressMessage("ReSharper", "RS2008")] private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
private const string RequiresExplicitImplementationAttributeMetadataName =
"Robust.Shared.Analyzers.RequiresExplicitImplementationAttribute";
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.MethodDeclaration);
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.PropertyDeclaration);
}
private void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
ISymbol symbol;
Location location;
switch (context.Node)
{
//we already have a explicit interface specified, no need to check further
case MethodDeclarationSyntax methodDecl when methodDecl.ExplicitInterfaceSpecifier != null || methodDecl.Modifiers.Any(m => ExcludedModifiers.Contains(m.Kind())):
return;
case PropertyDeclarationSyntax propertyDecl when propertyDecl.ExplicitInterfaceSpecifier != null || propertyDecl.Modifiers.Any(m => ExcludedModifiers.Contains(m.Kind())):
return;
case MethodDeclarationSyntax methodDecl:
symbol = context.SemanticModel.GetDeclaredSymbol(methodDecl);
location = methodDecl.Identifier.GetLocation();
break;
case PropertyDeclarationSyntax propertyDecl:
symbol = context.SemanticModel.GetDeclaredSymbol(propertyDecl);
location = propertyDecl.Identifier.GetLocation();
break;
default:
return;
}
var attrSymbol = context.Compilation.GetTypeByMetadataName(RequiresExplicitImplementationAttributeMetadataName);
var isInterfaceMember = symbol?.ContainingType.AllInterfaces.Any(
i =>
i.GetMembers().Any(m => SymbolEqualityComparer.Default.Equals(symbol, symbol.ContainingType.FindImplementationForInterfaceMember(m)))
&& i.GetAttributes().Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attrSymbol))
) ?? false;
if (isInterfaceMember)
{
//we do not have an explicit interface specified. bad!
var diagnostic = Diagnostic.Create(
Rule,
location);
context.ReportDiagnostic(diagnostic);
}
}
}
}

View File

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.8.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.Common" Version="3.8.0" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,150 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace Robust.Analyzers
{
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class SerializableAnalyzer : DiagnosticAnalyzer
{
// Metadata of the analyzer
public const string DiagnosticId = "RA0001";
// You could use LocalizedString but it's a little more complicated for this sample
private const string Title = "Class not marked as (Net)Serializable";
private const string MessageFormat = "Class not marked as (Net)Serializable";
private const string Description = "The class should be marked as (Net)Serializable.";
private const string Category = "Usage";
private const string RequiresSerializableAttributeMetadataName = "Robust.Shared.Analyzers.RequiresSerializableAttribute";
private const string SerializableAttributeMetadataName = "System.SerializableAttribute";
private const string NetSerializableAttributeMetadataName = "Robust.Shared.Serialization.NetSerializableAttribute";
[SuppressMessage("ReSharper", "RS2008")] private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Warning, isEnabledByDefault: true, description: Description);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
public override void Initialize(AnalysisContext context)
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.None);
context.EnableConcurrentExecution();
context.RegisterSyntaxNodeAction(AnalyzeNode, SyntaxKind.ClassDeclaration);
}
private bool Marked(INamedTypeSymbol namedTypeSymbol, INamedTypeSymbol attrSymbol)
{
if (namedTypeSymbol == null) return false;
if (namedTypeSymbol.GetAttributes()
.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, attrSymbol))) return true;
return Marked(namedTypeSymbol.BaseType, attrSymbol);
}
private void AnalyzeNode(SyntaxNodeAnalysisContext context)
{
var attrSymbol = context.Compilation.GetTypeByMetadataName(RequiresSerializableAttributeMetadataName);
var classDecl = (ClassDeclarationSyntax) context.Node;
var classSymbol = context.SemanticModel.GetDeclaredSymbol(classDecl);
if (classSymbol == null) return;
if (Marked(classSymbol, attrSymbol))
{
var attributes = classSymbol.GetAttributes();
var serAttr = context.Compilation.GetTypeByMetadataName(SerializableAttributeMetadataName);
var netSerAttr = context.Compilation.GetTypeByMetadataName(NetSerializableAttributeMetadataName);
var hasSerAttr = attributes.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, serAttr));
var hasNetSerAttr =
attributes.Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, netSerAttr));
if (!hasSerAttr || !hasNetSerAttr)
{
var requiredAttributes = new List<string>();
if(!hasSerAttr) requiredAttributes.Add(SerializableAttributeMetadataName);
if(!hasNetSerAttr) requiredAttributes.Add(NetSerializableAttributeMetadataName);
context.ReportDiagnostic(
Diagnostic.Create(
Rule,
classDecl.Identifier.GetLocation(),
ImmutableDictionary.CreateRange(new Dictionary<string, string>()
{
{
"requiredAttributes", string.Join(",", requiredAttributes)
}
})));
}
}
}
}
[ExportCodeFixProvider(LanguageNames.CSharp)]
public class SerializableCodeFixProvider : CodeFixProvider
{
private const string Title = "Annotate class as (Net)Serializable.";
public override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
foreach (var diagnostic in context.Diagnostics)
{
var span = diagnostic.Location.SourceSpan;
var classDecl = root.FindToken(span.Start).Parent.AncestorsAndSelf().OfType<ClassDeclarationSyntax>().First();
if(!diagnostic.Properties.TryGetValue("requiredAttributes", out var requiredAttributes)) return;
context.RegisterCodeFix(
CodeAction.Create(
Title,
c => FixAsync(context.Document, classDecl, requiredAttributes, c),
Title),
diagnostic);
}
}
private async Task<Document> FixAsync(Document document, ClassDeclarationSyntax classDecl,
string requiredAttributes, CancellationToken cancellationToken)
{
var attributes = new List<AttributeSyntax>();
var namespaces = new List<string>();
foreach (var attribute in requiredAttributes.Split(','))
{
var tempSplit = attribute.Split('.');
namespaces.Add(string.Join(".",tempSplit.Take(tempSplit.Length-1)));
var @class = tempSplit.Last();
@class = @class.Substring(0, @class.Length - 9); //cut out "Attribute" at the end
attributes.Add(SyntaxFactory.Attribute(SyntaxFactory.ParseName(@class)));
}
var newClassDecl =
classDecl.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(attributes)));
var root = (CompilationUnitSyntax) await document.GetSyntaxRootAsync(cancellationToken);
root = root.ReplaceNode(classDecl, newClassDecl);
foreach (var ns in namespaces)
{
if(root.Usings.Any(u => u.Name.ToString() == ns)) continue;
root = root.AddUsings(SyntaxFactory.UsingDirective(SyntaxFactory.ParseName(ns)));
}
return document.WithSyntaxRoot(root);
}
public sealed override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(SerializableAnalyzer.DiagnosticId);
public override FixAllProvider GetFixAllProvider()
{
return WellKnownFixAllProviders.BatchFixer;
}
}
}

View File

@@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using Robust.Client.GameObjects.Components.Animations;
using Robust.Client.GameObjects;
namespace Robust.Client.Animations
{

View File

@@ -1,7 +1,7 @@
using System;
using JetBrains.Annotations;
using Robust.Shared.Animations;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
namespace Robust.Client.Animations
{

View File

@@ -1,8 +1,7 @@
using System;
using Robust.Client.Animations;
using Robust.Shared.Animations;
namespace Content.Client.Animations
namespace Robust.Client.Animations
{
public class AnimationTrackControlProperty : AnimationTrackProperty
{

View File

@@ -1,11 +1,8 @@
using System;
using System.Collections.Generic;
using Robust.Client.GameObjects.EntitySystems;
using Robust.Client.GameObjects;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Utility;
using Robust.Shared.GameObjects;
namespace Robust.Client.Animations
{

View File

@@ -1,8 +1,8 @@
using System;
using System.Collections.Generic;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Interfaces.GameObjects.Components;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Utility;
namespace Robust.Client.Animations

View File

@@ -1,6 +1,5 @@
using System;
using Robust.Client.Graphics;
using Robust.Client.Graphics.Clyde;
namespace Robust.Client.Audio
{

View File

@@ -4,16 +4,15 @@ using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using NFluidsynth;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Log;
using Robust.Shared.Interfaces.Physics;
using Robust.Shared.Interfaces.Resources;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Shared.ContentPack;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Utility;
using Logger = Robust.Shared.Log.Logger;

View File

@@ -1,11 +1,9 @@
using System;
using System.IO;
using System.Runtime.Intrinsics.X86;
using NFluidsynth;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Graphics;
using Robust.Shared.Asynchronous;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Log;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
@@ -72,9 +70,9 @@ namespace Robust.Client.Audio.Midi
int PlayerTotalTick { get; }
/// <summary>
/// Gets the current tick of the MIDI player.
/// Gets or sets (seeks) the current tick of the MIDI player.
/// </summary>
int PlayerTick { get; }
int PlayerTick { get; set; }
/// <summary>
/// Gets the current tick of the sequencer.
@@ -235,7 +233,16 @@ namespace Robust.Client.Audio.Midi
public bool DisableProgramChangeEvent { get; set; } = true;
public int PlayerTotalTick => _player?.GetTotalTicks ?? 0;
public int PlayerTick => _player?.CurrentTick ?? 0;
public int PlayerTick
{
get => _player?.CurrentTick ?? 0;
set
{
lock (_playerStateLock)
_player?.Seek(Math.Max(Math.Min(value, PlayerTotalTick), 0));
}
}
public uint SequencerTick => _sequencer?.Tick ?? 0;
public double SequencerTimeScale => _sequencer?.TimeScale ?? 0;
@@ -310,9 +317,8 @@ namespace Robust.Client.Audio.Midi
lock (_playerStateLock)
{
if (_player == null)
_player = new NFluidsynth.Player(_synth);
_player.Stop();
_player?.Dispose();
_player = new NFluidsynth.Player(_synth);
_player.AddMem(buffer);
_player.SetPlaybackCallback(MidiPlayerEventHandler);
_player.Play();
@@ -351,10 +357,7 @@ namespace Robust.Client.Audio.Midi
public void StopAllNotes()
{
for (var i = 0; i < 16; i++)
{
_synth.AllNotesOff(i);
}
_synth.AllNotesOff(-1);
}
public void LoadSoundfont(string filename, bool resetPresets = false)
@@ -475,12 +478,6 @@ namespace Robust.Client.Audio.Midi
lock(_playerStateLock)
switch (midiEvent.Type)
{
// Sometimes MIDI files spam these for no good reason and I can't find any info on what they are.
case 1:
case 5:
case 81:
break;
// Note On 0x80
case 144:
_synth.NoteOn(midiEvent.Channel, midiEvent.Key, midiEvent.Velocity);
@@ -503,8 +500,10 @@ namespace Robust.Client.Audio.Midi
// Program Change - 0xC0
case 192:
if(!DisableProgramChangeEvent)
if (!DisableProgramChangeEvent)
_synth.ProgramChange(midiEvent.Channel, midiEvent.Program);
else
return;
break;
// Channel Pressure - 0xD0
@@ -517,13 +516,17 @@ namespace Robust.Client.Audio.Midi
_synth.PitchBend(midiEvent.Channel, midiEvent.Pitch);
break;
// Sometimes MIDI files spam these for no good reason and I can't find any info on what they are.
case 1:
case 5:
case 81:
// System Messages - 0xF0
case 240:
break;
return;
default:
_midiSawmill.Warning("Unhandled midi event of type {0}", midiEvent.Type, midiEvent);
break;
return;
}
}
catch (FluidSynthInteropException)

View File

@@ -1,20 +1,18 @@
using System;
using System.Net;
using Robust.Client.Interfaces;
using Robust.Client.Interfaces.Debugging;
using Robust.Client.Interfaces.GameObjects;
using Robust.Client.Interfaces.GameStates;
using Robust.Client.Interfaces.Utility;
using Robust.Client.Debugging;
using Robust.Client.GameObjects;
using Robust.Client.GameStates;
using Robust.Client.Player;
using Robust.Client.Utility;
using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Robust.Client
@@ -53,7 +51,7 @@ namespace Robust.Client
_net.ConnectFailed += OnConnectFailed;
_net.Disconnect += OnNetDisconnect;
_configManager.OnValueChanged(CVars.NetTickrate, TickRateChanged);
_configManager.OnValueChanged(CVars.NetTickrate, TickRateChanged, invokeImmediately: true);
_playMan.Initialize();
_debugDrawMan.Initialize();

View File

@@ -5,26 +5,8 @@ using Robust.Client.Debugging;
using Robust.Client.GameObjects;
using Robust.Client.GameStates;
using Robust.Client.Graphics;
using Robust.Client.Graphics.ClientEye;
using Robust.Client.Graphics.Clyde;
using Robust.Client.Graphics.Lighting;
using Robust.Client.Graphics.Overlays;
using Robust.Client.Input;
using Robust.Client.Interfaces;
using Robust.Client.Interfaces.Debugging;
using Robust.Client.Interfaces.GameObjects;
using Robust.Client.Interfaces.GameStates;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Client.Interfaces.Graphics.Lighting;
using Robust.Client.Interfaces.Graphics.Overlays;
using Robust.Client.Interfaces.Input;
using Robust.Client.Interfaces.Map;
using Robust.Client.Interfaces.Placement;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.Interfaces.State;
using Robust.Client.Interfaces.UserInterface;
using Robust.Client.Interfaces.Utility;
using Robust.Client.Map;
using Robust.Client.Placement;
using Robust.Client.Player;
@@ -35,15 +17,13 @@ using Robust.Client.UserInterface;
using Robust.Client.Utility;
using Robust.Client.ViewVariables;
using Robust.Shared;
using Robust.Shared.ContentPack;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.Interfaces.Resources;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Reflection;
namespace Robust.Client
{
@@ -78,10 +58,11 @@ namespace Robust.Client
IoCManager.Register<IDebugDrawingManager, DebugDrawingManager>();
IoCManager.Register<ILightManager, LightManager>();
IoCManager.Register<IDiscordRichPresence, DiscordRichPresence>();
IoCManager.Register<IClientConsole, ClientConsole>();
IoCManager.Register<IClientConsoleHost, ClientConsoleHost>();
IoCManager.Register<IFontManager, FontManager>();
IoCManager.Register<IFontManagerInternal, FontManager>();
IoCManager.Register<IMidiManager, MidiManager>();
IoCManager.Register<IAuthManager, AuthManager>();
switch (mode)
{
case GameController.DisplayMode.Headless:

View File

@@ -1,243 +0,0 @@
using System;
using System.Collections.Generic;
using Robust.Client.Interfaces.Console;
using Robust.Client.Log;
using Robust.Client.Utility;
using Robust.Shared.Console;
using Robust.Shared.Interfaces.Log;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Network.Messages;
using Robust.Shared.Reflection;
using Robust.Shared.Utility;
namespace Robust.Client.Console
{
public class AddStringArgs : EventArgs
{
public string Text { get; }
public Color Color { get; }
public AddStringArgs(string text, Color color)
{
Text = text;
Color = color;
}
}
public class AddFormattedMessageArgs : EventArgs
{
public readonly FormattedMessage Message;
public AddFormattedMessageArgs(FormattedMessage message)
{
Message = message;
}
}
internal sealed class ClientConsole : IClientConsole, IDebugConsole
{
private static readonly Color MsgColor = new Color(65, 105, 225);
[Dependency] private readonly IClientNetManager _network = default!;
[Dependency] private readonly IReflectionManager _reflectionManager = default!;
[Dependency] private readonly ILogManager logManager = default!;
private readonly Dictionary<string, IConsoleCommand> _commands = new Dictionary<string, IConsoleCommand>();
private bool _requestedCommands;
/// <inheritdoc />
public void Initialize()
{
_network.RegisterNetMessage<MsgConCmdReg>(MsgConCmdReg.NAME, HandleConCmdReg);
_network.RegisterNetMessage<MsgConCmdAck>(MsgConCmdAck.NAME, HandleConCmdAck);
_network.RegisterNetMessage<MsgConCmd>(MsgConCmd.NAME);
Reset();
logManager.RootSawmill.AddHandler(new DebugConsoleLogHandler(this));
}
/// <inheritdoc />
public void Reset()
{
_commands.Clear();
_requestedCommands = false;
_network.Connected += OnNetworkConnected;
InitializeCommands();
SendServerCommandRequest();
}
private void OnNetworkConnected(object? sender, NetChannelArgs netChannelArgs)
{
SendServerCommandRequest();
}
/// <inheritdoc />
public void Dispose()
{
// We don't have anything to dispose.
}
public IReadOnlyDictionary<string, IConsoleCommand> Commands => _commands;
public void AddLine(string text, Color color)
{
AddString?.Invoke(this, new AddStringArgs(text, color));
}
public void AddLine(string text)
{
AddLine(text, Color.White);
}
public void Clear()
{
ClearText?.Invoke(this, EventArgs.Empty);
}
public event EventHandler<AddStringArgs>? AddString;
public event EventHandler? ClearText;
public event EventHandler<AddFormattedMessageArgs>? AddFormatted;
private void HandleConCmdAck(MsgConCmdAck msg)
{
AddLine("< " + msg.Text, MsgColor);
}
private void HandleConCmdReg(MsgConCmdReg msg)
{
foreach (var cmd in msg.Commands)
{
var commandName = cmd.Name;
// Do not do duplicate commands.
if (_commands.ContainsKey(commandName))
{
Logger.DebugS("console", $"Server sent console command {commandName}, but we already have one with the same name. Ignoring.");
continue;
}
var command = new ServerDummyCommand(commandName, cmd.Help, cmd.Description);
_commands[commandName] = command;
}
}
/// <summary>
/// Processes commands (chat messages starting with /)
/// </summary>
/// <param name="text">input text</param>
public void ProcessCommand(string text)
{
if (string.IsNullOrWhiteSpace(text))
return;
// echo the command locally
AddLine("> " + text, Color.Lime);
//Commands are processed locally and then sent to the server to be processed there again.
var args = new List<string>();
CommandParsing.ParseArguments(text, args);
var commandname = args[0];
var forward = true;
if (_commands.ContainsKey(commandname))
{
var command = _commands[commandname];
args.RemoveAt(0);
forward = command.Execute(this, args.ToArray());
}
else if (!_network.IsConnected)
{
AddLine("Unknown command: " + commandname, Color.Red);
return;
}
if (forward)
SendServerConsoleCommand(text);
}
/// <summary>
/// Locates and registeres all local commands.
/// </summary>
private void InitializeCommands()
{
foreach (var t in _reflectionManager.GetAllChildren<IConsoleCommand>())
{
var instance = (IConsoleCommand)Activator.CreateInstance(t)!;
if (_commands.ContainsKey(instance.Command))
throw new InvalidOperationException($"Command already registered: {instance.Command}");
_commands[instance.Command] = instance;
}
}
/// <summary>
/// Requests remote commands from server.
/// </summary>
public void SendServerCommandRequest()
{
if (_requestedCommands)
return;
if (!_network.IsConnected)
return;
var msg = _network.CreateNetMessage<MsgConCmdReg>();
_network.ClientSendMessage(msg);
_requestedCommands = true;
}
/// <summary>
/// Sends a command directly to the server.
/// </summary>
private void SendServerConsoleCommand(string text)
{
if (_network == null || !_network.IsConnected)
return;
var msg = _network.CreateNetMessage<MsgConCmd>();
msg.Text = text;
_network.ClientSendMessage(msg);
}
public void AddFormattedLine(FormattedMessage message)
{
// Why the hell does this class implement IDebugConsole.
AddFormatted?.Invoke(this, new AddFormattedMessageArgs(message));
}
}
/// <summary>
/// These dummies are made purely so list and help can list server-side commands.
/// </summary>
[Reflect(false)]
internal class ServerDummyCommand : IConsoleCommand
{
internal ServerDummyCommand(string command, string help, string description)
{
Command = command;
Help = help;
Description = description;
}
public string Command { get; }
public string Help { get; }
public string Description { get; }
// Always forward to server.
public bool Execute(IDebugConsole console, params string[] args)
{
return true;
}
}
}

View File

@@ -0,0 +1,218 @@
using System;
using System.Collections.Generic;
using Robust.Client.Log;
using Robust.Shared.Console;
using Robust.Shared.Log;
using Robust.Shared.Network;
using Robust.Shared.Network.Messages;
using Robust.Shared.Players;
using Robust.Shared.Reflection;
using Robust.Shared.Utility;
namespace Robust.Client.Console
{
public class AddStringArgs : EventArgs
{
public string Text { get; }
public bool Local { get; }
public bool Error { get; }
public AddStringArgs(string text, bool local, bool error)
{
Text = text;
Local = local;
Error = error;
}
}
public class AddFormattedMessageArgs : EventArgs
{
public readonly FormattedMessage Message;
public AddFormattedMessageArgs(FormattedMessage message)
{
Message = message;
}
}
/// <inheritdoc cref="IClientConsoleHost" />
internal class ClientConsoleHost : ConsoleHost, IClientConsoleHost
{
private bool _requestedCommands;
/// <inheritdoc />
public void Initialize()
{
NetManager.RegisterNetMessage<MsgConCmdReg>(MsgConCmdReg.NAME, HandleConCmdReg);
NetManager.RegisterNetMessage<MsgConCmdAck>(MsgConCmdAck.NAME, HandleConCmdAck);
NetManager.RegisterNetMessage<MsgConCmd>(MsgConCmd.NAME, ProcessCommand);
Reset();
LogManager.RootSawmill.AddHandler(new DebugConsoleLogHandler(this));
}
private void ProcessCommand(MsgConCmd message)
{
string? text = message.Text;
LogManager.GetSawmill(SawmillName).Info($"SERVER:{text}");
ExecuteCommand(null, text);
}
/// <inheritdoc />
public void Reset()
{
AvailableCommands.Clear();
_requestedCommands = false;
NetManager.Connected += OnNetworkConnected;
LoadConsoleCommands();
SendServerCommandRequest();
}
/// <inheritdoc />
public event EventHandler<AddStringArgs>? AddString;
/// <inheritdoc />
public event EventHandler<AddFormattedMessageArgs>? AddFormatted;
/// <inheritdoc />
public void AddFormattedLine(FormattedMessage message)
{
AddFormatted?.Invoke(this, new AddFormattedMessageArgs(message));
}
/// <inheritdoc />
public override void WriteError(ICommonSession? session, string text)
{
OutputText(text, true, true);
}
/// <inheritdoc />
public override void ExecuteCommand(ICommonSession? session, string command)
{
if (string.IsNullOrWhiteSpace(command))
return;
// echo the command locally
WriteError(null, "> " + command);
//Commands are processed locally and then sent to the server to be processed there again.
var args = new List<string>();
CommandParsing.ParseArguments(command, args);
var commandName = args[0];
if (AvailableCommands.ContainsKey(commandName))
{
var command1 = AvailableCommands[commandName];
args.RemoveAt(0);
command1.Execute(new ConsoleShell(this, null), command, args.ToArray());
}
else
WriteError(null, "Unknown command: " + commandName);
}
/// <inheritdoc />
public override void RemoteExecuteCommand(ICommonSession? session, string command)
{
if (!NetManager.IsConnected) // we don't care about session on client
return;
var msg = NetManager.CreateNetMessage<MsgConCmd>();
msg.Text = command;
NetManager.ClientSendMessage(msg);
}
/// <inheritdoc />
public override void WriteLine(ICommonSession? session, string text)
{
OutputText(text, true, false);
}
/// <inheritdoc />
public void Dispose()
{
// We don't have anything to dispose.
}
private void OutputText(string text, bool local, bool error)
{
AddString?.Invoke(this, new AddStringArgs(text, local, error));
}
private void OnNetworkConnected(object? sender, NetChannelArgs netChannelArgs)
{
SendServerCommandRequest();
}
private void HandleConCmdAck(MsgConCmdAck msg)
{
OutputText("< " + msg.Text, false, msg.Error);
}
private void HandleConCmdReg(MsgConCmdReg msg)
{
foreach (var cmd in msg.Commands)
{
string? commandName = cmd.Name;
// Do not do duplicate commands.
if (AvailableCommands.ContainsKey(commandName))
{
Logger.DebugS("console", $"Server sent console command {commandName}, but we already have one with the same name. Ignoring.");
continue;
}
var command = new ServerDummyCommand(commandName, cmd.Help, cmd.Description);
AvailableCommands[commandName] = command;
}
}
/// <summary>
/// Requests remote commands from server.
/// </summary>
private void SendServerCommandRequest()
{
if (_requestedCommands)
return;
if (!NetManager.IsConnected)
return;
var msg = NetManager.CreateNetMessage<MsgConCmdReg>();
NetManager.ClientSendMessage(msg);
_requestedCommands = true;
}
}
/// <summary>
/// These dummies are made purely so list and help can list server-side commands.
/// </summary>
[Reflect(false)]
internal class ServerDummyCommand : IConsoleCommand
{
internal ServerDummyCommand(string command, string help, string description)
{
Command = command;
Help = help;
Description = description;
}
public string Command { get; }
public string Description { get; }
public string Help { get; }
// Always forward to server.
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
shell.RemoteExecuteCommand(argStr);
}
}
}

View File

@@ -1,8 +1,6 @@
using JetBrains.Annotations;
using Robust.Client.Interfaces.Console;
using Robust.Client.Player;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
namespace Robust.Client.Console.Commands
@@ -14,13 +12,13 @@ namespace Robust.Client.Console.Commands
public string Description => "Adds a component to an entity on the client";
public string Help => "addcompc <uid> <componentName>";
public bool Execute(IDebugConsole shell, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 2)
{
shell.AddLine("Wrong number of arguments");
return false;
shell.WriteLine("Wrong number of arguments");
return;
}
var entityUid = EntityUid.Parse(args[0]);
@@ -36,8 +34,6 @@ namespace Robust.Client.Console.Commands
component.Owner = entity;
compManager.AddComponent(entity, component);
return false;
}
}
@@ -48,12 +44,12 @@ namespace Robust.Client.Console.Commands
public string Description => "Removes a component from an entity.";
public string Help => "rmcompc <uid> <componentName>";
public bool Execute(IDebugConsole shell, string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 2)
{
shell.AddLine("Wrong number of arguments");
return false;
shell.WriteLine("Wrong number of arguments");
return;
}
var entityUid = EntityUid.Parse(args[0]);
@@ -65,8 +61,6 @@ namespace Robust.Client.Console.Commands
var registration = compFactory.GetRegistration(componentName);
compManager.RemoveComponent(entityUid, registration.Type);
return false;
}
}
}

View File

@@ -1,7 +1,7 @@
using JetBrains.Annotations;
using Robust.Client.Interfaces.Console;
using Robust.Client.Player;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
namespace Robust.Client.Console.Commands
@@ -13,18 +13,17 @@ namespace Robust.Client.Console.Commands
public string Description => "Spawns a client-side entity with specific type at your feet.";
public string Help => "cspawn <entity type>";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var player = IoCManager.Resolve<IPlayerManager>().LocalPlayer;
if (player?.ControlledEntity == null)
{
console.AddLine("You don't have an attached entity.");
return false;
shell.WriteLine("You don't have an attached entity.");
return;
}
var entityManager = IoCManager.Resolve<IEntityManager>();
entityManager.SpawnEntity(args[0], player.ControlledEntity.Transform.Coordinates);
return false;
}
}
}

View File

@@ -1,23 +1,21 @@
using System;
using System.Linq;
using JetBrains.Annotations;
using Robust.Client.Interfaces.Console;
using Robust.Shared.Configuration;
using Robust.Shared.Interfaces.Configuration;
using Robust.Shared.Console;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
namespace Robust.Client.Console.Commands
{
[UsedImplicitly]
internal sealed class CVarCommand : SharedCVarCommand, IConsoleCommand
{
public bool Execute(IDebugConsole console, params string[] args)
public override void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length < 1 || args.Length > 2)
{
console.AddLine("Must provide exactly one or two arguments.", Color.Red);
return false;
shell.WriteError("Must provide exactly one or two arguments.");
return;
}
var configManager = IoCManager.Resolve<IConfigurationManager>();
@@ -26,21 +24,21 @@ namespace Robust.Client.Console.Commands
if (name == "?")
{
var cvars = configManager.GetRegisteredCVars().OrderBy(c => c);
console.AddLine(string.Join("\n", cvars));
return false;
shell.WriteLine(string.Join("\n", cvars));
return;
}
if (!configManager.IsCVarRegistered(name))
{
console.AddLine($"CVar '{name}' is not registered. Use 'cvar ?' to get a list of all registered CVars.", Color.Red);
return false;
shell.WriteError($"CVar '{name}' is not registered. Use 'cvar ?' to get a list of all registered CVars.");
return;
}
if (args.Length == 1)
{
// Read CVar
var value = configManager.GetCVar<object>(name);
console.AddLine(value.ToString() ?? "");
shell.WriteLine(value.ToString() ?? "");
}
else
{
@@ -54,11 +52,9 @@ namespace Robust.Client.Console.Commands
}
catch (FormatException)
{
console.AddLine($"Input value is in incorrect format for type {type}");
shell.WriteLine($"Input value is in incorrect format for type {type}");
}
}
return false;
}
}
@@ -69,10 +65,9 @@ namespace Robust.Client.Console.Commands
public string Description => "Saves the client configuration to the config file";
public string Help => "saveconfig";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
IoCManager.Resolve<IConfigurationManager>().SaveToFile();
return false;
}
}

View File

@@ -1,13 +1,8 @@
// This file is for commands that do something to the console itself.
// This file is for commands that do something to the console itself.
// Not some generic console command type.
// Couldn't think of a better name sorry.
using System;
using Robust.Client.Interfaces.Console;
using Robust.Shared.Console;
using Robust.Shared.Interfaces.Random;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
namespace Robust.Client.Console.Commands
{
@@ -17,10 +12,9 @@ namespace Robust.Client.Console.Commands
public string Help => "Clears the debug console of all messages.";
public string Description => "Clears the console.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
console.Clear();
return false;
shell.Clear();
}
}
@@ -30,15 +24,12 @@ namespace Robust.Client.Console.Commands
public string Help => "Fills the console with some nonsense for debugging.";
public string Description => "Fill up the console for debugging.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
Color[] colors = { Color.Green, Color.Blue, Color.Red };
var random = IoCManager.Resolve<IRobustRandom>();
for (int x = 0; x < 50; x++)
{
console.AddLine("filling...", colors[random.Next(0, colors.Length)]);
shell.WriteLine("filling...");
}
return false;
}
}
}

View File

@@ -6,37 +6,25 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using Robust.Client.Input;
using System.Threading;
using Robust.Client.Interfaces;
using Robust.Client.Interfaces.Console;
using Robust.Client.Interfaces.Debugging;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Client.Interfaces.Graphics.Lighting;
using Robust.Client.Interfaces.Input;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.Interfaces.State;
using Robust.Client.Interfaces.UserInterface;
using Robust.Client.Debugging;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Client.ResourceManagement.ResourceTypes;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Asynchronous;
using Robust.Shared.Console;
using Robust.Shared.ContentPack;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.Interfaces.Resources;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
@@ -49,16 +37,14 @@ namespace Robust.Client.Console.Commands
public string Help => "Dump entity list";
public string Description => "Dumps entity list of UIDs and prototype.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var entityManager = IoCManager.Resolve<IEntityManager>();
foreach (var e in entityManager.GetEntities().OrderBy(e => e.Uid))
{
console.AddLine($"entity {e.Uid}, {e.Prototype?.ID}, {e.Transform.Coordinates}.", Color.White);
shell.WriteLine($"entity {e.Uid}, {e.Prototype?.ID}, {e.Transform.Coordinates}.");
}
return false;
}
}
@@ -68,12 +54,12 @@ namespace Robust.Client.Console.Commands
public string Help => "Usage: getcomponentregistration <componentName>";
public string Description => "Gets component registration information";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length < 1)
{
console.AddLine(Help);
return false;
shell.WriteLine(Help);
return;
}
var componentFactory = IoCManager.Resolve<IComponentFactory>();
@@ -94,19 +80,17 @@ namespace Robust.Client.Console.Commands
message.Append($", NSE: {registration.NetworkSynchronizeExistence}, references:");
console.AddLine(message.ToString(), Color.White);
shell.WriteLine(message.ToString());
foreach (var type in registration.References)
{
console.AddLine($" {type}", Color.White);
shell.WriteLine($" {type}");
}
}
catch (UnknownComponentException)
{
console.AddLine($"No registration found for '{args[0]}'", Color.Red);
shell.WriteError($"No registration found for '{args[0]}'");
}
return false;
}
}
@@ -119,14 +103,14 @@ namespace Robust.Client.Console.Commands
public string Description => "Toggles a debug monitor in the F3 menu.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var monitor = IoCManager.Resolve<IUserInterfaceManager>().DebugMonitors;
if (args.Length != 1)
{
console.AddLine(Help);
return false;
shell.WriteLine(Help);
return;
}
switch (args[0])
@@ -159,11 +143,9 @@ namespace Robust.Client.Console.Commands
monitor.ShowInput ^= true;
break;
default:
console.AddLine($"Invalid key: {args[0]}");
shell.WriteLine($"Invalid key: {args[0]}");
break;
}
return false;
}
}
@@ -173,7 +155,7 @@ namespace Robust.Client.Console.Commands
public string Help => "Throws an exception";
public string Description => "Throws an exception";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
throw new InvalidOperationException("Fuck");
}
@@ -185,11 +167,10 @@ namespace Robust.Client.Console.Commands
public string Help => "";
public string Description => "Enables debug drawing over all bounding boxes in the game, showing their size.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var mgr = IoCManager.Resolve<IDebugDrawing>();
mgr.DebugColliders = !mgr.DebugColliders;
return false;
}
}
@@ -199,11 +180,10 @@ namespace Robust.Client.Console.Commands
public string Help => "";
public string Description => "Enables debug drawing over all entity positions in the game.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var mgr = IoCManager.Resolve<IDebugDrawing>();
mgr.DebugPositions = !mgr.DebugPositions;
return false;
}
}
@@ -213,25 +193,24 @@ namespace Robust.Client.Console.Commands
public string Help => "Usage: showrays <raylifetime>";
public string Description => "Toggles debug drawing of physics rays. An integer for <raylifetime> must be provided";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
console.AddLine(Help);
return false;
shell.WriteLine(Help);
return;
}
if (!int.TryParse(args[0], out var id))
{
console.AddLine($"{args[0]} is not a valid integer.",Color.Red);
return false;
shell.WriteError($"{args[0]} is not a valid integer.");
return;
}
var mgr = IoCManager.Resolve<IDebugDrawingManager>();
mgr.DebugDrawRays = !mgr.DebugDrawRays;
console.AddLine("Toggled showing rays to:" + mgr.DebugDrawRays.ToString(), Color.Green);
shell.WriteError("Toggled showing rays to:" + mgr.DebugDrawRays.ToString());
mgr.DebugRayLifetime = TimeSpan.FromSeconds((double)int.Parse(args[0], CultureInfo.InvariantCulture));
return false;
}
}
@@ -241,10 +220,9 @@ namespace Robust.Client.Console.Commands
public string Help => "";
public string Description => "Immediately disconnect from the server and go back to the main menu.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
IoCManager.Resolve<IClientNetManager>().ClientDisconnect("Disconnect command used.");
return false;
}
}
@@ -257,33 +235,33 @@ namespace Robust.Client.Console.Commands
public string Description => "Displays verbose diagnostics for an entity.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
console.AddLine(Help);
return false;
shell.WriteLine(Help);
return;
}
if ((!new Regex(@"^c?[0-9]+$").IsMatch(args[0])))
{
console.AddLine("Malformed UID", Color.Red);
return false;
shell.WriteError("Malformed UID");
return;
}
var uid = EntityUid.Parse(args[0]);
var entmgr = IoCManager.Resolve<IEntityManager>();
if (!entmgr.TryGetEntity(uid, out var entity))
{
console.AddLine("That entity does not exist. Sorry lad.", Color.Red);
return false;
shell.WriteError("That entity does not exist. Sorry lad.");
return;
}
console.AddLine($"{entity.Uid}: {entity.Prototype?.ID}/{entity.Name}");
console.AddLine($"init/del/lmt: {entity.Initialized}/{entity.Deleted}/{entity.LastModifiedTick}");
shell.WriteLine($"{entity.Uid}: {entity.Prototype?.ID}/{entity.Name}");
shell.WriteLine($"init/del/lmt: {entity.Initialized}/{entity.Deleted}/{entity.LastModifiedTick}");
foreach (var component in entity.GetAllComponents())
{
console.AddLine(component.ToString() ?? "");
shell.WriteLine(component.ToString() ?? "");
if (component is IComponentDebug debug)
{
foreach (var line in debug.GetDebugString().Split('\n'))
@@ -293,12 +271,10 @@ namespace Robust.Client.Console.Commands
continue;
}
console.AddLine("\t" + line);
shell.WriteLine("\t" + line);
}
}
}
return false;
}
}
@@ -308,12 +284,12 @@ namespace Robust.Client.Console.Commands
public string Help => "sggcell <gridID> <vector2i> [offset]\nThat vector2i param is in the form x<int>,y<int>.";
public string Description => "Lists entities on a snap grid cell.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 2 && args.Length != 3)
{
console.AddLine(Help);
return false;
shell.WriteLine(Help);
return;
}
string gridId = args[0];
@@ -322,14 +298,14 @@ namespace Robust.Client.Console.Commands
if (!int.TryParse(args[0], out var id))
{
console.AddLine($"{args[0]} is not a valid integer.",Color.Red);
return false;
shell.WriteError($"{args[0]} is not a valid integer.");
return;
}
if (!new Regex(@"^-?[0-9]+,-?[0-9]+$").IsMatch(indices))
{
console.AddLine("mapIndicies must be of form x<int>,y<int>", Color.Red);
return false;
shell.WriteError("mapIndicies must be of form x<int>,y<int>");
return;
}
SnapGridOffset selectedOffset;
@@ -339,8 +315,8 @@ namespace Robust.Client.Console.Commands
}
else
{
console.AddLine("given offset type is not defined", Color.Red);
return false;
shell.WriteError("given offset type is not defined");
return;
}
var mapMan = IoCManager.Resolve<IMapManager>();
@@ -354,16 +330,13 @@ namespace Robust.Client.Console.Commands
int.Parse(indices.Split(',')[1], CultureInfo.InvariantCulture)),
selectedOffset))
{
console.AddLine(entity.Owner.Uid.ToString());
shell.WriteLine(entity.Owner.Uid.ToString());
}
}
else
{
console.AddLine("grid does not exist", Color.Red);
return false;
shell.WriteError("grid does not exist");
}
return false;
}
}
@@ -373,19 +346,17 @@ namespace Robust.Client.Console.Commands
public string Description => "Changes the name used when attempting to connect to the server.";
public string Help => Command + " <name>";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length < 1)
{
console.AddLine(Help);
return false;
shell.WriteLine(Help);
return;
}
var client = IoCManager.Resolve<IBaseClient>();
client.PlayerNameOverride = args[0];
console.AddLine($"Overriding player name to \"{args[0]}\".", Color.White);
return false;
shell.WriteLine($"Overriding player name to \"{args[0]}\".");
}
}
@@ -395,12 +366,12 @@ namespace Robust.Client.Console.Commands
public string Description => "Pre-caches a resource.";
public string Help => "ldrsc <path> <type>";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length < 2)
{
console.AddLine(Help);
return false;
shell.WriteLine(Help);
return;
}
var resourceCache = IoCManager.Resolve<IResourceCache>();
var reflection = IoCManager.Resolve<IReflectionManager>();
@@ -412,8 +383,8 @@ namespace Robust.Client.Console.Commands
}
catch(ArgumentException)
{
console.AddLine("Unable to find type", Color.Red);
return false;
shell.WriteError("Unable to find type");
return;
}
var getResourceMethod =
@@ -423,7 +394,6 @@ namespace Robust.Client.Console.Commands
DebugTools.Assert(getResourceMethod != null);
var generic = getResourceMethod!.MakeGenericMethod(type);
generic.Invoke(resourceCache, new object[] { args[0], true });
return false;
}
}
@@ -433,12 +403,12 @@ namespace Robust.Client.Console.Commands
public string Description => "Reloads a resource.";
public string Help => "rldrsc <path> <type>";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length < 2)
{
console.AddLine(Help);
return false;
shell.WriteLine(Help);
return;
}
var resourceCache = IoCManager.Resolve<IResourceCache>();
var reflection = IoCManager.Resolve<IReflectionManager>();
@@ -450,15 +420,14 @@ namespace Robust.Client.Console.Commands
}
catch(ArgumentException)
{
console.AddLine("Unable to find type", Color.Red);
return false;
shell.WriteError("Unable to find type");
return;
}
var getResourceMethod = resourceCache.GetType().GetMethod("ReloadResource", new[] { typeof(string) });
DebugTools.Assert(getResourceMethod != null);
var generic = getResourceMethod!.MakeGenericMethod(type);
generic.Invoke(resourceCache, new object[] { args[0] });
return false;
}
}
@@ -468,18 +437,18 @@ namespace Robust.Client.Console.Commands
public string Description => "Gets the tile count of a grid";
public string Help => "Usage: gridtc <gridId>";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
console.AddLine(Help);
return false;
shell.WriteLine(Help);
return;
}
if (!int.TryParse(args[0], out var id))
{
console.AddLine($"{args[0]} is not a valid integer.");
return false;
shell.WriteLine($"{args[0]} is not a valid integer.");
return;
}
var gridId = new GridId(int.Parse(args[0]));
@@ -487,13 +456,11 @@ namespace Robust.Client.Console.Commands
if (mapManager.TryGetGrid(gridId, out var grid))
{
console.AddLine(mapManager.GetGrid(gridId).GetAllTiles().Count().ToString());
return false;
shell.WriteLine(mapManager.GetGrid(gridId).GetAllTiles().Count().ToString());
}
else
{
console.AddLine($"No grid exists with id {id}",Color.Red);
return false;
shell.WriteError($"No grid exists with id {id}");
}
}
}
@@ -504,7 +471,7 @@ namespace Robust.Client.Console.Commands
public string Description => "Dump GUI tree to /guidump.txt in user data.";
public string Help => "guidump";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var root = IoCManager.Resolve<IUserInterfaceManager>().RootControl;
var res = IoCManager.Resolve<IResourceManager>();
@@ -514,8 +481,6 @@ namespace Robust.Client.Console.Commands
{
_writeNode(root, 0, writer);
}
return false;
}
private static void _writeNode(Control control, int indents, TextWriter writer)
@@ -575,7 +540,7 @@ namespace Robust.Client.Console.Commands
public string Description => "Open a dummy UI testing window";
public string Help => "uitest";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var window = new SS14Window { CustomMinimumSize = (500, 400)};
var tabContainer = new TabContainer();
@@ -667,8 +632,6 @@ namespace Robust.Client.Console.Commands
});
window.OpenCentered();
return false;
}
}
@@ -678,11 +641,10 @@ namespace Robust.Client.Console.Commands
public string Description => "Sets the system clipboard";
public string Help => "setclipboard <text>";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var mgr = IoCManager.Resolve<IClipboardManager>();
mgr.SetText(args[0]);
return false;
}
}
@@ -692,11 +654,10 @@ namespace Robust.Client.Console.Commands
public string Description => "Gets the system clipboard";
public string Help => "getclipboard";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var mgr = IoCManager.Resolve<IClipboardManager>();
console.AddLine(mgr.GetText());
return false;
shell.WriteLine(mgr.GetText());
}
}
@@ -706,12 +667,11 @@ namespace Robust.Client.Console.Commands
public string Description => "Toggles light rendering.";
public string Help => "togglelight";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var mgr = IoCManager.Resolve<ILightManager>();
if (!mgr.LockConsoleAccess)
mgr.Enabled = !mgr.Enabled;
return false;
}
}
@@ -721,14 +681,11 @@ namespace Robust.Client.Console.Commands
public string Description => "Toggles fov for client.";
public string Help => "togglefov";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var lmgr = IoCManager.Resolve<ILightManager>();
var mgr = IoCManager.Resolve<IEyeManager>();
if (!lmgr.LockConsoleAccess)
if (mgr.CurrentEye != null)
mgr.CurrentEye.DrawFov = !mgr.CurrentEye.DrawFov;
return false;
var mgr = IoCManager.Resolve<IEyeManager>();
if (mgr.CurrentEye != null)
mgr.CurrentEye.DrawFov = !mgr.CurrentEye.DrawFov;
}
}
@@ -738,12 +695,11 @@ namespace Robust.Client.Console.Commands
public string Description => "Toggles hard fov for client (for debugging space-station-14#2353).";
public string Help => "togglehardfov";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var mgr = IoCManager.Resolve<ILightManager>();
if (!mgr.LockConsoleAccess)
mgr.DrawHardFov = !mgr.DrawHardFov;
return false;
}
}
@@ -753,12 +709,11 @@ namespace Robust.Client.Console.Commands
public string Description => "Toggles shadow rendering.";
public string Help => "toggleshadows";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var mgr = IoCManager.Resolve<ILightManager>();
if (!mgr.LockConsoleAccess)
mgr.DrawShadows = !mgr.DrawShadows;
return false;
}
}
internal class ToggleLightBuf : IConsoleCommand
@@ -767,12 +722,11 @@ namespace Robust.Client.Console.Commands
public string Description => "Toggles lighting rendering. This includes shadows but not FOV.";
public string Help => "togglelightbuf";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var mgr = IoCManager.Resolve<ILightManager>();
if (!mgr.LockConsoleAccess)
mgr.DrawLighting = !mgr.DrawLighting;
return false;
}
}
@@ -782,7 +736,7 @@ namespace Robust.Client.Console.Commands
public string Description => "Run the GC.";
public string Help => "gc [generation]";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length == 0)
{
@@ -793,10 +747,8 @@ namespace Robust.Client.Console.Commands
if (int.TryParse(args[0], out int result))
GC.Collect(result);
else
console.AddLine("Failed to parse argument.",Color.Red);
shell.WriteError("Failed to parse argument.");
}
return false;
}
}
@@ -806,12 +758,10 @@ namespace Robust.Client.Console.Commands
public string Description => "Run the GC, fully, compacting LOH and everything.";
public string Help => "gcf";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect(2, GCCollectionMode.Forced, true, true);
return false;
}
}
@@ -824,16 +774,16 @@ namespace Robust.Client.Console.Commands
public string Help => "gc_mode\nSee current GC Latencymode\ngc_mode [type]\n Change GC Latency mode to [type]";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var prevMode = GCSettings.LatencyMode;
if (args.Length == 0)
{
console.AddLine($"current gc latency mode: {(int) prevMode} ({prevMode})");
console.AddLine("possible modes:");
shell.WriteLine($"current gc latency mode: {(int) prevMode} ({prevMode})");
shell.WriteLine("possible modes:");
foreach (int mode in (int[]) Enum.GetValues(typeof(GCLatencyMode)))
{
console.AddLine($" {mode}: {Enum.GetName(typeof(GCLatencyMode), mode)}");
shell.WriteLine($" {mode}: {Enum.GetName(typeof(GCLatencyMode), mode)}");
}
}
else
@@ -845,16 +795,14 @@ namespace Robust.Client.Console.Commands
}
else if (!Enum.TryParse(args[0], true, out mode))
{
console.AddLine($"unknown gc latency mode: {args[0]}");
return false;
shell.WriteLine($"unknown gc latency mode: {args[0]}");
return;
}
console.AddLine($"attempting gc latency mode change: {(int) prevMode} ({prevMode}) -> {(int) mode} ({mode})");
shell.WriteLine($"attempting gc latency mode change: {(int) prevMode} ({prevMode}) -> {(int) mode} ({mode})");
GCSettings.LatencyMode = mode;
console.AddLine($"resulting gc latency mode: {(int) GCSettings.LatencyMode} ({GCSettings.LatencyMode})");
shell.WriteLine($"resulting gc latency mode: {(int) GCSettings.LatencyMode} ({GCSettings.LatencyMode})");
}
return false;
}
}
@@ -868,15 +816,13 @@ namespace Robust.Client.Console.Commands
public string Help => "szr_stats";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
console.AddLine($"serialized: {RobustSerializer.BytesSerialized} bytes, {RobustSerializer.ObjectsSerialized} objects");
console.AddLine($"largest serialized: {RobustSerializer.LargestObjectSerializedBytes} bytes, {RobustSerializer.LargestObjectSerializedType} objects");
console.AddLine($"deserialized: {RobustSerializer.BytesDeserialized} bytes, {RobustSerializer.ObjectsDeserialized} objects");
console.AddLine($"largest serialized: {RobustSerializer.LargestObjectDeserializedBytes} bytes, {RobustSerializer.LargestObjectDeserializedType} objects");
return false;
shell.WriteLine($"serialized: {RobustSerializer.BytesSerialized} bytes, {RobustSerializer.ObjectsSerialized} objects");
shell.WriteLine($"largest serialized: {RobustSerializer.LargestObjectSerializedBytes} bytes, {RobustSerializer.LargestObjectSerializedType} objects");
shell.WriteLine($"deserialized: {RobustSerializer.BytesDeserialized} bytes, {RobustSerializer.ObjectsDeserialized} objects");
shell.WriteLine($"largest serialized: {RobustSerializer.LargestObjectDeserializedBytes} bytes, {RobustSerializer.LargestObjectDeserializedType} objects");
}
}
@@ -887,7 +833,7 @@ namespace Robust.Client.Console.Commands
public string Description => "Gets info about a chunk under your mouse cursor.";
public string Help => Command;
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var mapMan = IoCManager.Resolve<IMapManager>();
var inputMan = IoCManager.Resolve<IInputManager>();
@@ -897,8 +843,8 @@ namespace Robust.Client.Console.Commands
if (!mapMan.TryFindGridAt(mousePos, out var grid))
{
console.AddLine("No grid under your mouse cursor.");
return false;
shell.WriteLine("No grid under your mouse cursor.");
return;
}
var internalGrid = (IMapGridInternal)grid;
@@ -906,8 +852,7 @@ namespace Robust.Client.Console.Commands
var chunkIndex = grid.LocalToChunkIndices(grid.MapToGrid(mousePos));
var chunk = internalGrid.GetChunk(chunkIndex);
console.AddLine($"worldBounds: {chunk.CalcWorldBounds()} localBounds: {chunk.CalcLocalBounds()}");
return false;
shell.WriteLine($"worldBounds: {chunk.CalcWorldBounds()} localBounds: {chunk.CalcLocalBounds()}");
}
}
@@ -924,7 +869,7 @@ namespace Robust.Client.Console.Commands
public static ConcurrentDictionary<string, bool>? _reloadShadersQueued = new();
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
IResourceCacheInternal resC;
if (args.Length == 1)
@@ -933,8 +878,8 @@ namespace Robust.Client.Console.Commands
{
if (_watchers != null)
{
console.AddLine("Already watching.");
return false;
shell.WriteLine("Already watching.");
return;
}
resC = IoCManager.Resolve<IResourceCacheInternal>();
@@ -1003,11 +948,11 @@ namespace Robust.Client.Console.Commands
{
IoCManager.Resolve<IResourceCache>()
.ReloadResource<ShaderSourceResource>(resPath);
console.AddLine($"Reloaded shader: {resPath}");
shell.WriteLine($"Reloaded shader: {resPath}");
}
catch (Exception)
{
console.AddLine($"Failed to reload shader: {resPath}");
shell.WriteLine($"Failed to reload shader: {resPath}");
}
_reloadShadersQueued.TryRemove(ev.FullPath, out var _);
@@ -1027,17 +972,17 @@ namespace Robust.Client.Console.Commands
++created;
}
console.AddLine($"Created {created} shader directory watchers for {shaderCount} shaders.");
shell.WriteLine($"Created {created} shader directory watchers for {shaderCount} shaders.");
return false;
return;
}
if (args[0] == "-watch")
{
if (_watchers == null)
{
console.AddLine("No shader directory watchers active.");
return false;
shell.WriteLine("No shader directory watchers active.");
return;
}
var disposed = 0;
@@ -1049,19 +994,19 @@ namespace Robust.Client.Console.Commands
_watchers = null;
console.AddLine($"Disposed of {disposed} shader directory watchers.");
shell.WriteLine($"Disposed of {disposed} shader directory watchers.");
return false;
return;
}
}
if (args.Length > 1)
{
console.AddLine("Not implemented.");
return false;
shell.WriteLine("Not implemented.");
return;
}
console.AddLine("Reloading content shader resources...");
shell.WriteLine("Reloading content shader resources...");
resC = IoCManager.Resolve<IResourceCacheInternal>();
@@ -1073,13 +1018,11 @@ namespace Robust.Client.Console.Commands
}
catch (Exception)
{
console.AddLine($"Failed to reload shader: {path}");
shell.WriteLine($"Failed to reload shader: {path}");
}
}
console.AddLine("Done.");
return false;
shell.WriteLine("Done.");
}
}
@@ -1090,14 +1033,14 @@ namespace Robust.Client.Console.Commands
public string Description => "Toggle fov and light debug layers";
public string Help => "cldbglyr <layer>: Toggle <layer>\ncldbglyr: Turn all Layers off";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var clyde = IoCManager.Resolve<IClydeInternal>();
if (args.Length < 1)
{
clyde.DebugLayers = ClydeDebugLayers.None;
return false;
return;
}
clyde.DebugLayers = args[0] switch
@@ -1106,8 +1049,6 @@ namespace Robust.Client.Console.Commands
"light" => ClydeDebugLayers.Light,
_ => ClydeDebugLayers.None
};
return false;
}
}
@@ -1117,12 +1058,12 @@ namespace Robust.Client.Console.Commands
public string Description => "Keys key info for a key";
public string Help => "keyinfo <Key>";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
console.AddLine(Help);
return false;
shell.WriteLine(Help);
return;
}
var clyde = IoCManager.Resolve<IClydeInternal>();
@@ -1135,15 +1076,13 @@ namespace Robust.Client.Console.Commands
var scanCode = clyde.GetKeyScanCode(key);
var nameScanCode = clyde.GetKeyNameScanCode(scanCode);
console.AddLine($"name: '{name}' scan code: '{scanCode}' name via scan code: '{nameScanCode}'");
shell.WriteLine($"name: '{name}' scan code: '{scanCode}' name via scan code: '{nameScanCode}'");
}
else if (int.TryParse(args[0], out var scanCode))
{
var nameScanCode = clyde.GetKeyNameScanCode(scanCode);
console.AddLine($"name via scan code: '{nameScanCode}'");
shell.WriteLine($"name via scan code: '{nameScanCode}'");
}
return false;
}
}
}

View File

@@ -1,7 +1,6 @@
using System;
using Robust.Client.Interfaces.Console;
using Robust.Shared.Console;
using Robust.Shared.ContentPack;
using Robust.Shared.Maths;
namespace Robust.Client.Console.Commands
{
@@ -12,23 +11,21 @@ namespace Robust.Client.Console.Commands
public string Description => "Dumps a type's members in a format suitable for the sandbox configuration file.";
public string Help => "Usage: dmetamem <type>";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var type = Type.GetType(args[0]);
if (type == null)
{
console.AddLine("That type does not exist", Color.Red);
return false;
shell.WriteError("That type does not exist");
return;
}
foreach (var sig in AssemblyTypeChecker.DumpMetaMembers(type))
{
System.Console.WriteLine(@$"- ""{sig}""");
console.AddLine(sig);
shell.WriteLine(sig);
}
return false;
}
}
#endif

View File

@@ -1,8 +1,7 @@
using System.Linq;
using Robust.Client.Interfaces.Console;
using Robust.Shared.Interfaces.Network;
using System.Linq;
using Robust.Shared.Console;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Network;
namespace Robust.Client.Console.Commands
{
@@ -12,37 +11,36 @@ namespace Robust.Client.Console.Commands
public string Help => "When no arguments are provided, displays a generic help text. When an argument is passed, display the help text for the command with that name.";
public string Description => "Display help text.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
switch (args.Length)
{
case 0:
console.AddLine("To display help for a specific command, write 'help <command>'. To list all available commands, write 'list'.");
shell.WriteLine("To display help for a specific command, write 'help <command>'. To list all available commands, write 'list'.");
break;
case 1:
string commandname = args[0];
if (!console.Commands.ContainsKey(commandname))
if (!shell.ConsoleHost.RegisteredCommands.ContainsKey(commandname))
{
if (!IoCManager.Resolve<IClientNetManager>().IsConnected)
{
// No server so nothing to respond with unknown command.
console.AddLine("Unknown command: " + commandname, Color.Red);
return false;
shell.WriteError("Unknown command: " + commandname);
return;
}
// TODO: Maybe have a server side help?
return false;
return;
}
IConsoleCommand command = console.Commands[commandname];
console.AddLine(string.Format("{0} - {1}", command.Command, command.Description));
console.AddLine(command.Help);
IConsoleCommand command = shell.ConsoleHost.RegisteredCommands[commandname];
shell.WriteLine(string.Format("{0} - {1}", command.Command, command.Description));
shell.WriteLine(command.Help);
break;
default:
console.AddLine("Invalid amount of arguments.", Color.Red);
shell.WriteError("Invalid amount of arguments.");
break;
}
return false;
}
}
@@ -55,7 +53,7 @@ namespace Robust.Client.Console.Commands
"only commands that contain the given string in their name will be listed.";
public string Description => "List all commands, optionally with a filter.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var filter = "";
if (args.Length == 1)
@@ -64,14 +62,12 @@ namespace Robust.Client.Console.Commands
}
var conGroup = IoCManager.Resolve<IClientConGroupController>();
foreach (var command in console.Commands.Values
foreach (var command in shell.ConsoleHost.RegisteredCommands.Values
.Where(p => p.Command.Contains(filter) && conGroup.CanCommand(p.Command))
.OrderBy(c => c.Command))
{
console.AddLine(command.Command + ": " + command.Description);
shell.WriteLine(command.Command + ": " + command.Description);
}
return false;
}
}
}

View File

@@ -1,13 +1,13 @@
#if !FULL_RELEASE
using System;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using Robust.Client.Interfaces.Console;
using Robust.Client.Utility;
using Robust.Shared;
using Robust.Shared.Interfaces.Configuration;
using Robust.Shared.Console;
using Robust.Shared.IoC;
using Robust.Shared.Network;
namespace Robust.Client.Console.Commands
{
@@ -17,7 +17,7 @@ namespace Robust.Client.Console.Commands
public string Description => "Load authentication tokens from launcher data to aid in testing of live servers";
public string Help => "launchauth [account name]";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var wantName = args.Length > 0 ? args[0] : null;
@@ -32,18 +32,16 @@ namespace Robust.Client.Console.Commands
if (login == null)
{
console.AddLine("Unable to find a matching login");
return false;
shell.WriteLine("Unable to find a matching login");
return;
}
var token = login.Token.Token;
var userId = login.UserId;
var cfg = IoCManager.Resolve<IConfigurationManagerInternal>();
cfg.SetSecureCVar(CVars.AuthUserId, userId);
cfg.SetSecureCVar(CVars.AuthToken, token);
return false;
var cfg = IoCManager.Resolve<IAuthManager>();
cfg.Token = token;
cfg.UserId = new NetUserId(Guid.Parse(userId));
}
private sealed class LauncherConfig

View File

@@ -1,8 +1,7 @@
using System.Linq;
using System.Runtime.Loader;
using System.Text;
using JetBrains.Annotations;
using Robust.Client.Interfaces.Console;
using Robust.Shared.Console;
namespace Robust.Client.Console.Commands
{
@@ -13,18 +12,16 @@ namespace Robust.Client.Console.Commands
public string Description => "Lists loaded assemblies by load context.";
public string Help => Command;
public bool Execute(IDebugConsole console, string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
foreach (var context in AssemblyLoadContext.All)
{
console.AddLine($"{context.Name}:");
shell.WriteLine($"{context.Name}:");
foreach (var assembly in context.Assemblies.OrderBy(a => a.FullName))
{
console.AddLine($" {assembly.FullName}");
shell.WriteLine($" {assembly.FullName}");
}
}
return false;
}
}
}

View File

@@ -1,7 +1,6 @@
using Robust.Client.Interfaces.Console;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Log;
using System;
using Robust.Shared.Console;
namespace Robust.Client.Console.Commands
{
@@ -13,12 +12,12 @@ namespace Robust.Client.Console.Commands
+ "\n sawmill: A label prefixing log messages. This is the one you're setting the level for."
+ "\n level: The log level. Must match one of the values of the LogLevel enum.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 2)
{
console.AddLine("Invalid argument amount. Expected 2 arguments.", Color.Red);
return false;
shell.WriteError("Invalid argument amount. Expected 2 arguments.");
return;
}
var name = args[0];
@@ -32,13 +31,12 @@ namespace Robust.Client.Console.Commands
{
if (!Enum.TryParse<LogLevel>(levelname, out var result))
{
console.AddLine("Failed to parse 2nd argument. Must be one of the values of the LogLevel enum.");
return false;
shell.WriteLine("Failed to parse 2nd argument. Must be one of the values of the LogLevel enum.");
return;
}
level = result;
}
Logger.GetSawmill(name).Level = level;
return false;
}
}
@@ -51,12 +49,12 @@ namespace Robust.Client.Console.Commands
+ "\n level: The log level. Must match one of the values of the LogLevel enum."
+ "\n message: The message to be logged. Wrap this in double quotes if you want to use spaces.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 3)
{
console.AddLine("Invalid argument amount. Expected 3 arguments.", Color.Red);
return false;
shell.WriteError("Invalid argument amount. Expected 3 arguments.");
return;
}
var name = args[0];
@@ -64,13 +62,12 @@ namespace Robust.Client.Console.Commands
var message = args[2]; // yes this doesn't support spaces idgaf.
if (!Enum.TryParse<LogLevel>(levelname, out var result))
{
console.AddLine("Failed to parse 2nd argument. Must be one of the values of the LogLevel enum.");
return false;
shell.WriteLine("Failed to parse 2nd argument. Must be one of the values of the LogLevel enum.");
return;
}
var level = result;
Logger.LogS(level, name, message);
return false;
}
}
}

View File

@@ -1,5 +1,5 @@
using Robust.Client.Interfaces.Console;
using System;
using Robust.Shared.Console;
namespace Robust.Client.Console.Commands
{
@@ -9,10 +9,9 @@ namespace Robust.Client.Console.Commands
public string Description => "Kills the game client instantly.";
public string Help => "Kills the game client instantly, leaving no traces. No telling the server goodbye";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
Environment.Exit(0);
return false;
}
}
}

View File

@@ -1,22 +1,19 @@
using Robust.Client.Interfaces.Console;
using Robust.Shared.Console;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
namespace Robust.Client.Console.Commands
{
#if CLIENT_SCRIPTING
internal sealed class ScriptConsoleCommand : IConsoleCommand
internal sealed class ScriptCommand : IConsoleCommand
{
public string Command => "csi";
public string Description => "Opens a C# interactive console.";
public string Help => "csi";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
new ScriptConsoleClient().OpenCentered();
return false;
}
}
@@ -26,33 +23,29 @@ namespace Robust.Client.Console.Commands
public string Description => "Opens a variable watch window.";
public string Help => "watch";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
new WatchWindow().OpenCentered();
return false;
}
}
#endif
internal sealed class ServerScriptConsoleCommand : IConsoleCommand
internal sealed class ServerScriptCommand : IConsoleCommand
{
public string Command => "scsi";
public string Description => "Opens a C# interactive console on the server.";
public string Help => "scsi";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
var mgr = IoCManager.Resolve<IScriptClient>();
if (!mgr.CanScript)
{
console.AddLine(Loc.GetString("You do not have server side scripting permission."), Color.Red);
return false;
shell.WriteError(Loc.GetString("You do not have server side scripting permission."));
return;
}
mgr.StartSession();
return false;
}
}
}

View File

@@ -1,5 +1,4 @@
using Robust.Client.Interfaces.Console;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Console;
using Robust.Shared.IoC;
using Robust.Shared.Network;
@@ -11,7 +10,7 @@ namespace Robust.Client.Console.Commands
public string Description => "Sends garbage to the server.";
public string Help => "The server will reply with 'no u'";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
// MsgStringTableEntries is registered as NetMessageAccept.Client so the server will immediately deny it.
// And kick us.
@@ -19,8 +18,6 @@ namespace Robust.Client.Console.Commands
var msg = net.CreateNetMessage<MsgStringTableEntries>();
msg.Entries = new MsgStringTableEntries.Entry[0];
net.ClientSendMessage(msg);
return false;
}
}
}

View File

@@ -1,6 +1,6 @@
using JetBrains.Annotations;
using Robust.Client.Interfaces.Console;
using Robust.Client.Interfaces.Input;
using Robust.Client.Input;
using Robust.Shared.Console;
using Robust.Shared.IoC;
namespace Robust.Client.Console.Commands
@@ -12,24 +12,23 @@ namespace Robust.Client.Console.Commands
public string Description => "Sets the active input context.";
public string Help => "setinputcontext <context>";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
console.AddLine("Invalid number of arguments!");
return false;
shell.WriteLine("Invalid number of arguments!");
return;
}
var inputMan = IoCManager.Resolve<IInputManager>();
if (!inputMan.Contexts.Exists(args[0]))
{
console.AddLine("Context not found!");
return false;
shell.WriteLine("Context not found!");
return;
}
inputMan.Contexts.SetActiveContext(args[0]);
return false;
}
}
}

View File

@@ -1,6 +1,4 @@
using System;
namespace Robust.Client.Console
namespace Robust.Client.Console
{
public interface IClientConGroupController : IClientConGroupImplementation
{

View File

@@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
using Robust.Client.Interfaces.Console;
namespace Robust.Client.Console
{
public interface IClientConsole : IDisposable
{
/// <summary>
/// Initializes the console into a useable state.
/// </summary>
void Initialize();
/// <summary>
/// Resets the console to a post-initialized state.
/// </summary>
void Reset();
event EventHandler<AddStringArgs> AddString;
event EventHandler<AddFormattedMessageArgs> AddFormatted;
event EventHandler ClearText;
IReadOnlyDictionary<string, IConsoleCommand> Commands { get; }
/// <summary>
/// Parses console commands (verbs).
/// </summary>
/// <param name="text"></param>
void ProcessCommand(string text);
void SendServerCommandRequest();
}
}

View File

@@ -0,0 +1,24 @@
using System;
using Robust.Shared.Console;
using Robust.Shared.Utility;
namespace Robust.Client.Console
{
public interface IClientConsoleHost : IConsoleHost, IDisposable
{
/// <summary>
/// Initializes the console into a useable state.
/// </summary>
void Initialize();
/// <summary>
/// Resets the console to a post-initialized state.
/// </summary>
void Reset();
event EventHandler<AddStringArgs> AddString;
event EventHandler<AddFormattedMessageArgs> AddFormatted;
void AddFormattedLine(FormattedMessage message);
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.IoC;
using Robust.Shared.Network;
using Robust.Shared.Network.Messages;
namespace Robust.Client.Console

View File

@@ -10,10 +10,10 @@ using Microsoft.CodeAnalysis.Scripting;
using Microsoft.CodeAnalysis.Text;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.ViewVariables;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
using Robust.Shared.Reflection;
using Robust.Shared.Scripting;
using Robust.Shared.Utility;

View File

@@ -7,10 +7,10 @@ using Microsoft.CodeAnalysis.Scripting;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Maths;
using Robust.Shared.Reflection;
using Robust.Shared.Scripting;
using Robust.Shared.Timing;

View File

@@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.IO;
using Robust.Shared.Interfaces.Resources;
using Robust.Shared.ContentPack;
using Robust.Shared.IoC;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;

View File

@@ -1,17 +1,9 @@
using System;
using System.Collections.Generic;
using Robust.Client.Graphics;
using Robust.Client.Graphics.Drawing;
using Robust.Client.Graphics.Overlays;
using Robust.Client.Graphics.Shaders;
using Robust.Client.Interfaces.Debugging;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Client.Interfaces.Graphics.Overlays;
using Robust.Client.Interfaces.Input;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.Input;
using Robust.Client.ResourceManagement;
using Robust.Shared.GameObjects.Components;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
@@ -26,6 +18,7 @@ namespace Robust.Client.Debugging
[Dependency] private readonly IComponentManager _componentManager = default!;
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IPhysicsManager _physicsManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IInputManager _inputManager = default!;
@@ -48,7 +41,7 @@ namespace Robust.Client.Debugging
if (value)
{
_overlayManager.AddOverlay(new PhysicsOverlay(_componentManager, _eyeManager,
_prototypeManager, _inputManager));
_prototypeManager, _inputManager, _physicsManager));
}
else
{
@@ -86,6 +79,7 @@ namespace Robust.Client.Debugging
private readonly IComponentManager _componentManager;
private readonly IEyeManager _eyeManager;
private readonly IInputManager _inputManager;
private readonly IPhysicsManager _physicsManager;
public override OverlaySpace Space => OverlaySpace.WorldSpace | OverlaySpace.ScreenSpace;
private readonly ShaderInstance _shader;
@@ -94,12 +88,13 @@ namespace Robust.Client.Debugging
private Vector2 _hoverStartScreen = Vector2.Zero;
private List<IPhysBody> _hoverBodies = new();
public PhysicsOverlay(IComponentManager compMan, IEyeManager eyeMan, IPrototypeManager protoMan, IInputManager inputManager)
public PhysicsOverlay(IComponentManager compMan, IEyeManager eyeMan, IPrototypeManager protoMan, IInputManager inputManager, IPhysicsManager physicsManager)
: base(nameof(PhysicsOverlay))
{
_componentManager = compMan;
_eyeManager = eyeMan;
_inputManager = inputManager;
_physicsManager = physicsManager;
_shader = protoMan.Index<ShaderPrototype>("unshaded").Instance();
var cache = IoCManager.Resolve<IResourceCache>();
@@ -158,23 +153,20 @@ namespace Robust.Client.Debugging
_hoverStartScreen = mouseScreenPos;
var viewport = _eyeManager.GetWorldViewport();
foreach (var boundingBox in _componentManager.EntityQuery<IPhysicsComponent>())
{
var physBody = (IPhysBody) boundingBox;
if (viewport.IsEmpty()) return;
var mapId = _eyeManager.CurrentMap;
foreach (var physBody in _physicsManager.GetCollidingEntities(mapId, viewport))
{
// all entities have a TransformComponent
var transform = physBody.Entity.Transform;
// if not on the same map, continue
if (transform.MapID != _eyeManager.CurrentMap || !transform.IsMapTransform)
continue;
var worldBox = physBody.WorldAABB;
var colorEdge = Color.Red.WithAlpha(0.33f);
if (worldBox.IsEmpty()) continue;
// if not on screen, or too small, continue
if (!worldBox.Intersects(in viewport) || worldBox.IsEmpty())
continue;
var colorEdge = Color.Red.WithAlpha(0.33f);
foreach (var shape in physBody.PhysicsShapes)
{

View File

@@ -1,15 +1,11 @@
using Robust.Client.Interfaces.Debugging;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.IoC;
using Robust.Shared.IoC;
using Robust.Shared.Network.Messages;
using System;
using System.Collections.Generic;
using Robust.Client.Graphics.Overlays;
using Robust.Client.Graphics.Drawing;
using Robust.Client.Graphics;
using Robust.Shared.Maths;
using Robust.Client.Interfaces.Graphics.Overlays;
using Robust.Shared.Timing;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.Network;
namespace Robust.Client.Debugging
{

View File

@@ -1,4 +1,4 @@
namespace Robust.Client.Interfaces.Debugging
namespace Robust.Client.Debugging
{
/// <summary>
/// A collection of visual debug overlays for the client game.

View File

@@ -1,11 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Robust.Shared.Timing;
namespace Robust.Client.Interfaces.Debugging
namespace Robust.Client.Debugging
{
public interface IDebugDrawingManager
{

View File

@@ -3,18 +3,15 @@ using System.IO;
using System.Net;
using System.Threading.Tasks;
using Robust.Client.Console;
using Robust.Client.Interfaces;
using Robust.Client.Interfaces.GameObjects;
using Robust.Client.Interfaces.GameStates;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Interfaces.Graphics.Overlays;
using Robust.Client.Interfaces.Input;
using Robust.Client.Interfaces.Placement;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.Interfaces.State;
using Robust.Client.Interfaces.UserInterface;
using Robust.Client.Interfaces.Utility;
using Robust.Client.GameObjects;
using Robust.Client.GameStates;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.Placement;
using Robust.Client.Player;
using Robust.Client.ResourceManagement;
using Robust.Client.State;
using Robust.Client.UserInterface;
using Robust.Client.Utility;
using Robust.Client.ViewVariables;
using Robust.LoaderApi;
@@ -22,17 +19,14 @@ using Robust.Shared;
using Robust.Shared.Asynchronous;
using Robust.Shared.Configuration;
using Robust.Shared.ContentPack;
using Robust.Shared.Interfaces.Configuration;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Log;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Interfaces.Serialization;
using Robust.Shared.Interfaces.Timers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Timers;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -50,7 +44,7 @@ namespace Robust.Client
[Dependency] private readonly IUserInterfaceManagerInternal _userInterfaceManager = default!;
[Dependency] private readonly IBaseClient _client = default!;
[Dependency] private readonly IInputManager _inputManager = default!;
[Dependency] private readonly IClientConsole _console = default!;
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
[Dependency] private readonly ITimerManager _timerManager = default!;
[Dependency] private readonly IClientEntityManager _entityManager = default!;
[Dependency] private readonly IPlacementManager _placementManager = default!;
@@ -67,6 +61,7 @@ namespace Robust.Client
[Dependency] private readonly IComponentManager _componentManager = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IRobustMappedStringSerializer _stringSerializer = default!;
[Dependency] private readonly IAuthManager _authManager = default!;
private CommandLineArgs? _commandLineArgs;
private bool _disableAssemblyLoadContext;
@@ -167,7 +162,7 @@ namespace Robust.Client
IoCManager.Resolve<INetConfigurationManager>().SetupNetworking();
_serializer.Initialize();
_inputManager.Initialize();
_console.Initialize();
_consoleHost.Initialize();
_prototypeManager.LoadDirectory(new ResourcePath(@"/Prototypes/"));
_prototypeManager.Resync();
_mapManager.Initialize();
@@ -186,6 +181,8 @@ namespace Robust.Client
_client.PlayerNameOverride = _commandLineArgs.Username;
}
_authManager.LoadFromEnv();
_clyde.Ready();
if ((_commandLineArgs?.Connect == true || _commandLineArgs?.Launcher == true)

View File

@@ -1,4 +1,4 @@
using Robust.Client.Input;
using Robust.Client.Input;
namespace Robust.Client
{

View File

@@ -1,67 +1,9 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using Robust.Client.Graphics.Clyde;
using Robust.Client.Console;
using Robust.Client.Debugging;
using Robust.Client.GameObjects;
using Robust.Client.GameStates;
using Robust.Client.Graphics;
using Robust.Client.Graphics.ClientEye;
using Robust.Client.Graphics.Lighting;
using Robust.Client.Graphics.Overlays;
using Robust.Client.Input;
using Robust.Client.Interfaces;
using Robust.Client.Interfaces.Debugging;
using Robust.Client.Interfaces.GameObjects;
using Robust.Client.Interfaces.GameStates;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Client.Interfaces.Graphics.Lighting;
using Robust.Client.Interfaces.Graphics.Overlays;
using Robust.Client.Interfaces.Input;
using Robust.Client.Interfaces.Map;
using Robust.Client.Interfaces.Placement;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.Interfaces.State;
using Robust.Client.Interfaces.UserInterface;
using Robust.Client.Interfaces.Utility;
using Robust.Client.Map;
using Robust.Client.Placement;
using Robust.Client.Player;
using Robust.Client.Reflection;
using Robust.Client.ResourceManagement;
using Robust.Client.State;
using Robust.Client.UserInterface;
using Robust.Client.Utility;
using Robust.Client.ViewVariables;
using Robust.Shared;
using Robust.Shared.Asynchronous;
using Robust.Shared.Configuration;
using Robust.Shared.ContentPack;
using Robust.Shared.Exceptions;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.Configuration;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Log;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Interfaces.Physics;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.Interfaces.Resources;
using Robust.Shared.Interfaces.Serialization;
using Robust.Shared.Interfaces.Timers;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Physics;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Timers;
using Robust.Shared.Timing;
using Robust.Shared.Reflection;
namespace Robust.Client
{

View File

@@ -1,4 +1,4 @@
using Robust.Client;
using Robust.Client;
using Robust.LoaderApi;
[assembly: LoaderEntryPoint(typeof(GameController.LoaderEntryPoint))]
@@ -11,7 +11,7 @@ namespace Robust.Client
{
public void Main(IMainArgs args)
{
GameController.Start(args.Args, contentStart: false, args);
Start(args.Args, contentStart: false, args);
}
}
}

View File

@@ -1,7 +1,5 @@
using System;
using Robust.Client.Interfaces;
using System;
using Robust.LoaderApi;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Timing;

View File

@@ -0,0 +1,3 @@
Everything in this folder and subfolders needs to be in:
Robust.Client.GameObjects

View File

@@ -1,18 +1,4 @@
using Robust.Client.GameObjects.Components;
using Robust.Client.GameObjects.Components.Animations;
using Robust.Client.GameObjects.Components.Containers;
using Robust.Client.GameObjects.Components.UserInterface;
using Robust.Client.Interfaces.GameObjects.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components;
using Robust.Shared.GameObjects.Components.Appearance;
using Robust.Shared.GameObjects.Components.Eye;
using Robust.Shared.GameObjects.Components.Map;
using Robust.Shared.GameObjects.Components.Renderable;
using Robust.Shared.GameObjects.Components.Timers;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.Physics;
namespace Robust.Client.GameObjects
@@ -55,15 +41,13 @@ namespace Robust.Client.GameObjects
Register<AppearanceComponent>();
RegisterReference<AppearanceComponent, SharedAppearanceComponent>();
Register<AppearanceTestComponent>();
Register<SnapGridComponent>();
Register<ClientUserInterfaceComponent>();
RegisterReference<ClientUserInterfaceComponent, SharedUserInterfaceComponent>();
RegisterIgnore("IgnorePause");
Register<AnimationPlayerComponent>();
Register<ContainerManagerComponent>();

View File

@@ -1,11 +1,8 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Robust.Client.Interfaces.GameObjects;
using Robust.Shared.Exceptions;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;

View File

@@ -1,13 +1,11 @@
using System;
using System.Collections.Generic;
using Robust.Client.Interfaces.GameStates;
using Robust.Client.GameStates;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Network;
using Robust.Shared.Network.Messages;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Robust.Client.GameObjects

View File

@@ -5,7 +5,7 @@ using Robust.Client.Animations;
using Robust.Shared.GameObjects;
using static Robust.Client.Animations.AnimationPlaybackShared;
namespace Robust.Client.GameObjects.Components.Animations
namespace Robust.Client.GameObjects
{
/// <summary>
/// Plays back <see cref="Animation"/>s on entities.

View File

@@ -1,13 +1,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Robust.Client.GameObjects.EntitySystems;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.Appearance;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.IoC;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
@@ -78,6 +74,8 @@ namespace Robust.Client.GameObjects
private void SetData(object key, object value)
{
if (data.TryGetValue(key, out var existing) && existing.Equals(value)) return;
data[key] = value;
MarkDirty();
@@ -85,10 +83,9 @@ namespace Robust.Client.GameObjects
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
{
if (curState == null)
if (curState is not AppearanceComponentState actualState)
return;
var actualState = (AppearanceComponentState) curState;
data = actualState.Data;
MarkDirty();
}

View File

@@ -1,13 +1,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Robust.Client.GameObjects.EntitySystems;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.ViewVariables;
namespace Robust.Client.GameObjects.Components.Containers
namespace Robust.Client.GameObjects
{
public sealed partial class ContainerManagerComponent
{

View File

@@ -2,14 +2,10 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Robust.Client.GameObjects.EntitySystems;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.Containers;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.ViewVariables;
namespace Robust.Client.GameObjects.Components.Containers
namespace Robust.Client.GameObjects
{
public sealed partial class ContainerManagerComponent : SharedContainerManagerComponent
{

View File

@@ -1,8 +1,5 @@
using Robust.Client.Graphics.ClientEye;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Client.Graphics;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.Eye;
using Robust.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;

View File

@@ -1,9 +1,9 @@
using Robust.Client.Graphics;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.ResourceManagement;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
@@ -31,11 +31,11 @@ namespace Robust.Client.GameObjects
}
}
private static IDirectionalTextureProvider TextureForConfig(ObjectSerializer serializer, IResourceCache resourceCache)
private static IRsiStateLike TextureForConfig(ObjectSerializer serializer, IResourceCache resourceCache)
{
DebugTools.Assert(serializer.Reading);
if (serializer.TryGetCacheData<IDirectionalTextureProvider>(SerializationCache, out var dirTex))
if (serializer.TryGetCacheData<IRsiStateLike>(SerializationCache, out var dirTex))
{
return dirTex;
}
@@ -93,7 +93,7 @@ namespace Robust.Client.GameObjects
}
}
public static IDirectionalTextureProvider? GetPrototypeIcon(EntityPrototype prototype, IResourceCache resourceCache)
public static IRsiStateLike? GetPrototypeIcon(EntityPrototype prototype, IResourceCache resourceCache)
{
if (!prototype.Components.TryGetValue("Icon", out var mapping))
{

View File

@@ -0,0 +1,11 @@
using Robust.Shared.GameObjects;
namespace Robust.Client.GameObjects
{
[RegisterComponent]
[ComponentReference(typeof(SharedIgnorePauseComponent))]
public sealed class IgnorePauseComponent : SharedIgnorePauseComponent
{
}
}

View File

@@ -1,10 +1,9 @@
using Robust.Client.GameObjects.EntitySystems;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Input;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
namespace Robust.Client.GameObjects.Components
namespace Robust.Client.GameObjects
{
/// <summary>
/// Defines data fields used in the <see cref="InputSystem"/>.

View File

@@ -1,7 +1,5 @@
using System;
using Robust.Client.GameObjects.EntitySystems;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.ViewVariables;

View File

@@ -1,16 +1,13 @@
using Robust.Client.GameObjects.EntitySystems;
using System;
using Robust.Client.Graphics;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.ResourceManagement;
using Robust.Shared.Animations;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using System;
namespace Robust.Client.GameObjects
{

View File

@@ -1,9 +1,8 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Robust.Client.Interfaces.GameObjects
namespace Robust.Client.GameObjects
{
public interface IRenderableComponent : IComponent
{

View File

@@ -1,14 +1,12 @@
using System;
using System.Collections.Generic;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Graphics.Shaders;
using Robust.Shared.Animations;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
namespace Robust.Client.Interfaces.GameObjects.Components
namespace Robust.Client.GameObjects
{
public interface ISpriteComponent : IComponent, IAnimationProperties
{
@@ -205,29 +203,4 @@ namespace Robust.Client.Interfaces.GameObjects.Components
IEnumerable<ISpriteLayer> AllLayers { get; }
}
public interface ISpriteLayer
{
SpriteComponent.DirectionOffset DirOffset { get; set; }
RSI? Rsi { get; set; }
RSI.StateId RsiState { get; set; }
RSI? ActualRsi { get; }
Texture? Texture { get; set; }
Angle Rotation { get; set; }
Vector2 Scale { get; set; }
bool Visible { get; set; }
Color Color { get; set; }
float AnimationTime { get; set; }
int AnimationFrame { get; }
bool AutoAnimated { get; set; }
RSI.State.Direction EffectiveDirection(Angle worldRotation);
Vector2 LocalToLayer(Vector2 localPos);
}
}
}

View File

@@ -0,0 +1,30 @@
using Robust.Client.Graphics;
using Robust.Shared.Maths;
namespace Robust.Client.GameObjects
{
public interface ISpriteLayer
{
SpriteComponent.DirectionOffset DirOffset { get; set; }
RSI? Rsi { get; set; }
RSI.StateId RsiState { get; set; }
RSI? ActualRsi { get; }
Texture? Texture { get; set; }
Angle Rotation { get; set; }
Vector2 Scale { get; set; }
bool Visible { get; set; }
Color Color { get; set; }
float AnimationTime { get; set; }
int AnimationFrame { get; }
bool AutoAnimated { get; set; }
RSI.State.Direction EffectiveDirection(Angle worldRotation);
Vector2 LocalToLayer(Vector2 localPos);
}
}

View File

@@ -1,33 +1,24 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Text;
using Robust.Client.GameObjects.EntitySystems;
using Robust.Client.Graphics;
using Robust.Client.Graphics.ClientEye;
using Robust.Client.Graphics.Drawing;
using Robust.Client.Graphics.Shaders;
using Robust.Client.Interfaces.GameObjects.Components;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.ResourceManagement;
using Robust.Client.Utility;
using Robust.Shared.Animations;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.Renderable;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization;
using Robust.Shared.Utility;
using System.Linq;
using Robust.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
using DrawDepthTag = Robust.Shared.GameObjects.DrawDepth;
@@ -197,34 +188,34 @@ namespace Robust.Client.GameObjects
public void CopyFrom(SpriteComponent other)
{
//deep copying things to avoid entanglement
this._baseRsi = other._baseRsi;
this._directional = other._directional;
this._visible = other._visible;
this._layerMapShared = other._layerMapShared;
this.color = other.color;
this.offset = other.offset;
this.rotation = other.rotation;
this.scale = other.scale;
this.drawDepth = other.drawDepth;
this.Layers = new List<Layer>(other.Layers.Count);
_baseRsi = other._baseRsi;
_directional = other._directional;
_visible = other._visible;
_layerMapShared = other._layerMapShared;
color = other.color;
offset = other.offset;
rotation = other.rotation;
scale = other.scale;
drawDepth = other.drawDepth;
Layers = new List<Layer>(other.Layers.Count);
foreach (var otherLayer in other.Layers)
{
this.Layers.Add(new Layer(otherLayer, this));
Layers.Add(new Layer(otherLayer, this));
}
this.IsInert = other.IsInert;
this.LayerMap = other.LayerMap.ToDictionary(entry => entry.Key,
IsInert = other.IsInert;
LayerMap = other.LayerMap.ToDictionary(entry => entry.Key,
entry => entry.Value);
if (other.PostShader != null)
{
// only need to copy the shader if it's mutable
this.PostShader = other.PostShader.Mutable ? other.PostShader.Duplicate() : other.PostShader;
PostShader = other.PostShader.Mutable ? other.PostShader.Duplicate() : other.PostShader;
}
else
{
this.PostShader = null;
PostShader = null;
}
this.RenderOrder = other.RenderOrder;
RenderOrder = other.RenderOrder;
}
/// <inheritdoc />
@@ -1046,7 +1037,7 @@ namespace Robust.Client.GameObjects
var rsi = layer.RSI ?? BaseRSI;
if (rsi == null || !rsi.TryGetState(layer.State, out var state))
{
state = GetFallbackState();
state = GetFallbackState(resourceCache);
}
var layerSpecificDir = layer.EffectiveDirection(state, worldRotation, overrideDirection);
@@ -1279,7 +1270,7 @@ namespace Robust.Client.GameObjects
var rsi = layer.RSI ?? BaseRSI;
if (rsi == null || !rsi.TryGetState(layer.State, out var state))
{
state = GetFallbackState();
state = GetFallbackState(resourceCache);
}
if (!state.IsAnimated)
@@ -1407,7 +1398,7 @@ namespace Robust.Client.GameObjects
var rsi = layer.RSI ?? BaseRSI;
if (rsi == null || !rsi.TryGetState(layer.State, out var state))
{
state = GetFallbackState();
state = GetFallbackState(resourceCache);
}
if (state.IsAnimated)
@@ -1418,9 +1409,9 @@ namespace Robust.Client.GameObjects
}
}
private RSI.State GetFallbackState()
internal static RSI.State GetFallbackState(IResourceCache cache)
{
var rsi = resourceCache.GetResource<RSIResource>("/Textures/error.rsi").RSI;
var rsi = cache.GetResource<RSIResource>("/Textures/error.rsi").RSI;
return rsi["error"];
}
@@ -1738,14 +1729,14 @@ namespace Robust.Client.GameObjects
var rsi = ActualRsi;
if (rsi == null)
{
state = _parent.GetFallbackState();
state = GetFallbackState(_parent.resourceCache);
Logger.ErrorS(LogCategory, "No RSI to pull new state from! Trace:\n{0}", Environment.StackTrace);
}
else
{
if (!rsi.TryGetState(stateId, out state))
{
state = _parent.GetFallbackState();
state = GetFallbackState(_parent.resourceCache);
Logger.ErrorS(LogCategory, "State '{0}' does not exist in RSI. Trace:\n{1}", stateId,
Environment.StackTrace);
}
@@ -1796,7 +1787,7 @@ namespace Robust.Client.GameObjects
}
}
public IDirectionalTextureProvider? Icon
public IRsiStateLike? Icon
{
get
{
@@ -1806,13 +1797,13 @@ namespace Robust.Client.GameObjects
var texture = layer.Texture;
if (!layer.State.IsValid) return null;
if (!layer.State.IsValid) return texture;
// Pull texture from RSI state instead.
var rsi = layer.RSI ?? BaseRSI;
if (rsi == null || !rsi.TryGetState(layer.State, out var state))
{
state = GetFallbackState();
state = GetFallbackState(resourceCache);
}
return state;
@@ -1870,21 +1861,21 @@ namespace Robust.Client.GameObjects
}
public static IDirectionalTextureProvider? GetPrototypeIcon(EntityPrototype prototype, IResourceCache resourceCache)
public static IRsiStateLike GetPrototypeIcon(EntityPrototype prototype, IResourceCache resourceCache)
{
var icon = IconComponent.GetPrototypeIcon(prototype, resourceCache);
if (icon != null) return icon;
if (!prototype.Components.TryGetValue("Sprite", out var spriteNode))
if (!prototype.Components.ContainsKey("Sprite"))
{
return resourceCache.GetFallback<TextureResource>().Texture;
return GetFallbackState(resourceCache);
}
var dummy = new DummyIconEntity() {Prototype = prototype};
var dummy = new DummyIconEntity {Prototype = prototype};
var spriteComponent = dummy.AddComponent<SpriteComponent>();
dummy.Delete();
return spriteComponent?.Icon ?? resourceCache.GetFallback<TextureResource>().Texture;
return spriteComponent.Icon ?? GetFallbackState(resourceCache);
}
#region DummyIconEntity

View File

@@ -1,15 +1,13 @@
using System;
using System.Collections.Generic;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.UserInterface;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Interfaces.Reflection;
using Robust.Shared.IoC;
using Robust.Shared.Network;
using Robust.Shared.Players;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization;
using IComponent = Robust.Shared.Interfaces.GameObjects.IComponent;
namespace Robust.Client.GameObjects.Components.UserInterface
namespace Robust.Client.GameObjects
{
public class ClientUserInterfaceComponent : SharedUserInterfaceComponent
{

View File

@@ -1,7 +1,6 @@
using Robust.Client.Interfaces.GameStates;
using Robust.Client.GameStates;
using Robust.Client.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Utility;

View File

@@ -1,13 +1,12 @@
using Robust.Client.GameObjects.Components.Animations;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.GameObjects;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
internal sealed class AnimationPlayerSystem : EntitySystem
{
public override void FrameUpdate(float frameTime)
{
foreach (var animationPlayerComponent in EntityManager.ComponentManager.EntityQuery<AnimationPlayerComponent>())
foreach (var animationPlayerComponent in EntityManager.ComponentManager.EntityQuery<AnimationPlayerComponent>(true))
{
animationPlayerComponent.Update(frameTime);
}

View File

@@ -1,7 +1,7 @@
using System.Collections.Generic;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.GameObjects;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
internal sealed class AppearanceSystem : EntitySystem
{

View File

@@ -1,12 +1,12 @@
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.GameObjects;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
class AppearanceTestSystem : EntitySystem
{
public override void Update(float frameTime)
{
foreach (var appearanceTestComponent in EntityManager.ComponentManager.EntityQuery<AppearanceTestComponent>())
foreach (var appearanceTestComponent in EntityManager.ComponentManager.EntityQuery<AppearanceTestComponent>(true))
{
appearanceTestComponent.OnUpdate(frameTime);
}

View File

@@ -2,23 +2,18 @@
using System.Collections.Generic;
using JetBrains.Annotations;
using Robust.Client.Audio;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Shared.Audio;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.Interfaces.Physics;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Utility;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
[UsedImplicitly]
public class AudioSystem : EntitySystem
@@ -56,12 +51,12 @@ namespace Robust.Client.GameObjects.EntitySystems
private void PlayAudioPositionalHandler(PlayAudioPositionalMessage ev)
{
var gridId = ev.Coordinates.GetGridId(_entityManager);
if (!_mapManager.GridExists(gridId))
var mapId = ev.Coordinates.GetMapId(_entityManager);
if (!_mapManager.MapExists(mapId))
{
Logger.Error(
$"Server tried to play sound on grid {gridId}, which does not exist. Ignoring.");
$"Server tried to play sound on map {mapId}, which does not exist. Ignoring.");
return;
}
@@ -111,13 +106,13 @@ namespace Robust.Client.GameObjects.EntitySystems
if (stream.TrackingCoordinates != null)
{
var coords = stream.TrackingCoordinates.Value;
if (_mapManager.GridExists(coords.GetGridId(_entityManager)))
if (_mapManager.MapExists(coords.GetMapId(_entityManager)))
{
mapPos = stream.TrackingCoordinates.Value.ToMap(_entityManager);
}
else
{
// Grid no longer exists, delete stream.
// Map no longer exists, delete stream.
StreamDone(stream);
continue;
}
@@ -356,4 +351,76 @@ namespace Robust.Client.GameObjects.EntitySystems
event Action PlaybackDone;
}
public static class AudioSystemExtensions
{
/// <summary>
/// Play an audio file following an entity.
/// </summary>
/// <param name="filename">The resource path to the OGG Vorbis file to play.</param>
/// <param name="entity">The entity "emitting" the audio.</param>
/// <param name="audioParams"></param>
/// <param name="audioSystem">A pre-fetched instance of <see cref="AudioSystem"/> to use, can be null.</param>
public static IPlayingAudioStream? Play(
this IEntity entity,
string filename,
AudioParams? audioParams,
AudioSystem? audioSystem = null)
{
audioSystem ??= EntitySystem.Get<AudioSystem>();
return audioSystem.Play(filename, entity, audioParams);
}
/// <summary>
/// Play an audio stream following an entity.
/// </summary>
/// <param name="stream">The audio stream to play.</param>
/// <param name="entity">The entity "emitting" the audio.</param>
/// <param name="audioParams"></param>
/// <param name="audioSystem">A pre-fetched instance of <see cref="AudioSystem"/> to use, can be null.</param>
public static IPlayingAudioStream? Play(
this IEntity entity,
AudioStream stream,
AudioParams? audioParams = null,
AudioSystem? audioSystem = null)
{
audioSystem ??= EntitySystem.Get<AudioSystem>();
return audioSystem.Play(stream, entity, audioParams);
}
/// <summary>
/// Play an audio file at a static position.
/// </summary>
/// <param name="filename">The resource path to the OGG Vorbis file to play.</param>
/// <param name="coordinates">The coordinates at which to play the audio.</param>
/// <param name="audioParams"></param>
/// <param name="audioSystem">A pre-fetched instance of <see cref="AudioSystem"/> to use, can be null.</param>
public static IPlayingAudioStream? Play(
this EntityCoordinates coordinates,
string filename,
AudioParams? audioParams = null,
AudioSystem? audioSystem = null)
{
audioSystem ??= EntitySystem.Get<AudioSystem>();
return audioSystem.Play(filename, coordinates, audioParams);
}
/// <summary>
/// Play an audio stream at a static position.
/// </summary>
/// <param name="stream">The audio stream to play.</param>
/// <param name="coordinates">The coordinates at which to play the audio.</param>
/// <param name="audioParams"></param>
/// <param name="audioSystem">A pre-fetched instance of <see cref="AudioSystem"/> to use, can be null.</param>
public static IPlayingAudioStream? Play(
this EntityCoordinates coordinates,
AudioStream stream,
AudioParams? audioParams = null,
AudioSystem? audioSystem = null)
{
audioSystem ??= EntitySystem.Get<AudioSystem>();
return audioSystem.Play(stream, coordinates, audioParams);
}
}
}

View File

@@ -3,15 +3,11 @@ using System.Linq;
using JetBrains.Annotations;
using Robust.Client.Physics;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
// NOTE: this class handles both snap grid updates of occluders, as well as occluder tree updates (via its parent).
// This seems like it's doing somewhat double work because it already has an update queue for occluders but...

View File

@@ -1,9 +1,8 @@
using System.Collections.Generic;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
public class ContainerSystem : EntitySystem
{

View File

@@ -1,25 +1,15 @@
using Robust.Client.Graphics;
using Robust.Client.Graphics.Drawing;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Shared.GameObjects.EntitySystemMessages;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using System;
using System.Collections.Generic;
using Robust.Client.Graphics.Overlays;
using Robust.Client.Graphics.Shaders;
using Robust.Client.Interfaces.Graphics.Overlays;
using Robust.Client.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.Log;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Robust.Client.GameObjects
@@ -57,47 +47,54 @@ namespace Robust.Client.GameObjects
public void CreateEffect(EffectSystemMessage message)
{
// The source of effects is either local actions during FirstTimePredicted, or the network at LastServerTick
// When replaying predicted input, don't spam effects.
if(gameTiming.InPrediction && !gameTiming.IsFirstTimePredicted)
return;
if (message.AttachedEntityUid != null && message.Coordinates != default)
{
Logger.Warning("Set both an AttachedEntityUid and EntityCoordinates on an EffectSystemMessage for sprite {0} which is not supported!", message.EffectSprite);
}
var gameTime = gameTiming.CurTime;
if (gameTime > message.DeathTime) //Did we already die in transit? That's pretty troubling isn't it
if (message.LifeTime <= TimeSpan.Zero)
{
Logger.Warning("Effect using sprite {0} died in transit to the client", message.EffectSprite);
Logger.Warning("Effect using sprite {0} had zero lifetime.", message.EffectSprite);
return;
}
//Create effect from creation message
var effect = new Effect(message, resourceCache, _mapManager, _entityManager);
effect.Deathtime = gameTiming.CurTime + message.LifeTime;
if (effect.AttachedEntityUid != null)
{
effect.AttachedEntity = _entityManager.GetEntity(effect.AttachedEntityUid.Value);
}
//Age the effect through a single update to the previous update tick of the effect system
//effect.Update((float)((lasttimeprocessed - effect.Age).TotalSeconds));
_Effects.Add(effect);
}
public override void FrameUpdate(float frameTime)
{
var curTime = gameTiming.CurTime;
for (int i = 0; i < _Effects.Count; i++)
{
var effect = _Effects[i];
//Update variables of the effect via its deltas
effect.Update(frameTime);
//These effects have died
if (effect.Age > effect.Deathtime)
// Effects are purely visual, so they don't need to be ran through prediction.
// once CurTime ever passes DeathTime (clients render the top at IsFirstTimePredicted, where this happens) just remove them.
if (curTime > effect.Deathtime)
{
//Remove from the effects list and decrement the iterator
_Effects.Remove(effect);
i--;
}
else
{
//Update variables of the effect via its deltas
effect.Update(frameTime);
}
}
}
@@ -205,14 +202,9 @@ namespace Robust.Client.GameObjects
public bool Shaded = true;
/// <summary>
/// Effect's age -- from 0f
/// CurTime after which the effect will "die"
/// </summary>
public TimeSpan Age = TimeSpan.Zero;
/// <summary>
/// Time after which the effect will "die"
/// </summary>
public TimeSpan Deathtime = TimeSpan.FromSeconds(1);
public TimeSpan Deathtime;
private readonly IMapManager _mapManager;
private readonly IEntityManager _entityManager;
@@ -245,8 +237,6 @@ namespace Robust.Client.GameObjects
RadialAcceleration = effectcreation.RadialAcceleration;
TangentialVelocity = effectcreation.TangentialVelocity;
TangentialAcceleration = effectcreation.TangentialAcceleration;
Age = effectcreation.Born;
Deathtime = effectcreation.DeathTime;
Rotation = effectcreation.Rotation;
RotationRate = effectcreation.RotationRate;
Size = effectcreation.Size;
@@ -260,10 +250,6 @@ namespace Robust.Client.GameObjects
public void Update(float frameTime)
{
Age += TimeSpan.FromSeconds(frameTime);
if (Age >= Deathtime)
return;
Velocity += Acceleration * frameTime;
RadialVelocity += RadialAcceleration * frameTime;
TangentialVelocity += TangentialAcceleration * frameTime;

View File

@@ -1,8 +1,8 @@
using System;
using JetBrains.Annotations;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Client.Graphics;
using Robust.Client.Physics;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.GameObjects;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.IoC;
@@ -10,7 +10,7 @@ using Robust.Shared.Maths;
#nullable enable
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
/// <summary>
/// Updates the position of every Eye every frame, so that the camera follows the player around.
@@ -87,7 +87,7 @@ namespace Robust.Client.GameObjects.EntitySystems
}
}
foreach (var eyeComponent in EntityManager.ComponentManager.EntityQuery<EyeComponent>())
foreach (var eyeComponent in EntityManager.ComponentManager.EntityQuery<EyeComponent>(true))
{
eyeComponent.UpdateEyePosition();
}

View File

@@ -1,19 +1,15 @@
using System;
using Robust.Client.GameObjects.Components;
using Robust.Client.Interfaces.GameStates;
using Robust.Client.Interfaces.Input;
using Robust.Client.GameStates;
using Robust.Client.Input;
using Robust.Client.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Players;
using Robust.Shared.Utility;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
/// <summary>
/// Client-side processing of all input commands through the simulation.

View File

@@ -1,8 +1,8 @@
using Robust.Client.Audio.Midi;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
public class MidiSystem : EntitySystem
{

View File

@@ -1,16 +1,13 @@
using System.Collections.Generic;
using JetBrains.Annotations;
using Robust.Client.Physics;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.GameObjects.EntitySystemMessages;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
/// <summary>
/// Keeps track of <see cref="DynamicTree{T}"/>s for various rendering-related components.

View File

@@ -1,10 +1,10 @@
using JetBrains.Annotations;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Shared.GameObjects.Systems;
using Robust.Client.Graphics;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
/// <summary>
/// Updates the layer animation for every visible sprite.

View File

@@ -1,16 +1,14 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.GameObjects.EntitySystemMessages;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
namespace Robust.Client.GameObjects.EntitySystems
namespace Robust.Client.GameObjects
{
/// <summary>
/// Handles interpolation of transform positions.

View File

@@ -1,8 +1,7 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using System.Collections.Generic;
using System.Collections.Generic;
using Robust.Shared.GameObjects;
namespace Robust.Client.Interfaces.GameObjects
namespace Robust.Client.GameObjects
{
public interface IClientEntityManager : IEntityManager
{

View File

@@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using Robust.Client.GameObjects.EntitySystems;
using Robust.Client.Interfaces;
using Robust.Client.Interfaces.GameObjects;
using Robust.Client.Interfaces.GameStates;
using Robust.Client.Interfaces.Input;
using Robust.Client.GameObjects;
using Robust.Client.Input;
using Robust.Shared.GameStates;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.IoC;
using Robust.Shared.Network.Messages;
using Robust.Client.Player;
@@ -14,11 +10,9 @@ using Robust.Shared;
using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.Input;
using Robust.Shared.Interfaces.Configuration;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Map;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

View File

@@ -3,7 +3,6 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.Log;
using Robust.Shared.Timing;
using Robust.Shared.Utility;

View File

@@ -1,10 +1,9 @@
using System;
using Robust.Client.GameStates;
using Robust.Shared.GameObjects;
using Robust.Shared.Input;
using Robust.Shared.Timing;
namespace Robust.Client.Interfaces.GameStates
namespace Robust.Client.GameStates
{
/// <summary>
/// Engine service that provides processing and management of game states.

View File

@@ -0,0 +1,254 @@
using System.Collections.Generic;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Shared.Configuration;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Timing;
namespace Robust.Client.GameStates
{
/// <summary>
/// A network entity report that lists all entities as they are updated through game states.
/// https://developer.valvesoftware.com/wiki/Networking_Entities#cl_entityreport
/// </summary>
class NetEntityOverlay : Overlay
{
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly IClientNetManager _netManager = default!;
[Dependency] private readonly IClientGameStateManager _gameStateManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IConfigurationManager _configurationManager = default!;
[Dependency] private readonly IEyeManager _eyeManager = default!;
private const int TrafficHistorySize = 64; // Size of the traffic history bar in game ticks.
/// <inheritdoc />
public override OverlaySpace Space => OverlaySpace.ScreenSpace;
private readonly Font _font;
private readonly int _lineHeight;
private readonly List<NetEntity> _netEnts = new();
public NetEntityOverlay() : base(nameof(NetEntityOverlay))
{
IoCManager.InjectDependencies(this);
var cache = IoCManager.Resolve<IResourceCache>();
_font = new VectorFont(cache.GetResource<FontResource>("/Fonts/NotoSans/NotoSans-Regular.ttf"), 10);
_lineHeight = _font.GetLineHeight(1);
_gameStateManager.GameStateApplied += HandleGameStateApplied;
}
private void HandleGameStateApplied(GameStateAppliedArgs args)
{
if(_gameTiming.InPrediction) // we only care about real server states.
return;
// Shift traffic history down one
for (var i = 0; i < _netEnts.Count; i++)
{
var traffic = _netEnts[i].Traffic;
for (int j = 1; j < TrafficHistorySize; j++)
{
traffic[j - 1] = traffic[j];
}
traffic[^1] = 0;
}
var gameState = args.AppliedState;
if(gameState.EntityStates is not null)
{
// Loop over every entity that gets updated this state and record the traffic
foreach (var entityState in gameState.EntityStates)
{
var newEnt = true;
for(var i=0;i<_netEnts.Count;i++)
{
var netEnt = _netEnts[i];
if (netEnt.Id != entityState.Uid)
continue;
//TODO: calculate size of state and record it here.
netEnt.Traffic[^1] = 1;
netEnt.LastUpdate = gameState.ToSequence;
newEnt = false;
_netEnts[i] = netEnt; // copy struct back
break;
}
if (!newEnt)
continue;
var newNetEnt = new NetEntity(entityState.Uid);
newNetEnt.Traffic[^1] = 1;
newNetEnt.LastUpdate = gameState.ToSequence;
_netEnts.Add(newNetEnt);
}
}
bool pvsEnabled = _configurationManager.GetCVar<bool>("net.pvs");
float pvsSize = _configurationManager.GetCVar<float>("net.maxupdaterange");
var pvsCenter = _eyeManager.CurrentEye.Position;
Box2 pvsBox = Box2.CenteredAround(pvsCenter.Position, new Vector2(pvsSize*2, pvsSize*2));
int timeout = _gameTiming.TickRate * 3;
for (int i = 0; i < _netEnts.Count; i++)
{
var netEnt = _netEnts[i];
if(_entityManager.EntityExists(netEnt.Id))
{
//TODO: Whoever is working on PVS remake, change the InPVS detection.
var position = _entityManager.GetEntity(netEnt.Id).Transform.MapPosition;
netEnt.InPVS = !pvsEnabled || (pvsBox.Contains(position.Position) && position.MapId == pvsCenter.MapId);
_netEnts[i] = netEnt; // copy struct back
continue;
}
netEnt.Exists = false;
if (netEnt.LastUpdate.Value + timeout < _gameTiming.LastRealTick.Value)
{
_netEnts.RemoveAt(i);
i--;
continue;
}
_netEnts[i] = netEnt; // copy struct back
}
}
protected override void Draw(DrawingHandleBase handle, OverlaySpace currentSpace)
{
if (!_netManager.IsConnected)
return;
// remember, 0,0 is top left of ui with +X right and +Y down
var screenHandle = (DrawingHandleScreen)handle;
for (int i = 0; i < _netEnts.Count; i++)
{
var netEnt = _netEnts[i];
var xPos = 100;
var yPos = 10 + _lineHeight * i;
var name = $"({netEnt.Id}) {_entityManager.GetEntity(netEnt.Id).Prototype?.ID}";
var color = CalcTextColor(ref netEnt);
DrawString(screenHandle, _font, new Vector2(xPos + (TrafficHistorySize + 4), yPos), name, color);
DrawTrafficBox(screenHandle, ref netEnt, xPos, yPos);
}
}
private void DrawTrafficBox(DrawingHandleScreen handle, ref NetEntity netEntity, int x, int y)
{
handle.DrawRect(UIBox2.FromDimensions(x+1, y, TrafficHistorySize + 1, _lineHeight), new Color(32, 32, 32, 128));
handle.DrawRect(UIBox2.FromDimensions(x, y, TrafficHistorySize + 2, _lineHeight), Color.Gray.WithAlpha(0.15f), false);
var traffic = netEntity.Traffic;
//TODO: Local peak size, actually scale the peaks
for (int i = 0; i < TrafficHistorySize; i++)
{
if(traffic[i] == 0)
continue;
var xPos = x + 1 + i;
var yPosA = y + 1;
var yPosB = yPosA + _lineHeight - 1;
handle.DrawLine(new Vector2(xPos, yPosA), new Vector2(xPos, yPosB), Color.Green);
}
}
private Color CalcTextColor(ref NetEntity ent)
{
if(!ent.Exists)
return Color.Gray; // Entity is deleted, will be removed from list soon.
if(!ent.InPVS)
return Color.Red; // Entity still exists outside PVS, but not updated anymore.
if(_gameTiming.LastRealTick < ent.LastUpdate + _gameTiming.TickRate)
return Color.Blue; //Entity in PVS generating ongoing traffic.
return Color.Green; // Entity in PVS, but not updated recently.
}
protected override void Dispose(bool disposing)
{
_gameStateManager.GameStateApplied -= HandleGameStateApplied;
base.Dispose(disposing);
}
private static void DrawString(DrawingHandleScreen handle, Font font, Vector2 pos, string str, Color textColor)
{
var baseLine = new Vector2(pos.X, font.GetAscent(1) + pos.Y);
foreach (var chr in str)
{
var advance = font.DrawChar(handle, chr, baseLine, 1, textColor);
baseLine += new Vector2(advance, 0);
}
}
private struct NetEntity
{
public GameTick LastUpdate;
public readonly EntityUid Id;
public readonly int[] Traffic;
public bool Exists;
public bool InPVS;
public NetEntity(EntityUid id)
{
LastUpdate = GameTick.Zero;
Id = id;
Traffic = new int[TrafficHistorySize];
Exists = true;
InPVS = true;
}
}
private class NetEntityReportCommand : IConsoleCommand
{
public string Command => "net_entityreport";
public string Help => "net_entityreport <0|1>";
public string Description => "Toggles the net entity report panel.";
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
shell.WriteError("Invalid argument amount. Expected 2 arguments.");
return;
}
if (!byte.TryParse(args[0], out var iValue))
{
shell.WriteError("Invalid argument: Needs to be 0 or 1.");
return;
}
var bValue = iValue > 0;
var overlayMan = IoCManager.Resolve<IOverlayManager>();
if(bValue && !overlayMan.HasOverlay(nameof(NetEntityOverlay)))
{
overlayMan.AddOverlay(new NetEntityOverlay());
shell.WriteLine("Enabled network entity report overlay.");
}
else if(!bValue && overlayMan.HasOverlay(nameof(NetEntityOverlay)))
{
overlayMan.RemoveOverlay(nameof(NetEntityOverlay));
shell.WriteLine("Disabled network entity report overlay.");
}
}
}
}
}

View File

@@ -1,16 +1,10 @@
using System.Collections.Generic;
using Robust.Client.Graphics;
using Robust.Client.Graphics.Drawing;
using Robust.Client.Graphics.Overlays;
using Robust.Client.Interfaces.Console;
using Robust.Client.Interfaces.GameStates;
using Robust.Client.Interfaces.Graphics.Overlays;
using Robust.Client.Interfaces.ResourceManagement;
using Robust.Client.ResourceManagement;
using Robust.Shared.Interfaces.Network;
using Robust.Shared.Interfaces.Timing;
using Robust.Shared.Console;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Timing;
namespace Robust.Client.GameStates
@@ -172,18 +166,18 @@ namespace Robust.Client.GameStates
public string Help => "net_graph <0|1>";
public string Description => "Toggles the net statistics pannel.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
console.AddLine("Invalid argument amount. Expected 2 arguments.", Color.Red);
return false;
shell.WriteError("Invalid argument amount. Expected 2 arguments.");
return;
}
if (!byte.TryParse(args[0], out var iValue))
{
console.AddLine("Invalid argument: Needs to be 0 or 1.");
return false;
shell.WriteLine("Invalid argument: Needs to be 0 or 1.");
return;
}
var bValue = iValue > 0;
@@ -192,15 +186,13 @@ namespace Robust.Client.GameStates
if(bValue && !overlayMan.HasOverlay(nameof(NetGraphOverlay)))
{
overlayMan.AddOverlay(new NetGraphOverlay());
console.AddLine("Enabled network overlay.");
shell.WriteLine("Enabled network overlay.");
}
else if(overlayMan.HasOverlay(nameof(NetGraphOverlay)))
{
overlayMan.RemoveOverlay(nameof(NetGraphOverlay));
console.AddLine("Disabled network overlay.");
shell.WriteLine("Disabled network overlay.");
}
return false;
}
}
}

View File

@@ -1,16 +1,11 @@
using Robust.Client.Graphics.Drawing;
using Robust.Client.Graphics.Overlays;
using Robust.Client.Graphics.Shaders;
using Robust.Client.Interfaces.Console;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Client.Interfaces.Graphics.Overlays;
using Robust.Shared.GameObjects.Components;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.Timing;
using Robust.Client.Graphics;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Prototypes;
using Robust.Shared.Timing;
namespace Robust.Client.GameStates
{
@@ -34,7 +29,7 @@ namespace Robust.Client.GameStates
handle.UseShader(_shader);
var worldHandle = (DrawingHandleWorld) handle;
var viewport = _eyeManager.GetWorldViewport();
foreach (var boundingBox in _componentManager.EntityQuery<IPhysicsComponent>())
foreach (var boundingBox in _componentManager.EntityQuery<IPhysicsComponent>(true))
{
// all entities have a TransformComponent
var transform = ((IComponent)boundingBox).Owner.Transform;
@@ -73,18 +68,18 @@ namespace Robust.Client.GameStates
public string Help => "net_draw_interp <0|1>";
public string Description => "Toggles the debug drawing of the network interpolation.";
public bool Execute(IDebugConsole console, params string[] args)
public void Execute(IConsoleShell shell, string argStr, string[] args)
{
if (args.Length != 1)
{
console.AddLine("Invalid argument amount. Expected 2 arguments.", Color.Red);
return false;
shell.WriteError("Invalid argument amount. Expected 2 arguments.");
return;
}
if (!byte.TryParse(args[0], out var iValue))
{
console.AddLine("Invalid argument: Needs to be 0 or 1.");
return false;
shell.WriteLine("Invalid argument: Needs to be 0 or 1.");
return;
}
var bValue = iValue > 0;
@@ -93,15 +88,13 @@ namespace Robust.Client.GameStates
if (bValue && !overlayMan.HasOverlay(nameof(NetInterpOverlay)))
{
overlayMan.AddOverlay(new NetInterpOverlay());
console.AddLine("Enabled network interp overlay.");
shell.WriteLine("Enabled network interp overlay.");
}
else if (overlayMan.HasOverlay(nameof(NetInterpOverlay)))
{
overlayMan.RemoveOverlay(nameof(NetInterpOverlay));
console.AddLine("Disabled network interp overlay.");
shell.WriteLine("Disabled network interp overlay.");
}
return false;
}
}
}

View File

@@ -1,11 +1,10 @@
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Shared.Map;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.ViewVariables;
#nullable enable
namespace Robust.Client.Graphics.ClientEye
namespace Robust.Client.Graphics
{
/// <inheritdoc />
public class Eye : IEye

View File

@@ -1,13 +1,11 @@
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Interfaces.Graphics.ClientEye;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
#nullable enable
namespace Robust.Client.Graphics.ClientEye
namespace Robust.Client.Graphics
{
/// <inheritdoc />
public sealed class EyeManager : IEyeManager

View File

@@ -1,4 +1,4 @@
namespace Robust.Client.Graphics.ClientEye
namespace Robust.Client.Graphics
{
/// <summary>
/// A fixed eye is an eye which is fixed to one point, its position.

View File

@@ -2,7 +2,7 @@
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Robust.Client.Interfaces.Graphics.ClientEye
namespace Robust.Client.Graphics
{
/// <summary>
/// An Eye is a point through which the player can view the world.

View File

@@ -1,7 +1,7 @@
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Robust.Client.Interfaces.Graphics.ClientEye
namespace Robust.Client.Graphics
{
/// <summary>
/// Keeps a reference to the current eye (camera) that the client is seeing though, and provides

View File

@@ -8,7 +8,6 @@ using System.Threading;
using OpenToolkit.Audio.OpenAL;
using OpenToolkit.Audio.OpenAL.Extensions.Creative.EFX;
using Robust.Client.Audio;
using Robust.Client.Interfaces.Graphics;
using Robust.Shared;
using Robust.Shared.Log;
using Vector2 = Robust.Shared.Maths.Vector2;

View File

@@ -1,6 +1,3 @@
using Robust.Client.Graphics.ClientEye;
using Robust.Shared.Maths;
namespace Robust.Client.Graphics.Clyde
{
internal sealed partial class Clyde

View File

@@ -2,7 +2,6 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using OpenToolkit.GraphicsLibraryFramework;
using Robust.Client.Interfaces.Graphics;
using Robust.Client.Utility;
using Robust.Shared.Maths;
using SixLabors.ImageSharp;

View File

@@ -1,5 +1,3 @@
using Robust.Client.Interfaces.Graphics;
namespace Robust.Client.Graphics.Clyde
{
internal sealed partial class Clyde

View File

@@ -77,7 +77,7 @@ namespace Robust.Client.Graphics.Clyde
{
// OpenGL ES capabilities.
CheckGLCap(ref _hasGLKhrDebug, "khr_debug", (3, 2), "GL_KHR_debug");
if (CompareVersion(3, 2, major, minor))
if (!CompareVersion(3, 2, major, minor))
{
// We're ES <3.2, KHR_debug is extension and needs KHR suffixes.
_isGLKhrDebugESExtension = true;

View File

@@ -2,8 +2,7 @@
using System.Buffers;
using System.Collections.Generic;
using OpenToolkit.Graphics.OpenGL4;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Interfaces.GameObjects.Components;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;

Some files were not shown because too many files have changed in this diff Show More