diff --git a/GameAPI/ShopAPI.cs b/GameAPI/ShopAPI.cs deleted file mode 100644 index cd926f9..0000000 --- a/GameAPI/ShopAPI.cs +++ /dev/null @@ -1,359 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Bifrost.ShopGroup; -using UnityEngine; - -namespace MimicAPI.GameAPI -{ - public static class ShopAPI - { - public static ShopGroup_MasterData GetShopGroupData(int shopGroupID) - { - try - { - DataManager? dataManager = ManagerAPI.GetDataManager(); - if (dataManager == null) - return null; - - var excelDataManager = ReflectionHelper.GetFieldValue(dataManager, "ExcelDataManager"); - if (excelDataManager == null) - return null; - - var shopGroupDict = ReflectionHelper.GetFieldValue>(excelDataManager, "ShopGroupDict"); - if (shopGroupDict == null || !shopGroupDict.ContainsKey(shopGroupID)) - return null; - - return shopGroupDict[shopGroupID]; - } - catch - { - return null; - } - } - - public static List GetAllShopGroups() - { - try - { - DataManager? dataManager = ManagerAPI.GetDataManager(); - if (dataManager == null) - return new List(); - - var excelDataManager = ReflectionHelper.GetFieldValue(dataManager, "ExcelDataManager"); - if (excelDataManager == null) - return new List(); - - var shopGroupDict = ReflectionHelper.GetFieldValue>(excelDataManager, "ShopGroupDict"); - if (shopGroupDict == null) - return new List(); - - return shopGroupDict.Values.ToList(); - } - catch - { - return new List(); - } - } - - public static bool AddShop(int shopGroupID, ShopGroup_MasterData shopData) - { - if (shopData == null) - return false; - - try - { - DataManager? dataManager = ManagerAPI.GetDataManager(); - if (dataManager == null) - return false; - - var excelDataManager = ReflectionHelper.GetFieldValue(dataManager, "ExcelDataManager"); - if (excelDataManager == null) - return false; - - var shopGroupDict = ReflectionHelper.GetFieldValue>(excelDataManager, "ShopGroupDict"); - if (shopGroupDict == null) - return false; - - if (shopGroupDict.ContainsKey(shopGroupID)) - return false; - - shopGroupDict[shopGroupID] = shopData; - return true; - } - catch - { - return false; - } - } - - public static bool DeleteShop(int shopGroupID) - { - try - { - DataManager? dataManager = ManagerAPI.GetDataManager(); - if (dataManager == null) - return false; - - var excelDataManager = ReflectionHelper.GetFieldValue(dataManager, "ExcelDataManager"); - if (excelDataManager == null) - return false; - - var shopGroupDict = ReflectionHelper.GetFieldValue>(excelDataManager, "ShopGroupDict"); - if (shopGroupDict == null || !shopGroupDict.ContainsKey(shopGroupID)) - return false; - - shopGroupDict.Remove(shopGroupID); - return true; - } - catch - { - return false; - } - } - - public static bool UpdateShop(int shopGroupID, ShopGroup_MasterData updatedData) - { - if (updatedData == null) - return false; - - try - { - DataManager? dataManager = ManagerAPI.GetDataManager(); - if (dataManager == null) - return false; - - var excelDataManager = ReflectionHelper.GetFieldValue(dataManager, "ExcelDataManager"); - if (excelDataManager == null) - return false; - - var shopGroupDict = ReflectionHelper.GetFieldValue>(excelDataManager, "ShopGroupDict"); - if (shopGroupDict == null || !shopGroupDict.ContainsKey(shopGroupID)) - return false; - - shopGroupDict[shopGroupID] = updatedData; - return true; - } - catch - { - return false; - } - } - - public static bool UpdateShopItem(int shopGroupID, int itemSlot, int itemMasterID, int itemPrice) - { - if (itemSlot < 1 || itemSlot > 9) - return false; - - try - { - ShopGroup_MasterData shopData = GetShopGroupData(shopGroupID); - if (shopData == null) - return false; - - string masterIDField = $"item{itemSlot}_masterid"; - string priceField = $"item{itemSlot}_price"; - - ReflectionHelper.SetFieldValue(shopData, masterIDField, itemMasterID); - ReflectionHelper.SetFieldValue(shopData, priceField, itemPrice); - - return true; - } - catch - { - return false; - } - } - - public static bool RemoveShopItem(int shopGroupID, int itemSlot) - { - if (itemSlot < 1 || itemSlot > 9) - return false; - - try - { - ShopGroup_MasterData shopData = GetShopGroupData(shopGroupID); - if (shopData == null) - return false; - - string masterIDField = $"item{itemSlot}_masterid"; - string priceField = $"item{itemSlot}_price"; - string valListField = $"ShopGroup_item{itemSlot}_valval"; - - ReflectionHelper.SetFieldValue(shopData, masterIDField, 0); - ReflectionHelper.SetFieldValue(shopData, priceField, 0); - - var valList = ReflectionHelper.GetFieldValue(shopData, valListField); - if (valList is System.Collections.IList list) - { - list.Clear(); - } - - return true; - } - catch - { - return false; - } - } - - public static int GetShopItemMasterID(int shopGroupID, int itemSlot) - { - if (itemSlot < 1 || itemSlot > 9) - return 0; - - try - { - ShopGroup_MasterData shopData = GetShopGroupData(shopGroupID); - if (shopData == null) - return 0; - - string masterIDField = $"item{itemSlot}_masterid"; - return ReflectionHelper.GetFieldValue(shopData, masterIDField); - } - catch - { - return 0; - } - } - - public static int GetShopItemPrice(int shopGroupID, int itemSlot) - { - if (itemSlot < 1 || itemSlot > 9) - return 0; - - try - { - ShopGroup_MasterData shopData = GetShopGroupData(shopGroupID); - if (shopData == null) - return 0; - - string priceField = $"item{itemSlot}_price"; - return ReflectionHelper.GetFieldValue(shopData, priceField); - } - catch - { - return 0; - } - } - - public static List GetAllShopItemMasterIDs(int shopGroupID) - { - var itemIDs = new List(); - - try - { - ShopGroup_MasterData shopData = GetShopGroupData(shopGroupID); - if (shopData == null) - return itemIDs; - - for (int i = 1; i <= 9; i++) - { - int masterID = GetShopItemMasterID(shopGroupID, i); - if (masterID != 0) - { - itemIDs.Add(masterID); - } - } - } - catch { } - - return itemIDs; - } - - public static bool ShopExists(int shopGroupID) - { - try - { - DataManager? dataManager = ManagerAPI.GetDataManager(); - if (dataManager == null) - return false; - - var excelDataManager = ReflectionHelper.GetFieldValue(dataManager, "ExcelDataManager"); - if (excelDataManager == null) - return false; - - var shopGroupDict = ReflectionHelper.GetFieldValue>(excelDataManager, "ShopGroupDict"); - if (shopGroupDict == null) - return false; - - return shopGroupDict.ContainsKey(shopGroupID); - } - catch - { - return false; - } - } - - public static int GetShopCount() - { - try - { - DataManager? dataManager = ManagerAPI.GetDataManager(); - if (dataManager == null) - return 0; - - var excelDataManager = ReflectionHelper.GetFieldValue(dataManager, "ExcelDataManager"); - if (excelDataManager == null) - return 0; - - var shopGroupDict = ReflectionHelper.GetFieldValue>(excelDataManager, "ShopGroupDict"); - if (shopGroupDict == null) - return 0; - - return shopGroupDict.Count; - } - catch - { - return 0; - } - } - - public static ShopGroup_MasterData CreateNewShopGroup(int id) - { - try - { - var newShop = new ShopGroup_MasterData(); - ReflectionHelper.SetFieldValue(newShop, "id", id); - - for (int i = 1; i <= 9; i++) - { - string masterIDField = $"item{i}_masterid"; - string priceField = $"item{i}_price"; - string valListField = $"ShopGroup_item{i}_valval"; - - ReflectionHelper.SetFieldValue(newShop, masterIDField, 0); - ReflectionHelper.SetFieldValue(newShop, priceField, 0); - } - - return newShop; - } - catch - { - return null; - } - } - - public static bool ClearShopItems(int shopGroupID) - { - try - { - ShopGroup_MasterData shopData = GetShopGroupData(shopGroupID); - if (shopData == null) - return false; - - for (int i = 1; i <= 9; i++) - { - RemoveShopItem(shopGroupID, i); - } - - return true; - } - catch - { - return false; - } - } - } -} diff --git a/GameAPI/VoiceAPI.cs b/GameAPI/VoiceAPI.cs deleted file mode 100644 index 6b9ef5a..0000000 --- a/GameAPI/VoiceAPI.cs +++ /dev/null @@ -1,193 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Dissonance; -using Dissonance.Audio.Playback; -using Dissonance.Integrations.FishNet; -using UnityEngine; - -namespace MimicAPI.GameAPI -{ - public static class VoiceAPI - { - private static Dictionary _voicePitchCache = new Dictionary(); - - public static bool AddVoicePitch(string playerId, float pitchValue) - { - if (string.IsNullOrEmpty(playerId)) - return false; - - var voiceManager = ManagerAPI.GetUIManager(); - if (voiceManager == null) - return false; - - try - { - var dissonanceComms = DissonanceFishNetComms.Instance?.Comms; - if (dissonanceComms == null) - return false; - - var voicePlayerState = dissonanceComms.FindPlayer(playerId); - if (voicePlayerState == null) - return false; - - var customPlayback = voicePlayerState.Playback as CustomVoicePlayback; - if (customPlayback?.AudioSource == null) - return false; - - if (!_voicePitchCache.ContainsKey(playerId)) - { - _voicePitchCache[playerId] = customPlayback.AudioSource.pitch; - } - - customPlayback.AudioSource.pitch += pitchValue; - return true; - - return false; - } - catch - { - return false; - } - } - - public static bool RemoveVoicePitch(string playerId) - { - if (string.IsNullOrEmpty(playerId)) - return false; - - try - { - var dissonanceComms = DissonanceFishNetComms.Instance?.Comms; - if (dissonanceComms == null) - return false; - - var voicePlayerState = dissonanceComms.FindPlayer(playerId); - if (voicePlayerState == null) - return false; - - var customPlayback = voicePlayerState.Playback as CustomVoicePlayback; - if (customPlayback?.AudioSource == null || !_voicePitchCache.ContainsKey(playerId)) - return false; - - customPlayback.AudioSource.pitch = _voicePitchCache[playerId]; - _voicePitchCache.Remove(playerId); - return true; - - return false; - } - catch - { - return false; - } - } - - public static float GetVoicePitchBefore(string playerId) - { - if (string.IsNullOrEmpty(playerId)) - return 1f; - - if (_voicePitchCache.TryGetValue(playerId, out var originalPitch)) - return originalPitch; - - return 1f; - } - - public static float GetVoicePitchAfter(string playerId) - { - if (string.IsNullOrEmpty(playerId)) - return 1f; - - try - { - var dissonanceComms = DissonanceFishNetComms.Instance?.Comms; - if (dissonanceComms == null) - return 1f; - - var voicePlayerState = dissonanceComms.FindPlayer(playerId); - if (voicePlayerState == null) - return 1f; - - var audioSource = ReflectionHelper.GetFieldValue(voicePlayerState.Playback, "AudioSource"); - return audioSource?.pitch ?? 1f; - } - catch - { - return 1f; - } - } - - public static bool SetVoicePitch(string playerId, float pitchValue) - { - if (string.IsNullOrEmpty(playerId)) - return false; - - try - { - var dissonanceComms = DissonanceFishNetComms.Instance?.Comms; - if (dissonanceComms == null) - return false; - - var voicePlayerState = dissonanceComms.FindPlayer(playerId); - if (voicePlayerState == null) - return false; - - var customPlayback = voicePlayerState.Playback as CustomVoicePlayback; - if (customPlayback?.AudioSource == null) - return false; - - if (!_voicePitchCache.ContainsKey(playerId)) - { - _voicePitchCache[playerId] = customPlayback.AudioSource.pitch; - } - - customPlayback.AudioSource.pitch = Mathf.Clamp(pitchValue, 0.1f, 3f); - return true; - - return false; - } - catch - { - return false; - } - } - - public static List GetAllVoicePlayers() - { - var players = new List(); - - try - { - var dissonanceComms = DissonanceFishNetComms.Instance?.Comms; - if (dissonanceComms == null) - return players; - - var allPlayers = ReflectionHelper.GetFieldValue>(dissonanceComms, "_players"); - if (allPlayers != null) - { - players.AddRange(allPlayers.Keys); - } - } - catch { } - - return players; - } - - public static bool IsVoicePitchModified(string playerId) - { - if (string.IsNullOrEmpty(playerId)) - return false; - - var originalPitch = GetVoicePitchBefore(playerId); - var currentPitch = GetVoicePitchAfter(playerId); - - return !Mathf.Approximately(originalPitch, currentPitch); - } - - public static void ClearVoicePitchCache() - { - _voicePitchCache.Clear(); - } - } -} diff --git a/GameAPI/WeatherAPI.cs b/GameAPI/WeatherAPI.cs deleted file mode 100644 index c142d71..0000000 --- a/GameAPI/WeatherAPI.cs +++ /dev/null @@ -1,196 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using UnityEngine; - -namespace MimicAPI.GameAPI -{ - public static class WeatherAPI - { - public static SkyAndWeatherSystem.eWeatherPreset GetCurrentWeatherPreset(IVroom? room) - { - if (room == null) - return SkyAndWeatherSystem.eWeatherPreset.Sunny; - - try - { - var dungeonWeather = ReflectionHelper.GetFieldValue(room, "_dungeonWeather"); - if (dungeonWeather == null) - return SkyAndWeatherSystem.eWeatherPreset.Sunny; - - TimeUtil? timeUtil = ManagerAPI.GetTimeUtil(); - if (timeUtil == null) - return SkyAndWeatherSystem.eWeatherPreset.Sunny; - - int currentHour = GetCurrentHour(timeUtil); - return dungeonWeather.GetWeatherPreset(currentHour); - } - catch - { - return SkyAndWeatherSystem.eWeatherPreset.Sunny; - } - } - - public static int GetCurrentWeatherMasterID(IVroom? room) - { - if (room == null) - return 0; - - try - { - var dungeonWeather = ReflectionHelper.GetFieldValue(room, "_dungeonWeather"); - if (dungeonWeather == null) - return 0; - - TimeUtil? timeUtil = ManagerAPI.GetTimeUtil(); - if (timeUtil == null) - return 0; - - int currentHour = GetCurrentHour(timeUtil); - return dungeonWeather.GetWeatherMasterID(currentHour); - } - catch - { - return 0; - } - } - - public static int GetWeatherForecastMasterID(IVroom? room) - { - if (room == null) - return 0; - - try - { - var dungeonWeather = ReflectionHelper.GetFieldValue(room, "_dungeonWeather"); - if (dungeonWeather == null) - return 0; - - TimeUtil? timeUtil = ManagerAPI.GetTimeUtil(); - if (timeUtil == null) - return 0; - - int currentHour = GetCurrentHour(timeUtil); - return dungeonWeather.GetWeatherForecastMasterID(currentHour); - } - catch - { - return 0; - } - } - - public static bool UpdateWeather(IVroom? room, int newWeatherID, int startHour, int durationHour, bool forecast) - { - if (room == null) - return false; - - try - { - var dungeonWeather = ReflectionHelper.GetFieldValue(room, "_dungeonWeather"); - if (dungeonWeather == null) - return false; - - dungeonWeather.SetWeatherOverride(newWeatherID, startHour, durationHour, forecast); - return true; - } - catch - { - return false; - } - } - - public static bool UpdateWeatherAll(IVroom? room, int newWeatherID) - { - if (room == null) - return false; - - try - { - var dungeonWeather = ReflectionHelper.GetFieldValue(room, "_dungeonWeather"); - if (dungeonWeather == null) - return false; - - dungeonWeather.SetWeatherOverrideAll(newWeatherID); - return true; - } - catch - { - return false; - } - } - - public static float GetCurrentContaminationRate(IVroom? room) - { - if (room == null) - return 0f; - - try - { - var dungeonWeather = ReflectionHelper.GetFieldValue(room, "_dungeonWeather"); - if (dungeonWeather == null) - return 0f; - - TimeUtil? timeUtil = ManagerAPI.GetTimeUtil(); - if (timeUtil == null) - return 0f; - - int currentHour = GetCurrentHour(timeUtil); - return dungeonWeather.GetCurrentContaRate(currentHour); - } - catch - { - return 0f; - } - } - - public static bool IsRandomWeatherOccurred(IVroom? room) - { - if (room == null) - return false; - - try - { - var dungeonWeather = ReflectionHelper.GetFieldValue(room, "_dungeonWeather"); - if (dungeonWeather == null) - return false; - - return dungeonWeather.IsRandomOccured; - } - catch - { - return false; - } - } - - public static List GetAllWeatherByHour(IVroom? room) - { - if (room == null) - return new List(); - - try - { - var dungeonWeather = ReflectionHelper.GetFieldValue(room, "_dungeonWeather"); - if (dungeonWeather == null) - return new List(); - - return dungeonWeather.GetAllWeather(); - } - catch - { - return new List(); - } - } - - private static int GetCurrentHour(TimeUtil timeUtil) - { - object? currentTimeObj = ReflectionHelper.GetFieldValue(timeUtil, "_currentTime"); - if (currentTimeObj is long currentTime) - { - int hours = (int)((currentTime / 1000) / 3600) % 24; - return hours; - } - return 0; - } - } -} diff --git a/Directory.Build.props b/MimicAPI.TestMod/Directory.Build.props similarity index 100% rename from Directory.Build.props rename to MimicAPI.TestMod/Directory.Build.props diff --git a/Directory.Build.targets b/MimicAPI.TestMod/Directory.Build.targets similarity index 100% rename from Directory.Build.targets rename to MimicAPI.TestMod/Directory.Build.targets diff --git a/MimicAPI.TestMod/Libs/shadcnui.dll b/MimicAPI.TestMod/Libs/shadcnui.dll new file mode 100644 index 0000000..7b51a02 Binary files /dev/null and b/MimicAPI.TestMod/Libs/shadcnui.dll differ diff --git a/MimicAPI.TestMod/Loader.cs b/MimicAPI.TestMod/Loader.cs new file mode 100644 index 0000000..92582df --- /dev/null +++ b/MimicAPI.TestMod/Loader.cs @@ -0,0 +1,26 @@ +using MelonLoader; +using MimicAPI.TestMod; +using UnityEngine; + +[assembly: MelonInfo(typeof(Loader), "MimicAPI.TestMod", "0.2.0", "MimicAPI")] +[assembly: MelonGame("ReLUGames", "MIMESIS")] + +namespace MimicAPI.TestMod +{ + public class Loader : MelonMod + { + private GameObject gui; + + public override void OnInitializeMelon() { } + + public override void OnSceneWasLoaded(int buildIndex, string sceneName) + { + if (gui == null) + { + gui = new GameObject(nameof(TestGUI)); + gui.AddComponent(); + GameObject.DontDestroyOnLoad(gui); + } + } + } +} diff --git a/MimicAPI.TestMod/MimicAPI.TestMod.csproj b/MimicAPI.TestMod/MimicAPI.TestMod.csproj new file mode 100644 index 0000000..eb85098 --- /dev/null +++ b/MimicAPI.TestMod/MimicAPI.TestMod.csproj @@ -0,0 +1,665 @@ + + + netstandard2.1 + enable + 4 + $(NoWarn);MSB3277;MSB3270 + true + + + + $(MelonLoaderPath)\0Harmony.dll + + + $(GameAssemblyPath)\AllIn1SpriteShaderAssembly.dll + + + $(GameAssemblyPath)\Appccelerate.StateMachine.dll + + + $(GameAssemblyPath)\Assembly-CSharp.dll + + + $(GameAssemblyPath)\Assembly-CSharp-firstpass.dll + + + $(MelonLoaderPath)\AssetsTools.NET.dll + + + $(GameAssemblyPath)\Autodesk.Fbx.dll + + + $(GameAssemblyPath)\Autodesk.Fbx.BuildTestAssets.dll + + + $(GameAssemblyPath)\CodeStage.Maintainer.Demo.dll + + + $(GameAssemblyPath)\com.krafton.gpp.sdk.unity.dll + + + $(GameAssemblyPath)\com.krafton.gpp.sdk.unity.steam.dll + + + $(GameAssemblyPath)\com.rlabrecque.steamworks.net.dll + + + $(GameAssemblyPath)\com.Tivadar.Best.HTTP.dll + + + $(GameAssemblyPath)\com.Tivadar.Best.TLSSecurity.dll + + + $(GameAssemblyPath)\Crc32.NET.dll + + + $(GameAssemblyPath)\DemiLib.dll + + + $(GameAssemblyPath)\DissonanceVoip.dll + + + $(GameAssemblyPath)\DissonanceVoip.FishNet.dll + + + $(GameAssemblyPath)\DOTween.dll + + + $(GameAssemblyPath)\DOTween.Modules.dll + + + $(GameAssemblyPath)\DOTweenPro.dll + + + $(GameAssemblyPath)\DOTweenPro.Scripts.dll + + + $(GameAssemblyPath)\EZhex1991.EZSoftBone.dll + + + $(GameAssemblyPath)\FishNet.CodeAnalysis.dll + + + $(GameAssemblyPath)\FishNet.Demos.dll + + + $(GameAssemblyPath)\FishNet.Runtime.dll + + + $(GameAssemblyPath)\GameKit.Dependencies.dll + + + $(GameAssemblyPath)\Google.Protobuf.dll + + + $(GameAssemblyPath)\Google.Protobuf_Packed.dll + + + $(GameAssemblyPath)\Grpc.Core.Api.dll + + + $(GameAssemblyPath)\Grpc.Net.Client.dll + + + $(GameAssemblyPath)\Grpc.Net.Common.dll + + + $(GameAssemblyPath)\Lofelt.NiceVibrations.dll + + + $(GameAssemblyPath)\Lofelt.NiceVibrations.Demo.dll + + + $(GameAssemblyPath)\MagicaCloth.dll + + + $(MelonLoaderPath)\MelonLoader.dll + + + $(MelonLoaderPath)\MelonLoader.NativeHost.dll + + + $(GameAssemblyPath)\MemoryPack.Core.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.Configuration.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.Configuration.Abstractions.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.Configuration.Binder.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.DependencyInjection.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.DependencyInjection.Abstractions.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.Http.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.Logging.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.Logging.Abstractions.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.ObjectPool.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.Options.dll + + + $(GameAssemblyPath)\Microsoft.Extensions.Primitives.dll + + + $(MelonLoaderPath)\Mono.Cecil.dll + + + $(MelonLoaderPath)\Mono.Cecil.Mdb.dll + + + $(MelonLoaderPath)\Mono.Cecil.Pdb.dll + + + $(MelonLoaderPath)\Mono.Cecil.Rocks.dll + + + $(GameAssemblyPath)\Mono.Security.dll + + + $(MelonLoaderPath)\MonoMod.RuntimeDetour.dll + + + $(MelonLoaderPath)\MonoMod.Utils.dll + + + $(GameAssemblyPath)\MoreMountains.Tools.dll + + + $(GameAssemblyPath)\Newtonsoft.Json.dll + + + $(GameAssemblyPath)\NonConvexCollider.dll + + + $(GameAssemblyPath)\NonConvexColliderRuntimeAPI.dll + + + $(GameAssemblyPath)\OccaSoftware.Buto.Demo.dll + + + $(GameAssemblyPath)\OccaSoftware.Buto.Runtime.dll + + + $(GameAssemblyPath)\OccaSoftware.Buto.Shaders.dll + + + $(GameAssemblyPath)\prometheus-net.DotNetRuntime.dll + + + $(GameAssemblyPath)\Prometheus.NetStandard.dll + + + $(GameAssemblyPath)\RTLTMPro.dll + + + $(GameAssemblyPath)\RuntimeTestAssembly.dll + + + $(GameAssemblyPath)\sc.posteffects.runtime.dll + + + $(PluginsPath)\shadcnui.dll + + + $(PluginsPath)\MimicAPI.dll + + + $(GameAssemblyPath)\System.Collections.Immutable.dll + + + $(GameAssemblyPath)\Unity.AI.Navigation.dll + + + $(GameAssemblyPath)\Unity.Burst.dll + + + $(GameAssemblyPath)\Unity.Burst.Unsafe.dll + + + $(GameAssemblyPath)\Unity.Cinemachine.dll + + + $(GameAssemblyPath)\Unity.Collections.dll + + + $(GameAssemblyPath)\Unity.Collections.LowLevel.ILSupport.dll + + + $(GameAssemblyPath)\Unity.Formats.Fbx.Runtime.dll + + + $(GameAssemblyPath)\Unity.InputSystem.dll + + + $(GameAssemblyPath)\Unity.InputSystem.ForUI.dll + + + $(GameAssemblyPath)\Unity.Jobs.dll + + + $(GameAssemblyPath)\Unity.Mathematics.dll + + + $(GameAssemblyPath)\Unity.ML-Agents.dll + + + $(GameAssemblyPath)\Unity.ML-Agents.CommunicatorObjects.dll + + + $(GameAssemblyPath)\Unity.ML-Agents.Extensions.dll + + + $(GameAssemblyPath)\Unity.ML-Agents.Extensions.Input.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Center.Common.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Playmode.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Playmode.Common.Runtime.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.Adapters.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.Common.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.Initialization.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.MetricEvents.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.MetricTestData.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.MetricTypes.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.NetStats.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.NetStatsMonitor.Component.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.NetStatsMonitor.Configuration.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.NetStatsMonitor.Implementation.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.NetStatsReporting.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.NetVis.Configuration.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.NetworkProfiler.Runtime.dll + + + $(GameAssemblyPath)\Unity.Multiplayer.Tools.NetworkSolutionInterface.dll + + + $(GameAssemblyPath)\Unity.Polybrush.dll + + + $(GameAssemblyPath)\Unity.Postprocessing.Runtime.dll + + + $(GameAssemblyPath)\Unity.Profiling.Core.dll + + + $(GameAssemblyPath)\Unity.Recorder.dll + + + $(GameAssemblyPath)\Unity.Recorder.Base.dll + + + $(GameAssemblyPath)\Unity.Rendering.LightTransport.Runtime.dll + + + $(GameAssemblyPath)\Unity.RenderPipeline.Universal.ShaderLibrary.dll + + + $(GameAssemblyPath)\Unity.RenderPipelines.Core.Runtime.dll + + + $(GameAssemblyPath)\Unity.RenderPipelines.Core.Runtime.Shared.dll + + + $(GameAssemblyPath)\Unity.RenderPipelines.Core.ShaderLibrary.dll + + + $(GameAssemblyPath)\Unity.RenderPipelines.GPUDriven.Runtime.dll + + + $(GameAssemblyPath)\Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary.dll + + + $(GameAssemblyPath)\Unity.RenderPipelines.Universal.2D.Runtime.dll + + + $(GameAssemblyPath)\Unity.RenderPipelines.Universal.Config.Runtime.dll + + + $(GameAssemblyPath)\Unity.RenderPipelines.Universal.Runtime.dll + + + $(GameAssemblyPath)\Unity.RenderPipelines.Universal.Shaders.dll + + + $(GameAssemblyPath)\Unity.Sentis.dll + + + $(GameAssemblyPath)\Unity.Sentis.ONNX.dll + + + $(GameAssemblyPath)\Unity.Services.CloudDiagnostics.dll + + + $(GameAssemblyPath)\Unity.Services.Core.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Analytics.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Components.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Configuration.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Device.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Environments.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Environments.Internal.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Internal.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Networking.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Registration.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Scheduler.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Telemetry.dll + + + $(GameAssemblyPath)\Unity.Services.Core.Threading.dll + + + $(GameAssemblyPath)\Unity.Splines.dll + + + $(GameAssemblyPath)\Unity.TextMeshPro.dll + + + $(GameAssemblyPath)\Unity.Timeline.dll + + + $(GameAssemblyPath)\UnityEngine.dll + + + $(GameAssemblyPath)\UnityEngine.AccessibilityModule.dll + + + $(GameAssemblyPath)\UnityEngine.AIModule.dll + + + $(GameAssemblyPath)\UnityEngine.AMDModule.dll + + + $(GameAssemblyPath)\UnityEngine.AndroidJNIModule.dll + + + $(GameAssemblyPath)\UnityEngine.AnimationModule.dll + + + $(GameAssemblyPath)\UnityEngine.ARModule.dll + + + $(GameAssemblyPath)\UnityEngine.AssetBundleModule.dll + + + $(GameAssemblyPath)\UnityEngine.AudioModule.dll + + + $(GameAssemblyPath)\UnityEngine.ClothModule.dll + + + $(GameAssemblyPath)\UnityEngine.ClusterInputModule.dll + + + $(GameAssemblyPath)\UnityEngine.ClusterRendererModule.dll + + + $(GameAssemblyPath)\UnityEngine.ContentLoadModule.dll + + + $(GameAssemblyPath)\UnityEngine.CoreModule.dll + + + $(GameAssemblyPath)\UnityEngine.CrashReportingModule.dll + + + $(GameAssemblyPath)\UnityEngine.DirectorModule.dll + + + $(GameAssemblyPath)\UnityEngine.DSPGraphModule.dll + + + $(GameAssemblyPath)\UnityEngine.GameCenterModule.dll + + + $(GameAssemblyPath)\UnityEngine.GIModule.dll + + + $(GameAssemblyPath)\UnityEngine.GraphicsStateCollectionSerializerModule.dll + + + $(GameAssemblyPath)\UnityEngine.GridModule.dll + + + $(GameAssemblyPath)\UnityEngine.HierarchyCoreModule.dll + + + $(GameAssemblyPath)\UnityEngine.HotReloadModule.dll + + + $(MelonLoaderPath)\UnityEngine.Il2CppAssetBundleManager.dll + + + $(MelonLoaderPath)\UnityEngine.Il2CppImageConversionManager.dll + + + $(GameAssemblyPath)\UnityEngine.ImageConversionModule.dll + + + $(GameAssemblyPath)\UnityEngine.IMGUIModule.dll + + + $(GameAssemblyPath)\UnityEngine.InputForUIModule.dll + + + $(GameAssemblyPath)\UnityEngine.InputLegacyModule.dll + + + $(GameAssemblyPath)\UnityEngine.InputModule.dll + + + $(GameAssemblyPath)\UnityEngine.JSONSerializeModule.dll + + + $(GameAssemblyPath)\UnityEngine.LocalizationModule.dll + + + $(GameAssemblyPath)\UnityEngine.MarshallingModule.dll + + + $(GameAssemblyPath)\UnityEngine.MultiplayerModule.dll + + + $(GameAssemblyPath)\UnityEngine.NVIDIAModule.dll + + + $(GameAssemblyPath)\UnityEngine.ParticleSystemModule.dll + + + $(GameAssemblyPath)\UnityEngine.PerformanceReportingModule.dll + + + $(GameAssemblyPath)\UnityEngine.Physics2DModule.dll + + + $(GameAssemblyPath)\UnityEngine.PhysicsModule.dll + + + $(GameAssemblyPath)\UnityEngine.PropertiesModule.dll + + + $(GameAssemblyPath)\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll + + + $(GameAssemblyPath)\UnityEngine.ScreenCaptureModule.dll + + + $(GameAssemblyPath)\UnityEngine.ShaderVariantAnalyticsModule.dll + + + $(GameAssemblyPath)\UnityEngine.SharedInternalsModule.dll + + + $(GameAssemblyPath)\UnityEngine.SpriteMaskModule.dll + + + $(GameAssemblyPath)\UnityEngine.SpriteShapeModule.dll + + + $(GameAssemblyPath)\UnityEngine.StreamingModule.dll + + + $(GameAssemblyPath)\UnityEngine.SubstanceModule.dll + + + $(GameAssemblyPath)\UnityEngine.SubsystemsModule.dll + + + $(GameAssemblyPath)\UnityEngine.TerrainModule.dll + + + $(GameAssemblyPath)\UnityEngine.TerrainPhysicsModule.dll + + + $(GameAssemblyPath)\UnityEngine.TextCoreFontEngineModule.dll + + + $(GameAssemblyPath)\UnityEngine.TextCoreTextEngineModule.dll + + + $(GameAssemblyPath)\UnityEngine.TextRenderingModule.dll + + + $(GameAssemblyPath)\UnityEngine.TilemapModule.dll + + + $(GameAssemblyPath)\UnityEngine.TLSModule.dll + + + $(GameAssemblyPath)\UnityEngine.UI.dll + + + $(GameAssemblyPath)\UnityEngine.UIElementsModule.dll + + + $(GameAssemblyPath)\UnityEngine.UIModule.dll + + + $(GameAssemblyPath)\UnityEngine.UmbraModule.dll + + + $(GameAssemblyPath)\UnityEngine.UnityAnalyticsCommonModule.dll + + + $(GameAssemblyPath)\UnityEngine.UnityAnalyticsModule.dll + + + $(GameAssemblyPath)\UnityEngine.UnityConnectModule.dll + + + $(GameAssemblyPath)\UnityEngine.UnityCurlModule.dll + + + $(GameAssemblyPath)\UnityEngine.UnityTestProtocolModule.dll + + + $(GameAssemblyPath)\UnityEngine.UnityWebRequestAssetBundleModule.dll + + + $(GameAssemblyPath)\UnityEngine.UnityWebRequestAudioModule.dll + + + $(GameAssemblyPath)\UnityEngine.UnityWebRequestModule.dll + + + $(GameAssemblyPath)\UnityEngine.UnityWebRequestTextureModule.dll + + + $(GameAssemblyPath)\UnityEngine.UnityWebRequestWWWModule.dll + + + $(GameAssemblyPath)\UnityEngine.VehiclesModule.dll + + + $(GameAssemblyPath)\UnityEngine.VFXModule.dll + + + $(GameAssemblyPath)\UnityEngine.VideoModule.dll + + + $(GameAssemblyPath)\UnityEngine.VirtualTexturingModule.dll + + + $(GameAssemblyPath)\UnityEngine.VRModule.dll + + + $(GameAssemblyPath)\UnityEngine.WindModule.dll + + + $(GameAssemblyPath)\UnityEngine.XRModule.dll + + + $(GameAssemblyPath)\VorbisPluginImpl.dll + + + $(GameAssemblyPath)\websocket-sharp.dll + + + $(GameAssemblyPath)\zxing.unity.dll + + + diff --git a/MimicAPI.TestMod/TestGUI.cs b/MimicAPI.TestMod/TestGUI.cs new file mode 100644 index 0000000..87a9398 --- /dev/null +++ b/MimicAPI.TestMod/TestGUI.cs @@ -0,0 +1,965 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Bifrost.ConstEnum; +using MelonLoader; +using MimicAPI.GameAPI; +using shadcnui.GUIComponents.Core; +using shadcnui.GUIComponents.Core.Base; +using shadcnui.GUIComponents.Core.Styling; +using shadcnui.GUIComponents.Layout; +using UnityEngine; + +namespace MimicAPI.TestMod +{ + public class TestGUI : MonoBehaviour + { + private GUIHelper guiHelper; + private Rect windowRect = new Rect(20, 20, 1200, 700); + private Vector2 scrollPosition; + private int currentTab; + private Tabs.TabConfig[] tabs; + private bool showWindow = true; + + private Dictionary toggleStates = new Dictionary(); + private Dictionary sliderStates = new Dictionary(); + private List testResults = new List(); + + void Start() + { + try + { + guiHelper = new GUIHelper(); + tabs = new Tabs.TabConfig[] + { + new Tabs.TabConfig("Core", DrawCoreTab), + new Tabs.TabConfig("Managers", DrawManagersTab), + new Tabs.TabConfig("Player", DrawPlayerTab), + new Tabs.TabConfig("Room", DrawRoomTab), + new Tabs.TabConfig("Actor", DrawActorTab), + new Tabs.TabConfig("Loot", DrawLootTab), + new Tabs.TabConfig("Network", DrawNetworkTab), + new Tabs.TabConfig("Tests", DrawTestsTab), + }; + MelonLogger.Msg("TestGUI initialized"); + } + catch (Exception ex) + { + MelonLogger.Error($"TestGUI Start error: {ex.Message}"); + } + } + + void OnGUI() + { + try + { + if (guiHelper == null) + { + guiHelper = new GUIHelper(); + } + + windowRect = GUI.Window(12345, windowRect, DrawWindow, "MimicAPI Test"); + } + catch (Exception ex) + { + MelonLogger.Error($"OnGUI error: {ex.Message}"); + } + } + + void DrawWindow(int id) + { + try + { + guiHelper.UpdateGUI(showWindow); + if (!guiHelper.BeginGUI()) + { + GUI.DragWindow(); + return; + } + + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("MimicAPI Test", ControlVariant.Default); + GUILayout.FlexibleSpace(); + if (guiHelper.Button("Run All Tests", ControlVariant.Secondary)) + RunAllTests(); + guiHelper.EndHorizontalGroup(); + + currentTab = guiHelper.Tabs(tabs.Select(t => t.Name).ToArray(), currentTab, DrawTabContent); + + guiHelper.EndGUI(); + } + catch (Exception ex) + { + MelonLogger.Error($"DrawWindow error: {ex.Message}"); + } + GUI.DragWindow(); + } + + void DrawTabContent() + { + scrollPosition = guiHelper.ScrollView( + scrollPosition, + () => + { + guiHelper.BeginVerticalGroup(GUILayout.ExpandHeight(true)); + try + { + tabs[currentTab].Content?.Invoke(); + } + catch (Exception ex) + { + MelonLogger.Error($"Tab error: {ex.Message}"); + } + guiHelper.EndVerticalGroup(); + }, + GUILayout.Height(550) + ); + } + + void DrawSection(string title, Action content) + { + try + { + guiHelper.Label(title, ControlVariant.Default); + guiHelper.HorizontalSeparator(); + content?.Invoke(); + } + catch (Exception ex) + { + MelonLogger.Error($"Section '{title}' error: {ex.Message}"); + } + GUILayout.Space(15); + } + + #region Core Tab + void DrawCoreTab() + { + DrawSection( + "Hub", + () => + { + var hub = CoreAPI.GetHub(); + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Hub Status:"); + guiHelper.Badge(hub != null ? "Connected" : "Not Found", hub != null ? ControlVariant.Default : ControlVariant.Destructive); + guiHelper.EndHorizontalGroup(); + } + ); + + DrawSection( + "Persistent Data", + () => + { + var pdata = CoreAPI.GetPersistentData(); + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Persistent Data:"); + guiHelper.Badge(pdata != null ? "Loaded" : "Not Loaded", pdata != null ? ControlVariant.Default : ControlVariant.Secondary); + guiHelper.EndHorizontalGroup(); + } + ); + } + #endregion + + #region Managers Tab + void DrawManagersTab() + { + var managers = new (string Name, Func Getter)[] + { + ("DataManager", () => ManagerAPI.GetDataManager()), + ("TimeUtil", () => ManagerAPI.GetTimeUtil()), + ("NavManager", () => ManagerAPI.GetNavManager()), + ("DynamicDataManager", () => ManagerAPI.GetDynamicDataManager()), + ("UIManager", () => ManagerAPI.GetUIManager()), + ("CameraManager", () => ManagerAPI.GetCameraManager()), + ("AudioManager", () => ManagerAPI.GetAudioManager()), + ("InputManager", () => ManagerAPI.GetInputManager()), + ("NetworkManager", () => ManagerAPI.GetNetworkManager()), + ("APIHandler", () => ManagerAPI.GetAPIHandler()), + ("L10NManager", () => ManagerAPI.GetLocalisationManager()), + }; + + DrawSection( + "Manager Status", + () => + { + foreach (var (name, getter) in managers) + { + guiHelper.BeginHorizontalGroup(); + guiHelper.Label($"{name}:", ControlVariant.Default); + GUILayout.FlexibleSpace(); + try + { + var mgr = getter(); + guiHelper.Badge(mgr != null ? "OK" : "NULL", mgr != null ? ControlVariant.Default : ControlVariant.Secondary); + } + catch + { + guiHelper.Badge("Error", ControlVariant.Destructive); + } + guiHelper.EndHorizontalGroup(); + } + } + ); + } + #endregion + + #region Player Tab + void DrawPlayerTab() + { + DrawSection( + "Local Player", + () => + { + var player = PlayerAPI.GetLocalPlayer(); + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Local Player:"); + guiHelper.Badge(player != null ? PlayerAPI.GetPlayerName(player) : "Not Found", player != null ? ControlVariant.Default : ControlVariant.Destructive); + guiHelper.EndHorizontalGroup(); + + if (player != null) + { + var pos = PlayerAPI.GetLocalPlayerPosition(); + guiHelper.MutedLabel($"Position: {pos.x:F1}, {pos.y:F1}, {pos.z:F1}"); + + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Alive:"); + guiHelper.Badge(PlayerAPI.IsLocalPlayerAlive() ? "Yes" : "No", PlayerAPI.IsLocalPlayerAlive() ? ControlVariant.Default : ControlVariant.Destructive); + guiHelper.EndHorizontalGroup(); + } + } + ); + + DrawSection( + "All Players", + () => + { + var players = PlayerAPI.GetAllPlayers(); + guiHelper.Label($"Total Players: {players?.Length ?? 0}"); + + if (players != null && players.Length > 0) + { + string[] headers = { "Name", "Position", "Alive" }; + string[,] data = new string[Math.Min(players.Length, 10), 3]; + + for (int i = 0; i < Math.Min(players.Length, 10); i++) + { + var p = players[i]; + var pos = PlayerAPI.GetPlayerPosition(p); + data[i, 0] = PlayerAPI.GetPlayerName(p); + data[i, 1] = $"{pos.x:F0}, {pos.y:F0}, {pos.z:F0}"; + data[i, 2] = PlayerAPI.IsPlayerAlive(p) ? "Yes" : "No"; + } + + guiHelper.Table(headers, data, ControlVariant.Secondary); + } + } + ); + + DrawSection( + "Player Search", + () => + { + if (!sliderStates.ContainsKey("playerRange")) + sliderStates["playerRange"] = 50f; + sliderStates["playerRange"] = guiHelper.LabeledSlider("Search Range", sliderStates["playerRange"], 1f, 200f, true); + + guiHelper.BeginHorizontalGroup(); + if (guiHelper.Button("Find Players In Range")) + { + var nearby = PlayerAPI.GetPlayersInRange(sliderStates["playerRange"]); + guiHelper.ShowInfoToast("Players", $"Found {nearby.Count} players within {sliderStates["playerRange"]:F0}m"); + } + if (guiHelper.Button("Find Nearest Player")) + { + var nearest = PlayerAPI.GetNearestPlayer(); + if (nearest != null) + guiHelper.ShowSuccessToast("Nearest", PlayerAPI.GetPlayerName(nearest)); + else + guiHelper.ShowInfoToast("Nearest", "No players found"); + } + guiHelper.EndHorizontalGroup(); + } + ); + } + #endregion + + #region Room Tab + void DrawRoomTab() + { + DrawSection( + "Current Room", + () => + { + var room = RoomAPI.GetCurrentRoom(); + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Current Room:"); + guiHelper.Badge(room != null ? RoomAPI.GetRoomName(room) : "None", room != null ? ControlVariant.Default : ControlVariant.Secondary); + guiHelper.EndHorizontalGroup(); + + if (room != null) + { + guiHelper.MutedLabel($"Room ID: {RoomAPI.GetRoomID(room)}"); + guiHelper.MutedLabel($"Master ID: {RoomAPI.GetRoomMasterID(room)}"); + guiHelper.MutedLabel($"Game Day: {RoomAPI.GetCurrentGameDay(room)}"); + guiHelper.MutedLabel($"Session Cycle: {RoomAPI.GetCurrentSessionCycle(room)}"); + + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Playable:"); + guiHelper.Badge(RoomAPI.IsRoomPlayable(room) ? "Yes" : "No", RoomAPI.IsRoomPlayable(room) ? ControlVariant.Default : ControlVariant.Secondary); + guiHelper.EndHorizontalGroup(); + } + } + ); + + DrawSection( + "All Rooms", + () => + { + var rooms = RoomAPI.GetAllRooms(); + guiHelper.Label($"Total Rooms: {rooms.Length}"); + + var playableRooms = RoomAPI.GetAllPlayableRooms(); + guiHelper.Label($"Playable Rooms: {playableRooms.Count}"); + + if (rooms.Length > 0) + { + string[] headers = { "Name", "ID", "Playable", "Players" }; + string[,] data = new string[Math.Min(rooms.Length, 10), 4]; + + for (int i = 0; i < Math.Min(rooms.Length, 10); i++) + { + var r = rooms[i]; + data[i, 0] = RoomAPI.GetRoomName(r); + data[i, 1] = RoomAPI.GetRoomID(r).ToString(); + data[i, 2] = RoomAPI.IsRoomPlayable(r) ? "Yes" : "No"; + data[i, 3] = RoomAPI.GetRoomPlayers(r).Count.ToString(); + } + + guiHelper.Table(headers, data, ControlVariant.Secondary); + } + } + ); + + DrawSection( + "Room Settings", + () => + { + var room = RoomAPI.GetCurrentRoom(); + if (room != null) + { + int roomMaxPlayers = RoomAPI.GetRoomMaxPlayers(room); + guiHelper.Label($"Current Max Players: {roomMaxPlayers}"); + + if (!sliderStates.ContainsKey("roomMaxPlayers")) + sliderStates["roomMaxPlayers"] = roomMaxPlayers; + sliderStates["roomMaxPlayers"] = guiHelper.LabeledSlider("New Max Players", sliderStates["roomMaxPlayers"], 1f, 20f, 1f, true); + + if (guiHelper.Button("Set Max Players")) + { + RoomAPI.SetRoomMaxPlayers(room, (int)sliderStates["roomMaxPlayers"]); + guiHelper.ShowSuccessToast("Room", $"Max players set to {(int)sliderStates["roomMaxPlayers"]}"); + } + } + else + { + guiHelper.MutedLabel("No room available to configure"); + } + } + ); + } + #endregion + + #region Actor Tab + void DrawActorTab() + { + var room = RoomAPI.GetCurrentRoom(); + + DrawSection( + "VActors in Room", + () => + { + var actors = ActorAPI.GetAllVActorsInRoom(room); + guiHelper.Label($"Total Actors: {actors.Count}"); + + if (actors.Count > 0) + { + string[] headers = { "Type", "ID", "Alive" }; + string[,] data = new string[Math.Min(actors.Count, 10), 3]; + + for (int i = 0; i < Math.Min(actors.Count, 10); i++) + { + var a = actors[i]; + data[i, 0] = a?.GetType().Name ?? "Unknown"; + data[i, 1] = a?.ObjectID.ToString() ?? "N/A"; + data[i, 2] = a?.IsAliveStatus() == true ? "Yes" : "No"; + } + + guiHelper.Table(headers, data, ControlVariant.Secondary); + } + } + ); + + DrawSection( + "Monsters", + () => + { + var monsters = ActorAPI.GetMonstersInRoom(room); + var aliveMonsters = ActorAPI.GetAliveMonstersInRoom(room); + var deadMonsters = ActorAPI.GetDeadMonstersInRoom(room); + + guiHelper.BeginHorizontalGroup(); + guiHelper.Label($"Total Monsters: {monsters.Count}"); + guiHelper.Badge($"Alive: {aliveMonsters.Count}", ControlVariant.Destructive); + guiHelper.Badge($"Dead: {deadMonsters.Count}", ControlVariant.Secondary); + guiHelper.EndHorizontalGroup(); + + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Has Alive Monsters:"); + guiHelper.Badge(ActorAPI.HasAliveMonstersInRoom(room) ? "Yes" : "No", ActorAPI.HasAliveMonstersInRoom(room) ? ControlVariant.Destructive : ControlVariant.Default); + guiHelper.EndHorizontalGroup(); + } + ); + + DrawSection( + "Looting Objects", + () => + { + var lootObjs = ActorAPI.GetLootingObjectsInRoom(room); + guiHelper.Label($"Looting Objects: {lootObjs.Count}"); + } + ); + } + #endregion + + #region Loot Tab + void DrawLootTab() + { + DrawSection( + "Loot Overview", + () => + { + var allLoot = LootAPI.GetAllLoot(); + var inactiveLoot = LootAPI.GetInactiveLoot(); + + guiHelper.BeginHorizontalGroup(); + guiHelper.Label($"Active Loot: {allLoot.Length}"); + guiHelper.Label($"Inactive Loot: {inactiveLoot.Length}"); + guiHelper.EndHorizontalGroup(); + + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Has Loot:"); + guiHelper.Badge(LootAPI.HasLoot() ? "Yes" : "No", LootAPI.HasLoot() ? ControlVariant.Default : ControlVariant.Secondary); + guiHelper.EndHorizontalGroup(); + } + ); + + DrawSection( + "Nearby Loot", + () => + { + if (!sliderStates.ContainsKey("lootRange")) + sliderStates["lootRange"] = 50f; + sliderStates["lootRange"] = guiHelper.LabeledSlider("Search Range", sliderStates["lootRange"], 1f, 200f, true); + + var nearbyLoot = LootAPI.GetLootNearby(sliderStates["lootRange"]); + guiHelper.Label($"Loot within {sliderStates["lootRange"]:F0}m: {nearbyLoot.Length}"); + + if (guiHelper.Button("Find Nearest Loot")) + { + var nearest = LootAPI.GetNearestLoot(); + if (nearest != null) + { + var dist = LootAPI.GetDistanceToLoot(nearest); + guiHelper.ShowSuccessToast("Nearest Loot", $"{nearest.gameObject.name} at {dist:F1}m"); + } + else + { + guiHelper.ShowInfoToast("Loot", "No loot found"); + } + } + } + ); + + DrawSection( + "Loot List", + () => + { + var allLoot = LootAPI.GetAllLoot(); + if (allLoot.Length > 0) + { + string[] headers = { "Name", "Distance", "Position" }; + string[,] data = new string[Math.Min(allLoot.Length, 10), 3]; + + for (int i = 0; i < Math.Min(allLoot.Length, 10); i++) + { + var l = allLoot[i]; + var pos = LootAPI.GetLootPosition(l); + var dist = LootAPI.GetDistanceToLoot(l); + data[i, 0] = l.gameObject.name; + data[i, 1] = $"{dist:F1}m"; + data[i, 2] = $"{pos.x:F0}, {pos.y:F0}, {pos.z:F0}"; + } + + guiHelper.Table(headers, data, ControlVariant.Secondary); + } + else + { + guiHelper.MutedLabel("No loot available"); + } + } + ); + + DrawSection( + "Filter Loot", + () => + { + if (!sliderStates.ContainsKey("lootMinDist")) + sliderStates["lootMinDist"] = 10f; + if (!sliderStates.ContainsKey("lootMaxDist")) + sliderStates["lootMaxDist"] = 50f; + + sliderStates["lootMinDist"] = guiHelper.LabeledSlider("Min Distance", sliderStates["lootMinDist"], 0f, 100f, true); + sliderStates["lootMaxDist"] = guiHelper.LabeledSlider("Max Distance", sliderStates["lootMaxDist"], 0f, 200f, true); + + if (guiHelper.Button("Filter by Distance")) + { + var filtered = LootAPI.FilterLootByDistance(sliderStates["lootMinDist"], sliderStates["lootMaxDist"]); + guiHelper.ShowInfoToast("Filtered Loot", $"Found {filtered.Length} items between {sliderStates["lootMinDist"]:F0}m and {sliderStates["lootMaxDist"]:F0}m"); + } + } + ); + } + #endregion + + #region Network Tab + void DrawNetworkTab() + { + DrawSection( + "Server Status", + () => + { + var isRunning = ServerNetworkAPI.IsServerRunning(); + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Server Running:"); + guiHelper.Badge(isRunning ? "Yes" : "No", isRunning ? ControlVariant.Default : ControlVariant.Secondary); + guiHelper.EndHorizontalGroup(); + + if (isRunning) + { + var maxClients = ServerNetworkAPI.GetMaximumClients(); + var currentClients = ServerNetworkAPI.GetCurrentClientCount(); + + guiHelper.MutedLabel($"Max Clients: {maxClients}"); + guiHelper.MutedLabel($"Current Clients: {currentClients}"); + + guiHelper.Progress((float)currentClients / Math.Max(maxClients, 1), 300); + } + } + ); + + DrawSection( + "Waiting Room", + () => + { + var waitingRoom = ServerNetworkAPI.GetWaitingRoom(); + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Waiting Room:"); + guiHelper.Badge(waitingRoom != null ? "Available" : "Not Found", waitingRoom != null ? ControlVariant.Default : ControlVariant.Secondary); + guiHelper.EndHorizontalGroup(); + + if (waitingRoom != null) + { + var memberCount = ServerNetworkAPI.GetWaitingRoomMemberCount(); + var maxPlayers = ServerNetworkAPI.GetWaitingRoomMaxPlayers(); + + guiHelper.MutedLabel($"Members: {memberCount}/{maxPlayers}"); + guiHelper.Progress((float)memberCount / Math.Max(maxPlayers, 1), 300); + } + } + ); + + DrawSection( + "Maintenance Room", + () => + { + var maintenanceRoom = ServerNetworkAPI.GetMaintenanceRoom(); + guiHelper.BeginHorizontalGroup(); + guiHelper.Label("Maintenance Room:"); + guiHelper.Badge(maintenanceRoom != null ? "Available" : "Not Found", maintenanceRoom != null ? ControlVariant.Default : ControlVariant.Secondary); + guiHelper.EndHorizontalGroup(); + + if (maintenanceRoom != null) + { + var memberCount = ServerNetworkAPI.GetMaintenanceRoomMemberCount(); + var maxPlayers = ServerNetworkAPI.GetMaintenanceRoomMaxPlayers(); + + guiHelper.MutedLabel($"Members: {memberCount}/{maxPlayers}"); + } + } + ); + + DrawSection( + "Connected Players", + () => + { + var connected = ServerNetworkAPI.GetAllConnectedPlayers(); + guiHelper.Label($"Connected Players: {connected.Count}"); + } + ); + + DrawSection( + "Server Settings", + () => + { + var socket = ServerNetworkAPI.GetServerSocket(); + if (socket != null) + { + if (!sliderStates.ContainsKey("maxClients")) + sliderStates["maxClients"] = ServerNetworkAPI.GetMaximumClients(); + sliderStates["maxClients"] = guiHelper.LabeledSlider("Max Clients", sliderStates["maxClients"], 1f, 100f, 1f, true); + + if (guiHelper.Button("Set Max Clients")) + { + ServerNetworkAPI.SetMaximumClients(socket, (int)sliderStates["maxClients"]); + guiHelper.ShowSuccessToast("Server", $"Max clients set to {(int)sliderStates["maxClients"]}"); + } + } + else + { + guiHelper.MutedLabel("Server socket not available"); + } + } + ); + } + #endregion + + #region Tests Tab + void DrawTestsTab() + { + DrawSection( + "Test Controls", + () => + { + guiHelper.BeginHorizontalGroup(); + if (guiHelper.Button("Run All Tests", ControlVariant.Default)) + RunAllTests(); + if (guiHelper.Button("Clear Results", ControlVariant.Secondary)) + testResults.Clear(); + guiHelper.EndHorizontalGroup(); + + if (testResults.Count > 0) + { + int passed = testResults.Count(r => r.Passed); + int failed = testResults.Count - passed; + + guiHelper.BeginHorizontalGroup(); + guiHelper.Badge($"Passed: {passed}", ControlVariant.Default); + guiHelper.Badge($"Failed: {failed}", failed > 0 ? ControlVariant.Destructive : ControlVariant.Secondary); + guiHelper.EndHorizontalGroup(); + + guiHelper.Progress((float)passed / testResults.Count, 300); + } + } + ); + + DrawSection( + "Test Results", + () => + { + if (testResults.Count > 0) + { + string[] headers = { "Test", "Status", "Message" }; + string[,] data = new string[testResults.Count, 3]; + + for (int i = 0; i < testResults.Count; i++) + { + data[i, 0] = testResults[i].TestName; + data[i, 1] = testResults[i].Passed ? "PASS" : "FAIL"; + data[i, 2] = testResults[i].Message; + } + + guiHelper.Table(headers, data, ControlVariant.Secondary); + } + else + { + guiHelper.MutedLabel("No test results. Click 'Run All Tests' to start."); + } + } + ); + } + #endregion + + #region Test Methods + void RunAllTests() + { + testResults.Clear(); + TestReflectionHelper(); + TestCoreAPI(); + TestManagerAPI(); + TestPlayerAPI(); + TestRoomAPI(); + TestActorAPI(); + TestLootAPI(); + TestNetworkAPI(); + + int passed = testResults.Count(r => r.Passed); + guiHelper.ShowInfoToast("Tests Complete", $"{passed}/{testResults.Count} tests passed"); + } + + void TestReflectionHelper() + { + try + { + var testObj = new TestClass { TestField = "Hello", TestProperty = 42 }; + + var fieldValue = ReflectionHelper.GetFieldValue(testObj, "TestField"); + AddResult("ReflectionHelper.GetFieldValue", fieldValue?.ToString() == "Hello", $"Got: {fieldValue}"); + + var typedValue = ReflectionHelper.GetFieldValue(testObj, "TestField"); + AddResult("ReflectionHelper.GetFieldValue", typedValue == "Hello", $"Got: {typedValue}"); + + ReflectionHelper.SetFieldValue(testObj, "TestField", "Modified"); + AddResult("ReflectionHelper.SetFieldValue", testObj.TestField == "Modified", $"Got: {testObj.TestField}"); + + var methodResult = ReflectionHelper.InvokeMethod(testObj, "GetTestValue"); + AddResult("ReflectionHelper.InvokeMethod", methodResult?.ToString() == "TestValue", $"Got: {methodResult}"); + + var propValue = ReflectionHelper.GetPropertyValue(testObj, "TestProperty"); + AddResult("ReflectionHelper.GetPropertyValue", propValue == 42, $"Got: {propValue}"); + } + catch (Exception ex) + { + AddResult("ReflectionHelper", false, ex.Message); + } + } + + void TestCoreAPI() + { + try + { + AddResult("CoreAPI.GetHub", CoreAPI.GetHub() != null, "Hub check"); + } + catch (Exception ex) + { + AddResult("CoreAPI.GetHub", false, ex.Message); + } + + try + { + AddResult("CoreAPI.GetPersistentData", true, CoreAPI.GetPersistentData() != null ? "Found" : "Null"); + } + catch (Exception ex) + { + AddResult("CoreAPI.GetPersistentData", false, ex.Message); + } + } + + void TestManagerAPI() + { + var tests = new (string Name, Func Getter)[] + { + ("GetDataManager", () => ManagerAPI.GetDataManager()), + ("GetTimeUtil", () => ManagerAPI.GetTimeUtil()), + ("GetUIManager", () => ManagerAPI.GetUIManager()), + ("GetCameraManager", () => ManagerAPI.GetCameraManager()), + ("GetAudioManager", () => ManagerAPI.GetAudioManager()), + ("GetInputManager", () => ManagerAPI.GetInputManager()), + ("GetNetworkManager", () => ManagerAPI.GetNetworkManager()), + }; + + foreach (var (name, getter) in tests) + { + try + { + AddResult($"ManagerAPI.{name}", true, getter() != null ? "Found" : "Null"); + } + catch (Exception ex) + { + AddResult($"ManagerAPI.{name}", false, ex.Message); + } + } + } + + void TestPlayerAPI() + { + try + { + AddResult("PlayerAPI.HasLocalPlayer", true, $"{PlayerAPI.HasLocalPlayer()}"); + } + catch (Exception ex) + { + AddResult("PlayerAPI.HasLocalPlayer", false, ex.Message); + } + + try + { + AddResult("PlayerAPI.GetLocalPlayer", true, PlayerAPI.GetLocalPlayer() != null ? "Found" : "Null"); + } + catch (Exception ex) + { + AddResult("PlayerAPI.GetLocalPlayer", false, ex.Message); + } + + try + { + AddResult("PlayerAPI.GetAllPlayers", true, $"Count: {PlayerAPI.GetAllPlayers()?.Length ?? 0}"); + } + catch (Exception ex) + { + AddResult("PlayerAPI.GetAllPlayers", false, ex.Message); + } + + try + { + AddResult("PlayerAPI.GetLocalPlayerPosition", true, $"{PlayerAPI.GetLocalPlayerPosition()}"); + } + catch (Exception ex) + { + AddResult("PlayerAPI.GetLocalPlayerPosition", false, ex.Message); + } + } + + void TestRoomAPI() + { + try + { + AddResult("RoomAPI.GetAllRooms", true, $"Count: {RoomAPI.GetAllRooms().Length}"); + } + catch (Exception ex) + { + AddResult("RoomAPI.GetAllRooms", false, ex.Message); + } + + try + { + AddResult("RoomAPI.GetCurrentRoom", true, RoomAPI.GetCurrentRoom() != null ? "Found" : "Null"); + } + catch (Exception ex) + { + AddResult("RoomAPI.GetCurrentRoom", false, ex.Message); + } + + try + { + AddResult("RoomAPI.GetAllPlayableRooms", true, $"Count: {RoomAPI.GetAllPlayableRooms().Count}"); + } + catch (Exception ex) + { + AddResult("RoomAPI.GetAllPlayableRooms", false, ex.Message); + } + } + + void TestActorAPI() + { + var room = RoomAPI.GetCurrentRoom(); + + try + { + AddResult("ActorAPI.GetAllVActorsInRoom", true, $"Count: {ActorAPI.GetAllVActorsInRoom(room).Count}"); + } + catch (Exception ex) + { + AddResult("ActorAPI.GetAllVActorsInRoom", false, ex.Message); + } + + try + { + AddResult("ActorAPI.GetMonstersInRoom", true, $"Count: {ActorAPI.GetMonstersInRoom(room).Count}"); + } + catch (Exception ex) + { + AddResult("ActorAPI.GetMonstersInRoom", false, ex.Message); + } + } + + void TestLootAPI() + { + try + { + AddResult("LootAPI.GetAllLoot", true, $"Count: {LootAPI.GetAllLoot().Length}"); + } + catch (Exception ex) + { + AddResult("LootAPI.GetAllLoot", false, ex.Message); + } + + try + { + AddResult("LootAPI.HasLoot", true, $"{LootAPI.HasLoot()}"); + } + catch (Exception ex) + { + AddResult("LootAPI.HasLoot", false, ex.Message); + } + + try + { + AddResult("LootAPI.GetNearestLoot", true, LootAPI.GetNearestLoot() != null ? "Found" : "None"); + } + catch (Exception ex) + { + AddResult("LootAPI.GetNearestLoot", false, ex.Message); + } + } + + void TestNetworkAPI() + { + try + { + AddResult("ServerNetworkAPI.IsServerRunning", true, $"{ServerNetworkAPI.IsServerRunning()}"); + } + catch (Exception ex) + { + AddResult("ServerNetworkAPI.IsServerRunning", false, ex.Message); + } + + try + { + AddResult("ServerNetworkAPI.GetServerSocket", true, ServerNetworkAPI.GetServerSocket() != null ? "Found" : "Null"); + } + catch (Exception ex) + { + AddResult("ServerNetworkAPI.GetServerSocket", false, ex.Message); + } + + try + { + AddResult("ServerNetworkAPI.GetGameAssembly", true, ServerNetworkAPI.GetGameAssembly() != null ? "Found" : "Null"); + } + catch (Exception ex) + { + AddResult("ServerNetworkAPI.GetGameAssembly", false, ex.Message); + } + } + + void AddResult(string testName, bool passed, string message) + { + testResults.Add( + new TestResult + { + TestName = testName, + Passed = passed, + Message = message, + } + ); + } + #endregion + + #region Helper Classes + class TestResult + { + public string TestName { get; set; } = ""; + public bool Passed { get; set; } + public string Message { get; set; } = ""; + } + + class TestClass + { + public string TestField = ""; + public int TestProperty { get; set; } + + public string GetTestValue() => "TestValue"; + } + #endregion + } +} diff --git a/MimicAPI.sln b/MimicAPI.sln index 5f332b8..906401a 100644 --- a/MimicAPI.sln +++ b/MimicAPI.sln @@ -1,9 +1,11 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 18 -VisualStudioVersion = 18.0.11201.2 +VisualStudioVersion = 18.1.11312.151 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MimicAPI", "MimicAPI.csproj", "{3A94238E-A958-6913-E493-7C8E134B6970}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MimicAPI", "MimicAPI\MimicAPI.csproj", "{EC3A70FB-BBD5-CBDC-AD1C-0F94B5D0E912}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MimicAPI.TestMod", "MimicAPI.TestMod\MimicAPI.TestMod.csproj", "{25920676-0A1C-A024-50EC-ECB1AE6B75D4}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -11,15 +13,19 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3A94238E-A958-6913-E493-7C8E134B6970}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3A94238E-A958-6913-E493-7C8E134B6970}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3A94238E-A958-6913-E493-7C8E134B6970}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3A94238E-A958-6913-E493-7C8E134B6970}.Release|Any CPU.Build.0 = Release|Any CPU + {EC3A70FB-BBD5-CBDC-AD1C-0F94B5D0E912}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC3A70FB-BBD5-CBDC-AD1C-0F94B5D0E912}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC3A70FB-BBD5-CBDC-AD1C-0F94B5D0E912}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC3A70FB-BBD5-CBDC-AD1C-0F94B5D0E912}.Release|Any CPU.Build.0 = Release|Any CPU + {25920676-0A1C-A024-50EC-ECB1AE6B75D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25920676-0A1C-A024-50EC-ECB1AE6B75D4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25920676-0A1C-A024-50EC-ECB1AE6B75D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25920676-0A1C-A024-50EC-ECB1AE6B75D4}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {93E7B546-C199-4368-8D94-E1439C414FEA} + SolutionGuid = {92DA0585-7C21-4822-8F9B-08DD25051421} EndGlobalSection EndGlobal diff --git a/MimicAPI/Directory.Build.props b/MimicAPI/Directory.Build.props new file mode 100644 index 0000000..df3c4d4 --- /dev/null +++ b/MimicAPI/Directory.Build.props @@ -0,0 +1,15 @@ + + + + + C:\Program Files (x86)\Steam\steamapps\common\MIMESIS + $(GamePath)\Mimesis_Data\Managed + $(GamePath)\MelonLoader\net6 + $(GamePath)\Mods + + + pdbonly + true + bin\$(Configuration)\ + + diff --git a/MimicAPI/Directory.Build.targets b/MimicAPI/Directory.Build.targets new file mode 100644 index 0000000..8396c3a --- /dev/null +++ b/MimicAPI/Directory.Build.targets @@ -0,0 +1,7 @@ + + + + + + + diff --git a/GameAPI/ActorAPI.cs b/MimicAPI/GameAPI/ActorAPI.cs similarity index 100% rename from GameAPI/ActorAPI.cs rename to MimicAPI/GameAPI/ActorAPI.cs diff --git a/GameAPI/CoreAPI.cs b/MimicAPI/GameAPI/CoreAPI.cs similarity index 100% rename from GameAPI/CoreAPI.cs rename to MimicAPI/GameAPI/CoreAPI.cs diff --git a/GameAPI/LootAPI.cs b/MimicAPI/GameAPI/LootAPI.cs similarity index 100% rename from GameAPI/LootAPI.cs rename to MimicAPI/GameAPI/LootAPI.cs diff --git a/GameAPI/ManagerAPI.cs b/MimicAPI/GameAPI/ManagerAPI.cs similarity index 100% rename from GameAPI/ManagerAPI.cs rename to MimicAPI/GameAPI/ManagerAPI.cs diff --git a/GameAPI/PlayerAPI.cs b/MimicAPI/GameAPI/PlayerAPI.cs similarity index 100% rename from GameAPI/PlayerAPI.cs rename to MimicAPI/GameAPI/PlayerAPI.cs diff --git a/GameAPI/ReflectionHelper.cs b/MimicAPI/GameAPI/ReflectionHelper.cs similarity index 100% rename from GameAPI/ReflectionHelper.cs rename to MimicAPI/GameAPI/ReflectionHelper.cs diff --git a/GameAPI/RoomAPI.cs b/MimicAPI/GameAPI/RoomAPI.cs similarity index 100% rename from GameAPI/RoomAPI.cs rename to MimicAPI/GameAPI/RoomAPI.cs diff --git a/GameAPI/ServerNetworkAPI.cs b/MimicAPI/GameAPI/ServerNetworkAPI.cs similarity index 100% rename from GameAPI/ServerNetworkAPI.cs rename to MimicAPI/GameAPI/ServerNetworkAPI.cs diff --git a/MimicAPI/GameAPI/ShopAPI.cs b/MimicAPI/GameAPI/ShopAPI.cs new file mode 100644 index 0000000..d58715e --- /dev/null +++ b/MimicAPI/GameAPI/ShopAPI.cs @@ -0,0 +1,6 @@ +// This is not working + +namespace MimicAPI.GameAPI +{ + public static class ShopAPI { } +} diff --git a/MimicAPI/GameAPI/VoiceAPI.cs b/MimicAPI/GameAPI/VoiceAPI.cs new file mode 100644 index 0000000..884a2af --- /dev/null +++ b/MimicAPI/GameAPI/VoiceAPI.cs @@ -0,0 +1,6 @@ +// This is not working + +namespace MimicAPI.GameAPI +{ + public static class VoiceAPI { } +} diff --git a/MimicAPI/GameAPI/WeatherAPI.cs b/MimicAPI/GameAPI/WeatherAPI.cs new file mode 100644 index 0000000..cfc4415 --- /dev/null +++ b/MimicAPI/GameAPI/WeatherAPI.cs @@ -0,0 +1,6 @@ +// This is not working + +namespace MimicAPI.GameAPI +{ + public static class WeatherAPI { } +} diff --git a/MimicAPI.csproj b/MimicAPI/MimicAPI.csproj similarity index 100% rename from MimicAPI.csproj rename to MimicAPI/MimicAPI.csproj