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.Map.Components; 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; [field: Dependency] public IEntityManager ent { get; } = default!; [field: Dependency] public IEntitySystemManager esm { get; } = default!; [field: Dependency] public IPrototypeManager prot { get; } = default!; [field: Dependency] public IMapManager map { get; } = default!; [field: Dependency] public IDependencyCollection dependencies { get; } = default!; protected ScriptGlobalsShared(IDependencyCollection dependencies) { dependencies.InjectDependencies(this); } 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 EntityUid(gridId)); } public EntityCoordinates gpos(double x, double y, EntityUid gridId) { if (!map.TryGetGrid(gridId, out var grid)) { return new EntityCoordinates(EntityUid.Invalid, ((float) x, (float) y)); } return new EntityCoordinates(grid.Owner, ((float) x, (float) y)); } public EntityUid eid(int i) { return new(i); } public MapGridComponent getgrid(int i) { return map.GetGrid(new EntityUid(i)); } public MapGridComponent getgrid(EntityUid mapId) { return map.GetGrid(mapId); } public T res() { return dependencies.Resolve(); } public T ressys() where T : EntitySystem { return esm.GetEntitySystem(); } 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, false, false); } public void help(object obj, BindingFlags flags = DefaultHelpFlags, bool specialNameMethods = true, bool modifiers = true) { help(obj.GetType(), flags, specialNameMethods, modifiers); } 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); #region EntityManager proxy methods public T Comp(EntityUid uid) => ent.GetComponent(uid); public bool TryComp(EntityUid uid, out T? comp) => ent.TryGetComponent(uid, out comp); public bool HasComp(EntityUid uid) => ent.HasComponent(uid); public EntityUid Spawn(string? prototype, EntityCoordinates position) => ent.SpawnEntity(prototype, position); public void Del(EntityUid uid) => ent.DeleteEntity(uid); public void Dirty(EntityUid uid) => ent.DirtyEntity(uid); public void Dirty(Component comp) => ent.Dirty(comp); public string Name(EntityUid uid) => ent.GetComponent(uid).EntityName; public string Desc(EntityUid uid) => ent.GetComponent(uid).EntityDescription; public EntityPrototype? Prototype(EntityUid uid) => ent.GetComponent(uid).EntityPrototype; public EntityStringRepresentation ToPrettyString(EntityUid uid) => ent.ToPrettyString(uid); public IEnumerable AllComps(EntityUid uid) => ent.GetComponents(uid); public TransformComponent Transform(EntityUid uid) => ent.GetComponent(uid); public MetaDataComponent MetaData(EntityUid uid) => ent.GetComponent(uid); public EntityCoordinates Pos(EntityUid uid) => Transform(uid).Coordinates; public IEnumerable Query(bool includePaused = false) where TComp1 : IComponent { return ent.EntityQuery(includePaused); } public IEnumerable<(TComp1, TComp2)> Query(bool includePaused = false) where TComp1 : IComponent where TComp2 : IComponent { return ent.EntityQuery(includePaused); } public IEnumerable<(TComp1, TComp2, TComp3)> Query(bool includePaused = false) where TComp1 : IComponent where TComp2 : IComponent where TComp3 : IComponent { return ent.EntityQuery(includePaused); } #endregion } }