using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Text; using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Prototypes; using Robust.Shared.Utility; namespace Robust.Shared.Scripting { [PublicAPI] [SuppressMessage("ReSharper", "IdentifierTypo")] [SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "CA1822")] public abstract class ScriptGlobalsShared { private const BindingFlags DefaultHelpFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; [field: Dependency] public IEntityManager ent { get; } = default!; [field: Dependency] public IPrototypeManager prot { get; } = default!; [field: Dependency] public IMapManager map { get; } = default!; public IEnumerable protos() where T : class, IPrototype { return prot.EnumeratePrototypes(); } public IEnumerable eprotos => prot.EnumeratePrototypes(); public EntityCoordinates gpos(double x, double y, int gridId) { return gpos(x, y, new GridId(gridId)); } public EntityCoordinates gpos(double x, double y, GridId gridId) { if (!map.TryGetGrid(gridId, out var grid)) { return new EntityCoordinates(EntityUid.Invalid, ((float) x, (float) y)); } return new EntityCoordinates(grid.GridEntityId, ((float) x, (float) y)); } public EntityUid eid(int i) { return new(i); } public T gcm(int i) { return ent.GetComponent(eid(i)); } public IMapGrid getgrid(int i) { return map.GetGrid(new GridId(i)); } public IMapGrid getgrid(GridId mapId) { return map.GetGrid(mapId); } public EntityUid spawn(string prototype, EntityCoordinates position) { return ent.SpawnEntity(prototype, position); } public T res() { return IoCManager.Resolve(); } public object? prop(object target, string name) { return target.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic) !.GetValue(target); } public void setprop(object target, string name, object? value) { target.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) !.SetValue(target, value); } public object? fld(object target, string name) { return target.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) !.GetValue(target); } public void setfld(object target, string name, object? value) { target.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public) !.SetValue(target, value); } public object? call(object target, string name, params object[] args) { var t = target.GetType(); // TODO: overloads var m = t.GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); return m!.Invoke(target, args); } public void help() { help(GetType(), DefaultHelpFlags &~ BindingFlags.NonPublic, false, false); } public void help(Type type, BindingFlags flags = DefaultHelpFlags, bool specialNameMethods = true, bool modifiers = true) { var builder = new StringBuilder(); foreach (var member in type.GetMembers(flags)) { switch (member.MemberType) { case MemberTypes.Method: var method = (MethodInfo) member; if (!specialNameMethods && method.IsSpecialName) continue; // Let's not print constructors, property methods, etc. builder.Append(method.PrintMethodSignature(modifiers)); builder.AppendLine(";"); break; case MemberTypes.Property: builder.AppendLine(((PropertyInfo)member).PrintPropertySignature(modifiers, true)); break; case MemberTypes.Field: builder.Append(((FieldInfo) member).PrintFieldSignature(modifiers)); builder.AppendLine(";"); break; default: continue; } builder.AppendLine(); } // This is slow, so do it all at once. WriteSyntax(builder.ToString()); } protected abstract void WriteSyntax(object toString); public abstract void write(object toString); public abstract void show(object obj); } }