Browse Source

Removed all obsolete classes and some commented out code

tags/v2.0.0
NorbiPeti 3 years ago
parent
commit
f5e3010e48
Signed by: NorbiPeti <szatmari.norbert.peter@gmail.com> GPG Key ID: DBA4C4549A927E56
27 changed files with 2 additions and 1895 deletions
  1. +0
    -218
      TechbloxModdingAPI/Blocks/CustomBlock.cs
  2. +0
    -85
      TechbloxModdingAPI/Blocks/CustomBlockAttribute.cs
  3. +0
    -54
      TechbloxModdingAPI/Blocks/Engines/CustomBlockEngine.cs
  4. +0
    -47
      TechbloxModdingAPI/Events/DeterministicStepComposeEngineGroupsPatch.cs
  5. +0
    -106
      TechbloxModdingAPI/Events/EmitterBuilder.cs
  6. +0
    -61
      TechbloxModdingAPI/Events/EventEngineFactory.cs
  7. +0
    -33
      TechbloxModdingAPI/Events/EventExceptions.cs
  8. +0
    -128
      TechbloxModdingAPI/Events/EventManager.cs
  9. +0
    -24
      TechbloxModdingAPI/Events/EventType.cs
  10. +0
    -56
      TechbloxModdingAPI/Events/GameActivatedComposePatch.cs
  11. +0
    -26
      TechbloxModdingAPI/Events/GameReloadedPatch.cs
  12. +0
    -54
      TechbloxModdingAPI/Events/GameStateBuildEmitterEngine.cs
  13. +0
    -53
      TechbloxModdingAPI/Events/GameStateSimulationEmitterEngine.cs
  14. +0
    -30
      TechbloxModdingAPI/Events/GameSwitchedToPatch.cs
  15. +0
    -166
      TechbloxModdingAPI/Events/HandlerBuilder.cs
  16. +0
    -23
      TechbloxModdingAPI/Events/IEventEmitterEngine.cs
  17. +0
    -20
      TechbloxModdingAPI/Events/IEventHandlerEngine.cs
  18. +0
    -42
      TechbloxModdingAPI/Events/MenuActivatedPatch.cs
  19. +0
    -28
      TechbloxModdingAPI/Events/MenuSwitchedToPatch.cs
  20. +0
    -17
      TechbloxModdingAPI/Events/ModEventEntityDescriptor.cs
  21. +0
    -23
      TechbloxModdingAPI/Events/ModEventEntityStruct.cs
  22. +0
    -66
      TechbloxModdingAPI/Events/SimpleEventEmitterEngine.cs
  23. +0
    -145
      TechbloxModdingAPI/Events/SimpleEventHandlerEngine.cs
  24. +0
    -13
      TechbloxModdingAPI/Main.cs
  25. +2
    -244
      TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs
  26. +0
    -18
      TechbloxModdingAPI/Utility/Logging.cs
  27. +0
    -115
      TechbloxModdingAPI/Utility/VersionTracking.cs

+ 0
- 218
TechbloxModdingAPI/Blocks/CustomBlock.cs View File

@@ -1,218 +0,0 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using HarmonyLib;

using DataLoader;
using RobocraftX.Common;
using RobocraftX.Rendering;
using RobocraftX.Schedulers;
using Svelto.ECS;
using Svelto.ECS.Experimental;
using Svelto.Tasks;
using Svelto.Tasks.ExtraLean;
using UnityEngine;
using UnityEngine.AddressableAssets;
using Material = UnityEngine.Material;
using ServiceLayer;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Blocks
{
/// <summary>
/// Experimental support for adding custom blocks to the game.
/// </summary>
public class CustomBlock : Block
{
private static ushort nextID = 500;
/// <summary>
/// Key: Prefab path
/// </summary>
private static readonly Dictionary<string, Type> CustomBlocks = new Dictionary<string, Type>();
//private static readonly CustomBlockEngine Engine = new CustomBlockEngine();
private static readonly List<(ushort id, Action<CubeListData> action)> BlockChangeActions =
new List<(ushort, Action<CubeListData>)>();

private static bool _canRegister = true;
/// <summary>
/// Register a custom block type. Call it as soon as possible (in OnApplicationStart()).<br />
/// You need a Unity project with Addressables and Havok installed and need a prefab added as an addressable asset.
/// Build the addressables and the project and copy the catalog.json from StreamingAssets, you'll need to reference this file.
/// Also copy the asset files from the subfolder to the same path in the game.
/// </summary>
/// <typeparam name="T">The custom block type</typeparam>
public static void RegisterCustomBlock<T>() where T : CustomBlock
{
if (!_canRegister)
throw new InvalidOperationException(
"It's too late to register custom blocks. Register it before the game starts loading.");
var type = typeof(T);
var attr = type.GetCustomAttribute<CustomBlockAttribute>();
if (attr == null)
throw new ArgumentException("The custom block type is missing the CustomBlock annotation");
string typeName = type.FullName ??
throw new ArgumentException("The given block type doesn't have a concrete full name.");
if (!File.Exists(attr.Catalog))
throw new FileNotFoundException("The specified catalog cannot be found for " + typeName);
CustomBlocks.Add(attr.AssetPath, type);
Logging.MetaDebugLog("Registered custom block type " + typeName);
}

/// <summary>
/// A low-level method for changing any property of an existing block. Use with caution.
/// </summary>
/// <param name="id">The block ID</param>
/// <param name="modifier">An action that modifies a property of the block</param>
public static void ChangeExistingBlock(ushort id, Action<CubeListData> modifier)
{
BlockChangeActions.Add((id, modifier));
}

public CustomBlock(EGID id) : base(id)
{
/*if (id.groupID != Group)
throw new BlockTypeException("The block is not a custom block! It has a group of " + id.groupID);*/
}

public CustomBlock(uint id) : base(id)
{
}

//public static ExclusiveGroup Group { get; } = new ExclusiveGroup("Custom block");

//[HarmonyPatch] - TODO
public static class MaterialCopyPatch
{
private static Material[] materials;

public static void Prefix(List<PrefabData> prefabData, IList<GameObject> prefabs)
{
for (var index = 0; index < prefabs.Count; index++)
{
if (prefabData[index].prefabName == "ConsoleBlock")
materials = prefabs[index].GetComponentsInChildren<MeshRenderer>()[0].sharedMaterials;
}

for (var index = 0; index < prefabs.Count; index++)
{
if (CustomBlocks.ContainsKey(prefabData[index].prefabName)) //This is a custom block
prefabs[index].GetComponentsInChildren<MeshRenderer>()[0].sharedMaterials = materials;
}
}

public static MethodBase TargetMethod()
{ //General block registration
return AccessTools.Method("RobocraftX.Rendering.ECSGPUIResourceManager:InitPreRegisteredPrefabs");
}
}

[HarmonyPatch]
public static class CubeRegistrationPatch
{
public static void Prefix(IDataDB dataDB)
{
//var abd = dataDB.GetValue<CubeListData>((int) BlockIDs.Cube);
foreach (var (key, type) in CustomBlocks)
{
var attr = type.GetCustomAttribute<CustomBlockAttribute>();
var cld = new CubeListData
{ //"Assets/Prefabs/Cube.prefab" - "CTR_CommandBlock" - "strConsoleBlock"
cubeType = attr.Type,
//cubeCategory = (CubeCategory) 1000,
cubeCategory = attr.Category,
inventoryCategory = attr.InventoryCategory,
ID = nextID++,
Path = attr.AssetPath, //Index out of range exception: Asset failed to load (wrong path)
SpriteName = attr.SpriteName,
CubeNameKey = attr.NameKey,
CubeDescriptionKey = attr.DescKey,
SelectableFaces = new[] {0, 1, 2, 3, 4, 5},
GridScale = new[] {5f, 5, 5},
DefaultMaterialID = 0, //TODO: Material API
scalingPermission = attr.ScalingPermission,
SortIndex = attr.SortIndex,
DefaultColour = attr.DefaultColor.Index,
Volume = attr.Volume,
EdgeConnectingFaces = new[] {0, 1, 2, 3, 4, 5},
PointDataVolumeMultiplier = 1f
};
dataDB.GetValues<CubeListData>().Add(cld.ID.ToString(), cld); //The registration needs to happen after the ID has been set
dataDB.GetFasterValues<CubeListData>().Add(cld.ID, cld); //So can't use the builtin method to create a CubeListData
//Engine.RegisterBlock((ushort) cld.ID, key); - TODO
}

foreach (var (id, action) in BlockChangeActions)
action(dataDB.GetValue<CubeListData>(id));
/*ushort lastKey = ushort.MaxValue;
foreach (var (key, value) in dataDB.GetValues<CubeListData>()
.OrderBy(kv=>ushort.Parse(kv.Key)))
{
var data = (CubeListData) value;
ushort currentKey = ushort.Parse(key);
Console.WriteLine($"{LocalizationService.Localize(data.CubeNameKey)}{(currentKey != lastKey + 1 ? $" = {key}" : "")},");
lastKey = currentKey;
}*/

_canRegister = false;
}

public static MethodBase TargetMethod()
{
return AccessTools.Method("RobocraftX.CR.MainGame.MainGameCompositionRoot:Init");
}
}

/*[HarmonyPatch] - The block has no collision even in simulation if using a custom category
private static class FactorySetupPatch
{
public static void Prefix(BlockEntityFactory __instance)
{
var builders = (Dictionary<CubeCategory, IBlockBuilder>)
AccessTools.Field(__instance.GetType(), "_blockBuilders").GetValue(__instance);
builders.Add((CubeCategory) 1000, new BlockBuilder<StandardBlockEntityDescriptor>(Group));
}

public static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(BlockEntityFactory), "ParseDataDB");
}
}*/

private static IEnumerator Prepare()
{ //Should be pretty quick
foreach (var type in CustomBlocks.Values)
{
var attr = type.GetCustomAttribute<CustomBlockAttribute>();
Logging.Log("Loading custom block catalog " + attr.Catalog);
var res = Addressables.LoadContentCatalogAsync(attr.Catalog);
while (!res.IsDone) yield return Yield.It;
Logging.Log("Loaded custom block catalog: " + res.Result.LocatorId);
Addressables.AddResourceLocator(res.Result);
}
}

internal new static void Init()
{
Prepare().RunOn(ExtraLean.UIScheduler);
//GameEngineManager.AddGameEngine(Engine); - TODO: Fix serialization and implement block ID update
}

/*internal static void OnBlockFactoryObtained(BlockEntityFactory factory)
{
var builders = (Dictionary<CubeCategory, IBlockBuilder>)
AccessTools.Field(factory.GetType(), "_blockBuilders").GetValue(factory);
builders.Add((CubeCategory) 1000, new BlockBuilder<StandardBlockEntityDescriptor>(Group));
}*/

internal struct DataStruct : IEntityComponent
{
public ECSString Name;
public ushort ID;
}
}
}

