using System.Reflection; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using skyscraper5.Skyscraper.Plugins; using skyscraper8.UI.MonoGame.Bridge; namespace skyscraper8.UI.MonoGame.Screenhacks { internal class ScreenhackManager : GameObject { private Dictionary knownScreenhacks; public ScreenhackManager() { knownScreenhacks = new Dictionary(); Assembly assembly = GetType().Assembly; Type screenhackBaseType = typeof(IScreenhack); Type pluginPriorityTYpe = typeof(PluginPriorityAttribute); Type[] types = assembly.GetTypes(); foreach (Type type in types) { if (!type.IsAssignableTo(screenhackBaseType)) continue; if (type.IsInterface) continue; ConstructorInfo constructor = type.GetConstructor(new Type[] { }); Attribute attribute = type.GetCustomAttributes(pluginPriorityTYpe).FirstOrDefault(); if (attribute == null) { throw new ScreenhackException(String.Format("{0} is missing the {1} attribute.", type.Name, nameof(PluginPriorityAttribute))); } PluginPriorityAttribute ppa = (PluginPriorityAttribute)attribute; knownScreenhacks.Add(ppa.Priority, constructor); } } private IScreenhack currentScreenhack; private int currentScreenhackId; public int WantedScreenhackId { get; set; } public void Update(GameTime gameTime, GraphicsDevice graphicsDevice) { if (currentScreenhack == null || currentScreenhackId != WantedScreenhackId) { ConstructorInfo constructorInfo = knownScreenhacks[WantedScreenhackId]; object invoke = constructorInfo.Invoke(new object[] { }); currentScreenhack = (IScreenhack)invoke; currentScreenhack.SetGraphicsDevice(graphicsDevice,graphicsDevice.PresentationParameters.Bounds); currentScreenhackId = WantedScreenhackId; } } public void Draw(GameTime gameTime, SpriteBatch spriteBatch, Rectangle windowBounds) { currentScreenhack.Draw(gameTime, spriteBatch, windowBounds); } } }