This is a mobile optimized page that loads fast, if you want to load the real page, click this text.

FAQ [C#] Скрипт на получение всех инстансов Script в моде

DaVilka

Гуру
Автор темы
16 Сен 2020
607
228
108
Скрипт выдирает все инстансы мода изнутри бадстрапера, не нашел как это сделать легально, кроме как вручную в каждом скрипте добавлять в список текущий инстанс,
поэтому наговнокодил такую хрень. Может кому пригодится

C#:
using System.Reflection;
namespace HardLife.Utils
{
    internal class ScriptInstances : Script
    {
        internal static Action<List<Script>> OnScriptInstancesLoaded = null;
        [ServerEvent(Event.ResourceStart)]
        public void OnResourceStart()
        {
            OnScriptInstancesLoaded?.Invoke(GetScriptInstances());
        }
        internal static List<Script> GetScriptInstances()
        {
            List<Script> scripts = new List<Script>();
            BindingFlags bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;

            Assembly assembly = Assembly.GetEntryAssembly();
            Type gameServer = assembly.GetTypes().First(t => t.Name == "GameServer");

            PropertyInfo serverInstance = gameServer.GetProperty("ServerInstance", bf);
            var gameserver = serverInstance.GetValue(gameServer, null);

            FieldInfo eventHandler = gameServer.GetField("EventHandler", bf);
            var eventHandlerData = eventHandler.GetValue(gameServer);
            
            FieldInfo _cachedCollectionsInfo = eventHandlerData.GetType().GetField("_cachedCollections", bf);
            object _cachedCollections = ((object[])_cachedCollectionsInfo.GetValue(eventHandlerData))[0];

            FieldInfo resourcesField = _cachedCollections.GetType().GetField("Resource", bf);
            object resources = resourcesField.GetValue(_cachedCollections);


            if (resources != null)
            {
                PropertyInfo enginesProperty = resources.GetType().GetProperty("Engines", bf);
                var enginesValue = enginesProperty.GetValue(resources, null);
                object[] engines = (object[])enginesValue.GetType().GetMethod("ToArray", bf).Invoke(enginesValue, null);
                foreach (var item in engines)
                {
                    FieldInfo conpileScriptProp = item.GetType().GetField("CompiledScript", bf);
                    scripts.Add((Script)conpileScriptProp.GetValue(item));
                }
            }
            return scripts;
        }
    }
}
 

OGPRussia

Специалист
7 Окт 2020
132
36
85
Можно по подробнее, что за получения всех объектов.
Очень интересно! Для чего это используется?
 

DaVilka

Гуру
Автор темы
16 Сен 2020
607
228
108
А что за инстансы?
Когда вы создаёте скрипт вы должны унаследовать его от класса Script. Будстрапер с помощью рефлексии ищет все ваши классы и инициализирует их, а екземпляры хранит у себя внутри, соответственно класс который наследует Script не может быть статическим. С помощью этого скрипта можно получить все экземпляры классов созданные будстрапером в вашем моде(экземпляры классов которые наследовали Script и были инициализированны). Используется для своей рефлексии. Я на пример делал с его помощью свою систему ивентов, так как только классы унаследовавшие Script могут принимать server/remote events, мне нужно было получить их екземпляры что бы расширить их без ограничение и избавится от статических методов

P.S. Но это я делал до того как понял что можно использовать банальное переопределение, так что скрипт по сути не очень полезен
 
Последнее редактирование:

OGPRussia

Специалист
7 Окт 2020
132
36
85
Спасибо, было очень интересно.
 

DaVilka

Гуру
Автор темы
16 Сен 2020
607
228
108
Спасибо, было очень интересно.
Этот конкретно скрипт бесполезен, но самка идея не такая уж и бесполезная. В этом скрипте используется только GetValue, но помимо него есть еще SetValue.
Кто то давно создавал на форуме тему по поводу толкания машины. Типо когда толкает владелец (или там чтио т опро двери было?) то все ок, но когда толкает другой чел то не ок, крч вывод был такой что тачка синхрится тем челов который последний в ней сидел, по этому багает, но сменить контроллера тачки нельзя, только получить. С помощью этого примера можно реализовать функцию которая будет задавать контроллер тачки, сама эта возможность реализована в бадстрейпе, просто она не выведена. На сколько она работает хз