202 lines
6.2 KiB
C#
202 lines
6.2 KiB
C#
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<Cmd> _cmds;
|
|
|
|
public Plugin(IDalamudPluginInterface pluginInterface)
|
|
{
|
|
pluginInterface.Create<Service>();
|
|
|
|
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, bool housing)
|
|
{
|
|
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, housing);
|
|
}
|
|
|
|
private void Replace(EnvState* to, EnvState* from, bool housing)
|
|
{
|
|
to->SkyId = from->SkyId;
|
|
|
|
if (!housing)
|
|
{
|
|
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<EnvStateCopyDelegate> _envStateCopyHook = null!;
|
|
private unsafe nint EnvStateCopyDetour(EnvState* dest, EnvState* src)
|
|
{
|
|
Current = *dest;
|
|
|
|
var exec = _envStateCopyHook.Original(dest, src);
|
|
|
|
var replace = Preview != null;
|
|
var housing = false;
|
|
|
|
if (!Service.ClientState.IsLoggedIn)
|
|
{
|
|
replace |= dest->SkyId == 0;
|
|
}
|
|
else
|
|
{
|
|
housing |=
|
|
dest->SkyId == 0 &&
|
|
dest->Clouds.Gradient == 0.5f &&
|
|
dest->Lighting._unk1 == 0.5f &&
|
|
Math.Abs(dest->Lighting.Temperature - 0.6f) < 0.01f &&
|
|
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;
|
|
|
|
replace |= housing;
|
|
}
|
|
|
|
if (replace)
|
|
{
|
|
Replace(dest, housing);
|
|
}
|
|
|
|
return exec;
|
|
}
|
|
}
|