| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- using UnityEngine;
- using UnityEngine.Events;
- public abstract class ActDetectorBase : MonoBehaviour
- {
- protected const string CONTAINER_NAME = "anticheat detectors";
- protected const string MENU_PATH = "poc/anticheat/";
- protected const string GAME_OBJECT_MENU_PATH = "GameObject/Create Other/" + MENU_PATH;
- protected static GameObject detectorsContainer;
- /// <summary>
- /// Allows to start detector automatically.
- /// Otherwise, you'll need to call StartDetection() method to start it.
- /// </summary>
- /// Useful in conjunction with proper Detection Event configuration in the inspector.
- /// Allows to use detector without writing any code except the actual reaction on cheating.
- [Tooltip("Automatically start detector. Detection Event will be called on detection.")]
- public bool autoStart = false;
- /// <summary>
- /// Detector will survive new level (scene) load if checked. Otherwise it will be destroyed.
- /// </summary>
- /// On dispose Detector follows 2 rules:
- /// - if Game Object's name is "Anti-Cheat Toolkit Detectors": it will be automatically
- /// destroyed if no other Detectors left attached regardless of any other components or children;<br/>
- /// - if Game Object's name is NOT "Anti-Cheat Toolkit Detectors": it will be automatically destroyed only
- /// if it has neither other components nor children attached;
- [Tooltip("Detector will survive new level (scene) load if checked.")]
- public bool keepAlive = true;
- /// <summary>
- /// Detector component will be automatically disposed after firing callback if enabled.
- /// Otherwise, it will just stop internal processes.
- /// </summary>
- /// On dispose Detector follows 2 rules:
- /// - if Game Object's name is "Anti-Cheat Toolkit Detectors": it will be automatically
- /// destroyed if no other Detectors left attached regardless of any other components or children;<br/>
- /// - if Game Object's name is NOT "Anti-Cheat Toolkit Detectors": it will be automatically destroyed only
- /// if it has neither other components nor children attached;
- [Tooltip("Automatically dispose Detector after firing callback.")]
- public bool autoDispose = true;
- [SerializeField]
- protected UnityEvent detectionEvent = null;
- protected UnityAction detectionAction = null;
- [SerializeField]
- protected bool detectionEventHasListener = false;
- protected bool isRunning;
- protected bool started;
- #region detectors placement
- #if UNITY_EDITOR
- /*[UnityEditor.MenuItem(GAME_OBJECT_MENU_PATH + "All detectors", false, 0)]
- private static void AddAllDetectorsToScene()
- {
- AddInjectionDetectorToScene();
- AddSpeedHackDetectorToScene();
- }
- [UnityEditor.MenuItem(GAME_OBJECT_MENU_PATH + InjectionDetector.COMPONENT_NAME, false, 1)]
- private static void AddInjectionDetectorToScene()
- {
- SetupDetectorInScene<InjectionDetector>();
- }
- [UnityEditor.MenuItem(GAME_OBJECT_MENU_PATH + SpeedHackDetector.COMPONENT_NAME, false, 1)]
- private static void AddSpeedHackDetectorToScene()
- {
- SetupDetectorInScene<SpeedHackDetector>();
- }*/
- static void SetupDetectorInScene<T>() where T : ActDetectorBase
- {
- T component = FindObjectOfType<T>();
- string detectorName = typeof(T).Name;
- if(component !=null)
- {
- if(component.gameObject.name == CONTAINER_NAME)
- {
- UnityEditor.EditorUtility.DisplayDialog(detectorName + " already exists!", detectorName + " already exists in scene and correctly placed on object \"" + CONTAINER_NAME + "\"", "OK");
- }
- else
- {
- int dialogResult = UnityEditor.EditorUtility.DisplayDialogComplex(detectorName + " already exists!", detectorName + " already exists in scene and placed on object \"" + component.gameObject.name + "\". Do you wish to move it to the Game Object \"" + CONTAINER_NAME + "\" or delete it from scene at all?", "Move", "Delete", "Cancel");
- switch (dialogResult)
- {
- case 0:
- GameObject container = GameObject.Find(CONTAINER_NAME);
- if (container == null)
- {
- container = new GameObject(CONTAINER_NAME);
- }
- T newComponent = container.AddComponent<T>();
- UnityEditor.EditorUtility.CopySerialized(component, newComponent);
- DestroyDetectorImmediate(component);
- break;
- case 1:
- DestroyDetectorImmediate(component);
- break;
- }
- }
- }else
- {
- GameObject container = GameObject.Find(CONTAINER_NAME);
- if (container == null)
- {
- container = new GameObject(CONTAINER_NAME);
- UnityEditor.Undo.RegisterCreatedObjectUndo(container, "Create " + CONTAINER_NAME);
- }
- UnityEditor.Undo.AddComponent<T>(container);
- UnityEditor.EditorUtility.DisplayDialog(detectorName + " added!", detectorName + " successfully added to the object \"" + CONTAINER_NAME + "\"", "OK");
- }
- }
- static void DestroyDetectorImmediate(ActDetectorBase component)
- {
- if (component.transform.childCount == 0 && component.GetComponentsInChildren<Component>(true).Length <= 2)
- {
- DestroyImmediate(component.gameObject);
- }
- else
- {
- DestroyImmediate(component);
- }
- }
- #endif
- #endregion
- #region UNITY_MESSAGES
- private void Start()
- {
- if (detectorsContainer == null && gameObject.name == CONTAINER_NAME)
- {
- detectorsContainer = gameObject;
- }
- if (autoStart && !started)
- {
- StartDetectionAutomatically();
- }
- }
- private void OnEnable()
- {
- if (!started || (!detectionEventHasListener && detectionAction == null))
- return;
- ResumeDetector();
- }
- private void OnDisable()
- {
- if (!started) return;
- PauseDetector();
- }
- private void OnApplicationQuit()
- {
- DisposeInternal();
- }
- protected virtual void OnDestroy()
- {
- StopDetectionInternal();
- if (transform.childCount == 0 && GetComponentsInChildren<Component>().Length <= 2)
- {
- Destroy(gameObject);
- }
- else if (name == CONTAINER_NAME && GetComponentsInChildren<ActDetectorBase>().Length <= 1)
- {
- Destroy(gameObject);
- }
- }
- #endregion
- protected virtual bool Init(ActDetectorBase instance, string detectorName)
- {
- if (instance != null && instance != this && instance.keepAlive)
- {
- Destroy(this);
- return false;
- }
- DontDestroyOnLoad(gameObject);
- return true;
- }
- protected virtual void DisposeInternal()
- {
- Destroy(this);
- }
- internal virtual void OnCheatingDetected()
- {
- if (detectionAction != null) detectionAction();
- if (detectionEventHasListener) detectionEvent.Invoke();
- //if (autoDispose)
- //{
- // DisposeInternal();
- //}
- //else
- //{
- // StopDetectionInternal();
- //}
- }
- protected abstract void StartDetectionAutomatically();
- protected abstract void StopDetectionInternal();
- protected abstract void PauseDetector();
- protected abstract void ResumeDetector();
- }
|