+ 0
- 85
TechbloxModdingAPI/Blocks/CustomBlockAttribute.cs View File

@@ -1,85 +0,0 @@
using System;
using DataLoader;

namespace TechbloxModdingAPI.Blocks
{
[AttributeUsage(AttributeTargets.Class)]
public class CustomBlockAttribute : Attribute
{
/// <summary>
/// Custom block attribute necessary for configuration.
/// </summary>
/// <param name="catalog">File path to the catalog.json that holds asset references for the custom block</param>
/// <param name="assetPath">The path/address to the block's prefab specified in Unity</param>
/// <param name="nameKey">The translation key for the block's name</param>
/// <param name="spriteName">The path to the inventory sprite for the block, console block by default</param>
/// <param name="descKey">The translation key for the block's description</param>
public CustomBlockAttribute(string catalog, string assetPath, string nameKey,
string spriteName = "CTR_CommandBlock", string descKey = "")
{
Catalog = catalog;
AssetPath = assetPath;
SpriteName = spriteName;
NameKey = nameKey;
DescKey = descKey;
}

/// <summary>
/// The location of the catalog.json file used to find assets for this block.
/// </summary>
public string Catalog { get; }
/// <summary>
/// The asset path/address for the block's prefab.
/// </summary>
public string AssetPath { get; }
/// <summary>
/// The name of the sprite used in the inventory.
/// </summary>
public string SpriteName { get; }
/// <summary>
/// The translation key for the block's name.
/// </summary>
public string NameKey { get; }
/// <summary>
/// The translation key for the block's description.
/// </summary>
public string DescKey { get; }

/// <summary>
/// The block's type - block, joint, light.
/// </summary>
public CubeType Type { get; set; } = CubeType.Block;
/// <summary>
/// The block's category, so it's treated as a pre-existing functional block.
/// </summary>
public CubeCategory Category { get; set; } = CubeCategory.General;
/// <summary>
/// The block's inventory category.
/// </summary>
public InventoryCategory InventoryCategory { get; set; } = InventoryCategory.Shapes;
/// <summary>
/// The block's mass.
/// </summary>
public float Mass { get; set; } = 1f;
/// <summary>
/// The key of the material properties this block should use.
/// </summary>
public string Material { get; set; } = "Aluminium";
/// <summary>
/// The scaling permission determining what scaling is allowed on this block.
/// </summary>
public ScalingPermission ScalingPermission { get; set; }
/// <summary>
/// The sort index in the inventory.
/// </summary>
public int SortIndex { get; set; }
/// <summary>
/// The default color of the block when placed.
/// </summary>
public BlockColor DefaultColor { get; set; }
/// <summary>
/// The volume of the block.
/// </summary>
public float Volume { get; set; } = 1f;
}
}

+ 0
- 54
TechbloxModdingAPI/Blocks/Engines/CustomBlockEngine.cs View File

@@ -1,54 +0,0 @@
namespace TechbloxModdingAPI.Blocks.Engines
{
/*public class CustomBlockEngine : IFactoryEngine
{
public class CustomBlockEntityDescriptor : SerializableEntityDescriptor<CustomBlockEntityDescriptor._CustomBlockDescriptor>
{
[HashName("TechbloxModdingAPICustomBlockV0")]
public class _CustomBlockDescriptor : IEntityDescriptor
{
public IComponentBuilder[] componentsToBuild { get; } =
{
new SerializableComponentBuilder<SerializationType, CustomBlock.DataStruct>(
((int) SerializationType.Network, new DefaultSerializer<CustomBlock.DataStruct>()),
((int) SerializationType.Storage, new DefaultSerializer<CustomBlock.DataStruct>()))
};
}
}

public void Ready()
{
SerializerManager.AddSerializer<CustomBlockEntityDescriptor>(
new SimpleEntitySerializer<CustomBlockEntityDescriptor>(db =>
{
var (coll, c) = db.QueryEntities<CustomBlock.DataStruct>(ApiExclusiveGroups.customBlockGroup);
var egids = new EGID[c];
for (int i = 0; i < c; i++)
egids[i] = new EGID(coll[i].ID, ApiExclusiveGroups.customBlockGroup);

return egids;
}));
foreach (var (id, name) in _registeredBlocks)
{
Factory.BuildEntity<CustomBlockEntityDescriptor>(id, ApiExclusiveGroups.customBlockGroup)
.Init(new CustomBlock.DataStruct {Name = new ECSString(name), ID = id});
}
}

public EntitiesDB entitiesDB { get; set; }
private List<(ushort id, string name)> _registeredBlocks = new List<(ushort, string)>();

public void Dispose()
{
}

public void RegisterBlock(ushort id, string name)
{
_registeredBlocks.Add((id, name));
}

public string Name { get; } = "TechbloxModdingAPICustomBlockEngine";
public bool isRemovable { get; } = false;
public IEntityFactory Factory { get; set; }
}*/
}

+ 0
- 47
TechbloxModdingAPI/Events/DeterministicStepComposeEngineGroupsPatch.cs View File

@@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

