uwu
This commit is contained in:
parent
c827a5f570
commit
72d60a2bb5
|
@ -0,0 +1,19 @@
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
|
||||
namespace OrangeGuidanceTomestone;
|
||||
|
||||
[Serializable]
|
||||
[JsonObject(NamingStrategyType = typeof(SnakeCaseNamingStrategy))]
|
||||
internal class Message {
|
||||
public Guid Id { get; init; }
|
||||
public float X { get; init; }
|
||||
public float Y { get; init; }
|
||||
public float Z { get; init; }
|
||||
|
||||
[JsonProperty("message")]
|
||||
public string Text { get; init; }
|
||||
|
||||
public int PositiveVotes { get; init; }
|
||||
public int NegativeVotes { get; init; }
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
using System.Numerics;
|
||||
using Dalamud.Game;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace OrangeGuidanceTomestone;
|
||||
|
||||
internal class Messages : IDisposable {
|
||||
private const string VfxPath = "bg/ffxiv/fst_f1/common/vfx/eff/b0941trp1d_o.avfx";
|
||||
|
||||
private Plugin Plugin { get; }
|
||||
|
||||
private Queue<Message> SpawnQueue { get; } = new();
|
||||
|
||||
internal Messages(Plugin plugin) {
|
||||
this.Plugin = plugin;
|
||||
|
||||
this.SpawnVfx();
|
||||
|
||||
this.Plugin.Framework.Update += this.HandleSpawnQueue;
|
||||
this.Plugin.ClientState.Login += this.SpawnVfx;
|
||||
this.Plugin.ClientState.Logout += this.RemoveVfx;
|
||||
this.Plugin.ClientState.TerritoryChanged += this.SpawnVfx;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
this.Plugin.ClientState.TerritoryChanged -= this.SpawnVfx;
|
||||
this.Plugin.ClientState.Logout -= this.RemoveVfx;
|
||||
this.Plugin.ClientState.Login -= this.SpawnVfx;
|
||||
this.Plugin.Framework.Update -= this.HandleSpawnQueue;
|
||||
}
|
||||
|
||||
private unsafe void HandleSpawnQueue(Framework framework) {
|
||||
if (!this.SpawnQueue.TryDequeue(out var message)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.Plugin.Vfx.SpawnStatic(VfxPath, new Vector3(message.X, message.Y, message.Z));
|
||||
}
|
||||
|
||||
private void SpawnVfx(object? sender, EventArgs e) {
|
||||
this.SpawnVfx();
|
||||
}
|
||||
|
||||
private void SpawnVfx(object? sender, ushort e) {
|
||||
this.SpawnVfx();
|
||||
}
|
||||
|
||||
private void SpawnVfx() {
|
||||
var territory = this.Plugin.ClientState.TerritoryType;
|
||||
if (territory == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.RemoveVfx(null, null);
|
||||
|
||||
Task.Run(async () => {
|
||||
var resp = await new HttpClient().GetAsync($"https://tryfingerbuthole.anna.lgbt/messages/{territory}");
|
||||
var json = await resp.Content.ReadAsStringAsync();
|
||||
var messages = JsonConvert.DeserializeObject<Message[]>(json)!;
|
||||
foreach (var message in messages) {
|
||||
this.SpawnQueue.Enqueue(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void RemoveVfx(object? sender, EventArgs? e) {
|
||||
this.Plugin.Vfx.RemoveAll();
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.Plugin;
|
||||
|
||||
|
@ -13,8 +14,13 @@ public class Plugin : IDalamudPlugin {
|
|||
[PluginService]
|
||||
internal ClientState ClientState { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal Framework Framework { get; init; }
|
||||
|
||||
internal Configuration Config { get; }
|
||||
internal Vfx Vfx { get; }
|
||||
internal PluginUi Ui { get; }
|
||||
internal Messages Messages { get; }
|
||||
|
||||
public Plugin() {
|
||||
this.Config = this.Interface!.GetPluginConfig() as Configuration ?? new Configuration();
|
||||
|
@ -27,10 +33,13 @@ public class Plugin : IDalamudPlugin {
|
|||
});
|
||||
}
|
||||
|
||||
this.Vfx = new Vfx();
|
||||
this.Ui = new PluginUi(this);
|
||||
this.Messages = new Messages(this);
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
this.Messages.Dispose();
|
||||
this.Ui.Dispose();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Dalamud.Utility.Signatures;
|
||||
|
||||
namespace OrangeGuidanceTomestone;
|
||||
|
||||
internal unsafe class Vfx : IDisposable {
|
||||
private static readonly byte[] Pool = Encoding.UTF8.GetBytes("Client.System.Scheduler.Instance.VfxObject");
|
||||
|
||||
[Signature("E8 ?? ?? ?? ?? F3 0F 10 35 ?? ?? ?? ?? 48 89 43 08")]
|
||||
private delegate* unmanaged<byte*, byte*, VfxStruct*> _staticVfxCreate;
|
||||
|
||||
[Signature("E8 ?? ?? ?? ?? 8B 4B 7C 85 C9")]
|
||||
private delegate* unmanaged<VfxStruct*, float, uint, void> _staticVfxRun;
|
||||
|
||||
[Signature("40 53 48 83 EC 20 48 8B D9 48 8B 89 ?? ?? ?? ?? 48 85 C9 74 28 33 D2 E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9")]
|
||||
private delegate* unmanaged<VfxStruct*, void> _staticVfxRemove;
|
||||
|
||||
private List<IntPtr> Spawned { get; } = new();
|
||||
|
||||
internal Vfx() {
|
||||
SignatureHelper.Initialise(this);
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
this.RemoveAll();
|
||||
}
|
||||
|
||||
internal void RemoveAll() {
|
||||
foreach (var spawned in this.Spawned) {
|
||||
this.RemoveStatic((VfxStruct*) spawned);
|
||||
}
|
||||
|
||||
this.Spawned.Clear();
|
||||
}
|
||||
|
||||
internal VfxStruct* SpawnStatic(string path, Vector3 pos) {
|
||||
VfxStruct* vfx;
|
||||
fixed (byte* p = Encoding.UTF8.GetBytes(path)) {
|
||||
fixed (byte* pool = Pool) {
|
||||
vfx = this._staticVfxCreate(p, pool);
|
||||
}
|
||||
}
|
||||
|
||||
if (vfx == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
this._staticVfxRun(vfx, 0.0f, 0xFFFFFFFF);
|
||||
|
||||
// update position
|
||||
vfx->Position = new Vector3(pos.X, pos.Y, pos.Z);
|
||||
|
||||
// update
|
||||
vfx->Flags |= 2;
|
||||
|
||||
this.Spawned.Add((IntPtr) vfx);
|
||||
|
||||
return vfx;
|
||||
}
|
||||
|
||||
internal void RemoveStatic(VfxStruct* vfx) {
|
||||
this._staticVfxRemove(vfx);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal struct VfxStruct {
|
||||
[FieldOffset(0x38)]
|
||||
public byte Flags;
|
||||
|
||||
[FieldOffset(0x50)]
|
||||
public Vector3 Position;
|
||||
|
||||
[FieldOffset(0x70)]
|
||||
public Vector3 Scale;
|
||||
|
||||
[FieldOffset(0x128)]
|
||||
public int ActorCaster;
|
||||
|
||||
[FieldOffset(0x130)]
|
||||
public int ActorTarget;
|
||||
|
||||
[FieldOffset(0x1B8)]
|
||||
public int StaticCaster;
|
||||
|
||||
[FieldOffset(0x1C0)]
|
||||
public int StaticTarget;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue