using Dalamud.Hooking; using Dalamud.IoC; using Dalamud.Plugin; using Dalamud.Utility.Signatures; using Ktisis.Structs.Env; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; namespace VoidBox; public sealed unsafe class Plugin : IDalamudPlugin { private readonly List _cmds; public Plugin(IDalamudPluginInterface pluginInterface) { pluginInterface.Create(); Service.Plugin = this; try { Service.Config = Service.PluginInterface.GetPluginConfig() as Configuration ?? new(); } catch (Exception e) { Service.PluginLog.Error($"Failed to load config: {e}"); Service.Config = new(); } Service.PluginUI = new(); Service.Envs = new(); Service.Config.Initialize(Service.PluginInterface); _cmds = typeof(Plugin).Assembly.GetTypes() .Where(t => !t.IsAbstract && typeof(Cmd).IsAssignableFrom(t)) .Select(t => (Cmd) Activator.CreateInstance(t)!) .ToList(); foreach (Cmd cmd in _cmds) { cmd.Register(Service.CommandManager); } Service.GameInteropProvider.InitializeFromAttributes(this); _envStateCopyHook?.Enable(); } public string Name => "VoidBox"; public EnvState Current { get; private set; } public SavedEnv? Preview { get; set; } public void Dispose() { _envStateCopyHook?.Dispose(); foreach (Cmd cmd in _cmds) { cmd.Dispose(); } Service.PluginUI.Dispose(); Service.Plugin = null!; } private void Replace(EnvState* env) { var config = Service.Config; if (!config.IsEnabled) { return; } var savedEnv = (Preview ?? (Service.ClientState.IsLoggedIn ? config.HousingEnv : config.LoginEnv))?.Env; if (savedEnv == null) { return; } var savedEnvVal = savedEnv.Value; Replace(env, &savedEnvVal); } private void Replace(EnvState* to, EnvState* from) { to->SkyId = from->SkyId; to->Lighting.SunLightColor = from->Lighting.SunLightColor; to->Lighting.MoonLightColor = from->Lighting.MoonLightColor; to->Lighting.Ambient = from->Lighting.Ambient; to->Lighting._unk1 = from->Lighting._unk1; to->Lighting.AmbientSaturation = from->Lighting.AmbientSaturation; to->Lighting.Temperature = from->Lighting.Temperature; to->Lighting._unk2 = from->Lighting._unk2; to->Lighting._unk3 = from->Lighting._unk3; to->Lighting._unk4 = from->Lighting._unk4; to->Stars.ConstellationIntensity = from->Stars.ConstellationIntensity; to->Stars.Constellations = from->Stars.Constellations; to->Stars.Stars = from->Stars.Stars; to->Stars.GalaxyIntensity = from->Stars.GalaxyIntensity; to->Stars.StarIntensity = from->Stars.StarIntensity; to->Stars.MoonColor = from->Stars.MoonColor; to->Stars.MoonBrightness = from->Stars.MoonBrightness; to->Fog.Color = from->Fog.Color; to->Fog.Distance = from->Fog.Distance; to->Fog.Thickness = from->Fog.Thickness; to->Fog._unk1 = from->Fog._unk1; to->Fog._unk2 = from->Fog._unk2; to->Fog.Opacity = from->Fog.Opacity; to->Fog.SkyVisibility = from->Fog.SkyVisibility; to->Clouds.CloudColor = from->Clouds.CloudColor; to->Clouds.Color2 = from->Clouds.Color2; to->Clouds.Gradient = from->Clouds.Gradient; to->Clouds.SideHeight = from->Clouds.SideHeight; to->Clouds.CloudTexture = from->Clouds.CloudTexture; to->Clouds.CloudSideTexture = from->Clouds.CloudSideTexture; to->Rain.Raindrops = from->Rain.Raindrops; to->Rain.Intensity = from->Rain.Intensity; to->Rain.Weight = from->Rain.Weight; to->Rain.Scatter = from->Rain.Scatter; to->Rain._unk1 = from->Rain._unk1; to->Rain.Size = from->Rain.Size; to->Rain.Color = from->Rain.Color; to->Rain._unk2 = from->Rain._unk2; to->Rain._unk3 = from->Rain._unk3; to->Rain._unk4 = from->Rain._unk4; to->Dust._unk1 = from->Dust._unk1; to->Dust.Intensity = from->Dust.Intensity; to->Dust.Weight = from->Dust.Weight; to->Dust.Spread = from->Dust.Spread; to->Dust.Speed = from->Dust.Speed; to->Dust.Size = from->Dust.Size; to->Dust.Color = from->Dust.Color; to->Dust.Glow = from->Dust.Glow; to->Dust.Spin = from->Dust.Spin; to->Dust.TextureId = from->Dust.TextureId; to->Wind.Direction = from->Wind.Direction; to->Wind.Angle = from->Wind.Angle; to->Wind.Speed = from->Wind.Speed; } private unsafe delegate nint EnvStateCopyDelegate(EnvState* dest, EnvState* src); [Signature("E8 ?? ?? ?? ?? 49 3B F5 75 0D", DetourName = nameof(EnvStateCopyDetour))] private Hook _envStateCopyHook = null!; private unsafe nint EnvStateCopyDetour(EnvState* dest, EnvState* src) { Current = *dest; var exec = _envStateCopyHook.Original(dest, src); var replace = Preview != null; if (!Service.ClientState.IsLoggedIn) { replace |= dest->SkyId == 0; } else { replace |= dest->SkyId == 0 && dest->Clouds.Gradient == 0.5f && dest->Lighting._unk1 == 0.5f && dest->Lighting.Temperature == 0.6f && dest->Lighting._unk2 == 0.5f && dest->Fog.Color == new Vector4(0, 0, 0, 0) && dest->Fog.Distance == 0.0f && dest->Fog.Thickness == 0.0f && dest->Fog._unk1 == 1000.0f && dest->Fog._unk2 == 1.0f && dest->Fog.Opacity == 0.0f && dest->Fog.SkyVisibility == 1.0f; } if (replace) { Replace(dest); } return exec; } }