using HarmonyLib;
using Svelto.ECS;
using RobocraftX.Common;
using RobocraftX.StateSync;

using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Patch of RobocraftX.StateSync.DeterministicStepCompositionRoot.ComposeEnginesGroups(...)
/// </summary>
//[HarmonyPatch(typeof(DeterministicStepCompositionRoot), "DeterministicCompose")]
[Obsolete]
[HarmonyPatch]
class GameHostTransitionDeterministicGroupEnginePatch
{

public static readonly GameStateBuildEmitterEngine buildEngine = new GameStateBuildEmitterEngine();

public static readonly GameStateSimulationEmitterEngine simEngine = new GameStateSimulationEmitterEngine();
public static void Postfix()
{
//stateSyncReg.buildModeInitializationEngines.Add(buildEngine);
//stateSyncReg.simulationModeInitializationEngines.Add(simEngine);
//enginesRoot.AddEngine(buildEngine);
//enginesRoot.AddEngine(simEngine);
buildEngine.EmitIfBuildMode();
simEngine.EmitIfSimMode();
}

[HarmonyTargetMethod]
public static MethodBase TargetMethod(Harmony harmonyInstance)
{
return AccessTools.Method(AccessTools.TypeByName("RobocraftX.StateSync.GameHostTransitionDeterministicGroupEngine"), "EndTransition");
//.MakeGenericMethod(typeof(CosmeticEnginesSequenceBuildOrder), typeof(CosmeticEnginesSequenceSimOrder), typeof(DeterministicToCosmeticSyncBuildOrder), typeof(DeterministicToCosmeticSyncSimOrder));
}
}
}

+ 0
- 106
TechbloxModdingAPI/Events/EmitterBuilder.cs View File

@@ -1,106 +0,0 @@
using System;

using Svelto.ECS;

namespace TechbloxModdingAPI.Events
{
[Obsolete]
public class EmitterBuilder
{
private string name;

private int? type;

/// <summary>
/// Create a new event emitter builder.
/// </summary>
public EmitterBuilder()
{
}

/// <summary>
/// Create a new event emitter builder.
/// This is equivalent to new <code>EmitterBuilder().Name(name)</code>
/// </summary>
/// <param name="name">The emitter name.</param>
public EmitterBuilder(string name)
{
this.name = name;
}

/// <summary>
/// Create and return an event emitter builder.
/// </summary>
/// <returns>The builder.</returns>
public static EmitterBuilder Builder()
{
return new EmitterBuilder();
}

/// <summary>
/// Create and return an event emitter builder.
/// This is equivalent to <code>Builder().Name(name)</code>
/// </summary>
/// <returns>The builder.</returns>
/// <param name="name">The emitter name.</param>
public static EmitterBuilder Builder(string name)
{
return new EmitterBuilder(name);
}

/// <summary>
/// Name the event emitter.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="name">The event emitter name.</param>
public EmitterBuilder Name(string name)
{
this.name = name;
return this;
}

/// <summary>
/// Set the type of event to handle.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="eventType">The event type.</param>
public EmitterBuilder Handle(EventType eventType)
{
return Handle((int)eventType);
}

/// <summary>
/// Set the type of event to handle.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="eventType">The event type.</param>
public EmitterBuilder Handle(int eventType)
{
this.type = eventType;
return this;
}

/// <summary>
/// Build the event emitter.
/// </summary>
/// <returns>The event emitter.</returns>
/// <param name="register">Automatically register the event emitter with EventManager.AddEventemitter().</param>
public IEventEmitterEngine Build(bool register = true)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new EventParameterMissingException("Event emitter name must be defined before Build() is called");
}
if (!type.HasValue)
{
throw new EventParameterMissingException("Event emitter event type must be defined before Build() is called");
}
SimpleEventEmitterEngine result = new SimpleEventEmitterEngine(type.Value, name);
if (register)
{
EventManager.AddEventEmitter(result);
}
return result;
}
}
}

+ 0
- 61
TechbloxModdingAPI/Events/EventEngineFactory.cs View File

@@ -1,61 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Svelto.ECS;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Convenient factories for mod event engines
/// </summary>
[Obsolete]
public static class EventEngineFactory
{
/// <summary>
/// Factory method which automatically adds the SimpleEventHandlerEngine to the Manager
/// </summary>
/// <param name="name">The name of the engine</param>
/// <param name="type">The type of event to handle</param>
/// <param name="onActivated">The operation to do when the event is created</param>
/// <param name="onDestroyed">The operation to do when the event is destroyed (if applicable)</param>
/// <returns>The created object</returns>
public static SimpleEventHandlerEngine CreateAddSimpleHandler(string name, int type, Action onActivated, Action onDestroyed)
{
var engine = new SimpleEventHandlerEngine(onActivated, onDestroyed, type, name);
EventManager.AddEventHandler(engine);
return engine;
}

/// <summary>
/// Factory method which automatically adds the SimpleEventHandlerEngine to the Manager
/// </summary>
/// <param name="name">The name of the engine</param>
/// <param name="type">The type of event to handle</param>
/// <param name="onActivated">The operation to do when the event is created</param>
/// <param name="onDestroyed">The operation to do when the event is destroyed (if applicable)</param>
/// <returns>The created object</returns>
public static SimpleEventHandlerEngine CreateAddSimpleHandler(string name, int type, Action<EntitiesDB> onActivated, Action<EntitiesDB> onDestroyed)
{
var engine = new SimpleEventHandlerEngine(onActivated, onDestroyed, type, name);
EventManager.AddEventHandler(engine);
return engine;
}

/// <summary>
/// Factory method which automatically adds the SimpleEventEmitterEngine to the Manager
/// </summary>
/// <param name="name">The name of the engine</param>
/// <param name="type">The type of event to emit</param>
/// <param name="isRemovable">Will removing this engine not break your code?</param>
/// <returns>The created object</returns>
public static SimpleEventEmitterEngine CreateAddSimpleEmitter(string name, int type, bool isRemovable = true)
{
var engine = new SimpleEventEmitterEngine(type, name, isRemovable);
EventManager.AddEventEmitter(engine);
return engine;
}
}
}

+ 0
- 33
TechbloxModdingAPI/Events/EventExceptions.cs View File

@@ -16,28 +16,6 @@ namespace TechbloxModdingAPI.Events
}
}

public class EventNotFoundException : EventException
{
public EventNotFoundException()
{
}

public EventNotFoundException(string message) : base(message)
{
}
}

public class EventAlreadyExistsException : EventException
{
public EventAlreadyExistsException()
{
}

public EventAlreadyExistsException(string message) : base(message)
{
}
}

public class EventRuntimeException : EventException
{
public EventRuntimeException()
@@ -52,15 +30,4 @@ namespace TechbloxModdingAPI.Events
{
}
}

public class EventParameterMissingException : EventException
{
public EventParameterMissingException()
{
}

public EventParameterMissingException(string message) : base(message)
{
}
}
}

+ 0
- 128
TechbloxModdingAPI/Events/EventManager.cs View File

@@ -1,128 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Svelto.ECS;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Keeps track of event handlers and emitters.
/// This is used to add, remove and get API event handlers and emitters.
/// </summary>
[Obsolete("This will be removed in an upcoming update. Use the new C# event architecture from TechbloxModdingAPI.App")]
public static class EventManager
{
private static Dictionary<string, IEventEmitterEngine> _eventEmitters = new Dictionary<string, IEventEmitterEngine>();

private static Dictionary<string, IEventHandlerEngine> _eventHandlers = new Dictionary<string, IEventHandlerEngine>();

private static EnginesRoot _lastEngineRoot;

// event handler management
public static void AddEventHandler(IEventHandlerEngine engine)
{
if (ExistsEventHandler(engine))
{
throw new EventAlreadyExistsException($"IEventHandlerEngine {engine.Name} already exists");
}
_eventHandlers[engine.Name] = engine;
if (_lastEngineRoot != null)
{
Logging.MetaDebugLog($"Registering IEventHandlerEngine {engine.Name}");
_lastEngineRoot.AddEngine(engine);
}
}

public static bool ExistsEventHandler(string name)
{
return _eventHandlers.ContainsKey(name);
}

public static bool ExistsEventHandler(IEventHandlerEngine engine)
{
return ExistsEventHandler(engine.Name);
}

public static IEventHandlerEngine GetEventHandler(string name)
{
return _eventHandlers[name];
}

public static string[] GetEventHandlerNames()
{
return _eventHandlers.Keys.ToArray();
}

public static void RemoveEventHandler(string name)
{
_eventHandlers.Remove(name);
}

// event emitter management

public static void AddEventEmitter(IEventEmitterEngine engine)
{
if (ExistsEventEmitter(engine))
{
throw new EventAlreadyExistsException($"IEventEmitterEngine {engine.Name} already exists");
}
_eventEmitters[engine.Name] = engine;
if (_lastEngineRoot != null)
{
Logging.MetaDebugLog($"Registering IEventEmitterEngine {engine.Name}");
_lastEngineRoot.AddEngine(engine);
}
}

public static bool ExistsEventEmitter(string name)
{
return _eventEmitters.ContainsKey(name);
}

public static bool ExistsEventEmitter(IEventEmitterEngine engine)
{
return ExistsEventEmitter(engine.Name);
}

public static IEventEmitterEngine GetEventEmitter(string name)
{
return _eventEmitters[name];
}

public static string[] GetEventEmitterNames()
{
return _eventEmitters.Keys.ToArray();
}

public static void RemoveEventEmitter(string name)
{
if (_eventEmitters[name].isRemovable)
{
_eventEmitters.Remove(name);
}
}

public static void RegisterEngines(EnginesRoot enginesRoot)
{
_lastEngineRoot = enginesRoot;
// Register handlers before emitters so no events are missed
var entityFactory = enginesRoot.GenerateEntityFactory();
foreach (var key in _eventHandlers.Keys)
{
Logging.MetaDebugLog($"Registering IEventHandlerEngine {_eventHandlers[key].Name}");
enginesRoot.AddEngine(_eventHandlers[key]);
}
foreach (var key in _eventEmitters.Keys)
{
Logging.MetaDebugLog($"Registering IEventEmitterEngine {_eventEmitters[key].Name}");
_eventEmitters[key].Factory = entityFactory;
enginesRoot.AddEngine(_eventEmitters[key]);
}
}
}
}

+ 0
- 24
TechbloxModdingAPI/Events/EventType.cs View File

@@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Built-in event types.
/// These are configured to fire when the API is initialized.
/// </summary>
public enum EventType
{
ApplicationInitialized,
Menu,
MenuSwitchedTo,
Game,
GameReloaded,
GameSwitchedTo,
SimulationSwitchedTo,
BuildSwitchedTo
}
}

+ 0
- 56
TechbloxModdingAPI/Events/GameActivatedComposePatch.cs View File

@@ -1,56 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

using HarmonyLib;
using RobocraftX.CR.MainGame;
using Svelto.ECS;
using Unity.Entities;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Patch of RobocraftX.FullGameCompositionRoot.ActivateGame()
/// </summary>
[Obsolete]
[HarmonyPatch]
class GameActivatedComposePatch
{
public static bool IsGameSwitching = false;

public static bool IsGameReloading = false;

public static void Postfix(ref object contextHolder, ref EnginesRoot enginesRoot, World physicsWorld)
{
// register custom game engines
GameEngineManager.RegisterEngines(enginesRoot);
// A new EnginesRoot is always created when ActivateGame is called
// so all event emitters and handlers must be re-registered.
EventManager.RegisterEngines(enginesRoot);
Logging.Log("Dispatching Game Activated event");
EventManager.GetEventEmitter("TechbloxModdingAPIGameActivatedEventEmitter").Emit();
if (IsGameSwitching)
{
IsGameSwitching = false;
Logging.Log("Dispatching Game Switched To event");
EventManager.GetEventEmitter("TechbloxModdingAPIGameSwitchedToEventEmitter").Emit();
}
if (IsGameReloading)
{
IsGameReloading = false;
Logging.Log("Dispatching Game Reloaded event");
EventManager.GetEventEmitter("TechbloxModdingAPIGameReloadedEventEmitter").Emit();
}
}

public static MethodBase TargetMethod()
{
return typeof(MainGameCompositionRoot).GetMethods().First(m => m.Name == "Compose")
.MakeGenericMethod(typeof(object));
}
}
}

+ 0
- 26
TechbloxModdingAPI/Events/GameReloadedPatch.cs View File

@@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using HarmonyLib;
using RobocraftX;

using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Patch of RobocraftX.FullGameCompositionRoot.ReloadGame()
/// </summary>
[Obsolete]
[HarmonyPatch(typeof(FullGameCompositionRoot), "ReloadGame")]
class GameReloadedPatch
{
public static void Postfix()
{
GameActivatedComposePatch.IsGameReloading = true;
}
}
}

+ 0
- 54
TechbloxModdingAPI/Events/GameStateBuildEmitterEngine.cs View File

@@ -1,54 +0,0 @@
using System;

using Unity.Jobs;
using RobocraftX.SimulationModeState;
using RobocraftX.StateSync;
using Svelto.ECS;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Event emitter engine for switching to to build mode.
/// </summary>
[Obsolete]
public class GameStateBuildEmitterEngine : IEventEmitterEngine, IUnorderedInitializeOnTimeStoppedModeEntered
{
public string Name { get; } = "TechbloxModdingAPIGameStateBuildEventEmitter" ;

public EntitiesDB entitiesDB { set; private get; }

public int type { get; } = (int)EventType.BuildSwitchedTo;

public bool isRemovable { get; } = false;

public IEntityFactory Factory { set; private get; }

public void Dispose() { }

public void Emit()
{
Logging.Log("Dispatching Build Switched To event");
if (Factory == null) { return; }
Factory.BuildEntity<ModEventEntityDescriptor>(ApiExclusiveGroups.eventID++, ApiExclusiveGroups.eventsExclusiveGroup)
.Init(new ModEventEntityStruct { type = type });
}

public void EmitIfBuildMode()
{
//Logging.MetaDebugLog($"nextSimulationMode: {entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP).nextSimulationMode}");
if (entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP).nextSimulationMode == SimulationMode.TimeStopped)
{
Emit();
}
}
public JobHandle OnInitializeTimeStoppedMode(JobHandle inputDeps)
{
Emit();
return inputDeps;
}

public void Ready() { }
}
}

+ 0
- 53
TechbloxModdingAPI/Events/GameStateSimulationEmitterEngine.cs View File

@@ -1,53 +0,0 @@
using System;

using Unity.Jobs;
using RobocraftX.SimulationModeState;
using RobocraftX.StateSync;
using Svelto.ECS;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Event emitter engine for switching to simulation mode.
/// </summary>
[Obsolete]
public class GameStateSimulationEmitterEngine : IEventEmitterEngine, IUnorderedInitializeOnTimeRunningModeEntered
{
public string Name { get; } = "TechbloxModdingAPIGameStateSimulationEventEmitter" ;

public EntitiesDB entitiesDB { set; private get; }

public int type { get; } = (int)EventType.SimulationSwitchedTo;

public bool isRemovable { get; } = false;

public IEntityFactory Factory { set; private get; }

public void Dispose() { }

public void Emit()
{
Logging.Log("Dispatching Simulation Switched To event");
if (Factory == null) { return; }
Factory.BuildEntity<ModEventEntityDescriptor>(ApiExclusiveGroups.eventID++, ApiExclusiveGroups.eventsExclusiveGroup)
.Init(new ModEventEntityStruct { type = type });
}

public void EmitIfSimMode()
{
if (entitiesDB.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP).nextSimulationMode == SimulationMode.TimeRunning)
{
Emit();
}
}

public JobHandle OnInitializeTimeRunningMode(JobHandle inputDeps)
{
Emit();
return inputDeps;
}

public void Ready() { }
}
}

+ 0
- 30
TechbloxModdingAPI/Events/GameSwitchedToPatch.cs View File

@@ -1,30 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

using HarmonyLib;
using RobocraftX;
using RobocraftX.CR.MainGame;
using Svelto.ECS;

using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Patch of RobocraftX.FullGameCompositionRoot.ActivateGame()
/// (scheduled for execution during RobocraftX.FullGameCompositionRoot.SwitchToGame())
/// </summary>
[Obsolete]
[HarmonyPatch(typeof(FullGameCompositionRoot), "SwitchToGame")]
class GameSwitchedToPatch
{
public static void Prefix()
{
GameActivatedComposePatch.IsGameSwitching = true;
}
}
}

+ 0
- 166
TechbloxModdingAPI/Events/HandlerBuilder.cs View File

@@ -1,166 +0,0 @@
using System;

using Svelto.ECS;

namespace TechbloxModdingAPI.Events
{
[Obsolete]
public class HandlerBuilder
{
private string name;

private int? type;

private Action<EntitiesDB> activated;

private Action<EntitiesDB> destroyed;

/// <summary>
/// Create a new event handler builder.
/// </summary>
public HandlerBuilder()
{
}

/// <summary>
/// Create a new event handler builder.
/// This is equivalent to new <code>HandlerBuilder().Name(name)</code>
/// </summary>
/// <param name="name">The handler name.</param>
public HandlerBuilder(string name)
{
this.name = name;
}

/// <summary>
/// Create and return an event handler builder.
/// </summary>
/// <returns>The builder.</returns>
public static HandlerBuilder Builder()
{
return new HandlerBuilder();
}

/// <summary>
/// Create and return an event handler builder.
/// This is equivalent to <code>Builder().Name(name)</code>
/// </summary>
/// <returns>The builder.</returns>
/// <param name="name">The handler name.</param>
public static HandlerBuilder Builder(string name)
{
return new HandlerBuilder(name);
}

/// <summary>
/// Name the event handler.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="name">The event handler name.</param>
public HandlerBuilder Name(string name)
{
this.name = name;
return this;
}

/// <summary>
/// Set the action to perform on when the activated event occurs.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="action">The activated event action.</param>
public HandlerBuilder OnActivation(Action action)
{
return OnActivation((_) => { action(); });
}

/// <summary>
/// Set the action to perform on when the activated event occurs.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="action">The activated event action.</param>
public HandlerBuilder OnActivation(Action<EntitiesDB> action)
{
this.activated = action;
return this;
}

/// <summary>
/// Set the action to perform when the destroyed event occurs.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="action">The destroyed event action.</param>
public HandlerBuilder OnDestruction(Action action)
{
return OnDestruction((_) => { action(); });
}

/// <summary>
/// Set the action to perform when the destroyed event occurs.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="action">The destroyed event action.</param>
public HandlerBuilder OnDestruction(Action<EntitiesDB> action)
{
this.destroyed = action;
return this;
}

/// <summary>
/// Set the type of event to handle.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="eventType">The event type.</param>
public HandlerBuilder Handle(EventType eventType)
{
return Handle((int)eventType);
}

/// <summary>
/// Set the type of event to handle.
/// </summary>
/// <returns>The builder.</returns>
/// <param name="eventType">The event type.</param>
public HandlerBuilder Handle(int eventType)
{
this.type = eventType;
return this;
}

/// <summary>
/// Build the event handler.
/// </summary>
/// <returns>The event handler.</returns>
/// <param name="register">Automatically register the event handler with EventManager.AddEventHandler().</param>
public IEventHandlerEngine Build(bool register = true)
{
if (string.IsNullOrWhiteSpace(name))
{
throw new EventParameterMissingException("Event handler name must be defined before Build() is called");
}
if (activated == null && destroyed == null)
{
throw new EventParameterMissingException("Event handler destruction or activated event action must be defined before Build() is called");
}
if (!type.HasValue)
{
throw new EventParameterMissingException("Event handler event type must be defined before Build() is called");
}
Action<EntitiesDB> validActivated = activated;
if (validActivated == null)
{
validActivated = (_) => { };
}
Action<EntitiesDB> validDestroyed = destroyed;
if (validDestroyed == null)
{
validDestroyed = (_) => { };
}
SimpleEventHandlerEngine result = new SimpleEventHandlerEngine(validActivated, validDestroyed, type.Value, name);
if (register)
{
EventManager.AddEventHandler(result);
}
return result;
}
}
}

+ 0
- 23
TechbloxModdingAPI/Events/IEventEmitterEngine.cs View File

@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Svelto.ECS;
using TechbloxModdingAPI.Engines;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Engine interface to create a ModEventEntityStruct in entitiesDB when a specific event occurs.
/// </summary>
[Obsolete]
public interface IEventEmitterEngine : IFactoryEngine
{
/// <summary>
/// Emit the event. (Optional)
/// </summary>
void Emit();
}
}

+ 0
- 20
TechbloxModdingAPI/Events/IEventHandlerEngine.cs View File

@@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Svelto.ECS;
using Svelto.ECS.Internal;
using TechbloxModdingAPI.Engines;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Engine interface to handle ModEventEntityStruct events emitted by IEventEmitterEngines.
/// </summary>
[Obsolete]
public interface IEventHandlerEngine : IReactionaryEngine<ModEventEntityStruct>
{
}
}

+ 0
- 42
TechbloxModdingAPI/Events/MenuActivatedPatch.cs View File

@@ -1,42 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using HarmonyLib;
using RobocraftX;
using Svelto.ECS;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Patch of RobocraftX.FullGameCompositionRoot.ActivateMenu()
/// </summary>
[Obsolete]
[HarmonyPatch(typeof(FullGameCompositionRoot), "ActivateMenu")]
class MenuActivatedPatch
{

private static bool firstLoad = true;
public static void Postfix(ref EnginesRoot ____frontEndEnginesRoot, FullGameCompositionRoot __instance)
{
// register custom menu engines
MenuEngineManager.RegisterEngines(____frontEndEnginesRoot);
// A new EnginesRoot is always created when ActivateMenu is called
// so all event emitters and handlers must be re-registered.
EventManager.RegisterEngines(____frontEndEnginesRoot);
if (firstLoad)
{
firstLoad = false;
FullGameFields.Init(__instance);
//Application.Application.SetFullGameCompositionRoot(__instance);
Logging.Log("Dispatching App Init event");
EventManager.GetEventEmitter("TechbloxModdingAPIApplicationInitializedEventEmitter").Emit();
}
Logging.Log("Dispatching Menu Activated event");
EventManager.GetEventEmitter("TechbloxModdingAPIMenuActivatedEventEmitter").Emit();
}
}
}

+ 0
- 28
TechbloxModdingAPI/Events/MenuSwitchedToPatch.cs View File

@@ -1,28 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using HarmonyLib;
using RobocraftX;
using Svelto.ECS;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// Patch of RobocraftX.FullGameCompositionRoot.SwitchToMenu()
/// </summary>
[Obsolete]
[HarmonyPatch(typeof(FullGameCompositionRoot), "SwitchToMenu")]
class MenuSwitchedToPatch
{
public static void Postfix()
{
// Event emitters and handlers should already be registered by MenuActivated event
Logging.Log("Dispatching Menu Switched To event");
EventManager.GetEventEmitter("TechbloxModdingAPIMenuSwitchedToEventEmitter").Emit();
}
}
}

+ 0
- 17
TechbloxModdingAPI/Events/ModEventEntityDescriptor.cs View File

@@ -1,17 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Svelto.ECS;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// EntityDescriptor for creating ModEventEntityStructs
/// </summary>
public class ModEventEntityDescriptor : GenericEntityDescriptor<ModEventEntityStruct>
{
}
}

+ 0
- 23
TechbloxModdingAPI/Events/ModEventEntityStruct.cs View File

