uwu
This commit is contained in:
parent
2a47e2e251
commit
799700c985
19
client/Message.cs
Normal file
19
client/Message.cs
Normal file
|
@ -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; }
|
||||||
|
}
|
69
client/Messages.cs
Normal file
69
client/Messages.cs
Normal file
|
@ -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.IoC;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
|
|
||||||
|
@ -13,8 +14,13 @@ public class Plugin : IDalamudPlugin {
|
||||||
[PluginService]
|
[PluginService]
|
||||||
internal ClientState ClientState { get; init; }
|
internal ClientState ClientState { get; init; }
|
||||||
|
|
||||||
|
[PluginService]
|
||||||
|
internal Framework Framework { get; init; }
|
||||||
|
|
||||||
internal Configuration Config { get; }
|
internal Configuration Config { get; }
|
||||||
|
internal Vfx Vfx { get; }
|
||||||
internal PluginUi Ui { get; }
|
internal PluginUi Ui { get; }
|
||||||
|
internal Messages Messages { get; }
|
||||||
|
|
||||||
public Plugin() {
|
public Plugin() {
|
||||||
this.Config = this.Interface!.GetPluginConfig() as Configuration ?? new Configuration();
|
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.Ui = new PluginUi(this);
|
||||||
|
this.Messages = new Messages(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose() {
|
||||||
|
this.Messages.Dispose();
|
||||||
this.Ui.Dispose();
|
this.Ui.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
90
client/Vfx.cs
Normal file
90
client/Vfx.cs
Normal file
|
@ -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
Block a user