@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Svelto.ECS;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// The event entity struct
/// </summary>
public struct ModEventEntityStruct : IEntityComponent, INeedEGID
{
/// <summary>
/// The type of event that has been emitted
/// </summary>
public int type;

public EGID ID { get; set; }
}
}

+ 0
- 66
TechbloxModdingAPI/Events/SimpleEventEmitterEngine.cs View File

@@ -1,66 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Svelto.ECS;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// A simple implementation of IEventEmitterEngine sufficient for most uses
/// </summary>
[Obsolete]
public class SimpleEventEmitterEngine : IEventEmitterEngine
{
public string Name { get; set; }
public int type { get; set; }

public bool isRemovable { get; }

public IEntityFactory Factory { private get; set; }

public EntitiesDB entitiesDB { set; private get; }

public void Ready() { }

/// <summary>
/// Emit the event
/// </summary>
public void Emit()
{
Factory.BuildEntity<ModEventEntityDescriptor>(ApiExclusiveGroups.eventID++, ApiExclusiveGroups.eventsExclusiveGroup)
.Init(new ModEventEntityStruct { type = type });
}

public void Dispose() { }

/// <summary>
/// Construct the engine
/// </summary>
/// <param name="type">The EventType to use for ModEventEntityStruct.type</param>
/// <param name="name">The name of this engine</param>
/// <param name="isRemovable">Will removing this engine not break your code?</param>
public SimpleEventEmitterEngine(EventType type, string name, bool isRemovable = true)
{
this.type = (int)type;
this.Name = name;
this.isRemovable = isRemovable;
}

/// <summary>
/// Construct the engine
/// </summary>
/// <param name="type">The object to use for ModEventEntityStruct.type</param>
/// <param name="name">The name of this engine</param>
/// <param name="isRemovable">Will removing this engine not break your code?</param>
public SimpleEventEmitterEngine(int type, string name, bool isRemovable = true)
{
this.type = type;
this.Name = name;
this.isRemovable = isRemovable;
}
}
}

+ 0
- 145
TechbloxModdingAPI/Events/SimpleEventHandlerEngine.cs View File

@@ -1,145 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Svelto.ECS;
using TechbloxModdingAPI.Utility;

namespace TechbloxModdingAPI.Events
{
/// <summary>
/// A simple implementation of IEventHandlerEngine sufficient for most uses
/// </summary>
[Obsolete]
public class SimpleEventHandlerEngine : IEventHandlerEngine
{
public int type { get; set; }
public string Name { get; set; }

private bool isActivated = false;

private bool jankActivateFix = false;

private bool jankDestroyFix = false;

private readonly Action<EntitiesDB> onActivated;

private readonly Action<EntitiesDB> onDestroyed;

public EntitiesDB entitiesDB { set; private get; }

public bool isRemovable => true;

public void Add(ref ModEventEntityStruct entityView, EGID egid)
{
if (entityView.type.Equals(this.type))
{
jankActivateFix = !jankActivateFix;
if (jankActivateFix) return;
isActivated = true;
onActivatedInvokeCatchError(entitiesDB);
}
}

/// <summary>
/// Manually activate the EventHandler.
/// Once activated, the next remove event will not be ignored.
/// </summary>
/// <param name="handle">Whether to invoke the activated action</param>
public void Activate(bool handle = false)
{
isActivated = true;
if (handle && entitiesDB != null)
{
onActivatedInvokeCatchError(entitiesDB);
}
}

public void Deactivate()
{
isActivated = false;
}

public void Ready() { }

public void Remove(ref ModEventEntityStruct entityView, EGID egid)
{
if (entityView.type.Equals(this.type) && isActivated)
{
jankDestroyFix = !jankDestroyFix;
if (jankDestroyFix) return;
isActivated = false;
onDestroyedInvokeCatchError(entitiesDB);
}
}

public void Dispose()
{
if (isActivated)
{
isActivated = false;
onDestroyedInvokeCatchError(entitiesDB);
}
}

/// <summary>
/// Construct the engine
/// </summary>
/// <param name="activated">The operation to do when the event is created</param>
/// <param name="removed">The operation to do when the event is destroyed (if applicable)</param>
/// <param name="type">The type of event to handle</param>
/// <param name="name">The name of the engine</param>
/// <param name="simple">A useless parameter to use to avoid Python overload resolution errors</param>
public SimpleEventHandlerEngine(Action activated, Action removed, int type, string name, bool simple = true)
: this((EntitiesDB _) => { activated.Invoke(); }, (EntitiesDB _) => { removed.Invoke(); }, type, name) { }

/// <summary>
/// Construct the engine
/// </summary>
/// <param name="activated">The operation to do when the event is created</param>
/// <param name="removed">The operation to do when the event is destroyed (if applicable)</param>
/// <param name="type">The type of event to handler</param>
/// <param name="name">The name of the engine</param>
public SimpleEventHandlerEngine(Action<EntitiesDB> activated, Action<EntitiesDB> removed, int type, string name)
{
this.type = type;
this.Name = name;
this.onActivated = activated;
this.onDestroyed = removed;
}

private void onActivatedInvokeCatchError(EntitiesDB _entitiesDB)
{
try
{
onActivated.Invoke(_entitiesDB);
}
catch (Exception e)
{
EventRuntimeException wrappedException = new EventRuntimeException($"EventHandler {Name} threw an exception when activated", e);
Logging.LogWarning(wrappedException.ToString());
}
}

private void onDestroyedInvokeCatchError(EntitiesDB _entitiesDB)
{
try
{
onDestroyed.Invoke(_entitiesDB);
}
catch (Exception e)
{
EventRuntimeException wrappedException = new EventRuntimeException($"EventHandler {Name} threw an exception when destroyed", e);
Logging.LogWarning(wrappedException.ToString());
}
}

public SimpleEventHandlerEngine(Action activated, Action removed, EventType type, string name, bool simple = true)
: this((EntitiesDB _) => { activated.Invoke(); }, (EntitiesDB _) => { removed.Invoke(); }, (int)type, name) { }

public SimpleEventHandlerEngine(Action<EntitiesDB> activated, Action<EntitiesDB> removed, EventType type, string name, bool simple = true)
: this(activated, removed, (int)type, name) { }
}
}

+ 0
- 13
TechbloxModdingAPI/Main.cs View File

@@ -62,20 +62,7 @@ namespace TechbloxModdingAPI

// init utility
Logging.MetaDebugLog($"Initializing Utility");
#pragma warning disable 0612,0618
Utility.GameState.Init();
Utility.VersionTracking.Init();
// create default event emitters
Logging.MetaDebugLog($"Initializing Events");
EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.ApplicationInitialized, "TechbloxModdingAPIApplicationInitializedEventEmitter", false));
EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.Menu, "TechbloxModdingAPIMenuActivatedEventEmitter", false));
EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.MenuSwitchedTo, "TechbloxModdingAPIMenuSwitchedToEventEmitter", false));
EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.Game, "TechbloxModdingAPIGameActivatedEventEmitter", false));
EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.GameReloaded, "TechbloxModdingAPIGameReloadedEventEmitter", false));
EventManager.AddEventEmitter(new SimpleEventEmitterEngine(EventType.GameSwitchedTo, "TechbloxModdingAPIGameSwitchedToEventEmitter", false));
EventManager.AddEventEmitter(GameHostTransitionDeterministicGroupEnginePatch.buildEngine);
EventManager.AddEventEmitter(GameHostTransitionDeterministicGroupEnginePatch.simEngine);
#pragma warning restore 0612,0618
// init block implementors
Logging.MetaDebugLog($"Initializing Blocks");
// init inventory


+ 2
- 244
TechbloxModdingAPI/Tests/TechbloxModdingAPIPluginTest.cs View File

@@ -1,51 +1,20 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using TechbloxModdingAPI.App;
using HarmonyLib;
using IllusionInjector;
// test
using GPUInstancer;
using Svelto.ECS;
using RobocraftX.Blocks;
using RobocraftX.Common;
using RobocraftX.SimulationModeState;
using RobocraftX.FrontEnd;
using Unity.Mathematics;
using UnityEngine;
using RobocraftX.Schedulers;
using Svelto.Tasks.ExtraLean;
using uREPL;
using TechbloxModdingAPI.Interface.IMGUI;
using TechbloxModdingAPI.Tasks;
using RobocraftX.Common.Input;
using RobocraftX.CR.MainGame;
using RobocraftX.GUI.CommandLine;
using RobocraftX.Multiplayer;
using RobocraftX.StateSync;
using Svelto.Context;
using Svelto.DataStructures;
using Svelto.Services;
using TechbloxModdingAPI.Blocks;
using TechbloxModdingAPI.Commands;
using TechbloxModdingAPI.Events;
using TechbloxModdingAPI.Input;
using TechbloxModdingAPI.Players;
using TechbloxModdingAPI.Utility;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
using Debug = FMOD.Debug;
using EventType = TechbloxModdingAPI.Events.EventType;
using Label = TechbloxModdingAPI.Interface.IMGUI.Label;
using ScalingPermission = DataLoader.ScalingPermission;

namespace TechbloxModdingAPI.Tests
{
@@ -77,13 +46,6 @@ namespace TechbloxModdingAPI.Tests
Harmony.DEBUG = true;
Main.Init();
Logging.MetaDebugLog($"Version group id {(uint)ApiExclusiveGroups.versionGroup}");
// in case Steam is not installed/running
// this will crash the game slightly later during startup
//SteamInitPatch.ForcePassSteamCheck = true;
// in case running in a VM
//MinimumSpecsCheckPatch.ForcePassMinimumSpecCheck = true;
// disable some Techblox analytics
//AnalyticsDisablerPatch.DisableAnalytics = true;
// disable background music
Logging.MetaDebugLog("Audio Mixers: " + string.Join(",", AudioTools.GetMixers()));
//AudioTools.SetVolume(0.0f, "Music"); // The game now sets this from settings again after this is called :(
@@ -91,62 +53,7 @@ namespace TechbloxModdingAPI.Tests
//Utility.VersionTracking.Enable();//(very) unstable

// debug/test handlers
#pragma warning disable 0612
HandlerBuilder.Builder()
.Name("appinit API debug")
.Handle(EventType.ApplicationInitialized)
.OnActivation(() => { Logging.Log("App Inited event!"); })
.Build();

HandlerBuilder.Builder("menuact API debug")
.Handle(EventType.Menu)
.OnActivation(() => { Logging.Log("Menu Activated event!"); })
.OnDestruction(() => { Logging.Log("Menu Destroyed event!"); })
.Build();

HandlerBuilder.Builder("menuswitch API debug")
.Handle(EventType.MenuSwitchedTo)
.OnActivation(() => { Logging.Log("Menu Switched To event!"); })
.Build();

HandlerBuilder.Builder("gameact API debug")
.Handle(EventType.Menu)
.OnActivation(() => { Logging.Log("Game Activated event!"); })
.OnDestruction(() => { Logging.Log("Game Destroyed event!"); })
.Build();

HandlerBuilder.Builder("gamerel API debug")
.Handle(EventType.GameReloaded)
.OnActivation(() => { Logging.Log("Game Reloaded event!"); })
.Build();

HandlerBuilder.Builder("gameswitch API debug")
.Handle(EventType.GameSwitchedTo)
.OnActivation(() => { Logging.Log("Game Switched To event!"); })
.Build();

HandlerBuilder.Builder("simulationswitch API debug")
.Handle(EventType.SimulationSwitchedTo)
.OnActivation(() => { Logging.Log("Game Mode Simulation Switched To event!"); })
.Build();

HandlerBuilder.Builder("buildswitch API debug")
.Handle(EventType.BuildSwitchedTo)
.OnActivation(() => { Logging.Log("Game Mode Build Switched To event!"); })
.Build();

HandlerBuilder.Builder("menu activated API error thrower test")
.Handle(EventType.Menu)
.OnActivation(() => { throw new Exception("Event Handler always throws an exception!"); })
.Build();
#pragma warning restore 0612
/*HandlerBuilder.Builder("enter game from menu test")
.Handle(EventType.Menu)
.OnActivation(() =>
{
Tasks.Scheduler.Schedule(new Tasks.Repeatable(enterGame, shouldRetry, 0.2f));
})
.Build();*/
Client.EnterMenu += (sender, args) => throw new Exception("Test handler always throws an exception!");

// debug/test commands
if (Dependency.Hell("ExtraCommands"))
@@ -195,7 +102,6 @@ namespace TechbloxModdingAPI.Tests
for (int i = 0; i < 100; i++)
for (int j = 0; j < 100; j++)
Block.PlaceNew(BlockIDs.Cube, new float3(x + i, y, z + j));
//Block.Sync();
sw.Stop();
Logging.CommandLog("Finished in " + sw.ElapsedMilliseconds + "ms");
})
@@ -236,7 +142,7 @@ namespace TechbloxModdingAPI.Tests

}).Build();

CommandBuilder.Builder("GetBlockByID", "Gets a block based on its object identifier and teleports it up.")
CommandBuilder.Builder("MoveBlockByID", "Gets a block based on its object identifier and teleports it up.")
.Action<char>(ch =>
{
foreach (var body in SimBody.GetFromObjectID(ch))
@@ -251,41 +157,6 @@ namespace TechbloxModdingAPI.Tests
}
}).Build();

/*CommandBuilder.Builder()
.Name("PlaceConsole")
.Description("Place a bunch of console block with a given text - entering simulation with them crashes the game as the cmd doesn't exist")
.Action((float x, float y, float z) =>
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
var block = Block.PlaceNew<ConsoleBlock>(BlockIDs.ConsoleBlock,
new float3(x + i, y, z + j));
block.Command = "test_command";
}
}
sw.Stop();
Logging.CommandLog($"Blocks placed in {sw.ElapsedMilliseconds} ms");
})
.Build();*/
/*CommandBuilder.Builder()
.Name("WireTest")
.Description("Place two blocks and then wire them together")
.Action(() =>
{
LogicGate notBlock = Block.PlaceNew<LogicGate>(BlockIDs.NOTLogicBlock, new float3(1, 2, 0));
LogicGate andBlock = Block.PlaceNew<LogicGate>(BlockIDs.ANDLogicBlock, new float3(2, 2, 0));
// connect NOT Gate output to AND Gate input #2 (ports are zero-indexed, so 1 is 2nd position and 0 is 1st position)
Wire conn = notBlock.Connect(0, andBlock, 1);
Logging.CommandLog(conn.ToString());
})
.Build();*/

CommandBuilder.Builder("TestChunkHealth", "Sets the chunk looked at to the given health.")
.Action((float val, float max) =>
{
@@ -327,49 +198,6 @@ namespace TechbloxModdingAPI.Tests
Logging.MetaDebugLog("Placed block " + args.Block);
Block.Removed += (sender, args) =>
Logging.MetaDebugLog("Removed block " + args.Block);

/*
CommandManager.AddCommand(new SimpleCustomCommandEngine<float>((float d) => { UnityEngine.Camera.main.fieldOfView = d; },
"SetFOV", "Set the player camera's field of view"));
CommandManager.AddCommand(new SimpleCustomCommandEngine<float, float, float>(
(x, y, z) => {
bool success = TechbloxModdingAPI.Blocks.Movement.MoveConnectedBlocks(
TechbloxModdingAPI.Blocks.BlockIdentifiers.LatestBlockID,
new Unity.Mathematics.float3(x, y, z));
if (!success)
{
TechbloxModdingAPI.Utility.Logging.CommandLogError("Blocks can only be moved in Build mode!");
}
}, "MoveLastBlock", "Move the most-recently-placed block, and any connected blocks by the given offset"));
CommandManager.AddCommand(new SimpleCustomCommandEngine<float, float, float>(
(x, y, z) => { Blocks.Placement.PlaceBlock(Blocks.BlockIDs.Cube, new Unity.Mathematics.float3(x, y, z)); },
"PlaceAluminium", "Place a block of aluminium at the given coordinates"));
System.Random random = new System.Random(); // for command below
CommandManager.AddCommand(new SimpleCustomCommandEngine(
() => {
if (!GameState.IsSimulationMode())
{
Logging.CommandLogError("You must be in simulation mode for this to work!");
return;
}
Tasks.Repeatable task = new Tasks.Repeatable(() => {
uint count = 0;
EGID[] eBlocks = Blocks.Signals.GetElectricBlocks();
for (uint i = 0u; i < eBlocks.Length; i++)
{
uint[] ids = Blocks.Signals.GetSignalIDs(eBlocks[i]);
for (uint j = 0u; j < ids.Length; j++)
{
Blocks.Signals.SetSignalByID(ids[j], (float)random.NextDouble());
count++;
}
}
Logging.MetaDebugLog($"Did the thing on {count} inputs");
},
() => { return GameState.IsSimulationMode(); });
Tasks.Scheduler.Schedule(task);
}, "RandomizeSignalsInputs", "Do the thing"));
*/
}

// dependency test
@@ -406,30 +234,6 @@ namespace TechbloxModdingAPI.Tests
uiImg.Enabled = true;
Logging.MetaDebugLog($"Got blue bg asset {handle.Result}");
};*/

CommandBuilder.Builder("enableCompletions")
.Action(() =>
{
var p = Window.selected.main.parameters;
p.useCommandCompletion = true;
p.useMonoCompletion = true;
p.useGlobalClassCompletion = true;
Log.Output("Submitted: " + Window.selected.submittedCode);
})
.Build();
try
{
CustomBlock.RegisterCustomBlock<TestBlock>();
Logging.MetaDebugLog("Registered test custom block");
}
catch (FileNotFoundException)
{
Logging.MetaDebugLog("Test custom block catalog not found");
}

CustomBlock.ChangeExistingBlock((ushort) BlockIDs.CarWheel,
cld => cld.scalingPermission = ScalingPermission.NonUniform);
/*((FasterList<GuiInputMap.GuiInputMapElement>)AccessTools.Property(typeof(GuiInputMap), "GuiInputsButtonDown").GetValue(null))
.Add(new GuiInputMap.GuiInputMapElement(RewiredConsts.Action.ToggleCommandLine, GuiIn))*/
@@ -448,40 +252,6 @@ namespace TechbloxModdingAPI.Tests
return modsString = sb.ToString();
}

private bool retry = true;

private bool shouldRetry()
{
return retry;
}

private void enterGame()
{
App.Client app = new App.Client();
App.Game[] myGames = app.MyGames;
Logging.MetaDebugLog($"MyGames count {myGames.Length}");
if (myGames.Length != 0)
{
Logging.MetaDebugLog($"MyGames[0] EGID {myGames[0].EGID}");
retry = false;
try
{
//myGames[0].Description = "test msg pls ignore"; // make sure game exists first
Logging.MetaDebugLog($"Entering game {myGames[0].Name}");
myGames[0].EnterGame();
}
catch (Exception e)
{
Logging.MetaDebugLog($"Failed to enter game; exception: {e}");
retry = true;
}
}
else
{
Logging.MetaDebugLog("MyGames not populated yet :(");
}
}

public override void OnUpdate()
{
if (UnityEngine.Input.GetKeyDown(KeyCode.End))
@@ -504,18 +274,6 @@ namespace TechbloxModdingAPI.Tests
return ((Action) MinimumSpecsCheck.CheckRequirementsMet).Method;
}
}

[CustomBlock("customCatalog.json", "Assets/Prefabs/Cube.prefab", "strAluminiumCube", SortIndex = 12)]
public class TestBlock : CustomBlock
{
public TestBlock(EGID id) : base(id)
{
}

public TestBlock(uint id) : base(id)
{
}
}
}
#endif
}

+ 0
- 18
TechbloxModdingAPI/Utility/Logging.cs View File

@@ -123,24 +123,6 @@ namespace TechbloxModdingAPI.Utility
Svelto.Console.LogWarning(obj.ToString());
}

[Obsolete("SystemLog was removed from Svelto.Common")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SystemLog(string msg)
{
Svelto.Console.Log(msg);
}

/// <summary>
/// Write a message to stdout (ie the terminal, like Command Prompt or PowerShell)
/// </summary>
/// <param name="obj">The object to log</param>
[Obsolete("SystemLog was removed from Svelto.Common")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void SystemLog(object obj)
{
Svelto.Console.Log(obj.ToString());
}

// descriptive logging

/// <summary>


+ 0
- 115
TechbloxModdingAPI/Utility/VersionTracking.cs View File

@@ -1,115 +0,0 @@
using System;
using System.Reflection;

using RobocraftX.Common;
using Svelto.ECS;
using Svelto.ECS.Serialization;
using TechbloxModdingAPI.Events;
using TechbloxModdingAPI.Persistence;

namespace TechbloxModdingAPI.Utility
{
/// <summary>
/// Tracks the API version the current game was built for.
/// For compatibility reasons, this must be enabled before it will work.
/// </summary>
[Obsolete]
public static class VersionTracking
{
private static readonly VersionTrackingEngine versionEngine = new VersionTrackingEngine();

private static bool isEnabled = false;

/// <summary>
/// Gets the API version saved in the current game.
/// </summary>
/// <returns>The version.</returns>
public static uint GetVersion()
{
if (!isEnabled) return 0u;
return versionEngine.GetGameVersion();
}

/// <summary>
/// Enable API version tracking.
/// </summary>
public static void Enable()
{
if (!SerializerManager.ExistsSerializer(typeof(ModVersionStruct).FullName))
{
SerializerManager.AddSerializer<ModVersionDescriptor>(new SimpleEntitySerializer<ModVersionDescriptor>(
(_) => { return new EGID[1] { new EGID(0u, ApiExclusiveGroups.versionGroup) }; }
));
}
EventManager.AddEventEmitter(versionEngine);
isEnabled = true;
}

/// <summary>
/// Disable API version tracking.
/// </summary>
public static void Disable()
{
EventManager.AddEventEmitter(versionEngine);
isEnabled = false;
}

public static void Init() { }

}

[Obsolete]
internal class VersionTrackingEngine : IEventEmitterEngine
{
public string Name { get; } = "TechbloxModdingAPIVersionTrackingGameEngine";

public EntitiesDB entitiesDB { set; private get; }

public int type => -1;

public bool isRemovable => false;

public IEntityFactory Factory { set; private get; }

public void Dispose() { }

public void Ready()
{
EGID egid = new EGID(0u, ApiExclusiveGroups.versionGroup);
if (!entitiesDB.Exists<ModVersionStruct>(egid))
{
Version currentVersion = Assembly.GetExecutingAssembly().GetName().Version;
int v = (currentVersion.Major * 1000) + (currentVersion.Minor);
Factory.BuildEntity<ModVersionDescriptor>(egid).Init<ModVersionStruct>(new ModVersionStruct
{
version = (uint)v
});
}
}

public uint GetGameVersion()
{
return entitiesDB.QueryUniqueEntity<ModVersionStruct>(ApiExclusiveGroups.versionGroup).version;
}

public void Emit() { }
}

[Obsolete]
public struct ModVersionStruct : IEntityComponent
{
public uint version;
}

[Obsolete]
public class ModVersionDescriptor: SerializableEntityDescriptor<ModVersionDescriptor._ModVersionDescriptor>
{
[HashName("TechbloxModdingAPIVersionV0")]
public class _ModVersionDescriptor : IEntityDescriptor
{
public IComponentBuilder[] componentsToBuild { get; } = new IComponentBuilder[]{
new SerializableComponentBuilder<SerializationType, ModVersionStruct>(((int)SerializationType.Network, new DefaultSerializer<ModVersionStruct>()), ((int)SerializationType.Storage, new DefaultSerializer<ModVersionStruct>())),
};
}
}
}

Loading…
Cancel
Save